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