[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