1327952Sdim//===- DeclLookups.h - Low-level interface to all names in a DC -*- C++ -*-===//
2234287Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6234287Sdim//
7234287Sdim//===----------------------------------------------------------------------===//
8234287Sdim//
9234287Sdim//  This file defines DeclContext::all_lookups_iterator.
10234287Sdim//
11234287Sdim//===----------------------------------------------------------------------===//
12234287Sdim
13234287Sdim#ifndef LLVM_CLANG_AST_DECLLOOKUPS_H
14234287Sdim#define LLVM_CLANG_AST_DECLLOOKUPS_H
15234287Sdim
16249423Sdim#include "clang/AST/ASTContext.h"
17234287Sdim#include "clang/AST/DeclBase.h"
18234287Sdim#include "clang/AST/DeclContextInternals.h"
19234287Sdim#include "clang/AST/DeclarationName.h"
20327952Sdim#include "clang/AST/ExternalASTSource.h"
21327952Sdim#include <cstddef>
22327952Sdim#include <iterator>
23234287Sdim
24234287Sdimnamespace clang {
25234287Sdim
26234287Sdim/// all_lookups_iterator - An iterator that provides a view over the results
27234287Sdim/// of looking up every possible name.
28234287Sdimclass DeclContext::all_lookups_iterator {
29234287Sdim  StoredDeclsMap::iterator It, End;
30327952Sdim
31234287Sdimpublic:
32327952Sdim  using value_type = lookup_result;
33327952Sdim  using reference = lookup_result;
34327952Sdim  using pointer = lookup_result;
35327952Sdim  using iterator_category = std::forward_iterator_tag;
36327952Sdim  using difference_type = std::ptrdiff_t;
37234287Sdim
38327952Sdim  all_lookups_iterator() = default;
39234287Sdim  all_lookups_iterator(StoredDeclsMap::iterator It,
40234287Sdim                       StoredDeclsMap::iterator End)
41234287Sdim      : It(It), End(End) {}
42234287Sdim
43261991Sdim  DeclarationName getLookupName() const { return It->first; }
44261991Sdim
45234287Sdim  reference operator*() const { return It->second.getLookupResult(); }
46234287Sdim  pointer operator->() const { return It->second.getLookupResult(); }
47234287Sdim
48234287Sdim  all_lookups_iterator& operator++() {
49234287Sdim    // Filter out using directives. They don't belong as results from name
50234287Sdim    // lookup anyways, except as an implementation detail. Users of the API
51234287Sdim    // should not expect to get them (or worse, rely on it).
52234287Sdim    do {
53234287Sdim      ++It;
54234287Sdim    } while (It != End &&
55234287Sdim             It->first == DeclarationName::getUsingDirectiveName());
56341825Sdim
57234287Sdim    return *this;
58234287Sdim  }
59234287Sdim
60234287Sdim  all_lookups_iterator operator++(int) {
61234287Sdim    all_lookups_iterator tmp(*this);
62234287Sdim    ++(*this);
63234287Sdim    return tmp;
64234287Sdim  }
65234287Sdim
66234287Sdim  friend bool operator==(all_lookups_iterator x, all_lookups_iterator y) {
67234287Sdim    return x.It == y.It;
68234287Sdim  }
69327952Sdim
70234287Sdim  friend bool operator!=(all_lookups_iterator x, all_lookups_iterator y) {
71234287Sdim    return x.It != y.It;
72234287Sdim  }
73234287Sdim};
74234287Sdim
75276479Sdiminline DeclContext::lookups_range DeclContext::lookups() const {
76234287Sdim  DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
77239462Sdim  if (Primary->hasExternalVisibleStorage())
78234982Sdim    getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary);
79234287Sdim  if (StoredDeclsMap *Map = Primary->buildLookup())
80276479Sdim    return lookups_range(all_lookups_iterator(Map->begin(), Map->end()),
81276479Sdim                         all_lookups_iterator(Map->end(), Map->end()));
82280031Sdim
83280031Sdim  // Synthesize an empty range. This requires that two default constructed
84280031Sdim  // versions of these iterators form a valid empty range.
85280031Sdim  return lookups_range(all_lookups_iterator(), all_lookups_iterator());
86234287Sdim}
87234287Sdim
88341825Sdiminline DeclContext::lookups_range
89341825SdimDeclContext::noload_lookups(bool PreserveInternalState) const {
90234287Sdim  DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
91341825Sdim  if (!PreserveInternalState)
92341825Sdim    Primary->loadLazyLocalLexicalLookups();
93276479Sdim  if (StoredDeclsMap *Map = Primary->getLookupPtr())
94276479Sdim    return lookups_range(all_lookups_iterator(Map->begin(), Map->end()),
95276479Sdim                         all_lookups_iterator(Map->end(), Map->end()));
96280031Sdim
97280031Sdim  // Synthesize an empty range. This requires that two default constructed
98280031Sdim  // versions of these iterators form a valid empty range.
99280031Sdim  return lookups_range(all_lookups_iterator(), all_lookups_iterator());
100234287Sdim}
101234287Sdim
102327952Sdim} // namespace clang
103234287Sdim
104327952Sdim#endif // LLVM_CLANG_AST_DECLLOOKUPS_H
105