clang  5.0.0
AttributeList.cpp
Go to the documentation of this file.
1 //===--- AttributeList.cpp --------------------------------------*- C++ -*-===//
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"
16 #include "clang/AST/DeclCXX.h"
17 #include "clang/AST/DeclTemplate.h"
18 #include "clang/AST/Expr.h"
21 #include "clang/Basic/TargetInfo.h"
23 #include "llvm/ADT/SmallString.h"
24 using namespace clang;
25 
27  IdentifierInfo *Ident) {
28  IdentifierLoc *Result = new (Ctx) IdentifierLoc;
29  Result->Loc = Loc;
30  Result->Ident = Ident;
31  return Result;
32 }
33 
34 size_t AttributeList::allocated_size() const {
35  if (IsAvailability) return AttributeFactory::AvailabilityAllocSize;
36  else if (IsTypeTagForDatatype)
38  else if (IsProperty)
40  return (sizeof(AttributeList) + NumArgs * sizeof(ArgsUnion));
41 }
42 
44  // Go ahead and configure all the inline capacity. This is just a memset.
45  FreeLists.resize(InlineFreeListsCapacity);
46 }
48 
49 static size_t getFreeListIndexForSize(size_t size) {
50  assert(size >= sizeof(AttributeList));
51  assert((size % sizeof(void*)) == 0);
52  return ((size - sizeof(AttributeList)) / sizeof(void*));
53 }
54 
55 void *AttributeFactory::allocate(size_t size) {
56  // Check for a previously reclaimed attribute.
57  size_t index = getFreeListIndexForSize(size);
58  if (index < FreeLists.size()) {
59  if (AttributeList *attr = FreeLists[index]) {
60  FreeLists[index] = attr->NextInPool;
61  return attr;
62  }
63  }
64 
65  // Otherwise, allocate something new.
66  return Alloc.Allocate(size, alignof(AttributeFactory));
67 }
68 
69 void AttributeFactory::reclaimPool(AttributeList *cur) {
70  assert(cur && "reclaiming empty pool!");
71  do {
72  // Read this here, because we're going to overwrite NextInPool
73  // when we toss 'cur' into the appropriate queue.
74  AttributeList *next = cur->NextInPool;
75 
76  size_t size = cur->allocated_size();
77  size_t freeListIndex = getFreeListIndexForSize(size);
78 
79  // Expand FreeLists to the appropriate size, if required.
80  if (freeListIndex >= FreeLists.size())
81  FreeLists.resize(freeListIndex+1);
82 
83  // Add 'cur' to the appropriate free-list.
84  cur->NextInPool = FreeLists[freeListIndex];
85  FreeLists[freeListIndex] = cur;
86 
87  cur = next;
88  } while (cur);
89 }
90 
91 void AttributePool::takePool(AttributeList *pool) {
92  assert(pool);
93 
94  // Fast path: this pool is empty.
95  if (!Head) {
96  Head = pool;
97  return;
98  }
99 
100  // Reverse the pool onto the current head. This optimizes for the
101  // pattern of pulling a lot of pools into a single pool.
102  do {
103  AttributeList *next = pool->NextInPool;
104  pool->NextInPool = Head;
105  Head = pool;
106  pool = next;
107  } while (pool);
108 }
109 
110 #include "clang/Sema/AttrParsedAttrKinds.inc"
111 
112 static StringRef normalizeAttrName(StringRef AttrName, StringRef ScopeName,
113  AttributeList::Syntax SyntaxUsed) {
114  // Normalize the attribute name, __foo__ becomes foo. This is only allowable
115  // for GNU attributes.
116  bool IsGNU = SyntaxUsed == AttributeList::AS_GNU ||
117  (SyntaxUsed == AttributeList::AS_CXX11 && ScopeName == "gnu");
118  if (IsGNU && AttrName.size() >= 4 && AttrName.startswith("__") &&
119  AttrName.endswith("__"))
120  AttrName = AttrName.slice(2, AttrName.size() - 2);
121 
122  return AttrName;
123 }
124 
126  const IdentifierInfo *ScopeName,
127  Syntax SyntaxUsed) {
128  StringRef AttrName = Name->getName();
129 
130  SmallString<64> FullName;
131  if (ScopeName)
132  FullName += ScopeName->getName();
133 
134  AttrName = normalizeAttrName(AttrName, FullName, SyntaxUsed);
135 
136  // Ensure that in the case of C++11 attributes, we look for '::foo' if it is
137  // unscoped.
138  if (ScopeName || SyntaxUsed == AS_CXX11)
139  FullName += "::";
140  FullName += AttrName;
141 
142  return ::getAttrKind(FullName, SyntaxUsed);
143 }
144 
146  // Both variables will be used in tablegen generated
147  // attribute spell list index matching code.
148  StringRef Scope = ScopeName ? ScopeName->getName() : "";
149  StringRef Name = normalizeAttrName(AttrName->getName(), Scope,
150  (AttributeList::Syntax)SyntaxUsed);
151 
152 #include "clang/Sema/AttrSpellingListIndex.inc"
153 
154 }
155 
157  unsigned NumArgs : 4;
158  unsigned OptArgs : 4;
159  unsigned HasCustomParsing : 1;
160  unsigned IsTargetSpecific : 1;
161  unsigned IsType : 1;
162  unsigned IsStmt : 1;
163  unsigned IsKnownToGCC : 1;
164  unsigned IsSupportedByPragmaAttribute : 1;
165 
166  bool (*DiagAppertainsToDecl)(Sema &S, const AttributeList &Attr,
167  const Decl *);
168  bool (*DiagLangOpts)(Sema &S, const AttributeList &Attr);
169  bool (*ExistsInTarget)(const TargetInfo &Target);
170  unsigned (*SpellingIndexToSemanticSpelling)(const AttributeList &Attr);
171  void (*GetPragmaAttributeMatchRules)(
173  const LangOptions &LangOpts);
174 };
175 
176 namespace {
177  #include "clang/Sema/AttrParsedAttrImpl.inc"
178 }
179 
180 static const ParsedAttrInfo &getInfo(const AttributeList &A) {
181  return AttrInfoMap[A.getKind()];
182 }
183 
184 unsigned AttributeList::getMinArgs() const {
185  return getInfo(*this).NumArgs;
186 }
187 
188 unsigned AttributeList::getMaxArgs() const {
189  return getMinArgs() + getInfo(*this).OptArgs;
190 }
191 
193  return getInfo(*this).HasCustomParsing;
194 }
195 
197  return getInfo(*this).DiagAppertainsToDecl(S, *this, D);
198 }
199 
201  attr::SubjectMatchRule MatchRule) const {
202  return checkAttributeMatchRuleAppliesTo(D, MatchRule);
203 }
204 
206  const LangOptions &LangOpts,
207  SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &MatchRules)
208  const {
209  return getInfo(*this).GetPragmaAttributeMatchRules(MatchRules, LangOpts);
210 }
211 
213  return getInfo(*this).DiagLangOpts(S, *this);
214 }
215 
217  return getInfo(*this).IsTargetSpecific;
218 }
219 
221  return getInfo(*this).IsType;
222 }
223 
225  return getInfo(*this).IsStmt;
226 }
227 
228 bool AttributeList::existsInTarget(const TargetInfo &Target) const {
229  return getInfo(*this).ExistsInTarget(Target);
230 }
231 
233  return getInfo(*this).IsKnownToGCC;
234 }
235 
238 }
239 
241  return getInfo(*this).SpellingIndexToSemanticSpelling(*this);
242 }
243 
245  // If the attribute has the maximum number of optional arguments, we will
246  // claim that as being variadic. If we someday get an attribute that
247  // legitimately bumps up against that maximum, we can use another bit to track
248  // whether it's truly variadic or not.
249  return getInfo(*this).OptArgs == 15;
250 }
Defines the clang::ASTContext interface.
bool isSupportedByPragmaAttribute() const
The required allocation size of an availability attribute, which we want to ensure is a multiple of s...
bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const
bool appliesToDecl(const Decl *D, attr::SubjectMatchRule MatchRule) const
unsigned getSemanticSpelling() const
If the parsed attribute has a semantic equivalent, and it would have a semantic Spelling enumeration ...
void getMatchRules(const LangOptions &LangOpts, SmallVectorImpl< std::pair< attr::SubjectMatchRule, bool >> &MatchRules) const
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:81
Defines the C++ template declaration subclasses.
IdentifierInfo * Ident
Definition: AttributeList.h:75
void(* GetPragmaAttributeMatchRules)(llvm::SmallVectorImpl< std::pair< attr::SubjectMatchRule, bool >> &Rules, const LangOptions &LangOpts)
static IdentifierLoc * create(ASTContext &Ctx, SourceLocation Loc, IdentifierInfo *Ident)
bool hasCustomParsing() const
bool(* ExistsInTarget)(const TargetInfo &Target)
bool(* DiagLangOpts)(Sema &S, const AttributeList &Attr)
SourceLocation Loc
Definition: AttributeList.h:74
One of these records is kept for each identifier that is lexed.
SubjectMatchRule
A list of all the recognized kinds of attributes.
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:83
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:128
bool hasVariadicArg() const
unsigned(* SpellingIndexToSemanticSpelling)(const AttributeList &Attr)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:48
static const ParsedAttrInfo & getInfo(const AttributeList &A)
bool(* DiagAppertainsToDecl)(Sema &S, const AttributeList &Attr, const Decl *)
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:39
bool isStmtAttr() const
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:269
Kind getKind() const
Exposes information about the current target.
Definition: TargetInfo.h:54
StringRef getName() const
Return the actual identifier string.
unsigned HasCustomParsing
unsigned IsSupportedByPragmaAttribute
#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:73
The result type of a method or function.
unsigned getAttributeSpellingListIndex() const
Get an index into the attribute spelling list defined in Attr.td.
Encodes a location in the source.
unsigned getMinArgs() const
bool diagnoseLangOpts(class Sema &S) const
unsigned IsTargetSpecific
StringRef Name
Definition: USRFinder.cpp:123
Syntax
The style used to specify an attribute.
Definition: AttributeList.h:98
bool isKnownToGCC() const
unsigned getMaxArgs() const
static StringRef normalizeAttrName(StringRef AttrName, StringRef ScopeName, AttributeList::Syntax SyntaxUsed)
bool isTypeAttr() const
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
bool isTargetSpecificAttr() const
A factory, from which one makes pools, from which one creates individual attributes which are dealloc...
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.
Definition: AttributeList.h:95