folly::Optional lookupIn()

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;
    }
  }