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