[cfe-commits] r49144 - in /cfe/trunk: lib/CodeGen/CodeGenTypes.cpp lib/CodeGen/CodeGenTypes.h test/CodeGen/types.c

Chris Lattner sabre at nondot.org
Wed Apr 2 22:50:42 PDT 2008


Author: lattner
Date: Thu Apr  3 00:50:42 2008
New Revision: 49144

URL: http://llvm.org/viewvc/llvm-project?rev=49144&view=rev
Log:
Fix PR2081 (problems codegen'ing some recursive structures) patch
by Lauro Venancio!

Modified:
    cfe/trunk/lib/CodeGen/CodeGenTypes.cpp
    cfe/trunk/lib/CodeGen/CodeGenTypes.h
    cfe/trunk/test/CodeGen/types.c

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTypes.cpp Thu Apr  3 00:50:42 2008
@@ -92,6 +92,27 @@
 
 /// ConvertType - Convert the specified type to its LLVM form.
 const llvm::Type *CodeGenTypes::ConvertType(QualType T) {
+  llvm::PATypeHolder Result = ConvertTypeRecursive(T);
+
+  // Any pointers that were converted defered evaluation of their pointee type,
+  // creating an opaque type instead.  This is in order to avoid problems with
+  // circular types.  Loop through all these defered pointees, if any, and
+  // resolve them now.
+  while (!PointersToResolve.empty()) {
+    std::pair<const PointerLikeType *, llvm::OpaqueType*> P =
+      PointersToResolve.back();
+    PointersToResolve.pop_back();
+    // We can handle bare pointers here because we know that the only pointers
+    // to the Opaque type are P.second and from other types.  Refining the
+    // opqaue type away will invalidate P.second, but we don't mind :).
+    const llvm::Type *NT = ConvertTypeRecursive(P.first->getPointeeType());
+    P.second->refineAbstractTypeTo(NT);
+  }
+
+  return Result;
+}
+
+const llvm::Type *CodeGenTypes::ConvertTypeRecursive(QualType T) {
   // See if type is already cached.
   llvm::DenseMap<Type *, llvm::PATypeHolder>::iterator
     I = TypeCache.find(T.getCanonicalType().getTypePtr());
@@ -203,13 +224,16 @@
   }
   case Type::Complex: {
     const llvm::Type *EltTy = 
-      ConvertType(cast<ComplexType>(Ty).getElementType());
+      ConvertTypeRecursive(cast<ComplexType>(Ty).getElementType());
     return llvm::StructType::get(EltTy, EltTy, NULL);
   }
   case Type::Reference:
   case Type::Pointer: {
-    QualType ETy = cast<PointerLikeType>(Ty).getPointeeType();
-    return llvm::PointerType::get(ConvertType(ETy), ETy.getAddressSpace()); 
+    const PointerLikeType &PTy = cast<PointerLikeType>(Ty);
+    QualType ETy = PTy.getPointeeType();
+    llvm::OpaqueType *PointeeType = llvm::OpaqueType::get();
+    PointersToResolve.push_back(std::make_pair(&PTy, PointeeType));
+    return llvm::PointerType::get(PointeeType, ETy.getAddressSpace());
   }
     
   case Type::VariableArray: {
@@ -218,24 +242,24 @@
            "FIXME: We only handle trivial array types so far!");
     // VLAs resolve to the innermost element type; this matches
     // the return of alloca, and there isn't any obviously better choice.
-    return ConvertType(A.getElementType());
+    return ConvertTypeRecursive(A.getElementType());
   }
   case Type::IncompleteArray: {
     const IncompleteArrayType &A = cast<IncompleteArrayType>(Ty);
     assert(A.getIndexTypeQualifier() == 0 &&
            "FIXME: We only handle trivial array types so far!");
     // int X[] -> [0 x int]
-    return llvm::ArrayType::get(ConvertType(A.getElementType()), 0);
+    return llvm::ArrayType::get(ConvertTypeRecursive(A.getElementType()), 0);
   }
   case Type::ConstantArray: {
     const ConstantArrayType &A = cast<ConstantArrayType>(Ty);
-    const llvm::Type *EltTy = ConvertType(A.getElementType());
+    const llvm::Type *EltTy = ConvertTypeRecursive(A.getElementType());
     return llvm::ArrayType::get(EltTy, A.getSize().getZExtValue());
   }
   case Type::OCUVector:
   case Type::Vector: {
     const VectorType &VT = cast<VectorType>(Ty);
-    return llvm::VectorType::get(ConvertType(VT.getElementType()),
+    return llvm::VectorType::get(ConvertTypeRecursive(VT.getElementType()),
                                  VT.getNumElements());
   }
   case Type::FunctionNoProto:
@@ -246,7 +270,7 @@
     if (FP.getResultType()->isVoidType())
       ResultType = llvm::Type::VoidTy;    // Result of function uses llvm void.
     else
-      ResultType = ConvertType(FP.getResultType());
+      ResultType = ConvertTypeRecursive(FP.getResultType());
     
     // FIXME: Convert argument types.
     bool isVarArg;
@@ -270,7 +294,8 @@
   }
   
   case Type::ASQual:
-    return ConvertType(QualType(cast<ASQualType>(Ty).getBaseType(), 0));
+    return
+      ConvertTypeRecursive(QualType(cast<ASQualType>(Ty).getBaseType(), 0));
 
   case Type::ObjCInterface: {
     // Warning: Use of this is strongly discouraged.  Late binding of instance
@@ -324,7 +349,7 @@
 void CodeGenTypes::DecodeArgumentTypes(const FunctionTypeProto &FTP, 
                                        std::vector<const llvm::Type*> &ArgTys) {
   for (unsigned i = 0, e = FTP.getNumArgs(); i != e; ++i) {
-    const llvm::Type *Ty = ConvertType(FTP.getArgType(i));
+    const llvm::Type *Ty = ConvertTypeRecursive(FTP.getArgType(i));
     if (Ty->isFirstClassType())
       ArgTys.push_back(Ty);
     else
@@ -355,7 +380,7 @@
   
   if (TD->getKind() == Decl::Enum) {
     // Don't bother storing enums in TagDeclTypes.
-    return ConvertType(cast<EnumDecl>(TD)->getIntegerType());
+    return ConvertTypeRecursive(cast<EnumDecl>(TD)->getIntegerType());
   }
   
   // This decl could well be recursive.  In this case, insert an opaque
@@ -484,7 +509,7 @@
     if (FD->isBitField()) 
       placeBitField(FD);
     else {
-      const llvm::Type *Ty = CGT.ConvertType(FD->getType());
+      const llvm::Type *Ty = CGT.ConvertTypeRecursive(FD->getType());
       addLLVMField(Ty);
       CGT.addFieldInfo(FD, llvmFieldNo - 1);
       Cursor = llvmSize;
@@ -562,7 +587,8 @@
   }
 
   std::vector<const llvm::Type*> Fields;
-  const llvm::Type *Ty = CGT.ConvertType(FieldDecls[PrimaryEltNo]->getType());
+  const llvm::Type *Ty =
+    CGT.ConvertTypeRecursive(FieldDecls[PrimaryEltNo]->getType());
   Fields.push_back(Ty);
   STy = llvm::StructType::get(Fields);
 }
@@ -580,7 +606,7 @@
   assert (isBitField  && "Invalid BitField size expression");
   uint64_t BitFieldSize =  FieldSize.getZExtValue();
 
-  const llvm::Type *Ty = CGT.ConvertType(FD->getType());
+  const llvm::Type *Ty = CGT.ConvertTypeRecursive(FD->getType());
   uint64_t TySize = CGT.getTargetData().getABITypeSizeInBits(Ty);
 
   unsigned Idx = Cursor / TySize;

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTypes.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTypes.h Thu Apr  3 00:50:42 2008
@@ -21,6 +21,7 @@
 namespace llvm {
   class Module;
   class Type;
+  class OpaqueType;
   class PATypeHolder;
   class TargetData;
 }
@@ -30,6 +31,8 @@
   class TagDecl;
   class TargetInfo;
   class QualType;
+  class PointerType;
+  class PointerLikeType;
   class Type;
   class FunctionTypeProto;
   class FieldDecl;
@@ -77,6 +80,10 @@
   llvm::Module& TheModule;
   const llvm::TargetData& TheTargetData;
   
+
+  llvm::SmallVector<std::pair<const PointerLikeType *,
+                              llvm::OpaqueType *>, 8>  PointersToResolve;
+
   llvm::DenseMap<const TagDecl*, llvm::PATypeHolder> TagDeclTypes;
 
   /// CGRecordLayouts - This maps llvm struct type with corresponding 
@@ -124,6 +131,7 @@
 
   /// ConvertType - Convert type T into a llvm::Type.  
   const llvm::Type *ConvertType(QualType T);
+  const llvm::Type *ConvertTypeRecursive(QualType T);
   
   /// ConvertTypeForMem - Convert type T into a llvm::Type.  This differs from
   /// ConvertType in that it is used to convert to the memory representation for

Modified: cfe/trunk/test/CodeGen/types.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/types.c?rev=49144&r1=49143&r2=49144&view=diff

==============================================================================
--- cfe/trunk/test/CodeGen/types.c (original)
+++ cfe/trunk/test/CodeGen/types.c Thu Apr  3 00:50:42 2008
@@ -19,3 +19,16 @@
 typedef struct MpegEncContext {int pb;} MpegEncContext;
 static void test2(void) {MpegEncContext s; s.pb;}
 
+
+struct Village;
+
+struct List {
+  struct Village *v;
+};
+
+struct Village {
+  struct List returned;
+};
+
+void test3(struct List a) {
+}





More information about the cfe-commits mailing list