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