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