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