]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/Sema/AttributeList.h
MFV r328323,328324:
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / Sema / AttributeList.h
1 //===--- AttributeList.h - Parsed attribute sets ----------------*- 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 AttributeList class, which is used to collect
11 // parsed attributes.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_CLANG_SEMA_ATTRIBUTELIST_H
16 #define LLVM_CLANG_SEMA_ATTRIBUTELIST_H
17
18 #include "clang/Basic/AttrSubjectMatchRules.h"
19 #include "clang/Basic/SourceLocation.h"
20 #include "clang/Basic/TargetInfo.h"
21 #include "clang/Basic/VersionTuple.h"
22 #include "clang/Sema/Ownership.h"
23 #include "llvm/ADT/PointerUnion.h"
24 #include "llvm/ADT/SmallVector.h"
25 #include "llvm/Support/Allocator.h"
26 #include <cassert>
27
28 namespace clang {
29   class ASTContext;
30   class IdentifierInfo;
31   class Expr;
32
33 /// \brief Represents information about a change in availability for
34 /// an entity, which is part of the encoding of the 'availability'
35 /// attribute.
36 struct AvailabilityChange {
37   /// \brief The location of the keyword indicating the kind of change.
38   SourceLocation KeywordLoc;
39
40   /// \brief The version number at which the change occurred.
41   VersionTuple Version;
42
43   /// \brief The source range covering the version number.
44   SourceRange VersionRange;
45
46   /// \brief Determine whether this availability change is valid.
47   bool isValid() const { return !Version.empty(); }
48 };
49
50 namespace {
51 enum AvailabilitySlot {
52   IntroducedSlot, DeprecatedSlot, ObsoletedSlot, NumAvailabilitySlots
53 };
54
55 /// Describes the trailing object for Availability attribute in AttributeList.
56 struct AvailabilityData {
57   AvailabilityChange Changes[NumAvailabilitySlots];
58   SourceLocation StrictLoc;
59   const Expr *Replacement;
60   AvailabilityData(const AvailabilityChange &Introduced,
61                    const AvailabilityChange &Deprecated,
62                    const AvailabilityChange &Obsoleted,
63                    SourceLocation Strict, const Expr *ReplaceExpr)
64     : StrictLoc(Strict), Replacement(ReplaceExpr) {
65     Changes[IntroducedSlot] = Introduced;
66     Changes[DeprecatedSlot] = Deprecated;
67     Changes[ObsoletedSlot] = Obsoleted;
68   }
69 };
70 }
71
72 /// \brief Wraps an identifier and optional source location for the identifier.
73 struct IdentifierLoc {
74   SourceLocation Loc;
75   IdentifierInfo *Ident;
76
77   static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc,
78                                IdentifierInfo *Ident);
79 };
80
81 /// \brief A union of the various pointer types that can be passed to an
82 /// AttributeList as an argument.
83 typedef llvm::PointerUnion<Expr*, IdentifierLoc*> ArgsUnion;
84 typedef llvm::SmallVector<ArgsUnion, 12U> ArgsVector;
85
86 /// AttributeList - Represents a syntactic attribute.
87 ///
88 /// For a GNU attribute, there are four forms of this construct:
89 ///
90 /// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused.
91 /// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused.
92 /// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used.
93 /// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
94 ///
95 class AttributeList { // TODO: This should really be called ParsedAttribute
96 public:
97   /// The style used to specify an attribute.
98   enum Syntax {
99     /// __attribute__((...))
100     AS_GNU,
101     /// [[...]]
102     AS_CXX11,
103     /// [[...]]
104     AS_C2x,
105     /// __declspec(...)
106     AS_Declspec,
107     /// [uuid("...")] class Foo
108     AS_Microsoft,
109     /// __ptr16, alignas(...), etc.
110     AS_Keyword,
111     /// #pragma ...
112     AS_Pragma,
113     // Note TableGen depends on the order above.  Do not add or change the order
114     // without adding related code to TableGen/ClangAttrEmitter.cpp.
115     /// Context-sensitive version of a keyword attribute.
116     AS_ContextSensitiveKeyword,
117   };
118
119 private:
120   IdentifierInfo *AttrName;
121   IdentifierInfo *ScopeName;
122   SourceRange AttrRange;
123   SourceLocation ScopeLoc;
124   SourceLocation EllipsisLoc;
125
126   unsigned AttrKind : 16;
127
128   /// The number of expression arguments this attribute has.
129   /// The expressions themselves are stored after the object.
130   unsigned NumArgs : 16;
131
132   /// Corresponds to the Syntax enum.
133   unsigned SyntaxUsed : 3;
134
135   /// True if already diagnosed as invalid.
136   mutable unsigned Invalid : 1;
137
138   /// True if this attribute was used as a type attribute.
139   mutable unsigned UsedAsTypeAttr : 1;
140
141   /// True if this has the extra information associated with an
142   /// availability attribute.
143   unsigned IsAvailability : 1;
144
145   /// True if this has extra information associated with a
146   /// type_tag_for_datatype attribute.
147   unsigned IsTypeTagForDatatype : 1;
148
149   /// True if this has extra information associated with a
150   /// Microsoft __delcspec(property) attribute.
151   unsigned IsProperty : 1;
152
153   /// True if this has a ParsedType
154   unsigned HasParsedType : 1;
155
156   /// True if the processing cache is valid.
157   mutable unsigned HasProcessingCache : 1;
158
159   /// A cached value.
160   mutable unsigned ProcessingCache : 8;
161
162   /// \brief The location of the 'unavailable' keyword in an
163   /// availability attribute.
164   SourceLocation UnavailableLoc;
165   
166   const Expr *MessageExpr;
167
168   /// The next attribute in the current position.
169   AttributeList *NextInPosition;
170
171   /// The next attribute allocated in the current Pool.
172   AttributeList *NextInPool;
173
174   /// Arguments, if any, are stored immediately following the object.
175   ArgsUnion *getArgsBuffer() { return reinterpret_cast<ArgsUnion *>(this + 1); }
176   ArgsUnion const *getArgsBuffer() const {
177     return reinterpret_cast<ArgsUnion const *>(this + 1);
178   }
179
180   /// Availability information is stored immediately following the arguments,
181   /// if any, at the end of the object.
182   AvailabilityData *getAvailabilityData() {
183     return reinterpret_cast<AvailabilityData*>(getArgsBuffer() + NumArgs);
184   }
185   const AvailabilityData *getAvailabilityData() const {
186     return reinterpret_cast<const AvailabilityData*>(getArgsBuffer() + NumArgs);
187   }
188
189 public:
190   struct TypeTagForDatatypeData {
191     ParsedType *MatchingCType;
192     unsigned LayoutCompatible : 1;
193     unsigned MustBeNull : 1;
194   };
195   struct PropertyData {
196     IdentifierInfo *GetterId, *SetterId;
197     PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
198     : GetterId(getterId), SetterId(setterId) {}
199   };
200
201 private:
202   /// Type tag information is stored immediately following the arguments, if
203   /// any, at the end of the object.  They are mutually exlusive with
204   /// availability slots.
205   TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
206     return *reinterpret_cast<TypeTagForDatatypeData*>(getArgsBuffer()+NumArgs);
207   }
208
209   const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
210     return *reinterpret_cast<const TypeTagForDatatypeData*>(getArgsBuffer()
211                                                             + NumArgs);
212   }
213
214   /// The type buffer immediately follows the object and are mutually exclusive
215   /// with arguments.
216   ParsedType &getTypeBuffer() {
217     return *reinterpret_cast<ParsedType *>(this + 1);
218   }
219
220   const ParsedType &getTypeBuffer() const {
221     return *reinterpret_cast<const ParsedType *>(this + 1);
222   }
223
224   /// The property data immediately follows the object is is mutually exclusive
225   /// with arguments.
226   PropertyData &getPropertyDataBuffer() {
227     assert(IsProperty);
228     return *reinterpret_cast<PropertyData*>(this + 1);
229   }
230
231   const PropertyData &getPropertyDataBuffer() const {
232     assert(IsProperty);
233     return *reinterpret_cast<const PropertyData*>(this + 1);
234   }
235
236   AttributeList(const AttributeList &) = delete;
237   void operator=(const AttributeList &) = delete;
238   void operator delete(void *) = delete;
239   ~AttributeList() = delete;
240
241   size_t allocated_size() const;
242
243   /// Constructor for attributes with expression arguments.
244   AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
245                 IdentifierInfo *scopeName, SourceLocation scopeLoc,
246                 ArgsUnion *args, unsigned numArgs,
247                 Syntax syntaxUsed, SourceLocation ellipsisLoc)
248     : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
249       ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs),
250       SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false),
251       IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
252       HasParsedType(false), HasProcessingCache(false),
253       NextInPosition(nullptr), NextInPool(nullptr) {
254     if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion));
255     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
256   }
257
258   /// Constructor for availability attributes.
259   AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
260                 IdentifierInfo *scopeName, SourceLocation scopeLoc,
261                 IdentifierLoc *Parm, const AvailabilityChange &introduced,
262                 const AvailabilityChange &deprecated,
263                 const AvailabilityChange &obsoleted,
264                 SourceLocation unavailable, 
265                 const Expr *messageExpr,
266                 Syntax syntaxUsed, SourceLocation strict,
267                 const Expr *replacementExpr)
268     : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
269       ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
270       Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
271       IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
272       HasProcessingCache(false), UnavailableLoc(unavailable),
273       MessageExpr(messageExpr), NextInPosition(nullptr), NextInPool(nullptr) {
274     ArgsUnion PVal(Parm);
275     memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
276     new (getAvailabilityData()) AvailabilityData(
277         introduced, deprecated, obsoleted, strict, replacementExpr);
278     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
279   }
280
281   /// Constructor for objc_bridge_related attributes.
282   AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
283                 IdentifierInfo *scopeName, SourceLocation scopeLoc,
284                 IdentifierLoc *Parm1,
285                 IdentifierLoc *Parm2,
286                 IdentifierLoc *Parm3,
287                 Syntax syntaxUsed)
288   : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
289     ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(3), SyntaxUsed(syntaxUsed),
290     Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
291     IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
292     HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) {
293     ArgsUnion *Args = getArgsBuffer();
294     Args[0] = Parm1;
295     Args[1] = Parm2;
296     Args[2] = Parm3;
297     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
298   }
299   
300   /// Constructor for type_tag_for_datatype attribute.
301   AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
302                 IdentifierInfo *scopeName, SourceLocation scopeLoc,
303                 IdentifierLoc *ArgKind, ParsedType matchingCType,
304                 bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed)
305     : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
306       ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
307       Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
308       IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false),
309       HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) {
310     ArgsUnion PVal(ArgKind);
311     memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
312     TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
313     new (&ExtraData.MatchingCType) ParsedType(matchingCType);
314     ExtraData.LayoutCompatible = layoutCompatible;
315     ExtraData.MustBeNull = mustBeNull;
316     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
317   }
318
319   /// Constructor for attributes with a single type argument.
320   AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
321                 IdentifierInfo *scopeName, SourceLocation scopeLoc,
322                 ParsedType typeArg, Syntax syntaxUsed)
323       : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
324         ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
325         Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
326         IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true),
327         HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr){
328     new (&getTypeBuffer()) ParsedType(typeArg);
329     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
330   }
331
332   /// Constructor for microsoft __declspec(property) attribute.
333   AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
334                 IdentifierInfo *scopeName, SourceLocation scopeLoc,
335                 IdentifierInfo *getterId, IdentifierInfo *setterId,
336                 Syntax syntaxUsed)
337     : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
338       ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
339       Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
340       IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false),
341       HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) {
342     new (&getPropertyDataBuffer()) PropertyData(getterId, setterId);
343     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
344   }
345
346   friend class AttributePool;
347   friend class AttributeFactory;
348
349 public:
350   enum Kind {           
351     #define PARSED_ATTR(NAME) AT_##NAME,
352     #include "clang/Sema/AttrParsedAttrList.inc"
353     #undef PARSED_ATTR
354     IgnoredAttribute,
355     UnknownAttribute
356   };
357
358   IdentifierInfo *getName() const { return AttrName; }
359   SourceLocation getLoc() const { return AttrRange.getBegin(); }
360   SourceRange getRange() const { return AttrRange; }
361   
362   bool hasScope() const { return ScopeName; }
363   IdentifierInfo *getScopeName() const { return ScopeName; }
364   SourceLocation getScopeLoc() const { return ScopeLoc; }
365   
366   bool hasParsedType() const { return HasParsedType; }
367
368   /// Is this the Microsoft __declspec(property) attribute?
369   bool isDeclspecPropertyAttribute() const  {
370     return IsProperty;
371   }
372
373   bool isAlignasAttribute() const {
374     // FIXME: Use a better mechanism to determine this.
375     return getKind() == AT_Aligned && isKeywordAttribute();
376   }
377
378   bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
379   bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; }
380   bool isCXX11Attribute() const {
381     return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
382   }
383   bool isC2xAttribute() const {
384     return SyntaxUsed == AS_C2x;
385   }
386   bool isKeywordAttribute() const {
387     return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
388   }
389
390   bool isContextSensitiveKeywordAttribute() const {
391     return SyntaxUsed == AS_ContextSensitiveKeyword;
392   }
393
394   bool isInvalid() const { return Invalid; }
395   void setInvalid(bool b = true) const { Invalid = b; }
396
397   bool hasProcessingCache() const { return HasProcessingCache; }
398   unsigned getProcessingCache() const {
399     assert(hasProcessingCache());
400     return ProcessingCache;
401   }
402   void setProcessingCache(unsigned value) const {
403     ProcessingCache = value;
404     HasProcessingCache = true;
405   }
406
407   bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
408   void setUsedAsTypeAttr() { UsedAsTypeAttr = true; }
409
410   bool isPackExpansion() const { return EllipsisLoc.isValid(); }
411   SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
412
413   Kind getKind() const { return Kind(AttrKind); }
414   static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope,
415                       Syntax SyntaxUsed);
416
417   AttributeList *getNext() const { return NextInPosition; }
418   void setNext(AttributeList *N) { NextInPosition = N; }
419
420   /// getNumArgs - Return the number of actual arguments to this attribute.
421   unsigned getNumArgs() const { return NumArgs; }
422
423   /// getArg - Return the specified argument.
424   ArgsUnion getArg(unsigned Arg) const {
425     assert(Arg < NumArgs && "Arg access out of range!");
426     return getArgsBuffer()[Arg];
427   }
428
429   bool isArgExpr(unsigned Arg) const {
430     return Arg < NumArgs && getArg(Arg).is<Expr*>();
431   }
432   Expr *getArgAsExpr(unsigned Arg) const {
433     return getArg(Arg).get<Expr*>();
434   }
435
436   bool isArgIdent(unsigned Arg) const {
437     return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>();
438   }
439   IdentifierLoc *getArgAsIdent(unsigned Arg) const {
440     return getArg(Arg).get<IdentifierLoc*>();
441   }
442
443   const AvailabilityChange &getAvailabilityIntroduced() const {
444     assert(getKind() == AT_Availability && "Not an availability attribute");
445     return getAvailabilityData()->Changes[IntroducedSlot];
446   }
447
448   const AvailabilityChange &getAvailabilityDeprecated() const {
449     assert(getKind() == AT_Availability && "Not an availability attribute");
450     return getAvailabilityData()->Changes[DeprecatedSlot];
451   }
452
453   const AvailabilityChange &getAvailabilityObsoleted() const {
454     assert(getKind() == AT_Availability && "Not an availability attribute");
455     return getAvailabilityData()->Changes[ObsoletedSlot];
456   }
457
458   SourceLocation getStrictLoc() const {
459     assert(getKind() == AT_Availability && "Not an availability attribute");
460     return getAvailabilityData()->StrictLoc;
461   }
462
463   SourceLocation getUnavailableLoc() const {
464     assert(getKind() == AT_Availability && "Not an availability attribute");
465     return UnavailableLoc;
466   }
467   
468   const Expr * getMessageExpr() const {
469     assert(getKind() == AT_Availability && "Not an availability attribute");
470     return MessageExpr;
471   }
472
473   const Expr *getReplacementExpr() const {
474     assert(getKind() == AT_Availability && "Not an availability attribute");
475     return getAvailabilityData()->Replacement;
476   }
477
478   const ParsedType &getMatchingCType() const {
479     assert(getKind() == AT_TypeTagForDatatype &&
480            "Not a type_tag_for_datatype attribute");
481     return *getTypeTagForDatatypeDataSlot().MatchingCType;
482   }
483
484   bool getLayoutCompatible() const {
485     assert(getKind() == AT_TypeTagForDatatype &&
486            "Not a type_tag_for_datatype attribute");
487     return getTypeTagForDatatypeDataSlot().LayoutCompatible;
488   }
489
490   bool getMustBeNull() const {
491     assert(getKind() == AT_TypeTagForDatatype &&
492            "Not a type_tag_for_datatype attribute");
493     return getTypeTagForDatatypeDataSlot().MustBeNull;
494   }
495
496   const ParsedType &getTypeArg() const {
497     assert(HasParsedType && "Not a type attribute");
498     return getTypeBuffer();
499   }
500
501   const PropertyData &getPropertyData() const {
502     assert(isDeclspecPropertyAttribute() && "Not a __delcspec(property) attribute");
503     return getPropertyDataBuffer();
504   }
505
506   /// \brief Get an index into the attribute spelling list
507   /// defined in Attr.td. This index is used by an attribute
508   /// to pretty print itself.
509   unsigned getAttributeSpellingListIndex() const;
510
511   bool isTargetSpecificAttr() const;
512   bool isTypeAttr() const;
513   bool isStmtAttr() const;
514
515   bool hasCustomParsing() const;
516   unsigned getMinArgs() const;
517   unsigned getMaxArgs() const;
518   bool hasVariadicArg() const;
519   bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const;
520   bool appliesToDecl(const Decl *D, attr::SubjectMatchRule MatchRule) const;
521   void getMatchRules(const LangOptions &LangOpts,
522                      SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>>
523                          &MatchRules) const;
524   bool diagnoseLangOpts(class Sema &S) const;
525   bool existsInTarget(const TargetInfo &Target) const;
526   bool isKnownToGCC() const;
527   bool isSupportedByPragmaAttribute() const;
528
529   /// \brief If the parsed attribute has a semantic equivalent, and it would
530   /// have a semantic Spelling enumeration (due to having semantically-distinct
531   /// spelling variations), return the value of that semantic spelling. If the
532   /// parsed attribute does not have a semantic equivalent, or would not have
533   /// a Spelling enumeration, the value UINT_MAX is returned.
534   unsigned getSemanticSpelling() const;
535 };
536
537 /// A factory, from which one makes pools, from which one creates
538 /// individual attributes which are deallocated with the pool.
539 ///
540 /// Note that it's tolerably cheap to create and destroy one of
541 /// these as long as you don't actually allocate anything in it.
542 class AttributeFactory {
543 public:
544   enum {
545     /// The required allocation size of an availability attribute,
546     /// which we want to ensure is a multiple of sizeof(void*).
547     AvailabilityAllocSize =
548       sizeof(AttributeList)
549       + ((sizeof(AvailabilityData) + sizeof(void*) + sizeof(ArgsUnion) - 1)
550          / sizeof(void*) * sizeof(void*)),
551     TypeTagForDatatypeAllocSize =
552       sizeof(AttributeList)
553       + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) +
554          sizeof(ArgsUnion) - 1)
555         / sizeof(void*) * sizeof(void*),
556     PropertyAllocSize =
557       sizeof(AttributeList)
558       + (sizeof(AttributeList::PropertyData) + sizeof(void *) - 1)
559         / sizeof(void*) * sizeof(void*)
560   };
561
562 private:
563   enum {
564     /// The number of free lists we want to be sure to support
565     /// inline.  This is just enough that availability attributes
566     /// don't surpass it.  It's actually very unlikely we'll see an
567     /// attribute that needs more than that; on x86-64 you'd need 10
568     /// expression arguments, and on i386 you'd need 19.
569     InlineFreeListsCapacity =
570       1 + (AvailabilityAllocSize - sizeof(AttributeList)) / sizeof(void*)
571   };
572
573   llvm::BumpPtrAllocator Alloc;
574
575   /// Free lists.  The index is determined by the following formula:
576   ///   (size - sizeof(AttributeList)) / sizeof(void*)
577   SmallVector<AttributeList*, InlineFreeListsCapacity> FreeLists;
578
579   // The following are the private interface used by AttributePool.
580   friend class AttributePool;
581
582   /// Allocate an attribute of the given size.
583   void *allocate(size_t size);
584
585   /// Reclaim all the attributes in the given pool chain, which is
586   /// non-empty.  Note that the current implementation is safe
587   /// against reclaiming things which were not actually allocated
588   /// with the allocator, although of course it's important to make
589   /// sure that their allocator lives at least as long as this one.
590   void reclaimPool(AttributeList *head);
591
592 public:
593   AttributeFactory();
594   ~AttributeFactory();
595 };
596
597 class AttributePool {
598   AttributeFactory &Factory;
599   AttributeList *Head;
600
601   void *allocate(size_t size) {
602     return Factory.allocate(size);
603   }
604
605   AttributeList *add(AttributeList *attr) {
606     // We don't care about the order of the pool.
607     attr->NextInPool = Head;
608     Head = attr;
609     return attr;
610   }
611
612   void takePool(AttributeList *pool);
613
614 public:
615   /// Create a new pool for a factory.
616   AttributePool(AttributeFactory &factory) : Factory(factory), Head(nullptr) {}
617
618   AttributePool(const AttributePool &) = delete;
619
620   /// Move the given pool's allocations to this pool.
621   AttributePool(AttributePool &&pool) : Factory(pool.Factory), Head(pool.Head) {
622     pool.Head = nullptr;
623   }
624
625   AttributeFactory &getFactory() const { return Factory; }
626
627   void clear() {
628     if (Head) {
629       Factory.reclaimPool(Head);
630       Head = nullptr;
631     }
632   }
633
634   /// Take the given pool's allocations and add them to this pool.
635   void takeAllFrom(AttributePool &pool) {
636     if (pool.Head) {
637       takePool(pool.Head);
638       pool.Head = nullptr;
639     }
640   }
641
642   ~AttributePool() {
643     if (Head) Factory.reclaimPool(Head);
644   }
645
646   AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
647                         IdentifierInfo *scopeName, SourceLocation scopeLoc,
648                         ArgsUnion *args, unsigned numArgs,
649                         AttributeList::Syntax syntax,
650                         SourceLocation ellipsisLoc = SourceLocation()) {
651     void *memory = allocate(sizeof(AttributeList)
652                             + numArgs * sizeof(ArgsUnion));
653     return add(new (memory) AttributeList(attrName, attrRange,
654                                           scopeName, scopeLoc,
655                                           args, numArgs, syntax,
656                                           ellipsisLoc));
657   }
658
659   AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
660                         IdentifierInfo *scopeName, SourceLocation scopeLoc,
661                         IdentifierLoc *Param,
662                         const AvailabilityChange &introduced,
663                         const AvailabilityChange &deprecated,
664                         const AvailabilityChange &obsoleted,
665                         SourceLocation unavailable,
666                         const Expr *MessageExpr,
667                         AttributeList::Syntax syntax,
668                         SourceLocation strict, const Expr *ReplacementExpr) {
669     void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
670     return add(new (memory) AttributeList(attrName, attrRange,
671                                           scopeName, scopeLoc,
672                                           Param, introduced, deprecated,
673                                           obsoleted, unavailable, MessageExpr,
674                                           syntax, strict, ReplacementExpr));
675   }
676
677   AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
678                         IdentifierInfo *scopeName, SourceLocation scopeLoc,
679                         IdentifierLoc *Param1,
680                         IdentifierLoc *Param2,
681                         IdentifierLoc *Param3,
682                         AttributeList::Syntax syntax) {
683     size_t size = sizeof(AttributeList) + 3 * sizeof(ArgsUnion);
684     void *memory = allocate(size);
685     return add(new (memory) AttributeList(attrName, attrRange,
686                                           scopeName, scopeLoc,
687                                           Param1, Param2, Param3,
688                                           syntax));
689   }
690
691   AttributeList *createTypeTagForDatatype(
692                     IdentifierInfo *attrName, SourceRange attrRange,
693                     IdentifierInfo *scopeName, SourceLocation scopeLoc,
694                     IdentifierLoc *argumentKind, ParsedType matchingCType,
695                     bool layoutCompatible, bool mustBeNull,
696                     AttributeList::Syntax syntax) {
697     void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
698     return add(new (memory) AttributeList(attrName, attrRange,
699                                           scopeName, scopeLoc,
700                                           argumentKind, matchingCType,
701                                           layoutCompatible, mustBeNull,
702                                           syntax));
703   }
704
705   AttributeList *createTypeAttribute(
706                     IdentifierInfo *attrName, SourceRange attrRange,
707                     IdentifierInfo *scopeName, SourceLocation scopeLoc,
708                     ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
709     void *memory = allocate(sizeof(AttributeList) + sizeof(void *));
710     return add(new (memory) AttributeList(attrName, attrRange,
711                                           scopeName, scopeLoc,
712                                           typeArg, syntaxUsed));
713   }
714
715   AttributeList *createPropertyAttribute(
716                     IdentifierInfo *attrName, SourceRange attrRange,
717                     IdentifierInfo *scopeName, SourceLocation scopeLoc,
718                     IdentifierInfo *getterId, IdentifierInfo *setterId,
719                     AttributeList::Syntax syntaxUsed) {
720     void *memory = allocate(AttributeFactory::PropertyAllocSize);
721     return add(new (memory) AttributeList(attrName, attrRange,
722                                           scopeName, scopeLoc,
723                                           getterId, setterId,
724                                           syntaxUsed));
725   }
726 };
727
728 /// ParsedAttributes - A collection of parsed attributes.  Currently
729 /// we don't differentiate between the various attribute syntaxes,
730 /// which is basically silly.
731 ///
732 /// Right now this is a very lightweight container, but the expectation
733 /// is that this will become significantly more serious.
734 class ParsedAttributes {
735 public:
736   ParsedAttributes(AttributeFactory &factory)
737     : pool(factory), list(nullptr) {
738   }
739
740   ParsedAttributes(const ParsedAttributes &) = delete;
741
742   AttributePool &getPool() const { return pool; }
743
744   bool empty() const { return list == nullptr; }
745
746   void add(AttributeList *newAttr) {
747     assert(newAttr);
748     assert(newAttr->getNext() == nullptr);
749     newAttr->setNext(list);
750     list = newAttr;
751   }
752
753   void addAll(AttributeList *newList) {
754     if (!newList) return;
755
756     AttributeList *lastInNewList = newList;
757     while (AttributeList *next = lastInNewList->getNext())
758       lastInNewList = next;
759
760     lastInNewList->setNext(list);
761     list = newList;
762   }
763
764   void addAllAtEnd(AttributeList *newList) {
765     if (!list) {
766       list = newList;
767       return;
768     }
769
770     AttributeList *lastInList = list;
771     while (AttributeList *next = lastInList->getNext())
772       lastInList = next;
773
774     lastInList->setNext(newList);
775   }
776
777   void set(AttributeList *newList) {
778     list = newList;
779   }
780
781   void takeAllFrom(ParsedAttributes &attrs) {
782     addAll(attrs.list);
783     attrs.list = nullptr;
784     pool.takeAllFrom(attrs.pool);
785   }
786
787   void clear() { list = nullptr; pool.clear(); }
788   AttributeList *getList() const { return list; }
789
790   void clearListOnly() { list = nullptr; }
791
792   /// Returns a reference to the attribute list.  Try not to introduce
793   /// dependencies on this method, it may not be long-lived.
794   AttributeList *&getListRef() { return list; }
795
796   /// Add attribute with expression arguments.
797   AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
798                         IdentifierInfo *scopeName, SourceLocation scopeLoc,
799                         ArgsUnion *args, unsigned numArgs,
800                         AttributeList::Syntax syntax,
801                         SourceLocation ellipsisLoc = SourceLocation()) {
802     AttributeList *attr =
803       pool.create(attrName, attrRange, scopeName, scopeLoc, args, numArgs,
804                   syntax, ellipsisLoc);
805     add(attr);
806     return attr;
807   }
808
809   /// Add availability attribute.
810   AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
811                         IdentifierInfo *scopeName, SourceLocation scopeLoc,
812                         IdentifierLoc *Param,
813                         const AvailabilityChange &introduced,
814                         const AvailabilityChange &deprecated,
815                         const AvailabilityChange &obsoleted,
816                         SourceLocation unavailable,
817                         const Expr *MessageExpr,
818                         AttributeList::Syntax syntax,
819                         SourceLocation strict, const Expr *ReplacementExpr) {
820     AttributeList *attr =
821       pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced,
822                   deprecated, obsoleted, unavailable, MessageExpr, syntax,
823                   strict, ReplacementExpr);
824     add(attr);
825     return attr;
826   }
827
828   /// Add objc_bridge_related attribute.
829   AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
830                         IdentifierInfo *scopeName, SourceLocation scopeLoc,
831                         IdentifierLoc *Param1,
832                         IdentifierLoc *Param2,
833                         IdentifierLoc *Param3,
834                         AttributeList::Syntax syntax) {
835     AttributeList *attr =
836       pool.create(attrName, attrRange, scopeName, scopeLoc,
837                   Param1, Param2, Param3, syntax);
838     add(attr);
839     return attr;
840   }
841
842   /// Add type_tag_for_datatype attribute.
843   AttributeList *addNewTypeTagForDatatype(
844                         IdentifierInfo *attrName, SourceRange attrRange,
845                         IdentifierInfo *scopeName, SourceLocation scopeLoc,
846                         IdentifierLoc *argumentKind, ParsedType matchingCType,
847                         bool layoutCompatible, bool mustBeNull,
848                         AttributeList::Syntax syntax) {
849     AttributeList *attr =
850       pool.createTypeTagForDatatype(attrName, attrRange,
851                                     scopeName, scopeLoc,
852                                     argumentKind, matchingCType,
853                                     layoutCompatible, mustBeNull, syntax);
854     add(attr);
855     return attr;
856   }
857
858   /// Add an attribute with a single type argument.
859   AttributeList *
860   addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange,
861                  IdentifierInfo *scopeName, SourceLocation scopeLoc,
862                  ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
863     AttributeList *attr =
864         pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc,
865                                  typeArg, syntaxUsed);
866     add(attr);
867     return attr;
868   }
869
870   /// Add microsoft __delspec(property) attribute.
871   AttributeList *
872   addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange,
873                  IdentifierInfo *scopeName, SourceLocation scopeLoc,
874                  IdentifierInfo *getterId, IdentifierInfo *setterId,
875                  AttributeList::Syntax syntaxUsed) {
876     AttributeList *attr =
877         pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
878                                      getterId, setterId, syntaxUsed);
879     add(attr);
880     return attr;
881   }
882
883 private:
884   mutable AttributePool pool;
885   AttributeList *list;
886 };
887
888 /// These constants match the enumerated choices of
889 /// err_attribute_argument_n_type and err_attribute_argument_type.
890 enum AttributeArgumentNType {
891   AANT_ArgumentIntOrBool,
892   AANT_ArgumentIntegerConstant,
893   AANT_ArgumentString,
894   AANT_ArgumentIdentifier
895 };
896
897 /// These constants match the enumerated choices of
898 /// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
899 enum AttributeDeclKind {
900   ExpectedFunction,
901   ExpectedUnion,
902   ExpectedVariableOrFunction,
903   ExpectedFunctionOrMethod,
904   ExpectedFunctionMethodOrBlock,
905   ExpectedFunctionMethodOrParameter,
906   ExpectedVariable,
907   ExpectedVariableOrField,
908   ExpectedVariableFieldOrTag,
909   ExpectedTypeOrNamespace,
910   ExpectedFunctionVariableOrClass,
911   ExpectedKernelFunction,
912   ExpectedFunctionWithProtoType,
913   ExpectedForMaybeUnused,
914 };
915
916 }  // end namespace clang
917
918 #endif