clang  12.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,
50  detail::TypeTagForDatatypeData, ParsedType,
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 
163  attr::SubjectMatchRule MatchRule) const {
164  return checkAttributeMatchRuleAppliesTo(D, MatchRule);
165 }
166 
168  const LangOptions &LangOpts,
169  SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &MatchRules)
170  const {
171  return getInfo().getPragmaAttributeMatchRules(MatchRules, LangOpts);
172 }
173 
175  return getInfo().diagLangOpts(S, *this);
176 }
177 
179  return getInfo().IsTargetSpecific;
180 }
181 
182 bool ParsedAttr::isTypeAttr() const { return getInfo().IsType; }
183 
184 bool ParsedAttr::isStmtAttr() const { return getInfo().IsStmt; }
185 
187  return getInfo().existsInTarget(Target);
188 }
189 
191 
194 }
195 
198 }
199 
201  // If the attribute has the maximum number of optional arguments, we will
202  // claim that as being variadic. If we someday get an attribute that
203  // legitimately bumps up against that maximum, we can use another bit to track
204  // whether it's truly variadic or not.
205  return getInfo().OptArgs == 15;
206 }
Defines the clang::ASTContext interface.
static const ParsedAttrInfo & get(const AttributeCommonInfo &A)
Definition: ParsedAttr.cpp:112
bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const
Definition: ParsedAttr.cpp:158
static size_t getFreeListIndexForSize(size_t size)
Definition: ParsedAttr.cpp:60
virtual unsigned spellingIndexToSemanticSpelling(const ParsedAttr &Attr) const
Convert the spelling index of Attr to a semantic spelling enum value.
Definition: ParsedAttr.h:94
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:184
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:89
Syntax
The style used to specify an attribute.
IdentifierInfo * Ident
Definition: ParsedAttr.h:176
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:79
unsigned IsTargetSpecific
True if this attribute is only available for certain targets.
Definition: ParsedAttr.h:54
SourceLocation Loc
Definition: ParsedAttr.h:175
One of these records is kept for each identifier that is lexed.
SubjectMatchRule
A list of all the recognized kinds of attributes.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:174
unsigned NumArgs
The number of required arguments of this attribute.
Definition: ParsedAttr.h:48
void getMatchRules(const LangOptions &LangOpts, SmallVectorImpl< std::pair< attr::SubjectMatchRule, bool >> &MatchRules) const
Definition: ParsedAttr.cpp:167
bool isKnownToGCC() const
Definition: ParsedAttr.cpp:190
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
Definition: Ownership.h:244
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:54
llvm::Registry< ParsedAttrInfo > ParsedAttrInfoRegistry
Definition: ParsedAttr.h:118
bool existsInTarget(const TargetInfo &Target) const
Definition: ParsedAttr.cpp:186
unsigned getMinArgs() const
Definition: ParsedAttr.cpp:148
bool hasVariadicArg() const
Definition: ParsedAttr.cpp:200
__DEVICE__ void * memset(void *__a, int __b, size_t __c)
bool isTargetSpecificAttr() const
Definition: ParsedAttr.cpp:178
bool hasCustomParsing() const
Definition: ParsedAttr.cpp:154
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:98
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:340
unsigned IsSupportedByPragmaAttribute
True if this attribute is supported by #pragma clang attribute.
Definition: ParsedAttr.h:62
unsigned HasCustomParsing
True if the parsing does not match the semantic content.
Definition: ParsedAttr.h:52
Exposes information about the current target.
Definition: TargetInfo.h:179
unsigned IsKnownToGCC
True if this attribute has any spellings that are known to gcc.
Definition: ParsedAttr.h:60
virtual bool existsInTarget(const TargetInfo &Target) const
Check if this attribute is allowed when compiling for the given target.
Definition: ParsedAttr.h:89
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
Wraps an identifier and optional source location for the identifier.
Definition: ParsedAttr.h:174
unsigned OptArgs
The number of optional arguments of this attributes.
Definition: ParsedAttr.h:50
unsigned getSemanticSpelling() const
If the parsed attribute has a semantic equivalent, and it would have a semantic Spelling enumeration ...
Definition: ParsedAttr.cpp:196
const ParsedAttrInfo & getInfo() const
Definition: ParsedAttr.h:623
Encodes a location in the source.
unsigned IsType
True if this attribute applies to types.
Definition: ParsedAttr.h:56
ParsedAttr - Represents a syntactic attribute.
Definition: ParsedAttr.h:196
bool diagnoseLangOpts(class Sema &S) const
Definition: ParsedAttr.cpp:174
unsigned IsStmt
True if this attribute applies to statements.
Definition: ParsedAttr.h:58
Describes the trailing object for Availability attribute in ParsedAttr.
Definition: ParsedAttr.h:143
bool isStmtAttr() const
Definition: ParsedAttr.cpp:184
Dataflow Directional Tag Classes.
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
bool isTypeAttr() const
Definition: ParsedAttr.cpp:182
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:85
unsigned getMaxArgs() const
Definition: ParsedAttr.cpp:150
A factory, from which one makes pools, from which one creates individual attributes which are dealloc...
Definition: ParsedAttr.h:632
std::string getNormalizedFullName() const
Gets the normalized full name, which consists of both scope and name and with surrounding underscores...
Definition: Attributes.cpp:106
bool appliesToDecl(const Decl *D, attr::SubjectMatchRule MatchRule) const
Definition: ParsedAttr.cpp:162
Defines the clang::TargetInfo interface.
bool isSupportedByPragmaAttribute() const
Definition: ParsedAttr.cpp:192
Context-sensitive version of a keyword attribute.
Attr - This represents one attribute.
Definition: Attr.h:46