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