1 //===--- Attr.h - Classes for representing expressions ----------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the Attr interface and subclasses.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_AST_ATTR_H
15 #define LLVM_CLANG_AST_ATTR_H
17 #include "llvm/Support/Casting.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "clang/Basic/AttrKinds.h"
28 class ObjCInterfaceDecl;
32 // Defined in ASTContext.h
33 void *operator new(size_t Bytes, clang::ASTContext &C,
34 size_t Alignment = 16) throw ();
36 // It is good practice to pair new/delete operators. Also, MSVC gives many
37 // warnings if a matching delete overload is not declared, even though the
38 // throw() spec guarantees it will not be implicitly called.
39 void operator delete(void *Ptr, clang::ASTContext &C, size_t)
44 /// Attr - This represents one attribute.
52 void* operator new(size_t bytes) throw() {
53 assert(0 && "Attrs cannot be allocated with regular 'new'.");
56 void operator delete(void* data) throw() {
57 assert(0 && "Attrs cannot be released with regular 'delete'.");
61 Attr(attr::Kind AK) : Next(0), AttrKind(AK), Inherited(false) {}
63 assert(Next == 0 && "Destroy didn't work");
66 virtual void Destroy(ASTContext &C);
68 /// \brief Whether this attribute should be merged to new
70 virtual bool isMerged() const { return true; }
72 attr::Kind getKind() const { return AttrKind; }
74 Attr *getNext() { return Next; }
75 const Attr *getNext() const { return Next; }
76 void setNext(Attr *next) { Next = next; }
78 template<typename T> const T *getNext() const {
79 for (const Attr *attr = getNext(); attr; attr = attr->getNext())
80 if (const T *V = dyn_cast<T>(attr))
85 bool isInherited() const { return Inherited; }
86 void setInherited(bool value) { Inherited = value; }
88 void addAttr(Attr *attr) {
89 assert((attr != 0) && "addAttr(): attr is null");
91 // FIXME: This doesn't preserve the order in any way.
96 // Clone this attribute.
97 virtual Attr* clone(ASTContext &C) const = 0;
99 // Implement isa/cast/dyncast/etc.
100 static bool classof(const Attr *) { return true; }
103 #include "clang/AST/Attrs.inc"
105 class AttrWithString : public Attr {
110 AttrWithString(attr::Kind AK, ASTContext &C, llvm::StringRef s);
111 llvm::StringRef getString() const { return llvm::StringRef(Str, StrLen); }
112 void ReplaceString(ASTContext &C, llvm::StringRef newS);
114 virtual void Destroy(ASTContext &C);
117 #define DEF_SIMPLE_ATTR(ATTR) \
118 class ATTR##Attr : public Attr { \
120 ATTR##Attr() : Attr(attr::ATTR) {} \
121 virtual Attr *clone(ASTContext &C) const; \
122 static bool classof(const Attr *A) { return A->getKind() == attr::ATTR; } \
123 static bool classof(const ATTR##Attr *A) { return true; } \
126 DEF_SIMPLE_ATTR(Packed);
128 /// \brief Attribute for specifying a maximum field alignment; this is only
129 /// valid on record decls.
130 class MaxFieldAlignmentAttr : public Attr {
134 MaxFieldAlignmentAttr(unsigned alignment)
135 : Attr(attr::MaxFieldAlignment), Alignment(alignment) {}
137 /// getAlignment - The specified alignment in bits.
138 unsigned getAlignment() const { return Alignment; }
140 virtual Attr* clone(ASTContext &C) const;
142 // Implement isa/cast/dyncast/etc.
143 static bool classof(const Attr *A) {
144 return A->getKind() == attr::MaxFieldAlignment;
146 static bool classof(const MaxFieldAlignmentAttr *A) { return true; }
149 DEF_SIMPLE_ATTR(AlignMac68k);
151 /// \brief Atribute for specifying the alignment of a variable or type.
153 /// This node will either contain the precise Alignment (in bits, not bytes!)
154 /// or will contain the expression for the alignment attribute in the case of
155 /// a dependent expression within a class or function template. At template
156 /// instantiation time these are transformed into concrete attributes.
157 class AlignedAttr : public Attr {
161 AlignedAttr(unsigned alignment)
162 : Attr(attr::Aligned), Alignment(alignment), AlignmentExpr(0) {}
164 : Attr(attr::Aligned), Alignment(0), AlignmentExpr(E) {}
166 /// getAlignmentExpr - Get a dependent alignment expression if one is present.
167 Expr *getAlignmentExpr() const {
168 return AlignmentExpr;
171 /// isDependent - Is the alignment a dependent expression
172 bool isDependent() const {
173 return getAlignmentExpr();
176 /// getAlignment - The specified alignment in bits. Requires !isDependent().
177 unsigned getAlignment() const {
178 assert(!isDependent() && "Cannot get a value dependent alignment");
182 /// getMaxAlignment - Get the maximum alignment of attributes on this list.
183 unsigned getMaxAlignment() const {
184 const AlignedAttr *Next = getNext<AlignedAttr>();
186 return std::max(Next->getMaxAlignment(), getAlignment());
188 return getAlignment();
191 virtual Attr* clone(ASTContext &C) const;
193 // Implement isa/cast/dyncast/etc.
194 static bool classof(const Attr *A) {
195 return A->getKind() == attr::Aligned;
197 static bool classof(const AlignedAttr *A) { return true; }
200 class AnnotateAttr : public AttrWithString {
202 AnnotateAttr(ASTContext &C, llvm::StringRef ann)
203 : AttrWithString(attr::Annotate, C, ann) {}
205 llvm::StringRef getAnnotation() const { return getString(); }
207 virtual Attr* clone(ASTContext &C) const;
209 // Implement isa/cast/dyncast/etc.
210 static bool classof(const Attr *A) {
211 return A->getKind() == attr::Annotate;
213 static bool classof(const AnnotateAttr *A) { return true; }
216 class AsmLabelAttr : public AttrWithString {
218 AsmLabelAttr(ASTContext &C, llvm::StringRef L)
219 : AttrWithString(attr::AsmLabel, C, L) {}
221 llvm::StringRef getLabel() const { return getString(); }
223 virtual Attr* clone(ASTContext &C) const;
225 // Implement isa/cast/dyncast/etc.
226 static bool classof(const Attr *A) {
227 return A->getKind() == attr::AsmLabel;
229 static bool classof(const AsmLabelAttr *A) { return true; }
232 DEF_SIMPLE_ATTR(AlwaysInline);
234 class AliasAttr : public AttrWithString {
236 AliasAttr(ASTContext &C, llvm::StringRef aliasee)
237 : AttrWithString(attr::Alias, C, aliasee) {}
239 llvm::StringRef getAliasee() const { return getString(); }
241 virtual Attr *clone(ASTContext &C) const;
243 // Implement isa/cast/dyncast/etc.
244 static bool classof(const Attr *A) { return A->getKind() == attr::Alias; }
245 static bool classof(const AliasAttr *A) { return true; }
248 class ConstructorAttr : public Attr {
251 ConstructorAttr(int p) : Attr(attr::Constructor), priority(p) {}
253 int getPriority() const { return priority; }
255 virtual Attr *clone(ASTContext &C) const;
257 // Implement isa/cast/dyncast/etc.
258 static bool classof(const Attr *A)
259 { return A->getKind() == attr::Constructor; }
260 static bool classof(const ConstructorAttr *A) { return true; }
263 class DestructorAttr : public Attr {
266 DestructorAttr(int p) : Attr(attr::Destructor), priority(p) {}
268 int getPriority() const { return priority; }
270 virtual Attr *clone(ASTContext &C) const;
272 // Implement isa/cast/dyncast/etc.
273 static bool classof(const Attr *A)
274 { return A->getKind() == attr::Destructor; }
275 static bool classof(const DestructorAttr *A) { return true; }
278 class IBOutletAttr : public Attr {
280 IBOutletAttr() : Attr(attr::IBOutlet) {}
282 virtual Attr *clone(ASTContext &C) const;
284 // Implement isa/cast/dyncast/etc.
285 static bool classof(const Attr *A) {
286 return A->getKind() == attr::IBOutlet;
288 static bool classof(const IBOutletAttr *A) { return true; }
291 class IBOutletCollectionAttr : public Attr {
292 const ObjCInterfaceDecl *D;
294 IBOutletCollectionAttr(const ObjCInterfaceDecl *d = 0)
295 : Attr(attr::IBOutletCollection), D(d) {}
297 const ObjCInterfaceDecl *getClass() const { return D; }
299 virtual Attr *clone(ASTContext &C) const;
301 // Implement isa/cast/dyncast/etc.
302 static bool classof(const Attr *A) {
303 return A->getKind() == attr::IBOutletCollection;
305 static bool classof(const IBOutletCollectionAttr *A) { return true; }
308 class IBActionAttr : public Attr {
310 IBActionAttr() : Attr(attr::IBAction) {}
312 virtual Attr *clone(ASTContext &C) const;
314 // Implement isa/cast/dyncast/etc.
315 static bool classof(const Attr *A) {
316 return A->getKind() == attr::IBAction;
318 static bool classof(const IBActionAttr *A) { return true; }
321 DEF_SIMPLE_ATTR(AnalyzerNoReturn);
322 DEF_SIMPLE_ATTR(Deprecated);
323 DEF_SIMPLE_ATTR(GNUInline);
324 DEF_SIMPLE_ATTR(Malloc);
325 DEF_SIMPLE_ATTR(NoReturn);
326 DEF_SIMPLE_ATTR(NoInstrumentFunction);
328 class SectionAttr : public AttrWithString {
330 SectionAttr(ASTContext &C, llvm::StringRef N)
331 : AttrWithString(attr::Section, C, N) {}
333 llvm::StringRef getName() const { return getString(); }
335 virtual Attr *clone(ASTContext &C) const;
337 // Implement isa/cast/dyncast/etc.
338 static bool classof(const Attr *A) {
339 return A->getKind() == attr::Section;
341 static bool classof(const SectionAttr *A) { return true; }
344 DEF_SIMPLE_ATTR(Unavailable);
345 DEF_SIMPLE_ATTR(Unused);
346 DEF_SIMPLE_ATTR(Used);
347 DEF_SIMPLE_ATTR(Weak);
348 DEF_SIMPLE_ATTR(WeakImport);
349 DEF_SIMPLE_ATTR(WeakRef);
350 DEF_SIMPLE_ATTR(NoThrow);
351 DEF_SIMPLE_ATTR(Const);
352 DEF_SIMPLE_ATTR(Pure);
354 class NonNullAttr : public Attr {
358 NonNullAttr(ASTContext &C, unsigned* arg_nums = 0, unsigned size = 0);
360 virtual void Destroy(ASTContext &C);
362 typedef const unsigned *iterator;
363 iterator begin() const { return ArgNums; }
364 iterator end() const { return ArgNums + Size; }
365 unsigned size() const { return Size; }
367 bool isNonNull(unsigned arg) const {
368 return ArgNums ? std::binary_search(ArgNums, ArgNums+Size, arg) : true;
371 virtual Attr *clone(ASTContext &C) const;
373 static bool classof(const Attr *A) { return A->getKind() == attr::NonNull; }
374 static bool classof(const NonNullAttr *A) { return true; }
377 class FormatAttr : public AttrWithString {
378 int formatIdx, firstArg;
380 FormatAttr(ASTContext &C, llvm::StringRef type, int idx, int first)
381 : AttrWithString(attr::Format, C, type), formatIdx(idx), firstArg(first) {}
383 llvm::StringRef getType() const { return getString(); }
384 void setType(ASTContext &C, llvm::StringRef type);
385 int getFormatIdx() const { return formatIdx; }
386 int getFirstArg() const { return firstArg; }
388 virtual Attr *clone(ASTContext &C) const;
390 // Implement isa/cast/dyncast/etc.
391 static bool classof(const Attr *A) { return A->getKind() == attr::Format; }
392 static bool classof(const FormatAttr *A) { return true; }
395 class FormatArgAttr : public Attr {
398 FormatArgAttr(int idx) : Attr(attr::FormatArg), formatIdx(idx) {}
399 int getFormatIdx() const { return formatIdx; }
401 virtual Attr *clone(ASTContext &C) const;
403 // Implement isa/cast/dyncast/etc.
404 static bool classof(const Attr *A) { return A->getKind() == attr::FormatArg; }
405 static bool classof(const FormatArgAttr *A) { return true; }
408 class SentinelAttr : public Attr {
409 int sentinel, NullPos;
411 SentinelAttr(int sentinel_val, int nullPos) : Attr(attr::Sentinel),
412 sentinel(sentinel_val), NullPos(nullPos) {}
413 int getSentinel() const { return sentinel; }
414 int getNullPos() const { return NullPos; }
416 virtual Attr *clone(ASTContext &C) const;
418 // Implement isa/cast/dyncast/etc.
419 static bool classof(const Attr *A) { return A->getKind() == attr::Sentinel; }
420 static bool classof(const SentinelAttr *A) { return true; }
423 class VisibilityAttr : public Attr {
425 /// @brief An enumeration for the kinds of visibility of symbols.
426 enum VisibilityTypes {
427 DefaultVisibility = 0,
432 VisibilityTypes VisibilityType;
434 VisibilityAttr(VisibilityTypes v) : Attr(attr::Visibility),
437 VisibilityTypes getVisibility() const { return VisibilityType; }
439 virtual Attr *clone(ASTContext &C) const;
441 // Implement isa/cast/dyncast/etc.
442 static bool classof(const Attr *A)
443 { return A->getKind() == attr::Visibility; }
444 static bool classof(const VisibilityAttr *A) { return true; }
447 DEF_SIMPLE_ATTR(FastCall);
448 DEF_SIMPLE_ATTR(StdCall);
449 DEF_SIMPLE_ATTR(ThisCall);
450 DEF_SIMPLE_ATTR(CDecl);
451 DEF_SIMPLE_ATTR(TransparentUnion);
452 DEF_SIMPLE_ATTR(ObjCNSObject);
453 DEF_SIMPLE_ATTR(ObjCException);
455 class OverloadableAttr : public Attr {
457 OverloadableAttr() : Attr(attr::Overloadable) { }
459 virtual bool isMerged() const { return false; }
461 virtual Attr *clone(ASTContext &C) const;
463 static bool classof(const Attr *A)
464 { return A->getKind() == attr::Overloadable; }
465 static bool classof(const OverloadableAttr *) { return true; }
468 class BlocksAttr : public Attr {
470 enum BlocksAttrTypes {
474 BlocksAttrTypes BlocksAttrType;
476 BlocksAttr(BlocksAttrTypes t) : Attr(attr::Blocks), BlocksAttrType(t) {}
478 BlocksAttrTypes getType() const { return BlocksAttrType; }
480 virtual Attr *clone(ASTContext &C) const;
482 // Implement isa/cast/dyncast/etc.
483 static bool classof(const Attr *A) { return A->getKind() == attr::Blocks; }
484 static bool classof(const BlocksAttr *A) { return true; }
489 class CleanupAttr : public Attr {
493 CleanupAttr(FunctionDecl *fd) : Attr(attr::Cleanup), FD(fd) {}
495 const FunctionDecl *getFunctionDecl() const { return FD; }
497 virtual Attr *clone(ASTContext &C) const;
499 // Implement isa/cast/dyncast/etc.
500 static bool classof(const Attr *A) { return A->getKind() == attr::Cleanup; }
501 static bool classof(const CleanupAttr *A) { return true; }
504 DEF_SIMPLE_ATTR(NoDebug);
505 DEF_SIMPLE_ATTR(WarnUnusedResult);
506 DEF_SIMPLE_ATTR(NoInline);
508 class RegparmAttr : public Attr {
512 RegparmAttr(unsigned np) : Attr(attr::Regparm), NumParams(np) {}
514 unsigned getNumParams() const { return NumParams; }
516 virtual Attr *clone(ASTContext &C) const;
518 // Implement isa/cast/dyncast/etc.
519 static bool classof(const Attr *A) { return A->getKind() == attr::Regparm; }
520 static bool classof(const RegparmAttr *A) { return true; }
523 class ReqdWorkGroupSizeAttr : public Attr {
526 ReqdWorkGroupSizeAttr(unsigned X, unsigned Y, unsigned Z)
527 : Attr(attr::ReqdWorkGroupSize), X(X), Y(Y), Z(Z) {}
529 unsigned getXDim() const { return X; }
530 unsigned getYDim() const { return Y; }
531 unsigned getZDim() const { return Z; }
533 virtual Attr *clone(ASTContext &C) const;
535 // Implement isa/cast/dyncast/etc.
536 static bool classof(const Attr *A) {
537 return A->getKind() == attr::ReqdWorkGroupSize;
539 static bool classof(const ReqdWorkGroupSizeAttr *A) { return true; }
542 class InitPriorityAttr : public Attr {
545 InitPriorityAttr(unsigned priority)
546 : Attr(attr::InitPriority), Priority(priority) {}
548 virtual void Destroy(ASTContext &C) { Attr::Destroy(C); }
550 unsigned getPriority() const { return Priority; }
552 virtual Attr *clone(ASTContext &C) const;
554 static bool classof(const Attr *A)
555 { return A->getKind() == attr::InitPriority; }
556 static bool classof(const InitPriorityAttr *A) { return true; }
559 // Checker-specific attributes.
560 DEF_SIMPLE_ATTR(CFReturnsNotRetained);
561 DEF_SIMPLE_ATTR(CFReturnsRetained);
562 DEF_SIMPLE_ATTR(NSReturnsNotRetained);
563 DEF_SIMPLE_ATTR(NSReturnsRetained);
565 // Target-specific attributes
566 DEF_SIMPLE_ATTR(DLLImport);
567 DEF_SIMPLE_ATTR(DLLExport);
569 class MSP430InterruptAttr : public Attr {
573 MSP430InterruptAttr(unsigned n) : Attr(attr::MSP430Interrupt), Number(n) {}
575 unsigned getNumber() const { return Number; }
577 virtual Attr *clone(ASTContext &C) const;
579 // Implement isa/cast/dyncast/etc.
580 static bool classof(const Attr *A)
581 { return A->getKind() == attr::MSP430Interrupt; }
582 static bool classof(const MSP430InterruptAttr *A) { return true; }
585 DEF_SIMPLE_ATTR(X86ForceAlignArgPointer);
587 #undef DEF_SIMPLE_ATTR
589 } // end namespace clang