summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2018-05-04 13:42:57 -0700
committerGitHub <noreply@github.com>2018-05-04 13:42:57 -0700
commitb67f656ef3b41a44f4d4581a781c0958029281bd (patch)
tree5d5668d7f16fd50b765eee7b92f48f6ef8095ecf /source
parent07a59b623e44348caf06d65b2578b51d86ba0af5 (diff)
Re-enable emission of #line directives and clean up output (#554)
This was based on feedback from Falcor users, who felt like changing the default to have no line directives didn't work out well. Since I'd only made them disabled by default based on what I perceived to be Falcor's needs, I'm happy to turn this back on by default. I also added a few changes to clean up the output: * Don't emit a directive for a sub-expression, since that breaks up the code too much. The only directives inside a function body will be on top-level instructions that didn't get folded into a use site. * Add logic to emit a directive for top-level declarations (globals, functions, structs), and clean up their printing so that they put any extra space *after* the declaration rather than before (so the line numbers can be accurate) * Don't emit the file path part of a directive if it would be the same as the previous directive. This makes the output less noisy, at the cost of having to work your way backward to find the file if you are looking directly at the output. There are certainly more cleanups possible, but these make the output decent enough to be useful for working backwards from a downstream compiler error to the offending code.
Diffstat (limited to 'source')
-rw-r--r--source/slang/emit.cpp171
1 files changed, 83 insertions, 88 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index c86634c02..9874e3ef3 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -534,92 +534,96 @@ struct EmitVisitor
sprintf(buffer, "%llu", (unsigned long long)sourceLocation.line);
emitRawText(buffer);
- emitRawText(" ");
-
- bool shouldUseGLSLStyleLineDirective = false;
-
- auto mode = context->shared->entryPoint->compileRequest->lineDirectiveMode;
- switch (mode)
+ // Only emit the path part of a `#line` directive if needed
+ if(sourceLocation.path != context->shared->loc.path)
{
- case LineDirectiveMode::None:
- case LineDirectiveMode::Default:
- SLANG_UNEXPECTED("should not be trying to emit '#line' directive");
- return;
+ emitRawText(" ");
- default:
- // To try to make the default behavior reasonable, we will
- // always use C-style line directives (to give the user
- // good source locations on error messages from downstream
- // compilers) *unless* they requested raw GLSL as the
- // output (in which case we want to maximize compatibility
- // with downstream tools).
- if (context->shared->finalTarget == CodeGenTarget::GLSL)
- {
- shouldUseGLSLStyleLineDirective = true;
- }
- break;
+ bool shouldUseGLSLStyleLineDirective = false;
- case LineDirectiveMode::Standard:
- break;
+ auto mode = context->shared->entryPoint->compileRequest->lineDirectiveMode;
+ switch (mode)
+ {
+ case LineDirectiveMode::None:
+ SLANG_UNEXPECTED("should not be trying to emit '#line' directive");
+ return;
- case LineDirectiveMode::GLSL:
- shouldUseGLSLStyleLineDirective = true;
- break;
- }
+ case LineDirectiveMode::Default:
+ default:
+ // To try to make the default behavior reasonable, we will
+ // always use C-style line directives (to give the user
+ // good source locations on error messages from downstream
+ // compilers) *unless* they requested raw GLSL as the
+ // output (in which case we want to maximize compatibility
+ // with downstream tools).
+ if (context->shared->finalTarget == CodeGenTarget::GLSL)
+ {
+ shouldUseGLSLStyleLineDirective = true;
+ }
+ break;
- if(shouldUseGLSLStyleLineDirective)
- {
- auto path = sourceLocation.getPath();
+ case LineDirectiveMode::Standard:
+ break;
- // GLSL doesn't support the traditional form of a `#line` directive without
- // an extension. Rather than depend on that extension we will output
- // a directive in the traditional GLSL fashion.
- //
- // TODO: Add some kind of configuration where we require the appropriate
- // extension and then emit a traditional line directive.
+ case LineDirectiveMode::GLSL:
+ shouldUseGLSLStyleLineDirective = true;
+ break;
+ }
- int id = 0;
- if(!context->shared->mapGLSLSourcePathToID.TryGetValue(path, id))
+ if(shouldUseGLSLStyleLineDirective)
{
- id = context->shared->glslSourceIDCount++;
- context->shared->mapGLSLSourcePathToID.Add(path, id);
- }
+ auto path = sourceLocation.getPath();
- sprintf(buffer, "%d", id);
- emitRawText(buffer);
- }
- else
- {
- // The simple case is to emit the path for the current source
- // location. We need to be a little bit careful with this,
- // because the path might include backslash characters if we
- // are on Windows, and we want to canonicalize those over
- // to forward slashes.
- //
- // TODO: Canonicalization like this should be done centrally
- // in a module that tracks source files.
+ // GLSL doesn't support the traditional form of a `#line` directive without
+ // an extension. Rather than depend on that extension we will output
+ // a directive in the traditional GLSL fashion.
+ //
+ // TODO: Add some kind of configuration where we require the appropriate
+ // extension and then emit a traditional line directive.
- emitRawText("\"");
- for(auto c : sourceLocation.getPath())
- {
- char charBuffer[] = { c, 0 };
- switch(c)
+ int id = 0;
+ if(!context->shared->mapGLSLSourcePathToID.TryGetValue(path, id))
{
- default:
- emitRawText(charBuffer);
- break;
+ id = context->shared->glslSourceIDCount++;
+ context->shared->mapGLSLSourcePathToID.Add(path, id);
+ }
- // The incoming file path might use `/` and/or `\\` as
- // a directory separator. We want to canonicalize this.
+ sprintf(buffer, "%d", id);
+ emitRawText(buffer);
+ }
+ else
+ {
+ // The simple case is to emit the path for the current source
+ // location. We need to be a little bit careful with this,
+ // because the path might include backslash characters if we
+ // are on Windows, and we want to canonicalize those over
+ // to forward slashes.
//
- // TODO: should probably canonicalize paths to not use backslash somewhere else
- // in the compilation pipeline...
- case '\\':
- emitRawText("/");
- break;
+ // TODO: Canonicalization like this should be done centrally
+ // in a module that tracks source files.
+
+ emitRawText("\"");
+ for(auto c : sourceLocation.getPath())
+ {
+ char charBuffer[] = { c, 0 };
+ switch(c)
+ {
+ default:
+ emitRawText(charBuffer);
+ break;
+
+ // The incoming file path might use `/` and/or `\\` as
+ // a directory separator. We want to canonicalize this.
+ //
+ // TODO: should probably canonicalize paths to not use backslash somewhere else
+ // in the compilation pipeline...
+ case '\\':
+ emitRawText("/");
+ break;
+ }
}
+ emitRawText("\"");
}
- emitRawText("\"");
}
emitRawText("\n");
@@ -648,11 +652,9 @@ struct EmitVisitor
switch(mode)
{
case LineDirectiveMode::None:
- case LineDirectiveMode::Default:
- // Default behavior is to not emit line directives, since they
- // don't help readability much for IR-based output.
return;
+ case LineDirectiveMode::Default:
default:
break;
}
@@ -3176,8 +3178,6 @@ struct EmitVisitor
IRInst* inst,
IREmitMode mode)
{
- advanceToSourceLocation(inst->sourceLoc);
-
switch(inst->op)
{
case kIROp_IntLit:
@@ -4487,10 +4487,6 @@ struct EmitVisitor
{
auto resultType = func->getResultType();
- // Put a newline before the function so that
- // the output will be more readable.
- emit("\n");
-
// Deal with decorations that need
// to be emitted as attributes
auto entryPointLayout = asEntryPoint(func);
@@ -4553,11 +4549,11 @@ struct EmitVisitor
emitIRStmtsForBlocks(ctx, func->getFirstBlock(), nullptr, nullptr);
dedent();
- emit("}\n");
+ emit("}\n\n");
}
else
{
- emit(";\n");
+ emit(";\n\n");
}
}
@@ -4646,7 +4642,7 @@ struct EmitVisitor
emitIRParamType(ctx, paramType, paramName);
}
- emit(");\n");
+ emit(");\n\n");
}
EntryPointLayout* getEntryPointLayout(
@@ -4769,7 +4765,7 @@ struct EmitVisitor
}
dedent();
- emit("};\n");
+ emit("};\n\n");
}
void emitIRMatrixLayoutModifiers(
@@ -5420,9 +5416,6 @@ struct EmitVisitor
Emit("}\n");
}
- // Emit a blank line so that the formatting is nicer.
- emit("\n");
-
if (auto paramBlockType = as<IRUniformParameterGroupType>(varType))
{
emitIRParameterGroup(
@@ -5499,7 +5492,7 @@ struct EmitVisitor
Emit("()");
}
- emit(";\n");
+ emit(";\n\n");
}
void emitIRGlobalConstantInitializer(
@@ -5556,6 +5549,8 @@ struct EmitVisitor
EmitContext* ctx,
IRInst* inst)
{
+ advanceToSourceLocation(inst->sourceLoc);
+
switch(inst->op)
{
case kIROp_Func: