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