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