From 134b3f4b55837ae048703d3894c3109d778fa4a5 Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Mon, 29 Oct 2007 20:50:19 +0000 Subject: [PATCH] Add RecordOrganizer::layoutUnionFields() llvm-svn: 43472 --- clang/CodeGen/CodeGenTypes.cpp | 72 ++++++++++++++++++++++------------ clang/CodeGen/CodeGenTypes.h | 1 + 2 files changed, 49 insertions(+), 24 deletions(-) diff --git a/clang/CodeGen/CodeGenTypes.cpp b/clang/CodeGen/CodeGenTypes.cpp index 8b873286689a..06d960927b55 100644 --- a/clang/CodeGen/CodeGenTypes.cpp +++ b/clang/CodeGen/CodeGenTypes.cpp @@ -36,10 +36,15 @@ namespace { /// addField - Add new field. void addField(const FieldDecl *FD); - /// layoutFields - Do the actual work and lay out all fields. Create + /// layoutStructFields - 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); + void layoutStructFields(CodeGenTypes &CGT); + + /// layoutUnionFields - 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 layoutUnionFields(CodeGenTypes &CGT); /// getLLVMType - Return associated llvm struct type. This may be NULL /// if fields are not laid out. @@ -239,7 +244,7 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) { RecordOrganizer RO; for (unsigned i = 0, e = RD->getNumMembers(); i != e; ++i) RO.addField(RD->getMember(i)); - RO.layoutFields(*this); + RO.layoutStructFields(*this); // Get llvm::StructType. RecordLayoutInfo *RLI = new RecordLayoutInfo(RO.getLLVMType()); @@ -260,31 +265,16 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) { // highest aligned member. if (RD->getNumMembers() != 0) { - std::pair MaxElt = - Context.getTypeInfo(RD->getMember(0)->getType(), SourceLocation()); - unsigned MaxEltNo = 0; - addFieldInfo(RD->getMember(0), 0); // Each field gets first slot. - // FIXME : Move union field handling in RecordOrganize - for (unsigned i = 1, e = RD->getNumMembers(); i != e; ++i) { - addFieldInfo(RD->getMember(i), 0); // Each field gets first slot. - std::pair EltInfo = - Context.getTypeInfo(RD->getMember(i)->getType(), SourceLocation()); - if (EltInfo.first > MaxElt.first || - (EltInfo.first == MaxElt.first && - EltInfo.second > MaxElt.second)) { - MaxElt = EltInfo; - MaxEltNo = i; - } - } - RecordOrganizer RO; - RO.addField(RD->getMember(MaxEltNo)); - RO.layoutFields(*this); + for (unsigned i = 0, e = RD->getNumMembers(); i != e; ++i) + RO.addField(RD->getMember(i)); + RO.layoutUnionFields(*this); // Get llvm::StructType. RecordLayoutInfo *RLI = new RecordLayoutInfo(RO.getLLVMType()); ResultType = RLI->getLLVMType(); RecordLayouts[ResultType] = RLI; + RO.clear(); } else { std::vector Fields; ResultType = llvm::StructType::get(Fields); @@ -350,7 +340,7 @@ void RecordOrganizer::addField(const FieldDecl *FD) { FieldDecls.push_back(FD); } -/// layoutFields - Do the actual work and lay out all fields. Create +/// layoutStructFields - 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 @@ -359,7 +349,7 @@ void RecordOrganizer::addField(const FieldDecl *FD) { /// - Ignore bit fields /// - Ignore field aligments /// - Ignore packed structs -void RecordOrganizer::layoutFields(CodeGenTypes &CGT) { +void RecordOrganizer::layoutStructFields(CodeGenTypes &CGT) { // FIXME : Use SmallVector std::vector Fields; unsigned FieldNo = 0; @@ -376,6 +366,40 @@ void RecordOrganizer::layoutFields(CodeGenTypes &CGT) { STy = llvm::StructType::get(Fields); } +/// layoutUnionFields - 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 RecordOrganizer::layoutUnionFields(CodeGenTypes &CGT) { + + unsigned PrimaryEltNo = 0; + std::pair PrimaryElt = + CGT.getContext().getTypeInfo(FieldDecls[0]->getType(), SourceLocation()); + CGT.addFieldInfo(FieldDecls[0], 0); + + unsigned Size = FieldDecls.size(); + for(unsigned i = 1; i != Size; ++i) { + const FieldDecl *FD = FieldDecls[i]; + std::pair EltInfo = + CGT.getContext().getTypeInfo(FD->getType(), SourceLocation()); + + // Use largest element, breaking ties with the hightest aligned member. + if (EltInfo.first > PrimaryElt.first || + (EltInfo.first == PrimaryElt.first && + EltInfo.second > PrimaryElt.second)) { + PrimaryElt = EltInfo; + PrimaryEltNo = i; + } + + // In union, each field gets first slot. + CGT.addFieldInfo(FD, 0); + } + + std::vector Fields; + const llvm::Type *Ty = CGT.ConvertType(FieldDecls[PrimaryEltNo]->getType()); + Fields.push_back(Ty); + STy = llvm::StructType::get(Fields); +} + /// Clear private data so that this object can be reused. void RecordOrganizer::clear() { STy = NULL; diff --git a/clang/CodeGen/CodeGenTypes.h b/clang/CodeGen/CodeGenTypes.h index 91f6a1b24e65..a6e13c4ebf66 100644 --- a/clang/CodeGen/CodeGenTypes.h +++ b/clang/CodeGen/CodeGenTypes.h @@ -95,6 +95,7 @@ public: ~CodeGenTypes(); TargetInfo &getTarget() const { return Target; } + ASTContext &getContext() const { return Context; } /// ConvertType - Convert type T into a llvm::Type. Maintain and use /// type cache through TypeHOlderMap.