@@ -1026,9 +1026,6 @@ LookupConformanceInModuleRequest::evaluate(
1026
1026
}
1027
1027
1028
1028
namespace {
1029
- template <typename T>
1030
- using OperatorMap = SourceFile::OperatorMap<T>;
1031
-
1032
1029
template <typename T>
1033
1030
struct OperatorLookup {
1034
1031
// Don't fold this into the static_assert: this would trigger an MSVC bug
@@ -1039,7 +1036,6 @@ namespace {
1039
1036
1040
1037
template <>
1041
1038
struct OperatorLookup <PrefixOperatorDecl> {
1042
- constexpr static auto map_ptr = &SourceFile::PrefixOperators;
1043
1039
static PrefixOperatorDecl *lookup (Evaluator &eval,
1044
1040
const OperatorLookupDescriptor &desc) {
1045
1041
// We can return the first prefix operator. All prefix operators of the
@@ -1052,7 +1048,6 @@ namespace {
1052
1048
1053
1049
template <>
1054
1050
struct OperatorLookup <InfixOperatorDecl> {
1055
- constexpr static auto map_ptr = &SourceFile::InfixOperators;
1056
1051
static InfixOperatorDecl *lookup (Evaluator &eval,
1057
1052
const OperatorLookupDescriptor &desc) {
1058
1053
// Return the first result if it exists.
@@ -1064,7 +1059,6 @@ namespace {
1064
1059
1065
1060
template <>
1066
1061
struct OperatorLookup <PostfixOperatorDecl> {
1067
- constexpr static auto map_ptr = &SourceFile::PostfixOperators;
1068
1062
static PostfixOperatorDecl *lookup (Evaluator &eval,
1069
1063
const OperatorLookupDescriptor &desc) {
1070
1064
// We can return the first postfix operator. All postfix operators of the
@@ -1077,7 +1071,6 @@ namespace {
1077
1071
1078
1072
template <>
1079
1073
struct OperatorLookup <PrecedenceGroupDecl> {
1080
- constexpr static auto map_ptr = &SourceFile::PrecedenceGroups;
1081
1074
static PrecedenceGroupDecl *lookup (Evaluator &eval,
1082
1075
const OperatorLookupDescriptor &desc) {
1083
1076
// Return the first result if it exists.
@@ -1172,6 +1165,10 @@ static Optional<OP_DECL *>
1172
1165
lookupOperatorDeclForName (const FileUnit &File, SourceLoc Loc,
1173
1166
Identifier Name, bool includePrivate,
1174
1167
bool isCascading) {
1168
+ auto &eval = File.getASTContext ().evaluator ;
1169
+ auto desc = OperatorLookupDescriptor::forFile (const_cast <FileUnit *>(&File),
1170
+ Name, isCascading,
1171
+ /* diagLoc*/ SourceLoc ());
1175
1172
switch (File.getKind ()) {
1176
1173
case FileUnitKind::Builtin:
1177
1174
// The Builtin module declares no operators.
@@ -1180,23 +1177,16 @@ lookupOperatorDeclForName(const FileUnit &File, SourceLoc Loc,
1180
1177
break ;
1181
1178
case FileUnitKind::SerializedAST:
1182
1179
case FileUnitKind::ClangModule:
1183
- case FileUnitKind::DWARFModule: {
1184
- auto &eval = File.getASTContext ().evaluator ;
1185
- auto desc = OperatorLookupDescriptor::forFile (const_cast <FileUnit *>(&File),
1186
- Name, isCascading,
1187
- /* diagLoc*/ SourceLoc ());
1180
+ case FileUnitKind::DWARFModule:
1188
1181
return OperatorLookup<OP_DECL>::lookup (eval, desc);
1189
1182
}
1190
- }
1191
1183
1192
1184
auto &SF = cast<SourceFile>(File);
1193
1185
assert (SF.ASTStage >= SourceFile::NameBound);
1194
1186
1195
- // Look for an operator declaration in the current module.
1196
- const auto OP_MAP = OperatorLookup<OP_DECL>::map_ptr;
1197
- auto found = (SF.*OP_MAP).find (Name);
1198
- if (found != (SF.*OP_MAP).end () && (includePrivate || found->second .getInt ()))
1199
- return found->second .getPointer ();
1187
+ // Check if the decl exists on the file.
1188
+ if (auto *op = OperatorLookup<OP_DECL>::lookup (eval, desc))
1189
+ return op;
1200
1190
1201
1191
// Look for imported operator decls.
1202
1192
// Record whether they come from re-exported modules.
@@ -1224,24 +1214,16 @@ lookupOperatorDeclForName(const FileUnit &File, SourceLoc Loc,
1224
1214
importedOperators[op] |= isExported;
1225
1215
}
1226
1216
1227
- typename OperatorMap<OP_DECL *>::mapped_type result = { nullptr , true };
1228
-
1217
+ llvm::PointerIntPair<OP_DECL *, 1 , /* isPrivate*/ bool > result = {nullptr ,
1218
+ true };
1219
+
1229
1220
if (!importedOperators.empty ()) {
1230
1221
auto start = checkOperatorConflicts (SF, Loc, importedOperators);
1231
1222
if (start == importedOperators.end ())
1232
1223
return None;
1233
1224
result = { start->first , start->second };
1234
1225
}
1235
1226
1236
- if (includePrivate) {
1237
- // Cache the mapping so we don't need to troll imports next time.
1238
- // It's not safe to cache the non-private results because we didn't search
1239
- // private imports there, but in most non-private cases the result will
1240
- // be cached in the final lookup.
1241
- auto &mutableOpMap = const_cast <OperatorMap<OP_DECL *> &>(SF.*OP_MAP);
1242
- mutableOpMap[Name] = result;
1243
- }
1244
-
1245
1227
if (includePrivate || result.getInt ())
1246
1228
return result.getPointer ();
1247
1229
return nullptr ;
@@ -1311,9 +1293,18 @@ TinyPtrVector<OperatorDecl *>
1311
1293
DirectOperatorLookupRequest::evaluate (Evaluator &evaluator,
1312
1294
OperatorLookupDescriptor descriptor,
1313
1295
OperatorFixity fixity) const {
1314
- // Query each file.
1315
- // TODO: Module-level caching .
1296
+ // For a parsed module, we can check the source cache on the module rather
1297
+ // than doing an O(N) search over the source files .
1316
1298
TinyPtrVector<OperatorDecl *> results;
1299
+ if (auto module = descriptor.getModule ()) {
1300
+ if (isParsedModule (module )) {
1301
+ module ->getSourceLookupCache ().lookupOperator (descriptor.name , fixity,
1302
+ results);
1303
+ return results;
1304
+ }
1305
+ }
1306
+
1307
+ // Otherwise query each file.
1317
1308
for (auto *file : descriptor.getFiles ())
1318
1309
file->lookupOperatorDirect (descriptor.name , fixity, results);
1319
1310
@@ -1323,40 +1314,24 @@ DirectOperatorLookupRequest::evaluate(Evaluator &evaluator,
1323
1314
void SourceFile::lookupOperatorDirect (
1324
1315
Identifier name, OperatorFixity fixity,
1325
1316
TinyPtrVector<OperatorDecl *> &results) const {
1326
- OperatorDecl *op = nullptr ;
1327
- switch (fixity) {
1328
- case OperatorFixity::Infix: {
1329
- auto result = InfixOperators.find (name);
1330
- if (result != InfixOperators.end ())
1331
- op = result->second .getPointer ();
1332
- break ;
1333
- }
1334
- case OperatorFixity::Postfix: {
1335
- auto result = PostfixOperators.find (name);
1336
- if (result != PostfixOperators.end ())
1337
- op = result->second .getPointer ();
1338
- break ;
1339
- }
1340
- case OperatorFixity::Prefix: {
1341
- auto result = PrefixOperators.find (name);
1342
- if (result != PrefixOperators.end ())
1343
- op = result->second .getPointer ();
1344
- break ;
1345
- }
1346
- }
1347
-
1348
- // We currently can use the operator maps to cache lookup results from other
1349
- // modules. Make sure we only return results from the source file.
1350
- if (op && op->getDeclContext ()->getParentSourceFile () == this )
1351
- results.push_back (op);
1317
+ getCache ().lookupOperator (name, fixity, results);
1352
1318
}
1353
1319
1354
1320
TinyPtrVector<PrecedenceGroupDecl *>
1355
1321
DirectPrecedenceGroupLookupRequest::evaluate (
1356
1322
Evaluator &evaluator, OperatorLookupDescriptor descriptor) const {
1357
- // Query each file.
1358
- // TODO: Module-level caching .
1323
+ // For a parsed module, we can check the source cache on the module rather
1324
+ // than doing an O(N) search over the source files .
1359
1325
TinyPtrVector<PrecedenceGroupDecl *> results;
1326
+ if (auto module = descriptor.getModule ()) {
1327
+ if (isParsedModule (module )) {
1328
+ module ->getSourceLookupCache ().lookupPrecedenceGroup (descriptor.name ,
1329
+ results);
1330
+ return results;
1331
+ }
1332
+ }
1333
+
1334
+ // Otherwise query each file.
1360
1335
for (auto *file : descriptor.getFiles ())
1361
1336
file->lookupPrecedenceGroupDirect (descriptor.name , results);
1362
1337
@@ -1365,15 +1340,7 @@ DirectPrecedenceGroupLookupRequest::evaluate(
1365
1340
1366
1341
void SourceFile::lookupPrecedenceGroupDirect (
1367
1342
Identifier name, TinyPtrVector<PrecedenceGroupDecl *> &results) const {
1368
- auto result = PrecedenceGroups.find (name);
1369
- if (result == PrecedenceGroups.end ())
1370
- return ;
1371
-
1372
- // We currently can use the operator maps to cache lookup results from other
1373
- // modules. Make sure we only return results from the source file.
1374
- auto *group = result->second .getPointer ();
1375
- if (group->getDeclContext ()->getParentSourceFile () == this )
1376
- results.push_back (group);
1343
+ getCache ().lookupPrecedenceGroup (name, results);
1377
1344
}
1378
1345
1379
1346
void ModuleDecl::getImportedModules (SmallVectorImpl<ImportedModule> &modules,
0 commit comments