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