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