From 1700197e65896dc0e4697f3b802cb2e1bea0e850 Mon Sep 17 00:00:00 2001 From: John McCall Date: Sun, 18 Oct 2009 01:05:36 +0000 Subject: [PATCH] Clone the full Type hierarchy into the TypeLoc hierarchy. Normalize TypeLoc class names to be $(Type classname)Loc. Rewrite the visitor. Provide skeleton implementations for all the new TypeLocs. Handle all cases in PCH. Handle a few more cases when inserting location information in SemaType. It should be extremely straightforward to add new location information to existing TypeLoc objects now. llvm-svn: 84386 --- clang/include/clang/AST/TypeLoc.h | 509 ++++++++++++----------- clang/include/clang/AST/TypeLocNodes.def | 46 +- clang/include/clang/AST/TypeLocVisitor.h | 44 +- clang/include/clang/Index/ASTLocation.h | 2 +- clang/lib/AST/Decl.cpp | 11 +- clang/lib/AST/TypeLoc.cpp | 210 ++-------- clang/lib/Frontend/PCHReader.cpp | 147 +++++-- clang/lib/Frontend/PCHWriter.cpp | 147 +++++-- clang/lib/Index/ASTLocation.cpp | 2 +- clang/lib/Index/ASTVisitor.h | 8 +- clang/lib/Index/DeclReferenceMap.cpp | 8 +- clang/lib/Index/ResolveLocation.cpp | 20 +- clang/lib/Sema/SemaType.cpp | 165 ++++---- 13 files changed, 684 insertions(+), 635 deletions(-) diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h index 22837d804823..fb202a5a50a1 100644 --- a/clang/include/clang/AST/TypeLoc.h +++ b/clang/include/clang/AST/TypeLoc.h @@ -18,10 +18,15 @@ namespace clang { class ParmVarDecl; - class TypeSpecLoc; class DeclaratorInfo; class UnqualTypeLoc; +// Predeclare all the type nodes. +#define ABSTRACT_TYPELOC(Class, Base) +#define TYPELOC(Class, Base) \ + class Class##TypeLoc; +#include "clang/AST/TypeLocNodes.def" + /// \brief Base wrapper for a particular "section" of type source info. /// /// A client should use the TypeLoc subclasses through cast/dyn_cast in order to @@ -34,12 +39,28 @@ protected: void *Data; public: + /// The kinds of TypeLocs. Equivalent to the Type::TypeClass enum, + /// except it also defines a Qualified enum that corresponds to the + /// QualifiedLoc class. + enum TypeLocClass { +#define ABSTRACT_TYPE(Class, Base) +#define TYPE(Class, Base) \ + Class = Type::Class, +#include "clang/AST/TypeNodes.def" + Qualified + }; + TypeLoc() : Ty(0), Data(0) { } TypeLoc(QualType ty, void *opaqueData) : Ty(ty.getAsOpaquePtr()), Data(opaqueData) { } TypeLoc(Type *ty, void *opaqueData) : Ty(ty), Data(opaqueData) { } + TypeLocClass getTypeLocClass() const { + if (getType().hasQualifiers()) return Qualified; + return (TypeLocClass) getType()->getTypeClass(); + } + bool isNull() const { return !Ty; } operator bool() const { return Ty; } @@ -48,35 +69,36 @@ public: /// \brief Get the type for which this source info wrapper provides /// information. - QualType getSourceType() const { return QualType::getFromOpaquePtr(Ty); } + QualType getType() const { + return QualType::getFromOpaquePtr(Ty); + } - Type *getSourceTypePtr() const { + Type *getTypePtr() const { return QualType::getFromOpaquePtr(Ty).getTypePtr(); } /// \brief Get the pointer where source information is stored. - void *getOpaqueData() const { return Data; } - - SourceRange getSourceRange() const; - - /// \brief Find the TypeSpecLoc that is part of this TypeLoc. - TypeSpecLoc getTypeSpecLoc() const; + void *getOpaqueData() const { + return Data; + } - /// \brief Find the TypeSpecLoc that is part of this TypeLoc and return its - /// SourceRange. - SourceRange getTypeSpecRange() const; + SourceRange getSourceRange() const { + return getSourceRangeImpl(*this); + } /// \brief Returns the size of the type source info data block. unsigned getFullDataSize() const { - return getFullDataSizeForType(getSourceType()); + return getFullDataSizeForType(getType()); } /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the /// TypeLoc is a PointerLoc and next TypeLoc is for "int". - TypeLoc getNextTypeLoc() const; + TypeLoc getNextTypeLoc() const { + return getNextTypeLocImpl(*this); + } /// \brief Skips past any qualifiers, if this is qualified. - UnqualTypeLoc getUnqualifiedLoc() const; + UnqualTypeLoc getUnqualifiedLoc() const; // implemented in this header /// \brief Initializes this to state that every location in this /// type is the given location. @@ -99,6 +121,8 @@ public: private: static void initializeImpl(TypeLoc TL, SourceLocation Loc); + static TypeLoc getNextTypeLocImpl(TypeLoc TL); + static SourceRange getSourceRangeImpl(TypeLoc TL); }; /// \brief Wrapper of type source information for a type with @@ -108,12 +132,16 @@ public: UnqualTypeLoc() {} UnqualTypeLoc(Type *Ty, void *Data) : TypeLoc(Ty, Data) {} - Type *getSourceTypePtr() const { + Type *getTypePtr() const { return reinterpret_cast(Ty); } + TypeLocClass getTypeLocClass() const { + return (TypeLocClass) getTypePtr()->getTypeClass(); + } + static bool classof(const TypeLoc *TL) { - return !TL->getSourceType().hasQualifiers(); + return !TL->getType().hasQualifiers(); } static bool classof(const UnqualTypeLoc *TL) { return true; } }; @@ -123,14 +151,14 @@ public: /// /// Currently, we intentionally do not provide source location for /// type qualifiers. -class QualifiedLoc : public TypeLoc { +class QualifiedTypeLoc : public TypeLoc { public: SourceRange getSourceRange() const { return SourceRange(); } UnqualTypeLoc getUnqualifiedLoc() const { - return UnqualTypeLoc(getSourceTypePtr(), Data); + return UnqualTypeLoc(getTypePtr(), Data); } /// Initializes the local data of this type source info block to @@ -154,52 +182,21 @@ public: /// \brief Returns the size of the type source info data block. unsigned getFullDataSize() const { return getLocalDataSize() + - getFullDataSizeForType(getSourceType().getUnqualifiedType()); + getFullDataSizeForType(getType().getUnqualifiedType()); } static bool classof(const TypeLoc *TL) { - return TL->getSourceType().hasQualifiers(); + return TL->getType().hasQualifiers(); } - static bool classof(const QualifiedLoc *TL) { return true; } + static bool classof(const QualifiedTypeLoc *TL) { return true; } }; inline UnqualTypeLoc TypeLoc::getUnqualifiedLoc() const { - if (isa(this)) - return cast(this)->getUnqualifiedLoc(); + if (isa(this)) + return cast(this)->getUnqualifiedLoc(); return cast(*this); } -/// \brief Base wrapper of type source info data for type-spec types. -class TypeSpecLoc : public UnqualTypeLoc { -public: - static bool classof(const TypeLoc *TL) { - return (UnqualTypeLoc::classof(TL) && - classof(static_cast(TL))); - } - static bool classof(const UnqualTypeLoc *TL); - static bool classof(const TypeSpecLoc *TL) { return true; } -}; - -inline SourceRange TypeLoc::getTypeSpecRange() const { - return getTypeSpecLoc().getSourceRange(); -} - -/// \brief Base wrapper of type source info data for types part of a declarator, -/// excluding type-spec types. -class DeclaratorLoc : public UnqualTypeLoc { -public: - /// \brief Find the TypeSpecLoc that is part of this DeclaratorLoc. - TypeSpecLoc getTypeSpecLoc() const; - - static bool classof(const TypeLoc *TL) { - return (UnqualTypeLoc::classof(TL) && - classof(static_cast(TL))); - } - static bool classof(const UnqualTypeLoc *TL); - static bool classof(const DeclaratorLoc *TL) { return true; } -}; - - /// A metaprogramming base class for TypeLoc classes which correspond /// to a particular Type subclass. It is accepted for a single /// TypeLoc class to correspond to multiple Type classes. @@ -222,6 +219,15 @@ public: /// QualType getInnerType() const /// and getInnerTypeLoc() will then point to this inner type's /// location data. +/// +/// A word about hierarchies: this template is not designed to be +/// derived from multiple times in a hierarchy. It is also not +/// designed to be used for classes where subtypes might provide +/// different amounts of source information. It should be subclassed +/// only at the deepest portion of the hierarchy where all children +/// have identical source information; if that's an abstract type, +/// then further descendents should inherit from +/// InheritingConcreteTypeLoc instead. template class ConcreteTypeLoc : public Base { @@ -238,16 +244,6 @@ public: return asDerived()->getLocalDataSize() + getInnerTypeSize(); } - static bool classof(const TypeLoc *TL) { - return Derived::classofType(TL->getSourceTypePtr()); - } - static bool classof(const UnqualTypeLoc *TL) { - return Derived::classofType(TL->getSourceTypePtr()); - } - static bool classof(const Derived *TL) { - return true; - } - static bool classofType(const Type *Ty) { return TypeClass::classof(Ty); } @@ -256,11 +252,11 @@ public: return getNextTypeLoc(asDerived()->getInnerType()); } -protected: TypeClass *getTypePtr() const { - return cast(Base::getSourceTypePtr()); + return cast(Base::getTypePtr()); } +protected: unsigned getExtraLocalDataSize() const { return 0; } @@ -309,88 +305,70 @@ private: } }; - -struct DefaultTypeSpecLocInfo { - SourceLocation StartLoc; -}; - -/// \brief The default wrapper for type-spec types that are not handled by -/// another specific wrapper. -class DefaultTypeSpecLoc : public ConcreteTypeLoc { +/// A metaprogramming class designed for concrete subtypes of abstract +/// types where all subtypes share equivalently-structured source +/// information. See the note on ConcreteTypeLoc. +template +class InheritingConcreteTypeLoc : public Base { public: - SourceLocation getStartLoc() const { - return getLocalData()->StartLoc; + static bool classof(const TypeLoc *TL) { + return Derived::classofType(TL->getTypePtr()); } - void setStartLoc(SourceLocation Loc) { - getLocalData()->StartLoc = Loc; + static bool classof(const UnqualTypeLoc *TL) { + return Derived::classofType(TL->getTypePtr()); } - SourceRange getSourceRange() const { - return SourceRange(getStartLoc(), getStartLoc()); + static bool classof(const Derived *TL) { + return true; } - void initializeLocal(SourceLocation Loc) { - setStartLoc(Loc); + TypeClass *getTypePtr() const { + return cast(Base::getTypePtr()); } - - static bool classofType(const Type *T); }; - -struct TypedefLocInfo { +struct TypeSpecLocInfo { SourceLocation NameLoc; }; -/// \brief Wrapper for source info for typedefs. -class TypedefLoc : public ConcreteTypeLoc { +/// \brief A reasonable base class for TypeLocs that correspond to +/// types that are written as a type-specifier. +template +class TypeSpecTypeLoc + : public ConcreteTypeLoc { public: SourceLocation getNameLoc() const { - return getLocalData()->NameLoc; + return this->getLocalData()->NameLoc; } void setNameLoc(SourceLocation Loc) { - getLocalData()->NameLoc = Loc; + this->getLocalData()->NameLoc = Loc; } SourceRange getSourceRange() const { return SourceRange(getNameLoc(), getNameLoc()); } - void initializeLocal(SourceLocation Loc) { setNameLoc(Loc); } +}; +/// \brief Wrapper for source info for typedefs. +class TypedefTypeLoc : public TypeSpecTypeLoc { +public: TypedefDecl *getTypedefDecl() const { return getTypePtr()->getDecl(); } }; -struct ObjCInterfaceLocInfo { - SourceLocation NameLoc; +/// \brief Wrapper for source info for builtin types. +class BuiltinTypeLoc : public TypeSpecTypeLoc { }; + /// \brief Wrapper for source info for ObjC interfaces. -class ObjCInterfaceLoc : public ConcreteTypeLoc { +class ObjCInterfaceTypeLoc : public TypeSpecTypeLoc { public: - SourceLocation getNameLoc() const { - return getLocalData()->NameLoc; - } - void setNameLoc(SourceLocation Loc) { - getLocalData()->NameLoc = Loc; - } - SourceRange getSourceRange() const { - return SourceRange(getNameLoc(), getNameLoc()); - } - - void initializeLocal(SourceLocation Loc) { - setNameLoc(Loc); - } - ObjCInterfaceDecl *getIFaceDecl() const { return getTypePtr()->getDecl(); } @@ -402,10 +380,11 @@ struct ObjCProtocolListLocInfo { }; /// \brief Wrapper for source info for ObjC protocol lists. -class ObjCProtocolListLoc : public ConcreteTypeLoc { +class ObjCProtocolListTypeLoc + : public ConcreteTypeLoc { // SourceLocations are stored after Info, one for each Protocol. SourceLocation *getProtocolLocArray() const { return (SourceLocation*) getExtraLocalData(); @@ -469,155 +448,119 @@ public: }; -struct PointerLocInfo { + +struct PointerLikeLocInfo { SourceLocation StarLoc; }; -/// \brief Wrapper for source info for pointers. -class PointerLoc : public ConcreteTypeLoc { -public: - SourceLocation getStarLoc() const { - return getLocalData()->StarLoc; +/// A base class for +template +class PointerLikeTypeLoc : public ConcreteTypeLoc { +protected: + SourceLocation getSigilLoc() const { + return this->getLocalData()->StarLoc; } - void setStarLoc(SourceLocation Loc) { - getLocalData()->StarLoc = Loc; + void setSigilLoc(SourceLocation Loc) { + this->getLocalData()->StarLoc = Loc; } +public: TypeLoc getPointeeLoc() const { - return getInnerTypeLoc(); - } - - /// \brief Find the TypeSpecLoc that is part of this PointerLoc. - TypeSpecLoc getTypeSpecLoc() const { - return getPointeeLoc().getTypeSpecLoc(); + return this->getInnerTypeLoc(); } SourceRange getSourceRange() const { - return SourceRange(getStarLoc(), getStarLoc()); + return SourceRange(getSigilLoc(), getSigilLoc()); } void initializeLocal(SourceLocation Loc) { - setStarLoc(Loc); + setSigilLoc(Loc); } - QualType getInnerType() const { return getTypePtr()->getPointeeType(); } + QualType getInnerType() const { + return this->getTypePtr()->getPointeeType(); + } }; -struct BlockPointerLocInfo { - SourceLocation CaretLoc; +/// \brief Wrapper for source info for pointers. +class PointerTypeLoc : public PointerLikeTypeLoc { +public: + SourceLocation getStarLoc() const { + return getSigilLoc(); + } + void setStarLoc(SourceLocation Loc) { + setSigilLoc(Loc); + } }; + /// \brief Wrapper for source info for block pointers. -class BlockPointerLoc : public ConcreteTypeLoc { +class BlockPointerTypeLoc : public PointerLikeTypeLoc { public: SourceLocation getCaretLoc() const { - return getLocalData()->CaretLoc; + return getSigilLoc(); } void setCaretLoc(SourceLocation Loc) { - getLocalData()->CaretLoc = Loc; + setSigilLoc(Loc); } - - TypeLoc getPointeeLoc() const { - return getInnerTypeLoc(); - } - - /// \brief Find the TypeSpecLoc that is part of this BlockPointerLoc. - TypeSpecLoc getTypeSpecLoc() const { - return getPointeeLoc().getTypeSpecLoc(); - } - - SourceRange getSourceRange() const { - return SourceRange(getCaretLoc(), getCaretLoc()); - } - - void initializeLocal(SourceLocation Loc) { - setCaretLoc(Loc); - } - - QualType getInnerType() const { return getTypePtr()->getPointeeType(); } }; -struct MemberPointerLocInfo { - SourceLocation StarLoc; -}; - /// \brief Wrapper for source info for member pointers. -class MemberPointerLoc : public ConcreteTypeLoc { +class MemberPointerTypeLoc : public PointerLikeTypeLoc { public: SourceLocation getStarLoc() const { - return getLocalData()->StarLoc; + return getSigilLoc(); } void setStarLoc(SourceLocation Loc) { - getLocalData()->StarLoc = Loc; - } - - TypeLoc getPointeeLoc() const { - return getInnerTypeLoc(); - } - - /// \brief Find the TypeSpecLoc that is part of this MemberPointerLoc. - TypeSpecLoc getTypeSpecLoc() const { - return getPointeeLoc().getTypeSpecLoc(); - } - - SourceRange getSourceRange() const { - return SourceRange(getStarLoc(), getStarLoc()); - } - - void initializeLocal(SourceLocation Loc) { - setStarLoc(Loc); + setSigilLoc(Loc); } - - QualType getInnerType() const { return getTypePtr()->getPointeeType(); } }; -struct ReferenceLocInfo { - SourceLocation AmpLoc; +class ReferenceTypeLoc : public PointerLikeTypeLoc { }; -/// \brief Wrapper for source info for references. -class ReferenceLoc : public ConcreteTypeLoc { +class LValueReferenceTypeLoc : public PointerLikeTypeLoc { public: SourceLocation getAmpLoc() const { - return getLocalData()->AmpLoc; + return getSigilLoc(); } void setAmpLoc(SourceLocation Loc) { - getLocalData()->AmpLoc = Loc; + setSigilLoc(Loc); } +}; - TypeLoc getPointeeLoc() const { - return TypeLoc(getTypePtr()->getPointeeType(), getNonLocalData()); +class RValueReferenceTypeLoc : public PointerLikeTypeLoc { +public: + SourceLocation getAmpAmpLoc() const { + return getSigilLoc(); } - - /// \brief Find the TypeSpecLoc that is part of this ReferenceLoc. - TypeSpecLoc getTypeSpecLoc() const { - return getPointeeLoc().getTypeSpecLoc(); + void setAmpAmpLoc(SourceLocation Loc) { + setSigilLoc(Loc); } +}; - SourceRange getSourceRange() const { - return SourceRange(getAmpLoc(), getAmpLoc()); +/// Wraps an ObjCPointerType with source location information. Note +/// that not all ObjCPointerTypes actually have a star location. +class ObjCObjectPointerTypeLoc : + public PointerLikeTypeLoc { +public: + SourceLocation getStarLoc() const { + return getSigilLoc(); } - - void initializeLocal(SourceLocation Loc) { - setAmpLoc(Loc); + void setStarLoc(SourceLocation Loc) { + setSigilLoc(Loc); } - - QualType getInnerType() const { return getTypePtr()->getPointeeType(); } }; @@ -626,10 +569,10 @@ struct FunctionLocInfo { }; /// \brief Wrapper for source info for functions. -class FunctionLoc : public ConcreteTypeLoc { +class FunctionTypeLoc : public ConcreteTypeLoc { // ParmVarDecls* are stored after Info, one for each argument. ParmVarDecl **getParmArray() const { return (ParmVarDecl**) getExtraLocalData(); @@ -664,10 +607,6 @@ public: return getInnerTypeLoc(); } - /// \brief Find the TypeSpecLoc that is part of this FunctionLoc. - TypeSpecLoc getTypeSpecLoc() const { - return getResultLoc().getTypeSpecLoc(); - } SourceRange getSourceRange() const { return SourceRange(getLParenLoc(), getRParenLoc()); } @@ -688,6 +627,18 @@ public: QualType getInnerType() const { return getTypePtr()->getResultType(); } }; +class FunctionProtoTypeLoc : + public InheritingConcreteTypeLoc { +}; + +class FunctionNoProtoTypeLoc : + public InheritingConcreteTypeLoc { +}; + struct ArrayLocInfo { SourceLocation LBracketLoc, RBracketLoc; @@ -695,10 +646,10 @@ struct ArrayLocInfo { }; /// \brief Wrapper for source info for arrays. -class ArrayLoc : public ConcreteTypeLoc { +class ArrayTypeLoc : public ConcreteTypeLoc { public: SourceLocation getLBracketLoc() const { return getLocalData()->LBracketLoc; @@ -725,10 +676,6 @@ public: return getInnerTypeLoc(); } - /// \brief Find the TypeSpecLoc that is part of this ArrayLoc. - TypeSpecLoc getTypeSpecLoc() const { - return getElementLoc().getTypeSpecLoc(); - } SourceRange getSourceRange() const { return SourceRange(getLBracketLoc(), getRBracketLoc()); } @@ -742,6 +689,100 @@ public: QualType getInnerType() const { return getTypePtr()->getElementType(); } }; +class ConstantArrayTypeLoc : + public InheritingConcreteTypeLoc { +}; + +class IncompleteArrayTypeLoc : + public InheritingConcreteTypeLoc { +}; + +class DependentSizedArrayTypeLoc : + public InheritingConcreteTypeLoc { + +}; + +class VariableArrayTypeLoc : + public InheritingConcreteTypeLoc { +}; + + +// None of these types have proper implementations yet. + +class VectorTypeLoc : public TypeSpecTypeLoc { +}; + +class ExtVectorTypeLoc : public InheritingConcreteTypeLoc { +}; + +// For some reason, this isn't a subtype of VectorType. +class DependentSizedExtVectorTypeLoc : + public TypeSpecTypeLoc { +}; + +class FixedWidthIntTypeLoc : public TypeSpecTypeLoc { +}; + +class ComplexTypeLoc : public TypeSpecTypeLoc { +}; + +class TypeOfExprTypeLoc : public TypeSpecTypeLoc { +}; + +class TypeOfTypeLoc : public TypeSpecTypeLoc { +}; + +class DecltypeTypeLoc : public TypeSpecTypeLoc { +}; + +class TagTypeLoc : public TypeSpecTypeLoc { +}; + +class RecordTypeLoc : public InheritingConcreteTypeLoc { +}; + +class EnumTypeLoc : public InheritingConcreteTypeLoc { +}; + +class ElaboratedTypeLoc : public TypeSpecTypeLoc { +}; + +class TemplateTypeParmTypeLoc : public TypeSpecTypeLoc { +}; + +class TemplateSpecializationTypeLoc + : public TypeSpecTypeLoc { +}; + +class QualifiedNameTypeLoc : public TypeSpecTypeLoc { +}; + +class TypenameTypeLoc : public TypeSpecTypeLoc { +}; + } #endif diff --git a/clang/include/clang/AST/TypeLocNodes.def b/clang/include/clang/AST/TypeLocNodes.def index ecf7cc5c2995..4590e489e3f7 100644 --- a/clang/include/clang/AST/TypeLocNodes.def +++ b/clang/include/clang/AST/TypeLocNodes.def @@ -7,54 +7,32 @@ // //===----------------------------------------------------------------------===// // -// This file defines the TypeLoc info database. Each node is -// enumerated by providing its name (e.g., "PointerLoc" or "ArrayLoc"), -// base class (e.g., "TypeSpecLoc" or "DeclaratorLoc"), and the Type subclass -// that the TypeLoc is associated with. +// This file defines the TypeLoc info database. Each node is +// enumerated by providing its core name (e.g., "Pointer" for "PointerTypeLoc") +// and base class (e.g., "DeclaratorLoc"). All nodes except QualifiedTypeLoc +// are associated // -// TYPELOC(Class, Base) - A TypeLoc subclass. +// TYPELOC(Class, Base) - A TypeLoc subclass. If UNQUAL_TYPELOC is +// provided, there will be exactly one of these, Qualified. // // UNQUAL_TYPELOC(Class, Base, Type) - An UnqualTypeLoc subclass. // // ABSTRACT_TYPELOC(Class) - Refers to TypeSpecLoc and DeclaratorLoc. // -// TYPESPEC_TYPELOC(Class, Type) - A TypeLoc referring to a type-spec type. -// -// DECLARATOR_TYPELOC(Class, Type) - A TypeLoc referring to a type part of -// a declarator, excluding type-spec types. -// //===----------------------------------------------------------------------===// #ifndef UNQUAL_TYPELOC -# define UNQUAL_TYPELOC(Class, Base, Type) TYPELOC(Class, Base) +# define UNQUAL_TYPELOC(Class, Base) TYPELOC(Class, Base) #endif #ifndef ABSTRACT_TYPELOC -# define ABSTRACT_TYPELOC(Class) TYPELOC(Class, TypeLoc) -#endif - -#ifndef TYPESPEC_TYPELOC -# define TYPESPEC_TYPELOC(Class, Type) UNQUAL_TYPELOC(Class, TypeSpecLoc, Type) +# define ABSTRACT_TYPELOC(Class, Base) UNQUAL_TYPELOC(Class, Base) #endif -#ifndef DECLARATOR_TYPELOC -# define DECLARATOR_TYPELOC(Class, Type) UNQUAL_TYPELOC(Class, DeclaratorLoc, Type) -#endif - -TYPESPEC_TYPELOC(DefaultTypeSpecLoc, Type) -TYPESPEC_TYPELOC(TypedefLoc, TypedefType) -TYPESPEC_TYPELOC(ObjCInterfaceLoc, ObjCInterfaceType) -TYPESPEC_TYPELOC(ObjCProtocolListLoc, ObjCProtocolListType) -DECLARATOR_TYPELOC(PointerLoc, PointerType) -DECLARATOR_TYPELOC(BlockPointerLoc, BlockPointerType) -DECLARATOR_TYPELOC(MemberPointerLoc, MemberPointerType) -DECLARATOR_TYPELOC(ReferenceLoc, ReferenceType) -DECLARATOR_TYPELOC(FunctionLoc, FunctionType) -DECLARATOR_TYPELOC(ArrayLoc, ArrayType) -ABSTRACT_TYPELOC(DeclaratorLoc) -ABSTRACT_TYPELOC(TypeSpecLoc) -TYPELOC(QualifiedLoc, TypeLoc) - +TYPELOC(Qualified, TypeLoc) +#define TYPE(Class, Base) UNQUAL_TYPELOC(Class, Base##Loc) +#define ABSTRACT_TYPE(Class, Base) ABSTRACT_TYPELOC(Class, Base##Loc) +#include "clang/AST/TypeNodes.def" #undef DECLARATOR_TYPELOC #undef TYPESPEC_TYPELOC diff --git a/clang/include/clang/AST/TypeLocVisitor.h b/clang/include/clang/AST/TypeLocVisitor.h index a96757f123e8..a62bb3f853bc 100644 --- a/clang/include/clang/AST/TypeLocVisitor.h +++ b/clang/include/clang/AST/TypeLocVisitor.h @@ -15,46 +15,38 @@ #include "clang/AST/TypeLoc.h" #include "clang/AST/TypeVisitor.h" +#include "llvm/Support/ErrorHandling.h" namespace clang { -#define DISPATCH(CLASS) \ - return static_cast(this)->Visit ## CLASS(cast(TyLoc)) +#define DISPATCH(CLASSNAME) \ + return static_cast(this)-> \ + Visit##CLASSNAME(cast(TyLoc)) template class TypeLocVisitor { - class TypeDispatch : public TypeVisitor { - ImplClass *Impl; - UnqualTypeLoc TyLoc; - - public: - TypeDispatch(ImplClass *impl, UnqualTypeLoc &tyLoc) - : Impl(impl), TyLoc(tyLoc) { } -#define TYPELOC(CLASS, BASE) -#define ABSTRACT_TYPELOC(CLASS) -#define UNQUAL_TYPELOC(CLASS, PARENT, TYPE) \ - RetTy Visit##TYPE(TYPE *) { \ - return Impl->Visit##CLASS(reinterpret_cast(TyLoc)); \ - } -#include "clang/AST/TypeLocNodes.def" - }; - public: RetTy Visit(TypeLoc TyLoc) { - if (isa(TyLoc)) - return static_cast(this)-> - VisitQualifiedLoc(cast(TyLoc)); - - return Visit(cast(TyLoc)); + switch (TyLoc.getTypeLocClass()) { +#define ABSTRACT_TYPELOC(CLASS, PARENT) +#define TYPELOC(CLASS, PARENT) \ + case TypeLoc::CLASS: DISPATCH(CLASS##TypeLoc); +#include "clang/AST/TypeLocNodes.def" + } + llvm::llvm_unreachable("unexpected type loc class!"); } RetTy Visit(UnqualTypeLoc TyLoc) { - TypeDispatch TD(static_cast(this), TyLoc); - return TD.Visit(TyLoc.getSourceTypePtr()); + switch (TyLoc.getTypeLocClass()) { +#define ABSTRACT_TYPELOC(CLASS, PARENT) +#define TYPELOC(CLASS, PARENT) \ + case TypeLoc::CLASS: DISPATCH(CLASS##TypeLoc); +#include "clang/AST/TypeLocNodes.def" + } } #define TYPELOC(CLASS, PARENT) \ - RetTy Visit##CLASS(CLASS TyLoc) { \ + RetTy Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \ DISPATCH(PARENT); \ } #include "clang/AST/TypeLocNodes.def" diff --git a/clang/include/clang/Index/ASTLocation.h b/clang/include/clang/Index/ASTLocation.h index 0fec84152b13..fc18dae1a20c 100644 --- a/clang/include/clang/Index/ASTLocation.h +++ b/clang/include/clang/Index/ASTLocation.h @@ -91,7 +91,7 @@ public: ASTLocation(const Decl *parentDecl, TypeLoc tyLoc) : ParentDecl(const_cast(parentDecl), N_Type) { if (tyLoc) { - Ty.TyPtr = tyLoc.getSourceType().getAsOpaquePtr(); + Ty.TyPtr = tyLoc.getType().getAsOpaquePtr(); Ty.Data = tyLoc.getOpaqueData(); } else ParentDecl.setPointer(0); diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 9d7d3d087cc2..0c413f674235 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -336,8 +336,15 @@ NamedDecl *NamedDecl::getUnderlyingDecl() { //===----------------------------------------------------------------------===// SourceLocation DeclaratorDecl::getTypeSpecStartLoc() const { - if (DeclInfo) - return DeclInfo->getTypeLoc().getTypeSpecRange().getBegin(); + if (DeclInfo) { + TypeLoc TL = DeclInfo->getTypeLoc(); + while (true) { + TypeLoc NextTL = TL.getNextTypeLoc(); + if (!NextTL) + return TL.getSourceRange().getBegin(); + TL = NextTL; + } + } return SourceLocation(); } diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp index c216a29e644f..7e6b110bf5ed 100644 --- a/clang/lib/AST/TypeLoc.cpp +++ b/clang/lib/AST/TypeLoc.cpp @@ -20,55 +20,32 @@ using namespace clang; //===----------------------------------------------------------------------===// namespace { - -/// \brief Return the source range for the visited TypeSpecLoc. -class TypeLocRanger : public TypeLocVisitor { -public: -#define ABSTRACT_TYPELOC(CLASS) + class TypeLocRanger : public TypeLocVisitor { + public: +#define ABSTRACT_TYPELOC(CLASS, PARENT) #define TYPELOC(CLASS, PARENT) \ - SourceRange Visit##CLASS(CLASS TyLoc) { return TyLoc.getSourceRange(); } + SourceRange Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \ + return TyLoc.getSourceRange(); \ + } #include "clang/AST/TypeLocNodes.def" - - SourceRange VisitTypeLoc(TypeLoc TyLoc) { - assert(0 && "A typeloc wrapper was not handled!"); - return SourceRange(); - } -}; - -} - -SourceRange TypeLoc::getSourceRange() const { - if (isNull()) - return SourceRange(); - return TypeLocRanger().Visit(*this); + }; } -/// \brief Find the TypeSpecLoc that is part of this TypeLoc. -TypeSpecLoc TypeLoc::getTypeSpecLoc() const { - if (isNull()) - return TypeSpecLoc(); - UnqualTypeLoc Cur = getUnqualifiedLoc(); - if (const DeclaratorLoc *DL = dyn_cast(&Cur)) - return DL->getTypeSpecLoc(); - return cast(Cur); +SourceRange TypeLoc::getSourceRangeImpl(TypeLoc TL) { + if (TL.isNull()) return SourceRange(); + return TypeLocRanger().Visit(TL); } namespace { - -/// \brief Report the full source info data size for the visited TypeLoc. -class TypeSizer : public TypeLocVisitor { -public: -#define ABSTRACT_TYPELOC(CLASS) + class TypeSizer : public TypeLocVisitor { + public: +#define ABSTRACT_TYPELOC(CLASS, PARENT) #define TYPELOC(CLASS, PARENT) \ - unsigned Visit##CLASS(CLASS TyLoc) { return TyLoc.getFullDataSize(); } + unsigned Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \ + return TyLoc.getFullDataSize(); \ + } #include "clang/AST/TypeLocNodes.def" - - unsigned VisitTypeLoc(TypeLoc TyLoc) { - assert(0 && "A type loc wrapper was not handled!"); - return 0; - } -}; - + }; } /// \brief Returns the size of the type source info data block. @@ -78,153 +55,42 @@ unsigned TypeLoc::getFullDataSizeForType(QualType Ty) { } namespace { - -/// \brief Return the "next" TypeLoc for the visited TypeLoc, e.g for "int*" the -/// TypeLoc is a PointerLoc and next TypeLoc is for "int". -class NextLoc : public TypeLocVisitor { -public: -#define TYPELOC(CLASS, PARENT) -#define DECLARATOR_TYPELOC(CLASS, TYPE) \ - TypeLoc Visit##CLASS(CLASS TyLoc); + class NextLoc : public TypeLocVisitor { + public: +#define ABSTRACT_TYPELOC(CLASS, PARENT) +#define TYPELOC(CLASS, PARENT) \ + TypeLoc Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \ + return TyLoc.getNextTypeLoc(); \ + } #include "clang/AST/TypeLocNodes.def" - - TypeLoc VisitTypeSpecLoc(TypeLoc TyLoc) { return TypeLoc(); } - TypeLoc VisitObjCProtocolListLoc(ObjCProtocolListLoc TL); - TypeLoc VisitQualifiedLoc(QualifiedLoc TyLoc) { - return TyLoc.getNextTypeLoc(); - } - - TypeLoc VisitTypeLoc(TypeLoc TyLoc) { - assert(0 && "A declarator loc wrapper was not handled!"); - return TypeLoc(); - } -}; - -} - -TypeLoc NextLoc::VisitObjCProtocolListLoc(ObjCProtocolListLoc TL) { - return TL.getNextTypeLoc(); -} - -TypeLoc NextLoc::VisitPointerLoc(PointerLoc TL) { - return TL.getNextTypeLoc(); -} -TypeLoc NextLoc::VisitMemberPointerLoc(MemberPointerLoc TL) { - return TL.getNextTypeLoc(); -} -TypeLoc NextLoc::VisitBlockPointerLoc(BlockPointerLoc TL) { - return TL.getNextTypeLoc(); -} -TypeLoc NextLoc::VisitReferenceLoc(ReferenceLoc TL) { - return TL.getNextTypeLoc(); -} -TypeLoc NextLoc::VisitFunctionLoc(FunctionLoc TL) { - return TL.getNextTypeLoc(); -} -TypeLoc NextLoc::VisitArrayLoc(ArrayLoc TL) { - return TL.getNextTypeLoc(); + }; } /// \brief Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the /// TypeLoc is a PointerLoc and next TypeLoc is for "int". -TypeLoc TypeLoc::getNextTypeLoc() const { - return NextLoc().Visit(*this); +TypeLoc TypeLoc::getNextTypeLocImpl(TypeLoc TL) { + return NextLoc().Visit(TL); } namespace { -struct TypeLocInitializer : public TypeLocVisitor { - SourceLocation Loc; - TypeLocInitializer(SourceLocation Loc) : Loc(Loc) {} + struct TypeLocInitializer : public TypeLocVisitor { + SourceLocation Loc; + TypeLocInitializer(SourceLocation Loc) : Loc(Loc) {} -#define ABSTRACT_TYPELOC(CLASS) +#define ABSTRACT_TYPELOC(CLASS, PARENT) #define TYPELOC(CLASS, PARENT) \ - void Visit##CLASS(CLASS TyLoc) { TyLoc.initializeLocal(Loc); } + void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc) { \ + TyLoc.initializeLocal(Loc); \ + } #include "clang/AST/TypeLocNodes.def" -}; + }; } +/// \brief Initializes a type location, and all of its children +/// recursively, as if the entire tree had been written in the +/// given location. void TypeLoc::initializeImpl(TypeLoc TL, SourceLocation Loc) { do { TypeLocInitializer(Loc).Visit(TL); } while (TL = TL.getNextTypeLoc()); } - -//===----------------------------------------------------------------------===// -// TypeSpecLoc Implementation -//===----------------------------------------------------------------------===// - -namespace { -class TypeSpecChecker : public TypeLocVisitor { -public: - bool VisitTypeSpecLoc(TypeSpecLoc TyLoc) { return true; } -}; - -} - -bool TypeSpecLoc::classof(const UnqualTypeLoc *TL) { - return TypeSpecChecker().Visit(*TL); -} - -//===----------------------------------------------------------------------===// -// DeclaratorLoc Implementation -//===----------------------------------------------------------------------===// - -namespace { - -/// \brief Return the TypeSpecLoc for the visited DeclaratorLoc. -class TypeSpecGetter : public TypeLocVisitor { -public: -#define TYPELOC(CLASS, PARENT) -#define DECLARATOR_TYPELOC(CLASS, TYPE) \ - TypeSpecLoc Visit##CLASS(CLASS TyLoc) { return TyLoc.getTypeSpecLoc(); } -#include "clang/AST/TypeLocNodes.def" - - TypeSpecLoc VisitTypeLoc(TypeLoc TyLoc) { - assert(0 && "A declarator loc wrapper was not handled!"); - return TypeSpecLoc(); - } - - TypeSpecLoc VisitQualifiedLoc(QualifiedLoc TyLoc) { - return Visit(TyLoc.getUnqualifiedLoc()); - } -}; - -} - -/// \brief Find the TypeSpecLoc that is part of this DeclaratorLoc. -TypeSpecLoc DeclaratorLoc::getTypeSpecLoc() const { - return TypeSpecGetter().Visit(*this); -} - -namespace { - -class DeclaratorLocChecker : public TypeLocVisitor { -public: - bool VisitDeclaratorLoc(DeclaratorLoc TyLoc) { return true; } -}; - -} - -bool DeclaratorLoc::classof(const UnqualTypeLoc *TL) { - return DeclaratorLocChecker().Visit(*TL); -} - -//===----------------------------------------------------------------------===// -// DefaultTypeSpecLoc Implementation -//===----------------------------------------------------------------------===// - -namespace { - -class DefaultTypeSpecLocChecker : - public TypeLocVisitor { -public: - bool VisitDefaultTypeSpecLoc(DefaultTypeSpecLoc TyLoc) { return true; } -}; - -} - -bool DefaultTypeSpecLoc::classofType(const Type *Ty) { - return - DefaultTypeSpecLocChecker().Visit(UnqualTypeLoc(const_cast(Ty), 0)); -} - diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp index 87caf770981f..98f3f0b39590 100644 --- a/clang/lib/Frontend/PCHReader.cpp +++ b/clang/lib/Frontend/PCHReader.cpp @@ -1985,61 +1985,136 @@ public: unsigned &Idx) : Reader(Reader), Record(Record), Idx(Idx) { } -#define ABSTRACT_TYPELOC(CLASS) + // We want compile-time assurance that we've enumerated all of + // these, so unfortunately we have to declare them first, then + // define them out-of-line. +#define ABSTRACT_TYPELOC(CLASS, PARENT) #define TYPELOC(CLASS, PARENT) \ - void Visit##CLASS(CLASS TyLoc); + void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc); #include "clang/AST/TypeLocNodes.def" - void VisitTypeLoc(TypeLoc TyLoc) { - assert(0 && "A type loc wrapper was not handled!"); - } + void VisitFunctionTypeLoc(FunctionTypeLoc); + void VisitArrayTypeLoc(ArrayTypeLoc); }; } -void TypeLocReader::VisitQualifiedLoc(QualifiedLoc TyLoc) { +void TypeLocReader::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { // nothing to do } -void TypeLocReader::VisitDefaultTypeSpecLoc(DefaultTypeSpecLoc TyLoc) { - TyLoc.setStartLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); -} -void TypeLocReader::VisitTypedefLoc(TypedefLoc TyLoc) { - TyLoc.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +void TypeLocReader::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { + TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); } -void TypeLocReader::VisitObjCInterfaceLoc(ObjCInterfaceLoc TyLoc) { - TyLoc.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +void TypeLocReader::VisitFixedWidthIntTypeLoc(FixedWidthIntTypeLoc TL) { + TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); } -void TypeLocReader::VisitObjCProtocolListLoc(ObjCProtocolListLoc TyLoc) { - TyLoc.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - TyLoc.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - for (unsigned i = 0, e = TyLoc.getNumProtocols(); i != e; ++i) - TyLoc.setProtocolLoc(i, SourceLocation::getFromRawEncoding(Record[Idx++])); +void TypeLocReader::VisitComplexTypeLoc(ComplexTypeLoc TL) { + TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); } -void TypeLocReader::VisitPointerLoc(PointerLoc TyLoc) { - TyLoc.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +void TypeLocReader::VisitPointerTypeLoc(PointerTypeLoc TL) { + TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); } -void TypeLocReader::VisitBlockPointerLoc(BlockPointerLoc TyLoc) { - TyLoc.setCaretLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { + TL.setCaretLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); } -void TypeLocReader::VisitMemberPointerLoc(MemberPointerLoc TyLoc) { - TyLoc.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +void TypeLocReader::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) { + TL.setAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); } -void TypeLocReader::VisitReferenceLoc(ReferenceLoc TyLoc) { - TyLoc.setAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +void TypeLocReader::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) { + TL.setAmpAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); } -void TypeLocReader::VisitFunctionLoc(FunctionLoc TyLoc) { - TyLoc.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - TyLoc.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - for (unsigned i = 0, e = TyLoc.getNumArgs(); i != e; ++i) - TyLoc.setArg(i, cast(Reader.GetDecl(Record[Idx++]))); +void TypeLocReader::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) { + TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); } -void TypeLocReader::VisitArrayLoc(ArrayLoc TyLoc) { - TyLoc.setLBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); - TyLoc.setRBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +void TypeLocReader::VisitArrayTypeLoc(ArrayTypeLoc TL) { + TL.setLBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setRBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); if (Record[Idx++]) - TyLoc.setSizeExpr(Reader.ReadDeclExpr()); + TL.setSizeExpr(Reader.ReadDeclExpr()); else - TyLoc.setSizeExpr(0); + TL.setSizeExpr(0); +} +void TypeLocReader::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) { + VisitArrayTypeLoc(TL); +} +void TypeLocReader::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) { + VisitArrayTypeLoc(TL); +} +void TypeLocReader::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) { + VisitArrayTypeLoc(TL); +} +void TypeLocReader::VisitDependentSizedArrayTypeLoc( + DependentSizedArrayTypeLoc TL) { + VisitArrayTypeLoc(TL); +} +void TypeLocReader::VisitDependentSizedExtVectorTypeLoc( + DependentSizedExtVectorTypeLoc TL) { + TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitVectorTypeLoc(VectorTypeLoc TL) { + TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) { + TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitFunctionTypeLoc(FunctionTypeLoc TL) { + TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) { + TL.setArg(i, cast(Reader.GetDecl(Record[Idx++]))); + } +} +void TypeLocReader::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) { + VisitFunctionTypeLoc(TL); +} +void TypeLocReader::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) { + VisitFunctionTypeLoc(TL); +} +void TypeLocReader::VisitTypedefTypeLoc(TypedefTypeLoc TL) { + TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { + TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { + TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { + TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitRecordTypeLoc(RecordTypeLoc TL) { + TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitEnumTypeLoc(EnumTypeLoc TL) { + TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { + TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { + TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitTemplateSpecializationTypeLoc( + TemplateSpecializationTypeLoc TL) { + TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitQualifiedNameTypeLoc(QualifiedNameTypeLoc TL) { + TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitTypenameTypeLoc(TypenameTypeLoc TL) { + TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { + TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { + TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitObjCProtocolListTypeLoc(ObjCProtocolListTypeLoc TL) { + TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); + for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) + TL.setProtocolLoc(i, SourceLocation::getFromRawEncoding(Record[Idx++])); } DeclaratorInfo *PCHReader::GetDeclaratorInfo(const RecordData &Record, diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp index 40c9e1f085c3..a15576a82f0c 100644 --- a/clang/lib/Frontend/PCHWriter.cpp +++ b/clang/lib/Frontend/PCHWriter.cpp @@ -259,60 +259,131 @@ public: TypeLocWriter(PCHWriter &Writer, PCHWriter::RecordData &Record) : Writer(Writer), Record(Record) { } -#define ABSTRACT_TYPELOC(CLASS) +#define ABSTRACT_TYPELOC(CLASS, PARENT) #define TYPELOC(CLASS, PARENT) \ - void Visit##CLASS(CLASS TyLoc); + void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc); #include "clang/AST/TypeLocNodes.def" - void VisitTypeLoc(TypeLoc TyLoc) { - assert(0 && "A type loc wrapper was not handled!"); - } + void VisitArrayTypeLoc(ArrayTypeLoc TyLoc); + void VisitFunctionTypeLoc(FunctionTypeLoc TyLoc); }; } -void TypeLocWriter::VisitQualifiedLoc(QualifiedLoc TyLoc) { - // nothing to do here +void TypeLocWriter::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { + // nothing to do +} +void TypeLocWriter::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { + Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitFixedWidthIntTypeLoc(FixedWidthIntTypeLoc TL) { + Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitComplexTypeLoc(ComplexTypeLoc TL) { + Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitPointerTypeLoc(PointerTypeLoc TL) { + Writer.AddSourceLocation(TL.getStarLoc(), Record); +} +void TypeLocWriter::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { + Writer.AddSourceLocation(TL.getCaretLoc(), Record); +} +void TypeLocWriter::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) { + Writer.AddSourceLocation(TL.getAmpLoc(), Record); +} +void TypeLocWriter::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) { + Writer.AddSourceLocation(TL.getAmpAmpLoc(), Record); +} +void TypeLocWriter::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) { + Writer.AddSourceLocation(TL.getStarLoc(), Record); +} +void TypeLocWriter::VisitArrayTypeLoc(ArrayTypeLoc TL) { + Writer.AddSourceLocation(TL.getLBracketLoc(), Record); + Writer.AddSourceLocation(TL.getRBracketLoc(), Record); + Record.push_back(TL.getSizeExpr() ? 1 : 0); + if (TL.getSizeExpr()) + Writer.AddStmt(TL.getSizeExpr()); +} +void TypeLocWriter::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) { + VisitArrayTypeLoc(TL); +} +void TypeLocWriter::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) { + VisitArrayTypeLoc(TL); +} +void TypeLocWriter::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) { + VisitArrayTypeLoc(TL); +} +void TypeLocWriter::VisitDependentSizedArrayTypeLoc( + DependentSizedArrayTypeLoc TL) { + VisitArrayTypeLoc(TL); +} +void TypeLocWriter::VisitDependentSizedExtVectorTypeLoc( + DependentSizedExtVectorTypeLoc TL) { + Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitVectorTypeLoc(VectorTypeLoc TL) { + Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) { + Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitFunctionTypeLoc(FunctionTypeLoc TL) { + Writer.AddSourceLocation(TL.getLParenLoc(), Record); + Writer.AddSourceLocation(TL.getRParenLoc(), Record); + for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) + Writer.AddDeclRef(TL.getArg(i), Record); +} +void TypeLocWriter::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) { + VisitFunctionTypeLoc(TL); +} +void TypeLocWriter::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) { + VisitFunctionTypeLoc(TL); +} +void TypeLocWriter::VisitTypedefTypeLoc(TypedefTypeLoc TL) { + Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { + Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { + Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { + Writer.AddSourceLocation(TL.getNameLoc(), Record); } -void TypeLocWriter::VisitDefaultTypeSpecLoc(DefaultTypeSpecLoc TyLoc) { - Writer.AddSourceLocation(TyLoc.getStartLoc(), Record); +void TypeLocWriter::VisitRecordTypeLoc(RecordTypeLoc TL) { + Writer.AddSourceLocation(TL.getNameLoc(), Record); } -void TypeLocWriter::VisitTypedefLoc(TypedefLoc TyLoc) { - Writer.AddSourceLocation(TyLoc.getNameLoc(), Record); +void TypeLocWriter::VisitEnumTypeLoc(EnumTypeLoc TL) { + Writer.AddSourceLocation(TL.getNameLoc(), Record); } -void TypeLocWriter::VisitObjCInterfaceLoc(ObjCInterfaceLoc TyLoc) { - Writer.AddSourceLocation(TyLoc.getNameLoc(), Record); +void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { + Writer.AddSourceLocation(TL.getNameLoc(), Record); } -void TypeLocWriter::VisitObjCProtocolListLoc(ObjCProtocolListLoc TyLoc) { - Writer.AddSourceLocation(TyLoc.getLAngleLoc(), Record); - Writer.AddSourceLocation(TyLoc.getRAngleLoc(), Record); - for (unsigned i = 0, e = TyLoc.getNumProtocols(); i != e; ++i) - Writer.AddSourceLocation(TyLoc.getProtocolLoc(i), Record); +void TypeLocWriter::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { + Writer.AddSourceLocation(TL.getNameLoc(), Record); } -void TypeLocWriter::VisitPointerLoc(PointerLoc TyLoc) { - Writer.AddSourceLocation(TyLoc.getStarLoc(), Record); +void TypeLocWriter::VisitTemplateSpecializationTypeLoc( + TemplateSpecializationTypeLoc TL) { + Writer.AddSourceLocation(TL.getNameLoc(), Record); } -void TypeLocWriter::VisitBlockPointerLoc(BlockPointerLoc TyLoc) { - Writer.AddSourceLocation(TyLoc.getCaretLoc(), Record); +void TypeLocWriter::VisitQualifiedNameTypeLoc(QualifiedNameTypeLoc TL) { + Writer.AddSourceLocation(TL.getNameLoc(), Record); } -void TypeLocWriter::VisitMemberPointerLoc(MemberPointerLoc TyLoc) { - Writer.AddSourceLocation(TyLoc.getStarLoc(), Record); +void TypeLocWriter::VisitTypenameTypeLoc(TypenameTypeLoc TL) { + Writer.AddSourceLocation(TL.getNameLoc(), Record); } -void TypeLocWriter::VisitReferenceLoc(ReferenceLoc TyLoc) { - Writer.AddSourceLocation(TyLoc.getAmpLoc(), Record); +void TypeLocWriter::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { + Writer.AddSourceLocation(TL.getNameLoc(), Record); } -void TypeLocWriter::VisitFunctionLoc(FunctionLoc TyLoc) { - Writer.AddSourceLocation(TyLoc.getLParenLoc(), Record); - Writer.AddSourceLocation(TyLoc.getRParenLoc(), Record); - for (unsigned i = 0, e = TyLoc.getNumArgs(); i != e; ++i) - Writer.AddDeclRef(TyLoc.getArg(i), Record); +void TypeLocWriter::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { + Writer.AddSourceLocation(TL.getStarLoc(), Record); } -void TypeLocWriter::VisitArrayLoc(ArrayLoc TyLoc) { - Writer.AddSourceLocation(TyLoc.getLBracketLoc(), Record); - Writer.AddSourceLocation(TyLoc.getRBracketLoc(), Record); - Record.push_back(TyLoc.getSizeExpr() ? 1 : 0); - if (TyLoc.getSizeExpr()) - Writer.AddStmt(TyLoc.getSizeExpr()); +void TypeLocWriter::VisitObjCProtocolListTypeLoc(ObjCProtocolListTypeLoc TL) { + Writer.AddSourceLocation(TL.getLAngleLoc(), Record); + Writer.AddSourceLocation(TL.getRAngleLoc(), Record); + for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) + Writer.AddSourceLocation(TL.getProtocolLoc(i), Record); } //===----------------------------------------------------------------------===// @@ -2032,7 +2103,7 @@ void PCHWriter::AddDeclaratorInfo(DeclaratorInfo *DInfo, RecordData &Record) { return; } - AddTypeRef(DInfo->getTypeLoc().getSourceType(), Record); + AddTypeRef(DInfo->getType(), Record); TypeLocWriter TLW(*this, Record); for (TypeLoc TL = DInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc()) TLW.Visit(TL); diff --git a/clang/lib/Index/ASTLocation.cpp b/clang/lib/Index/ASTLocation.cpp index 6294d699a88c..c24f3bf5b3c1 100644 --- a/clang/lib/Index/ASTLocation.cpp +++ b/clang/lib/Index/ASTLocation.cpp @@ -101,7 +101,7 @@ void ASTLocation::print(llvm::raw_ostream &OS) const { break; case N_Type: { - QualType T = AsTypeLoc().getSourceType(); + QualType T = AsTypeLoc().getType(); OS << "[Type: " << T->getTypeClassName() << " " << T.getAsString(); } } diff --git a/clang/lib/Index/ASTVisitor.h b/clang/lib/Index/ASTVisitor.h index e18aa57b4d1a..0ae78fb74ff4 100644 --- a/clang/lib/Index/ASTVisitor.h +++ b/clang/lib/Index/ASTVisitor.h @@ -123,14 +123,14 @@ public: BaseTypeLocVisitor::Visit(TL); } - void VisitArrayLoc(ArrayLoc TL) { - BaseTypeLocVisitor::VisitArrayLoc(TL); + void VisitArrayLoc(ArrayTypeLoc TL) { + BaseTypeLocVisitor::VisitArrayTypeLoc(TL); if (TL.getSizeExpr()) Visit(TL.getSizeExpr()); } - void VisitFunctionLoc(FunctionLoc TL) { - BaseTypeLocVisitor::VisitFunctionLoc(TL); + void VisitFunctionTypeLoc(FunctionTypeLoc TL) { + BaseTypeLocVisitor::VisitFunctionTypeLoc(TL); for (unsigned i = 0; i != TL.getNumArgs(); ++i) Visit(TL.getArg(i)); } diff --git a/clang/lib/Index/DeclReferenceMap.cpp b/clang/lib/Index/DeclReferenceMap.cpp index 0e48a369d5d9..366cf1b10830 100644 --- a/clang/lib/Index/DeclReferenceMap.cpp +++ b/clang/lib/Index/DeclReferenceMap.cpp @@ -31,8 +31,8 @@ public: void VisitMemberExpr(MemberExpr *Node); void VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node); - void VisitTypedefLoc(TypedefLoc TL); - void VisitObjCInterfaceLoc(ObjCInterfaceLoc TL); + void VisitTypedefTypeLoc(TypedefTypeLoc TL); + void VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL); }; } // anonymous namespace @@ -55,12 +55,12 @@ void RefMapper::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) { Map.insert(std::make_pair(Node->getDecl(), ASTLocation(CurrentDecl, Node))); } -void RefMapper::VisitTypedefLoc(TypedefLoc TL) { +void RefMapper::VisitTypedefTypeLoc(TypedefTypeLoc TL) { NamedDecl *ND = TL.getTypedefDecl(); Map.insert(std::make_pair(ND, ASTLocation(CurrentDecl, ND, TL.getNameLoc()))); } -void RefMapper::VisitObjCInterfaceLoc(ObjCInterfaceLoc TL) { +void RefMapper::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { NamedDecl *ND = TL.getIFaceDecl(); Map.insert(std::make_pair(ND, ASTLocation(CurrentDecl, ND, TL.getNameLoc()))); } diff --git a/clang/lib/Index/ResolveLocation.cpp b/clang/lib/Index/ResolveLocation.cpp index 229669dc330b..b94d48e33d6f 100644 --- a/clang/lib/Index/ResolveLocation.cpp +++ b/clang/lib/Index/ResolveLocation.cpp @@ -120,11 +120,11 @@ public: TypeLocResolver(ASTContext &ctx, SourceLocation loc, Decl *pd) : LocResolverBase(ctx, loc), ParentDecl(pd) { } - ASTLocation VisitTypedefLoc(TypedefLoc TL); - ASTLocation VisitFunctionLoc(FunctionLoc TL); - ASTLocation VisitArrayLoc(ArrayLoc TL); - ASTLocation VisitObjCInterfaceLoc(ObjCInterfaceLoc TL); - ASTLocation VisitObjCProtocolListLoc(ObjCProtocolListLoc TL); + ASTLocation VisitTypedefTypeLoc(TypedefTypeLoc TL); + ASTLocation VisitFunctionTypeLoc(FunctionTypeLoc TL); + ASTLocation VisitArrayTypeLoc(ArrayTypeLoc TL); + ASTLocation VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL); + ASTLocation VisitObjCProtocolListTypeLoc(ObjCProtocolListTypeLoc TL); ASTLocation VisitTypeLoc(TypeLoc TL); }; @@ -349,7 +349,7 @@ ASTLocation DeclLocResolver::VisitDecl(Decl *D) { return ASTLocation(D); } -ASTLocation TypeLocResolver::VisitTypedefLoc(TypedefLoc TL) { +ASTLocation TypeLocResolver::VisitTypedefTypeLoc(TypedefTypeLoc TL) { assert(ContainsLocation(TL) && "Should visit only after verifying that loc is in range"); if (ContainsLocation(TL.getNameLoc())) @@ -357,7 +357,7 @@ ASTLocation TypeLocResolver::VisitTypedefLoc(TypedefLoc TL) { return ASTLocation(ParentDecl, TL); } -ASTLocation TypeLocResolver::VisitFunctionLoc(FunctionLoc TL) { +ASTLocation TypeLocResolver::VisitFunctionTypeLoc(FunctionTypeLoc TL) { assert(ContainsLocation(TL) && "Should visit only after verifying that loc is in range"); @@ -373,7 +373,7 @@ ASTLocation TypeLocResolver::VisitFunctionLoc(FunctionLoc TL) { return ASTLocation(ParentDecl, TL); } -ASTLocation TypeLocResolver::VisitArrayLoc(ArrayLoc TL) { +ASTLocation TypeLocResolver::VisitArrayTypeLoc(ArrayTypeLoc TL) { assert(ContainsLocation(TL) && "Should visit only after verifying that loc is in range"); @@ -384,7 +384,7 @@ ASTLocation TypeLocResolver::VisitArrayLoc(ArrayLoc TL) { return ASTLocation(ParentDecl, TL); } -ASTLocation TypeLocResolver::VisitObjCInterfaceLoc(ObjCInterfaceLoc TL) { +ASTLocation TypeLocResolver::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { assert(ContainsLocation(TL) && "Should visit only after verifying that loc is in range"); if (ContainsLocation(TL.getNameLoc())) @@ -392,7 +392,7 @@ ASTLocation TypeLocResolver::VisitObjCInterfaceLoc(ObjCInterfaceLoc TL) { return ASTLocation(ParentDecl, TL); } -ASTLocation TypeLocResolver::VisitObjCProtocolListLoc(ObjCProtocolListLoc TL) { +ASTLocation TypeLocResolver::VisitObjCProtocolListTypeLoc(ObjCProtocolListTypeLoc TL) { assert(ContainsLocation(TL) && "Should visit only after verifying that loc is in range"); diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 99b2a51ce72b..117f595d9212 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -17,6 +17,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/TypeLoc.h" +#include "clang/AST/TypeLocVisitor.h" #include "clang/AST/Expr.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Parse/DeclSpec.h" @@ -1298,100 +1299,118 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, return T; } -static void FillTypeSpecLoc(TypeLoc TSL, const DeclSpec &DS) { - if (TSL.isNull()) return; +namespace { + class TypeSpecLocFiller : public TypeLocVisitor { + const DeclSpec &DS; - if (TypedefLoc *TL = dyn_cast(&TSL)) { - TL->setNameLoc(DS.getTypeSpecTypeLoc()); + public: + TypeSpecLocFiller(const DeclSpec &DS) : DS(DS) {} - } else if (ObjCInterfaceLoc *TL = dyn_cast(&TSL)) { - TL->setNameLoc(DS.getTypeSpecTypeLoc()); + void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { + Visit(TL.getUnqualifiedLoc()); + } + void VisitTypedefTypeLoc(TypedefTypeLoc TL) { + TL.setNameLoc(DS.getTypeSpecTypeLoc()); + } + void VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { + TL.setNameLoc(DS.getTypeSpecTypeLoc()); + } + void VisitObjCProtocolListTypeLoc(ObjCProtocolListTypeLoc TL) { + assert(TL.getNumProtocols() == DS.getNumProtocolQualifiers()); + TL.setLAngleLoc(DS.getProtocolLAngleLoc()); + TL.setRAngleLoc(DS.getSourceRange().getEnd()); + for (unsigned i = 0; i != DS.getNumProtocolQualifiers(); ++i) + TL.setProtocolLoc(i, DS.getProtocolLocs()[i]); + + TypeLoc BaseLoc = TL.getBaseTypeLoc(); + if (BaseLoc) + Visit(TL.getBaseTypeLoc()); + } + void VisitTypeLoc(TypeLoc TL) { + // FIXME: add other typespec types and change this to an assert. + TL.initialize(DS.getTypeSpecTypeLoc()); + } + }; - } else if (ObjCProtocolListLoc *PLL = dyn_cast(&TSL)) { - assert(PLL->getNumProtocols() == DS.getNumProtocolQualifiers()); - PLL->setLAngleLoc(DS.getProtocolLAngleLoc()); - PLL->setRAngleLoc(DS.getSourceRange().getEnd()); - for (unsigned i = 0; i != DS.getNumProtocolQualifiers(); ++i) - PLL->setProtocolLoc(i, DS.getProtocolLocs()[i]); - FillTypeSpecLoc(PLL->getBaseTypeLoc(), DS); + class DeclaratorLocFiller : public TypeLocVisitor { + const DeclaratorChunk &Chunk; - } else { - //FIXME: Other typespecs. - DefaultTypeSpecLoc &DTL = cast(TSL); - DTL.setStartLoc(DS.getSourceRange().getBegin()); - } -} + public: + DeclaratorLocFiller(const DeclaratorChunk &Chunk) : Chunk(Chunk) {} -/// \brief Create and instantiate a DeclaratorInfo with type source information. -/// -/// \param T QualType referring to the type as written in source code. -DeclaratorInfo * -Sema::GetDeclaratorInfoForDeclarator(Declarator &D, QualType T, unsigned Skip) { - DeclaratorInfo *DInfo = Context.CreateDeclaratorInfo(T); - TypeLoc CurrTL = DInfo->getTypeLoc(); - - for (unsigned i = Skip, e = D.getNumTypeObjects(); i != e; ++i) { - assert(!CurrTL.isNull()); - - // Don't bother recording source locations for qualifiers. - CurrTL = CurrTL.getUnqualifiedLoc(); + void VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { + llvm::llvm_unreachable("qualified type locs not expected here!"); + } - DeclaratorChunk &DeclType = D.getTypeObject(i); - switch (DeclType.Kind) { - default: assert(0 && "Unknown decltype!"); - case DeclaratorChunk::BlockPointer: { - BlockPointerLoc &BPL = cast(CurrTL); - BPL.setCaretLoc(DeclType.Loc); - break; + void VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { + assert(Chunk.Kind == DeclaratorChunk::BlockPointer); + TL.setCaretLoc(Chunk.Loc); } - case DeclaratorChunk::Pointer: { - //FIXME: ObjCObject pointers. - PointerLoc &PL = cast(CurrTL); - PL.setStarLoc(DeclType.Loc); - break; + void VisitPointerTypeLoc(PointerTypeLoc TL) { + assert(Chunk.Kind == DeclaratorChunk::Pointer); + TL.setStarLoc(Chunk.Loc); } - case DeclaratorChunk::Reference: { - ReferenceLoc &RL = cast(CurrTL); - RL.setAmpLoc(DeclType.Loc); - break; + void VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { + assert(Chunk.Kind == DeclaratorChunk::Pointer); + TL.setStarLoc(Chunk.Loc); } - case DeclaratorChunk::Array: { - DeclaratorChunk::ArrayTypeInfo &ATI = DeclType.Arr; - ArrayLoc &AL = cast(CurrTL); - AL.setLBracketLoc(DeclType.Loc); - AL.setRBracketLoc(DeclType.EndLoc); - AL.setSizeExpr(static_cast(ATI.NumElts)); - //FIXME: Star location for [*]. - break; + void VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) { + assert(Chunk.Kind == DeclaratorChunk::MemberPointer); + TL.setStarLoc(Chunk.Loc); + // FIXME: nested name specifier } - case DeclaratorChunk::Function: { - const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun; - FunctionLoc &FL = cast(CurrTL); - FL.setLParenLoc(DeclType.Loc); - FL.setRParenLoc(DeclType.EndLoc); + void VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) { + assert(Chunk.Kind == DeclaratorChunk::Reference); + assert(Chunk.Ref.LValueRef); + TL.setAmpLoc(Chunk.Loc); + } + void VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) { + assert(Chunk.Kind == DeclaratorChunk::Reference); + assert(!Chunk.Ref.LValueRef); + TL.setAmpAmpLoc(Chunk.Loc); + } + void VisitArrayTypeLoc(ArrayTypeLoc TL) { + assert(Chunk.Kind == DeclaratorChunk::Array); + TL.setLBracketLoc(Chunk.Loc); + TL.setRBracketLoc(Chunk.EndLoc); + TL.setSizeExpr(static_cast(Chunk.Arr.NumElts)); + } + void VisitFunctionTypeLoc(FunctionTypeLoc TL) { + assert(Chunk.Kind == DeclaratorChunk::Function); + TL.setLParenLoc(Chunk.Loc); + TL.setRParenLoc(Chunk.EndLoc); + + const DeclaratorChunk::FunctionTypeInfo &FTI = Chunk.Fun; for (unsigned i = 0, e = FTI.NumArgs, tpi = 0; i != e; ++i) { ParmVarDecl *Param = FTI.ArgInfo[i].Param.getAs(); if (Param) { - assert(tpi < FL.getNumArgs()); - FL.setArg(tpi++, Param); + assert(tpi < TL.getNumArgs()); + TL.setArg(tpi++, Param); } } - break; - //FIXME: Exception specs. - } - case DeclaratorChunk::MemberPointer: { - MemberPointerLoc &MPL = cast(CurrTL); - MPL.setStarLoc(DeclType.Loc); - //FIXME: Class location. - break; + // FIXME: exception specs } + void VisitTypeLoc(TypeLoc TL) { + llvm::llvm_unreachable("unsupported TypeLoc kind in declarator!"); } + }; +} - CurrTL = CurrTL.getNextTypeLoc(); +/// \brief Create and instantiate a DeclaratorInfo with type source information. +/// +/// \param T QualType referring to the type as written in source code. +DeclaratorInfo * +Sema::GetDeclaratorInfoForDeclarator(Declarator &D, QualType T, unsigned Skip) { + DeclaratorInfo *DInfo = Context.CreateDeclaratorInfo(T); + UnqualTypeLoc CurrTL = DInfo->getTypeLoc().getUnqualifiedLoc(); + + for (unsigned i = Skip, e = D.getNumTypeObjects(); i != e; ++i) { + DeclaratorLocFiller(D.getTypeObject(i)).Visit(CurrTL); + CurrTL = CurrTL.getNextTypeLoc().getUnqualifiedLoc(); } - FillTypeSpecLoc(CurrTL, D.getDeclSpec()); + TypeSpecLocFiller(D.getDeclSpec()).Visit(CurrTL); return DInfo; } -- GitLab