@@ -151,8 +151,8 @@ GetTypeAlias(swift::Demangle::Demangler &dem,
151
151
}
152
152
153
153
// / Find a Clang type by name in the modules in \p module_holder.
154
- TypeSP TypeSystemSwiftTypeRef::LookupClangType (StringRef name ) {
155
- auto lookup = [](Module &M, StringRef name) -> TypeSP {
154
+ TypeSP TypeSystemSwiftTypeRef::LookupClangType (StringRef name_ref ) {
155
+ auto lookup = [](Module &M, ConstString name) -> TypeSP {
156
156
llvm::SmallVector<CompilerContext, 2 > decl_context;
157
157
decl_context.push_back ({CompilerContextKind::AnyModule, ConstString ()});
158
158
decl_context.push_back ({CompilerContextKind::AnyType, ConstString (name)});
@@ -164,18 +164,33 @@ TypeSP TypeSystemSwiftTypeRef::LookupClangType(StringRef name) {
164
164
return {};
165
165
return clang_types.GetTypeAtIndex (0 );
166
166
};
167
- if (auto *M = GetModule ())
168
- return lookup (*M, name);
167
+
168
+ // Check the cache first. Negative results are also cached.
169
+ TypeSP result;
170
+ ConstString name (name_ref);
171
+ if (m_clang_type_cache.Lookup (name.AsCString (), result))
172
+ return result;
173
+
174
+ if (auto *M = GetModule ()) {
175
+ TypeSP result = lookup (*M, name);
176
+ // Cache it.
177
+ m_clang_type_cache.Insert (name.AsCString (), result);
178
+ return result;
179
+ }
169
180
170
181
SwiftASTContext *target_holder = GetSwiftASTContext ();
171
182
if (!target_holder)
172
183
return {};
173
184
TargetSP target_sp = target_holder->GetTarget ().lock ();
174
185
if (!target_sp)
175
186
return {};
176
- TypeSP result;
177
187
target_sp->GetImages ().ForEach ([&](const ModuleSP &module) -> bool {
188
+ // Don't recursively call into LookupClangTypes() to avoid filling
189
+ // hundreds of image caches with negative results.
178
190
result = lookup (const_cast <Module &>(*module), name);
191
+ // Cache it in the expression context.
192
+ if (result)
193
+ m_clang_type_cache.Insert (name.AsCString (), result);
179
194
return !result;
180
195
});
181
196
return result;
0 commit comments