summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2009-08-19 01:27:32 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2009-08-19 01:27:32 +0000
commitb17166c8077cd900cca83a895c43b30ea6660598 (patch)
tree90b8da7dcff7f09dbdf395d1aea436bfeb9799b9 /include
parent7d878eb7f340a6995bd3414ba6cbdfcfdb1e8a76 (diff)
Introduce DeclaratorInfo and TypeLoc, intended to be used for storing and reading source information for types.
DeclaratorInfo will contain a flat memory block for source information about a type that came out of a declarator. TypeLoc and its subclasses will be used by clients as wrappers to "traverse" the memory block and read the information. Both DeclaratorInfo and TypeLoc are not utilized in this commit. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@79391 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/clang/AST/ASTContext.h10
-rw-r--r--include/clang/AST/Decl.h23
-rw-r--r--include/clang/AST/TypeLoc.h470
-rw-r--r--include/clang/AST/TypeLocNodes.def53
4 files changed, 555 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