keep track of whether being in a RS_StructPointer state
caused us to skip layout out a function accurately.  If
so, flush the type cache for both the function and struct
case to ensure that any pointers to the functions get
recomputed.  This is overconservative, but with this patch
clang can build itself again.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134863 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index 59c632f..16946b6 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -32,6 +32,7 @@
   : Context(Ctx), Target(Ctx.Target), TheModule(M), TheTargetData(TD),
     TheABIInfo(Info), TheCXXABI(CXXABI), CodeGenOpts(CGO) {
   RecursionState = RS_Normal;
+  SkippedLayout = false;
 }
 
 CodeGenTypes::~CodeGenTypes() {
@@ -345,6 +346,8 @@
       // This function's type depends on an incomplete tag type.
       // Return a placeholder type.
       ResultType = llvm::StructType::get(getLLVMContext());
+      
+      SkippedLayout |= RecursionState == RS_StructPointer;
       break;
     }
 
@@ -373,6 +376,9 @@
     
     // Restore our recursion state.
     RecursionState = SavedRecursionState;
+
+    if (SkippedLayout)
+      TypeCache.clear();
     
     if (RecursionState == RS_Normal)
       while (!DeferredRecords.empty())
@@ -487,7 +493,8 @@
   // If this struct blocked a FunctionType conversion, then recompute whatever
   // was derived from that.
   // FIXME: This is hugely overconservative.
-  TypeCache.clear();
+  if (SkippedLayout)
+    TypeCache.clear();
   
   
   // Restore our recursion state.  If we're done converting the outer-most
diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h
index 9878600..4229c59 100644
--- a/lib/CodeGen/CodeGenTypes.h
+++ b/lib/CodeGen/CodeGenTypes.h
@@ -86,7 +86,11 @@
     RS_Struct,        // Recursively inside a struct conversion.
     RS_StructPointer  // Recursively inside a pointer in a struct.
   } RecursionState;
-  
+
+  /// SkippedLayout - True if we didn't layout a function bit due to a
+  /// RS_StructPointer RecursionState.
+  bool SkippedLayout;
+
   llvm::SmallVector<const RecordDecl *, 8> DeferredRecords;
   
   struct RecursionStatePointerRAII {