[ASTImporter] At import of records re-order indirect fields too.

Summary:
Correct order of fields and indirect fields in imported RecordDecl
is needed for correct work of record layout calculations.

Reviewers: martong, a.sidorin, shafik, a_sidorin

Reviewed By: martong, a_sidorin

Subscribers: rnkovacs, dkrupp, Szelethus, gamesh411, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D66866

llvm-svn: 370621
This commit is contained in:
Balazs Keri 2019-09-02 07:17:01 +00:00
parent 3ab210862a
commit 6e08669879
2 changed files with 35 additions and 7 deletions

View File

@ -1702,7 +1702,7 @@ ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
// Remove all declarations, which may be in wrong order in the
// lexical DeclContext and then add them in the proper order.
for (auto *D : FromRD->decls()) {
if (isa<FieldDecl>(D) || isa<FriendDecl>(D)) {
if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D) || isa<FriendDecl>(D)) {
assert(D && "DC contains a null decl");
Decl *ToD = Importer.GetAlreadyImportedOrNull(D);
// Remove only the decls which we successfully imported.

View File

@ -1421,12 +1421,15 @@ TEST_P(ASTImporterOptionSpecificTestBase,
AST_MATCHER_P(RecordDecl, hasFieldOrder, std::vector<StringRef>, Order) {
size_t Index = 0;
for (FieldDecl *Field : Node.fields()) {
if (Index == Order.size())
return false;
if (Field->getName() != Order[Index])
return false;
++Index;
for (Decl *D : Node.decls()) {
if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D)) {
auto *ND = cast<NamedDecl>(D);
if (Index == Order.size())
return false;
if (ND->getName() != Order[Index])
return false;
++Index;
}
}
return Index == Order.size();
}
@ -1493,6 +1496,31 @@ TEST_P(ASTImporterOptionSpecificTestBase,
Verifier.match(To, cxxRecordDecl(hasFieldOrder({"a", "b", "c"}))));
}
TEST_P(ASTImporterOptionSpecificTestBase,
CXXRecordDeclFieldAndIndirectFieldOrder) {
Decl *From, *To;
std::tie(From, To) = getImportedDecl(
// First field is "a", then the field for unnamed union, then "b" and "c"
// from it (indirect fields), then "d".
R"s(
struct declToImport {
int a = d;
union {
int b;
int c;
};
int d;
};
)s",
Lang_CXX11, "", Lang_CXX11);
MatchVerifier<Decl> Verifier;
ASSERT_TRUE(Verifier.match(
From, cxxRecordDecl(hasFieldOrder({"a", "", "b", "c", "d"}))));
EXPECT_TRUE(Verifier.match(
To, cxxRecordDecl(hasFieldOrder({"a", "", "b", "c", "d"}))));
}
TEST_P(ASTImporterOptionSpecificTestBase, ShouldImportImplicitCXXRecordDecl) {
Decl *From, *To;
std::tie(From, To) = getImportedDecl(