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