1//===- ParsedAttrInfo.h - Info needed to parse an attribute -----*- 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 ParsedAttrInfo class, which dictates how to
10// parse an attribute. This class is the one that plugins derive to
11// define a new attribute.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_BASIC_PARSEDATTRINFO_H
16#define LLVM_CLANG_BASIC_PARSEDATTRINFO_H
17
18#include "clang/Basic/AttrSubjectMatchRules.h"
19#include "clang/Basic/AttributeCommonInfo.h"
20#include "llvm/ADT/ArrayRef.h"
21#include "llvm/Support/Registry.h"
22#include <climits>
23#include <list>
24
25namespace clang {
26
27class Decl;
28class LangOptions;
29class ParsedAttr;
30class Sema;
31class Stmt;
32class TargetInfo;
33
34struct ParsedAttrInfo {
35 /// Corresponds to the Kind enum.
36 LLVM_PREFERRED_TYPE(AttributeCommonInfo::Kind)
37 unsigned AttrKind : 16;
38 /// The number of required arguments of this attribute.
39 unsigned NumArgs : 4;
40 /// The number of optional arguments of this attributes.
41 unsigned OptArgs : 4;
42 /// The number of non-fake arguments specified in the attribute definition.
43 unsigned NumArgMembers : 4;
44 /// True if the parsing does not match the semantic content.
45 LLVM_PREFERRED_TYPE(bool)
46 unsigned HasCustomParsing : 1;
47 // True if this attribute accepts expression parameter pack expansions.
48 LLVM_PREFERRED_TYPE(bool)
49 unsigned AcceptsExprPack : 1;
50 /// True if this attribute is only available for certain targets.
51 LLVM_PREFERRED_TYPE(bool)
52 unsigned IsTargetSpecific : 1;
53 /// True if this attribute applies to types.
54 LLVM_PREFERRED_TYPE(bool)
55 unsigned IsType : 1;
56 /// True if this attribute applies to statements.
57 LLVM_PREFERRED_TYPE(bool)
58 unsigned IsStmt : 1;
59 /// True if this attribute has any spellings that are known to gcc.
60 LLVM_PREFERRED_TYPE(bool)
61 unsigned IsKnownToGCC : 1;
62 /// True if this attribute is supported by #pragma clang attribute.
63 LLVM_PREFERRED_TYPE(bool)
64 unsigned IsSupportedByPragmaAttribute : 1;
65 /// The syntaxes supported by this attribute and how they're spelled.
66 struct Spelling {
67 AttributeCommonInfo::Syntax Syntax;
68 const char *NormalizedFullName;
69 };
70 ArrayRef<Spelling> Spellings;
71 // The names of the known arguments of this attribute.
72 ArrayRef<const char *> ArgNames;
73
74protected:
75 constexpr ParsedAttrInfo(AttributeCommonInfo::Kind AttrKind =
76 AttributeCommonInfo::NoSemaHandlerAttribute)
77 : AttrKind(AttrKind), NumArgs(0), OptArgs(0), NumArgMembers(0),
78 HasCustomParsing(0), AcceptsExprPack(0), IsTargetSpecific(0), IsType(0),
79 IsStmt(0), IsKnownToGCC(0), IsSupportedByPragmaAttribute(0) {}
80
81 constexpr ParsedAttrInfo(AttributeCommonInfo::Kind AttrKind, unsigned NumArgs,
82 unsigned OptArgs, unsigned NumArgMembers,
83 unsigned HasCustomParsing, unsigned AcceptsExprPack,
84 unsigned IsTargetSpecific, unsigned IsType,
85 unsigned IsStmt, unsigned IsKnownToGCC,
86 unsigned IsSupportedByPragmaAttribute,
87 ArrayRef<Spelling> Spellings,
88 ArrayRef<const char *> ArgNames)
89 : AttrKind(AttrKind), NumArgs(NumArgs), OptArgs(OptArgs),
90 NumArgMembers(NumArgMembers), HasCustomParsing(HasCustomParsing),
91 AcceptsExprPack(AcceptsExprPack), IsTargetSpecific(IsTargetSpecific),
92 IsType(IsType), IsStmt(IsStmt), IsKnownToGCC(IsKnownToGCC),
93 IsSupportedByPragmaAttribute(IsSupportedByPragmaAttribute),
94 Spellings(Spellings), ArgNames(ArgNames) {}
95
96public:
97 virtual ~ParsedAttrInfo() = default;
98
99 /// Check if this attribute has specified spelling.
100 bool hasSpelling(AttributeCommonInfo::Syntax Syntax, StringRef Name) const {
101 return llvm::any_of(Range: Spellings, P: [&](const Spelling &S) {
102 return (S.Syntax == Syntax && S.NormalizedFullName == Name);
103 });
104 }
105
106 /// Check if this attribute appertains to D, and issue a diagnostic if not.
107 virtual bool diagAppertainsToDecl(Sema &S, const ParsedAttr &Attr,
108 const Decl *D) const {
109 return true;
110 }
111 /// Check if this attribute appertains to St, and issue a diagnostic if not.
112 virtual bool diagAppertainsToStmt(Sema &S, const ParsedAttr &Attr,
113 const Stmt *St) const {
114 return true;
115 }
116 /// Check if the given attribute is mutually exclusive with other attributes
117 /// already applied to the given declaration.
118 virtual bool diagMutualExclusion(Sema &S, const ParsedAttr &A,
119 const Decl *D) const {
120 return true;
121 }
122 /// Check if this attribute is allowed by the language we are compiling.
123 virtual bool acceptsLangOpts(const LangOptions &LO) const { return true; }
124
125 /// Check if this attribute is allowed when compiling for the given target.
126 virtual bool existsInTarget(const TargetInfo &Target) const { return true; }
127
128 /// Check if this attribute's spelling is allowed when compiling for the given
129 /// target.
130 virtual bool spellingExistsInTarget(const TargetInfo &Target,
131 const unsigned SpellingListIndex) const {
132 return true;
133 }
134
135 /// Convert the spelling index of Attr to a semantic spelling enum value.
136 virtual unsigned
137 spellingIndexToSemanticSpelling(const ParsedAttr &Attr) const {
138 return UINT_MAX;
139 }
140 /// Returns true if the specified parameter index for this attribute in
141 /// Attr.td is an ExprArgument or VariadicExprArgument, or a subclass thereof;
142 /// returns false otherwise.
143 virtual bool isParamExpr(size_t N) const { return false; }
144 /// Populate Rules with the match rules of this attribute.
145 virtual void getPragmaAttributeMatchRules(
146 llvm::SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &Rules,
147 const LangOptions &LangOpts) const {}
148
149 enum AttrHandling { NotHandled, AttributeApplied, AttributeNotApplied };
150 /// If this ParsedAttrInfo knows how to handle this ParsedAttr applied to this
151 /// Decl then do so and return either AttributeApplied if it was applied or
152 /// AttributeNotApplied if it wasn't. Otherwise return NotHandled.
153 virtual AttrHandling handleDeclAttribute(Sema &S, Decl *D,
154 const ParsedAttr &Attr) const {
155 return NotHandled;
156 }
157
158 static const ParsedAttrInfo &get(const AttributeCommonInfo &A);
159 static ArrayRef<const ParsedAttrInfo *> getAllBuiltin();
160};
161
162typedef llvm::Registry<ParsedAttrInfo> ParsedAttrInfoRegistry;
163
164const std::list<std::unique_ptr<ParsedAttrInfo>> &getAttributePluginInstances();
165
166} // namespace clang
167
168#endif // LLVM_CLANG_BASIC_PARSEDATTRINFO_H
169

source code of clang/include/clang/Basic/ParsedAttrInfo.h