fix rdar://8147692 - yet another crash due to my abi work.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@107387 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index 2910442..c0c2a47 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -251,18 +251,27 @@
     // If this is being called from the guts of the ConvertType loop, make sure
     // to call ConvertTypeRecursive so we don't get into issues with cyclic
     // pointer type structures.
-    const llvm::Type *ArgType;
-    if (IsRecursive)
-      ArgType = ConvertTypeRecursive(*I);
-    else 
-      ArgType = ConvertType(*I);
-    PreferredArgTypes.push_back(ArgType);
+    PreferredArgTypes.push_back(ConvertTypeRecursive(*I));
   }
-
+  
   // Compute ABI information.
   getABIInfo().computeInfo(*FI, getContext(), TheModule.getContext(),
                            PreferredArgTypes.data(), PreferredArgTypes.size());
 
+  // If this is a top-level call and ConvertTypeRecursive hit unresolved pointer
+  // types, resolve them now.  These pointers may point to this function, which
+  // we *just* filled in the FunctionInfo for.
+  if (!IsRecursive && !PointersToResolve.empty()) {
+    // Use PATypeHolder's so that our preferred types don't dangle under
+    // refinement.
+    llvm::SmallVector<llvm::PATypeHolder, 8> Handles(PreferredArgTypes.begin(),
+                                                     PreferredArgTypes.end());
+    HandleLateResolvedPointers();
+    PreferredArgTypes.clear();
+    PreferredArgTypes.append(Handles.begin(), Handles.end());
+  }
+  
+  
   return *FI;
 }
 
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index 7876e5a..d469b90 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -42,14 +42,11 @@
     delete &*I++;
 }
 
-/// ConvertType - Convert the specified type to its LLVM form.
-const llvm::Type *CodeGenTypes::ConvertType(QualType T, bool IsRecursive) {
-  const llvm::Type *RawResult = ConvertTypeRecursive(T);
-  
-  if (IsRecursive || PointersToResolve.empty())
-    return RawResult;
-
-  llvm::PATypeHolder Result = RawResult;
+/// HandleLateResolvedPointers - For top-level ConvertType calls, this handles
+/// pointers that are referenced but have not been converted yet.  This is used
+/// to handle cyclic structures properly.
+void CodeGenTypes::HandleLateResolvedPointers() {
+  assert(!PointersToResolve.empty() && "No pointers to resolve!");
   
   // Any pointers that were converted deferred evaluation of their pointee type,
   // creating an opaque type instead.  This is in order to avoid problems with
@@ -64,7 +61,21 @@
     const llvm::Type *NT = ConvertTypeForMemRecursive(P.first);
     P.second->refineAbstractTypeTo(NT);
   }
+}
 
+
+/// ConvertType - Convert the specified type to its LLVM form.
+const llvm::Type *CodeGenTypes::ConvertType(QualType T, bool IsRecursive) {
+  const llvm::Type *Result = ConvertTypeRecursive(T);
+  
+  // If this is a top-level call to ConvertType and sub-conversions caused
+  // pointers to get lazily built as opaque types, resolve the pointers, which
+  // might cause Result to be merged away.
+  if (!IsRecursive && !PointersToResolve.empty()) {
+    llvm::PATypeHolder ResultHandle = Result;
+    HandleLateResolvedPointers();
+    Result = ResultHandle;
+  }
   return Result;
 }
 
diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h
index bf55fc5..c7f48e6 100644
--- a/lib/CodeGen/CodeGenTypes.h
+++ b/lib/CodeGen/CodeGenTypes.h
@@ -94,6 +94,12 @@
   /// is available only for ConvertType(). CovertType() is preferred
   /// interface to convert type T into a llvm::Type.
   const llvm::Type *ConvertNewType(QualType T);
+  
+  /// HandleLateResolvedPointers - For top-level ConvertType calls, this handles
+  /// pointers that are referenced but have not been converted yet.  This is
+  /// used to handle cyclic structures properly.
+  void HandleLateResolvedPointers();
+
 public:
   CodeGenTypes(ASTContext &Ctx, llvm::Module &M, const llvm::TargetData &TD,
                const ABIInfo &Info);