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