diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -3902,7 +3902,6 @@ auto ToTInfo = importChecked(Err, D->getTypeSourceInfo()); auto ToBitWidth = importChecked(Err, D->getBitWidth()); auto ToInnerLocStart = importChecked(Err, D->getInnerLocStart()); - auto ToInitializer = importChecked(Err, D->getInClassInitializer()); if (Err) return std::move(Err); const Type *ToCapturedVLAType = nullptr; @@ -3925,12 +3924,17 @@ return std::move(Err); ToField->setAccess(D->getAccess()); ToField->setLexicalDeclContext(LexicalDC); - if (ToInitializer) - ToField->setInClassInitializer(ToInitializer); ToField->setImplicit(D->isImplicit()); if (ToCapturedVLAType) ToField->setCapturedVLAType(cast(ToCapturedVLAType)); LexicalDC->addDeclInternal(ToField); + // Import initializer only after the field was created, it may have recursive + // reference to the field. + auto ToInitializer = importChecked(Err, D->getInClassInitializer()); + if (Err) + return std::move(Err); + if (ToInitializer) + ToField->setInClassInitializer(ToInitializer); return ToField; } diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -8107,6 +8107,23 @@ EXPECT_TRUE(ToX->getInClassInitializer()); } +TEST_P(ASTImporterOptionSpecificTestBase, ImportRecursiveFieldInitializer) { + const char *Code = + R"( + class A { + int b{b}; + }; + )"; + Decl *FromTU = getTuDecl(Code, Lang_CXX11); + + auto *FromB = + FirstDeclMatcher().match(FromTU, fieldDecl(hasName("b"))); + EXPECT_TRUE(FromB->hasInClassInitializer()); + + auto *ToB = Import(FromB, Lang_CXX11); + EXPECT_TRUE(ToB->hasInClassInitializer()); +} + TEST_P(ASTImporterOptionSpecificTestBase, isNewDecl) { Decl *FromTU = getTuDecl( R"(