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