]> granicus.if.org Git - clang/commitdiff
implement rudimentary union layout support.
authorChris Lattner <sabre@nondot.org>
Sun, 26 Aug 2007 04:50:19 +0000 (04:50 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 26 Aug 2007 04:50:19 +0000 (04:50 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41421 91177308-0d34-0410-b5e6-96231b3b80d8

CodeGen/CodeGenTypes.cpp

index 3888538864c24f16943be028cfa5af692eaffdc4..9fb1568a03ec5c7086b9da360146c04f17df6aa2 100644 (file)
@@ -143,15 +143,38 @@ const llvm::Type *CodeGenTypes::ConvertType(QualType T) {
     
     if (!TD->isDefinition()) {
       ResultType = llvm::OpaqueType::get();    
+    } else if (TD->getKind() == Decl::Struct) {
+      const RecordDecl *RD = cast<const RecordDecl>(TD);
+      std::vector<const llvm::Type*> Fields;
+      for (unsigned i = 0, e = RD->getNumMembers(); i != e; ++i)
+        Fields.push_back(ConvertType(RD->getMember(i)->getType()));
+      ResultType = llvm::StructType::get(Fields);
+    } 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
+      // highest aligned member.
+      std::vector<const llvm::Type*> Fields;
+      if (RD->getNumMembers() != 0) {
+        std::pair<uint64_t, unsigned> MaxElt = 
+          Context.getTypeInfo(RD->getMember(0)->getType(), SourceLocation());
+        unsigned MaxEltNo = 0;
+        
+        for (unsigned i = 1, e = RD->getNumMembers(); i != e; ++i) {
+          std::pair<uint64_t, unsigned> 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;
+          }
+        }
+        
+        Fields.push_back(ConvertType(RD->getMember(MaxEltNo)->getType()));
+      }        
+      ResultType = llvm::StructType::get(Fields);
     } else {
-      if (TD->getKind() == Decl::Struct) {
-        const RecordDecl *RD = cast<const RecordDecl>(TD);
-        std::vector<const llvm::Type*> Fields;
-        for (unsigned i = 0, e = RD->getNumMembers(); i != e; ++i)
-          Fields.push_back(ConvertType(RD->getMember(i)->getType()));
-        ResultType = llvm::StructType::get(Fields);
-      } else 
-        assert(0 && "FIXME: Implement tag decl kind!");
+      assert(0 && "FIXME: Implement tag decl kind!");
     }
           
     std::string TypeName(TD->getKindName());