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