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