 |
|
 |
|
| Files: |
1 |
|
Branches Taken: |
17.2% |
5 / 29 |
| Generated: |
2010-02-10 01:31 |
|
Branches Executed: |
17.2% |
5 / 29 |
| |
|
Line Coverage: |
73.7% |
123 / 167 |
| |
 |
|
 |
1 : //===--- Attr.h - Classes for representing expressions ----------*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // This file defines the Attr interface and subclasses.
11 : //
12 : //===----------------------------------------------------------------------===//
13 :
14 : #ifndef LLVM_CLANG_AST_ATTR_H
15 : #define LLVM_CLANG_AST_ATTR_H
16 :
17 : #include "llvm/Support/Casting.h"
18 : #include "llvm/ADT/StringRef.h"
19 : #include <cassert>
20 : #include <cstring>
21 : #include <string>
22 : #include <algorithm>
23 : using llvm::dyn_cast;
24 :
25 : namespace clang {
26 : class ASTContext;
27 : }
28 :
29 :
30 : // Defined in ASTContext.h
31 : void *operator new(size_t Bytes, clang::ASTContext &C,
32 : size_t Alignment = 16) throw ();
33 :
34 : // It is good practice to pair new/delete operators. Also, MSVC gives many
35 : // warnings if a matching delete overload is not declared, even though the
36 : // throw() spec guarantees it will not be implicitly called.
37 : void operator delete(void *Ptr, clang::ASTContext &C, size_t)
38 : throw ();
39 :
40 : namespace clang {
41 :
42 : /// Attr - This represents one attribute.
43 : class Attr {
44 : public:
45 : enum Kind {
46 : Alias,
47 : Aligned,
48 : AlwaysInline,
49 : AnalyzerNoReturn, // Clang-specific.
50 : Annotate,
51 : AsmLabel, // Represent GCC asm label extension.
52 : BaseCheck,
53 : Blocks,
54 : CDecl,
55 : Cleanup,
56 : Const,
57 : Constructor,
58 : Deprecated,
59 : Destructor,
60 : FastCall,
61 : Final,
62 : Format,
63 : FormatArg,
64 : GNUInline,
65 : Hiding,
66 : IBOutletKind, // Clang-specific. Use "Kind" suffix to not conflict with
67 : Malloc,
68 : NoDebug,
69 : NoInline,
70 : NonNull,
71 : NoReturn,
72 : NoThrow,
73 : ObjCException,
74 : ObjCNSObject,
75 : Override,
76 : CFReturnsRetained, // Clang/Checker-specific.
77 : NSReturnsRetained, // Clang/Checker-specific.
78 : Overloadable, // Clang-specific
79 : Packed,
80 : PragmaPack,
81 : Pure,
82 : Regparm,
83 : ReqdWorkGroupSize, // OpenCL-specific
84 : Section,
85 : Sentinel,
86 : StdCall,
87 : TransparentUnion,
88 : Unavailable,
89 : Unused,
90 : Used,
91 : Visibility,
92 : WarnUnusedResult,
93 : Weak,
94 : WeakImport,
95 :
96 : FIRST_TARGET_ATTRIBUTE,
97 : DLLExport,
98 : DLLImport,
99 : MSP430Interrupt
100 : };
101 :
102 : private:
103 : Attr *Next;
104 : Kind AttrKind;
105 : bool Inherited : 1;
106 :
107 : protected:
108 : void* operator new(size_t bytes) throw() {
109 : assert(0 && "Attrs cannot be allocated with regular 'new'.");
110 : return 0;
111 : }
112 0: void operator delete(void* data) throw() {
113 0: assert(0 && "Attrs cannot be released with regular 'delete'.");
114 : }
115 :
116 : protected:
117 4981: Attr(Kind AK) : Next(0), AttrKind(AK), Inherited(false) {}
118 0: virtual ~Attr() {
0: branch 0 not taken
0: branch 1 not taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 6 not taken
0: branch 7 not taken
119 0: assert(Next == 0 && "Destroy didn't work");
0: branch 0 not taken
0: branch 1 not taken
0: branch 3 not taken
0: branch 4 not taken
0: branch 7 not taken
120 0: }
121 : public:
122 :
123 : void Destroy(ASTContext &C);
124 :
125 : /// \brief Whether this attribute should be merged to new
126 : /// declarations.
127 163: virtual bool isMerged() const { return true; }
128 :
129 35602: Kind getKind() const { return AttrKind; }
130 :
131 6: Attr *getNext() { return Next; }
132 31333: const Attr *getNext() const { return Next; }
133 4993: void setNext(Attr *next) { Next = next; }
134 :
135 113: template<typename T> const T *getNext() const {
65: branch 3 taken
0: branch 3 not taken
136 125: for (const Attr *attr = getNext(); attr; attr = attr->getNext())
2: branch 1 taken
12: branch 2 taken
137 16: if (const T *V = dyn_cast<T>(attr))
138 4: return V;
139 109: return 0;
140 : }
141 :
142 10: bool isInherited() const { return Inherited; }
143 169: void setInherited(bool value) { Inherited = value; }
144 :
145 : void addAttr(Attr *attr) {
146 : assert((attr != 0) && "addAttr(): attr is null");
147 :
148 : // FIXME: This doesn't preserve the order in any way.
149 : attr->Next = Next;
150 : Next = attr;
151 : }
152 :
153 : // Clone this attribute.
154 : virtual Attr* clone(ASTContext &C) const = 0;
155 :
156 : // Implement isa/cast/dyncast/etc.
157 : static bool classof(const Attr *) { return true; }
158 : };
159 :
160 : #define DEF_SIMPLE_ATTR(ATTR) \
161 : class ATTR##Attr : public Attr { \
162 : public: \
163 : ATTR##Attr() : Attr(ATTR) {} \
164 : virtual Attr *clone(ASTContext &C) const; \
165 : static bool classof(const Attr *A) { return A->getKind() == ATTR; } \
166 : static bool classof(const ATTR##Attr *A) { return true; } \
167 : }
168 :
0: branch 2 not taken
0: branch 3 not taken
0: branch 6 not taken
0: branch 7 not taken
169 166: DEF_SIMPLE_ATTR(Packed);
170 :
0: branch 1 not taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
171 0: class PragmaPackAttr : public Attr {
172 : unsigned Alignment;
173 :
174 : public:
175 24: PragmaPackAttr(unsigned alignment) : Attr(PragmaPack), Alignment(alignment) {}
176 :
177 : /// getAlignment - The specified alignment in bits.
178 27: unsigned getAlignment() const { return Alignment; }
179 :
180 : virtual Attr* clone(ASTContext &C) const;
181 :
182 : // Implement isa/cast/dyncast/etc.
183 84: static bool classof(const Attr *A) {
184 84: return A->getKind() == PragmaPack;
185 : }
186 : static bool classof(const PragmaPackAttr *A) { return true; }
187 : };
188 :
0: branch 1 not taken
0: branch 2 not taken
0: branch 5 not taken
0: branch 6 not taken
189 0: class AlignedAttr : public Attr {
190 : unsigned Alignment;
191 : public:
192 55: AlignedAttr(unsigned alignment)
193 55: : Attr(Aligned), Alignment(alignment) {}
194 :
195 : /// getAlignment - The specified alignment in bits.
196 4: unsigned getAlignment() const { return Alignment; }
197 :
198 : /// getMaxAlignment - Get the maximum alignment of attributes on this list.
199 63: unsigned getMaxAlignment() const {
200 63: const AlignedAttr *Next = getNext<AlignedAttr>();
2: branch 0 taken
61: branch 1 taken
201 63: if (Next)
202 2: return std::max(Next->getMaxAlignment(), Alignment);
203 : else
204 61: return Alignment;
205 : }
206 :
207 : virtual Attr* clone(ASTContext &C) const;
208 :
209 : // Implement isa/cast/dyncast/etc.
210 414: static bool classof(const Attr *A) {
211 414: return A->getKind() == Aligned;
212 : }
213 : static bool classof(const AlignedAttr *A) { return true; }
214 : };
215 :
216 0: class AnnotateAttr : public Attr {
217 : std::string Annotation;
218 : public:
219 4: AnnotateAttr(llvm::StringRef ann) : Attr(Annotate), Annotation(ann) {}
220 :
221 2: const std::string& getAnnotation() const { return Annotation; }
222 :
223 : virtual Attr* clone(ASTContext &C) const;
224 :
225 : // Implement isa/cast/dyncast/etc.
226 34: static bool classof(const Attr *A) {
227 34: return A->getKind() == Annotate;
228 : }
229 : static bool classof(const AnnotateAttr *A) { return true; }
230 : };
231 :
232 0: class AsmLabelAttr : public Attr {
233 : std::string Label;
234 : public:
235 34: AsmLabelAttr(llvm::StringRef L) : Attr(AsmLabel), Label(L) {}
236 :
237 27: const std::string& getLabel() const { return Label; }
238 :
239 : virtual Attr* clone(ASTContext &C) const;
240 :
241 : // Implement isa/cast/dyncast/etc.
242 776: static bool classof(const Attr *A) {
243 776: return A->getKind() == AsmLabel;
244 : }
245 : static bool classof(const AsmLabelAttr *A) { return true; }
246 : };
247 :
248 1380: DEF_SIMPLE_ATTR(AlwaysInline);
249 :
250 0: class AliasAttr : public Attr {
251 : std::string Aliasee;
252 : public:
253 29: AliasAttr(llvm::StringRef aliasee) : Attr(Alias), Aliasee(aliasee) {}
254 :
255 27: const std::string& getAliasee() const { return Aliasee; }
256 :
257 : virtual Attr *clone(ASTContext &C) const;
258 :
259 : // Implement isa/cast/dyncast/etc.
260 903: static bool classof(const Attr *A) { return A->getKind() == Alias; }
261 : static bool classof(const AliasAttr *A) { return true; }
262 : };
263 :
264 0: class ConstructorAttr : public Attr {
265 : int priority;
266 : public:
267 15: ConstructorAttr(int p) : Attr(Constructor), priority(p) {}
268 :
269 2: int getPriority() const { return priority; }
270 :
271 : virtual Attr *clone(ASTContext &C) const;
272 :
273 : // Implement isa/cast/dyncast/etc.
274 374: static bool classof(const Attr *A) { return A->getKind() == Constructor; }
275 : static bool classof(const ConstructorAttr *A) { return true; }
276 : };
277 :
278 0: class DestructorAttr : public Attr {
279 : int priority;
280 : public:
281 9: DestructorAttr(int p) : Attr(Destructor), priority(p) {}
282 :
283 2: int getPriority() const { return priority; }
284 :
285 : virtual Attr *clone(ASTContext &C) const;
286 :
287 : // Implement isa/cast/dyncast/etc.
288 370: static bool classof(const Attr *A) { return A->getKind() == Destructor; }
289 : static bool classof(const DestructorAttr *A) { return true; }
290 : };
291 :
292 0: class GNUInlineAttr : public Attr {
293 : public:
294 28: GNUInlineAttr() : Attr(GNUInline) {}
295 :
296 : virtual Attr *clone(ASTContext &C) const;
297 :
298 : // Implement isa/cast/dyncast/etc.
299 50: static bool classof(const Attr *A) {
300 50: return A->getKind() == GNUInline;
301 : }
302 : static bool classof(const GNUInlineAttr *A) { return true; }
303 : };
304 :
305 0: class IBOutletAttr : public Attr {
306 : public:
307 1: IBOutletAttr() : Attr(IBOutletKind) {}
308 :
309 : virtual Attr *clone(ASTContext &C) const;
310 :
311 : // Implement isa/cast/dyncast/etc.
312 2: static bool classof(const Attr *A) {
313 2: return A->getKind() == IBOutletKind;
314 : }
315 : static bool classof(const IBOutletAttr *A) { return true; }
316 : };
317 :
318 505: DEF_SIMPLE_ATTR(Malloc);
319 6284: DEF_SIMPLE_ATTR(NoReturn);
320 296: DEF_SIMPLE_ATTR(AnalyzerNoReturn);
321 2125: DEF_SIMPLE_ATTR(Deprecated);
322 8: DEF_SIMPLE_ATTR(Final);
323 :
324 0: class SectionAttr : public Attr {
325 : std::string Name;
326 : public:
327 12: SectionAttr(llvm::StringRef N) : Attr(Section), Name(N) {}
328 :
329 12: const std::string& getName() const { return Name; }
330 :
331 : virtual Attr *clone(ASTContext &C) const;
332 :
333 : // Implement isa/cast/dyncast/etc.
334 389: static bool classof(const Attr *A) {
335 389: return A->getKind() == Section;
336 : }
337 : static bool classof(const SectionAttr *A) { return true; }
338 : };
339 :
340 2337: DEF_SIMPLE_ATTR(Unavailable);
341 217: DEF_SIMPLE_ATTR(Unused);
342 506: DEF_SIMPLE_ATTR(Used);
343 443: DEF_SIMPLE_ATTR(Weak);
344 267: DEF_SIMPLE_ATTR(WeakImport);
345 1821: DEF_SIMPLE_ATTR(NoThrow);
346 1032: DEF_SIMPLE_ATTR(Const);
347 845: DEF_SIMPLE_ATTR(Pure);
348 :
349 : class NonNullAttr : public Attr {
350 : unsigned* ArgNums;
351 : unsigned Size;
352 : public:
353 407: NonNullAttr(unsigned* arg_nums = 0, unsigned size = 0) : Attr(NonNull),
354 407: ArgNums(0), Size(0) {
355 :
356 407: if (size == 0) return;
357 407: assert(arg_nums);
358 407: ArgNums = new unsigned[size];
359 407: Size = size;
360 407: memcpy(ArgNums, arg_nums, sizeof(*ArgNums)*size);
361 : }
362 :
363 0: virtual ~NonNullAttr() {
364 0: delete [] ArgNums;
365 0: }
366 :
367 : typedef const unsigned *iterator;
368 46: iterator begin() const { return ArgNums; }
369 46: iterator end() const { return ArgNums + Size; }
370 0: unsigned size() const { return Size; }
371 :
372 70: bool isNonNull(unsigned arg) const {
373 70: return ArgNums ? std::binary_search(ArgNums, ArgNums+Size, arg) : true;
374 : }
375 :
376 : virtual Attr *clone(ASTContext &C) const;
377 :
378 2191: static bool classof(const Attr *A) { return A->getKind() == NonNull; }
379 : static bool classof(const NonNullAttr *A) { return true; }
380 : };
381 :
382 0: class FormatAttr : public Attr {
383 : std::string Type;
384 : int formatIdx, firstArg;
385 : public:
386 261: FormatAttr(llvm::StringRef type, int idx, int first) : Attr(Format),
387 261: Type(type), formatIdx(idx), firstArg(first) {}
388 :
389 510: const std::string& getType() const { return Type; }
390 14: void setType(llvm::StringRef type) { Type = type; }
391 506: int getFormatIdx() const { return formatIdx; }
392 984: int getFirstArg() const { return firstArg; }
393 :
394 : virtual Attr *clone(ASTContext &C) const;
395 :
396 : // Implement isa/cast/dyncast/etc.
397 2502: static bool classof(const Attr *A) { return A->getKind() == Format; }
398 : static bool classof(const FormatAttr *A) { return true; }
399 : };
400 :
401 0: class FormatArgAttr : public Attr {
402 : int formatIdx;
403 : public:
404 9: FormatArgAttr(int idx) : Attr(FormatArg), formatIdx(idx) {}
405 3: int getFormatIdx() const { return formatIdx; }
406 :
407 : virtual Attr *clone(ASTContext &C) const;
408 :
409 : // Implement isa/cast/dyncast/etc.
410 6: static bool classof(const Attr *A) { return A->getKind() == FormatArg; }
411 : static bool classof(const FormatArgAttr *A) { return true; }
412 : };
413 :
414 0: class SentinelAttr : public Attr {
415 : int sentinel, NullPos;
416 : public:
417 29: SentinelAttr(int sentinel_val, int nullPos) : Attr(Sentinel),
418 29: sentinel(sentinel_val), NullPos(nullPos) {}
419 33: int getSentinel() const { return sentinel; }
420 33: int getNullPos() const { return NullPos; }
421 :
422 : virtual Attr *clone(ASTContext &C) const;
423 :
424 : // Implement isa/cast/dyncast/etc.
425 1879: static bool classof(const Attr *A) { return A->getKind() == Sentinel; }
426 : static bool classof(const SentinelAttr *A) { return true; }
427 : };
428 :
429 0: class VisibilityAttr : public Attr {
430 : public:
431 : /// @brief An enumeration for the kinds of visibility of symbols.
432 : enum VisibilityTypes {
433 : DefaultVisibility = 0,
434 : HiddenVisibility,
435 : ProtectedVisibility
436 : };
437 : private:
438 : VisibilityTypes VisibilityType;
439 : public:
440 15: VisibilityAttr(VisibilityTypes v) : Attr(Visibility),
441 15: VisibilityType(v) {}
442 :
443 13: VisibilityTypes getVisibility() const { return VisibilityType; }
444 :
445 : virtual Attr *clone(ASTContext &C) const;
446 :
447 : // Implement isa/cast/dyncast/etc.
448 154: static bool classof(const Attr *A) { return A->getKind() == Visibility; }
449 : static bool classof(const VisibilityAttr *A) { return true; }
450 : };
451 :
452 0: DEF_SIMPLE_ATTR(FastCall);
453 0: DEF_SIMPLE_ATTR(StdCall);
454 0: DEF_SIMPLE_ATTR(CDecl);
455 12: DEF_SIMPLE_ATTR(TransparentUnion);
456 21: DEF_SIMPLE_ATTR(ObjCNSObject);
457 21: DEF_SIMPLE_ATTR(ObjCException);
458 :
459 0: class OverloadableAttr : public Attr {
460 : public:
461 39: OverloadableAttr() : Attr(Overloadable) { }
462 :
463 1: virtual bool isMerged() const { return false; }
464 :
465 : virtual Attr *clone(ASTContext &C) const;
466 :
467 3937: static bool classof(const Attr *A) { return A->getKind() == Overloadable; }
468 : static bool classof(const OverloadableAttr *) { return true; }
469 : };
470 :
471 0: class BlocksAttr : public Attr {
472 : public:
473 : enum BlocksAttrTypes {
474 : ByRef = 0
475 : };
476 : private:
477 : BlocksAttrTypes BlocksAttrType;
478 : public:
479 113: BlocksAttr(BlocksAttrTypes t) : Attr(Blocks), BlocksAttrType(t) {}
480 :
481 1: BlocksAttrTypes getType() const { return BlocksAttrType; }
482 :
483 : virtual Attr *clone(ASTContext &C) const;
484 :
485 : // Implement isa/cast/dyncast/etc.
486 1217: static bool classof(const Attr *A) { return A->getKind() == Blocks; }
487 : static bool classof(const BlocksAttr *A) { return true; }
488 : };
489 :
490 : class FunctionDecl;
491 :
492 0: class CleanupAttr : public Attr {
493 : FunctionDecl *FD;
494 :
495 : public:
496 8: CleanupAttr(FunctionDecl *fd) : Attr(Cleanup), FD(fd) {}
497 :
498 4: const FunctionDecl *getFunctionDecl() const { return FD; }
499 :
500 : virtual Attr *clone(ASTContext &C) const;
501 :
502 : // Implement isa/cast/dyncast/etc.
503 378: static bool classof(const Attr *A) { return A->getKind() == Cleanup; }
504 : static bool classof(const CleanupAttr *A) { return true; }
505 : };
506 :
507 1265: DEF_SIMPLE_ATTR(NoDebug);
508 550: DEF_SIMPLE_ATTR(WarnUnusedResult);
509 110: DEF_SIMPLE_ATTR(NoInline);
510 :
511 0: class RegparmAttr : public Attr {
512 : unsigned NumParams;
513 :
514 : public:
515 8: RegparmAttr(unsigned np) : Attr(Regparm), NumParams(np) {}
516 :
517 4: unsigned getNumParams() const { return NumParams; }
518 :
519 : virtual Attr *clone(ASTContext &C) const;
520 :
521 : // Implement isa/cast/dyncast/etc.
522 304: static bool classof(const Attr *A) { return A->getKind() == Regparm; }
523 : static bool classof(const RegparmAttr *A) { return true; }
524 : };
525 :
526 0: class ReqdWorkGroupSizeAttr : public Attr {
527 : unsigned X, Y, Z;
528 : public:
529 0: ReqdWorkGroupSizeAttr(unsigned X, unsigned Y, unsigned Z)
530 0: : Attr(ReqdWorkGroupSize), X(X), Y(Y), Z(Z) {}
531 :
532 0: unsigned getXDim() const { return X; }
533 0: unsigned getYDim() const { return Y; }
534 0: unsigned getZDim() const { return Z; }
535 :
536 : virtual Attr *clone(ASTContext &C) const;
537 :
538 : // Implement isa/cast/dyncast/etc.
539 0: static bool classof(const Attr *A) {
540 0: return A->getKind() == ReqdWorkGroupSize;
541 : }
542 : static bool classof(const ReqdWorkGroupSizeAttr *A) { return true; }
543 : };
544 :
545 : // Checker-specific attributes.
546 167: DEF_SIMPLE_ATTR(CFReturnsRetained);
547 59: DEF_SIMPLE_ATTR(NSReturnsRetained);
548 :
549 : // C++0x member checking attributes.
550 3: DEF_SIMPLE_ATTR(BaseCheck);
551 0: DEF_SIMPLE_ATTR(Hiding);
552 0: DEF_SIMPLE_ATTR(Override);
553 :
554 : // Target-specific attributes
555 2858: DEF_SIMPLE_ATTR(DLLImport);
556 141: DEF_SIMPLE_ATTR(DLLExport);
557 :
558 0: class MSP430InterruptAttr : public Attr {
559 : unsigned Number;
560 :
561 : public:
562 0: MSP430InterruptAttr(unsigned n) : Attr(MSP430Interrupt), Number(n) {}
563 :
564 0: unsigned getNumber() const { return Number; }
565 :
566 : virtual Attr *clone(ASTContext &C) const;
567 :
568 : // Implement isa/cast/dyncast/etc.
569 0: static bool classof(const Attr *A) { return A->getKind() == MSP430Interrupt; }
570 : static bool classof(const MSP430InterruptAttr *A) { return true; }
571 : };
572 :
573 : #undef DEF_SIMPLE_ATTR
574 :
575 : } // end namespace clang
576 :
577 : #endif
Generated: 2010-02-10 01:31 by zcov