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