TypeLoc.h revision 1de6a6cb485fb58b4fb100282bb3cf298eedacd9
1//===--- TypeLoc.h - Type Source Info Wrapper -------------------*- 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 TypeLoc interface and subclasses.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_TYPELOC_H
15#define LLVM_CLANG_AST_TYPELOC_H
16
17#include "clang/AST/Type.h"
18#include "clang/AST/Decl.h"
19#include "clang/AST/TemplateBase.h"
20#include "clang/Basic/Specifiers.h"
21#include "llvm/Support/Compiler.h"
22
23namespace clang {
24  class ASTContext;
25  class ParmVarDecl;
26  class TypeSourceInfo;
27  class UnqualTypeLoc;
28
29// Predeclare all the type nodes.
30#define ABSTRACT_TYPELOC(Class, Base)
31#define TYPELOC(Class, Base) \
32  class Class##TypeLoc;
33#include "clang/AST/TypeLocNodes.def"
34
35/// \brief Base wrapper for a particular "section" of type source info.
36///
37/// A client should use the TypeLoc subclasses through cast/dyn_cast in order to
38/// get at the actual information.
39class TypeLoc {
40protected:
41  // The correctness of this relies on the property that, for Type *Ty,
42  //   QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
43  const void *Ty;
44  void *Data;
45
46public:
47  /// The kinds of TypeLocs.  Equivalent to the Type::TypeClass enum,
48  /// except it also defines a Qualified enum that corresponds to the
49  /// QualifiedLoc class.
50  enum TypeLocClass {
51#define ABSTRACT_TYPE(Class, Base)
52#define TYPE(Class, Base) \
53    Class = Type::Class,
54#include "clang/AST/TypeNodes.def"
55    Qualified
56  };
57
58  TypeLoc() : Ty(0), Data(0) { }
59  TypeLoc(QualType ty, void *opaqueData)
60    : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { }
61  TypeLoc(const Type *ty, void *opaqueData)
62    : Ty(ty), Data(opaqueData) { }
63
64  TypeLocClass getTypeLocClass() const {
65    if (getType().hasLocalQualifiers()) return Qualified;
66    return (TypeLocClass) getType()->getTypeClass();
67  }
68
69  bool isNull() const { return !Ty; }
70  operator bool() const { return Ty; }
71
72  /// \brief Returns the size of type source info data block for the given type.
73  static unsigned getFullDataSizeForType(QualType Ty);
74
75  /// \brief Get the type for which this source info wrapper provides
76  /// information.
77  QualType getType() const {
78    return QualType::getFromOpaquePtr(Ty);
79  }
80
81  const Type *getTypePtr() const {
82    return QualType::getFromOpaquePtr(Ty).getTypePtr();
83  }
84
85  /// \brief Get the pointer where source information is stored.
86  void *getOpaqueData() const {
87    return Data;
88  }
89
90  /// \brief Get the begin source location.
91  SourceLocation getBeginLoc() const;
92
93  /// \brief Get the end source location.
94  SourceLocation getEndLoc() const;
95
96  /// \brief Get the full source range.
97  SourceRange getSourceRange() const LLVM_READONLY {
98    return SourceRange(getBeginLoc(), getEndLoc());
99  }
100  SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
101  SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
102
103  /// \brief Get the local source range.
104  SourceRange getLocalSourceRange() const {
105    return getLocalSourceRangeImpl(*this);
106  }
107
108  /// \brief Returns the size of the type source info data block.
109  unsigned getFullDataSize() const {
110    return getFullDataSizeForType(getType());
111  }
112
113  /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
114  /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
115  TypeLoc getNextTypeLoc() const {
116    return getNextTypeLocImpl(*this);
117  }
118
119  /// \brief Skips past any qualifiers, if this is qualified.
120  UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
121
122  TypeLoc IgnoreParens() const {
123    if (isa<ParenTypeLoc>(this))
124      return IgnoreParensImpl(*this);
125    return *this;
126  }
127
128  /// \brief Initializes this to state that every location in this
129  /// type is the given location.
130  ///
131  /// This method exists to provide a simple transition for code that
132  /// relies on location-less types.
133  void initialize(ASTContext &Context, SourceLocation Loc) const {
134    initializeImpl(Context, *this, Loc);
135  }
136
137  /// \brief Initializes this by copying its information from another
138  /// TypeLoc of the same type.
139  void initializeFullCopy(TypeLoc Other) const {
140    assert(getType() == Other.getType());
141    size_t Size = getFullDataSize();
142    memcpy(getOpaqueData(), Other.getOpaqueData(), Size);
143  }
144
145  /// \brief Initializes this by copying its information from another
146  /// TypeLoc of the same type.  The given size must be the full data
147  /// size.
148  void initializeFullCopy(TypeLoc Other, unsigned Size) const {
149    assert(getType() == Other.getType());
150    assert(getFullDataSize() == Size);
151    memcpy(getOpaqueData(), Other.getOpaqueData(), Size);
152  }
153
154  friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
155    return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
156  }
157
158  friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) {
159    return !(LHS == RHS);
160  }
161
162  static bool classof(const TypeLoc *TL) { return true; }
163
164private:
165  static void initializeImpl(ASTContext &Context, TypeLoc TL,
166                             SourceLocation Loc);
167  static TypeLoc getNextTypeLocImpl(TypeLoc TL);
168  static TypeLoc IgnoreParensImpl(TypeLoc TL);
169  static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
170};
171
172/// \brief Return the TypeLoc for a type source info.
173inline TypeLoc TypeSourceInfo::getTypeLoc() const {
174  return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1)));
175}
176
177/// \brief Wrapper of type source information for a type with
178/// no direct qualifiers.
179class UnqualTypeLoc : public TypeLoc {
180public:
181  UnqualTypeLoc() {}
182  UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
183
184  const Type *getTypePtr() const {
185    return reinterpret_cast<const Type*>(Ty);
186  }
187
188  TypeLocClass getTypeLocClass() const {
189    return (TypeLocClass) getTypePtr()->getTypeClass();
190  }
191
192  static bool classof(const TypeLoc *TL) {
193    return !TL->getType().hasLocalQualifiers();
194  }
195  static bool classof(const UnqualTypeLoc *TL) { return true; }
196};
197
198/// \brief Wrapper of type source information for a type with
199/// non-trivial direct qualifiers.
200///
201/// Currently, we intentionally do not provide source location for
202/// type qualifiers.
203class QualifiedTypeLoc : public TypeLoc {
204public:
205  SourceRange getLocalSourceRange() const {
206    return SourceRange();
207  }
208
209  UnqualTypeLoc getUnqualifiedLoc() const {
210    return UnqualTypeLoc(getTypePtr(), Data);
211  }
212
213  /// Initializes the local data of this type source info block to
214  /// provide no information.
215  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
216    // do nothing
217  }
218
219  TypeLoc getNextTypeLoc() const {
220    return getUnqualifiedLoc();
221  }
222
223  /// \brief Returns the size of the type source info data block that is
224  /// specific to this type.
225  unsigned getLocalDataSize() const {
226    // In fact, we don't currently preserve any location information
227    // for qualifiers.
228    return 0;
229  }
230
231  /// \brief Returns the size of the type source info data block.
232  unsigned getFullDataSize() const {
233    return getLocalDataSize() +
234      getFullDataSizeForType(getType().getLocalUnqualifiedType());
235  }
236
237  static bool classof(const TypeLoc *TL) {
238    return TL->getType().hasLocalQualifiers();
239  }
240  static bool classof(const QualifiedTypeLoc *TL) { return true; }
241};
242
243inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
244  if (isa<QualifiedTypeLoc>(this))
245    return cast<QualifiedTypeLoc>(this)->getUnqualifiedLoc();
246  return cast<UnqualTypeLoc>(*this);
247}
248
249/// A metaprogramming base class for TypeLoc classes which correspond
250/// to a particular Type subclass.  It is accepted for a single
251/// TypeLoc class to correspond to multiple Type classes.
252///
253/// \param Base a class from which to derive
254/// \param Derived the class deriving from this one
255/// \param TypeClass the concrete Type subclass associated with this
256///   location type
257/// \param LocalData the structure type of local location data for
258///   this type
259///
260/// sizeof(LocalData) needs to be a multiple of sizeof(void*) or
261/// else the world will end.
262///
263/// TypeLocs with non-constant amounts of local data should override
264/// getExtraLocalDataSize(); getExtraLocalData() will then point to
265/// this extra memory.
266///
267/// TypeLocs with an inner type should define
268///   QualType getInnerType() const
269/// and getInnerTypeLoc() will then point to this inner type's
270/// location data.
271///
272/// A word about hierarchies: this template is not designed to be
273/// derived from multiple times in a hierarchy.  It is also not
274/// designed to be used for classes where subtypes might provide
275/// different amounts of source information.  It should be subclassed
276/// only at the deepest portion of the hierarchy where all children
277/// have identical source information; if that's an abstract type,
278/// then further descendents should inherit from
279/// InheritingConcreteTypeLoc instead.
280template <class Base, class Derived, class TypeClass, class LocalData>
281class ConcreteTypeLoc : public Base {
282
283  const Derived *asDerived() const {
284    return static_cast<const Derived*>(this);
285  }
286
287public:
288  unsigned getLocalDataSize() const {
289    return sizeof(LocalData) + asDerived()->getExtraLocalDataSize();
290  }
291  // Give a default implementation that's useful for leaf types.
292  unsigned getFullDataSize() const {
293    return asDerived()->getLocalDataSize() + getInnerTypeSize();
294  }
295
296  static bool classofType(const Type *Ty) {
297    return TypeClass::classof(Ty);
298  }
299
300  static bool classof(const TypeLoc *TL) {
301    return Derived::classofType(TL->getTypePtr());
302  }
303  static bool classof(const UnqualTypeLoc *TL) {
304    return Derived::classofType(TL->getTypePtr());
305  }
306  static bool classof(const Derived *TL) {
307    return true;
308  }
309
310  TypeLoc getNextTypeLoc() const {
311    return getNextTypeLoc(asDerived()->getInnerType());
312  }
313
314  const TypeClass *getTypePtr() const {
315    return cast<TypeClass>(Base::getTypePtr());
316  }
317
318protected:
319  unsigned getExtraLocalDataSize() const {
320    return 0;
321  }
322
323  LocalData *getLocalData() const {
324    return static_cast<LocalData*>(Base::Data);
325  }
326
327  /// Gets a pointer past the Info structure; useful for classes with
328  /// local data that can't be captured in the Info (e.g. because it's
329  /// of variable size).
330  void *getExtraLocalData() const {
331    return getLocalData() + 1;
332  }
333
334  void *getNonLocalData() const {
335    return static_cast<char*>(Base::Data) + asDerived()->getLocalDataSize();
336  }
337
338  struct HasNoInnerType {};
339  HasNoInnerType getInnerType() const { return HasNoInnerType(); }
340
341  TypeLoc getInnerTypeLoc() const {
342    return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
343  }
344
345private:
346  unsigned getInnerTypeSize() const {
347    return getInnerTypeSize(asDerived()->getInnerType());
348  }
349
350  unsigned getInnerTypeSize(HasNoInnerType _) const {
351    return 0;
352  }
353
354  unsigned getInnerTypeSize(QualType _) const {
355    return getInnerTypeLoc().getFullDataSize();
356  }
357
358  TypeLoc getNextTypeLoc(HasNoInnerType _) const {
359    return TypeLoc();
360  }
361
362  TypeLoc getNextTypeLoc(QualType T) const {
363    return TypeLoc(T, getNonLocalData());
364  }
365};
366
367/// A metaprogramming class designed for concrete subtypes of abstract
368/// types where all subtypes share equivalently-structured source
369/// information.  See the note on ConcreteTypeLoc.
370template <class Base, class Derived, class TypeClass>
371class InheritingConcreteTypeLoc : public Base {
372public:
373  static bool classofType(const Type *Ty) {
374    return TypeClass::classof(Ty);
375  }
376
377  static bool classof(const TypeLoc *TL) {
378    return Derived::classofType(TL->getTypePtr());
379  }
380  static bool classof(const UnqualTypeLoc *TL) {
381    return Derived::classofType(TL->getTypePtr());
382  }
383  static bool classof(const Derived *TL) {
384    return true;
385  }
386
387  const TypeClass *getTypePtr() const {
388    return cast<TypeClass>(Base::getTypePtr());
389  }
390};
391
392
393struct TypeSpecLocInfo {
394  SourceLocation NameLoc;
395};
396
397/// \brief A reasonable base class for TypeLocs that correspond to
398/// types that are written as a type-specifier.
399class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
400                                               TypeSpecTypeLoc,
401                                               Type,
402                                               TypeSpecLocInfo> {
403public:
404  enum { LocalDataSize = sizeof(TypeSpecLocInfo) };
405
406  SourceLocation getNameLoc() const {
407    return this->getLocalData()->NameLoc;
408  }
409  void setNameLoc(SourceLocation Loc) {
410    this->getLocalData()->NameLoc = Loc;
411  }
412  SourceRange getLocalSourceRange() const {
413    return SourceRange(getNameLoc(), getNameLoc());
414  }
415  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
416    setNameLoc(Loc);
417  }
418
419  static bool classof(const TypeLoc *TL);
420  static bool classof(const TypeSpecTypeLoc *TL) { return true; }
421};
422
423
424struct BuiltinLocInfo {
425  SourceLocation BuiltinLoc;
426};
427
428/// \brief Wrapper for source info for builtin types.
429class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
430                                              BuiltinTypeLoc,
431                                              BuiltinType,
432                                              BuiltinLocInfo> {
433public:
434  enum { LocalDataSize = sizeof(BuiltinLocInfo) };
435
436  SourceLocation getBuiltinLoc() const {
437    return getLocalData()->BuiltinLoc;
438  }
439  void setBuiltinLoc(SourceLocation Loc) {
440    getLocalData()->BuiltinLoc = Loc;
441  }
442
443  SourceLocation getNameLoc() const { return getBuiltinLoc(); }
444
445  WrittenBuiltinSpecs& getWrittenBuiltinSpecs() {
446    return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
447  }
448  const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
449    return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
450  }
451
452  bool needsExtraLocalData() const {
453    BuiltinType::Kind bk = getTypePtr()->getKind();
454    return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
455      || (bk >= BuiltinType::Short && bk <= BuiltinType::LongDouble)
456      || bk == BuiltinType::UChar
457      || bk == BuiltinType::SChar;
458  }
459
460  unsigned getExtraLocalDataSize() const {
461    return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
462  }
463
464  SourceRange getLocalSourceRange() const {
465    return SourceRange(getBuiltinLoc(), getBuiltinLoc());
466  }
467
468  TypeSpecifierSign getWrittenSignSpec() const {
469    if (needsExtraLocalData())
470      return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign);
471    else
472      return TSS_unspecified;
473  }
474  bool hasWrittenSignSpec() const {
475    return getWrittenSignSpec() != TSS_unspecified;
476  }
477  void setWrittenSignSpec(TypeSpecifierSign written) {
478    if (needsExtraLocalData())
479      getWrittenBuiltinSpecs().Sign = written;
480  }
481
482  TypeSpecifierWidth getWrittenWidthSpec() const {
483    if (needsExtraLocalData())
484      return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width);
485    else
486      return TSW_unspecified;
487  }
488  bool hasWrittenWidthSpec() const {
489    return getWrittenWidthSpec() != TSW_unspecified;
490  }
491  void setWrittenWidthSpec(TypeSpecifierWidth written) {
492    if (needsExtraLocalData())
493      getWrittenBuiltinSpecs().Width = written;
494  }
495
496  TypeSpecifierType getWrittenTypeSpec() const;
497  bool hasWrittenTypeSpec() const {
498    return getWrittenTypeSpec() != TST_unspecified;
499  }
500  void setWrittenTypeSpec(TypeSpecifierType written) {
501    if (needsExtraLocalData())
502      getWrittenBuiltinSpecs().Type = written;
503  }
504
505  bool hasModeAttr() const {
506    if (needsExtraLocalData())
507      return getWrittenBuiltinSpecs().ModeAttr;
508    else
509      return false;
510  }
511  void setModeAttr(bool written) {
512    if (needsExtraLocalData())
513      getWrittenBuiltinSpecs().ModeAttr = written;
514  }
515
516  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
517    setBuiltinLoc(Loc);
518    if (needsExtraLocalData()) {
519      WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs();
520      wbs.Sign = TSS_unspecified;
521      wbs.Width = TSW_unspecified;
522      wbs.Type = TST_unspecified;
523      wbs.ModeAttr = false;
524    }
525  }
526};
527
528
529/// \brief Wrapper for source info for typedefs.
530class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
531                                                        TypedefTypeLoc,
532                                                        TypedefType> {
533public:
534  TypedefNameDecl *getTypedefNameDecl() const {
535    return getTypePtr()->getDecl();
536  }
537};
538
539/// \brief Wrapper for source info for injected class names of class
540/// templates.
541class InjectedClassNameTypeLoc :
542    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
543                                     InjectedClassNameTypeLoc,
544                                     InjectedClassNameType> {
545public:
546  CXXRecordDecl *getDecl() const {
547    return getTypePtr()->getDecl();
548  }
549};
550
551/// \brief Wrapper for source info for unresolved typename using decls.
552class UnresolvedUsingTypeLoc :
553    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
554                                     UnresolvedUsingTypeLoc,
555                                     UnresolvedUsingType> {
556public:
557  UnresolvedUsingTypenameDecl *getDecl() const {
558    return getTypePtr()->getDecl();
559  }
560};
561
562/// \brief Wrapper for source info for tag types.  Note that this only
563/// records source info for the name itself; a type written 'struct foo'
564/// should be represented as an ElaboratedTypeLoc.  We currently
565/// only do that when C++ is enabled because of the expense of
566/// creating an ElaboratedType node for so many type references in C.
567class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
568                                                    TagTypeLoc,
569                                                    TagType> {
570public:
571  TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
572
573  /// \brief True if the tag was defined in this type specifier.
574  bool isDefinition() const {
575    TagDecl *D = getDecl();
576    return D->isCompleteDefinition() &&
577         (D->getIdentifier() == 0 || D->getLocation() == getNameLoc());
578  }
579};
580
581/// \brief Wrapper for source info for record types.
582class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
583                                                       RecordTypeLoc,
584                                                       RecordType> {
585public:
586  RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
587};
588
589/// \brief Wrapper for source info for enum types.
590class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
591                                                     EnumTypeLoc,
592                                                     EnumType> {
593public:
594  EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
595};
596
597/// \brief Wrapper for template type parameters.
598class TemplateTypeParmTypeLoc :
599    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
600                                     TemplateTypeParmTypeLoc,
601                                     TemplateTypeParmType> {
602public:
603  TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
604};
605
606/// \brief Wrapper for substituted template type parameters.
607class SubstTemplateTypeParmTypeLoc :
608    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
609                                     SubstTemplateTypeParmTypeLoc,
610                                     SubstTemplateTypeParmType> {
611};
612
613  /// \brief Wrapper for substituted template type parameters.
614class SubstTemplateTypeParmPackTypeLoc :
615    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
616                                     SubstTemplateTypeParmPackTypeLoc,
617                                     SubstTemplateTypeParmPackType> {
618};
619
620struct AttributedLocInfo {
621  union {
622    Expr *ExprOperand;
623
624    /// A raw SourceLocation.
625    unsigned EnumOperandLoc;
626  };
627
628  SourceRange OperandParens;
629
630  SourceLocation AttrLoc;
631};
632
633/// \brief Type source information for an attributed type.
634class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
635                                                 AttributedTypeLoc,
636                                                 AttributedType,
637                                                 AttributedLocInfo> {
638public:
639  AttributedType::Kind getAttrKind() const {
640    return getTypePtr()->getAttrKind();
641  }
642
643  bool hasAttrExprOperand() const {
644    return (getAttrKind() >= AttributedType::FirstExprOperandKind &&
645            getAttrKind() <= AttributedType::LastExprOperandKind);
646  }
647
648  bool hasAttrEnumOperand() const {
649    return (getAttrKind() >= AttributedType::FirstEnumOperandKind &&
650            getAttrKind() <= AttributedType::LastEnumOperandKind);
651  }
652
653  bool hasAttrOperand() const {
654    return hasAttrExprOperand() || hasAttrEnumOperand();
655  }
656
657  /// The modified type, which is generally canonically different from
658  /// the attribute type.
659  ///    int main(int, char**) __attribute__((noreturn))
660  ///    ~~~     ~~~~~~~~~~~~~
661  TypeLoc getModifiedLoc() const {
662    return getInnerTypeLoc();
663  }
664
665  /// The location of the attribute name, i.e.
666  ///    __attribute__((regparm(1000)))
667  ///                   ^~~~~~~
668  SourceLocation getAttrNameLoc() const {
669    return getLocalData()->AttrLoc;
670  }
671  void setAttrNameLoc(SourceLocation loc) {
672    getLocalData()->AttrLoc = loc;
673  }
674
675  /// The attribute's expression operand, if it has one.
676  ///    void *cur_thread __attribute__((address_space(21)))
677  ///                                                  ^~
678  Expr *getAttrExprOperand() const {
679    assert(hasAttrExprOperand());
680    return getLocalData()->ExprOperand;
681  }
682  void setAttrExprOperand(Expr *e) {
683    assert(hasAttrExprOperand());
684    getLocalData()->ExprOperand = e;
685  }
686
687  /// The location of the attribute's enumerated operand, if it has one.
688  ///    void * __attribute__((objc_gc(weak)))
689  ///                                  ^~~~
690  SourceLocation getAttrEnumOperandLoc() const {
691    assert(hasAttrEnumOperand());
692    return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc);
693  }
694  void setAttrEnumOperandLoc(SourceLocation loc) {
695    assert(hasAttrEnumOperand());
696    getLocalData()->EnumOperandLoc = loc.getRawEncoding();
697  }
698
699  /// The location of the parentheses around the operand, if there is
700  /// an operand.
701  ///    void * __attribute__((objc_gc(weak)))
702  ///                                 ^    ^
703  SourceRange getAttrOperandParensRange() const {
704    assert(hasAttrOperand());
705    return getLocalData()->OperandParens;
706  }
707  void setAttrOperandParensRange(SourceRange range) {
708    assert(hasAttrOperand());
709    getLocalData()->OperandParens = range;
710  }
711
712  SourceRange getLocalSourceRange() const {
713    // Note that this does *not* include the range of the attribute
714    // enclosure, e.g.:
715    //    __attribute__((foo(bar)))
716    //    ^~~~~~~~~~~~~~~        ~~
717    // or
718    //    [[foo(bar)]]
719    //    ^~        ~~
720    // That enclosure doesn't necessarily belong to a single attribute
721    // anyway.
722    SourceRange range(getAttrNameLoc());
723    if (hasAttrOperand())
724      range.setEnd(getAttrOperandParensRange().getEnd());
725    return range;
726  }
727
728  void initializeLocal(ASTContext &Context, SourceLocation loc) {
729    setAttrNameLoc(loc);
730    if (hasAttrExprOperand()) {
731      setAttrOperandParensRange(SourceRange(loc));
732      setAttrExprOperand(0);
733    } else if (hasAttrEnumOperand()) {
734      setAttrOperandParensRange(SourceRange(loc));
735      setAttrEnumOperandLoc(loc);
736    }
737  }
738
739  QualType getInnerType() const {
740    return getTypePtr()->getModifiedType();
741  }
742};
743
744
745struct ObjCProtocolListLocInfo {
746  SourceLocation LAngleLoc;
747  SourceLocation RAngleLoc;
748  bool HasBaseTypeAsWritten;
749};
750
751// A helper class for defining ObjC TypeLocs that can qualified with
752// protocols.
753//
754// TypeClass basically has to be either ObjCInterfaceType or
755// ObjCObjectPointerType.
756class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
757                                                 ObjCObjectTypeLoc,
758                                                 ObjCObjectType,
759                                                 ObjCProtocolListLocInfo> {
760  // SourceLocations are stored after Info, one for each Protocol.
761  SourceLocation *getProtocolLocArray() const {
762    return (SourceLocation*) this->getExtraLocalData();
763  }
764
765public:
766  SourceLocation getLAngleLoc() const {
767    return this->getLocalData()->LAngleLoc;
768  }
769  void setLAngleLoc(SourceLocation Loc) {
770    this->getLocalData()->LAngleLoc = Loc;
771  }
772
773  SourceLocation getRAngleLoc() const {
774    return this->getLocalData()->RAngleLoc;
775  }
776  void setRAngleLoc(SourceLocation Loc) {
777    this->getLocalData()->RAngleLoc = Loc;
778  }
779
780  unsigned getNumProtocols() const {
781    return this->getTypePtr()->getNumProtocols();
782  }
783
784  SourceLocation getProtocolLoc(unsigned i) const {
785    assert(i < getNumProtocols() && "Index is out of bounds!");
786    return getProtocolLocArray()[i];
787  }
788  void setProtocolLoc(unsigned i, SourceLocation Loc) {
789    assert(i < getNumProtocols() && "Index is out of bounds!");
790    getProtocolLocArray()[i] = Loc;
791  }
792
793  ObjCProtocolDecl *getProtocol(unsigned i) const {
794    assert(i < getNumProtocols() && "Index is out of bounds!");
795    return *(this->getTypePtr()->qual_begin() + i);
796  }
797
798  bool hasBaseTypeAsWritten() const {
799    return getLocalData()->HasBaseTypeAsWritten;
800  }
801
802  void setHasBaseTypeAsWritten(bool HasBaseType) {
803    getLocalData()->HasBaseTypeAsWritten = HasBaseType;
804  }
805
806  TypeLoc getBaseLoc() const {
807    return getInnerTypeLoc();
808  }
809
810  SourceRange getLocalSourceRange() const {
811    return SourceRange(getLAngleLoc(), getRAngleLoc());
812  }
813
814  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
815    setHasBaseTypeAsWritten(true);
816    setLAngleLoc(Loc);
817    setRAngleLoc(Loc);
818    for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
819      setProtocolLoc(i, Loc);
820  }
821
822  unsigned getExtraLocalDataSize() const {
823    return this->getNumProtocols() * sizeof(SourceLocation);
824  }
825
826  QualType getInnerType() const {
827    return getTypePtr()->getBaseType();
828  }
829};
830
831
832struct ObjCInterfaceLocInfo {
833  SourceLocation NameLoc;
834  SourceLocation NameEndLoc;
835};
836
837/// \brief Wrapper for source info for ObjC interfaces.
838class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
839                                                    ObjCInterfaceTypeLoc,
840                                                    ObjCInterfaceType,
841                                                    ObjCInterfaceLocInfo> {
842public:
843  ObjCInterfaceDecl *getIFaceDecl() const {
844    return getTypePtr()->getDecl();
845  }
846
847  SourceLocation getNameLoc() const {
848    return getLocalData()->NameLoc;
849  }
850
851  void setNameLoc(SourceLocation Loc) {
852    getLocalData()->NameLoc = Loc;
853  }
854
855  SourceRange getLocalSourceRange() const {
856    return SourceRange(getNameLoc(), getNameEndLoc());
857  }
858
859  SourceLocation getNameEndLoc() const {
860    return getLocalData()->NameEndLoc;
861  }
862
863  void setNameEndLoc(SourceLocation Loc) {
864    getLocalData()->NameEndLoc = Loc;
865  }
866
867  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
868    setNameLoc(Loc);
869  }
870};
871
872struct ParenLocInfo {
873  SourceLocation LParenLoc;
874  SourceLocation RParenLoc;
875};
876
877class ParenTypeLoc
878  : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType,
879                           ParenLocInfo> {
880public:
881  SourceLocation getLParenLoc() const {
882    return this->getLocalData()->LParenLoc;
883  }
884  SourceLocation getRParenLoc() const {
885    return this->getLocalData()->RParenLoc;
886  }
887  void setLParenLoc(SourceLocation Loc) {
888    this->getLocalData()->LParenLoc = Loc;
889  }
890  void setRParenLoc(SourceLocation Loc) {
891    this->getLocalData()->RParenLoc = Loc;
892  }
893
894  SourceRange getLocalSourceRange() const {
895    return SourceRange(getLParenLoc(), getRParenLoc());
896  }
897
898  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
899    setLParenLoc(Loc);
900    setRParenLoc(Loc);
901  }
902
903  TypeLoc getInnerLoc() const {
904    return getInnerTypeLoc();
905  }
906
907  QualType getInnerType() const {
908    return this->getTypePtr()->getInnerType();
909  }
910};
911
912
913struct PointerLikeLocInfo {
914  SourceLocation StarLoc;
915};
916
917/// A base class for
918template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
919class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
920                                                  TypeClass, LocalData> {
921public:
922  SourceLocation getSigilLoc() const {
923    return this->getLocalData()->StarLoc;
924  }
925  void setSigilLoc(SourceLocation Loc) {
926    this->getLocalData()->StarLoc = Loc;
927  }
928
929  TypeLoc getPointeeLoc() const {
930    return this->getInnerTypeLoc();
931  }
932
933  SourceRange getLocalSourceRange() const {
934    return SourceRange(getSigilLoc(), getSigilLoc());
935  }
936
937  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
938    setSigilLoc(Loc);
939  }
940
941  QualType getInnerType() const {
942    return this->getTypePtr()->getPointeeType();
943  }
944};
945
946
947/// \brief Wrapper for source info for pointers.
948class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
949                                                 PointerType> {
950public:
951  SourceLocation getStarLoc() const {
952    return getSigilLoc();
953  }
954  void setStarLoc(SourceLocation Loc) {
955    setSigilLoc(Loc);
956  }
957};
958
959
960/// \brief Wrapper for source info for block pointers.
961class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
962                                                      BlockPointerType> {
963public:
964  SourceLocation getCaretLoc() const {
965    return getSigilLoc();
966  }
967  void setCaretLoc(SourceLocation Loc) {
968    setSigilLoc(Loc);
969  }
970};
971
972struct MemberPointerLocInfo : public PointerLikeLocInfo {
973  TypeSourceInfo *ClassTInfo;
974};
975
976/// \brief Wrapper for source info for member pointers.
977class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
978                                                       MemberPointerType,
979                                                       MemberPointerLocInfo> {
980public:
981  SourceLocation getStarLoc() const {
982    return getSigilLoc();
983  }
984  void setStarLoc(SourceLocation Loc) {
985    setSigilLoc(Loc);
986  }
987
988  const Type *getClass() const {
989    return getTypePtr()->getClass();
990  }
991  TypeSourceInfo *getClassTInfo() const {
992    return getLocalData()->ClassTInfo;
993  }
994  void setClassTInfo(TypeSourceInfo* TI) {
995    getLocalData()->ClassTInfo = TI;
996  }
997
998  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
999    setSigilLoc(Loc);
1000    setClassTInfo(0);
1001  }
1002
1003  SourceRange getLocalSourceRange() const {
1004    if (TypeSourceInfo *TI = getClassTInfo())
1005      return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
1006    else
1007      return SourceRange(getStarLoc());
1008  }
1009};
1010
1011/// Wraps an ObjCPointerType with source location information.
1012class ObjCObjectPointerTypeLoc :
1013    public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
1014                              ObjCObjectPointerType> {
1015public:
1016  SourceLocation getStarLoc() const {
1017    return getSigilLoc();
1018  }
1019
1020  void setStarLoc(SourceLocation Loc) {
1021    setSigilLoc(Loc);
1022  }
1023};
1024
1025
1026class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
1027                                                   ReferenceType> {
1028public:
1029  QualType getInnerType() const {
1030    return getTypePtr()->getPointeeTypeAsWritten();
1031  }
1032};
1033
1034class LValueReferenceTypeLoc :
1035    public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1036                                     LValueReferenceTypeLoc,
1037                                     LValueReferenceType> {
1038public:
1039  SourceLocation getAmpLoc() const {
1040    return getSigilLoc();
1041  }
1042  void setAmpLoc(SourceLocation Loc) {
1043    setSigilLoc(Loc);
1044  }
1045};
1046
1047class RValueReferenceTypeLoc :
1048    public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1049                                     RValueReferenceTypeLoc,
1050                                     RValueReferenceType> {
1051public:
1052  SourceLocation getAmpAmpLoc() const {
1053    return getSigilLoc();
1054  }
1055  void setAmpAmpLoc(SourceLocation Loc) {
1056    setSigilLoc(Loc);
1057  }
1058};
1059
1060
1061struct FunctionLocInfo {
1062  SourceLocation LocalRangeBegin;
1063  SourceLocation LocalRangeEnd;
1064  bool TrailingReturn;
1065};
1066
1067/// \brief Wrapper for source info for functions.
1068class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1069                                               FunctionTypeLoc,
1070                                               FunctionType,
1071                                               FunctionLocInfo> {
1072public:
1073  SourceLocation getLocalRangeBegin() const {
1074    return getLocalData()->LocalRangeBegin;
1075  }
1076  void setLocalRangeBegin(SourceLocation L) {
1077    getLocalData()->LocalRangeBegin = L;
1078  }
1079
1080  SourceLocation getLocalRangeEnd() const {
1081    return getLocalData()->LocalRangeEnd;
1082  }
1083  void setLocalRangeEnd(SourceLocation L) {
1084    getLocalData()->LocalRangeEnd = L;
1085  }
1086
1087  bool getTrailingReturn() const {
1088    return getLocalData()->TrailingReturn;
1089  }
1090  void setTrailingReturn(bool Trailing) {
1091    getLocalData()->TrailingReturn = Trailing;
1092  }
1093
1094  ArrayRef<ParmVarDecl *> getParams() const {
1095    return ArrayRef<ParmVarDecl *>(getParmArray(), getNumArgs());
1096  }
1097
1098  // ParmVarDecls* are stored after Info, one for each argument.
1099  ParmVarDecl **getParmArray() const {
1100    return (ParmVarDecl**) getExtraLocalData();
1101  }
1102
1103  unsigned getNumArgs() const {
1104    if (isa<FunctionNoProtoType>(getTypePtr()))
1105      return 0;
1106    return cast<FunctionProtoType>(getTypePtr())->getNumArgs();
1107  }
1108  ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; }
1109  void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
1110
1111  TypeLoc getResultLoc() const {
1112    return getInnerTypeLoc();
1113  }
1114
1115  SourceRange getLocalSourceRange() const {
1116    return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
1117  }
1118
1119  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1120    setLocalRangeBegin(Loc);
1121    setLocalRangeEnd(Loc);
1122    setTrailingReturn(false);
1123    for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
1124      setArg(i, NULL);
1125  }
1126
1127  /// \brief Returns the size of the type source info data block that is
1128  /// specific to this type.
1129  unsigned getExtraLocalDataSize() const {
1130    return getNumArgs() * sizeof(ParmVarDecl*);
1131  }
1132
1133  QualType getInnerType() const { return getTypePtr()->getResultType(); }
1134};
1135
1136class FunctionProtoTypeLoc :
1137    public InheritingConcreteTypeLoc<FunctionTypeLoc,
1138                                     FunctionProtoTypeLoc,
1139                                     FunctionProtoType> {
1140};
1141
1142class FunctionNoProtoTypeLoc :
1143    public InheritingConcreteTypeLoc<FunctionTypeLoc,
1144                                     FunctionNoProtoTypeLoc,
1145                                     FunctionNoProtoType> {
1146};
1147
1148
1149struct ArrayLocInfo {
1150  SourceLocation LBracketLoc, RBracketLoc;
1151  Expr *Size;
1152};
1153
1154/// \brief Wrapper for source info for arrays.
1155class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1156                                            ArrayTypeLoc,
1157                                            ArrayType,
1158                                            ArrayLocInfo> {
1159public:
1160  SourceLocation getLBracketLoc() const {
1161    return getLocalData()->LBracketLoc;
1162  }
1163  void setLBracketLoc(SourceLocation Loc) {
1164    getLocalData()->LBracketLoc = Loc;
1165  }
1166
1167  SourceLocation getRBracketLoc() const {
1168    return getLocalData()->RBracketLoc;
1169  }
1170  void setRBracketLoc(SourceLocation Loc) {
1171    getLocalData()->RBracketLoc = Loc;
1172  }
1173
1174  SourceRange getBracketsRange() const {
1175    return SourceRange(getLBracketLoc(), getRBracketLoc());
1176  }
1177
1178  Expr *getSizeExpr() const {
1179    return getLocalData()->Size;
1180  }
1181  void setSizeExpr(Expr *Size) {
1182    getLocalData()->Size = Size;
1183  }
1184
1185  TypeLoc getElementLoc() const {
1186    return getInnerTypeLoc();
1187  }
1188
1189  SourceRange getLocalSourceRange() const {
1190    return SourceRange(getLBracketLoc(), getRBracketLoc());
1191  }
1192
1193  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1194    setLBracketLoc(Loc);
1195    setRBracketLoc(Loc);
1196    setSizeExpr(NULL);
1197  }
1198
1199  QualType getInnerType() const { return getTypePtr()->getElementType(); }
1200};
1201
1202class ConstantArrayTypeLoc :
1203    public InheritingConcreteTypeLoc<ArrayTypeLoc,
1204                                     ConstantArrayTypeLoc,
1205                                     ConstantArrayType> {
1206};
1207
1208class IncompleteArrayTypeLoc :
1209    public InheritingConcreteTypeLoc<ArrayTypeLoc,
1210                                     IncompleteArrayTypeLoc,
1211                                     IncompleteArrayType> {
1212};
1213
1214class DependentSizedArrayTypeLoc :
1215    public InheritingConcreteTypeLoc<ArrayTypeLoc,
1216                                     DependentSizedArrayTypeLoc,
1217                                     DependentSizedArrayType> {
1218
1219};
1220
1221class VariableArrayTypeLoc :
1222    public InheritingConcreteTypeLoc<ArrayTypeLoc,
1223                                     VariableArrayTypeLoc,
1224                                     VariableArrayType> {
1225};
1226
1227
1228// Location information for a TemplateName.  Rudimentary for now.
1229struct TemplateNameLocInfo {
1230  SourceLocation NameLoc;
1231};
1232
1233struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
1234  SourceLocation TemplateKWLoc;
1235  SourceLocation LAngleLoc;
1236  SourceLocation RAngleLoc;
1237};
1238
1239class TemplateSpecializationTypeLoc :
1240    public ConcreteTypeLoc<UnqualTypeLoc,
1241                           TemplateSpecializationTypeLoc,
1242                           TemplateSpecializationType,
1243                           TemplateSpecializationLocInfo> {
1244public:
1245  SourceLocation getTemplateKeywordLoc() const {
1246    return getLocalData()->TemplateKWLoc;
1247  }
1248  void setTemplateKeywordLoc(SourceLocation Loc) {
1249    getLocalData()->TemplateKWLoc = Loc;
1250  }
1251
1252  SourceLocation getLAngleLoc() const {
1253    return getLocalData()->LAngleLoc;
1254  }
1255  void setLAngleLoc(SourceLocation Loc) {
1256    getLocalData()->LAngleLoc = Loc;
1257  }
1258
1259  SourceLocation getRAngleLoc() const {
1260    return getLocalData()->RAngleLoc;
1261  }
1262  void setRAngleLoc(SourceLocation Loc) {
1263    getLocalData()->RAngleLoc = Loc;
1264  }
1265
1266  unsigned getNumArgs() const {
1267    return getTypePtr()->getNumArgs();
1268  }
1269  void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1270    getArgInfos()[i] = AI;
1271  }
1272  TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1273    return getArgInfos()[i];
1274  }
1275
1276  TemplateArgumentLoc getArgLoc(unsigned i) const {
1277    return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1278  }
1279
1280  SourceLocation getTemplateNameLoc() const {
1281    return getLocalData()->NameLoc;
1282  }
1283  void setTemplateNameLoc(SourceLocation Loc) {
1284    getLocalData()->NameLoc = Loc;
1285  }
1286
1287  /// \brief - Copy the location information from the given info.
1288  void copy(TemplateSpecializationTypeLoc Loc) {
1289    unsigned size = getFullDataSize();
1290    assert(size == Loc.getFullDataSize());
1291
1292    // We're potentially copying Expr references here.  We don't
1293    // bother retaining them because TypeSourceInfos live forever, so
1294    // as long as the Expr was retained when originally written into
1295    // the TypeLoc, we're okay.
1296    memcpy(Data, Loc.Data, size);
1297  }
1298
1299  SourceRange getLocalSourceRange() const {
1300    if (getTemplateKeywordLoc().isValid())
1301      return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1302    else
1303      return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1304  }
1305
1306  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1307    setTemplateKeywordLoc(Loc);
1308    setTemplateNameLoc(Loc);
1309    setLAngleLoc(Loc);
1310    setRAngleLoc(Loc);
1311    initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
1312                      getArgInfos(), Loc);
1313  }
1314
1315  static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
1316                                const TemplateArgument *Args,
1317                                TemplateArgumentLocInfo *ArgInfos,
1318                                SourceLocation Loc);
1319
1320  unsigned getExtraLocalDataSize() const {
1321    return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1322  }
1323
1324private:
1325  TemplateArgumentLocInfo *getArgInfos() const {
1326    return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1327  }
1328};
1329
1330//===----------------------------------------------------------------------===//
1331//
1332//  All of these need proper implementations.
1333//
1334//===----------------------------------------------------------------------===//
1335
1336// FIXME: size expression and attribute locations (or keyword if we
1337// ever fully support altivec syntax).
1338class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1339                                                       VectorTypeLoc,
1340                                                       VectorType> {
1341};
1342
1343// FIXME: size expression and attribute locations.
1344class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
1345                                                          ExtVectorTypeLoc,
1346                                                          ExtVectorType> {
1347};
1348
1349// FIXME: attribute locations.
1350// For some reason, this isn't a subtype of VectorType.
1351class DependentSizedExtVectorTypeLoc :
1352    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1353                                     DependentSizedExtVectorTypeLoc,
1354                                     DependentSizedExtVectorType> {
1355};
1356
1357// FIXME: location of the '_Complex' keyword.
1358class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1359                                                        ComplexTypeLoc,
1360                                                        ComplexType> {
1361};
1362
1363struct TypeofLocInfo {
1364  SourceLocation TypeofLoc;
1365  SourceLocation LParenLoc;
1366  SourceLocation RParenLoc;
1367};
1368
1369struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
1370};
1371
1372struct TypeOfTypeLocInfo : public TypeofLocInfo {
1373  TypeSourceInfo* UnderlyingTInfo;
1374};
1375
1376template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
1377class TypeofLikeTypeLoc
1378  : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
1379public:
1380  SourceLocation getTypeofLoc() const {
1381    return this->getLocalData()->TypeofLoc;
1382  }
1383  void setTypeofLoc(SourceLocation Loc) {
1384    this->getLocalData()->TypeofLoc = Loc;
1385  }
1386
1387  SourceLocation getLParenLoc() const {
1388    return this->getLocalData()->LParenLoc;
1389  }
1390  void setLParenLoc(SourceLocation Loc) {
1391    this->getLocalData()->LParenLoc = Loc;
1392  }
1393
1394  SourceLocation getRParenLoc() const {
1395    return this->getLocalData()->RParenLoc;
1396  }
1397  void setRParenLoc(SourceLocation Loc) {
1398    this->getLocalData()->RParenLoc = Loc;
1399  }
1400
1401  SourceRange getParensRange() const {
1402    return SourceRange(getLParenLoc(), getRParenLoc());
1403  }
1404  void setParensRange(SourceRange range) {
1405      setLParenLoc(range.getBegin());
1406      setRParenLoc(range.getEnd());
1407  }
1408
1409  SourceRange getLocalSourceRange() const {
1410    return SourceRange(getTypeofLoc(), getRParenLoc());
1411  }
1412
1413  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1414    setTypeofLoc(Loc);
1415    setLParenLoc(Loc);
1416    setRParenLoc(Loc);
1417  }
1418};
1419
1420class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
1421                                                   TypeOfExprType,
1422                                                   TypeOfExprTypeLocInfo> {
1423public:
1424  Expr* getUnderlyingExpr() const {
1425    return getTypePtr()->getUnderlyingExpr();
1426  }
1427  // Reimplemented to account for GNU/C++ extension
1428  //     typeof unary-expression
1429  // where there are no parentheses.
1430  SourceRange getLocalSourceRange() const;
1431};
1432
1433class TypeOfTypeLoc
1434  : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
1435public:
1436  QualType getUnderlyingType() const {
1437    return this->getTypePtr()->getUnderlyingType();
1438  }
1439  TypeSourceInfo* getUnderlyingTInfo() const {
1440    return this->getLocalData()->UnderlyingTInfo;
1441  }
1442  void setUnderlyingTInfo(TypeSourceInfo* TI) const {
1443    this->getLocalData()->UnderlyingTInfo = TI;
1444  }
1445};
1446
1447// FIXME: location of the 'decltype' and parens.
1448class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1449                                                         DecltypeTypeLoc,
1450                                                         DecltypeType> {
1451public:
1452  Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
1453};
1454
1455struct UnaryTransformTypeLocInfo {
1456  // FIXME: While there's only one unary transform right now, future ones may
1457  // need different representations
1458  SourceLocation KWLoc, LParenLoc, RParenLoc;
1459  TypeSourceInfo *UnderlyingTInfo;
1460};
1461
1462class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1463                                                    UnaryTransformTypeLoc,
1464                                                    UnaryTransformType,
1465                                                    UnaryTransformTypeLocInfo> {
1466public:
1467  SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
1468  void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
1469
1470  SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
1471  void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
1472
1473  SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
1474  void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
1475
1476  TypeSourceInfo* getUnderlyingTInfo() const {
1477    return getLocalData()->UnderlyingTInfo;
1478  }
1479  void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
1480    getLocalData()->UnderlyingTInfo = TInfo;
1481  }
1482
1483  SourceRange getLocalSourceRange() const {
1484    return SourceRange(getKWLoc(), getRParenLoc());
1485  }
1486
1487  SourceRange getParensRange() const {
1488    return SourceRange(getLParenLoc(), getRParenLoc());
1489  }
1490  void setParensRange(SourceRange Range) {
1491    setLParenLoc(Range.getBegin());
1492    setRParenLoc(Range.getEnd());
1493  }
1494
1495  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1496    setKWLoc(Loc);
1497    setRParenLoc(Loc);
1498    setLParenLoc(Loc);
1499  }
1500};
1501
1502class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1503                                                        AutoTypeLoc,
1504                                                        AutoType> {
1505};
1506
1507struct ElaboratedLocInfo {
1508  SourceLocation ElaboratedKWLoc;
1509  /// \brief Data associated with the nested-name-specifier location.
1510  void *QualifierData;
1511};
1512
1513class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1514                                                 ElaboratedTypeLoc,
1515                                                 ElaboratedType,
1516                                                 ElaboratedLocInfo> {
1517public:
1518  SourceLocation getElaboratedKeywordLoc() const {
1519    return this->getLocalData()->ElaboratedKWLoc;
1520  }
1521  void setElaboratedKeywordLoc(SourceLocation Loc) {
1522    this->getLocalData()->ElaboratedKWLoc = Loc;
1523  }
1524
1525  NestedNameSpecifierLoc getQualifierLoc() const {
1526    return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1527                                  getLocalData()->QualifierData);
1528  }
1529
1530  void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1531    assert(QualifierLoc.getNestedNameSpecifier()
1532                                            == getTypePtr()->getQualifier() &&
1533           "Inconsistent nested-name-specifier pointer");
1534    getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1535  }
1536
1537  SourceRange getLocalSourceRange() const {
1538    if (getElaboratedKeywordLoc().isValid())
1539      if (getQualifierLoc())
1540        return SourceRange(getElaboratedKeywordLoc(),
1541                           getQualifierLoc().getEndLoc());
1542      else
1543        return SourceRange(getElaboratedKeywordLoc());
1544    else
1545      return getQualifierLoc().getSourceRange();
1546  }
1547
1548  void initializeLocal(ASTContext &Context, SourceLocation Loc);
1549
1550  TypeLoc getNamedTypeLoc() const {
1551    return getInnerTypeLoc();
1552  }
1553
1554  QualType getInnerType() const {
1555    return getTypePtr()->getNamedType();
1556  }
1557
1558  void copy(ElaboratedTypeLoc Loc) {
1559    unsigned size = getFullDataSize();
1560    assert(size == Loc.getFullDataSize());
1561    memcpy(Data, Loc.Data, size);
1562  }
1563};
1564
1565// This is exactly the structure of an ElaboratedTypeLoc whose inner
1566// type is some sort of TypeDeclTypeLoc.
1567struct DependentNameLocInfo : ElaboratedLocInfo {
1568  SourceLocation NameLoc;
1569};
1570
1571class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1572                                                    DependentNameTypeLoc,
1573                                                    DependentNameType,
1574                                                    DependentNameLocInfo> {
1575public:
1576  SourceLocation getElaboratedKeywordLoc() const {
1577    return this->getLocalData()->ElaboratedKWLoc;
1578  }
1579  void setElaboratedKeywordLoc(SourceLocation Loc) {
1580    this->getLocalData()->ElaboratedKWLoc = Loc;
1581  }
1582
1583  NestedNameSpecifierLoc getQualifierLoc() const {
1584    return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1585                                  getLocalData()->QualifierData);
1586  }
1587
1588  void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1589    assert(QualifierLoc.getNestedNameSpecifier()
1590                                            == getTypePtr()->getQualifier() &&
1591           "Inconsistent nested-name-specifier pointer");
1592    getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1593  }
1594
1595  SourceLocation getNameLoc() const {
1596    return this->getLocalData()->NameLoc;
1597  }
1598  void setNameLoc(SourceLocation Loc) {
1599    this->getLocalData()->NameLoc = Loc;
1600  }
1601
1602  SourceRange getLocalSourceRange() const {
1603    if (getElaboratedKeywordLoc().isValid())
1604      return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
1605    else
1606      return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
1607  }
1608
1609  void copy(DependentNameTypeLoc Loc) {
1610    unsigned size = getFullDataSize();
1611    assert(size == Loc.getFullDataSize());
1612    memcpy(Data, Loc.Data, size);
1613  }
1614
1615  void initializeLocal(ASTContext &Context, SourceLocation Loc);
1616};
1617
1618struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
1619  SourceLocation TemplateKWLoc;
1620  SourceLocation LAngleLoc;
1621  SourceLocation RAngleLoc;
1622  // followed by a TemplateArgumentLocInfo[]
1623};
1624
1625class DependentTemplateSpecializationTypeLoc :
1626    public ConcreteTypeLoc<UnqualTypeLoc,
1627                           DependentTemplateSpecializationTypeLoc,
1628                           DependentTemplateSpecializationType,
1629                           DependentTemplateSpecializationLocInfo> {
1630public:
1631  SourceLocation getElaboratedKeywordLoc() const {
1632    return this->getLocalData()->ElaboratedKWLoc;
1633  }
1634  void setElaboratedKeywordLoc(SourceLocation Loc) {
1635    this->getLocalData()->ElaboratedKWLoc = Loc;
1636  }
1637
1638  NestedNameSpecifierLoc getQualifierLoc() const {
1639    if (!getLocalData()->QualifierData)
1640      return NestedNameSpecifierLoc();
1641
1642    return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1643                                  getLocalData()->QualifierData);
1644  }
1645
1646  void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1647    if (!QualifierLoc) {
1648      // Even if we have a nested-name-specifier in the dependent
1649      // template specialization type, we won't record the nested-name-specifier
1650      // location information when this type-source location information is
1651      // part of a nested-name-specifier.
1652      getLocalData()->QualifierData = 0;
1653      return;
1654    }
1655
1656    assert(QualifierLoc.getNestedNameSpecifier()
1657                                        == getTypePtr()->getQualifier() &&
1658           "Inconsistent nested-name-specifier pointer");
1659    getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1660  }
1661
1662  SourceLocation getTemplateKeywordLoc() const {
1663    return getLocalData()->TemplateKWLoc;
1664  }
1665  void setTemplateKeywordLoc(SourceLocation Loc) {
1666    getLocalData()->TemplateKWLoc = Loc;
1667  }
1668
1669  SourceLocation getTemplateNameLoc() const {
1670    return this->getLocalData()->NameLoc;
1671  }
1672  void setTemplateNameLoc(SourceLocation Loc) {
1673    this->getLocalData()->NameLoc = Loc;
1674  }
1675
1676  SourceLocation getLAngleLoc() const {
1677    return this->getLocalData()->LAngleLoc;
1678  }
1679  void setLAngleLoc(SourceLocation Loc) {
1680    this->getLocalData()->LAngleLoc = Loc;
1681  }
1682
1683  SourceLocation getRAngleLoc() const {
1684    return this->getLocalData()->RAngleLoc;
1685  }
1686  void setRAngleLoc(SourceLocation Loc) {
1687    this->getLocalData()->RAngleLoc = Loc;
1688  }
1689
1690  unsigned getNumArgs() const {
1691    return getTypePtr()->getNumArgs();
1692  }
1693
1694  void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1695    getArgInfos()[i] = AI;
1696  }
1697  TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1698    return getArgInfos()[i];
1699  }
1700
1701  TemplateArgumentLoc getArgLoc(unsigned i) const {
1702    return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1703  }
1704
1705  SourceRange getLocalSourceRange() const {
1706    if (getElaboratedKeywordLoc().isValid())
1707      return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
1708    else if (getQualifierLoc())
1709      return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
1710    else if (getTemplateKeywordLoc().isValid())
1711      return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1712    else
1713      return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1714  }
1715
1716  void copy(DependentTemplateSpecializationTypeLoc Loc) {
1717    unsigned size = getFullDataSize();
1718    assert(size == Loc.getFullDataSize());
1719    memcpy(Data, Loc.Data, size);
1720  }
1721
1722  void initializeLocal(ASTContext &Context, SourceLocation Loc);
1723
1724  unsigned getExtraLocalDataSize() const {
1725    return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1726  }
1727
1728private:
1729  TemplateArgumentLocInfo *getArgInfos() const {
1730    return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1731  }
1732};
1733
1734
1735struct PackExpansionTypeLocInfo {
1736  SourceLocation EllipsisLoc;
1737};
1738
1739class PackExpansionTypeLoc
1740  : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
1741                           PackExpansionType, PackExpansionTypeLocInfo> {
1742public:
1743  SourceLocation getEllipsisLoc() const {
1744    return this->getLocalData()->EllipsisLoc;
1745  }
1746
1747  void setEllipsisLoc(SourceLocation Loc) {
1748    this->getLocalData()->EllipsisLoc = Loc;
1749  }
1750
1751  SourceRange getLocalSourceRange() const {
1752    return SourceRange(getEllipsisLoc(), getEllipsisLoc());
1753  }
1754
1755  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1756    setEllipsisLoc(Loc);
1757  }
1758
1759  TypeLoc getPatternLoc() const {
1760    return getInnerTypeLoc();
1761  }
1762
1763  QualType getInnerType() const {
1764    return this->getTypePtr()->getPattern();
1765  }
1766};
1767
1768struct AtomicTypeLocInfo {
1769  SourceLocation KWLoc, LParenLoc, RParenLoc;
1770};
1771
1772class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
1773                                             AtomicType, AtomicTypeLocInfo> {
1774public:
1775  TypeLoc getValueLoc() const {
1776    return this->getInnerTypeLoc();
1777  }
1778
1779  SourceRange getLocalSourceRange() const {
1780    return SourceRange(getKWLoc(), getRParenLoc());
1781  }
1782
1783  SourceLocation getKWLoc() const {
1784    return this->getLocalData()->KWLoc;
1785  }
1786  void setKWLoc(SourceLocation Loc) {
1787    this->getLocalData()->KWLoc = Loc;
1788  }
1789
1790  SourceLocation getLParenLoc() const {
1791    return this->getLocalData()->LParenLoc;
1792  }
1793  void setLParenLoc(SourceLocation Loc) {
1794    this->getLocalData()->LParenLoc = Loc;
1795  }
1796
1797  SourceLocation getRParenLoc() const {
1798    return this->getLocalData()->RParenLoc;
1799  }
1800  void setRParenLoc(SourceLocation Loc) {
1801    this->getLocalData()->RParenLoc = Loc;
1802  }
1803
1804  SourceRange getParensRange() const {
1805    return SourceRange(getLParenLoc(), getRParenLoc());
1806  }
1807  void setParensRange(SourceRange Range) {
1808    setLParenLoc(Range.getBegin());
1809    setRParenLoc(Range.getEnd());
1810  }
1811
1812  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1813    setKWLoc(Loc);
1814    setLParenLoc(Loc);
1815    setRParenLoc(Loc);
1816  }
1817
1818  QualType getInnerType() const {
1819    return this->getTypePtr()->getValueType();
1820  }
1821};
1822
1823
1824}
1825
1826#endif
1827