@@ -1200,17 +1200,23 @@ namespace {
1200
1200
if (!protocol)
1201
1201
return Type ();
1202
1202
1203
- auto openedType = CS.getTypeOfMacroReference (
1204
- ctx.getIdentifier (kind), expr);
1205
- if (!openedType)
1206
- return Type ();
1207
-
1208
- CS.addConstraint (ConstraintKind::LiteralConformsTo, openedType,
1209
- protocol->getDeclaredInterfaceType (),
1210
- CS.getConstraintLocator (expr));
1211
-
1212
- return openedType;
1203
+ auto macroIdent = ctx.getIdentifier (kind);
1204
+ auto macros = lookupMacros (macroIdent, FunctionRefKind::Unapplied);
1205
+ if (!macros.empty ()) {
1206
+ // Introduce an overload set for the macro reference.
1207
+ auto locator = CS.getConstraintLocator (expr);
1208
+ auto macroRefType = Type (CS.createTypeVariable (locator, 0 ));
1209
+ CS.addOverloadSet (macroRefType, macros, CurDC, locator);
1210
+
1211
+ // FIXME: Can this be encoded in the macro definition somehow?
1212
+ CS.addConstraint (ConstraintKind::LiteralConformsTo, macroRefType,
1213
+ protocol->getDeclaredInterfaceType (),
1214
+ CS.getConstraintLocator (expr));
1215
+
1216
+ return macroRefType;
1217
+ }
1213
1218
}
1219
+
1214
1220
// Fall through to use old implementation.
1215
1221
#endif
1216
1222
@@ -3629,41 +3635,72 @@ namespace {
3629
3635
return resultTy;
3630
3636
}
3631
3637
3638
+ // / Lookup all macros with the given macro name.
3639
+ SmallVector<OverloadChoice, 1 >
3640
+ lookupMacros (Identifier macroName, FunctionRefKind functionRefKind) {
3641
+ auto req = MacroLookupRequest{macroName, CS.DC ->getParentModule ()};
3642
+ auto macros = evaluateOrDefault (
3643
+ CS.getASTContext ().evaluator , req, { });
3644
+ if (macros.empty ())
3645
+ return { };
3646
+
3647
+ // FIXME: At some point, we need to check for function-like macros without
3648
+ // arguments and vice-versa.
3649
+
3650
+
3651
+ SmallVector<OverloadChoice, 1 > choices;
3652
+ for (auto macro : macros) {
3653
+ OverloadChoice choice = OverloadChoice (Type (), macro, functionRefKind);
3654
+ choices.push_back (choice);
3655
+ }
3656
+ return choices;
3657
+ }
3658
+
3632
3659
Type visitMacroExpansionExpr (MacroExpansionExpr *expr) {
3633
3660
#if SWIFT_SWIFT_PARSER
3634
3661
auto &ctx = CS.getASTContext ();
3635
3662
if (ctx.LangOpts .hasFeature (Feature::Macros)) {
3663
+ // Look up the macros with this name.
3636
3664
auto macroIdent = expr->getMacroName ().getBaseIdentifier ();
3637
- auto refType = CS.getTypeOfMacroReference (macroIdent, expr);
3638
- if (!refType) {
3665
+ bool isCall = expr->getArgs () != nullptr ;
3666
+ FunctionRefKind functionRefKind = isCall ? FunctionRefKind::SingleApply
3667
+ : FunctionRefKind::Unapplied;
3668
+ auto macros = lookupMacros (macroIdent, functionRefKind);
3669
+ if (macros.empty ()) {
3639
3670
ctx.Diags .diagnose (expr->getMacroNameLoc (), diag::macro_undefined,
3640
3671
macroIdent)
3641
3672
.highlight (expr->getMacroNameLoc ().getSourceRange ());
3642
3673
return Type ();
3643
3674
}
3644
- if (expr->getArgs ()) {
3645
- CS.associateArgumentList (CS.getConstraintLocator (expr), expr->getArgs ());
3646
- // FIXME: Do we have object-like vs. function-like macros?
3647
- if (auto fnType = dyn_cast<FunctionType>(refType.getPointer ())) {
3648
- SmallVector<AnyFunctionType::Param, 8 > params;
3649
- getMatchingParams (expr->getArgs (), params);
3650
-
3651
- Type resultType = CS.createTypeVariable (
3652
- CS.getConstraintLocator (expr, ConstraintLocator::FunctionResult),
3653
- TVO_CanBindToNoEscape);
3654
-
3655
- CS.addConstraint (
3656
- ConstraintKind::ApplicableFunction,
3657
- FunctionType::get (params, resultType),
3658
- fnType,
3659
- CS.getConstraintLocator (
3660
- expr, ConstraintLocator::ApplyFunction));
3661
-
3662
- return resultType;
3663
- }
3664
- }
3665
3675
3666
- return refType;
3676
+ // Introduce an overload set for the macro reference.
3677
+ auto locator = CS.getConstraintLocator (expr);
3678
+ auto macroRefType = Type (CS.createTypeVariable (locator, 0 ));
3679
+ CS.addOverloadSet (macroRefType, macros, CurDC, locator);
3680
+
3681
+ // For non-calls, the type variable is the result.
3682
+ if (!isCall)
3683
+ return macroRefType;
3684
+
3685
+ // For calls, set up the argument list and form the applicable-function
3686
+ // constraint. The result type is the result of that call.
3687
+ CS.associateArgumentList (locator, expr->getArgs ());
3688
+
3689
+ SmallVector<AnyFunctionType::Param, 8 > params;
3690
+ getMatchingParams (expr->getArgs (), params);
3691
+
3692
+ Type resultType = CS.createTypeVariable (
3693
+ CS.getConstraintLocator (expr, ConstraintLocator::FunctionResult),
3694
+ TVO_CanBindToNoEscape);
3695
+
3696
+ CS.addConstraint (
3697
+ ConstraintKind::ApplicableFunction,
3698
+ FunctionType::get (params, resultType),
3699
+ macroRefType,
3700
+ CS.getConstraintLocator (
3701
+ expr, ConstraintLocator::ApplyFunction));
3702
+
3703
+ return resultType;
3667
3704
}
3668
3705
#endif
3669
3706
return Type ();
0 commit comments