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