TypeLoc.h revision 44ee0a710c59d8e6793189f903bae21c16814324
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
977struct PointerLikeLocInfo {
978  SourceLocation StarLoc;
979};
980
981/// A base class for
982template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
983class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
984                                                  TypeClass, LocalData> {
985public:
986  SourceLocation getSigilLoc() const {
987    return this->getLocalData()->StarLoc;
988  }
989  void setSigilLoc(SourceLocation Loc) {
990    this->getLocalData()->StarLoc = Loc;
991  }
992
993  TypeLoc getPointeeLoc() const {
994    return this->getInnerTypeLoc();
995  }
996
997  SourceRange getLocalSourceRange() const {
998    return SourceRange(getSigilLoc(), getSigilLoc());
999  }
1000
1001  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1002    setSigilLoc(Loc);
1003  }
1004
1005  QualType getInnerType() const {
1006    return this->getTypePtr()->getPointeeType();
1007  }
1008};
1009
1010
1011/// \brief Wrapper for source info for pointers.
1012class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
1013                                                 PointerType> {
1014public:
1015  SourceLocation getStarLoc() const {
1016    return getSigilLoc();
1017  }
1018  void setStarLoc(SourceLocation Loc) {
1019    setSigilLoc(Loc);
1020  }
1021};
1022
1023
1024/// \brief Wrapper for source info for block pointers.
1025class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
1026                                                      BlockPointerType> {
1027public:
1028  SourceLocation getCaretLoc() const {
1029    return getSigilLoc();
1030  }
1031  void setCaretLoc(SourceLocation Loc) {
1032    setSigilLoc(Loc);
1033  }
1034};
1035
1036struct MemberPointerLocInfo : public PointerLikeLocInfo {
1037  TypeSourceInfo *ClassTInfo;
1038};
1039
1040/// \brief Wrapper for source info for member pointers.
1041class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
1042                                                       MemberPointerType,
1043                                                       MemberPointerLocInfo> {
1044public:
1045  SourceLocation getStarLoc() const {
1046    return getSigilLoc();
1047  }
1048  void setStarLoc(SourceLocation Loc) {
1049    setSigilLoc(Loc);
1050  }
1051
1052  const Type *getClass() const {
1053    return getTypePtr()->getClass();
1054  }
1055  TypeSourceInfo *getClassTInfo() const {
1056    return getLocalData()->ClassTInfo;
1057  }
1058  void setClassTInfo(TypeSourceInfo* TI) {
1059    getLocalData()->ClassTInfo = TI;
1060  }
1061
1062  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1063    setSigilLoc(Loc);
1064    setClassTInfo(0);
1065  }
1066
1067  SourceRange getLocalSourceRange() const {
1068    if (TypeSourceInfo *TI = getClassTInfo())
1069      return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
1070    else
1071      return SourceRange(getStarLoc());
1072  }
1073};
1074
1075/// Wraps an ObjCPointerType with source location information.
1076class ObjCObjectPointerTypeLoc :
1077    public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
1078                              ObjCObjectPointerType> {
1079public:
1080  SourceLocation getStarLoc() const {
1081    return getSigilLoc();
1082  }
1083
1084  void setStarLoc(SourceLocation Loc) {
1085    setSigilLoc(Loc);
1086  }
1087};
1088
1089
1090class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
1091                                                   ReferenceType> {
1092public:
1093  QualType getInnerType() const {
1094    return getTypePtr()->getPointeeTypeAsWritten();
1095  }
1096};
1097
1098class LValueReferenceTypeLoc :
1099    public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1100                                     LValueReferenceTypeLoc,
1101                                     LValueReferenceType> {
1102public:
1103  SourceLocation getAmpLoc() const {
1104    return getSigilLoc();
1105  }
1106  void setAmpLoc(SourceLocation Loc) {
1107    setSigilLoc(Loc);
1108  }
1109};
1110
1111class RValueReferenceTypeLoc :
1112    public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1113                                     RValueReferenceTypeLoc,
1114                                     RValueReferenceType> {
1115public:
1116  SourceLocation getAmpAmpLoc() const {
1117    return getSigilLoc();
1118  }
1119  void setAmpAmpLoc(SourceLocation Loc) {
1120    setSigilLoc(Loc);
1121  }
1122};
1123
1124
1125struct FunctionLocInfo {
1126  SourceLocation LocalRangeBegin;
1127  SourceLocation LParenLoc;
1128  SourceLocation RParenLoc;
1129  SourceLocation LocalRangeEnd;
1130};
1131
1132/// \brief Wrapper for source info for functions.
1133class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1134                                               FunctionTypeLoc,
1135                                               FunctionType,
1136                                               FunctionLocInfo> {
1137public:
1138  SourceLocation getLocalRangeBegin() const {
1139    return getLocalData()->LocalRangeBegin;
1140  }
1141  void setLocalRangeBegin(SourceLocation L) {
1142    getLocalData()->LocalRangeBegin = L;
1143  }
1144
1145  SourceLocation getLocalRangeEnd() const {
1146    return getLocalData()->LocalRangeEnd;
1147  }
1148  void setLocalRangeEnd(SourceLocation L) {
1149    getLocalData()->LocalRangeEnd = L;
1150  }
1151
1152  SourceLocation getLParenLoc() const {
1153    return this->getLocalData()->LParenLoc;
1154  }
1155  void setLParenLoc(SourceLocation Loc) {
1156    this->getLocalData()->LParenLoc = Loc;
1157  }
1158
1159  SourceLocation getRParenLoc() const {
1160    return this->getLocalData()->RParenLoc;
1161  }
1162  void setRParenLoc(SourceLocation Loc) {
1163    this->getLocalData()->RParenLoc = Loc;
1164  }
1165
1166  SourceRange getParensRange() const {
1167    return SourceRange(getLParenLoc(), getRParenLoc());
1168  }
1169
1170  ArrayRef<ParmVarDecl *> getParams() const {
1171    return ArrayRef<ParmVarDecl *>(getParmArray(), getNumArgs());
1172  }
1173
1174  // ParmVarDecls* are stored after Info, one for each argument.
1175  ParmVarDecl **getParmArray() const {
1176    return (ParmVarDecl**) getExtraLocalData();
1177  }
1178
1179  unsigned getNumArgs() const {
1180    if (isa<FunctionNoProtoType>(getTypePtr()))
1181      return 0;
1182    return cast<FunctionProtoType>(getTypePtr())->getNumArgs();
1183  }
1184  ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; }
1185  void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
1186
1187  TypeLoc getResultLoc() const {
1188    return getInnerTypeLoc();
1189  }
1190
1191  SourceRange getLocalSourceRange() const {
1192    return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
1193  }
1194
1195  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1196    setLocalRangeBegin(Loc);
1197    setLParenLoc(Loc);
1198    setRParenLoc(Loc);
1199    setLocalRangeEnd(Loc);
1200    for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
1201      setArg(i, NULL);
1202  }
1203
1204  /// \brief Returns the size of the type source info data block that is
1205  /// specific to this type.
1206  unsigned getExtraLocalDataSize() const {
1207    return getNumArgs() * sizeof(ParmVarDecl*);
1208  }
1209
1210  unsigned getExtraLocalDataAlignment() const {
1211    return llvm::alignOf<ParmVarDecl*>();
1212  }
1213
1214  QualType getInnerType() const { return getTypePtr()->getResultType(); }
1215};
1216
1217class FunctionProtoTypeLoc :
1218    public InheritingConcreteTypeLoc<FunctionTypeLoc,
1219                                     FunctionProtoTypeLoc,
1220                                     FunctionProtoType> {
1221};
1222
1223class FunctionNoProtoTypeLoc :
1224    public InheritingConcreteTypeLoc<FunctionTypeLoc,
1225                                     FunctionNoProtoTypeLoc,
1226                                     FunctionNoProtoType> {
1227};
1228
1229
1230struct ArrayLocInfo {
1231  SourceLocation LBracketLoc, RBracketLoc;
1232  Expr *Size;
1233};
1234
1235/// \brief Wrapper for source info for arrays.
1236class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1237                                            ArrayTypeLoc,
1238                                            ArrayType,
1239                                            ArrayLocInfo> {
1240public:
1241  SourceLocation getLBracketLoc() const {
1242    return getLocalData()->LBracketLoc;
1243  }
1244  void setLBracketLoc(SourceLocation Loc) {
1245    getLocalData()->LBracketLoc = Loc;
1246  }
1247
1248  SourceLocation getRBracketLoc() const {
1249    return getLocalData()->RBracketLoc;
1250  }
1251  void setRBracketLoc(SourceLocation Loc) {
1252    getLocalData()->RBracketLoc = Loc;
1253  }
1254
1255  SourceRange getBracketsRange() const {
1256    return SourceRange(getLBracketLoc(), getRBracketLoc());
1257  }
1258
1259  Expr *getSizeExpr() const {
1260    return getLocalData()->Size;
1261  }
1262  void setSizeExpr(Expr *Size) {
1263    getLocalData()->Size = Size;
1264  }
1265
1266  TypeLoc getElementLoc() const {
1267    return getInnerTypeLoc();
1268  }
1269
1270  SourceRange getLocalSourceRange() const {
1271    return SourceRange(getLBracketLoc(), getRBracketLoc());
1272  }
1273
1274  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1275    setLBracketLoc(Loc);
1276    setRBracketLoc(Loc);
1277    setSizeExpr(NULL);
1278  }
1279
1280  QualType getInnerType() const { return getTypePtr()->getElementType(); }
1281};
1282
1283class ConstantArrayTypeLoc :
1284    public InheritingConcreteTypeLoc<ArrayTypeLoc,
1285                                     ConstantArrayTypeLoc,
1286                                     ConstantArrayType> {
1287};
1288
1289class IncompleteArrayTypeLoc :
1290    public InheritingConcreteTypeLoc<ArrayTypeLoc,
1291                                     IncompleteArrayTypeLoc,
1292                                     IncompleteArrayType> {
1293};
1294
1295class DependentSizedArrayTypeLoc :
1296    public InheritingConcreteTypeLoc<ArrayTypeLoc,
1297                                     DependentSizedArrayTypeLoc,
1298                                     DependentSizedArrayType> {
1299
1300};
1301
1302class VariableArrayTypeLoc :
1303    public InheritingConcreteTypeLoc<ArrayTypeLoc,
1304                                     VariableArrayTypeLoc,
1305                                     VariableArrayType> {
1306};
1307
1308
1309// Location information for a TemplateName.  Rudimentary for now.
1310struct TemplateNameLocInfo {
1311  SourceLocation NameLoc;
1312};
1313
1314struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
1315  SourceLocation TemplateKWLoc;
1316  SourceLocation LAngleLoc;
1317  SourceLocation RAngleLoc;
1318};
1319
1320class TemplateSpecializationTypeLoc :
1321    public ConcreteTypeLoc<UnqualTypeLoc,
1322                           TemplateSpecializationTypeLoc,
1323                           TemplateSpecializationType,
1324                           TemplateSpecializationLocInfo> {
1325public:
1326  SourceLocation getTemplateKeywordLoc() const {
1327    return getLocalData()->TemplateKWLoc;
1328  }
1329  void setTemplateKeywordLoc(SourceLocation Loc) {
1330    getLocalData()->TemplateKWLoc = Loc;
1331  }
1332
1333  SourceLocation getLAngleLoc() const {
1334    return getLocalData()->LAngleLoc;
1335  }
1336  void setLAngleLoc(SourceLocation Loc) {
1337    getLocalData()->LAngleLoc = Loc;
1338  }
1339
1340  SourceLocation getRAngleLoc() const {
1341    return getLocalData()->RAngleLoc;
1342  }
1343  void setRAngleLoc(SourceLocation Loc) {
1344    getLocalData()->RAngleLoc = Loc;
1345  }
1346
1347  unsigned getNumArgs() const {
1348    return getTypePtr()->getNumArgs();
1349  }
1350  void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1351    getArgInfos()[i] = AI;
1352  }
1353  TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1354    return getArgInfos()[i];
1355  }
1356
1357  TemplateArgumentLoc getArgLoc(unsigned i) const {
1358    return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1359  }
1360
1361  SourceLocation getTemplateNameLoc() const {
1362    return getLocalData()->NameLoc;
1363  }
1364  void setTemplateNameLoc(SourceLocation Loc) {
1365    getLocalData()->NameLoc = Loc;
1366  }
1367
1368  /// \brief - Copy the location information from the given info.
1369  void copy(TemplateSpecializationTypeLoc Loc) {
1370    unsigned size = getFullDataSize();
1371    assert(size == Loc.getFullDataSize());
1372
1373    // We're potentially copying Expr references here.  We don't
1374    // bother retaining them because TypeSourceInfos live forever, so
1375    // as long as the Expr was retained when originally written into
1376    // the TypeLoc, we're okay.
1377    memcpy(Data, Loc.Data, size);
1378  }
1379
1380  SourceRange getLocalSourceRange() const {
1381    if (getTemplateKeywordLoc().isValid())
1382      return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1383    else
1384      return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1385  }
1386
1387  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1388    setTemplateKeywordLoc(Loc);
1389    setTemplateNameLoc(Loc);
1390    setLAngleLoc(Loc);
1391    setRAngleLoc(Loc);
1392    initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
1393                      getArgInfos(), Loc);
1394  }
1395
1396  static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
1397                                const TemplateArgument *Args,
1398                                TemplateArgumentLocInfo *ArgInfos,
1399                                SourceLocation Loc);
1400
1401  unsigned getExtraLocalDataSize() const {
1402    return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1403  }
1404
1405  unsigned getExtraLocalDataAlignment() const {
1406    return llvm::alignOf<TemplateArgumentLocInfo>();
1407  }
1408
1409private:
1410  TemplateArgumentLocInfo *getArgInfos() const {
1411    return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1412  }
1413};
1414
1415//===----------------------------------------------------------------------===//
1416//
1417//  All of these need proper implementations.
1418//
1419//===----------------------------------------------------------------------===//
1420
1421// FIXME: size expression and attribute locations (or keyword if we
1422// ever fully support altivec syntax).
1423class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1424                                                       VectorTypeLoc,
1425                                                       VectorType> {
1426};
1427
1428// FIXME: size expression and attribute locations.
1429class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
1430                                                          ExtVectorTypeLoc,
1431                                                          ExtVectorType> {
1432};
1433
1434// FIXME: attribute locations.
1435// For some reason, this isn't a subtype of VectorType.
1436class DependentSizedExtVectorTypeLoc :
1437    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1438                                     DependentSizedExtVectorTypeLoc,
1439                                     DependentSizedExtVectorType> {
1440};
1441
1442// FIXME: location of the '_Complex' keyword.
1443class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1444                                                        ComplexTypeLoc,
1445                                                        ComplexType> {
1446};
1447
1448struct TypeofLocInfo {
1449  SourceLocation TypeofLoc;
1450  SourceLocation LParenLoc;
1451  SourceLocation RParenLoc;
1452};
1453
1454struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
1455};
1456
1457struct TypeOfTypeLocInfo : public TypeofLocInfo {
1458  TypeSourceInfo* UnderlyingTInfo;
1459};
1460
1461template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
1462class TypeofLikeTypeLoc
1463  : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
1464public:
1465  SourceLocation getTypeofLoc() const {
1466    return this->getLocalData()->TypeofLoc;
1467  }
1468  void setTypeofLoc(SourceLocation Loc) {
1469    this->getLocalData()->TypeofLoc = Loc;
1470  }
1471
1472  SourceLocation getLParenLoc() const {
1473    return this->getLocalData()->LParenLoc;
1474  }
1475  void setLParenLoc(SourceLocation Loc) {
1476    this->getLocalData()->LParenLoc = Loc;
1477  }
1478
1479  SourceLocation getRParenLoc() const {
1480    return this->getLocalData()->RParenLoc;
1481  }
1482  void setRParenLoc(SourceLocation Loc) {
1483    this->getLocalData()->RParenLoc = Loc;
1484  }
1485
1486  SourceRange getParensRange() const {
1487    return SourceRange(getLParenLoc(), getRParenLoc());
1488  }
1489  void setParensRange(SourceRange range) {
1490      setLParenLoc(range.getBegin());
1491      setRParenLoc(range.getEnd());
1492  }
1493
1494  SourceRange getLocalSourceRange() const {
1495    return SourceRange(getTypeofLoc(), getRParenLoc());
1496  }
1497
1498  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1499    setTypeofLoc(Loc);
1500    setLParenLoc(Loc);
1501    setRParenLoc(Loc);
1502  }
1503};
1504
1505class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
1506                                                   TypeOfExprType,
1507                                                   TypeOfExprTypeLocInfo> {
1508public:
1509  Expr* getUnderlyingExpr() const {
1510    return getTypePtr()->getUnderlyingExpr();
1511  }
1512  // Reimplemented to account for GNU/C++ extension
1513  //     typeof unary-expression
1514  // where there are no parentheses.
1515  SourceRange getLocalSourceRange() const;
1516};
1517
1518class TypeOfTypeLoc
1519  : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
1520public:
1521  QualType getUnderlyingType() const {
1522    return this->getTypePtr()->getUnderlyingType();
1523  }
1524  TypeSourceInfo* getUnderlyingTInfo() const {
1525    return this->getLocalData()->UnderlyingTInfo;
1526  }
1527  void setUnderlyingTInfo(TypeSourceInfo* TI) const {
1528    this->getLocalData()->UnderlyingTInfo = TI;
1529  }
1530};
1531
1532// FIXME: location of the 'decltype' and parens.
1533class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1534                                                         DecltypeTypeLoc,
1535                                                         DecltypeType> {
1536public:
1537  Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
1538};
1539
1540struct UnaryTransformTypeLocInfo {
1541  // FIXME: While there's only one unary transform right now, future ones may
1542  // need different representations
1543  SourceLocation KWLoc, LParenLoc, RParenLoc;
1544  TypeSourceInfo *UnderlyingTInfo;
1545};
1546
1547class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1548                                                    UnaryTransformTypeLoc,
1549                                                    UnaryTransformType,
1550                                                    UnaryTransformTypeLocInfo> {
1551public:
1552  SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
1553  void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
1554
1555  SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
1556  void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
1557
1558  SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
1559  void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
1560
1561  TypeSourceInfo* getUnderlyingTInfo() const {
1562    return getLocalData()->UnderlyingTInfo;
1563  }
1564  void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
1565    getLocalData()->UnderlyingTInfo = TInfo;
1566  }
1567
1568  SourceRange getLocalSourceRange() const {
1569    return SourceRange(getKWLoc(), getRParenLoc());
1570  }
1571
1572  SourceRange getParensRange() const {
1573    return SourceRange(getLParenLoc(), getRParenLoc());
1574  }
1575  void setParensRange(SourceRange Range) {
1576    setLParenLoc(Range.getBegin());
1577    setRParenLoc(Range.getEnd());
1578  }
1579
1580  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1581    setKWLoc(Loc);
1582    setRParenLoc(Loc);
1583    setLParenLoc(Loc);
1584  }
1585};
1586
1587class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1588                                                        AutoTypeLoc,
1589                                                        AutoType> {
1590};
1591
1592struct ElaboratedLocInfo {
1593  SourceLocation ElaboratedKWLoc;
1594  /// \brief Data associated with the nested-name-specifier location.
1595  void *QualifierData;
1596};
1597
1598class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1599                                                 ElaboratedTypeLoc,
1600                                                 ElaboratedType,
1601                                                 ElaboratedLocInfo> {
1602public:
1603  SourceLocation getElaboratedKeywordLoc() const {
1604    return this->getLocalData()->ElaboratedKWLoc;
1605  }
1606  void setElaboratedKeywordLoc(SourceLocation Loc) {
1607    this->getLocalData()->ElaboratedKWLoc = Loc;
1608  }
1609
1610  NestedNameSpecifierLoc getQualifierLoc() const {
1611    return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1612                                  getLocalData()->QualifierData);
1613  }
1614
1615  void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1616    assert(QualifierLoc.getNestedNameSpecifier()
1617                                            == getTypePtr()->getQualifier() &&
1618           "Inconsistent nested-name-specifier pointer");
1619    getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1620  }
1621
1622  SourceRange getLocalSourceRange() const {
1623    if (getElaboratedKeywordLoc().isValid())
1624      if (getQualifierLoc())
1625        return SourceRange(getElaboratedKeywordLoc(),
1626                           getQualifierLoc().getEndLoc());
1627      else
1628        return SourceRange(getElaboratedKeywordLoc());
1629    else
1630      return getQualifierLoc().getSourceRange();
1631  }
1632
1633  void initializeLocal(ASTContext &Context, SourceLocation Loc);
1634
1635  TypeLoc getNamedTypeLoc() const {
1636    return getInnerTypeLoc();
1637  }
1638
1639  QualType getInnerType() const {
1640    return getTypePtr()->getNamedType();
1641  }
1642
1643  void copy(ElaboratedTypeLoc Loc) {
1644    unsigned size = getFullDataSize();
1645    assert(size == Loc.getFullDataSize());
1646    memcpy(Data, Loc.Data, size);
1647  }
1648};
1649
1650// This is exactly the structure of an ElaboratedTypeLoc whose inner
1651// type is some sort of TypeDeclTypeLoc.
1652struct DependentNameLocInfo : ElaboratedLocInfo {
1653  SourceLocation NameLoc;
1654};
1655
1656class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1657                                                    DependentNameTypeLoc,
1658                                                    DependentNameType,
1659                                                    DependentNameLocInfo> {
1660public:
1661  SourceLocation getElaboratedKeywordLoc() const {
1662    return this->getLocalData()->ElaboratedKWLoc;
1663  }
1664  void setElaboratedKeywordLoc(SourceLocation Loc) {
1665    this->getLocalData()->ElaboratedKWLoc = Loc;
1666  }
1667
1668  NestedNameSpecifierLoc getQualifierLoc() const {
1669    return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1670                                  getLocalData()->QualifierData);
1671  }
1672
1673  void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1674    assert(QualifierLoc.getNestedNameSpecifier()
1675                                            == getTypePtr()->getQualifier() &&
1676           "Inconsistent nested-name-specifier pointer");
1677    getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1678  }
1679
1680  SourceLocation getNameLoc() const {
1681    return this->getLocalData()->NameLoc;
1682  }
1683  void setNameLoc(SourceLocation Loc) {
1684    this->getLocalData()->NameLoc = Loc;
1685  }
1686
1687  SourceRange getLocalSourceRange() const {
1688    if (getElaboratedKeywordLoc().isValid())
1689      return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
1690    else
1691      return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
1692  }
1693
1694  void copy(DependentNameTypeLoc Loc) {
1695    unsigned size = getFullDataSize();
1696    assert(size == Loc.getFullDataSize());
1697    memcpy(Data, Loc.Data, size);
1698  }
1699
1700  void initializeLocal(ASTContext &Context, SourceLocation Loc);
1701};
1702
1703struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
1704  SourceLocation TemplateKWLoc;
1705  SourceLocation LAngleLoc;
1706  SourceLocation RAngleLoc;
1707  // followed by a TemplateArgumentLocInfo[]
1708};
1709
1710class DependentTemplateSpecializationTypeLoc :
1711    public ConcreteTypeLoc<UnqualTypeLoc,
1712                           DependentTemplateSpecializationTypeLoc,
1713                           DependentTemplateSpecializationType,
1714                           DependentTemplateSpecializationLocInfo> {
1715public:
1716  SourceLocation getElaboratedKeywordLoc() const {
1717    return this->getLocalData()->ElaboratedKWLoc;
1718  }
1719  void setElaboratedKeywordLoc(SourceLocation Loc) {
1720    this->getLocalData()->ElaboratedKWLoc = Loc;
1721  }
1722
1723  NestedNameSpecifierLoc getQualifierLoc() const {
1724    if (!getLocalData()->QualifierData)
1725      return NestedNameSpecifierLoc();
1726
1727    return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1728                                  getLocalData()->QualifierData);
1729  }
1730
1731  void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1732    if (!QualifierLoc) {
1733      // Even if we have a nested-name-specifier in the dependent
1734      // template specialization type, we won't record the nested-name-specifier
1735      // location information when this type-source location information is
1736      // part of a nested-name-specifier.
1737      getLocalData()->QualifierData = 0;
1738      return;
1739    }
1740
1741    assert(QualifierLoc.getNestedNameSpecifier()
1742                                        == getTypePtr()->getQualifier() &&
1743           "Inconsistent nested-name-specifier pointer");
1744    getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1745  }
1746
1747  SourceLocation getTemplateKeywordLoc() const {
1748    return getLocalData()->TemplateKWLoc;
1749  }
1750  void setTemplateKeywordLoc(SourceLocation Loc) {
1751    getLocalData()->TemplateKWLoc = Loc;
1752  }
1753
1754  SourceLocation getTemplateNameLoc() const {
1755    return this->getLocalData()->NameLoc;
1756  }
1757  void setTemplateNameLoc(SourceLocation Loc) {
1758    this->getLocalData()->NameLoc = Loc;
1759  }
1760
1761  SourceLocation getLAngleLoc() const {
1762    return this->getLocalData()->LAngleLoc;
1763  }
1764  void setLAngleLoc(SourceLocation Loc) {
1765    this->getLocalData()->LAngleLoc = Loc;
1766  }
1767
1768  SourceLocation getRAngleLoc() const {
1769    return this->getLocalData()->RAngleLoc;
1770  }
1771  void setRAngleLoc(SourceLocation Loc) {
1772    this->getLocalData()->RAngleLoc = Loc;
1773  }
1774
1775  unsigned getNumArgs() const {
1776    return getTypePtr()->getNumArgs();
1777  }
1778
1779  void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1780    getArgInfos()[i] = AI;
1781  }
1782  TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1783    return getArgInfos()[i];
1784  }
1785
1786  TemplateArgumentLoc getArgLoc(unsigned i) const {
1787    return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1788  }
1789
1790  SourceRange getLocalSourceRange() const {
1791    if (getElaboratedKeywordLoc().isValid())
1792      return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
1793    else if (getQualifierLoc())
1794      return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
1795    else if (getTemplateKeywordLoc().isValid())
1796      return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1797    else
1798      return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1799  }
1800
1801  void copy(DependentTemplateSpecializationTypeLoc Loc) {
1802    unsigned size = getFullDataSize();
1803    assert(size == Loc.getFullDataSize());
1804    memcpy(Data, Loc.Data, size);
1805  }
1806
1807  void initializeLocal(ASTContext &Context, SourceLocation Loc);
1808
1809  unsigned getExtraLocalDataSize() const {
1810    return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1811  }
1812
1813  unsigned getExtraLocalDataAlignment() const {
1814    return llvm::alignOf<TemplateArgumentLocInfo>();
1815  }
1816
1817private:
1818  TemplateArgumentLocInfo *getArgInfos() const {
1819    return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1820  }
1821};
1822
1823
1824struct PackExpansionTypeLocInfo {
1825  SourceLocation EllipsisLoc;
1826};
1827
1828class PackExpansionTypeLoc
1829  : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
1830                           PackExpansionType, PackExpansionTypeLocInfo> {
1831public:
1832  SourceLocation getEllipsisLoc() const {
1833    return this->getLocalData()->EllipsisLoc;
1834  }
1835
1836  void setEllipsisLoc(SourceLocation Loc) {
1837    this->getLocalData()->EllipsisLoc = Loc;
1838  }
1839
1840  SourceRange getLocalSourceRange() const {
1841    return SourceRange(getEllipsisLoc(), getEllipsisLoc());
1842  }
1843
1844  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1845    setEllipsisLoc(Loc);
1846  }
1847
1848  TypeLoc getPatternLoc() const {
1849    return getInnerTypeLoc();
1850  }
1851
1852  QualType getInnerType() const {
1853    return this->getTypePtr()->getPattern();
1854  }
1855};
1856
1857struct AtomicTypeLocInfo {
1858  SourceLocation KWLoc, LParenLoc, RParenLoc;
1859};
1860
1861class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
1862                                             AtomicType, AtomicTypeLocInfo> {
1863public:
1864  TypeLoc getValueLoc() const {
1865    return this->getInnerTypeLoc();
1866  }
1867
1868  SourceRange getLocalSourceRange() const {
1869    return SourceRange(getKWLoc(), getRParenLoc());
1870  }
1871
1872  SourceLocation getKWLoc() const {
1873    return this->getLocalData()->KWLoc;
1874  }
1875  void setKWLoc(SourceLocation Loc) {
1876    this->getLocalData()->KWLoc = Loc;
1877  }
1878
1879  SourceLocation getLParenLoc() const {
1880    return this->getLocalData()->LParenLoc;
1881  }
1882  void setLParenLoc(SourceLocation Loc) {
1883    this->getLocalData()->LParenLoc = Loc;
1884  }
1885
1886  SourceLocation getRParenLoc() const {
1887    return this->getLocalData()->RParenLoc;
1888  }
1889  void setRParenLoc(SourceLocation Loc) {
1890    this->getLocalData()->RParenLoc = Loc;
1891  }
1892
1893  SourceRange getParensRange() const {
1894    return SourceRange(getLParenLoc(), getRParenLoc());
1895  }
1896  void setParensRange(SourceRange Range) {
1897    setLParenLoc(Range.getBegin());
1898    setRParenLoc(Range.getEnd());
1899  }
1900
1901  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1902    setKWLoc(Loc);
1903    setLParenLoc(Loc);
1904    setRParenLoc(Loc);
1905  }
1906
1907  QualType getInnerType() const {
1908    return this->getTypePtr()->getValueType();
1909  }
1910};
1911
1912
1913}
1914
1915#endif
1916