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