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 ObjCObjectTypeLocInfo {
905   SourceLocation TypeArgsLAngleLoc;
906   SourceLocation TypeArgsRAngleLoc;
907   SourceLocation ProtocolLAngleLoc;
908   SourceLocation ProtocolRAngleLoc;
909   bool HasBaseTypeAsWritten;
910 };
911 
912 // A helper class for defining ObjC TypeLocs that can qualified with
913 // protocols.
914 //
915 // TypeClass basically has to be either ObjCInterfaceType or
916 // ObjCObjectPointerType.
917 class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
918                                                  ObjCObjectTypeLoc,
919                                                  ObjCObjectType,
920                                                  ObjCObjectTypeLocInfo> {
921   // TypeSourceInfo*'s are stored after Info, one for each type argument.
922   TypeSourceInfo **getTypeArgLocArray() const {
923     return (TypeSourceInfo**)this->getExtraLocalData();
924   }
925 
926   // SourceLocations are stored after the type argument information, one for
927   // each Protocol.
928   SourceLocation *getProtocolLocArray() const {
929     return (SourceLocation*)(getTypeArgLocArray() + getNumTypeArgs());
930   }
931 
932 public:
933   SourceLocation getTypeArgsLAngleLoc() const {
934     return this->getLocalData()->TypeArgsLAngleLoc;
935   }
936 
937   void setTypeArgsLAngleLoc(SourceLocation Loc) {
938     this->getLocalData()->TypeArgsLAngleLoc = Loc;
939   }
940 
941   SourceLocation getTypeArgsRAngleLoc() const {
942     return this->getLocalData()->TypeArgsRAngleLoc;
943   }
944 
945   void setTypeArgsRAngleLoc(SourceLocation Loc) {
946     this->getLocalData()->TypeArgsRAngleLoc = Loc;
947   }
948 
949   unsigned getNumTypeArgs() const {
950     return this->getTypePtr()->getTypeArgsAsWritten().size();
951   }
952 
953   TypeSourceInfo *getTypeArgTInfo(unsigned i) const {
954     assert(i < getNumTypeArgs() && "Index is out of bounds!");
955     return getTypeArgLocArray()[i];
956   }
957 
958   void setTypeArgTInfo(unsigned i, TypeSourceInfo *TInfo) {
959     assert(i < getNumTypeArgs() && "Index is out of bounds!");
960     getTypeArgLocArray()[i] = TInfo;
961   }
962 
963   SourceLocation getProtocolLAngleLoc() const {
964     return this->getLocalData()->ProtocolLAngleLoc;
965   }
966 
967   void setProtocolLAngleLoc(SourceLocation Loc) {
968     this->getLocalData()->ProtocolLAngleLoc = Loc;
969   }
970 
971   SourceLocation getProtocolRAngleLoc() const {
972     return this->getLocalData()->ProtocolRAngleLoc;
973   }
974 
975   void setProtocolRAngleLoc(SourceLocation Loc) {
976     this->getLocalData()->ProtocolRAngleLoc = Loc;
977   }
978 
979   unsigned getNumProtocols() const {
980     return this->getTypePtr()->getNumProtocols();
981   }
982 
983   SourceLocation getProtocolLoc(unsigned i) const {
984     assert(i < getNumProtocols() && "Index is out of bounds!");
985     return getProtocolLocArray()[i];
986   }
987 
988   void setProtocolLoc(unsigned i, SourceLocation Loc) {
989     assert(i < getNumProtocols() && "Index is out of bounds!");
990     getProtocolLocArray()[i] = Loc;
991   }
992 
993   ObjCProtocolDecl *getProtocol(unsigned i) const {
994     assert(i < getNumProtocols() && "Index is out of bounds!");
995     return *(this->getTypePtr()->qual_begin() + i);
996   }
997 
998 
999   ArrayRef<SourceLocation> getProtocolLocs() const {
1000     return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols());
1001   }
1002 
1003   bool hasBaseTypeAsWritten() const {
1004     return getLocalData()->HasBaseTypeAsWritten;
1005   }
1006 
1007   void setHasBaseTypeAsWritten(bool HasBaseType) {
1008     getLocalData()->HasBaseTypeAsWritten = HasBaseType;
1009   }
1010 
1011   TypeLoc getBaseLoc() const {
1012     return getInnerTypeLoc();
1013   }
1014 
1015   SourceRange getLocalSourceRange() const {
1016     SourceLocation start = getTypeArgsLAngleLoc();
1017     if (start.isInvalid())
1018       start = getProtocolLAngleLoc();
1019     SourceLocation end = getProtocolRAngleLoc();
1020     if (end.isInvalid())
1021       end = getTypeArgsRAngleLoc();
1022     return SourceRange(start, end);
1023   }
1024 
1025   void initializeLocal(ASTContext &Context, SourceLocation Loc);
1026 
1027   unsigned getExtraLocalDataSize() const {
1028     return this->getNumTypeArgs() * sizeof(TypeSourceInfo *)
1029          + this->getNumProtocols() * sizeof(SourceLocation);
1030   }
1031 
1032   unsigned getExtraLocalDataAlignment() const {
1033     static_assert(alignof(ObjCObjectTypeLoc) >= alignof(TypeSourceInfo *),
1034                   "not enough alignment for tail-allocated data");
1035     return alignof(TypeSourceInfo *);
1036   }
1037 
1038   QualType getInnerType() const {
1039     return getTypePtr()->getBaseType();
1040   }
1041 };
1042 
1043 struct ObjCInterfaceLocInfo {
1044   SourceLocation NameLoc;
1045   SourceLocation NameEndLoc;
1046 };
1047 
1048 /// Wrapper for source info for ObjC interfaces.
1049 class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
1050                                                     ObjCInterfaceTypeLoc,
1051                                                     ObjCInterfaceType,
1052                                                     ObjCInterfaceLocInfo> {
1053 public:
1054   ObjCInterfaceDecl *getIFaceDecl() const {
1055     return getTypePtr()->getDecl();
1056   }
1057 
1058   SourceLocation getNameLoc() const {
1059     return getLocalData()->NameLoc;
1060   }
1061 
1062   void setNameLoc(SourceLocation Loc) {
1063     getLocalData()->NameLoc = Loc;
1064   }
1065 
1066   SourceRange getLocalSourceRange() const {
1067     return SourceRange(getNameLoc(), getNameEndLoc());
1068   }
1069 
1070   SourceLocation getNameEndLoc() const {
1071     return getLocalData()->NameEndLoc;
1072   }
1073 
1074   void setNameEndLoc(SourceLocation Loc) {
1075     getLocalData()->NameEndLoc = Loc;
1076   }
1077 
1078   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1079     setNameLoc(Loc);
1080     setNameEndLoc(Loc);
1081   }
1082 };
1083 
1084 struct MacroQualifiedLocInfo {
1085   SourceLocation ExpansionLoc;
1086 };
1087 
1088 class MacroQualifiedTypeLoc
1089     : public ConcreteTypeLoc<UnqualTypeLoc, MacroQualifiedTypeLoc,
1090                              MacroQualifiedType, MacroQualifiedLocInfo> {
1091 public:
1092   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1093     setExpansionLoc(Loc);
1094   }
1095 
1096   TypeLoc getInnerLoc() const { return getInnerTypeLoc(); }
1097 
1098   const IdentifierInfo *getMacroIdentifier() const {
1099     return getTypePtr()->getMacroIdentifier();
1100   }
1101 
1102   SourceLocation getExpansionLoc() const {
1103     return this->getLocalData()->ExpansionLoc;
1104   }
1105 
1106   void setExpansionLoc(SourceLocation Loc) {
1107     this->getLocalData()->ExpansionLoc = Loc;
1108   }
1109 
1110   QualType getInnerType() const { return getTypePtr()->getUnderlyingType(); }
1111 
1112   SourceRange getLocalSourceRange() const {
1113     return getInnerLoc().getLocalSourceRange();
1114   }
1115 };
1116 
1117 struct ParenLocInfo {
1118   SourceLocation LParenLoc;
1119   SourceLocation RParenLoc;
1120 };
1121 
1122 class ParenTypeLoc
1123   : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType,
1124                            ParenLocInfo> {
1125 public:
1126   SourceLocation getLParenLoc() const {
1127     return this->getLocalData()->LParenLoc;
1128   }
1129 
1130   SourceLocation getRParenLoc() const {
1131     return this->getLocalData()->RParenLoc;
1132   }
1133 
1134   void setLParenLoc(SourceLocation Loc) {
1135     this->getLocalData()->LParenLoc = Loc;
1136   }
1137 
1138   void setRParenLoc(SourceLocation Loc) {
1139     this->getLocalData()->RParenLoc = Loc;
1140   }
1141 
1142   SourceRange getLocalSourceRange() const {
1143     return SourceRange(getLParenLoc(), getRParenLoc());
1144   }
1145 
1146   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1147     setLParenLoc(Loc);
1148     setRParenLoc(Loc);
1149   }
1150 
1151   TypeLoc getInnerLoc() const {
1152     return getInnerTypeLoc();
1153   }
1154 
1155   QualType getInnerType() const {
1156     return this->getTypePtr()->getInnerType();
1157   }
1158 };
1159 
1160 inline TypeLoc TypeLoc::IgnoreParens() const {
1161   if (ParenTypeLoc::isKind(*this))
1162     return IgnoreParensImpl(*this);
1163   return *this;
1164 }
1165 
1166 struct AdjustedLocInfo {}; // Nothing.
1167 
1168 class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc,
1169                                                AdjustedType, AdjustedLocInfo> {
1170 public:
1171   TypeLoc getOriginalLoc() const {
1172     return getInnerTypeLoc();
1173   }
1174 
1175   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1176     // do nothing
1177   }
1178 
1179   QualType getInnerType() const {
1180     // The inner type is the undecayed type, since that's what we have source
1181     // location information for.
1182     return getTypePtr()->getOriginalType();
1183   }
1184 
1185   SourceRange getLocalSourceRange() const { return {}; }
1186 
1187   unsigned getLocalDataSize() const {
1188     // sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique
1189     // anyway.  TypeLocBuilder can't handle data sizes of 1.
1190     return 0;  // No data.
1191   }
1192 };
1193 
1194 /// Wrapper for source info for pointers decayed from arrays and
1195 /// functions.
1196 class DecayedTypeLoc : public InheritingConcreteTypeLoc<
1197                            AdjustedTypeLoc, DecayedTypeLoc, DecayedType> {
1198 };
1199 
1200 struct PointerLikeLocInfo {
1201   SourceLocation StarLoc;
1202 };
1203 
1204 /// A base class for
1205 template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
1206 class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
1207                                                   TypeClass, LocalData> {
1208 public:
1209   SourceLocation getSigilLoc() const {
1210     return this->getLocalData()->StarLoc;
1211   }
1212 
1213   void setSigilLoc(SourceLocation Loc) {
1214     this->getLocalData()->StarLoc = Loc;
1215   }
1216 
1217   TypeLoc getPointeeLoc() const {
1218     return this->getInnerTypeLoc();
1219   }
1220 
1221   SourceRange getLocalSourceRange() const {
1222     return SourceRange(getSigilLoc(), getSigilLoc());
1223   }
1224 
1225   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1226     setSigilLoc(Loc);
1227   }
1228 
1229   QualType getInnerType() const {
1230     return this->getTypePtr()->getPointeeType();
1231   }
1232 };
1233 
1234 /// Wrapper for source info for pointers.
1235 class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
1236                                                  PointerType> {
1237 public:
1238   SourceLocation getStarLoc() const {
1239     return getSigilLoc();
1240   }
1241 
1242   void setStarLoc(SourceLocation Loc) {
1243     setSigilLoc(Loc);
1244   }
1245 };
1246 
1247 /// Wrapper for source info for block pointers.
1248 class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
1249                                                       BlockPointerType> {
1250 public:
1251   SourceLocation getCaretLoc() const {
1252     return getSigilLoc();
1253   }
1254 
1255   void setCaretLoc(SourceLocation Loc) {
1256     setSigilLoc(Loc);
1257   }
1258 };
1259 
1260 struct MemberPointerLocInfo : public PointerLikeLocInfo {
1261   TypeSourceInfo *ClassTInfo;
1262 };
1263 
1264 /// Wrapper for source info for member pointers.
1265 class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
1266                                                        MemberPointerType,
1267                                                        MemberPointerLocInfo> {
1268 public:
1269   SourceLocation getStarLoc() const {
1270     return getSigilLoc();
1271   }
1272 
1273   void setStarLoc(SourceLocation Loc) {
1274     setSigilLoc(Loc);
1275   }
1276 
1277   const Type *getClass() const {
1278     return getTypePtr()->getClass();
1279   }
1280 
1281   TypeSourceInfo *getClassTInfo() const {
1282     return getLocalData()->ClassTInfo;
1283   }
1284 
1285   void setClassTInfo(TypeSourceInfo* TI) {
1286     getLocalData()->ClassTInfo = TI;
1287   }
1288 
1289   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1290     setSigilLoc(Loc);
1291     setClassTInfo(nullptr);
1292   }
1293 
1294   SourceRange getLocalSourceRange() const {
1295     if (TypeSourceInfo *TI = getClassTInfo())
1296       return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
1297     else
1298       return SourceRange(getStarLoc());
1299   }
1300 };
1301 
1302 /// Wraps an ObjCPointerType with source location information.
1303 class ObjCObjectPointerTypeLoc :
1304     public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
1305                               ObjCObjectPointerType> {
1306 public:
1307   SourceLocation getStarLoc() const {
1308     return getSigilLoc();
1309   }
1310 
1311   void setStarLoc(SourceLocation Loc) {
1312     setSigilLoc(Loc);
1313   }
1314 };
1315 
1316 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
1317                                                    ReferenceType> {
1318 public:
1319   QualType getInnerType() const {
1320     return getTypePtr()->getPointeeTypeAsWritten();
1321   }
1322 };
1323 
1324 class LValueReferenceTypeLoc :
1325     public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1326                                      LValueReferenceTypeLoc,
1327                                      LValueReferenceType> {
1328 public:
1329   SourceLocation getAmpLoc() const {
1330     return getSigilLoc();
1331   }
1332 
1333   void setAmpLoc(SourceLocation Loc) {
1334     setSigilLoc(Loc);
1335   }
1336 };
1337 
1338 class RValueReferenceTypeLoc :
1339     public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1340                                      RValueReferenceTypeLoc,
1341                                      RValueReferenceType> {
1342 public:
1343   SourceLocation getAmpAmpLoc() const {
1344     return getSigilLoc();
1345   }
1346 
1347   void setAmpAmpLoc(SourceLocation Loc) {
1348     setSigilLoc(Loc);
1349   }
1350 };
1351 
1352 struct FunctionLocInfo {
1353   SourceLocation LocalRangeBegin;
1354   SourceLocation LParenLoc;
1355   SourceLocation RParenLoc;
1356   SourceLocation LocalRangeEnd;
1357 };
1358 
1359 /// Wrapper for source info for functions.
1360 class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1361                                                FunctionTypeLoc,
1362                                                FunctionType,
1363                                                FunctionLocInfo> {
1364   bool hasExceptionSpec() const {
1365     if (auto *FPT = dyn_cast<FunctionProtoType>(getTypePtr())) {
1366       return FPT->hasExceptionSpec();
1367     }
1368     return false;
1369   }
1370 
1371   SourceRange *getExceptionSpecRangePtr() const {
1372     assert(hasExceptionSpec() && "No exception spec range");
1373     // After the Info comes the ParmVarDecl array, and after that comes the
1374     // exception specification information.
1375     return (SourceRange *)(getParmArray() + getNumParams());
1376   }
1377 
1378 public:
1379   SourceLocation getLocalRangeBegin() const {
1380     return getLocalData()->LocalRangeBegin;
1381   }
1382 
1383   void setLocalRangeBegin(SourceLocation L) {
1384     getLocalData()->LocalRangeBegin = L;
1385   }
1386 
1387   SourceLocation getLocalRangeEnd() const {
1388     return getLocalData()->LocalRangeEnd;
1389   }
1390 
1391   void setLocalRangeEnd(SourceLocation L) {
1392     getLocalData()->LocalRangeEnd = L;
1393   }
1394 
1395   SourceLocation getLParenLoc() const {
1396     return this->getLocalData()->LParenLoc;
1397   }
1398 
1399   void setLParenLoc(SourceLocation Loc) {
1400     this->getLocalData()->LParenLoc = Loc;
1401   }
1402 
1403   SourceLocation getRParenLoc() const {
1404     return this->getLocalData()->RParenLoc;
1405   }
1406 
1407   void setRParenLoc(SourceLocation Loc) {
1408     this->getLocalData()->RParenLoc = Loc;
1409   }
1410 
1411   SourceRange getParensRange() const {
1412     return SourceRange(getLParenLoc(), getRParenLoc());
1413   }
1414 
1415   SourceRange getExceptionSpecRange() const {
1416     if (hasExceptionSpec())
1417       return *getExceptionSpecRangePtr();
1418     return {};
1419   }
1420 
1421   void setExceptionSpecRange(SourceRange R) {
1422     if (hasExceptionSpec())
1423       *getExceptionSpecRangePtr() = R;
1424   }
1425 
1426   ArrayRef<ParmVarDecl *> getParams() const {
1427     return llvm::makeArrayRef(getParmArray(), getNumParams());
1428   }
1429 
1430   // ParmVarDecls* are stored after Info, one for each parameter.
1431   ParmVarDecl **getParmArray() const {
1432     return (ParmVarDecl**) getExtraLocalData();
1433   }
1434 
1435   unsigned getNumParams() const {
1436     if (isa<FunctionNoProtoType>(getTypePtr()))
1437       return 0;
1438     return cast<FunctionProtoType>(getTypePtr())->getNumParams();
1439   }
1440 
1441   ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; }
1442   void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
1443 
1444   TypeLoc getReturnLoc() const {
1445     return getInnerTypeLoc();
1446   }
1447 
1448   SourceRange getLocalSourceRange() const {
1449     return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
1450   }
1451 
1452   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1453     setLocalRangeBegin(Loc);
1454     setLParenLoc(Loc);
1455     setRParenLoc(Loc);
1456     setLocalRangeEnd(Loc);
1457     for (unsigned i = 0, e = getNumParams(); i != e; ++i)
1458       setParam(i, nullptr);
1459     if (hasExceptionSpec())
1460       setExceptionSpecRange(Loc);
1461   }
1462 
1463   /// Returns the size of the type source info data block that is
1464   /// specific to this type.
1465   unsigned getExtraLocalDataSize() const {
1466     unsigned ExceptSpecSize = hasExceptionSpec() ? sizeof(SourceRange) : 0;
1467     return (getNumParams() * sizeof(ParmVarDecl *)) + ExceptSpecSize;
1468   }
1469 
1470   unsigned getExtraLocalDataAlignment() const { return alignof(ParmVarDecl *); }
1471 
1472   QualType getInnerType() const { return getTypePtr()->getReturnType(); }
1473 };
1474 
1475 class FunctionProtoTypeLoc :
1476     public InheritingConcreteTypeLoc<FunctionTypeLoc,
1477                                      FunctionProtoTypeLoc,
1478                                      FunctionProtoType> {
1479 };
1480 
1481 class FunctionNoProtoTypeLoc :
1482     public InheritingConcreteTypeLoc<FunctionTypeLoc,
1483                                      FunctionNoProtoTypeLoc,
1484                                      FunctionNoProtoType> {
1485 };
1486 
1487 struct ArrayLocInfo {
1488   SourceLocation LBracketLoc, RBracketLoc;
1489   Expr *Size;
1490 };
1491 
1492 /// Wrapper for source info for arrays.
1493 class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1494                                             ArrayTypeLoc,
1495                                             ArrayType,
1496                                             ArrayLocInfo> {
1497 public:
1498   SourceLocation getLBracketLoc() const {
1499     return getLocalData()->LBracketLoc;
1500   }
1501 
1502   void setLBracketLoc(SourceLocation Loc) {
1503     getLocalData()->LBracketLoc = Loc;
1504   }
1505 
1506   SourceLocation getRBracketLoc() const {
1507     return getLocalData()->RBracketLoc;
1508   }
1509 
1510   void setRBracketLoc(SourceLocation Loc) {
1511     getLocalData()->RBracketLoc = Loc;
1512   }
1513 
1514   SourceRange getBracketsRange() const {
1515     return SourceRange(getLBracketLoc(), getRBracketLoc());
1516   }
1517 
1518   Expr *getSizeExpr() const {
1519     return getLocalData()->Size;
1520   }
1521 
1522   void setSizeExpr(Expr *Size) {
1523     getLocalData()->Size = Size;
1524   }
1525 
1526   TypeLoc getElementLoc() const {
1527     return getInnerTypeLoc();
1528   }
1529 
1530   SourceRange getLocalSourceRange() const {
1531     return SourceRange(getLBracketLoc(), getRBracketLoc());
1532   }
1533 
1534   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1535     setLBracketLoc(Loc);
1536     setRBracketLoc(Loc);
1537     setSizeExpr(nullptr);
1538   }
1539 
1540   QualType getInnerType() const { return getTypePtr()->getElementType(); }
1541 };
1542 
1543 class ConstantArrayTypeLoc :
1544     public InheritingConcreteTypeLoc<ArrayTypeLoc,
1545                                      ConstantArrayTypeLoc,
1546                                      ConstantArrayType> {
1547 };
1548 
1549 class IncompleteArrayTypeLoc :
1550     public InheritingConcreteTypeLoc<ArrayTypeLoc,
1551                                      IncompleteArrayTypeLoc,
1552                                      IncompleteArrayType> {
1553 };
1554 
1555 class DependentSizedArrayTypeLoc :
1556     public InheritingConcreteTypeLoc<ArrayTypeLoc,
1557                                      DependentSizedArrayTypeLoc,
1558                                      DependentSizedArrayType> {
1559 public:
1560   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1561     ArrayTypeLoc::initializeLocal(Context, Loc);
1562     setSizeExpr(getTypePtr()->getSizeExpr());
1563   }
1564 };
1565 
1566 class VariableArrayTypeLoc :
1567     public InheritingConcreteTypeLoc<ArrayTypeLoc,
1568                                      VariableArrayTypeLoc,
1569                                      VariableArrayType> {
1570 };
1571 
1572 // Location information for a TemplateName.  Rudimentary for now.
1573 struct TemplateNameLocInfo {
1574   SourceLocation NameLoc;
1575 };
1576 
1577 struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
1578   SourceLocation TemplateKWLoc;
1579   SourceLocation LAngleLoc;
1580   SourceLocation RAngleLoc;
1581 };
1582 
1583 class TemplateSpecializationTypeLoc :
1584     public ConcreteTypeLoc<UnqualTypeLoc,
1585                            TemplateSpecializationTypeLoc,
1586                            TemplateSpecializationType,
1587                            TemplateSpecializationLocInfo> {
1588 public:
1589   SourceLocation getTemplateKeywordLoc() const {
1590     return getLocalData()->TemplateKWLoc;
1591   }
1592 
1593   void setTemplateKeywordLoc(SourceLocation Loc) {
1594     getLocalData()->TemplateKWLoc = Loc;
1595   }
1596 
1597   SourceLocation getLAngleLoc() const {
1598     return getLocalData()->LAngleLoc;
1599   }
1600 
1601   void setLAngleLoc(SourceLocation Loc) {
1602     getLocalData()->LAngleLoc = Loc;
1603   }
1604 
1605   SourceLocation getRAngleLoc() const {
1606     return getLocalData()->RAngleLoc;
1607   }
1608 
1609   void setRAngleLoc(SourceLocation Loc) {
1610     getLocalData()->RAngleLoc = Loc;
1611   }
1612 
1613   unsigned getNumArgs() const {
1614     return getTypePtr()->getNumArgs();
1615   }
1616 
1617   void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1618     getArgInfos()[i] = AI;
1619   }
1620 
1621   TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1622     return getArgInfos()[i];
1623   }
1624 
1625   TemplateArgumentLoc getArgLoc(unsigned i) const {
1626     return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1627   }
1628 
1629   SourceLocation getTemplateNameLoc() const {
1630     return getLocalData()->NameLoc;
1631   }
1632 
1633   void setTemplateNameLoc(SourceLocation Loc) {
1634     getLocalData()->NameLoc = Loc;
1635   }
1636 
1637   /// - Copy the location information from the given info.
1638   void copy(TemplateSpecializationTypeLoc Loc) {
1639     unsigned size = getFullDataSize();
1640     assert(size == Loc.getFullDataSize());
1641 
1642     // We're potentially copying Expr references here.  We don't
1643     // bother retaining them because TypeSourceInfos live forever, so
1644     // as long as the Expr was retained when originally written into
1645     // the TypeLoc, we're okay.
1646     memcpy(Data, Loc.Data, size);
1647   }
1648 
1649   SourceRange getLocalSourceRange() const {
1650     if (getTemplateKeywordLoc().isValid())
1651       return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1652     else
1653       return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1654   }
1655 
1656   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1657     setTemplateKeywordLoc(Loc);
1658     setTemplateNameLoc(Loc);
1659     setLAngleLoc(Loc);
1660     setRAngleLoc(Loc);
1661     initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
1662                       getArgInfos(), Loc);
1663   }
1664 
1665   static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
1666                                 const TemplateArgument *Args,
1667                                 TemplateArgumentLocInfo *ArgInfos,
1668                                 SourceLocation Loc);
1669 
1670   unsigned getExtraLocalDataSize() const {
1671     return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1672   }
1673 
1674   unsigned getExtraLocalDataAlignment() const {
1675     return alignof(TemplateArgumentLocInfo);
1676   }
1677 
1678 private:
1679   TemplateArgumentLocInfo *getArgInfos() const {
1680     return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1681   }
1682 };
1683 
1684 struct DependentAddressSpaceLocInfo {
1685   Expr *ExprOperand;
1686   SourceRange OperandParens;
1687   SourceLocation AttrLoc;
1688 };
1689 
1690 class DependentAddressSpaceTypeLoc
1691     : public ConcreteTypeLoc<UnqualTypeLoc,
1692                              DependentAddressSpaceTypeLoc,
1693                              DependentAddressSpaceType,
1694                              DependentAddressSpaceLocInfo> {
1695 public:
1696   /// The location of the attribute name, i.e.
1697   ///    int * __attribute__((address_space(11)))
1698   ///                         ^~~~~~~~~~~~~
1699   SourceLocation getAttrNameLoc() const {
1700     return getLocalData()->AttrLoc;
1701   }
1702   void setAttrNameLoc(SourceLocation loc) {
1703     getLocalData()->AttrLoc = loc;
1704   }
1705 
1706   /// The attribute's expression operand, if it has one.
1707   ///    int * __attribute__((address_space(11)))
1708   ///                                       ^~
1709   Expr *getAttrExprOperand() const {
1710     return getLocalData()->ExprOperand;
1711   }
1712   void setAttrExprOperand(Expr *e) {
1713     getLocalData()->ExprOperand = e;
1714   }
1715 
1716   /// The location of the parentheses around the operand, if there is
1717   /// an operand.
1718   ///    int * __attribute__((address_space(11)))
1719   ///                                      ^  ^
1720   SourceRange getAttrOperandParensRange() const {
1721     return getLocalData()->OperandParens;
1722   }
1723   void setAttrOperandParensRange(SourceRange range) {
1724     getLocalData()->OperandParens = range;
1725   }
1726 
1727   SourceRange getLocalSourceRange() const {
1728     SourceRange range(getAttrNameLoc());
1729     range.setEnd(getAttrOperandParensRange().getEnd());
1730     return range;
1731   }
1732 
1733   ///  Returns the type before the address space attribute application
1734   ///  area.
1735   ///    int * __attribute__((address_space(11))) *
1736   ///    ^   ^
1737   QualType getInnerType() const {
1738     return this->getTypePtr()->getPointeeType();
1739   }
1740 
1741   TypeLoc getPointeeTypeLoc() const {
1742     return this->getInnerTypeLoc();
1743   }
1744 
1745   void initializeLocal(ASTContext &Context, SourceLocation loc) {
1746     setAttrNameLoc(loc);
1747     setAttrOperandParensRange(loc);
1748     setAttrOperandParensRange(SourceRange(loc));
1749     setAttrExprOperand(getTypePtr()->getAddrSpaceExpr());
1750   }
1751 };
1752 
1753 //===----------------------------------------------------------------------===//
1754 //
1755 //  All of these need proper implementations.
1756 //
1757 //===----------------------------------------------------------------------===//
1758 
1759 // FIXME: size expression and attribute locations (or keyword if we
1760 // ever fully support altivec syntax).
1761 struct VectorTypeLocInfo {
1762   SourceLocation NameLoc;
1763 };
1764 
1765 class VectorTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, VectorTypeLoc,
1766                                              VectorType, VectorTypeLocInfo> {
1767 public:
1768   SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; }
1769 
1770   void setNameLoc(SourceLocation Loc) { this->getLocalData()->NameLoc = Loc; }
1771 
1772   SourceRange getLocalSourceRange() const {
1773     return SourceRange(getNameLoc(), getNameLoc());
1774   }
1775 
1776   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1777     setNameLoc(Loc);
1778   }
1779 
1780   TypeLoc getElementLoc() const { return getInnerTypeLoc(); }
1781 
1782   QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
1783 };
1784 
1785 // FIXME: size expression and attribute locations (or keyword if we
1786 // ever fully support altivec syntax).
1787 class DependentVectorTypeLoc
1788     : public ConcreteTypeLoc<UnqualTypeLoc, DependentVectorTypeLoc,
1789                              DependentVectorType, 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.
1809 class ExtVectorTypeLoc
1810     : public InheritingConcreteTypeLoc<VectorTypeLoc, ExtVectorTypeLoc,
1811                                        ExtVectorType> {};
1812 
1813 // FIXME: attribute locations.
1814 // For some reason, this isn't a subtype of VectorType.
1815 class DependentSizedExtVectorTypeLoc
1816     : public ConcreteTypeLoc<UnqualTypeLoc, DependentSizedExtVectorTypeLoc,
1817                              DependentSizedExtVectorType, VectorTypeLocInfo> {
1818 public:
1819   SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; }
1820 
1821   void setNameLoc(SourceLocation Loc) { this->getLocalData()->NameLoc = Loc; }
1822 
1823   SourceRange getLocalSourceRange() const {
1824     return SourceRange(getNameLoc(), getNameLoc());
1825   }
1826 
1827   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1828     setNameLoc(Loc);
1829   }
1830 
1831   TypeLoc getElementLoc() const { return getInnerTypeLoc(); }
1832 
1833   QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
1834 };
1835 
1836 struct MatrixTypeLocInfo {
1837   SourceLocation AttrLoc;
1838   SourceRange OperandParens;
1839   Expr *RowOperand;
1840   Expr *ColumnOperand;
1841 };
1842 
1843 class MatrixTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, MatrixTypeLoc,
1844                                              MatrixType, MatrixTypeLocInfo> {
1845 public:
1846   /// The location of the attribute name, i.e.
1847   ///    float __attribute__((matrix_type(4, 2)))
1848   ///                         ^~~~~~~~~~~~~~~~~
1849   SourceLocation getAttrNameLoc() const { return getLocalData()->AttrLoc; }
1850   void setAttrNameLoc(SourceLocation loc) { getLocalData()->AttrLoc = loc; }
1851 
1852   /// The attribute's row operand, if it has one.
1853   ///    float __attribute__((matrix_type(4, 2)))
1854   ///                                     ^
1855   Expr *getAttrRowOperand() const { return getLocalData()->RowOperand; }
1856   void setAttrRowOperand(Expr *e) { getLocalData()->RowOperand = e; }
1857 
1858   /// The attribute's column operand, if it has one.
1859   ///    float __attribute__((matrix_type(4, 2)))
1860   ///                                        ^
1861   Expr *getAttrColumnOperand() const { return getLocalData()->ColumnOperand; }
1862   void setAttrColumnOperand(Expr *e) { getLocalData()->ColumnOperand = e; }
1863 
1864   /// The location of the parentheses around the operand, if there is
1865   /// an operand.
1866   ///    float __attribute__((matrix_type(4, 2)))
1867   ///                                    ^    ^
1868   SourceRange getAttrOperandParensRange() const {
1869     return getLocalData()->OperandParens;
1870   }
1871   void setAttrOperandParensRange(SourceRange range) {
1872     getLocalData()->OperandParens = range;
1873   }
1874 
1875   SourceRange getLocalSourceRange() const {
1876     SourceRange range(getAttrNameLoc());
1877     range.setEnd(getAttrOperandParensRange().getEnd());
1878     return range;
1879   }
1880 
1881   void initializeLocal(ASTContext &Context, SourceLocation loc) {
1882     setAttrNameLoc(loc);
1883     setAttrOperandParensRange(loc);
1884     setAttrRowOperand(nullptr);
1885     setAttrColumnOperand(nullptr);
1886   }
1887 };
1888 
1889 class ConstantMatrixTypeLoc
1890     : public InheritingConcreteTypeLoc<MatrixTypeLoc, ConstantMatrixTypeLoc,
1891                                        ConstantMatrixType> {};
1892 
1893 class DependentSizedMatrixTypeLoc
1894     : public InheritingConcreteTypeLoc<MatrixTypeLoc,
1895                                        DependentSizedMatrixTypeLoc,
1896                                        DependentSizedMatrixType> {};
1897 
1898 // FIXME: location of the '_Complex' keyword.
1899 class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1900                                                         ComplexTypeLoc,
1901                                                         ComplexType> {
1902 };
1903 
1904 struct TypeofLocInfo {
1905   SourceLocation TypeofLoc;
1906   SourceLocation LParenLoc;
1907   SourceLocation RParenLoc;
1908 };
1909 
1910 struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
1911 };
1912 
1913 struct TypeOfTypeLocInfo : public TypeofLocInfo {
1914   TypeSourceInfo* UnderlyingTInfo;
1915 };
1916 
1917 template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
1918 class TypeofLikeTypeLoc
1919   : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
1920 public:
1921   SourceLocation getTypeofLoc() const {
1922     return this->getLocalData()->TypeofLoc;
1923   }
1924 
1925   void setTypeofLoc(SourceLocation Loc) {
1926     this->getLocalData()->TypeofLoc = Loc;
1927   }
1928 
1929   SourceLocation getLParenLoc() const {
1930     return this->getLocalData()->LParenLoc;
1931   }
1932 
1933   void setLParenLoc(SourceLocation Loc) {
1934     this->getLocalData()->LParenLoc = Loc;
1935   }
1936 
1937   SourceLocation getRParenLoc() const {
1938     return this->getLocalData()->RParenLoc;
1939   }
1940 
1941   void setRParenLoc(SourceLocation Loc) {
1942     this->getLocalData()->RParenLoc = Loc;
1943   }
1944 
1945   SourceRange getParensRange() const {
1946     return SourceRange(getLParenLoc(), getRParenLoc());
1947   }
1948 
1949   void setParensRange(SourceRange range) {
1950       setLParenLoc(range.getBegin());
1951       setRParenLoc(range.getEnd());
1952   }
1953 
1954   SourceRange getLocalSourceRange() const {
1955     return SourceRange(getTypeofLoc(), getRParenLoc());
1956   }
1957 
1958   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1959     setTypeofLoc(Loc);
1960     setLParenLoc(Loc);
1961     setRParenLoc(Loc);
1962   }
1963 };
1964 
1965 class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
1966                                                    TypeOfExprType,
1967                                                    TypeOfExprTypeLocInfo> {
1968 public:
1969   Expr* getUnderlyingExpr() const {
1970     return getTypePtr()->getUnderlyingExpr();
1971   }
1972 
1973   // Reimplemented to account for GNU/C++ extension
1974   //     typeof unary-expression
1975   // where there are no parentheses.
1976   SourceRange getLocalSourceRange() const;
1977 };
1978 
1979 class TypeOfTypeLoc
1980   : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
1981 public:
1982   QualType getUnderlyingType() const {
1983     return this->getTypePtr()->getUnderlyingType();
1984   }
1985 
1986   TypeSourceInfo* getUnderlyingTInfo() const {
1987     return this->getLocalData()->UnderlyingTInfo;
1988   }
1989 
1990   void setUnderlyingTInfo(TypeSourceInfo* TI) const {
1991     this->getLocalData()->UnderlyingTInfo = TI;
1992   }
1993 
1994   void initializeLocal(ASTContext &Context, SourceLocation Loc);
1995 };
1996 
1997 // decltype(expression) abc;
1998 // ~~~~~~~~                  DecltypeLoc
1999 //                    ~      RParenLoc
2000 // FIXME: add LParenLoc, it is tricky to support due to the limitation of
2001 // annotated-decltype token.
2002 struct DecltypeTypeLocInfo {
2003   SourceLocation DecltypeLoc;
2004   SourceLocation RParenLoc;
2005 };
2006 class DecltypeTypeLoc
2007     : public ConcreteTypeLoc<UnqualTypeLoc, DecltypeTypeLoc, DecltypeType,
2008                              DecltypeTypeLocInfo> {
2009 public:
2010   Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
2011 
2012   SourceLocation getDecltypeLoc() const { return getLocalData()->DecltypeLoc; }
2013   void setDecltypeLoc(SourceLocation Loc) { getLocalData()->DecltypeLoc = Loc; }
2014 
2015   SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
2016   void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
2017 
2018   SourceRange getLocalSourceRange() const {
2019     return SourceRange(getDecltypeLoc(), getRParenLoc());
2020   }
2021 
2022   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2023     setDecltypeLoc(Loc);
2024     setRParenLoc(Loc);
2025   }
2026 };
2027 
2028 struct UnaryTransformTypeLocInfo {
2029   // FIXME: While there's only one unary transform right now, future ones may
2030   // need different representations
2031   SourceLocation KWLoc, LParenLoc, RParenLoc;
2032   TypeSourceInfo *UnderlyingTInfo;
2033 };
2034 
2035 class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
2036                                                     UnaryTransformTypeLoc,
2037                                                     UnaryTransformType,
2038                                                     UnaryTransformTypeLocInfo> {
2039 public:
2040   SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
2041   void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
2042 
2043   SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
2044   void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
2045 
2046   SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
2047   void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
2048 
2049   TypeSourceInfo* getUnderlyingTInfo() const {
2050     return getLocalData()->UnderlyingTInfo;
2051   }
2052 
2053   void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
2054     getLocalData()->UnderlyingTInfo = TInfo;
2055   }
2056 
2057   SourceRange getLocalSourceRange() const {
2058     return SourceRange(getKWLoc(), getRParenLoc());
2059   }
2060 
2061   SourceRange getParensRange() const {
2062     return SourceRange(getLParenLoc(), getRParenLoc());
2063   }
2064 
2065   void setParensRange(SourceRange Range) {
2066     setLParenLoc(Range.getBegin());
2067     setRParenLoc(Range.getEnd());
2068   }
2069 
2070   void initializeLocal(ASTContext &Context, SourceLocation Loc);
2071 };
2072 
2073 class DeducedTypeLoc
2074     : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DeducedTypeLoc,
2075                                        DeducedType> {};
2076 
2077 struct AutoTypeLocInfo : TypeSpecLocInfo {
2078   NestedNameSpecifierLoc NestedNameSpec;
2079   SourceLocation TemplateKWLoc;
2080   SourceLocation ConceptNameLoc;
2081   NamedDecl *FoundDecl;
2082   SourceLocation LAngleLoc;
2083   SourceLocation RAngleLoc;
2084 
2085   // For decltype(auto).
2086   SourceLocation RParenLoc;
2087 
2088   // Followed by a TemplateArgumentLocInfo[]
2089 };
2090 
2091 class AutoTypeLoc
2092     : public ConcreteTypeLoc<DeducedTypeLoc,
2093                              AutoTypeLoc,
2094                              AutoType,
2095                              AutoTypeLocInfo> {
2096 public:
2097   AutoTypeKeyword getAutoKeyword() const {
2098     return getTypePtr()->getKeyword();
2099   }
2100 
2101   bool isDecltypeAuto() const { return getTypePtr()->isDecltypeAuto(); }
2102   SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
2103   void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
2104 
2105   bool isConstrained() const {
2106     return getTypePtr()->isConstrained();
2107   }
2108 
2109   const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
2110     return getLocalData()->NestedNameSpec;
2111   }
2112 
2113   void setNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
2114     getLocalData()->NestedNameSpec = NNS;
2115   }
2116 
2117   SourceLocation getTemplateKWLoc() const {
2118     return getLocalData()->TemplateKWLoc;
2119   }
2120 
2121   void setTemplateKWLoc(SourceLocation Loc) {
2122     getLocalData()->TemplateKWLoc = Loc;
2123   }
2124 
2125   SourceLocation getConceptNameLoc() const {
2126     return getLocalData()->ConceptNameLoc;
2127   }
2128 
2129   void setConceptNameLoc(SourceLocation Loc) {
2130     getLocalData()->ConceptNameLoc = Loc;
2131   }
2132 
2133   NamedDecl *getFoundDecl() const {
2134     return getLocalData()->FoundDecl;
2135   }
2136 
2137   void setFoundDecl(NamedDecl *D) {
2138     getLocalData()->FoundDecl = D;
2139   }
2140 
2141   ConceptDecl *getNamedConcept() const {
2142     return getTypePtr()->getTypeConstraintConcept();
2143   }
2144 
2145   DeclarationNameInfo getConceptNameInfo() const;
2146 
2147   bool hasExplicitTemplateArgs() const {
2148     return getLocalData()->LAngleLoc.isValid();
2149   }
2150 
2151   SourceLocation getLAngleLoc() const {
2152     return this->getLocalData()->LAngleLoc;
2153   }
2154 
2155   void setLAngleLoc(SourceLocation Loc) {
2156     this->getLocalData()->LAngleLoc = Loc;
2157   }
2158 
2159   SourceLocation getRAngleLoc() const {
2160     return this->getLocalData()->RAngleLoc;
2161   }
2162 
2163   void setRAngleLoc(SourceLocation Loc) {
2164     this->getLocalData()->RAngleLoc = Loc;
2165   }
2166 
2167   unsigned getNumArgs() const {
2168     return getTypePtr()->getNumArgs();
2169   }
2170 
2171   void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
2172     getArgInfos()[i] = AI;
2173   }
2174 
2175   TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
2176     return getArgInfos()[i];
2177   }
2178 
2179   TemplateArgumentLoc getArgLoc(unsigned i) const {
2180     return TemplateArgumentLoc(getTypePtr()->getTypeConstraintArguments()[i],
2181                                getArgLocInfo(i));
2182   }
2183 
2184   SourceRange getLocalSourceRange() const {
2185     return {isConstrained()
2186                 ? (getNestedNameSpecifierLoc()
2187                        ? getNestedNameSpecifierLoc().getBeginLoc()
2188                        : (getTemplateKWLoc().isValid() ? getTemplateKWLoc()
2189                                                        : getConceptNameLoc()))
2190                 : getNameLoc(),
2191             isDecltypeAuto() ? getRParenLoc() : getNameLoc()};
2192   }
2193 
2194   void copy(AutoTypeLoc Loc) {
2195     unsigned size = getFullDataSize();
2196     assert(size == Loc.getFullDataSize());
2197     memcpy(Data, Loc.Data, size);
2198   }
2199 
2200   void initializeLocal(ASTContext &Context, SourceLocation Loc);
2201 
2202   unsigned getExtraLocalDataSize() const {
2203     return getNumArgs() * sizeof(TemplateArgumentLocInfo);
2204   }
2205 
2206   unsigned getExtraLocalDataAlignment() const {
2207     return alignof(TemplateArgumentLocInfo);
2208   }
2209 
2210 private:
2211   TemplateArgumentLocInfo *getArgInfos() const {
2212     return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
2213   }
2214 };
2215 
2216 class DeducedTemplateSpecializationTypeLoc
2217     : public InheritingConcreteTypeLoc<DeducedTypeLoc,
2218                                        DeducedTemplateSpecializationTypeLoc,
2219                                        DeducedTemplateSpecializationType> {
2220 public:
2221   SourceLocation getTemplateNameLoc() const {
2222     return getNameLoc();
2223   }
2224 
2225   void setTemplateNameLoc(SourceLocation Loc) {
2226     setNameLoc(Loc);
2227   }
2228 };
2229 
2230 struct ElaboratedLocInfo {
2231   SourceLocation ElaboratedKWLoc;
2232 
2233   /// Data associated with the nested-name-specifier location.
2234   void *QualifierData;
2235 };
2236 
2237 class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
2238                                                  ElaboratedTypeLoc,
2239                                                  ElaboratedType,
2240                                                  ElaboratedLocInfo> {
2241 public:
2242   SourceLocation getElaboratedKeywordLoc() const {
2243     return this->getLocalData()->ElaboratedKWLoc;
2244   }
2245 
2246   void setElaboratedKeywordLoc(SourceLocation Loc) {
2247     this->getLocalData()->ElaboratedKWLoc = Loc;
2248   }
2249 
2250   NestedNameSpecifierLoc getQualifierLoc() const {
2251     return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
2252                                   getLocalData()->QualifierData);
2253   }
2254 
2255   void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
2256     assert(QualifierLoc.getNestedNameSpecifier()
2257                                             == getTypePtr()->getQualifier() &&
2258            "Inconsistent nested-name-specifier pointer");
2259     getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
2260   }
2261 
2262   SourceRange getLocalSourceRange() const {
2263     if (getElaboratedKeywordLoc().isValid())
2264       if (getQualifierLoc())
2265         return SourceRange(getElaboratedKeywordLoc(),
2266                            getQualifierLoc().getEndLoc());
2267       else
2268         return SourceRange(getElaboratedKeywordLoc());
2269     else
2270       return getQualifierLoc().getSourceRange();
2271   }
2272 
2273   void initializeLocal(ASTContext &Context, SourceLocation Loc);
2274 
2275   TypeLoc getNamedTypeLoc() const {
2276     return getInnerTypeLoc();
2277   }
2278 
2279   QualType getInnerType() const {
2280     return getTypePtr()->getNamedType();
2281   }
2282 
2283   void copy(ElaboratedTypeLoc Loc) {
2284     unsigned size = getFullDataSize();
2285     assert(size == Loc.getFullDataSize());
2286     memcpy(Data, Loc.Data, size);
2287   }
2288 };
2289 
2290 // This is exactly the structure of an ElaboratedTypeLoc whose inner
2291 // type is some sort of TypeDeclTypeLoc.
2292 struct DependentNameLocInfo : ElaboratedLocInfo {
2293   SourceLocation NameLoc;
2294 };
2295 
2296 class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
2297                                                     DependentNameTypeLoc,
2298                                                     DependentNameType,
2299                                                     DependentNameLocInfo> {
2300 public:
2301   SourceLocation getElaboratedKeywordLoc() const {
2302     return this->getLocalData()->ElaboratedKWLoc;
2303   }
2304 
2305   void setElaboratedKeywordLoc(SourceLocation Loc) {
2306     this->getLocalData()->ElaboratedKWLoc = Loc;
2307   }
2308 
2309   NestedNameSpecifierLoc getQualifierLoc() const {
2310     return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
2311                                   getLocalData()->QualifierData);
2312   }
2313 
2314   void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
2315     assert(QualifierLoc.getNestedNameSpecifier()
2316                                             == getTypePtr()->getQualifier() &&
2317            "Inconsistent nested-name-specifier pointer");
2318     getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
2319   }
2320 
2321   SourceLocation getNameLoc() const {
2322     return this->getLocalData()->NameLoc;
2323   }
2324 
2325   void setNameLoc(SourceLocation Loc) {
2326     this->getLocalData()->NameLoc = Loc;
2327   }
2328 
2329   SourceRange getLocalSourceRange() const {
2330     if (getElaboratedKeywordLoc().isValid())
2331       return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
2332     else
2333       return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
2334   }
2335 
2336   void copy(DependentNameTypeLoc Loc) {
2337     unsigned size = getFullDataSize();
2338     assert(size == Loc.getFullDataSize());
2339     memcpy(Data, Loc.Data, size);
2340   }
2341 
2342   void initializeLocal(ASTContext &Context, SourceLocation Loc);
2343 };
2344 
2345 struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
2346   SourceLocation TemplateKWLoc;
2347   SourceLocation LAngleLoc;
2348   SourceLocation RAngleLoc;
2349   // followed by a TemplateArgumentLocInfo[]
2350 };
2351 
2352 class DependentTemplateSpecializationTypeLoc :
2353     public ConcreteTypeLoc<UnqualTypeLoc,
2354                            DependentTemplateSpecializationTypeLoc,
2355                            DependentTemplateSpecializationType,
2356                            DependentTemplateSpecializationLocInfo> {
2357 public:
2358   SourceLocation getElaboratedKeywordLoc() const {
2359     return this->getLocalData()->ElaboratedKWLoc;
2360   }
2361 
2362   void setElaboratedKeywordLoc(SourceLocation Loc) {
2363     this->getLocalData()->ElaboratedKWLoc = Loc;
2364   }
2365 
2366   NestedNameSpecifierLoc getQualifierLoc() const {
2367     if (!getLocalData()->QualifierData)
2368       return NestedNameSpecifierLoc();
2369 
2370     return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
2371                                   getLocalData()->QualifierData);
2372   }
2373 
2374   void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
2375     if (!QualifierLoc) {
2376       // Even if we have a nested-name-specifier in the dependent
2377       // template specialization type, we won't record the nested-name-specifier
2378       // location information when this type-source location information is
2379       // part of a nested-name-specifier.
2380       getLocalData()->QualifierData = nullptr;
2381       return;
2382     }
2383 
2384     assert(QualifierLoc.getNestedNameSpecifier()
2385                                         == getTypePtr()->getQualifier() &&
2386            "Inconsistent nested-name-specifier pointer");
2387     getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
2388   }
2389 
2390   SourceLocation getTemplateKeywordLoc() const {
2391     return getLocalData()->TemplateKWLoc;
2392   }
2393 
2394   void setTemplateKeywordLoc(SourceLocation Loc) {
2395     getLocalData()->TemplateKWLoc = Loc;
2396   }
2397 
2398   SourceLocation getTemplateNameLoc() const {
2399     return this->getLocalData()->NameLoc;
2400   }
2401 
2402   void setTemplateNameLoc(SourceLocation Loc) {
2403     this->getLocalData()->NameLoc = Loc;
2404   }
2405 
2406   SourceLocation getLAngleLoc() const {
2407     return this->getLocalData()->LAngleLoc;
2408   }
2409 
2410   void setLAngleLoc(SourceLocation Loc) {
2411     this->getLocalData()->LAngleLoc = Loc;
2412   }
2413 
2414   SourceLocation getRAngleLoc() const {
2415     return this->getLocalData()->RAngleLoc;
2416   }
2417 
2418   void setRAngleLoc(SourceLocation Loc) {
2419     this->getLocalData()->RAngleLoc = Loc;
2420   }
2421 
2422   unsigned getNumArgs() const {
2423     return getTypePtr()->getNumArgs();
2424   }
2425 
2426   void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
2427     getArgInfos()[i] = AI;
2428   }
2429 
2430   TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
2431     return getArgInfos()[i];
2432   }
2433 
2434   TemplateArgumentLoc getArgLoc(unsigned i) const {
2435     return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
2436   }
2437 
2438   SourceRange getLocalSourceRange() const {
2439     if (getElaboratedKeywordLoc().isValid())
2440       return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
2441     else if (getQualifierLoc())
2442       return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
2443     else if (getTemplateKeywordLoc().isValid())
2444       return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
2445     else
2446       return SourceRange(getTemplateNameLoc(), getRAngleLoc());
2447   }
2448 
2449   void copy(DependentTemplateSpecializationTypeLoc Loc) {
2450     unsigned size = getFullDataSize();
2451     assert(size == Loc.getFullDataSize());
2452     memcpy(Data, Loc.Data, size);
2453   }
2454 
2455   void initializeLocal(ASTContext &Context, SourceLocation Loc);
2456 
2457   unsigned getExtraLocalDataSize() const {
2458     return getNumArgs() * sizeof(TemplateArgumentLocInfo);
2459   }
2460 
2461   unsigned getExtraLocalDataAlignment() const {
2462     return alignof(TemplateArgumentLocInfo);
2463   }
2464 
2465 private:
2466   TemplateArgumentLocInfo *getArgInfos() const {
2467     return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
2468   }
2469 };
2470 
2471 struct PackExpansionTypeLocInfo {
2472   SourceLocation EllipsisLoc;
2473 };
2474 
2475 class PackExpansionTypeLoc
2476   : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
2477                            PackExpansionType, PackExpansionTypeLocInfo> {
2478 public:
2479   SourceLocation getEllipsisLoc() const {
2480     return this->getLocalData()->EllipsisLoc;
2481   }
2482 
2483   void setEllipsisLoc(SourceLocation Loc) {
2484     this->getLocalData()->EllipsisLoc = Loc;
2485   }
2486 
2487   SourceRange getLocalSourceRange() const {
2488     return SourceRange(getEllipsisLoc(), getEllipsisLoc());
2489   }
2490 
2491   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2492     setEllipsisLoc(Loc);
2493   }
2494 
2495   TypeLoc getPatternLoc() const {
2496     return getInnerTypeLoc();
2497   }
2498 
2499   QualType getInnerType() const {
2500     return this->getTypePtr()->getPattern();
2501   }
2502 };
2503 
2504 struct AtomicTypeLocInfo {
2505   SourceLocation KWLoc, LParenLoc, RParenLoc;
2506 };
2507 
2508 class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
2509                                              AtomicType, AtomicTypeLocInfo> {
2510 public:
2511   TypeLoc getValueLoc() const {
2512     return this->getInnerTypeLoc();
2513   }
2514 
2515   SourceRange getLocalSourceRange() const {
2516     return SourceRange(getKWLoc(), getRParenLoc());
2517   }
2518 
2519   SourceLocation getKWLoc() const {
2520     return this->getLocalData()->KWLoc;
2521   }
2522 
2523   void setKWLoc(SourceLocation Loc) {
2524     this->getLocalData()->KWLoc = Loc;
2525   }
2526 
2527   SourceLocation getLParenLoc() const {
2528     return this->getLocalData()->LParenLoc;
2529   }
2530 
2531   void setLParenLoc(SourceLocation Loc) {
2532     this->getLocalData()->LParenLoc = Loc;
2533   }
2534 
2535   SourceLocation getRParenLoc() const {
2536     return this->getLocalData()->RParenLoc;
2537   }
2538 
2539   void setRParenLoc(SourceLocation Loc) {
2540     this->getLocalData()->RParenLoc = Loc;
2541   }
2542 
2543   SourceRange getParensRange() const {
2544     return SourceRange(getLParenLoc(), getRParenLoc());
2545   }
2546 
2547   void setParensRange(SourceRange Range) {
2548     setLParenLoc(Range.getBegin());
2549     setRParenLoc(Range.getEnd());
2550   }
2551 
2552   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2553     setKWLoc(Loc);
2554     setLParenLoc(Loc);
2555     setRParenLoc(Loc);
2556   }
2557 
2558   QualType getInnerType() const {
2559     return this->getTypePtr()->getValueType();
2560   }
2561 };
2562 
2563 struct PipeTypeLocInfo {
2564   SourceLocation KWLoc;
2565 };
2566 
2567 class PipeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, PipeTypeLoc, PipeType,
2568                                            PipeTypeLocInfo> {
2569 public:
2570   TypeLoc getValueLoc() const { return this->getInnerTypeLoc(); }
2571 
2572   SourceRange getLocalSourceRange() const { return SourceRange(getKWLoc()); }
2573 
2574   SourceLocation getKWLoc() const { return this->getLocalData()->KWLoc; }
2575   void setKWLoc(SourceLocation Loc) { this->getLocalData()->KWLoc = Loc; }
2576 
2577   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2578     setKWLoc(Loc);
2579   }
2580 
2581   QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
2582 };
2583 
2584 template <typename T>
2585 inline T TypeLoc::getAsAdjusted() const {
2586   TypeLoc Cur = *this;
2587   while (!T::isKind(Cur)) {
2588     if (auto PTL = Cur.getAs<ParenTypeLoc>())
2589       Cur = PTL.getInnerLoc();
2590     else if (auto ATL = Cur.getAs<AttributedTypeLoc>())
2591       Cur = ATL.getModifiedLoc();
2592     else if (auto ETL = Cur.getAs<ElaboratedTypeLoc>())
2593       Cur = ETL.getNamedTypeLoc();
2594     else if (auto ATL = Cur.getAs<AdjustedTypeLoc>())
2595       Cur = ATL.getOriginalLoc();
2596     else if (auto MQL = Cur.getAs<MacroQualifiedTypeLoc>())
2597       Cur = MQL.getInnerLoc();
2598     else
2599       break;
2600   }
2601   return Cur.getAs<T>();
2602 }
2603 class BitIntTypeLoc final
2604     : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, BitIntTypeLoc,
2605                                        BitIntType> {};
2606 class DependentBitIntTypeLoc final
2607     : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, DependentBitIntTypeLoc,
2608                                        DependentBitIntType> {};
2609 
2610 } // namespace clang
2611 
2612 #endif // LLVM_CLANG_AST_TYPELOC_H
2613