|
@@ -1347,6 +1347,32 @@ bool DeclContext::containsDecl(Decl *D) const {
|
|
(D->NextInContextAndBits.getPointer() || D == LastDecl));
|
|
(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) {
|
|
void DeclContext::removeDecl(Decl *D) {
|
|
assert(D->getLexicalDeclContext() == this &&
|
|
assert(D->getLexicalDeclContext() == this &&
|
|
"decl being removed from non-lexical context");
|
|
"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.
|
|
// Mark that D is no longer in the decl chain.
|
|
D->NextInContextAndBits.setPointer(nullptr);
|
|
D->NextInContextAndBits.setPointer(nullptr);
|
|
|
|
|
|
@@ -1377,8 +1403,14 @@ void DeclContext::removeDecl(Decl *D) {
|
|
if (isa<NamedDecl>(D)) {
|
|
if (isa<NamedDecl>(D)) {
|
|
auto *ND = cast<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
|
|
// Remove only decls that have a name
|
|
- if (!ND->getDeclName()) return;
|
|
|
|
|
|
+ if (!ND->getDeclName())
|
|
|
|
+ return;
|
|
|
|
|
|
auto *DC = D->getDeclContext();
|
|
auto *DC = D->getDeclContext();
|
|
do {
|
|
do {
|
|
@@ -1435,32 +1467,6 @@ void DeclContext::addDeclInternal(Decl *D) {
|
|
makeDeclVisibleInContextWithFlags(ND, true, true);
|
|
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
|
|
/// buildLookup - Build the lookup data structure with all of the
|
|
/// declarations in this DeclContext (and any other contexts linked
|
|
/// declarations in this DeclContext (and any other contexts linked
|
|
/// to it or transparent contexts nested within it) and return it.
|
|
/// to it or transparent contexts nested within it) and return it.
|