diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/DeclBase.cpp | 62 |
1 files changed, 34 insertions, 28 deletions
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 51518a78626..3db886957c0 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -1347,6 +1347,32 @@ bool DeclContext::containsDecl(Decl *D) const { (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 *D) { 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. |