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 Find a type with the location of an explicit type qualifier.
156 /// The result, if non-null, will be one of:
159 /// AttributedTypeLoc, for those type attributes that behave as qualifiers
160 TypeLoc findExplicitQualifierLoc() const;
162 /// \brief Initializes this to state that every location in this
163 /// type is the given location.
165 /// This method exists to provide a simple transition for code that
166 /// relies on location-less types.
167 void initialize(ASTContext &Context, SourceLocation Loc) const {
168 initializeImpl(Context, *this, Loc);
171 /// \brief Initializes this by copying its information from another
172 /// TypeLoc of the same type.
173 void initializeFullCopy(TypeLoc Other) {
174 assert(getType() == Other.getType());
178 /// \brief Initializes this by copying its information from another
179 /// TypeLoc of the same type. The given size must be the full data
181 void initializeFullCopy(TypeLoc Other, unsigned Size) {
182 assert(getType() == Other.getType());
183 assert(getFullDataSize() == Size);
187 /// Copies the other type loc into this one.
188 void copy(TypeLoc other);
190 friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) {
191 return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data;
194 friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) {
195 return !(LHS == RHS);
198 /// Find the location of the nullability specifier (__nonnull,
199 /// __nullable, or __null_unspecifier), if there is one.
200 SourceLocation findNullabilityLoc() const;
203 static bool isKind(const TypeLoc&) {
207 static void initializeImpl(ASTContext &Context, TypeLoc TL,
209 static TypeLoc getNextTypeLocImpl(TypeLoc TL);
210 static TypeLoc IgnoreParensImpl(TypeLoc TL);
211 static SourceRange getLocalSourceRangeImpl(TypeLoc TL);
214 /// \brief Return the TypeLoc for a type source info.
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)));
220 /// \brief Wrapper of type source information for a type with
221 /// no direct qualifiers.
222 class UnqualTypeLoc : public TypeLoc {
225 UnqualTypeLoc(const Type *Ty, void *Data) : TypeLoc(Ty, Data) {}
227 const Type *getTypePtr() const {
228 return reinterpret_cast<const Type*>(Ty);
231 TypeLocClass getTypeLocClass() const {
232 return (TypeLocClass) getTypePtr()->getTypeClass();
236 friend class TypeLoc;
237 static bool isKind(const TypeLoc &TL) {
238 return !TL.getType().hasLocalQualifiers();
242 /// \brief Wrapper of type source information for a type with
243 /// non-trivial direct qualifiers.
245 /// Currently, we intentionally do not provide source location for
247 class QualifiedTypeLoc : public TypeLoc {
249 SourceRange getLocalSourceRange() const {
250 return SourceRange();
253 UnqualTypeLoc getUnqualifiedLoc() const {
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));
261 /// Initializes the local data of this type source info block to
262 /// provide no information.
263 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
267 void copyLocal(TypeLoc other) {
271 TypeLoc getNextTypeLoc() const {
272 return getUnqualifiedLoc();
275 /// \brief Returns the size of the type source info data block that is
276 /// specific to this type.
277 unsigned getLocalDataSize() const {
278 // In fact, we don't currently preserve any location information
283 /// \brief Returns the alignment of the type source info data block that is
284 /// specific to this type.
285 unsigned getLocalDataAlignment() const {
286 // We don't preserve any location information.
291 friend class TypeLoc;
292 static bool isKind(const TypeLoc &TL) {
293 return TL.getType().hasLocalQualifiers();
297 inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const {
298 if (QualifiedTypeLoc Loc = getAs<QualifiedTypeLoc>())
299 return Loc.getUnqualifiedLoc();
300 return castAs<UnqualTypeLoc>();
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.
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
311 /// \tparam LocalData the structure type of local location data for
314 /// TypeLocs with non-constant amounts of local data should override
315 /// getExtraLocalDataSize(); getExtraLocalData() will then point to
316 /// this extra memory.
318 /// TypeLocs with an inner type should define
319 /// QualType getInnerType() const
320 /// and getInnerTypeLoc() will then point to this inner type's
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 {
334 const Derived *asDerived() const {
335 return static_cast<const Derived*>(this);
338 friend class TypeLoc;
339 static bool isKind(const TypeLoc &TL) {
340 return !TL.getType().hasLocalQualifiers() &&
341 Derived::classofType(TL.getTypePtr());
344 static bool classofType(const Type *Ty) {
345 return TypeClass::classof(Ty);
349 unsigned getLocalDataAlignment() const {
350 return std::max(unsigned(alignof(LocalData)),
351 asDerived()->getExtraLocalDataAlignment());
353 unsigned getLocalDataSize() const {
354 unsigned size = sizeof(LocalData);
355 unsigned extraAlign = asDerived()->getExtraLocalDataAlignment();
356 size = llvm::alignTo(size, extraAlign);
357 size += asDerived()->getExtraLocalDataSize();
361 void copyLocal(Derived other) {
362 // Some subclasses have no data to copy.
363 if (asDerived()->getLocalDataSize() == 0) return;
365 // Copy the fixed-sized local data.
366 memcpy(getLocalData(), other.getLocalData(), sizeof(LocalData));
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());
375 TypeLoc getNextTypeLoc() const {
376 return getNextTypeLoc(asDerived()->getInnerType());
379 const TypeClass *getTypePtr() const {
380 return cast<TypeClass>(Base::getTypePtr());
384 unsigned getExtraLocalDataSize() const {
388 unsigned getExtraLocalDataAlignment() const {
392 LocalData *getLocalData() const {
393 return static_cast<LocalData*>(Base::Data);
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).
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;
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);
413 struct HasNoInnerType {};
414 HasNoInnerType getInnerType() const { return HasNoInnerType(); }
416 TypeLoc getInnerTypeLoc() const {
417 return TypeLoc(asDerived()->getInnerType(), getNonLocalData());
421 unsigned getInnerTypeSize() const {
422 return getInnerTypeSize(asDerived()->getInnerType());
425 unsigned getInnerTypeSize(HasNoInnerType _) const {
429 unsigned getInnerTypeSize(QualType _) const {
430 return getInnerTypeLoc().getFullDataSize();
433 unsigned getNextTypeAlign() const {
434 return getNextTypeAlign(asDerived()->getInnerType());
437 unsigned getNextTypeAlign(HasNoInnerType _) const {
441 unsigned getNextTypeAlign(QualType T) const {
442 return TypeLoc::getLocalAlignmentForType(T);
445 TypeLoc getNextTypeLoc(HasNoInnerType _) const {
449 TypeLoc getNextTypeLoc(QualType T) const {
450 return TypeLoc(T, getNonLocalData());
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;
460 static bool classofType(const Type *Ty) {
461 return TypeClass::classof(Ty);
464 static bool isKind(const TypeLoc &TL) {
465 return !TL.getType().hasLocalQualifiers() &&
466 Derived::classofType(TL.getTypePtr());
468 static bool isKind(const UnqualTypeLoc &TL) {
469 return Derived::classofType(TL.getTypePtr());
473 const TypeClass *getTypePtr() const {
474 return cast<TypeClass>(Base::getTypePtr());
479 struct TypeSpecLocInfo {
480 SourceLocation NameLoc;
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,
491 LocalDataSize = sizeof(TypeSpecLocInfo),
492 LocalDataAlignment = alignof(TypeSpecLocInfo)
495 SourceLocation getNameLoc() const {
496 return this->getLocalData()->NameLoc;
498 void setNameLoc(SourceLocation Loc) {
499 this->getLocalData()->NameLoc = Loc;
501 SourceRange getLocalSourceRange() const {
502 return SourceRange(getNameLoc(), getNameLoc());
504 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
509 friend class TypeLoc;
510 static bool isKind(const TypeLoc &TL);
514 struct BuiltinLocInfo {
515 SourceRange BuiltinRange;
518 /// \brief Wrapper for source info for builtin types.
519 class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
524 SourceLocation getBuiltinLoc() const {
525 return getLocalData()->BuiltinRange.getBegin();
527 void setBuiltinLoc(SourceLocation Loc) {
528 getLocalData()->BuiltinRange = Loc;
530 void expandBuiltinRange(SourceRange Range) {
531 SourceRange &BuiltinRange = getLocalData()->BuiltinRange;
532 if (!BuiltinRange.getBegin().isValid()) {
533 BuiltinRange = Range;
535 BuiltinRange.setBegin(std::min(Range.getBegin(), BuiltinRange.getBegin()));
536 BuiltinRange.setEnd(std::max(Range.getEnd(), BuiltinRange.getEnd()));
540 SourceLocation getNameLoc() const { return getBuiltinLoc(); }
542 WrittenBuiltinSpecs& getWrittenBuiltinSpecs() {
543 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
545 const WrittenBuiltinSpecs& getWrittenBuiltinSpecs() const {
546 return *(static_cast<WrittenBuiltinSpecs*>(getExtraLocalData()));
549 bool needsExtraLocalData() const {
550 BuiltinType::Kind bk = getTypePtr()->getKind();
551 return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
552 || (bk >= BuiltinType::Short && bk <= BuiltinType::Float128)
553 || bk == BuiltinType::UChar
554 || bk == BuiltinType::SChar;
557 unsigned getExtraLocalDataSize() const {
558 return needsExtraLocalData() ? sizeof(WrittenBuiltinSpecs) : 0;
561 unsigned getExtraLocalDataAlignment() const {
562 return needsExtraLocalData() ? alignof(WrittenBuiltinSpecs) : 1;
565 SourceRange getLocalSourceRange() const {
566 return getLocalData()->BuiltinRange;
569 TypeSpecifierSign getWrittenSignSpec() const {
570 if (needsExtraLocalData())
571 return static_cast<TypeSpecifierSign>(getWrittenBuiltinSpecs().Sign);
573 return TSS_unspecified;
575 bool hasWrittenSignSpec() const {
576 return getWrittenSignSpec() != TSS_unspecified;
578 void setWrittenSignSpec(TypeSpecifierSign written) {
579 if (needsExtraLocalData())
580 getWrittenBuiltinSpecs().Sign = written;
583 TypeSpecifierWidth getWrittenWidthSpec() const {
584 if (needsExtraLocalData())
585 return static_cast<TypeSpecifierWidth>(getWrittenBuiltinSpecs().Width);
587 return TSW_unspecified;
589 bool hasWrittenWidthSpec() const {
590 return getWrittenWidthSpec() != TSW_unspecified;
592 void setWrittenWidthSpec(TypeSpecifierWidth written) {
593 if (needsExtraLocalData())
594 getWrittenBuiltinSpecs().Width = written;
597 TypeSpecifierType getWrittenTypeSpec() const;
598 bool hasWrittenTypeSpec() const {
599 return getWrittenTypeSpec() != TST_unspecified;
601 void setWrittenTypeSpec(TypeSpecifierType written) {
602 if (needsExtraLocalData())
603 getWrittenBuiltinSpecs().Type = written;
606 bool hasModeAttr() const {
607 if (needsExtraLocalData())
608 return getWrittenBuiltinSpecs().ModeAttr;
612 void setModeAttr(bool written) {
613 if (needsExtraLocalData())
614 getWrittenBuiltinSpecs().ModeAttr = written;
617 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
619 if (needsExtraLocalData()) {
620 WrittenBuiltinSpecs &wbs = getWrittenBuiltinSpecs();
621 wbs.Sign = TSS_unspecified;
622 wbs.Width = TSW_unspecified;
623 wbs.Type = TST_unspecified;
624 wbs.ModeAttr = false;
630 /// \brief Wrapper for source info for typedefs.
631 class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
635 TypedefNameDecl *getTypedefNameDecl() const {
636 return getTypePtr()->getDecl();
640 /// \brief Wrapper for source info for injected class names of class
642 class InjectedClassNameTypeLoc :
643 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
644 InjectedClassNameTypeLoc,
645 InjectedClassNameType> {
647 CXXRecordDecl *getDecl() const {
648 return getTypePtr()->getDecl();
652 /// \brief Wrapper for source info for unresolved typename using decls.
653 class UnresolvedUsingTypeLoc :
654 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
655 UnresolvedUsingTypeLoc,
656 UnresolvedUsingType> {
658 UnresolvedUsingTypenameDecl *getDecl() const {
659 return getTypePtr()->getDecl();
663 /// \brief Wrapper for source info for tag types. Note that this only
664 /// records source info for the name itself; a type written 'struct foo'
665 /// should be represented as an ElaboratedTypeLoc. We currently
666 /// only do that when C++ is enabled because of the expense of
667 /// creating an ElaboratedType node for so many type references in C.
668 class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
672 TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
674 /// \brief True if the tag was defined in this type specifier.
675 bool isDefinition() const {
676 TagDecl *D = getDecl();
677 return D->isCompleteDefinition() &&
678 (D->getIdentifier() == nullptr || D->getLocation() == getNameLoc());
682 /// \brief Wrapper for source info for record types.
683 class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
687 RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
690 /// \brief Wrapper for source info for enum types.
691 class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
695 EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
698 /// \brief Wrapper for template type parameters.
699 class TemplateTypeParmTypeLoc :
700 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
701 TemplateTypeParmTypeLoc,
702 TemplateTypeParmType> {
704 TemplateTypeParmDecl *getDecl() const { return getTypePtr()->getDecl(); }
707 struct ObjCTypeParamTypeLocInfo {
708 SourceLocation NameLoc;
711 /// ProtocolLAngleLoc, ProtocolRAngleLoc, and the source locations for
712 /// protocol qualifiers are stored after Info.
713 class ObjCTypeParamTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
714 ObjCTypeParamTypeLoc,
716 ObjCTypeParamTypeLocInfo> {
717 // SourceLocations are stored after Info, one for each protocol qualifier.
718 SourceLocation *getProtocolLocArray() const {
719 return (SourceLocation*)this->getExtraLocalData() + 2;
723 ObjCTypeParamDecl *getDecl() const { return getTypePtr()->getDecl(); }
725 SourceLocation getNameLoc() const {
726 return this->getLocalData()->NameLoc;
729 void setNameLoc(SourceLocation Loc) {
730 this->getLocalData()->NameLoc = Loc;
733 SourceLocation getProtocolLAngleLoc() const {
734 return getNumProtocols() ?
735 *((SourceLocation*)this->getExtraLocalData()) :
738 void setProtocolLAngleLoc(SourceLocation Loc) {
739 *((SourceLocation*)this->getExtraLocalData()) = Loc;
742 SourceLocation getProtocolRAngleLoc() const {
743 return getNumProtocols() ?
744 *((SourceLocation*)this->getExtraLocalData() + 1) :
747 void setProtocolRAngleLoc(SourceLocation Loc) {
748 *((SourceLocation*)this->getExtraLocalData() + 1) = Loc;
751 unsigned getNumProtocols() const {
752 return this->getTypePtr()->getNumProtocols();
755 SourceLocation getProtocolLoc(unsigned i) const {
756 assert(i < getNumProtocols() && "Index is out of bounds!");
757 return getProtocolLocArray()[i];
759 void setProtocolLoc(unsigned i, SourceLocation Loc) {
760 assert(i < getNumProtocols() && "Index is out of bounds!");
761 getProtocolLocArray()[i] = Loc;
764 ObjCProtocolDecl *getProtocol(unsigned i) const {
765 assert(i < getNumProtocols() && "Index is out of bounds!");
766 return *(this->getTypePtr()->qual_begin() + i);
769 ArrayRef<SourceLocation> getProtocolLocs() const {
770 return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols());
773 void initializeLocal(ASTContext &Context, SourceLocation Loc);
775 unsigned getExtraLocalDataSize() const {
776 if (!this->getNumProtocols()) return 0;
777 // When there are protocol qualifers, we have LAngleLoc and RAngleLoc
779 return (this->getNumProtocols() + 2) * sizeof(SourceLocation) ;
781 unsigned getExtraLocalDataAlignment() const {
782 return alignof(SourceLocation);
784 SourceRange getLocalSourceRange() const {
785 SourceLocation start = getNameLoc();
786 SourceLocation end = getProtocolRAngleLoc();
787 if (end.isInvalid()) return SourceRange(start, start);
788 return SourceRange(start, end);
792 /// \brief Wrapper for substituted template type parameters.
793 class SubstTemplateTypeParmTypeLoc :
794 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
795 SubstTemplateTypeParmTypeLoc,
796 SubstTemplateTypeParmType> {
799 /// \brief Wrapper for substituted template type parameters.
800 class SubstTemplateTypeParmPackTypeLoc :
801 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
802 SubstTemplateTypeParmPackTypeLoc,
803 SubstTemplateTypeParmPackType> {
806 struct AttributedLocInfo {
810 /// A raw SourceLocation.
811 unsigned EnumOperandLoc;
814 SourceRange OperandParens;
816 SourceLocation AttrLoc;
819 /// \brief Type source information for an attributed type.
820 class AttributedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
825 AttributedType::Kind getAttrKind() const {
826 return getTypePtr()->getAttrKind();
829 bool hasAttrExprOperand() const {
830 return (getAttrKind() >= AttributedType::FirstExprOperandKind &&
831 getAttrKind() <= AttributedType::LastExprOperandKind);
834 bool hasAttrEnumOperand() const {
835 return (getAttrKind() >= AttributedType::FirstEnumOperandKind &&
836 getAttrKind() <= AttributedType::LastEnumOperandKind);
839 bool hasAttrOperand() const {
840 return hasAttrExprOperand() || hasAttrEnumOperand();
843 bool isQualifier() const {
844 return getTypePtr()->isQualifier();
847 /// The modified type, which is generally canonically different from
848 /// the attribute type.
849 /// int main(int, char**) __attribute__((noreturn))
850 /// ~~~ ~~~~~~~~~~~~~
851 TypeLoc getModifiedLoc() const {
852 return getInnerTypeLoc();
855 /// The location of the attribute name, i.e.
856 /// __attribute__((regparm(1000)))
858 SourceLocation getAttrNameLoc() const {
859 return getLocalData()->AttrLoc;
861 void setAttrNameLoc(SourceLocation loc) {
862 getLocalData()->AttrLoc = loc;
865 /// The attribute's expression operand, if it has one.
866 /// void *cur_thread __attribute__((address_space(21)))
868 Expr *getAttrExprOperand() const {
869 assert(hasAttrExprOperand());
870 return getLocalData()->ExprOperand;
872 void setAttrExprOperand(Expr *e) {
873 assert(hasAttrExprOperand());
874 getLocalData()->ExprOperand = e;
877 /// The location of the attribute's enumerated operand, if it has one.
878 /// void * __attribute__((objc_gc(weak)))
880 SourceLocation getAttrEnumOperandLoc() const {
881 assert(hasAttrEnumOperand());
882 return SourceLocation::getFromRawEncoding(getLocalData()->EnumOperandLoc);
884 void setAttrEnumOperandLoc(SourceLocation loc) {
885 assert(hasAttrEnumOperand());
886 getLocalData()->EnumOperandLoc = loc.getRawEncoding();
889 /// The location of the parentheses around the operand, if there is
891 /// void * __attribute__((objc_gc(weak)))
893 SourceRange getAttrOperandParensRange() const {
894 assert(hasAttrOperand());
895 return getLocalData()->OperandParens;
897 void setAttrOperandParensRange(SourceRange range) {
898 assert(hasAttrOperand());
899 getLocalData()->OperandParens = range;
902 SourceRange getLocalSourceRange() const {
903 // Note that this does *not* include the range of the attribute
905 // __attribute__((foo(bar)))
906 // ^~~~~~~~~~~~~~~ ~~
910 // That enclosure doesn't necessarily belong to a single attribute
912 SourceRange range(getAttrNameLoc());
913 if (hasAttrOperand())
914 range.setEnd(getAttrOperandParensRange().getEnd());
918 void initializeLocal(ASTContext &Context, SourceLocation loc) {
920 if (hasAttrExprOperand()) {
921 setAttrOperandParensRange(SourceRange(loc));
922 setAttrExprOperand(nullptr);
923 } else if (hasAttrEnumOperand()) {
924 setAttrOperandParensRange(SourceRange(loc));
925 setAttrEnumOperandLoc(loc);
929 QualType getInnerType() const {
930 return getTypePtr()->getModifiedType();
935 struct ObjCObjectTypeLocInfo {
936 SourceLocation TypeArgsLAngleLoc;
937 SourceLocation TypeArgsRAngleLoc;
938 SourceLocation ProtocolLAngleLoc;
939 SourceLocation ProtocolRAngleLoc;
940 bool HasBaseTypeAsWritten;
943 // A helper class for defining ObjC TypeLocs that can qualified with
946 // TypeClass basically has to be either ObjCInterfaceType or
947 // ObjCObjectPointerType.
948 class ObjCObjectTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
951 ObjCObjectTypeLocInfo> {
952 // TypeSourceInfo*'s are stored after Info, one for each type argument.
953 TypeSourceInfo **getTypeArgLocArray() const {
954 return (TypeSourceInfo**)this->getExtraLocalData();
957 // SourceLocations are stored after the type argument information, one for
959 SourceLocation *getProtocolLocArray() const {
960 return (SourceLocation*)(getTypeArgLocArray() + getNumTypeArgs());
964 SourceLocation getTypeArgsLAngleLoc() const {
965 return this->getLocalData()->TypeArgsLAngleLoc;
967 void setTypeArgsLAngleLoc(SourceLocation Loc) {
968 this->getLocalData()->TypeArgsLAngleLoc = Loc;
971 SourceLocation getTypeArgsRAngleLoc() const {
972 return this->getLocalData()->TypeArgsRAngleLoc;
974 void setTypeArgsRAngleLoc(SourceLocation Loc) {
975 this->getLocalData()->TypeArgsRAngleLoc = Loc;
978 unsigned getNumTypeArgs() const {
979 return this->getTypePtr()->getTypeArgsAsWritten().size();
982 TypeSourceInfo *getTypeArgTInfo(unsigned i) const {
983 assert(i < getNumTypeArgs() && "Index is out of bounds!");
984 return getTypeArgLocArray()[i];
987 void setTypeArgTInfo(unsigned i, TypeSourceInfo *TInfo) {
988 assert(i < getNumTypeArgs() && "Index is out of bounds!");
989 getTypeArgLocArray()[i] = TInfo;
992 SourceLocation getProtocolLAngleLoc() const {
993 return this->getLocalData()->ProtocolLAngleLoc;
995 void setProtocolLAngleLoc(SourceLocation Loc) {
996 this->getLocalData()->ProtocolLAngleLoc = Loc;
999 SourceLocation getProtocolRAngleLoc() const {
1000 return this->getLocalData()->ProtocolRAngleLoc;
1002 void setProtocolRAngleLoc(SourceLocation Loc) {
1003 this->getLocalData()->ProtocolRAngleLoc = Loc;
1006 unsigned getNumProtocols() const {
1007 return this->getTypePtr()->getNumProtocols();
1010 SourceLocation getProtocolLoc(unsigned i) const {
1011 assert(i < getNumProtocols() && "Index is out of bounds!");
1012 return getProtocolLocArray()[i];
1014 void setProtocolLoc(unsigned i, SourceLocation Loc) {
1015 assert(i < getNumProtocols() && "Index is out of bounds!");
1016 getProtocolLocArray()[i] = Loc;
1019 ObjCProtocolDecl *getProtocol(unsigned i) const {
1020 assert(i < getNumProtocols() && "Index is out of bounds!");
1021 return *(this->getTypePtr()->qual_begin() + i);
1025 ArrayRef<SourceLocation> getProtocolLocs() const {
1026 return llvm::makeArrayRef(getProtocolLocArray(), getNumProtocols());
1029 bool hasBaseTypeAsWritten() const {
1030 return getLocalData()->HasBaseTypeAsWritten;
1033 void setHasBaseTypeAsWritten(bool HasBaseType) {
1034 getLocalData()->HasBaseTypeAsWritten = HasBaseType;
1037 TypeLoc getBaseLoc() const {
1038 return getInnerTypeLoc();
1041 SourceRange getLocalSourceRange() const {
1042 SourceLocation start = getTypeArgsLAngleLoc();
1043 if (start.isInvalid())
1044 start = getProtocolLAngleLoc();
1045 SourceLocation end = getProtocolRAngleLoc();
1046 if (end.isInvalid())
1047 end = getTypeArgsRAngleLoc();
1048 return SourceRange(start, end);
1051 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1053 unsigned getExtraLocalDataSize() const {
1054 return this->getNumTypeArgs() * sizeof(TypeSourceInfo *)
1055 + this->getNumProtocols() * sizeof(SourceLocation);
1058 unsigned getExtraLocalDataAlignment() const {
1059 static_assert(alignof(ObjCObjectTypeLoc) >= alignof(TypeSourceInfo *),
1060 "not enough alignment for tail-allocated data");
1061 return alignof(TypeSourceInfo *);
1064 QualType getInnerType() const {
1065 return getTypePtr()->getBaseType();
1070 struct ObjCInterfaceLocInfo {
1071 SourceLocation NameLoc;
1072 SourceLocation NameEndLoc;
1075 /// \brief Wrapper for source info for ObjC interfaces.
1076 class ObjCInterfaceTypeLoc : public ConcreteTypeLoc<ObjCObjectTypeLoc,
1077 ObjCInterfaceTypeLoc,
1079 ObjCInterfaceLocInfo> {
1081 ObjCInterfaceDecl *getIFaceDecl() const {
1082 return getTypePtr()->getDecl();
1085 SourceLocation getNameLoc() const {
1086 return getLocalData()->NameLoc;
1089 void setNameLoc(SourceLocation Loc) {
1090 getLocalData()->NameLoc = Loc;
1093 SourceRange getLocalSourceRange() const {
1094 return SourceRange(getNameLoc(), getNameEndLoc());
1097 SourceLocation getNameEndLoc() const {
1098 return getLocalData()->NameEndLoc;
1101 void setNameEndLoc(SourceLocation Loc) {
1102 getLocalData()->NameEndLoc = Loc;
1105 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1111 struct ParenLocInfo {
1112 SourceLocation LParenLoc;
1113 SourceLocation RParenLoc;
1117 : public ConcreteTypeLoc<UnqualTypeLoc, ParenTypeLoc, ParenType,
1120 SourceLocation getLParenLoc() const {
1121 return this->getLocalData()->LParenLoc;
1123 SourceLocation getRParenLoc() const {
1124 return this->getLocalData()->RParenLoc;
1126 void setLParenLoc(SourceLocation Loc) {
1127 this->getLocalData()->LParenLoc = Loc;
1129 void setRParenLoc(SourceLocation Loc) {
1130 this->getLocalData()->RParenLoc = Loc;
1133 SourceRange getLocalSourceRange() const {
1134 return SourceRange(getLParenLoc(), getRParenLoc());
1137 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1142 TypeLoc getInnerLoc() const {
1143 return getInnerTypeLoc();
1146 QualType getInnerType() const {
1147 return this->getTypePtr()->getInnerType();
1151 inline TypeLoc TypeLoc::IgnoreParens() const {
1152 if (ParenTypeLoc::isKind(*this))
1153 return IgnoreParensImpl(*this);
1158 struct AdjustedLocInfo { }; // Nothing.
1160 class AdjustedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AdjustedTypeLoc,
1161 AdjustedType, AdjustedLocInfo> {
1163 TypeLoc getOriginalLoc() const {
1164 return getInnerTypeLoc();
1167 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1171 QualType getInnerType() const {
1172 // The inner type is the undecayed type, since that's what we have source
1173 // location information for.
1174 return getTypePtr()->getOriginalType();
1177 SourceRange getLocalSourceRange() const {
1178 return SourceRange();
1181 unsigned getLocalDataSize() const {
1182 // sizeof(AdjustedLocInfo) is 1, but we don't need its address to be unique
1183 // anyway. TypeLocBuilder can't handle data sizes of 1.
1184 return 0; // No data.
1188 /// \brief Wrapper for source info for pointers decayed from arrays and
1190 class DecayedTypeLoc : public InheritingConcreteTypeLoc<
1191 AdjustedTypeLoc, DecayedTypeLoc, DecayedType> {
1194 struct PointerLikeLocInfo {
1195 SourceLocation StarLoc;
1198 /// A base class for
1199 template <class Derived, class TypeClass, class LocalData = PointerLikeLocInfo>
1200 class PointerLikeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, Derived,
1201 TypeClass, LocalData> {
1203 SourceLocation getSigilLoc() const {
1204 return this->getLocalData()->StarLoc;
1206 void setSigilLoc(SourceLocation Loc) {
1207 this->getLocalData()->StarLoc = Loc;
1210 TypeLoc getPointeeLoc() const {
1211 return this->getInnerTypeLoc();
1214 SourceRange getLocalSourceRange() const {
1215 return SourceRange(getSigilLoc(), getSigilLoc());
1218 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1222 QualType getInnerType() const {
1223 return this->getTypePtr()->getPointeeType();
1228 /// \brief Wrapper for source info for pointers.
1229 class PointerTypeLoc : public PointerLikeTypeLoc<PointerTypeLoc,
1232 SourceLocation getStarLoc() const {
1233 return getSigilLoc();
1235 void setStarLoc(SourceLocation Loc) {
1241 /// \brief Wrapper for source info for block pointers.
1242 class BlockPointerTypeLoc : public PointerLikeTypeLoc<BlockPointerTypeLoc,
1245 SourceLocation getCaretLoc() const {
1246 return getSigilLoc();
1248 void setCaretLoc(SourceLocation Loc) {
1253 struct MemberPointerLocInfo : public PointerLikeLocInfo {
1254 TypeSourceInfo *ClassTInfo;
1257 /// \brief Wrapper for source info for member pointers.
1258 class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
1260 MemberPointerLocInfo> {
1262 SourceLocation getStarLoc() const {
1263 return getSigilLoc();
1265 void setStarLoc(SourceLocation Loc) {
1269 const Type *getClass() const {
1270 return getTypePtr()->getClass();
1272 TypeSourceInfo *getClassTInfo() const {
1273 return getLocalData()->ClassTInfo;
1275 void setClassTInfo(TypeSourceInfo* TI) {
1276 getLocalData()->ClassTInfo = TI;
1279 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1281 setClassTInfo(nullptr);
1284 SourceRange getLocalSourceRange() const {
1285 if (TypeSourceInfo *TI = getClassTInfo())
1286 return SourceRange(TI->getTypeLoc().getBeginLoc(), getStarLoc());
1288 return SourceRange(getStarLoc());
1292 /// Wraps an ObjCPointerType with source location information.
1293 class ObjCObjectPointerTypeLoc :
1294 public PointerLikeTypeLoc<ObjCObjectPointerTypeLoc,
1295 ObjCObjectPointerType> {
1297 SourceLocation getStarLoc() const {
1298 return getSigilLoc();
1301 void setStarLoc(SourceLocation Loc) {
1307 class ReferenceTypeLoc : public PointerLikeTypeLoc<ReferenceTypeLoc,
1310 QualType getInnerType() const {
1311 return getTypePtr()->getPointeeTypeAsWritten();
1315 class LValueReferenceTypeLoc :
1316 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1317 LValueReferenceTypeLoc,
1318 LValueReferenceType> {
1320 SourceLocation getAmpLoc() const {
1321 return getSigilLoc();
1323 void setAmpLoc(SourceLocation Loc) {
1328 class RValueReferenceTypeLoc :
1329 public InheritingConcreteTypeLoc<ReferenceTypeLoc,
1330 RValueReferenceTypeLoc,
1331 RValueReferenceType> {
1333 SourceLocation getAmpAmpLoc() const {
1334 return getSigilLoc();
1336 void setAmpAmpLoc(SourceLocation Loc) {
1342 struct FunctionLocInfo {
1343 SourceLocation LocalRangeBegin;
1344 SourceLocation LParenLoc;
1345 SourceLocation RParenLoc;
1346 SourceLocation LocalRangeEnd;
1349 /// \brief Wrapper for source info for functions.
1350 class FunctionTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1354 bool hasExceptionSpec() const {
1355 if (auto *FPT = dyn_cast<FunctionProtoType>(getTypePtr())) {
1356 return FPT->hasExceptionSpec();
1361 SourceRange *getExceptionSpecRangePtr() const {
1362 assert(hasExceptionSpec() && "No exception spec range");
1363 // After the Info comes the ParmVarDecl array, and after that comes the
1364 // exception specification information.
1365 return (SourceRange *)(getParmArray() + getNumParams());
1368 SourceLocation getLocalRangeBegin() const {
1369 return getLocalData()->LocalRangeBegin;
1371 void setLocalRangeBegin(SourceLocation L) {
1372 getLocalData()->LocalRangeBegin = L;
1375 SourceLocation getLocalRangeEnd() const {
1376 return getLocalData()->LocalRangeEnd;
1378 void setLocalRangeEnd(SourceLocation L) {
1379 getLocalData()->LocalRangeEnd = L;
1382 SourceLocation getLParenLoc() const {
1383 return this->getLocalData()->LParenLoc;
1385 void setLParenLoc(SourceLocation Loc) {
1386 this->getLocalData()->LParenLoc = Loc;
1389 SourceLocation getRParenLoc() const {
1390 return this->getLocalData()->RParenLoc;
1392 void setRParenLoc(SourceLocation Loc) {
1393 this->getLocalData()->RParenLoc = Loc;
1396 SourceRange getParensRange() const {
1397 return SourceRange(getLParenLoc(), getRParenLoc());
1400 SourceRange getExceptionSpecRange() const {
1401 if (hasExceptionSpec())
1402 return *getExceptionSpecRangePtr();
1403 return SourceRange();
1405 void setExceptionSpecRange(SourceRange R) {
1406 if (hasExceptionSpec())
1407 *getExceptionSpecRangePtr() = R;
1410 ArrayRef<ParmVarDecl *> getParams() const {
1411 return llvm::makeArrayRef(getParmArray(), getNumParams());
1414 // ParmVarDecls* are stored after Info, one for each parameter.
1415 ParmVarDecl **getParmArray() const {
1416 return (ParmVarDecl**) getExtraLocalData();
1419 unsigned getNumParams() const {
1420 if (isa<FunctionNoProtoType>(getTypePtr()))
1422 return cast<FunctionProtoType>(getTypePtr())->getNumParams();
1424 ParmVarDecl *getParam(unsigned i) const { return getParmArray()[i]; }
1425 void setParam(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; }
1427 TypeLoc getReturnLoc() const {
1428 return getInnerTypeLoc();
1431 SourceRange getLocalSourceRange() const {
1432 return SourceRange(getLocalRangeBegin(), getLocalRangeEnd());
1435 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1436 setLocalRangeBegin(Loc);
1439 setLocalRangeEnd(Loc);
1440 for (unsigned i = 0, e = getNumParams(); i != e; ++i)
1441 setParam(i, nullptr);
1442 if (hasExceptionSpec())
1443 setExceptionSpecRange(Loc);
1446 /// \brief Returns the size of the type source info data block that is
1447 /// specific to this type.
1448 unsigned getExtraLocalDataSize() const {
1449 unsigned ExceptSpecSize = hasExceptionSpec() ? sizeof(SourceRange) : 0;
1450 return (getNumParams() * sizeof(ParmVarDecl *)) + ExceptSpecSize;
1453 unsigned getExtraLocalDataAlignment() const { return alignof(ParmVarDecl *); }
1455 QualType getInnerType() const { return getTypePtr()->getReturnType(); }
1458 class FunctionProtoTypeLoc :
1459 public InheritingConcreteTypeLoc<FunctionTypeLoc,
1460 FunctionProtoTypeLoc,
1461 FunctionProtoType> {
1464 class FunctionNoProtoTypeLoc :
1465 public InheritingConcreteTypeLoc<FunctionTypeLoc,
1466 FunctionNoProtoTypeLoc,
1467 FunctionNoProtoType> {
1471 struct ArrayLocInfo {
1472 SourceLocation LBracketLoc, RBracketLoc;
1476 /// \brief Wrapper for source info for arrays.
1477 class ArrayTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1482 SourceLocation getLBracketLoc() const {
1483 return getLocalData()->LBracketLoc;
1485 void setLBracketLoc(SourceLocation Loc) {
1486 getLocalData()->LBracketLoc = Loc;
1489 SourceLocation getRBracketLoc() const {
1490 return getLocalData()->RBracketLoc;
1492 void setRBracketLoc(SourceLocation Loc) {
1493 getLocalData()->RBracketLoc = Loc;
1496 SourceRange getBracketsRange() const {
1497 return SourceRange(getLBracketLoc(), getRBracketLoc());
1500 Expr *getSizeExpr() const {
1501 return getLocalData()->Size;
1503 void setSizeExpr(Expr *Size) {
1504 getLocalData()->Size = Size;
1507 TypeLoc getElementLoc() const {
1508 return getInnerTypeLoc();
1511 SourceRange getLocalSourceRange() const {
1512 return SourceRange(getLBracketLoc(), getRBracketLoc());
1515 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1516 setLBracketLoc(Loc);
1517 setRBracketLoc(Loc);
1518 setSizeExpr(nullptr);
1521 QualType getInnerType() const { return getTypePtr()->getElementType(); }
1524 class ConstantArrayTypeLoc :
1525 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1526 ConstantArrayTypeLoc,
1527 ConstantArrayType> {
1530 class IncompleteArrayTypeLoc :
1531 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1532 IncompleteArrayTypeLoc,
1533 IncompleteArrayType> {
1536 class DependentSizedArrayTypeLoc :
1537 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1538 DependentSizedArrayTypeLoc,
1539 DependentSizedArrayType> {
1543 class VariableArrayTypeLoc :
1544 public InheritingConcreteTypeLoc<ArrayTypeLoc,
1545 VariableArrayTypeLoc,
1546 VariableArrayType> {
1550 // Location information for a TemplateName. Rudimentary for now.
1551 struct TemplateNameLocInfo {
1552 SourceLocation NameLoc;
1555 struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
1556 SourceLocation TemplateKWLoc;
1557 SourceLocation LAngleLoc;
1558 SourceLocation RAngleLoc;
1561 class TemplateSpecializationTypeLoc :
1562 public ConcreteTypeLoc<UnqualTypeLoc,
1563 TemplateSpecializationTypeLoc,
1564 TemplateSpecializationType,
1565 TemplateSpecializationLocInfo> {
1567 SourceLocation getTemplateKeywordLoc() const {
1568 return getLocalData()->TemplateKWLoc;
1570 void setTemplateKeywordLoc(SourceLocation Loc) {
1571 getLocalData()->TemplateKWLoc = Loc;
1574 SourceLocation getLAngleLoc() const {
1575 return getLocalData()->LAngleLoc;
1577 void setLAngleLoc(SourceLocation Loc) {
1578 getLocalData()->LAngleLoc = Loc;
1581 SourceLocation getRAngleLoc() const {
1582 return getLocalData()->RAngleLoc;
1584 void setRAngleLoc(SourceLocation Loc) {
1585 getLocalData()->RAngleLoc = Loc;
1588 unsigned getNumArgs() const {
1589 return getTypePtr()->getNumArgs();
1591 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
1592 getArgInfos()[i] = AI;
1594 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
1595 return getArgInfos()[i];
1598 TemplateArgumentLoc getArgLoc(unsigned i) const {
1599 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
1602 SourceLocation getTemplateNameLoc() const {
1603 return getLocalData()->NameLoc;
1605 void setTemplateNameLoc(SourceLocation Loc) {
1606 getLocalData()->NameLoc = Loc;
1609 /// \brief - Copy the location information from the given info.
1610 void copy(TemplateSpecializationTypeLoc Loc) {
1611 unsigned size = getFullDataSize();
1612 assert(size == Loc.getFullDataSize());
1614 // We're potentially copying Expr references here. We don't
1615 // bother retaining them because TypeSourceInfos live forever, so
1616 // as long as the Expr was retained when originally written into
1617 // the TypeLoc, we're okay.
1618 memcpy(Data, Loc.Data, size);
1621 SourceRange getLocalSourceRange() const {
1622 if (getTemplateKeywordLoc().isValid())
1623 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
1625 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
1628 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1629 setTemplateKeywordLoc(Loc);
1630 setTemplateNameLoc(Loc);
1633 initializeArgLocs(Context, getNumArgs(), getTypePtr()->getArgs(),
1634 getArgInfos(), Loc);
1637 static void initializeArgLocs(ASTContext &Context, unsigned NumArgs,
1638 const TemplateArgument *Args,
1639 TemplateArgumentLocInfo *ArgInfos,
1640 SourceLocation Loc);
1642 unsigned getExtraLocalDataSize() const {
1643 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
1646 unsigned getExtraLocalDataAlignment() const {
1647 return alignof(TemplateArgumentLocInfo);
1651 TemplateArgumentLocInfo *getArgInfos() const {
1652 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
1656 //===----------------------------------------------------------------------===//
1658 // All of these need proper implementations.
1660 //===----------------------------------------------------------------------===//
1662 // FIXME: size expression and attribute locations (or keyword if we
1663 // ever fully support altivec syntax).
1664 class VectorTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1669 // FIXME: size expression and attribute locations.
1670 class ExtVectorTypeLoc : public InheritingConcreteTypeLoc<VectorTypeLoc,
1675 // FIXME: attribute locations.
1676 // For some reason, this isn't a subtype of VectorType.
1677 class DependentSizedExtVectorTypeLoc :
1678 public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1679 DependentSizedExtVectorTypeLoc,
1680 DependentSizedExtVectorType> {
1683 // FIXME: location of the '_Complex' keyword.
1684 class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1689 struct TypeofLocInfo {
1690 SourceLocation TypeofLoc;
1691 SourceLocation LParenLoc;
1692 SourceLocation RParenLoc;
1695 struct TypeOfExprTypeLocInfo : public TypeofLocInfo {
1698 struct TypeOfTypeLocInfo : public TypeofLocInfo {
1699 TypeSourceInfo* UnderlyingTInfo;
1702 template <class Derived, class TypeClass, class LocalData = TypeofLocInfo>
1703 class TypeofLikeTypeLoc
1704 : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> {
1706 SourceLocation getTypeofLoc() const {
1707 return this->getLocalData()->TypeofLoc;
1709 void setTypeofLoc(SourceLocation Loc) {
1710 this->getLocalData()->TypeofLoc = Loc;
1713 SourceLocation getLParenLoc() const {
1714 return this->getLocalData()->LParenLoc;
1716 void setLParenLoc(SourceLocation Loc) {
1717 this->getLocalData()->LParenLoc = Loc;
1720 SourceLocation getRParenLoc() const {
1721 return this->getLocalData()->RParenLoc;
1723 void setRParenLoc(SourceLocation Loc) {
1724 this->getLocalData()->RParenLoc = Loc;
1727 SourceRange getParensRange() const {
1728 return SourceRange(getLParenLoc(), getRParenLoc());
1730 void setParensRange(SourceRange range) {
1731 setLParenLoc(range.getBegin());
1732 setRParenLoc(range.getEnd());
1735 SourceRange getLocalSourceRange() const {
1736 return SourceRange(getTypeofLoc(), getRParenLoc());
1739 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1746 class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc,
1748 TypeOfExprTypeLocInfo> {
1750 Expr* getUnderlyingExpr() const {
1751 return getTypePtr()->getUnderlyingExpr();
1753 // Reimplemented to account for GNU/C++ extension
1754 // typeof unary-expression
1755 // where there are no parentheses.
1756 SourceRange getLocalSourceRange() const;
1760 : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> {
1762 QualType getUnderlyingType() const {
1763 return this->getTypePtr()->getUnderlyingType();
1765 TypeSourceInfo* getUnderlyingTInfo() const {
1766 return this->getLocalData()->UnderlyingTInfo;
1768 void setUnderlyingTInfo(TypeSourceInfo* TI) const {
1769 this->getLocalData()->UnderlyingTInfo = TI;
1772 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1775 // FIXME: location of the 'decltype' and parens.
1776 class DecltypeTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1780 Expr *getUnderlyingExpr() const { return getTypePtr()->getUnderlyingExpr(); }
1783 struct UnaryTransformTypeLocInfo {
1784 // FIXME: While there's only one unary transform right now, future ones may
1785 // need different representations
1786 SourceLocation KWLoc, LParenLoc, RParenLoc;
1787 TypeSourceInfo *UnderlyingTInfo;
1790 class UnaryTransformTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1791 UnaryTransformTypeLoc,
1793 UnaryTransformTypeLocInfo> {
1795 SourceLocation getKWLoc() const { return getLocalData()->KWLoc; }
1796 void setKWLoc(SourceLocation Loc) { getLocalData()->KWLoc = Loc; }
1798 SourceLocation getLParenLoc() const { return getLocalData()->LParenLoc; }
1799 void setLParenLoc(SourceLocation Loc) { getLocalData()->LParenLoc = Loc; }
1801 SourceLocation getRParenLoc() const { return getLocalData()->RParenLoc; }
1802 void setRParenLoc(SourceLocation Loc) { getLocalData()->RParenLoc = Loc; }
1804 TypeSourceInfo* getUnderlyingTInfo() const {
1805 return getLocalData()->UnderlyingTInfo;
1807 void setUnderlyingTInfo(TypeSourceInfo *TInfo) {
1808 getLocalData()->UnderlyingTInfo = TInfo;
1811 SourceRange getLocalSourceRange() const {
1812 return SourceRange(getKWLoc(), getRParenLoc());
1815 SourceRange getParensRange() const {
1816 return SourceRange(getLParenLoc(), getRParenLoc());
1818 void setParensRange(SourceRange Range) {
1819 setLParenLoc(Range.getBegin());
1820 setRParenLoc(Range.getEnd());
1823 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
1830 class AutoTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
1835 struct ElaboratedLocInfo {
1836 SourceLocation ElaboratedKWLoc;
1837 /// \brief Data associated with the nested-name-specifier location.
1838 void *QualifierData;
1841 class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1844 ElaboratedLocInfo> {
1846 SourceLocation getElaboratedKeywordLoc() const {
1847 return this->getLocalData()->ElaboratedKWLoc;
1849 void setElaboratedKeywordLoc(SourceLocation Loc) {
1850 this->getLocalData()->ElaboratedKWLoc = Loc;
1853 NestedNameSpecifierLoc getQualifierLoc() const {
1854 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1855 getLocalData()->QualifierData);
1858 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1859 assert(QualifierLoc.getNestedNameSpecifier()
1860 == getTypePtr()->getQualifier() &&
1861 "Inconsistent nested-name-specifier pointer");
1862 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1865 SourceRange getLocalSourceRange() const {
1866 if (getElaboratedKeywordLoc().isValid())
1867 if (getQualifierLoc())
1868 return SourceRange(getElaboratedKeywordLoc(),
1869 getQualifierLoc().getEndLoc());
1871 return SourceRange(getElaboratedKeywordLoc());
1873 return getQualifierLoc().getSourceRange();
1876 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1878 TypeLoc getNamedTypeLoc() const {
1879 return getInnerTypeLoc();
1882 QualType getInnerType() const {
1883 return getTypePtr()->getNamedType();
1886 void copy(ElaboratedTypeLoc Loc) {
1887 unsigned size = getFullDataSize();
1888 assert(size == Loc.getFullDataSize());
1889 memcpy(Data, Loc.Data, size);
1893 // This is exactly the structure of an ElaboratedTypeLoc whose inner
1894 // type is some sort of TypeDeclTypeLoc.
1895 struct DependentNameLocInfo : ElaboratedLocInfo {
1896 SourceLocation NameLoc;
1899 class DependentNameTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
1900 DependentNameTypeLoc,
1902 DependentNameLocInfo> {
1904 SourceLocation getElaboratedKeywordLoc() const {
1905 return this->getLocalData()->ElaboratedKWLoc;
1907 void setElaboratedKeywordLoc(SourceLocation Loc) {
1908 this->getLocalData()->ElaboratedKWLoc = Loc;
1911 NestedNameSpecifierLoc getQualifierLoc() const {
1912 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1913 getLocalData()->QualifierData);
1916 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1917 assert(QualifierLoc.getNestedNameSpecifier()
1918 == getTypePtr()->getQualifier() &&
1919 "Inconsistent nested-name-specifier pointer");
1920 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1923 SourceLocation getNameLoc() const {
1924 return this->getLocalData()->NameLoc;
1926 void setNameLoc(SourceLocation Loc) {
1927 this->getLocalData()->NameLoc = Loc;
1930 SourceRange getLocalSourceRange() const {
1931 if (getElaboratedKeywordLoc().isValid())
1932 return SourceRange(getElaboratedKeywordLoc(), getNameLoc());
1934 return SourceRange(getQualifierLoc().getBeginLoc(), getNameLoc());
1937 void copy(DependentNameTypeLoc Loc) {
1938 unsigned size = getFullDataSize();
1939 assert(size == Loc.getFullDataSize());
1940 memcpy(Data, Loc.Data, size);
1943 void initializeLocal(ASTContext &Context, SourceLocation Loc);
1946 struct DependentTemplateSpecializationLocInfo : DependentNameLocInfo {
1947 SourceLocation TemplateKWLoc;
1948 SourceLocation LAngleLoc;
1949 SourceLocation RAngleLoc;
1950 // followed by a TemplateArgumentLocInfo[]
1953 class DependentTemplateSpecializationTypeLoc :
1954 public ConcreteTypeLoc<UnqualTypeLoc,
1955 DependentTemplateSpecializationTypeLoc,
1956 DependentTemplateSpecializationType,
1957 DependentTemplateSpecializationLocInfo> {
1959 SourceLocation getElaboratedKeywordLoc() const {
1960 return this->getLocalData()->ElaboratedKWLoc;
1962 void setElaboratedKeywordLoc(SourceLocation Loc) {
1963 this->getLocalData()->ElaboratedKWLoc = Loc;
1966 NestedNameSpecifierLoc getQualifierLoc() const {
1967 if (!getLocalData()->QualifierData)
1968 return NestedNameSpecifierLoc();
1970 return NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
1971 getLocalData()->QualifierData);
1974 void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
1975 if (!QualifierLoc) {
1976 // Even if we have a nested-name-specifier in the dependent
1977 // template specialization type, we won't record the nested-name-specifier
1978 // location information when this type-source location information is
1979 // part of a nested-name-specifier.
1980 getLocalData()->QualifierData = nullptr;
1984 assert(QualifierLoc.getNestedNameSpecifier()
1985 == getTypePtr()->getQualifier() &&
1986 "Inconsistent nested-name-specifier pointer");
1987 getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
1990 SourceLocation getTemplateKeywordLoc() const {
1991 return getLocalData()->TemplateKWLoc;
1993 void setTemplateKeywordLoc(SourceLocation Loc) {
1994 getLocalData()->TemplateKWLoc = Loc;
1997 SourceLocation getTemplateNameLoc() const {
1998 return this->getLocalData()->NameLoc;
2000 void setTemplateNameLoc(SourceLocation Loc) {
2001 this->getLocalData()->NameLoc = Loc;
2004 SourceLocation getLAngleLoc() const {
2005 return this->getLocalData()->LAngleLoc;
2007 void setLAngleLoc(SourceLocation Loc) {
2008 this->getLocalData()->LAngleLoc = Loc;
2011 SourceLocation getRAngleLoc() const {
2012 return this->getLocalData()->RAngleLoc;
2014 void setRAngleLoc(SourceLocation Loc) {
2015 this->getLocalData()->RAngleLoc = Loc;
2018 unsigned getNumArgs() const {
2019 return getTypePtr()->getNumArgs();
2022 void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
2023 getArgInfos()[i] = AI;
2025 TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
2026 return getArgInfos()[i];
2029 TemplateArgumentLoc getArgLoc(unsigned i) const {
2030 return TemplateArgumentLoc(getTypePtr()->getArg(i), getArgLocInfo(i));
2033 SourceRange getLocalSourceRange() const {
2034 if (getElaboratedKeywordLoc().isValid())
2035 return SourceRange(getElaboratedKeywordLoc(), getRAngleLoc());
2036 else if (getQualifierLoc())
2037 return SourceRange(getQualifierLoc().getBeginLoc(), getRAngleLoc());
2038 else if (getTemplateKeywordLoc().isValid())
2039 return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
2041 return SourceRange(getTemplateNameLoc(), getRAngleLoc());
2044 void copy(DependentTemplateSpecializationTypeLoc Loc) {
2045 unsigned size = getFullDataSize();
2046 assert(size == Loc.getFullDataSize());
2047 memcpy(Data, Loc.Data, size);
2050 void initializeLocal(ASTContext &Context, SourceLocation Loc);
2052 unsigned getExtraLocalDataSize() const {
2053 return getNumArgs() * sizeof(TemplateArgumentLocInfo);
2056 unsigned getExtraLocalDataAlignment() const {
2057 return alignof(TemplateArgumentLocInfo);
2061 TemplateArgumentLocInfo *getArgInfos() const {
2062 return static_cast<TemplateArgumentLocInfo*>(getExtraLocalData());
2067 struct PackExpansionTypeLocInfo {
2068 SourceLocation EllipsisLoc;
2071 class PackExpansionTypeLoc
2072 : public ConcreteTypeLoc<UnqualTypeLoc, PackExpansionTypeLoc,
2073 PackExpansionType, PackExpansionTypeLocInfo> {
2075 SourceLocation getEllipsisLoc() const {
2076 return this->getLocalData()->EllipsisLoc;
2079 void setEllipsisLoc(SourceLocation Loc) {
2080 this->getLocalData()->EllipsisLoc = Loc;
2083 SourceRange getLocalSourceRange() const {
2084 return SourceRange(getEllipsisLoc(), getEllipsisLoc());
2087 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2088 setEllipsisLoc(Loc);
2091 TypeLoc getPatternLoc() const {
2092 return getInnerTypeLoc();
2095 QualType getInnerType() const {
2096 return this->getTypePtr()->getPattern();
2100 struct AtomicTypeLocInfo {
2101 SourceLocation KWLoc, LParenLoc, RParenLoc;
2104 class AtomicTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, AtomicTypeLoc,
2105 AtomicType, AtomicTypeLocInfo> {
2107 TypeLoc getValueLoc() const {
2108 return this->getInnerTypeLoc();
2111 SourceRange getLocalSourceRange() const {
2112 return SourceRange(getKWLoc(), getRParenLoc());
2115 SourceLocation getKWLoc() const {
2116 return this->getLocalData()->KWLoc;
2118 void setKWLoc(SourceLocation Loc) {
2119 this->getLocalData()->KWLoc = Loc;
2122 SourceLocation getLParenLoc() const {
2123 return this->getLocalData()->LParenLoc;
2125 void setLParenLoc(SourceLocation Loc) {
2126 this->getLocalData()->LParenLoc = Loc;
2129 SourceLocation getRParenLoc() const {
2130 return this->getLocalData()->RParenLoc;
2132 void setRParenLoc(SourceLocation Loc) {
2133 this->getLocalData()->RParenLoc = Loc;
2136 SourceRange getParensRange() const {
2137 return SourceRange(getLParenLoc(), getRParenLoc());
2139 void setParensRange(SourceRange Range) {
2140 setLParenLoc(Range.getBegin());
2141 setRParenLoc(Range.getEnd());
2144 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2150 QualType getInnerType() const {
2151 return this->getTypePtr()->getValueType();
2155 struct PipeTypeLocInfo {
2156 SourceLocation KWLoc;
2159 class PipeTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, PipeTypeLoc, PipeType,
2162 TypeLoc getValueLoc() const { return this->getInnerTypeLoc(); }
2164 SourceRange getLocalSourceRange() const { return SourceRange(getKWLoc()); }
2166 SourceLocation getKWLoc() const { return this->getLocalData()->KWLoc; }
2167 void setKWLoc(SourceLocation Loc) { this->getLocalData()->KWLoc = Loc; }
2169 void initializeLocal(ASTContext &Context, SourceLocation Loc) {
2173 QualType getInnerType() const { return this->getTypePtr()->getElementType(); }