]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/AST/TypeLoc.h
Merge ACPICA 20150515.
[FreeBSD/FreeBSD.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(nullptr), Data(nullptr) { }
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() == nullptr || 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(nullptr);
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 AdjustedLocInfo { }; // Nothing.
982
983 class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc,
984                                                AdjustedType, AdjustedLocInfo> {
985 public:
986   TypeLoc getOriginalLoc() const {
987     return getInnerTypeLoc();
988   }
989
990   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
991     // do nothing
992   }
993
994   QualType getInnerType() const {
995     // The inner type is the undecayed type, since that's what we have source
996     // location information for.
997     return getTypePtr()->getOriginalType();
998   }
999
1000   SourceRange getLocalSourceRange() const {
1001     return SourceRange();
1002   }
1003
1004   unsigned getLocalDataSize() const {
1005     // sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique
1006     // anyway.  TypeLocBuilder can't handle data sizes of 1.
1007     return 0;  // No data.
1008   }
1009 };
1010
1011 /// \brief Wrapper for source info for pointers decayed from arrays and
1012 /// functions.
1013 class DecayedTypeLoc : public InheritingConcreteTypeLoc<
1014                            AdjustedTypeLoc, DecayedTypeLoc, DecayedType> {
1015 };
1016
1017 struct PointerLikeLocInfo {
1018   SourceLocation StarLoc;
1019 };
1020
1021 /// A base class for
1022 template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
1023 class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
1024                                                   TypeClass, LocalData> {
1025 public:
1026   SourceLocation getSigilLoc() const {
1027     return this->getLocalData()->StarLoc;
1028   }
1029   void setSigilLoc(SourceLocation Loc) {
1030     this->getLocalData()->StarLoc = Loc;
1031   }
1032
1033   TypeLoc getPointeeLoc() const {
1034     return this->getInnerTypeLoc();
1035   }
1036
1037   SourceRange getLocalSourceRange() const {
1038     return SourceRange(getSigilLoc(), getSigilLoc());
1039   }
1040
1041   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1042     setSigilLoc(Loc);
1043   }
1044
1045   QualType getInnerType() const {
1046     return this->getTypePtr()->getPointeeType();
1047   }
1048 };
1049
1050
1051 /// \brief Wrapper for source info for pointers.
1052 class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
1053                                                  PointerType> {
1054 public:
1055   SourceLocation getStarLoc() const {
1056     return getSigilLoc();
1057   }
1058   void setStarLoc(SourceLocation Loc) {
1059     setSigilLoc(Loc);
1060   }
1061 };
1062
1063
1064 /// \brief Wrapper for source info for block pointers.
1065 class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
1066                                                       BlockPointerType> {
1067 public:
1068   SourceLocation getCaretLoc() const {
1069     return getSigilLoc();
1070   }
1071   void setCaretLoc(SourceLocation Loc) {
1072     setSigilLoc(Loc);
1073   }
1074 };
1075
1076 struct MemberPointerLocInfo : public PointerLikeLocInfo {
1077   TypeSourceInfo *ClassTInfo;
1078 };
1079
1080 /// \brief Wrapper for source info for member pointers.
1081 class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
1082                                                        MemberPointerType,
1083                                                        MemberPointerLocInfo> {
1084 public:
1085   SourceLocation getStarLoc() const {
1086     return getSigilLoc();
1087   }
1088   void setStarLoc(SourceLocation Loc) {
1089     setSigilLoc(Loc);
1090   }
1091
1092   const Type *getClass() const {
1093     return getTypePtr()->getClass();
1094   }
1095   TypeSourceInfo *getClassTInfo() const {
1096     return getLocalData()->ClassTInfo;
1097   }
1098   void setClassTInfo(TypeSourceInfo* TI) {
1099     getLocalData()->ClassTInfo = TI;
1100   }
1101
1102   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1103     setSigilLoc(Loc);
1104     setClassTInfo(nullptr);
1105   }
1106
1107   SourceRange getLocalSourceRange() const {
1108     if (TypeSourceInfo *TI = getClassTInfo())
1109       return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
1110     else
1111       return SourceRange(getStarLoc());
1112   }
1113 };
1114
1115 /// Wraps an ObjCPointerType with source location information.
1116 class ObjCObjectPointerTypeLoc :
1117     public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
1118                               ObjCObjectPointerType> {
1119 public:
1120   SourceLocation getStarLoc() const {
1121     return getSigilLoc();
1122   }
1123
1124   void setStarLoc(SourceLocation Loc) {
1125     setSigilLoc(Loc);
1126   }
1127 };
1128
1129
1130 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
1131                                                    ReferenceType> {
1132 public:
1133   QualType getInnerType() const {
1134     return getTypePtr()->getPointeeTypeAsWritten();
1135   }
1136 };
1137
1138 class LValueReferenceTypeLoc :
1139     public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1140                                      LValueReferenceTypeLoc,
1141                                      LValueReferenceType> {
1142 public:
1143   SourceLocation getAmpLoc() const {
1144     return getSigilLoc();
1145   }
1146   void setAmpLoc(SourceLocation Loc) {
1147     setSigilLoc(Loc);
1148   }
1149 };
1150
1151 class RValueReferenceTypeLoc :
1152     public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1153                                      RValueReferenceTypeLoc,
1154                                      RValueReferenceType> {
1155 public:
1156   SourceLocation getAmpAmpLoc() const {
1157     return getSigilLoc();
1158   }
1159   void setAmpAmpLoc(SourceLocation Loc) {
1160     setSigilLoc(Loc);
1161   }
1162 };
1163
1164
1165 struct FunctionLocInfo {
1166   SourceLocation LocalRangeBegin;
1167   SourceLocation LParenLoc;
1168   SourceLocation RParenLoc;
1169   SourceLocation LocalRangeEnd;
1170 };
1171
1172 /// \brief Wrapper for source info for functions.
1173 class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1174                                                FunctionTypeLoc,
1175                                                FunctionType,
1176                                                FunctionLocInfo> {
1177 public:
1178   SourceLocation getLocalRangeBegin() const {
1179     return getLocalData()->LocalRangeBegin;
1180   }
1181   void setLocalRangeBegin(SourceLocation L) {
1182     getLocalData()->LocalRangeBegin = L;
1183   }
1184
1185   SourceLocation getLocalRangeEnd() const {
1186     return getLocalData()->LocalRangeEnd;
1187   }
1188   void setLocalRangeEnd(SourceLocation L) {
1189     getLocalData()->LocalRangeEnd = L;
1190   }
1191
1192   SourceLocation getLParenLoc() const {
1193     return this->getLocalData()->LParenLoc;
1194   }
1195   void setLParenLoc(SourceLocation Loc) {
1196     this->getLocalData()->LParenLoc = Loc;
1197   }
1198
1199   SourceLocation getRParenLoc() const {
1200     return this->getLocalData()->RParenLoc;
1201   }
1202   void setRParenLoc(SourceLocation Loc) {
1203     this->getLocalData()->RParenLoc = Loc;
1204   }
1205
1206   SourceRange getParensRange() const {
1207     return SourceRange(getLParenLoc(), getRParenLoc());
1208   }
1209
1210   ArrayRef<ParmVarDecl *> getParams() const {
1211     return llvm::makeArrayRef(getParmArray(), getNumParams());
1212   }
1213
1214   // ParmVarDecls* are stored after Info, one for each parameter.
1215   ParmVarDecl **getParmArray() const {
1216     return (ParmVarDecl**) getExtraLocalData();
1217   }
1218
1219   unsigned getNumParams() const {
1220     if (isa<FunctionNoProtoType>(getTypePtr()))
1221       return 0;
1222     return cast<FunctionProtoType>(getTypePtr())->getNumParams();
1223   }
1224   ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; }
1225   void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
1226
1227   TypeLoc getReturnLoc() const {
1228     return getInnerTypeLoc();
1229   }
1230
1231   SourceRange getLocalSourceRange() const {
1232     return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
1233   }
1234
1235   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1236     setLocalRangeBegin(Loc);
1237     setLParenLoc(Loc);
1238     setRParenLoc(Loc);
1239     setLocalRangeEnd(Loc);
1240     for (unsigned i = 0, e = getNumParams(); i != e; ++i)
1241       setParam(i, nullptr);
1242   }
1243
1244   /// \brief Returns the size of the type source info data block that is
1245   /// specific to this type.
1246   unsigned getExtraLocalDataSize() const {
1247     return getNumParams() * sizeof(ParmVarDecl *);
1248   }
1249
1250   unsigned getExtraLocalDataAlignment() const {
1251     return llvm::alignOf<ParmVarDecl*>();
1252   }
1253
1254   QualType getInnerType() const { return getTypePtr()->getReturnType(); }
1255 };
1256
1257 class FunctionProtoTypeLoc :
1258     public InheritingConcreteTypeLoc<FunctionTypeLoc,
1259                                      FunctionProtoTypeLoc,
1260                                      FunctionProtoType> {
1261 };
1262
1263 class FunctionNoProtoTypeLoc :
1264     public InheritingConcreteTypeLoc<FunctionTypeLoc,
1265                                      FunctionNoProtoTypeLoc,
1266                                      FunctionNoProtoType> {
1267 };
1268
1269
1270 struct ArrayLocInfo {
1271   SourceLocation LBracketLoc, RBracketLoc;
1272   Expr *Size;
1273 };
1274
1275 /// \brief Wrapper for source info for arrays.
1276 class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1277                                             ArrayTypeLoc,
1278                                             ArrayType,
1279                                             ArrayLocInfo> {
1280 public:
1281   SourceLocation getLBracketLoc() const {
1282     return getLocalData()->LBracketLoc;
1283   }
1284   void setLBracketLoc(SourceLocation Loc) {
1285     getLocalData()->LBracketLoc = Loc;
1286   }
1287
1288   SourceLocation getRBracketLoc() const {
1289     return getLocalData()->RBracketLoc;
1290   }
1291   void setRBracketLoc(SourceLocation Loc) {
1292     getLocalData()->RBracketLoc = Loc;
1293   }
1294
1295   SourceRange getBracketsRange() const {
1296     return SourceRange(getLBracketLoc(), getRBracketLoc());
1297   }
1298
1299   Expr *getSizeExpr() const {
1300     return getLocalData()->Size;
1301   }
1302   void setSizeExpr(Expr *Size) {
1303     getLocalData()->Size = Size;
1304   }
1305
1306   TypeLoc getElementLoc() const {
1307     return getInnerTypeLoc();
1308   }
1309
1310   SourceRange getLocalSourceRange() const {
1311     return SourceRange(getLBracketLoc(), getRBracketLoc());
1312   }
1313
1314   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1315     setLBracketLoc(Loc);
1316     setRBracketLoc(Loc);
1317     setSizeExpr(nullptr);
1318   }
1319
1320   QualType getInnerType() const { return getTypePtr()->getElementType(); }
1321 };
1322
1323 class ConstantArrayTypeLoc :
1324     public InheritingConcreteTypeLoc<ArrayTypeLoc,
1325                                      ConstantArrayTypeLoc,
1326                                      ConstantArrayType> {
1327 };
1328
1329 class IncompleteArrayTypeLoc :
1330     public InheritingConcreteTypeLoc<ArrayTypeLoc,
1331                                      IncompleteArrayTypeLoc,
1332                                      IncompleteArrayType> {
1333 };
1334
1335 class DependentSizedArrayTypeLoc :
1336     public InheritingConcreteTypeLoc<ArrayTypeLoc,
1337                                      DependentSizedArrayTypeLoc,
1338                                      DependentSizedArrayType> {
1339
1340 };
1341
1342 class VariableArrayTypeLoc :
1343     public InheritingConcreteTypeLoc<ArrayTypeLoc,
1344                                      VariableArrayTypeLoc,
1345                                      VariableArrayType> {
1346 };
1347
1348
1349 // Location information for a TemplateName.  Rudimentary for now.
1350 struct TemplateNameLocInfo {
1351   SourceLocation NameLoc;
1352 };
1353
1354 struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
1355   SourceLocation TemplateKWLoc;
1356   SourceLocation LAngleLoc;
1357   SourceLocation RAngleLoc;
1358 };
1359
1360 class TemplateSpecializationTypeLoc :
1361     public ConcreteTypeLoc<UnqualTypeLoc,
1362                            TemplateSpecializationTypeLoc,
1363                            TemplateSpecializationType,
1364                            TemplateSpecializationLocInfo> {
1365 public:
1366   SourceLocation getTemplateKeywordLoc() const {
1367     return getLocalData()->TemplateKWLoc;
1368   }
1369   void setTemplateKeywordLoc(SourceLocation Loc) {
1370     getLocalData()->TemplateKWLoc = Loc;
1371   }
1372
1373   SourceLocation getLAngleLoc() const {
1374     return getLocalData()->LAngleLoc;
1375   }
1376   void setLAngleLoc(SourceLocation Loc) {
1377     getLocalData()->LAngleLoc = Loc;
1378   }
1379
1380   SourceLocation getRAngleLoc() const {
1381     return getLocalData()->RAngleLoc;
1382   }
1383   void setRAngleLoc(SourceLocation Loc) {
1384     getLocalData()->RAngleLoc = Loc;
1385   }
1386
1387   unsigned getNumArgs() const {
1388     return getTypePtr()->getNumArgs();
1389   }
1390   void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1391     getArgInfos()[i] = AI;
1392   }
1393   TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1394     return getArgInfos()[i];
1395   }
1396
1397   TemplateArgumentLoc getArgLoc(unsigned i) const {
1398     return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1399   }
1400
1401   SourceLocation getTemplateNameLoc() const {
1402     return getLocalData()->NameLoc;
1403   }
1404   void setTemplateNameLoc(SourceLocation Loc) {
1405     getLocalData()->NameLoc = Loc;
1406   }
1407
1408   /// \brief - Copy the location information from the given info.
1409   void copy(TemplateSpecializationTypeLoc Loc) {
1410     unsigned size = getFullDataSize();
1411     assert(size == Loc.getFullDataSize());
1412
1413     // We're potentially copying Expr references here.  We don't
1414     // bother retaining them because TypeSourceInfos live forever, so
1415     // as long as the Expr was retained when originally written into
1416     // the TypeLoc, we're okay.
1417     memcpy(Data, Loc.Data, size);
1418   }
1419
1420   SourceRange getLocalSourceRange() const {
1421     if (getTemplateKeywordLoc().isValid())
1422       return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1423     else
1424       return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1425   }
1426
1427   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1428     setTemplateKeywordLoc(Loc);
1429     setTemplateNameLoc(Loc);
1430     setLAngleLoc(Loc);
1431     setRAngleLoc(Loc);
1432     initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
1433                       getArgInfos(), Loc);
1434   }
1435
1436   static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
1437                                 const TemplateArgument *Args,
1438                                 TemplateArgumentLocInfo *ArgInfos,
1439                                 SourceLocation Loc);
1440
1441   unsigned getExtraLocalDataSize() const {
1442     return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1443   }
1444
1445   unsigned getExtraLocalDataAlignment() const {
1446     return llvm::alignOf<TemplateArgumentLocInfo>();
1447   }
1448
1449 private:
1450   TemplateArgumentLocInfo *getArgInfos() const {
1451     return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1452   }
1453 };
1454
1455 //===----------------------------------------------------------------------===//
1456 //
1457 //  All of these need proper implementations.
1458 //
1459 //===----------------------------------------------------------------------===//
1460
1461 // FIXME: size expression and attribute locations (or keyword if we
1462 // ever fully support altivec syntax).
1463 class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1464                                                        VectorTypeLoc,
1465                                                        VectorType> {
1466 };
1467
1468 // FIXME: size expression and attribute locations.
1469 class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
1470                                                           ExtVectorTypeLoc,
1471                                                           ExtVectorType> {
1472 };
1473
1474 // FIXME: attribute locations.
1475 // For some reason, this isn't a subtype of VectorType.
1476 class DependentSizedExtVectorTypeLoc :
1477     public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1478                                      DependentSizedExtVectorTypeLoc,
1479                                      DependentSizedExtVectorType> {
1480 };
1481
1482 // FIXME: location of the '_Complex' keyword.
1483 class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1484                                                         ComplexTypeLoc,
1485                                                         ComplexType> {
1486 };
1487
1488 struct TypeofLocInfo {
1489   SourceLocation TypeofLoc;
1490   SourceLocation LParenLoc;
1491   SourceLocation RParenLoc;
1492 };
1493
1494 struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
1495 };
1496
1497 struct TypeOfTypeLocInfo : public TypeofLocInfo {
1498   TypeSourceInfo* UnderlyingTInfo;
1499 };
1500
1501 template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
1502 class TypeofLikeTypeLoc
1503   : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
1504 public:
1505   SourceLocation getTypeofLoc() const {
1506     return this->getLocalData()->TypeofLoc;
1507   }
1508   void setTypeofLoc(SourceLocation Loc) {
1509     this->getLocalData()->TypeofLoc = Loc;
1510   }
1511
1512   SourceLocation getLParenLoc() const {
1513     return this->getLocalData()->LParenLoc;
1514   }
1515   void setLParenLoc(SourceLocation Loc) {
1516     this->getLocalData()->LParenLoc = Loc;
1517   }
1518
1519   SourceLocation getRParenLoc() const {
1520     return this->getLocalData()->RParenLoc;
1521   }
1522   void setRParenLoc(SourceLocation Loc) {
1523     this->getLocalData()->RParenLoc = Loc;
1524   }
1525
1526   SourceRange getParensRange() const {
1527     return SourceRange(getLParenLoc(), getRParenLoc());
1528   }
1529   void setParensRange(SourceRange range) {
1530       setLParenLoc(range.getBegin());
1531       setRParenLoc(range.getEnd());
1532   }
1533
1534   SourceRange getLocalSourceRange() const {
1535     return SourceRange(getTypeofLoc(), getRParenLoc());
1536   }
1537
1538   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1539     setTypeofLoc(Loc);
1540     setLParenLoc(Loc);
1541     setRParenLoc(Loc);
1542   }
1543 };
1544
1545 class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
1546                                                    TypeOfExprType,
1547                                                    TypeOfExprTypeLocInfo> {
1548 public:
1549   Expr* getUnderlyingExpr() const {
1550     return getTypePtr()->getUnderlyingExpr();
1551   }
1552   // Reimplemented to account for GNU/C++ extension
1553   //     typeof unary-expression
1554   // where there are no parentheses.
1555   SourceRange getLocalSourceRange() const;
1556 };
1557
1558 class TypeOfTypeLoc
1559   : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
1560 public:
1561   QualType getUnderlyingType() const {
1562     return this->getTypePtr()->getUnderlyingType();
1563   }
1564   TypeSourceInfo* getUnderlyingTInfo() const {
1565     return this->getLocalData()->UnderlyingTInfo;
1566   }
1567   void setUnderlyingTInfo(TypeSourceInfo* TI) const {
1568     this->getLocalData()->UnderlyingTInfo = TI;
1569   }
1570
1571   void initializeLocal(ASTContext &Context, SourceLocation Loc);
1572 };
1573
1574 // FIXME: location of the 'decltype' and parens.
1575 class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1576                                                          DecltypeTypeLoc,
1577                                                          DecltypeType> {
1578 public:
1579   Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
1580 };
1581
1582 struct UnaryTransformTypeLocInfo {
1583   // FIXME: While there's only one unary transform right now, future ones may
1584   // need different representations
1585   SourceLocation KWLoc, LParenLoc, RParenLoc;
1586   TypeSourceInfo *UnderlyingTInfo;
1587 };
1588
1589 class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1590                                                     UnaryTransformTypeLoc,
1591                                                     UnaryTransformType,
1592                                                     UnaryTransformTypeLocInfo> {
1593 public:
1594   SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
1595   void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
1596
1597   SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
1598   void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
1599
1600   SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
1601   void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
1602
1603   TypeSourceInfo* getUnderlyingTInfo() const {
1604     return getLocalData()->UnderlyingTInfo;
1605   }
1606   void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
1607     getLocalData()->UnderlyingTInfo = TInfo;
1608   }
1609
1610   SourceRange getLocalSourceRange() const {
1611     return SourceRange(getKWLoc(), getRParenLoc());
1612   }
1613
1614   SourceRange getParensRange() const {
1615     return SourceRange(getLParenLoc(), getRParenLoc());
1616   }
1617   void setParensRange(SourceRange Range) {
1618     setLParenLoc(Range.getBegin());
1619     setRParenLoc(Range.getEnd());
1620   }
1621
1622   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1623     setKWLoc(Loc);
1624     setRParenLoc(Loc);
1625     setLParenLoc(Loc);
1626   }
1627 };
1628
1629 class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1630                                                         AutoTypeLoc,
1631                                                         AutoType> {
1632 };
1633
1634 struct ElaboratedLocInfo {
1635   SourceLocation ElaboratedKWLoc;
1636   /// \brief Data associated with the nested-name-specifier location.
1637   void *QualifierData;
1638 };
1639
1640 class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1641                                                  ElaboratedTypeLoc,
1642                                                  ElaboratedType,
1643                                                  ElaboratedLocInfo> {
1644 public:
1645   SourceLocation getElaboratedKeywordLoc() const {
1646     return this->getLocalData()->ElaboratedKWLoc;
1647   }
1648   void setElaboratedKeywordLoc(SourceLocation Loc) {
1649     this->getLocalData()->ElaboratedKWLoc = Loc;
1650   }
1651
1652   NestedNameSpecifierLoc getQualifierLoc() const {
1653     return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1654                                   getLocalData()->QualifierData);
1655   }
1656
1657   void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1658     assert(QualifierLoc.getNestedNameSpecifier()
1659                                             == getTypePtr()->getQualifier() &&
1660            "Inconsistent nested-name-specifier pointer");
1661     getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1662   }
1663
1664   SourceRange getLocalSourceRange() const {
1665     if (getElaboratedKeywordLoc().isValid())
1666       if (getQualifierLoc())
1667         return SourceRange(getElaboratedKeywordLoc(),
1668                            getQualifierLoc().getEndLoc());
1669       else
1670         return SourceRange(getElaboratedKeywordLoc());
1671     else
1672       return getQualifierLoc().getSourceRange();
1673   }
1674
1675   void initializeLocal(ASTContext &Context, SourceLocation Loc);
1676
1677   TypeLoc getNamedTypeLoc() const {
1678     return getInnerTypeLoc();
1679   }
1680
1681   QualType getInnerType() const {
1682     return getTypePtr()->getNamedType();
1683   }
1684
1685   void copy(ElaboratedTypeLoc Loc) {
1686     unsigned size = getFullDataSize();
1687     assert(size == Loc.getFullDataSize());
1688     memcpy(Data, Loc.Data, size);
1689   }
1690 };
1691
1692 // This is exactly the structure of an ElaboratedTypeLoc whose inner
1693 // type is some sort of TypeDeclTypeLoc.
1694 struct DependentNameLocInfo : ElaboratedLocInfo {
1695   SourceLocation NameLoc;
1696 };
1697
1698 class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1699                                                     DependentNameTypeLoc,
1700                                                     DependentNameType,
1701                                                     DependentNameLocInfo> {
1702 public:
1703   SourceLocation getElaboratedKeywordLoc() const {
1704     return this->getLocalData()->ElaboratedKWLoc;
1705   }
1706   void setElaboratedKeywordLoc(SourceLocation Loc) {
1707     this->getLocalData()->ElaboratedKWLoc = Loc;
1708   }
1709
1710   NestedNameSpecifierLoc getQualifierLoc() const {
1711     return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1712                                   getLocalData()->QualifierData);
1713   }
1714
1715   void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1716     assert(QualifierLoc.getNestedNameSpecifier()
1717                                             == getTypePtr()->getQualifier() &&
1718            "Inconsistent nested-name-specifier pointer");
1719     getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1720   }
1721
1722   SourceLocation getNameLoc() const {
1723     return this->getLocalData()->NameLoc;
1724   }
1725   void setNameLoc(SourceLocation Loc) {
1726     this->getLocalData()->NameLoc = Loc;
1727   }
1728
1729   SourceRange getLocalSourceRange() const {
1730     if (getElaboratedKeywordLoc().isValid())
1731       return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
1732     else
1733       return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
1734   }
1735
1736   void copy(DependentNameTypeLoc Loc) {
1737     unsigned size = getFullDataSize();
1738     assert(size == Loc.getFullDataSize());
1739     memcpy(Data, Loc.Data, size);
1740   }
1741
1742   void initializeLocal(ASTContext &Context, SourceLocation Loc);
1743 };
1744
1745 struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
1746   SourceLocation TemplateKWLoc;
1747   SourceLocation LAngleLoc;
1748   SourceLocation RAngleLoc;
1749   // followed by a TemplateArgumentLocInfo[]
1750 };
1751
1752 class DependentTemplateSpecializationTypeLoc :
1753     public ConcreteTypeLoc<UnqualTypeLoc,
1754                            DependentTemplateSpecializationTypeLoc,
1755                            DependentTemplateSpecializationType,
1756                            DependentTemplateSpecializationLocInfo> {
1757 public:
1758   SourceLocation getElaboratedKeywordLoc() const {
1759     return this->getLocalData()->ElaboratedKWLoc;
1760   }
1761   void setElaboratedKeywordLoc(SourceLocation Loc) {
1762     this->getLocalData()->ElaboratedKWLoc = Loc;
1763   }
1764
1765   NestedNameSpecifierLoc getQualifierLoc() const {
1766     if (!getLocalData()->QualifierData)
1767       return NestedNameSpecifierLoc();
1768
1769     return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1770                                   getLocalData()->QualifierData);
1771   }
1772
1773   void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1774     if (!QualifierLoc) {
1775       // Even if we have a nested-name-specifier in the dependent
1776       // template specialization type, we won't record the nested-name-specifier
1777       // location information when this type-source location information is
1778       // part of a nested-name-specifier.
1779       getLocalData()->QualifierData = nullptr;
1780       return;
1781     }
1782
1783     assert(QualifierLoc.getNestedNameSpecifier()
1784                                         == getTypePtr()->getQualifier() &&
1785            "Inconsistent nested-name-specifier pointer");
1786     getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1787   }
1788
1789   SourceLocation getTemplateKeywordLoc() const {
1790     return getLocalData()->TemplateKWLoc;
1791   }
1792   void setTemplateKeywordLoc(SourceLocation Loc) {
1793     getLocalData()->TemplateKWLoc = Loc;
1794   }
1795
1796   SourceLocation getTemplateNameLoc() const {
1797     return this->getLocalData()->NameLoc;
1798   }
1799   void setTemplateNameLoc(SourceLocation Loc) {
1800     this->getLocalData()->NameLoc = Loc;
1801   }
1802
1803   SourceLocation getLAngleLoc() const {
1804     return this->getLocalData()->LAngleLoc;
1805   }
1806   void setLAngleLoc(SourceLocation Loc) {
1807     this->getLocalData()->LAngleLoc = Loc;
1808   }
1809
1810   SourceLocation getRAngleLoc() const {
1811     return this->getLocalData()->RAngleLoc;
1812   }
1813   void setRAngleLoc(SourceLocation Loc) {
1814     this->getLocalData()->RAngleLoc = Loc;
1815   }
1816
1817   unsigned getNumArgs() const {
1818     return getTypePtr()->getNumArgs();
1819   }
1820
1821   void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1822     getArgInfos()[i] = AI;
1823   }
1824   TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1825     return getArgInfos()[i];
1826   }
1827
1828   TemplateArgumentLoc getArgLoc(unsigned i) const {
1829     return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1830   }
1831
1832   SourceRange getLocalSourceRange() const {
1833     if (getElaboratedKeywordLoc().isValid())
1834       return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
1835     else if (getQualifierLoc())
1836       return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
1837     else if (getTemplateKeywordLoc().isValid())
1838       return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1839     else
1840       return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1841   }
1842
1843   void copy(DependentTemplateSpecializationTypeLoc Loc) {
1844     unsigned size = getFullDataSize();
1845     assert(size == Loc.getFullDataSize());
1846     memcpy(Data, Loc.Data, size);
1847   }
1848
1849   void initializeLocal(ASTContext &Context, SourceLocation Loc);
1850
1851   unsigned getExtraLocalDataSize() const {
1852     return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1853   }
1854
1855   unsigned getExtraLocalDataAlignment() const {
1856     return llvm::alignOf<TemplateArgumentLocInfo>();
1857   }
1858
1859 private:
1860   TemplateArgumentLocInfo *getArgInfos() const {
1861     return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1862   }
1863 };
1864
1865
1866 struct PackExpansionTypeLocInfo {
1867   SourceLocation EllipsisLoc;
1868 };
1869
1870 class PackExpansionTypeLoc
1871   : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
1872                            PackExpansionType, PackExpansionTypeLocInfo> {
1873 public:
1874   SourceLocation getEllipsisLoc() const {
1875     return this->getLocalData()->EllipsisLoc;
1876   }
1877
1878   void setEllipsisLoc(SourceLocation Loc) {
1879     this->getLocalData()->EllipsisLoc = Loc;
1880   }
1881
1882   SourceRange getLocalSourceRange() const {
1883     return SourceRange(getEllipsisLoc(), getEllipsisLoc());
1884   }
1885
1886   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1887     setEllipsisLoc(Loc);
1888   }
1889
1890   TypeLoc getPatternLoc() const {
1891     return getInnerTypeLoc();
1892   }
1893
1894   QualType getInnerType() const {
1895     return this->getTypePtr()->getPattern();
1896   }
1897 };
1898
1899 struct AtomicTypeLocInfo {
1900   SourceLocation KWLoc, LParenLoc, RParenLoc;
1901 };
1902
1903 class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
1904                                              AtomicType, AtomicTypeLocInfo> {
1905 public:
1906   TypeLoc getValueLoc() const {
1907     return this->getInnerTypeLoc();
1908   }
1909
1910   SourceRange getLocalSourceRange() const {
1911     return SourceRange(getKWLoc(), getRParenLoc());
1912   }
1913
1914   SourceLocation getKWLoc() const {
1915     return this->getLocalData()->KWLoc;
1916   }
1917   void setKWLoc(SourceLocation Loc) {
1918     this->getLocalData()->KWLoc = Loc;
1919   }
1920
1921   SourceLocation getLParenLoc() const {
1922     return this->getLocalData()->LParenLoc;
1923   }
1924   void setLParenLoc(SourceLocation Loc) {
1925     this->getLocalData()->LParenLoc = Loc;
1926   }
1927
1928   SourceLocation getRParenLoc() const {
1929     return this->getLocalData()->RParenLoc;
1930   }
1931   void setRParenLoc(SourceLocation Loc) {
1932     this->getLocalData()->RParenLoc = Loc;
1933   }
1934
1935   SourceRange getParensRange() const {
1936     return SourceRange(getLParenLoc(), getRParenLoc());
1937   }
1938   void setParensRange(SourceRange Range) {
1939     setLParenLoc(Range.getBegin());
1940     setRParenLoc(Range.getEnd());
1941   }
1942
1943   void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1944     setKWLoc(Loc);
1945     setLParenLoc(Loc);
1946     setRParenLoc(Loc);
1947   }
1948
1949   QualType getInnerType() const {
1950     return this->getTypePtr()->getValueType();
1951   }
1952 };
1953
1954
1955 }
1956
1957 #endif