/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/Frontend/CommandLineSourceLoc.h
Line | Count | Source (jump to first uncovered line) |
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 | | |
21 | | namespace clang { |
22 | | |
23 | | /// A source location that has been parsed on the command line. |
24 | | struct ParsedSourceLocation { |
25 | | std::string FileName; |
26 | | unsigned Line; |
27 | | unsigned Column; |
28 | | |
29 | | public: |
30 | | /// Construct a parsed source location from a string; the Filename is empty on |
31 | | /// error. |
32 | 661 | static ParsedSourceLocation FromString(StringRef Str) { |
33 | 661 | ParsedSourceLocation PSL; |
34 | 661 | std::pair<StringRef, StringRef> ColSplit = Str.rsplit(':'); |
35 | 661 | std::pair<StringRef, StringRef> LineSplit = |
36 | 661 | ColSplit.first.rsplit(':'); |
37 | | |
38 | | // If both tail splits were valid integers, return success. |
39 | 661 | if (!ColSplit.second.getAsInteger(10, PSL.Column) && |
40 | 661 | !LineSplit.second.getAsInteger(10, PSL.Line)) { |
41 | 661 | PSL.FileName = std::string(LineSplit.first); |
42 | | |
43 | | // On the command-line, stdin may be specified via "-". Inside the |
44 | | // compiler, stdin is called "<stdin>". |
45 | 661 | if (PSL.FileName == "-") |
46 | 2 | PSL.FileName = "<stdin>"; |
47 | 661 | } |
48 | | |
49 | 661 | return PSL; |
50 | 661 | } |
51 | | |
52 | | /// Serialize ParsedSourceLocation back to a string. |
53 | 650 | std::string ToString() const { |
54 | 650 | return (llvm::Twine(FileName == "<stdin>" ? "-"2 : FileName648 ) + ":" + |
55 | 650 | Twine(Line) + ":" + Twine(Column)) |
56 | 650 | .str(); |
57 | 650 | } |
58 | | }; |
59 | | |
60 | | /// A source range that has been parsed on the command line. |
61 | | struct ParsedSourceRange { |
62 | | std::string FileName; |
63 | | /// The starting location of the range. The first element is the line and |
64 | | /// the second element is the column. |
65 | | std::pair<unsigned, unsigned> Begin; |
66 | | /// The ending location of the range. The first element is the line and the |
67 | | /// second element is the column. |
68 | | std::pair<unsigned, unsigned> End; |
69 | | |
70 | | /// Returns a parsed source range from a string or None if the string is |
71 | | /// invalid. |
72 | | /// |
73 | | /// These source string has the following format: |
74 | | /// |
75 | | /// file:start_line:start_column[-end_line:end_column] |
76 | | /// |
77 | | /// If the end line and column are omitted, the starting line and columns |
78 | | /// are used as the end values. |
79 | 11 | static Optional<ParsedSourceRange> fromString(StringRef Str) { |
80 | 11 | std::pair<StringRef, StringRef> RangeSplit = Str.rsplit('-'); |
81 | 11 | unsigned EndLine, EndColumn; |
82 | 11 | bool HasEndLoc = false; |
83 | 11 | if (!RangeSplit.second.empty()) { |
84 | 11 | std::pair<StringRef, StringRef> Split = RangeSplit.second.rsplit(':'); |
85 | 11 | if (Split.first.getAsInteger(10, EndLine) || |
86 | 11 | Split.second.getAsInteger(10, EndColumn)4 ) { |
87 | | // The string does not end in end_line:end_column, so the '-' |
88 | | // probably belongs to the filename which menas the whole |
89 | | // string should be parsed. |
90 | 7 | RangeSplit.first = Str; |
91 | 7 | } else |
92 | 4 | HasEndLoc = true; |
93 | 11 | } |
94 | 11 | auto Begin = ParsedSourceLocation::FromString(RangeSplit.first); |
95 | 11 | if (Begin.FileName.empty()) |
96 | 0 | return None; |
97 | 11 | if (!HasEndLoc) { |
98 | 7 | EndLine = Begin.Line; |
99 | 7 | EndColumn = Begin.Column; |
100 | 7 | } |
101 | 11 | return ParsedSourceRange{std::move(Begin.FileName), |
102 | 11 | {Begin.Line, Begin.Column}, |
103 | 11 | {EndLine, EndColumn}}; |
104 | 11 | } |
105 | | }; |
106 | | } |
107 | | |
108 | | namespace llvm { |
109 | | namespace cl { |
110 | | /// Command-line option parser that parses source locations. |
111 | | /// |
112 | | /// Source locations are of the form filename:line:column. |
113 | | template<> |
114 | | class parser<clang::ParsedSourceLocation> final |
115 | | : public basic_parser<clang::ParsedSourceLocation> { |
116 | | public: |
117 | | inline bool parse(Option &O, StringRef ArgName, StringRef ArgValue, |
118 | | clang::ParsedSourceLocation &Val); |
119 | | }; |
120 | | |
121 | | bool |
122 | | parser<clang::ParsedSourceLocation>:: |
123 | | parse(Option &O, StringRef ArgName, StringRef ArgValue, |
124 | 0 | clang::ParsedSourceLocation &Val) { |
125 | 0 | using namespace clang; |
126 | 0 |
|
127 | 0 | Val = ParsedSourceLocation::FromString(ArgValue); |
128 | 0 | if (Val.FileName.empty()) { |
129 | 0 | errs() << "error: " |
130 | 0 | << "source location must be of the form filename:line:column\n"; |
131 | 0 | return true; |
132 | 0 | } |
133 | 0 |
|
134 | 0 | return false; |
135 | 0 | } |
136 | | } |
137 | | } |
138 | | |
139 | | #endif |