1//===- DeclLookups.h - Low-level interface to all names in a DC -*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9//  This file defines DeclContext::all_lookups_iterator.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_AST_DECLLOOKUPS_H
14#define LLVM_CLANG_AST_DECLLOOKUPS_H
15
16#include "clang/AST/ASTContext.h"
17#include "clang/AST/DeclBase.h"
18#include "clang/AST/DeclContextInternals.h"
19#include "clang/AST/DeclarationName.h"
20#include "clang/AST/ExternalASTSource.h"
21#include <cstddef>
22#include <iterator>
23
24namespace clang {
25
26/// all_lookups_iterator - An iterator that provides a view over the results
27/// of looking up every possible name.
28class DeclContext::all_lookups_iterator {
29  StoredDeclsMap::iterator It, End;
30
31public:
32  using value_type = lookup_result;
33  using reference = lookup_result;
34  using pointer = lookup_result;
35  using iterator_category = std::forward_iterator_tag;
36  using difference_type = std::ptrdiff_t;
37
38  all_lookups_iterator() = default;
39  all_lookups_iterator(StoredDeclsMap::iterator It,
40                       StoredDeclsMap::iterator End)
41      : It(It), End(End) {}
42
43  DeclarationName getLookupName() const { return It->first; }
44
45  reference operator*() const { return It->second.getLookupResult(); }
46  pointer operator->() const { return It->second.getLookupResult(); }
47
48  all_lookups_iterator& operator++() {
49    // Filter out using directives. They don't belong as results from name
50    // lookup anyways, except as an implementation detail. Users of the API
51    // should not expect to get them (or worse, rely on it).
52    do {
53      ++It;
54    } while (It != End &&
55             It->first == DeclarationName::getUsingDirectiveName());
56
57    return *this;
58  }
59
60  all_lookups_iterator operator++(int) {
61    all_lookups_iterator tmp(*this);
62    ++(*this);
63    return tmp;
64  }
65
66  friend bool operator==(all_lookups_iterator x, all_lookups_iterator y) {
67    return x.It == y.It;
68  }
69
70  friend bool operator!=(all_lookups_iterator x, all_lookups_iterator y) {
71    return x.It != y.It;
72  }
73};
74
75inline DeclContext::lookups_range DeclContext::lookups() const {
76  DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
77  if (Primary->hasExternalVisibleStorage())
78    getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary);
79  if (StoredDeclsMap *Map = Primary->buildLookup())
80    return lookups_range(all_lookups_iterator(Map->begin(), Map->end()),
81                         all_lookups_iterator(Map->end(), Map->end()));
82
83  // Synthesize an empty range. This requires that two default constructed
84  // versions of these iterators form a valid empty range.
85  return lookups_range(all_lookups_iterator(), all_lookups_iterator());
86}
87
88inline DeclContext::lookups_range
89DeclContext::noload_lookups(bool PreserveInternalState) const {
90  DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
91  if (!PreserveInternalState)
92    Primary->loadLazyLocalLexicalLookups();
93  if (StoredDeclsMap *Map = Primary->getLookupPtr())
94    return lookups_range(all_lookups_iterator(Map->begin(), Map->end()),
95                         all_lookups_iterator(Map->end(), Map->end()));
96
97  // Synthesize an empty range. This requires that two default constructed
98  // versions of these iterators form a valid empty range.
99  return lookups_range(all_lookups_iterator(), all_lookups_iterator());
100}
101
102} // namespace clang
103
104#endif // LLVM_CLANG_AST_DECLLOOKUPS_H
105