1199482Srdivacky
2195099Sed//===--- CommandLineSourceLoc.h - Parsing for source locations-*- C++ -*---===//
3195099Sed//
4195099Sed//                     The LLVM Compiler Infrastructure
5195099Sed//
6195099Sed// This file is distributed under the University of Illinois Open Source
7195099Sed// License. See LICENSE.TXT for details.
8195099Sed//
9195099Sed//===----------------------------------------------------------------------===//
10195099Sed//
11195099Sed// Command line parsing for source locations.
12195099Sed//
13195099Sed//===----------------------------------------------------------------------===//
14195099Sed
15195099Sed#ifndef LLVM_CLANG_FRONTEND_COMMANDLINESOURCELOC_H
16195099Sed#define LLVM_CLANG_FRONTEND_COMMANDLINESOURCELOC_H
17195099Sed
18226633Sdim#include "clang/Basic/LLVM.h"
19195099Sed#include "llvm/Support/CommandLine.h"
20199990Srdivacky#include "llvm/Support/raw_ostream.h"
21195099Sed
22195099Sednamespace clang {
23195099Sed
24195099Sed/// \brief A source location that has been parsed on the command line.
25195099Sedstruct ParsedSourceLocation {
26195099Sed  std::string FileName;
27195099Sed  unsigned Line;
28195099Sed  unsigned Column;
29199990Srdivacky
30199990Srdivackypublic:
31199990Srdivacky  /// Construct a parsed source location from a string; the Filename is empty on
32199990Srdivacky  /// error.
33226633Sdim  static ParsedSourceLocation FromString(StringRef Str) {
34199990Srdivacky    ParsedSourceLocation PSL;
35226633Sdim    std::pair<StringRef, StringRef> ColSplit = Str.rsplit(':');
36226633Sdim    std::pair<StringRef, StringRef> LineSplit =
37199990Srdivacky      ColSplit.first.rsplit(':');
38199990Srdivacky
39199990Srdivacky    // If both tail splits were valid integers, return success.
40199990Srdivacky    if (!ColSplit.second.getAsInteger(10, PSL.Column) &&
41218893Sdim        !LineSplit.second.getAsInteger(10, PSL.Line)) {
42199990Srdivacky      PSL.FileName = LineSplit.first;
43199990Srdivacky
44218893Sdim      // On the command-line, stdin may be specified via "-". Inside the
45218893Sdim      // compiler, stdin is called "<stdin>".
46218893Sdim      if (PSL.FileName == "-")
47218893Sdim        PSL.FileName = "<stdin>";
48218893Sdim    }
49218893Sdim
50199990Srdivacky    return PSL;
51199990Srdivacky  }
52195099Sed};
53195099Sed
54195099Sed}
55195099Sed
56195099Sednamespace llvm {
57195099Sed  namespace cl {
58195099Sed    /// \brief Command-line option parser that parses source locations.
59195099Sed    ///
60195099Sed    /// Source locations are of the form filename:line:column.
61195099Sed    template<>
62198092Srdivacky    class parser<clang::ParsedSourceLocation>
63195099Sed      : public basic_parser<clang::ParsedSourceLocation> {
64195099Sed    public:
65199482Srdivacky      inline bool parse(Option &O, StringRef ArgName, StringRef ArgValue,
66195099Sed                 clang::ParsedSourceLocation &Val);
67195099Sed    };
68195099Sed
69198092Srdivacky    bool
70195099Sed    parser<clang::ParsedSourceLocation>::
71198092Srdivacky    parse(Option &O, StringRef ArgName, StringRef ArgValue,
72195099Sed          clang::ParsedSourceLocation &Val) {
73195099Sed      using namespace clang;
74195099Sed
75199990Srdivacky      Val = ParsedSourceLocation::FromString(ArgValue);
76199990Srdivacky      if (Val.FileName.empty()) {
77199990Srdivacky        errs() << "error: "
78199990Srdivacky               << "source location must be of the form filename:line:column\n";
79195099Sed        return true;
80195099Sed      }
81198092Srdivacky
82195099Sed      return false;
83195099Sed    }
84195099Sed  }
85195099Sed}
86195099Sed
87195099Sed#endif
88