diff options
-rw-r--r-- | include/clang/AST/ASTContext.h | 10 | ||||
-rw-r--r-- | include/clang/AST/Decl.h | 23 | ||||
-rw-r--r-- | include/clang/AST/TypeLoc.h | 470 | ||||
-rw-r--r-- | include/clang/AST/TypeLocNodes.def | 53 | ||||
-rw-r--r-- | lib/AST/ASTContext.cpp | 17 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 5 | ||||
-rw-r--r-- | lib/AST/TypeLoc.cpp | 328 |
7 files changed, 905 insertions, 1 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 0c1ccfddb7..7d7c25c895 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -918,6 +918,16 @@ public: void setObjCImplementation(ObjCCategoryDecl *CatD, ObjCCategoryImplDecl *ImplD); + /// \brief Allocate an uninitialized DeclaratorInfo. + /// + /// The caller should initialize the memory held by DeclaratorInfo using + /// the TypeLoc wrappers. + /// + /// \param T the type that will be the basis for type source info. This type + /// should refer to how the declarator was written in source code, not to + /// what type semantic analysis resolved the declarator to. + DeclaratorInfo *CreateDeclaratorInfo(QualType T); + private: ASTContext(const ASTContext&); // DO NOT IMPLEMENT void operator=(const ASTContext&); // DO NOT IMPLEMENT diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index d603e677b2..432ae4c63b 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -28,7 +28,28 @@ class CompoundStmt; class StringLiteral; class TemplateArgumentList; class FunctionTemplateSpecializationInfo; - +class TypeLoc; + +/// \brief A container of type source information. +/// +/// A client can read the relevant info using TypeLoc wrappers, e.g: +/// @code +/// TypeLoc TL = DeclaratorInfo->getTypeLoc(); +/// if (PointerLoc *PL = dyn_cast<PointerLoc>(&TL)) +/// PL->getStarLoc().print(OS, SrcMgr); +/// @endcode +/// +class DeclaratorInfo { + QualType Ty; + // Contains a memory block after the class, used for type source information, + // allocated by ASTContext. + friend class ASTContext; + DeclaratorInfo(QualType ty) : Ty(ty) { } +public: + /// \brief Return the TypeLoc wrapper for the type source info. + TypeLoc getTypeLoc() const; +}; + /// TranslationUnitDecl - The top declaration context. class TranslationUnitDecl : public Decl, public DeclContext { ASTContext &Ctx; diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h new file mode 100644 index 0000000000..5aa13a5c53 --- /dev/null +++ b/include/clang/AST/TypeLoc.h @@ -0,0 +1,470 @@ +//===--- TypeLoc.h - Type Source Info Wrapper -------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the TypeLoc interface and subclasses. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_TYPELOC_H +#define LLVM_CLANG_AST_TYPELOC_H + +#include "clang/AST/Type.h" +#include "clang/AST/TypeVisitor.h" + +namespace clang { + class ParmVarDecl; + class TypeSpecLoc; + class DeclaratorInfo; + +/// \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 +/// get at the actual information. +class TypeLoc { +protected: + QualType Ty; + void *Data; + + TypeLoc(QualType ty, void *data) : Ty(ty), Data(data) { } + static TypeLoc Create(QualType ty, void *data) { return TypeLoc(ty,data); } + friend class DeclaratorInfo; +public: + TypeLoc() : Data(0) { } + + bool isNull() const { return Ty.isNull(); } + operator bool() const { return isNull(); } + + /// \brief Returns the size of type source info data block for the given type. + static unsigned getFullDataSizeForType(QualType Ty); + + /// \brief Get the type for which this source info wrapper provides + /// information. + QualType getSourceType() const { return Ty; } + + /// \brief Find the TypeSpecLoc that is part of this TypeLoc. + TypeSpecLoc getTypeSpecLoc() const; + + /// \brief Find the TypeSpecLoc that is part of this TypeLoc and return its + /// SourceRange. + SourceRange getTypeSpecRange() const; + + /// \brief Returns the size of the type source info data block. + unsigned getFullDataSize() const; + + /// \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; + + friend bool operator==(const TypeLoc &LHS, const TypeLoc &RHS) { + return LHS.Ty == RHS.Ty && LHS.Data == RHS.Data; + } + + friend bool operator!=(const TypeLoc &LHS, const TypeLoc &RHS) { + return !(LHS == RHS); + } + + static bool classof(const TypeLoc *TL) { return true; } +}; + +/// \brief Base wrapper of type source info data for type-spec types. +class TypeSpecLoc : public TypeLoc { +public: + SourceRange getSourceRange() const; + + static bool classof(const TypeLoc *TL); + static bool classof(const TypeSpecLoc *TL) { return true; } +}; + +/// \brief Base wrapper of type source info data for types part of a declarator, +/// excluding type-spec types. +class DeclaratorLoc : public TypeLoc { +public: + /// \brief Find the TypeSpecLoc that is part of this DeclaratorLoc. + TypeSpecLoc getTypeSpecLoc() const; + + static bool classof(const TypeLoc *TL); + static bool classof(const DeclaratorLoc *TL) { return true; } +}; + +/// \brief The default wrapper for type-spec types that are not handled by +/// another specific wrapper. +class DefaultTypeSpecLoc : public TypeSpecLoc { + struct Info { + SourceLocation StartLoc; + }; + +public: + SourceLocation getStartLoc() const { + return static_cast<Info*>(Data)->StartLoc; + } + void setStartLoc(SourceLocation Loc) { + static_cast<Info*>(Data)->StartLoc = Loc; + } + SourceRange getSourceRange() const { + return SourceRange(getStartLoc(), getStartLoc()); + } + + /// \brief Returns the size of the type source info data block that is + /// specific to this type. + unsigned getLocalDataSize() const { return sizeof(Info); } + + /// \brief Returns the size of the type source info data block. + unsigned getFullDataSize() const { return getLocalDataSize(); } + + static bool classof(const TypeLoc *TL); + static bool classof(const DefaultTypeSpecLoc *TL) { return true; } +}; + +/// \brief Wrapper for source info for typedefs. +class TypedefLoc : public TypeSpecLoc { + struct Info { + SourceLocation NameLoc; + }; + +public: + SourceLocation getNameLoc() const { + return static_cast<Info*>(Data)->NameLoc; + } + void setNameLoc(SourceLocation Loc) { + static_cast<Info*>(Data)->NameLoc = Loc; + } + SourceRange getSourceRange() const { + return SourceRange(getNameLoc(), getNameLoc()); + } + + /// \brief Returns the size of the type source info data block that is + /// specific to this type. + unsigned getLocalDataSize() const { return sizeof(Info); } + + /// \brief Returns the size of the type source info data block. + unsigned getFullDataSize() const { return getLocalDataSize(); } + + static bool classof(const TypeLoc *TL); + static bool classof(const TypedefLoc *TL) { return true; } +}; + +/// \brief Wrapper for source info for pointers. +class PointerLoc : public DeclaratorLoc { + struct Info { + SourceLocation StarLoc; + }; + +public: + SourceLocation getStarLoc() const { + return static_cast<Info*>(Data)->StarLoc; + } + void setStarLoc(SourceLocation Loc) { + static_cast<Info*>(Data)->StarLoc = Loc; + } + + TypeLoc getPointeeLoc() const { + void *Next = static_cast<char*>(Data) + getLocalDataSize(); + return Create(cast<PointerType>(Ty)->getPointeeType(), Next); + } + + /// \brief Find the TypeSpecLoc that is part of this PointerLoc. + TypeSpecLoc getTypeSpecLoc() const { + return getPointeeLoc().getTypeSpecLoc(); + } + + SourceRange getSourceRange() const { + return SourceRange(getStarLoc(), getStarLoc()); + } + + /// \brief Returns the size of the type source info data block that is + /// specific to this type. + unsigned getLocalDataSize() const { return sizeof(Info); } + + /// \brief Returns the size of the type source info data block. + unsigned getFullDataSize() const { + return getLocalDataSize() + getPointeeLoc().getFullDataSize(); + } + + static bool classof(const TypeLoc *TL); + static bool classof(const PointerLoc *TL) { return true; } +}; + +/// \brief Wrapper for source info for block pointers. +class BlockPointerLoc : public DeclaratorLoc { + struct Info { + SourceLocation CaretLoc; + }; + +public: + SourceLocation getCaretLoc() const { + return static_cast<Info*>(Data)->CaretLoc; + } + void setCaretLoc(SourceLocation Loc) { + static_cast<Info*>(Data)->CaretLoc = Loc; + } + + TypeLoc getPointeeLoc() const { + void *Next = static_cast<char*>(Data) + getLocalDataSize(); + return Create(cast<BlockPointerType>(Ty)->getPointeeType(), Next); + } + + /// \brief Find the TypeSpecLoc that is part of this BlockPointerLoc. + TypeSpecLoc getTypeSpecLoc() const { + return getPointeeLoc().getTypeSpecLoc(); + } + + SourceRange getSourceRange() const { + return SourceRange(getCaretLoc(), getCaretLoc()); + } + + /// \brief Returns the size of the type source info data block that is + /// specific to this type. + unsigned getLocalDataSize() const { return sizeof(Info); } + + /// \brief Returns the size of the type source info data block. + unsigned getFullDataSize() const { + return getLocalDataSize() + getPointeeLoc().getFullDataSize(); + } + + static bool classof(const TypeLoc *TL); + static bool classof(const BlockPointerLoc *TL) { return true; } +}; + +/// \brief Wrapper for source info for member pointers. +class MemberPointerLoc : public DeclaratorLoc { + struct Info { + SourceLocation StarLoc; + }; + +public: + SourceLocation getStarLoc() const { + return static_cast<Info*>(Data)->StarLoc; + } + void setStarLoc(SourceLocation Loc) { + static_cast<Info*>(Data)->StarLoc = Loc; + } + + TypeLoc getPointeeLoc() const { + void *Next = static_cast<char*>(Data) + getLocalDataSize(); + return Create(cast<MemberPointerType>(Ty)->getPointeeType(), Next); + } + + /// \brief Find the TypeSpecLoc that is part of this MemberPointerLoc. + TypeSpecLoc getTypeSpecLoc() const { + return getPointeeLoc().getTypeSpecLoc(); + } + + SourceRange getSourceRange() const { + return SourceRange(getStarLoc(), getStarLoc()); + } + + /// \brief Returns the size of the type source info data block that is + /// specific to this type. + unsigned getLocalDataSize() const { return sizeof(Info); } + + /// \brief Returns the size of the type source info data block. + unsigned getFullDataSize() const { + return getLocalDataSize() + getPointeeLoc().getFullDataSize(); + } + + static bool classof(const TypeLoc *TL); + static bool classof(const MemberPointerLoc *TL) { return true; } +}; + +/// \brief Wrapper for source info for references. +class ReferenceLoc : public DeclaratorLoc { + struct Info { + SourceLocation AmpLoc; + }; + +public: + SourceLocation getAmpLoc() const { + return static_cast<Info*>(Data)->AmpLoc; + } + void setAmpLoc(SourceLocation Loc) { + static_cast<Info*>(Data)->AmpLoc = Loc; + } + + TypeLoc getPointeeLoc() const { + void *Next = static_cast<char*>(Data) + getLocalDataSize(); + return Create(cast<ReferenceType>(Ty)->getPointeeType(), Next); + } + + /// \brief Find the TypeSpecLoc that is part of this ReferenceLoc. + TypeSpecLoc getTypeSpecLoc() const { + return getPointeeLoc().getTypeSpecLoc(); + } + + SourceRange getSourceRange() const { + return SourceRange(getAmpLoc(), getAmpLoc()); + } + + /// \brief Returns the size of the type source info data block that is + /// specific to this type. + unsigned getLocalDataSize() const { return sizeof(Info); } + + /// \brief Returns the size of the type source info data block. + unsigned getFullDataSize() const { + return getLocalDataSize() + getPointeeLoc().getFullDataSize(); + } + + static bool classof(const TypeLoc *TL); + static bool classof(const ReferenceLoc *TL) { return true; } +}; + +/// \brief Wrapper for source info for functions. +class FunctionLoc : public DeclaratorLoc { + struct Info { + SourceLocation LParenLoc, RParenLoc; + }; + // ParmVarDecls* are stored after Info, one for each argument. + ParmVarDecl **getParmArray() const { + return reinterpret_cast<ParmVarDecl**>(static_cast<Info*>(Data) + 1); + } + +public: + SourceLocation getLParenLoc() const { + return static_cast<Info*>(Data)->LParenLoc; + } + void setLParenLoc(SourceLocation Loc) { + static_cast<Info*>(Data)->LParenLoc = Loc; + } + + SourceLocation getRParenLoc() const { + return static_cast<Info*>(Data)->RParenLoc; + } + void setRParenLoc(SourceLocation Loc) { + static_cast<Info*>(Data)->RParenLoc = Loc; + } + + unsigned getNumArgs() const { + if (isa<FunctionNoProtoType>(Ty)) + return 0; + return cast<FunctionProtoType>(Ty)->getNumArgs(); + } + ParmVarDecl *getArg(unsigned i) const { return getParmArray()[i]; } + void setArg(unsigned i, ParmVarDecl *VD) { getParmArray()[i] = VD; } + + TypeLoc getArgLoc(unsigned i) const; + + TypeLoc getResultLoc() const { + void *Next = static_cast<char*>(Data) + getLocalDataSize(); + return Create(cast<FunctionType>(Ty)->getResultType(), Next); + } + + /// \brief Find the TypeSpecLoc that is part of this FunctionLoc. + TypeSpecLoc getTypeSpecLoc() const { + return getResultLoc().getTypeSpecLoc(); + } + SourceRange getSourceRange() const { + return SourceRange(getLParenLoc(), getRParenLoc()); + } + + /// \brief Returns the size of the type source info data block that is + /// specific to this type. + unsigned getLocalDataSize() const { + return sizeof(Info) + getNumArgs() * sizeof(ParmVarDecl*); + } + + /// \brief Returns the size of the type source info data block. + unsigned getFullDataSize() const { + return getLocalDataSize() + getResultLoc().getFullDataSize(); + } + + static bool classof(const TypeLoc *TL); + static bool classof(const FunctionLoc *TL) { return true; } +}; + +/// \brief Wrapper for source info for arrays. +class ArrayLoc : public DeclaratorLoc { + struct Info { + SourceLocation LBracketLoc, RBracketLoc; + Expr *Size; + }; +public: + SourceLocation getLBracketLoc() const { + return static_cast<Info*>(Data)->LBracketLoc; + } + void setLBracketLoc(SourceLocation Loc) { + static_cast<Info*>(Data)->LBracketLoc = Loc; + } + + SourceLocation getRBracketLoc() const { + return static_cast<Info*>(Data)->RBracketLoc; + } + void setRBracketLoc(SourceLocation Loc) { + static_cast<Info*>(Data)->RBracketLoc = Loc; + } + + Expr *getSizeExpr() const { + return static_cast<Info*>(Data)->Size; + } + void setSizeExpr(Expr *Size) { + static_cast<Info*>(Data)->Size = Size; + } + + TypeLoc getElementLoc() const { + void *Next = static_cast<char*>(Data) + getLocalDataSize(); + return Create(cast<ArrayType>(Ty)->getElementType(), Next); + } + + /// \brief Find the TypeSpecLoc that is part of this ArrayLoc. + TypeSpecLoc getTypeSpecLoc() const { + return getElementLoc().getTypeSpecLoc(); + } + SourceRange getSourceRange() const { + return SourceRange(getLBracketLoc(), getRBracketLoc()); + } + + /// \brief Returns the size of the type source info data block that is + /// specific to this type. + unsigned getLocalDataSize() const { return sizeof(Info); } + + /// \brief Returns the size of the type source info data block. + unsigned getFullDataSize() const { + return getLocalDataSize() + getElementLoc().getFullDataSize(); + } + + static bool classof(const TypeLoc *TL); + static bool classof(const ArrayLoc *TL) { return true; } +}; + +#define DISPATCH(CLASS) \ + return static_cast<ImplClass*>(this)->Visit ## CLASS(cast<CLASS>(TyLoc)) + +template<typename ImplClass, typename RetTy=void> +class TypeLocVisitor { + class TypeDispatch : public TypeVisitor<TypeDispatch, RetTy> { + ImplClass *Impl; + TypeLoc TyLoc; + + public: + TypeDispatch(ImplClass *impl, TypeLoc &tyLoc) : Impl(impl), TyLoc(tyLoc) { } +#define ABSTRACT_TYPELOC(CLASS) +#define TYPELOC(CLASS, PARENT, TYPE) \ + RetTy Visit##TYPE(TYPE *) { \ + return Impl->Visit##CLASS(reinterpret_cast<CLASS&>(TyLoc)); \ + } +#include "clang/AST/TypeLocNodes.def" + }; + +public: + RetTy Visit(TypeLoc TyLoc) { + TypeDispatch TD(static_cast<ImplClass*>(this), TyLoc); + return TD.Visit(TyLoc.getSourceType().getTypePtr()); + } + +#define TYPELOC(CLASS, PARENT, TYPE) RetTy Visit##CLASS(CLASS TyLoc) { \ + DISPATCH(PARENT); \ +} +#include "clang/AST/TypeLocNodes.def" + + RetTy VisitTypeLoc(TypeLoc TyLoc) { return RetTy(); } +}; + +#undef DISPATCH + +} + +#endif diff --git a/include/clang/AST/TypeLocNodes.def b/include/clang/AST/TypeLocNodes.def new file mode 100644 index 0000000000..e2604524e8 --- /dev/null +++ b/include/clang/AST/TypeLocNodes.def @@ -0,0 +1,53 @@ +//===-- TypeLocNodes.def - Metadata about TypeLoc wrappers ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// 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. +// +// TYPELOC(Class, Base, Type) - Description of the TypeLoc 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 ABSTRACT_TYPELOC +# define ABSTRACT_TYPELOC(Class) TYPELOC(Class, TypeLoc, Type) +#endif + +#ifndef TYPESPEC_TYPELOC +# define TYPESPEC_TYPELOC(Class, Type) TYPELOC(Class, TypeSpecLoc, Type) +#endif + +#ifndef DECLARATOR_TYPELOC +# define DECLARATOR_TYPELOC(Class, Type) TYPELOC(Class, DeclaratorLoc, Type) +#endif + +TYPESPEC_TYPELOC(DefaultTypeSpecLoc, Type) +TYPESPEC_TYPELOC(TypedefLoc, TypedefType) +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) + + +#undef DECLARATOR_TYPELOC +#undef TYPESPEC_TYPELOC +#undef ABSTRACT_TYPELOC +#undef TYPELOC diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index f0ab845f7c..69ff79240a 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -15,6 +15,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/TypeLoc.h" #include "clang/AST/Expr.h" #include "clang/AST/ExternalASTSource.h" #include "clang/AST/RecordLayout.h" @@ -875,6 +876,22 @@ void ASTContext::setObjCImplementation(ObjCCategoryDecl *CatD, ObjCImpls[CatD] = ImplD; } +/// \brief Allocate an uninitialized DeclaratorInfo. +/// +/// The caller should initialize the memory held by DeclaratorInfo using +/// the TypeLoc wrappers. +/// +/// \param T the type that will be the basis for type source info. This type +/// should refer to how the declarator was written in source code, not to +/// what type semantic analysis resolved the declarator to. +DeclaratorInfo *ASTContext::CreateDeclaratorInfo(QualType T) { + unsigned DataSize = TypeLoc::getFullDataSizeForType(T); + DeclaratorInfo *DInfo = + (DeclaratorInfo*)BumpAlloc.Allocate(sizeof(DeclaratorInfo) + DataSize, 8); + new (DInfo) DeclaratorInfo(T); + return DInfo; +} + /// getInterfaceLayoutImpl - Get or compute information about the /// layout of the given interface. /// diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index c91cb1dba2..f5acb2c9aa 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -16,6 +16,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/TypeLoc.h" #include "clang/AST/Stmt.h" #include "clang/AST/Expr.h" #include "clang/AST/PrettyPrinter.h" @@ -34,6 +35,10 @@ void Attr::Destroy(ASTContext &C) { C.Deallocate((void*)this); } +/// \brief Return the TypeLoc wrapper for the type source info. +TypeLoc DeclaratorInfo::getTypeLoc() const { + return TypeLoc::Create(Ty, (void*)(this + 1)); +} //===----------------------------------------------------------------------===// // Decl Allocation/Deallocation Method Implementations diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp new file mode 100644 index 0000000000..85415ba09a --- /dev/null +++ b/lib/AST/TypeLoc.cpp @@ -0,0 +1,328 @@ +//===--- TypeLoc.cpp - Type Source Info Wrapper -----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the TypeLoc subclasses implementations. +// +//===----------------------------------------------------------------------===// + +#include "clang/AST/TypeLoc.h" +using namespace clang; + +//===----------------------------------------------------------------------===// +// TypeLoc Implementation +//===----------------------------------------------------------------------===// + +/// \brief Returns the size of type source info data block for the given type. +unsigned TypeLoc::getFullDataSizeForType(QualType Ty) { + return TypeLoc(Ty, 0).getFullDataSize(); +} + +/// \brief Find the TypeSpecLoc that is part of this TypeLoc. +TypeSpecLoc TypeLoc::getTypeSpecLoc() const { + if (isNull()) + return TypeSpecLoc(); + + if (const DeclaratorLoc *DL = dyn_cast<DeclaratorLoc>(this)) + return DL->getTypeSpecLoc(); + return cast<TypeSpecLoc>(*this); +} + +/// \brief Find the TypeSpecLoc that is part of this TypeLoc and return its +/// SourceRange. +SourceRange TypeLoc::getTypeSpecRange() const { + return getTypeSpecLoc().getSourceRange(); +} + +namespace { + +/// \brief Report the full source info data size for the visited TypeLoc. +class TypeSizer : public TypeLocVisitor<TypeSizer, unsigned> { +public: +#define ABSTRACT_TYPELOC(CLASS) +#define TYPELOC(CLASS, PARENT, TYPE) \ + unsigned Visit##CLASS(CLASS 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. +unsigned TypeLoc::getFullDataSize() const { + return TypeSizer().Visit(*this); +} + +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<NextLoc, TypeLoc> { +public: +#define TYPELOC(CLASS, PARENT, TYPE) +#define DECLARATOR_TYPELOC(CLASS, TYPE) \ + TypeLoc Visit##CLASS(CLASS TyLoc); +#include "clang/AST/TypeLocNodes.def" + + TypeLoc VisitTypeSpecLoc(TypeLoc TyLoc) { return TypeLoc(); } + + TypeLoc VisitTypeLoc(TypeLoc TyLoc) { + assert(0 && "A declarator loc wrapper was not handled!"); + return TypeLoc(); + } +}; + +} + +TypeLoc NextLoc::VisitPointerLoc(PointerLoc TL) { + return TL.getPointeeLoc(); +} +TypeLoc NextLoc::VisitMemberPointerLoc(MemberPointerLoc TL) { + return TL.getPointeeLoc(); +} +TypeLoc NextLoc::VisitBlockPointerLoc(BlockPointerLoc TL) { + return TL.getPointeeLoc(); +} +TypeLoc NextLoc::VisitReferenceLoc(ReferenceLoc TL) { + return TL.getPointeeLoc(); +} +TypeLoc NextLoc::VisitFunctionLoc(FunctionLoc TL) { + return TL.getResultLoc(); +} +TypeLoc NextLoc::VisitArrayLoc(ArrayLoc TL) { + return TL.getElementLoc(); +} + +/// \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); +} + +//===----------------------------------------------------------------------===// +// TypeSpecLoc Implementation +//===----------------------------------------------------------------------===// + +namespace { + +/// \brief Return the source range for the visited TypeSpecLoc. +class TypeSpecRanger : public TypeLocVisitor<TypeSpecRanger, SourceRange> { +public: +#define TYPELOC(CLASS, PARENT, TYPE) +#define TYPESPEC_TYPELOC(CLASS, TYPE) \ + SourceRange Visit##CLASS(CLASS TyLoc) { return TyLoc.getSourceRange(); } +#include "clang/AST/TypeLocNodes.def" + + SourceRange VisitTypeLoc(TypeLoc TyLoc) { + assert(0 && "A typespec loc wrapper was not handled!"); + return SourceRange(); + } +}; + +} + +SourceRange TypeSpecLoc::getSourceRange() const { + if (isNull()) + return SourceRange(); + return TypeSpecRanger().Visit(*this); +} + +namespace { +class TypeSpecChecker : public TypeLocVisitor<TypeSpecChecker, bool> { +public: + bool VisitTypeSpecLoc(TypeSpecLoc TyLoc) { return true; } +}; + +} + +bool TypeSpecLoc::classof(const TypeLoc *TL) { + return TypeSpecChecker().Visit(*TL); +} + +//===----------------------------------------------------------------------===// +// DeclaratorLoc Implementation +//===----------------------------------------------------------------------===// + +namespace { + +/// \brief Return the TypeSpecLoc for the visited DeclaratorLoc. +class TypeSpecGetter : public TypeLocVisitor<TypeSpecGetter, TypeSpecLoc> { +public: +#define TYPELOC(CLASS, PARENT, TYPE) +#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(); + } +}; + +} + +/// \brief Find the TypeSpecLoc that is part of this DeclaratorLoc. +TypeSpecLoc DeclaratorLoc::getTypeSpecLoc() const { + return TypeSpecGetter().Visit(*this); +} + +namespace { + +class DeclaratorLocChecker : public TypeLocVisitor<DeclaratorLocChecker, bool> { +public: + bool VisitDeclaratorLoc(DeclaratorLoc TyLoc) { return true; } +}; + +} + +bool DeclaratorLoc::classof(const TypeLoc *TL) { + return DeclaratorLocChecker().Visit(*TL); +} + +//===----------------------------------------------------------------------===// +// DefaultTypeSpecLoc Implementation +//===----------------------------------------------------------------------===// + +namespace { + +class DefaultTypeSpecLocChecker : + public TypeLocVisitor<DefaultTypeSpecLocChecker, bool> { +public: + bool VisitDefaultTypeSpecLoc(DefaultTypeSpecLoc TyLoc) { return true; } +}; + +} + +bool DefaultTypeSpecLoc::classof(const TypeLoc *TL) { + return DefaultTypeSpecLocChecker().Visit(*TL); +} + +//===----------------------------------------------------------------------===// +// TypedefLoc Implementation +//===----------------------------------------------------------------------===// + +namespace { + +class TypedefLocChecker : public TypeLocVisitor<TypedefLocChecker, bool> { +public: + bool VisitTypedefLoc(TypedefLoc TyLoc) { return true; } +}; + +} + +bool TypedefLoc::classof(const TypeLoc *TL) { + return TypedefLocChecker().Visit(*TL); +} + +//===----------------------------------------------------------------------===// +// PointerLoc Implementation +//===----------------------------------------------------------------------===// + +namespace { + +class PointerLocChecker : public TypeLocVisitor<PointerLocChecker, bool> { +public: + bool VisitPointerLoc(PointerLoc TyLoc) { return true; } +}; + +} + +bool PointerLoc::classof(const TypeLoc *TL) { + return PointerLocChecker().Visit(*TL); +} + +//===----------------------------------------------------------------------===// +// BlockPointerLoc Implementation +//===----------------------------------------------------------------------===// + +namespace { + +class BlockPointerLocChecker : + public TypeLocVisitor<BlockPointerLocChecker, bool> { +public: + bool VisitBlockPointerLoc(BlockPointerLoc TyLoc) { return true; } +}; + +} + +bool BlockPointerLoc::classof(const TypeLoc *TL) { + return BlockPointerLocChecker().Visit(*TL); +} + +//===----------------------------------------------------------------------===// +// MemberPointerLoc Implementation +//===----------------------------------------------------------------------===// + +namespace { + +class MemberPointerLocChecker : + public TypeLocVisitor<MemberPointerLocChecker, bool> { +public: + bool VisitMemberPointerLoc(MemberPointerLoc TyLoc) { return true; } +}; + +} + +bool MemberPointerLoc::classof(const TypeLoc *TL) { + return MemberPointerLocChecker().Visit(*TL); +} + +//===----------------------------------------------------------------------===// +// ReferenceLoc Implementation +//===----------------------------------------------------------------------===// + +namespace { + +class ReferenceLocChecker : public TypeLocVisitor<ReferenceLocChecker, bool> { +public: + bool VisitReferenceLoc(ReferenceLoc TyLoc) { return true; } +}; + +} + +bool ReferenceLoc::classof(const TypeLoc *TL) { + return ReferenceLocChecker().Visit(*TL); +} + +//===----------------------------------------------------------------------===// +// FunctionLoc Implementation +//===----------------------------------------------------------------------===// + +namespace { + +class FunctionLocChecker : public TypeLocVisitor<FunctionLocChecker, bool> { +public: + bool VisitFunctionLoc(FunctionLoc TyLoc) { return true; } +}; + +} + +bool FunctionLoc::classof(const TypeLoc *TL) { + return FunctionLocChecker().Visit(*TL); +} + +//===----------------------------------------------------------------------===// +// ArrayLoc Implementation +//===----------------------------------------------------------------------===// + +namespace { + +class ArrayLocChecker : public TypeLocVisitor<ArrayLocChecker, bool> { +public: + bool VisitArrayLoc(ArrayLoc TyLoc) { return true; } +}; + +} + +bool ArrayLoc::classof(const TypeLoc *TL) { + return ArrayLocChecker().Visit(*TL); +} |