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