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