balazske created this revision. Herald added subscribers: cfe-commits, martong. Herald added a reviewer: a.sidorin.
At equality check of fields without name the index of fields is compared. At determining the index of a field all fields of the parent context should be loaded from external source to find the field at all. Repository: rC Clang https://reviews.llvm.org/D49796 Files: lib/AST/ASTImporter.cpp test/ASTMerge/unnamed_fields/Inputs/il.cpp test/ASTMerge/unnamed_fields/test.cpp unittests/AST/ASTImporterTest.cpp Index: unittests/AST/ASTImporterTest.cpp =================================================================== --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -2612,6 +2612,45 @@ R1, recordDecl(has(fieldDecl(hasName("next")))))); } +TEST_P(ASTImporterTestBase, ImportUnnamedFieldsInCorrectOrder) { + Decl *FromTU = getTuDecl( + R"( + void f(int X, int Y, bool Z) { + (void)[X, Y, Z] { (void)Z; }; + } + )", + Lang_CXX11, "input0.cc"); + auto *FromF = FirstDeclMatcher<FunctionDecl>().match( + FromTU, functionDecl(hasName("f"))); + auto *ToF = cast_or_null<FunctionDecl>(Import(FromF, Lang_CXX11)); + EXPECT_TRUE(ToF); + + CXXRecordDecl *FromLambda = + cast<LambdaExpr>(cast<CStyleCastExpr>(cast<CompoundStmt>( + FromF->getBody())->body_front())->getSubExpr())->getLambdaClass(); + + auto *ToLambda = cast_or_null<CXXRecordDecl>(Import(FromLambda, Lang_CXX11)); + EXPECT_TRUE(ToLambda); + + // Check if the fields of the lambda class are imported in correct order. + unsigned FromIndex = 0u; + for (auto *FromField : FromLambda->fields()) { + ASSERT_FALSE(FromField->getDeclName()); + auto *ToField = cast_or_null<FieldDecl>(Import(FromField, Lang_CXX11)); + EXPECT_TRUE(ToField); + unsigned ToIndex = 0u; + for (auto *F : ToLambda->fields()) { + if (F == ToField) + break; + ++ToIndex; + } + EXPECT_EQ(ToIndex, FromIndex); + ++FromIndex; + } + + EXPECT_EQ(FromIndex, 3u); +} + struct DeclContextTest : ASTImporterTestBase {}; TEST_P(DeclContextTest, removeDeclOfClassTemplateSpecialization) { Index: test/ASTMerge/unnamed_fields/test.cpp =================================================================== --- /dev/null +++ test/ASTMerge/unnamed_fields/test.cpp @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/il.cpp +// RUN: %clang_cc1 -ast-merge %t.1.ast -fsyntax-only %s 2>&1 | FileCheck --allow-empty %s +// CHECK-NOT: warning: field '' declared with incompatible types in different translation units ('bool' vs. 'int') Index: test/ASTMerge/unnamed_fields/Inputs/il.cpp =================================================================== --- /dev/null +++ test/ASTMerge/unnamed_fields/Inputs/il.cpp @@ -0,0 +1,3 @@ +void f(int X, int Y, bool Z) { + auto x = [X, Y, Z] { (void)Z; }; +} Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -2829,15 +2829,17 @@ return 0; unsigned Index = 1; - for (const auto *D : Owner->noload_decls()) { + for (const auto *D : Owner->decls()) { if (D == F) return Index; if (isa<FieldDecl>(*D) || isa<IndirectFieldDecl>(*D)) ++Index; } - return Index; + assert(false && "Field was not found in its parent context."); + + return 0; } Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
Index: unittests/AST/ASTImporterTest.cpp =================================================================== --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -2612,6 +2612,45 @@ R1, recordDecl(has(fieldDecl(hasName("next")))))); } +TEST_P(ASTImporterTestBase, ImportUnnamedFieldsInCorrectOrder) { + Decl *FromTU = getTuDecl( + R"( + void f(int X, int Y, bool Z) { + (void)[X, Y, Z] { (void)Z; }; + } + )", + Lang_CXX11, "input0.cc"); + auto *FromF = FirstDeclMatcher<FunctionDecl>().match( + FromTU, functionDecl(hasName("f"))); + auto *ToF = cast_or_null<FunctionDecl>(Import(FromF, Lang_CXX11)); + EXPECT_TRUE(ToF); + + CXXRecordDecl *FromLambda = + cast<LambdaExpr>(cast<CStyleCastExpr>(cast<CompoundStmt>( + FromF->getBody())->body_front())->getSubExpr())->getLambdaClass(); + + auto *ToLambda = cast_or_null<CXXRecordDecl>(Import(FromLambda, Lang_CXX11)); + EXPECT_TRUE(ToLambda); + + // Check if the fields of the lambda class are imported in correct order. + unsigned FromIndex = 0u; + for (auto *FromField : FromLambda->fields()) { + ASSERT_FALSE(FromField->getDeclName()); + auto *ToField = cast_or_null<FieldDecl>(Import(FromField, Lang_CXX11)); + EXPECT_TRUE(ToField); + unsigned ToIndex = 0u; + for (auto *F : ToLambda->fields()) { + if (F == ToField) + break; + ++ToIndex; + } + EXPECT_EQ(ToIndex, FromIndex); + ++FromIndex; + } + + EXPECT_EQ(FromIndex, 3u); +} + struct DeclContextTest : ASTImporterTestBase {}; TEST_P(DeclContextTest, removeDeclOfClassTemplateSpecialization) { Index: test/ASTMerge/unnamed_fields/test.cpp =================================================================== --- /dev/null +++ test/ASTMerge/unnamed_fields/test.cpp @@ -0,0 +1,3 @@ +// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/il.cpp +// RUN: %clang_cc1 -ast-merge %t.1.ast -fsyntax-only %s 2>&1 | FileCheck --allow-empty %s +// CHECK-NOT: warning: field '' declared with incompatible types in different translation units ('bool' vs. 'int') Index: test/ASTMerge/unnamed_fields/Inputs/il.cpp =================================================================== --- /dev/null +++ test/ASTMerge/unnamed_fields/Inputs/il.cpp @@ -0,0 +1,3 @@ +void f(int X, int Y, bool Z) { + auto x = [X, Y, Z] { (void)Z; }; +} Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -2829,15 +2829,17 @@ return 0; unsigned Index = 1; - for (const auto *D : Owner->noload_decls()) { + for (const auto *D : Owner->decls()) { if (D == F) return Index; if (isa<FieldDecl>(*D) || isa<IndirectFieldDecl>(*D)) ++Index; } - return Index; + assert(false && "Field was not found in its parent context."); + + return 0; } Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits