Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:55

0001 
0002 //===--- CommandLineSourceLoc.h - Parsing for source locations-*- C++ -*---===//
0003 //
0004 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0005 // See https://llvm.org/LICENSE.txt for license information.
0006 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0007 //
0008 //===----------------------------------------------------------------------===//
0009 //
0010 // Command line parsing for source locations.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_CLANG_FRONTEND_COMMANDLINESOURCELOC_H
0015 #define LLVM_CLANG_FRONTEND_COMMANDLINESOURCELOC_H
0016 
0017 #include "clang/Basic/LLVM.h"
0018 #include "llvm/Support/CommandLine.h"
0019 #include "llvm/Support/raw_ostream.h"
0020 #include <optional>
0021 
0022 namespace clang {
0023 
0024 /// A source location that has been parsed on the command line.
0025 struct ParsedSourceLocation {
0026   std::string FileName;
0027   unsigned Line;
0028   unsigned Column;
0029 
0030 public:
0031   /// Construct a parsed source location from a string; the Filename is empty on
0032   /// error.
0033   static ParsedSourceLocation FromString(StringRef Str) {
0034     ParsedSourceLocation PSL;
0035     std::pair<StringRef, StringRef> ColSplit = Str.rsplit(':');
0036     std::pair<StringRef, StringRef> LineSplit =
0037       ColSplit.first.rsplit(':');
0038 
0039     // If both tail splits were valid integers, return success.
0040     if (!ColSplit.second.getAsInteger(10, PSL.Column) &&
0041         !LineSplit.second.getAsInteger(10, PSL.Line)) {
0042       PSL.FileName = std::string(LineSplit.first);
0043 
0044       // On the command-line, stdin may be specified via "-". Inside the
0045       // compiler, stdin is called "<stdin>".
0046       if (PSL.FileName == "-")
0047         PSL.FileName = "<stdin>";
0048     }
0049 
0050     return PSL;
0051   }
0052 
0053   /// Serialize ParsedSourceLocation back to a string.
0054   std::string ToString() const {
0055     return (llvm::Twine(FileName == "<stdin>" ? "-" : FileName) + ":" +
0056             Twine(Line) + ":" + Twine(Column))
0057         .str();
0058   }
0059 };
0060 
0061 /// A source range that has been parsed on the command line.
0062 struct ParsedSourceRange {
0063   std::string FileName;
0064   /// The starting location of the range. The first element is the line and
0065   /// the second element is the column.
0066   std::pair<unsigned, unsigned> Begin;
0067   /// The ending location of the range. The first element is the line and the
0068   /// second element is the column.
0069   std::pair<unsigned, unsigned> End;
0070 
0071   /// Returns a parsed source range from a string or std::nullopt if the string
0072   /// is invalid.
0073   ///
0074   /// These source string has the following format:
0075   ///
0076   /// file:start_line:start_column[-end_line:end_column]
0077   ///
0078   /// If the end line and column are omitted, the starting line and columns
0079   /// are used as the end values.
0080   static std::optional<ParsedSourceRange> fromString(StringRef Str) {
0081     std::pair<StringRef, StringRef> RangeSplit = Str.rsplit('-');
0082     unsigned EndLine, EndColumn;
0083     bool HasEndLoc = false;
0084     if (!RangeSplit.second.empty()) {
0085       std::pair<StringRef, StringRef> Split = RangeSplit.second.rsplit(':');
0086       if (Split.first.getAsInteger(10, EndLine) ||
0087           Split.second.getAsInteger(10, EndColumn)) {
0088         // The string does not end in end_line:end_column, so the '-'
0089         // probably belongs to the filename which menas the whole
0090         // string should be parsed.
0091         RangeSplit.first = Str;
0092       } else
0093         HasEndLoc = true;
0094     }
0095     auto Begin = ParsedSourceLocation::FromString(RangeSplit.first);
0096     if (Begin.FileName.empty())
0097       return std::nullopt;
0098     if (!HasEndLoc) {
0099       EndLine = Begin.Line;
0100       EndColumn = Begin.Column;
0101     }
0102     return ParsedSourceRange{std::move(Begin.FileName),
0103                              {Begin.Line, Begin.Column},
0104                              {EndLine, EndColumn}};
0105   }
0106 };
0107 }
0108 
0109 namespace llvm {
0110   namespace cl {
0111     /// Command-line option parser that parses source locations.
0112     ///
0113     /// Source locations are of the form filename:line:column.
0114     template<>
0115     class parser<clang::ParsedSourceLocation> final
0116       : public basic_parser<clang::ParsedSourceLocation> {
0117     public:
0118       inline bool parse(Option &O, StringRef ArgName, StringRef ArgValue,
0119                  clang::ParsedSourceLocation &Val);
0120     };
0121 
0122     bool
0123     parser<clang::ParsedSourceLocation>::
0124     parse(Option &O, StringRef ArgName, StringRef ArgValue,
0125           clang::ParsedSourceLocation &Val) {
0126       using namespace clang;
0127 
0128       Val = ParsedSourceLocation::FromString(ArgValue);
0129       if (Val.FileName.empty()) {
0130         errs() << "error: "
0131                << "source location must be of the form filename:line:column\n";
0132         return true;
0133       }
0134 
0135       return false;
0136     }
0137   }
0138 }
0139 
0140 #endif