[cfe-commits] r43236 - in /cfe/trunk/CodeGen: CodeGenFunction.cpp CodeGenFunction.h CodeGenTypes.cpp CodeGenTypes.h

Devang Patel dpatel at apple.com
Mon Oct 22 19:10:50 PDT 2007


Author: dpatel
Date: Mon Oct 22 21:10:49 2007
New Revision: 43236

URL: http://llvm.org/viewvc/llvm-project?rev=43236&view=rev
Log:
Begin struct layout work.

Modified:
    cfe/trunk/CodeGen/CodeGenFunction.cpp
    cfe/trunk/CodeGen/CodeGenFunction.h
    cfe/trunk/CodeGen/CodeGenTypes.cpp
    cfe/trunk/CodeGen/CodeGenTypes.h

Modified: cfe/trunk/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CodeGenFunction.cpp?rev=43236&r1=43235&r2=43236&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/CodeGen/CodeGenFunction.cpp Mon Oct 22 21:10:49 2007
@@ -126,3 +126,14 @@
     BB->setName(N);
 }
 
+/// getRecordLayoutInfo - Return record layout info.
+RecordLayoutInfo *CodeGenFunction::getRecordLayoutInfo(CodeGenTypes &CGT,
+						       QualType RTy) {
+  assert (isa<RecordType>(RTy) 
+          && "Unexpected type. RecordType expected here.");
+
+  const llvm::Type *Ty = ConvertType(RTy);
+  assert (Ty && "Unable to find llvm::Type");
+  
+  return CGT.getRecordLayoutInfo(Ty);
+}

Modified: cfe/trunk/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CodeGenFunction.h?rev=43236&r1=43235&r2=43236&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/CodeGen/CodeGenFunction.h Mon Oct 22 21:10:49 2007
@@ -65,13 +65,15 @@
   class ChooseExpr;
   class PreDefinedExpr;
   class ObjCStringLiteral;
-  
+  class MemberExpr;
+
   class BlockVarDecl;
   class EnumConstantDecl;
   class ParmVarDecl;
 namespace CodeGen {
   class CodeGenModule;
-  
+  class CodeGenTypes;
+  class RecordLayoutInfo;  
 
 /// RValue - This trivial value class is used to represent the result of an
 /// expression that is evaluated.  It can be one of three things: either a
@@ -296,6 +298,8 @@
   /// then reuse it.
   void StartBlock(const char *N);
 
+  /// getRecordLayoutInfo - Return record layout info.
+  RecordLayoutInfo *getRecordLayoutInfo(CodeGenTypes &CGT, QualType RTy);
   //===--------------------------------------------------------------------===//
   //                            Declaration Emission
   //===--------------------------------------------------------------------===//
@@ -370,6 +374,7 @@
   LValue EmitUnaryOpLValue(const UnaryOperator *E);
   LValue EmitArraySubscriptExpr(const ArraySubscriptExpr *E);
   LValue EmitOCUVectorElementExpr(const OCUVectorElementExpr *E);
+  LValue EmitMemberExpr(const MemberExpr *E);
     
   //===--------------------------------------------------------------------===//
   //                         Scalar Expression Emission

Modified: cfe/trunk/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CodeGenTypes.cpp?rev=43236&r1=43235&r2=43236&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/trunk/CodeGen/CodeGenTypes.cpp Mon Oct 22 21:10:49 2007
@@ -24,6 +24,14 @@
   : Context(Ctx), Target(Ctx.Target), TheModule(M) {
 }
 
+CodeGenTypes::~CodeGenTypes() {
+  for(llvm::DenseMap<const llvm::Type *, RecordLayoutInfo *>::iterator
+	I = RecordLayouts.begin(), E = RecordLayouts.end();
+      I != E; ++I)
+    delete I->second;
+  RecordLayouts.clear();
+}
+
 /// ConvertType - Convert the specified type to its LLVM form.
 const llvm::Type *CodeGenTypes::ConvertType(QualType T) {
   // FIXME: Cache these, move the CodeGenModule, expand, etc.
@@ -159,10 +167,14 @@
       return ConvertType(cast<EnumDecl>(TD)->getIntegerType());
     } else if (TD->getKind() == Decl::Struct) {
       const RecordDecl *RD = cast<const RecordDecl>(TD);
-      std::vector<const llvm::Type*> Fields;
+      RecordOrganizer *RO = new RecordOrganizer();
       for (unsigned i = 0, e = RD->getNumMembers(); i != e; ++i)
-        Fields.push_back(ConvertType(RD->getMember(i)->getType()));
-      ResultType = llvm::StructType::get(Fields);
+	RO->addField(RD->getMember(i));
+      RO->layoutFields(*this);
+      RecordLayoutInfo *RLI = new RecordLayoutInfo(RO);
+      ResultType = RLI->getLLVMType();
+      RecordLayouts[ResultType] = RLI;
+      delete RO;
     } else if (TD->getKind() == Decl::Union) {
       const RecordDecl *RD = cast<const RecordDecl>(TD);
       // Just use the largest element of the union, breaking ties with the
@@ -214,3 +226,67 @@
   }
 }
 
+/// getLLVMFieldNo - Return llvm::StructType element number
+/// that corresponds to the field FD.
+unsigned CodeGenTypes::getLLVMFieldNo(const FieldDecl *FD) {
+  llvm::DenseMap<const FieldDecl *, unsigned>::iterator
+    I = FieldInfo.find(FD);
+  if (I != FieldInfo.end()  && "Unable to find field info");
+  return I->second;
+}
+
+  /// addFieldInfo - Assign field number to field FD.
+void CodeGenTypes::addFieldInfo(const FieldDecl *FD, unsigned No) {
+  FieldInfo[FD] = No;
+}
+
+/// getRecordLayoutInfo - Return record layout info for the given llvm::Type.
+RecordLayoutInfo *CodeGenTypes::getRecordLayoutInfo(const llvm::Type* Ty) {
+  llvm::DenseMap<const llvm::Type*, RecordLayoutInfo *>::iterator I
+    = RecordLayouts.find(Ty);
+  assert (I != RecordLayouts.end() 
+          && "Unable to find record layout information for type");
+  return I->second;
+}
+
+/// RecordLayoutInfo - Construct record layout info object using layout 
+/// organized by record organizer.
+RecordLayoutInfo::RecordLayoutInfo(RecordOrganizer *RO) {
+  STy = RO->getLLVMType();
+  assert (STy && "Record layout is incomplete to determine llvm::Type");
+  // FIXME : Collect info about fields that requires adjustments 
+  // (i.e. fields that do not directly map to llvm struct fields.)
+}
+
+
+/// addField - Add new field.
+void RecordOrganizer::addField(const FieldDecl *FD) {
+  assert (!STy && "Record fields are already laid out");
+  FieldDecls.push_back(FD);
+}
+
+/// layoutFields - Do the actual work and lay out all fields. Create
+/// corresponding llvm struct type.  This should be invoked only after
+/// all fields are added.
+/// FIXME : At the moment assume 
+///    - one to one mapping between AST FieldDecls and 
+///      llvm::StructType elements.
+///    - Ignore bit fields
+///    - Ignore field aligments
+///    - Ignore packed structs
+void RecordOrganizer::layoutFields(CodeGenTypes &CGT) {
+  // FIXME : Use SmallVector
+  std::vector<const llvm::Type*> Fields;
+  unsigned FieldNo = 0;
+  for (llvm::SmallVector<const FieldDecl *, 8>::iterator I = FieldDecls.begin(),
+	 E = FieldDecls.end(); I != E; ++I) {
+    const FieldDecl *FD = *I;
+    const llvm::Type *Ty = CGT.ConvertType(FD->getType());
+
+    // FIXME : Layout FieldDecl FD
+
+    Fields.push_back(Ty);
+    CGT.addFieldInfo(FD, FieldNo++);
+  }
+  STy = llvm::StructType::get(Fields);
+}

Modified: cfe/trunk/CodeGen/CodeGenTypes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CodeGenTypes.h?rev=43236&r1=43235&r2=43236&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CodeGenTypes.h (original)
+++ cfe/trunk/CodeGen/CodeGenTypes.h Mon Oct 22 21:10:49 2007
@@ -15,6 +15,7 @@
 #define CODEGEN_CODEGENTYPES_H
 
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
 #include <vector>
 
 namespace llvm {
@@ -28,8 +29,57 @@
   class TargetInfo;
   class QualType;
   class FunctionTypeProto;
-  
+ class FieldDecl;
+
 namespace CodeGen {
+  class CodeGenTypes;
+
+  /// RecordOrganizer - This helper class, used by RecordLayoutInfo, layouts 
+  /// structs and unions. It manages transient information used during layout.
+  /// FIXME : At the moment assume 
+  ///    - one to one mapping between AST FieldDecls and 
+  ///      llvm::StructType elements.
+  ///    - Ignore bit fields
+  ///    - Ignore field aligments
+  ///    - Ignore packed structs
+  class RecordOrganizer {
+  public:
+    RecordOrganizer() : STy(NULL) {}
+    
+    /// addField - Add new field.
+    void addField(const FieldDecl *FD);
+
+    /// layoutFields - Do the actual work and lay out all fields. Create
+    /// corresponding llvm struct type.  This should be invoked only after
+    /// all fields are added.
+    void layoutFields(CodeGenTypes &CGT);
+
+    /// getLLVMType - Return associated llvm struct type. This may be NULL
+    /// if fields are not laid out.
+    llvm::Type *getLLVMType() {
+      return STy;
+    }
+
+  private:
+    llvm::Type *STy;
+    llvm::SmallVector<const FieldDecl *, 8> FieldDecls;
+  };
+
+  /// RecordLayoutInfo - This class handles struct and union layout info while 
+  /// lowering AST types to LLVM types.
+  class RecordLayoutInfo {
+    RecordLayoutInfo(); // DO NOT IMPLEMENT
+  public:
+    RecordLayoutInfo(RecordOrganizer *RO);
+
+    /// getLLVMType - Return llvm type associated with this record.
+    llvm::Type *getLLVMType() {
+      return STy;
+    }
+
+  private:
+    llvm::Type *STy;
+  };
   
 /// CodeGenTypes - This class organizes the cross-module state that is used
 /// while lowering AST types to LLVM types.
@@ -39,14 +89,33 @@
   llvm::Module& TheModule;
   
   llvm::DenseMap<const TagDecl*, llvm::Type*> TagDeclTypes;
+
+  /// RecordLayouts - This maps llvm struct type with corresponding 
+  /// record layout info. 
+  llvm::DenseMap<const llvm::Type*, RecordLayoutInfo *> RecordLayouts;
+
+  /// FieldInfo - This maps struct field with corresponding llvm struct type
+  /// field no. This info is populated by record organizer.
+  llvm::DenseMap<const FieldDecl *, unsigned> FieldInfo;
+
 public:
   CodeGenTypes(ASTContext &Ctx, llvm::Module &M);
+  ~CodeGenTypes();
   
   TargetInfo &getTarget() const { return Target; }
   
   const llvm::Type *ConvertType(QualType T);
   void DecodeArgumentTypes(const FunctionTypeProto &FTP, 
                            std::vector<const llvm::Type*> &ArgTys);
+
+  RecordLayoutInfo *getRecordLayoutInfo(const llvm::Type*);
+  
+  /// getLLVMFieldNo - Return llvm::StructType element number
+  /// that corresponds to the field FD.
+  unsigned getLLVMFieldNo(const FieldDecl *FD);
+
+  /// addFieldInfo - Assign field number to field FD.
+  void addFieldInfo(const FieldDecl *FD, unsigned No);
 };
 
 }  // end namespace CodeGen





More information about the cfe-commits mailing list