Optional<Version> Version::parseVersionString(StringRef VersionString, SourceLoc Loc, DiagnosticEngine *Diags) { Version TheVersion; SmallString<16> digits; llvm::raw_svector_ostream OS(digits); SmallVector<std::pair<StringRef, SourceRange>, 5> SplitComponents; // Skip over quote character in string literal. if (VersionString.empty()) { if (Diags) Diags->diagnose(Loc, diag::empty_version_string); return None; } splitVersionComponents(SplitComponents, VersionString, Loc, Diags); uint64_t ComponentNumber; bool isValidVersion = true; for (size_t i = 0; i < SplitComponents.size(); ++i) { StringRef SplitComponent; SourceRange Range; std::tie(SplitComponent, Range) = SplitComponents[i]; // Version components can't be empty. if (SplitComponent.empty()) { if (Diags) Diags->diagnose(Range.Start, diag::empty_version_component); isValidVersion = false; continue; } // All other version components must be numbers. if (!SplitComponent.getAsInteger(10, ComponentNumber)) { TheVersion.Components.push_back(ComponentNumber); continue; } else { if (Diags) Diags->diagnose(Range.Start, diag::version_component_not_number); isValidVersion = false; } } return isValidVersion ? Optional<Version>(TheVersion) : None; }
Version Version::parseCompilerVersionString( StringRef VersionString, SourceLoc Loc, DiagnosticEngine *Diags) { Version CV; SmallString<16> digits; llvm::raw_svector_ostream OS(digits); SmallVector<std::pair<StringRef, SourceRange>, 5> SplitComponents; auto checkVersionComponent = [&](unsigned Component, SourceRange Range) { unsigned limit = CV.Components.size() == 0 ? 9223371 : 999; if (Component > limit) { if (Diags) Diags->diagnose(Range.Start, diag::compiler_version_component_out_of_range, limit); else llvm_unreachable("Compiler version component out of range"); } }; splitVersionComponents(SplitComponents, VersionString, Loc, Diags, /*skipQuote=*/true); uint64_t ComponentNumber; for (size_t i = 0; i < SplitComponents.size(); ++i) { StringRef SplitComponent; SourceRange Range; std::tie(SplitComponent, Range) = SplitComponents[i]; // Version components can't be empty. if (SplitComponent.empty()) { if (Diags) Diags->diagnose(Range.Start, diag::empty_version_component); else llvm_unreachable("Found empty compiler version component"); continue; } // The second version component isn't used for comparison. if (i == 1) { if (!SplitComponent.equals("*")) { if (Diags) { Diags->diagnose(Range.Start, diag::unused_compiler_version_component) .fixItReplaceChars(Range.Start, Range.End, "*"); } else { llvm_unreachable("Expected * for second compiler version component"); } } CV.Components.push_back(0); continue; } // All other version components must be numbers. if (!SplitComponent.getAsInteger(10, ComponentNumber)) { checkVersionComponent(ComponentNumber, Range); CV.Components.push_back(ComponentNumber); continue; } else if (Diags) { Diags->diagnose(Range.Start, diag::version_component_not_number); } else { llvm_unreachable("Invalid character in _compiler_version condition"); } } if (CV.Components.size() > 5) { if (Diags) { Diags->diagnose(Loc, diag::compiler_version_too_many_components); } else { llvm_unreachable("Compiler version must not have more than 5 components"); } } return CV; }
Optional<Version> Version::parseCompilerVersionString( StringRef VersionString, SourceLoc Loc, DiagnosticEngine *Diags) { Version CV; SmallString<16> digits; llvm::raw_svector_ostream OS(digits); SmallVector<std::pair<StringRef, SourceRange>, 5> SplitComponents; splitVersionComponents(SplitComponents, VersionString, Loc, /*skipQuote=*/true); uint64_t ComponentNumber; bool isValidVersion = true; auto checkVersionComponent = [&](unsigned Component, SourceRange Range) { unsigned limit = CV.Components.size() == 0 ? 9223371 : 999; if (Component > limit) { if (Diags) Diags->diagnose(Range.Start, diag::compiler_version_component_out_of_range, limit); isValidVersion = false; } }; for (size_t i = 0; i < SplitComponents.size(); ++i) { StringRef SplitComponent; SourceRange Range; std::tie(SplitComponent, Range) = SplitComponents[i]; // Version components can't be empty. if (SplitComponent.empty()) { if (Diags) Diags->diagnose(Range.Start, diag::empty_version_component); isValidVersion = false; continue; } // The second version component isn't used for comparison. if (i == 1) { if (!SplitComponent.equals("*")) { if (Diags) Diags->diagnose(Range.Start, diag::unused_compiler_version_component) .fixItReplaceChars(Range.Start, Range.End, "*"); } CV.Components.push_back(0); continue; } // All other version components must be numbers. if (!SplitComponent.getAsInteger(10, ComponentNumber)) { checkVersionComponent(ComponentNumber, Range); CV.Components.push_back(ComponentNumber); continue; } else { if (Diags) Diags->diagnose(Range.Start, diag::version_component_not_number); isValidVersion = false; } } if (CV.Components.size() > 5) { if (Diags) Diags->diagnose(Loc, diag::compiler_version_too_many_components); isValidVersion = false; } return isValidVersion ? Optional<Version>(CV) : None; }