summaryrefslogtreecommitdiffstats
path: root/source/slang/slang.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2021-03-31 13:11:49 -0400
committerGitHub <noreply@github.com>2021-03-31 13:11:49 -0400
commit5fde038b1a6b3c8b335cd5b380c3ee8d15403052 (patch)
tree27975331c960edc405a5294031fd6a4a79eff964 /source/slang/slang.cpp
parent5fefb120e0c2469563e937f4ee39b391d7678cdf (diff)
Support for __LINE__ and __FILE__ in preprocessor (#1772)
* #include an absolute path didn't work - because paths were taken to always be relative. * First pass support for __LINE__ and __FILE__. * Test include handling with __FILE__ Fix diagnostic compare when input is empty. * Fix some issues in preprocessor handling of special macros like __LINE__ Add a more complex test. * Use CONCAT2 in tests, because preprocessor doesn't quite get parameter expansion correct. * Make __FILE__ and __LINE__ behave more like Clang/Gcc. * A test for preprocessor bug. * Fix __LINE__ and __FILE__ in macro expansion, should be initiating location. * Fix some comments. * Small tidy up around builtin macros. * Small improvements for macro type names. Escape found paths.
Diffstat (limited to 'source/slang/slang.cpp')
-rw-r--r--source/slang/slang.cpp52
1 files changed, 49 insertions, 3 deletions
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index 93d7be310..bcc3d1c67 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -1186,7 +1186,7 @@ static ISlangWriter* _getDefaultWriter(WriterChannel chan)
void EndToEndCompileRequest::setWriter(WriterChannel chan, ISlangWriter* writer)
{
// If the user passed in null, we will use the default writer on that channel
- m_writers[int(chan)] = writer ? writer : _getDefaultWriter(chan);
+ m_writers->setWriter(SlangWriterChannel(chan), writer ? writer : _getDefaultWriter(chan));
// For diagnostic output, if the user passes in nullptr, we set on mSink.writer as that enables buffering on DiagnosticSink
if (chan == WriterChannel::Diagnostic)
@@ -1307,8 +1307,10 @@ CompileRequestBase::CompileRequestBase(
FrontEndCompileRequest::FrontEndCompileRequest(
Linkage* linkage,
+ StdWriters* writers,
DiagnosticSink* sink)
: CompileRequestBase(linkage, sink)
+ , m_writers(writers)
{
}
@@ -1540,6 +1542,26 @@ static void _outputIncludesRec(SourceView* sourceView, Index depth, ViewInitiati
}
}
+static void _outputPreprocessorTokens(const TokenList& toks, ISlangWriter* writer)
+{
+ if (writer == nullptr)
+ {
+ return;
+ }
+
+ StringBuilder buf;
+ for (const auto& tok : toks)
+ {
+ buf << tok.getContent();
+ // We'll separate tokens with space for now
+ buf.appendChar(' ');
+ }
+
+ buf.appendChar('\n');
+
+ writer->write(buf.getBuffer(), buf.getLength());
+}
+
static void _outputIncludes(const List<SourceFile*>& sourceFiles, SourceManager* sourceManager, DiagnosticSink* sink)
{
// Set up the hierarchy to know how all the source views relate. This could be argued as overkill, but makes recursive
@@ -1651,6 +1673,16 @@ void FrontEndCompileRequest::parseTranslationUnit(
_outputIncludes(translationUnit->getSourceFiles(), getSink()->getSourceManager(), getSink());
}
+ if (outputPreprocessor)
+ {
+ if (m_writers)
+ {
+ _outputPreprocessorTokens(tokens, m_writers->getWriter(SLANG_WRITER_CHANNEL_STD_OUTPUT));
+ }
+ // If we output the preprocessor output then we are done doing anything else
+ return;
+ }
+
parseSourceFile(
astBuilder,
translationUnit,
@@ -1828,6 +1860,12 @@ SlangResult FrontEndCompileRequest::executeActionsInner()
parseTranslationUnit(translationUnit.Ptr());
}
+ if (outputPreprocessor)
+ {
+ // If doing pre-processor output, then we are done
+ return SLANG_OK;
+ }
+
if (getSink()->getErrorCount() != 0)
return SLANG_FAIL;
@@ -1954,13 +1992,15 @@ void EndToEndCompileRequest::init()
{
m_sink.setSourceManager(m_linkage->getSourceManager());
+ m_writers = new StdWriters;
+
// Set all the default writers
for (int i = 0; i < int(WriterChannel::CountOf); ++i)
{
setWriter(WriterChannel(i), nullptr);
}
- m_frontEndReq = new FrontEndCompileRequest(getLinkage(), getSink());
+ m_frontEndReq = new FrontEndCompileRequest(getLinkage(), m_writers, getSink());
m_backEndReq = new BackEndCompileRequest(getLinkage(), getSink());
}
@@ -1999,6 +2039,11 @@ SlangResult EndToEndCompileRequest::executeActionsInner()
SLANG_RETURN_ON_FAIL(getFrontEndReq()->executeActionsInner());
}
+ if (getFrontEndReq()->outputPreprocessor)
+ {
+ return SLANG_OK;
+ }
+
// If command line specifies to skip codegen, we exit here.
// Note: this is a debugging option.
//
@@ -2288,7 +2333,7 @@ RefPtr<Module> Linkage::loadModule(
SourceLoc const& srcLoc,
DiagnosticSink* sink)
{
- RefPtr<FrontEndCompileRequest> frontEndReq = new FrontEndCompileRequest(this, sink);
+ RefPtr<FrontEndCompileRequest> frontEndReq = new FrontEndCompileRequest(this, nullptr, sink);
RefPtr<TranslationUnitRequest> translationUnit = new TranslationUnitRequest(frontEndReq);
translationUnit->compileRequest = frontEndReq;
@@ -3674,6 +3719,7 @@ void Session::addBuiltinSource(
DiagnosticSink sink(sourceManager, Lexer::sourceLocationLexer);
RefPtr<FrontEndCompileRequest> compileRequest = new FrontEndCompileRequest(
m_builtinLinkage,
+ nullptr,
&sink);
compileRequest->m_isStandardLibraryCode = true;