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  else if (HasParsedType)
44  return sizeof(AttributeList) + sizeof(void *);
45  return (sizeof(AttributeList) + NumArgs * sizeof(ArgsUnion));
46 }
47 
49  // Go ahead and configure all the inline capacity. This is just a memset.
50  FreeLists.resize(InlineFreeListsCapacity);
51 }
53 
54 static size_t getFreeListIndexForSize(size_t size) {
55  assert(size >= sizeof(AttributeList));
56  assert((size % sizeof(void*)) == 0);
57  return ((size - sizeof(AttributeList)) / sizeof(void*));
58 }
59 
60 void *AttributeFactory::allocate(size_t size) {
61  // Check for a previously reclaimed attribute.
62  size_t index = getFreeListIndexForSize(size);
63  if (index < FreeLists.size() && !FreeLists[index].empty()) {
64  AttributeList *attr = FreeLists[index].back();
65  FreeLists[index].pop_back();
66  return attr;
67  }
68 
69  // Otherwise, allocate something new.
70  return Alloc.Allocate(size, alignof(AttributeFactory));
71 }
72 
73 void AttributeFactory::deallocate(AttributeList *Attr) {
74  size_t size = Attr->allocated_size();
75  size_t freeListIndex = getFreeListIndexForSize(size);
76 
77  // Expand FreeLists to the appropriate size, if required.
78  if (freeListIndex >= FreeLists.size())
79  FreeLists.resize(freeListIndex + 1);
80 
81 #if !NDEBUG
82  // In debug mode, zero out the attribute to help find memory overwriting.
83  memset(Attr, 0, size);
84 #endif
85 
86  // Add 'Attr' to the appropriate free-list.
87  FreeLists[freeListIndex].push_back(Attr);
88 }
89 
90 void AttributeFactory::reclaimPool(AttributePool &cur) {
91  for (AttributeList *AL : cur.Attrs)
92  deallocate(AL);
93 }
94 
95 void AttributePool::takePool(AttributePool &pool) {
96  Attrs.insert(Attrs.end(), pool.Attrs.begin(), pool.Attrs.end());
97  pool.Attrs.clear();
98 }
99 
100 #include "clang/Sema/AttrParsedAttrKinds.inc"
101 
102 static StringRef normalizeAttrName(StringRef AttrName, StringRef ScopeName,
103  AttributeList::Syntax SyntaxUsed) {
104  // Normalize the attribute name, __foo__ becomes foo. This is only allowable
105  // for GNU attributes.
106  bool IsGNU = SyntaxUsed == AttributeList::AS_GNU ||
107  ((SyntaxUsed == AttributeList::AS_CXX11 ||
108  SyntaxUsed == AttributeList::AS_C2x) && ScopeName == "gnu");
109  if (IsGNU && AttrName.size() >= 4 && AttrName.startswith("__") &&
110  AttrName.endswith("__"))
111  AttrName = AttrName.slice(2, AttrName.size() - 2);
112 
113  return AttrName;
114 }
115 
117  const IdentifierInfo *ScopeName,
118  Syntax SyntaxUsed) {
119  StringRef AttrName = Name->getName();
120 
121  SmallString<64> FullName;
122  if (ScopeName)
123  FullName += ScopeName->getName();
124 
125  AttrName = normalizeAttrName(AttrName, FullName, SyntaxUsed);
126 
127  // Ensure that in the case of C++11 attributes, we look for '::foo' if it is
128  // unscoped.
129  if (ScopeName || SyntaxUsed == AS_CXX11 || SyntaxUsed == AS_C2x)
130  FullName += "::";
131  FullName += AttrName;
132 
133  return ::getAttrKind(FullName, SyntaxUsed);
134 }
135 
137  // Both variables will be used in tablegen generated
138  // attribute spell list index matching code.
139  StringRef Scope = ScopeName ? ScopeName->getName() : "";
140  StringRef Name = normalizeAttrName(AttrName->getName(), Scope,
141  (AttributeList::Syntax)SyntaxUsed);
142 
143 #include "clang/Sema/AttrSpellingListIndex.inc"
144 
145 }
146 
148  unsigned NumArgs : 4;
149  unsigned OptArgs : 4;
150  unsigned HasCustomParsing : 1;
151  unsigned IsTargetSpecific : 1;
152  unsigned IsType : 1;
153  unsigned IsStmt : 1;
154  unsigned IsKnownToGCC : 1;
156 
157  bool (*DiagAppertainsToDecl)(Sema &S, const AttributeList &Attr,
158  const Decl *);
159  bool (*DiagLangOpts)(Sema &S, const AttributeList &Attr);
160  bool (*ExistsInTarget)(const TargetInfo &Target);
161  unsigned (*SpellingIndexToSemanticSpelling)(const AttributeList &Attr);
162  void (*GetPragmaAttributeMatchRules)(
164  const LangOptions &LangOpts);
165 };
166 
167 namespace {
168 
169 #include "clang/Sema/AttrParsedAttrImpl.inc"
170 
171 } // namespace
172 
173 static const ParsedAttrInfo &getInfo(const AttributeList &A) {
174  return AttrInfoMap[A.getKind()];
175 }
176 
177 unsigned AttributeList::getMinArgs() const {
178  return getInfo(*this).NumArgs;
179 }
180 
181 unsigned AttributeList::getMaxArgs() const {
182  return getMinArgs() + getInfo(*this).OptArgs;
183 }
184 
186  return getInfo(*this).HasCustomParsing;
187 }
188 
190  return getInfo(*this).DiagAppertainsToDecl(S, *this, D);
191 }
192 
194  attr::SubjectMatchRule MatchRule) const {
195  return checkAttributeMatchRuleAppliesTo(D, MatchRule);
196 }
197 
199  const LangOptions &LangOpts,
200  SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &MatchRules)
201  const {
202  return getInfo(*this).GetPragmaAttributeMatchRules(MatchRules, LangOpts);
203 }
204 
206  return getInfo(*this).DiagLangOpts(S, *this);
207 }
208 
210  return getInfo(*this).IsTargetSpecific;
211 }
212 
214  return getInfo(*this).IsType;
215 }
216 
218  return getInfo(*this).IsStmt;
219 }
220 
221 bool AttributeList::existsInTarget(const TargetInfo &Target) const {
222  return getInfo(*this).ExistsInTarget(Target);
223 }
224 
226  return getInfo(*this).IsKnownToGCC;
227 }
228 
231 }
232 
234  return getInfo(*this).SpellingIndexToSemanticSpelling(*this);
235 }
236 
238  // If the attribute has the maximum number of optional arguments, we will
239  // claim that as being variadic. If we someday get an attribute that
240  // legitimately bumps up against that maximum, we can use another bit to track
241  // whether it's truly variadic or not.
242  return getInfo(*this).OptArgs == 15;
243 }
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:93
bool isSupportedByPragmaAttribute() const
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
IdentifierInfo * Ident
Definition: AttributeList.h:85
static IdentifierLoc * create(ASTContext &Ctx, SourceLocation Loc, IdentifierInfo *Ident)
bool(* ExistsInTarget)(const TargetInfo &Target)
SourceLocation Loc
Definition: AttributeList.h:84
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
__DEVICE__ void * memset(void *__a, int __b, size_t __c)
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:277
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:83
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.