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