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