File indexing completed on 2026-05-10 08:36:55
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
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
0025 struct ParsedSourceLocation {
0026 std::string FileName;
0027 unsigned Line;
0028 unsigned Column;
0029
0030 public:
0031
0032
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
0040 if (!ColSplit.second.getAsInteger(10, PSL.Column) &&
0041 !LineSplit.second.getAsInteger(10, PSL.Line)) {
0042 PSL.FileName = std::string(LineSplit.first);
0043
0044
0045
0046 if (PSL.FileName == "-")
0047 PSL.FileName = "<stdin>";
0048 }
0049
0050 return PSL;
0051 }
0052
0053
0054 std::string ToString() const {
0055 return (llvm::Twine(FileName == "<stdin>" ? "-" : FileName) + ":" +
0056 Twine(Line) + ":" + Twine(Column))
0057 .str();
0058 }
0059 };
0060
0061
0062 struct ParsedSourceRange {
0063 std::string FileName;
0064
0065
0066 std::pair<unsigned, unsigned> Begin;
0067
0068
0069 std::pair<unsigned, unsigned> End;
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
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
0089
0090
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
0112
0113
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