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