@@ -564,6 +564,72 @@ DerivedArgList *Driver::TranslateInputArgs(const InputArgList &Args) const {
564564 return DAL;
565565}
566566
567+ static void setZosTargetVersion (const Driver &D, llvm::Triple &Target,
568+ StringRef ArgTarget) {
569+
570+ static bool BeSilent = false ;
571+ auto IsTooOldToBeSupported = [](int v, int r) -> bool {
572+ return ((v < 2 ) || ((v == 2 ) && (r < 4 )));
573+ };
574+
575+ /* expect CURRENT, zOSV2R[45], or 0xnnnnnnnn */
576+ if (ArgTarget.equals_insensitive (" CURRENT" )) {
577+ /* If the user gives CURRENT, then we rely on the LE to set */
578+ /* __TARGET_LIB__. There's nothing more we need to do. */
579+ } else {
580+ unsigned int Version = 0 ;
581+ unsigned int Release = 0 ;
582+ unsigned int Modification = 0 ;
583+ bool IsOk = true ;
584+ llvm::Regex ZOsvRegex (" [zZ][oO][sS][vV]([0-9])[rR]([0-9])" );
585+ llvm::Regex HexRegex (
586+ " 0x4" /* product */
587+ " ([0-9a-fA-F])" /* version */
588+ " ([0-9a-fA-F][0-9a-fA-F])" /* release */
589+ " ([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])" /* modification */ );
590+ SmallVector<StringRef> Matches;
591+
592+ if (ZOsvRegex.match (ArgTarget, &Matches)) {
593+ Matches[1 ].getAsInteger (10 , Version);
594+ Matches[2 ].getAsInteger (10 , Release);
595+ Modification = 0 ;
596+ if (IsTooOldToBeSupported (Version, Release)) {
597+ if (!BeSilent)
598+ D.Diag (diag::err_zos_target_release_discontinued) << ArgTarget;
599+ IsOk = false ;
600+ }
601+ } else if (HexRegex.match (ArgTarget, &Matches)) {
602+ Matches[1 ].getAsInteger (16 , Version);
603+ Matches[2 ].getAsInteger (16 , Release);
604+ Matches[3 ].getAsInteger (16 , Modification);
605+ if (IsTooOldToBeSupported (Version, Release)) {
606+ if (!BeSilent)
607+ D.Diag (diag::err_zos_target_release_discontinued) << ArgTarget;
608+ IsOk = false ;
609+ }
610+ } else {
611+ /* something else: need to report an error */
612+ if (!BeSilent)
613+ D.Diag (diag::err_zos_target_unrecognized_release) << ArgTarget;
614+ IsOk = false ;
615+ }
616+
617+ if (IsOk) {
618+ llvm::VersionTuple V (Version, Release, Modification);
619+ llvm::VersionTuple TV = Target.getOSVersion ();
620+ // The goal is to pick the minimally supported version of
621+ // the OS. Pick the lesser as the target.
622+ if (TV.empty () || V < TV) {
623+ SmallString<16 > Str;
624+ Str = llvm::Triple::getOSTypeName (Target.getOS ());
625+ Str += V.getAsString ();
626+ Target.setOSName (Str);
627+ }
628+ }
629+ }
630+ BeSilent = true ;
631+ }
632+
567633// / Compute target triple from args.
568634// /
569635// / This routine provides the logic to compute a target triple from various
@@ -689,6 +755,12 @@ static llvm::Triple computeTargetTriple(const Driver &D,
689755 }
690756 }
691757
758+ if (Target.isOSzOS ()) {
759+ if ((A = Args.getLastArg (options::OPT_mzos_target_EQ))) {
760+ setZosTargetVersion (D, Target, A->getValue ());
761+ }
762+ }
763+
692764 // Handle -miamcu flag.
693765 if (Args.hasFlag (options::OPT_miamcu, options::OPT_mno_iamcu, false )) {
694766 if (Target.get32BitArchVariant ().getArch () != llvm::Triple::x86)
0 commit comments