From 327f2b7ec50a7480b458d6d3ba8e2ca7fcdb8498 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Tue, 20 Jun 2017 08:11:27 -0700 Subject: Overhaul handling of entry points and translation units. The main user-visible change here is that instead of `spAddTranslationUnitEntryPoint` we have `spAddEntryPoint`, to reflect that the list of entry points is "global" to a compile request. As a result, `spGetEntryPointSource` now only needs the entry point index, and not the translation unit index. There are a bunch more behind-the-scenes changes, though, reflecting a streamlining of the concepts related to compilation into a smaller number of classes. Now there is: - `Session` (unchanged) to manage the lifetimes of shared stuff like the stdlib - `CompileRequest` (merges in `CompileOptions`) to handle all the lifetime related to a single invocation of the compiler - `TranslationUnitRequest` (merges `TranslationUnitOptions`, `CompileUnit`) to represent a single translation unit ("module") that the user is trying to compile. This is a single file for HLSL/GLSL, but can be multiple files for Slang. - `EntryPointRequest` (merges `EntryPointOption` and a bit of `EntryPointResult`) to track a single entry point that the user is asking to compile (that entry point always comes from a single translation unit) A lot of functions used to take some combination of these and end up with really long signatures. I've given most of the objects "parent" pointers so that they can get back to all the context they need, so most functions don't need as many parameters. It may eventually be important to tease these apart again, in particular: - The code-generation side of things (the `*Result` types) might need to be pulled out in case we want to codegen multiple times from the same AST - Similarly, the layout stuff may also need to be pulled out, in case we want to lay things out multiple times with different rules. --- source/slang/compiler.h | 172 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 127 insertions(+), 45 deletions(-) (limited to 'source/slang/compiler.h') 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 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 > sourceFiles; + // The entry points associated with this translation unit + List > entryPoints; + // Preprocessor definitions to use for this translation unit only // (whereas the ones on `CompileOptions` will be shared) Dictionary preprocessorDefinitions; // Compile flags for this translation unit SlangCompileFlags compileFlags = 0; - }; + // The parsed syntax for the translation unit + RefPtr 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 preprocessorDefinitions; // Translation units we are being asked to compile - List translationUnits; + List > translationUnits; + + // Entry points we've been asked to compile (each + // assocaited with a translation unit). + List > 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 SyntaxNode; - }; + // Output stuff + DiagnosticSink mSink; + String mDiagnosticOutput; - // TODO: pick an appropriate name for this... - class CollectionOfTranslationUnits : public RefObject - { - public: - List translationUnits; + // Files that compilation depended on + List mDependencyFilePaths; - // TODO: this is more output-oriented, but maybe okay to have here... + // The resulting reflection layout information RefPtr 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> loadedModules; + + + CompileRequest(Session* session) + : mSession(session) + {} - CompileResult* compileResult = nullptr; + ~CompileRequest() + {} - RefPtr 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 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 findOrImportModule( + String const& name, + CodePosition const& loc); + }; void generateOutput( - ExtraContext& context, - CollectionOfTranslationUnits* collectionOfTranslationUnits); + CompileRequest* compileRequest); } #endif \ No newline at end of file -- cgit v1.2.3