diff options
-rw-r--r-- | lib/CodeGen/CodeGenTypes.cpp | 9 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenTypes.h | 6 | ||||
-rw-r--r-- | test/CodeGenCXX/anonymous-union-member-initializer.cpp | 2 | ||||
-rw-r--r-- | test/CodeGenObjC/arc-foreach.m | 4 | ||||
-rw-r--r-- | test/CodeGenObjC/arc.m | 8 |
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]]) |