Skip to content

Commit 47550f7

Browse files
committed
Speed up the parser
Prefer std::vector to std::unordered_set in the name lookup caches and cxx::Identifier to std::string_view for the preprocessor hidesets.
1 parent 2d3f00f commit 47550f7

File tree

3 files changed

+287
-317
lines changed

3 files changed

+287
-317
lines changed

src/parser/cxx/name_lookup.cc

Lines changed: 10 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -31,152 +31,9 @@ namespace cxx {
3131

3232
Lookup::Lookup(ScopeSymbol* scope) : scope_(scope) {}
3333

34-
auto Lookup::operator()(const Name* name,
35-
const std::function<bool(Symbol*)>& accept) const
36-
-> Symbol* {
37-
return lookup(nullptr, name, accept);
38-
}
39-
40-
auto Lookup::operator()(NestedNameSpecifierAST* nestedNameSpecifier,
41-
const Name* name,
42-
const std::function<bool(Symbol*)>& accept) const
43-
-> Symbol* {
44-
return lookup(nestedNameSpecifier, name, accept);
45-
}
46-
47-
auto Lookup::unqualifiedLookup(const Name* name,
48-
const std::function<bool(Symbol*)>& accept) const
49-
-> Symbol* {
50-
std::unordered_set<ScopeSymbol*> cache;
51-
for (auto current = scope_; current; current = current->parent()) {
52-
if (auto symbol = lookupHelper(current, name, cache, accept)) {
53-
return symbol;
54-
}
55-
}
56-
return nullptr;
57-
}
58-
59-
auto Lookup::qualifiedLookup(ScopeSymbol* scope, const Name* name,
60-
const std::function<bool(Symbol*)>& accept) const
61-
-> Symbol* {
62-
std::unordered_set<ScopeSymbol*> cache;
63-
return lookupHelper(scope, name, cache, accept);
64-
}
65-
66-
auto Lookup::qualifiedLookup(Symbol* scopeSymbol, const Name* name,
67-
const std::function<bool(Symbol*)>& accept) const
68-
-> Symbol* {
69-
if (!scopeSymbol) return nullptr;
70-
switch (scopeSymbol->kind()) {
71-
case SymbolKind::kNamespace:
72-
return qualifiedLookup(symbol_cast<NamespaceSymbol>(scopeSymbol), name,
73-
accept);
74-
75-
case SymbolKind::kClass:
76-
return qualifiedLookup(symbol_cast<ClassSymbol>(scopeSymbol), name,
77-
accept);
78-
79-
case SymbolKind::kEnum:
80-
return qualifiedLookup(symbol_cast<EnumSymbol>(scopeSymbol), name,
81-
accept);
82-
83-
case SymbolKind::kScopedEnum:
84-
return qualifiedLookup(symbol_cast<ScopedEnumSymbol>(scopeSymbol), name,
85-
accept);
86-
87-
case SymbolKind::kTypeAlias: {
88-
auto alias = symbol_cast<TypeAliasSymbol>(scopeSymbol);
89-
90-
if (auto classType = type_cast<ClassType>(alias->type())) {
91-
auto classSymbol = classType->symbol();
92-
return qualifiedLookup(classSymbol, name, accept);
93-
}
94-
95-
if (auto enumType = type_cast<EnumType>(alias->type())) {
96-
auto enumSymbol = enumType->symbol();
97-
return qualifiedLookup(enumSymbol, name, accept);
98-
}
99-
100-
if (auto scopedEnumType = type_cast<ScopedEnumType>(alias->type())) {
101-
auto scopedEnumSymbol = scopedEnumType->symbol();
102-
return qualifiedLookup(scopedEnumSymbol, name, accept);
103-
}
104-
105-
return nullptr;
106-
}
107-
108-
default:
109-
return nullptr;
110-
} // switch
111-
}
112-
113-
auto Lookup::lookup(NestedNameSpecifierAST* nestedNameSpecifier,
114-
const Name* name,
115-
const std::function<bool(Symbol*)>& accept) const
116-
-> Symbol* {
117-
if (!name) return nullptr;
118-
if (!nestedNameSpecifier) return unqualifiedLookup(name, accept);
119-
if (!nestedNameSpecifier->symbol) return nullptr;
120-
return qualifiedLookup(nestedNameSpecifier->symbol, name, accept);
121-
}
122-
123-
auto Lookup::lookupHelper(ScopeSymbol* scope, const Name* name,
124-
std::unordered_set<ScopeSymbol*>& cache,
125-
const std::function<bool(Symbol*)>& accept) const
126-
-> Symbol* {
127-
if (cache.contains(scope)) {
128-
return nullptr;
129-
}
130-
131-
cache.insert(scope);
132-
133-
for (auto symbol : scope->find(name)) {
134-
if (auto u = symbol_cast<UsingDeclarationSymbol>(symbol);
135-
u && u->target()) {
136-
if (!accept || accept(u->target())) {
137-
return u->target();
138-
}
139-
}
140-
141-
if (!accept || accept(symbol)) {
142-
return symbol;
143-
}
144-
}
145-
146-
if (auto classSymbol = symbol_cast<ClassSymbol>(scope)) {
147-
// iterate over the annonymous symbols
148-
for (auto member : classSymbol->find(/*unnamed=*/nullptr)) {
149-
auto nestedClass = symbol_cast<ClassSymbol>(member);
150-
if (!nestedClass) continue;
151-
152-
auto symbol = lookupHelper(nestedClass, name, cache, accept);
153-
if (symbol) {
154-
// found a match in an anonymous nested class
155-
return symbol;
156-
}
157-
}
158-
159-
for (const auto& base : classSymbol->baseClasses()) {
160-
auto baseClass = symbol_cast<ClassSymbol>(base->symbol());
161-
if (!baseClass) continue;
162-
if (auto symbol = lookupHelper(baseClass, name, cache, accept)) {
163-
return symbol;
164-
}
165-
}
166-
}
167-
168-
for (auto u : scope->usingDirectives()) {
169-
if (auto symbol = lookupHelper(u, name, cache, accept)) {
170-
return symbol;
171-
}
172-
}
173-
174-
return nullptr;
175-
}
176-
17734
auto Lookup::lookupNamespace(NestedNameSpecifierAST* nestedNameSpecifier,
17835
const Identifier* id) const -> NamespaceSymbol* {
179-
std::unordered_set<ScopeSymbol*> set;
36+
std::vector<ScopeSymbol*> set;
18037

18138
if (!nestedNameSpecifier) {
18239
// unqualified lookup, start with the current scope and go up.
@@ -197,12 +54,14 @@ auto Lookup::lookupNamespace(NestedNameSpecifierAST* nestedNameSpecifier,
19754
}
19855

19956
auto Lookup::lookupNamespaceHelper(ScopeSymbol* scope, const Identifier* id,
200-
std::unordered_set<ScopeSymbol*>& set) const
57+
std::vector<ScopeSymbol*>& set) const
20158
-> NamespaceSymbol* {
202-
if (!set.insert(scope).second) {
59+
if (std::ranges::contains(set, scope)) {
20360
return nullptr;
20461
}
20562

63+
set.push_back(scope);
64+
20665
for (auto candidate : scope->find(id) | views::namespaces) {
20766
return candidate;
20867
}
@@ -218,7 +77,7 @@ auto Lookup::lookupNamespaceHelper(ScopeSymbol* scope, const Identifier* id,
21877

21978
auto Lookup::lookupType(NestedNameSpecifierAST* nestedNameSpecifier,
22079
const Identifier* id) const -> Symbol* {
221-
std::unordered_set<ScopeSymbol*> set;
80+
std::vector<ScopeSymbol*> set;
22281

22382
if (!nestedNameSpecifier) {
22483
// unqualified lookup, start with the current scope and go up.
@@ -282,12 +141,13 @@ auto Lookup::lookupType(NestedNameSpecifierAST* nestedNameSpecifier,
282141
}
283142

284143
auto Lookup::lookupTypeHelper(ScopeSymbol* scope, const Identifier* id,
285-
std::unordered_set<ScopeSymbol*>& set) const
286-
-> Symbol* {
287-
if (!set.insert(scope).second) {
144+
std::vector<ScopeSymbol*>& set) const -> Symbol* {
145+
if (std::ranges::contains(set, scope)) {
288146
return nullptr;
289147
}
290148

149+
set.push_back(scope);
150+
291151
for (auto candidate : scope->find(id)) {
292152
if (auto u = symbol_cast<UsingDeclarationSymbol>(candidate);
293153
u && u->target()) {

0 commit comments

Comments
 (0)