summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-emit-source-writer.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2021-02-17 19:04:48 -0500
committerGitHub <noreply@github.com>2021-02-17 16:04:48 -0800
commit360d4f7a17a066cc878cdb2c558464bfdeaa3418 (patch)
tree99133158bb0cae370c70ce060344ca1acbe958a2 /source/slang/slang-emit-source-writer.cpp
parente59aee131b6d51236613bc374cfa2d5f3b54efe1 (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.cpp61
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)