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