1 //===--- TypeLoc.h - Type Source Info Wrapper -------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// \brief Defines the clang::TypeLoc interface and its subclasses.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_CLANG_AST_TYPELOC_H
16 #define LLVM_CLANG_AST_TYPELOC_H
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"
30 // Predeclare all the type nodes.
31 #define ABSTRACT_TYPELOC(Class, Base)
32 #define TYPELOC(Class, Base) \
34 #include "clang/AST/TypeLocNodes.def"
36 /// \brief Base wrapper for a particular "section" of type source info.
38 /// A client should use the TypeLoc subclasses through castAs()/getAs()
39 /// in order to get at the actual information.
42 // The correctness of this relies on the property that, for Type *Ty,
43 // QualType(Ty, 0).getAsOpaquePtr() == (void*) Ty
48 /// \brief Convert to the specified TypeLoc type, asserting that this TypeLoc
49 /// is of the desired type.
51 /// \pre T::isKind(*this)
54 assert(T::isKind(*this));
61 /// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if
62 /// this TypeLoc is not of the desired type.
65 if (!T::isKind(*this))
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.
77 #define ABSTRACT_TYPE(Class, Base)
78 #define TYPE(Class, Base) \
80 #include "clang/AST/TypeNodes.def"
84 TypeLoc() : Ty(nullptr), Data(nullptr) { }
85 TypeLoc(QualType ty, void *opaqueData)
86 : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { }
87 TypeLoc(const Type *ty, void *opaqueData)
88 : Ty(ty), Data(opaqueData) { }
90 TypeLocClass getTypeLocClass() const {
91 if (getType().hasLocalQualifiers()) return Qualified;
92 return (TypeLocClass) getType()->getTypeClass();
95 bool isNull() const { return !Ty; }
96 explicit operator bool() const { return Ty; }
98 /// \brief Returns the size of type source info data block for the given type.
99 static unsigned getFullDataSizeForType(QualType Ty);
101 /// \brief Returns the alignment of type source info data block for
103 static unsigned getLocalAlignmentForType(QualType Ty);
105 /// \brief Get the type for which this source info wrapper provides
107 QualType getType() const {
108 return QualType::getFromOpaquePtr(Ty);
111 const Type *getTypePtr() const {
112 return QualType::getFromOpaquePtr(Ty).getTypePtr();
115 /// \brief Get the pointer where source information is stored.
116 void *getOpaqueData() const {
120 /// \brief Get the begin source location.
121 SourceLocation getBeginLoc() const;
123 /// \brief Get the end source location.
124 SourceLocation getEndLoc() const;
126 /// \brief Get the full source range.
127 SourceRange getSourceRange() const LLVM_READONLY {
128 return SourceRange(getBeginLoc(), getEndLoc());
130 SourceLocation getLocStart() const LLVM_READONLY { return getBeginLoc(); }
131 SourceLocation getLocEnd() const LLVM_READONLY { return getEndLoc(); }
133 /// \brief Get the local source range.
134 SourceRange getLocalSourceRange() const {
135 return getLocalSourceRangeImpl(*this);
138 /// \brief Returns the size of the type source info data block.
139 unsigned getFullDataSize() const {
140 return getFullDataSizeForType(getType());
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".
145 TypeLoc getNextTypeLoc() const {
146 return getNextTypeLocImpl(*this);
149 /// \brief Skips past any qualifiers, if this is qualified.
150 UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header
152 TypeLoc IgnoreParens() const;
154 /// \brief Initializes this to state that every location in this
155 /// type is the given location.
157 /// This method exists to provide a simple transition for code that
158 /// relies on location-less types.
159 void initialize(ASTContext &Context, SourceLocation Loc) const {
160 initializeImpl(Context, *this, Loc);
163 /// \brief Initializes this by copying its information from another
164 /// TypeLoc of the same type.
165 void initializeFullCopy(TypeLoc Other) const {
166 assert(getType() == Other.getType());
167 size_t Size = getFullDataSize();
168 memcpy(getOpaqueData(), Other.getOpaqueData(), Size);
171 /// \brief Initializes this by copying its information from another
172 /// TypeLoc of the same type. The given size must be the full data
174 void initializeFullCopy(TypeLoc Other, unsigned Size) const {
175 assert(getType() == Other.getType());
176 assert(getFullDataSize() == Size);
177 memcpy(getOpaqueData(), Other.getOpaqueData(), Size);
180 /// Copies the other type loc into this one.
181 void copy(TypeLoc other);
183 friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
184 return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
187 friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) {
188 return !(LHS == RHS);
191 /// Find the location of the nullability specifier (__nonnull,
192 /// __nullable, or __null_unspecifier), if there is one.
193 SourceLocation findNullabilityLoc() const;
196 static bool isKind(const TypeLoc&) {
200 static void initializeImpl(ASTContext &Context, TypeLoc TL,
202 static TypeLoc getNextTypeLocImpl(TypeLoc TL);
203 static TypeLoc IgnoreParensImpl(TypeLoc TL);
204 static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
207 /// \brief Return the TypeLoc for a type source info.
208 inline TypeLoc TypeSourceInfo::getTypeLoc() const {
209 return TypeLoc(Ty, const_cast<void*>(static_cast<const void*>(this + 1)));
212 /// \brief Wrapper of type source information for a type with
213 /// no direct qualifiers.
214 class UnqualTypeLoc : public TypeLoc {
217 UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
219 const Type *getTypePtr() const {
220 return reinterpret_cast<const Type*>(Ty);
223 TypeLocClass getTypeLocClass() const {
224 return (TypeLocClass) getTypePtr()->getTypeClass();
228 friend class TypeLoc;
229 static bool isKind(const TypeLoc &TL) {
230 return !TL.getType().hasLocalQualifiers();
234 /// \brief Wrapper of type source information for a type with
235 /// non-trivial direct qualifiers.
237 /// Currently, we intentionally do not provide source location for
239 class QualifiedTypeLoc : public TypeLoc {
241 SourceRange getLocalSourceRange() const {
242 return SourceRange();
245 UnqualTypeLoc getUnqualifiedLoc() const {
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));
253 /// Initializes the local data of this type source info block to
254 /// provide no information.
255 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
259 void copyLocal(TypeLoc other) {
263 TypeLoc getNextTypeLoc() const {
264 return getUnqualifiedLoc();
267 /// \brief Returns the size of the type source info data block that is
268 /// specific to this type.
269 unsigned getLocalDataSize() const {
270 // In fact, we don't currently preserve any location information
275 /// \brief Returns the alignment of the type source info data block that is
276 /// specific to this type.
277 unsigned getLocalDataAlignment() const {
278 // We don't preserve any location information.
283 friend class TypeLoc;
284 static bool isKind(const TypeLoc &TL) {
285 return TL.getType().hasLocalQualifiers();
289 inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
290 if (QualifiedTypeLoc Loc = getAs<QualifiedTypeLoc>())
291 return Loc.getUnqualifiedLoc();
292 return castAs<UnqualTypeLoc>();
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.
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
303 /// \tparam LocalData the structure type of local location data for
306 /// TypeLocs with non-constant amounts of local data should override
307 /// getExtraLocalDataSize(); getExtraLocalData() will then point to
308 /// this extra memory.
310 /// TypeLocs with an inner type should define
311 /// QualType getInnerType() const
312 /// and getInnerTypeLoc() will then point to this inner type's
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 {
326 const Derived *asDerived() const {
327 return static_cast<const Derived*>(this);
330 friend class TypeLoc;
331 static bool isKind(const TypeLoc &TL) {
332 return !TL.getType().hasLocalQualifiers() &&
333 Derived::classofType(TL.getTypePtr());
336 static bool classofType(const Type *Ty) {
337 return TypeClass::classof(Ty);
341 unsigned getLocalDataAlignment() const {
342 return std::max(llvm::alignOf<LocalData>(),
343 asDerived()->getExtraLocalDataAlignment());
345 unsigned getLocalDataSize() const {
346 unsigned size = sizeof(LocalData);
347 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
348 size = llvm::RoundUpToAlignment(size, extraAlign);
349 size += asDerived()->getExtraLocalDataSize();
353 void copyLocal(Derived other) {
354 // Some subclasses have no data to copy.
355 if (asDerived()->getLocalDataSize() == 0) return;
357 // Copy the fixed-sized local data.
358 memcpy(getLocalData(), other.getLocalData(), sizeof(LocalData));
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());
367 TypeLoc getNextTypeLoc() const {
368 return getNextTypeLoc(asDerived()->getInnerType());
371 const TypeClass *getTypePtr() const {
372 return cast<TypeClass>(Base::getTypePtr());
376 unsigned getExtraLocalDataSize() const {
380 unsigned getExtraLocalDataAlignment() const {
384 LocalData *getLocalData() const {
385 return static_cast<LocalData*>(Base::Data);
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).
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;
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);
405 struct HasNoInnerType {};
406 HasNoInnerType getInnerType() const { return HasNoInnerType(); }
408 TypeLoc getInnerTypeLoc() const {
409 return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
413 unsigned getInnerTypeSize() const {
414 return getInnerTypeSize(asDerived()->getInnerType());
417 unsigned getInnerTypeSize(HasNoInnerType _) const {
421 unsigned getInnerTypeSize(QualType _) const {
422 return getInnerTypeLoc().getFullDataSize();
425 unsigned getNextTypeAlign() const {
426 return getNextTypeAlign(asDerived()->getInnerType());
429 unsigned getNextTypeAlign(HasNoInnerType _) const {
433 unsigned getNextTypeAlign(QualType T) const {
434 return TypeLoc::getLocalAlignmentForType(T);
437 TypeLoc getNextTypeLoc(HasNoInnerType _) const {
441 TypeLoc getNextTypeLoc(QualType T) const {
442 return TypeLoc(T, getNonLocalData());
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;
452 static bool classofType(const Type *Ty) {
453 return TypeClass::classof(Ty);
456 static bool isKind(const TypeLoc &TL) {
457 return !TL.getType().hasLocalQualifiers() &&
458 Derived::classofType(TL.getTypePtr());
460 static bool isKind(const UnqualTypeLoc &TL) {
461 return Derived::classofType(TL.getTypePtr());
465 const TypeClass *getTypePtr() const {
466 return cast<TypeClass>(Base::getTypePtr());
471 struct TypeSpecLocInfo {
472 SourceLocation NameLoc;
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,
482 enum { LocalDataSize = sizeof(TypeSpecLocInfo),
483 LocalDataAlignment = llvm::AlignOf<TypeSpecLocInfo>::Alignment };
485 SourceLocation getNameLoc() const {
486 return this->getLocalData()->NameLoc;
488 void setNameLoc(SourceLocation Loc) {
489 this->getLocalData()->NameLoc = Loc;
491 SourceRange getLocalSourceRange() const {
492 return SourceRange(getNameLoc(), getNameLoc());
494 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
499 friend class TypeLoc;
500 static bool isKind(const TypeLoc &TL);
504 struct BuiltinLocInfo {
505 SourceLocation BuiltinLoc;
508 /// \brief Wrapper for source info for builtin types.
509 class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
514 SourceLocation getBuiltinLoc() const {
515 return getLocalData()->BuiltinLoc;
517 void setBuiltinLoc(SourceLocation Loc) {
518 getLocalData()->BuiltinLoc = Loc;
521 SourceLocation getNameLoc() const { return getBuiltinLoc(); }
523 WrittenBuiltinSpecs& getWrittenBuiltinSpecs() {
524 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
526 const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
527 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
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;
538 unsigned getExtraLocalDataSize() const {
539 return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
542 unsigned getExtraLocalDataAlignment() const {
543 return needsExtraLocalData() ? llvm::alignOf<WrittenBuiltinSpecs>() : 1;
546 SourceRange getLocalSourceRange() const {
547 return SourceRange(getBuiltinLoc(), getBuiltinLoc());
550 TypeSpecifierSign getWrittenSignSpec() const {
551 if (needsExtraLocalData())
552 return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign);
554 return TSS_unspecified;
556 bool hasWrittenSignSpec() const {
557 return getWrittenSignSpec() != TSS_unspecified;
559 void setWrittenSignSpec(TypeSpecifierSign written) {
560 if (needsExtraLocalData())
561 getWrittenBuiltinSpecs().Sign = written;
564 TypeSpecifierWidth getWrittenWidthSpec() const {
565 if (needsExtraLocalData())
566 return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width);
568 return TSW_unspecified;
570 bool hasWrittenWidthSpec() const {
571 return getWrittenWidthSpec() != TSW_unspecified;
573 void setWrittenWidthSpec(TypeSpecifierWidth written) {
574 if (needsExtraLocalData())
575 getWrittenBuiltinSpecs().Width = written;
578 TypeSpecifierType getWrittenTypeSpec() const;
579 bool hasWrittenTypeSpec() const {
580 return getWrittenTypeSpec() != TST_unspecified;
582 void setWrittenTypeSpec(TypeSpecifierType written) {
583 if (needsExtraLocalData())
584 getWrittenBuiltinSpecs().Type = written;
587 bool hasModeAttr() const {
588 if (needsExtraLocalData())
589 return getWrittenBuiltinSpecs().ModeAttr;
593 void setModeAttr(bool written) {
594 if (needsExtraLocalData())
595 getWrittenBuiltinSpecs().ModeAttr = written;
598 void initializeLocal(ASTContext &Context, SourceLocation 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;
611 /// \brief Wrapper for source info for typedefs.
612 class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
616 TypedefNameDecl *getTypedefNameDecl() const {
617 return getTypePtr()->getDecl();
621 /// \brief Wrapper for source info for injected class names of class
623 class InjectedClassNameTypeLoc :
624 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
625 InjectedClassNameTypeLoc,
626 InjectedClassNameType> {
628 CXXRecordDecl *getDecl() const {
629 return getTypePtr()->getDecl();
633 /// \brief Wrapper for source info for unresolved typename using decls.
634 class UnresolvedUsingTypeLoc :
635 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
636 UnresolvedUsingTypeLoc,
637 UnresolvedUsingType> {
639 UnresolvedUsingTypenameDecl *getDecl() const {
640 return getTypePtr()->getDecl();
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,
653 TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
655 /// \brief True if the tag was defined in this type specifier.
656 bool isDefinition() const {
657 TagDecl *D = getDecl();
658 return D->isCompleteDefinition() &&
659 (D->getIdentifier() == nullptr || D->getLocation() == getNameLoc());
663 /// \brief Wrapper for source info for record types.
664 class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
668 RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
671 /// \brief Wrapper for source info for enum types.
672 class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
676 EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
679 /// \brief Wrapper for template type parameters.
680 class TemplateTypeParmTypeLoc :
681 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
682 TemplateTypeParmTypeLoc,
683 TemplateTypeParmType> {
685 TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
688 /// \brief Wrapper for substituted template type parameters.
689 class SubstTemplateTypeParmTypeLoc :
690 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
691 SubstTemplateTypeParmTypeLoc,
692 SubstTemplateTypeParmType> {
695 /// \brief Wrapper for substituted template type parameters.
696 class SubstTemplateTypeParmPackTypeLoc :
697 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
698 SubstTemplateTypeParmPackTypeLoc,
699 SubstTemplateTypeParmPackType> {
702 struct AttributedLocInfo {
706 /// A raw SourceLocation.
707 unsigned EnumOperandLoc;
710 SourceRange OperandParens;
712 SourceLocation AttrLoc;
715 /// \brief Type source information for an attributed type.
716 class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
721 AttributedType::Kind getAttrKind() const {
722 return getTypePtr()->getAttrKind();
725 bool hasAttrExprOperand() const {
726 return (getAttrKind() >= AttributedType::FirstExprOperandKind &&
727 getAttrKind() <= AttributedType::LastExprOperandKind);
730 bool hasAttrEnumOperand() const {
731 return (getAttrKind() >= AttributedType::FirstEnumOperandKind &&
732 getAttrKind() <= AttributedType::LastEnumOperandKind);
735 bool hasAttrOperand() const {
736 return hasAttrExprOperand() || hasAttrEnumOperand();
739 /// The modified type, which is generally canonically different from
740 /// the attribute type.
741 /// int main(int, char**) __attribute__((noreturn))
742 /// ~~~ ~~~~~~~~~~~~~
743 TypeLoc getModifiedLoc() const {
744 return getInnerTypeLoc();
747 /// The location of the attribute name, i.e.
748 /// __attribute__((regparm(1000)))
750 SourceLocation getAttrNameLoc() const {
751 return getLocalData()->AttrLoc;
753 void setAttrNameLoc(SourceLocation loc) {
754 getLocalData()->AttrLoc = loc;
757 /// The attribute's expression operand, if it has one.
758 /// void *cur_thread __attribute__((address_space(21)))
760 Expr *getAttrExprOperand() const {
761 assert(hasAttrExprOperand());
762 return getLocalData()->ExprOperand;
764 void setAttrExprOperand(Expr *e) {
765 assert(hasAttrExprOperand());
766 getLocalData()->ExprOperand = e;
769 /// The location of the attribute's enumerated operand, if it has one.
770 /// void * __attribute__((objc_gc(weak)))
772 SourceLocation getAttrEnumOperandLoc() const {
773 assert(hasAttrEnumOperand());
774 return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc);
776 void setAttrEnumOperandLoc(SourceLocation loc) {
777 assert(hasAttrEnumOperand());
778 getLocalData()->EnumOperandLoc = loc.getRawEncoding();
781 /// The location of the parentheses around the operand, if there is
783 /// void * __attribute__((objc_gc(weak)))
785 SourceRange getAttrOperandParensRange() const {
786 assert(hasAttrOperand());
787 return getLocalData()->OperandParens;
789 void setAttrOperandParensRange(SourceRange range) {
790 assert(hasAttrOperand());
791 getLocalData()->OperandParens = range;
794 SourceRange getLocalSourceRange() const {
795 // Note that this does *not* include the range of the attribute
797 // __attribute__((foo(bar)))
798 // ^~~~~~~~~~~~~~~ ~~
802 // That enclosure doesn't necessarily belong to a single attribute
804 SourceRange range(getAttrNameLoc());
805 if (hasAttrOperand())
806 range.setEnd(getAttrOperandParensRange().getEnd());
810 void initializeLocal(ASTContext &Context, SourceLocation loc) {
812 if (hasAttrExprOperand()) {
813 setAttrOperandParensRange(SourceRange(loc));
814 setAttrExprOperand(nullptr);
815 } else if (hasAttrEnumOperand()) {
816 setAttrOperandParensRange(SourceRange(loc));
817 setAttrEnumOperandLoc(loc);
821 QualType getInnerType() const {
822 return getTypePtr()->getModifiedType();
827 struct ObjCObjectTypeLocInfo {
828 SourceLocation TypeArgsLAngleLoc;
829 SourceLocation TypeArgsRAngleLoc;
830 SourceLocation ProtocolLAngleLoc;
831 SourceLocation ProtocolRAngleLoc;
832 bool HasBaseTypeAsWritten;
835 // A helper class for defining ObjC TypeLocs that can qualified with
838 // TypeClass basically has to be either ObjCInterfaceType or
839 // ObjCObjectPointerType.
840 class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
843 ObjCObjectTypeLocInfo> {
844 // TypeSourceInfo*'s are stored after Info, one for each type argument.
845 TypeSourceInfo **getTypeArgLocArray() const {
846 return (TypeSourceInfo**)this->getExtraLocalData();
849 // SourceLocations are stored after the type argument information, one for
851 SourceLocation *getProtocolLocArray() const {
852 return (SourceLocation*)(getTypeArgLocArray() + getNumTypeArgs());
856 SourceLocation getTypeArgsLAngleLoc() const {
857 return this->getLocalData()->TypeArgsLAngleLoc;
859 void setTypeArgsLAngleLoc(SourceLocation Loc) {
860 this->getLocalData()->TypeArgsLAngleLoc = Loc;
863 SourceLocation getTypeArgsRAngleLoc() const {
864 return this->getLocalData()->TypeArgsRAngleLoc;
866 void setTypeArgsRAngleLoc(SourceLocation Loc) {
867 this->getLocalData()->TypeArgsRAngleLoc = Loc;
870 unsigned getNumTypeArgs() const {
871 return this->getTypePtr()->getTypeArgsAsWritten().size();
874 TypeSourceInfo *getTypeArgTInfo(unsigned i) const {
875 assert(i < getNumTypeArgs() && "Index is out of bounds!");
876 return getTypeArgLocArray()[i];
879 void setTypeArgTInfo(unsigned i, TypeSourceInfo *TInfo) {
880 assert(i < getNumTypeArgs() && "Index is out of bounds!");
881 getTypeArgLocArray()[i] = TInfo;
884 SourceLocation getProtocolLAngleLoc() const {
885 return this->getLocalData()->ProtocolLAngleLoc;
887 void setProtocolLAngleLoc(SourceLocation Loc) {
888 this->getLocalData()->ProtocolLAngleLoc = Loc;
891 SourceLocation getProtocolRAngleLoc() const {
892 return this->getLocalData()->ProtocolRAngleLoc;
894 void setProtocolRAngleLoc(SourceLocation Loc) {
895 this->getLocalData()->ProtocolRAngleLoc = Loc;
898 unsigned getNumProtocols() const {
899 return this->getTypePtr()->getNumProtocols();
902 SourceLocation getProtocolLoc(unsigned i) const {
903 assert(i < getNumProtocols() && "Index is out of bounds!");
904 return getProtocolLocArray()[i];
906 void setProtocolLoc(unsigned i, SourceLocation Loc) {
907 assert(i < getNumProtocols() && "Index is out of bounds!");
908 getProtocolLocArray()[i] = Loc;
911 ObjCProtocolDecl *getProtocol(unsigned i) const {
912 assert(i < getNumProtocols() && "Index is out of bounds!");
913 return *(this->getTypePtr()->qual_begin() + i);
917 ArrayRef<SourceLocation> getProtocolLocs() const {
918 return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols());
921 bool hasBaseTypeAsWritten() const {
922 return getLocalData()->HasBaseTypeAsWritten;
925 void setHasBaseTypeAsWritten(bool HasBaseType) {
926 getLocalData()->HasBaseTypeAsWritten = HasBaseType;
929 TypeLoc getBaseLoc() const {
930 return getInnerTypeLoc();
933 SourceRange getLocalSourceRange() const {
934 SourceLocation start = getTypeArgsLAngleLoc();
935 if (start.isInvalid())
936 start = getProtocolLAngleLoc();
937 SourceLocation end = getProtocolRAngleLoc();
939 end = getTypeArgsRAngleLoc();
940 return SourceRange(start, end);
943 void initializeLocal(ASTContext &Context, SourceLocation Loc);
945 unsigned getExtraLocalDataSize() const {
946 return this->getNumTypeArgs() * sizeof(TypeSourceInfo *)
947 + this->getNumProtocols() * sizeof(SourceLocation);
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 *>();
957 QualType getInnerType() const {
958 return getTypePtr()->getBaseType();
963 struct ObjCInterfaceLocInfo {
964 SourceLocation NameLoc;
965 SourceLocation NameEndLoc;
968 /// \brief Wrapper for source info for ObjC interfaces.
969 class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
970 ObjCInterfaceTypeLoc,
972 ObjCInterfaceLocInfo> {
974 ObjCInterfaceDecl *getIFaceDecl() const {
975 return getTypePtr()->getDecl();
978 SourceLocation getNameLoc() const {
979 return getLocalData()->NameLoc;
982 void setNameLoc(SourceLocation Loc) {
983 getLocalData()->NameLoc = Loc;
986 SourceRange getLocalSourceRange() const {
987 return SourceRange(getNameLoc(), getNameEndLoc());
990 SourceLocation getNameEndLoc() const {
991 return getLocalData()->NameEndLoc;
994 void setNameEndLoc(SourceLocation Loc) {
995 getLocalData()->NameEndLoc = Loc;
998 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1004 struct ParenLocInfo {
1005 SourceLocation LParenLoc;
1006 SourceLocation RParenLoc;
1010 : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType,
1013 SourceLocation getLParenLoc() const {
1014 return this->getLocalData()->LParenLoc;
1016 SourceLocation getRParenLoc() const {
1017 return this->getLocalData()->RParenLoc;
1019 void setLParenLoc(SourceLocation Loc) {
1020 this->getLocalData()->LParenLoc = Loc;
1022 void setRParenLoc(SourceLocation Loc) {
1023 this->getLocalData()->RParenLoc = Loc;
1026 SourceRange getLocalSourceRange() const {
1027 return SourceRange(getLParenLoc(), getRParenLoc());
1030 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1035 TypeLoc getInnerLoc() const {
1036 return getInnerTypeLoc();
1039 QualType getInnerType() const {
1040 return this->getTypePtr()->getInnerType();
1044 inline TypeLoc TypeLoc::IgnoreParens() const {
1045 if (ParenTypeLoc::isKind(*this))
1046 return IgnoreParensImpl(*this);
1051 struct AdjustedLocInfo { }; // Nothing.
1053 class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc,
1054 AdjustedType, AdjustedLocInfo> {
1056 TypeLoc getOriginalLoc() const {
1057 return getInnerTypeLoc();
1060 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
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();
1070 SourceRange getLocalSourceRange() const {
1071 return SourceRange();
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.
1081 /// \brief Wrapper for source info for pointers decayed from arrays and
1083 class DecayedTypeLoc : public InheritingConcreteTypeLoc<
1084 AdjustedTypeLoc, DecayedTypeLoc, DecayedType> {
1087 struct PointerLikeLocInfo {
1088 SourceLocation StarLoc;
1091 /// A base class for
1092 template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
1093 class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
1094 TypeClass, LocalData> {
1096 SourceLocation getSigilLoc() const {
1097 return this->getLocalData()->StarLoc;
1099 void setSigilLoc(SourceLocation Loc) {
1100 this->getLocalData()->StarLoc = Loc;
1103 TypeLoc getPointeeLoc() const {
1104 return this->getInnerTypeLoc();
1107 SourceRange getLocalSourceRange() const {
1108 return SourceRange(getSigilLoc(), getSigilLoc());
1111 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1115 QualType getInnerType() const {
1116 return this->getTypePtr()->getPointeeType();
1121 /// \brief Wrapper for source info for pointers.
1122 class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
1125 SourceLocation getStarLoc() const {
1126 return getSigilLoc();
1128 void setStarLoc(SourceLocation Loc) {
1134 /// \brief Wrapper for source info for block pointers.
1135 class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
1138 SourceLocation getCaretLoc() const {
1139 return getSigilLoc();
1141 void setCaretLoc(SourceLocation Loc) {
1146 struct MemberPointerLocInfo : public PointerLikeLocInfo {
1147 TypeSourceInfo *ClassTInfo;
1150 /// \brief Wrapper for source info for member pointers.
1151 class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
1153 MemberPointerLocInfo> {
1155 SourceLocation getStarLoc() const {
1156 return getSigilLoc();
1158 void setStarLoc(SourceLocation Loc) {
1162 const Type *getClass() const {
1163 return getTypePtr()->getClass();
1165 TypeSourceInfo *getClassTInfo() const {
1166 return getLocalData()->ClassTInfo;
1168 void setClassTInfo(TypeSourceInfo* TI) {
1169 getLocalData()->ClassTInfo = TI;
1172 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1174 setClassTInfo(nullptr);
1177 SourceRange getLocalSourceRange() const {
1178 if (TypeSourceInfo *TI = getClassTInfo())
1179 return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
1181 return SourceRange(getStarLoc());
1185 /// Wraps an ObjCPointerType with source location information.
1186 class ObjCObjectPointerTypeLoc :
1187 public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
1188 ObjCObjectPointerType> {
1190 SourceLocation getStarLoc() const {
1191 return getSigilLoc();
1194 void setStarLoc(SourceLocation Loc) {
1200 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
1203 QualType getInnerType() const {
1204 return getTypePtr()->getPointeeTypeAsWritten();
1208 class LValueReferenceTypeLoc :
1209 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1210 LValueReferenceTypeLoc,
1211 LValueReferenceType> {
1213 SourceLocation getAmpLoc() const {
1214 return getSigilLoc();
1216 void setAmpLoc(SourceLocation Loc) {
1221 class RValueReferenceTypeLoc :
1222 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1223 RValueReferenceTypeLoc,
1224 RValueReferenceType> {
1226 SourceLocation getAmpAmpLoc() const {
1227 return getSigilLoc();
1229 void setAmpAmpLoc(SourceLocation Loc) {
1235 struct FunctionLocInfo {
1236 SourceLocation LocalRangeBegin;
1237 SourceLocation LParenLoc;
1238 SourceLocation RParenLoc;
1239 SourceLocation LocalRangeEnd;
1242 /// \brief Wrapper for source info for functions.
1243 class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1248 SourceLocation getLocalRangeBegin() const {
1249 return getLocalData()->LocalRangeBegin;
1251 void setLocalRangeBegin(SourceLocation L) {
1252 getLocalData()->LocalRangeBegin = L;
1255 SourceLocation getLocalRangeEnd() const {
1256 return getLocalData()->LocalRangeEnd;
1258 void setLocalRangeEnd(SourceLocation L) {
1259 getLocalData()->LocalRangeEnd = L;
1262 SourceLocation getLParenLoc() const {
1263 return this->getLocalData()->LParenLoc;
1265 void setLParenLoc(SourceLocation Loc) {
1266 this->getLocalData()->LParenLoc = Loc;
1269 SourceLocation getRParenLoc() const {
1270 return this->getLocalData()->RParenLoc;
1272 void setRParenLoc(SourceLocation Loc) {
1273 this->getLocalData()->RParenLoc = Loc;
1276 SourceRange getParensRange() const {
1277 return SourceRange(getLParenLoc(), getRParenLoc());
1280 ArrayRef<ParmVarDecl *> getParams() const {
1281 return llvm::makeArrayRef(getParmArray(), getNumParams());
1284 // ParmVarDecls* are stored after Info, one for each parameter.
1285 ParmVarDecl **getParmArray() const {
1286 return (ParmVarDecl**) getExtraLocalData();
1289 unsigned getNumParams() const {
1290 if (isa<FunctionNoProtoType>(getTypePtr()))
1292 return cast<FunctionProtoType>(getTypePtr())->getNumParams();
1294 ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; }
1295 void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
1297 TypeLoc getReturnLoc() const {
1298 return getInnerTypeLoc();
1301 SourceRange getLocalSourceRange() const {
1302 return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
1305 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1306 setLocalRangeBegin(Loc);
1309 setLocalRangeEnd(Loc);
1310 for (unsigned i = 0, e = getNumParams(); i != e; ++i)
1311 setParam(i, nullptr);
1314 /// \brief Returns the size of the type source info data block that is
1315 /// specific to this type.
1316 unsigned getExtraLocalDataSize() const {
1317 return getNumParams() * sizeof(ParmVarDecl *);
1320 unsigned getExtraLocalDataAlignment() const {
1321 return llvm::alignOf<ParmVarDecl*>();
1324 QualType getInnerType() const { return getTypePtr()->getReturnType(); }
1327 class FunctionProtoTypeLoc :
1328 public InheritingConcreteTypeLoc<FunctionTypeLoc,
1329 FunctionProtoTypeLoc,
1330 FunctionProtoType> {
1333 class FunctionNoProtoTypeLoc :
1334 public InheritingConcreteTypeLoc<FunctionTypeLoc,
1335 FunctionNoProtoTypeLoc,
1336 FunctionNoProtoType> {
1340 struct ArrayLocInfo {
1341 SourceLocation LBracketLoc, RBracketLoc;
1345 /// \brief Wrapper for source info for arrays.
1346 class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1351 SourceLocation getLBracketLoc() const {
1352 return getLocalData()->LBracketLoc;
1354 void setLBracketLoc(SourceLocation Loc) {
1355 getLocalData()->LBracketLoc = Loc;
1358 SourceLocation getRBracketLoc() const {
1359 return getLocalData()->RBracketLoc;
1361 void setRBracketLoc(SourceLocation Loc) {
1362 getLocalData()->RBracketLoc = Loc;
1365 SourceRange getBracketsRange() const {
1366 return SourceRange(getLBracketLoc(), getRBracketLoc());
1369 Expr *getSizeExpr() const {
1370 return getLocalData()->Size;
1372 void setSizeExpr(Expr *Size) {
1373 getLocalData()->Size = Size;
1376 TypeLoc getElementLoc() const {
1377 return getInnerTypeLoc();
1380 SourceRange getLocalSourceRange() const {
1381 return SourceRange(getLBracketLoc(), getRBracketLoc());
1384 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1385 setLBracketLoc(Loc);
1386 setRBracketLoc(Loc);
1387 setSizeExpr(nullptr);
1390 QualType getInnerType() const { return getTypePtr()->getElementType(); }
1393 class ConstantArrayTypeLoc :
1394 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1395 ConstantArrayTypeLoc,
1396 ConstantArrayType> {
1399 class IncompleteArrayTypeLoc :
1400 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1401 IncompleteArrayTypeLoc,
1402 IncompleteArrayType> {
1405 class DependentSizedArrayTypeLoc :
1406 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1407 DependentSizedArrayTypeLoc,
1408 DependentSizedArrayType> {
1412 class VariableArrayTypeLoc :
1413 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1414 VariableArrayTypeLoc,
1415 VariableArrayType> {
1419 // Location information for a TemplateName. Rudimentary for now.
1420 struct TemplateNameLocInfo {
1421 SourceLocation NameLoc;
1424 struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
1425 SourceLocation TemplateKWLoc;
1426 SourceLocation LAngleLoc;
1427 SourceLocation RAngleLoc;
1430 class TemplateSpecializationTypeLoc :
1431 public ConcreteTypeLoc<UnqualTypeLoc,
1432 TemplateSpecializationTypeLoc,
1433 TemplateSpecializationType,
1434 TemplateSpecializationLocInfo> {
1436 SourceLocation getTemplateKeywordLoc() const {
1437 return getLocalData()->TemplateKWLoc;
1439 void setTemplateKeywordLoc(SourceLocation Loc) {
1440 getLocalData()->TemplateKWLoc = Loc;
1443 SourceLocation getLAngleLoc() const {
1444 return getLocalData()->LAngleLoc;
1446 void setLAngleLoc(SourceLocation Loc) {
1447 getLocalData()->LAngleLoc = Loc;
1450 SourceLocation getRAngleLoc() const {
1451 return getLocalData()->RAngleLoc;
1453 void setRAngleLoc(SourceLocation Loc) {
1454 getLocalData()->RAngleLoc = Loc;
1457 unsigned getNumArgs() const {
1458 return getTypePtr()->getNumArgs();
1460 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1461 getArgInfos()[i] = AI;
1463 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1464 return getArgInfos()[i];
1467 TemplateArgumentLoc getArgLoc(unsigned i) const {
1468 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1471 SourceLocation getTemplateNameLoc() const {
1472 return getLocalData()->NameLoc;
1474 void setTemplateNameLoc(SourceLocation Loc) {
1475 getLocalData()->NameLoc = Loc;
1478 /// \brief - Copy the location information from the given info.
1479 void copy(TemplateSpecializationTypeLoc Loc) {
1480 unsigned size = getFullDataSize();
1481 assert(size == Loc.getFullDataSize());
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);
1490 SourceRange getLocalSourceRange() const {
1491 if (getTemplateKeywordLoc().isValid())
1492 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1494 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1497 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1498 setTemplateKeywordLoc(Loc);
1499 setTemplateNameLoc(Loc);
1502 initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
1503 getArgInfos(), Loc);
1506 static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
1507 const TemplateArgument *Args,
1508 TemplateArgumentLocInfo *ArgInfos,
1509 SourceLocation Loc);
1511 unsigned getExtraLocalDataSize() const {
1512 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1515 unsigned getExtraLocalDataAlignment() const {
1516 return llvm::alignOf<TemplateArgumentLocInfo>();
1520 TemplateArgumentLocInfo *getArgInfos() const {
1521 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1525 //===----------------------------------------------------------------------===//
1527 // All of these need proper implementations.
1529 //===----------------------------------------------------------------------===//
1531 // FIXME: size expression and attribute locations (or keyword if we
1532 // ever fully support altivec syntax).
1533 class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1538 // FIXME: size expression and attribute locations.
1539 class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
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> {
1552 // FIXME: location of the '_Complex' keyword.
1553 class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1558 struct TypeofLocInfo {
1559 SourceLocation TypeofLoc;
1560 SourceLocation LParenLoc;
1561 SourceLocation RParenLoc;
1564 struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
1567 struct TypeOfTypeLocInfo : public TypeofLocInfo {
1568 TypeSourceInfo* UnderlyingTInfo;
1571 template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
1572 class TypeofLikeTypeLoc
1573 : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
1575 SourceLocation getTypeofLoc() const {
1576 return this->getLocalData()->TypeofLoc;
1578 void setTypeofLoc(SourceLocation Loc) {
1579 this->getLocalData()->TypeofLoc = Loc;
1582 SourceLocation getLParenLoc() const {
1583 return this->getLocalData()->LParenLoc;
1585 void setLParenLoc(SourceLocation Loc) {
1586 this->getLocalData()->LParenLoc = Loc;
1589 SourceLocation getRParenLoc() const {
1590 return this->getLocalData()->RParenLoc;
1592 void setRParenLoc(SourceLocation Loc) {
1593 this->getLocalData()->RParenLoc = Loc;
1596 SourceRange getParensRange() const {
1597 return SourceRange(getLParenLoc(), getRParenLoc());
1599 void setParensRange(SourceRange range) {
1600 setLParenLoc(range.getBegin());
1601 setRParenLoc(range.getEnd());
1604 SourceRange getLocalSourceRange() const {
1605 return SourceRange(getTypeofLoc(), getRParenLoc());
1608 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1615 class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
1617 TypeOfExprTypeLocInfo> {
1619 Expr* getUnderlyingExpr() const {
1620 return getTypePtr()->getUnderlyingExpr();
1622 // Reimplemented to account for GNU/C++ extension
1623 // typeof unary-expression
1624 // where there are no parentheses.
1625 SourceRange getLocalSourceRange() const;
1629 : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
1631 QualType getUnderlyingType() const {
1632 return this->getTypePtr()->getUnderlyingType();
1634 TypeSourceInfo* getUnderlyingTInfo() const {
1635 return this->getLocalData()->UnderlyingTInfo;
1637 void setUnderlyingTInfo(TypeSourceInfo* TI) const {
1638 this->getLocalData()->UnderlyingTInfo = TI;
1641 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1644 // FIXME: location of the 'decltype' and parens.
1645 class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1649 Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
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;
1659 class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1660 UnaryTransformTypeLoc,
1662 UnaryTransformTypeLocInfo> {
1664 SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
1665 void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
1667 SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
1668 void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
1670 SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
1671 void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
1673 TypeSourceInfo* getUnderlyingTInfo() const {
1674 return getLocalData()->UnderlyingTInfo;
1676 void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
1677 getLocalData()->UnderlyingTInfo = TInfo;
1680 SourceRange getLocalSourceRange() const {
1681 return SourceRange(getKWLoc(), getRParenLoc());
1684 SourceRange getParensRange() const {
1685 return SourceRange(getLParenLoc(), getRParenLoc());
1687 void setParensRange(SourceRange Range) {
1688 setLParenLoc(Range.getBegin());
1689 setRParenLoc(Range.getEnd());
1692 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1699 class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1704 struct ElaboratedLocInfo {
1705 SourceLocation ElaboratedKWLoc;
1706 /// \brief Data associated with the nested-name-specifier location.
1707 void *QualifierData;
1710 class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1713 ElaboratedLocInfo> {
1715 SourceLocation getElaboratedKeywordLoc() const {
1716 return this->getLocalData()->ElaboratedKWLoc;
1718 void setElaboratedKeywordLoc(SourceLocation Loc) {
1719 this->getLocalData()->ElaboratedKWLoc = Loc;
1722 NestedNameSpecifierLoc getQualifierLoc() const {
1723 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1724 getLocalData()->QualifierData);
1727 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1728 assert(QualifierLoc.getNestedNameSpecifier()
1729 == getTypePtr()->getQualifier() &&
1730 "Inconsistent nested-name-specifier pointer");
1731 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1734 SourceRange getLocalSourceRange() const {
1735 if (getElaboratedKeywordLoc().isValid())
1736 if (getQualifierLoc())
1737 return SourceRange(getElaboratedKeywordLoc(),
1738 getQualifierLoc().getEndLoc());
1740 return SourceRange(getElaboratedKeywordLoc());
1742 return getQualifierLoc().getSourceRange();
1745 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1747 TypeLoc getNamedTypeLoc() const {
1748 return getInnerTypeLoc();
1751 QualType getInnerType() const {
1752 return getTypePtr()->getNamedType();
1755 void copy(ElaboratedTypeLoc Loc) {
1756 unsigned size = getFullDataSize();
1757 assert(size == Loc.getFullDataSize());
1758 memcpy(Data, Loc.Data, size);
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;
1768 class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1769 DependentNameTypeLoc,
1771 DependentNameLocInfo> {
1773 SourceLocation getElaboratedKeywordLoc() const {
1774 return this->getLocalData()->ElaboratedKWLoc;
1776 void setElaboratedKeywordLoc(SourceLocation Loc) {
1777 this->getLocalData()->ElaboratedKWLoc = Loc;
1780 NestedNameSpecifierLoc getQualifierLoc() const {
1781 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1782 getLocalData()->QualifierData);
1785 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1786 assert(QualifierLoc.getNestedNameSpecifier()
1787 == getTypePtr()->getQualifier() &&
1788 "Inconsistent nested-name-specifier pointer");
1789 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1792 SourceLocation getNameLoc() const {
1793 return this->getLocalData()->NameLoc;
1795 void setNameLoc(SourceLocation Loc) {
1796 this->getLocalData()->NameLoc = Loc;
1799 SourceRange getLocalSourceRange() const {
1800 if (getElaboratedKeywordLoc().isValid())
1801 return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
1803 return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
1806 void copy(DependentNameTypeLoc Loc) {
1807 unsigned size = getFullDataSize();
1808 assert(size == Loc.getFullDataSize());
1809 memcpy(Data, Loc.Data, size);
1812 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1815 struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
1816 SourceLocation TemplateKWLoc;
1817 SourceLocation LAngleLoc;
1818 SourceLocation RAngleLoc;
1819 // followed by a TemplateArgumentLocInfo[]
1822 class DependentTemplateSpecializationTypeLoc :
1823 public ConcreteTypeLoc<UnqualTypeLoc,
1824 DependentTemplateSpecializationTypeLoc,
1825 DependentTemplateSpecializationType,
1826 DependentTemplateSpecializationLocInfo> {
1828 SourceLocation getElaboratedKeywordLoc() const {
1829 return this->getLocalData()->ElaboratedKWLoc;
1831 void setElaboratedKeywordLoc(SourceLocation Loc) {
1832 this->getLocalData()->ElaboratedKWLoc = Loc;
1835 NestedNameSpecifierLoc getQualifierLoc() const {
1836 if (!getLocalData()->QualifierData)
1837 return NestedNameSpecifierLoc();
1839 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1840 getLocalData()->QualifierData);
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;
1853 assert(QualifierLoc.getNestedNameSpecifier()
1854 == getTypePtr()->getQualifier() &&
1855 "Inconsistent nested-name-specifier pointer");
1856 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1859 SourceLocation getTemplateKeywordLoc() const {
1860 return getLocalData()->TemplateKWLoc;
1862 void setTemplateKeywordLoc(SourceLocation Loc) {
1863 getLocalData()->TemplateKWLoc = Loc;
1866 SourceLocation getTemplateNameLoc() const {
1867 return this->getLocalData()->NameLoc;
1869 void setTemplateNameLoc(SourceLocation Loc) {
1870 this->getLocalData()->NameLoc = Loc;
1873 SourceLocation getLAngleLoc() const {
1874 return this->getLocalData()->LAngleLoc;
1876 void setLAngleLoc(SourceLocation Loc) {
1877 this->getLocalData()->LAngleLoc = Loc;
1880 SourceLocation getRAngleLoc() const {
1881 return this->getLocalData()->RAngleLoc;
1883 void setRAngleLoc(SourceLocation Loc) {
1884 this->getLocalData()->RAngleLoc = Loc;
1887 unsigned getNumArgs() const {
1888 return getTypePtr()->getNumArgs();
1891 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1892 getArgInfos()[i] = AI;
1894 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1895 return getArgInfos()[i];
1898 TemplateArgumentLoc getArgLoc(unsigned i) const {
1899 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
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());
1910 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1913 void copy(DependentTemplateSpecializationTypeLoc Loc) {
1914 unsigned size = getFullDataSize();
1915 assert(size == Loc.getFullDataSize());
1916 memcpy(Data, Loc.Data, size);
1919 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1921 unsigned getExtraLocalDataSize() const {
1922 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1925 unsigned getExtraLocalDataAlignment() const {
1926 return llvm::alignOf<TemplateArgumentLocInfo>();
1930 TemplateArgumentLocInfo *getArgInfos() const {
1931 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1936 struct PackExpansionTypeLocInfo {
1937 SourceLocation EllipsisLoc;
1940 class PackExpansionTypeLoc
1941 : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
1942 PackExpansionType, PackExpansionTypeLocInfo> {
1944 SourceLocation getEllipsisLoc() const {
1945 return this->getLocalData()->EllipsisLoc;
1948 void setEllipsisLoc(SourceLocation Loc) {
1949 this->getLocalData()->EllipsisLoc = Loc;
1952 SourceRange getLocalSourceRange() const {
1953 return SourceRange(getEllipsisLoc(), getEllipsisLoc());
1956 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1957 setEllipsisLoc(Loc);
1960 TypeLoc getPatternLoc() const {
1961 return getInnerTypeLoc();
1964 QualType getInnerType() const {
1965 return this->getTypePtr()->getPattern();
1969 struct AtomicTypeLocInfo {
1970 SourceLocation KWLoc, LParenLoc, RParenLoc;
1973 class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
1974 AtomicType, AtomicTypeLocInfo> {
1976 TypeLoc getValueLoc() const {
1977 return this->getInnerTypeLoc();
1980 SourceRange getLocalSourceRange() const {
1981 return SourceRange(getKWLoc(), getRParenLoc());
1984 SourceLocation getKWLoc() const {
1985 return this->getLocalData()->KWLoc;
1987 void setKWLoc(SourceLocation Loc) {
1988 this->getLocalData()->KWLoc = Loc;
1991 SourceLocation getLParenLoc() const {
1992 return this->getLocalData()->LParenLoc;
1994 void setLParenLoc(SourceLocation Loc) {
1995 this->getLocalData()->LParenLoc = Loc;
1998 SourceLocation getRParenLoc() const {
1999 return this->getLocalData()->RParenLoc;
2001 void setRParenLoc(SourceLocation Loc) {
2002 this->getLocalData()->RParenLoc = Loc;
2005 SourceRange getParensRange() const {
2006 return SourceRange(getLParenLoc(), getRParenLoc());
2008 void setParensRange(SourceRange Range) {
2009 setLParenLoc(Range.getBegin());
2010 setRParenLoc(Range.getEnd());
2013 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2019 QualType getInnerType() const {
2020 return this->getTypePtr()->getValueType();