1//===- TypeLoc.h - Type Source Info Wrapper ---------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10/// Defines the clang::TypeLoc interface and its subclasses.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_TYPELOC_H
15#define LLVM_CLANG_AST_TYPELOC_H
16
17#include "clang/AST/DeclarationName.h"
18#include "clang/AST/NestedNameSpecifier.h"
19#include "clang/AST/TemplateBase.h"
20#include "clang/AST/Type.h"
21#include "clang/Basic/LLVM.h"
22#include "clang/Basic/SourceLocation.h"
23#include "clang/Basic/Specifiers.h"
24#include "llvm/ADT/ArrayRef.h"
25#include "llvm/Support/Casting.h"
26#include "llvm/Support/Compiler.h"
27#include "llvm/Support/MathExtras.h"
28#include <algorithm>
29#include <cassert>
30#include <cstdint>
31#include <cstring>
32
33namespace clang {
34
35class Attr;
36class ASTContext;
37class CXXRecordDecl;
38class ConceptDecl;
39class Expr;
40class ObjCInterfaceDecl;
41class ObjCProtocolDecl;
42class ObjCTypeParamDecl;
43class ParmVarDecl;
44class TemplateTypeParmDecl;
45class UnqualTypeLoc;
46class UnresolvedUsingTypenameDecl;
47
48// Predeclare all the type nodes.
49#define ABSTRACT_TYPELOC(Class, Base)
50#define TYPELOC(Class, Base) \
51  class Class##TypeLoc;
52#include "clang/AST/TypeLocNodes.def"
53
54/// Base wrapper for a particular "section" of type source info.
55///
56/// A client should use the TypeLoc subclasses through castAs()/getAs()
57/// in order to get at the actual information.
58class TypeLoc {
59protected:
60  // The correctness of this relies on the property that, for Type *Ty,
61  //   QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
62  const void *Ty = nullptr;
63  void *Data = nullptr;
64
65public:
66  TypeLoc() = default;
67  TypeLoc(QualType ty, void *opaqueData)
68      : Ty(ty.getAsOpaquePtr()), Data(opaqueData) {}
69  TypeLoc(const Type *ty, void *opaqueData)
70      : Ty(ty), Data(opaqueData) {}
71
72  /// Convert to the specified TypeLoc type, asserting that this TypeLoc
73  /// is of the desired type.
74  ///
75  /// \pre T::isKind(*this)
76  template<typename T>
77  T castAs() const {
78    assert(T::isKind(*this));
79    T t;
80    TypeLoc& tl = t;
81    tl = *this;
82    return t;
83  }
84
85  /// Convert to the specified TypeLoc type, returning a null TypeLoc if
86  /// this TypeLoc is not of the desired type.
87  template<typename T>
88  T getAs() const {
89    if (!T::isKind(*this))
90      return {};
91    T t;
92    TypeLoc& tl = t;
93    tl = *this;
94    return t;
95  }
96
97  /// Convert to the specified TypeLoc type, returning a null TypeLoc if
98  /// this TypeLoc is not of the desired type. It will consider type
99  /// adjustments from a type that was written as a T to another type that is
100  /// still canonically a T (ignores parens, attributes, elaborated types, etc).
101  template <typename T>
102  T getAsAdjusted() const;
103
104  /// The kinds of TypeLocs.  Equivalent to the Type::TypeClass enum,
105  /// except it also defines a Qualified enum that corresponds to the
106  /// QualifiedLoc class.
107  enum TypeLocClass {
108#define ABSTRACT_TYPE(Class, Base)
109#define TYPE(Class, Base) \
110    Class = Type::Class,
111#include "clang/AST/TypeNodes.inc"
112    Qualified
113  };
114
115  TypeLocClass getTypeLocClass() const {
116    if (getType().hasLocalQualifiers()) return Qualified;
117    return (TypeLocClass) getType()->getTypeClass();
118  }
119
120  bool isNull() const { return !Ty; }
121  explicit operator bool() const { return Ty; }
122
123  /// Returns the size of type source info data block for the given type.
124  static unsigned getFullDataSizeForType(QualType Ty);
125
126  /// Returns the alignment of type source info data block for
127  /// the given type.
128  static unsigned getLocalAlignmentForType(QualType Ty);
129
130  /// Get the type for which this source info wrapper provides
131  /// information.
132  QualType getType() const {
133    return QualType::getFromOpaquePtr(Ty);
134  }
135
136  const Type *getTypePtr() const {
137    return QualType::getFromOpaquePtr(Ty).getTypePtr();
138  }
139
140  /// Get the pointer where source information is stored.
141  void *getOpaqueData() const {
142    return Data;
143  }
144
145  /// Get the begin source location.
146  SourceLocation getBeginLoc() const;
147
148  /// Get the end source location.
149  SourceLocation getEndLoc() const;
150
151  /// Get the full source range.
152  SourceRange getSourceRange() const LLVM_READONLY {
153    return SourceRange(getBeginLoc(), getEndLoc());
154  }
155
156
157  /// Get the local source range.
158  SourceRange getLocalSourceRange() const {
159    return getLocalSourceRangeImpl(*this);
160  }
161
162  /// Returns the size of the type source info data block.
163  unsigned getFullDataSize() const {
164    return getFullDataSizeForType(getType());
165  }
166
167  /// Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
168  /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
169  TypeLoc getNextTypeLoc() const {
170    return getNextTypeLocImpl(*this);
171  }
172
173  /// Skips past any qualifiers, if this is qualified.
174  UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
175
176  TypeLoc IgnoreParens() const;
177
178  /// Find a type with the location of an explicit type qualifier.
179  ///
180  /// The result, if non-null, will be one of:
181  ///   QualifiedTypeLoc
182  ///   AtomicTypeLoc
183  ///   AttributedTypeLoc, for those type attributes that behave as qualifiers
184  TypeLoc findExplicitQualifierLoc() const;
185
186  /// Get the typeloc of an AutoType whose type will be deduced for a variable
187  /// with an initializer of this type. This looks through declarators like
188  /// pointer types, but not through decltype or typedefs.
189  AutoTypeLoc getContainedAutoTypeLoc() const;
190
191  /// Initializes this to state that every location in this
192  /// type is the given location.
193  ///
194  /// This method exists to provide a simple transition for code that
195  /// relies on location-less types.
196  void initialize(ASTContext &Context, SourceLocation Loc) const {
197    initializeImpl(Context, *this, Loc);
198  }
199
200  /// Initializes this by copying its information from another
201  /// TypeLoc of the same type.
202  void initializeFullCopy(TypeLoc Other) {
203    assert(getType() == Other.getType());
204    copy(Other);
205  }
206
207  /// Initializes this by copying its information from another
208  /// TypeLoc of the same type.  The given size must be the full data
209  /// size.
210  void initializeFullCopy(TypeLoc Other, unsigned Size) {
211    assert(getType() == Other.getType());
212    assert(getFullDataSize() == Size);
213    copy(Other);
214  }
215
216  /// Copies the other type loc into this one.
217  void copy(TypeLoc other);
218
219  friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
220    return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
221  }
222
223  friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) {
224    return !(LHS == RHS);
225  }
226
227  /// Find the location of the nullability specifier (__nonnull,
228  /// __nullable, or __null_unspecifier), if there is one.
229  SourceLocation findNullabilityLoc() const;
230
231private:
232  static bool isKind(const TypeLoc&) {
233    return true;
234  }
235
236  static void initializeImpl(ASTContext &Context, TypeLoc TL,
237                             SourceLocation Loc);
238  static TypeLoc getNextTypeLocImpl(TypeLoc TL);
239  static TypeLoc IgnoreParensImpl(TypeLoc TL);
240  static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
241};
242
243/// Return the TypeLoc for a type source info.
244inline TypeLoc TypeSourceInfo::getTypeLoc() const {
245  // TODO: is this alignment already sufficient?
246  return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1)));
247}
248
249/// Wrapper of type source information for a type with
250/// no direct qualifiers.
251class UnqualTypeLoc : public TypeLoc {
252public:
253  UnqualTypeLoc() = default;
254  UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
255
256  const Type *getTypePtr() const {
257    return reinterpret_cast<const Type*>(Ty);
258  }
259
260  TypeLocClass getTypeLocClass() const {
261    return (TypeLocClass) getTypePtr()->getTypeClass();
262  }
263
264private:
265  friend class TypeLoc;
266
267  static bool isKind(const TypeLoc &TL) {
268    return !TL.getType().hasLocalQualifiers();
269  }
270};
271
272/// Wrapper of type source information for a type with
273/// non-trivial direct qualifiers.
274///
275/// Currently, we intentionally do not provide source location for
276/// type qualifiers.
277class QualifiedTypeLoc : public TypeLoc {
278public:
279  SourceRange getLocalSourceRange() const { return {}; }
280
281  UnqualTypeLoc getUnqualifiedLoc() const {
282    unsigned align =
283        TypeLoc::getLocalAlignmentForType(QualType(getTypePtr(), 0));
284    auto dataInt = reinterpret_cast<uintptr_t>(Data);
285    dataInt = llvm::alignTo(dataInt, align);
286    return UnqualTypeLoc(getTypePtr(), reinterpret_cast<void*>(dataInt));
287  }
288
289  /// Initializes the local data of this type source info block to
290  /// provide no information.
291  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
292    // do nothing
293  }
294
295  void copyLocal(TypeLoc other) {
296    // do nothing
297  }
298
299  TypeLoc getNextTypeLoc() const {
300    return getUnqualifiedLoc();
301  }
302
303  /// Returns the size of the type source info data block that is
304  /// specific to this type.
305  unsigned getLocalDataSize() const {
306    // In fact, we don't currently preserve any location information
307    // for qualifiers.
308    return 0;
309  }
310
311  /// Returns the alignment of the type source info data block that is
312  /// specific to this type.
313  unsigned getLocalDataAlignment() const {
314    // We don't preserve any location information.
315    return 1;
316  }
317
318private:
319  friend class TypeLoc;
320
321  static bool isKind(const TypeLoc &TL) {
322    return TL.getType().hasLocalQualifiers();
323  }
324};
325
326inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
327  if (QualifiedTypeLoc Loc = getAs<QualifiedTypeLoc>())
328    return Loc.getUnqualifiedLoc();
329  return castAs<UnqualTypeLoc>();
330}
331
332/// A metaprogramming base class for TypeLoc classes which correspond
333/// to a particular Type subclass.  It is accepted for a single
334/// TypeLoc class to correspond to multiple Type classes.
335///
336/// \tparam Base a class from which to derive
337/// \tparam Derived the class deriving from this one
338/// \tparam TypeClass the concrete Type subclass associated with this
339///   location type
340/// \tparam LocalData the structure type of local location data for
341///   this type
342///
343/// TypeLocs with non-constant amounts of local data should override
344/// getExtraLocalDataSize(); getExtraLocalData() will then point to
345/// this extra memory.
346///
347/// TypeLocs with an inner type should define
348///   QualType getInnerType() const
349/// and getInnerTypeLoc() will then point to this inner type's
350/// location data.
351///
352/// A word about hierarchies: this template is not designed to be
353/// derived from multiple times in a hierarchy.  It is also not
354/// designed to be used for classes where subtypes might provide
355/// different amounts of source information.  It should be subclassed
356/// only at the deepest portion of the hierarchy where all children
357/// have identical source information; if that's an abstract type,
358/// then further descendents should inherit from
359/// InheritingConcreteTypeLoc instead.
360template <class Base, class Derived, class TypeClass, class LocalData>
361class ConcreteTypeLoc : public Base {
362  friend class TypeLoc;
363
364  const Derived *asDerived() const {
365    return static_cast<const Derived*>(this);
366  }
367
368  static bool isKind(const TypeLoc &TL) {
369    return !TL.getType().hasLocalQualifiers() &&
370           Derived::classofType(TL.getTypePtr());
371  }
372
373  static bool classofType(const Type *Ty) {
374    return TypeClass::classof(Ty);
375  }
376
377public:
378  unsigned getLocalDataAlignment() const {
379    return std::max(unsigned(alignof(LocalData)),
380                    asDerived()->getExtraLocalDataAlignment());
381  }
382
383  unsigned getLocalDataSize() const {
384    unsigned size = sizeof(LocalData);
385    unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
386    size = llvm::alignTo(size, extraAlign);
387    size += asDerived()->getExtraLocalDataSize();
388    return size;
389  }
390
391  void copyLocal(Derived other) {
392    // Some subclasses have no data to copy.
393    if (asDerived()->getLocalDataSize() == 0) return;
394
395    // Copy the fixed-sized local data.
396    memcpy(getLocalData(), other.getLocalData(), sizeof(LocalData));
397
398    // Copy the variable-sized local data. We need to do this
399    // separately because the padding in the source and the padding in
400    // the destination might be different.
401    memcpy(getExtraLocalData(), other.getExtraLocalData(),
402           asDerived()->getExtraLocalDataSize());
403  }
404
405  TypeLoc getNextTypeLoc() const {
406    return getNextTypeLoc(asDerived()->getInnerType());
407  }
408
409  const TypeClass *getTypePtr() const {
410    return cast<TypeClass>(Base::getTypePtr());
411  }
412
413protected:
414  unsigned getExtraLocalDataSize() const {
415    return 0;
416  }
417
418  unsigned getExtraLocalDataAlignment() const {
419    return 1;
420  }
421
422  LocalData *getLocalData() const {
423    return static_cast<LocalData*>(Base::Data);
424  }
425
426  /// Gets a pointer past the Info structure; useful for classes with
427  /// local data that can't be captured in the Info (e.g. because it's
428  /// of variable size).
429  void *getExtraLocalData() const {
430    unsigned size = sizeof(LocalData);
431    unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
432    size = llvm::alignTo(size, extraAlign);
433    return reinterpret_cast<char*>(Base::Data) + size;
434  }
435
436  void *getNonLocalData() const {
437    auto data = reinterpret_cast<uintptr_t>(Base::Data);
438    data += asDerived()->getLocalDataSize();
439    data = llvm::alignTo(data, getNextTypeAlign());
440    return reinterpret_cast<void*>(data);
441  }
442
443  struct HasNoInnerType {};
444  HasNoInnerType getInnerType() const { return HasNoInnerType(); }
445
446  TypeLoc getInnerTypeLoc() const {
447    return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
448  }
449
450private:
451  unsigned getInnerTypeSize() const {
452    return getInnerTypeSize(asDerived()->getInnerType());
453  }
454
455  unsigned getInnerTypeSize(HasNoInnerType _) const {
456    return 0;
457  }
458
459  unsigned getInnerTypeSize(QualType _) const {
460    return getInnerTypeLoc().getFullDataSize();
461  }
462
463  unsigned getNextTypeAlign() const {
464    return getNextTypeAlign(asDerived()->getInnerType());
465  }
466
467  unsigned getNextTypeAlign(HasNoInnerType _) const {
468    return 1;
469  }
470
471  unsigned getNextTypeAlign(QualType T) const {
472    return TypeLoc::getLocalAlignmentForType(T);
473  }
474
475  TypeLoc getNextTypeLoc(HasNoInnerType _) const { return {}; }
476
477  TypeLoc getNextTypeLoc(QualType T) const {
478    return TypeLoc(T, getNonLocalData());
479  }
480};
481
482/// A metaprogramming class designed for concrete subtypes of abstract
483/// types where all subtypes share equivalently-structured source
484/// information.  See the note on ConcreteTypeLoc.
485template <class Base, class Derived, class TypeClass>
486class InheritingConcreteTypeLoc : public Base {
487  friend class TypeLoc;
488
489  static bool classofType(const Type *Ty) {
490    return TypeClass::classof(Ty);
491  }
492
493  static bool isKind(const TypeLoc &TL) {
494    return !TL.getType().hasLocalQualifiers() &&
495           Derived::classofType(TL.getTypePtr());
496  }
497  static bool isKind(const UnqualTypeLoc &TL) {
498    return Derived::classofType(TL.getTypePtr());
499  }
500
501public:
502  const TypeClass *getTypePtr() const {
503    return cast<TypeClass>(Base::getTypePtr());
504  }
505};
506
507struct TypeSpecLocInfo {
508  SourceLocation NameLoc;
509};
510
511/// A reasonable base class for TypeLocs that correspond to
512/// types that are written as a type-specifier.
513class TypeSpecTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
514                                               TypeSpecTypeLoc,
515                                               Type,
516                                               TypeSpecLocInfo> {
517public:
518  enum {
519    LocalDataSize = sizeof(TypeSpecLocInfo),
520    LocalDataAlignment = alignof(TypeSpecLocInfo)
521  };
522
523  SourceLocation getNameLoc() const {
524    return this->getLocalData()->NameLoc;
525  }
526
527  void setNameLoc(SourceLocation Loc) {
528    this->getLocalData()->NameLoc = Loc;
529  }
530
531  SourceRange getLocalSourceRange() const {
532    return SourceRange(getNameLoc(), getNameLoc());
533  }
534
535  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
536    setNameLoc(Loc);
537  }
538
539private:
540  friend class TypeLoc;
541
542  static bool isKind(const TypeLoc &TL);
543};
544
545struct BuiltinLocInfo {
546  SourceRange BuiltinRange;
547};
548
549/// Wrapper for source info for builtin types.
550class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
551                                              BuiltinTypeLoc,
552                                              BuiltinType,
553                                              BuiltinLocInfo> {
554public:
555  SourceLocation getBuiltinLoc() const {
556    return getLocalData()->BuiltinRange.getBegin();
557  }
558
559  void setBuiltinLoc(SourceLocation Loc) {
560    getLocalData()->BuiltinRange = Loc;
561  }
562
563  void expandBuiltinRange(SourceRange Range) {
564    SourceRange &BuiltinRange = getLocalData()->BuiltinRange;
565    if (!BuiltinRange.getBegin().isValid()) {
566      BuiltinRange = Range;
567    } else {
568      BuiltinRange.setBegin(std::min(Range.getBegin(), BuiltinRange.getBegin()));
569      BuiltinRange.setEnd(std::max(Range.getEnd(), BuiltinRange.getEnd()));
570    }
571  }
572
573  SourceLocation getNameLoc() const { return getBuiltinLoc(); }
574
575  WrittenBuiltinSpecs& getWrittenBuiltinSpecs() {
576    return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
577  }
578  const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
579    return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
580  }
581
582  bool needsExtraLocalData() const {
583    BuiltinType::Kind bk = getTypePtr()->getKind();
584    return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
585      || (bk >= BuiltinType::Short && bk <= BuiltinType::Float128)
586      || bk == BuiltinType::UChar
587      || bk == BuiltinType::SChar;
588  }
589
590  unsigned getExtraLocalDataSize() const {
591    return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
592  }
593
594  unsigned getExtraLocalDataAlignment() const {
595    return needsExtraLocalData() ? alignof(WrittenBuiltinSpecs) : 1;
596  }
597
598  SourceRange getLocalSourceRange() const {
599    return getLocalData()->BuiltinRange;
600  }
601
602  TypeSpecifierSign getWrittenSignSpec() const {
603    if (needsExtraLocalData())
604      return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign);
605    else
606      return TSS_unspecified;
607  }
608
609  bool hasWrittenSignSpec() const {
610    return getWrittenSignSpec() != TSS_unspecified;
611  }
612
613  void setWrittenSignSpec(TypeSpecifierSign written) {
614    if (needsExtraLocalData())
615      getWrittenBuiltinSpecs().Sign = written;
616  }
617
618  TypeSpecifierWidth getWrittenWidthSpec() const {
619    if (needsExtraLocalData())
620      return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width);
621    else
622      return TSW_unspecified;
623  }
624
625  bool hasWrittenWidthSpec() const {
626    return getWrittenWidthSpec() != TSW_unspecified;
627  }
628
629  void setWrittenWidthSpec(TypeSpecifierWidth written) {
630    if (needsExtraLocalData())
631      getWrittenBuiltinSpecs().Width = written;
632  }
633
634  TypeSpecifierType getWrittenTypeSpec() const;
635
636  bool hasWrittenTypeSpec() const {
637    return getWrittenTypeSpec() != TST_unspecified;
638  }
639
640  void setWrittenTypeSpec(TypeSpecifierType written) {
641    if (needsExtraLocalData())
642      getWrittenBuiltinSpecs().Type = written;
643  }
644
645  bool hasModeAttr() const {
646    if (needsExtraLocalData())
647      return getWrittenBuiltinSpecs().ModeAttr;
648    else
649      return false;
650  }
651
652  void setModeAttr(bool written) {
653    if (needsExtraLocalData())
654      getWrittenBuiltinSpecs().ModeAttr = written;
655  }
656
657  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
658    setBuiltinLoc(Loc);
659    if (needsExtraLocalData()) {
660      WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs();
661      wbs.Sign = TSS_unspecified;
662      wbs.Width = TSW_unspecified;
663      wbs.Type = TST_unspecified;
664      wbs.ModeAttr = false;
665    }
666  }
667};
668
669/// Wrapper for source info for typedefs.
670class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
671                                                        TypedefTypeLoc,
672                                                        TypedefType> {
673public:
674  TypedefNameDecl *getTypedefNameDecl() const {
675    return getTypePtr()->getDecl();
676  }
677};
678
679/// Wrapper for source info for injected class names of class
680/// templates.
681class InjectedClassNameTypeLoc :
682    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
683                                     InjectedClassNameTypeLoc,
684                                     InjectedClassNameType> {
685public:
686  CXXRecordDecl *getDecl() const {
687    return getTypePtr()->getDecl();
688  }
689};
690
691/// Wrapper for source info for unresolved typename using decls.
692class UnresolvedUsingTypeLoc :
693    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
694                                     UnresolvedUsingTypeLoc,
695                                     UnresolvedUsingType> {
696public:
697  UnresolvedUsingTypenameDecl *getDecl() const {
698    return getTypePtr()->getDecl();
699  }
700};
701
702/// Wrapper for source info for tag types.  Note that this only
703/// records source info for the name itself; a type written 'struct foo'
704/// should be represented as an ElaboratedTypeLoc.  We currently
705/// only do that when C++ is enabled because of the expense of
706/// creating an ElaboratedType node for so many type references in C.
707class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
708                                                    TagTypeLoc,
709                                                    TagType> {
710public:
711  TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
712
713  /// True if the tag was defined in this type specifier.
714  bool isDefinition() const;
715};
716
717/// Wrapper for source info for record types.
718class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
719                                                       RecordTypeLoc,
720                                                       RecordType> {
721public:
722  RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
723};
724
725/// Wrapper for source info for enum types.
726class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
727                                                     EnumTypeLoc,
728                                                     EnumType> {
729public:
730  EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
731};
732
733/// Wrapper for template type parameters.
734class TemplateTypeParmTypeLoc :
735    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
736                                     TemplateTypeParmTypeLoc,
737                                     TemplateTypeParmType> {
738public:
739  TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
740};
741
742struct ObjCTypeParamTypeLocInfo {
743  SourceLocation NameLoc;
744};
745
746/// ProtocolLAngleLoc, ProtocolRAngleLoc, and the source locations for
747/// protocol qualifiers are stored after Info.
748class ObjCTypeParamTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
749                                     ObjCTypeParamTypeLoc,
750                                     ObjCTypeParamType,
751                                     ObjCTypeParamTypeLocInfo> {
752  // SourceLocations are stored after Info, one for each protocol qualifier.
753  SourceLocation *getProtocolLocArray() const {
754    return (SourceLocation*)this->getExtraLocalData() + 2;
755  }
756
757public:
758  ObjCTypeParamDecl *getDecl() const { return getTypePtr()->getDecl(); }
759
760  SourceLocation getNameLoc() const {
761    return this->getLocalData()->NameLoc;
762  }
763
764  void setNameLoc(SourceLocation Loc) {
765    this->getLocalData()->NameLoc = Loc;
766  }
767
768  SourceLocation getProtocolLAngleLoc() const {
769    return getNumProtocols()  ?
770      *((SourceLocation*)this->getExtraLocalData()) :
771      SourceLocation();
772  }
773
774  void setProtocolLAngleLoc(SourceLocation Loc) {
775    *((SourceLocation*)this->getExtraLocalData()) = Loc;
776  }
777
778  SourceLocation getProtocolRAngleLoc() const {
779    return getNumProtocols()  ?
780      *((SourceLocation*)this->getExtraLocalData() + 1) :
781      SourceLocation();
782  }
783
784  void setProtocolRAngleLoc(SourceLocation Loc) {
785    *((SourceLocation*)this->getExtraLocalData() + 1) = Loc;
786  }
787
788  unsigned getNumProtocols() const {
789    return this->getTypePtr()->getNumProtocols();
790  }
791
792  SourceLocation getProtocolLoc(unsigned i) const {
793    assert(i < getNumProtocols() && "Index is out of bounds!");
794    return getProtocolLocArray()[i];
795  }
796
797  void setProtocolLoc(unsigned i, SourceLocation Loc) {
798    assert(i < getNumProtocols() && "Index is out of bounds!");
799    getProtocolLocArray()[i] = Loc;
800  }
801
802  ObjCProtocolDecl *getProtocol(unsigned i) const {
803    assert(i < getNumProtocols() && "Index is out of bounds!");
804    return *(this->getTypePtr()->qual_begin() + i);
805  }
806
807  ArrayRef<SourceLocation> getProtocolLocs() const {
808    return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols());
809  }
810
811  void initializeLocal(ASTContext &Context, SourceLocation Loc);
812
813  unsigned getExtraLocalDataSize() const {
814    if (!this->getNumProtocols()) return 0;
815    // When there are protocol qualifers, we have LAngleLoc and RAngleLoc
816    // as well.
817    return (this->getNumProtocols() + 2) * sizeof(SourceLocation) ;
818  }
819
820  unsigned getExtraLocalDataAlignment() const {
821    return alignof(SourceLocation);
822  }
823
824  SourceRange getLocalSourceRange() const {
825    SourceLocation start = getNameLoc();
826    SourceLocation end = getProtocolRAngleLoc();
827    if (end.isInvalid()) return SourceRange(start, start);
828    return SourceRange(start, end);
829  }
830};
831
832/// Wrapper for substituted template type parameters.
833class SubstTemplateTypeParmTypeLoc :
834    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
835                                     SubstTemplateTypeParmTypeLoc,
836                                     SubstTemplateTypeParmType> {
837};
838
839  /// Wrapper for substituted template type parameters.
840class SubstTemplateTypeParmPackTypeLoc :
841    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
842                                     SubstTemplateTypeParmPackTypeLoc,
843                                     SubstTemplateTypeParmPackType> {
844};
845
846struct AttributedLocInfo {
847  const Attr *TypeAttr;
848};
849
850/// Type source information for an attributed type.
851class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
852                                                 AttributedTypeLoc,
853                                                 AttributedType,
854                                                 AttributedLocInfo> {
855public:
856  attr::Kind getAttrKind() const {
857    return getTypePtr()->getAttrKind();
858  }
859
860  bool isQualifier() const {
861    return getTypePtr()->isQualifier();
862  }
863
864  /// The modified type, which is generally canonically different from
865  /// the attribute type.
866  ///    int main(int, char**) __attribute__((noreturn))
867  ///    ~~~     ~~~~~~~~~~~~~
868  TypeLoc getModifiedLoc() const {
869    return getInnerTypeLoc();
870  }
871
872  /// The type attribute.
873  const Attr *getAttr() const {
874    return getLocalData()->TypeAttr;
875  }
876  void setAttr(const Attr *A) {
877    getLocalData()->TypeAttr = A;
878  }
879
880  template<typename T> const T *getAttrAs() {
881    return dyn_cast_or_null<T>(getAttr());
882  }
883
884  SourceRange getLocalSourceRange() const;
885
886  void initializeLocal(ASTContext &Context, SourceLocation loc) {
887    setAttr(nullptr);
888  }
889
890  QualType getInnerType() const {
891    return getTypePtr()->getModifiedType();
892  }
893};
894
895struct ObjCObjectTypeLocInfo {
896  SourceLocation TypeArgsLAngleLoc;
897  SourceLocation TypeArgsRAngleLoc;
898  SourceLocation ProtocolLAngleLoc;
899  SourceLocation ProtocolRAngleLoc;
900  bool HasBaseTypeAsWritten;
901};
902
903// A helper class for defining ObjC TypeLocs that can qualified with
904// protocols.
905//
906// TypeClass basically has to be either ObjCInterfaceType or
907// ObjCObjectPointerType.
908class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
909                                                 ObjCObjectTypeLoc,
910                                                 ObjCObjectType,
911                                                 ObjCObjectTypeLocInfo> {
912  // TypeSourceInfo*'s are stored after Info, one for each type argument.
913  TypeSourceInfo **getTypeArgLocArray() const {
914    return (TypeSourceInfo**)this->getExtraLocalData();
915  }
916
917  // SourceLocations are stored after the type argument information, one for
918  // each Protocol.
919  SourceLocation *getProtocolLocArray() const {
920    return (SourceLocation*)(getTypeArgLocArray() + getNumTypeArgs());
921  }
922
923public:
924  SourceLocation getTypeArgsLAngleLoc() const {
925    return this->getLocalData()->TypeArgsLAngleLoc;
926  }
927
928  void setTypeArgsLAngleLoc(SourceLocation Loc) {
929    this->getLocalData()->TypeArgsLAngleLoc = Loc;
930  }
931
932  SourceLocation getTypeArgsRAngleLoc() const {
933    return this->getLocalData()->TypeArgsRAngleLoc;
934  }
935
936  void setTypeArgsRAngleLoc(SourceLocation Loc) {
937    this->getLocalData()->TypeArgsRAngleLoc = Loc;
938  }
939
940  unsigned getNumTypeArgs() const {
941    return this->getTypePtr()->getTypeArgsAsWritten().size();
942  }
943
944  TypeSourceInfo *getTypeArgTInfo(unsigned i) const {
945    assert(i < getNumTypeArgs() && "Index is out of bounds!");
946    return getTypeArgLocArray()[i];
947  }
948
949  void setTypeArgTInfo(unsigned i, TypeSourceInfo *TInfo) {
950    assert(i < getNumTypeArgs() && "Index is out of bounds!");
951    getTypeArgLocArray()[i] = TInfo;
952  }
953
954  SourceLocation getProtocolLAngleLoc() const {
955    return this->getLocalData()->ProtocolLAngleLoc;
956  }
957
958  void setProtocolLAngleLoc(SourceLocation Loc) {
959    this->getLocalData()->ProtocolLAngleLoc = Loc;
960  }
961
962  SourceLocation getProtocolRAngleLoc() const {
963    return this->getLocalData()->ProtocolRAngleLoc;
964  }
965
966  void setProtocolRAngleLoc(SourceLocation Loc) {
967    this->getLocalData()->ProtocolRAngleLoc = Loc;
968  }
969
970  unsigned getNumProtocols() const {
971    return this->getTypePtr()->getNumProtocols();
972  }
973
974  SourceLocation getProtocolLoc(unsigned i) const {
975    assert(i < getNumProtocols() && "Index is out of bounds!");
976    return getProtocolLocArray()[i];
977  }
978
979  void setProtocolLoc(unsigned i, SourceLocation Loc) {
980    assert(i < getNumProtocols() && "Index is out of bounds!");
981    getProtocolLocArray()[i] = Loc;
982  }
983
984  ObjCProtocolDecl *getProtocol(unsigned i) const {
985    assert(i < getNumProtocols() && "Index is out of bounds!");
986    return *(this->getTypePtr()->qual_begin() + i);
987  }
988
989
990  ArrayRef<SourceLocation> getProtocolLocs() const {
991    return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols());
992  }
993
994  bool hasBaseTypeAsWritten() const {
995    return getLocalData()->HasBaseTypeAsWritten;
996  }
997
998  void setHasBaseTypeAsWritten(bool HasBaseType) {
999    getLocalData()->HasBaseTypeAsWritten = HasBaseType;
1000  }
1001
1002  TypeLoc getBaseLoc() const {
1003    return getInnerTypeLoc();
1004  }
1005
1006  SourceRange getLocalSourceRange() const {
1007    SourceLocation start = getTypeArgsLAngleLoc();
1008    if (start.isInvalid())
1009      start = getProtocolLAngleLoc();
1010    SourceLocation end = getProtocolRAngleLoc();
1011    if (end.isInvalid())
1012      end = getTypeArgsRAngleLoc();
1013    return SourceRange(start, end);
1014  }
1015
1016  void initializeLocal(ASTContext &Context, SourceLocation Loc);
1017
1018  unsigned getExtraLocalDataSize() const {
1019    return this->getNumTypeArgs() * sizeof(TypeSourceInfo *)
1020         + this->getNumProtocols() * sizeof(SourceLocation);
1021  }
1022
1023  unsigned getExtraLocalDataAlignment() const {
1024    static_assert(alignof(ObjCObjectTypeLoc) >= alignof(TypeSourceInfo *),
1025                  "not enough alignment for tail-allocated data");
1026    return alignof(TypeSourceInfo *);
1027  }
1028
1029  QualType getInnerType() const {
1030    return getTypePtr()->getBaseType();
1031  }
1032};
1033
1034struct ObjCInterfaceLocInfo {
1035  SourceLocation NameLoc;
1036  SourceLocation NameEndLoc;
1037};
1038
1039/// Wrapper for source info for ObjC interfaces.
1040class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
1041                                                    ObjCInterfaceTypeLoc,
1042                                                    ObjCInterfaceType,
1043                                                    ObjCInterfaceLocInfo> {
1044public:
1045  ObjCInterfaceDecl *getIFaceDecl() const {
1046    return getTypePtr()->getDecl();
1047  }
1048
1049  SourceLocation getNameLoc() const {
1050    return getLocalData()->NameLoc;
1051  }
1052
1053  void setNameLoc(SourceLocation Loc) {
1054    getLocalData()->NameLoc = Loc;
1055  }
1056
1057  SourceRange getLocalSourceRange() const {
1058    return SourceRange(getNameLoc(), getNameEndLoc());
1059  }
1060
1061  SourceLocation getNameEndLoc() const {
1062    return getLocalData()->NameEndLoc;
1063  }
1064
1065  void setNameEndLoc(SourceLocation Loc) {
1066    getLocalData()->NameEndLoc = Loc;
1067  }
1068
1069  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1070    setNameLoc(Loc);
1071    setNameEndLoc(Loc);
1072  }
1073};
1074
1075struct MacroQualifiedLocInfo {
1076  SourceLocation ExpansionLoc;
1077};
1078
1079class MacroQualifiedTypeLoc
1080    : public ConcreteTypeLoc<UnqualTypeLoc, MacroQualifiedTypeLoc,
1081                             MacroQualifiedType, MacroQualifiedLocInfo> {
1082public:
1083  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1084    setExpansionLoc(Loc);
1085  }
1086
1087  TypeLoc getInnerLoc() const { return getInnerTypeLoc(); }
1088
1089  const IdentifierInfo *getMacroIdentifier() const {
1090    return getTypePtr()->getMacroIdentifier();
1091  }
1092
1093  SourceLocation getExpansionLoc() const {
1094    return this->getLocalData()->ExpansionLoc;
1095  }
1096
1097  void setExpansionLoc(SourceLocation Loc) {
1098    this->getLocalData()->ExpansionLoc = Loc;
1099  }
1100
1101  QualType getInnerType() const { return getTypePtr()->getUnderlyingType(); }
1102
1103  SourceRange getLocalSourceRange() const {
1104    return getInnerLoc().getLocalSourceRange();
1105  }
1106};
1107
1108struct ParenLocInfo {
1109  SourceLocation LParenLoc;
1110  SourceLocation RParenLoc;
1111};
1112
1113class ParenTypeLoc
1114  : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType,
1115                           ParenLocInfo> {
1116public:
1117  SourceLocation getLParenLoc() const {
1118    return this->getLocalData()->LParenLoc;
1119  }
1120
1121  SourceLocation getRParenLoc() const {
1122    return this->getLocalData()->RParenLoc;
1123  }
1124
1125  void setLParenLoc(SourceLocation Loc) {
1126    this->getLocalData()->LParenLoc = Loc;
1127  }
1128
1129  void setRParenLoc(SourceLocation Loc) {
1130    this->getLocalData()->RParenLoc = Loc;
1131  }
1132
1133  SourceRange getLocalSourceRange() const {
1134    return SourceRange(getLParenLoc(), getRParenLoc());
1135  }
1136
1137  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1138    setLParenLoc(Loc);
1139    setRParenLoc(Loc);
1140  }
1141
1142  TypeLoc getInnerLoc() const {
1143    return getInnerTypeLoc();
1144  }
1145
1146  QualType getInnerType() const {
1147    return this->getTypePtr()->getInnerType();
1148  }
1149};
1150
1151inline TypeLoc TypeLoc::IgnoreParens() const {
1152  if (ParenTypeLoc::isKind(*this))
1153    return IgnoreParensImpl(*this);
1154  return *this;
1155}
1156
1157struct AdjustedLocInfo {}; // Nothing.
1158
1159class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc,
1160                                               AdjustedType, AdjustedLocInfo> {
1161public:
1162  TypeLoc getOriginalLoc() const {
1163    return getInnerTypeLoc();
1164  }
1165
1166  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1167    // do nothing
1168  }
1169
1170  QualType getInnerType() const {
1171    // The inner type is the undecayed type, since that's what we have source
1172    // location information for.
1173    return getTypePtr()->getOriginalType();
1174  }
1175
1176  SourceRange getLocalSourceRange() const { return {}; }
1177
1178  unsigned getLocalDataSize() const {
1179    // sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique
1180    // anyway.  TypeLocBuilder can't handle data sizes of 1.
1181    return 0;  // No data.
1182  }
1183};
1184
1185/// Wrapper for source info for pointers decayed from arrays and
1186/// functions.
1187class DecayedTypeLoc : public InheritingConcreteTypeLoc<
1188                           AdjustedTypeLoc, DecayedTypeLoc, DecayedType> {
1189};
1190
1191struct PointerLikeLocInfo {
1192  SourceLocation StarLoc;
1193};
1194
1195/// A base class for
1196template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
1197class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
1198                                                  TypeClass, LocalData> {
1199public:
1200  SourceLocation getSigilLoc() const {
1201    return this->getLocalData()->StarLoc;
1202  }
1203
1204  void setSigilLoc(SourceLocation Loc) {
1205    this->getLocalData()->StarLoc = Loc;
1206  }
1207
1208  TypeLoc getPointeeLoc() const {
1209    return this->getInnerTypeLoc();
1210  }
1211
1212  SourceRange getLocalSourceRange() const {
1213    return SourceRange(getSigilLoc(), getSigilLoc());
1214  }
1215
1216  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1217    setSigilLoc(Loc);
1218  }
1219
1220  QualType getInnerType() const {
1221    return this->getTypePtr()->getPointeeType();
1222  }
1223};
1224
1225/// Wrapper for source info for pointers.
1226class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
1227                                                 PointerType> {
1228public:
1229  SourceLocation getStarLoc() const {
1230    return getSigilLoc();
1231  }
1232
1233  void setStarLoc(SourceLocation Loc) {
1234    setSigilLoc(Loc);
1235  }
1236};
1237
1238/// Wrapper for source info for block pointers.
1239class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
1240                                                      BlockPointerType> {
1241public:
1242  SourceLocation getCaretLoc() const {
1243    return getSigilLoc();
1244  }
1245
1246  void setCaretLoc(SourceLocation Loc) {
1247    setSigilLoc(Loc);
1248  }
1249};
1250
1251struct MemberPointerLocInfo : public PointerLikeLocInfo {
1252  TypeSourceInfo *ClassTInfo;
1253};
1254
1255/// Wrapper for source info for member pointers.
1256class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
1257                                                       MemberPointerType,
1258                                                       MemberPointerLocInfo> {
1259public:
1260  SourceLocation getStarLoc() const {
1261    return getSigilLoc();
1262  }
1263
1264  void setStarLoc(SourceLocation Loc) {
1265    setSigilLoc(Loc);
1266  }
1267
1268  const Type *getClass() const {
1269    return getTypePtr()->getClass();
1270  }
1271
1272  TypeSourceInfo *getClassTInfo() const {
1273    return getLocalData()->ClassTInfo;
1274  }
1275
1276  void setClassTInfo(TypeSourceInfo* TI) {
1277    getLocalData()->ClassTInfo = TI;
1278  }
1279
1280  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1281    setSigilLoc(Loc);
1282    setClassTInfo(nullptr);
1283  }
1284
1285  SourceRange getLocalSourceRange() const {
1286    if (TypeSourceInfo *TI = getClassTInfo())
1287      return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
1288    else
1289      return SourceRange(getStarLoc());
1290  }
1291};
1292
1293/// Wraps an ObjCPointerType with source location information.
1294class ObjCObjectPointerTypeLoc :
1295    public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
1296                              ObjCObjectPointerType> {
1297public:
1298  SourceLocation getStarLoc() const {
1299    return getSigilLoc();
1300  }
1301
1302  void setStarLoc(SourceLocation Loc) {
1303    setSigilLoc(Loc);
1304  }
1305};
1306
1307class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
1308                                                   ReferenceType> {
1309public:
1310  QualType getInnerType() const {
1311    return getTypePtr()->getPointeeTypeAsWritten();
1312  }
1313};
1314
1315class LValueReferenceTypeLoc :
1316    public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1317                                     LValueReferenceTypeLoc,
1318                                     LValueReferenceType> {
1319public:
1320  SourceLocation getAmpLoc() const {
1321    return getSigilLoc();
1322  }
1323
1324  void setAmpLoc(SourceLocation Loc) {
1325    setSigilLoc(Loc);
1326  }
1327};
1328
1329class RValueReferenceTypeLoc :
1330    public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1331                                     RValueReferenceTypeLoc,
1332                                     RValueReferenceType> {
1333public:
1334  SourceLocation getAmpAmpLoc() const {
1335    return getSigilLoc();
1336  }
1337
1338  void setAmpAmpLoc(SourceLocation Loc) {
1339    setSigilLoc(Loc);
1340  }
1341};
1342
1343struct FunctionLocInfo {
1344  SourceLocation LocalRangeBegin;
1345  SourceLocation LParenLoc;
1346  SourceLocation RParenLoc;
1347  SourceLocation LocalRangeEnd;
1348};
1349
1350/// Wrapper for source info for functions.
1351class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1352                                               FunctionTypeLoc,
1353                                               FunctionType,
1354                                               FunctionLocInfo> {
1355  bool hasExceptionSpec() const {
1356    if (auto *FPT = dyn_cast<FunctionProtoType>(getTypePtr())) {
1357      return FPT->hasExceptionSpec();
1358    }
1359    return false;
1360  }
1361
1362  SourceRange *getExceptionSpecRangePtr() const {
1363    assert(hasExceptionSpec() && "No exception spec range");
1364    // After the Info comes the ParmVarDecl array, and after that comes the
1365    // exception specification information.
1366    return (SourceRange *)(getParmArray() + getNumParams());
1367  }
1368
1369public:
1370  SourceLocation getLocalRangeBegin() const {
1371    return getLocalData()->LocalRangeBegin;
1372  }
1373
1374  void setLocalRangeBegin(SourceLocation L) {
1375    getLocalData()->LocalRangeBegin = L;
1376  }
1377
1378  SourceLocation getLocalRangeEnd() const {
1379    return getLocalData()->LocalRangeEnd;
1380  }
1381
1382  void setLocalRangeEnd(SourceLocation L) {
1383    getLocalData()->LocalRangeEnd = L;
1384  }
1385
1386  SourceLocation getLParenLoc() const {
1387    return this->getLocalData()->LParenLoc;
1388  }
1389
1390  void setLParenLoc(SourceLocation Loc) {
1391    this->getLocalData()->LParenLoc = Loc;
1392  }
1393
1394  SourceLocation getRParenLoc() const {
1395    return this->getLocalData()->RParenLoc;
1396  }
1397
1398  void setRParenLoc(SourceLocation Loc) {
1399    this->getLocalData()->RParenLoc = Loc;
1400  }
1401
1402  SourceRange getParensRange() const {
1403    return SourceRange(getLParenLoc(), getRParenLoc());
1404  }
1405
1406  SourceRange getExceptionSpecRange() const {
1407    if (hasExceptionSpec())
1408      return *getExceptionSpecRangePtr();
1409    return {};
1410  }
1411
1412  void setExceptionSpecRange(SourceRange R) {
1413    if (hasExceptionSpec())
1414      *getExceptionSpecRangePtr() = R;
1415  }
1416
1417  ArrayRef<ParmVarDecl *> getParams() const {
1418    return llvm::makeArrayRef(getParmArray(), getNumParams());
1419  }
1420
1421  // ParmVarDecls* are stored after Info, one for each parameter.
1422  ParmVarDecl **getParmArray() const {
1423    return (ParmVarDecl**) getExtraLocalData();
1424  }
1425
1426  unsigned getNumParams() const {
1427    if (isa<FunctionNoProtoType>(getTypePtr()))
1428      return 0;
1429    return cast<FunctionProtoType>(getTypePtr())->getNumParams();
1430  }
1431
1432  ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; }
1433  void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
1434
1435  TypeLoc getReturnLoc() const {
1436    return getInnerTypeLoc();
1437  }
1438
1439  SourceRange getLocalSourceRange() const {
1440    return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
1441  }
1442
1443  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1444    setLocalRangeBegin(Loc);
1445    setLParenLoc(Loc);
1446    setRParenLoc(Loc);
1447    setLocalRangeEnd(Loc);
1448    for (unsigned i = 0, e = getNumParams(); i != e; ++i)
1449      setParam(i, nullptr);
1450    if (hasExceptionSpec())
1451      setExceptionSpecRange(Loc);
1452  }
1453
1454  /// Returns the size of the type source info data block that is
1455  /// specific to this type.
1456  unsigned getExtraLocalDataSize() const {
1457    unsigned ExceptSpecSize = hasExceptionSpec() ? sizeof(SourceRange) : 0;
1458    return (getNumParams() * sizeof(ParmVarDecl *)) + ExceptSpecSize;
1459  }
1460
1461  unsigned getExtraLocalDataAlignment() const { return alignof(ParmVarDecl *); }
1462
1463  QualType getInnerType() const { return getTypePtr()->getReturnType(); }
1464};
1465
1466class FunctionProtoTypeLoc :
1467    public InheritingConcreteTypeLoc<FunctionTypeLoc,
1468                                     FunctionProtoTypeLoc,
1469                                     FunctionProtoType> {
1470};
1471
1472class FunctionNoProtoTypeLoc :
1473    public InheritingConcreteTypeLoc<FunctionTypeLoc,
1474                                     FunctionNoProtoTypeLoc,
1475                                     FunctionNoProtoType> {
1476};
1477
1478struct ArrayLocInfo {
1479  SourceLocation LBracketLoc, RBracketLoc;
1480  Expr *Size;
1481};
1482
1483/// Wrapper for source info for arrays.
1484class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1485                                            ArrayTypeLoc,
1486                                            ArrayType,
1487                                            ArrayLocInfo> {
1488public:
1489  SourceLocation getLBracketLoc() const {
1490    return getLocalData()->LBracketLoc;
1491  }
1492
1493  void setLBracketLoc(SourceLocation Loc) {
1494    getLocalData()->LBracketLoc = Loc;
1495  }
1496
1497  SourceLocation getRBracketLoc() const {
1498    return getLocalData()->RBracketLoc;
1499  }
1500
1501  void setRBracketLoc(SourceLocation Loc) {
1502    getLocalData()->RBracketLoc = Loc;
1503  }
1504
1505  SourceRange getBracketsRange() const {
1506    return SourceRange(getLBracketLoc(), getRBracketLoc());
1507  }
1508
1509  Expr *getSizeExpr() const {
1510    return getLocalData()->Size;
1511  }
1512
1513  void setSizeExpr(Expr *Size) {
1514    getLocalData()->Size = Size;
1515  }
1516
1517  TypeLoc getElementLoc() const {
1518    return getInnerTypeLoc();
1519  }
1520
1521  SourceRange getLocalSourceRange() const {
1522    return SourceRange(getLBracketLoc(), getRBracketLoc());
1523  }
1524
1525  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1526    setLBracketLoc(Loc);
1527    setRBracketLoc(Loc);
1528    setSizeExpr(nullptr);
1529  }
1530
1531  QualType getInnerType() const { return getTypePtr()->getElementType(); }
1532};
1533
1534class ConstantArrayTypeLoc :
1535    public InheritingConcreteTypeLoc<ArrayTypeLoc,
1536                                     ConstantArrayTypeLoc,
1537                                     ConstantArrayType> {
1538};
1539
1540class IncompleteArrayTypeLoc :
1541    public InheritingConcreteTypeLoc<ArrayTypeLoc,
1542                                     IncompleteArrayTypeLoc,
1543                                     IncompleteArrayType> {
1544};
1545
1546class DependentSizedArrayTypeLoc :
1547    public InheritingConcreteTypeLoc<ArrayTypeLoc,
1548                                     DependentSizedArrayTypeLoc,
1549                                     DependentSizedArrayType> {
1550public:
1551  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1552    ArrayTypeLoc::initializeLocal(Context, Loc);
1553    setSizeExpr(getTypePtr()->getSizeExpr());
1554  }
1555};
1556
1557class VariableArrayTypeLoc :
1558    public InheritingConcreteTypeLoc<ArrayTypeLoc,
1559                                     VariableArrayTypeLoc,
1560                                     VariableArrayType> {
1561};
1562
1563// Location information for a TemplateName.  Rudimentary for now.
1564struct TemplateNameLocInfo {
1565  SourceLocation NameLoc;
1566};
1567
1568struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
1569  SourceLocation TemplateKWLoc;
1570  SourceLocation LAngleLoc;
1571  SourceLocation RAngleLoc;
1572};
1573
1574class TemplateSpecializationTypeLoc :
1575    public ConcreteTypeLoc<UnqualTypeLoc,
1576                           TemplateSpecializationTypeLoc,
1577                           TemplateSpecializationType,
1578                           TemplateSpecializationLocInfo> {
1579public:
1580  SourceLocation getTemplateKeywordLoc() const {
1581    return getLocalData()->TemplateKWLoc;
1582  }
1583
1584  void setTemplateKeywordLoc(SourceLocation Loc) {
1585    getLocalData()->TemplateKWLoc = Loc;
1586  }
1587
1588  SourceLocation getLAngleLoc() const {
1589    return getLocalData()->LAngleLoc;
1590  }
1591
1592  void setLAngleLoc(SourceLocation Loc) {
1593    getLocalData()->LAngleLoc = Loc;
1594  }
1595
1596  SourceLocation getRAngleLoc() const {
1597    return getLocalData()->RAngleLoc;
1598  }
1599
1600  void setRAngleLoc(SourceLocation Loc) {
1601    getLocalData()->RAngleLoc = Loc;
1602  }
1603
1604  unsigned getNumArgs() const {
1605    return getTypePtr()->getNumArgs();
1606  }
1607
1608  void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1609    getArgInfos()[i] = AI;
1610  }
1611
1612  TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1613    return getArgInfos()[i];
1614  }
1615
1616  TemplateArgumentLoc getArgLoc(unsigned i) const {
1617    return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1618  }
1619
1620  SourceLocation getTemplateNameLoc() const {
1621    return getLocalData()->NameLoc;
1622  }
1623
1624  void setTemplateNameLoc(SourceLocation Loc) {
1625    getLocalData()->NameLoc = Loc;
1626  }
1627
1628  /// - Copy the location information from the given info.
1629  void copy(TemplateSpecializationTypeLoc Loc) {
1630    unsigned size = getFullDataSize();
1631    assert(size == Loc.getFullDataSize());
1632
1633    // We're potentially copying Expr references here.  We don't
1634    // bother retaining them because TypeSourceInfos live forever, so
1635    // as long as the Expr was retained when originally written into
1636    // the TypeLoc, we're okay.
1637    memcpy(Data, Loc.Data, size);
1638  }
1639
1640  SourceRange getLocalSourceRange() const {
1641    if (getTemplateKeywordLoc().isValid())
1642      return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1643    else
1644      return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1645  }
1646
1647  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1648    setTemplateKeywordLoc(Loc);
1649    setTemplateNameLoc(Loc);
1650    setLAngleLoc(Loc);
1651    setRAngleLoc(Loc);
1652    initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
1653                      getArgInfos(), Loc);
1654  }
1655
1656  static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
1657                                const TemplateArgument *Args,
1658                                TemplateArgumentLocInfo *ArgInfos,
1659                                SourceLocation Loc);
1660
1661  unsigned getExtraLocalDataSize() const {
1662    return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1663  }
1664
1665  unsigned getExtraLocalDataAlignment() const {
1666    return alignof(TemplateArgumentLocInfo);
1667  }
1668
1669private:
1670  TemplateArgumentLocInfo *getArgInfos() const {
1671    return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1672  }
1673};
1674
1675struct DependentAddressSpaceLocInfo {
1676  Expr *ExprOperand;
1677  SourceRange OperandParens;
1678  SourceLocation AttrLoc;
1679};
1680
1681class DependentAddressSpaceTypeLoc
1682    : public ConcreteTypeLoc<UnqualTypeLoc,
1683                             DependentAddressSpaceTypeLoc,
1684                             DependentAddressSpaceType,
1685                             DependentAddressSpaceLocInfo> {
1686public:
1687  /// The location of the attribute name, i.e.
1688  ///    int * __attribute__((address_space(11)))
1689  ///                         ^~~~~~~~~~~~~
1690  SourceLocation getAttrNameLoc() const {
1691    return getLocalData()->AttrLoc;
1692  }
1693  void setAttrNameLoc(SourceLocation loc) {
1694    getLocalData()->AttrLoc = loc;
1695  }
1696
1697  /// The attribute's expression operand, if it has one.
1698  ///    int * __attribute__((address_space(11)))
1699  ///                                       ^~
1700  Expr *getAttrExprOperand() const {
1701    return getLocalData()->ExprOperand;
1702  }
1703  void setAttrExprOperand(Expr *e) {
1704    getLocalData()->ExprOperand = e;
1705  }
1706
1707  /// The location of the parentheses around the operand, if there is
1708  /// an operand.
1709  ///    int * __attribute__((address_space(11)))
1710  ///                                      ^  ^
1711  SourceRange getAttrOperandParensRange() const {
1712    return getLocalData()->OperandParens;
1713  }
1714  void setAttrOperandParensRange(SourceRange range) {
1715    getLocalData()->OperandParens = range;
1716  }
1717
1718  SourceRange getLocalSourceRange() const {
1719    SourceRange range(getAttrNameLoc());
1720    range.setEnd(getAttrOperandParensRange().getEnd());
1721    return range;
1722  }
1723
1724  ///  Returns the type before the address space attribute application
1725  ///  area.
1726  ///    int * __attribute__((address_space(11))) *
1727  ///    ^   ^
1728  QualType getInnerType() const {
1729    return this->getTypePtr()->getPointeeType();
1730  }
1731
1732  TypeLoc getPointeeTypeLoc() const {
1733    return this->getInnerTypeLoc();
1734  }
1735
1736  void initializeLocal(ASTContext &Context, SourceLocation loc) {
1737    setAttrNameLoc(loc);
1738    setAttrOperandParensRange(SourceRange(loc));
1739    setAttrExprOperand(getTypePtr()->getAddrSpaceExpr());
1740  }
1741};
1742
1743//===----------------------------------------------------------------------===//
1744//
1745//  All of these need proper implementations.
1746//
1747//===----------------------------------------------------------------------===//
1748
1749// FIXME: size expression and attribute locations (or keyword if we
1750// ever fully support altivec syntax).
1751class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1752                                                       VectorTypeLoc,
1753                                                       VectorType> {
1754};
1755
1756// FIXME: size expression and attribute locations (or keyword if we
1757// ever fully support altivec syntax).
1758class DependentVectorTypeLoc
1759    : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1760                                       DependentVectorTypeLoc,
1761                                       DependentVectorType> {};
1762
1763// FIXME: size expression and attribute locations.
1764class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
1765                                                          ExtVectorTypeLoc,
1766                                                          ExtVectorType> {
1767};
1768
1769// FIXME: attribute locations.
1770// For some reason, this isn't a subtype of VectorType.
1771class DependentSizedExtVectorTypeLoc :
1772    public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1773                                     DependentSizedExtVectorTypeLoc,
1774                                     DependentSizedExtVectorType> {
1775};
1776
1777// FIXME: location of the '_Complex' keyword.
1778class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1779                                                        ComplexTypeLoc,
1780                                                        ComplexType> {
1781};
1782
1783struct TypeofLocInfo {
1784  SourceLocation TypeofLoc;
1785  SourceLocation LParenLoc;
1786  SourceLocation RParenLoc;
1787};
1788
1789struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
1790};
1791
1792struct TypeOfTypeLocInfo : public TypeofLocInfo {
1793  TypeSourceInfo* UnderlyingTInfo;
1794};
1795
1796template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
1797class TypeofLikeTypeLoc
1798  : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
1799public:
1800  SourceLocation getTypeofLoc() const {
1801    return this->getLocalData()->TypeofLoc;
1802  }
1803
1804  void setTypeofLoc(SourceLocation Loc) {
1805    this->getLocalData()->TypeofLoc = Loc;
1806  }
1807
1808  SourceLocation getLParenLoc() const {
1809    return this->getLocalData()->LParenLoc;
1810  }
1811
1812  void setLParenLoc(SourceLocation Loc) {
1813    this->getLocalData()->LParenLoc = Loc;
1814  }
1815
1816  SourceLocation getRParenLoc() const {
1817    return this->getLocalData()->RParenLoc;
1818  }
1819
1820  void setRParenLoc(SourceLocation Loc) {
1821    this->getLocalData()->RParenLoc = Loc;
1822  }
1823
1824  SourceRange getParensRange() const {
1825    return SourceRange(getLParenLoc(), getRParenLoc());
1826  }
1827
1828  void setParensRange(SourceRange range) {
1829      setLParenLoc(range.getBegin());
1830      setRParenLoc(range.getEnd());
1831  }
1832
1833  SourceRange getLocalSourceRange() const {
1834    return SourceRange(getTypeofLoc(), getRParenLoc());
1835  }
1836
1837  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1838    setTypeofLoc(Loc);
1839    setLParenLoc(Loc);
1840    setRParenLoc(Loc);
1841  }
1842};
1843
1844class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
1845                                                   TypeOfExprType,
1846                                                   TypeOfExprTypeLocInfo> {
1847public:
1848  Expr* getUnderlyingExpr() const {
1849    return getTypePtr()->getUnderlyingExpr();
1850  }
1851
1852  // Reimplemented to account for GNU/C++ extension
1853  //     typeof unary-expression
1854  // where there are no parentheses.
1855  SourceRange getLocalSourceRange() const;
1856};
1857
1858class TypeOfTypeLoc
1859  : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
1860public:
1861  QualType getUnderlyingType() const {
1862    return this->getTypePtr()->getUnderlyingType();
1863  }
1864
1865  TypeSourceInfo* getUnderlyingTInfo() const {
1866    return this->getLocalData()->UnderlyingTInfo;
1867  }
1868
1869  void setUnderlyingTInfo(TypeSourceInfo* TI) const {
1870    this->getLocalData()->UnderlyingTInfo = TI;
1871  }
1872
1873  void initializeLocal(ASTContext &Context, SourceLocation Loc);
1874};
1875
1876// FIXME: location of the 'decltype' and parens.
1877class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1878                                                         DecltypeTypeLoc,
1879                                                         DecltypeType> {
1880public:
1881  Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
1882};
1883
1884struct UnaryTransformTypeLocInfo {
1885  // FIXME: While there's only one unary transform right now, future ones may
1886  // need different representations
1887  SourceLocation KWLoc, LParenLoc, RParenLoc;
1888  TypeSourceInfo *UnderlyingTInfo;
1889};
1890
1891class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1892                                                    UnaryTransformTypeLoc,
1893                                                    UnaryTransformType,
1894                                                    UnaryTransformTypeLocInfo> {
1895public:
1896  SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
1897  void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
1898
1899  SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
1900  void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
1901
1902  SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
1903  void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
1904
1905  TypeSourceInfo* getUnderlyingTInfo() const {
1906    return getLocalData()->UnderlyingTInfo;
1907  }
1908
1909  void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
1910    getLocalData()->UnderlyingTInfo = TInfo;
1911  }
1912
1913  SourceRange getLocalSourceRange() const {
1914    return SourceRange(getKWLoc(), getRParenLoc());
1915  }
1916
1917  SourceRange getParensRange() const {
1918    return SourceRange(getLParenLoc(), getRParenLoc());
1919  }
1920
1921  void setParensRange(SourceRange Range) {
1922    setLParenLoc(Range.getBegin());
1923    setRParenLoc(Range.getEnd());
1924  }
1925
1926  void initializeLocal(ASTContext &Context, SourceLocation Loc);
1927};
1928
1929class DeducedTypeLoc
1930    : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DeducedTypeLoc,
1931                                       DeducedType> {};
1932
1933struct AutoTypeLocInfo : TypeSpecLocInfo {
1934  NestedNameSpecifierLoc NestedNameSpec;
1935  SourceLocation TemplateKWLoc;
1936  SourceLocation ConceptNameLoc;
1937  NamedDecl *FoundDecl;
1938  SourceLocation LAngleLoc;
1939  SourceLocation RAngleLoc;
1940};
1941
1942class AutoTypeLoc
1943    : public ConcreteTypeLoc<DeducedTypeLoc,
1944                             AutoTypeLoc,
1945                             AutoType,
1946                             AutoTypeLocInfo> {
1947public:
1948  AutoTypeKeyword getAutoKeyword() const {
1949    return getTypePtr()->getKeyword();
1950  }
1951
1952  bool isConstrained() const {
1953    return getTypePtr()->isConstrained();
1954  }
1955
1956  const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
1957    return getLocalData()->NestedNameSpec;
1958  }
1959
1960  void setNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
1961    getLocalData()->NestedNameSpec = NNS;
1962  }
1963
1964  SourceLocation getTemplateKWLoc() const {
1965    return getLocalData()->TemplateKWLoc;
1966  }
1967
1968  void setTemplateKWLoc(SourceLocation Loc) {
1969    getLocalData()->TemplateKWLoc = Loc;
1970  }
1971
1972  SourceLocation getConceptNameLoc() const {
1973    return getLocalData()->ConceptNameLoc;
1974  }
1975
1976  void setConceptNameLoc(SourceLocation Loc) {
1977    getLocalData()->ConceptNameLoc = Loc;
1978  }
1979
1980  NamedDecl *getFoundDecl() const {
1981    return getLocalData()->FoundDecl;
1982  }
1983
1984  void setFoundDecl(NamedDecl *D) {
1985    getLocalData()->FoundDecl = D;
1986  }
1987
1988  ConceptDecl *getNamedConcept() const {
1989    return getTypePtr()->getTypeConstraintConcept();
1990  }
1991
1992  DeclarationNameInfo getConceptNameInfo() const;
1993
1994  bool hasExplicitTemplateArgs() const {
1995    return getLocalData()->LAngleLoc.isValid();
1996  }
1997
1998  SourceLocation getLAngleLoc() const {
1999    return this->getLocalData()->LAngleLoc;
2000  }
2001
2002  void setLAngleLoc(SourceLocation Loc) {
2003    this->getLocalData()->LAngleLoc = Loc;
2004  }
2005
2006  SourceLocation getRAngleLoc() const {
2007    return this->getLocalData()->RAngleLoc;
2008  }
2009
2010  void setRAngleLoc(SourceLocation Loc) {
2011    this->getLocalData()->RAngleLoc = Loc;
2012  }
2013
2014  unsigned getNumArgs() const {
2015    return getTypePtr()->getNumArgs();
2016  }
2017
2018  void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
2019    getArgInfos()[i] = AI;
2020  }
2021
2022  TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
2023    return getArgInfos()[i];
2024  }
2025
2026  TemplateArgumentLoc getArgLoc(unsigned i) const {
2027    return TemplateArgumentLoc(getTypePtr()->getTypeConstraintArguments()[i],
2028                               getArgLocInfo(i));
2029  }
2030
2031  SourceRange getLocalSourceRange() const {
2032    return{
2033        isConstrained()
2034          ? (getNestedNameSpecifierLoc()
2035               ? getNestedNameSpecifierLoc().getBeginLoc()
2036               : (getTemplateKWLoc().isValid()
2037                  ? getTemplateKWLoc()
2038                  : getConceptNameLoc()))
2039          : getNameLoc(),
2040        getNameLoc()
2041    };
2042  }
2043
2044  void copy(AutoTypeLoc Loc) {
2045    unsigned size = getFullDataSize();
2046    assert(size == Loc.getFullDataSize());
2047    memcpy(Data, Loc.Data, size);
2048  }
2049
2050  void initializeLocal(ASTContext &Context, SourceLocation Loc);
2051
2052  unsigned getExtraLocalDataSize() const {
2053    return getNumArgs() * sizeof(TemplateArgumentLocInfo);
2054  }
2055
2056  unsigned getExtraLocalDataAlignment() const {
2057    return alignof(TemplateArgumentLocInfo);
2058  }
2059
2060private:
2061  TemplateArgumentLocInfo *getArgInfos() const {
2062    return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
2063  }
2064};
2065
2066class DeducedTemplateSpecializationTypeLoc
2067    : public InheritingConcreteTypeLoc<DeducedTypeLoc,
2068                                       DeducedTemplateSpecializationTypeLoc,
2069                                       DeducedTemplateSpecializationType> {
2070public:
2071  SourceLocation getTemplateNameLoc() const {
2072    return getNameLoc();
2073  }
2074
2075  void setTemplateNameLoc(SourceLocation Loc) {
2076    setNameLoc(Loc);
2077  }
2078};
2079
2080struct ElaboratedLocInfo {
2081  SourceLocation ElaboratedKWLoc;
2082
2083  /// Data associated with the nested-name-specifier location.
2084  void *QualifierData;
2085};
2086
2087class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
2088                                                 ElaboratedTypeLoc,
2089                                                 ElaboratedType,
2090                                                 ElaboratedLocInfo> {
2091public:
2092  SourceLocation getElaboratedKeywordLoc() const {
2093    return this->getLocalData()->ElaboratedKWLoc;
2094  }
2095
2096  void setElaboratedKeywordLoc(SourceLocation Loc) {
2097    this->getLocalData()->ElaboratedKWLoc = Loc;
2098  }
2099
2100  NestedNameSpecifierLoc getQualifierLoc() const {
2101    return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
2102                                  getLocalData()->QualifierData);
2103  }
2104
2105  void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
2106    assert(QualifierLoc.getNestedNameSpecifier()
2107                                            == getTypePtr()->getQualifier() &&
2108           "Inconsistent nested-name-specifier pointer");
2109    getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
2110  }
2111
2112  SourceRange getLocalSourceRange() const {
2113    if (getElaboratedKeywordLoc().isValid())
2114      if (getQualifierLoc())
2115        return SourceRange(getElaboratedKeywordLoc(),
2116                           getQualifierLoc().getEndLoc());
2117      else
2118        return SourceRange(getElaboratedKeywordLoc());
2119    else
2120      return getQualifierLoc().getSourceRange();
2121  }
2122
2123  void initializeLocal(ASTContext &Context, SourceLocation Loc);
2124
2125  TypeLoc getNamedTypeLoc() const {
2126    return getInnerTypeLoc();
2127  }
2128
2129  QualType getInnerType() const {
2130    return getTypePtr()->getNamedType();
2131  }
2132
2133  void copy(ElaboratedTypeLoc Loc) {
2134    unsigned size = getFullDataSize();
2135    assert(size == Loc.getFullDataSize());
2136    memcpy(Data, Loc.Data, size);
2137  }
2138};
2139
2140// This is exactly the structure of an ElaboratedTypeLoc whose inner
2141// type is some sort of TypeDeclTypeLoc.
2142struct DependentNameLocInfo : ElaboratedLocInfo {
2143  SourceLocation NameLoc;
2144};
2145
2146class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
2147                                                    DependentNameTypeLoc,
2148                                                    DependentNameType,
2149                                                    DependentNameLocInfo> {
2150public:
2151  SourceLocation getElaboratedKeywordLoc() const {
2152    return this->getLocalData()->ElaboratedKWLoc;
2153  }
2154
2155  void setElaboratedKeywordLoc(SourceLocation Loc) {
2156    this->getLocalData()->ElaboratedKWLoc = Loc;
2157  }
2158
2159  NestedNameSpecifierLoc getQualifierLoc() const {
2160    return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
2161                                  getLocalData()->QualifierData);
2162  }
2163
2164  void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
2165    assert(QualifierLoc.getNestedNameSpecifier()
2166                                            == getTypePtr()->getQualifier() &&
2167           "Inconsistent nested-name-specifier pointer");
2168    getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
2169  }
2170
2171  SourceLocation getNameLoc() const {
2172    return this->getLocalData()->NameLoc;
2173  }
2174
2175  void setNameLoc(SourceLocation Loc) {
2176    this->getLocalData()->NameLoc = Loc;
2177  }
2178
2179  SourceRange getLocalSourceRange() const {
2180    if (getElaboratedKeywordLoc().isValid())
2181      return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
2182    else
2183      return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
2184  }
2185
2186  void copy(DependentNameTypeLoc Loc) {
2187    unsigned size = getFullDataSize();
2188    assert(size == Loc.getFullDataSize());
2189    memcpy(Data, Loc.Data, size);
2190  }
2191
2192  void initializeLocal(ASTContext &Context, SourceLocation Loc);
2193};
2194
2195struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
2196  SourceLocation TemplateKWLoc;
2197  SourceLocation LAngleLoc;
2198  SourceLocation RAngleLoc;
2199  // followed by a TemplateArgumentLocInfo[]
2200};
2201
2202class DependentTemplateSpecializationTypeLoc :
2203    public ConcreteTypeLoc<UnqualTypeLoc,
2204                           DependentTemplateSpecializationTypeLoc,
2205                           DependentTemplateSpecializationType,
2206                           DependentTemplateSpecializationLocInfo> {
2207public:
2208  SourceLocation getElaboratedKeywordLoc() const {
2209    return this->getLocalData()->ElaboratedKWLoc;
2210  }
2211
2212  void setElaboratedKeywordLoc(SourceLocation Loc) {
2213    this->getLocalData()->ElaboratedKWLoc = Loc;
2214  }
2215
2216  NestedNameSpecifierLoc getQualifierLoc() const {
2217    if (!getLocalData()->QualifierData)
2218      return NestedNameSpecifierLoc();
2219
2220    return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
2221                                  getLocalData()->QualifierData);
2222  }
2223
2224  void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
2225    if (!QualifierLoc) {
2226      // Even if we have a nested-name-specifier in the dependent
2227      // template specialization type, we won't record the nested-name-specifier
2228      // location information when this type-source location information is
2229      // part of a nested-name-specifier.
2230      getLocalData()->QualifierData = nullptr;
2231      return;
2232    }
2233
2234    assert(QualifierLoc.getNestedNameSpecifier()
2235                                        == getTypePtr()->getQualifier() &&
2236           "Inconsistent nested-name-specifier pointer");
2237    getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
2238  }
2239
2240  SourceLocation getTemplateKeywordLoc() const {
2241    return getLocalData()->TemplateKWLoc;
2242  }
2243
2244  void setTemplateKeywordLoc(SourceLocation Loc) {
2245    getLocalData()->TemplateKWLoc = Loc;
2246  }
2247
2248  SourceLocation getTemplateNameLoc() const {
2249    return this->getLocalData()->NameLoc;
2250  }
2251
2252  void setTemplateNameLoc(SourceLocation Loc) {
2253    this->getLocalData()->NameLoc = Loc;
2254  }
2255
2256  SourceLocation getLAngleLoc() const {
2257    return this->getLocalData()->LAngleLoc;
2258  }
2259
2260  void setLAngleLoc(SourceLocation Loc) {
2261    this->getLocalData()->LAngleLoc = Loc;
2262  }
2263
2264  SourceLocation getRAngleLoc() const {
2265    return this->getLocalData()->RAngleLoc;
2266  }
2267
2268  void setRAngleLoc(SourceLocation Loc) {
2269    this->getLocalData()->RAngleLoc = Loc;
2270  }
2271
2272  unsigned getNumArgs() const {
2273    return getTypePtr()->getNumArgs();
2274  }
2275
2276  void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
2277    getArgInfos()[i] = AI;
2278  }
2279
2280  TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
2281    return getArgInfos()[i];
2282  }
2283
2284  TemplateArgumentLoc getArgLoc(unsigned i) const {
2285    return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
2286  }
2287
2288  SourceRange getLocalSourceRange() const {
2289    if (getElaboratedKeywordLoc().isValid())
2290      return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
2291    else if (getQualifierLoc())
2292      return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
2293    else if (getTemplateKeywordLoc().isValid())
2294      return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
2295    else
2296      return SourceRange(getTemplateNameLoc(), getRAngleLoc());
2297  }
2298
2299  void copy(DependentTemplateSpecializationTypeLoc Loc) {
2300    unsigned size = getFullDataSize();
2301    assert(size == Loc.getFullDataSize());
2302    memcpy(Data, Loc.Data, size);
2303  }
2304
2305  void initializeLocal(ASTContext &Context, SourceLocation Loc);
2306
2307  unsigned getExtraLocalDataSize() const {
2308    return getNumArgs() * sizeof(TemplateArgumentLocInfo);
2309  }
2310
2311  unsigned getExtraLocalDataAlignment() const {
2312    return alignof(TemplateArgumentLocInfo);
2313  }
2314
2315private:
2316  TemplateArgumentLocInfo *getArgInfos() const {
2317    return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
2318  }
2319};
2320
2321struct PackExpansionTypeLocInfo {
2322  SourceLocation EllipsisLoc;
2323};
2324
2325class PackExpansionTypeLoc
2326  : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
2327                           PackExpansionType, PackExpansionTypeLocInfo> {
2328public:
2329  SourceLocation getEllipsisLoc() const {
2330    return this->getLocalData()->EllipsisLoc;
2331  }
2332
2333  void setEllipsisLoc(SourceLocation Loc) {
2334    this->getLocalData()->EllipsisLoc = Loc;
2335  }
2336
2337  SourceRange getLocalSourceRange() const {
2338    return SourceRange(getEllipsisLoc(), getEllipsisLoc());
2339  }
2340
2341  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2342    setEllipsisLoc(Loc);
2343  }
2344
2345  TypeLoc getPatternLoc() const {
2346    return getInnerTypeLoc();
2347  }
2348
2349  QualType getInnerType() const {
2350    return this->getTypePtr()->getPattern();
2351  }
2352};
2353
2354struct AtomicTypeLocInfo {
2355  SourceLocation KWLoc, LParenLoc, RParenLoc;
2356};
2357
2358class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
2359                                             AtomicType, AtomicTypeLocInfo> {
2360public:
2361  TypeLoc getValueLoc() const {
2362    return this->getInnerTypeLoc();
2363  }
2364
2365  SourceRange getLocalSourceRange() const {
2366    return SourceRange(getKWLoc(), getRParenLoc());
2367  }
2368
2369  SourceLocation getKWLoc() const {
2370    return this->getLocalData()->KWLoc;
2371  }
2372
2373  void setKWLoc(SourceLocation Loc) {
2374    this->getLocalData()->KWLoc = Loc;
2375  }
2376
2377  SourceLocation getLParenLoc() const {
2378    return this->getLocalData()->LParenLoc;
2379  }
2380
2381  void setLParenLoc(SourceLocation Loc) {
2382    this->getLocalData()->LParenLoc = Loc;
2383  }
2384
2385  SourceLocation getRParenLoc() const {
2386    return this->getLocalData()->RParenLoc;
2387  }
2388
2389  void setRParenLoc(SourceLocation Loc) {
2390    this->getLocalData()->RParenLoc = Loc;
2391  }
2392
2393  SourceRange getParensRange() const {
2394    return SourceRange(getLParenLoc(), getRParenLoc());
2395  }
2396
2397  void setParensRange(SourceRange Range) {
2398    setLParenLoc(Range.getBegin());
2399    setRParenLoc(Range.getEnd());
2400  }
2401
2402  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2403    setKWLoc(Loc);
2404    setLParenLoc(Loc);
2405    setRParenLoc(Loc);
2406  }
2407
2408  QualType getInnerType() const {
2409    return this->getTypePtr()->getValueType();
2410  }
2411};
2412
2413struct PipeTypeLocInfo {
2414  SourceLocation KWLoc;
2415};
2416
2417class PipeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, PipeTypeLoc, PipeType,
2418                                           PipeTypeLocInfo> {
2419public:
2420  TypeLoc getValueLoc() const { return this->getInnerTypeLoc(); }
2421
2422  SourceRange getLocalSourceRange() const { return SourceRange(getKWLoc()); }
2423
2424  SourceLocation getKWLoc() const { return this->getLocalData()->KWLoc; }
2425  void setKWLoc(SourceLocation Loc) { this->getLocalData()->KWLoc = Loc; }
2426
2427  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2428    setKWLoc(Loc);
2429  }
2430
2431  QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
2432};
2433
2434template <typename T>
2435inline T TypeLoc::getAsAdjusted() const {
2436  TypeLoc Cur = *this;
2437  while (!T::isKind(Cur)) {
2438    if (auto PTL = Cur.getAs<ParenTypeLoc>())
2439      Cur = PTL.getInnerLoc();
2440    else if (auto ATL = Cur.getAs<AttributedTypeLoc>())
2441      Cur = ATL.getModifiedLoc();
2442    else if (auto ETL = Cur.getAs<ElaboratedTypeLoc>())
2443      Cur = ETL.getNamedTypeLoc();
2444    else if (auto ATL = Cur.getAs<AdjustedTypeLoc>())
2445      Cur = ATL.getOriginalLoc();
2446    else if (auto MQL = Cur.getAs<MacroQualifiedTypeLoc>())
2447      Cur = MQL.getInnerLoc();
2448    else
2449      break;
2450  }
2451  return Cur.getAs<T>();
2452}
2453
2454} // namespace clang
2455
2456#endif // LLVM_CLANG_AST_TYPELOC_H
2457