Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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