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