diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2021-02-17 19:04:48 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-02-17 16:04:48 -0800 |
| commit | 360d4f7a17a066cc878cdb2c558464bfdeaa3418 (patch) | |
| tree | 99133158bb0cae370c70ce060344ca1acbe958a2 /source/slang/slang-emit-source-writer.cpp | |
| parent | e59aee131b6d51236613bc374cfa2d5f3b54efe1 (diff) | |
More #line improvements (#1713)
* #include an absolute path didn't work - because paths were taken to always be relative.
* WIP: First pass in supporting output of line error information.
* Add support for lexing to better be able to indicate SourceLocation information.
* Fix lexer usage in DiagnosticSink in C++ extractor.
* Update diagnostics tests to have line location info.
* Fixed test expected output that now have source location information in them.
* Better handling of tab.
* Fix test expected results for tabbing change.
* DiagnosticLexer -> DiagnosticSink::SourceLocationLexer
Added line continuation tests.
* Fix typo.
* Added String::appendRepeatedChar
* Change to rerun tests.
* Added source locations to IR dumping.
* Output column for IR dump source loc.
* Add support for closing brace location to AST.
Use closing brace location in lowering when adding return void.
* Set the source location through SourceLoc - simplifies identifying if current loc is valid.
* Copy terminator sloc.
* Test for improved #line handling.
* Made writer the last parameter for dumpIR.
Small improvements to comments.
* Disable sloc output on dump IR by default.
* Fix issue with #line and inlining.
* Fix for output with improved #line output.
* Small comment change - mainly to kick off TC build.
Co-authored-by: Tim Foley <tfoleyNV@users.noreply.github.com>
Diffstat (limited to 'source/slang/slang-emit-source-writer.cpp')
| -rw-r--r-- | source/slang/slang-emit-source-writer.cpp | 61 |
1 files changed, 50 insertions, 11 deletions
diff --git a/source/slang/slang-emit-source-writer.cpp b/source/slang/slang-emit-source-writer.cpp index 8deecc846..29a83a1fc 100644 --- a/source/slang/slang-emit-source-writer.cpp +++ b/source/slang/slang-emit-source-writer.cpp @@ -152,19 +152,19 @@ void SourceWriter::emit(Name* name) void SourceWriter::emit(const NameLoc& nameAndLoc) { - advanceToSourceLocation(nameAndLoc.loc); + advanceToSourceLocationIfValid(nameAndLoc.loc); emit(getText(nameAndLoc.name)); } void SourceWriter::emit(const StringSliceLoc& nameAndLoc) { - advanceToSourceLocation(nameAndLoc.loc); + advanceToSourceLocationIfValid(nameAndLoc.loc); emit(nameAndLoc.name); } void SourceWriter::emitName(Name* name, const SourceLoc& locIn) { - advanceToSourceLocation(locIn); + advanceToSourceLocationIfValid(locIn); emit(name); } @@ -251,19 +251,58 @@ void SourceWriter::emit(double value) emit(stream.str().c_str()); } -void SourceWriter::advanceToSourceLocation(const SourceLoc& sourceLocation) +void SourceWriter::advanceToSourceLocationIfValid(const SourceLoc& sourceLocation) { - advanceToSourceLocation(getSourceManager()->getHumaneLoc(sourceLocation)); + if (sourceLocation.isValid()) + { + advanceToSourceLocation(sourceLocation); + } } -void SourceWriter::advanceToSourceLocation(const HumaneSourceLoc& sourceLocation) +void SourceWriter::advanceToSourceLocation(const SourceLoc& sourceLocation) { - // Skip invalid locations - if (sourceLocation.line <= 0) + if (getLineDirectiveMode() == LineDirectiveMode::None) + { + // Ignore if we aren't outputting directives + return; + } + + if (!sourceLocation.isValid()) + { + // If it's not valid, we will just keep the current location. + + // The question now is if we want to trigger outputting the source location again. We do so if + // * The nextSourceLoc is valid + // * The line number on the output is different from that location + m_needToUpdateSourceLocation = m_needToUpdateSourceLocation || (m_nextSourceLoc.isValid() && m_nextHumaneSourceLocation.line != m_loc.line); return; + } + + // Even if the source location is the same, we still want to trigger output, as long + // as we have a valid line location. + if (sourceLocation == m_nextSourceLoc) + { + // This is important because we can end up with many instructions with the same source location - for example + // when we have [__unsafeForceInlineEarly] all the inlined instructions get the same location. + // When we output lines of source, the target sources line numbers change, therefore we need to + // output the same #line directive multiple times. + + m_needToUpdateSourceLocation = m_needToUpdateSourceLocation || (m_nextHumaneSourceLocation.line > 0); + return; + } + + // Workout the humane source location. + const HumaneSourceLoc humaneSourceLoc = getSourceManager()->getHumaneLoc(sourceLocation); + + // If the location is valid, mark need to update, and the new location + if (humaneSourceLoc.line > 0) + { + m_needToUpdateSourceLocation = true; + m_nextHumaneSourceLocation = humaneSourceLoc; + } - m_needToUpdateSourceLocation = true; - m_nextSourceLocation = sourceLocation; + // Either way set this as the current source location. + m_nextSourceLoc = sourceLocation; } void SourceWriter::_flushSourceLocationChange() @@ -276,7 +315,7 @@ void SourceWriter::_flushSourceLocationChange() // advances the location, and outputting text is what // triggers this flush operation. m_needToUpdateSourceLocation = false; - _emitLineDirectiveIfNeeded(m_nextSourceLocation); + _emitLineDirectiveIfNeeded(m_nextHumaneSourceLocation); } void SourceWriter::_emitLineDirectiveAndUpdateSourceLocation(const HumaneSourceLoc& sourceLocation) |
