aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/CodeGenTypes.cpp9
-rw-r--r--lib/CodeGen/CodeGenTypes.h6
-rw-r--r--test/CodeGenCXX/anonymous-union-member-initializer.cpp2
-rw-r--r--test/CodeGenObjC/arc-foreach.m4
-rw-r--r--test/CodeGenObjC/arc.m8
5 files changed, 20 insertions, 9 deletions
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index 59c632f0d7..16946b64b3 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -32,6 +32,7 @@ CodeGenTypes::CodeGenTypes(ASTContext &Ctx, llvm::Module& M,
: 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 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
// 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 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
// Restore our recursion state.
RecursionState = SavedRecursionState;
+
+ if (SkippedLayout)
+ TypeCache.clear();
if (RecursionState == RS_Normal)
while (!DeferredRecords.empty())
@@ -487,7 +493,8 @@ llvm::StructType *CodeGenTypes::ConvertRecordDeclType(const RecordDecl *RD) {
// 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 98786007d7..4229c59b83 100644
--- a/lib/CodeGen/CodeGenTypes.h
+++ b/lib/CodeGen/CodeGenTypes.h
@@ -86,7 +86,11 @@ class CodeGenTypes {
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 {
diff --git a/test/CodeGenCXX/anonymous-union-member-initializer.cpp b/test/CodeGenCXX/anonymous-union-member-initializer.cpp
index 1d514fb09e..f626a01d53 100644
--- a/test/CodeGenCXX/anonymous-union-member-initializer.cpp
+++ b/test/CodeGenCXX/anonymous-union-member-initializer.cpp
@@ -86,7 +86,7 @@ namespace test3 {
// CHECK-NEXT: [[UNION:%.*]] = getelementptr inbounds {{.*}} [[THIS]], i32 0, i32 0
// CHECK-NEXT: [[STRUCT:%.*]] = bitcast {{.*}}* [[UNION]] to
// CHECK-NEXT: [[CALLBACK:%.*]] = getelementptr inbounds {{.*}} [[STRUCT]], i32 0, i32 0
- // CHECK-NEXT: store {{.*}}* null, {{.*}}** [[CALLBACK]]
+ // CHECK: store {{.*}}* null, {{.*}}** [[CALLBACK]]
// CHECK-NEXT: [[UNION:%.*]] = getelementptr inbounds {{.*}} [[THIS]], i32 0, i32 0
// CHECK-NEXT: [[STRUCT:%.*]] = bitcast {{.*}}* [[UNION]] to
// CHECK-NEXT: [[CVALUE:%.*]] = getelementptr inbounds {{.*}} [[STRUCT]], i32 0, i32 1
diff --git a/test/CodeGenObjC/arc-foreach.m b/test/CodeGenObjC/arc-foreach.m
index ccf655b137..f9d7782fbe 100644
--- a/test/CodeGenObjC/arc-foreach.m
+++ b/test/CodeGenObjC/arc-foreach.m
@@ -34,7 +34,7 @@ void test0(NSArray *array) {
// CHECK-LP64-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]])
// CHECK-LP64-NEXT: store i8* [[T2]], i8** [[T0]]
// CHECK-LP64-NEXT: [[T1:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]]
-// CHECK-LP64-NEXT: call void @use_block({{.*}}* [[T1]])
+// CHECK-LP64: call void @use_block(
// CHECK-LP64-NEXT: [[T1:%.*]] = load i8** [[T0]]
// CHECK-LP64-NEXT: call void @objc_release(i8* [[T1]])
@@ -67,6 +67,6 @@ void test1(NSArray *array) {
// CHECK-LP64-NEXT: [[T1:%.*]] = call i8* @objc_loadWeak(i8** [[X]])
// CHECK-LP64-NEXT: call i8* @objc_initWeak(i8** [[T0]], i8* [[T1]])
// CHECK-LP64-NEXT: [[T1:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to
-// CHECK-LP64-NEXT: call void @use_block({{.*}} [[T1]])
+// CHECK-LP64: call void @use_block
// CHECK-LP64-NEXT: call void @objc_destroyWeak(i8** [[T0]])
// CHECK-LP64-NEXT: call void @objc_destroyWeak(i8** [[X]])
diff --git a/test/CodeGenObjC/arc.m b/test/CodeGenObjC/arc.m
index dbfd9d335c..6beac19632 100644
--- a/test/CodeGenObjC/arc.m
+++ b/test/CodeGenObjC/arc.m
@@ -1216,7 +1216,7 @@ void test39(void) {
// CHECK: define void @test39()
// CHECK: [[VAR:%.*]] = alloca i8*
// CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
- // CHECK-NEXT: [[T0:%.*]] = call i8* @test39_source()
+ // CHECK: [[T0:%.*]] = call i8* @test39_source()
// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* [[T0]])
// CHECK-NEXT: store i8* [[T1]], i8** [[VAR]],
// CHECK-NEXT: call void @objc_release(i8* [[T1]])
@@ -1226,7 +1226,7 @@ void test39(void) {
// CHECK-NEXT: [[T0:%.*]] = load i8** [[VAR]]
// CHECK-NEXT: store i8* [[T0]], i8** [[CAPTURE]]
// CHECK-NEXT: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to
- // CHECK-NEXT: call void @test39_helper({{.*}} [[T0]])
+ // CHECK: call void @test39_helper
// CHECK-NEXT: ret void
}
@@ -1330,7 +1330,7 @@ void test41(void) {
// CHECK: [[SELF:%.*]] = alloca [[TEST42:%.*]]*,
// CHECK-NEXT: alloca i8*
// CHECK-NEXT: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]],
-// CHECK-NEXT: store
+// CHECK: store
// CHECK-NEXT: store
// CHECK: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
// CHECK-NEXT: [[T1:%.*]] = load [[TEST42]]** [[SELF]],
@@ -1339,7 +1339,7 @@ void test41(void) {
// CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to [[TEST42]]*
// CHECK-NEXT: store [[TEST42]]* [[T4]], [[TEST42]]** [[T0]]
// CHECK-NEXT: bitcast [[BLOCK_T]]* [[BLOCK]] to
-// CHECK-NEXT: call void @test42_helper(
+// CHECK: call void @test42_helper(
// CHECK-NEXT: [[T1:%.*]] = load [[TEST42]]** [[T0]]
// CHECK-NEXT: [[T2:%.*]] = bitcast [[TEST42]]* [[T1]] to i8*
// CHECK-NEXT: call void @objc_release(i8* [[T2]])