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