clang  3.9.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"
20 #include "clang/Basic/TargetInfo.h"
22 #include "llvm/ADT/SmallString.h"
23 #include "llvm/ADT/StringSwitch.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, llvm::AlignOf<AttributeFactory>::Alignment);
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 
165  bool (*DiagAppertainsToDecl)(Sema &S, const AttributeList &Attr,
166  const Decl *);
167  bool (*DiagLangOpts)(Sema &S, const AttributeList &Attr);
168  bool (*ExistsInTarget)(const TargetInfo &Target);
169  unsigned (*SpellingIndexToSemanticSpelling)(const AttributeList &Attr);
170 };
171 
172 namespace {
173  #include "clang/Sema/AttrParsedAttrImpl.inc"
174 }
175 
176 static const ParsedAttrInfo &getInfo(const AttributeList &A) {
177  return AttrInfoMap[A.getKind()];
178 }
179 
180 unsigned AttributeList::getMinArgs() const {
181  return getInfo(*this).NumArgs;
182 }
183 
184 unsigned AttributeList::getMaxArgs() const {
185  return getMinArgs() + getInfo(*this).OptArgs;
186 }
187 
189  return getInfo(*this).HasCustomParsing;
190 }
191 
193  return getInfo(*this).DiagAppertainsToDecl(S, *this, D);
194 }
195 
197  return getInfo(*this).DiagLangOpts(S, *this);
198 }
199 
201  return getInfo(*this).IsTargetSpecific;
202 }
203 
205  return getInfo(*this).IsType;
206 }
207 
209  return getInfo(*this).IsStmt;
210 }
211 
212 bool AttributeList::existsInTarget(const TargetInfo &Target) const {
213  return getInfo(*this).ExistsInTarget(Target);
214 }
215 
217  return getInfo(*this).IsKnownToGCC;
218 }
219 
221  return getInfo(*this).SpellingIndexToSemanticSpelling(*this);
222 }
223 
225  // If the attribute has the maximum number of optional arguments, we will
226  // claim that as being variadic. If we someday get an attribute that
227  // legitimately bumps up against that maximum, we can use another bit to track
228  // whether it's truly variadic or not.
229  return getInfo(*this).OptArgs == 15;
230 }
Defines the clang::ASTContext interface.
bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const
unsigned getSemanticSpelling() const
If the parsed attribute has a semantic equivalent, and it would have a semantic Spelling enumeration ...
Defines the C++ template declaration subclasses.
IdentifierInfo * Ident
Definition: AttributeList.h:74
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:73
One of these records is kept for each identifier that is lexed.
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
Definition: Type.h:4549
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:82
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:92
bool hasVariadicArg() const
unsigned(* SpellingIndexToSemanticSpelling)(const AttributeList &Attr)
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:263
Kind getKind() const
Exposes information about the current target.
StringRef getName() const
Return the actual identifier string.
unsigned HasCustomParsing
#define bool
Definition: stdbool.h:31
unsigned IsKnownToGCC
Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.
class LLVM_ALIGNAS(8) TemplateSpecializationType unsigned NumArgs
Represents a type template specialization; the template must be a class template, a type alias templa...
Definition: Type.h:4154
bool existsInTarget(const TargetInfo &Target) const
Wraps an identifier and optional source location for the identifier.
Definition: AttributeList.h:72
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.
The required allocation size of an availability attribute, which we want to ensure is a multiple of s...
unsigned getMinArgs() const
bool diagnoseLangOpts(class Sema &S) const
unsigned IsTargetSpecific
Syntax
The style used to specify an attribute.
Definition: AttributeList.h:97
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
Defines the clang::TargetInfo interface.
static size_t getFreeListIndexForSize(size_t size)
Attr - This represents one attribute.
Definition: Attr.h:45
AttributeList - Represents a syntactic attribute.
Definition: AttributeList.h:94