summaryrefslogtreecommitdiffstats
path: root/source/slang/compiler.h
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2019-05-31 17:20:37 -0400
committerGitHub <noreply@github.com>2019-05-31 17:20:37 -0400
commit6cbc3929a54d37bd23cb5efa8e3320ba02f78b2f (patch)
tree5a23cb47782e9e2a77762c90dd35da1005eba8d0 /source/slang/compiler.h
parentb81ff3ef968d1cc4e954b31a1812b3c391d17b02 (diff)
Use slang- prefix on slang compiler and core source (#973)
* Prefixing source files in source/slang with slang- * Prefix source in source/slang with slang- prefix. * Rename core source files with slang- prefix. * Update project files. * Fix problems from automatic merge.
Diffstat (limited to 'source/slang/compiler.h')
-rw-r--r--source/slang/compiler.h1423
1 files changed, 0 insertions, 1423 deletions
diff --git a/source/slang/compiler.h b/source/slang/compiler.h
deleted file mode 100644
index 5d9e47aee..000000000
--- a/source/slang/compiler.h
+++ /dev/null
@@ -1,1423 +0,0 @@
-#ifndef SLANG_COMPILER_H_INCLUDED
-#define SLANG_COMPILER_H_INCLUDED
-
-#include "../core/basic.h"
-#include "../core/slang-shared-library.h"
-
-#include "../../slang-com-ptr.h"
-
-#include "diagnostics.h"
-#include "name.h"
-#include "profile.h"
-#include "syntax.h"
-
-#include "../../slang.h"
-
-namespace Slang
-{
- struct PathInfo;
- struct IncludeHandler;
- class ProgramLayout;
- class PtrType;
- class TargetProgram;
- class TargetRequest;
- class TypeLayout;
-
- enum class CompilerMode
- {
- ProduceLibrary,
- ProduceShader,
- GenerateChoice
- };
-
- enum class StageTarget
- {
- Unknown,
- VertexShader,
- HullShader,
- DomainShader,
- GeometryShader,
- FragmentShader,
- ComputeShader,
- };
-
- enum class CodeGenTarget
- {
- Unknown = SLANG_TARGET_UNKNOWN,
- None = SLANG_TARGET_NONE,
- GLSL = SLANG_GLSL,
- GLSL_Vulkan = SLANG_GLSL_VULKAN,
- GLSL_Vulkan_OneDesc = SLANG_GLSL_VULKAN_ONE_DESC,
- HLSL = SLANG_HLSL,
- SPIRV = SLANG_SPIRV,
- SPIRVAssembly = SLANG_SPIRV_ASM,
- DXBytecode = SLANG_DXBC,
- DXBytecodeAssembly = SLANG_DXBC_ASM,
- DXIL = SLANG_DXIL,
- DXILAssembly = SLANG_DXIL_ASM,
- CSource = SLANG_C_SOURCE,
- CPPSource = SLANG_CPP_SOURCE,
- };
-
- enum class ContainerFormat
- {
- None = SLANG_CONTAINER_FORMAT_NONE,
- SlangModule = SLANG_CONTAINER_FORMAT_SLANG_MODULE,
- };
-
- enum class LineDirectiveMode : SlangLineDirectiveMode
- {
- Default = SLANG_LINE_DIRECTIVE_MODE_DEFAULT,
- None = SLANG_LINE_DIRECTIVE_MODE_NONE,
- Standard = SLANG_LINE_DIRECTIVE_MODE_STANDARD,
- GLSL = SLANG_LINE_DIRECTIVE_MODE_GLSL,
- };
-
- enum class ResultFormat
- {
- None,
- Text,
- Binary
- };
-
- // When storing the layout for a matrix-type
- // value, we need to know whether it has been
- // laid out with row-major or column-major
- // storage.
- //
- enum MatrixLayoutMode
- {
- kMatrixLayoutMode_RowMajor = SLANG_MATRIX_LAYOUT_ROW_MAJOR,
- kMatrixLayoutMode_ColumnMajor = SLANG_MATRIX_LAYOUT_COLUMN_MAJOR,
- };
-
- enum class DebugInfoLevel : SlangDebugInfoLevel
- {
- None = SLANG_DEBUG_INFO_LEVEL_NONE,
- Minimal = SLANG_DEBUG_INFO_LEVEL_MINIMAL,
- Standard = SLANG_DEBUG_INFO_LEVEL_STANDARD,
- Maximal = SLANG_DEBUG_INFO_LEVEL_MAXIMAL,
- };
-
- enum class OptimizationLevel : SlangOptimizationLevel
- {
- None = SLANG_OPTIMIZATION_LEVEL_NONE,
- Default = SLANG_OPTIMIZATION_LEVEL_DEFAULT,
- High = SLANG_OPTIMIZATION_LEVEL_HIGH,
- Maximal = SLANG_OPTIMIZATION_LEVEL_MAXIMAL,
- };
-
- class Linkage;
- class Module;
- class Program;
- class FrontEndCompileRequest;
- class BackEndCompileRequest;
- class EndToEndCompileRequest;
- class TranslationUnitRequest;
-
- // Result of compiling an entry point.
- // Should only ever be string OR binary.
- class CompileResult
- {
- public:
- CompileResult() = default;
- CompileResult(String const& str) : format(ResultFormat::Text), outputString(str) {}
- CompileResult(List<uint8_t> const& buffer) : format(ResultFormat::Binary), outputBinary(buffer) {}
-
- void append(CompileResult const& result);
-
- ComPtr<ISlangBlob> getBlob();
-
- ResultFormat format = ResultFormat::None;
- String outputString;
- List<uint8_t> outputBinary;
-
- ComPtr<ISlangBlob> blob;
- };
-
- /// Information collected about global or entry-point shader parameters
- struct ShaderParamInfo
- {
- DeclRef<VarDeclBase> paramDeclRef;
- UInt firstExistentialTypeSlot = 0;
- UInt existentialTypeSlotCount = 0;
- };
-
- /// Extended information specific to global shader parameters
- struct GlobalShaderParamInfo : ShaderParamInfo
- {
- // Additional global-scope declarations that are conceptually
- // declaring the "same" parameter as the `paramDeclRef`.
- List<DeclRef<VarDeclBase>> additionalParamDeclRefs;
- };
-
- /// A request for the front-end to find and validate an entry-point function
- struct FrontEndEntryPointRequest : RefObject
- {
- public:
- /// Create a request for an entry point.
- FrontEndEntryPointRequest(
- FrontEndCompileRequest* compileRequest,
- int translationUnitIndex,
- Name* name,
- Profile profile);
-
- /// Get the parent front-end compile request.
- FrontEndCompileRequest* getCompileRequest() { return m_compileRequest; }
-
- /// Get the translation unit that contains the entry point.
- TranslationUnitRequest* getTranslationUnit();
-
- /// Get the name of the entry point to find.
- Name* getName() { return m_name; }
-
- /// Get the stage that the entry point is to be compiled for
- Stage getStage() { return m_profile.GetStage(); }
-
- /// Get the profile that the entry point is to be compiled for
- Profile getProfile() { return m_profile; }
-
- private:
- // The parent compile request
- FrontEndCompileRequest* m_compileRequest;
-
- // The index of the translation unit that will hold the entry point
- int m_translationUnitIndex;
-
- // The name of the entry point function to look for
- Name* m_name;
-
- // The profile to compile for (including stage)
- Profile m_profile;
- };
-
- /// Tracks an ordered list of modules that something depends on.
- struct ModuleDependencyList
- {
- public:
- /// Get the list of modules that are depended on.
- List<RefPtr<Module>> const& getModuleList() { return m_moduleList; }
-
- /// Add a module and everything it depends on to the list.
- void addDependency(Module* module);
-
- /// Add a module to the list, but not the modules it depends on.
- void addLeafDependency(Module* module);
-
- private:
- void _addDependency(Module* module);
-
- List<RefPtr<Module>> m_moduleList;
- HashSet<Module*> m_moduleSet;
- };
-
- /// Tracks an unordered list of filesystem paths that something depends on
- struct FilePathDependencyList
- {
- public:
- /// Get the list of paths that are depended on.
- List<String> const& getFilePathList() { return m_filePathList; }
-
- /// Add a path to the list, if it is not already present
- void addDependency(String const& path);
-
- /// Add all of the paths that `module` depends on to the list
- void addDependency(Module* module);
-
- private:
-
- // TODO: We are using a `HashSet` here to deduplicate
- // the paths so that we don't return the same path
- // multiple times from `getFilePathList`, but because
- // order isn't important, we could potentially do better
- // in terms of memory (at some cost in performance) by
- // just sorting the `m_filePathList` every once in
- // a while and then deduplicating.
-
- List<String> m_filePathList;
- HashSet<String> m_filePathSet;
- };
-
- /// Describes an entry point for the purposes of layout and code generation.
- ///
- /// This class also tracks any generic arguments to the entry point,
- /// in the case that it is a specialization of a generic entry point.
- ///
- /// There is also a provision for creating a "dummy" entry point for
- /// the purposes of pass-through compilation modes. Only the
- /// `getName()` and `getProfile()` methods should be expected to
- /// return useful data on pass-through entry points.
- ///
- class EntryPoint : public RefObject
- {
- public:
- /// Create an entry point that refers to the given function.
- static RefPtr<EntryPoint> create(
- DeclRef<FuncDecl> funcDeclRef,
- Profile profile);
-
- /// Get the function decl-ref, including any generic arguments.
- DeclRef<FuncDecl> getFuncDeclRef() { return m_funcDeclRef; }
-
- /// Get the function declaration (without generic arguments).
- RefPtr<FuncDecl> getFuncDecl() { return m_funcDeclRef.getDecl(); }
-
- /// Get the name of the entry point
- Name* getName() { return m_name; }
-
- /// Get the profile associated with the entry point
- ///
- /// Note: only the stage part of the profile is expected
- /// to contain useful data, but certain legacy code paths
- /// allow for "shader model" information to come via this path.
- ///
- Profile getProfile() { return m_profile; }
-
- /// Get the stage that the entry point is for.
- Stage getStage() { return m_profile.GetStage(); }
-
- /// Get the module that contains the entry point.
- Module* getModule();
-
- /// Get the linkage that contains the module for this entry point.
- Linkage* getLinkage();
-
- /// Get a list of modules that this entry point depends on.
- ///
- /// This will include the module that defines the entry point (see `getModule()`),
- /// but may also include modules that are required by its generic type arguments.
- ///
- List<RefPtr<Module>> getModuleDependencies() { return m_dependencyList.getModuleList(); }
-
- /// Get a list of tagged-union types referenced by the entry point's generic parameters.
- List<RefPtr<TaggedUnionType>> const& getTaggedUnionTypes() { return m_taggedUnionTypes; }
-
- /// Create a dummy `EntryPoint` that is only usable for pass-through compilation.
- static RefPtr<EntryPoint> createDummyForPassThrough(
- Name* name,
- Profile profile);
-
- /// Get the number of existential type parameters for the entry point.
- Index getExistentialTypeParamCount() { return m_existentialSlots.paramTypes.getCount(); }
-
- /// Get the existential type parameter at `index`.
- Type* getExistentialTypeParam(Index index) { return m_existentialSlots.paramTypes[index]; }
-
- /// Get the number of arguments supplied for existential type parameters.
- ///
- /// Note that the number of arguments may not match the number of parameters.
- /// In particular, an unspecialized entry point may have many parameters, but zero arguments.
- Index getExistentialTypeArgCount() { return m_existentialSlots.args.getCount(); }
-
- /// Get the existential type argument (type and witness table) at `index`.
- ExistentialTypeSlots::Arg getExistentialTypeArg(Index index) { return m_existentialSlots.args[index]; }
-
- /// Get an array of all existential type arguments.
- ExistentialTypeSlots::Arg const* getExistentialTypeArgs() { return m_existentialSlots.args.getBuffer(); }
-
- /// Get an array of all entry-point shader parameters.
- List<ShaderParamInfo> const& getShaderParams() { return m_shaderParams; }
-
- void _specializeExistentialTypeParams(
- List<RefPtr<Expr>> const& args,
- DiagnosticSink* sink);
-
- private:
- EntryPoint(
- Name* name,
- Profile profile,
- DeclRef<FuncDecl> funcDeclRef);
-
- void _collectShaderParams();
-
- // The name of the entry point function (e.g., `main`)
- //
- Name* m_name = nullptr;
-
- // The declaration of the entry-point function itself.
- //
- DeclRef<FuncDecl> m_funcDeclRef;
-
- /// The existential/interface slots associated with the entry point parameter scope.
- ExistentialTypeSlots m_existentialSlots;
-
- /// Information about entry-point parameters
- List<ShaderParamInfo> m_shaderParams;
-
- // The profile that the entry point will be compiled for
- // (this is a combination of the target stage, and also
- // a feature level that sets capabilities)
- //
- // Note: the profile-version part of this should probably
- // be moving towards deprecation, in favor of the version
- // information (e.g., "Shader Model 5.1") always coming
- // from the target, while the stage part is all that is
- // intrinsic to the entry point.
- //
- Profile m_profile;
-
- // Any tagged union types that were referenced by the generic arguments of the entry point.
- List<RefPtr<TaggedUnionType>> m_taggedUnionTypes;
-
- // Modules the entry point depends on.
- ModuleDependencyList m_dependencyList;
- };
-
- enum class PassThroughMode : SlangPassThrough
- {
- None = SLANG_PASS_THROUGH_NONE, // don't pass through: use Slang compiler
- fxc = SLANG_PASS_THROUGH_FXC, // pass through HLSL to `D3DCompile` API
- dxc = SLANG_PASS_THROUGH_DXC, // pass through HLSL to `IDxcCompiler` API
- glslang = SLANG_PASS_THROUGH_GLSLANG, // pass through GLSL to `glslang` library
- };
-
- class SourceFile;
-
- /// A module of code that has been compiled through the front-end
- ///
- /// A module comprises all the code from one translation unit (which
- /// may span multiple Slang source files), and provides access
- /// to both the AST and IR representations of that code.
- ///
- class Module : public RefObject
- {
- public:
- /// Create a module (initially empty).
- Module(Linkage* linkage);
-
- /// Get the parent linkage of this module.
- Linkage* getLinkage() { return m_linkage; }
-
- /// Get the AST for the module (if it has been parsed)
- ModuleDecl* getModuleDecl() { return m_moduleDecl; }
-
- /// The the IR for the module (if it has been generated)
- IRModule* getIRModule() { return m_irModule; }
-
- /// Get the list of other modules this module depends on
- List<RefPtr<Module>> const& getModuleDependencyList() { return m_moduleDependencyList.getModuleList(); }
-
- /// Get the list of filesystem paths this module depends on
- List<String> const& getFilePathDependencyList() { return m_filePathDependencyList.getFilePathList(); }
-
- /// Register a module that this module depends on
- void addModuleDependency(Module* module);
-
- /// Register a filesystem path that this module depends on
- void addFilePathDependency(String const& path);
-
- /// Set the AST for this module.
- ///
- /// This should only be called once, during creation of the module.
- ///
- void setModuleDecl(ModuleDecl* moduleDecl) { m_moduleDecl = moduleDecl; }
-
- /// Set the IR for this module.
- ///
- /// This should only be called once, during creation of the module.
- ///
- void setIRModule(IRModule* irModule) { m_irModule = irModule; }
-
- private:
- // The parent linkage
- Linkage* m_linkage = nullptr;
-
- // The AST for the module
- RefPtr<ModuleDecl> m_moduleDecl;
-
- // The IR for the module
- RefPtr<IRModule> m_irModule = nullptr;
-
- // List of modules this module depends on
- ModuleDependencyList m_moduleDependencyList;
-
- // List of filesystem paths this module depends on
- FilePathDependencyList m_filePathDependencyList;
- };
- typedef Module LoadedModule;
-
- /// A request for the front-end to compile a translation unit.
- class TranslationUnitRequest : public RefObject
- {
- public:
- TranslationUnitRequest(
- FrontEndCompileRequest* compileRequest);
-
- // The parent compile request
- FrontEndCompileRequest* compileRequest = nullptr;
-
- // 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<SourceFile*> m_sourceFiles;
-
- List<SourceFile*> const& getSourceFiles() { return m_sourceFiles; }
- void addSourceFile(SourceFile* sourceFile);
-
- // The entry points associated with this translation unit
- List<RefPtr<EntryPoint>> entryPoints;
-
- // Preprocessor definitions to use for this translation unit only
- // (whereas the ones on `compileRequest` will be shared)
- Dictionary<String, String> preprocessorDefinitions;
-
- /// The name that will be used for the module this translation unit produces.
- Name* moduleName = nullptr;
-
- /// Result of compiling this translation unit (a module)
- RefPtr<Module> module;
-
- Module* getModule() { return module; }
- RefPtr<ModuleDecl> getModuleDecl() { return module->getModuleDecl(); }
-
- Session* getSession();
- NamePool* getNamePool();
- SourceManager* getSourceManager();
- };
-
- enum class FloatingPointMode : SlangFloatingPointMode
- {
- Default = SLANG_FLOATING_POINT_MODE_DEFAULT,
- Fast = SLANG_FLOATING_POINT_MODE_FAST,
- Precise = SLANG_FLOATING_POINT_MODE_PRECISE,
- };
-
- enum class WriterChannel : SlangWriterChannel
- {
- Diagnostic = SLANG_WRITER_CHANNEL_DIAGNOSTIC,
- StdOutput = SLANG_WRITER_CHANNEL_STD_OUTPUT,
- StdError = SLANG_WRITER_CHANNEL_STD_ERROR,
- CountOf = SLANG_WRITER_CHANNEL_COUNT_OF,
- };
-
- enum class WriterMode : SlangWriterMode
- {
- Text = SLANG_WRITER_MODE_TEXT,
- Binary = SLANG_WRITER_MODE_BINARY,
- };
-
- /// A request to generate output in some target format.
- class TargetRequest : public RefObject
- {
- public:
- Linkage* linkage;
- CodeGenTarget target;
- SlangTargetFlags targetFlags = 0;
- Slang::Profile targetProfile = Slang::Profile();
- FloatingPointMode floatingPointMode = FloatingPointMode::Default;
-
- Linkage* getLinkage() { return linkage; }
- CodeGenTarget getTarget() { return target; }
- Profile getTargetProfile() { return targetProfile; }
- FloatingPointMode getFloatingPointMode() { return floatingPointMode; }
-
- Session* getSession();
- MatrixLayoutMode getDefaultMatrixLayoutMode();
-
- // TypeLayouts created on the fly by reflection API
- Dictionary<Type*, RefPtr<TypeLayout>> typeLayouts;
-
- Dictionary<Type*, RefPtr<TypeLayout>>& getTypeLayouts() { return typeLayouts; }
- };
-
- /// Are we generating code for a D3D API?
- bool isD3DTarget(TargetRequest* targetReq);
-
- /// Are we generating code for a Khronos API (OpenGL or Vulkan)?
- bool isKhronosTarget(TargetRequest* targetReq);
-
- // Compute the "effective" profile to use when outputting the given entry point
- // for the chosen code-generation target.
- //
- // The stage of the effective profile will always come from the entry point, while
- // the profile version (aka "shader model") will be computed as follows:
- //
- // - If the entry point and target belong to the same profile family, then take
- // the latest version between the two (e.g., if the entry point specified `ps_5_1`
- // and the target specifies `sm_5_0` then use `sm_5_1` as the version).
- //
- // - If the entry point and target disagree on the profile family, always use the
- // profile family and version from the target.
- //
- Profile getEffectiveProfile(EntryPoint* entryPoint, TargetRequest* target);
-
-
- // A directory to be searched when looking for files (e.g., `#include`)
- struct SearchDirectory
- {
- SearchDirectory() = default;
- SearchDirectory(SearchDirectory const& other) = default;
- SearchDirectory(String const& path)
- : path(path)
- {}
-
- String path;
- };
-
- /// A list of directories to search for files (e.g., `#include`)
- struct SearchDirectoryList
- {
- // A parent list that should also be searched
- SearchDirectoryList* parent = nullptr;
-
- // Directories to be searched
- List<SearchDirectory> searchDirectories;
- };
-
- /// Create a blob that will retain (a copy of) raw data.
- ///
- ComPtr<ISlangBlob> createRawBlob(void const* data, size_t size);
-
- /// A context for loading and re-using code modules.
- class Linkage : public RefObject
- {
- public:
- /// Create an initially-empty linkage
- Linkage(Session* session);
-
- /// Get the parent session for this linkage
- Session* getSession() { return m_session; }
-
- // Information on the targets we are being asked to
- // generate code for.
- List<RefPtr<TargetRequest>> targets;
-
- // Directories to search for `#include` files or `import`ed modules
- SearchDirectoryList searchDirectories;
-
- SearchDirectoryList const& getSearchDirectories() { return searchDirectories; }
-
- // Definitions to provide during preprocessing
- Dictionary<String, String> preprocessorDefinitions;
-
- // Source manager to help track files loaded
- SourceManager m_defaultSourceManager;
- SourceManager* m_sourceManager = nullptr;
-
- // Name pool for looking up names
- NamePool namePool;
-
- NamePool* getNamePool() { return &namePool; }
-
- // Modules that have been dynamically loaded via `import`
- //
- // This is a list of unique modules loaded, in the order they were encountered.
- List<RefPtr<LoadedModule> > loadedModulesList;
-
- // Map from the path (or uniqueIdentity if available) of a module file to its definition
- Dictionary<String, RefPtr<LoadedModule>> mapPathToLoadedModule;
-
- // Map from the logical name of a module to its definition
- Dictionary<Name*, RefPtr<LoadedModule>> mapNameToLoadedModules;
-
- // The resulting specialized IR module for each entry point request
- List<RefPtr<IRModule>> compiledModules;
-
- /// File system implementation to use when loading files from disk.
- ///
- /// If this member is `null`, a default implementation that tries
- /// to use the native OS filesystem will be used instead.
- ///
- ComPtr<ISlangFileSystem> fileSystem;
-
- /// The extended file system implementation. Will be set to a default implementation
- /// if fileSystem is nullptr. Otherwise it will either be fileSystem's interface,
- /// or a wrapped impl that makes fileSystem operate as fileSystemExt
- ComPtr<ISlangFileSystemExt> fileSystemExt;
-
- ISlangFileSystemExt* getFileSystemExt() { return fileSystemExt; }
-
- /// Load a file into memory using the configured file system.
- ///
- /// @param path The path to attempt to load from
- /// @param outBlob A destination pointer to receive the loaded blob
- /// @returns A `SlangResult` to indicate success or failure.
- ///
- SlangResult loadFile(String const& path, ISlangBlob** outBlob);
-
-
- RefPtr<Expr> parseTypeString(String typeStr, RefPtr<Scope> scope);
-
- Type* specializeType(
- Type* unspecializedType,
- Int argCount,
- Type* const* args,
- DiagnosticSink* sink);
-
- /// Add a mew target amd return its index.
- UInt addTarget(
- CodeGenTarget target);
-
- RefPtr<Module> loadModule(
- Name* name,
- const PathInfo& filePathInfo,
- ISlangBlob* fileContentsBlob,
- SourceLoc const& loc,
- DiagnosticSink* sink);
-
- void loadParsedModule(
- RefPtr<TranslationUnitRequest> translationUnit,
- Name* name,
- PathInfo const& pathInfo);
-
- /// Load a module of the given name.
- Module* loadModule(String const& name);
-
- RefPtr<Module> findOrImportModule(
- Name* name,
- SourceLoc const& loc,
- DiagnosticSink* sink);
-
- SourceManager* getSourceManager()
- {
- return m_sourceManager;
- }
-
- /// Override the source manager for the linakge.
- ///
- /// This is only used to install a temporary override when
- /// parsing stuff from strings (where we don't want to retain
- /// full source files for the parsed result).
- ///
- /// TODO: We should remove the need for this hack.
- ///
- void setSourceManager(SourceManager* sourceManager)
- {
- m_sourceManager = sourceManager;
- }
-
- void setFileSystem(ISlangFileSystem* fileSystem);
-
- /// The layout to use for matrices by default (row/column major)
- MatrixLayoutMode defaultMatrixLayoutMode = kMatrixLayoutMode_ColumnMajor;
- MatrixLayoutMode getDefaultMatrixLayoutMode() { return defaultMatrixLayoutMode; }
-
- DebugInfoLevel debugInfoLevel = DebugInfoLevel::None;
-
- OptimizationLevel optimizationLevel = OptimizationLevel::Default;
-
- private:
- Session* m_session = nullptr;
-
- /// Tracks state of modules currently being loaded.
- ///
- /// This information is used to diagnose cases where
- /// a user tries to recursively import the same module
- /// (possibly along a transitive chain of `import`s).
- ///
- struct ModuleBeingImportedRAII
- {
- public:
- ModuleBeingImportedRAII(
- Linkage* linkage,
- Module* module)
- : linkage(linkage)
- , module(module)
- {
- next = linkage->m_modulesBeingImported;
- linkage->m_modulesBeingImported = this;
- }
-
- ~ModuleBeingImportedRAII()
- {
- linkage->m_modulesBeingImported = next;
- }
-
- Linkage* linkage;
- Module* module;
- ModuleBeingImportedRAII* next;
- };
-
- // Any modules currently being imported will be listed here
- ModuleBeingImportedRAII* m_modulesBeingImported = nullptr;
-
- /// Is the given module in the middle of being imported?
- bool isBeingImported(Module* module);
-
- List<RefPtr<Type>> m_specializedTypes;
- };
-
- /// Shared functionality between front- and back-end compile requests.
- ///
- /// This is the base class for both `FrontEndCompileRequest` and
- /// `BackEndCompileRequest`, and allows a small number of parts of
- /// the compiler to be easily invocable from either front-end or
- /// back-end work.
- ///
- class CompileRequestBase : public RefObject
- {
- // TODO: We really shouldn't need this type in the long run.
- // The few places that rely on it should be refactored to just
- // depend on the underlying information (a linkage and a diagnostic
- // sink) directly.
- //
- // The flags to control dumping and validation of IR should be
- // moved to some kind of shared settings/options `struct` that
- // both front-end and back-end requests can store.
-
- public:
- Session* getSession();
- Linkage* getLinkage() { return m_linkage; }
- DiagnosticSink* getSink() { return m_sink; }
- SourceManager* getSourceManager() { return getLinkage()->getSourceManager(); }
- NamePool* getNamePool() { return getLinkage()->getNamePool(); }
- ISlangFileSystemExt* getFileSystemExt() { return getLinkage()->getFileSystemExt(); }
- SlangResult loadFile(String const& path, ISlangBlob** outBlob) { return getLinkage()->loadFile(path, outBlob); }
-
- bool shouldDumpIR = false;
- bool shouldValidateIR = false;
-
- protected:
- CompileRequestBase(
- Linkage* linkage,
- DiagnosticSink* sink);
-
- private:
- Linkage* m_linkage = nullptr;
- DiagnosticSink* m_sink = nullptr;
- };
-
- /// A request to compile source code to an AST + IR.
- class FrontEndCompileRequest : public CompileRequestBase
- {
- public:
- FrontEndCompileRequest(
- Linkage* linkage,
- DiagnosticSink* sink);
-
- int addEntryPoint(
- int translationUnitIndex,
- String const& name,
- Profile entryPointProfile);
-
- // Translation units we are being asked to compile
- List<RefPtr<TranslationUnitRequest> > translationUnits;
-
- RefPtr<TranslationUnitRequest> getTranslationUnit(UInt index) { return translationUnits[index]; }
-
- // Compile flags to be shared by all translation units
- SlangCompileFlags compileFlags = 0;
-
- // If true then generateIR will serialize out IR, and serialize back in again. Making
- // serialization a bottleneck or firewall between the front end and the backend
- bool useSerialIRBottleneck = false;
-
- // If true will serialize and de-serialize with debug information
- bool verifyDebugSerialization = false;
-
- List<RefPtr<FrontEndEntryPointRequest>> m_entryPointReqs;
-
- List<RefPtr<FrontEndEntryPointRequest>> const& getEntryPointReqs() { return m_entryPointReqs; }
- UInt getEntryPointReqCount() { return m_entryPointReqs.getCount(); }
- FrontEndEntryPointRequest* getEntryPointReq(UInt index) { return m_entryPointReqs[index]; }
-
- // Directories to search for `#include` files or `import`ed modules
- // NOTE! That for now these search directories are not settable via the API
- // so the search directories on Linkage is used for #include as well as for modules.
- SearchDirectoryList searchDirectories;
-
- SearchDirectoryList const& getSearchDirectories() { return searchDirectories; }
-
- // Definitions to provide during preprocessing
- Dictionary<String, String> preprocessorDefinitions;
-
- void parseTranslationUnit(
- TranslationUnitRequest* translationUnit);
-
- // Perform primary semantic checking on all
- // of the translation units in the program
- void checkAllTranslationUnits();
-
- void generateIR();
-
- SlangResult executeActionsInner();
-
- /// Add a translation unit to be compiled.
- ///
- /// @param language The source language that the translation unit will use (e.g., `SourceLanguage::Slang`
- /// @param moduleName The name that will be used for the module compile from the translation unit.
- /// @return The zero-based index of the translation unit in this compile request.
- int addTranslationUnit(SourceLanguage language, Name* moduleName);
-
- /// Add a translation unit to be compiled.
- ///
- /// @param language The source language that the translation unit will use (e.g., `SourceLanguage::Slang`
- /// @return The zero-based index of the translation unit in this compile request.
- ///
- /// The module name for the translation unit will be automatically generated.
- /// If all translation units in a compile request use automatically generated
- /// module names, then they are guaranteed not to conflict with one another.
- ///
- int addTranslationUnit(SourceLanguage language);
-
- void addTranslationUnitSourceFile(
- int translationUnitIndex,
- SourceFile* sourceFile);
-
- void addTranslationUnitSourceBlob(
- int translationUnitIndex,
- String const& path,
- ISlangBlob* sourceBlob);
-
- void addTranslationUnitSourceString(
- int translationUnitIndex,
- String const& path,
- String const& source);
-
- void addTranslationUnitSourceFile(
- int translationUnitIndex,
- String const& path);
-
- Program* getProgram() { return m_program; }
-
- private:
- RefPtr<Program> m_program;
- };
-
- /// A collection of code modules and entry points that are intended to be used together.
- ///
- /// A `Program` establishes that certain pieces of code are intended
- /// to be used togehter so that, e.g., layout can make sure to allocate
- /// space for the global shader parameters in all referenced modules.
- ///
- class Program : public RefObject
- {
- public:
- /// Create a new program, initially empty.
- ///
- /// All code loaded into the program must come
- /// from the given `linkage`.
- Program(
- Linkage* linkage);
-
- /// Get the linkage that this program uses.
- Linkage* getLinkage() { return m_linkage; }
-
- /// Get the number of entry points added to the program
- Index getEntryPointCount() { return m_entryPoints.getCount(); }
-
- /// Get the entry point at the given `index`.
- RefPtr<EntryPoint> getEntryPoint(Index index) { return m_entryPoints[index]; }
-
- /// Get the full ist of entry points on the program.
- List<RefPtr<EntryPoint>> const& getEntryPoints() { return m_entryPoints; }
-
- /// Get the substitution (if any) that represents how global generics are specialized.
- RefPtr<Substitutions> getGlobalGenericSubstitution() { return m_globalGenericSubst; }
-
- /// Get the full list of modules this program depends on
- List<RefPtr<Module>> getModuleDependencies() { return m_moduleDependencyList.getModuleList(); }
-
- /// Get the full list of filesystem paths this program depends on
- List<String> getFilePathDependencies() { return m_filePathDependencyList.getFilePathList(); }
-
- /// Get the target-specific version of this program for the given `target`.
- ///
- /// The `target` must be a target on the `Linkage` that was used to create this program.
- TargetProgram* getTargetProgram(TargetRequest* target);
-
- /// Add a module (and everything it depends on) to the list of references
- void addReferencedModule(Module* module);
-
- /// Add a module (but not the things it depends on) to the list of references
- ///
- /// This is a compatiblity hack for legacy compiler behavior.
- void addReferencedLeafModule(Module* module);
-
-
- /// Add an entry point to the program
- ///
- /// This also adds everything the entry point depends on to the list of references.
- ///
- void addEntryPoint(EntryPoint* entryPoint);
-
- /// Set the global generic argument substitution to use.
- void setGlobalGenericSubsitution(RefPtr<Substitutions> subst)
- {
- m_globalGenericSubst = subst;
- }
-
- /// Parse a type from a string, in the context of this program.
- ///
- /// Any names in the string will be resolved using the modules
- /// referenced by the program.
- ///
- /// On an error, returns null and reports diagnostic messages
- /// to the provided `sink`.
- ///
- Type* getTypeFromString(String typeStr, DiagnosticSink* sink);
-
- /// Get the IR module that represents this program and its entry points.
- ///
- /// The IR module for a program tries to be minimal, and in the
- /// common case will only include symbols with `[import]` declarations
- /// for the entry point(s) of the program, and any types they
- /// depend on.
- ///
- /// This IR module is intended to be linked against the IR modules
- /// for all of the dependencies (see `getModuleDependencies()`) to
- /// provide complete code.
- ///
- RefPtr<IRModule> getOrCreateIRModule(DiagnosticSink* sink);
-
- /// Get the number of existential type parameters for the program.
- Index getExistentialTypeParamCount() { return m_globalExistentialSlots.paramTypes.getCount(); }
-
- /// Get the existential type parameter at `index`.
- Type* getExistentialTypeParam(Index index) { return m_globalExistentialSlots.paramTypes[index]; }
-
- /// Get the number of arguments supplied for existential type parameters.
- ///
- /// Note that the number of arguments may not match the number of parameters.
- /// In particular, an unspecialized program may have many parameters, but zero arguments.
- Index getExistentialTypeArgCount() { return m_globalExistentialSlots.args.getCount(); }
-
- /// Get the existential type argument (type and witness table) at `index`.
- ExistentialTypeSlots::Arg getExistentialTypeArg(Index index) { return m_globalExistentialSlots.args[index]; }
-
- /// Get an array of all existential type arguments.
- ExistentialTypeSlots::Arg const* getExistentialTypeArgs() { return m_globalExistentialSlots.args.getBuffer(); }
-
- /// Get an array of all global shader parameters.
- List<GlobalShaderParamInfo> const& getShaderParams() { return m_shaderParams; }
-
- void _collectShaderParams(DiagnosticSink* sink);
- void _specializeExistentialTypeParams(
- List<RefPtr<Expr>> const& args,
- DiagnosticSink* sink);
-
- private:
-
- // The linakge this program is associated with.
- //
- // Note that a `Program` keeps its associated linkage alive,
- // and not vice versa.
- //
- RefPtr<Linkage> m_linkage;
-
- // Tracking data for the list of modules dependend on
- ModuleDependencyList m_moduleDependencyList;
-
- // Tracking data for the list of filesystem paths dependend on
- FilePathDependencyList m_filePathDependencyList;
-
- // Entry points that are part of the program.
- List<RefPtr<EntryPoint> > m_entryPoints;
-
- // Specializations for global generic parameters (if any)
- RefPtr<Substitutions> m_globalGenericSubst;
-
- // The existential/interface slots associated with the global scope.
- ExistentialTypeSlots m_globalExistentialSlots;
-
- /// Information about global shader parameters
- List<GlobalShaderParamInfo> m_shaderParams;
-
- // Generated IR for this program.
- RefPtr<IRModule> m_irModule;
-
- // Cache of target-specific programs for each target.
- Dictionary<TargetRequest*, RefPtr<TargetProgram>> m_targetPrograms;
-
- // Any types looked up dynamically using `getTypeFromString`
- Dictionary<String, RefPtr<Type>> m_types;
- };
-
- /// A `Program` specialized for a particular `TargetRequest`
- class TargetProgram : public RefObject
- {
- public:
- TargetProgram(
- Program* program,
- TargetRequest* targetReq);
-
- /// Get the underlying program
- Program* getProgram() { return m_program; }
-
- /// Get the underlying target
- TargetRequest* getTargetReq() { return m_targetReq; }
-
- /// Get the layout for the program on the target.
- ///
- /// If this is the first time the layout has been
- /// requested, report any errors that arise during
- /// layout to the given `sink`.
- ///
- ProgramLayout* getOrCreateLayout(DiagnosticSink* sink);
-
- /// Get the layout for the program on the taarget.
- ///
- /// This routine assumes that `getOrCreateLayout`
- /// has already been called previously.
- ///
- ProgramLayout* getExistingLayout()
- {
- SLANG_ASSERT(m_layout);
- return m_layout;
- }
-
- /// Get the compiled code for an entry point on the target.
- ///
- /// This routine assumes code generation has already been
- /// performed and called `setEntryPointResult`.
- ///
- CompileResult& getExistingEntryPointResult(Int entryPointIndex)
- {
- return m_entryPointResults[entryPointIndex];
- }
-
- // TODO: Need a lazy `getOrCreateEntryPointResult`
-
- /// Set the compiled code for an entry point.
- ///
- /// Should only be called by code generation.
- void setEntryPointResult(Int entryPointIndex, CompileResult const& result)
- {
- m_entryPointResults[entryPointIndex] = result;
- }
-
- private:
- // The program being compiled or laid out
- Program* m_program;
-
- // The target that code/layout will be generated for
- TargetRequest* m_targetReq;
-
- // The computed layout, if it has been generated yet
- RefPtr<ProgramLayout> m_layout;
-
- // Generated compile results for each entry point
- // in the parent `Program` (indexing matches
- // the order they are given in the `Program`)
- List<CompileResult> m_entryPointResults;
- };
-
- /// A request to generate code for a program
- class BackEndCompileRequest : public CompileRequestBase
- {
- public:
- BackEndCompileRequest(
- Linkage* linkage,
- DiagnosticSink* sink,
- Program* program = nullptr);
-
- // Should we dump intermediate results along the way, for debugging?
- bool shouldDumpIntermediates = false;
-
- // How should `#line` directives be emitted (if at all)?
- LineDirectiveMode lineDirectiveMode = LineDirectiveMode::Default;
-
- LineDirectiveMode getLineDirectiveMode() { return lineDirectiveMode; }
-
- Program* getProgram() { return m_program; }
- void setProgram(Program* program) { m_program = program; }
-
- // Should R/W images without explicit formats be assumed to have "unknown" format?
- //
- // The default behavior is to make a best-effort guess as to what format is intended.
- //
- bool useUnknownImageFormatAsDefault = false;
-
- private:
- RefPtr<Program> m_program;
- };
-
- /// A compile request that spans the front and back ends of the compiler
- ///
- /// This is what the command-line `slangc` uses, as well as the legacy
- /// C API. It ties together the functionality of `Linkage`,
- /// `FrontEndCompileRequest`, and `BackEndCompileRequest`, plus a small
- /// number of additional features that primarily make sense for
- /// command-line usage.
- ///
- class EndToEndCompileRequest : public RefObject
- {
- public:
- EndToEndCompileRequest(
- Session* session);
-
- // What container format are we being asked to generate?
- //
- // Note: This field is unused except by the options-parsing
- // logic; it exists to support wriiting out binary modules
- // once that feature is ready.
- //
- ContainerFormat containerFormat = ContainerFormat::None;
-
- // Path to output container to
- //
- // Note: This field exists to support wriiting out binary modules
- // once that feature is ready.
- //
- String containerOutputPath;
-
- // Should we just pass the input to another compiler?
- PassThroughMode passThrough = PassThroughMode::None;
-
- /// Source code for the generic arguments to use for the global generic parameters of the program.
- List<String> globalGenericArgStrings;
-
- /// Types to use to fill global existential "slots"
- List<String> globalExistentialSlotArgStrings;
-
- bool shouldSkipCodegen = false;
-
- // Are we being driven by the command-line `slangc`, and should act accordingly?
- bool isCommandLineCompile = false;
-
- String mDiagnosticOutput;
-
- /// A blob holding the diagnostic output
- ComPtr<ISlangBlob> diagnosticOutputBlob;
-
- /// Per-entry-point information not tracked by other compile requests
- class EntryPointInfo : public RefObject
- {
- public:
- /// Source code for the generic arguments to use for the generic parameters of the entry point.
- List<String> genericArgStrings;
-
- /// Source code for the type arguments to plug into the existential type "slots" of the entry point
- List<String> existentialArgStrings;
- };
- List<EntryPointInfo> entryPoints;
-
- /// Per-target information only needed for command-line compiles
- class TargetInfo : public RefObject
- {
- public:
- // Requested output paths for each entry point.
- // An empty string indices no output desired for
- // the given entry point.
- Dictionary<Int, String> entryPointOutputPaths;
- };
- Dictionary<TargetRequest*, RefPtr<TargetInfo>> targetInfos;
-
- Linkage* getLinkage() { return m_linkage; }
-
- int addEntryPoint(
- int translationUnitIndex,
- String const& name,
- Profile profile,
- List<String> const & genericTypeNames);
-
- void setWriter(WriterChannel chan, ISlangWriter* writer);
- ISlangWriter* getWriter(WriterChannel chan) const { return m_writers[int(chan)]; }
-
- SlangResult executeActionsInner();
- SlangResult executeActions();
-
- Session* getSession() { return m_session; }
- DiagnosticSink* getSink() { return &m_sink; }
- NamePool* getNamePool() { return getLinkage()->getNamePool(); }
-
- FrontEndCompileRequest* getFrontEndReq() { return m_frontEndReq; }
- BackEndCompileRequest* getBackEndReq() { return m_backEndReq; }
- Program* getUnspecializedProgram() { return getFrontEndReq()->getProgram(); }
- Program* getSpecializedProgram() { return m_specializedProgram; }
-
- private:
- Session* m_session = nullptr;
- RefPtr<Linkage> m_linkage;
- DiagnosticSink m_sink;
- RefPtr<FrontEndCompileRequest> m_frontEndReq;
- RefPtr<Program> m_unspecializedProgram;
- RefPtr<Program> m_specializedProgram;
- RefPtr<BackEndCompileRequest> m_backEndReq;
-
- // For output
- ComPtr<ISlangWriter> m_writers[SLANG_WRITER_CHANNEL_COUNT_OF];
- };
-
- void generateOutput(
- BackEndCompileRequest* compileRequest);
-
- void generateOutput(
- EndToEndCompileRequest* compileRequest);
-
- // Helper to dump intermediate output when debugging
- void maybeDumpIntermediate(
- BackEndCompileRequest* compileRequest,
- void const* data,
- size_t size,
- CodeGenTarget target);
- void maybeDumpIntermediate(
- BackEndCompileRequest* compileRequest,
- char const* text,
- CodeGenTarget target);
-
- /* Returns SLANG_OK if a codeGen target is available. */
- SlangResult checkCompileTargetSupport(Session* session, CodeGenTarget target);
- /* Returns SLANG_OK if pass through support is available */
- SlangResult checkExternalCompilerSupport(Session* session, PassThroughMode passThrough);
-
- /* Report an error appearing from external compiler to the diagnostic sink error to the diagnostic sink.
- @param compilerName The name of the compiler the error came for (or nullptr if not known)
- @param res Result associated with the error. The error code will be reported. (Can take HRESULT - and will expand to string if known)
- @param diagnostic The diagnostic string associated with the compile failure
- @param sink The diagnostic sink to report to */
- void reportExternalCompileError(const char* compilerName, SlangResult res, const UnownedStringSlice& diagnostic, DiagnosticSink* sink);
-
- /* Determines a suitable filename to identify the input for a given entry point being compiled.
- If the end-to-end compile is a pass-through case, will attempt to find the (unique) source file
- pathname for the translation unit containing the entry point at `entryPointIndex.
- If the compilation is not in a pass-through case, then always returns `"slang-generated"`.
- @param endToEndReq The end-to-end compile request which might be using pass-through copmilation
- @param entryPointIndex The index of the entry point to compute a filename for.
- @return the appropriate source filename */
- String calcSourcePathForEntryPoint(EndToEndCompileRequest* endToEndReq, UInt entryPointIndex);
-
- struct TypeCheckingCache;
- //
-
- class Session
- {
- public:
- enum class SharedLibraryFuncType
- {
- Glslang_Compile,
- Fxc_D3DCompile,
- Fxc_D3DDisassemble,
- Dxc_DxcCreateInstance,
- CountOf,
- };
-
- //
-
- RefPtr<Scope> baseLanguageScope;
- RefPtr<Scope> coreLanguageScope;
- RefPtr<Scope> hlslLanguageScope;
- RefPtr<Scope> slangLanguageScope;
-
- List<RefPtr<ModuleDecl>> loadedModuleCode;
-
- SourceManager builtinSourceManager;
-
- SourceManager* getBuiltinSourceManager() { return &builtinSourceManager; }
-
- // Name pool stuff for unique-ing identifiers
-
- RootNamePool rootNamePool;
- NamePool namePool;
-
- RootNamePool* getRootNamePool() { return &rootNamePool; }
- NamePool* getNamePool() { return &namePool; }
- Name* getNameObj(String name) { return namePool.getName(name); }
- Name* tryGetNameObj(String name) { return namePool.tryGetName(name); }
- //
-
- // Generated code for stdlib, etc.
- String stdlibPath;
- String coreLibraryCode;
- String slangLibraryCode;
- String hlslLibraryCode;
- String glslLibraryCode;
-
- String getStdlibPath();
- String getCoreLibraryCode();
- String getHLSLLibraryCode();
-
- // Basic types that we don't want to re-create all the time
- RefPtr<Type> errorType;
- RefPtr<Type> initializerListType;
- RefPtr<Type> overloadedType;
- RefPtr<Type> constExprRate;
- RefPtr<Type> irBasicBlockType;
-
- RefPtr<Type> stringType;
- RefPtr<Type> enumTypeType;
-
- ComPtr<ISlangSharedLibraryLoader> sharedLibraryLoader; ///< The shared library loader (never null)
- ComPtr<ISlangSharedLibrary> sharedLibraries[int(SharedLibraryType::CountOf)]; ///< The loaded shared libraries
- SlangFuncPtr sharedLibraryFunctions[int(SharedLibraryFuncType::CountOf)];
-
- Dictionary<int, RefPtr<Type>> builtinTypes;
- Dictionary<String, Decl*> magicDecls;
-
- void initializeTypes();
-
- Type* getBoolType();
- Type* getHalfType();
- Type* getFloatType();
- Type* getDoubleType();
- Type* getIntType();
- Type* getInt64Type();
- Type* getUIntType();
- Type* getUInt64Type();
- Type* getVoidType();
- Type* getBuiltinType(BaseType flavor);
-
- Type* getInitializerListType();
- Type* getOverloadedType();
- Type* getErrorType();
- Type* getStringType();
-
- Type* getEnumTypeType();
-
- // Construct the type `Ptr<valueType>`, where `Ptr`
- // is looked up as a builtin type.
- RefPtr<PtrType> getPtrType(RefPtr<Type> valueType);
-
- // Construct the type `Out<valueType>`
- RefPtr<OutType> getOutType(RefPtr<Type> valueType);
-
- // Construct the type `InOut<valueType>`
- RefPtr<InOutType> getInOutType(RefPtr<Type> valueType);
-
- // Construct the type `Ref<valueType>`
- RefPtr<RefType> getRefType(RefPtr<Type> valueType);
-
- // Construct a pointer type like `Ptr<valueType>`, but where
- // the actual type name for the pointer type is given by `ptrTypeName`
- RefPtr<PtrTypeBase> getPtrType(RefPtr<Type> valueType, char const* ptrTypeName);
-
- // Construct a pointer type like `Ptr<valueType>`, but where
- // the generic declaration for the pointer type is `genericDecl`
- RefPtr<PtrTypeBase> getPtrType(RefPtr<Type> valueType, GenericDecl* genericDecl);
-
- RefPtr<ArrayExpressionType> getArrayType(
- Type* elementType,
- IntVal* elementCount);
-
- RefPtr<VectorExpressionType> getVectorType(
- RefPtr<Type> elementType,
- RefPtr<IntVal> elementCount);
-
- SyntaxClass<RefObject> findSyntaxClass(Name* name);
-
- Dictionary<Name*, SyntaxClass<RefObject> > mapNameToSyntaxClass;
-
- // cache used by type checking, implemented in check.cpp
- TypeCheckingCache* typeCheckingCache = nullptr;
- TypeCheckingCache* getTypeCheckingCache();
- void destroyTypeCheckingCache();
- //
-
- /// Will try to load the library by specified name (using the set loader), if not one already available.
- ISlangSharedLibrary* getOrLoadSharedLibrary(SharedLibraryType type, DiagnosticSink* sink);
-
- /// Gets a shared library by type, or null if not loaded
- ISlangSharedLibrary* getSharedLibrary(SharedLibraryType type) const { return sharedLibraries[int(type)]; }
-
- SlangFuncPtr getSharedLibraryFunc(SharedLibraryFuncType type, DiagnosticSink* sink);
-
- Session();
-
- void addBuiltinSource(
- RefPtr<Scope> const& scope,
- String const& path,
- String const& source);
- ~Session();
-
- private:
- /// Linkage used for all built-in (stdlib) code.
- RefPtr<Linkage> m_builtinLinkage;
- };
-
-}
-
-#endif