clang 20.0.0git
ParsedAttr.cpp
Go to the documentation of this file.
1//======- ParsedAttr.cpp --------------------------------------------------===//
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 implementation
10//
11//===----------------------------------------------------------------------===//
12
19#include "llvm/ADT/SmallVector.h"
20#include <cassert>
21#include <cstddef>
22#include <utility>
23
24using namespace clang;
25
27 IdentifierInfo *Ident) {
29 Result->Loc = Loc;
30 Result->Ident = Ident;
31 return Result;
32}
33
34size_t ParsedAttr::allocated_size() const {
35 if (IsAvailability) return AttributeFactory::AvailabilityAllocSize;
36 else if (IsTypeTagForDatatype)
38 else if (IsProperty)
40 else if (HasParsedType)
41 return totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
43 detail::PropertyData>(0, 0, 0, 1, 0);
44 return totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
46 detail::PropertyData>(NumArgs, 0, 0, 0, 0);
47}
48
50 // Go ahead and configure all the inline capacity. This is just a memset.
51 FreeLists.resize(InlineFreeListsCapacity);
52}
54
55static size_t getFreeListIndexForSize(size_t size) {
56 assert(size >= sizeof(ParsedAttr));
57 assert((size % sizeof(void*)) == 0);
58 return ((size - sizeof(ParsedAttr)) / sizeof(void *));
59}
60
61void *AttributeFactory::allocate(size_t size) {
62 // Check for a previously reclaimed attribute.
63 size_t index = getFreeListIndexForSize(size);
64 if (index < FreeLists.size() && !FreeLists[index].empty()) {
65 ParsedAttr *attr = FreeLists[index].back();
66 FreeLists[index].pop_back();
67 return attr;
68 }
69
70 // Otherwise, allocate something new.
71 return Alloc.Allocate(size, alignof(AttributeFactory));
72}
73
74void AttributeFactory::deallocate(ParsedAttr *Attr) {
75 size_t size = Attr->allocated_size();
76 size_t freeListIndex = getFreeListIndexForSize(size);
77
78 // Expand FreeLists to the appropriate size, if required.
79 if (freeListIndex >= FreeLists.size())
80 FreeLists.resize(freeListIndex + 1);
81
82#ifndef NDEBUG
83 // In debug mode, zero out the attribute to help find memory overwriting.
84 memset(Attr, 0, size);
85#endif
86
87 // Add 'Attr' to the appropriate free-list.
88 FreeLists[freeListIndex].push_back(Attr);
89}
90
91void AttributeFactory::reclaimPool(AttributePool &cur) {
92 for (ParsedAttr *AL : cur.Attrs)
93 deallocate(AL);
94}
95
96void AttributePool::takePool(AttributePool &pool) {
97 Attrs.insert(Attrs.end(), pool.Attrs.begin(), pool.Attrs.end());
98 pool.Attrs.clear();
99}
100
102 assert(&Pool != this && "AttributePool can't take attributes from itself");
103 llvm::for_each(List.AttrList, [&Pool](ParsedAttr *A) { Pool.remove(A); });
104 Attrs.insert(Attrs.end(), List.AttrList.begin(), List.AttrList.end());
105}
106
107namespace {
108
109#include "clang/Sema/AttrParsedAttrImpl.inc"
110
111} // namespace
112
114 // If we have a ParsedAttrInfo for this ParsedAttr then return that.
115 if ((size_t)A.getParsedKind() < std::size(AttrInfoMap))
116 return *AttrInfoMap[A.getParsedKind()];
117
118 // If this is an ignored attribute then return an appropriate ParsedAttrInfo.
119 static const ParsedAttrInfo IgnoredParsedAttrInfo(
122 return IgnoredParsedAttrInfo;
123
124 // Otherwise this may be an attribute defined by a plugin.
125
126 // Search for a ParsedAttrInfo whose name and syntax match.
127 std::string FullName = A.getNormalizedFullName();
128 AttributeCommonInfo::Syntax SyntaxUsed = A.getSyntax();
131
132 for (auto &Ptr : getAttributePluginInstances())
133 if (Ptr->hasSpelling(SyntaxUsed, FullName))
134 return *Ptr;
135
136 // If we failed to find a match then return a default ParsedAttrInfo.
137 static const ParsedAttrInfo DefaultParsedAttrInfo(
139 return DefaultParsedAttrInfo;
140}
141
143 return llvm::ArrayRef(AttrInfoMap);
144}
145
146unsigned ParsedAttr::getMinArgs() const { return getInfo().NumArgs; }
147
148unsigned ParsedAttr::getMaxArgs() const {
149 return getMinArgs() + getInfo().OptArgs;
150}
151
153 return getInfo().NumArgMembers;
154}
155
157 return getInfo().HasCustomParsing;
158}
159
161 return getInfo().diagAppertainsToDecl(S, *this, D);
162}
163
164bool ParsedAttr::diagnoseAppertainsTo(Sema &S, const Stmt *St) const {
165 return getInfo().diagAppertainsToStmt(S, *this, St);
166}
167
169 return getInfo().diagMutualExclusion(S, *this, D);
170}
171
173 attr::SubjectMatchRule MatchRule) const {
174 return checkAttributeMatchRuleAppliesTo(D, MatchRule);
175}
176
178 const LangOptions &LangOpts,
179 SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &MatchRules)
180 const {
181 return getInfo().getPragmaAttributeMatchRules(MatchRules, LangOpts);
182}
183
185 if (getInfo().acceptsLangOpts(S.getLangOpts()))
186 return true;
187 S.Diag(getLoc(), diag::warn_attribute_ignored) << *this;
188 return false;
189}
190
192 return getInfo().IsTargetSpecific;
193}
194
195bool ParsedAttr::isTypeAttr() const { return getInfo().IsType; }
196
197bool ParsedAttr::isStmtAttr() const { return getInfo().IsStmt; }
198
200 Kind K = getParsedKind();
201
202 // If the attribute has a target-specific spelling, check that it exists.
203 // Only call this if the attr is not ignored/unknown. For most targets, this
204 // function just returns true.
205 bool HasSpelling = K != IgnoredAttribute && K != UnknownAttribute &&
207 bool TargetSpecificSpellingExists =
208 !HasSpelling ||
210
211 return getInfo().existsInTarget(Target) && TargetSpecificSpellingExists;
212}
213
215
218}
219
222 // The appurtenance rules are applied strictly for all regular keyword
223 // atributes.
224 return false;
225
227
228 // We have historically allowed some type attributes with standard attribute
229 // syntax to slide to the decl-specifier-seq, so we have to keep supporting
230 // it. This property is consciously not defined as a flag in Attr.td because
231 // we don't want new attributes to specify it.
232 //
233 // Note: No new entries should be added to this list. Entries should be
234 // removed from this list after a suitable deprecation period, provided that
235 // there are no compatibility considerations with other compilers. If
236 // possible, we would like this list to go away entirely.
237 switch (getParsedKind()) {
238 case AT_AddressSpace:
239 case AT_OpenCLPrivateAddressSpace:
240 case AT_OpenCLGlobalAddressSpace:
241 case AT_OpenCLGlobalDeviceAddressSpace:
242 case AT_OpenCLGlobalHostAddressSpace:
243 case AT_OpenCLLocalAddressSpace:
244 case AT_OpenCLConstantAddressSpace:
245 case AT_OpenCLGenericAddressSpace:
246 case AT_NeonPolyVectorType:
247 case AT_NeonVectorType:
248 case AT_ArmMveStrictPolymorphism:
249 case AT_BTFTypeTag:
250 case AT_ObjCGC:
251 case AT_MatrixType:
252 return true;
253 default:
254 return false;
255 }
256}
257
259
262}
263
265 // If the attribute has the maximum number of optional arguments, we will
266 // claim that as being variadic. If we someday get an attribute that
267 // legitimately bumps up against that maximum, we can use another bit to track
268 // whether it's truly variadic or not.
269 return getInfo().OptArgs == 15;
270}
271
272bool ParsedAttr::isParamExpr(size_t N) const {
273 return getInfo().isParamExpr(N);
274}
275
278}
279
280static unsigned getNumAttributeArgs(const ParsedAttr &AL) {
281 // FIXME: Include the type in the argument list.
282 return AL.getNumArgs() + AL.hasParsedType();
283}
284
285template <typename Compare>
286static bool checkAttributeNumArgsImpl(Sema &S, const ParsedAttr &AL,
287 unsigned Num, unsigned Diag,
288 Compare Comp) {
289 if (Comp(getNumAttributeArgs(AL), Num)) {
290 S.Diag(AL.getLoc(), Diag) << AL << Num;
291 return false;
292 }
293 return true;
294}
295
296bool ParsedAttr::checkExactlyNumArgs(Sema &S, unsigned Num) const {
297 return checkAttributeNumArgsImpl(S, *this, Num,
298 diag::err_attribute_wrong_number_arguments,
299 std::not_equal_to<unsigned>());
300}
301bool ParsedAttr::checkAtLeastNumArgs(Sema &S, unsigned Num) const {
302 return checkAttributeNumArgsImpl(S, *this, Num,
303 diag::err_attribute_too_few_arguments,
304 std::less<unsigned>());
305}
306bool ParsedAttr::checkAtMostNumArgs(Sema &S, unsigned Num) const {
307 return checkAttributeNumArgsImpl(S, *this, Num,
308 diag::err_attribute_too_many_arguments,
309 std::greater<unsigned>());
310}
311
313 ParsedAttributes &Second,
315 // Note that takeAllFrom() puts the attributes at the beginning of the list,
316 // so to obtain the correct ordering, we add `Second`, then `First`.
317 Result.takeAllFrom(Second);
318 Result.takeAllFrom(First);
319 if (First.Range.getBegin().isValid())
320 Result.Range.setBegin(First.Range.getBegin());
321 else
322 Result.Range.setBegin(Second.Range.getBegin());
323 if (Second.Range.getEnd().isValid())
324 Result.Range.setEnd(Second.Range.getEnd());
325 else
326 Result.Range.setEnd(First.Range.getEnd());
327}
Defines the clang::ASTContext interface.
const Decl * D
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
llvm::MachO::Target Target
Definition: MachO.h:51
static bool checkAttributeNumArgsImpl(Sema &S, const ParsedAttr &AL, unsigned Num, unsigned Diag, Compare Comp)
Definition: ParsedAttr.cpp:286
static size_t getFreeListIndexForSize(size_t size)
Definition: ParsedAttr.cpp:55
static unsigned getNumAttributeArgs(const ParsedAttr &AL)
Definition: ParsedAttr.cpp:280
int32_t FullName
Definition: SemaARM.cpp:1135
SourceLocation Loc
Definition: SemaObjC.cpp:759
__DEVICE__ void * memset(void *__a, int __b, size_t __c)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
Attr - This represents one attribute.
Definition: Attr.h:43
std::string getNormalizedFullName() const
Gets the normalized full name, which consists of both scope and name and with surrounding underscores...
Definition: Attributes.cpp:154
Syntax
The style used to specify an attribute.
@ AS_Keyword
__ptr16, alignas(...), etc.
@ AS_ContextSensitiveKeyword
Context-sensitive version of a keyword attribute.
unsigned getAttributeSpellingListIndex() const
SourceLocation getLoc() const
bool isStandardAttributeSyntax() const
The attribute is spelled [[]] in either C or C++ mode, including standard attributes spelled with a k...
A factory, from which one makes pools, from which one creates individual attributes which are dealloc...
Definition: ParsedAttr.h:637
void takeFrom(ParsedAttributesView &List, AttributePool &Pool)
Removes the attributes from List, which are owned by Pool, and adds them at the end of this Attribute...
Definition: ParsedAttr.cpp:101
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
One of these records is kept for each identifier that is lexed.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:499
ParsedAttr - Represents a syntactic attribute.
Definition: ParsedAttr.h:129
bool isTargetSpecificAttr() const
Definition: ParsedAttr.cpp:191
bool hasCustomParsing() const
Definition: ParsedAttr.cpp:156
unsigned getSemanticSpelling() const
If the parsed attribute has a semantic equivalent, and it would have a semantic Spelling enumeration ...
Definition: ParsedAttr.cpp:260
bool appliesToDecl(const Decl *D, attr::SubjectMatchRule MatchRule) const
Definition: ParsedAttr.cpp:172
bool isKnownToGCC() const
Definition: ParsedAttr.cpp:214
bool existsInTarget(const TargetInfo &Target) const
Definition: ParsedAttr.cpp:199
unsigned getMinArgs() const
Definition: ParsedAttr.cpp:146
bool checkExactlyNumArgs(class Sema &S, unsigned Num) const
Check if the attribute has exactly as many args as Num.
Definition: ParsedAttr.cpp:296
bool hasParsedType() const
Definition: ParsedAttr.h:352
bool hasVariadicArg() const
Definition: ParsedAttr.cpp:264
const ParsedAttrInfo & getInfo() const
Definition: ParsedAttr.h:628
void handleAttrWithDelayedArgs(Sema &S, Decl *D) const
Definition: ParsedAttr.cpp:276
bool diagnoseMutualExclusion(class Sema &S, const Decl *D) const
Definition: ParsedAttr.cpp:168
bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const
Definition: ParsedAttr.cpp:160
bool acceptsExprPack() const
Definition: ParsedAttr.cpp:258
bool isTypeAttr() const
Definition: ParsedAttr.cpp:195
bool isSupportedByPragmaAttribute() const
Definition: ParsedAttr.cpp:216
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this attribute.
Definition: ParsedAttr.h:386
bool checkAtLeastNumArgs(class Sema &S, unsigned Num) const
Check if the attribute has at least as many args as Num.
Definition: ParsedAttr.cpp:301
unsigned getNumArgMembers() const
Definition: ParsedAttr.cpp:152
bool isStmtAttr() const
Definition: ParsedAttr.cpp:197
unsigned getMaxArgs() const
Definition: ParsedAttr.cpp:148
bool slidesFromDeclToDeclSpecLegacyBehavior() const
Returns whether a [[]] attribute, if specified ahead of a declaration, should be applied to the decl-...
Definition: ParsedAttr.cpp:220
void getMatchRules(const LangOptions &LangOpts, SmallVectorImpl< std::pair< attr::SubjectMatchRule, bool > > &MatchRules) const
Definition: ParsedAttr.cpp:177
bool isParamExpr(size_t N) const
Definition: ParsedAttr.cpp:272
bool diagnoseLangOpts(class Sema &S) const
Definition: ParsedAttr.cpp:184
bool checkAtMostNumArgs(class Sema &S, unsigned Num) const
Check if the attribute has at most as many args as Num.
Definition: ParsedAttr.cpp:306
ParsedAttributes - A collection of parsed attributes.
Definition: ParsedAttr.h:956
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: SemaBase.cpp:60
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:463
const LangOptions & getLangOpts() const
Definition: Sema.h:524
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
Definition: Stmt.h:84
Exposes information about the current target.
Definition: TargetInfo.h:220
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Attr > attr
Matches attributes.
SubjectMatchRule
A list of all the recognized kinds of attributes.
The JSON file list parser is used to communicate input to InstallAPI.
llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion
A union of the various pointer types that can be passed to an ParsedAttr as an argument.
Definition: ParsedAttr.h:113
void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &Second, ParsedAttributes &Result)
Consumes the attributes from First and Second and concatenates them into Result.
Definition: ParsedAttr.cpp:312
@ Result
The result type of a method or function.
const std::list< std::unique_ptr< ParsedAttrInfo > > & getAttributePluginInstances()
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
Definition: Ownership.h:229
Wraps an identifier and optional source location for the identifier.
Definition: ParsedAttr.h:103
SourceLocation Loc
Definition: ParsedAttr.h:104
IdentifierInfo * Ident
Definition: ParsedAttr.h:105
static IdentifierLoc * create(ASTContext &Ctx, SourceLocation Loc, IdentifierInfo *Ident)
Definition: ParsedAttr.cpp:26
static ArrayRef< const ParsedAttrInfo * > getAllBuiltin()
Definition: ParsedAttr.cpp:142
unsigned IsKnownToGCC
True if this attribute has any spellings that are known to gcc.
unsigned HasCustomParsing
True if the parsing does not match the semantic content.
unsigned IsType
True if this attribute applies to types.
unsigned IsTargetSpecific
True if this attribute is only available for certain targets.
unsigned IsSupportedByPragmaAttribute
True if this attribute is supported by #pragma clang attribute.
unsigned NumArgs
The number of required arguments of this attribute.
virtual bool diagAppertainsToStmt(Sema &S, const ParsedAttr &Attr, const Stmt *St) const
Check if this attribute appertains to St, and issue a diagnostic if not.
virtual unsigned spellingIndexToSemanticSpelling(const ParsedAttr &Attr) const
Convert the spelling index of Attr to a semantic spelling enum value.
static const ParsedAttrInfo & get(const AttributeCommonInfo &A)
Definition: ParsedAttr.cpp:113
virtual bool isParamExpr(size_t N) const
Returns true if the specified parameter index for this attribute in Attr.td is an ExprArgument or Var...
virtual void getPragmaAttributeMatchRules(llvm::SmallVectorImpl< std::pair< attr::SubjectMatchRule, bool > > &Rules, const LangOptions &LangOpts) const
Populate Rules with the match rules of this attribute.
virtual bool existsInTarget(const TargetInfo &Target) const
Check if this attribute is allowed when compiling for the given target.
virtual bool spellingExistsInTarget(const TargetInfo &Target, const unsigned SpellingListIndex) const
Check if this attribute's spelling is allowed when compiling for the given target.
virtual bool diagAppertainsToDecl(Sema &S, const ParsedAttr &Attr, const Decl *D) const
Check if this attribute appertains to D, and issue a diagnostic if not.
unsigned OptArgs
The number of optional arguments of this attributes.
virtual bool diagMutualExclusion(Sema &S, const ParsedAttr &A, const Decl *D) const
Check if the given attribute is mutually exclusive with other attributes already applied to the given...
unsigned IsStmt
True if this attribute applies to statements.
unsigned NumArgMembers
The number of non-fake arguments specified in the attribute definition.
Describes the trailing object for Availability attribute in ParsedAttr.
Definition: ParsedAttr.h:68