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