12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //======- ParsedAttr.h - Parsed attribute sets ------------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file defines the ParsedAttr class, which is used to collect
- // parsed attributes.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CLANG_SEMA_PARSEDATTR_H
- #define LLVM_CLANG_SEMA_PARSEDATTR_H
- #include "clang/Basic/AttrSubjectMatchRules.h"
- #include "clang/Basic/AttributeCommonInfo.h"
- #include "clang/Basic/Diagnostic.h"
- #include "clang/Basic/SourceLocation.h"
- #include "clang/Sema/Ownership.h"
- #include "llvm/ADT/PointerUnion.h"
- #include "llvm/ADT/SmallVector.h"
- #include "llvm/Support/Allocator.h"
- #include "llvm/Support/Registry.h"
- #include "llvm/Support/VersionTuple.h"
- #include <cassert>
- #include <cstddef>
- #include <cstring>
- #include <utility>
- namespace clang {
- class ASTContext;
- class Decl;
- class Expr;
- class IdentifierInfo;
- class LangOptions;
- class ParsedAttr;
- class Sema;
- class Stmt;
- class TargetInfo;
- struct ParsedAttrInfo {
- /// Corresponds to the Kind enum.
- unsigned AttrKind : 16;
- /// The number of required arguments of this attribute.
- unsigned NumArgs : 4;
- /// The number of optional arguments of this attributes.
- unsigned OptArgs : 4;
- /// The number of non-fake arguments specified in the attribute definition.
- unsigned NumArgMembers : 4;
- /// True if the parsing does not match the semantic content.
- unsigned HasCustomParsing : 1;
- // True if this attribute accepts expression parameter pack expansions.
- unsigned AcceptsExprPack : 1;
- /// True if this attribute is only available for certain targets.
- unsigned IsTargetSpecific : 1;
- /// True if this attribute applies to types.
- unsigned IsType : 1;
- /// True if this attribute applies to statements.
- unsigned IsStmt : 1;
- /// True if this attribute has any spellings that are known to gcc.
- unsigned IsKnownToGCC : 1;
- /// True if this attribute is supported by #pragma clang attribute.
- unsigned IsSupportedByPragmaAttribute : 1;
- /// The syntaxes supported by this attribute and how they're spelled.
- struct Spelling {
- AttributeCommonInfo::Syntax Syntax;
- const char *NormalizedFullName;
- };
- ArrayRef<Spelling> Spellings;
- // The names of the known arguments of this attribute.
- ArrayRef<const char *> ArgNames;
- protected:
- constexpr ParsedAttrInfo(AttributeCommonInfo::Kind AttrKind =
- AttributeCommonInfo::NoSemaHandlerAttribute)
- : AttrKind(AttrKind), NumArgs(0), OptArgs(0), NumArgMembers(0),
- HasCustomParsing(0), AcceptsExprPack(0), IsTargetSpecific(0), IsType(0),
- IsStmt(0), IsKnownToGCC(0), IsSupportedByPragmaAttribute(0) {}
- constexpr ParsedAttrInfo(AttributeCommonInfo::Kind AttrKind, unsigned NumArgs,
- unsigned OptArgs, unsigned NumArgMembers,
- unsigned HasCustomParsing, unsigned AcceptsExprPack,
- unsigned IsTargetSpecific, unsigned IsType,
- unsigned IsStmt, unsigned IsKnownToGCC,
- unsigned IsSupportedByPragmaAttribute,
- ArrayRef<Spelling> Spellings,
- ArrayRef<const char *> ArgNames)
- : AttrKind(AttrKind), NumArgs(NumArgs), OptArgs(OptArgs),
- NumArgMembers(NumArgMembers), HasCustomParsing(HasCustomParsing),
- AcceptsExprPack(AcceptsExprPack), IsTargetSpecific(IsTargetSpecific),
- IsType(IsType), IsStmt(IsStmt), IsKnownToGCC(IsKnownToGCC),
- IsSupportedByPragmaAttribute(IsSupportedByPragmaAttribute),
- Spellings(Spellings), ArgNames(ArgNames) {}
- public:
- virtual ~ParsedAttrInfo() = default;
- /// Check if this attribute appertains to D, and issue a diagnostic if not.
- virtual bool diagAppertainsToDecl(Sema &S, const ParsedAttr &Attr,
- const Decl *D) const {
- return true;
- }
- /// Check if this attribute appertains to St, and issue a diagnostic if not.
- virtual bool diagAppertainsToStmt(Sema &S, const ParsedAttr &Attr,
- const Stmt *St) const {
- return true;
- }
- /// Check if the given attribute is mutually exclusive with other attributes
- /// already applied to the given declaration.
- virtual bool diagMutualExclusion(Sema &S, const ParsedAttr &A,
- const Decl *D) const {
- return true;
- }
- /// Check if this attribute is allowed by the language we are compiling.
- virtual bool acceptsLangOpts(const LangOptions &LO) const { return true; }
- /// Check if this attribute is allowed when compiling for the given target.
- virtual bool existsInTarget(const TargetInfo &Target) const {
- return true;
- }
- /// Convert the spelling index of Attr to a semantic spelling enum value.
- virtual unsigned
- spellingIndexToSemanticSpelling(const ParsedAttr &Attr) const {
- return UINT_MAX;
- }
- /// Returns true if the specified parameter index for this attribute in
- /// Attr.td is an ExprArgument or VariadicExprArgument, or a subclass thereof;
- /// returns false otherwise.
- virtual bool isParamExpr(size_t N) const { return false; }
- /// Populate Rules with the match rules of this attribute.
- virtual void getPragmaAttributeMatchRules(
- llvm::SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &Rules,
- const LangOptions &LangOpts) const {
- }
- enum AttrHandling {
- NotHandled,
- AttributeApplied,
- AttributeNotApplied
- };
- /// If this ParsedAttrInfo knows how to handle this ParsedAttr applied to this
- /// Decl then do so and return either AttributeApplied if it was applied or
- /// AttributeNotApplied if it wasn't. Otherwise return NotHandled.
- virtual AttrHandling handleDeclAttribute(Sema &S, Decl *D,
- const ParsedAttr &Attr) const {
- return NotHandled;
- }
- static const ParsedAttrInfo &get(const AttributeCommonInfo &A);
- static ArrayRef<const ParsedAttrInfo *> getAllBuiltin();
- };
- typedef llvm::Registry<ParsedAttrInfo> ParsedAttrInfoRegistry;
- /// Represents information about a change in availability for
- /// an entity, which is part of the encoding of the 'availability'
- /// attribute.
- struct AvailabilityChange {
- /// The location of the keyword indicating the kind of change.
- SourceLocation KeywordLoc;
- /// The version number at which the change occurred.
- VersionTuple Version;
- /// The source range covering the version number.
- SourceRange VersionRange;
- /// Determine whether this availability change is valid.
- bool isValid() const { return !Version.empty(); }
- };
- namespace detail {
- enum AvailabilitySlot {
- IntroducedSlot, DeprecatedSlot, ObsoletedSlot, NumAvailabilitySlots
- };
- /// Describes the trailing object for Availability attribute in ParsedAttr.
- struct AvailabilityData {
- AvailabilityChange Changes[NumAvailabilitySlots];
- SourceLocation StrictLoc;
- const Expr *Replacement;
- AvailabilityData(const AvailabilityChange &Introduced,
- const AvailabilityChange &Deprecated,
- const AvailabilityChange &Obsoleted,
- SourceLocation Strict, const Expr *ReplaceExpr)
- : StrictLoc(Strict), Replacement(ReplaceExpr) {
- Changes[IntroducedSlot] = Introduced;
- Changes[DeprecatedSlot] = Deprecated;
- Changes[ObsoletedSlot] = Obsoleted;
- }
- };
- struct TypeTagForDatatypeData {
- ParsedType MatchingCType;
- unsigned LayoutCompatible : 1;
- unsigned MustBeNull : 1;
- };
- struct PropertyData {
- IdentifierInfo *GetterId, *SetterId;
- PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
- : GetterId(getterId), SetterId(setterId) {}
- };
- } // namespace
- /// Wraps an identifier and optional source location for the identifier.
- struct IdentifierLoc {
- SourceLocation Loc;
- IdentifierInfo *Ident;
- static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc,
- IdentifierInfo *Ident);
- };
- /// A union of the various pointer types that can be passed to an
- /// ParsedAttr as an argument.
- using ArgsUnion = llvm::PointerUnion<Expr *, IdentifierLoc *>;
- using ArgsVector = llvm::SmallVector<ArgsUnion, 12U>;
- /// ParsedAttr - Represents a syntactic attribute.
- ///
- /// For a GNU attribute, there are four forms of this construct:
- ///
- /// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused.
- /// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused.
- /// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used.
- /// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
- ///
- class ParsedAttr final
- : public AttributeCommonInfo,
- private llvm::TrailingObjects<
- ParsedAttr, ArgsUnion, detail::AvailabilityData,
- detail::TypeTagForDatatypeData, ParsedType, detail::PropertyData> {
- friend TrailingObjects;
- size_t numTrailingObjects(OverloadToken<ArgsUnion>) const { return NumArgs; }
- size_t numTrailingObjects(OverloadToken<detail::AvailabilityData>) const {
- return IsAvailability;
- }
- size_t
- numTrailingObjects(OverloadToken<detail::TypeTagForDatatypeData>) const {
- return IsTypeTagForDatatype;
- }
- size_t numTrailingObjects(OverloadToken<ParsedType>) const {
- return HasParsedType;
- }
- size_t numTrailingObjects(OverloadToken<detail::PropertyData>) const {
- return IsProperty;
- }
- private:
- IdentifierInfo *MacroII = nullptr;
- SourceLocation MacroExpansionLoc;
- SourceLocation EllipsisLoc;
- /// The number of expression arguments this attribute has.
- /// The expressions themselves are stored after the object.
- unsigned NumArgs : 16;
- /// True if already diagnosed as invalid.
- mutable unsigned Invalid : 1;
- /// True if this attribute was used as a type attribute.
- mutable unsigned UsedAsTypeAttr : 1;
- /// True if this has the extra information associated with an
- /// availability attribute.
- unsigned IsAvailability : 1;
- /// True if this has extra information associated with a
- /// type_tag_for_datatype attribute.
- unsigned IsTypeTagForDatatype : 1;
- /// True if this has extra information associated with a
- /// Microsoft __delcspec(property) attribute.
- unsigned IsProperty : 1;
- /// True if this has a ParsedType
- unsigned HasParsedType : 1;
- /// True if the processing cache is valid.
- mutable unsigned HasProcessingCache : 1;
- /// A cached value.
- mutable unsigned ProcessingCache : 8;
- /// True if the attribute is specified using '#pragma clang attribute'.
- mutable unsigned IsPragmaClangAttribute : 1;
- /// The location of the 'unavailable' keyword in an
- /// availability attribute.
- SourceLocation UnavailableLoc;
- const Expr *MessageExpr;
- const ParsedAttrInfo &Info;
- ArgsUnion *getArgsBuffer() { return getTrailingObjects<ArgsUnion>(); }
- ArgsUnion const *getArgsBuffer() const {
- return getTrailingObjects<ArgsUnion>();
- }
- detail::AvailabilityData *getAvailabilityData() {
- return getTrailingObjects<detail::AvailabilityData>();
- }
- const detail::AvailabilityData *getAvailabilityData() const {
- return getTrailingObjects<detail::AvailabilityData>();
- }
- private:
- friend class AttributeFactory;
- friend class AttributePool;
- /// Constructor for attributes with expression arguments.
- ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- ArgsUnion *args, unsigned numArgs, Syntax syntaxUsed,
- SourceLocation ellipsisLoc)
- : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc,
- syntaxUsed),
- EllipsisLoc(ellipsisLoc), NumArgs(numArgs), Invalid(false),
- UsedAsTypeAttr(false), IsAvailability(false),
- IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
- HasProcessingCache(false), IsPragmaClangAttribute(false),
- Info(ParsedAttrInfo::get(*this)) {
- if (numArgs)
- memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion));
- }
- /// Constructor for availability attributes.
- ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierLoc *Parm, const AvailabilityChange &introduced,
- const AvailabilityChange &deprecated,
- const AvailabilityChange &obsoleted, SourceLocation unavailable,
- const Expr *messageExpr, Syntax syntaxUsed, SourceLocation strict,
- const Expr *replacementExpr)
- : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc,
- syntaxUsed),
- NumArgs(1), Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
- IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
- HasProcessingCache(false), IsPragmaClangAttribute(false),
- UnavailableLoc(unavailable), MessageExpr(messageExpr),
- Info(ParsedAttrInfo::get(*this)) {
- ArgsUnion PVal(Parm);
- memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
- new (getAvailabilityData()) detail::AvailabilityData(
- introduced, deprecated, obsoleted, strict, replacementExpr);
- }
- /// Constructor for objc_bridge_related attributes.
- ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierLoc *Parm1, IdentifierLoc *Parm2, IdentifierLoc *Parm3,
- Syntax syntaxUsed)
- : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc,
- syntaxUsed),
- NumArgs(3), Invalid(false), UsedAsTypeAttr(false),
- IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
- HasParsedType(false), HasProcessingCache(false),
- IsPragmaClangAttribute(false), Info(ParsedAttrInfo::get(*this)) {
- ArgsUnion *Args = getArgsBuffer();
- Args[0] = Parm1;
- Args[1] = Parm2;
- Args[2] = Parm3;
- }
- /// Constructor for type_tag_for_datatype attribute.
- ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierLoc *ArgKind, ParsedType matchingCType,
- bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed)
- : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc,
- syntaxUsed),
- NumArgs(1), Invalid(false), UsedAsTypeAttr(false),
- IsAvailability(false), IsTypeTagForDatatype(true), IsProperty(false),
- HasParsedType(false), HasProcessingCache(false),
- IsPragmaClangAttribute(false), Info(ParsedAttrInfo::get(*this)) {
- ArgsUnion PVal(ArgKind);
- memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
- detail::TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
- new (&ExtraData.MatchingCType) ParsedType(matchingCType);
- ExtraData.LayoutCompatible = layoutCompatible;
- ExtraData.MustBeNull = mustBeNull;
- }
- /// Constructor for attributes with a single type argument.
- ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- ParsedType typeArg, Syntax syntaxUsed)
- : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc,
- syntaxUsed),
- NumArgs(0), Invalid(false), UsedAsTypeAttr(false),
- IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
- HasParsedType(true), HasProcessingCache(false),
- IsPragmaClangAttribute(false), Info(ParsedAttrInfo::get(*this)) {
- new (&getTypeBuffer()) ParsedType(typeArg);
- }
- /// Constructor for microsoft __declspec(property) attribute.
- ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierInfo *getterId, IdentifierInfo *setterId,
- Syntax syntaxUsed)
- : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc,
- syntaxUsed),
- NumArgs(0), Invalid(false), UsedAsTypeAttr(false),
- IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(true),
- HasParsedType(false), HasProcessingCache(false),
- IsPragmaClangAttribute(false), Info(ParsedAttrInfo::get(*this)) {
- new (&getPropertyDataBuffer()) detail::PropertyData(getterId, setterId);
- }
- /// Type tag information is stored immediately following the arguments, if
- /// any, at the end of the object. They are mutually exclusive with
- /// availability slots.
- detail::TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
- return *getTrailingObjects<detail::TypeTagForDatatypeData>();
- }
- const detail::TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
- return *getTrailingObjects<detail::TypeTagForDatatypeData>();
- }
- /// The type buffer immediately follows the object and are mutually exclusive
- /// with arguments.
- ParsedType &getTypeBuffer() { return *getTrailingObjects<ParsedType>(); }
- const ParsedType &getTypeBuffer() const {
- return *getTrailingObjects<ParsedType>();
- }
- /// The property data immediately follows the object is mutually exclusive
- /// with arguments.
- detail::PropertyData &getPropertyDataBuffer() {
- assert(IsProperty);
- return *getTrailingObjects<detail::PropertyData>();
- }
- const detail::PropertyData &getPropertyDataBuffer() const {
- assert(IsProperty);
- return *getTrailingObjects<detail::PropertyData>();
- }
- size_t allocated_size() const;
- public:
- ParsedAttr(const ParsedAttr &) = delete;
- ParsedAttr(ParsedAttr &&) = delete;
- ParsedAttr &operator=(const ParsedAttr &) = delete;
- ParsedAttr &operator=(ParsedAttr &&) = delete;
- ~ParsedAttr() = delete;
- void operator delete(void *) = delete;
- bool hasParsedType() const { return HasParsedType; }
- /// Is this the Microsoft __declspec(property) attribute?
- bool isDeclspecPropertyAttribute() const {
- return IsProperty;
- }
- bool isInvalid() const { return Invalid; }
- void setInvalid(bool b = true) const { Invalid = b; }
- bool hasProcessingCache() const { return HasProcessingCache; }
- unsigned getProcessingCache() const {
- assert(hasProcessingCache());
- return ProcessingCache;
- }
- void setProcessingCache(unsigned value) const {
- ProcessingCache = value;
- HasProcessingCache = true;
- }
- bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
- void setUsedAsTypeAttr(bool Used = true) { UsedAsTypeAttr = Used; }
- /// True if the attribute is specified using '#pragma clang attribute'.
- bool isPragmaClangAttribute() const { return IsPragmaClangAttribute; }
- void setIsPragmaClangAttribute() { IsPragmaClangAttribute = true; }
- bool isPackExpansion() const { return EllipsisLoc.isValid(); }
- SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
- /// getNumArgs - Return the number of actual arguments to this attribute.
- unsigned getNumArgs() const { return NumArgs; }
- /// getArg - Return the specified argument.
- ArgsUnion getArg(unsigned Arg) const {
- assert(Arg < NumArgs && "Arg access out of range!");
- return getArgsBuffer()[Arg];
- }
- bool isArgExpr(unsigned Arg) const {
- return Arg < NumArgs && getArg(Arg).is<Expr*>();
- }
- Expr *getArgAsExpr(unsigned Arg) const {
- return getArg(Arg).get<Expr*>();
- }
- bool isArgIdent(unsigned Arg) const {
- return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>();
- }
- IdentifierLoc *getArgAsIdent(unsigned Arg) const {
- return getArg(Arg).get<IdentifierLoc*>();
- }
- const AvailabilityChange &getAvailabilityIntroduced() const {
- assert(getParsedKind() == AT_Availability &&
- "Not an availability attribute");
- return getAvailabilityData()->Changes[detail::IntroducedSlot];
- }
- const AvailabilityChange &getAvailabilityDeprecated() const {
- assert(getParsedKind() == AT_Availability &&
- "Not an availability attribute");
- return getAvailabilityData()->Changes[detail::DeprecatedSlot];
- }
- const AvailabilityChange &getAvailabilityObsoleted() const {
- assert(getParsedKind() == AT_Availability &&
- "Not an availability attribute");
- return getAvailabilityData()->Changes[detail::ObsoletedSlot];
- }
- SourceLocation getStrictLoc() const {
- assert(getParsedKind() == AT_Availability &&
- "Not an availability attribute");
- return getAvailabilityData()->StrictLoc;
- }
- SourceLocation getUnavailableLoc() const {
- assert(getParsedKind() == AT_Availability &&
- "Not an availability attribute");
- return UnavailableLoc;
- }
- const Expr * getMessageExpr() const {
- assert(getParsedKind() == AT_Availability &&
- "Not an availability attribute");
- return MessageExpr;
- }
- const Expr *getReplacementExpr() const {
- assert(getParsedKind() == AT_Availability &&
- "Not an availability attribute");
- return getAvailabilityData()->Replacement;
- }
- const ParsedType &getMatchingCType() const {
- assert(getParsedKind() == AT_TypeTagForDatatype &&
- "Not a type_tag_for_datatype attribute");
- return getTypeTagForDatatypeDataSlot().MatchingCType;
- }
- bool getLayoutCompatible() const {
- assert(getParsedKind() == AT_TypeTagForDatatype &&
- "Not a type_tag_for_datatype attribute");
- return getTypeTagForDatatypeDataSlot().LayoutCompatible;
- }
- bool getMustBeNull() const {
- assert(getParsedKind() == AT_TypeTagForDatatype &&
- "Not a type_tag_for_datatype attribute");
- return getTypeTagForDatatypeDataSlot().MustBeNull;
- }
- const ParsedType &getTypeArg() const {
- assert(HasParsedType && "Not a type attribute");
- return getTypeBuffer();
- }
- IdentifierInfo *getPropertyDataGetter() const {
- assert(isDeclspecPropertyAttribute() &&
- "Not a __delcspec(property) attribute");
- return getPropertyDataBuffer().GetterId;
- }
- IdentifierInfo *getPropertyDataSetter() const {
- assert(isDeclspecPropertyAttribute() &&
- "Not a __delcspec(property) attribute");
- return getPropertyDataBuffer().SetterId;
- }
- /// Set the macro identifier info object that this parsed attribute was
- /// declared in if it was declared in a macro. Also set the expansion location
- /// of the macro.
- void setMacroIdentifier(IdentifierInfo *MacroName, SourceLocation Loc) {
- MacroII = MacroName;
- MacroExpansionLoc = Loc;
- }
- /// Returns true if this attribute was declared in a macro.
- bool hasMacroIdentifier() const { return MacroII != nullptr; }
- /// Return the macro identifier if this attribute was declared in a macro.
- /// nullptr is returned if it was not declared in a macro.
- IdentifierInfo *getMacroIdentifier() const { return MacroII; }
- SourceLocation getMacroExpansionLoc() const {
- assert(hasMacroIdentifier() && "Can only get the macro expansion location "
- "if this attribute has a macro identifier.");
- return MacroExpansionLoc;
- }
- /// Check if the attribute has exactly as many args as Num. May output an
- /// error. Returns false if a diagnostic is produced.
- bool checkExactlyNumArgs(class Sema &S, unsigned Num) const;
- /// Check if the attribute has at least as many args as Num. May output an
- /// error. Returns false if a diagnostic is produced.
- bool checkAtLeastNumArgs(class Sema &S, unsigned Num) const;
- /// Check if the attribute has at most as many args as Num. May output an
- /// error. Returns false if a diagnostic is produced.
- bool checkAtMostNumArgs(class Sema &S, unsigned Num) const;
- bool isTargetSpecificAttr() const;
- bool isTypeAttr() const;
- bool isStmtAttr() const;
- bool hasCustomParsing() const;
- bool acceptsExprPack() const;
- bool isParamExpr(size_t N) const;
- unsigned getMinArgs() const;
- unsigned getMaxArgs() const;
- unsigned getNumArgMembers() const;
- bool hasVariadicArg() const;
- void handleAttrWithDelayedArgs(Sema &S, Decl *D) const;
- bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const;
- bool diagnoseAppertainsTo(class Sema &S, const Stmt *St) const;
- bool diagnoseMutualExclusion(class Sema &S, const Decl *D) const;
- // This function stub exists for parity with the declaration checking code so
- // that checkCommonAttributeFeatures() can work generically on declarations
- // or statements.
- bool diagnoseMutualExclusion(class Sema &S, const Stmt *St) const {
- return true;
- }
- bool appliesToDecl(const Decl *D, attr::SubjectMatchRule MatchRule) const;
- void getMatchRules(const LangOptions &LangOpts,
- SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>>
- &MatchRules) const;
- bool diagnoseLangOpts(class Sema &S) const;
- bool existsInTarget(const TargetInfo &Target) const;
- bool isKnownToGCC() const;
- bool isSupportedByPragmaAttribute() const;
- /// Returns whether a [[]] attribute, if specified ahead of a declaration,
- /// should be applied to the decl-specifier-seq instead (i.e. whether it
- /// "slides" to the decl-specifier-seq).
- ///
- /// By the standard, attributes specified before the declaration always
- /// appertain to the declaration, but historically we have allowed some of
- /// these attributes to slide to the decl-specifier-seq, so we need to keep
- /// supporting this behavior.
- ///
- /// This may only be called if isStandardAttributeSyntax() returns true.
- bool slidesFromDeclToDeclSpecLegacyBehavior() const;
- /// If the parsed attribute has a semantic equivalent, and it would
- /// have a semantic Spelling enumeration (due to having semantically-distinct
- /// spelling variations), return the value of that semantic spelling. If the
- /// parsed attribute does not have a semantic equivalent, or would not have
- /// a Spelling enumeration, the value UINT_MAX is returned.
- unsigned getSemanticSpelling() const;
- /// If this is an OpenCL address space attribute, returns its representation
- /// in LangAS, otherwise returns default address space.
- LangAS asOpenCLLangAS() const {
- switch (getParsedKind()) {
- case ParsedAttr::AT_OpenCLConstantAddressSpace:
- return LangAS::opencl_constant;
- case ParsedAttr::AT_OpenCLGlobalAddressSpace:
- return LangAS::opencl_global;
- case ParsedAttr::AT_OpenCLGlobalDeviceAddressSpace:
- return LangAS::opencl_global_device;
- case ParsedAttr::AT_OpenCLGlobalHostAddressSpace:
- return LangAS::opencl_global_host;
- case ParsedAttr::AT_OpenCLLocalAddressSpace:
- return LangAS::opencl_local;
- case ParsedAttr::AT_OpenCLPrivateAddressSpace:
- return LangAS::opencl_private;
- case ParsedAttr::AT_OpenCLGenericAddressSpace:
- return LangAS::opencl_generic;
- default:
- return LangAS::Default;
- }
- }
- /// If this is an OpenCL address space attribute, returns its SYCL
- /// representation in LangAS, otherwise returns default address space.
- LangAS asSYCLLangAS() const {
- switch (getKind()) {
- case ParsedAttr::AT_OpenCLGlobalAddressSpace:
- return LangAS::sycl_global;
- case ParsedAttr::AT_OpenCLGlobalDeviceAddressSpace:
- return LangAS::sycl_global_device;
- case ParsedAttr::AT_OpenCLGlobalHostAddressSpace:
- return LangAS::sycl_global_host;
- case ParsedAttr::AT_OpenCLLocalAddressSpace:
- return LangAS::sycl_local;
- case ParsedAttr::AT_OpenCLPrivateAddressSpace:
- return LangAS::sycl_private;
- case ParsedAttr::AT_OpenCLGenericAddressSpace:
- default:
- return LangAS::Default;
- }
- }
- /// If this is an HLSL address space attribute, returns its representation
- /// in LangAS, otherwise returns default address space.
- LangAS asHLSLLangAS() const {
- switch (getParsedKind()) {
- case ParsedAttr::AT_HLSLGroupSharedAddressSpace:
- return LangAS::hlsl_groupshared;
- default:
- return LangAS::Default;
- }
- }
- AttributeCommonInfo::Kind getKind() const {
- return AttributeCommonInfo::Kind(Info.AttrKind);
- }
- const ParsedAttrInfo &getInfo() const { return Info; }
- };
- class AttributePool;
- /// A factory, from which one makes pools, from which one creates
- /// individual attributes which are deallocated with the pool.
- ///
- /// Note that it's tolerably cheap to create and destroy one of
- /// these as long as you don't actually allocate anything in it.
- class AttributeFactory {
- public:
- enum {
- AvailabilityAllocSize =
- ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
- detail::TypeTagForDatatypeData, ParsedType,
- detail::PropertyData>(1, 1, 0, 0, 0),
- TypeTagForDatatypeAllocSize =
- ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
- detail::TypeTagForDatatypeData, ParsedType,
- detail::PropertyData>(1, 0, 1, 0, 0),
- PropertyAllocSize =
- ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
- detail::TypeTagForDatatypeData, ParsedType,
- detail::PropertyData>(0, 0, 0, 0, 1),
- };
- private:
- enum {
- /// The number of free lists we want to be sure to support
- /// inline. This is just enough that availability attributes
- /// don't surpass it. It's actually very unlikely we'll see an
- /// attribute that needs more than that; on x86-64 you'd need 10
- /// expression arguments, and on i386 you'd need 19.
- InlineFreeListsCapacity =
- 1 + (AvailabilityAllocSize - sizeof(ParsedAttr)) / sizeof(void *)
- };
- llvm::BumpPtrAllocator Alloc;
- /// Free lists. The index is determined by the following formula:
- /// (size - sizeof(ParsedAttr)) / sizeof(void*)
- SmallVector<SmallVector<ParsedAttr *, 8>, InlineFreeListsCapacity> FreeLists;
- // The following are the private interface used by AttributePool.
- friend class AttributePool;
- /// Allocate an attribute of the given size.
- void *allocate(size_t size);
- void deallocate(ParsedAttr *AL);
- /// Reclaim all the attributes in the given pool chain, which is
- /// non-empty. Note that the current implementation is safe
- /// against reclaiming things which were not actually allocated
- /// with the allocator, although of course it's important to make
- /// sure that their allocator lives at least as long as this one.
- void reclaimPool(AttributePool &head);
- public:
- AttributeFactory();
- ~AttributeFactory();
- };
- class AttributePool {
- friend class AttributeFactory;
- friend class ParsedAttributes;
- AttributeFactory &Factory;
- llvm::SmallVector<ParsedAttr *> Attrs;
- void *allocate(size_t size) {
- return Factory.allocate(size);
- }
- ParsedAttr *add(ParsedAttr *attr) {
- Attrs.push_back(attr);
- return attr;
- }
- void remove(ParsedAttr *attr) {
- assert(llvm::is_contained(Attrs, attr) &&
- "Can't take attribute from a pool that doesn't own it!");
- Attrs.erase(llvm::find(Attrs, attr));
- }
- void takePool(AttributePool &pool);
- public:
- /// Create a new pool for a factory.
- AttributePool(AttributeFactory &factory) : Factory(factory) {}
- AttributePool(const AttributePool &) = delete;
- ~AttributePool() { Factory.reclaimPool(*this); }
- /// Move the given pool's allocations to this pool.
- AttributePool(AttributePool &&pool) = default;
- AttributeFactory &getFactory() const { return Factory; }
- void clear() {
- Factory.reclaimPool(*this);
- Attrs.clear();
- }
- /// Take the given pool's allocations and add them to this pool.
- void takeAllFrom(AttributePool &pool) {
- takePool(pool);
- pool.Attrs.clear();
- }
- ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- ArgsUnion *args, unsigned numArgs,
- ParsedAttr::Syntax syntax,
- SourceLocation ellipsisLoc = SourceLocation()) {
- size_t temp =
- ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
- detail::TypeTagForDatatypeData, ParsedType,
- detail::PropertyData>(numArgs, 0, 0, 0, 0);
- (void)temp;
- void *memory = allocate(
- ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
- detail::TypeTagForDatatypeData, ParsedType,
- detail::PropertyData>(numArgs, 0, 0, 0,
- 0));
- return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
- args, numArgs, syntax, ellipsisLoc));
- }
- ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierLoc *Param, const AvailabilityChange &introduced,
- const AvailabilityChange &deprecated,
- const AvailabilityChange &obsoleted,
- SourceLocation unavailable, const Expr *MessageExpr,
- ParsedAttr::Syntax syntax, SourceLocation strict,
- const Expr *ReplacementExpr) {
- void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
- return add(new (memory) ParsedAttr(
- attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated,
- obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr));
- }
- ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierLoc *Param1, IdentifierLoc *Param2,
- IdentifierLoc *Param3, ParsedAttr::Syntax syntax) {
- void *memory = allocate(
- ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
- detail::TypeTagForDatatypeData, ParsedType,
- detail::PropertyData>(3, 0, 0, 0, 0));
- return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
- Param1, Param2, Param3, syntax));
- }
- ParsedAttr *
- createTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierLoc *argumentKind,
- ParsedType matchingCType, bool layoutCompatible,
- bool mustBeNull, ParsedAttr::Syntax syntax) {
- void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
- return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
- argumentKind, matchingCType,
- layoutCompatible, mustBeNull, syntax));
- }
- ParsedAttr *createTypeAttribute(IdentifierInfo *attrName,
- SourceRange attrRange,
- IdentifierInfo *scopeName,
- SourceLocation scopeLoc, ParsedType typeArg,
- ParsedAttr::Syntax syntaxUsed) {
- void *memory = allocate(
- ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
- detail::TypeTagForDatatypeData, ParsedType,
- detail::PropertyData>(0, 0, 0, 1, 0));
- return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
- typeArg, syntaxUsed));
- }
- ParsedAttr *
- createPropertyAttribute(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierInfo *getterId, IdentifierInfo *setterId,
- ParsedAttr::Syntax syntaxUsed) {
- void *memory = allocate(AttributeFactory::PropertyAllocSize);
- return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
- getterId, setterId, syntaxUsed));
- }
- };
- class ParsedAttributesView {
- using VecTy = llvm::SmallVector<ParsedAttr *>;
- using SizeType = decltype(std::declval<VecTy>().size());
- public:
- SourceRange Range;
- static const ParsedAttributesView &none() {
- static const ParsedAttributesView Attrs;
- return Attrs;
- }
- bool empty() const { return AttrList.empty(); }
- SizeType size() const { return AttrList.size(); }
- ParsedAttr &operator[](SizeType pos) { return *AttrList[pos]; }
- const ParsedAttr &operator[](SizeType pos) const { return *AttrList[pos]; }
- void addAtEnd(ParsedAttr *newAttr) {
- assert(newAttr);
- AttrList.push_back(newAttr);
- }
- void remove(ParsedAttr *ToBeRemoved) {
- assert(is_contained(AttrList, ToBeRemoved) &&
- "Cannot remove attribute that isn't in the list");
- AttrList.erase(llvm::find(AttrList, ToBeRemoved));
- }
- void clearListOnly() { AttrList.clear(); }
- struct iterator : llvm::iterator_adaptor_base<iterator, VecTy::iterator,
- std::random_access_iterator_tag,
- ParsedAttr> {
- iterator() : iterator_adaptor_base(nullptr) {}
- iterator(VecTy::iterator I) : iterator_adaptor_base(I) {}
- reference operator*() const { return **I; }
- friend class ParsedAttributesView;
- };
- struct const_iterator
- : llvm::iterator_adaptor_base<const_iterator, VecTy::const_iterator,
- std::random_access_iterator_tag,
- ParsedAttr> {
- const_iterator() : iterator_adaptor_base(nullptr) {}
- const_iterator(VecTy::const_iterator I) : iterator_adaptor_base(I) {}
- reference operator*() const { return **I; }
- friend class ParsedAttributesView;
- };
- void addAll(iterator B, iterator E) {
- AttrList.insert(AttrList.begin(), B.I, E.I);
- }
- void addAll(const_iterator B, const_iterator E) {
- AttrList.insert(AttrList.begin(), B.I, E.I);
- }
- void addAllAtEnd(iterator B, iterator E) {
- AttrList.insert(AttrList.end(), B.I, E.I);
- }
- void addAllAtEnd(const_iterator B, const_iterator E) {
- AttrList.insert(AttrList.end(), B.I, E.I);
- }
- iterator begin() { return iterator(AttrList.begin()); }
- const_iterator begin() const { return const_iterator(AttrList.begin()); }
- iterator end() { return iterator(AttrList.end()); }
- const_iterator end() const { return const_iterator(AttrList.end()); }
- ParsedAttr &front() {
- assert(!empty());
- return *AttrList.front();
- }
- const ParsedAttr &front() const {
- assert(!empty());
- return *AttrList.front();
- }
- ParsedAttr &back() {
- assert(!empty());
- return *AttrList.back();
- }
- const ParsedAttr &back() const {
- assert(!empty());
- return *AttrList.back();
- }
- bool hasAttribute(ParsedAttr::Kind K) const {
- return llvm::any_of(AttrList, [K](const ParsedAttr *AL) {
- return AL->getParsedKind() == K;
- });
- }
- private:
- VecTy AttrList;
- };
- /// ParsedAttributes - A collection of parsed attributes. Currently
- /// we don't differentiate between the various attribute syntaxes,
- /// which is basically silly.
- ///
- /// Right now this is a very lightweight container, but the expectation
- /// is that this will become significantly more serious.
- class ParsedAttributes : public ParsedAttributesView {
- public:
- ParsedAttributes(AttributeFactory &factory) : pool(factory) {}
- ParsedAttributes(const ParsedAttributes &) = delete;
- AttributePool &getPool() const { return pool; }
- void takeAllFrom(ParsedAttributes &Other) {
- assert(&Other != this &&
- "ParsedAttributes can't take attributes from itself");
- addAll(Other.begin(), Other.end());
- Other.clearListOnly();
- pool.takeAllFrom(Other.pool);
- }
- void takeOneFrom(ParsedAttributes &Other, ParsedAttr *PA) {
- assert(&Other != this &&
- "ParsedAttributes can't take attribute from itself");
- Other.getPool().remove(PA);
- Other.remove(PA);
- getPool().add(PA);
- addAtEnd(PA);
- }
- void clear() {
- clearListOnly();
- pool.clear();
- Range = SourceRange();
- }
- /// Add attribute with expression arguments.
- ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- ArgsUnion *args, unsigned numArgs,
- ParsedAttr::Syntax syntax,
- SourceLocation ellipsisLoc = SourceLocation()) {
- ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
- args, numArgs, syntax, ellipsisLoc);
- addAtEnd(attr);
- return attr;
- }
- /// Add availability attribute.
- ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierLoc *Param, const AvailabilityChange &introduced,
- const AvailabilityChange &deprecated,
- const AvailabilityChange &obsoleted,
- SourceLocation unavailable, const Expr *MessageExpr,
- ParsedAttr::Syntax syntax, SourceLocation strict,
- const Expr *ReplacementExpr) {
- ParsedAttr *attr = pool.create(
- attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated,
- obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr);
- addAtEnd(attr);
- return attr;
- }
- /// Add objc_bridge_related attribute.
- ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierLoc *Param1, IdentifierLoc *Param2,
- IdentifierLoc *Param3, ParsedAttr::Syntax syntax) {
- ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
- Param1, Param2, Param3, syntax);
- addAtEnd(attr);
- return attr;
- }
- /// Add type_tag_for_datatype attribute.
- ParsedAttr *
- addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierLoc *argumentKind,
- ParsedType matchingCType, bool layoutCompatible,
- bool mustBeNull, ParsedAttr::Syntax syntax) {
- ParsedAttr *attr = pool.createTypeTagForDatatype(
- attrName, attrRange, scopeName, scopeLoc, argumentKind, matchingCType,
- layoutCompatible, mustBeNull, syntax);
- addAtEnd(attr);
- return attr;
- }
- /// Add an attribute with a single type argument.
- ParsedAttr *addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- ParsedType typeArg,
- ParsedAttr::Syntax syntaxUsed) {
- ParsedAttr *attr = pool.createTypeAttribute(attrName, attrRange, scopeName,
- scopeLoc, typeArg, syntaxUsed);
- addAtEnd(attr);
- return attr;
- }
- /// Add microsoft __delspec(property) attribute.
- ParsedAttr *
- addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange,
- IdentifierInfo *scopeName, SourceLocation scopeLoc,
- IdentifierInfo *getterId, IdentifierInfo *setterId,
- ParsedAttr::Syntax syntaxUsed) {
- ParsedAttr *attr =
- pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
- getterId, setterId, syntaxUsed);
- addAtEnd(attr);
- return attr;
- }
- private:
- mutable AttributePool pool;
- };
- /// Consumes the attributes from `First` and `Second` and concatenates them into
- /// `Result`. Sets `Result.Range` to the combined range of `First` and `Second`.
- void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &Second,
- ParsedAttributes &Result);
- /// These constants match the enumerated choices of
- /// err_attribute_argument_n_type and err_attribute_argument_type.
- enum AttributeArgumentNType {
- AANT_ArgumentIntOrBool,
- AANT_ArgumentIntegerConstant,
- AANT_ArgumentString,
- AANT_ArgumentIdentifier,
- AANT_ArgumentConstantExpr,
- AANT_ArgumentBuiltinFunction,
- };
- /// These constants match the enumerated choices of
- /// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
- enum AttributeDeclKind {
- ExpectedFunction,
- ExpectedUnion,
- ExpectedVariableOrFunction,
- ExpectedFunctionOrMethod,
- ExpectedFunctionMethodOrBlock,
- ExpectedFunctionMethodOrParameter,
- ExpectedVariable,
- ExpectedVariableOrField,
- ExpectedVariableFieldOrTag,
- ExpectedTypeOrNamespace,
- ExpectedFunctionVariableOrClass,
- ExpectedKernelFunction,
- ExpectedFunctionWithProtoType,
- };
- inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
- const ParsedAttr &At) {
- DB.AddTaggedVal(reinterpret_cast<uint64_t>(At.getAttrName()),
- DiagnosticsEngine::ak_identifierinfo);
- return DB;
- }
- inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
- const ParsedAttr *At) {
- DB.AddTaggedVal(reinterpret_cast<uint64_t>(At->getAttrName()),
- DiagnosticsEngine::ak_identifierinfo);
- return DB;
- }
- /// AttributeCommonInfo has a non-explicit constructor which takes an
- /// SourceRange as its only argument, this constructor has many uses so making
- /// it explicit is hard. This constructor causes ambiguity with
- /// DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, SourceRange R).
- /// We use SFINAE to disable any conversion and remove any ambiguity.
- template <
- typename ACI,
- std::enable_if_t<std::is_same<ACI, AttributeCommonInfo>::value, int> = 0>
- inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
- const ACI &CI) {
- DB.AddTaggedVal(reinterpret_cast<uint64_t>(CI.getAttrName()),
- DiagnosticsEngine::ak_identifierinfo);
- return DB;
- }
- template <
- typename ACI,
- std::enable_if_t<std::is_same<ACI, AttributeCommonInfo>::value, int> = 0>
- inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
- const ACI *CI) {
- DB.AddTaggedVal(reinterpret_cast<uint64_t>(CI->getAttrName()),
- DiagnosticsEngine::ak_identifierinfo);
- return DB;
- }
- } // namespace clang
- #endif // LLVM_CLANG_SEMA_PARSEDATTR_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|