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