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