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