[flang] Using new Prov to Cooked mappings for get-definition.
authorTin Huynh <tinlun123@gmail.com>
Mon, 9 Sep 2019 18:36:42 +0000 (11:36 -0700)
committerTin Huynh <tinlun123@gmail.com>
Wed, 11 Sep 2019 00:55:59 +0000 (17:55 -0700)
Original-commit: flang-compiler/f18@5a42c5c9e19c5a56fdc256db56d32e3564e72765
Reviewed-on: https://github.com/flang-compiler/f18/pull/698

flang/lib/parser/provenance.cc
flang/lib/parser/provenance.h
flang/lib/parser/source.h
flang/lib/semantics/semantics.cc
flang/tools/f18/f18.cc

index f32be04..f989534 100644 (file)
@@ -111,17 +111,6 @@ ProvenanceRange OffsetToProvenanceMappings::Map(std::size_t at) const {
   return provenanceMap_[low].range.Suffix(offset);
 }
 
-std::optional<std::size_t> OffsetToProvenanceMappings::ReverseMap(
-    Provenance at) const {
-  for (const auto &[start, range] : provenanceMap_) {
-    if (range.Contains(at)) {
-      std::size_t offset{at.offset() - range.start().offset()};
-      return start + offset;
-    }
-  }
-  return std::nullopt;
-}
-
 void OffsetToProvenanceMappings::RemoveLastBytes(std::size_t bytes) {
   for (; bytes > 0; provenanceMap_.pop_back()) {
     CHECK(!provenanceMap_.empty());
@@ -432,38 +421,19 @@ std::optional<ProvenanceRange> CookedSource::GetProvenanceRange(
   return {ProvenanceRange{first.start(), last.start() - first.start()}};
 }
 
-std::optional<CharBlock> CookedSource::GetCharBlock(
-    ProvenanceRange range) const {
-  CHECK(!invertedMap_.empty() &&
-      "CompileProvenanceRangeToOffsetMappings not called");
-  if (auto to{invertedMap_.Map(range)}) {
-    return CharBlock{data_.c_str() + *to, range.size()};
-  } else {
-    return std::nullopt;
-  }
-}
-
 std::optional<CharBlock> CookedSource::GetCharBlockFromLineAndColumns(
     int line, int startColumn, int endColumn) const {
   // 2nd column is exclusive, meaning it is target column + 1.
   CHECK(line > 0 && startColumn > 0 && endColumn > 0);
+  CHECK(startColumn < endColumn);
   auto provenanceStart{allSources_.GetFirstFileProvenance().value().start()};
   if (auto sourceFile{allSources_.GetSourceFile(provenanceStart)}) {
     CHECK(line <= static_cast<int>(sourceFile->lines()));
-    if (auto firstOffset{
-            provenanceMap_.ReverseMap(sourceFile->GetLineStartOffset(line) +
-                provenanceStart.offset() + startColumn - 1)}) {
-      if (auto secondOffset{
-              provenanceMap_.ReverseMap(sourceFile->GetLineStartOffset(line) +
-                  provenanceStart.offset() + endColumn - 2)}) {
-        if (*secondOffset >= *firstOffset) {
-          // Returned 2nd column is also exclusive.
-          return CharBlock(
-              &data_[*firstOffset], *secondOffset - *firstOffset + 1);
-        }
-      }
-    }
+    return GetCharBlock(ProvenanceRange(sourceFile->GetLineStartOffset(line) +
+            provenanceStart.offset() + startColumn - 1,
+        endColumn - startColumn));
   }
+  return std::nullopt;
 }
 
 std::optional<std::pair<SourcePosition, SourcePosition>>
@@ -479,6 +449,17 @@ CookedSource::GetSourcePositionRange(CharBlock cookedRange) const {
   return std::nullopt;
 }
 
+std::optional<CharBlock> CookedSource::GetCharBlock(
+    ProvenanceRange range) const {
+  CHECK(!invertedMap_.empty() &&
+      "CompileProvenanceRangeToOffsetMappings not called");
+  if (auto to{invertedMap_.Map(range)}) {
+    return CharBlock{data_.c_str() + *to, range.size()};
+  } else {
+    return std::nullopt;
+  }
+}
+
 void CookedSource::Marshal() {
   CHECK(provenanceMap_.SizeInBytes() == buffer_.bytes());
   provenanceMap_.Put(allSources_.AddCompilerInsertion("(after end of source)"));
index 2eaa6ab..30d2058 100644 (file)
@@ -52,6 +52,8 @@ namespace Fortran::parser {
 // by the upper bits of an offset, but that does not appear to be
 // necessary.)
 
+class AllSources;
+
 class Provenance {
 public:
   Provenance() {}
@@ -122,7 +124,6 @@ public:
   void Put(ProvenanceRange);
   void Put(const OffsetToProvenanceMappings &);
   ProvenanceRange Map(std::size_t at) const;
-  std::optional<std::size_t> ReverseMap(Provenance) const;
   void RemoveLastBytes(std::size_t);
   ProvenanceRangeToOffsetMappings Invert(const AllSources &) const;
   std::ostream &Dump(std::ostream &) const;
@@ -173,7 +174,7 @@ public:
   const SourceFile *GetSourceFile(
       Provenance, std::size_t *offset = nullptr) const;
   std::optional<SourcePosition> GetSourcePosition(Provenance) const;
-  std::optional<ProvenanceRange> GetFirstFileProvenance();
+  std::optional<ProvenanceRange> GetFirstFileProvenance() const;
   std::string GetPath(Provenance) const;  // __FILE__
   int GetLineNumber(Provenance) const;  // __LINE__
   Provenance CompilerInsertionProvenance(char ch);
@@ -237,11 +238,11 @@ public:
   bool IsValid(ProvenanceRange r) const { return allSources_.IsValid(r); }
 
   std::optional<ProvenanceRange> GetProvenanceRange(CharBlock) const;
-  std::optional<CharBlock> GetCharBlock(ProvenanceRange) const;
   std::optional<CharBlock> GetCharBlockFromLineAndColumns(
       int line, int startColumn, int endColumn) const;
   std::optional<std::pair<SourcePosition, SourcePosition>>
       GetSourcePositionRange(CharBlock) const;
+  std::optional<CharBlock> GetCharBlock(ProvenanceRange) const;
 
   // The result of a Put() is the offset that the new data
   // will have in the eventually marshaled contiguous buffer.
index ef7ec54..02cc8cc 100644 (file)
@@ -36,11 +36,6 @@ std::string LocateSourceFile(
 class SourceFile;
 
 struct SourcePosition {
-  SourcePosition(const SourceFile &file, int line, int column)
-    : file{file}, line{line}, column{column} {}
-  SourcePosition(const SourceFile &file, std::pair<int, int> pos)
-    : file{file}, line{pos.first}, column{pos.second} {}
-
   const SourceFile &file;
   int line, column;
 };
index 3f96aef..2a164fb 100644 (file)
@@ -236,8 +236,7 @@ void Semantics::DumpSymbolsSources(std::ostream &os) const {
   GetSymbolNames(context_.globalScope(), symbols);
   for (const auto pair : symbols) {
     const Symbol &symbol{*pair.second};
-    auto sourceInfo{cooked_.GetSourcePositionRange(symbol.name())};
-    if (sourceInfo) {
+    if (auto sourceInfo{cooked_.GetSourcePositionRange(symbol.name())}) {
       os << symbol.name().ToString() << ": " << sourceInfo->first.file.path()
          << ", " << sourceInfo->first.line << ", " << sourceInfo->first.column
          << "-" << sourceInfo->second.column << "\n";
index c520c09..edbea5d 100644 (file)
@@ -77,8 +77,6 @@ void CleanUpAtExit() {
 }
 
 struct GetDefinitionArgs {
-  GetDefinitionArgs(int line, int startColumn, int endColumn)
-    : line{line}, startColumn{startColumn}, endColumn{endColumn} {}
   int line, startColumn, endColumn;
 };
 
@@ -262,38 +260,28 @@ std::string CompileFortran(std::string path, Fortran::parser::Options options,
       return {};
     }
     if (driver.getDefinition) {
-      std::string notFoundText{"Symbol not found.\n"};
-      auto cb{parsing.cooked().GetCharBlockFromLineAndColumns(
-          driver.getDefinitionArgs.line, driver.getDefinitionArgs.startColumn,
-          driver.getDefinitionArgs.endColumn)};
-      if (!cb) {
-        std::cerr << notFoundText;
-        exitStatus = EXIT_FAILURE;
-        return {};
-      }
-      std::cerr << "String range: >" << std::string(cb->begin(), cb->size())
-                << "<\n";
-      auto &scope{semanticsContext.FindScope(*cb)};
-      auto symbol{scope.FindSymbol(*cb)};
-      if (!symbol) {
-        std::cerr << notFoundText;
-        exitStatus = EXIT_FAILURE;
-        return {};
-      }
-      std::cerr << "Found symbol name: "
-                << std::string(symbol->name().begin(), symbol->name().size())
-                << "\n";
-      auto sourceInfo{parsing.cooked().GetSourcePositionRange(symbol->name())};
-      if (!sourceInfo) {
-        std::cerr << notFoundText;
-        exitStatus = EXIT_FAILURE;
-        return {};
+      if (auto cb{parsing.cooked().GetCharBlockFromLineAndColumns(
+              driver.getDefinitionArgs.line,
+              driver.getDefinitionArgs.startColumn,
+              driver.getDefinitionArgs.endColumn)}) {
+        std::cerr << "String range: >" << cb->ToString() << "<\n";
+        if (auto symbol{semanticsContext.FindScope(*cb).FindSymbol(*cb)}) {
+          std::cerr << "Found symbol name: " << symbol->name().ToString()
+                    << "\n";
+          if (auto sourceInfo{
+                  parsing.cooked().GetSourcePositionRange(symbol->name())}) {
+            std::cout << symbol->name().ToString() << ": "
+                      << sourceInfo->first.file.path() << ", "
+                      << sourceInfo->first.line << ", "
+                      << sourceInfo->first.column << "-"
+                      << sourceInfo->second.column << "\n";
+            exitStatus = EXIT_SUCCESS;
+            return {};
+          }
+        }
       }
-      std::cout << symbol->name().ToString() << ": "
-                << sourceInfo->first.file.path() << ", "
-                << sourceInfo->first.line << ", " << sourceInfo->first.column
-                << "-" << sourceInfo->second.column << "\n";
-      exitStatus = EXIT_SUCCESS;
+      std::cerr << "Symbol not found.\n";
+      exitStatus = EXIT_FAILURE;
       return {};
     }
   }
@@ -530,6 +518,7 @@ int main(int argc, char *const argv[]) {
       driver.encoding = Fortran::parser::Encoding::LATIN_1;
     } else if (arg == "-fget-definition") {
       // Receives 3 arguments: line, startColumn, endColumn.
+      options.needProvenanceRangeToCharBlockMappings = true;
       driver.getDefinition = true;
       char *endptr;
       int arguments[3];