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