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