diff options
Diffstat (limited to 'include/clang/AST/TypeLoc.h')
-rw-r--r-- | include/clang/AST/TypeLoc.h | 538 |
1 files changed, 538 insertions, 0 deletions
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h new file mode 100644 index 000000000000..a6184375e095 --- /dev/null +++ b/include/clang/AST/TypeLoc.h @@ -0,0 +1,538 @@ +//===--- 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" + +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; + +public: + TypeLoc() : Data(0) { } + TypeLoc(QualType ty, void *opaqueData) : Ty(ty), Data(opaqueData) { } + + 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 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; + + /// \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: + 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()); + } + + TypedefDecl *getTypedefDecl() const { + return cast<TypedefType>(Ty)->getDecl(); + } + + /// \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 ObjC interfaces. +class ObjCInterfaceLoc : 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()); + } + + ObjCInterfaceDecl *getIFaceDecl() const { + return cast<ObjCInterfaceType>(Ty)->getDecl(); + } + + /// \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 ObjC protocol lists. +class ObjCProtocolListLoc : public TypeSpecLoc { + struct Info { + SourceLocation LAngleLoc, RAngleLoc; + }; + // SourceLocations are stored after Info, one for each Protocol. + SourceLocation *getProtocolLocArray() const { + return reinterpret_cast<SourceLocation*>(static_cast<Info*>(Data) + 1); + } + +public: + SourceLocation getLAngleLoc() const { + return static_cast<Info*>(Data)->LAngleLoc; + } + void setLAngleLoc(SourceLocation Loc) { + static_cast<Info*>(Data)->LAngleLoc = Loc; + } + + SourceLocation getRAngleLoc() const { + return static_cast<Info*>(Data)->RAngleLoc; + } + void setRAngleLoc(SourceLocation Loc) { + static_cast<Info*>(Data)->RAngleLoc = Loc; + } + + unsigned getNumProtocols() const { + return cast<ObjCProtocolListType>(Ty)->getNumProtocols(); + } + + SourceLocation getProtocolLoc(unsigned i) const { + assert(i < getNumProtocols() && "Index is out of bounds!"); + return getProtocolLocArray()[i]; + } + void setProtocolLoc(unsigned i, SourceLocation Loc) { + assert(i < getNumProtocols() && "Index is out of bounds!"); + getProtocolLocArray()[i] = Loc; + } + + ObjCProtocolDecl *getProtocol(unsigned i) const { + assert(i < getNumProtocols() && "Index is out of bounds!"); + return *(cast<ObjCProtocolListType>(Ty)->qual_begin() + i); + } + + TypeLoc getBaseTypeLoc() const { + void *Next = static_cast<char*>(Data) + getLocalDataSize(); + return TypeLoc(cast<ObjCProtocolListType>(Ty)->getBaseType(), Next); + } + + SourceRange getSourceRange() const { + return SourceRange(getLAngleLoc(), getRAngleLoc()); + } + + /// \brief Returns the size of the type source info data block that is + /// specific to this type. + unsigned getLocalDataSize() const { + return sizeof(Info) + getNumProtocols() * sizeof(SourceLocation); + } + + /// \brief Returns the size of the type source info data block. + unsigned getFullDataSize() const { + return getLocalDataSize() + getBaseTypeLoc().getFullDataSize(); + } + + static bool classof(const TypeLoc *TL); + static bool classof(const ObjCProtocolListLoc *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 TypeLoc(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 TypeLoc(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 TypeLoc(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 TypeLoc(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 TypeLoc(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 TypeLoc(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; } +}; + +} + +#endif |