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