in glean/lang/clang/ast.cpp [148:186]
folly::Optional<const clang::DeclContext *> lookupIn(
const clang::DeclContext * context, LookupState& s) {
if (s.visited.find(context) == s.visited.end()) {
s.visited.insert(context);
if (context == s.context || context == s.parentContext) {
return nullptr;
} else if (auto r = folly::get_optional(usingDecls, {context, s.decl})) {
s.via.push_front(Cxx::XRefVia::usingDeclaration(r->second));
// Follow chains of using decls - for instance:
//
// namespace foo { using std::vector; }
// namespace bar { using foo::vector; }
// bar::vector
//
// TODO: We should probably cache this rather than recomputing every
// time.
return getSpecifierContext(r->first->getQualifier());
} else {
auto p = forwards.find(context);
if (p != forwards.end()) {
// If we find a decl through a using directive we'll have to place it
// in the right spot in the via list so remember the current position.
auto pos = s.via.begin();
for (auto i = p->second.rbegin(); i != p->second.rend(); ++i) {
if (auto ctx = lookupIn(i->context, s)) {
if (i->fact) {
s.via.insert(
pos, Cxx::XRefVia::usingDirective(i->fact.value()));
}
return ctx;
}
}
}
return folly::none;
}
} else {
return folly::none;
}
}