1 //======- ParsedAttr.h - Parsed attribute sets ------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines the ParsedAttr class, which is used to collect
10 // parsed attributes.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_SEMA_ATTRIBUTELIST_H
15 #define LLVM_CLANG_SEMA_ATTRIBUTELIST_H
16 
17 #include "clang/Basic/AttrSubjectMatchRules.h"
18 #include "clang/Basic/AttributeCommonInfo.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     : public AttributeCommonInfo,
119       private llvm::TrailingObjects<
120           ParsedAttr, ArgsUnion, detail::AvailabilityData,
121           detail::TypeTagForDatatypeData, ParsedType, detail::PropertyData> {
122   friend TrailingObjects;
123 
124   size_t numTrailingObjects(OverloadToken<ArgsUnion>) const { return NumArgs; }
125   size_t numTrailingObjects(OverloadToken<detail::AvailabilityData>) const {
126     return IsAvailability;
127   }
128   size_t
129       numTrailingObjects(OverloadToken<detail::TypeTagForDatatypeData>) const {
130     return IsTypeTagForDatatype;
131   }
132   size_t numTrailingObjects(OverloadToken<ParsedType>) const {
133     return HasParsedType;
134   }
135   size_t numTrailingObjects(OverloadToken<detail::PropertyData>) const {
136     return IsProperty;
137   }
138 
139 private:
140   IdentifierInfo *MacroII = nullptr;
141   SourceLocation MacroExpansionLoc;
142   SourceLocation EllipsisLoc;
143 
144   /// The number of expression arguments this attribute has.
145   /// The expressions themselves are stored after the object.
146   unsigned NumArgs : 16;
147 
148   /// True if already diagnosed as invalid.
149   mutable unsigned Invalid : 1;
150 
151   /// True if this attribute was used as a type attribute.
152   mutable unsigned UsedAsTypeAttr : 1;
153 
154   /// True if this has the extra information associated with an
155   /// availability attribute.
156   unsigned IsAvailability : 1;
157 
158   /// True if this has extra information associated with a
159   /// type_tag_for_datatype attribute.
160   unsigned IsTypeTagForDatatype : 1;
161 
162   /// True if this has extra information associated with a
163   /// Microsoft __delcspec(property) attribute.
164   unsigned IsProperty : 1;
165 
166   /// True if this has a ParsedType
167   unsigned HasParsedType : 1;
168 
169   /// True if the processing cache is valid.
170   mutable unsigned HasProcessingCache : 1;
171 
172   /// A cached value.
173   mutable unsigned ProcessingCache : 8;
174 
175   /// True if the attribute is specified using '#pragma clang attribute'.
176   mutable unsigned IsPragmaClangAttribute : 1;
177 
178   /// The location of the 'unavailable' keyword in an
179   /// availability attribute.
180   SourceLocation UnavailableLoc;
181 
182   const Expr *MessageExpr;
183 
184   ArgsUnion *getArgsBuffer() { return getTrailingObjects<ArgsUnion>(); }
185   ArgsUnion const *getArgsBuffer() const {
186     return getTrailingObjects<ArgsUnion>();
187   }
188 
189   detail::AvailabilityData *getAvailabilityData() {
190     return getTrailingObjects<detail::AvailabilityData>();
191   }
192   const detail::AvailabilityData *getAvailabilityData() const {
193     return getTrailingObjects<detail::AvailabilityData>();
194   }
195 
196 private:
197   friend class AttributeFactory;
198   friend class AttributePool;
199 
200   /// Constructor for attributes with expression arguments.
201   ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
202              IdentifierInfo *scopeName, SourceLocation scopeLoc,
203              ArgsUnion *args, unsigned numArgs, Syntax syntaxUsed,
204              SourceLocation ellipsisLoc)
205       : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc,
206                             syntaxUsed),
207         EllipsisLoc(ellipsisLoc), NumArgs(numArgs), Invalid(false),
208         UsedAsTypeAttr(false), IsAvailability(false),
209         IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
210         HasProcessingCache(false), IsPragmaClangAttribute(false) {
211     if (numArgs)
212       memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion));
213   }
214 
215   /// Constructor for availability attributes.
216   ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
217              IdentifierInfo *scopeName, SourceLocation scopeLoc,
218              IdentifierLoc *Parm, const AvailabilityChange &introduced,
219              const AvailabilityChange &deprecated,
220              const AvailabilityChange &obsoleted, SourceLocation unavailable,
221              const Expr *messageExpr, Syntax syntaxUsed, SourceLocation strict,
222              const Expr *replacementExpr)
223       : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc,
224                             syntaxUsed),
225         NumArgs(1), Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
226         IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
227         HasProcessingCache(false), IsPragmaClangAttribute(false),
228         UnavailableLoc(unavailable), MessageExpr(messageExpr) {
229     ArgsUnion PVal(Parm);
230     memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
231     new (getAvailabilityData()) detail::AvailabilityData(
232         introduced, deprecated, obsoleted, strict, replacementExpr);
233   }
234 
235   /// Constructor for objc_bridge_related attributes.
236   ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
237              IdentifierInfo *scopeName, SourceLocation scopeLoc,
238              IdentifierLoc *Parm1, IdentifierLoc *Parm2, IdentifierLoc *Parm3,
239              Syntax syntaxUsed)
240       : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc,
241                             syntaxUsed),
242         NumArgs(3), Invalid(false), UsedAsTypeAttr(false),
243         IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
244         HasParsedType(false), HasProcessingCache(false),
245         IsPragmaClangAttribute(false) {
246     ArgsUnion *Args = getArgsBuffer();
247     Args[0] = Parm1;
248     Args[1] = Parm2;
249     Args[2] = Parm3;
250   }
251 
252   /// Constructor for type_tag_for_datatype attribute.
253   ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
254              IdentifierInfo *scopeName, SourceLocation scopeLoc,
255              IdentifierLoc *ArgKind, ParsedType matchingCType,
256              bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed)
257       : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc,
258                             syntaxUsed),
259         NumArgs(1), Invalid(false), UsedAsTypeAttr(false),
260         IsAvailability(false), IsTypeTagForDatatype(true), IsProperty(false),
261         HasParsedType(false), HasProcessingCache(false),
262         IsPragmaClangAttribute(false) {
263     ArgsUnion PVal(ArgKind);
264     memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
265     detail::TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
266     new (&ExtraData.MatchingCType) ParsedType(matchingCType);
267     ExtraData.LayoutCompatible = layoutCompatible;
268     ExtraData.MustBeNull = mustBeNull;
269   }
270 
271   /// Constructor for attributes with a single type argument.
272   ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
273              IdentifierInfo *scopeName, SourceLocation scopeLoc,
274              ParsedType typeArg, Syntax syntaxUsed)
275       : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc,
276                             syntaxUsed),
277         NumArgs(0), Invalid(false), UsedAsTypeAttr(false),
278         IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
279         HasParsedType(true), HasProcessingCache(false),
280         IsPragmaClangAttribute(false) {
281     new (&getTypeBuffer()) ParsedType(typeArg);
282   }
283 
284   /// Constructor for microsoft __declspec(property) attribute.
285   ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
286              IdentifierInfo *scopeName, SourceLocation scopeLoc,
287              IdentifierInfo *getterId, IdentifierInfo *setterId,
288              Syntax syntaxUsed)
289       : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc,
290                             syntaxUsed),
291         NumArgs(0), Invalid(false), UsedAsTypeAttr(false),
292         IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(true),
293         HasParsedType(false), HasProcessingCache(false),
294         IsPragmaClangAttribute(false) {
295     new (&getPropertyDataBuffer()) detail::PropertyData(getterId, setterId);
296   }
297 
298   /// Type tag information is stored immediately following the arguments, if
299   /// any, at the end of the object.  They are mutually exclusive with
300   /// availability slots.
301   detail::TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
302     return *getTrailingObjects<detail::TypeTagForDatatypeData>();
303   }
304   const detail::TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
305     return *getTrailingObjects<detail::TypeTagForDatatypeData>();
306   }
307 
308   /// The type buffer immediately follows the object and are mutually exclusive
309   /// with arguments.
310   ParsedType &getTypeBuffer() { return *getTrailingObjects<ParsedType>(); }
311   const ParsedType &getTypeBuffer() const {
312     return *getTrailingObjects<ParsedType>();
313   }
314 
315   /// The property data immediately follows the object is is mutually exclusive
316   /// with arguments.
317   detail::PropertyData &getPropertyDataBuffer() {
318     assert(IsProperty);
319     return *getTrailingObjects<detail::PropertyData>();
320   }
321   const detail::PropertyData &getPropertyDataBuffer() const {
322     assert(IsProperty);
323     return *getTrailingObjects<detail::PropertyData>();
324   }
325 
326   size_t allocated_size() const;
327 
328 public:
329   ParsedAttr(const ParsedAttr &) = delete;
330   ParsedAttr(ParsedAttr &&) = delete;
331   ParsedAttr &operator=(const ParsedAttr &) = delete;
332   ParsedAttr &operator=(ParsedAttr &&) = delete;
333   ~ParsedAttr() = delete;
334 
335   void operator delete(void *) = delete;
336 
337   bool hasParsedType() const { return HasParsedType; }
338 
339   /// Is this the Microsoft __declspec(property) attribute?
340   bool isDeclspecPropertyAttribute() const  {
341     return IsProperty;
342   }
343 
344   bool isInvalid() const { return Invalid; }
345   void setInvalid(bool b = true) const { Invalid = b; }
346 
347   bool hasProcessingCache() const { return HasProcessingCache; }
348 
349   unsigned getProcessingCache() const {
350     assert(hasProcessingCache());
351     return ProcessingCache;
352   }
353 
354   void setProcessingCache(unsigned value) const {
355     ProcessingCache = value;
356     HasProcessingCache = true;
357   }
358 
359   bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
360   void setUsedAsTypeAttr(bool Used = true) { UsedAsTypeAttr = Used; }
361 
362   /// True if the attribute is specified using '#pragma clang attribute'.
363   bool isPragmaClangAttribute() const { return IsPragmaClangAttribute; }
364 
365   void setIsPragmaClangAttribute() { IsPragmaClangAttribute = true; }
366 
367   bool isPackExpansion() const { return EllipsisLoc.isValid(); }
368   SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
369 
370   /// getNumArgs - Return the number of actual arguments to this attribute.
371   unsigned getNumArgs() const { return NumArgs; }
372 
373   /// getArg - Return the specified argument.
374   ArgsUnion getArg(unsigned Arg) const {
375     assert(Arg < NumArgs && "Arg access out of range!");
376     return getArgsBuffer()[Arg];
377   }
378 
379   bool isArgExpr(unsigned Arg) const {
380     return Arg < NumArgs && getArg(Arg).is<Expr*>();
381   }
382 
383   Expr *getArgAsExpr(unsigned Arg) const {
384     return getArg(Arg).get<Expr*>();
385   }
386 
387   bool isArgIdent(unsigned Arg) const {
388     return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>();
389   }
390 
391   IdentifierLoc *getArgAsIdent(unsigned Arg) const {
392     return getArg(Arg).get<IdentifierLoc*>();
393   }
394 
395   const AvailabilityChange &getAvailabilityIntroduced() const {
396     assert(getParsedKind() == AT_Availability &&
397            "Not an availability attribute");
398     return getAvailabilityData()->Changes[detail::IntroducedSlot];
399   }
400 
401   const AvailabilityChange &getAvailabilityDeprecated() const {
402     assert(getParsedKind() == AT_Availability &&
403            "Not an availability attribute");
404     return getAvailabilityData()->Changes[detail::DeprecatedSlot];
405   }
406 
407   const AvailabilityChange &getAvailabilityObsoleted() const {
408     assert(getParsedKind() == AT_Availability &&
409            "Not an availability attribute");
410     return getAvailabilityData()->Changes[detail::ObsoletedSlot];
411   }
412 
413   SourceLocation getStrictLoc() const {
414     assert(getParsedKind() == AT_Availability &&
415            "Not an availability attribute");
416     return getAvailabilityData()->StrictLoc;
417   }
418 
419   SourceLocation getUnavailableLoc() const {
420     assert(getParsedKind() == AT_Availability &&
421            "Not an availability attribute");
422     return UnavailableLoc;
423   }
424 
425   const Expr * getMessageExpr() const {
426     assert(getParsedKind() == AT_Availability &&
427            "Not an availability attribute");
428     return MessageExpr;
429   }
430 
431   const Expr *getReplacementExpr() const {
432     assert(getParsedKind() == AT_Availability &&
433            "Not an availability attribute");
434     return getAvailabilityData()->Replacement;
435   }
436 
437   const ParsedType &getMatchingCType() const {
438     assert(getParsedKind() == AT_TypeTagForDatatype &&
439            "Not a type_tag_for_datatype attribute");
440     return getTypeTagForDatatypeDataSlot().MatchingCType;
441   }
442 
443   bool getLayoutCompatible() const {
444     assert(getParsedKind() == AT_TypeTagForDatatype &&
445            "Not a type_tag_for_datatype attribute");
446     return getTypeTagForDatatypeDataSlot().LayoutCompatible;
447   }
448 
449   bool getMustBeNull() const {
450     assert(getParsedKind() == AT_TypeTagForDatatype &&
451            "Not a type_tag_for_datatype attribute");
452     return getTypeTagForDatatypeDataSlot().MustBeNull;
453   }
454 
455   const ParsedType &getTypeArg() const {
456     assert(HasParsedType && "Not a type attribute");
457     return getTypeBuffer();
458   }
459 
460   IdentifierInfo *getPropertyDataGetter() const {
461     assert(isDeclspecPropertyAttribute() &&
462            "Not a __delcspec(property) attribute");
463     return getPropertyDataBuffer().GetterId;
464   }
465 
466   IdentifierInfo *getPropertyDataSetter() const {
467     assert(isDeclspecPropertyAttribute() &&
468            "Not a __delcspec(property) attribute");
469     return getPropertyDataBuffer().SetterId;
470   }
471 
472   /// Set the macro identifier info object that this parsed attribute was
473   /// declared in if it was declared in a macro. Also set the expansion location
474   /// of the macro.
475   void setMacroIdentifier(IdentifierInfo *MacroName, SourceLocation Loc) {
476     MacroII = MacroName;
477     MacroExpansionLoc = Loc;
478   }
479 
480   /// Returns true if this attribute was declared in a macro.
481   bool hasMacroIdentifier() const { return MacroII != nullptr; }
482 
483   /// Return the macro identifier if this attribute was declared in a macro.
484   /// nullptr is returned if it was not declared in a macro.
485   IdentifierInfo *getMacroIdentifier() const { return MacroII; }
486 
487   SourceLocation getMacroExpansionLoc() const {
488     assert(hasMacroIdentifier() && "Can only get the macro expansion location "
489                                    "if this attribute has a macro identifier.");
490     return MacroExpansionLoc;
491   }
492 
493   bool isTargetSpecificAttr() const;
494   bool isTypeAttr() const;
495   bool isStmtAttr() const;
496 
497   bool hasCustomParsing() const;
498   unsigned getMinArgs() const;
499   unsigned getMaxArgs() const;
500   bool hasVariadicArg() const;
501   bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const;
502   bool appliesToDecl(const Decl *D, attr::SubjectMatchRule MatchRule) const;
503   void getMatchRules(const LangOptions &LangOpts,
504                      SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>>
505                          &MatchRules) const;
506   bool diagnoseLangOpts(class Sema &S) const;
507   bool existsInTarget(const TargetInfo &Target) const;
508   bool isKnownToGCC() const;
509   bool isSupportedByPragmaAttribute() const;
510 
511   /// If the parsed attribute has a semantic equivalent, and it would
512   /// have a semantic Spelling enumeration (due to having semantically-distinct
513   /// spelling variations), return the value of that semantic spelling. If the
514   /// parsed attribute does not have a semantic equivalent, or would not have
515   /// a Spelling enumeration, the value UINT_MAX is returned.
516   unsigned getSemanticSpelling() const;
517 
518   /// If this is an OpenCL addr space attribute returns its representation
519   /// in LangAS, otherwise returns default addr space.
520   LangAS asOpenCLLangAS() const {
521     switch (getParsedKind()) {
522     case ParsedAttr::AT_OpenCLConstantAddressSpace:
523       return LangAS::opencl_constant;
524     case ParsedAttr::AT_OpenCLGlobalAddressSpace:
525       return LangAS::opencl_global;
526     case ParsedAttr::AT_OpenCLLocalAddressSpace:
527       return LangAS::opencl_local;
528     case ParsedAttr::AT_OpenCLPrivateAddressSpace:
529       return LangAS::opencl_private;
530     case ParsedAttr::AT_OpenCLGenericAddressSpace:
531       return LangAS::opencl_generic;
532     default:
533       return LangAS::Default;
534     }
535   }
536 
537   AttributeCommonInfo::Kind getKind() const { return getParsedKind(); }
538 };
539 
540 class AttributePool;
541 /// A factory, from which one makes pools, from which one creates
542 /// individual attributes which are deallocated with the pool.
543 ///
544 /// Note that it's tolerably cheap to create and destroy one of
545 /// these as long as you don't actually allocate anything in it.
546 class AttributeFactory {
547 public:
548   enum {
549     AvailabilityAllocSize =
550         ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
551                                      detail::TypeTagForDatatypeData, ParsedType,
552                                      detail::PropertyData>(1, 1, 0, 0, 0),
553     TypeTagForDatatypeAllocSize =
554         ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
555                                      detail::TypeTagForDatatypeData, ParsedType,
556                                      detail::PropertyData>(1, 0, 1, 0, 0),
557     PropertyAllocSize =
558         ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
559                                      detail::TypeTagForDatatypeData, ParsedType,
560                                      detail::PropertyData>(0, 0, 0, 0, 1),
561   };
562 
563 private:
564   enum {
565     /// The number of free lists we want to be sure to support
566     /// inline.  This is just enough that availability attributes
567     /// don't surpass it.  It's actually very unlikely we'll see an
568     /// attribute that needs more than that; on x86-64 you'd need 10
569     /// expression arguments, and on i386 you'd need 19.
570     InlineFreeListsCapacity =
571         1 + (AvailabilityAllocSize - sizeof(ParsedAttr)) / sizeof(void *)
572   };
573 
574   llvm::BumpPtrAllocator Alloc;
575 
576   /// Free lists.  The index is determined by the following formula:
577   ///   (size - sizeof(ParsedAttr)) / sizeof(void*)
578   SmallVector<SmallVector<ParsedAttr *, 8>, InlineFreeListsCapacity> FreeLists;
579 
580   // The following are the private interface used by AttributePool.
581   friend class AttributePool;
582 
583   /// Allocate an attribute of the given size.
584   void *allocate(size_t size);
585 
586   void deallocate(ParsedAttr *AL);
587 
588   /// Reclaim all the attributes in the given pool chain, which is
589   /// non-empty.  Note that the current implementation is safe
590   /// against reclaiming things which were not actually allocated
591   /// with the allocator, although of course it's important to make
592   /// sure that their allocator lives at least as long as this one.
593   void reclaimPool(AttributePool &head);
594 
595 public:
596   AttributeFactory();
597   ~AttributeFactory();
598 };
599 
600 class AttributePool {
601   friend class AttributeFactory;
602   friend class ParsedAttributes;
603   AttributeFactory &Factory;
604   llvm::TinyPtrVector<ParsedAttr *> Attrs;
605 
606   void *allocate(size_t size) {
607     return Factory.allocate(size);
608   }
609 
610   ParsedAttr *add(ParsedAttr *attr) {
611     Attrs.push_back(attr);
612     return attr;
613   }
614 
615   void remove(ParsedAttr *attr) {
616     assert(llvm::is_contained(Attrs, attr) &&
617            "Can't take attribute from a pool that doesn't own it!");
618     Attrs.erase(llvm::find(Attrs, attr));
619   }
620 
621   void takePool(AttributePool &pool);
622 
623 public:
624   /// Create a new pool for a factory.
625   AttributePool(AttributeFactory &factory) : Factory(factory) {}
626 
627   AttributePool(const AttributePool &) = delete;
628 
629   ~AttributePool() { Factory.reclaimPool(*this); }
630 
631   /// Move the given pool's allocations to this pool.
632   AttributePool(AttributePool &&pool) = default;
633 
634   AttributeFactory &getFactory() const { return Factory; }
635 
636   void clear() {
637     Factory.reclaimPool(*this);
638     Attrs.clear();
639   }
640 
641   /// Take the given pool's allocations and add them to this pool.
642   void takeAllFrom(AttributePool &pool) {
643     takePool(pool);
644     pool.Attrs.clear();
645   }
646 
647   ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
648                      IdentifierInfo *scopeName, SourceLocation scopeLoc,
649                      ArgsUnion *args, unsigned numArgs,
650                      ParsedAttr::Syntax syntax,
651                      SourceLocation ellipsisLoc = SourceLocation()) {
652     size_t temp =
653         ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
654                                      detail::TypeTagForDatatypeData, ParsedType,
655                                      detail::PropertyData>(numArgs, 0, 0, 0, 0);
656     (void)temp;
657     void *memory = allocate(
658         ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
659                                      detail::TypeTagForDatatypeData, ParsedType,
660                                      detail::PropertyData>(numArgs, 0, 0, 0,
661                                                            0));
662     return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
663                                        args, numArgs, syntax, ellipsisLoc));
664   }
665 
666   ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
667                      IdentifierInfo *scopeName, SourceLocation scopeLoc,
668                      IdentifierLoc *Param, const AvailabilityChange &introduced,
669                      const AvailabilityChange &deprecated,
670                      const AvailabilityChange &obsoleted,
671                      SourceLocation unavailable, const Expr *MessageExpr,
672                      ParsedAttr::Syntax syntax, SourceLocation strict,
673                      const Expr *ReplacementExpr) {
674     void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
675     return add(new (memory) ParsedAttr(
676         attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated,
677         obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr));
678   }
679 
680   ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
681                      IdentifierInfo *scopeName, SourceLocation scopeLoc,
682                      IdentifierLoc *Param1, IdentifierLoc *Param2,
683                      IdentifierLoc *Param3, ParsedAttr::Syntax syntax) {
684     void *memory = allocate(
685         ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
686                                      detail::TypeTagForDatatypeData, ParsedType,
687                                      detail::PropertyData>(3, 0, 0, 0, 0));
688     return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
689                                        Param1, Param2, Param3, syntax));
690   }
691 
692   ParsedAttr *
693   createTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange,
694                            IdentifierInfo *scopeName, SourceLocation scopeLoc,
695                            IdentifierLoc *argumentKind,
696                            ParsedType matchingCType, bool layoutCompatible,
697                            bool mustBeNull, ParsedAttr::Syntax syntax) {
698     void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
699     return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
700                                        argumentKind, matchingCType,
701                                        layoutCompatible, mustBeNull, syntax));
702   }
703 
704   ParsedAttr *createTypeAttribute(IdentifierInfo *attrName,
705                                   SourceRange attrRange,
706                                   IdentifierInfo *scopeName,
707                                   SourceLocation scopeLoc, ParsedType typeArg,
708                                   ParsedAttr::Syntax syntaxUsed) {
709     void *memory = allocate(
710         ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
711                                      detail::TypeTagForDatatypeData, ParsedType,
712                                      detail::PropertyData>(0, 0, 0, 1, 0));
713     return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
714                                        typeArg, syntaxUsed));
715   }
716 
717   ParsedAttr *
718   createPropertyAttribute(IdentifierInfo *attrName, SourceRange attrRange,
719                           IdentifierInfo *scopeName, SourceLocation scopeLoc,
720                           IdentifierInfo *getterId, IdentifierInfo *setterId,
721                           ParsedAttr::Syntax syntaxUsed) {
722     void *memory = allocate(AttributeFactory::PropertyAllocSize);
723     return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
724                                        getterId, setterId, syntaxUsed));
725   }
726 };
727 
728 class ParsedAttributesView {
729   using VecTy = llvm::TinyPtrVector<ParsedAttr *>;
730   using SizeType = decltype(std::declval<VecTy>().size());
731 
732 public:
733   bool empty() const { return AttrList.empty(); }
734   SizeType size() const { return AttrList.size(); }
735   ParsedAttr &operator[](SizeType pos) { return *AttrList[pos]; }
736   const ParsedAttr &operator[](SizeType pos) const { return *AttrList[pos]; }
737 
738   void addAtEnd(ParsedAttr *newAttr) {
739     assert(newAttr);
740     AttrList.push_back(newAttr);
741   }
742 
743   void remove(ParsedAttr *ToBeRemoved) {
744     assert(is_contained(AttrList, ToBeRemoved) &&
745            "Cannot remove attribute that isn't in the list");
746     AttrList.erase(llvm::find(AttrList, ToBeRemoved));
747   }
748 
749   void clearListOnly() { AttrList.clear(); }
750 
751   struct iterator : llvm::iterator_adaptor_base<iterator, VecTy::iterator,
752                                                 std::random_access_iterator_tag,
753                                                 ParsedAttr> {
754     iterator() : iterator_adaptor_base(nullptr) {}
755     iterator(VecTy::iterator I) : iterator_adaptor_base(I) {}
756     reference operator*() { return **I; }
757     friend class ParsedAttributesView;
758   };
759   struct const_iterator
760       : llvm::iterator_adaptor_base<const_iterator, VecTy::const_iterator,
761                                     std::random_access_iterator_tag,
762                                     ParsedAttr> {
763     const_iterator() : iterator_adaptor_base(nullptr) {}
764     const_iterator(VecTy::const_iterator I) : iterator_adaptor_base(I) {}
765 
766     reference operator*() const { return **I; }
767     friend class ParsedAttributesView;
768   };
769 
770   void addAll(iterator B, iterator E) {
771     AttrList.insert(AttrList.begin(), B.I, E.I);
772   }
773 
774   void addAll(const_iterator B, const_iterator E) {
775     AttrList.insert(AttrList.begin(), B.I, E.I);
776   }
777 
778   void addAllAtEnd(iterator B, iterator E) {
779     AttrList.insert(AttrList.end(), B.I, E.I);
780   }
781 
782   void addAllAtEnd(const_iterator B, const_iterator E) {
783     AttrList.insert(AttrList.end(), B.I, E.I);
784   }
785 
786   iterator begin() { return iterator(AttrList.begin()); }
787   const_iterator begin() const { return const_iterator(AttrList.begin()); }
788   iterator end() { return iterator(AttrList.end()); }
789   const_iterator end() const { return const_iterator(AttrList.end()); }
790 
791   ParsedAttr &front() {
792     assert(!empty());
793     return *AttrList.front();
794   }
795   const ParsedAttr &front() const {
796     assert(!empty());
797     return *AttrList.front();
798   }
799   ParsedAttr &back() {
800     assert(!empty());
801     return *AttrList.back();
802   }
803   const ParsedAttr &back() const {
804     assert(!empty());
805     return *AttrList.back();
806   }
807 
808   bool hasAttribute(ParsedAttr::Kind K) const {
809     return llvm::any_of(AttrList, [K](const ParsedAttr *AL) {
810       return AL->getParsedKind() == K;
811     });
812   }
813 
814 private:
815   VecTy AttrList;
816 };
817 
818 /// ParsedAttributes - A collection of parsed attributes.  Currently
819 /// we don't differentiate between the various attribute syntaxes,
820 /// which is basically silly.
821 ///
822 /// Right now this is a very lightweight container, but the expectation
823 /// is that this will become significantly more serious.
824 class ParsedAttributes : public ParsedAttributesView {
825 public:
826   ParsedAttributes(AttributeFactory &factory) : pool(factory) {}
827   ParsedAttributes(const ParsedAttributes &) = delete;
828 
829   AttributePool &getPool() const { return pool; }
830 
831   void takeAllFrom(ParsedAttributes &attrs) {
832     addAll(attrs.begin(), attrs.end());
833     attrs.clearListOnly();
834     pool.takeAllFrom(attrs.pool);
835   }
836 
837   void takeOneFrom(ParsedAttributes &Attrs, ParsedAttr *PA) {
838     Attrs.getPool().remove(PA);
839     Attrs.remove(PA);
840     getPool().add(PA);
841     addAtEnd(PA);
842   }
843 
844   void clear() {
845     clearListOnly();
846     pool.clear();
847   }
848 
849   /// Add attribute with expression arguments.
850   ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
851                      IdentifierInfo *scopeName, SourceLocation scopeLoc,
852                      ArgsUnion *args, unsigned numArgs,
853                      ParsedAttr::Syntax syntax,
854                      SourceLocation ellipsisLoc = SourceLocation()) {
855     ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
856                                    args, numArgs, syntax, ellipsisLoc);
857     addAtEnd(attr);
858     return attr;
859   }
860 
861   /// Add availability attribute.
862   ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
863                      IdentifierInfo *scopeName, SourceLocation scopeLoc,
864                      IdentifierLoc *Param, const AvailabilityChange &introduced,
865                      const AvailabilityChange &deprecated,
866                      const AvailabilityChange &obsoleted,
867                      SourceLocation unavailable, const Expr *MessageExpr,
868                      ParsedAttr::Syntax syntax, SourceLocation strict,
869                      const Expr *ReplacementExpr) {
870     ParsedAttr *attr = pool.create(
871         attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated,
872         obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr);
873     addAtEnd(attr);
874     return attr;
875   }
876 
877   /// Add objc_bridge_related attribute.
878   ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
879                      IdentifierInfo *scopeName, SourceLocation scopeLoc,
880                      IdentifierLoc *Param1, IdentifierLoc *Param2,
881                      IdentifierLoc *Param3, ParsedAttr::Syntax syntax) {
882     ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
883                                    Param1, Param2, Param3, syntax);
884     addAtEnd(attr);
885     return attr;
886   }
887 
888   /// Add type_tag_for_datatype attribute.
889   ParsedAttr *
890   addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange,
891                            IdentifierInfo *scopeName, SourceLocation scopeLoc,
892                            IdentifierLoc *argumentKind,
893                            ParsedType matchingCType, bool layoutCompatible,
894                            bool mustBeNull, ParsedAttr::Syntax syntax) {
895     ParsedAttr *attr = pool.createTypeTagForDatatype(
896         attrName, attrRange, scopeName, scopeLoc, argumentKind, matchingCType,
897         layoutCompatible, mustBeNull, syntax);
898     addAtEnd(attr);
899     return attr;
900   }
901 
902   /// Add an attribute with a single type argument.
903   ParsedAttr *addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange,
904                              IdentifierInfo *scopeName, SourceLocation scopeLoc,
905                              ParsedType typeArg,
906                              ParsedAttr::Syntax syntaxUsed) {
907     ParsedAttr *attr = pool.createTypeAttribute(attrName, attrRange, scopeName,
908                                                 scopeLoc, typeArg, syntaxUsed);
909     addAtEnd(attr);
910     return attr;
911   }
912 
913   /// Add microsoft __delspec(property) attribute.
914   ParsedAttr *
915   addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange,
916                      IdentifierInfo *scopeName, SourceLocation scopeLoc,
917                      IdentifierInfo *getterId, IdentifierInfo *setterId,
918                      ParsedAttr::Syntax syntaxUsed) {
919     ParsedAttr *attr =
920         pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
921                                      getterId, setterId, syntaxUsed);
922     addAtEnd(attr);
923     return attr;
924   }
925 
926 private:
927   mutable AttributePool pool;
928 };
929 
930 /// These constants match the enumerated choices of
931 /// err_attribute_argument_n_type and err_attribute_argument_type.
932 enum AttributeArgumentNType {
933   AANT_ArgumentIntOrBool,
934   AANT_ArgumentIntegerConstant,
935   AANT_ArgumentString,
936   AANT_ArgumentIdentifier
937 };
938 
939 /// These constants match the enumerated choices of
940 /// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
941 enum AttributeDeclKind {
942   ExpectedFunction,
943   ExpectedUnion,
944   ExpectedVariableOrFunction,
945   ExpectedFunctionOrMethod,
946   ExpectedFunctionMethodOrBlock,
947   ExpectedFunctionMethodOrParameter,
948   ExpectedVariable,
949   ExpectedVariableOrField,
950   ExpectedVariableFieldOrTag,
951   ExpectedTypeOrNamespace,
952   ExpectedFunctionVariableOrClass,
953   ExpectedKernelFunction,
954   ExpectedFunctionWithProtoType,
955 };
956 
957 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
958                                            const ParsedAttr &At) {
959   DB.AddTaggedVal(reinterpret_cast<intptr_t>(At.getAttrName()),
960                   DiagnosticsEngine::ak_identifierinfo);
961   return DB;
962 }
963 
964 inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
965                                            const ParsedAttr &At) {
966   PD.AddTaggedVal(reinterpret_cast<intptr_t>(At.getAttrName()),
967                   DiagnosticsEngine::ak_identifierinfo);
968   return PD;
969 }
970 
971 inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
972                                            const ParsedAttr *At) {
973   DB.AddTaggedVal(reinterpret_cast<intptr_t>(At->getAttrName()),
974                   DiagnosticsEngine::ak_identifierinfo);
975   return DB;
976 }
977 
978 inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD,
979                                            const ParsedAttr *At) {
980   PD.AddTaggedVal(reinterpret_cast<intptr_t>(At->getAttrName()),
981                   DiagnosticsEngine::ak_identifierinfo);
982   return PD;
983 }
984 
985 } // namespace clang
986 
987 #endif // LLVM_CLANG_SEMA_ATTRIBUTELIST_H
988