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