DeclLookups.h revision 280031
1234287Sdim//===-- DeclLookups.h - Low-level interface to all names in a DC-*- C++ -*-===//
2234287Sdim//
3234287Sdim//                     The LLVM Compiler Infrastructure
4234287Sdim//
5234287Sdim// This file is distributed under the University of Illinois Open Source
6234287Sdim// License. See LICENSE.TXT for details.
7234287Sdim//
8234287Sdim//===----------------------------------------------------------------------===//
9234287Sdim//
10234287Sdim//  This file defines DeclContext::all_lookups_iterator.
11234287Sdim//
12234287Sdim//===----------------------------------------------------------------------===//
13234287Sdim
14234287Sdim#ifndef LLVM_CLANG_AST_DECLLOOKUPS_H
15234287Sdim#define LLVM_CLANG_AST_DECLLOOKUPS_H
16234287Sdim
17249423Sdim#include "clang/AST/ASTContext.h"
18234287Sdim#include "clang/AST/DeclBase.h"
19234287Sdim#include "clang/AST/DeclContextInternals.h"
20234287Sdim#include "clang/AST/DeclarationName.h"
21234287Sdim
22234287Sdimnamespace clang {
23234287Sdim
24234287Sdim/// all_lookups_iterator - An iterator that provides a view over the results
25234287Sdim/// of looking up every possible name.
26234287Sdimclass DeclContext::all_lookups_iterator {
27234287Sdim  StoredDeclsMap::iterator It, End;
28234287Sdimpublic:
29234287Sdim  typedef lookup_result             value_type;
30234287Sdim  typedef lookup_result             reference;
31234287Sdim  typedef lookup_result             pointer;
32234287Sdim  typedef std::forward_iterator_tag iterator_category;
33234287Sdim  typedef std::ptrdiff_t            difference_type;
34234287Sdim
35234287Sdim  all_lookups_iterator() {}
36234287Sdim  all_lookups_iterator(StoredDeclsMap::iterator It,
37234287Sdim                       StoredDeclsMap::iterator End)
38234287Sdim      : It(It), End(End) {}
39234287Sdim
40261991Sdim  DeclarationName getLookupName() const { return It->first; }
41261991Sdim
42234287Sdim  reference operator*() const { return It->second.getLookupResult(); }
43234287Sdim  pointer operator->() const { return It->second.getLookupResult(); }
44234287Sdim
45234287Sdim  all_lookups_iterator& operator++() {
46234287Sdim    // Filter out using directives. They don't belong as results from name
47234287Sdim    // lookup anyways, except as an implementation detail. Users of the API
48234287Sdim    // should not expect to get them (or worse, rely on it).
49234287Sdim    do {
50234287Sdim      ++It;
51234287Sdim    } while (It != End &&
52234287Sdim             It->first == DeclarationName::getUsingDirectiveName());
53234287Sdim
54234287Sdim    return *this;
55234287Sdim  }
56234287Sdim
57234287Sdim  all_lookups_iterator operator++(int) {
58234287Sdim    all_lookups_iterator tmp(*this);
59234287Sdim    ++(*this);
60234287Sdim    return tmp;
61234287Sdim  }
62234287Sdim
63234287Sdim  friend bool operator==(all_lookups_iterator x, all_lookups_iterator y) {
64234287Sdim    return x.It == y.It;
65234287Sdim  }
66234287Sdim  friend bool operator!=(all_lookups_iterator x, all_lookups_iterator y) {
67234287Sdim    return x.It != y.It;
68234287Sdim  }
69234287Sdim};
70234287Sdim
71276479Sdiminline DeclContext::lookups_range DeclContext::lookups() const {
72234287Sdim  DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
73239462Sdim  if (Primary->hasExternalVisibleStorage())
74234982Sdim    getParentASTContext().getExternalSource()->completeVisibleDeclsMap(Primary);
75234287Sdim  if (StoredDeclsMap *Map = Primary->buildLookup())
76276479Sdim    return lookups_range(all_lookups_iterator(Map->begin(), Map->end()),
77276479Sdim                         all_lookups_iterator(Map->end(), Map->end()));
78280031Sdim
79280031Sdim  // Synthesize an empty range. This requires that two default constructed
80280031Sdim  // versions of these iterators form a valid empty range.
81280031Sdim  return lookups_range(all_lookups_iterator(), all_lookups_iterator());
82234287Sdim}
83234287Sdim
84276479Sdiminline DeclContext::all_lookups_iterator DeclContext::lookups_begin() const {
85276479Sdim  return lookups().begin();
86276479Sdim}
87276479Sdim
88261991Sdiminline DeclContext::all_lookups_iterator DeclContext::lookups_end() const {
89276479Sdim  return lookups().end();
90276479Sdim}
91276479Sdim
92276479Sdiminline DeclContext::lookups_range DeclContext::noload_lookups() const {
93234287Sdim  DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
94276479Sdim  if (StoredDeclsMap *Map = Primary->getLookupPtr())
95276479Sdim    return lookups_range(all_lookups_iterator(Map->begin(), Map->end()),
96276479Sdim                         all_lookups_iterator(Map->end(), Map->end()));
97280031Sdim
98280031Sdim  // Synthesize an empty range. This requires that two default constructed
99280031Sdim  // versions of these iterators form a valid empty range.
100280031Sdim  return lookups_range(all_lookups_iterator(), all_lookups_iterator());
101234287Sdim}
102234287Sdim
103261991Sdiminline
104261991SdimDeclContext::all_lookups_iterator DeclContext::noload_lookups_begin() const {
105276479Sdim  return noload_lookups().begin();
106261991Sdim}
107261991Sdim
108261991Sdiminline
109261991SdimDeclContext::all_lookups_iterator DeclContext::noload_lookups_end() const {
110276479Sdim  return noload_lookups().end();
111261991Sdim}
112261991Sdim
113234287Sdim} // end namespace clang
114234287Sdim
115234287Sdim#endif
116