clang 22.0.0git
CommandLineSourceLoc.h
Go to the documentation of this file.
1
2//===--- CommandLineSourceLoc.h - Parsing for source locations-*- C++ -*---===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9//
10// Command line parsing for source locations.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_FRONTEND_COMMANDLINESOURCELOC_H
15#define LLVM_CLANG_FRONTEND_COMMANDLINESOURCELOC_H
16
17#include "clang/Basic/LLVM.h"
18#include "llvm/Support/CommandLine.h"
19#include "llvm/Support/raw_ostream.h"
20#include <optional>
21
22namespace clang {
23
24/// A source location that has been parsed on the command line.
26 std::string FileName;
27 // The 1-based line number
28 unsigned Line;
29 // The 1-based column number
30 unsigned Column;
31
32public:
33 /// Construct a parsed source location from a string; the Filename is empty on
34 /// error.
35 static ParsedSourceLocation FromString(StringRef Str) {
37 std::pair<StringRef, StringRef> ColSplit = Str.rsplit(':');
38 std::pair<StringRef, StringRef> LineSplit =
39 ColSplit.first.rsplit(':');
40
41 // If both tail splits were valid integers, return success.
42 if (!ColSplit.second.getAsInteger(10, PSL.Column) &&
43 !LineSplit.second.getAsInteger(10, PSL.Line) &&
44 !(PSL.Column == 0 || PSL.Line == 0)) {
45 PSL.FileName = std::string(LineSplit.first);
46
47 // On the command-line, stdin may be specified via "-". Inside the
48 // compiler, stdin is called "<stdin>".
49 if (PSL.FileName == "-")
50 PSL.FileName = "<stdin>";
51 }
52
53 return PSL;
54 }
55
56 /// Serialize ParsedSourceLocation back to a string.
57 std::string ToString() const {
58 return (llvm::Twine(FileName == "<stdin>" ? "-" : FileName) + ":" +
59 Twine(Line) + ":" + Twine(Column))
60 .str();
61 }
62};
63
64/// A source range that has been parsed on the command line.
66 std::string FileName;
67 /// The starting location of the range. The first element is the line and
68 /// the second element is the column.
69 std::pair<unsigned, unsigned> Begin;
70 /// The ending location of the range. The first element is the line and the
71 /// second element is the column.
72 std::pair<unsigned, unsigned> End;
73
74 /// Returns a parsed source range from a string or std::nullopt if the string
75 /// is invalid.
76 ///
77 /// These source string has the following format:
78 ///
79 /// file:start_line:start_column[-end_line:end_column]
80 ///
81 /// If the end line and column are omitted, the starting line and columns
82 /// are used as the end values.
83 static std::optional<ParsedSourceRange> fromString(StringRef Str) {
84 std::pair<StringRef, StringRef> RangeSplit = Str.rsplit('-');
85 unsigned EndLine, EndColumn;
86 bool HasEndLoc = false;
87 if (!RangeSplit.second.empty()) {
88 std::pair<StringRef, StringRef> Split = RangeSplit.second.rsplit(':');
89 if (Split.first.getAsInteger(10, EndLine) ||
90 Split.second.getAsInteger(10, EndColumn)) {
91 // The string does not end in end_line:end_column, so the '-'
92 // probably belongs to the filename which menas the whole
93 // string should be parsed.
94 RangeSplit.first = Str;
95 } else {
96 // Column and line numbers are 1-based.
97 if (EndLine == 0 || EndColumn == 0)
98 return std::nullopt;
99 HasEndLoc = true;
100 }
101 }
102 auto Begin = ParsedSourceLocation::FromString(RangeSplit.first);
103 if (Begin.FileName.empty())
104 return std::nullopt;
105 if (!HasEndLoc) {
106 EndLine = Begin.Line;
107 EndColumn = Begin.Column;
108 }
109 return ParsedSourceRange{std::move(Begin.FileName),
110 {Begin.Line, Begin.Column},
111 {EndLine, EndColumn}};
112 }
113};
114}
115
116namespace llvm {
117 namespace cl {
118 /// Command-line option parser that parses source locations.
119 ///
120 /// Source locations are of the form filename:line:column.
121 template<>
122 class parser<clang::ParsedSourceLocation> final
123 : public basic_parser<clang::ParsedSourceLocation> {
124 public:
125 inline bool parse(Option &O, StringRef ArgName, StringRef ArgValue,
127 };
128
129 bool
130 parser<clang::ParsedSourceLocation>::
131 parse(Option &O, StringRef ArgName, StringRef ArgValue,
133 using namespace clang;
134
135 Val = ParsedSourceLocation::FromString(ArgValue);
136 if (Val.FileName.empty()) {
137 errs() << "error: "
138 << "source location must be of the form filename:line:column\n";
139 return true;
140 }
141
142 return false;
143 }
144 }
145}
146
147#endif
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
The JSON file list parser is used to communicate input to InstallAPI.
Diagnostic wrappers for TextAPI types for error reporting.
Definition: Dominators.h:30
A source location that has been parsed on the command line.
static ParsedSourceLocation FromString(StringRef Str)
Construct a parsed source location from a string; the Filename is empty on error.
std::string ToString() const
Serialize ParsedSourceLocation back to a string.
A source range that has been parsed on the command line.
std::pair< unsigned, unsigned > End
The ending location of the range.
static std::optional< ParsedSourceRange > fromString(StringRef Str)
Returns a parsed source range from a string or std::nullopt if the string is invalid.
std::pair< unsigned, unsigned > Begin
The starting location of the range.