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