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