clang  7.0.0svn
AttributeList.cpp
Go to the documentation of this file.
1 //===- AttributeList.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 AttributeList class implementation
11 //
12 //===----------------------------------------------------------------------===//
13 
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 AttributeList::allocated_size() const {
38  if (IsAvailability) return AttributeFactory::AvailabilityAllocSize;
39  else if (IsTypeTagForDatatype)
41  else if (IsProperty)
43  return (sizeof(AttributeList) + NumArgs * sizeof(ArgsUnion));
44 }
45 
47  // Go ahead and configure all the inline capacity. This is just a memset.
48  FreeLists.resize(InlineFreeListsCapacity);
49 }
51 
52 static size_t getFreeListIndexForSize(size_t size) {
53  assert(size >= sizeof(AttributeList));
54  assert((size % sizeof(void*)) == 0);
55  return ((size - sizeof(AttributeList)) / sizeof(void*));
56 }
57 
58 void *AttributeFactory::allocate(size_t size) {
59  // Check for a previously reclaimed attribute.
60  size_t index = getFreeListIndexForSize(size);
61  if (index < FreeLists.size()) {
62  if (AttributeList *attr = FreeLists[index]) {
63  FreeLists[index] = attr->NextInPool;
64  return attr;
65  }
66  }
67 
68  // Otherwise, allocate something new.
69  return Alloc.Allocate(size, alignof(AttributeFactory));
70 }
71 
72 void AttributeFactory::reclaimPool(AttributeList *cur) {
73  assert(cur && "reclaiming empty pool!");
74  do {
75  // Read this here, because we're going to overwrite NextInPool
76  // when we toss 'cur' into the appropriate queue.
77  AttributeList *next = cur->NextInPool;
78 
79  size_t size = cur->allocated_size();
80  size_t freeListIndex = getFreeListIndexForSize(size);
81 
82  // Expand FreeLists to the appropriate size, if required.
83  if (freeListIndex >= FreeLists.size())
84  FreeLists.resize(freeListIndex+1);
85 
86  // Add 'cur' to the appropriate free-list.
87  cur->NextInPool = FreeLists[freeListIndex];
88  FreeLists[freeListIndex] = cur;
89 
90  cur = next;
91  } while (cur);
92 }
93 
94 void AttributePool::takePool(AttributeList *pool) {
95  assert(pool);
96 
97  // Fast path: this pool is empty.
98  if (!Head) {
99  Head = pool;
100  return;
101  }
102 
103  // Reverse the pool onto the current head. This optimizes for the
104  // pattern of pulling a lot of pools into a single pool.
105  do {
106  AttributeList *next = pool->NextInPool;
107  pool->NextInPool = Head;
108  Head = pool;
109  pool = next;
110  } while (pool);
111 }
112 
113 #include "clang/Sema/AttrParsedAttrKinds.inc"
114 
115 static StringRef normalizeAttrName(StringRef AttrName, StringRef ScopeName,
116  AttributeList::Syntax SyntaxUsed) {
117  // Normalize the attribute name, __foo__ becomes foo. This is only allowable
118  // for GNU attributes.
119  bool IsGNU = SyntaxUsed == AttributeList::AS_GNU ||
120  ((SyntaxUsed == AttributeList::AS_CXX11 ||
121  SyntaxUsed == AttributeList::AS_C2x) && ScopeName == "gnu");
122  if (IsGNU && AttrName.size() >= 4 && AttrName.startswith("__") &&
123  AttrName.endswith("__"))
124  AttrName = AttrName.slice(2, AttrName.size() - 2);
125 
126  return AttrName;
127 }
128 
130  const IdentifierInfo *ScopeName,
131  Syntax SyntaxUsed) {
132  StringRef AttrName = Name->getName();
133 
134  SmallString<64> FullName;
135  if (ScopeName)
136  FullName += ScopeName->getName();
137 
138  AttrName = normalizeAttrName(AttrName, FullName, SyntaxUsed);
139 
140  // Ensure that in the case of C++11 attributes, we look for '::foo' if it is
141  // unscoped.
142  if (ScopeName || SyntaxUsed == AS_CXX11 || SyntaxUsed == AS_C2x)
143  FullName += "::";
144  FullName += AttrName;
145 
146  return ::getAttrKind(FullName, SyntaxUsed);
147 }
148 
150  // Both variables will be used in tablegen generated
151  // attribute spell list index matching code.
152  StringRef Scope = ScopeName ? ScopeName->getName() : "";
153  StringRef Name = normalizeAttrName(AttrName->getName(), Scope,
154  (AttributeList::Syntax)SyntaxUsed);
155 
156 #include "clang/Sema/AttrSpellingListIndex.inc"
157 
158 }
159 
161  unsigned NumArgs : 4;
162  unsigned OptArgs : 4;
163  unsigned HasCustomParsing : 1;
164  unsigned IsTargetSpecific : 1;
165  unsigned IsType : 1;
166  unsigned IsStmt : 1;
167  unsigned IsKnownToGCC : 1;
169 
170  bool (*DiagAppertainsToDecl)(Sema &S, const AttributeList &Attr,
171  const Decl *);
172  bool (*DiagLangOpts)(Sema &S, const AttributeList &Attr);
173  bool (*ExistsInTarget)(const TargetInfo &Target);
174  unsigned (*SpellingIndexToSemanticSpelling)(const AttributeList &Attr);
175  void (*GetPragmaAttributeMatchRules)(
177  const LangOptions &LangOpts);
178 };
179 
180 namespace {
181 
182 #include "clang/Sema/AttrParsedAttrImpl.inc"
183 
184 } // namespace
185 
186 static const ParsedAttrInfo &getInfo(const AttributeList &A) {
187  return AttrInfoMap[A.getKind()];
188 }
189 
190 unsigned AttributeList::getMinArgs() const {
191  return getInfo(*this).NumArgs;
192 }
193 
194 unsigned AttributeList::getMaxArgs() const {
195  return getMinArgs() + getInfo(*this).OptArgs;
196 }
197 
199  return getInfo(*this).HasCustomParsing;
200 }
201 
203  return getInfo(*this).DiagAppertainsToDecl(S, *this, D);
204 }
205 
207  attr::SubjectMatchRule MatchRule) const {
208  return checkAttributeMatchRuleAppliesTo(D, MatchRule);
209 }
210 
212  const LangOptions &LangOpts,
213  SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &MatchRules)
214  const {
215  return getInfo(*this).GetPragmaAttributeMatchRules(MatchRules, LangOpts);
216 }
217 
219  return getInfo(*this).DiagLangOpts(S, *this);
220 }
221 
223  return getInfo(*this).IsTargetSpecific;
224 }
225 
227  return getInfo(*this).IsType;
228 }
229 
231  return getInfo(*this).IsStmt;
232 }
233 
234 bool AttributeList::existsInTarget(const TargetInfo &Target) const {
235  return getInfo(*this).ExistsInTarget(Target);
236 }
237 
239  return getInfo(*this).IsKnownToGCC;
240 }
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 appliesToDecl(const Decl *D, attr::SubjectMatchRule MatchRule) const
bool hasCustomParsing() const
bool(* DiagAppertainsToDecl)(Sema &S, const AttributeList &Attr, const Decl *)
llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion
A union of the various pointer types that can be passed to an AttributeList as an argument...
Definition: AttributeList.h:92
bool isSupportedByPragmaAttribute() const
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
IdentifierInfo * Ident
Definition: AttributeList.h:84
static IdentifierLoc * create(ASTContext &Ctx, SourceLocation Loc, IdentifierInfo *Ident)
bool(* ExistsInTarget)(const TargetInfo &Target)
SourceLocation Loc
Definition: AttributeList.h:83
One of these records is kept for each identifier that is lexed.
Kind getKind() const
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:150
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:50
static const ParsedAttrInfo & getInfo(const AttributeList &A)
void getMatchRules(const LangOptions &LangOpts, SmallVectorImpl< std::pair< attr::SubjectMatchRule, bool >> &MatchRules) const
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:40
unsigned getAttributeSpellingListIndex() const
Get an index into the attribute spelling list defined in Attr.td.
bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:276
Exposes information about the current target.
Definition: TargetInfo.h:54
unsigned HasCustomParsing
unsigned(* SpellingIndexToSemanticSpelling)(const AttributeList &Attr)
unsigned IsSupportedByPragmaAttribute
bool isKnownToGCC() const
#define bool
Definition: stdbool.h:31
unsigned IsKnownToGCC
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
bool existsInTarget(const TargetInfo &Target) const
Wraps an identifier and optional source location for the identifier.
Definition: AttributeList.h:82
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 ...
bool(* DiagLangOpts)(Sema &S, const AttributeList &Attr)
Encodes a location in the source.
bool hasVariadicArg() const
StringRef getName() const
Return the actual identifier string.
Dataflow Directional Tag Classes.
unsigned IsTargetSpecific
bool diagnoseLangOpts(class Sema &S) const
bool isTargetSpecificAttr() const
void(* GetPragmaAttributeMatchRules)(llvm::SmallVectorImpl< std::pair< attr::SubjectMatchRule, bool >> &Rules, const LangOptions &LangOpts)
Syntax
The style used to specify an attribute.
static StringRef normalizeAttrName(StringRef AttrName, StringRef ScopeName, AttributeList::Syntax SyntaxUsed)
unsigned getMaxArgs() const
The required allocation size of an availability attribute, which we want to ensure is a multiple of s...
A factory, from which one makes pools, from which one creates individual attributes which are dealloc...
unsigned getMinArgs() const
Defines the clang::TargetInfo interface.
static size_t getFreeListIndexForSize(size_t size)
Attr - This represents one attribute.
Definition: Attr.h:43
AttributeList - Represents a syntactic attribute.