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