@@ -36,6 +36,7 @@ Optional<PlatformConditionKind> getPlatformConditionKind(StringRef Name) {
3636 .Case (" arch" , PlatformConditionKind::Arch)
3737 .Case (" _endian" , PlatformConditionKind::Endianness)
3838 .Case (" _runtime" , PlatformConditionKind::Runtime)
39+ .Case (" canImport" , PlatformConditionKind::CanImport)
3940 .Default (None);
4041}
4142
@@ -289,7 +290,7 @@ class ValidateIfConfigCondition :
289290 return E;
290291 }
291292
292- // ( 'os' | 'arch' | '_endian' | '_runtime' ) '(' identifier ')''
293+ // ( 'os' | 'arch' | '_endian' | '_runtime' | 'canImport' ) '(' identifier ')''
293294 auto Kind = getPlatformConditionKind (*KindName);
294295 if (!Kind.hasValue ()) {
295296 D.diagnose (E->getLoc (), diag::unsupported_platform_condition_expression);
@@ -331,6 +332,8 @@ class ValidateIfConfigCondition :
331332 DiagName = " architecture" ; break ;
332333 case PlatformConditionKind::Endianness:
333334 DiagName = " endianness" ; break ;
335+ case PlatformConditionKind::CanImport:
336+ DiagName = " import conditional" ; break ;
334337 case PlatformConditionKind::Runtime:
335338 llvm_unreachable (" handled above" );
336339 }
@@ -450,6 +453,9 @@ class EvaluateIfConfigCondition :
450453 Str, SourceLoc (), nullptr ).getValue ();
451454 auto thisVersion = Ctx.LangOpts .EffectiveLanguageVersion ;
452455 return thisVersion >= Val;
456+ } else if (KindName == " canImport" ) {
457+ auto Str = extractExprSource (Ctx.SourceMgr , Arg);
458+ return Ctx.canImportModule ({ Ctx.getIdentifier (Str) , E->getLoc () });
453459 }
454460
455461 auto Val = getDeclRefStr (Arg);
@@ -567,9 +573,10 @@ ParserResult<IfConfigDecl> Parser::parseIfConfig(
567573 Expr *Condition = nullptr ;
568574 bool isActive = false ;
569575
570- // Parse and evaluate the directive.
576+ // Parse the condition. Evaluate it to determine the active
577+ // clause unless we're doing a parse-only pass.
571578 if (isElse) {
572- isActive = !foundActive;
579+ isActive = !foundActive && State-> PerformConditionEvaluation ;
573580 } else {
574581 llvm::SaveAndRestore<bool > S (InPoundIfEnvironment, true );
575582 ParserResult<Expr> Result = parseExprSequence (diag::expected_expr,
@@ -582,8 +589,9 @@ ParserResult<IfConfigDecl> Parser::parseIfConfig(
582589 // Error in the condition;
583590 isActive = false ;
584591 isVersionCondition = false ;
585- } else if (!foundActive) {
586- // Evaluate the condition only if we haven't found any active one.
592+ } else if (!foundActive && State->PerformConditionEvaluation ) {
593+ // Evaluate the condition only if we haven't found any active one and
594+ // we're not in parse-only mode.
587595 isActive = evaluateIfConfigCondition (Condition, Context);
588596 isVersionCondition = isVersionIfConfigCondition (Condition);
589597 }
0 commit comments