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