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