aboutsummaryrefslogtreecommitdiff
path: root/include/clang/AST/TypeLoc.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST/TypeLoc.h')
-rw-r--r--include/clang/AST/TypeLoc.h538
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