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