[flang] Using new Prov to Cooked mappings for get-definition.

Original-commit: flang-compiler/f18@5a42c5c9e1
Reviewed-on: https://github.com/flang-compiler/f18/pull/698
This commit is contained in:
Tin Huynh 2019-09-09 11:36:42 -07:00
parent 69fd49a002
commit 2e1807998c
5 changed files with 43 additions and 78 deletions

View 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)"));

View 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.

View 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;
};

View 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";

View 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 {};
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::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 {};
}
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];