<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/93891>93891</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
`DeclContext::lookup` do not return all declarations with given name
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
giulianobelinassi
</td>
</tr>
</table>
<pre>
Unlike what the documentation says, `DeclContext::lookup` does not provide every declaration with the requested name. Rather than that, it returns the **last** declaration that has this name [(source)](https://clang.llvm.org/doxygen/classclang_1_1DeclContext.html#a47c9a0e81f53370347c491bb29f9efe7).
**Proof:**
With the following code:
```
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
using namespace clang;
using namespace llvm;
static const char *const test_file =
"void f(void);\n"
"void sink(void);\n"
"void f(void)\n"
"{\n"
" sink();\n"
"}\n"
"extern void f(void);\n";
static const std::vector<const char *> clang_args = {"clang", "-O2", "-c", "test.c"};
int main(void)
{
IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
std::shared_ptr<CompilerInvocation> CInvok;
std::shared_ptr<PCHContainerOperations> PCHContainerOps;
IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> MFS;
MFS = IntrusiveRefCntPtr<vfs::InMemoryFileSystem>(new vfs::InMemoryFileSystem);
MFS->addFile("test.c", 0, MemoryBuffer::getMemBufferCopy(test_file));
DiagnosticOptions *diagopts = new DiagnosticOptions();
Diags = CompilerInstance::createDiagnostics(diagopts);
clang::CreateInvocationOptions CIOpts;
CIOpts.Diags = Diags;
CInvok = clang::createInvocation(clang_args, std::move(CIOpts));
FileManager *FileMgr = new FileManager(FileSystemOptions(), MFS);
PCHContainerOps = std::make_shared<PCHContainerOperations>();
auto AST = ASTUnit::LoadFromCompilerInvocation(
CInvok, PCHContainerOps, Diags, FileMgr, false, CaptureDiagsKind::None, 1,
TU_Complete, false, false, false);
const DiagnosticsEngine &de = AST->getDiagnostics();
if (AST == nullptr || de.hasErrorOccurred()) {
llvm::outs() << "Rejected: compilation error.\n";
return 1;
}
TranslationUnitDecl *tu = AST->getASTContext().getTranslationUnitDecl();
IdentifierTable &idtbl = AST->getPreprocessor().getIdentifierTable();
SourceManager &sm = AST->getSourceManager();
/* Find out how many definitions of `f` we have. */
DeclContext::lookup_result decls = tu->lookup(DeclarationName(&idtbl.get("f")));
/* Print out the definitions we found of function 'f'. */
for (Decl *decl : decls) {
FunctionDecl *fdecl = dyn_cast<FunctionDecl>(decl);
if (fdecl) {
PresumedLoc ploc = sm.getPresumedLoc(fdecl->getBeginLoc());
llvm::outs() << "Found function " << fdecl->getName() << " at "
<< ploc.getLine() << ":" << ploc.getColumn() << '\n';
}
}
return 0;
}
```
as `lookup.cpp`, compiling with:
```
$ clang++ -g lookup.cpp -lclang-cpp -lLLVM
```
generates a binary `a.out` that when run have the following output:
```
Found function f at 7:1
```
Therefore, **contradicting the documentation**, which says:
> lookup - Find the declarations (if any) with the given Name in this context.
>
> Returns a range of iterators that contains all of the declarations with this name, with object, function, member, and enumerator names preceding any tag name. Note that this routine will not look into parent contexts.
[(source)](https://clang.llvm.org/doxygen/classclang_1_1DeclContext.html#a47c9a0e81f53370347c491bb29f9efe7)
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzEWM9y4jDSfxpxUYUycojhwIGYob6pL5mkJpndY0rIbVsbW_JKMgxvv9WSwcYwmb1tKmWE1f1T_1c33FpZKIAVmT-S-WbCW1dqsypkW0mu9A4qqZBmstPZcfVLVfIT6KHkjroSaKZFW4Ny3EmtqOVHS1hKyUO0AVGlWjn47Ui8JvG60vqzbchDRDMNlirtaGP0XmZAYQ_mSDMQFTcB6CBd6fEN_LsF6yCjitcwpT-5K8FQV3KFD4enSUcNuNYo61kIWxO2rrh1YXUBjDy05EgprcekqDdbWN0aAYQtyXxD2KJ0rrEoONsSthUVV8W0qvb1VJuCsG2mfx8LUGHLWr__MfuYDbSelq6uCIv5fSKWPILFLJ_HcRLF94m4X852O7bMl5BDQthySqINidbd00v9arTOvQD-f7D_z5Ntcl1V-iBVQYXOAGkD1UPU_XdwsVSiajO0DPOSErbdGpRSZYRt12_vv5R005Iw9l-ypLpuZAXmu7KOKwFDXv9sLYqF5rUNF0ADRvx4excNe94MT4sRJajQyjoqSm7QreGbA-s-clkBJfHmJDDba5nRnLAFLtCN8SOZp2qgUyCxUn3-nWoINNonyRULPaHeRiTJZvwKfjswin4h9BfmsC4LKbUH4bQhcXppJhJ_Cwb_4KawaCWKQp89yXyKMnb3wgZfRL9GC09FJ_mlIFI5WnOpBjKH3aQjo9-VM62Ve_gJearcq0MBN5IXSlsnhf2mCqkAZcSX9ozfq2VLbiD7aDxnH2p7LXwOI2uKXz__xvua_h8mI5cKzEsDoQRY5L_csSMlb-sQotTbPbdh8V09Q63NcSsreDtaBzWCP2_fxoD4zjviJvLXeIQtFBzoV0QhcsJRz9u3OxJ_41mGBD4oBw5lKY3wESAe2zwHE2ALcM9Qhzepbo6ELc6ZhgcMzjgp1Xv1pfGmxejLJC9040LcoeBXVH2iXKEFrnF5CQIKA9zBIJIIW5wOu4HXlRzkTD1nH0EnadPvL8h7Nl33YtpLMgrRLu781gBfjPAJW_T5h9Y-h2et9-iS7uCbVkWvPXPFC_DJ7L8W5mzNwTZhiz4GLm2LHt6-XcTFKOQ9YC8X_4SPkDtf5c0fPMdbp-n67d1jdtdJwH3SPNsaXd_IYrY4seNfl9AsvUpNlnZeYCntjIHLnFcWcJHyxrXGx4X9f6k6hX5o5XdnhKXDc95_faAsFTi4QBkvrpUMNfaqkFHCHjI4aY6ZV4C7DNJbaDKnhC06m3nftlXVOENJkpIkpRlMS26_GaPNixCtQcd0rl3SvthSSvuypFvXHUdJnJLY1_Kf8C8QDt26psJ7ITRCgNDT8W2DgKGXorPBS7wHLsR_N1zZgITOxrYHg9W1I0Os395PTaAXbFqAu8E7MhKl3zNQTuYSzDvfVd7IMnO7agT_aqAxWoC12vQHjJivwN98q9fn2IOtR7gXFH_woO8MMV1VRnXraKkPtOYK-9hcKhkqjM6xF86x6z0ALfkepjQ0qNtz2bvdKH8YsG3lfPMaktW1KF3XRrPFpu9qf_A6aBmMhDYIdT_3JX_5h_LdafBq8FJHFXxDP5D-gD1mi_rlNG-V8IFDWJITllzpkWu05eIUCpn_jEP3bS-jdtthnWjzjnhDs6P6ENi5x-mQKJSezEfK8iJYQx7l3dZlZlD6ikasIXvSgjaVFqHo1dMQOqetE0Dn_EcopAqvR4b7W65tvbEGlmKnzSH-2VtDVsodPTeIp_coMsr6hA3TmMPPBmxMmuqqrdWYOAl5nvSanDP6RnJ3BSDqA-ZMcTlacIvRHSJyKhoc7rCEhjKDLT6OcX-eS-67O5Q9EvZI7wraI9G7yu_dhfXT0z-eb4IUoPB6Aks53UnFzREl4lPdOsw5P-0dSlDUtMqn32hw0q1rWteLeOuMkVdzdFVC4vXsJvV7CQZybSD00uswtjjDMykcHnk1NXcTHkvpoZSiDEP0SKL4W2ccehcqTkjVcwXAzmshc8rVER1_Hp8LuQdFMeKoVGHmFd142iP3q5_dGM2p4aoAzHvp0MDa2GBMEa5mS3lV4faVHN3R3XDttcI3eofXkL9gO0PiuoZ6B_465yqjoNo6HBZmQ9oYEJCh0bCuOl50PwL80A6COP4go1uHN_FBVpX_XQFNRaVymjbcgHInne1J6f_9xB8EmWSrOFvGSz6B1SyZJbNZNE_iSbnK4_lOJIs5j9kDWywhhntYZpCwZQ4PuUgmcsUidh_N44jF0TKOp9FuJ1iU3UcsX2Q8FuQ-gprL6qzDRFrbwmoZL5azScV3UFn_kw9j2Fb6Tawq883ErJDnbtcWltxHlbTO9ihOugpWf_uBx7uhqyMYKdchEiIT_TlpTbW6tH4hXdnupkLXhG190Q0fd43RIY62XmBL2DYotF-x_wQAAP__BpqwXg">