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