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