]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - include/clang/AST/TypeLoc.h
Update clang to r86025.
[FreeBSD/FreeBSD.git] / 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/TemplateBase.h"
19
20 namespace clang {
21   class ParmVarDecl;
22   class DeclaratorInfo;
23   class UnqualTypeLoc;
24
25 // Predeclare all the type nodes.
26 #define ABSTRACT_TYPELOC(Class, Base)
27 #define TYPELOC(Class, Base) \
28   class Class##TypeLoc;
29 #include "clang/AST/TypeLocNodes.def"
30
31 /// \brief Base wrapper for a particular "section" of type source info.
32 ///
33 /// A client should use the TypeLoc subclasses through cast/dyn_cast in order to
34 /// get at the actual information.
35 class TypeLoc {
36 protected:
37   // The correctness of this relies on the property that, for Type *Ty,
38   //   QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
39   void *Ty;
40   void *Data;
41
42 public:
43   /// The kinds of TypeLocs.  Equivalent to the Type::TypeClass enum,
44   /// except it also defines a Qualified enum that corresponds to the
45   /// QualifiedLoc class.
46   enum TypeLocClass {
47 #define ABSTRACT_TYPE(Class, Base)
48 #define TYPE(Class, Base) \
49     Class = Type::Class,
50 #include "clang/AST/TypeNodes.def"
51     Qualified
52   };
53
54   TypeLoc() : Ty(0), Data(0) { }
55   TypeLoc(QualType ty, void *opaqueData)
56     : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { }
57   TypeLoc(Type *ty, void *opaqueData)
58     : Ty(ty), Data(opaqueData) { }
59
60   TypeLocClass getTypeLocClass() const {
61     if (getType().hasQualifiers()) return Qualified;
62     return (TypeLocClass) getType()->getTypeClass();
63   }
64
65   bool isNull() const { return !Ty; }
66   operator bool() const { return Ty; }
67
68   /// \brief Returns the size of type source info data block for the given type.
69   static unsigned getFullDataSizeForType(QualType Ty);
70
71   /// \brief Get the type for which this source info wrapper provides
72   /// information.
73   QualType getType() const {
74     return QualType::getFromOpaquePtr(Ty);
75   }
76
77   Type *getTypePtr() const {
78     return QualType::getFromOpaquePtr(Ty).getTypePtr();
79   }
80
81   /// \brief Get the pointer where source information is stored.
82   void *getOpaqueData() const {
83     return Data;
84   }
85
86   /// \brief Get the full source range.
87   SourceRange getFullSourceRange() const {
88     SourceLocation End = getSourceRange().getEnd();
89     TypeLoc Cur = *this;
90     while (true) {
91       TypeLoc Next = Cur.getNextTypeLoc();
92       if (Next.isNull()) break;
93       Cur = Next;
94     }
95     return SourceRange(Cur.getSourceRange().getBegin(), End);
96   }
97
98   /// \brief Get the local source range.
99   SourceRange getSourceRange() const {
100     return getSourceRangeImpl(*this);
101   }
102
103   /// \brief Returns the size of the type source info data block.
104   unsigned getFullDataSize() const {
105     return getFullDataSizeForType(getType());
106   }
107
108   /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the
109   /// TypeLoc is a PointerLoc and next TypeLoc is for "int".
110   TypeLoc getNextTypeLoc() const {
111     return getNextTypeLocImpl(*this);
112   }
113
114   /// \brief Skips past any qualifiers, if this is qualified.
115   UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
116
117   /// \brief Initializes this to state that every location in this
118   /// type is the given location.
119   ///
120   /// This method exists to provide a simple transition for code that
121   /// relies on location-less types.
122   void initialize(SourceLocation Loc) const {
123     initializeImpl(*this, Loc);
124   }
125
126   friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
127     return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
128   }
129
130   friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) {
131     return !(LHS == RHS);
132   }
133
134   static bool classof(const TypeLoc *TL) { return true; }
135
136 private:
137   static void initializeImpl(TypeLoc TL, SourceLocation Loc);
138   static TypeLoc getNextTypeLocImpl(TypeLoc TL);
139   static SourceRange getSourceRangeImpl(TypeLoc TL);
140 };
141
142 /// \brief Wrapper of type source information for a type with
143 /// no direct quqlaifiers.
144 class UnqualTypeLoc : public TypeLoc {
145 public:
146   UnqualTypeLoc() {}
147   UnqualTypeLoc(Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
148
149   Type *getTypePtr() const {
150     return reinterpret_cast<Type*>(Ty);
151   }
152
153   TypeLocClass getTypeLocClass() const {
154     return (TypeLocClass) getTypePtr()->getTypeClass();
155   }
156
157   static bool classof(const TypeLoc *TL) {
158     return !TL->getType().hasQualifiers();
159   }
160   static bool classof(const UnqualTypeLoc *TL) { return true; }
161 };
162
163 /// \brief Wrapper of type source information for a type with
164 /// non-trivial direct qualifiers.
165 ///
166 /// Currently, we intentionally do not provide source location for
167 /// type qualifiers.
168 class QualifiedTypeLoc : public TypeLoc {
169 public:
170   SourceRange getSourceRange() const {
171     return SourceRange();
172   }
173
174   UnqualTypeLoc getUnqualifiedLoc() const {
175     return UnqualTypeLoc(getTypePtr(), Data);
176   }
177
178   /// Initializes the local data of this type source info block to
179   /// provide no information.
180   void initializeLocal(SourceLocation Loc) {
181     // do nothing
182   }
183
184   TypeLoc getNextTypeLoc() const {
185     return getUnqualifiedLoc();
186   }
187
188   /// \brief Returns the size of the type source info data block that is
189   /// specific to this type.
190   unsigned getLocalDataSize() const {
191     // In fact, we don't currently preserve any location information
192     // for qualifiers.
193     return 0;
194   }
195
196   /// \brief Returns the size of the type source info data block.
197   unsigned getFullDataSize() const {
198     return getLocalDataSize() + 
199       getFullDataSizeForType(getType().getUnqualifiedType());
200   }
201
202   static bool classof(const TypeLoc *TL) {
203     return TL->getType().hasQualifiers();
204   }
205   static bool classof(const QualifiedTypeLoc *TL) { return true; }
206 };
207
208 inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
209   if (isa<QualifiedTypeLoc>(this))
210     return cast<QualifiedTypeLoc>(this)->getUnqualifiedLoc();
211   return cast<UnqualTypeLoc>(*this);
212 }
213
214 /// A metaprogramming base class for TypeLoc classes which correspond
215 /// to a particular Type subclass.  It is accepted for a single
216 /// TypeLoc class to correspond to multiple Type classes.
217 ///
218 /// \param Base a class from which to derive
219 /// \param Derived the class deriving from this one
220 /// \param TypeClass the concrete Type subclass associated with this
221 ///   location type
222 /// \param LocalData the structure type of local location data for
223 ///   this type
224 ///
225 /// sizeof(LocalData) needs to be a multiple of sizeof(void*) or
226 /// else the world will end.
227 ///
228 /// TypeLocs with non-constant amounts of local data should override
229 /// getExtraLocalDataSize(); getExtraLocalData() will then point to
230 /// this extra memory.
231 ///
232 /// TypeLocs with an inner type should define
233 ///   QualType getInnerType() const
234 /// and getInnerTypeLoc() will then point to this inner type's
235 /// location data.
236 ///
237 /// A word about hierarchies: this template is not designed to be
238 /// derived from multiple times in a hierarchy.  It is also not
239 /// designed to be used for classes where subtypes might provide
240 /// different amounts of source information.  It should be subclassed
241 /// only at the deepest portion of the hierarchy where all children
242 /// have identical source information; if that's an abstract type,
243 /// then further descendents should inherit from
244 /// InheritingConcreteTypeLoc instead.
245 template <class Base, class Derived, class TypeClass, class LocalData>
246 class ConcreteTypeLoc : public Base {
247
248   const Derived *asDerived() const {
249     return static_cast<const Derived*>(this);
250   }
251
252 public:
253   unsigned getLocalDataSize() const {
254     return sizeof(LocalData) + asDerived()->getExtraLocalDataSize();
255   }
256   // Give a default implementation that's useful for leaf types.
257   unsigned getFullDataSize() const {
258     return asDerived()->getLocalDataSize() + getInnerTypeSize();
259   }
260
261   static bool classofType(const Type *Ty) {
262     return TypeClass::classof(Ty);
263   }
264
265   TypeLoc getNextTypeLoc() const {
266     return getNextTypeLoc(asDerived()->getInnerType());
267   }
268
269   TypeClass *getTypePtr() const {
270     return cast<TypeClass>(Base::getTypePtr());
271   }
272
273 protected:
274   unsigned getExtraLocalDataSize() const {
275     return 0;
276   }
277
278   LocalData *getLocalData() const {
279     return static_cast<LocalData*>(Base::Data);
280   }
281
282   /// Gets a pointer past the Info structure; useful for classes with
283   /// local data that can't be captured in the Info (e.g. because it's
284   /// of variable size).
285   void *getExtraLocalData() const {
286     return getLocalData() + 1;
287   }
288   
289   void *getNonLocalData() const {
290     return static_cast<char*>(Base::Data) + asDerived()->getLocalDataSize();
291   }
292
293   struct HasNoInnerType {};
294   HasNoInnerType getInnerType() const { return HasNoInnerType(); }
295
296   TypeLoc getInnerTypeLoc() const {
297     return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
298   }
299
300 private:
301   unsigned getInnerTypeSize() const {
302     return getInnerTypeSize(asDerived()->getInnerType());
303   }
304
305   unsigned getInnerTypeSize(HasNoInnerType _) const {
306     return 0;
307   }
308
309   unsigned getInnerTypeSize(QualType _) const {
310     return getInnerTypeLoc().getFullDataSize();
311   }
312
313   TypeLoc getNextTypeLoc(HasNoInnerType _) const {
314     return TypeLoc();
315   }
316
317   TypeLoc getNextTypeLoc(QualType T) const {
318     return TypeLoc(T, getNonLocalData());
319   }
320 };
321
322 /// A metaprogramming class designed for concrete subtypes of abstract
323 /// types where all subtypes share equivalently-structured source
324 /// information.  See the note on ConcreteTypeLoc.
325 template <class Base, class Derived, class TypeClass>
326 class InheritingConcreteTypeLoc : public Base {
327 public:
328   static bool classof(const TypeLoc *TL) {
329     return Derived::classofType(TL->getTypePtr());
330   }
331   static bool classof(const UnqualTypeLoc *TL) {
332     return Derived::classofType(TL->getTypePtr());
333   }
334   static bool classof(const Derived *TL) {
335     return true;
336   }
337
338   TypeClass *getTypePtr() const {
339     return cast<TypeClass>(Base::getTypePtr());
340   }
341 };
342
343 struct TypeSpecLocInfo {
344   SourceLocation NameLoc;
345 };
346
347 /// \brief A reasonable base class for TypeLocs that correspond to
348 /// types that are written as a type-specifier.
349 template <class Derived, class TypeClass, class LocalData = TypeSpecLocInfo>
350 class TypeSpecTypeLoc
351   : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
352 public:
353   SourceLocation getNameLoc() const {
354     return this->getLocalData()->NameLoc;
355   }
356   void setNameLoc(SourceLocation Loc) {
357     this->getLocalData()->NameLoc = Loc;
358   }
359   SourceRange getSourceRange() const {
360     return SourceRange(getNameLoc(), getNameLoc());
361   }
362   void initializeLocal(SourceLocation Loc) {
363     setNameLoc(Loc);
364   }
365 };
366
367 /// \brief Wrapper for source info for typedefs.
368 class TypedefTypeLoc : public TypeSpecTypeLoc<TypedefTypeLoc,TypedefType> {
369 public:
370   TypedefDecl *getTypedefDecl() const {
371     return getTypePtr()->getDecl();
372   }
373 };
374
375
376 /// \brief Wrapper for source info for builtin types.
377 class BuiltinTypeLoc : public TypeSpecTypeLoc<BuiltinTypeLoc,
378                                               BuiltinType> {
379 };
380
381 /// \brief Wrapper for template type parameters.
382 class TemplateTypeParmTypeLoc : public TypeSpecTypeLoc<TemplateTypeParmTypeLoc,
383                                                        TemplateTypeParmType> {
384 };
385
386 /// \brief Wrapper for substituted template type parameters.
387 class SubstTemplateTypeParmTypeLoc :
388     public TypeSpecTypeLoc<SubstTemplateTypeParmTypeLoc,
389                            SubstTemplateTypeParmType> {
390 };
391
392
393 struct ObjCProtocolListLocInfo {
394   SourceLocation LAngleLoc;
395   SourceLocation RAngleLoc;
396 };
397
398 // A helper class for defining ObjC TypeLocs that can qualified with
399 // protocols.
400 //
401 // TypeClass basically has to be either ObjCInterfaceType or
402 // ObjCObjectPointerType.
403 template <class Derived, class TypeClass, class LocalData>
404 class ObjCProtocolListTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
405                                                        Derived,
406                                                        TypeClass,
407                                                        LocalData> {
408   // SourceLocations are stored after Info, one for each Protocol.
409   SourceLocation *getProtocolLocArray() const {
410     return (SourceLocation*) this->getExtraLocalData();
411   }
412
413 protected:
414   void initializeLocalBase(SourceLocation Loc) {
415     setLAngleLoc(Loc);
416     setRAngleLoc(Loc);
417     for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
418       setProtocolLoc(i, Loc);
419   }
420
421 public:
422   SourceLocation getLAngleLoc() const {
423     return this->getLocalData()->LAngleLoc;
424   }
425   void setLAngleLoc(SourceLocation Loc) {
426     this->getLocalData()->LAngleLoc = Loc;
427   }
428
429   SourceLocation getRAngleLoc() const {
430     return this->getLocalData()->RAngleLoc;
431   }
432   void setRAngleLoc(SourceLocation Loc) {
433     this->getLocalData()->RAngleLoc = Loc;
434   }
435
436   unsigned getNumProtocols() const {
437     return this->getTypePtr()->getNumProtocols();
438   }
439
440   SourceLocation getProtocolLoc(unsigned i) const {
441     assert(i < getNumProtocols() && "Index is out of bounds!");
442     return getProtocolLocArray()[i];
443   }
444   void setProtocolLoc(unsigned i, SourceLocation Loc) {
445     assert(i < getNumProtocols() && "Index is out of bounds!");
446     getProtocolLocArray()[i] = Loc;
447   }
448
449   ObjCProtocolDecl *getProtocol(unsigned i) const {
450     assert(i < getNumProtocols() && "Index is out of bounds!");
451     return *(this->getTypePtr()->qual_begin() + i);
452   }
453   
454   SourceRange getSourceRange() const {
455     return SourceRange(getLAngleLoc(), getRAngleLoc());
456   }
457
458   void initializeLocal(SourceLocation Loc) {
459     initializeLocalBase(Loc);
460   }
461
462   unsigned getExtraLocalDataSize() const {
463     return this->getNumProtocols() * sizeof(SourceLocation);
464   }
465 };
466
467
468 struct ObjCInterfaceLocInfo : ObjCProtocolListLocInfo {
469   SourceLocation NameLoc;
470 };
471
472 /// \brief Wrapper for source info for ObjC interfaces.
473 class ObjCInterfaceTypeLoc :
474     public ObjCProtocolListTypeLoc<ObjCInterfaceTypeLoc,
475                                    ObjCInterfaceType,
476                                    ObjCInterfaceLocInfo> {
477 public:
478   ObjCInterfaceDecl *getIFaceDecl() const {
479     return getTypePtr()->getDecl();
480   }
481
482   SourceLocation getNameLoc() const {
483     return getLocalData()->NameLoc;
484   }
485
486   void setNameLoc(SourceLocation Loc) {
487     getLocalData()->NameLoc = Loc;
488   }
489
490   SourceRange getSourceRange() const {
491     if (getNumProtocols()) 
492       return SourceRange(getNameLoc(), getRAngleLoc());
493     else
494       return SourceRange(getNameLoc(), getNameLoc());
495   }
496
497   void initializeLocal(SourceLocation Loc) {
498     initializeLocalBase(Loc);
499     setNameLoc(Loc);
500   }
501 };
502
503
504 struct ObjCObjectPointerLocInfo : ObjCProtocolListLocInfo {
505   SourceLocation StarLoc;
506   bool HasProtocols;
507   bool HasBaseType;
508 };
509
510 /// Wraps an ObjCPointerType with source location information.  Note
511 /// that not all ObjCPointerTypes actually have a star location; nor
512 /// are protocol locations necessarily written in the source just
513 /// because they're present on the type.
514 class ObjCObjectPointerTypeLoc :
515     public ObjCProtocolListTypeLoc<ObjCObjectPointerTypeLoc,
516                                    ObjCObjectPointerType,
517                                    ObjCObjectPointerLocInfo> {
518 public:
519   bool hasProtocolsAsWritten() const {
520     return getLocalData()->HasProtocols;
521   }
522
523   void setHasProtocolsAsWritten(bool HasProtocols) {
524     getLocalData()->HasProtocols = HasProtocols;
525   }
526
527   bool hasBaseTypeAsWritten() const {
528     return getLocalData()->HasBaseType;
529   }
530
531   void setHasBaseTypeAsWritten(bool HasBaseType) {
532     getLocalData()->HasBaseType = HasBaseType;
533   }
534
535   SourceLocation getStarLoc() const {
536     return getLocalData()->StarLoc;
537   }
538
539   void setStarLoc(SourceLocation Loc) {
540     getLocalData()->StarLoc = Loc;
541   }
542
543   SourceRange getSourceRange() const {
544     // Being written with protocols is incompatible with being written
545     // with a star.
546     if (hasProtocolsAsWritten())
547       return SourceRange(getLAngleLoc(), getRAngleLoc());
548     else
549       return SourceRange(getStarLoc(), getStarLoc());
550   }
551
552   void initializeLocal(SourceLocation Loc) {
553     initializeLocalBase(Loc);
554     setHasProtocolsAsWritten(false);
555     setHasBaseTypeAsWritten(false);
556     setStarLoc(Loc);
557   }
558
559   TypeLoc getBaseTypeLoc() const {
560     return getInnerTypeLoc();
561   }
562
563   QualType getInnerType() const {
564     return getTypePtr()->getPointeeType();
565   }
566 };
567
568
569 struct PointerLikeLocInfo {
570   SourceLocation StarLoc;
571 };
572
573 /// A base class for 
574 template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
575 class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
576                                                   TypeClass, LocalData> {
577 public:  
578   SourceLocation getSigilLoc() const {
579     return this->getLocalData()->StarLoc;
580   }
581   void setSigilLoc(SourceLocation Loc) {
582     this->getLocalData()->StarLoc = Loc;
583   }
584
585   TypeLoc getPointeeLoc() const {
586     return this->getInnerTypeLoc();
587   }
588
589   SourceRange getSourceRange() const {
590     return SourceRange(getSigilLoc(), getSigilLoc());
591   }
592
593   void initializeLocal(SourceLocation Loc) {
594     setSigilLoc(Loc);
595   }
596
597   QualType getInnerType() const {
598     return this->getTypePtr()->getPointeeType();
599   }
600 };
601
602
603 /// \brief Wrapper for source info for pointers.
604 class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
605                                                  PointerType> {
606 public:
607   SourceLocation getStarLoc() const {
608     return getSigilLoc();
609   }
610   void setStarLoc(SourceLocation Loc) {
611     setSigilLoc(Loc);
612   }
613 };
614
615
616 /// \brief Wrapper for source info for block pointers.
617 class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
618                                                       BlockPointerType> {
619 public:
620   SourceLocation getCaretLoc() const {
621     return getSigilLoc();
622   }
623   void setCaretLoc(SourceLocation Loc) {
624     setSigilLoc(Loc);
625   }
626 };
627
628
629 /// \brief Wrapper for source info for member pointers.
630 class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
631                                                        MemberPointerType> {
632 public:
633   SourceLocation getStarLoc() const {
634     return getSigilLoc();
635   }
636   void setStarLoc(SourceLocation Loc) {
637     setSigilLoc(Loc);
638   }
639 };
640
641
642 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
643                                                    ReferenceType> {
644 public:
645   QualType getInnerType() const {
646     return getTypePtr()->getPointeeTypeAsWritten();
647   }
648 };
649
650 class LValueReferenceTypeLoc :
651     public InheritingConcreteTypeLoc<ReferenceTypeLoc,
652                                      LValueReferenceTypeLoc,
653                                      LValueReferenceType> {
654 public:
655   SourceLocation getAmpLoc() const {
656     return getSigilLoc();
657   }
658   void setAmpLoc(SourceLocation Loc) {
659     setSigilLoc(Loc);
660   }
661 };
662
663 class RValueReferenceTypeLoc :
664     public InheritingConcreteTypeLoc<ReferenceTypeLoc,
665                                      RValueReferenceTypeLoc,
666                                      RValueReferenceType> {
667 public:
668   SourceLocation getAmpAmpLoc() const {
669     return getSigilLoc();
670   }
671   void setAmpAmpLoc(SourceLocation Loc) {
672     setSigilLoc(Loc);
673   }
674 };
675
676
677 struct FunctionLocInfo {
678   SourceLocation LParenLoc, RParenLoc;
679 };
680
681 /// \brief Wrapper for source info for functions.
682 class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
683                                                FunctionTypeLoc,
684                                                FunctionType,
685                                                FunctionLocInfo> {
686   // ParmVarDecls* are stored after Info, one for each argument.
687   ParmVarDecl **getParmArray() const {
688     return (ParmVarDecl**) getExtraLocalData();
689   }
690
691 public:
692   SourceLocation getLParenLoc() const {
693     return getLocalData()->LParenLoc;
694   }
695   void setLParenLoc(SourceLocation Loc) {
696     getLocalData()->LParenLoc = Loc;
697   }
698
699   SourceLocation getRParenLoc() const {
700     return getLocalData()->RParenLoc;
701   }
702   void setRParenLoc(SourceLocation Loc) {
703     getLocalData()->RParenLoc = Loc;
704   }
705
706   unsigned getNumArgs() const {
707     if (isa<FunctionNoProtoType>(getTypePtr()))
708       return 0;
709     return cast<FunctionProtoType>(getTypePtr())->getNumArgs();
710   }
711   ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; }
712   void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
713
714   TypeLoc getArgLoc(unsigned i) const;
715
716   TypeLoc getResultLoc() const {
717     return getInnerTypeLoc();
718   }
719
720   SourceRange getSourceRange() const {
721     return SourceRange(getLParenLoc(), getRParenLoc());
722   }
723
724   void initializeLocal(SourceLocation Loc) {
725     setLParenLoc(Loc);
726     setRParenLoc(Loc);
727     for (unsigned i = 0, e = getNumArgs(); i != e; ++i)
728       setArg(i, NULL);
729   }
730
731   /// \brief Returns the size of the type source info data block that is
732   /// specific to this type.
733   unsigned getExtraLocalDataSize() const {
734     return getNumArgs() * sizeof(ParmVarDecl*);
735   }
736
737   QualType getInnerType() const { return getTypePtr()->getResultType(); }
738 };
739
740 class FunctionProtoTypeLoc :
741     public InheritingConcreteTypeLoc<FunctionTypeLoc,
742                                      FunctionProtoTypeLoc,
743                                      FunctionProtoType> {
744 };
745
746 class FunctionNoProtoTypeLoc :
747     public InheritingConcreteTypeLoc<FunctionTypeLoc,
748                                      FunctionNoProtoTypeLoc,
749                                      FunctionNoProtoType> {
750 };
751
752
753 struct ArrayLocInfo {
754   SourceLocation LBracketLoc, RBracketLoc;
755   Expr *Size;
756 };
757
758 /// \brief Wrapper for source info for arrays.
759 class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
760                                             ArrayTypeLoc,
761                                             ArrayType,
762                                             ArrayLocInfo> {
763 public:
764   SourceLocation getLBracketLoc() const {
765     return getLocalData()->LBracketLoc;
766   }
767   void setLBracketLoc(SourceLocation Loc) {
768     getLocalData()->LBracketLoc = Loc;
769   }
770
771   SourceLocation getRBracketLoc() const {
772     return getLocalData()->RBracketLoc;
773   }
774   void setRBracketLoc(SourceLocation Loc) {
775     getLocalData()->RBracketLoc = Loc;
776   }
777
778   SourceRange getBracketsRange() const {
779     return SourceRange(getLBracketLoc(), getRBracketLoc());
780   }
781
782   Expr *getSizeExpr() const {
783     return getLocalData()->Size;
784   }
785   void setSizeExpr(Expr *Size) {
786     getLocalData()->Size = Size;
787   }
788
789   TypeLoc getElementLoc() const {
790     return getInnerTypeLoc();
791   }
792
793   SourceRange getSourceRange() const {
794     return SourceRange(getLBracketLoc(), getRBracketLoc());
795   }
796
797   void initializeLocal(SourceLocation Loc) {
798     setLBracketLoc(Loc);
799     setRBracketLoc(Loc);
800     setSizeExpr(NULL);
801   }
802
803   QualType getInnerType() const { return getTypePtr()->getElementType(); }
804 };
805
806 class ConstantArrayTypeLoc :
807     public InheritingConcreteTypeLoc<ArrayTypeLoc,
808                                      ConstantArrayTypeLoc,
809                                      ConstantArrayType> {
810 };
811
812 class IncompleteArrayTypeLoc :
813     public InheritingConcreteTypeLoc<ArrayTypeLoc,
814                                      IncompleteArrayTypeLoc,
815                                      IncompleteArrayType> {
816 };
817
818 class DependentSizedArrayTypeLoc :
819     public InheritingConcreteTypeLoc<ArrayTypeLoc,
820                                      DependentSizedArrayTypeLoc,
821                                      DependentSizedArrayType> {
822
823 };
824
825 class VariableArrayTypeLoc :
826     public InheritingConcreteTypeLoc<ArrayTypeLoc,
827                                      VariableArrayTypeLoc,
828                                      VariableArrayType> {
829 };
830
831
832 // Location information for a TemplateName.  Rudimentary for now.
833 struct TemplateNameLocInfo {
834   SourceLocation NameLoc;
835 };
836
837 struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
838   SourceLocation LAngleLoc;
839   SourceLocation RAngleLoc;
840 };
841
842 class TemplateSpecializationTypeLoc :
843     public ConcreteTypeLoc<UnqualTypeLoc,
844                            TemplateSpecializationTypeLoc,
845                            TemplateSpecializationType,
846                            TemplateSpecializationLocInfo> {
847 public:
848   SourceLocation getLAngleLoc() const {
849     return getLocalData()->LAngleLoc;
850   }
851   void setLAngleLoc(SourceLocation Loc) {
852     getLocalData()->LAngleLoc = Loc;
853   }
854
855   SourceLocation getRAngleLoc() const {
856     return getLocalData()->RAngleLoc;
857   }
858   void setRAngleLoc(SourceLocation Loc) {
859     getLocalData()->RAngleLoc = Loc;
860   }
861
862   unsigned getNumArgs() const {
863     return getTypePtr()->getNumArgs();
864   }
865   void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
866 #ifndef NDEBUG
867     AI.validateForArgument(getTypePtr()->getArg(i));
868 #endif
869     getArgInfos()[i] = AI;
870   }
871   TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
872     return getArgInfos()[i];
873   }
874
875   TemplateArgumentLoc getArgLoc(unsigned i) const {
876     return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
877   }
878
879   SourceLocation getTemplateNameLoc() const {
880     return getLocalData()->NameLoc;
881   }
882   void setTemplateNameLoc(SourceLocation Loc) {
883     getLocalData()->NameLoc = Loc;
884   }
885
886   /// \brief - Copy the location information from the given info.
887   void copy(TemplateSpecializationTypeLoc Loc) {
888     unsigned size = getFullDataSize();
889     assert(size == Loc.getFullDataSize());
890
891     // We're potentially copying Expr references here.  We don't
892     // bother retaining them because DeclaratorInfos live forever, so
893     // as long as the Expr was retained when originally written into
894     // the TypeLoc, we're okay.
895     memcpy(Data, Loc.Data, size);
896   }
897
898   SourceRange getSourceRange() const {
899     return SourceRange(getTemplateNameLoc(), getRAngleLoc());
900   }
901
902   void initializeLocal(SourceLocation Loc) {
903     setLAngleLoc(Loc);
904     setRAngleLoc(Loc);
905     setTemplateNameLoc(Loc);
906
907     for (unsigned i = 0, e = getNumArgs(); i != e; ++i) {
908       TemplateArgumentLocInfo Info;
909 #ifndef NDEBUG
910       // If asserts are enabled, be sure to initialize the argument
911       // loc with the right kind of pointer.
912       switch (getTypePtr()->getArg(i).getKind()) {
913       case TemplateArgument::Expression:
914       case TemplateArgument::Declaration:
915         Info = TemplateArgumentLocInfo((Expr*) 0);
916         break;
917
918       case TemplateArgument::Type:
919         Info = TemplateArgumentLocInfo((DeclaratorInfo*) 0);
920         break;
921
922       case TemplateArgument::Integral:
923       case TemplateArgument::Pack:
924       case TemplateArgument::Null:
925         // K_None is fine.
926         break;
927       }
928 #endif
929       getArgInfos()[i] = Info;
930     }
931   }
932
933   unsigned getExtraLocalDataSize() const {
934     return getNumArgs() * sizeof(TemplateArgumentLocInfo);
935   }
936
937 private:
938   TemplateArgumentLocInfo *getArgInfos() const {
939     return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
940   }
941 };
942
943 // None of these types have proper implementations yet.
944
945 class VectorTypeLoc : public TypeSpecTypeLoc<VectorTypeLoc, VectorType> {
946 };
947
948 class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
949                                                           ExtVectorTypeLoc,
950                                                           ExtVectorType> {
951 };
952
953 // For some reason, this isn't a subtype of VectorType.
954 class DependentSizedExtVectorTypeLoc :
955     public TypeSpecTypeLoc<DependentSizedExtVectorTypeLoc,
956                            DependentSizedExtVectorType> {
957 };
958
959 class FixedWidthIntTypeLoc : public TypeSpecTypeLoc<FixedWidthIntTypeLoc,
960                                                     FixedWidthIntType> {
961 };
962
963 class ComplexTypeLoc : public TypeSpecTypeLoc<ComplexTypeLoc,
964                                               ComplexType> {
965 };
966
967 class TypeOfExprTypeLoc : public TypeSpecTypeLoc<TypeOfExprTypeLoc,
968                                                  TypeOfExprType> {
969 };
970
971 class TypeOfTypeLoc : public TypeSpecTypeLoc<TypeOfTypeLoc, TypeOfType> {
972 };
973
974 class DecltypeTypeLoc : public TypeSpecTypeLoc<DecltypeTypeLoc, DecltypeType> {
975 };
976
977 class TagTypeLoc : public TypeSpecTypeLoc<TagTypeLoc, TagType> {
978 };
979
980 class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
981                                                        RecordTypeLoc,
982                                                        RecordType> {
983 };
984
985 class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
986                                                      EnumTypeLoc,
987                                                      EnumType> {
988 };
989
990 class ElaboratedTypeLoc : public TypeSpecTypeLoc<ElaboratedTypeLoc,
991                                                  ElaboratedType> {
992 };
993
994 class QualifiedNameTypeLoc : public TypeSpecTypeLoc<QualifiedNameTypeLoc,
995                                                     QualifiedNameType> {
996 };
997
998 class TypenameTypeLoc : public TypeSpecTypeLoc<TypenameTypeLoc,
999                                                TypenameType> {
1000 };
1001
1002 }
1003
1004 #endif