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