r332699 - Do not try to remove invisible Decls from DeclContext
Gabor Marton via cfe-commits
cfe-commits at lists.llvm.org
Fri May 18 02:08:47 PDT 2018
Author: martong
Date: Fri May 18 02:08:47 2018
New Revision: 332699
URL: http://llvm.org/viewvc/llvm-project?rev=332699&view=rev
Log:
Do not try to remove invisible Decls from DeclContext
Modified:
cfe/trunk/lib/AST/DeclBase.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp
Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=332699&r1=332698&r2=332699&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Fri May 18 02:08:47 2018
@@ -1347,6 +1347,32 @@ bool DeclContext::containsDecl(Decl *D)
(D->NextInContextAndBits.getPointer() || D == LastDecl));
}
+/// shouldBeHidden - Determine whether a declaration which was declared
+/// within its semantic context should be invisible to qualified name lookup.
+static bool shouldBeHidden(NamedDecl *D) {
+ // Skip unnamed declarations.
+ if (!D->getDeclName())
+ return true;
+
+ // Skip entities that can't be found by name lookup into a particular
+ // context.
+ if ((D->getIdentifierNamespace() == 0 && !isa<UsingDirectiveDecl>(D)) ||
+ D->isTemplateParameter())
+ return true;
+
+ // Skip template specializations.
+ // FIXME: This feels like a hack. Should DeclarationName support
+ // template-ids, or is there a better way to keep specializations
+ // from being visible?
+ if (isa<ClassTemplateSpecializationDecl>(D))
+ return true;
+ if (auto *FD = dyn_cast<FunctionDecl>(D))
+ if (FD->isFunctionTemplateSpecialization())
+ return true;
+
+ return false;
+}
+
void DeclContext::removeDecl(Decl *D) {
assert(D->getLexicalDeclContext() == this &&
"decl being removed from non-lexical context");
@@ -1369,7 +1395,7 @@ void DeclContext::removeDecl(Decl *D) {
}
}
}
-
+
// Mark that D is no longer in the decl chain.
D->NextInContextAndBits.setPointer(nullptr);
@@ -1377,8 +1403,14 @@ void DeclContext::removeDecl(Decl *D) {
if (isa<NamedDecl>(D)) {
auto *ND = cast<NamedDecl>(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;
+ if (!ND->getDeclName())
+ return;
auto *DC = D->getDeclContext();
do {
@@ -1435,32 +1467,6 @@ void DeclContext::addDeclInternal(Decl *
makeDeclVisibleInContextWithFlags(ND, true, true);
}
-/// shouldBeHidden - Determine whether a declaration which was declared
-/// within its semantic context should be invisible to qualified name lookup.
-static bool shouldBeHidden(NamedDecl *D) {
- // Skip unnamed declarations.
- if (!D->getDeclName())
- return true;
-
- // Skip entities that can't be found by name lookup into a particular
- // context.
- if ((D->getIdentifierNamespace() == 0 && !isa<UsingDirectiveDecl>(D)) ||
- D->isTemplateParameter())
- return true;
-
- // Skip template specializations.
- // FIXME: This feels like a hack. Should DeclarationName support
- // template-ids, or is there a better way to keep specializations
- // from being visible?
- if (isa<ClassTemplateSpecializationDecl>(D))
- return true;
- if (auto *FD = dyn_cast<FunctionDecl>(D))
- if (FD->isFunctionTemplateSpecialization())
- return true;
-
- return false;
-}
-
/// buildLookup - Build the lookup data structure with all of the
/// declarations in this DeclContext (and any other contexts linked
/// to it or transparent contexts nested within it) and return it.
Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=332699&r1=332698&r2=332699&view=diff
==============================================================================
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Fri May 18 02:08:47 2018
@@ -1797,5 +1797,38 @@ TEST(ImportExpr, UnresolvedMemberExpr) {
compoundStmt(has(callExpr(has(unresolvedMemberExpr())))))))));
}
+struct DeclContextTest : ASTImporterTestBase {};
+
+TEST_P(DeclContextTest, removeDeclOfClassTemplateSpecialization) {
+ Decl *TU = getTuDecl(
+ R"(
+ namespace NS {
+
+ template <typename T>
+ struct S {};
+ template struct S<int>;
+
+ inline namespace INS {
+ template <typename T>
+ struct S {};
+ template struct S<int>;
+ }
+
+ }
+ )", Lang_CXX11, "input0.cc");
+ auto *NS = FirstDeclMatcher<NamespaceDecl>().match(
+ TU, namespaceDecl());
+ auto *Spec = FirstDeclMatcher<ClassTemplateSpecializationDecl>().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
More information about the cfe-commits
mailing list