aboutsummaryrefslogtreecommitdiff
path: root/clang/include/clang/Sema/ParsedAttr.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang/include/clang/Sema/ParsedAttr.h')
-rw-r--r--clang/include/clang/Sema/ParsedAttr.h102
1 files changed, 94 insertions, 8 deletions
diff --git a/clang/include/clang/Sema/ParsedAttr.h b/clang/include/clang/Sema/ParsedAttr.h
index d9d8585970d9..21e030fe5134 100644
--- a/clang/include/clang/Sema/ParsedAttr.h
+++ b/clang/include/clang/Sema/ParsedAttr.h
@@ -18,12 +18,12 @@
#include "clang/Basic/AttributeCommonInfo.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceLocation.h"
-#include "clang/Basic/TargetInfo.h"
#include "clang/Sema/Ownership.h"
#include "llvm/ADT/PointerUnion.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Registry.h"
#include "llvm/Support/VersionTuple.h"
#include <cassert>
#include <cstddef>
@@ -37,6 +37,85 @@ class Decl;
class Expr;
class IdentifierInfo;
class LangOptions;
+class ParsedAttr;
+class Sema;
+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;
+ /// True if the parsing does not match the semantic content.
+ unsigned HasCustomParsing : 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;
+
+ ParsedAttrInfo(AttributeCommonInfo::Kind AttrKind =
+ AttributeCommonInfo::NoSemaHandlerAttribute)
+ : AttrKind(AttrKind), NumArgs(0), OptArgs(0), HasCustomParsing(0),
+ IsTargetSpecific(0), IsType(0), IsStmt(0), IsKnownToGCC(0),
+ IsSupportedByPragmaAttribute(0) {}
+
+ 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 is allowed by the language we are compiling, and
+ /// issue a diagnostic if not.
+ virtual bool diagLangOpts(Sema &S, const ParsedAttr &Attr) 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;
+ }
+ /// 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);
+};
+
+typedef llvm::Registry<ParsedAttrInfo> ParsedAttrInfoRegistry;
/// Represents information about a change in availability for
/// an entity, which is part of the encoding of the 'availability'
@@ -181,6 +260,8 @@ private:
const Expr *MessageExpr;
+ const ParsedAttrInfo &Info;
+
ArgsUnion *getArgsBuffer() { return getTrailingObjects<ArgsUnion>(); }
ArgsUnion const *getArgsBuffer() const {
return getTrailingObjects<ArgsUnion>();
@@ -207,7 +288,8 @@ private:
EllipsisLoc(ellipsisLoc), NumArgs(numArgs), Invalid(false),
UsedAsTypeAttr(false), IsAvailability(false),
IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
- HasProcessingCache(false), IsPragmaClangAttribute(false) {
+ HasProcessingCache(false), IsPragmaClangAttribute(false),
+ Info(ParsedAttrInfo::get(*this)) {
if (numArgs)
memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion));
}
@@ -225,7 +307,8 @@ private:
NumArgs(1), Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
HasProcessingCache(false), IsPragmaClangAttribute(false),
- UnavailableLoc(unavailable), MessageExpr(messageExpr) {
+ UnavailableLoc(unavailable), MessageExpr(messageExpr),
+ Info(ParsedAttrInfo::get(*this)) {
ArgsUnion PVal(Parm);
memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
new (getAvailabilityData()) detail::AvailabilityData(
@@ -242,7 +325,7 @@ private:
NumArgs(3), Invalid(false), UsedAsTypeAttr(false),
IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
HasParsedType(false), HasProcessingCache(false),
- IsPragmaClangAttribute(false) {
+ IsPragmaClangAttribute(false), Info(ParsedAttrInfo::get(*this)) {
ArgsUnion *Args = getArgsBuffer();
Args[0] = Parm1;
Args[1] = Parm2;
@@ -259,7 +342,7 @@ private:
NumArgs(1), Invalid(false), UsedAsTypeAttr(false),
IsAvailability(false), IsTypeTagForDatatype(true), IsProperty(false),
HasParsedType(false), HasProcessingCache(false),
- IsPragmaClangAttribute(false) {
+ IsPragmaClangAttribute(false), Info(ParsedAttrInfo::get(*this)) {
ArgsUnion PVal(ArgKind);
memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
detail::TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
@@ -277,7 +360,7 @@ private:
NumArgs(0), Invalid(false), UsedAsTypeAttr(false),
IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
HasParsedType(true), HasProcessingCache(false),
- IsPragmaClangAttribute(false) {
+ IsPragmaClangAttribute(false), Info(ParsedAttrInfo::get(*this)) {
new (&getTypeBuffer()) ParsedType(typeArg);
}
@@ -291,7 +374,7 @@ private:
NumArgs(0), Invalid(false), UsedAsTypeAttr(false),
IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(true),
HasParsedType(false), HasProcessingCache(false),
- IsPragmaClangAttribute(false) {
+ IsPragmaClangAttribute(false), Info(ParsedAttrInfo::get(*this)) {
new (&getPropertyDataBuffer()) detail::PropertyData(getterId, setterId);
}
@@ -534,7 +617,10 @@ public:
}
}
- AttributeCommonInfo::Kind getKind() const { return getParsedKind(); }
+ AttributeCommonInfo::Kind getKind() const {
+ return AttributeCommonInfo::Kind(Info.AttrKind);
+ }
+ const ParsedAttrInfo &getInfo() const { return Info; }
};
class AttributePool;