aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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
-rw-r--r--lib/AST/ASTContext.cpp17
-rw-r--r--lib/AST/Decl.cpp5
-rw-r--r--lib/AST/TypeLoc.cpp328
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);
+}