[cfe-commits] r79391 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/AST/Decl.h include/clang/AST/TypeLoc.h include/clang/AST/TypeLocNodes.def lib/AST/ASTContext.cpp lib/AST/Decl.cpp lib/AST/TypeLoc.cpp

Argiris Kirtzidis akyrtzi at gmail.com
Tue Aug 18 18:27:32 PDT 2009


Author: akirtzidis
Date: Tue Aug 18 20:27:32 2009
New Revision: 79391

URL: http://llvm.org/viewvc/llvm-project?rev=79391&view=rev
Log:
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.

Added:
    cfe/trunk/include/clang/AST/TypeLoc.h
    cfe/trunk/include/clang/AST/TypeLocNodes.def
    cfe/trunk/lib/AST/TypeLoc.cpp
Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/Decl.cpp

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=79391&r1=79390&r2=79391&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Tue Aug 18 20:27:32 2009
@@ -918,6 +918,16 @@
   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

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=79391&r1=79390&r2=79391&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Tue Aug 18 20:27:32 2009
@@ -28,7 +28,28 @@
 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;

Added: cfe/trunk/include/clang/AST/TypeLoc.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=79391&view=auto

==============================================================================
--- cfe/trunk/include/clang/AST/TypeLoc.h (added)
+++ cfe/trunk/include/clang/AST/TypeLoc.h Tue Aug 18 20:27:32 2009
@@ -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

Added: cfe/trunk/include/clang/AST/TypeLocNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLocNodes.def?rev=79391&view=auto

==============================================================================
--- cfe/trunk/include/clang/AST/TypeLocNodes.def (added)
+++ cfe/trunk/include/clang/AST/TypeLocNodes.def Tue Aug 18 20:27:32 2009
@@ -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

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=79391&r1=79390&r2=79391&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Tue Aug 18 20:27:32 2009
@@ -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 @@
   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.
 ///

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=79391&r1=79390&r2=79391&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Tue Aug 18 20:27:32 2009
@@ -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 @@
   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

Added: cfe/trunk/lib/AST/TypeLoc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypeLoc.cpp?rev=79391&view=auto

==============================================================================
--- cfe/trunk/lib/AST/TypeLoc.cpp (added)
+++ cfe/trunk/lib/AST/TypeLoc.cpp Tue Aug 18 20:27:32 2009
@@ -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);  
+}





More information about the cfe-commits mailing list