diff --git a/clang/include/clang/Basic/ParsedAttrInfo.h b/clang/include/clang/Basic/ParsedAttrInfo.h new file mode 100644 --- /dev/null +++ b/clang/include/clang/Basic/ParsedAttrInfo.h @@ -0,0 +1,142 @@ +//===- ParsedAttrInfo.h - Info needed to parse an attribute -----*- 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 ParsedAttrInfo class, which dictates how to +// parse an attribute. This class is the one that plugins derive to +// define a new attribute. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_PARSEDATTRINFO_H +#define LLVM_CLANG_BASIC_PARSEDATTRINFO_H + +#include "clang/Basic/AttrSubjectMatchRules.h" +#include "clang/Basic/AttributeCommonInfo.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/Registry.h" +#include + +namespace clang { + +class Decl; +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 Spellings; + // The names of the known arguments of this attribute. + ArrayRef 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 Spellings, + ArrayRef 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> &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 getAllBuiltin(); +}; + +typedef llvm::Registry ParsedAttrInfoRegistry; + +} // namespace clang + +#endif // LLVM_CLANG_BASIC_PARSEDATTRINFO_H diff --git a/clang/include/clang/Sema/ParsedAttr.h b/clang/include/clang/Sema/ParsedAttr.h --- a/clang/include/clang/Sema/ParsedAttr.h +++ b/clang/include/clang/Sema/ParsedAttr.h @@ -17,12 +17,12 @@ #include "clang/Basic/AttrSubjectMatchRules.h" #include "clang/Basic/AttributeCommonInfo.h" #include "clang/Basic/Diagnostic.h" +#include "clang/Basic/ParsedAttrInfo.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 #include @@ -36,124 +36,10 @@ 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 Spellings; - // The names of the known arguments of this attribute. - ArrayRef 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 Spellings, - ArrayRef 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> &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 getAllBuiltin(); -}; - -typedef llvm::Registry ParsedAttrInfoRegistry; - /// Represents information about a change in availability for /// an entity, which is part of the encoding of the 'availability' /// attribute. diff --git a/clang/lib/Basic/CMakeLists.txt b/clang/lib/Basic/CMakeLists.txt --- a/clang/lib/Basic/CMakeLists.txt +++ b/clang/lib/Basic/CMakeLists.txt @@ -61,6 +61,7 @@ OpenCLOptions.cpp OpenMPKinds.cpp OperatorPrecedence.cpp + ParsedAttrInfo.cpp ProfileList.cpp NoSanitizeList.cpp SanitizerSpecialCaseList.cpp diff --git a/clang/lib/Basic/ParsedAttrInfo.cpp b/clang/lib/Basic/ParsedAttrInfo.cpp new file mode 100644 --- /dev/null +++ b/clang/lib/Basic/ParsedAttrInfo.cpp @@ -0,0 +1,18 @@ +//===- ParsedAttrInfo.cpp - Registry for attribute plugins ------*- 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 contains the Registry of attributes added by plugins which +// derive the ParsedAttrInfo class. +// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/ParsedAttrInfo.h" + +using namespace clang; + +LLVM_INSTANTIATE_REGISTRY(ParsedAttrInfoRegistry) diff --git a/clang/lib/Sema/ParsedAttr.cpp b/clang/lib/Sema/ParsedAttr.cpp --- a/clang/lib/Sema/ParsedAttr.cpp +++ b/clang/lib/Sema/ParsedAttr.cpp @@ -26,8 +26,6 @@ using namespace clang; -LLVM_INSTANTIATE_REGISTRY(ParsedAttrInfoRegistry) - IdentifierLoc *IdentifierLoc::create(ASTContext &Ctx, SourceLocation Loc, IdentifierInfo *Ident) { IdentifierLoc *Result = new (Ctx) IdentifierLoc;