@@ -945,39 +945,50 @@ namespace {
945
945
template <>
946
946
struct OperatorLookup <PrefixOperatorDecl> {
947
947
constexpr static auto map_ptr = &SourceFile::PrefixOperators;
948
- template <typename T>
949
- static PrefixOperatorDecl *lookup (T &container, Identifier name) {
950
- return cast_or_null<PrefixOperatorDecl>(
951
- container.lookupOperator (name, OperatorFixity::Prefix));
948
+ static PrefixOperatorDecl *lookup (Evaluator &eval,
949
+ const OperatorLookupDescriptor &desc) {
950
+ // We can return the first prefix operator. All prefix operators of the
951
+ // same name are equivalent.
952
+ DirectOperatorLookupRequest req{desc, OperatorFixity::Prefix};
953
+ auto results = evaluateOrDefault (eval, req, {});
954
+ return results.empty () ? nullptr : cast<PrefixOperatorDecl>(results[0 ]);
952
955
}
953
956
};
954
957
955
958
template <>
956
959
struct OperatorLookup <InfixOperatorDecl> {
957
960
constexpr static auto map_ptr = &SourceFile::InfixOperators;
958
- template <typename T>
959
- static InfixOperatorDecl *lookup (T &container, Identifier name) {
960
- return cast_or_null<InfixOperatorDecl>(
961
- container.lookupOperator (name, OperatorFixity::Infix));
961
+ static InfixOperatorDecl *lookup (Evaluator &eval,
962
+ const OperatorLookupDescriptor &desc) {
963
+ // Return the first result if it exists.
964
+ DirectOperatorLookupRequest req{desc, OperatorFixity::Infix};
965
+ auto results = evaluateOrDefault (eval, req, {});
966
+ return results.empty () ? nullptr : cast<InfixOperatorDecl>(results[0 ]);
962
967
}
963
968
};
964
969
965
970
template <>
966
971
struct OperatorLookup <PostfixOperatorDecl> {
967
972
constexpr static auto map_ptr = &SourceFile::PostfixOperators;
968
- template <typename T>
969
- static PostfixOperatorDecl *lookup (T &container, Identifier name) {
970
- return cast_or_null<PostfixOperatorDecl>(
971
- container.lookupOperator (name, OperatorFixity::Postfix));
973
+ static PostfixOperatorDecl *lookup (Evaluator &eval,
974
+ const OperatorLookupDescriptor &desc) {
975
+ // We can return the first postfix operator. All postfix operators of the
976
+ // same name are equivalent.
977
+ DirectOperatorLookupRequest req{desc, OperatorFixity::Postfix};
978
+ auto results = evaluateOrDefault (eval, req, {});
979
+ return results.empty () ? nullptr : cast<PostfixOperatorDecl>(results[0 ]);
972
980
}
973
981
};
974
982
975
983
template <>
976
984
struct OperatorLookup <PrecedenceGroupDecl> {
977
985
constexpr static auto map_ptr = &SourceFile::PrecedenceGroups;
978
- template <typename T>
979
- static PrecedenceGroupDecl *lookup (T &container, Identifier name) {
980
- return container.lookupPrecedenceGroup (name);
986
+ static PrecedenceGroupDecl *lookup (Evaluator &eval,
987
+ const OperatorLookupDescriptor &desc) {
988
+ // Return the first result if it exists.
989
+ auto results =
990
+ evaluateOrDefault (eval, DirectPrecedenceGroupLookupRequest{desc}, {});
991
+ return results.empty () ? nullptr : results[0 ];
981
992
}
982
993
};
983
994
} // end anonymous namespace
@@ -1014,7 +1025,8 @@ void SourceFile::setSyntaxRoot(syntax::SourceFileSyntax &&Root) {
1014
1025
1015
1026
template <typename OP_DECL>
1016
1027
static Optional<OP_DECL *>
1017
- lookupOperatorDeclForName (ModuleDecl *M, SourceLoc Loc, Identifier Name);
1028
+ lookupOperatorDeclForName (ModuleDecl *M, SourceLoc Loc, Identifier Name,
1029
+ bool isCascading);
1018
1030
1019
1031
template <typename OP_DECL>
1020
1032
using ImportedOperatorsMap = llvm::SmallDenseMap<OP_DECL*, bool , 16 >;
@@ -1063,7 +1075,8 @@ checkOperatorConflicts(const SourceFile &SF, SourceLoc loc,
1063
1075
template <typename OP_DECL>
1064
1076
static Optional<OP_DECL *>
1065
1077
lookupOperatorDeclForName (const FileUnit &File, SourceLoc Loc,
1066
- Identifier Name, bool includePrivate) {
1078
+ Identifier Name, bool includePrivate,
1079
+ bool isCascading) {
1067
1080
switch (File.getKind ()) {
1068
1081
case FileUnitKind::Builtin:
1069
1082
// The Builtin module declares no operators.
@@ -1072,8 +1085,13 @@ lookupOperatorDeclForName(const FileUnit &File, SourceLoc Loc,
1072
1085
break ;
1073
1086
case FileUnitKind::SerializedAST:
1074
1087
case FileUnitKind::ClangModule:
1075
- case FileUnitKind::DWARFModule:
1076
- return OperatorLookup<OP_DECL>::lookup (cast<LoadedFile>(File), Name);
1088
+ case FileUnitKind::DWARFModule: {
1089
+ auto &eval = File.getASTContext ().evaluator ;
1090
+ auto desc = OperatorLookupDescriptor::forFile (const_cast <FileUnit *>(&File),
1091
+ Name, isCascading,
1092
+ /* diagLoc*/ SourceLoc ());
1093
+ return OperatorLookup<OP_DECL>::lookup (eval, desc);
1094
+ }
1077
1095
}
1078
1096
1079
1097
auto &SF = cast<SourceFile>(File);
@@ -1102,7 +1120,8 @@ lookupOperatorDeclForName(const FileUnit &File, SourceLoc Loc,
1102
1120
continue ;
1103
1121
1104
1122
Optional<OP_DECL *> maybeOp =
1105
- lookupOperatorDeclForName<OP_DECL>(imported.module .second , Loc, Name);
1123
+ lookupOperatorDeclForName<OP_DECL>(imported.module .second , Loc, Name,
1124
+ isCascading);
1106
1125
if (!maybeOp)
1107
1126
return None;
1108
1127
@@ -1135,10 +1154,12 @@ lookupOperatorDeclForName(const FileUnit &File, SourceLoc Loc,
1135
1154
1136
1155
template <typename OP_DECL>
1137
1156
static Optional<OP_DECL *>
1138
- lookupOperatorDeclForName (ModuleDecl *M, SourceLoc Loc, Identifier Name) {
1157
+ lookupOperatorDeclForName (ModuleDecl *M, SourceLoc Loc, Identifier Name,
1158
+ bool isCascading) {
1139
1159
OP_DECL *result = nullptr ;
1140
1160
for (const FileUnit *File : M->getFiles ()) {
1141
- auto next = lookupOperatorDeclForName<OP_DECL>(*File, Loc, Name, false );
1161
+ auto next = lookupOperatorDeclForName<OP_DECL>(*File, Loc, Name, false ,
1162
+ isCascading);
1142
1163
if (!next.hasValue ())
1143
1164
return next;
1144
1165
@@ -1155,9 +1176,10 @@ template <typename OperatorType>
1155
1176
llvm::Expected<OperatorType *> LookupOperatorRequest<OperatorType>::evaluate(
1156
1177
Evaluator &evaluator, OperatorLookupDescriptor desc) const {
1157
1178
auto *file = desc.fileOrModule .get <FileUnit *>();
1158
- auto result = lookupOperatorDeclForName<OperatorType>(*file, desc.diagLoc ,
1159
- desc.name ,
1160
- /* includePrivate*/ true );
1179
+ auto result =
1180
+ lookupOperatorDeclForName<OperatorType>(*file, desc.diagLoc , desc.name ,
1181
+ /* includePrivate*/ true ,
1182
+ desc.isCascading );
1161
1183
if (!result.hasValue ())
1162
1184
return nullptr ;
1163
1185
@@ -1167,16 +1189,17 @@ llvm::Expected<OperatorType *> LookupOperatorRequest<OperatorType>::evaluate(
1167
1189
}
1168
1190
if (!result.getValue ()) {
1169
1191
result = lookupOperatorDeclForName<OperatorType>(file->getParentModule (),
1170
- desc.diagLoc , desc.name );
1192
+ desc.diagLoc , desc.name ,
1193
+ desc.isCascading );
1171
1194
}
1172
1195
return result.hasValue () ? result.getValue () : nullptr ;
1173
1196
}
1174
1197
1175
-
1176
1198
#define LOOKUP_OPERATOR (Kind ) \
1177
1199
Kind##Decl *ModuleDecl::lookup##Kind(Identifier name, SourceLoc loc) { \
1178
1200
auto result = \
1179
- lookupOperatorDeclForName<Kind##Decl>(this , loc, name); \
1201
+ lookupOperatorDeclForName<Kind##Decl>(this , loc, name, \
1202
+ /* isCascading*/ false ); \
1180
1203
return result ? *result : nullptr ; \
1181
1204
} \
1182
1205
template llvm::Expected<Kind##Decl *> \
@@ -1189,6 +1212,75 @@ LOOKUP_OPERATOR(PostfixOperator)
1189
1212
LOOKUP_OPERATOR(PrecedenceGroup)
1190
1213
#undef LOOKUP_OPERATOR
1191
1214
1215
+ llvm::Expected<TinyPtrVector<OperatorDecl *>>
1216
+ DirectOperatorLookupRequest::evaluate (Evaluator &evaluator,
1217
+ OperatorLookupDescriptor descriptor,
1218
+ OperatorFixity fixity) const {
1219
+ // Query each file.
1220
+ // TODO: Module-level caching.
1221
+ TinyPtrVector<OperatorDecl *> results;
1222
+ for (auto *file : descriptor.getFiles ())
1223
+ file->lookupOperatorDirect (descriptor.name , fixity, results);
1224
+
1225
+ return std::move (results);
1226
+ }
1227
+
1228
+ void SourceFile::lookupOperatorDirect (
1229
+ Identifier name, OperatorFixity fixity,
1230
+ TinyPtrVector<OperatorDecl *> &results) const {
1231
+ OperatorDecl *op = nullptr ;
1232
+ switch (fixity) {
1233
+ case OperatorFixity::Infix: {
1234
+ auto result = InfixOperators.find (name);
1235
+ if (result != InfixOperators.end ())
1236
+ op = result->second .getPointer ();
1237
+ break ;
1238
+ }
1239
+ case OperatorFixity::Postfix: {
1240
+ auto result = PostfixOperators.find (name);
1241
+ if (result != PostfixOperators.end ())
1242
+ op = result->second .getPointer ();
1243
+ break ;
1244
+ }
1245
+ case OperatorFixity::Prefix: {
1246
+ auto result = PrefixOperators.find (name);
1247
+ if (result != PrefixOperators.end ())
1248
+ op = result->second .getPointer ();
1249
+ break ;
1250
+ }
1251
+ }
1252
+
1253
+ // We currently can use the operator maps to cache lookup results from other
1254
+ // modules. Make sure we only return results from the source file.
1255
+ if (op && op->getDeclContext ()->getParentSourceFile () == this )
1256
+ results.push_back (op);
1257
+ }
1258
+
1259
+ llvm::Expected<TinyPtrVector<PrecedenceGroupDecl *>>
1260
+ DirectPrecedenceGroupLookupRequest::evaluate (
1261
+ Evaluator &evaluator, OperatorLookupDescriptor descriptor) const {
1262
+ // Query each file.
1263
+ // TODO: Module-level caching.
1264
+ TinyPtrVector<PrecedenceGroupDecl *> results;
1265
+ for (auto *file : descriptor.getFiles ())
1266
+ file->lookupPrecedenceGroupDirect (descriptor.name , results);
1267
+
1268
+ return std::move (results);
1269
+ }
1270
+
1271
+ void SourceFile::lookupPrecedenceGroupDirect (
1272
+ Identifier name, TinyPtrVector<PrecedenceGroupDecl *> &results) const {
1273
+ auto result = PrecedenceGroups.find (name);
1274
+ if (result == PrecedenceGroups.end ())
1275
+ return ;
1276
+
1277
+ // We currently can use the operator maps to cache lookup results from other
1278
+ // modules. Make sure we only return results from the source file.
1279
+ auto *group = result->second .getPointer ();
1280
+ if (group->getDeclContext ()->getParentSourceFile () == this )
1281
+ results.push_back (group);
1282
+ }
1283
+
1192
1284
void ModuleDecl::getImportedModules (SmallVectorImpl<ImportedModule> &modules,
1193
1285
ModuleDecl::ImportFilter filter) const {
1194
1286
FORWARD (getImportedModules, (modules, filter));
0 commit comments