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