clang  7.0.0
ParsedAttr.h
Go to the documentation of this file.
1 //======- ParsedAttr.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 ParsedAttr 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 ParsedAttr.
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 /// ParsedAttr as an argument.
93 using ArgsUnion = llvm::PointerUnion<Expr *, IdentifierLoc *>;
95 
96 /// ParsedAttr - 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 ParsedAttr { // 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  ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
219  IdentifierInfo *scopeName, SourceLocation scopeLoc,
220  ArgsUnion *args, unsigned numArgs, Syntax syntaxUsed,
221  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  ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
233  IdentifierInfo *scopeName, SourceLocation scopeLoc,
234  IdentifierLoc *Parm, const AvailabilityChange &introduced,
235  const AvailabilityChange &deprecated,
236  const AvailabilityChange &obsoleted, SourceLocation unavailable,
237  const Expr *messageExpr, Syntax syntaxUsed, SourceLocation strict,
238  const Expr *replacementExpr)
239  : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
240  ScopeLoc(scopeLoc), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false),
241  UsedAsTypeAttr(false), IsAvailability(true),
242  IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
243  HasProcessingCache(false), UnavailableLoc(unavailable),
244  MessageExpr(messageExpr) {
245  ArgsUnion PVal(Parm);
246  memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
247  new (getAvailabilityData()) AvailabilityData(
248  introduced, deprecated, obsoleted, strict, replacementExpr);
249  AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
250  }
251 
252  /// Constructor for objc_bridge_related attributes.
253  ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
254  IdentifierInfo *scopeName, SourceLocation scopeLoc,
255  IdentifierLoc *Parm1, IdentifierLoc *Parm2, IdentifierLoc *Parm3,
256  Syntax syntaxUsed)
257  : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
258  ScopeLoc(scopeLoc), NumArgs(3), SyntaxUsed(syntaxUsed), Invalid(false),
259  UsedAsTypeAttr(false), IsAvailability(false),
260  IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
261  HasProcessingCache(false) {
262  ArgsUnion *Args = getArgsBuffer();
263  Args[0] = Parm1;
264  Args[1] = Parm2;
265  Args[2] = Parm3;
266  AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
267  }
268 
269  /// Constructor for type_tag_for_datatype attribute.
270  ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
271  IdentifierInfo *scopeName, SourceLocation scopeLoc,
272  IdentifierLoc *ArgKind, ParsedType matchingCType,
273  bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed)
274  : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
275  ScopeLoc(scopeLoc), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false),
276  UsedAsTypeAttr(false), IsAvailability(false),
277  IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false),
278  HasProcessingCache(false) {
279  ArgsUnion PVal(ArgKind);
280  memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
281  TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
282  new (&ExtraData.MatchingCType) ParsedType(matchingCType);
283  ExtraData.LayoutCompatible = layoutCompatible;
284  ExtraData.MustBeNull = mustBeNull;
285  AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
286  }
287 
288  /// Constructor for attributes with a single type argument.
289  ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
290  IdentifierInfo *scopeName, SourceLocation scopeLoc,
291  ParsedType typeArg, Syntax syntaxUsed)
292  : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
293  ScopeLoc(scopeLoc), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false),
294  UsedAsTypeAttr(false), IsAvailability(false),
295  IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true),
296  HasProcessingCache(false) {
297  new (&getTypeBuffer()) ParsedType(typeArg);
298  AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
299  }
300 
301  /// Constructor for microsoft __declspec(property) attribute.
302  ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
303  IdentifierInfo *scopeName, SourceLocation scopeLoc,
304  IdentifierInfo *getterId, IdentifierInfo *setterId,
305  Syntax syntaxUsed)
306  : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
307  ScopeLoc(scopeLoc), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false),
308  UsedAsTypeAttr(false), IsAvailability(false),
309  IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false),
310  HasProcessingCache(false) {
311  new (&getPropertyDataBuffer()) PropertyData(getterId, setterId);
312  AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
313  }
314 
315  /// Type tag information is stored immediately following the arguments, if
316  /// any, at the end of the object. They are mutually exclusive with
317  /// availability slots.
318  TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
319  return *reinterpret_cast<TypeTagForDatatypeData*>(getArgsBuffer()+NumArgs);
320  }
321  const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
322  return *reinterpret_cast<const TypeTagForDatatypeData*>(getArgsBuffer()
323  + NumArgs);
324  }
325 
326  /// The type buffer immediately follows the object and are mutually exclusive
327  /// with arguments.
328  ParsedType &getTypeBuffer() {
329  return *reinterpret_cast<ParsedType *>(this + 1);
330  }
331  const ParsedType &getTypeBuffer() const {
332  return *reinterpret_cast<const ParsedType *>(this + 1);
333  }
334 
335  /// The property data immediately follows the object is is mutually exclusive
336  /// with arguments.
337  PropertyData &getPropertyDataBuffer() {
338  assert(IsProperty);
339  return *reinterpret_cast<PropertyData*>(this + 1);
340  }
341  const PropertyData &getPropertyDataBuffer() const {
342  assert(IsProperty);
343  return *reinterpret_cast<const PropertyData*>(this + 1);
344  }
345 
346  size_t allocated_size() const;
347 
348 public:
349  ParsedAttr(const ParsedAttr &) = delete;
350  ParsedAttr &operator=(const ParsedAttr &) = delete;
351  ~ParsedAttr() = delete;
352 
353  void operator delete(void *) = delete;
354 
355  enum Kind {
356  #define PARSED_ATTR(NAME) AT_##NAME,
357  #include "clang/Sema/AttrParsedAttrList.inc"
358  #undef PARSED_ATTR
360  UnknownAttribute
361  };
362 
363  IdentifierInfo *getName() const { return AttrName; }
364  SourceLocation getLoc() const { return AttrRange.getBegin(); }
365  SourceRange getRange() const { return AttrRange; }
366 
367  bool hasScope() const { return ScopeName; }
368  IdentifierInfo *getScopeName() const { return ScopeName; }
369  SourceLocation getScopeLoc() const { return ScopeLoc; }
370 
371  bool hasParsedType() const { return HasParsedType; }
372 
373  /// Is this the Microsoft __declspec(property) attribute?
375  return IsProperty;
376  }
377 
378  bool isAlignasAttribute() const {
379  // FIXME: Use a better mechanism to determine this.
380  return getKind() == AT_Aligned && isKeywordAttribute();
381  }
382 
383  bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
384  bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; }
385 
386  bool isCXX11Attribute() const {
387  return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
388  }
389 
390  bool isC2xAttribute() const {
391  return SyntaxUsed == AS_C2x;
392  }
393 
394  bool isKeywordAttribute() const {
395  return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
396  }
397 
399  return SyntaxUsed == AS_ContextSensitiveKeyword;
400  }
401 
402  bool isInvalid() const { return Invalid; }
403  void setInvalid(bool b = true) const { Invalid = b; }
404 
405  bool hasProcessingCache() const { return HasProcessingCache; }
406 
407  unsigned getProcessingCache() const {
408  assert(hasProcessingCache());
409  return ProcessingCache;
410  }
411 
412  void setProcessingCache(unsigned value) const {
413  ProcessingCache = value;
414  HasProcessingCache = true;
415  }
416 
417  bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
418  void setUsedAsTypeAttr() { UsedAsTypeAttr = true; }
419 
420  bool isPackExpansion() const { return EllipsisLoc.isValid(); }
421  SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
422 
423  Kind getKind() const { return Kind(AttrKind); }
424  static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope,
425  Syntax SyntaxUsed);
426 
427  /// getNumArgs - Return the number of actual arguments to this attribute.
428  unsigned getNumArgs() const { return NumArgs; }
429 
430  /// getArg - Return the specified argument.
431  ArgsUnion getArg(unsigned Arg) const {
432  assert(Arg < NumArgs && "Arg access out of range!");
433  return getArgsBuffer()[Arg];
434  }
435 
436  bool isArgExpr(unsigned Arg) const {
437  return Arg < NumArgs && getArg(Arg).is<Expr*>();
438  }
439 
440  Expr *getArgAsExpr(unsigned Arg) const {
441  return getArg(Arg).get<Expr*>();
442  }
443 
444  bool isArgIdent(unsigned Arg) const {
445  return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>();
446  }
447 
448  IdentifierLoc *getArgAsIdent(unsigned Arg) const {
449  return getArg(Arg).get<IdentifierLoc*>();
450  }
451 
453  assert(getKind() == AT_Availability && "Not an availability attribute");
454  return getAvailabilityData()->Changes[IntroducedSlot];
455  }
456 
458  assert(getKind() == AT_Availability && "Not an availability attribute");
459  return getAvailabilityData()->Changes[DeprecatedSlot];
460  }
461 
463  assert(getKind() == AT_Availability && "Not an availability attribute");
464  return getAvailabilityData()->Changes[ObsoletedSlot];
465  }
466 
468  assert(getKind() == AT_Availability && "Not an availability attribute");
469  return getAvailabilityData()->StrictLoc;
470  }
471 
473  assert(getKind() == AT_Availability && "Not an availability attribute");
474  return UnavailableLoc;
475  }
476 
477  const Expr * getMessageExpr() const {
478  assert(getKind() == AT_Availability && "Not an availability attribute");
479  return MessageExpr;
480  }
481 
482  const Expr *getReplacementExpr() const {
483  assert(getKind() == AT_Availability && "Not an availability attribute");
484  return getAvailabilityData()->Replacement;
485  }
486 
487  const ParsedType &getMatchingCType() const {
488  assert(getKind() == AT_TypeTagForDatatype &&
489  "Not a type_tag_for_datatype attribute");
490  return *getTypeTagForDatatypeDataSlot().MatchingCType;
491  }
492 
493  bool getLayoutCompatible() const {
494  assert(getKind() == AT_TypeTagForDatatype &&
495  "Not a type_tag_for_datatype attribute");
496  return getTypeTagForDatatypeDataSlot().LayoutCompatible;
497  }
498 
499  bool getMustBeNull() const {
500  assert(getKind() == AT_TypeTagForDatatype &&
501  "Not a type_tag_for_datatype attribute");
502  return getTypeTagForDatatypeDataSlot().MustBeNull;
503  }
504 
505  const ParsedType &getTypeArg() const {
506  assert(HasParsedType && "Not a type attribute");
507  return getTypeBuffer();
508  }
509 
510  const PropertyData &getPropertyData() const {
511  assert(isDeclspecPropertyAttribute() && "Not a __delcspec(property) attribute");
512  return getPropertyDataBuffer();
513  }
514 
515  /// Get an index into the attribute spelling list
516  /// defined in Attr.td. This index is used by an attribute
517  /// to pretty print itself.
518  unsigned getAttributeSpellingListIndex() const;
519 
520  bool isTargetSpecificAttr() const;
521  bool isTypeAttr() const;
522  bool isStmtAttr() const;
523 
524  bool hasCustomParsing() const;
525  unsigned getMinArgs() const;
526  unsigned getMaxArgs() const;
527  bool hasVariadicArg() const;
528  bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const;
529  bool appliesToDecl(const Decl *D, attr::SubjectMatchRule MatchRule) const;
530  void getMatchRules(const LangOptions &LangOpts,
531  SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>>
532  &MatchRules) const;
533  bool diagnoseLangOpts(class Sema &S) const;
534  bool existsInTarget(const TargetInfo &Target) const;
535  bool isKnownToGCC() const;
536  bool isSupportedByPragmaAttribute() const;
537 
538  /// If the parsed attribute has a semantic equivalent, and it would
539  /// have a semantic Spelling enumeration (due to having semantically-distinct
540  /// spelling variations), return the value of that semantic spelling. If the
541  /// parsed attribute does not have a semantic equivalent, or would not have
542  /// a Spelling enumeration, the value UINT_MAX is returned.
543  unsigned getSemanticSpelling() const;
544 };
545 
546 class AttributePool;
547 /// A factory, from which one makes pools, from which one creates
548 /// individual attributes which are deallocated with the pool.
549 ///
550 /// Note that it's tolerably cheap to create and destroy one of
551 /// these as long as you don't actually allocate anything in it.
553 public:
554  enum {
555  /// The required allocation size of an availability attribute,
556  /// which we want to ensure is a multiple of sizeof(void*).
557  AvailabilityAllocSize =
558  sizeof(ParsedAttr) +
559  ((sizeof(AvailabilityData) + sizeof(void *) + sizeof(ArgsUnion) - 1) /
560  sizeof(void *) * sizeof(void *)),
561  TypeTagForDatatypeAllocSize = sizeof(ParsedAttr) +
563  sizeof(void *) + sizeof(ArgsUnion) - 1) /
564  sizeof(void *) * sizeof(void *),
565  PropertyAllocSize =
566  sizeof(ParsedAttr) +
567  (sizeof(ParsedAttr::PropertyData) + sizeof(void *) - 1) /
568  sizeof(void *) * sizeof(void *)
569  };
570 
571 private:
572  enum {
573  /// The number of free lists we want to be sure to support
574  /// inline. This is just enough that availability attributes
575  /// don't surpass it. It's actually very unlikely we'll see an
576  /// attribute that needs more than that; on x86-64 you'd need 10
577  /// expression arguments, and on i386 you'd need 19.
578  InlineFreeListsCapacity =
579  1 + (AvailabilityAllocSize - sizeof(ParsedAttr)) / sizeof(void *)
580  };
581 
582  llvm::BumpPtrAllocator Alloc;
583 
584  /// Free lists. The index is determined by the following formula:
585  /// (size - sizeof(ParsedAttr)) / sizeof(void*)
586  SmallVector<SmallVector<ParsedAttr *, 8>, InlineFreeListsCapacity> FreeLists;
587 
588  // The following are the private interface used by AttributePool.
589  friend class AttributePool;
590 
591  /// Allocate an attribute of the given size.
592  void *allocate(size_t size);
593 
594  void deallocate(ParsedAttr *AL);
595 
596  /// Reclaim all the attributes in the given pool chain, which is
597  /// non-empty. Note that the current implementation is safe
598  /// against reclaiming things which were not actually allocated
599  /// with the allocator, although of course it's important to make
600  /// sure that their allocator lives at least as long as this one.
601  void reclaimPool(AttributePool &head);
602 
603 public:
605  ~AttributeFactory();
606 };
607 
609  friend class AttributeFactory;
611  llvm::TinyPtrVector<ParsedAttr *> Attrs;
612 
613  void *allocate(size_t size) {
614  return Factory.allocate(size);
615  }
616 
617  ParsedAttr *add(ParsedAttr *attr) {
618  Attrs.push_back(attr);
619  return attr;
620  }
621 
622  void remove(ParsedAttr *attr) {
623  assert(llvm::is_contained(Attrs, attr) &&
624  "Can't take attribute from a pool that doesn't own it!");
625  Attrs.erase(llvm::find(Attrs, attr));
626  }
627 
628  void takePool(AttributePool &pool);
629 
630 public:
631  /// Create a new pool for a factory.
632  AttributePool(AttributeFactory &factory) : Factory(factory) {}
633 
634  AttributePool(const AttributePool &) = delete;
635 
636  ~AttributePool() { Factory.reclaimPool(*this); }
637 
638  /// Move the given pool's allocations to this pool.
639  AttributePool(AttributePool &&pool) = default;
640 
641  AttributeFactory &getFactory() const { return Factory; }
642 
643  void clear() {
644  Factory.reclaimPool(*this);
645  Attrs.clear();
646  }
647 
648  /// Take the given pool's allocations and add them to this pool.
650  takePool(pool);
651  pool.Attrs.clear();
652  }
653 
655  IdentifierInfo *scopeName, SourceLocation scopeLoc,
656  ArgsUnion *args, unsigned numArgs,
657  ParsedAttr::Syntax syntax,
658  SourceLocation ellipsisLoc = SourceLocation()) {
659  void *memory = allocate(sizeof(ParsedAttr) + numArgs * sizeof(ArgsUnion));
660  return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
661  args, numArgs, syntax, ellipsisLoc));
662  }
663 
665  IdentifierInfo *scopeName, SourceLocation scopeLoc,
666  IdentifierLoc *Param, const AvailabilityChange &introduced,
667  const AvailabilityChange &deprecated,
668  const AvailabilityChange &obsoleted,
669  SourceLocation unavailable, const Expr *MessageExpr,
670  ParsedAttr::Syntax syntax, SourceLocation strict,
671  const Expr *ReplacementExpr) {
672  void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
673  return add(new (memory) ParsedAttr(
674  attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated,
675  obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr));
676  }
677 
679  IdentifierInfo *scopeName, SourceLocation scopeLoc,
680  IdentifierLoc *Param1, IdentifierLoc *Param2,
681  IdentifierLoc *Param3, ParsedAttr::Syntax syntax) {
682  size_t size = sizeof(ParsedAttr) + 3 * sizeof(ArgsUnion);
683  void *memory = allocate(size);
684  return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
685  Param1, Param2, Param3, syntax));
686  }
687 
688  ParsedAttr *
690  IdentifierInfo *scopeName, SourceLocation scopeLoc,
691  IdentifierLoc *argumentKind,
692  ParsedType matchingCType, bool layoutCompatible,
693  bool mustBeNull, ParsedAttr::Syntax syntax) {
694  void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
695  return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
696  argumentKind, matchingCType,
697  layoutCompatible, mustBeNull, syntax));
698  }
699 
701  SourceRange attrRange,
702  IdentifierInfo *scopeName,
703  SourceLocation scopeLoc, ParsedType typeArg,
704  ParsedAttr::Syntax syntaxUsed) {
705  void *memory = allocate(sizeof(ParsedAttr) + sizeof(void *));
706  return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
707  typeArg, syntaxUsed));
708  }
709 
710  ParsedAttr *
712  IdentifierInfo *scopeName, SourceLocation scopeLoc,
713  IdentifierInfo *getterId, IdentifierInfo *setterId,
714  ParsedAttr::Syntax syntaxUsed) {
715  void *memory = allocate(AttributeFactory::PropertyAllocSize);
716  return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
717  getterId, setterId, syntaxUsed));
718  }
719 };
720 
722  using VecTy = llvm::TinyPtrVector<ParsedAttr *>;
723  using SizeType = decltype(std::declval<VecTy>().size());
724 
725 public:
726  bool empty() const { return AttrList.empty(); }
727  SizeType size() const { return AttrList.size(); }
728  ParsedAttr &operator[](SizeType pos) { return *AttrList[pos]; }
729  const ParsedAttr &operator[](SizeType pos) const { return *AttrList[pos]; }
730 
731  void addAtStart(ParsedAttr *newAttr) {
732  assert(newAttr);
733  AttrList.insert(AttrList.begin(), newAttr);
734  }
735  void addAtEnd(ParsedAttr *newAttr) {
736  assert(newAttr);
737  AttrList.push_back(newAttr);
738  }
739 
740  void remove(ParsedAttr *ToBeRemoved) {
741  assert(is_contained(AttrList, ToBeRemoved) &&
742  "Cannot remove attribute that isn't in the list");
743  AttrList.erase(llvm::find(AttrList, ToBeRemoved));
744  }
745 
746  void clearListOnly() { AttrList.clear(); }
747 
748  struct iterator : llvm::iterator_adaptor_base<iterator, VecTy::iterator,
749  std::random_access_iterator_tag,
750  ParsedAttr> {
751  iterator() : iterator_adaptor_base(nullptr) {}
752  iterator(VecTy::iterator I) : iterator_adaptor_base(I) {}
753  reference operator*() { return **I; }
754  friend class ParsedAttributesView;
755  };
757  : llvm::iterator_adaptor_base<const_iterator, VecTy::const_iterator,
758  std::random_access_iterator_tag,
759  ParsedAttr> {
760  const_iterator() : iterator_adaptor_base(nullptr) {}
761  const_iterator(VecTy::const_iterator I) : iterator_adaptor_base(I) {}
762 
763  reference operator*() const { return **I; }
764  friend class ParsedAttributesView;
765  };
766 
767  void addAll(iterator B, iterator E) {
768  AttrList.insert(AttrList.begin(), B.I, E.I);
769  }
770 
772  AttrList.insert(AttrList.begin(), B.I, E.I);
773  }
774 
776  AttrList.insert(AttrList.end(), B.I, E.I);
777  }
778 
780  AttrList.insert(AttrList.end(), B.I, E.I);
781  }
782 
783  iterator begin() { return iterator(AttrList.begin()); }
784  const_iterator begin() const { return const_iterator(AttrList.begin()); }
785  iterator end() { return iterator(AttrList.end()); }
786  const_iterator end() const { return const_iterator(AttrList.end()); }
787 
789  return llvm::any_of(
790  AttrList, [K](const ParsedAttr *AL) { return AL->getKind() == K; });
791  }
792 
793 private:
794  VecTy AttrList;
795 };
796 
797 /// ParsedAttributes - A collection of parsed attributes. Currently
798 /// we don't differentiate between the various attribute syntaxes,
799 /// which is basically silly.
800 ///
801 /// Right now this is a very lightweight container, but the expectation
802 /// is that this will become significantly more serious.
804 public:
805  ParsedAttributes(AttributeFactory &factory) : pool(factory) {}
806  ParsedAttributes(const ParsedAttributes &) = delete;
807 
808  AttributePool &getPool() const { return pool; }
809 
811  addAll(attrs.begin(), attrs.end());
812  attrs.clearListOnly();
813  pool.takeAllFrom(attrs.pool);
814  }
815 
816  void clear() {
817  clearListOnly();
818  pool.clear();
819  }
820 
821  /// Add attribute with expression arguments.
823  IdentifierInfo *scopeName, SourceLocation scopeLoc,
824  ArgsUnion *args, unsigned numArgs,
825  ParsedAttr::Syntax syntax,
826  SourceLocation ellipsisLoc = SourceLocation()) {
827  ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
828  args, numArgs, syntax, ellipsisLoc);
829  addAtStart(attr);
830  return attr;
831  }
832 
833  /// Add availability attribute.
835  IdentifierInfo *scopeName, SourceLocation scopeLoc,
836  IdentifierLoc *Param, const AvailabilityChange &introduced,
837  const AvailabilityChange &deprecated,
838  const AvailabilityChange &obsoleted,
839  SourceLocation unavailable, const Expr *MessageExpr,
840  ParsedAttr::Syntax syntax, SourceLocation strict,
841  const Expr *ReplacementExpr) {
842  ParsedAttr *attr = pool.create(
843  attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated,
844  obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr);
845  addAtStart(attr);
846  return attr;
847  }
848 
849  /// Add objc_bridge_related attribute.
851  IdentifierInfo *scopeName, SourceLocation scopeLoc,
852  IdentifierLoc *Param1, IdentifierLoc *Param2,
853  IdentifierLoc *Param3, ParsedAttr::Syntax syntax) {
854  ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
855  Param1, Param2, Param3, syntax);
856  addAtStart(attr);
857  return attr;
858  }
859 
860  /// Add type_tag_for_datatype attribute.
861  ParsedAttr *
863  IdentifierInfo *scopeName, SourceLocation scopeLoc,
864  IdentifierLoc *argumentKind,
865  ParsedType matchingCType, bool layoutCompatible,
866  bool mustBeNull, ParsedAttr::Syntax syntax) {
867  ParsedAttr *attr = pool.createTypeTagForDatatype(
868  attrName, attrRange, scopeName, scopeLoc, argumentKind, matchingCType,
869  layoutCompatible, mustBeNull, syntax);
870  addAtStart(attr);
871  return attr;
872  }
873 
874  /// Add an attribute with a single type argument.
876  IdentifierInfo *scopeName, SourceLocation scopeLoc,
877  ParsedType typeArg,
878  ParsedAttr::Syntax syntaxUsed) {
879  ParsedAttr *attr = pool.createTypeAttribute(attrName, attrRange, scopeName,
880  scopeLoc, typeArg, syntaxUsed);
881  addAtStart(attr);
882  return attr;
883  }
884 
885  /// Add microsoft __delspec(property) attribute.
886  ParsedAttr *
888  IdentifierInfo *scopeName, SourceLocation scopeLoc,
889  IdentifierInfo *getterId, IdentifierInfo *setterId,
890  ParsedAttr::Syntax syntaxUsed) {
891  ParsedAttr *attr =
892  pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
893  getterId, setterId, syntaxUsed);
894  addAtStart(attr);
895  return attr;
896  }
897 
898 private:
899  mutable AttributePool pool;
900 };
901 
902 /// These constants match the enumerated choices of
903 /// err_attribute_argument_n_type and err_attribute_argument_type.
909 };
910 
911 /// These constants match the enumerated choices of
912 /// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
927 };
928 
929 } // namespace clang
930 
931 #endif // LLVM_CLANG_SEMA_ATTRIBUTELIST_H
ParsedAttr * createTypeAttribute(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ParsedType typeArg, ParsedAttr::Syntax syntaxUsed)
Definition: ParsedAttr.h:700
PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
Definition: ParsedAttr.h:209
ParsedAttr * create(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierLoc *Param1, IdentifierLoc *Param2, IdentifierLoc *Param3, ParsedAttr::Syntax syntax)
Definition: ParsedAttr.h:678
bool isAlignasAttribute() const
Definition: ParsedAttr.h:378
const_iterator end() const
Definition: ParsedAttr.h:786
bool isDeclspecAttribute() const
Definition: ParsedAttr.h:383
const_iterator(VecTy::const_iterator I)
Definition: ParsedAttr.h:761
SizeType size() const
Definition: ParsedAttr.h:727
ParsedAttributes(AttributeFactory &factory)
Definition: ParsedAttr.h:805
llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion
A union of the various pointer types that can be passed to an ParsedAttr as an argument.
Definition: ParsedAttr.h:93
The required allocation size of an availability attribute, which we want to ensure is a multiple of s...
Definition: ParsedAttr.h:557
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
IdentifierInfo * Ident
Definition: ParsedAttr.h:85
Expr * getArgAsExpr(unsigned Arg) const
Definition: ParsedAttr.h:440
bool getMustBeNull() const
Definition: ParsedAttr.h:499
void setUsedAsTypeAttr()
Definition: ParsedAttr.h:418
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
bool hasParsedType() const
Definition: ParsedAttr.h:371
const_iterator begin() const
Definition: ParsedAttr.h:784
bool hasAttribute(ParsedAttr::Kind K) const
Definition: ParsedAttr.h:788
attribute((...))
Definition: ParsedAttr.h:110
bool isCXX11Attribute() const
Definition: ParsedAttr.h:386
ParsedAttr & operator[](SizeType pos)
Definition: ParsedAttr.h:728
std::string getName(ArrayRef< StringRef > Parts) const
Get the platform-specific name separator.
SourceLocation Loc
Definition: ParsedAttr.h:84
const ParsedType & getMatchingCType() const
Definition: ParsedAttr.h:487
One of these records is kept for each identifier that is lexed.
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
SourceLocation StrictLoc
Definition: ParsedAttr.h:66
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
Definition: Ownership.h:248
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:50
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this attribute.
Definition: ParsedAttr.h:428
AttributeArgumentNType
These constants match the enumerated choices of err_attribute_argument_n_type and err_attribute_argum...
Definition: ParsedAttr.h:904
void takeAllFrom(ParsedAttributes &attrs)
Definition: ParsedAttr.h:810
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: ParsedAttr.h:43
void addAtEnd(ParsedAttr *newAttr)
Definition: ParsedAttr.h:735
VersionTuple Version
The version number at which the change occurred.
Definition: ParsedAttr.h:48
void setInvalid(bool b=true) const
Definition: ParsedAttr.h:403
bool isDeclspecPropertyAttribute() const
Is this the Microsoft __declspec(property) attribute?
Definition: ParsedAttr.h:374
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:277
ParsedAttr * addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierLoc *argumentKind, ParsedType matchingCType, bool layoutCompatible, bool mustBeNull, ParsedAttr::Syntax syntax)
Add type_tag_for_datatype attribute.
Definition: ParsedAttr.h:862
void addAllAtEnd(const_iterator B, const_iterator E)
Definition: ParsedAttr.h:779
Exposes information about the current target.
Definition: TargetInfo.h:54
SourceLocation getScopeLoc() const
Definition: ParsedAttr.h:369
Expr - This represents one expression.
Definition: Expr.h:106
ParsedAttr * addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *getterId, IdentifierInfo *setterId, ParsedAttr::Syntax syntaxUsed)
Add microsoft __delspec(property) attribute.
Definition: ParsedAttr.h:887
bool isC2xAttribute() const
Definition: ParsedAttr.h:390
Kind getKind() const
Definition: ParsedAttr.h:423
const AvailabilityChange & getAvailabilityObsoleted() const
Definition: ParsedAttr.h:462
ParsedAttr * 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, ParsedAttr::Syntax syntax, SourceLocation strict, const Expr *ReplacementExpr)
Add availability attribute.
Definition: ParsedAttr.h:834
AttributeFactory & getFactory() const
Definition: ParsedAttr.h:641
void addAllAtEnd(iterator B, iterator E)
Definition: ParsedAttr.h:775
void addAll(iterator B, iterator E)
Definition: ParsedAttr.h:767
SourceLocation KeywordLoc
The location of the keyword indicating the kind of change.
Definition: ParsedAttr.h:45
bool isValid() const
Determine whether this availability change is valid.
Definition: ParsedAttr.h:54
Wraps an identifier and optional source location for the identifier.
Definition: ParsedAttr.h:83
SourceRange VersionRange
The source range covering the version number.
Definition: ParsedAttr.h:51
bool getLayoutCompatible() const
Definition: ParsedAttr.h:493
SourceLocation getEllipsisLoc() const
Definition: ParsedAttr.h:421
ParsedAttr * createPropertyAttribute(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *getterId, IdentifierInfo *setterId, ParsedAttr::Syntax syntaxUsed)
Definition: ParsedAttr.h:711
void addAtStart(ParsedAttr *newAttr)
Definition: ParsedAttr.h:731
#define false
Definition: stdbool.h:33
Kind
Encodes a location in the source.
const ParsedType & getTypeArg() const
Definition: ParsedAttr.h:505
void addAll(const_iterator B, const_iterator E)
Definition: ParsedAttr.h:771
Syntax
The style used to specify an attribute.
Definition: ParsedAttr.h:108
ParsedAttr - Represents a syntactic attribute.
Definition: ParsedAttr.h:105
const ParsedAttr & operator[](SizeType pos) const
Definition: ParsedAttr.h:729
bool hasProcessingCache() const
Definition: ParsedAttr.h:405
bool isUsedAsTypeAttr() const
Definition: ParsedAttr.h:417
ParsedAttr * addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, ParsedAttr::Syntax syntax, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
Definition: ParsedAttr.h:822
bool isContextSensitiveKeywordAttribute() const
Definition: ParsedAttr.h:398
bool isArgExpr(unsigned Arg) const
Definition: ParsedAttr.h:436
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
SourceRange getRange() const
Definition: ParsedAttr.h:365
void setProcessingCache(unsigned value) const
Definition: ParsedAttr.h:412
ArgsUnion getArg(unsigned Arg) const
getArg - Return the specified argument.
Definition: ParsedAttr.h:431
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
const AvailabilityChange & getAvailabilityIntroduced() const
Definition: ParsedAttr.h:452
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
bool isKeywordAttribute() const
Definition: ParsedAttr.h:394
bool isPackExpansion() const
Definition: ParsedAttr.h:420
bool isMicrosoftAttribute() const
Definition: ParsedAttr.h:384
SourceLocation getLoc() const
Definition: ParsedAttr.h:364
const PropertyData & getPropertyData() const
Definition: ParsedAttr.h:510
void takeAllFrom(AttributePool &pool)
Take the given pool&#39;s allocations and add them to this pool.
Definition: ParsedAttr.h:649
SourceLocation getStrictLoc() const
Definition: ParsedAttr.h:467
ParsedAttr * create(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, ParsedAttr::Syntax syntax, SourceLocation ellipsisLoc=SourceLocation())
Definition: ParsedAttr.h:654
AttributePool(AttributeFactory &factory)
Create a new pool for a factory.
Definition: ParsedAttr.h:632
IdentifierInfo * getName() const
Definition: ParsedAttr.h:363
ParsedAttr * createTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierLoc *argumentKind, ParsedType matchingCType, bool layoutCompatible, bool mustBeNull, ParsedAttr::Syntax syntax)
Definition: ParsedAttr.h:689
const Expr * Replacement
Definition: ParsedAttr.h:67
const AvailabilityChange & getAvailabilityDeprecated() const
Definition: ParsedAttr.h:457
bool hasScope() const
Definition: ParsedAttr.h:367
ParsedAttr * addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierLoc *Param1, IdentifierLoc *Param2, IdentifierLoc *Param3, ParsedAttr::Syntax syntax)
Add objc_bridge_related attribute.
Definition: ParsedAttr.h:850
ParsedAttr * addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ParsedType typeArg, ParsedAttr::Syntax syntaxUsed)
Add an attribute with a single type argument.
Definition: ParsedAttr.h:875
bool isInvalid() const
Definition: ParsedAttr.h:402
Context-sensitive version of a keyword attribute.
Definition: ParsedAttr.h:133
Defines the clang::SourceLocation class and associated facilities.
A factory, from which one makes pools, from which one creates individual attributes which are dealloc...
Definition: ParsedAttr.h:552
ParsedAttr * 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, ParsedAttr::Syntax syntax, SourceLocation strict, const Expr *ReplacementExpr)
Definition: ParsedAttr.h:664
AvailabilityChange Changes[NumAvailabilitySlots]
Definition: ParsedAttr.h:65
[uuid("...")] class Foo
Definition: ParsedAttr.h:122
AttributePool & getPool() const
Definition: ParsedAttr.h:808
const Expr * getMessageExpr() const
Definition: ParsedAttr.h:477
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
bool isArgIdent(unsigned Arg) const
Definition: ParsedAttr.h:444
A trivial tuple used to represent a source range.
__ptr16, alignas(...), etc.
Definition: ParsedAttr.h:125
SourceLocation getBegin() const
SourceLocation getUnavailableLoc() const
Definition: ParsedAttr.h:472
ParsedAttributes - A collection of parsed attributes.
Definition: ParsedAttr.h:803
AttributeDeclKind
These constants match the enumerated choices of warn_attribute_wrong_decl_type and err_attribute_wron...
Definition: ParsedAttr.h:913
IdentifierLoc * getArgAsIdent(unsigned Arg) const
Definition: ParsedAttr.h:448
IdentifierInfo * getScopeName() const
Definition: ParsedAttr.h:368
unsigned getProcessingCache() const
Definition: ParsedAttr.h:407
const Expr * getReplacementExpr() const
Definition: ParsedAttr.h:482