clang  9.0.0
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 <cassert>
23 #include <cstddef>
24 #include <utility>
25 
26 using namespace clang;
27 
29  IdentifierInfo *Ident) {
30  IdentifierLoc *Result = new (Ctx) IdentifierLoc;
31  Result->Loc = Loc;
32  Result->Ident = Ident;
33  return Result;
34 }
35 
36 size_t ParsedAttr::allocated_size() const {
37  if (IsAvailability) return AttributeFactory::AvailabilityAllocSize;
38  else if (IsTypeTagForDatatype)
40  else if (IsProperty)
42  else if (HasParsedType)
43  return totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
45  detail::PropertyData>(0, 0, 0, 1, 0);
46  return totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
47  detail::TypeTagForDatatypeData, ParsedType,
48  detail::PropertyData>(NumArgs, 0, 0, 0, 0);
49 }
50 
52  // Go ahead and configure all the inline capacity. This is just a memset.
53  FreeLists.resize(InlineFreeListsCapacity);
54 }
56 
57 static size_t getFreeListIndexForSize(size_t size) {
58  assert(size >= sizeof(ParsedAttr));
59  assert((size % sizeof(void*)) == 0);
60  return ((size - sizeof(ParsedAttr)) / sizeof(void *));
61 }
62 
63 void *AttributeFactory::allocate(size_t size) {
64  // Check for a previously reclaimed attribute.
65  size_t index = getFreeListIndexForSize(size);
66  if (index < FreeLists.size() && !FreeLists[index].empty()) {
67  ParsedAttr *attr = FreeLists[index].back();
68  FreeLists[index].pop_back();
69  return attr;
70  }
71 
72  // Otherwise, allocate something new.
73  return Alloc.Allocate(size, alignof(AttributeFactory));
74 }
75 
76 void AttributeFactory::deallocate(ParsedAttr *Attr) {
77  size_t size = Attr->allocated_size();
78  size_t freeListIndex = getFreeListIndexForSize(size);
79 
80  // Expand FreeLists to the appropriate size, if required.
81  if (freeListIndex >= FreeLists.size())
82  FreeLists.resize(freeListIndex + 1);
83 
84 #ifndef NDEBUG
85  // In debug mode, zero out the attribute to help find memory overwriting.
86  memset(Attr, 0, size);
87 #endif
88 
89  // Add 'Attr' to the appropriate free-list.
90  FreeLists[freeListIndex].push_back(Attr);
91 }
92 
93 void AttributeFactory::reclaimPool(AttributePool &cur) {
94  for (ParsedAttr *AL : cur.Attrs)
95  deallocate(AL);
96 }
97 
98 void AttributePool::takePool(AttributePool &pool) {
99  Attrs.insert(Attrs.end(), pool.Attrs.begin(), pool.Attrs.end());
100  pool.Attrs.clear();
101 }
102 
103 #include "clang/Sema/AttrParsedAttrKinds.inc"
104 
105 static StringRef normalizeAttrScopeName(StringRef ScopeName,
106  ParsedAttr::Syntax SyntaxUsed) {
107  // Normalize the "__gnu__" scope name to be "gnu" and the "_Clang" scope name
108  // to be "clang".
109  if (SyntaxUsed == ParsedAttr::AS_CXX11 ||
110  SyntaxUsed == ParsedAttr::AS_C2x) {
111  if (ScopeName == "__gnu__")
112  ScopeName = "gnu";
113  else if (ScopeName == "_Clang")
114  ScopeName = "clang";
115  }
116  return ScopeName;
117 }
118 
119 static StringRef normalizeAttrName(StringRef AttrName,
120  StringRef NormalizedScopeName,
121  ParsedAttr::Syntax SyntaxUsed) {
122  // Normalize the attribute name, __foo__ becomes foo. This is only allowable
123  // for GNU attributes, and attributes using the double square bracket syntax.
124  bool ShouldNormalize =
125  SyntaxUsed == ParsedAttr::AS_GNU ||
126  ((SyntaxUsed == ParsedAttr::AS_CXX11 ||
127  SyntaxUsed == ParsedAttr::AS_C2x) &&
128  (NormalizedScopeName == "gnu" || NormalizedScopeName == "clang"));
129  if (ShouldNormalize && AttrName.size() >= 4 && AttrName.startswith("__") &&
130  AttrName.endswith("__"))
131  AttrName = AttrName.slice(2, AttrName.size() - 2);
132 
133  return AttrName;
134 }
135 
137  const IdentifierInfo *ScopeName,
138  Syntax SyntaxUsed) {
139  StringRef AttrName = Name->getName();
140 
141  SmallString<64> FullName;
142  if (ScopeName)
143  FullName += normalizeAttrScopeName(ScopeName->getName(), SyntaxUsed);
144 
145  AttrName = normalizeAttrName(AttrName, FullName, SyntaxUsed);
146 
147  // Ensure that in the case of C++11 attributes, we look for '::foo' if it is
148  // unscoped.
149  if (ScopeName || SyntaxUsed == AS_CXX11 || SyntaxUsed == AS_C2x)
150  FullName += "::";
151  FullName += AttrName;
152 
153  return ::getAttrKind(FullName, SyntaxUsed);
154 }
155 
157  // Both variables will be used in tablegen generated
158  // attribute spell list index matching code.
159  auto Syntax = static_cast<ParsedAttr::Syntax>(SyntaxUsed);
160  StringRef Scope =
161  ScopeName ? normalizeAttrScopeName(ScopeName->getName(), Syntax) : "";
162  StringRef Name = normalizeAttrName(AttrName->getName(), Scope, Syntax);
163 
164 #include "clang/Sema/AttrSpellingListIndex.inc"
165 
166 }
167 
169  unsigned NumArgs : 4;
170  unsigned OptArgs : 4;
171  unsigned HasCustomParsing : 1;
172  unsigned IsTargetSpecific : 1;
173  unsigned IsType : 1;
174  unsigned IsStmt : 1;
175  unsigned IsKnownToGCC : 1;
177 
178  bool (*DiagAppertainsToDecl)(Sema &S, const ParsedAttr &Attr, const Decl *);
179  bool (*DiagLangOpts)(Sema &S, const ParsedAttr &Attr);
180  bool (*ExistsInTarget)(const TargetInfo &Target);
181  unsigned (*SpellingIndexToSemanticSpelling)(const ParsedAttr &Attr);
182  void (*GetPragmaAttributeMatchRules)(
184  const LangOptions &LangOpts);
185 };
186 
187 namespace {
188 
189 #include "clang/Sema/AttrParsedAttrImpl.inc"
190 
191 } // namespace
192 
193 static const ParsedAttrInfo &getInfo(const ParsedAttr &A) {
194  return AttrInfoMap[A.getKind()];
195 }
196 
197 unsigned ParsedAttr::getMinArgs() const { return getInfo(*this).NumArgs; }
198 
199 unsigned ParsedAttr::getMaxArgs() const {
200  return getMinArgs() + getInfo(*this).OptArgs;
201 }
202 
204  return getInfo(*this).HasCustomParsing;
205 }
206 
207 bool ParsedAttr::diagnoseAppertainsTo(Sema &S, const Decl *D) const {
208  return getInfo(*this).DiagAppertainsToDecl(S, *this, D);
209 }
210 
212  attr::SubjectMatchRule MatchRule) const {
213  return checkAttributeMatchRuleAppliesTo(D, MatchRule);
214 }
215 
217  const LangOptions &LangOpts,
218  SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &MatchRules)
219  const {
220  return getInfo(*this).GetPragmaAttributeMatchRules(MatchRules, LangOpts);
221 }
222 
224  return getInfo(*this).DiagLangOpts(S, *this);
225 }
226 
228  return getInfo(*this).IsTargetSpecific;
229 }
230 
231 bool ParsedAttr::isTypeAttr() const { return getInfo(*this).IsType; }
232 
233 bool ParsedAttr::isStmtAttr() const { return getInfo(*this).IsStmt; }
234 
236  return getInfo(*this).ExistsInTarget(Target);
237 }
238 
239 bool ParsedAttr::isKnownToGCC() const { return getInfo(*this).IsKnownToGCC; }
240 
243 }
244 
246  return getInfo(*this).SpellingIndexToSemanticSpelling(*this);
247 }
248 
250  // If the attribute has the maximum number of optional arguments, we will
251  // claim that as being variadic. If we someday get an attribute that
252  // legitimately bumps up against that maximum, we can use another bit to track
253  // whether it's truly variadic or not.
254  return getInfo(*this).OptArgs == 15;
255 }
Defines the clang::ASTContext interface.
bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const
Definition: ParsedAttr.cpp:207
static size_t getFreeListIndexForSize(size_t size)
Definition: ParsedAttr.cpp:57
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:104
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:88
IdentifierInfo * Ident
Definition: ParsedAttr.h:96
static IdentifierLoc * create(ASTContext &Ctx, SourceLocation Loc, IdentifierInfo *Ident)
Definition: ParsedAttr.cpp:28
attribute((...))
Definition: ParsedAttr.h:141
unsigned IsStmt
Definition: ParsedAttr.cpp:174
bool(* DiagLangOpts)(Sema &S, const ParsedAttr &Attr)
Definition: ParsedAttr.cpp:179
unsigned OptArgs
Definition: ParsedAttr.cpp:170
bool(* ExistsInTarget)(const TargetInfo &Target)
Definition: ParsedAttr.cpp:180
SourceLocation Loc
Definition: ParsedAttr.h:95
One of these records is kept for each identifier that is lexed.
unsigned getAttributeSpellingListIndex() const
Get an index into the attribute spelling list defined in Attr.td.
Definition: ParsedAttr.cpp:156
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:154
void getMatchRules(const LangOptions &LangOpts, SmallVectorImpl< std::pair< attr::SubjectMatchRule, bool >> &MatchRules) const
Definition: ParsedAttr.cpp:216
bool isKnownToGCC() const
Definition: ParsedAttr.cpp:239
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:49
unsigned NumArgs
Definition: ParsedAttr.cpp:169
bool existsInTarget(const TargetInfo &Target) const
Definition: ParsedAttr.cpp:235
unsigned getMinArgs() const
Definition: ParsedAttr.cpp:197
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:40
bool hasVariadicArg() const
Definition: ParsedAttr.cpp:249
__DEVICE__ void * memset(void *__a, int __b, size_t __c)
bool(* DiagAppertainsToDecl)(Sema &S, const ParsedAttr &Attr, const Decl *)
Definition: ParsedAttr.cpp:178
bool isTargetSpecificAttr() const
Definition: ParsedAttr.cpp:227
bool hasCustomParsing() const
Definition: ParsedAttr.cpp:203
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:328
Exposes information about the current target.
Definition: TargetInfo.h:161
unsigned HasCustomParsing
Definition: ParsedAttr.cpp:171
Kind getKind() const
Definition: ParsedAttr.h:453
unsigned IsSupportedByPragmaAttribute
Definition: ParsedAttr.cpp:176
static StringRef normalizeAttrScopeName(StringRef ScopeName, ParsedAttr::Syntax SyntaxUsed)
Definition: ParsedAttr.cpp:105
#define bool
Definition: stdbool.h:15
unsigned IsKnownToGCC
Definition: ParsedAttr.cpp:175
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
unsigned IsType
Definition: ParsedAttr.cpp:173
Wraps an identifier and optional source location for the identifier.
Definition: ParsedAttr.h:94
The result type of a method or function.
unsigned getSemanticSpelling() const
If the parsed attribute has a semantic equivalent, and it would have a semantic Spelling enumeration ...
Definition: ParsedAttr.cpp:245
Encodes a location in the source.
Syntax
The style used to specify an attribute.
Definition: ParsedAttr.h:139
ParsedAttr - Represents a syntactic attribute.
Definition: ParsedAttr.h:116
bool diagnoseLangOpts(class Sema &S) const
Definition: ParsedAttr.cpp:223
Describes the trailing object for Availability attribute in ParsedAttr.
Definition: ParsedAttr.h:63
StringRef getName() const
Return the actual identifier string.
bool isStmtAttr() const
Definition: ParsedAttr.cpp:233
Dataflow Directional Tag Classes.
unsigned IsTargetSpecific
Definition: ParsedAttr.cpp:172
bool isTypeAttr() const
Definition: ParsedAttr.cpp:231
void(* GetPragmaAttributeMatchRules)(llvm::SmallVectorImpl< std::pair< attr::SubjectMatchRule, bool >> &Rules, const LangOptions &LangOpts)
Definition: ParsedAttr.cpp:182
static const ParsedAttrInfo & getInfo(const ParsedAttr &A)
Definition: ParsedAttr.cpp:193
unsigned getMaxArgs() const
Definition: ParsedAttr.cpp:199
A factory, from which one makes pools, from which one creates individual attributes which are dealloc...
Definition: ParsedAttr.h:629
bool appliesToDecl(const Decl *D, attr::SubjectMatchRule MatchRule) const
Definition: ParsedAttr.cpp:211
unsigned(* SpellingIndexToSemanticSpelling)(const ParsedAttr &Attr)
Definition: ParsedAttr.cpp:181
Defines the clang::TargetInfo interface.
static StringRef normalizeAttrName(StringRef AttrName, StringRef NormalizedScopeName, ParsedAttr::Syntax SyntaxUsed)
Definition: ParsedAttr.cpp:119
bool isSupportedByPragmaAttribute() const
Definition: ParsedAttr.cpp:241
Attr - This represents one attribute.
Definition: Attr.h:43