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