summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/slang/check.cpp29
-rw-r--r--source/slang/compiled-program.h36
-rw-r--r--source/slang/compiler.cpp227
-rw-r--r--source/slang/compiler.h172
-rw-r--r--source/slang/options.cpp2
-rw-r--r--source/slang/parameter-binding.cpp40
-rw-r--r--source/slang/parameter-binding.h6
-rw-r--r--source/slang/parser.cpp22
-rw-r--r--source/slang/parser.h4
-rw-r--r--source/slang/preprocessor.h2
-rw-r--r--source/slang/slang.cpp769
-rw-r--r--source/slang/syntax-visitors.h12
-rw-r--r--source/slangc/main.cpp37
13 files changed, 667 insertions, 691 deletions
diff --git a/source/slang/check.cpp b/source/slang/check.cpp
index f79df0c40..128afcefe 100644
--- a/source/slang/check.cpp
+++ b/source/slang/check.cpp
@@ -46,27 +46,25 @@ namespace Slang
{
ProgramSyntaxNode * program = nullptr;
FunctionSyntaxNode * function = nullptr;
- CompileOptions const* options = nullptr;
- TranslationUnitOptions const* translationUnitOptions = nullptr;
+
CompileRequest* request = nullptr;
+ TranslationUnitRequest* translationUnit = nullptr;
// lexical outer statements
List<StatementSyntaxNode*> outerStmts;
public:
SemanticsVisitor(
DiagnosticSink * pErr,
- CompileOptions const& options,
- TranslationUnitOptions const& translationUnitOptions,
- CompileRequest* request)
+ CompileRequest* request,
+ TranslationUnitRequest* translationUnit)
: SyntaxVisitor(pErr)
- , options(&options)
- , translationUnitOptions(&translationUnitOptions)
, request(request)
+ , translationUnit(translationUnit)
{
}
- CompileOptions const& getOptions() { return *options; }
- TranslationUnitOptions const& getTranslationUnitOptions() { return *translationUnitOptions; }
+ CompileRequest* getCompileRequest() { return request; }
+ TranslationUnitRequest* getTranslationUnit() { return translationUnit; }
public:
// Translate Types
@@ -969,7 +967,7 @@ namespace Slang
// expressions without a type, and we need to ignore them.
if( !fromExpr->Type.type )
{
- if(getTranslationUnitOptions().compileFlags & SLANG_COMPILE_FLAG_NO_CHECKING )
+ if(getTranslationUnit()->compileFlags & SLANG_COMPILE_FLAG_NO_CHECKING )
return fromExpr;
}
@@ -981,7 +979,7 @@ namespace Slang
fromExpr.Ptr(),
nullptr))
{
- if(!(getTranslationUnitOptions().compileFlags & SLANG_COMPILE_FLAG_NO_CHECKING))
+ if(!(getTranslationUnit()->compileFlags & SLANG_COMPILE_FLAG_NO_CHECKING))
{
getSink()->diagnose(fromExpr->Position, Diagnostics::typeMismatch, toType, fromExpr->Type);
}
@@ -4967,12 +4965,11 @@ namespace Slang
};
SyntaxVisitor* CreateSemanticsVisitor(
- DiagnosticSink* err,
- CompileOptions const& options,
- TranslationUnitOptions const& translationUnitOptions,
- CompileRequest* request)
+ DiagnosticSink* err,
+ CompileRequest* request,
+ TranslationUnitRequest* translationUnit)
{
- return new SemanticsVisitor(err, options, translationUnitOptions, request);
+ return new SemanticsVisitor(err, request, translationUnit);
}
//
diff --git a/source/slang/compiled-program.h b/source/slang/compiled-program.h
index 1766127b2..7f5b674a0 100644
--- a/source/slang/compiled-program.h
+++ b/source/slang/compiled-program.h
@@ -8,42 +8,6 @@
namespace Slang
{
- void IndentString(StringBuilder & sb, String src);
-
- struct EntryPointResult
- {
- String outputSource;
- };
-
- struct TranslationUnitResult
- {
- String outputSource;
- List<EntryPointResult> entryPoints;
- };
-
- class CompileResult
- {
- public:
- DiagnosticSink* mSink = nullptr;
-
- // Per-translation-unit results
- List<TranslationUnitResult> translationUnits;
-
- CompileResult()
- {}
- ~CompileResult()
- {
- }
- DiagnosticSink * GetErrorWriter()
- {
- return mSink;
- }
- int GetErrorCount()
- {
- return mSink->GetErrorCount();
- }
- };
-
}
#endif \ No newline at end of file
diff --git a/source/slang/compiler.cpp b/source/slang/compiler.cpp
index 6db04b900..9132624f9 100644
--- a/source/slang/compiler.cpp
+++ b/source/slang/compiler.cpp
@@ -32,6 +32,14 @@
namespace Slang
{
+
+ // EntryPointRequest
+
+ TranslationUnitRequest* EntryPointRequest::getTranslationUnit()
+ {
+ return compileRequest->translationUnits[translationUnitIndex].Ptr();
+ }
+
//
Profile Profile::LookUp(char const* name)
@@ -47,34 +55,91 @@ namespace Slang
//
- String EmitHLSL(ExtraContext& context)
+ String emitHLSLForTranslationUnit(
+ TranslationUnitRequest* translationUnit)
{
- if (context.getOptions().passThrough != PassThroughMode::None)
+ auto compileRequest = translationUnit->compileRequest;
+ if (compileRequest->passThrough != PassThroughMode::None)
{
- return context.sourceText;
+ // Generate a string that includes the content of
+ // the source file(s), along with a line directive
+ // to ensure that we get reasonable messages
+ // from the downstream compiler when in pass-through
+ // mode.
+
+ StringBuilder codeBuilder;
+ for(auto sourceFile : translationUnit->sourceFiles)
+ {
+ codeBuilder << "#line 1 \"";
+ for(auto c : sourceFile->path)
+ {
+ char buffer[] = { c, 0 };
+ switch(c)
+ {
+ default:
+ codeBuilder << buffer;
+ break;
+
+ case '\\':
+ codeBuilder << "\\\\";
+ }
+ }
+ codeBuilder << "\"\n";
+ codeBuilder << sourceFile->content << "\n";
+ }
+
+ return codeBuilder.ProduceString();
}
else
{
- // TODO(tfoley): probably need a way to customize the emit logic...
return emitProgram(
- context.programSyntax.Ptr(),
- context.programLayout,
+ translationUnit->SyntaxNode.Ptr(),
+ compileRequest->layout.Ptr(),
CodeGenTarget::HLSL);
}
}
- String emitGLSLForEntryPoint(ExtraContext& context, EntryPointOption const& /*entryPoint*/)
+ String emitGLSLForEntryPoint(
+ EntryPointRequest* entryPoint)
{
- if (context.getOptions().passThrough != PassThroughMode::None)
+ auto compileRequest = entryPoint->compileRequest;
+ auto translationUnit = entryPoint->getTranslationUnit();
+
+ if (compileRequest->passThrough != PassThroughMode::None)
{
- return context.sourceText;
+ // Generate a string that includes the content of
+ // the source file(s), along with a line directive
+ // to ensure that we get reasonable messages
+ // from the downstream compiler when in pass-through
+ // mode.
+
+ StringBuilder codeBuilder;
+ int translationUnitCounter = 0;
+ for(auto sourceFile : translationUnit->sourceFiles)
+ {
+ int translationUnitIndex = translationUnitCounter++;
+
+ // We want to output `#line` directives, but we need
+ // to skip this for the first file, since otherwise
+ // some GLSL implementations will get tripped up by
+ // not having the `#version` directive be the first
+ // thing in the file.
+ if(translationUnitIndex != 0)
+ {
+ codeBuilder << "#line 1 " << translationUnitIndex << "\n";
+ }
+ codeBuilder << sourceFile->content << "\n";
+ }
+
+ return codeBuilder.ProduceString();
}
else
{
- // TODO(tfoley): probably need a way to customize the emit logic...
+ // TODO(tfoley): need to pass along the entry point
+ // so that we properly emit it as the `main` function.
return emitProgram(
- context.programSyntax.Ptr(),
- context.programLayout,
+ translationUnit->SyntaxNode.Ptr(),
+ compileRequest->layout.Ptr(),
CodeGenTarget::GLSL);
}
}
@@ -103,8 +168,7 @@ namespace Slang
}
List<uint8_t> EmitDXBytecodeForEntryPoint(
- ExtraContext& context,
- EntryPointOption const& entryPoint)
+ EntryPointRequest* entryPoint)
{
static pD3DCompile D3DCompile_ = nullptr;
if (!D3DCompile_)
@@ -122,38 +186,20 @@ namespace Slang
//
// To work around that, we prepend a custom `#line` directive.
- String rawHlslCode = EmitHLSL(context);
+ auto translationUnit = entryPoint->getTranslationUnit();
- StringBuilder hlslCodeBuilder;
- hlslCodeBuilder << "#line 1 \"";
- for(auto c : context.sourcePath)
- {
- char buffer[] = { c, 0 };
- switch(c)
- {
- default:
- hlslCodeBuilder << buffer;
- break;
-
- case '\\':
- hlslCodeBuilder << "\\\\";
- }
- }
- hlslCodeBuilder << "\"\n";
- hlslCodeBuilder << rawHlslCode;
-
- auto hlslCode = hlslCodeBuilder.ProduceString();
+ auto hlslCode = emitHLSLForTranslationUnit(translationUnit);
ID3DBlob* codeBlob;
ID3DBlob* diagnosticsBlob;
HRESULT hr = D3DCompile_(
hlslCode.begin(),
hlslCode.Length(),
- context.sourcePath.begin(),
+ "slang",
nullptr,
nullptr,
- entryPoint.name.begin(),
- GetHLSLProfileName(entryPoint.profile),
+ entryPoint->name.begin(),
+ GetHLSLProfileName(entryPoint->profile),
0,
0,
&codeBlob,
@@ -181,6 +227,7 @@ namespace Slang
return data;
}
+#if 0
List<uint8_t> EmitDXBytecode(
ExtraContext& context)
{
@@ -200,10 +247,10 @@ namespace Slang
return EmitDXBytecodeForEntryPoint(context, context.getTranslationUnitOptions().entryPoints[0]);
}
+#endif
String EmitDXBytecodeAssemblyForEntryPoint(
- ExtraContext& context,
- EntryPointOption const& entryPoint)
+ EntryPointRequest* entryPoint)
{
static pD3DDisassemble D3DDisassemble_ = nullptr;
if (!D3DDisassemble_)
@@ -215,7 +262,7 @@ namespace Slang
assert(D3DDisassemble_);
}
- List<uint8_t> dxbc = EmitDXBytecodeForEntryPoint(context, entryPoint);
+ List<uint8_t> dxbc = EmitDXBytecodeForEntryPoint(entryPoint);
if (!dxbc.Count())
{
return "";
@@ -242,7 +289,7 @@ namespace Slang
return result;
}
-
+#if 0
String EmitDXBytecodeAssembly(
ExtraContext& context)
{
@@ -260,6 +307,7 @@ namespace Slang
}
return sb.ProduceString();
}
+#endif
HMODULE getGLSLCompilerDLL()
@@ -273,10 +321,9 @@ namespace Slang
String emitSPIRVAssemblyForEntryPoint(
- ExtraContext& context,
- EntryPointOption const& entryPoint)
+ EntryPointRequest* entryPoint)
{
- String rawGLSL = emitGLSLForEntryPoint(context, entryPoint);
+ String rawGLSL = emitGLSLForEntryPoint(entryPoint);
static glslang_CompileFunc glslang_compile = nullptr;
if (!glslang_compile)
@@ -297,9 +344,9 @@ namespace Slang
};
glslang_CompileRequest request;
- request.sourcePath = context.sourcePath.begin();
+ request.sourcePath = "slang";
request.sourceText = rawGLSL.begin();
- request.slangStage = (SlangStage) entryPoint.profile.GetStage();
+ request.slangStage = (SlangStage) entryPoint->profile.GetStage();
request.diagnosticFunc = outputFunc;
request.diagnosticUserData = &diagnosticBuilder;
@@ -323,6 +370,7 @@ namespace Slang
}
#endif
+#if 0
String emitSPIRVAssembly(
ExtraContext& context)
{
@@ -340,24 +388,28 @@ namespace Slang
}
return sb.ProduceString();
}
+#endif
// Do emit logic for a single entry point
- EntryPointResult emitEntryPoint(ExtraContext& context, EntryPointOption& entryPoint)
+ EntryPointResult emitEntryPoint(
+ EntryPointRequest* entryPoint)
{
EntryPointResult result;
- switch (context.getOptions().Target)
+ auto compileRequest = entryPoint->compileRequest;
+
+ switch (compileRequest->Target)
{
case CodeGenTarget::GLSL:
{
- String code = emitGLSLForEntryPoint(context, entryPoint);
+ String code = emitGLSLForEntryPoint(entryPoint);
result.outputSource = code;
}
break;
case CodeGenTarget::DXBytecode:
{
- auto code = EmitDXBytecodeForEntryPoint(context, entryPoint);
+ auto code = EmitDXBytecodeForEntryPoint(entryPoint);
// TODO(tfoley): Need to figure out an appropriate interface
// for returning binary code, in addition to source.
@@ -396,14 +448,14 @@ namespace Slang
case CodeGenTarget::DXBytecodeAssembly:
{
- String code = EmitDXBytecodeAssemblyForEntryPoint(context, entryPoint);
+ String code = EmitDXBytecodeAssemblyForEntryPoint(entryPoint);
result.outputSource = code;
}
break;
case CodeGenTarget::SPIRVAssembly:
{
- String code = emitSPIRVAssemblyForEntryPoint(context, entryPoint);
+ String code = emitSPIRVAssemblyForEntryPoint(entryPoint);
result.outputSource = code;
}
break;
@@ -421,26 +473,28 @@ namespace Slang
}
- TranslationUnitResult emitTranslationUnitEntryPoints(ExtraContext& context)
+ TranslationUnitResult emitTranslationUnitEntryPoints(
+ TranslationUnitRequest* translationUnit)
{
TranslationUnitResult result;
- for (auto& entryPoint : context.getTranslationUnitOptions().entryPoints)
+ for (auto& entryPoint : translationUnit->entryPoints)
{
- EntryPointResult entryPointResult = emitEntryPoint(context, entryPoint);
+ EntryPointResult entryPointResult = emitEntryPoint(entryPoint.Ptr());
- result.entryPoints.Add(entryPointResult);
+ entryPoint->result = entryPointResult;
}
// The result for the translation unit will just be the concatenation
// of the results for each entry point. This doesn't actually make
// much sense, but it is good enough for now.
+ //
+ // TODO: Replace this with a packaged JSON and/or binary format.
StringBuilder sb;
- for (auto& entryPointResult : result.entryPoints)
+ for (auto& entryPoint : translationUnit->entryPoints)
{
- sb << entryPointResult.outputSource;
+ sb << entryPoint->result.outputSource;
}
-
result.outputSource = sb.ProduceString();
return result;
@@ -448,26 +502,29 @@ namespace Slang
// Do emit logic for an entire translation unit, which might
// have zero or more entry points
- TranslationUnitResult emitTranslationUnit(ExtraContext& context)
+ TranslationUnitResult emitTranslationUnit(
+ TranslationUnitRequest* translationUnit)
{
+ auto compileRequest = translationUnit->compileRequest;
+
// Most of our code generation targets will require us
// to proceed through one entry point at a time, but
// in some cases we can emit an entire translation unit
// in one go.
- switch (context.getOptions().Target)
+ switch (compileRequest->Target)
{
default:
// The default behavior is going to loop over all the entry
// points, and then collect an aggregate result.
- return emitTranslationUnitEntryPoints(context);
+ return emitTranslationUnitEntryPoints(translationUnit);
case CodeGenTarget::HLSL:
// When targetting HLSL, we can emit the entire translation unit
// as a single HLSL program, and include all the entry points.
{
- String hlsl = EmitHLSL(context);
+ String hlsl = emitHLSLForTranslationUnit(translationUnit);
TranslationUnitResult result;
result.outputSource = hlsl;
@@ -475,13 +532,12 @@ namespace Slang
// Because the user might ask for per-entry-point source,
// we will just attach the same string as the result for
// each entry point.
- for( auto& entryPoint : context.getTranslationUnitOptions().entryPoints )
+ for( auto& entryPoint : translationUnit->entryPoints )
{
- (void)entryPoint;
-
EntryPointResult entryPointResult;
entryPointResult.outputSource = hlsl;
- result.entryPoints.Add(entryPointResult);
+
+ entryPoint->result = entryPointResult;
}
return result;
@@ -490,36 +546,31 @@ namespace Slang
}
}
+#if 0
TranslationUnitResult generateOutput(ExtraContext& context)
{
TranslationUnitResult result = emitTranslationUnit(context);
return result;
}
+#endif
void generateOutput(
- ExtraContext& context,
- CollectionOfTranslationUnits* collectionOfTranslationUnits)
+ CompileRequest* compileRequest)
{
- switch (context.getOptions().Target)
+ switch (compileRequest->Target)
{
default:
// For most targets, we will do things per-translation-unit
- for( auto translationUnit : collectionOfTranslationUnits->translationUnits )
+ for( auto translationUnit : compileRequest->translationUnits )
{
- ExtraContext innerContext = context;
- innerContext.translationUnitOptions = &translationUnit.options;
- innerContext.programSyntax = translationUnit.SyntaxNode;
- innerContext.sourcePath = "slang"; // don't have this any more!
- innerContext.sourceText = "";
-
- TranslationUnitResult translationUnitResult = generateOutput(innerContext);
- context.compileResult->translationUnits.Add(translationUnitResult);
+ TranslationUnitResult translationUnitResult = emitTranslationUnit(translationUnit.Ptr());
+ translationUnit->result = translationUnitResult;
}
break;
case CodeGenTarget::ReflectionJSON:
{
- String reflectionJSON = emitReflectionJSON(context.programLayout);
+ String reflectionJSON = emitReflectionJSON(compileRequest->layout.Ptr());
// HACK(tfoley): just print it out since that is what people probably expect.
// TODO: need a way to control where output gets routed across all possible targets.
@@ -528,20 +579,4 @@ namespace Slang
break;
}
}
-
- TranslationUnitResult passThrough(
- String const& sourceText,
- String const& sourcePath,
- const CompileOptions & options,
- TranslationUnitOptions const& translationUnitOptions)
- {
- ExtraContext extra;
- extra.options = &options;
- extra.translationUnitOptions = &translationUnitOptions;
- extra.sourcePath = sourcePath;
- extra.sourceText = sourceText;
-
- return generateOutput(extra);
- }
-
}
diff --git a/source/slang/compiler.h b/source/slang/compiler.h
index 39c91e21b..36fc5f42f 100644
--- a/source/slang/compiler.h
+++ b/source/slang/compiler.h
@@ -14,7 +14,7 @@
namespace Slang
{
struct IncludeHandler;
- struct CompileRequest;
+ class CompileRequest;
enum class CompilerMode
{
@@ -48,11 +48,42 @@ namespace Slang
ReflectionJSON = SLANG_REFLECTION_JSON,
};
+ class CompileRequest;
+ class TranslationUnitRequest;
+
+ // Result of compiling an entry point
+ struct EntryPointResult
+ {
+ String outputSource;
+ };
+
// Describes an entry point that we've been requested to compile
- struct EntryPointOption
+ class EntryPointRequest : public RefObject
{
+ public:
+ // The parent compile request
+ CompileRequest* compileRequest = nullptr;
+
+ // The name of the entry point function (e.g., `main`)
String name;
+
+ // The profile that the entry point will be compiled for
+ // (this is a combination of the target state, and also
+ // a feature level that sets capabilities)
Profile profile;
+
+ // The index of the translation unit (within the parent
+ // compile request) that the entry point function is
+ // supposed to be defined in.
+ int translationUnitIndex;
+
+ // The resulting output for the enry point
+ //
+ // TODO: low-level code generation should be a distinct step
+ EntryPointResult result;
+
+ // The translation unit that this entry point came from
+ TranslationUnitRequest* getTranslationUnit();
};
enum class PassThroughMode : SlangPassThrough
@@ -74,27 +105,49 @@ namespace Slang
String content;
};
- // Options for a single translation unit being requested by the user
- class TranslationUnitOptions
+ // Result of compiling a translation unit
+ struct TranslationUnitResult
+ {
+ String outputSource;
+ };
+
+ // A single translation unit requested to be compiled.
+ //
+ class TranslationUnitRequest : public RefObject
{
public:
- SourceLanguage sourceLanguage = SourceLanguage::Unknown;
+ // The parent compile request
+ CompileRequest* compileRequest = nullptr;
- // All entry points we've been asked to compile for this translation unit
- List<EntryPointOption> entryPoints;
+ // The language in which the source file(s)
+ // are assumed to be written
+ SourceLanguage sourceLanguage = SourceLanguage::Unknown;
// The source file(s) that will be compiled to form this translation unit
+ //
+ // Usually, for HLSL or GLSL there will be only one file.
List<RefPtr<SourceFile> > sourceFiles;
+ // The entry points associated with this translation unit
+ List<RefPtr<EntryPointRequest> > entryPoints;
+
// Preprocessor definitions to use for this translation unit only
// (whereas the ones on `CompileOptions` will be shared)
Dictionary<String, String> preprocessorDefinitions;
// Compile flags for this translation unit
SlangCompileFlags compileFlags = 0;
- };
+ // The parsed syntax for the translation unit
+ RefPtr<ProgramSyntaxNode> SyntaxNode;
+ // The resulting output for the translation unit
+ //
+ // TODO: low-level code generation should be a distinct step
+ TranslationUnitResult result;
+ };
+
+ // A directory to be searched when looking for files (e.g., `#include`)
struct SearchDirectory
{
enum Kind
@@ -114,9 +167,14 @@ namespace Slang
Kind kind;
};
- class CompileOptions
+ class Session;
+
+ class CompileRequest : public RefObject
{
public:
+ // Pointer to parent session
+ Session* mSession;
+
// What target language are we compiling to?
CodeGenTarget Target = CodeGenTarget::Unknown;
@@ -127,7 +185,11 @@ namespace Slang
Dictionary<String, String> preprocessorDefinitions;
// Translation units we are being asked to compile
- List<TranslationUnitOptions> translationUnits;
+ List<RefPtr<TranslationUnitRequest> > translationUnits;
+
+ // Entry points we've been asked to compile (each
+ // assocaited with a translation unit).
+ List<RefPtr<EntryPointRequest> > entryPoints;
// The code generation profile we've been asked to use.
Profile profile;
@@ -137,53 +199,73 @@ namespace Slang
// Compile flags to be shared by all translation units
SlangCompileFlags compileFlags = 0;
- };
- // This is the representation of a given translation unit
- class CompileUnit
- {
- public:
- TranslationUnitOptions options;
- RefPtr<ProgramSyntaxNode> SyntaxNode;
- };
+ // Output stuff
+ DiagnosticSink mSink;
+ String mDiagnosticOutput;
- // TODO: pick an appropriate name for this...
- class CollectionOfTranslationUnits : public RefObject
- {
- public:
- List<CompileUnit> translationUnits;
+ // Files that compilation depended on
+ List<String> mDependencyFilePaths;
- // TODO: this is more output-oriented, but maybe okay to have here...
+ // The resulting reflection layout information
RefPtr<ProgramLayout> layout;
- };
- // Context information for code generation
- struct ExtraContext
- {
- CompileOptions const* options = nullptr;
- TranslationUnitOptions const* translationUnitOptions = nullptr;
+ // Modules that have been dynamically loaded via `import`
+ Dictionary<String, RefPtr<ProgramSyntaxNode>> loadedModules;
+
+
+ CompileRequest(Session* session)
+ : mSession(session)
+ {}
- CompileResult* compileResult = nullptr;
+ ~CompileRequest()
+ {}
- RefPtr<ProgramSyntaxNode> programSyntax;
- ProgramLayout* programLayout;
+ void parseTranslationUnit(
+ TranslationUnitRequest* translationUnit);
- String sourceText;
- String sourcePath;
+ void CompileRequest::checkTranslationUnit(
+ TranslationUnitRequest* translationUnit);
- CompileOptions const& getOptions() { return *options; }
- TranslationUnitOptions const& getTranslationUnitOptions() { return *translationUnitOptions; }
- };
+ void checkAllTranslationUnits();
+
+ int executeActionsInner();
+ int executeActions();
+
+ int addTranslationUnit(SourceLanguage language, String const& name);
+
+ void addTranslationUnitSourceString(
+ int translationUnitIndex,
+ String const& path,
+ String const& source);
- TranslationUnitResult passThrough(
- String const& sourceText,
- String const& sourcePath,
- const CompileOptions & options,
- TranslationUnitOptions const& translationUnitOptions);
+ void addTranslationUnitSourceFile(
+ int translationUnitIndex,
+ String const& path);
+
+ int addEntryPoint(
+ int translationUnitIndex,
+ String const& name,
+ Profile profile);
+
+ RefPtr<ProgramSyntaxNode> loadModule(
+ String const& name,
+ String const& path,
+ String const& source,
+ CodePosition const& loc);
+
+ String autoImportModule(
+ String const& path,
+ String const& source,
+ CodePosition const& loc);
+
+ RefPtr<ProgramSyntaxNode> findOrImportModule(
+ String const& name,
+ CodePosition const& loc);
+ };
void generateOutput(
- ExtraContext& context,
- CollectionOfTranslationUnits* collectionOfTranslationUnits);
+ CompileRequest* compileRequest);
}
#endif \ No newline at end of file
diff --git a/source/slang/options.cpp b/source/slang/options.cpp
index b3f0629c6..81b893d66 100644
--- a/source/slang/options.cpp
+++ b/source/slang/options.cpp
@@ -520,7 +520,7 @@ struct OptionsParser
// Now place all those entry points where they belong
for( auto& entryPoint : rawEntryPoints )
{
- spAddTranslationUnitEntryPoint(
+ spAddEntryPoint(
compileRequest,
entryPoint.translationUnitIndex,
entryPoint.name.begin(),
diff --git a/source/slang/parameter-binding.cpp b/source/slang/parameter-binding.cpp
index 0756eb68c..70cb4e7ba 100644
--- a/source/slang/parameter-binding.cpp
+++ b/source/slang/parameter-binding.cpp
@@ -941,7 +941,7 @@ static void processEntryPointParameter(
static void collectEntryPointParameters(
ParameterBindingContext* context,
- EntryPointOption const& entryPoint,
+ EntryPointRequest* entryPoint,
ProgramSyntaxNode* translationUnitSyntax)
{
// First, look for the entry point with the specified name
@@ -950,7 +950,7 @@ static void collectEntryPointParameters(
buildMemberDictionary(translationUnitSyntax);
Decl* entryPointDecl;
- if( !translationUnitSyntax->memberDictionary.TryGetValue(entryPoint.name, entryPointDecl) )
+ if( !translationUnitSyntax->memberDictionary.TryGetValue(entryPoint->name, entryPointDecl) )
{
// No such entry point!
return;
@@ -970,7 +970,7 @@ static void collectEntryPointParameters(
// Create the layout object here
auto entryPointLayout = new EntryPointLayout();
- entryPointLayout->profile = entryPoint.profile;
+ entryPointLayout->profile = entryPoint->profile;
entryPointLayout->entryPoint = entryPointFuncDecl;
@@ -1043,18 +1043,18 @@ static void collectEntryPointParameters(
// inputs and outputs).
static Stage
inferStageForTranslationUnit(
- CompileUnit const& translationUnit)
+ TranslationUnitRequest* translationUnit)
{
// In the specific case where we are compiling GLSL input,
// and have only a single entry point, use the stage
// of the entry point.
//
// TODO: can we generalize this at all?
- if( translationUnit.options.sourceLanguage == SourceLanguage::GLSL )
+ if( translationUnit->sourceLanguage == SourceLanguage::GLSL )
{
- if( translationUnit.options.entryPoints.Count() == 1 )
+ if( translationUnit->entryPoints.Count() == 1 )
{
- return translationUnit.options.entryPoints[0].profile.GetStage();
+ return translationUnit->entryPoints[0]->profile.GetStage();
}
}
@@ -1063,36 +1063,36 @@ inferStageForTranslationUnit(
static void collectParameters(
ParameterBindingContext* inContext,
- CollectionOfTranslationUnits* program)
+ CompileRequest* request)
{
ParameterBindingContext contextData = *inContext;
auto context = &contextData;
- for( auto& translationUnit : program->translationUnits )
+ for( auto& translationUnit : request->translationUnits )
{
- context->stage = inferStageForTranslationUnit(translationUnit);
+ context->stage = inferStageForTranslationUnit(translationUnit.Ptr());
// First look at global-scope parameters
- collectGlobalScopeParameters(context, translationUnit.SyntaxNode.Ptr());
+ collectGlobalScopeParameters(context, translationUnit->SyntaxNode.Ptr());
// Next consider parameters for entry points
- for( auto& entryPoint : translationUnit.options.entryPoints )
+ for( auto& entryPoint : translationUnit->entryPoints )
{
- context->stage = entryPoint.profile.GetStage();
- collectEntryPointParameters(context, entryPoint, translationUnit.SyntaxNode.Ptr());
+ context->stage = entryPoint->profile.GetStage();
+ collectEntryPointParameters(context, entryPoint.Ptr(), translationUnit->SyntaxNode.Ptr());
}
}
}
-void GenerateParameterBindings(
- CollectionOfTranslationUnits* program)
+void generateParameterBindings(
+ CompileRequest* request)
{
// TODO: infer a language or set of language rules to use based on the
// source files and entry points given
auto language = SourceLanguage::Unknown;
- for( auto& translationUnit : program->translationUnits )
+ for( auto& translationUnit : request->translationUnits )
{
- auto translationUnitLanguage = translationUnit.options.sourceLanguage;
+ auto translationUnitLanguage = translationUnit->sourceLanguage;
if( language == SourceLanguage::Unknown )
{
language = translationUnitLanguage;
@@ -1129,7 +1129,7 @@ void GenerateParameterBindings(
context.layoutRules = sharedContext.defaultLayoutRules;
// Walk through AST to discover all the parameters
- collectParameters(&context, program);
+ collectParameters(&context, request);
// Now walk through the parameters to generate initial binding information
for( auto& parameter : sharedContext.parameters )
@@ -1245,7 +1245,7 @@ void GenerateParameterBindings(
// We now have a bunch of layout information, which we should
// record into a suitable object that represents the program
programLayout->globalScopeLayout = globalScopeLayout;
- program->layout = programLayout;
+ request->layout = programLayout;
}
}
diff --git a/source/slang/parameter-binding.h b/source/slang/parameter-binding.h
index 2fff08090..66c8053d3 100644
--- a/source/slang/parameter-binding.h
+++ b/source/slang/parameter-binding.h
@@ -8,7 +8,7 @@
namespace Slang {
-class CollectionOfTranslationUnits;
+class CompileRequest;
// The parameter-binding interface is responsible for assigning
// binding locations/registers to every parameter of a shader
@@ -23,8 +23,8 @@ class CollectionOfTranslationUnits;
// and attach that information to the syntax nodes
// of the program.
-void GenerateParameterBindings(
- CollectionOfTranslationUnits* program);
+void generateParameterBindings(
+ CompileRequest* compileRequest);
}
diff --git a/source/slang/parser.cpp b/source/slang/parser.cpp
index 75398a40d..5e06aa877 100644
--- a/source/slang/parser.cpp
+++ b/source/slang/parser.cpp
@@ -32,8 +32,7 @@ namespace Slang
class Parser
{
public:
- CompileOptions const& options;
- TranslationUnitOptions const& translationUnitOptions;
+ TranslationUnitRequest* translationUnit;
int anonymousCounter = 0;
@@ -67,15 +66,11 @@ namespace Slang
currentScope = currentScope->parent;
}
Parser(
- CompileOptions const& options,
- TranslationUnitOptions const& translationUnitOptions,
TokenSpan const& _tokens,
DiagnosticSink * sink,
String _fileName,
RefPtr<Scope> const& outerScope)
- : options(options)
- , translationUnitOptions(translationUnitOptions)
- , tokenReader(_tokens)
+ : tokenReader(_tokens)
, sink(sink)
, fileName(_fileName)
, outerScope(outerScope)
@@ -2500,7 +2495,7 @@ parser->ReadToken(TokenType::Comma);
RefPtr<StatementSyntaxNode> Parser::ParseBlockStatement()
{
- if( translationUnitOptions.compileFlags & SLANG_COMPILE_FLAG_NO_CHECKING )
+ if( translationUnit->compileFlags & SLANG_COMPILE_FLAG_NO_CHECKING )
{
// We have been asked to parse the input, but not attempt to understand it.
@@ -3157,15 +3152,16 @@ parser->ReadToken(TokenType::Comma);
// Parse a source file into an existing translation unit
void parseSourceFile(
- ProgramSyntaxNode* translationUnitSyntax,
- CompileOptions const& options,
- TranslationUnitOptions const& translationUnitOptions,
+ TranslationUnitRequest* translationUnit,
TokenSpan const& tokens,
DiagnosticSink* sink,
String const& fileName,
RefPtr<Scope> const& outerScope)
{
- Parser parser(options, translationUnitOptions, tokens, sink, fileName, outerScope);
- return parser.parseSourceFile(translationUnitSyntax);
+ Parser parser(tokens, sink, fileName, outerScope);
+
+ parser.translationUnit = translationUnit;
+
+ return parser.parseSourceFile(translationUnit->SyntaxNode.Ptr());
}
}
diff --git a/source/slang/parser.h b/source/slang/parser.h
index d74a3f5a8..8dfef4c12 100644
--- a/source/slang/parser.h
+++ b/source/slang/parser.h
@@ -9,9 +9,7 @@ namespace Slang
{
// Parse a source file into an existing translation unit
void parseSourceFile(
- ProgramSyntaxNode* translationUnitSyntax,
- CompileOptions const& options,
- TranslationUnitOptions const& translationUnitOptions,
+ TranslationUnitRequest* translationUnit,
TokenSpan const& tokens,
DiagnosticSink* sink,
String const& fileName,
diff --git a/source/slang/preprocessor.h b/source/slang/preprocessor.h
index f16bc3929..0c7848bb4 100644
--- a/source/slang/preprocessor.h
+++ b/source/slang/preprocessor.h
@@ -7,7 +7,7 @@
namespace Slang {
-struct CompileRequest;
+class CompileRequest;
class DiagnosticSink;
class ProgramSyntaxNode;
diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp
index d86825766..37d72cadc 100644
--- a/source/slang/slang.cpp
+++ b/source/slang/slang.cpp
@@ -79,66 +79,50 @@ public:
ExpressionType::Finalize();
}
- CompileUnit createPredefUnit()
- {
- CompileUnit translationUnit;
-
-
- RefPtr<ProgramSyntaxNode> translationUnitSyntax = new ProgramSyntaxNode();
-
- TranslationUnitOptions translationUnitOptions;
- translationUnit.options = translationUnitOptions;
- translationUnit.SyntaxNode = translationUnitSyntax;
-
- return translationUnit;
- }
-
void addBuiltinSource(
RefPtr<Scope> const& scope,
String const& path,
String const& source);
};
-struct CompileRequest
+struct IncludeHandlerImpl : IncludeHandler
{
- // Pointer to parent session
- Session* mSession;
-
- // Input options
- CompileOptions Options;
-
- // Output stuff
- DiagnosticSink mSink;
- String mDiagnosticOutput;
-
- RefPtr<CollectionOfTranslationUnits> mCollectionOfTranslationUnits;
-
- RefPtr<ProgramLayout> mReflectionData;
+ CompileRequest* request;
- CompileResult mResult;
+ virtual IncludeResult TryToFindIncludeFile(
+ String const& pathToInclude,
+ String const& pathIncludedFrom,
+ String* outFoundPath,
+ String* outFoundSource) override
+ {
+ String path = Path::Combine(Path::GetDirectoryName(pathIncludedFrom), pathToInclude);
+ if (File::Exists(path))
+ {
+ *outFoundPath = path;
+ *outFoundSource = File::ReadAllText(path);
- List<String> mDependencyFilePaths;
+ request->mDependencyFilePaths.Add(path);
- CompileRequest(Session* session)
- : mSession(session)
- {}
+ // HACK(tfoley): We might have found the file in the same directory,
+ // but what if this is also inside an auto-import path?
+ for (auto & dir : request->searchDirectories)
+ {
+ // Only consider auto-import paths
+ if(dir.kind != SearchDirectory::Kind::AutoImport)
+ continue;
- ~CompileRequest()
- {}
+ String otherPath = Path::Combine(dir.path, pathToInclude);
- struct IncludeHandlerImpl : IncludeHandler
- {
- CompileRequest* request;
+ if(otherPath == path)
+ return IncludeResult::FoundAutoImportFile;
+ }
- List<SearchDirectory> searchDirs;
+ return IncludeResult::FoundIncludeFile;
+ }
- virtual IncludeResult TryToFindIncludeFile(
- String const& pathToInclude,
- String const& pathIncludedFrom,
- String* outFoundPath,
- String* outFoundSource) override
+ for (auto & dir : request->searchDirectories)
{
- String path = Path::Combine(Path::GetDirectoryName(pathIncludedFrom), pathToInclude);
+ path = Path::Combine(dir.path, pathToInclude);
if (File::Exists(path))
{
*outFoundPath = path;
@@ -146,464 +130,381 @@ struct CompileRequest
request->mDependencyFilePaths.Add(path);
- // HACK(tfoley): We might have found the file in the same directory,
- // but what if this is also inside an auto-import path?
- for (auto & dir : searchDirs)
- {
- // Only consider auto-import paths
- if(dir.kind != SearchDirectory::Kind::AutoImport)
- continue;
-
- String otherPath = Path::Combine(dir.path, pathToInclude);
-
- if(otherPath == path)
- return IncludeResult::FoundAutoImportFile;
- }
-
- return IncludeResult::FoundIncludeFile;
- }
-
- for (auto & dir : searchDirs)
- {
- path = Path::Combine(dir.path, pathToInclude);
- if (File::Exists(path))
+ switch( dir.kind )
{
- *outFoundPath = path;
- *outFoundSource = File::ReadAllText(path);
-
- request->mDependencyFilePaths.Add(path);
+ case SearchDirectory::Kind::Default:
+ return IncludeResult::FoundIncludeFile;
- switch( dir.kind )
- {
- case SearchDirectory::Kind::Default:
- return IncludeResult::FoundIncludeFile;
-
- case SearchDirectory::Kind::AutoImport:
- return IncludeResult::FoundAutoImportFile;
- }
+ case SearchDirectory::Kind::AutoImport:
+ return IncludeResult::FoundAutoImportFile;
}
}
- return IncludeResult::NotFound;
- }
- };
-
-
- CompileUnit parseTranslationUnit(
- TranslationUnitOptions const& translationUnitOptions,
- CompileOptions& options)
- {
- IncludeHandlerImpl includeHandler;
- includeHandler.request = this;
-
- CompileUnit translationUnit;
-
- RefPtr<Scope> languageScope;
- switch (translationUnitOptions.sourceLanguage)
- {
- case SourceLanguage::HLSL:
- languageScope = mSession->hlslLanguageScope;
- break;
-
- case SourceLanguage::GLSL:
- languageScope = mSession->glslLanguageScope;
- break;
-
- case SourceLanguage::Slang:
- default:
- languageScope = mSession->slangLanguageScope;
- break;
- }
-
- Dictionary<String, String> preprocessorDefinitions;
- for(auto& def : options.preprocessorDefinitions)
- preprocessorDefinitions.Add(def.Key, def.Value);
- for(auto& def : translationUnitOptions.preprocessorDefinitions)
- preprocessorDefinitions.Add(def.Key, def.Value);
-
- RefPtr<ProgramSyntaxNode> translationUnitSyntax = new ProgramSyntaxNode();
-
- for (auto sourceFile : translationUnitOptions.sourceFiles)
- {
- auto sourceFilePath = sourceFile->path;
-
- auto searchDirs = options.searchDirectories;
- searchDirs.Reverse();
- searchDirs.Add(SearchDirectory(Path::GetDirectoryName(sourceFilePath), SearchDirectory::Kind::Default));
- searchDirs.Reverse();
- includeHandler.searchDirs = searchDirs;
-
- String source = sourceFile->content;
-
- auto tokens = preprocessSource(
- source,
- sourceFilePath,
- mResult.GetErrorWriter(),
- &includeHandler,
- preprocessorDefinitions,
- translationUnitSyntax.Ptr(),
- this);
-
- parseSourceFile(
- translationUnitSyntax.Ptr(),
- options,
- translationUnitOptions,
- tokens,
- mResult.GetErrorWriter(),
- sourceFilePath,
- languageScope);
}
+ return IncludeResult::NotFound;
+ }
+};
- translationUnit.options = translationUnitOptions;
- translationUnit.SyntaxNode = translationUnitSyntax;
- return translationUnit;
- }
+void CompileRequest::parseTranslationUnit(
+ TranslationUnitRequest* translationUnit)
+{
+ IncludeHandlerImpl includeHandler;
+ includeHandler.request = this;
- CompileUnit parseTranslationUnit(
- TranslationUnitOptions const& translationUnitOptions)
+ RefPtr<Scope> languageScope;
+ switch (translationUnit->sourceLanguage)
{
- return parseTranslationUnit(translationUnitOptions, Options);
+ case SourceLanguage::HLSL:
+ languageScope = mSession->hlslLanguageScope;
+ break;
+
+ case SourceLanguage::GLSL:
+ languageScope = mSession->glslLanguageScope;
+ break;
+
+ case SourceLanguage::Slang:
+ default:
+ languageScope = mSession->slangLanguageScope;
+ break;
}
- void checkTranslationUnit(
- CompileUnit& translationUnit,
- RefPtr<SyntaxVisitor> visitor)
- {
- visitor->setSourceLanguage(translationUnit.options.sourceLanguage);
- translationUnit.SyntaxNode->Accept(visitor.Ptr());
- }
+ Dictionary<String, String> combinedPreprocessorDefinitions;
+ for(auto& def : preprocessorDefinitions)
+ combinedPreprocessorDefinitions.Add(def.Key, def.Value);
+ for(auto& def : translationUnit->preprocessorDefinitions)
+ combinedPreprocessorDefinitions.Add(def.Key, def.Value);
+
+ RefPtr<ProgramSyntaxNode> translationUnitSyntax = new ProgramSyntaxNode();
+ translationUnit->SyntaxNode = translationUnitSyntax;
- void checkTranslationUnit(
- CompileUnit& translationUnit,
- CompileOptions& options)
+ for (auto sourceFile : translationUnit->sourceFiles)
{
- RefPtr<SyntaxVisitor> visitor = CreateSemanticsVisitor(
- mResult.GetErrorWriter(),
- options,
- translationUnit.options,
+ auto sourceFilePath = sourceFile->path;
+ String source = sourceFile->content;
+
+ auto tokens = preprocessSource(
+ source,
+ sourceFilePath,
+ &mSink,
+ &includeHandler,
+ combinedPreprocessorDefinitions,
+ translationUnitSyntax.Ptr(),
this);
- checkTranslationUnit(translationUnit, visitor);
+ parseSourceFile(
+ translationUnit,
+ tokens,
+ &mSink,
+ sourceFilePath,
+ languageScope);
}
+}
+
+void CompileRequest::checkTranslationUnit(
+ TranslationUnitRequest* translationUnit)
+{
+ RefPtr<SyntaxVisitor> visitor = CreateSemanticsVisitor(
+ &mSink,
+ this,
+ translationUnit);
- void checkCollectionOfTranslationUnits(
- RefPtr<CollectionOfTranslationUnits> collectionOfTranslationUnits)
+ visitor->setSourceLanguage(translationUnit->sourceLanguage);
+ translationUnit->SyntaxNode->Accept(visitor.Ptr());
+}
+
+void CompileRequest::checkAllTranslationUnits()
+{
+ for( auto& translationUnit : translationUnits )
{
- for( auto& translationUnit : collectionOfTranslationUnits->translationUnits )
- {
- checkTranslationUnit(translationUnit, Options);
- }
+ checkTranslationUnit(translationUnit.Ptr());
}
+}
- void generateOutputForCollectionOfTranslationUnits(
- RefPtr<CollectionOfTranslationUnits> collectionOfTranslationUnits)
+int CompileRequest::executeActionsInner()
+{
+ // Do some cleanup on settings specified by user.
+ // In particular, we want to propagate flags from the overall request down to
+ // each translation unit.
+ for( auto& translationUnit : translationUnits )
{
- // Do binding generation, and then reflection (globally)
- // before we move on to any code-generation activites.
- GenerateParameterBindings(collectionOfTranslationUnits.Ptr());
-
-
- // HACK(tfoley): for right now I just want to pretty-print an AST
- // into another language, so the whole compiler back-end is just
- // getting in the way.
- //
- // I'm going to bypass it for now and see what I can do:
-
- ExtraContext extra;
- extra.options = &Options;
- extra.programLayout = collectionOfTranslationUnits->layout.Ptr();
- extra.compileResult = &mResult;
+ translationUnit->compileFlags |= compileFlags;
- generateOutput(extra, collectionOfTranslationUnits.Ptr());
+ // However, the "no checking" flag shouldn't be applied to
+ // any translation unit that is native Slang code.
+ if( translationUnit->sourceLanguage == SourceLanguage::Slang )
+ {
+ translationUnit->compileFlags &= ~SLANG_COMPILE_FLAG_NO_CHECKING;
+ }
}
- int executeCompilerDriverActions()
+#if 0
+ // If we are being asked to do pass-through, then we need to do that here...
+ if (passThrough != PassThroughMode::None)
{
- // Do some cleanup on settings specified by user.
- // In particular, we want to propagate flags from the overall request down to
- // each translation unit.
- for( auto& translationUnitOptions : Options.translationUnits )
+ for (auto& translationUnitOptions : Options.translationUnits)
{
- translationUnitOptions.compileFlags |= Options.compileFlags;
-
- // However, the "no checking" flag shouldn't be applied to
- // any translation unit that is native Slang code.
- if( translationUnitOptions.sourceLanguage == SourceLanguage::Slang )
+ switch (translationUnitOptions.sourceLanguage)
{
- translationUnitOptions.compileFlags &= SLANG_COMPILE_FLAG_NO_CHECKING;
+ // We can pass-through code written in a native shading language
+ case SourceLanguage::GLSL:
+ case SourceLanguage::HLSL:
+ break;
+
+ // All other translation units need to be skipped
+ default:
+ continue;
}
- }
- // If we are being asked to do pass-through, then we need to do that here...
- if (Options.passThrough != PassThroughMode::None)
- {
- for (auto& translationUnitOptions : Options.translationUnits)
- {
- switch (translationUnitOptions.sourceLanguage)
- {
- // We can pass-through code written in a native shading language
- case SourceLanguage::GLSL:
- case SourceLanguage::HLSL:
- break;
-
- // All other translation units need to be skipped
- default:
- continue;
- }
-
- auto sourceFile = translationUnitOptions.sourceFiles[0];
- auto sourceFilePath = sourceFile->path;
- String source = sourceFile->content;
+ auto sourceFile = translationUnitOptions.sourceFiles[0];
+ auto sourceFilePath = sourceFile->path;
+ String source = sourceFile->content;
- auto translationUnitResult = passThrough(
- source,
- sourceFilePath,
- Options,
- translationUnitOptions);
+ auto translationUnitResult = passThrough(
+ source,
+ sourceFilePath,
+ Options,
+ translationUnitOptions);
- mResult.translationUnits.Add(translationUnitResult);
- }
- return 0;
+ mResult.translationUnits.Add(translationUnitResult);
}
+ return 0;
+ }
+#endif
- // TODO: load the stdlib
-
- mCollectionOfTranslationUnits = new CollectionOfTranslationUnits();
-
+ // We only do parsing and semantic checking if we *aren't* doing
+ // a pass-through compilation.
+ //
+ // Note that we *do* perform output generation as normal in pass-through mode.
+ if( passThrough == PassThroughMode::None )
+ {
// Parse everything from the input files requested
- //
- // TODO: this may trigger the loading and/or compilation of additional modules.
- for (auto& translationUnitOptions : Options.translationUnits)
+ for (auto& translationUnit : translationUnits)
{
- auto translationUnit = parseTranslationUnit(translationUnitOptions);
- mCollectionOfTranslationUnits->translationUnits.Add(translationUnit);
+ parseTranslationUnit(translationUnit.Ptr());
}
- if (mResult.GetErrorCount() != 0)
+ if (mSink.GetErrorCount() != 0)
return 1;
// Perform semantic checking on the whole collection
- checkCollectionOfTranslationUnits(mCollectionOfTranslationUnits);
- if (mResult.GetErrorCount() != 0)
+ checkAllTranslationUnits();
+ if (mSink.GetErrorCount() != 0)
return 1;
- // Generate output code, in whatever format was requested
- generateOutputForCollectionOfTranslationUnits(mCollectionOfTranslationUnits);
- if (mResult.GetErrorCount() != 0)
+ // Now do shader parameter binding generation, which
+ // needs to be performed globally.
+ generateParameterBindings(this);
+ if (mSink.GetErrorCount() != 0)
return 1;
+ }
- // Extract the reflection layout information so that users
- // can easily query it.
- mReflectionData = mCollectionOfTranslationUnits->layout;
+ // Generate output code, in whatever format was requested
+ generateOutput(this);
+ if (mSink.GetErrorCount() != 0)
+ return 1;
- return 0;
- }
+ return 0;
+}
- // Act as expected of the API-based compiler
- int executeAPIActions()
- {
- mResult.mSink = &mSink;
+// Act as expected of the API-based compiler
+int CompileRequest::executeActions()
+{
+ int err = executeActionsInner();
- int err = executeCompilerDriverActions();
+ mDiagnosticOutput = mSink.outputBuffer.ProduceString();
- mDiagnosticOutput = mSink.outputBuffer.ProduceString();
+ return err;
+}
- if (mSink.GetErrorCount() != 0)
- return mSink.GetErrorCount();
+int CompileRequest::addTranslationUnit(SourceLanguage language, String const& name)
+{
+ int result = translationUnits.Count();
- return err;
- }
+ RefPtr<TranslationUnitRequest> translationUnit = new TranslationUnitRequest();
+ translationUnit->compileRequest = this;
+ translationUnit->sourceLanguage = SourceLanguage(language);
- int addTranslationUnit(SourceLanguage language, String const& name)
- {
- int result = Options.translationUnits.Count();
+ translationUnits.Add(translationUnit);
- TranslationUnitOptions translationUnit;
- translationUnit.sourceLanguage = SourceLanguage(language);
+ return result;
+}
- Options.translationUnits.Add(translationUnit);
+void CompileRequest::addTranslationUnitSourceString(
+ int translationUnitIndex,
+ String const& path,
+ String const& source)
+{
+ RefPtr<SourceFile> sourceFile = new SourceFile();
+ sourceFile->path = path;
+ sourceFile->content = source;
- return result;
- }
+ translationUnits[translationUnitIndex]->sourceFiles.Add(sourceFile);
+}
- void addTranslationUnitSourceString(
- int translationUnitIndex,
- String const& path,
- String const& source)
+void CompileRequest::addTranslationUnitSourceFile(
+ int translationUnitIndex,
+ String const& path)
+{
+ String source;
+ try
{
- RefPtr<SourceFile> sourceFile = new SourceFile();
- sourceFile->path = path;
- sourceFile->content = source;
-
- Options.translationUnits[translationUnitIndex].sourceFiles.Add(sourceFile);
+ source = File::ReadAllText(path);
}
-
- void addTranslationUnitSourceFile(
- int translationUnitIndex,
- String const& path)
+ catch (...)
{
- String source;
- try
- {
- source = File::ReadAllText(path);
- }
- catch (...)
- {
- // Emit a diagnostic!
- mSink.diagnose(
- CodePosition(0, 0, 0, path),
- Diagnostics::cannotOpenFile,
- path);
- return;
- }
+ // Emit a diagnostic!
+ mSink.diagnose(
+ CodePosition(0, 0, 0, path),
+ Diagnostics::cannotOpenFile,
+ path);
+ return;
+ }
- addTranslationUnitSourceString(
- translationUnitIndex,
- path,
- source);
+ addTranslationUnitSourceString(
+ translationUnitIndex,
+ path,
+ source);
- mDependencyFilePaths.Add(path);
- }
+ mDependencyFilePaths.Add(path);
+}
- int addTranslationUnitEntryPoint(
- int translationUnitIndex,
- String const& name,
- Profile profile)
- {
- EntryPointOption entryPoint;
- entryPoint.name = name;
- entryPoint.profile = profile;
+int CompileRequest::addEntryPoint(
+ int translationUnitIndex,
+ String const& name,
+ Profile profile)
+{
+ RefPtr<EntryPointRequest> entryPoint = new EntryPointRequest();
+ entryPoint->compileRequest = this;
+ entryPoint->name = name;
+ entryPoint->profile = profile;
+ entryPoint->translationUnitIndex = translationUnitIndex;
- // TODO: realistically want this to be global across all TUs...
- int result = Options.translationUnits[translationUnitIndex].entryPoints.Count();
+ auto translationUnit = translationUnits[translationUnitIndex].Ptr();
+ translationUnit->entryPoints.Add(entryPoint);
- Options.translationUnits[translationUnitIndex].entryPoints.Add(entryPoint);
- return result;
- }
+ int result = entryPoints.Count();
+ entryPoints.Add(entryPoint);
+ return result;
+}
- Dictionary<String, RefPtr<ProgramSyntaxNode>> loadedModules;
+RefPtr<ProgramSyntaxNode> CompileRequest::loadModule(
+ String const& name,
+ String const& path,
+ String const& source,
+ CodePosition const& loc)
+{
+ RefPtr<TranslationUnitRequest> translationUnit = new TranslationUnitRequest();
+ translationUnit->compileRequest = this;
- RefPtr<ProgramSyntaxNode> loadModule(
- String const& name,
- String const& path,
- String const& source,
- CodePosition const& loc)
- {
- // now we need to try compiling it, etc.
+ // We don't want to use the same options that the user specified
+ // for loading modules on-demand. In particular, we always want
+ // semantic checking to be enabled.
+ //
+ // TODO: decide which options, if any, should be inherited.
- // We don't want to use the same options that the user specified
- // for loading modules on-demand. In particular, we always want
- // semantic checking to be enabled.
- CompileOptions moduleOptions;
- moduleOptions.searchDirectories = Options.searchDirectories;
- moduleOptions.profile = Options.profile;
+ RefPtr<SourceFile> sourceFile = new SourceFile();
+ sourceFile->path = path;
+ sourceFile->content = source;
- RefPtr<SourceFile> sourceFile = new SourceFile();
- sourceFile->path = path;
- sourceFile->content = source;
+ translationUnit->sourceFiles.Add(sourceFile);
- TranslationUnitOptions translationUnitOptions;
- translationUnitOptions.sourceFiles.Add(sourceFile);
+ parseTranslationUnit(translationUnit.Ptr());
- CompileUnit translationUnit = parseTranslationUnit(translationUnitOptions, moduleOptions);
+ // TODO: handle errors
- // TODO: handle errors
+ checkTranslationUnit(translationUnit.Ptr());
- checkTranslationUnit(translationUnit, moduleOptions);
+ // Skip code generation
- // Skip code generation
+ //
- //
+ RefPtr<ProgramSyntaxNode> moduleDecl = translationUnit->SyntaxNode;
- RefPtr<ProgramSyntaxNode> moduleDecl = translationUnit.SyntaxNode;
+ loadedModules.Add(name, moduleDecl);
- loadedModules.Add(name, moduleDecl);
+ return moduleDecl;
- return moduleDecl;
+}
- }
+String CompileRequest::autoImportModule(
+ String const& path,
+ String const& source,
+ CodePosition const& loc)
+{
+ // TODO: may want to have some kind of canonicalization step here
+ String name = path;
- String autoImportModule(
- String const& path,
- String const& source,
- CodePosition const& loc)
- {
- // TODO: may want to have some kind of canonicalization step here
- String name = path;
+ // Have we already loaded a module matching this name?
+ if (loadedModules.TryGetValue(name))
+ return name;
+
+ loadModule(name, path, source, loc);
- // Have we already loaded a module matching this name?
- if (loadedModules.TryGetValue(name))
- return name;
+ return name;
+}
- loadModule(name, path, source, loc);
+RefPtr<ProgramSyntaxNode> CompileRequest::findOrImportModule(
+ String const& name,
+ CodePosition const& loc)
+{
+ // Have we already loaded a module matching this name?
+ // If so, return it.
+ RefPtr<ProgramSyntaxNode> moduleDecl;
+ if (loadedModules.TryGetValue(name, moduleDecl))
+ return moduleDecl;
- return name;
- }
+ // Derive a file name for the module, by taking the given
+ // identifier, replacing all occurences of `_` with `-`,
+ // and then appending `.slang`.
+ //
+ // For example, `foo_bar` becomes `foo-bar.slang`.
- RefPtr<ProgramSyntaxNode> findOrImportModule(
- String const& name,
- CodePosition const& loc)
+ StringBuilder sb;
+ for (auto c : name)
{
- // Have we already loaded a module matching this name?
- // If so, return it.
- RefPtr<ProgramSyntaxNode> moduleDecl;
- if (loadedModules.TryGetValue(name, moduleDecl))
- return moduleDecl;
-
- // Derive a file name for the module, by taking the given
- // identifier, replacing all occurences of `_` with `-`,
- // and then appending `.slang`.
- //
- // For example, `foo_bar` becomes `foo-bar.slang`.
+ if (c == '_')
+ c = '-';
- StringBuilder sb;
- for (auto c : name)
- {
- if (c == '_')
- c = '-';
-
- sb.Append(c);
- }
- sb.Append(".slang");
+ sb.Append(c);
+ }
+ sb.Append(".slang");
- String fileName = sb.ProduceString();
+ String fileName = sb.ProduceString();
- // Next, try to find the file of the given name,
- // using our ordinary include-handling logic.
+ // Next, try to find the file of the given name,
+ // using our ordinary include-handling logic.
- IncludeHandlerImpl includeHandler;
- includeHandler.request = this;
+ IncludeHandlerImpl includeHandler;
+ includeHandler.request = this;
- String pathIncludedFrom = loc.FileName;
+ String pathIncludedFrom = loc.FileName;
- String foundPath;
- String foundSource;
- IncludeResult includeResult = includeHandler.TryToFindIncludeFile(fileName, pathIncludedFrom, &foundPath, &foundSource);
- switch( includeResult )
+ String foundPath;
+ String foundSource;
+ IncludeResult includeResult = includeHandler.TryToFindIncludeFile(fileName, pathIncludedFrom, &foundPath, &foundSource);
+ switch( includeResult )
+ {
+ case IncludeResult::NotFound:
+ case IncludeResult::Error:
{
- case IncludeResult::NotFound:
- case IncludeResult::Error:
- {
- this->mSink.diagnose(loc, Diagnostics::cannotFindFile, fileName);
-
- loadedModules[name] = nullptr;
- return nullptr;
- }
- break;
+ this->mSink.diagnose(loc, Diagnostics::cannotFindFile, fileName);
- default:
- break;
+ loadedModules[name] = nullptr;
+ return nullptr;
}
+ break;
- // We've found a file that we can load for the given module, so
- // go ahead and perform the module-load action
- return loadModule(
- name,
- foundPath,
- foundSource,
- loc);
+ default:
+ break;
}
-};
+ // We've found a file that we can load for the given module, so
+ // go ahead and perform the module-load action
+ return loadModule(
+ name,
+ foundPath,
+ foundSource,
+ loc);
+}
RefPtr<ProgramSyntaxNode> findOrImportModule(
CompileRequest* request,
@@ -627,29 +528,29 @@ void Session::addBuiltinSource(
String const& path,
String const& source)
{
- CompileRequest compileRequest(this);
+ RefPtr<CompileRequest> compileRequest = new CompileRequest(this);
- auto translationUnitIndex = compileRequest.addTranslationUnit(SourceLanguage::Slang, path);
+ auto translationUnitIndex = compileRequest->addTranslationUnit(SourceLanguage::Slang, path);
- compileRequest.addTranslationUnitSourceString(
+ compileRequest->addTranslationUnitSourceString(
translationUnitIndex,
path,
source);
- int err = compileRequest.executeAPIActions();
+ int err = compileRequest->executeActions();
if (err)
{
- fprintf(stderr, "%s", compileRequest.mDiagnosticOutput.Buffer());
+ fprintf(stderr, "%s", compileRequest->mDiagnosticOutput.Buffer());
#ifdef _WIN32
- OutputDebugStringA(compileRequest.mDiagnosticOutput.Buffer());
+ OutputDebugStringA(compileRequest->mDiagnosticOutput.Buffer());
#endif
assert(!"error in stdlib");
}
// Extract the AST for the code we just parsed
- auto syntax = compileRequest.mCollectionOfTranslationUnits->translationUnits[translationUnitIndex].SyntaxNode;
+ auto syntax = compileRequest->translationUnits[translationUnitIndex]->SyntaxNode;
// HACK(tfoley): mark all declarations in the "stdlib" so
// that we can detect them later (e.g., so we don't emit them)
@@ -739,21 +640,21 @@ SLANG_API void spSetCompileFlags(
SlangCompileRequest* request,
SlangCompileFlags flags)
{
- REQ(request)->Options.compileFlags = flags;
+ REQ(request)->compileFlags = flags;
}
SLANG_API void spSetCodeGenTarget(
SlangCompileRequest* request,
int target)
{
- REQ(request)->Options.Target = (Slang::CodeGenTarget)target;
+ REQ(request)->Target = (Slang::CodeGenTarget)target;
}
SLANG_API void spSetPassThrough(
SlangCompileRequest* request,
SlangPassThrough passThrough)
{
- REQ(request)->Options.passThrough = Slang::PassThroughMode(passThrough);
+ REQ(request)->passThrough = Slang::PassThroughMode(passThrough);
}
SLANG_API void spSetDiagnosticCallback(
@@ -772,14 +673,14 @@ SLANG_API void spAddSearchPath(
SlangCompileRequest* request,
const char* path)
{
- REQ(request)->Options.searchDirectories.Add(Slang::SearchDirectory(path, Slang::SearchDirectory::Kind::Default));
+ REQ(request)->searchDirectories.Add(Slang::SearchDirectory(path, Slang::SearchDirectory::Kind::Default));
}
SLANG_API void spAddAutoImportPath(
SlangCompileRequest* request,
const char* path)
{
- REQ(request)->Options.searchDirectories.Add(Slang::SearchDirectory(path, Slang::SearchDirectory::Kind::AutoImport));
+ REQ(request)->searchDirectories.Add(Slang::SearchDirectory(path, Slang::SearchDirectory::Kind::AutoImport));
}
SLANG_API void spAddPreprocessorDefine(
@@ -787,7 +688,7 @@ SLANG_API void spAddPreprocessorDefine(
const char* key,
const char* value)
{
- REQ(request)->Options.preprocessorDefinitions[key] = value;
+ REQ(request)->preprocessorDefinitions[key] = value;
}
SLANG_API char const* spGetDiagnosticOutput(
@@ -820,7 +721,7 @@ SLANG_API void spTranslationUnit_addPreprocessorDefine(
{
auto req = REQ(request);
- req->Options.translationUnits[translationUnitIndex].preprocessorDefinitions[key] = value;
+ req->translationUnits[translationUnitIndex]->preprocessorDefinitions[key] = value;
}
@@ -833,7 +734,7 @@ SLANG_API void spAddTranslationUnitSourceFile(
auto req = REQ(request);
if(!path) return;
if(translationUnitIndex < 0) return;
- if(translationUnitIndex >= req->Options.translationUnits.Count()) return;
+ if(translationUnitIndex >= req->translationUnits.Count()) return;
req->addTranslationUnitSourceFile(
translationUnitIndex,
@@ -851,7 +752,7 @@ SLANG_API void spAddTranslationUnitSourceString(
auto req = REQ(request);
if(!source) return;
if(translationUnitIndex < 0) return;
- if(translationUnitIndex >= req->Options.translationUnits.Count()) return;
+ if(translationUnitIndex >= req->translationUnits.Count()) return;
if(!path) path = "";
@@ -869,7 +770,7 @@ SLANG_API SlangProfileID spFindProfile(
return Slang::Profile::LookUp(name).raw;
}
-SLANG_API int spAddTranslationUnitEntryPoint(
+SLANG_API int spAddEntryPoint(
SlangCompileRequest* request,
int translationUnitIndex,
char const* name,
@@ -879,10 +780,9 @@ SLANG_API int spAddTranslationUnitEntryPoint(
auto req = REQ(request);
if(!name) return -1;
if(translationUnitIndex < 0) return -1;
- if(translationUnitIndex >= req->Options.translationUnits.Count()) return -1;
+ if(translationUnitIndex >= req->translationUnits.Count()) return -1;
-
- return req->addTranslationUnitEntryPoint(
+ return req->addEntryPoint(
translationUnitIndex,
name,
Slang::Profile(Slang::Profile::RawVal(profile)));
@@ -895,7 +795,7 @@ SLANG_API int spCompile(
{
auto req = REQ(request);
- int anyErrors = req->executeAPIActions();
+ int anyErrors = req->executeActions();
return anyErrors;
}
@@ -925,7 +825,7 @@ spGetTranslationUnitCount(
SlangCompileRequest* request)
{
auto req = REQ(request);
- return req->mResult.translationUnits.Count();
+ return req->translationUnits.Count();
}
// Get the output code associated with a specific translation unit
@@ -934,16 +834,15 @@ SLANG_API char const* spGetTranslationUnitSource(
int translationUnitIndex)
{
auto req = REQ(request);
- return req->mResult.translationUnits[translationUnitIndex].outputSource.Buffer();
+ return req->translationUnits[translationUnitIndex]->result.outputSource.Buffer();
}
SLANG_API char const* spGetEntryPointSource(
SlangCompileRequest* request,
- int translationUnitIndex,
int entryPointIndex)
{
auto req = REQ(request);
- return req->mResult.translationUnits[translationUnitIndex].entryPoints[entryPointIndex].outputSource.Buffer();
+ return req->entryPoints[entryPointIndex]->result.outputSource.Buffer();
}
@@ -955,7 +854,7 @@ SLANG_API SlangReflection* spGetReflection(
if( !request ) return 0;
auto req = REQ(request);
- return (SlangReflection*) req->mReflectionData.Ptr();
+ return (SlangReflection*) req->layout.Ptr();
}
diff --git a/source/slang/syntax-visitors.h b/source/slang/syntax-visitors.h
index dbcbf2781..5d712b671 100644
--- a/source/slang/syntax-visitors.h
+++ b/source/slang/syntax-visitors.h
@@ -7,18 +7,16 @@
namespace Slang
{
- class CompileOptions;
- struct CompileRequest;
+ class CompileRequest;
class ShaderCompiler;
class ShaderLinkInfo;
class ShaderSymbol;
- class TranslationUnitOptions;
+ class TranslationUnitRequest;
SyntaxVisitor* CreateSemanticsVisitor(
- DiagnosticSink* err,
- CompileOptions const& options,
- TranslationUnitOptions const& translationUnitOptions,
- CompileRequest* request);
+ DiagnosticSink* err,
+ CompileRequest* request,
+ TranslationUnitRequest* translationUnit);
// Look for a module that matches the given name:
// either one we've loaded already, or one we
diff --git a/source/slangc/main.cpp b/source/slangc/main.cpp
index 06f004531..4a783a17c 100644
--- a/source/slangc/main.cpp
+++ b/source/slangc/main.cpp
@@ -12,7 +12,7 @@ using namespace Slang;
static void diagnosticCallback(
char const* message,
- void* userData)
+ void* /*userData*/)
{
fputs(message, stderr);
fflush(stderr);
@@ -89,29 +89,36 @@ int MAIN(int argc, char** argv)
}
#endif
-#ifdef _MSC_VER
- _CrtDumpMemoryLeaks();
-#endif
return 0;
}
#ifdef _WIN32
int wmain(int argc, wchar_t** argv)
{
- // Conver the wide-character Unicode arguments to UTF-8,
- // since that is what Slang expects on the API side.
+ int result = 0;
- List<String> args;
- for(int ii = 0; ii < argc; ++ii)
- {
- args.Add(String::FromWString(argv[ii]));
- }
- List<char const*> argBuffers;
- for(int ii = 0; ii < argc; ++ii)
{
- argBuffers.Add(args[ii].Buffer());
+ // Conver the wide-character Unicode arguments to UTF-8,
+ // since that is what Slang expects on the API side.
+
+ List<String> args;
+ for(int ii = 0; ii < argc; ++ii)
+ {
+ args.Add(String::FromWString(argv[ii]));
+ }
+ List<char const*> argBuffers;
+ for(int ii = 0; ii < argc; ++ii)
+ {
+ argBuffers.Add(args[ii].Buffer());
+ }
+
+ result = MAIN(argc, (char**) &argBuffers[0]);
}
- return MAIN(argc, (char**) &argBuffers[0]);
+#ifdef _MSC_VER
+ _CrtDumpMemoryLeaks();
+#endif
+
+ return result;
}
#endif