clang  6.0.0svn
AttributeList.h
Go to the documentation of this file.
1 //===--- AttributeList.h - Parsed attribute sets ----------------*- 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, which is used to collect
11 // parsed attributes.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CLANG_SEMA_ATTRIBUTELIST_H
16 #define LLVM_CLANG_SEMA_ATTRIBUTELIST_H
17 
20 #include "clang/Basic/TargetInfo.h"
22 #include "clang/Sema/Ownership.h"
23 #include "llvm/ADT/PointerUnion.h"
24 #include "llvm/ADT/SmallVector.h"
25 #include "llvm/Support/Allocator.h"
26 #include <cassert>
27 
28 namespace clang {
29  class ASTContext;
30  class IdentifierInfo;
31  class Expr;
32 
33 /// \brief Represents information about a change in availability for
34 /// an entity, which is part of the encoding of the 'availability'
35 /// attribute.
37  /// \brief The location of the keyword indicating the kind of change.
39 
40  /// \brief The version number at which the change occurred.
42 
43  /// \brief The source range covering the version number.
45 
46  /// \brief Determine whether this availability change is valid.
47  bool isValid() const { return !Version.empty(); }
48 };
49 
50 namespace {
52  IntroducedSlot, DeprecatedSlot, ObsoletedSlot, NumAvailabilitySlots
53 };
54 
55 /// Describes the trailing object for Availability attribute in AttributeList.
56 struct AvailabilityData {
57  AvailabilityChange Changes[NumAvailabilitySlots];
58  SourceLocation StrictLoc;
59  const Expr *Replacement;
60  AvailabilityData(const AvailabilityChange &Introduced,
61  const AvailabilityChange &Deprecated,
62  const AvailabilityChange &Obsoleted,
63  SourceLocation Strict, const Expr *ReplaceExpr)
64  : StrictLoc(Strict), Replacement(ReplaceExpr) {
65  Changes[IntroducedSlot] = Introduced;
66  Changes[DeprecatedSlot] = Deprecated;
67  Changes[ObsoletedSlot] = Obsoleted;
68  }
69 };
70 }
71 
72 /// \brief Wraps an identifier and optional source location for the identifier.
73 struct IdentifierLoc {
76 
78  IdentifierInfo *Ident);
79 };
80 
81 /// \brief A union of the various pointer types that can be passed to an
82 /// AttributeList as an argument.
83 typedef llvm::PointerUnion<Expr*, IdentifierLoc*> ArgsUnion;
85 
86 /// AttributeList - Represents a syntactic attribute.
87 ///
88 /// For a GNU attribute, there are four forms of this construct:
89 ///
90 /// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused.
91 /// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused.
92 /// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used.
93 /// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
94 ///
95 class AttributeList { // TODO: This should really be called ParsedAttribute
96 public:
97  /// The style used to specify an attribute.
98  enum Syntax {
99  /// __attribute__((...))
101  /// [[...]]
103  /// [[...]]
105  /// __declspec(...)
107  /// [uuid("...")] class Foo
109  /// __ptr16, alignas(...), etc.
111  /// #pragma ...
113  // Note TableGen depends on the order above. Do not add or change the order
114  // without adding related code to TableGen/ClangAttrEmitter.cpp.
115  /// Context-sensitive version of a keyword attribute.
117  };
118 
119 private:
120  IdentifierInfo *AttrName;
121  IdentifierInfo *ScopeName;
122  SourceRange AttrRange;
123  SourceLocation ScopeLoc;
124  SourceLocation EllipsisLoc;
125 
126  unsigned AttrKind : 16;
127 
128  /// The number of expression arguments this attribute has.
129  /// The expressions themselves are stored after the object.
130  unsigned NumArgs : 16;
131 
132  /// Corresponds to the Syntax enum.
133  unsigned SyntaxUsed : 3;
134 
135  /// True if already diagnosed as invalid.
136  mutable unsigned Invalid : 1;
137 
138  /// True if this attribute was used as a type attribute.
139  mutable unsigned UsedAsTypeAttr : 1;
140 
141  /// True if this has the extra information associated with an
142  /// availability attribute.
143  unsigned IsAvailability : 1;
144 
145  /// True if this has extra information associated with a
146  /// type_tag_for_datatype attribute.
147  unsigned IsTypeTagForDatatype : 1;
148 
149  /// True if this has extra information associated with a
150  /// Microsoft __delcspec(property) attribute.
151  unsigned IsProperty : 1;
152 
153  /// True if this has a ParsedType
154  unsigned HasParsedType : 1;
155 
156  /// True if the processing cache is valid.
157  mutable unsigned HasProcessingCache : 1;
158 
159  /// A cached value.
160  mutable unsigned ProcessingCache : 8;
161 
162  /// \brief The location of the 'unavailable' keyword in an
163  /// availability attribute.
164  SourceLocation UnavailableLoc;
165 
166  const Expr *MessageExpr;
167 
168  /// The next attribute in the current position.
169  AttributeList *NextInPosition;
170 
171  /// The next attribute allocated in the current Pool.
172  AttributeList *NextInPool;
173 
174  /// Arguments, if any, are stored immediately following the object.
175  ArgsUnion *getArgsBuffer() { return reinterpret_cast<ArgsUnion *>(this + 1); }
176  ArgsUnion const *getArgsBuffer() const {
177  return reinterpret_cast<ArgsUnion const *>(this + 1);
178  }
179 
180  /// Availability information is stored immediately following the arguments,
181  /// if any, at the end of the object.
182  AvailabilityData *getAvailabilityData() {
183  return reinterpret_cast<AvailabilityData*>(getArgsBuffer() + NumArgs);
184  }
185  const AvailabilityData *getAvailabilityData() const {
186  return reinterpret_cast<const AvailabilityData*>(getArgsBuffer() + NumArgs);
187  }
188 
189 public:
192  unsigned LayoutCompatible : 1;
193  unsigned MustBeNull : 1;
194  };
195  struct PropertyData {
198  : GetterId(getterId), SetterId(setterId) {}
199  };
200 
201 private:
202  /// Type tag information is stored immediately following the arguments, if
203  /// any, at the end of the object. They are mutually exlusive with
204  /// availability slots.
205  TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
206  return *reinterpret_cast<TypeTagForDatatypeData*>(getArgsBuffer()+NumArgs);
207  }
208 
209  const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
210  return *reinterpret_cast<const TypeTagForDatatypeData*>(getArgsBuffer()
211  + NumArgs);
212  }
213 
214  /// The type buffer immediately follows the object and are mutually exclusive
215  /// with arguments.
216  ParsedType &getTypeBuffer() {
217  return *reinterpret_cast<ParsedType *>(this + 1);
218  }
219 
220  const ParsedType &getTypeBuffer() const {
221  return *reinterpret_cast<const ParsedType *>(this + 1);
222  }
223 
224  /// The property data immediately follows the object is is mutually exclusive
225  /// with arguments.
226  PropertyData &getPropertyDataBuffer() {
227  assert(IsProperty);
228  return *reinterpret_cast<PropertyData*>(this + 1);
229  }
230 
231  const PropertyData &getPropertyDataBuffer() const {
232  assert(IsProperty);
233  return *reinterpret_cast<const PropertyData*>(this + 1);
234  }
235 
236  AttributeList(const AttributeList &) = delete;
237  void operator=(const AttributeList &) = delete;
238  void operator delete(void *) = delete;
239  ~AttributeList() = delete;
240 
241  size_t allocated_size() const;
242 
243  /// Constructor for attributes with expression arguments.
244  AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
245  IdentifierInfo *scopeName, SourceLocation scopeLoc,
246  ArgsUnion *args, unsigned numArgs,
247  Syntax syntaxUsed, SourceLocation ellipsisLoc)
248  : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
249  ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs),
250  SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false),
251  IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
252  HasParsedType(false), HasProcessingCache(false),
253  NextInPosition(nullptr), NextInPool(nullptr) {
254  if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion));
255  AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
256  }
257 
258  /// Constructor for availability attributes.
259  AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
260  IdentifierInfo *scopeName, SourceLocation scopeLoc,
261  IdentifierLoc *Parm, const AvailabilityChange &introduced,
262  const AvailabilityChange &deprecated,
263  const AvailabilityChange &obsoleted,
264  SourceLocation unavailable,
265  const Expr *messageExpr,
266  Syntax syntaxUsed, SourceLocation strict,
267  const Expr *replacementExpr)
268  : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
269  ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
270  Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
271  IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
272  HasProcessingCache(false), UnavailableLoc(unavailable),
273  MessageExpr(messageExpr), NextInPosition(nullptr), NextInPool(nullptr) {
274  ArgsUnion PVal(Parm);
275  memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
276  new (getAvailabilityData()) AvailabilityData(
277  introduced, deprecated, obsoleted, strict, replacementExpr);
278  AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
279  }
280 
281  /// Constructor for objc_bridge_related attributes.
282  AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
283  IdentifierInfo *scopeName, SourceLocation scopeLoc,
284  IdentifierLoc *Parm1,
285  IdentifierLoc *Parm2,
286  IdentifierLoc *Parm3,
287  Syntax syntaxUsed)
288  : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
289  ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(3), SyntaxUsed(syntaxUsed),
290  Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
291  IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
292  HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) {
293  ArgsUnion *Args = getArgsBuffer();
294  Args[0] = Parm1;
295  Args[1] = Parm2;
296  Args[2] = Parm3;
297  AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
298  }
299 
300  /// Constructor for type_tag_for_datatype attribute.
301  AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
302  IdentifierInfo *scopeName, SourceLocation scopeLoc,
303  IdentifierLoc *ArgKind, ParsedType matchingCType,
304  bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed)
305  : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
306  ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
307  Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
308  IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false),
309  HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) {
310  ArgsUnion PVal(ArgKind);
311  memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
312  TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
313  new (&ExtraData.MatchingCType) ParsedType(matchingCType);
314  ExtraData.LayoutCompatible = layoutCompatible;
315  ExtraData.MustBeNull = mustBeNull;
316  AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
317  }
318 
319  /// Constructor for attributes with a single type argument.
320  AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
321  IdentifierInfo *scopeName, SourceLocation scopeLoc,
322  ParsedType typeArg, Syntax syntaxUsed)
323  : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
324  ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
325  Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
326  IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true),
327  HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr){
328  new (&getTypeBuffer()) ParsedType(typeArg);
329  AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
330  }
331 
332  /// Constructor for microsoft __declspec(property) attribute.
333  AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
334  IdentifierInfo *scopeName, SourceLocation scopeLoc,
335  IdentifierInfo *getterId, IdentifierInfo *setterId,
336  Syntax syntaxUsed)
337  : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
338  ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
339  Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
340  IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false),
341  HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) {
342  new (&getPropertyDataBuffer()) PropertyData(getterId, setterId);
343  AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
344  }
345 
346  friend class AttributePool;
347  friend class AttributeFactory;
348 
349 public:
350  enum Kind {
351  #define PARSED_ATTR(NAME) AT_##NAME,
352  #include "clang/Sema/AttrParsedAttrList.inc"
353  #undef PARSED_ATTR
355  UnknownAttribute
356  };
357 
358  IdentifierInfo *getName() const { return AttrName; }
359  SourceLocation getLoc() const { return AttrRange.getBegin(); }
360  SourceRange getRange() const { return AttrRange; }
361 
362  bool hasScope() const { return ScopeName; }
363  IdentifierInfo *getScopeName() const { return ScopeName; }
364  SourceLocation getScopeLoc() const { return ScopeLoc; }
365 
366  bool hasParsedType() const { return HasParsedType; }
367 
368  /// Is this the Microsoft __declspec(property) attribute?
370  return IsProperty;
371  }
372 
373  bool isAlignasAttribute() const {
374  // FIXME: Use a better mechanism to determine this.
375  return getKind() == AT_Aligned && isKeywordAttribute();
376  }
377 
378  bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
379  bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; }
380  bool isCXX11Attribute() const {
381  return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
382  }
383  bool isC2xAttribute() const {
384  return SyntaxUsed == AS_C2x;
385  }
386  bool isKeywordAttribute() const {
387  return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
388  }
389 
391  return SyntaxUsed == AS_ContextSensitiveKeyword;
392  }
393 
394  bool isInvalid() const { return Invalid; }
395  void setInvalid(bool b = true) const { Invalid = b; }
396 
397  bool hasProcessingCache() const { return HasProcessingCache; }
398  unsigned getProcessingCache() const {
399  assert(hasProcessingCache());
400  return ProcessingCache;
401  }
402  void setProcessingCache(unsigned value) const {
403  ProcessingCache = value;
404  HasProcessingCache = true;
405  }
406 
407  bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
408  void setUsedAsTypeAttr() { UsedAsTypeAttr = true; }
409 
410  bool isPackExpansion() const { return EllipsisLoc.isValid(); }
411  SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
412 
413  Kind getKind() const { return Kind(AttrKind); }
414  static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope,
415  Syntax SyntaxUsed);
416 
417  AttributeList *getNext() const { return NextInPosition; }
418  void setNext(AttributeList *N) { NextInPosition = N; }
419 
420  /// getNumArgs - Return the number of actual arguments to this attribute.
421  unsigned getNumArgs() const { return NumArgs; }
422 
423  /// getArg - Return the specified argument.
424  ArgsUnion getArg(unsigned Arg) const {
425  assert(Arg < NumArgs && "Arg access out of range!");
426  return getArgsBuffer()[Arg];
427  }
428 
429  bool isArgExpr(unsigned Arg) const {
430  return Arg < NumArgs && getArg(Arg).is<Expr*>();
431  }
432  Expr *getArgAsExpr(unsigned Arg) const {
433  return getArg(Arg).get<Expr*>();
434  }
435 
436  bool isArgIdent(unsigned Arg) const {
437  return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>();
438  }
439  IdentifierLoc *getArgAsIdent(unsigned Arg) const {
440  return getArg(Arg).get<IdentifierLoc*>();
441  }
442 
444  assert(getKind() == AT_Availability && "Not an availability attribute");
445  return getAvailabilityData()->Changes[IntroducedSlot];
446  }
447 
449  assert(getKind() == AT_Availability && "Not an availability attribute");
450  return getAvailabilityData()->Changes[DeprecatedSlot];
451  }
452 
454  assert(getKind() == AT_Availability && "Not an availability attribute");
455  return getAvailabilityData()->Changes[ObsoletedSlot];
456  }
457 
459  assert(getKind() == AT_Availability && "Not an availability attribute");
460  return getAvailabilityData()->StrictLoc;
461  }
462 
464  assert(getKind() == AT_Availability && "Not an availability attribute");
465  return UnavailableLoc;
466  }
467 
468  const Expr * getMessageExpr() const {
469  assert(getKind() == AT_Availability && "Not an availability attribute");
470  return MessageExpr;
471  }
472 
473  const Expr *getReplacementExpr() const {
474  assert(getKind() == AT_Availability && "Not an availability attribute");
475  return getAvailabilityData()->Replacement;
476  }
477 
478  const ParsedType &getMatchingCType() const {
479  assert(getKind() == AT_TypeTagForDatatype &&
480  "Not a type_tag_for_datatype attribute");
481  return *getTypeTagForDatatypeDataSlot().MatchingCType;
482  }
483 
484  bool getLayoutCompatible() const {
485  assert(getKind() == AT_TypeTagForDatatype &&
486  "Not a type_tag_for_datatype attribute");
487  return getTypeTagForDatatypeDataSlot().LayoutCompatible;
488  }
489 
490  bool getMustBeNull() const {
491  assert(getKind() == AT_TypeTagForDatatype &&
492  "Not a type_tag_for_datatype attribute");
493  return getTypeTagForDatatypeDataSlot().MustBeNull;
494  }
495 
496  const ParsedType &getTypeArg() const {
497  assert(HasParsedType && "Not a type attribute");
498  return getTypeBuffer();
499  }
500 
501  const PropertyData &getPropertyData() const {
502  assert(isDeclspecPropertyAttribute() && "Not a __delcspec(property) attribute");
503  return getPropertyDataBuffer();
504  }
505 
506  /// \brief Get an index into the attribute spelling list
507  /// defined in Attr.td. This index is used by an attribute
508  /// to pretty print itself.
509  unsigned getAttributeSpellingListIndex() const;
510 
511  bool isTargetSpecificAttr() const;
512  bool isTypeAttr() const;
513  bool isStmtAttr() const;
514 
515  bool hasCustomParsing() const;
516  unsigned getMinArgs() const;
517  unsigned getMaxArgs() const;
518  bool hasVariadicArg() const;
519  bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const;
520  bool appliesToDecl(const Decl *D, attr::SubjectMatchRule MatchRule) const;
521  void getMatchRules(const LangOptions &LangOpts,
522  SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>>
523  &MatchRules) const;
524  bool diagnoseLangOpts(class Sema &S) const;
525  bool existsInTarget(const TargetInfo &Target) const;
526  bool isKnownToGCC() const;
527  bool isSupportedByPragmaAttribute() const;
528 
529  /// \brief If the parsed attribute has a semantic equivalent, and it would
530  /// have a semantic Spelling enumeration (due to having semantically-distinct
531  /// spelling variations), return the value of that semantic spelling. If the
532  /// parsed attribute does not have a semantic equivalent, or would not have
533  /// a Spelling enumeration, the value UINT_MAX is returned.
534  unsigned getSemanticSpelling() const;
535 };
536 
537 /// A factory, from which one makes pools, from which one creates
538 /// individual attributes which are deallocated with the pool.
539 ///
540 /// Note that it's tolerably cheap to create and destroy one of
541 /// these as long as you don't actually allocate anything in it.
543 public:
544  enum {
545  /// The required allocation size of an availability attribute,
546  /// which we want to ensure is a multiple of sizeof(void*).
547  AvailabilityAllocSize =
548  sizeof(AttributeList)
549  + ((sizeof(AvailabilityData) + sizeof(void*) + sizeof(ArgsUnion) - 1)
550  / sizeof(void*) * sizeof(void*)),
551  TypeTagForDatatypeAllocSize =
552  sizeof(AttributeList)
553  + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) +
554  sizeof(ArgsUnion) - 1)
555  / sizeof(void*) * sizeof(void*),
556  PropertyAllocSize =
557  sizeof(AttributeList)
558  + (sizeof(AttributeList::PropertyData) + sizeof(void *) - 1)
559  / sizeof(void*) * sizeof(void*)
560  };
561 
562 private:
563  enum {
564  /// The number of free lists we want to be sure to support
565  /// inline. This is just enough that availability attributes
566  /// don't surpass it. It's actually very unlikely we'll see an
567  /// attribute that needs more than that; on x86-64 you'd need 10
568  /// expression arguments, and on i386 you'd need 19.
569  InlineFreeListsCapacity =
570  1 + (AvailabilityAllocSize - sizeof(AttributeList)) / sizeof(void*)
571  };
572 
573  llvm::BumpPtrAllocator Alloc;
574 
575  /// Free lists. The index is determined by the following formula:
576  /// (size - sizeof(AttributeList)) / sizeof(void*)
578 
579  // The following are the private interface used by AttributePool.
580  friend class AttributePool;
581 
582  /// Allocate an attribute of the given size.
583  void *allocate(size_t size);
584 
585  /// Reclaim all the attributes in the given pool chain, which is
586  /// non-empty. Note that the current implementation is safe
587  /// against reclaiming things which were not actually allocated
588  /// with the allocator, although of course it's important to make
589  /// sure that their allocator lives at least as long as this one.
590  void reclaimPool(AttributeList *head);
591 
592 public:
594  ~AttributeFactory();
595 };
596 
598  AttributeFactory &Factory;
599  AttributeList *Head;
600 
601  void *allocate(size_t size) {
602  return Factory.allocate(size);
603  }
604 
605  AttributeList *add(AttributeList *attr) {
606  // We don't care about the order of the pool.
607  attr->NextInPool = Head;
608  Head = attr;
609  return attr;
610  }
611 
612  void takePool(AttributeList *pool);
613 
614 public:
615  /// Create a new pool for a factory.
616  AttributePool(AttributeFactory &factory) : Factory(factory), Head(nullptr) {}
617 
618  AttributePool(const AttributePool &) = delete;
619 
620  /// Move the given pool's allocations to this pool.
621  AttributePool(AttributePool &&pool) : Factory(pool.Factory), Head(pool.Head) {
622  pool.Head = nullptr;
623  }
624 
625  AttributeFactory &getFactory() const { return Factory; }
626 
627  void clear() {
628  if (Head) {
629  Factory.reclaimPool(Head);
630  Head = nullptr;
631  }
632  }
633 
634  /// Take the given pool's allocations and add them to this pool.
636  if (pool.Head) {
637  takePool(pool.Head);
638  pool.Head = nullptr;
639  }
640  }
641 
643  if (Head) Factory.reclaimPool(Head);
644  }
645 
647  IdentifierInfo *scopeName, SourceLocation scopeLoc,
648  ArgsUnion *args, unsigned numArgs,
649  AttributeList::Syntax syntax,
650  SourceLocation ellipsisLoc = SourceLocation()) {
651  void *memory = allocate(sizeof(AttributeList)
652  + numArgs * sizeof(ArgsUnion));
653  return add(new (memory) AttributeList(attrName, attrRange,
654  scopeName, scopeLoc,
655  args, numArgs, syntax,
656  ellipsisLoc));
657  }
658 
660  IdentifierInfo *scopeName, SourceLocation scopeLoc,
661  IdentifierLoc *Param,
662  const AvailabilityChange &introduced,
663  const AvailabilityChange &deprecated,
664  const AvailabilityChange &obsoleted,
665  SourceLocation unavailable,
666  const Expr *MessageExpr,
667  AttributeList::Syntax syntax,
668  SourceLocation strict, const Expr *ReplacementExpr) {
669  void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
670  return add(new (memory) AttributeList(attrName, attrRange,
671  scopeName, scopeLoc,
672  Param, introduced, deprecated,
673  obsoleted, unavailable, MessageExpr,
674  syntax, strict, ReplacementExpr));
675  }
676 
678  IdentifierInfo *scopeName, SourceLocation scopeLoc,
679  IdentifierLoc *Param1,
680  IdentifierLoc *Param2,
681  IdentifierLoc *Param3,
682  AttributeList::Syntax syntax) {
683  size_t size = sizeof(AttributeList) + 3 * sizeof(ArgsUnion);
684  void *memory = allocate(size);
685  return add(new (memory) AttributeList(attrName, attrRange,
686  scopeName, scopeLoc,
687  Param1, Param2, Param3,
688  syntax));
689  }
690 
692  IdentifierInfo *attrName, SourceRange attrRange,
693  IdentifierInfo *scopeName, SourceLocation scopeLoc,
694  IdentifierLoc *argumentKind, ParsedType matchingCType,
695  bool layoutCompatible, bool mustBeNull,
696  AttributeList::Syntax syntax) {
697  void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
698  return add(new (memory) AttributeList(attrName, attrRange,
699  scopeName, scopeLoc,
700  argumentKind, matchingCType,
701  layoutCompatible, mustBeNull,
702  syntax));
703  }
704 
706  IdentifierInfo *attrName, SourceRange attrRange,
707  IdentifierInfo *scopeName, SourceLocation scopeLoc,
708  ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
709  void *memory = allocate(sizeof(AttributeList) + sizeof(void *));
710  return add(new (memory) AttributeList(attrName, attrRange,
711  scopeName, scopeLoc,
712  typeArg, syntaxUsed));
713  }
714 
716  IdentifierInfo *attrName, SourceRange attrRange,
717  IdentifierInfo *scopeName, SourceLocation scopeLoc,
718  IdentifierInfo *getterId, IdentifierInfo *setterId,
719  AttributeList::Syntax syntaxUsed) {
720  void *memory = allocate(AttributeFactory::PropertyAllocSize);
721  return add(new (memory) AttributeList(attrName, attrRange,
722  scopeName, scopeLoc,
723  getterId, setterId,
724  syntaxUsed));
725  }
726 };
727 
728 /// ParsedAttributes - A collection of parsed attributes. Currently
729 /// we don't differentiate between the various attribute syntaxes,
730 /// which is basically silly.
731 ///
732 /// Right now this is a very lightweight container, but the expectation
733 /// is that this will become significantly more serious.
735 public:
737  : pool(factory), list(nullptr) {
738  }
739 
740  ParsedAttributes(const ParsedAttributes &) = delete;
741 
742  AttributePool &getPool() const { return pool; }
743 
744  bool empty() const { return list == nullptr; }
745 
746  void add(AttributeList *newAttr) {
747  assert(newAttr);
748  assert(newAttr->getNext() == nullptr);
749  newAttr->setNext(list);
750  list = newAttr;
751  }
752 
753  void addAll(AttributeList *newList) {
754  if (!newList) return;
755 
756  AttributeList *lastInNewList = newList;
757  while (AttributeList *next = lastInNewList->getNext())
758  lastInNewList = next;
759 
760  lastInNewList->setNext(list);
761  list = newList;
762  }
763 
764  void addAllAtEnd(AttributeList *newList) {
765  if (!list) {
766  list = newList;
767  return;
768  }
769 
770  AttributeList *lastInList = list;
771  while (AttributeList *next = lastInList->getNext())
772  lastInList = next;
773 
774  lastInList->setNext(newList);
775  }
776 
777  void set(AttributeList *newList) {
778  list = newList;
779  }
780 
782  addAll(attrs.list);
783  attrs.list = nullptr;
784  pool.takeAllFrom(attrs.pool);
785  }
786 
787  void clear() { list = nullptr; pool.clear(); }
788  AttributeList *getList() const { return list; }
789 
790  void clearListOnly() { list = nullptr; }
791 
792  /// Returns a reference to the attribute list. Try not to introduce
793  /// dependencies on this method, it may not be long-lived.
794  AttributeList *&getListRef() { return list; }
795 
796  /// Add attribute with expression arguments.
798  IdentifierInfo *scopeName, SourceLocation scopeLoc,
799  ArgsUnion *args, unsigned numArgs,
800  AttributeList::Syntax syntax,
801  SourceLocation ellipsisLoc = SourceLocation()) {
802  AttributeList *attr =
803  pool.create(attrName, attrRange, scopeName, scopeLoc, args, numArgs,
804  syntax, ellipsisLoc);
805  add(attr);
806  return attr;
807  }
808 
809  /// Add availability attribute.
811  IdentifierInfo *scopeName, SourceLocation scopeLoc,
812  IdentifierLoc *Param,
813  const AvailabilityChange &introduced,
814  const AvailabilityChange &deprecated,
815  const AvailabilityChange &obsoleted,
816  SourceLocation unavailable,
817  const Expr *MessageExpr,
818  AttributeList::Syntax syntax,
819  SourceLocation strict, const Expr *ReplacementExpr) {
820  AttributeList *attr =
821  pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced,
822  deprecated, obsoleted, unavailable, MessageExpr, syntax,
823  strict, ReplacementExpr);
824  add(attr);
825  return attr;
826  }
827 
828  /// Add objc_bridge_related attribute.
830  IdentifierInfo *scopeName, SourceLocation scopeLoc,
831  IdentifierLoc *Param1,
832  IdentifierLoc *Param2,
833  IdentifierLoc *Param3,
834  AttributeList::Syntax syntax) {
835  AttributeList *attr =
836  pool.create(attrName, attrRange, scopeName, scopeLoc,
837  Param1, Param2, Param3, syntax);
838  add(attr);
839  return attr;
840  }
841 
842  /// Add type_tag_for_datatype attribute.
844  IdentifierInfo *attrName, SourceRange attrRange,
845  IdentifierInfo *scopeName, SourceLocation scopeLoc,
846  IdentifierLoc *argumentKind, ParsedType matchingCType,
847  bool layoutCompatible, bool mustBeNull,
848  AttributeList::Syntax syntax) {
849  AttributeList *attr =
850  pool.createTypeTagForDatatype(attrName, attrRange,
851  scopeName, scopeLoc,
852  argumentKind, matchingCType,
853  layoutCompatible, mustBeNull, syntax);
854  add(attr);
855  return attr;
856  }
857 
858  /// Add an attribute with a single type argument.
859  AttributeList *
861  IdentifierInfo *scopeName, SourceLocation scopeLoc,
862  ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
863  AttributeList *attr =
864  pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc,
865  typeArg, syntaxUsed);
866  add(attr);
867  return attr;
868  }
869 
870  /// Add microsoft __delspec(property) attribute.
871  AttributeList *
873  IdentifierInfo *scopeName, SourceLocation scopeLoc,
874  IdentifierInfo *getterId, IdentifierInfo *setterId,
875  AttributeList::Syntax syntaxUsed) {
876  AttributeList *attr =
877  pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
878  getterId, setterId, syntaxUsed);
879  add(attr);
880  return attr;
881  }
882 
883 private:
884  mutable AttributePool pool;
885  AttributeList *list;
886 };
887 
888 /// These constants match the enumerated choices of
889 /// err_attribute_argument_n_type and err_attribute_argument_type.
895 };
896 
897 /// These constants match the enumerated choices of
898 /// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
914 };
915 
916 } // end namespace clang
917 
918 #endif
bool isAlignasAttribute() const
AttributeList * addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *getterId, IdentifierInfo *setterId, AttributeList::Syntax syntaxUsed)
Add microsoft __delspec(property) attribute.
void setProcessingCache(unsigned value) const
bool isUsedAsTypeAttr() const
const Expr * getMessageExpr() const
Represents a version number in the form major[.minor[.subminor[.build]]].
Definition: VersionTuple.h:26
AttributeList * getNext() const
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this attribute.
ParsedAttributes(AttributeFactory &factory)
const AvailabilityChange & getAvailabilityIntroduced() const
AttributeList * createPropertyAttribute(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *getterId, IdentifierInfo *setterId, AttributeList::Syntax syntaxUsed)
unsigned getProcessingCache() const
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
IdentifierInfo * Ident
Definition: AttributeList.h:75
bool getMustBeNull() const
AttributeList * create(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierLoc *Param, const AvailabilityChange &introduced, const AvailabilityChange &deprecated, const AvailabilityChange &obsoleted, SourceLocation unavailable, const Expr *MessageExpr, AttributeList::Syntax syntax, SourceLocation strict, const Expr *ReplacementExpr)
bool isArgIdent(unsigned Arg) const
AttributeList * getList() const
void addAll(AttributeList *newList)
SourceLocation Loc
Definition: AttributeList.h:74
SourceLocation getLoc() const
__ptr16, alignas(...), etc.
One of these records is kept for each identifier that is lexed.
Kind getKind() const
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
Definition: Ownership.h:232
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
ArgsUnion getArg(unsigned Arg) const
getArg - Return the specified argument.
const PropertyData & getPropertyData() const
AttributeList * addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ParsedType typeArg, AttributeList::Syntax syntaxUsed)
Add an attribute with a single type argument.
AttributeList * create(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierLoc *Param1, IdentifierLoc *Param2, IdentifierLoc *Param3, AttributeList::Syntax syntax)
SourceLocation getScopeLoc() const
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:48
bool getLayoutCompatible() const
bool isDeclspecPropertyAttribute() const
Is this the Microsoft __declspec(property) attribute?
AttributeArgumentNType
These constants match the enumerated choices of err_attribute_argument_n_type and err_attribute_argum...
bool isKeywordAttribute() const
void takeAllFrom(ParsedAttributes &attrs)
IdentifierLoc * getArgAsIdent(unsigned Arg) const
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:39
Represents information about a change in availability for an entity, which is part of the encoding of...
Definition: AttributeList.h:36
AvailabilityChange Changes[NumAvailabilitySlots]
Definition: AttributeList.h:57
AttributeList * createTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierLoc *argumentKind, ParsedType matchingCType, bool layoutCompatible, bool mustBeNull, AttributeList::Syntax syntax)
VersionTuple Version
The version number at which the change occurred.
Definition: AttributeList.h:41
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:274
[uuid("...")] class Foo
Exposes information about the current target.
Definition: TargetInfo.h:54
Expr - This represents one expression.
Definition: Expr.h:106
void addAllAtEnd(AttributeList *newList)
AttributeFactory & getFactory() const
SourceLocation KeywordLoc
The location of the keyword indicating the kind of change.
Definition: AttributeList.h:38
bool isValid() const
Determine whether this availability change is valid.
Definition: AttributeList.h:47
const AvailabilityChange & getAvailabilityObsoleted() const
Wraps an identifier and optional source location for the identifier.
Definition: AttributeList.h:73
bool isCXX11Attribute() const
SourceRange VersionRange
The source range covering the version number.
Definition: AttributeList.h:44
AttributeList * create(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, AttributeList::Syntax syntax, SourceLocation ellipsisLoc=SourceLocation())
bool hasParsedType() const
SourceRange getRange() const
bool isC2xAttribute() const
Context-sensitive version of a keyword attribute.
bool hasScope() const
bool empty() const
Determine whether this version information is empty (e.g., all version components are zero)...
Definition: VersionTuple.h:69
AttributeList * createTypeAttribute(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ParsedType typeArg, AttributeList::Syntax syntaxUsed)
Kind
Encodes a location in the source.
bool isContextSensitiveKeywordAttribute() const
SourceLocation getUnavailableLoc() const
IdentifierInfo * getScopeName() const
const ParsedType & getMatchingCType() const
SourceLocation StrictLoc
Definition: AttributeList.h:58
bool isDeclspecAttribute() const
llvm::SmallVector< ArgsUnion, 12U > ArgsVector
Definition: AttributeList.h:84
AttributeList * addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierLoc *Param, const AvailabilityChange &introduced, const AvailabilityChange &deprecated, const AvailabilityChange &obsoleted, SourceLocation unavailable, const Expr *MessageExpr, AttributeList::Syntax syntax, SourceLocation strict, const Expr *ReplacementExpr)
Add availability attribute.
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
bool isMicrosoftAttribute() const
bool hasProcessingCache() const
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
Expr * getArgAsExpr(unsigned Arg) const
void takeAllFrom(AttributePool &pool)
Take the given pool&#39;s allocations and add them to this pool.
AttributePool(AttributeFactory &factory)
Create a new pool for a factory.
const AvailabilityChange & getAvailabilityDeprecated() const
IdentifierInfo * getName() const
void add(AttributeList *newAttr)
Syntax
The style used to specify an attribute.
Definition: AttributeList.h:98
const ParsedType & getTypeArg() const
bool isPackExpansion() const
bool isArgExpr(unsigned Arg) const
void setNext(AttributeList *N)
void setInvalid(bool b=true) const
AttributeList * addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, AttributeList::Syntax syntax, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
const Expr * Replacement
Definition: AttributeList.h:59
const Expr * getReplacementExpr() const
SourceLocation getStrictLoc() const
Defines the clang::SourceLocation class and associated facilities.
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...
PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
SourceLocation getEllipsisLoc() const
AttributePool(AttributePool &&pool)
Move the given pool&#39;s allocations to this pool.
AttributePool & getPool() const
Defines the clang::TargetInfo interface.
Defines the clang::VersionTuple class, which represents a version in the form major[.minor[.subminor]].
static Decl::Kind getKind(const Decl *D)
Definition: DeclBase.cpp:915
A trivial tuple used to represent a source range.
AttributeList * addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierLoc *Param1, IdentifierLoc *Param2, IdentifierLoc *Param3, AttributeList::Syntax syntax)
Add objc_bridge_related attribute.
SourceLocation getBegin() const
ParsedAttributes - A collection of parsed attributes.
AttributeDeclKind
These constants match the enumerated choices of warn_attribute_wrong_decl_type and err_attribute_wron...
AttributeList *& getListRef()
Returns a reference to the attribute list.
AttributeList * addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierLoc *argumentKind, ParsedType matchingCType, bool layoutCompatible, bool mustBeNull, AttributeList::Syntax syntax)
Add type_tag_for_datatype attribute.
AttributeList - Represents a syntactic attribute.
Definition: AttributeList.h:95
bool isInvalid() const