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