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