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