clang  6.0.0svn
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 ||
118  SyntaxUsed == AttributeList::AS_C2x) && ScopeName == "gnu");
119  if (IsGNU && AttrName.size() >= 4 && AttrName.startswith("__") &&
120  AttrName.endswith("__"))
121  AttrName = AttrName.slice(2, AttrName.size() - 2);
122 
123  return AttrName;
124 }
125 
127  const IdentifierInfo *ScopeName,
128  Syntax SyntaxUsed) {
129  StringRef AttrName = Name->getName();
130 
131  SmallString<64> FullName;
132  if (ScopeName)
133  FullName += ScopeName->getName();
134 
135  AttrName = normalizeAttrName(AttrName, FullName, SyntaxUsed);
136 
137  // Ensure that in the case of C++11 attributes, we look for '::foo' if it is
138  // unscoped.
139  if (ScopeName || SyntaxUsed == AS_CXX11 || SyntaxUsed == AS_C2x)
140  FullName += "::";
141  FullName += AttrName;
142 
143  return ::getAttrKind(FullName, SyntaxUsed);
144 }
145 
147  // Both variables will be used in tablegen generated
148  // attribute spell list index matching code.
149  StringRef Scope = ScopeName ? ScopeName->getName() : "";
150  StringRef Name = normalizeAttrName(AttrName->getName(), Scope,
151  (AttributeList::Syntax)SyntaxUsed);
152 
153 #include "clang/Sema/AttrSpellingListIndex.inc"
154 
155 }
156 
158  unsigned NumArgs : 4;
159  unsigned OptArgs : 4;
160  unsigned HasCustomParsing : 1;
161  unsigned IsTargetSpecific : 1;
162  unsigned IsType : 1;
163  unsigned IsStmt : 1;
164  unsigned IsKnownToGCC : 1;
166 
167  bool (*DiagAppertainsToDecl)(Sema &S, const AttributeList &Attr,
168  const Decl *);
169  bool (*DiagLangOpts)(Sema &S, const AttributeList &Attr);
170  bool (*ExistsInTarget)(const TargetInfo &Target);
171  unsigned (*SpellingIndexToSemanticSpelling)(const AttributeList &Attr);
172  void (*GetPragmaAttributeMatchRules)(
174  const LangOptions &LangOpts);
175 };
176 
177 namespace {
178  #include "clang/Sema/AttrParsedAttrImpl.inc"
179 }
180 
181 static const ParsedAttrInfo &getInfo(const AttributeList &A) {
182  return AttrInfoMap[A.getKind()];
183 }
184 
185 unsigned AttributeList::getMinArgs() const {
186  return getInfo(*this).NumArgs;
187 }
188 
189 unsigned AttributeList::getMaxArgs() const {
190  return getMinArgs() + getInfo(*this).OptArgs;
191 }
192 
194  return getInfo(*this).HasCustomParsing;
195 }
196 
198  return getInfo(*this).DiagAppertainsToDecl(S, *this, D);
199 }
200 
202  attr::SubjectMatchRule MatchRule) const {
203  return checkAttributeMatchRuleAppliesTo(D, MatchRule);
204 }
205 
207  const LangOptions &LangOpts,
208  SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &MatchRules)
209  const {
210  return getInfo(*this).GetPragmaAttributeMatchRules(MatchRules, LangOpts);
211 }
212 
214  return getInfo(*this).DiagLangOpts(S, *this);
215 }
216 
218  return getInfo(*this).IsTargetSpecific;
219 }
220 
222  return getInfo(*this).IsType;
223 }
224 
226  return getInfo(*this).IsStmt;
227 }
228 
229 bool AttributeList::existsInTarget(const TargetInfo &Target) const {
230  return getInfo(*this).ExistsInTarget(Target);
231 }
232 
234  return getInfo(*this).IsKnownToGCC;
235 }
236 
239 }
240 
242  return getInfo(*this).SpellingIndexToSemanticSpelling(*this);
243 }
244 
246  // If the attribute has the maximum number of optional arguments, we will
247  // claim that as being variadic. If we someday get an attribute that
248  // legitimately bumps up against that maximum, we can use another bit to track
249  // whether it's truly variadic or not.
250  return getInfo(*this).OptArgs == 15;
251 }
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 *)
bool isSupportedByPragmaAttribute() const
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
Defines the C++ template declaration subclasses.
IdentifierInfo * Ident
Definition: AttributeList.h:75
static IdentifierLoc * create(ASTContext &Ctx, SourceLocation Loc, IdentifierInfo *Ident)
bool(* ExistsInTarget)(const TargetInfo &Target)
SourceLocation Loc
Definition: AttributeList.h:74
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.
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:149
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)
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:39
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:274
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:73
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.
Definition: AttributeList.h:98
static StringRef normalizeAttrName(StringRef AttrName, StringRef ScopeName, AttributeList::Syntax SyntaxUsed)
unsigned getMaxArgs() const
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
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.
Definition: AttributeList.h:95