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