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