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