Fix ROOT-8739: Lookup of symbol inside of namespace shadowed by function (in another 'used' namespace).

This was happening when a namespace had the same as the function in a namespace that was 'used'.  Namely,
in the issue report it was the 'next' namespace and the function std::next.

This required the quick search function in LookupHelper.cxx to properly handle the return value of utils::Lookup::Named.
This commit is contained in:
Philippe Canal 2017-04-07 13:13:49 -05:00 committed by sftnight
parent 3a1db539f6
commit f5c7037763
3 changed files with 117 additions and 4 deletions

View File

@ -162,7 +162,10 @@ namespace cling {
return true;
}
next = utils::Lookup::Named(&S, declName.substr(last, c - last), sofar);
if (next && next != (void *) -1) {
if (next == (void *) -1) {
// Ambiguous result, we need to go through the long path
return false;
} else if (next && next != (void *) -1) {
// Need to handle typedef here too.
const TypedefNameDecl *typedefDecl = dyn_cast<TypedefNameDecl>(next);
if (typedefDecl) {
@ -219,7 +222,7 @@ namespace cling {
}
if (!sofar) {
// We are looking into something that is not a decl context,
// we won't find anything.
// so we won't find anything.
return true;
}
last = c + 2;
@ -227,7 +230,8 @@ namespace cling {
} else if (c + 1 == declName.size()) {
// End of the line.
next = utils::Lookup::Named(&S, declName.substr(last, c + 1 - last), sofar);
if (next == (void *) -1) next = 0;
// If there is an ambiguity, we need to go the long route.
if (next == (void *) -1) return false;
if (next) {
resultDecl = next;
}

96
test/Lookup/named.C Normal file
View File

@ -0,0 +1,96 @@
//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------
// RUN: cat %s | %built_cling -fno-rtti 2>&1 | FileCheck %s
// Test Lookup::Named and Namespace, used in quick simple lookups.
#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/LookupHelper.h"
#include "cling/Utils/AST.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Type.h"
#include <cstdio>
using namespace cling;
using namespace llvm;
.rawInput 1
namespace Functions {
void Next();
}
using namespace Functions;
namespace Next {
class Inside_Next {};
}
namespace AnotherNext {
class Inside_AnotherNext {};
}
.rawInput 0
clang::Sema& S = gCling->getSema();
const LookupHelper& lookup = gCling->getLookupHelper();
LookupHelper::DiagSetting diags = LookupHelper::WithDiagnostics;
const clang::NamedDecl *decl{nullptr};
decl = utils::Lookup::Named(&S, "AnotherNext", nullptr);
decl
//CHECK: (const clang::NamedDecl *) 0x{{[1-9a-f][0-9a-f]*$}}
decl->getQualifiedNameAsString().c_str()
//CHECK-NEXT: ({{[^)]+}}) "AnotherNext"
const clang::DeclContext *context = dyn_cast<clang::DeclContext>(decl);
context
//CHECK: (const clang::DeclContext *) 0x{{[1-9a-f][0-9a-f]*$}}
decl = utils::Lookup::Named(&S, "Inside_AnotherNext", context);
decl
//CHECK: (const clang::NamedDecl *) 0x{{[1-9a-f][0-9a-f]*$}}
decl->getQualifiedNameAsString().c_str()
//CHECK-NEXT: ({{[^)]+}}) "AnotherNext::Inside_AnotherNext"
// Now test the ambiguities.
decl = utils::Lookup::Named(&S, "Next", nullptr);
decl
//CHECK: (const clang::NamedDecl *) 0x{{f+[ $]}}
const clang::Decl* nextDecl = lookup.findScope("Next", diags);
nextDecl
//CHECK: (const clang::Decl *) 0x{{[1-9a-f][0-9a-f]*$}}
cast<clang::NamedDecl>(nextDecl)->getQualifiedNameAsString().c_str()
//CHECK-NEXT: ({{[^)]+}}) "Next"
context = llvm::dyn_cast<clang::DeclContext>(nextDecl);
context
//CHECK: (const clang::DeclContext *) 0x{{[1-9a-f][0-9a-f]*$}}
decl = utils::Lookup::Named(&S, "Inside_Next", context);
decl
//CHECK: (const clang::NamedDecl *) 0x{{[1-9a-f][0-9a-f]*$}}
// Now test looking up non-existing things.
// In global scope
decl = utils::Lookup::Named(&S, "DoesNotExist", nullptr);
decl
//CHECK: (const clang::NamedDecl *) {{0x0*$|nullptr}}
// In a namespace
decl = utils::Lookup::Named(&S, "EvenLess", context);
decl
//CHECK: (const clang::NamedDecl *) {{0x0*$|nullptr}}

View File

@ -7,7 +7,7 @@
//------------------------------------------------------------------------------
// RUN: cat %s | %built_cling -fno-rtti 2>&1 | FileCheck %s
// Test findScope, which is esentially is a DeclContext.
// Test findScope, which is essentially is a DeclContext.
#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/LookupHelper.h"
@ -90,3 +90,16 @@ lookup.findScope("W<Int_t>", diags, &resType);
clang::QualType(resType,0).getAsString().c_str()
//CHECK-NEXT: ({{[^)]+}}) "W<Int_t>"
.rawInput 1
namespace Functions {
void Next();
}
using namespace Functions;
namespace Next {}
.rawInput 0
const clang::Decl* cl_Next = lookup.findScope("Next", diags);
printf("cl_Next: 0x%lx\n", (unsigned long) cl_Next);
//CHECK-NEXT: cl_Next: 0x{{[1-9a-f][0-9a-f]*$}}