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