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