Index: lib/AST/DeclBase.cpp =================================================================== --- lib/AST/DeclBase.cpp +++ lib/AST/DeclBase.cpp @@ -1350,6 +1350,8 @@ (D->NextInContextAndBits.getPointer() || D == LastDecl)); } +static bool shouldBeHidden(NamedDecl *D); + void DeclContext::removeDecl(Decl *D) { assert(D->getLexicalDeclContext() == this && "decl being removed from non-lexical context"); @@ -1372,7 +1374,7 @@ } } } - + // Mark that D is no longer in the decl chain. D->NextInContextAndBits.setPointer(nullptr); @@ -1380,6 +1382,10 @@ if (isa(D)) { auto *ND = cast(D); + // Do not try to remove the declaration if that is invisible to qualified + // lookup. E.g. template specializations are skipped. + if (shouldBeHidden(ND)) return; + // Remove only decls that have a name if (!ND->getDeclName()) return; Index: unittests/AST/ASTImporterTest.cpp =================================================================== --- unittests/AST/ASTImporterTest.cpp +++ unittests/AST/ASTImporterTest.cpp @@ -1764,5 +1764,38 @@ compoundStmt(has(callExpr(has(unresolvedMemberExpr()))))))))); } +struct DeclContextTest : ASTImporterTestBase {}; + +TEST_P(DeclContextTest, removeDeclOfClassTemplateSpecialization) { + Decl *TU = getTuDecl( + R"( + namespace NS { + + template + struct S {}; + template struct S; + + inline namespace INS { + template + struct S {}; + template struct S; + } + + } + )", Lang_CXX11, "input0.cc"); + auto *NS = FirstDeclMatcher().match( + TU, namespaceDecl()); + auto *Spec = FirstDeclMatcher().match( + TU, classTemplateSpecializationDecl()); + ASSERT_TRUE(NS->containsDecl(Spec)); + + NS->removeDecl(Spec); + EXPECT_FALSE(NS->containsDecl(Spec)); +} + +INSTANTIATE_TEST_CASE_P( + ParameterizedTests, DeclContextTest, + ::testing::Values(ArgVector(), ArgVector{"-fdelayed-template-parsing"}),); + } // end namespace ast_matchers } // end namespace clang Index: unittests/AST/MatchVerifier.h =================================================================== --- unittests/AST/MatchVerifier.h +++ unittests/AST/MatchVerifier.h @@ -28,7 +28,7 @@ namespace clang { namespace ast_matchers { -enum Language { +enum Language { Lang_C, Lang_C89, Lang_CXX,