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