Diagnose shadowing of decls in the std
namespace
Related to the discussion in ROOT-5971 (see https://sft.its.cern.ch/jira/browse/ROOT-5971), this commit improves the situation by diagnosing the shadowing of declarations in the `std` namespace. In summary, given that ROOT issues an implicit `using namespace std;` and due to the way `SemaLookup` works, decls that shadow something in the `std` namespace cannot be referenced without using their fully-qualified name, i.e. `::xxx`. Thus, we need to emit a warning for that case.
This commit is contained in:
parent
2e500a3fb8
commit
0d71789370
@ -62,7 +62,11 @@ namespace cling {
|
||||
|
||||
DefinitionShadower::DefinitionShadower(Sema& S, Interpreter& I)
|
||||
: ASTTransformer(&S), m_Context(S.getASTContext()), m_Interp(I),
|
||||
m_TU(S.getASTContext().getTranslationUnitDecl())
|
||||
m_TU(S.getASTContext().getTranslationUnitDecl()),
|
||||
m_ShadowsDeclInStdDiagID(S.getDiagnostics().getCustomDiagID(
|
||||
DiagnosticsEngine::Warning,
|
||||
"'%0' shadows a declaration with the same name in the 'std' "
|
||||
"namespace; consider using '::%0' to reference this declaration"))
|
||||
{}
|
||||
|
||||
bool DefinitionShadower::isClingShadowNamespace(const DeclContext *DC) {
|
||||
@ -94,9 +98,12 @@ namespace cling {
|
||||
}
|
||||
|
||||
void DefinitionShadower::invalidatePreviousDefinitions(NamedDecl *D) const {
|
||||
// NotForRedeclaration: lookup anything visible; follows using directives
|
||||
LookupResult Previous(*m_Sema, D->getDeclName(), D->getLocation(),
|
||||
Sema::LookupOrdinaryName, Sema::ForVisibleRedeclaration);
|
||||
Sema::LookupOrdinaryName, Sema::NotForRedeclaration);
|
||||
Previous.suppressDiagnostics();
|
||||
m_Sema->LookupQualifiedName(Previous, m_TU);
|
||||
bool shadowsDeclInStd{};
|
||||
|
||||
for (auto Prev : Previous) {
|
||||
if (Prev == D)
|
||||
@ -116,6 +123,7 @@ namespace cling {
|
||||
/*IsForUsingDecl=*/false))
|
||||
continue;
|
||||
|
||||
shadowsDeclInStd |= Prev->isInStdNamespace();
|
||||
hideDecl(Prev);
|
||||
|
||||
// For unscoped enumerations, also invalidate all enumerators.
|
||||
@ -132,6 +140,18 @@ namespace cling {
|
||||
// : reference to 'xxx' is ambiguous" in `class C {}; class C; C foo;`.
|
||||
if (!Previous.empty() && !isDefinition(D))
|
||||
D->setInvalidDecl();
|
||||
|
||||
// Diagnose shadowing of decls in the `std` namespace (see ROOT-5971).
|
||||
// For unnamed macros, the input is ingested in a single `Interpreter::process()`
|
||||
// call. Do not emit the warning in that case, as all references are local
|
||||
// to the wrapper function and this diagnostic might be misleading.
|
||||
if (shadowsDeclInStd
|
||||
&& ((m_Interp.getInputFlags() & (Interpreter::kInputFromFile
|
||||
| Interpreter::kIFFLineByLine))
|
||||
!= Interpreter::kInputFromFile)) {
|
||||
m_Sema->Diag(D->getBeginLoc(), m_ShadowsDeclInStdDiagID)
|
||||
<< D->getQualifiedNameAsString();
|
||||
}
|
||||
}
|
||||
|
||||
void DefinitionShadower::invalidatePreviousDefinitions(FunctionDecl *D) const {
|
||||
|
@ -53,6 +53,7 @@ namespace cling {
|
||||
clang::ASTContext &m_Context;
|
||||
Interpreter &m_Interp;
|
||||
clang::TranslationUnitDecl *m_TU;
|
||||
unsigned m_ShadowsDeclInStdDiagID;
|
||||
|
||||
unsigned long long m_UniqueNameCounter = 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user