forked from OSchip/llvm-project
[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:
parent
69fd49a002
commit
2e1807998c
|
@ -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)"));
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in New Issue