Warning: That file was not part of the compilation database. It may have many parsing errors.

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

Warning: That file was not part of the compilation database. It may have many parsing errors.