clang  13.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 
13 #include "clang/Sema/ParsedAttr.h"
14 #include "clang/AST/ASTContext.h"
17 #include "clang/Basic/TargetInfo.h"
19 #include "llvm/ADT/SmallString.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/Support/ManagedStatic.h"
23 #include <cassert>
24 #include <cstddef>
25 #include <utility>
26 
27 using namespace clang;
28 
29 LLVM_INSTANTIATE_REGISTRY(ParsedAttrInfoRegistry)
30 
32  IdentifierInfo *Ident) {
33  IdentifierLoc *Result = new (Ctx) IdentifierLoc;
34  Result->Loc = Loc;
35  Result->Ident = Ident;
36  return Result;
37 }
38 
39 size_t ParsedAttr::allocated_size() const {
40  if (IsAvailability) return AttributeFactory::AvailabilityAllocSize;
41  else if (IsTypeTagForDatatype)
43  else if (IsProperty)
45  else if (HasParsedType)
46  return totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
48  detail::PropertyData>(0, 0, 0, 1, 0);
49  return totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
51  detail::PropertyData>(NumArgs, 0, 0, 0, 0);
52 }
53 
55  // Go ahead and configure all the inline capacity. This is just a memset.
56  FreeLists.resize(InlineFreeListsCapacity);
57 }
59 
60 static size_t getFreeListIndexForSize(size_t size) {
61  assert(size >= sizeof(ParsedAttr));
62  assert((size % sizeof(void*)) == 0);
63  return ((size - sizeof(ParsedAttr)) / sizeof(void *));
64 }
65 
66 void *AttributeFactory::allocate(size_t size) {
67  // Check for a previously reclaimed attribute.
68  size_t index = getFreeListIndexForSize(size);
69  if (index < FreeLists.size() && !FreeLists[index].empty()) {
70  ParsedAttr *attr = FreeLists[index].back();
71  FreeLists[index].pop_back();
72  return attr;
73  }
74 
75  // Otherwise, allocate something new.
76  return Alloc.Allocate(size, alignof(AttributeFactory));
77 }
78 
79 void AttributeFactory::deallocate(ParsedAttr *Attr) {
80  size_t size = Attr->allocated_size();
81  size_t freeListIndex = getFreeListIndexForSize(size);
82 
83  // Expand FreeLists to the appropriate size, if required.
84  if (freeListIndex >= FreeLists.size())
85  FreeLists.resize(freeListIndex + 1);
86 
87 #ifndef NDEBUG
88  // In debug mode, zero out the attribute to help find memory overwriting.
89  memset(Attr, 0, size);
90 #endif
91 
92  // Add 'Attr' to the appropriate free-list.
93  FreeLists[freeListIndex].push_back(Attr);
94 }
95 
96 void AttributeFactory::reclaimPool(AttributePool &cur) {
97  for (ParsedAttr *AL : cur.Attrs)
98  deallocate(AL);
99 }
100 
101 void AttributePool::takePool(AttributePool &pool) {
102  Attrs.insert(Attrs.end(), pool.Attrs.begin(), pool.Attrs.end());
103  pool.Attrs.clear();
104 }
105 
106 namespace {
107 
108 #include "clang/Sema/AttrParsedAttrImpl.inc"
109 
110 } // namespace
111 
113  // If we have a ParsedAttrInfo for this ParsedAttr then return that.
114  if ((size_t)A.getParsedKind() < llvm::array_lengthof(AttrInfoMap))
115  return *AttrInfoMap[A.getParsedKind()];
116 
117  // If this is an ignored attribute then return an appropriate ParsedAttrInfo.
118  static const ParsedAttrInfo IgnoredParsedAttrInfo(
121  return IgnoredParsedAttrInfo;
122 
123  // Otherwise this may be an attribute defined by a plugin. First instantiate
124  // all plugin attributes if we haven't already done so.
125  static llvm::ManagedStatic<std::list<std::unique_ptr<ParsedAttrInfo>>>
126  PluginAttrInstances;
127  if (PluginAttrInstances->empty())
128  for (auto It : ParsedAttrInfoRegistry::entries())
129  PluginAttrInstances->emplace_back(It.instantiate());
130 
131  // Search for a ParsedAttrInfo whose name and syntax match.
132  std::string FullName = A.getNormalizedFullName();
133  AttributeCommonInfo::Syntax SyntaxUsed = A.getSyntax();
135  SyntaxUsed = AttributeCommonInfo::AS_Keyword;
136 
137  for (auto &Ptr : *PluginAttrInstances)
138  for (auto &S : Ptr->Spellings)
139  if (S.Syntax == SyntaxUsed && S.NormalizedFullName == FullName)
140  return *Ptr;
141 
142  // If we failed to find a match then return a default ParsedAttrInfo.
143  static const ParsedAttrInfo DefaultParsedAttrInfo(
145  return DefaultParsedAttrInfo;
146 }
147 
148 unsigned ParsedAttr::getMinArgs() const { return getInfo().NumArgs; }
149 
150 unsigned ParsedAttr::getMaxArgs() const {
151  return getMinArgs() + getInfo().OptArgs;
152 }
153 
155  return getInfo().HasCustomParsing;
156 }
157 
158 bool ParsedAttr::diagnoseAppertainsTo(Sema &S, const Decl *D) const {
159  return getInfo().diagAppertainsToDecl(S, *this, D);
160 }
161 
162 bool ParsedAttr::diagnoseAppertainsTo(Sema &S, const Stmt *St) const {
163  return getInfo().diagAppertainsToStmt(S, *this, St);
164 }
165 
167  return getInfo().diagMutualExclusion(S, *this, D);
168 }
169 
170 bool ParsedAttr::diagnoseMutualExclusion(Sema &S, const Stmt *St) const {
171  return getInfo().diagMutualExclusion(S, *this, St);
172 }
173 
175  attr::SubjectMatchRule MatchRule) const {
176  return checkAttributeMatchRuleAppliesTo(D, MatchRule);
177 }
178 
180  const LangOptions &LangOpts,
181  SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &MatchRules)
182  const {
183  return getInfo().getPragmaAttributeMatchRules(MatchRules, LangOpts);
184 }
185 
187  return getInfo().diagLangOpts(S, *this);
188 }
189 
191  return getInfo().IsTargetSpecific;
192 }
193 
194 bool ParsedAttr::isTypeAttr() const { return getInfo().IsType; }
195 
196 bool ParsedAttr::isStmtAttr() const { return getInfo().IsStmt; }
197 
198 bool ParsedAttr::existsInTarget(const TargetInfo &Target) const {
199  return getInfo().existsInTarget(Target);
200 }
201 
203 
206 }
207 
210 }
211 
213  // If the attribute has the maximum number of optional arguments, we will
214  // claim that as being variadic. If we someday get an attribute that
215  // legitimately bumps up against that maximum, we can use another bit to track
216  // whether it's truly variadic or not.
217  return getInfo().OptArgs == 15;
218 }
219 
220 static unsigned getNumAttributeArgs(const ParsedAttr &AL) {
221  // FIXME: Include the type in the argument list.
222  return AL.getNumArgs() + AL.hasParsedType();
223 }
224 
225 template <typename Compare>
226 static bool checkAttributeNumArgsImpl(Sema &S, const ParsedAttr &AL,
227  unsigned Num, unsigned Diag,
228  Compare Comp) {
229  if (Comp(getNumAttributeArgs(AL), Num)) {
230  S.Diag(AL.getLoc(), Diag) << AL << Num;
231  return false;
232  }
233  return true;
234 }
235 
236 bool ParsedAttr::checkExactlyNumArgs(Sema &S, unsigned Num) const {
237  return checkAttributeNumArgsImpl(S, *this, Num,
238  diag::err_attribute_wrong_number_arguments,
239  std::not_equal_to<unsigned>());
240 }
241 bool ParsedAttr::checkAtLeastNumArgs(Sema &S, unsigned Num) const {
242  return checkAttributeNumArgsImpl(S, *this, Num,
243  diag::err_attribute_too_few_arguments,
244  std::less<unsigned>());
245 }
246 bool ParsedAttr::checkAtMostNumArgs(Sema &S, unsigned Num) const {
247  return checkAttributeNumArgsImpl(S, *this, Num,
248  diag::err_attribute_too_many_arguments,
249  std::greater<unsigned>());
250 }
clang::AttributeCommonInfo::getParsedKind
Kind getParsedKind() const
Definition: AttributeCommonInfo.h:126
clang::ParsedAttr::getMinArgs
unsigned getMinArgs() const
Definition: ParsedAttr.cpp:148
clang::AttributeCommonInfo::getLoc
SourceLocation getLoc() const
Definition: AttributeCommonInfo.h:129
clang::ParsedAttrInfo::diagLangOpts
virtual bool diagLangOpts(Sema &S, const ParsedAttr &Attr) const
Check if this attribute is allowed by the language we are compiling, and issue a diagnostic if not.
Definition: ParsedAttr.h:103
clang::ParsedAttrInfo::IsTargetSpecific
unsigned IsTargetSpecific
True if this attribute is only available for certain targets.
Definition: ParsedAttr.h:55
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
Diag
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.
Definition: LiteralSupport.cpp:78
clang::ParsedAttrInfo::diagAppertainsToDecl
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.
Definition: ParsedAttr.h:80
SemaInternal.h
clang::ArgsUnion
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:202
clang::ParsedAttr::appliesToDecl
bool appliesToDecl(const Decl *D, attr::SubjectMatchRule MatchRule) const
Definition: ParsedAttr.cpp:174
clang::ParsedAttrInfo
Definition: ParsedAttr.h:45
clang::SourceLocation
Encodes a location in the source.
Definition: SourceLocation.h:89
clang::AttributePool
Definition: ParsedAttr.h:721
TargetInfo.h
clang::MultiVersionKind::Target
@ Target
clang::ParsedAttr::getSemanticSpelling
unsigned getSemanticSpelling() const
If the parsed attribute has a semantic equivalent, and it would have a semantic Spelling enumeration ...
Definition: ParsedAttr.cpp:208
clang::Sema::Diag
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: Sema.cpp:1778
clang::TargetInfo
Exposes information about the current target.
Definition: TargetInfo.h:188
clang::ParsedAttrInfo::diagAppertainsToStmt
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.
Definition: ParsedAttr.h:85
getNumAttributeArgs
static unsigned getNumAttributeArgs(const ParsedAttr &AL)
Definition: ParsedAttr.cpp:220
clang::ParsedAttrInfo::spellingIndexToSemanticSpelling
virtual unsigned spellingIndexToSemanticSpelling(const ParsedAttr &Attr) const
Convert the spelling index of Attr to a semantic spelling enum value.
Definition: ParsedAttr.h:112
clang::ParsedAttr::isTargetSpecificAttr
bool isTargetSpecificAttr() const
Definition: ParsedAttr.cpp:190
clang::ParsedAttrInfo::IsKnownToGCC
unsigned IsKnownToGCC
True if this attribute has any spellings that are known to gcc.
Definition: ParsedAttr.h:61
clang::ParsedAttrInfo::OptArgs
unsigned OptArgs
The number of optional arguments of this attributes.
Definition: ParsedAttr.h:51
clang::ParsedAttr::checkAtLeastNumArgs
bool checkAtLeastNumArgs(class Sema &S, unsigned Num) const
Check if the attribute has at least as many args as Num.
Definition: ParsedAttr.cpp:241
clang::AttributeCommonInfo::Syntax
Syntax
The style used to specify an attribute.
Definition: AttributeCommonInfo.h:25
clang::AttributeFactory::PropertyAllocSize
@ PropertyAllocSize
Definition: ParsedAttr.h:678
clang::detail::TypeTagForDatatypeData
Definition: ParsedAttr.h:177
clang::attr::SubjectMatchRule
SubjectMatchRule
A list of all the recognized kinds of attributes.
Definition: AttrSubjectMatchRules.h:19
clang::ParsedAttr::checkExactlyNumArgs
bool checkExactlyNumArgs(class Sema &S, unsigned Num) const
Check if the attribute has exactly as many args as Num.
Definition: ParsedAttr.cpp:236
clang::detail::AvailabilityData
Describes the trailing object for Availability attribute in ParsedAttr.
Definition: ParsedAttr.h:161
clang::AttributeCommonInfo::AS_Keyword
@ AS_Keyword
__ptr16, alignas(...), etc.
Definition: AttributeCommonInfo.h:42
clang::ParsedAttr::getNumArgs
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this attribute.
Definition: ParsedAttr.h:472
clang::AttributeFactory
A factory, from which one makes pools, from which one creates individual attributes which are dealloc...
Definition: ParsedAttr.h:667
clang::AttributeCommonInfo::UnknownAttribute
@ UnknownAttribute
Definition: AttributeCommonInfo.h:58
clang::interp::Compare
ComparisonCategoryResult Compare(const T &X, const T &Y)
Helper to compare two comparable types.
Definition: Integral.h:32
clang::AttributeCommonInfo::AS_ContextSensitiveKeyword
@ AS_ContextSensitiveKeyword
Context-sensitive version of a keyword attribute.
Definition: AttributeCommonInfo.h:50
clang::ParsedAttr::getMaxArgs
unsigned getMaxArgs() const
Definition: ParsedAttr.cpp:150
clang::ASTContext
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:187
clang::AttributeCommonInfo::getSyntax
Syntax getSyntax() const
Definition: AttributeCommonInfo.h:127
clang::ParsedAttrInfo::NumArgs
unsigned NumArgs
The number of required arguments of this attribute.
Definition: ParsedAttr.h:49
clang::ParsedAttrInfo::IsType
unsigned IsType
True if this attribute applies to types.
Definition: ParsedAttr.h:57
IdentifierTable.h
clang::ParsedAttr
ParsedAttr - Represents a syntactic attribute.
Definition: ParsedAttr.h:214
checkAttributeNumArgsImpl
static bool checkAttributeNumArgsImpl(Sema &S, const ParsedAttr &AL, unsigned Num, unsigned Diag, Compare Comp)
Definition: ParsedAttr.cpp:226
clang::ParsedAttr::isTypeAttr
bool isTypeAttr() const
Definition: ParsedAttr.cpp:194
ASTContext.h
AttrSubjectMatchRules.h
clang::AttributeFactory::AttributeFactory
AttributeFactory()
Definition: ParsedAttr.cpp:54
clang::ParsedAttrInfo::get
static const ParsedAttrInfo & get(const AttributeCommonInfo &A)
Definition: ParsedAttr.cpp:112
clang::ParsedType
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
Definition: Ownership.h:243
clang::ParsedAttrInfo::IsSupportedByPragmaAttribute
unsigned IsSupportedByPragmaAttribute
True if this attribute is supported by #pragma clang attribute.
Definition: ParsedAttr.h:63
clang::ParsedAttr::existsInTarget
bool existsInTarget(const TargetInfo &Target) const
Definition: ParsedAttr.cpp:198
clang::ParsedAttr::isKnownToGCC
bool isKnownToGCC() const
Definition: ParsedAttr.cpp:202
clang::ParsedAttr::hasVariadicArg
bool hasVariadicArg() const
Definition: ParsedAttr.cpp:212
clang::ParsedAttr::checkAtMostNumArgs
bool checkAtMostNumArgs(class Sema &S, unsigned Num) const
Check if the attribute has at most as many args as Num.
Definition: ParsedAttr.cpp:246
clang::ParsedAttr::diagnoseMutualExclusion
bool diagnoseMutualExclusion(class Sema &S, const Decl *D) const
Definition: ParsedAttr.cpp:166
clang::AttributeFactory::AvailabilityAllocSize
@ AvailabilityAllocSize
Definition: ParsedAttr.h:670
clang::serialized_diags::create
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
Definition: SerializedDiagnosticPrinter.cpp:302
getFreeListIndexForSize
static size_t getFreeListIndexForSize(size_t size)
Definition: ParsedAttr.cpp:60
clang::ParsedAttr::hasParsedType
bool hasParsedType() const
Definition: ParsedAttr.h:438
clang::Decl
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:89
clang::AttributeCommonInfo
Definition: AttributeCommonInfo.h:22
clang::ParsedAttr::isStmtAttr
bool isStmtAttr() const
Definition: ParsedAttr.cpp:196
clang::Sema
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:352
clang::detail::PropertyData
Definition: ParsedAttr.h:182
clang::AttributeCommonInfo::getNormalizedFullName
std::string getNormalizedFullName() const
Gets the normalized full name, which consists of both scope and name and with surrounding underscores...
Definition: Attributes.cpp:106
clang::ParsedAttr::diagnoseAppertainsTo
bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const
Definition: ParsedAttr.cpp:158
clang::ParsedAttr::getInfo
const ParsedAttrInfo & getInfo() const
Definition: ParsedAttr.h:658
clang::AttributeCommonInfo::IgnoredAttribute
@ IgnoredAttribute
Definition: AttributeCommonInfo.h:57
clang::IdentifierInfo
One of these records is kept for each identifier that is lexed.
Definition: IdentifierTable.h:59
clang::LangOptions
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:58
clang::ParsedAttrInfoRegistry
llvm::Registry< ParsedAttrInfo > ParsedAttrInfoRegistry
Definition: ParsedAttr.h:136
clang
Dataflow Directional Tag Classes.
Definition: CalledOnceCheck.h:17
memset
__DEVICE__ void * memset(void *__a, int __b, size_t __c)
Definition: __clang_cuda_device_functions.h:1480
clang::ParsedAttr::hasCustomParsing
bool hasCustomParsing() const
Definition: ParsedAttr.cpp:154
clang::ParsedAttrInfo::HasCustomParsing
unsigned HasCustomParsing
True if the parsing does not match the semantic content.
Definition: ParsedAttr.h:53
clang::Stmt
Stmt - This represents one statement.
Definition: Stmt.h:68
clang::ParsedAttr::diagnoseLangOpts
bool diagnoseLangOpts(class Sema &S) const
Definition: ParsedAttr.cpp:186
clang::ParsedAttrInfo::IsStmt
unsigned IsStmt
True if this attribute applies to statements.
Definition: ParsedAttr.h:59
clang::AttributeFactory::~AttributeFactory
~AttributeFactory()
clang::ParsedAttr::getMatchRules
void getMatchRules(const LangOptions &LangOpts, SmallVectorImpl< std::pair< attr::SubjectMatchRule, bool >> &MatchRules) const
Definition: ParsedAttr.cpp:179
clang::Attr
Attr - This represents one attribute.
Definition: Attr.h:46
clang::AttributeFactory::TypeTagForDatatypeAllocSize
@ TypeTagForDatatypeAllocSize
Definition: ParsedAttr.h:674
llvm::SmallVectorImpl
Definition: LLVM.h:39
ParsedAttr.h
clang::IdentifierLoc
Wraps an identifier and optional source location for the identifier.
Definition: ParsedAttr.h:192
clang::ParsedAttrInfo::diagMutualExclusion
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...
Definition: ParsedAttr.h:91
clang::ParsedAttr::isSupportedByPragmaAttribute
bool isSupportedByPragmaAttribute() const
Definition: ParsedAttr.cpp:204
clang::ParsedAttrInfo::existsInTarget
virtual bool existsInTarget(const TargetInfo &Target) const
Check if this attribute is allowed when compiling for the given target.
Definition: ParsedAttr.h:107
clang::ParsedAttrInfo::getPragmaAttributeMatchRules
virtual void getPragmaAttributeMatchRules(llvm::SmallVectorImpl< std::pair< attr::SubjectMatchRule, bool >> &Rules, const LangOptions &LangOpts) const
Populate Rules with the match rules of this attribute.
Definition: ParsedAttr.h:116