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::makeArrayRef(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::makeArrayRef(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::makeArrayRef(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()->getNumArgs();
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()->getArg(i), getArgLocInfo(i));
1650   }
1651 
1652   SourceLocation getTemplateNameLoc() const {
1653     return getLocalData()->NameLoc;
1654   }
1655 
1656   void setTemplateNameLoc(SourceLocation Loc) {
1657     getLocalData()->NameLoc = Loc;
1658   }
1659 
1660   /// - Copy the location information from the given info.
1661   void copy(TemplateSpecializationTypeLoc Loc) {
1662     unsigned size = getFullDataSize();
1663     assert(size == Loc.getFullDataSize());
1664 
1665     // We're potentially copying Expr references here.  We don't
1666     // bother retaining them because TypeSourceInfos live forever, so
1667     // as long as the Expr was retained when originally written into
1668     // the TypeLoc, we're okay.
1669     memcpy(Data, Loc.Data, size);
1670   }
1671 
1672   SourceRange getLocalSourceRange() const {
1673     if (getTemplateKeywordLoc().isValid())
1674       return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1675     else
1676       return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1677   }
1678 
1679   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1680     setTemplateKeywordLoc(Loc);
1681     setTemplateNameLoc(Loc);
1682     setLAngleLoc(Loc);
1683     setRAngleLoc(Loc);
1684     initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
1685                       getArgInfos(), Loc);
1686   }
1687 
1688   static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
1689                                 const TemplateArgument *Args,
1690                                 TemplateArgumentLocInfo *ArgInfos,
1691                                 SourceLocation Loc);
1692 
1693   unsigned getExtraLocalDataSize() const {
1694     return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1695   }
1696 
1697   unsigned getExtraLocalDataAlignment() const {
1698     return alignof(TemplateArgumentLocInfo);
1699   }
1700 
1701 private:
1702   TemplateArgumentLocInfo *getArgInfos() const {
1703     return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1704   }
1705 };
1706 
1707 struct DependentAddressSpaceLocInfo {
1708   Expr *ExprOperand;
1709   SourceRange OperandParens;
1710   SourceLocation AttrLoc;
1711 };
1712 
1713 class DependentAddressSpaceTypeLoc
1714     : public ConcreteTypeLoc<UnqualTypeLoc,
1715                              DependentAddressSpaceTypeLoc,
1716                              DependentAddressSpaceType,
1717                              DependentAddressSpaceLocInfo> {
1718 public:
1719   /// The location of the attribute name, i.e.
1720   ///    int * __attribute__((address_space(11)))
1721   ///                         ^~~~~~~~~~~~~
1722   SourceLocation getAttrNameLoc() const {
1723     return getLocalData()->AttrLoc;
1724   }
1725   void setAttrNameLoc(SourceLocation loc) {
1726     getLocalData()->AttrLoc = loc;
1727   }
1728 
1729   /// The attribute's expression operand, if it has one.
1730   ///    int * __attribute__((address_space(11)))
1731   ///                                       ^~
1732   Expr *getAttrExprOperand() const {
1733     return getLocalData()->ExprOperand;
1734   }
1735   void setAttrExprOperand(Expr *e) {
1736     getLocalData()->ExprOperand = e;
1737   }
1738 
1739   /// The location of the parentheses around the operand, if there is
1740   /// an operand.
1741   ///    int * __attribute__((address_space(11)))
1742   ///                                      ^  ^
1743   SourceRange getAttrOperandParensRange() const {
1744     return getLocalData()->OperandParens;
1745   }
1746   void setAttrOperandParensRange(SourceRange range) {
1747     getLocalData()->OperandParens = range;
1748   }
1749 
1750   SourceRange getLocalSourceRange() const {
1751     SourceRange range(getAttrNameLoc());
1752     range.setEnd(getAttrOperandParensRange().getEnd());
1753     return range;
1754   }
1755 
1756   ///  Returns the type before the address space attribute application
1757   ///  area.
1758   ///    int * __attribute__((address_space(11))) *
1759   ///    ^   ^
1760   QualType getInnerType() const {
1761     return this->getTypePtr()->getPointeeType();
1762   }
1763 
1764   TypeLoc getPointeeTypeLoc() const {
1765     return this->getInnerTypeLoc();
1766   }
1767 
1768   void initializeLocal(ASTContext &Context, SourceLocation loc) {
1769     setAttrNameLoc(loc);
1770     setAttrOperandParensRange(loc);
1771     setAttrOperandParensRange(SourceRange(loc));
1772     setAttrExprOperand(getTypePtr()->getAddrSpaceExpr());
1773   }
1774 };
1775 
1776 //===----------------------------------------------------------------------===//
1777 //
1778 //  All of these need proper implementations.
1779 //
1780 //===----------------------------------------------------------------------===//
1781 
1782 // FIXME: size expression and attribute locations (or keyword if we
1783 // ever fully support altivec syntax).
1784 struct VectorTypeLocInfo {
1785   SourceLocation NameLoc;
1786 };
1787 
1788 class VectorTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, VectorTypeLoc,
1789                                              VectorType, VectorTypeLocInfo> {
1790 public:
1791   SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; }
1792 
1793   void setNameLoc(SourceLocation Loc) { this->getLocalData()->NameLoc = Loc; }
1794 
1795   SourceRange getLocalSourceRange() const {
1796     return SourceRange(getNameLoc(), getNameLoc());
1797   }
1798 
1799   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1800     setNameLoc(Loc);
1801   }
1802 
1803   TypeLoc getElementLoc() const { return getInnerTypeLoc(); }
1804 
1805   QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
1806 };
1807 
1808 // FIXME: size expression and attribute locations (or keyword if we
1809 // ever fully support altivec syntax).
1810 class DependentVectorTypeLoc
1811     : public ConcreteTypeLoc<UnqualTypeLoc, DependentVectorTypeLoc,
1812                              DependentVectorType, VectorTypeLocInfo> {
1813 public:
1814   SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; }
1815 
1816   void setNameLoc(SourceLocation Loc) { this->getLocalData()->NameLoc = Loc; }
1817 
1818   SourceRange getLocalSourceRange() const {
1819     return SourceRange(getNameLoc(), getNameLoc());
1820   }
1821 
1822   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1823     setNameLoc(Loc);
1824   }
1825 
1826   TypeLoc getElementLoc() const { return getInnerTypeLoc(); }
1827 
1828   QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
1829 };
1830 
1831 // FIXME: size expression and attribute locations.
1832 class ExtVectorTypeLoc
1833     : public InheritingConcreteTypeLoc<VectorTypeLoc, ExtVectorTypeLoc,
1834                                        ExtVectorType> {};
1835 
1836 // FIXME: attribute locations.
1837 // For some reason, this isn't a subtype of VectorType.
1838 class DependentSizedExtVectorTypeLoc
1839     : public ConcreteTypeLoc<UnqualTypeLoc, DependentSizedExtVectorTypeLoc,
1840                              DependentSizedExtVectorType, VectorTypeLocInfo> {
1841 public:
1842   SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; }
1843 
1844   void setNameLoc(SourceLocation Loc) { this->getLocalData()->NameLoc = Loc; }
1845 
1846   SourceRange getLocalSourceRange() const {
1847     return SourceRange(getNameLoc(), getNameLoc());
1848   }
1849 
1850   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1851     setNameLoc(Loc);
1852   }
1853 
1854   TypeLoc getElementLoc() const { return getInnerTypeLoc(); }
1855 
1856   QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
1857 };
1858 
1859 struct MatrixTypeLocInfo {
1860   SourceLocation AttrLoc;
1861   SourceRange OperandParens;
1862   Expr *RowOperand;
1863   Expr *ColumnOperand;
1864 };
1865 
1866 class MatrixTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, MatrixTypeLoc,
1867                                              MatrixType, MatrixTypeLocInfo> {
1868 public:
1869   /// The location of the attribute name, i.e.
1870   ///    float __attribute__((matrix_type(4, 2)))
1871   ///                         ^~~~~~~~~~~~~~~~~
1872   SourceLocation getAttrNameLoc() const { return getLocalData()->AttrLoc; }
1873   void setAttrNameLoc(SourceLocation loc) { getLocalData()->AttrLoc = loc; }
1874 
1875   /// The attribute's row operand, if it has one.
1876   ///    float __attribute__((matrix_type(4, 2)))
1877   ///                                     ^
1878   Expr *getAttrRowOperand() const { return getLocalData()->RowOperand; }
1879   void setAttrRowOperand(Expr *e) { getLocalData()->RowOperand = e; }
1880 
1881   /// The attribute's column operand, if it has one.
1882   ///    float __attribute__((matrix_type(4, 2)))
1883   ///                                        ^
1884   Expr *getAttrColumnOperand() const { return getLocalData()->ColumnOperand; }
1885   void setAttrColumnOperand(Expr *e) { getLocalData()->ColumnOperand = e; }
1886 
1887   /// The location of the parentheses around the operand, if there is
1888   /// an operand.
1889   ///    float __attribute__((matrix_type(4, 2)))
1890   ///                                    ^    ^
1891   SourceRange getAttrOperandParensRange() const {
1892     return getLocalData()->OperandParens;
1893   }
1894   void setAttrOperandParensRange(SourceRange range) {
1895     getLocalData()->OperandParens = range;
1896   }
1897 
1898   SourceRange getLocalSourceRange() const {
1899     SourceRange range(getAttrNameLoc());
1900     range.setEnd(getAttrOperandParensRange().getEnd());
1901     return range;
1902   }
1903 
1904   void initializeLocal(ASTContext &Context, SourceLocation loc) {
1905     setAttrNameLoc(loc);
1906     setAttrOperandParensRange(loc);
1907     setAttrRowOperand(nullptr);
1908     setAttrColumnOperand(nullptr);
1909   }
1910 };
1911 
1912 class ConstantMatrixTypeLoc
1913     : public InheritingConcreteTypeLoc<MatrixTypeLoc, ConstantMatrixTypeLoc,
1914                                        ConstantMatrixType> {};
1915 
1916 class DependentSizedMatrixTypeLoc
1917     : public InheritingConcreteTypeLoc<MatrixTypeLoc,
1918                                        DependentSizedMatrixTypeLoc,
1919                                        DependentSizedMatrixType> {};
1920 
1921 // FIXME: location of the '_Complex' keyword.
1922 class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1923                                                         ComplexTypeLoc,
1924                                                         ComplexType> {
1925 };
1926 
1927 struct TypeofLocInfo {
1928   SourceLocation TypeofLoc;
1929   SourceLocation LParenLoc;
1930   SourceLocation RParenLoc;
1931 };
1932 
1933 struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
1934 };
1935 
1936 struct TypeOfTypeLocInfo : public TypeofLocInfo {
1937   TypeSourceInfo* UnderlyingTInfo;
1938 };
1939 
1940 template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
1941 class TypeofLikeTypeLoc
1942   : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
1943 public:
1944   SourceLocation getTypeofLoc() const {
1945     return this->getLocalData()->TypeofLoc;
1946   }
1947 
1948   void setTypeofLoc(SourceLocation Loc) {
1949     this->getLocalData()->TypeofLoc = Loc;
1950   }
1951 
1952   SourceLocation getLParenLoc() const {
1953     return this->getLocalData()->LParenLoc;
1954   }
1955 
1956   void setLParenLoc(SourceLocation Loc) {
1957     this->getLocalData()->LParenLoc = Loc;
1958   }
1959 
1960   SourceLocation getRParenLoc() const {
1961     return this->getLocalData()->RParenLoc;
1962   }
1963 
1964   void setRParenLoc(SourceLocation Loc) {
1965     this->getLocalData()->RParenLoc = Loc;
1966   }
1967 
1968   SourceRange getParensRange() const {
1969     return SourceRange(getLParenLoc(), getRParenLoc());
1970   }
1971 
1972   void setParensRange(SourceRange range) {
1973       setLParenLoc(range.getBegin());
1974       setRParenLoc(range.getEnd());
1975   }
1976 
1977   SourceRange getLocalSourceRange() const {
1978     return SourceRange(getTypeofLoc(), getRParenLoc());
1979   }
1980 
1981   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1982     setTypeofLoc(Loc);
1983     setLParenLoc(Loc);
1984     setRParenLoc(Loc);
1985   }
1986 };
1987 
1988 class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
1989                                                    TypeOfExprType,
1990                                                    TypeOfExprTypeLocInfo> {
1991 public:
1992   Expr* getUnderlyingExpr() const {
1993     return getTypePtr()->getUnderlyingExpr();
1994   }
1995 
1996   // Reimplemented to account for GNU/C++ extension
1997   //     typeof unary-expression
1998   // where there are no parentheses.
1999   SourceRange getLocalSourceRange() const;
2000 };
2001 
2002 class TypeOfTypeLoc
2003   : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
2004 public:
2005   QualType getUnderlyingType() const {
2006     return this->getTypePtr()->getUnderlyingType();
2007   }
2008 
2009   TypeSourceInfo* getUnderlyingTInfo() const {
2010     return this->getLocalData()->UnderlyingTInfo;
2011   }
2012 
2013   void setUnderlyingTInfo(TypeSourceInfo* TI) const {
2014     this->getLocalData()->UnderlyingTInfo = TI;
2015   }
2016 
2017   void initializeLocal(ASTContext &Context, SourceLocation Loc);
2018 };
2019 
2020 // decltype(expression) abc;
2021 // ~~~~~~~~                  DecltypeLoc
2022 //                    ~      RParenLoc
2023 // FIXME: add LParenLoc, it is tricky to support due to the limitation of
2024 // annotated-decltype token.
2025 struct DecltypeTypeLocInfo {
2026   SourceLocation DecltypeLoc;
2027   SourceLocation RParenLoc;
2028 };
2029 class DecltypeTypeLoc
2030     : public ConcreteTypeLoc<UnqualTypeLoc, DecltypeTypeLoc, DecltypeType,
2031                              DecltypeTypeLocInfo> {
2032 public:
2033   Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
2034 
2035   SourceLocation getDecltypeLoc() const { return getLocalData()->DecltypeLoc; }
2036   void setDecltypeLoc(SourceLocation Loc) { getLocalData()->DecltypeLoc = Loc; }
2037 
2038   SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
2039   void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
2040 
2041   SourceRange getLocalSourceRange() const {
2042     return SourceRange(getDecltypeLoc(), getRParenLoc());
2043   }
2044 
2045   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2046     setDecltypeLoc(Loc);
2047     setRParenLoc(Loc);
2048   }
2049 };
2050 
2051 struct UnaryTransformTypeLocInfo {
2052   // FIXME: While there's only one unary transform right now, future ones may
2053   // need different representations
2054   SourceLocation KWLoc, LParenLoc, RParenLoc;
2055   TypeSourceInfo *UnderlyingTInfo;
2056 };
2057 
2058 class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
2059                                                     UnaryTransformTypeLoc,
2060                                                     UnaryTransformType,
2061                                                     UnaryTransformTypeLocInfo> {
2062 public:
2063   SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
2064   void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
2065 
2066   SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
2067   void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
2068 
2069   SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
2070   void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
2071 
2072   TypeSourceInfo* getUnderlyingTInfo() const {
2073     return getLocalData()->UnderlyingTInfo;
2074   }
2075 
2076   void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
2077     getLocalData()->UnderlyingTInfo = TInfo;
2078   }
2079 
2080   SourceRange getLocalSourceRange() const {
2081     return SourceRange(getKWLoc(), getRParenLoc());
2082   }
2083 
2084   SourceRange getParensRange() const {
2085     return SourceRange(getLParenLoc(), getRParenLoc());
2086   }
2087 
2088   void setParensRange(SourceRange Range) {
2089     setLParenLoc(Range.getBegin());
2090     setRParenLoc(Range.getEnd());
2091   }
2092 
2093   void initializeLocal(ASTContext &Context, SourceLocation Loc);
2094 };
2095 
2096 class DeducedTypeLoc
2097     : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DeducedTypeLoc,
2098                                        DeducedType> {};
2099 
2100 struct AutoTypeLocInfo : TypeSpecLocInfo {
2101   NestedNameSpecifierLoc NestedNameSpec;
2102   SourceLocation TemplateKWLoc;
2103   SourceLocation ConceptNameLoc;
2104   NamedDecl *FoundDecl;
2105   SourceLocation LAngleLoc;
2106   SourceLocation RAngleLoc;
2107 
2108   // For decltype(auto).
2109   SourceLocation RParenLoc;
2110 
2111   // Followed by a TemplateArgumentLocInfo[]
2112 };
2113 
2114 class AutoTypeLoc
2115     : public ConcreteTypeLoc<DeducedTypeLoc,
2116                              AutoTypeLoc,
2117                              AutoType,
2118                              AutoTypeLocInfo> {
2119 public:
2120   AutoTypeKeyword getAutoKeyword() const {
2121     return getTypePtr()->getKeyword();
2122   }
2123 
2124   bool isDecltypeAuto() const { return getTypePtr()->isDecltypeAuto(); }
2125   SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
2126   void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
2127 
2128   bool isConstrained() const {
2129     return getTypePtr()->isConstrained();
2130   }
2131 
2132   const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
2133     return getLocalData()->NestedNameSpec;
2134   }
2135 
2136   void setNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
2137     getLocalData()->NestedNameSpec = NNS;
2138   }
2139 
2140   SourceLocation getTemplateKWLoc() const {
2141     return getLocalData()->TemplateKWLoc;
2142   }
2143 
2144   void setTemplateKWLoc(SourceLocation Loc) {
2145     getLocalData()->TemplateKWLoc = Loc;
2146   }
2147 
2148   SourceLocation getConceptNameLoc() const {
2149     return getLocalData()->ConceptNameLoc;
2150   }
2151 
2152   void setConceptNameLoc(SourceLocation Loc) {
2153     getLocalData()->ConceptNameLoc = Loc;
2154   }
2155 
2156   NamedDecl *getFoundDecl() const {
2157     return getLocalData()->FoundDecl;
2158   }
2159 
2160   void setFoundDecl(NamedDecl *D) {
2161     getLocalData()->FoundDecl = D;
2162   }
2163 
2164   ConceptDecl *getNamedConcept() const {
2165     return getTypePtr()->getTypeConstraintConcept();
2166   }
2167 
2168   DeclarationNameInfo getConceptNameInfo() const;
2169 
2170   bool hasExplicitTemplateArgs() const {
2171     return getLocalData()->LAngleLoc.isValid();
2172   }
2173 
2174   SourceLocation getLAngleLoc() const {
2175     return this->getLocalData()->LAngleLoc;
2176   }
2177 
2178   void setLAngleLoc(SourceLocation Loc) {
2179     this->getLocalData()->LAngleLoc = Loc;
2180   }
2181 
2182   SourceLocation getRAngleLoc() const {
2183     return this->getLocalData()->RAngleLoc;
2184   }
2185 
2186   void setRAngleLoc(SourceLocation Loc) {
2187     this->getLocalData()->RAngleLoc = Loc;
2188   }
2189 
2190   unsigned getNumArgs() const {
2191     return getTypePtr()->getNumArgs();
2192   }
2193 
2194   void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
2195     getArgInfos()[i] = AI;
2196   }
2197 
2198   TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
2199     return getArgInfos()[i];
2200   }
2201 
2202   TemplateArgumentLoc getArgLoc(unsigned i) const {
2203     return TemplateArgumentLoc(getTypePtr()->getTypeConstraintArguments()[i],
2204                                getArgLocInfo(i));
2205   }
2206 
2207   SourceRange getLocalSourceRange() const {
2208     return {isConstrained()
2209                 ? (getNestedNameSpecifierLoc()
2210                        ? getNestedNameSpecifierLoc().getBeginLoc()
2211                        : (getTemplateKWLoc().isValid() ? getTemplateKWLoc()
2212                                                        : getConceptNameLoc()))
2213                 : getNameLoc(),
2214             isDecltypeAuto() ? getRParenLoc() : getNameLoc()};
2215   }
2216 
2217   void copy(AutoTypeLoc Loc) {
2218     unsigned size = getFullDataSize();
2219     assert(size == Loc.getFullDataSize());
2220     memcpy(Data, Loc.Data, size);
2221   }
2222 
2223   void initializeLocal(ASTContext &Context, SourceLocation Loc);
2224 
2225   unsigned getExtraLocalDataSize() const {
2226     return getNumArgs() * sizeof(TemplateArgumentLocInfo);
2227   }
2228 
2229   unsigned getExtraLocalDataAlignment() const {
2230     return alignof(TemplateArgumentLocInfo);
2231   }
2232 
2233 private:
2234   TemplateArgumentLocInfo *getArgInfos() const {
2235     return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
2236   }
2237 };
2238 
2239 class DeducedTemplateSpecializationTypeLoc
2240     : public InheritingConcreteTypeLoc<DeducedTypeLoc,
2241                                        DeducedTemplateSpecializationTypeLoc,
2242                                        DeducedTemplateSpecializationType> {
2243 public:
2244   SourceLocation getTemplateNameLoc() const {
2245     return getNameLoc();
2246   }
2247 
2248   void setTemplateNameLoc(SourceLocation Loc) {
2249     setNameLoc(Loc);
2250   }
2251 };
2252 
2253 struct ElaboratedLocInfo {
2254   SourceLocation ElaboratedKWLoc;
2255 
2256   /// Data associated with the nested-name-specifier location.
2257   void *QualifierData;
2258 };
2259 
2260 class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
2261                                                  ElaboratedTypeLoc,
2262                                                  ElaboratedType,
2263                                                  ElaboratedLocInfo> {
2264 public:
2265   SourceLocation getElaboratedKeywordLoc() const {
2266     return this->getLocalData()->ElaboratedKWLoc;
2267   }
2268 
2269   void setElaboratedKeywordLoc(SourceLocation Loc) {
2270     this->getLocalData()->ElaboratedKWLoc = Loc;
2271   }
2272 
2273   NestedNameSpecifierLoc getQualifierLoc() const {
2274     return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
2275                                   getLocalData()->QualifierData);
2276   }
2277 
2278   void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
2279     assert(QualifierLoc.getNestedNameSpecifier()
2280                                             == getTypePtr()->getQualifier() &&
2281            "Inconsistent nested-name-specifier pointer");
2282     getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
2283   }
2284 
2285   SourceRange getLocalSourceRange() const {
2286     if (getElaboratedKeywordLoc().isValid())
2287       if (getQualifierLoc())
2288         return SourceRange(getElaboratedKeywordLoc(),
2289                            getQualifierLoc().getEndLoc());
2290       else
2291         return SourceRange(getElaboratedKeywordLoc());
2292     else
2293       return getQualifierLoc().getSourceRange();
2294   }
2295 
2296   void initializeLocal(ASTContext &Context, SourceLocation Loc);
2297 
2298   TypeLoc getNamedTypeLoc() const {
2299     return getInnerTypeLoc();
2300   }
2301 
2302   QualType getInnerType() const {
2303     return getTypePtr()->getNamedType();
2304   }
2305 
2306   void copy(ElaboratedTypeLoc Loc) {
2307     unsigned size = getFullDataSize();
2308     assert(size == Loc.getFullDataSize());
2309     memcpy(Data, Loc.Data, size);
2310   }
2311 };
2312 
2313 // This is exactly the structure of an ElaboratedTypeLoc whose inner
2314 // type is some sort of TypeDeclTypeLoc.
2315 struct DependentNameLocInfo : ElaboratedLocInfo {
2316   SourceLocation NameLoc;
2317 };
2318 
2319 class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
2320                                                     DependentNameTypeLoc,
2321                                                     DependentNameType,
2322                                                     DependentNameLocInfo> {
2323 public:
2324   SourceLocation getElaboratedKeywordLoc() const {
2325     return this->getLocalData()->ElaboratedKWLoc;
2326   }
2327 
2328   void setElaboratedKeywordLoc(SourceLocation Loc) {
2329     this->getLocalData()->ElaboratedKWLoc = Loc;
2330   }
2331 
2332   NestedNameSpecifierLoc getQualifierLoc() const {
2333     return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
2334                                   getLocalData()->QualifierData);
2335   }
2336 
2337   void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
2338     assert(QualifierLoc.getNestedNameSpecifier()
2339                                             == getTypePtr()->getQualifier() &&
2340            "Inconsistent nested-name-specifier pointer");
2341     getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
2342   }
2343 
2344   SourceLocation getNameLoc() const {
2345     return this->getLocalData()->NameLoc;
2346   }
2347 
2348   void setNameLoc(SourceLocation Loc) {
2349     this->getLocalData()->NameLoc = Loc;
2350   }
2351 
2352   SourceRange getLocalSourceRange() const {
2353     if (getElaboratedKeywordLoc().isValid())
2354       return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
2355     else
2356       return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
2357   }
2358 
2359   void copy(DependentNameTypeLoc Loc) {
2360     unsigned size = getFullDataSize();
2361     assert(size == Loc.getFullDataSize());
2362     memcpy(Data, Loc.Data, size);
2363   }
2364 
2365   void initializeLocal(ASTContext &Context, SourceLocation Loc);
2366 };
2367 
2368 struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
2369   SourceLocation TemplateKWLoc;
2370   SourceLocation LAngleLoc;
2371   SourceLocation RAngleLoc;
2372   // followed by a TemplateArgumentLocInfo[]
2373 };
2374 
2375 class DependentTemplateSpecializationTypeLoc :
2376     public ConcreteTypeLoc<UnqualTypeLoc,
2377                            DependentTemplateSpecializationTypeLoc,
2378                            DependentTemplateSpecializationType,
2379                            DependentTemplateSpecializationLocInfo> {
2380 public:
2381   SourceLocation getElaboratedKeywordLoc() const {
2382     return this->getLocalData()->ElaboratedKWLoc;
2383   }
2384 
2385   void setElaboratedKeywordLoc(SourceLocation Loc) {
2386     this->getLocalData()->ElaboratedKWLoc = Loc;
2387   }
2388 
2389   NestedNameSpecifierLoc getQualifierLoc() const {
2390     if (!getLocalData()->QualifierData)
2391       return NestedNameSpecifierLoc();
2392 
2393     return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
2394                                   getLocalData()->QualifierData);
2395   }
2396 
2397   void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
2398     if (!QualifierLoc) {
2399       // Even if we have a nested-name-specifier in the dependent
2400       // template specialization type, we won't record the nested-name-specifier
2401       // location information when this type-source location information is
2402       // part of a nested-name-specifier.
2403       getLocalData()->QualifierData = nullptr;
2404       return;
2405     }
2406 
2407     assert(QualifierLoc.getNestedNameSpecifier()
2408                                         == getTypePtr()->getQualifier() &&
2409            "Inconsistent nested-name-specifier pointer");
2410     getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
2411   }
2412 
2413   SourceLocation getTemplateKeywordLoc() const {
2414     return getLocalData()->TemplateKWLoc;
2415   }
2416 
2417   void setTemplateKeywordLoc(SourceLocation Loc) {
2418     getLocalData()->TemplateKWLoc = Loc;
2419   }
2420 
2421   SourceLocation getTemplateNameLoc() const {
2422     return this->getLocalData()->NameLoc;
2423   }
2424 
2425   void setTemplateNameLoc(SourceLocation Loc) {
2426     this->getLocalData()->NameLoc = Loc;
2427   }
2428 
2429   SourceLocation getLAngleLoc() const {
2430     return this->getLocalData()->LAngleLoc;
2431   }
2432 
2433   void setLAngleLoc(SourceLocation Loc) {
2434     this->getLocalData()->LAngleLoc = Loc;
2435   }
2436 
2437   SourceLocation getRAngleLoc() const {
2438     return this->getLocalData()->RAngleLoc;
2439   }
2440 
2441   void setRAngleLoc(SourceLocation Loc) {
2442     this->getLocalData()->RAngleLoc = Loc;
2443   }
2444 
2445   unsigned getNumArgs() const {
2446     return getTypePtr()->getNumArgs();
2447   }
2448 
2449   void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
2450     getArgInfos()[i] = AI;
2451   }
2452 
2453   TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
2454     return getArgInfos()[i];
2455   }
2456 
2457   TemplateArgumentLoc getArgLoc(unsigned i) const {
2458     return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
2459   }
2460 
2461   SourceRange getLocalSourceRange() const {
2462     if (getElaboratedKeywordLoc().isValid())
2463       return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
2464     else if (getQualifierLoc())
2465       return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
2466     else if (getTemplateKeywordLoc().isValid())
2467       return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
2468     else
2469       return SourceRange(getTemplateNameLoc(), getRAngleLoc());
2470   }
2471 
2472   void copy(DependentTemplateSpecializationTypeLoc Loc) {
2473     unsigned size = getFullDataSize();
2474     assert(size == Loc.getFullDataSize());
2475     memcpy(Data, Loc.Data, size);
2476   }
2477 
2478   void initializeLocal(ASTContext &Context, SourceLocation Loc);
2479 
2480   unsigned getExtraLocalDataSize() const {
2481     return getNumArgs() * sizeof(TemplateArgumentLocInfo);
2482   }
2483 
2484   unsigned getExtraLocalDataAlignment() const {
2485     return alignof(TemplateArgumentLocInfo);
2486   }
2487 
2488 private:
2489   TemplateArgumentLocInfo *getArgInfos() const {
2490     return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
2491   }
2492 };
2493 
2494 struct PackExpansionTypeLocInfo {
2495   SourceLocation EllipsisLoc;
2496 };
2497 
2498 class PackExpansionTypeLoc
2499   : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
2500                            PackExpansionType, PackExpansionTypeLocInfo> {
2501 public:
2502   SourceLocation getEllipsisLoc() const {
2503     return this->getLocalData()->EllipsisLoc;
2504   }
2505 
2506   void setEllipsisLoc(SourceLocation Loc) {
2507     this->getLocalData()->EllipsisLoc = Loc;
2508   }
2509 
2510   SourceRange getLocalSourceRange() const {
2511     return SourceRange(getEllipsisLoc(), getEllipsisLoc());
2512   }
2513 
2514   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2515     setEllipsisLoc(Loc);
2516   }
2517 
2518   TypeLoc getPatternLoc() const {
2519     return getInnerTypeLoc();
2520   }
2521 
2522   QualType getInnerType() const {
2523     return this->getTypePtr()->getPattern();
2524   }
2525 };
2526 
2527 struct AtomicTypeLocInfo {
2528   SourceLocation KWLoc, LParenLoc, RParenLoc;
2529 };
2530 
2531 class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
2532                                              AtomicType, AtomicTypeLocInfo> {
2533 public:
2534   TypeLoc getValueLoc() const {
2535     return this->getInnerTypeLoc();
2536   }
2537 
2538   SourceRange getLocalSourceRange() const {
2539     return SourceRange(getKWLoc(), getRParenLoc());
2540   }
2541 
2542   SourceLocation getKWLoc() const {
2543     return this->getLocalData()->KWLoc;
2544   }
2545 
2546   void setKWLoc(SourceLocation Loc) {
2547     this->getLocalData()->KWLoc = Loc;
2548   }
2549 
2550   SourceLocation getLParenLoc() const {
2551     return this->getLocalData()->LParenLoc;
2552   }
2553 
2554   void setLParenLoc(SourceLocation Loc) {
2555     this->getLocalData()->LParenLoc = Loc;
2556   }
2557 
2558   SourceLocation getRParenLoc() const {
2559     return this->getLocalData()->RParenLoc;
2560   }
2561 
2562   void setRParenLoc(SourceLocation Loc) {
2563     this->getLocalData()->RParenLoc = Loc;
2564   }
2565 
2566   SourceRange getParensRange() const {
2567     return SourceRange(getLParenLoc(), getRParenLoc());
2568   }
2569 
2570   void setParensRange(SourceRange Range) {
2571     setLParenLoc(Range.getBegin());
2572     setRParenLoc(Range.getEnd());
2573   }
2574 
2575   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2576     setKWLoc(Loc);
2577     setLParenLoc(Loc);
2578     setRParenLoc(Loc);
2579   }
2580 
2581   QualType getInnerType() const {
2582     return this->getTypePtr()->getValueType();
2583   }
2584 };
2585 
2586 struct PipeTypeLocInfo {
2587   SourceLocation KWLoc;
2588 };
2589 
2590 class PipeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, PipeTypeLoc, PipeType,
2591                                            PipeTypeLocInfo> {
2592 public:
2593   TypeLoc getValueLoc() const { return this->getInnerTypeLoc(); }
2594 
2595   SourceRange getLocalSourceRange() const { return SourceRange(getKWLoc()); }
2596 
2597   SourceLocation getKWLoc() const { return this->getLocalData()->KWLoc; }
2598   void setKWLoc(SourceLocation Loc) { this->getLocalData()->KWLoc = Loc; }
2599 
2600   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2601     setKWLoc(Loc);
2602   }
2603 
2604   QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
2605 };
2606 
2607 template <typename T>
2608 inline T TypeLoc::getAsAdjusted() const {
2609   TypeLoc Cur = *this;
2610   while (!T::isKind(Cur)) {
2611     if (auto PTL = Cur.getAs<ParenTypeLoc>())
2612       Cur = PTL.getInnerLoc();
2613     else if (auto ATL = Cur.getAs<AttributedTypeLoc>())
2614       Cur = ATL.getModifiedLoc();
2615     else if (auto ATL = Cur.getAs<BTFTagAttributedTypeLoc>())
2616       Cur = ATL.getWrappedLoc();
2617     else if (auto ETL = Cur.getAs<ElaboratedTypeLoc>())
2618       Cur = ETL.getNamedTypeLoc();
2619     else if (auto ATL = Cur.getAs<AdjustedTypeLoc>())
2620       Cur = ATL.getOriginalLoc();
2621     else if (auto MQL = Cur.getAs<MacroQualifiedTypeLoc>())
2622       Cur = MQL.getInnerLoc();
2623     else
2624       break;
2625   }
2626   return Cur.getAs<T>();
2627 }
2628 class BitIntTypeLoc final
2629     : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, BitIntTypeLoc,
2630                                        BitIntType> {};
2631 class DependentBitIntTypeLoc final
2632     : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DependentBitIntTypeLoc,
2633                                        DependentBitIntType> {};
2634 
2635 class ObjCProtocolLoc {
2636   ObjCProtocolDecl *Protocol = nullptr;
2637   SourceLocation Loc = SourceLocation();
2638 
2639 public:
2640   ObjCProtocolLoc(ObjCProtocolDecl *protocol, SourceLocation loc)
2641       : Protocol(protocol), Loc(loc) {}
2642   ObjCProtocolDecl *getProtocol() const { return Protocol; }
2643   SourceLocation getLocation() const { return Loc; }
2644 
2645   /// The source range is just the protocol name.
2646   SourceRange getSourceRange() const LLVM_READONLY {
2647     return SourceRange(Loc, Loc);
2648   }
2649 };
2650 
2651 } // namespace clang
2652 
2653 #endif // LLVM_CLANG_AST_TYPELOC_H
2654