@@ -4390,6 +4390,51 @@ checkImplicitPromotionsInCondition(const StmtConditionElement &cond,
4390
4390
}
4391
4391
}
4392
4392
4393
+ // / Diagnoses a `if #_hasSymbol(...)` condition. Returns true if a diagnostic
4394
+ // / was emitted.
4395
+ static bool diagnoseHasSymbolCondition (PoundHasSymbolInfo *info,
4396
+ DeclContext *DC) {
4397
+ // If we have an invalid info, null expression, or expression without a type
4398
+ // then type checking failed already for this condition.
4399
+ if (info->isInvalid ())
4400
+ return false ;
4401
+
4402
+ auto symbolExpr = info->getSymbolExpr ();
4403
+ if (!symbolExpr)
4404
+ return false ;
4405
+
4406
+ if (!symbolExpr->getType ())
4407
+ return false ;
4408
+
4409
+ auto &ctx = DC->getASTContext ();
4410
+ if (!ctx.LangOpts .Target .isOSDarwin ()) {
4411
+ // SILGen for #_hasSymbol is currently implemented assuming the target OS
4412
+ // is a Darwin platform.
4413
+ ctx.Diags .diagnose (info->getStartLoc (), diag::has_symbol_unsupported,
4414
+ ctx.LangOpts .Target .str ());
4415
+ return true ;
4416
+ }
4417
+
4418
+ auto decl = info->getReferencedDecl ().getDecl ();
4419
+ if (!decl) {
4420
+ // Diagnose because we weren't able to interpret the expression as one
4421
+ // that uniquely identifies a single declaration.
4422
+ ctx.Diags .diagnose (symbolExpr->getLoc (), diag::has_symbol_invalid_expr);
4423
+ return true ;
4424
+ }
4425
+
4426
+ if (!decl->isWeakImported (DC->getParentModule ())) {
4427
+ // `if #_hasSymbol(someStronglyLinkedSymbol)` is functionally a no-op
4428
+ // and may indicate the developer has mis-identified the declaration
4429
+ // they want to check (or forgot to import the module weakly).
4430
+ ctx.Diags .diagnose (symbolExpr->getLoc (), diag::has_symbol_decl_must_be_weak,
4431
+ decl->getDescriptiveKind (), decl->getName ());
4432
+ return true ;
4433
+ }
4434
+
4435
+ return false ;
4436
+ }
4437
+
4393
4438
// / Perform MiscDiagnostics for the conditions belonging to a \c
4394
4439
// / LabeledConditionalStmt.
4395
4440
static void checkLabeledStmtConditions (ASTContext &ctx,
@@ -4407,32 +4452,9 @@ static void checkLabeledStmtConditions(ASTContext &ctx,
4407
4452
4408
4453
case StmtConditionElement::CK_HasSymbol: {
4409
4454
auto info = elt.getHasSymbolInfo ();
4410
- if (info->isInvalid ())
4411
- break ;
4412
-
4413
- auto symbolExpr = info->getSymbolExpr ();
4414
- if (!symbolExpr)
4415
- break ;
4416
-
4417
- if (!symbolExpr->getType ())
4418
- break ;
4419
-
4420
- if (auto decl = info->getReferencedDecl ().getDecl ()) {
4421
- // `if #_hasSymbol(someStronglyLinkedSymbol)` is functionally a no-op
4422
- // and may indicate the developer has mis-identified the declaration
4423
- // they want to check (or forgot to import the module weakly).
4424
- if (!decl->isWeakImported (DC->getParentModule ())) {
4425
- ctx.Diags .diagnose (symbolExpr->getLoc (),
4426
- diag::has_symbol_decl_must_be_weak,
4427
- decl->getDescriptiveKind (), decl->getName ());
4428
- info->setInvalid ();
4429
- }
4430
- } else {
4431
- // Diagnose because we weren't able to interpret the expression as one
4432
- // that uniquely identifies a single declaration.
4433
- ctx.Diags .diagnose (symbolExpr->getLoc (), diag::has_symbol_invalid_expr);
4455
+ if (diagnoseHasSymbolCondition (info, DC))
4434
4456
info->setInvalid ();
4435
- }
4457
+
4436
4458
break ;
4437
4459
}
4438
4460
}
0 commit comments