diff options
| author | Yong He <yonghe@outlook.com> | 2024-02-23 16:39:46 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-23 16:39:46 -0800 |
| commit | 401d8cdb12ae69aeb216c80c9bb90240d8359649 (patch) | |
| tree | 4548c9de52bdeff424a0a3969ad407fccb3c0f09 /source | |
| parent | 58eb6f7da01af1767282ee12b0b4b25c57e52afb (diff) | |
Add slangc interface to compile and use ir modules. (#3615)
* Add slangc interface to compile and use ir modules.
* Fix glsl scalar layout settings not copied to target.
* Fix.
* Cleanups.
Diffstat (limited to 'source')
| -rw-r--r-- | source/compiler-core/slang-source-loc.h | 2 | ||||
| -rw-r--r-- | source/slang/slang-api.cpp | 3 | ||||
| -rw-r--r-- | source/slang/slang-check-decl.cpp | 15 | ||||
| -rw-r--r-- | source/slang/slang-check-modifier.cpp | 1 | ||||
| -rw-r--r-- | source/slang/slang-compiler.cpp | 11 | ||||
| -rwxr-xr-x | source/slang/slang-compiler.h | 19 | ||||
| -rw-r--r-- | source/slang/slang-ir-link.cpp | 9 | ||||
| -rw-r--r-- | source/slang/slang-module-library.cpp | 30 | ||||
| -rw-r--r-- | source/slang/slang-module-library.h | 6 | ||||
| -rw-r--r-- | source/slang/slang-options.cpp | 106 | ||||
| -rw-r--r-- | source/slang/slang-serialize-container.cpp | 72 | ||||
| -rw-r--r-- | source/slang/slang-serialize-container.h | 19 | ||||
| -rw-r--r-- | source/slang/slang-serialize-factory.cpp | 38 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 137 |
14 files changed, 263 insertions, 205 deletions
diff --git a/source/compiler-core/slang-source-loc.h b/source/compiler-core/slang-source-loc.h index a5919d809..0a94980d1 100644 --- a/source/compiler-core/slang-source-loc.h +++ b/source/compiler-core/slang-source-loc.h @@ -61,7 +61,7 @@ struct PathInfo /// True if has a canonical path SLANG_FORCE_INLINE bool hasUniqueIdentity() const { return type == Type::Normal && uniqueIdentity.getLength() > 0; } /// True if has a regular found path - SLANG_FORCE_INLINE bool hasFoundPath() const { return type == Type::Normal || type == Type::FoundPath || (type == Type::FromString && foundPath.getLength() > 0); } + SLANG_FORCE_INLINE bool hasFoundPath() const { return (type == Type::Normal || type == Type::FoundPath || type == Type::FromString) && foundPath.getLength() > 0; } /// True if has a found path that has originated from a file (as opposed to string or some other origin) SLANG_FORCE_INLINE bool hasFileFoundPath() const { return (type == Type::Normal || type == Type::FoundPath) && foundPath.getLength() > 0; } /// Get the 'name'/path of the item. Will return an empty string if not applicable or not set. diff --git a/source/slang/slang-api.cpp b/source/slang/slang-api.cpp index 864bc8b7d..7284f2468 100644 --- a/source/slang/slang-api.cpp +++ b/source/slang/slang-api.cpp @@ -495,11 +495,12 @@ SLANG_API void spSetDefaultModuleName( SLANG_API SlangResult spAddLibraryReference( slang::ICompileRequest* request, + const char* basePath, const void* libData, size_t libDataSize) { SLANG_ASSERT(request); - return request->addLibraryReference(libData, libDataSize); + return request->addLibraryReference(basePath, libData, libDataSize); } SLANG_API void spTranslationUnit_addPreprocessorDefine( diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index 28db66c45..25f535825 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -1712,7 +1712,7 @@ namespace Slang { if (auto varDeclRefType = as<DeclRefType>(varDecl->type.type)) { - parentAggTypeDecl->unionTagsWith(getTypeTags(varDecl->type.type)); + parentAggTypeDecl->unionTagsWith(getTypeTags(varDeclRefType)); } } @@ -9321,20 +9321,21 @@ namespace Slang else if (as<PrivateModifier>(modifier)) return DeclVisibility::Private; } - // Interface members will always have the same visibility as the interface itself. if (auto interfaceDecl = findParentInterfaceDecl(decl)) { return getDeclVisibility(interfaceDecl); } - else if (as<NamespaceDecl>(decl)) + auto defaultVis = DeclVisibility::Default; + if (auto parentModule = getModuleDecl(decl)) + defaultVis = parentModule->isInLegacyLanguage ? DeclVisibility::Public : DeclVisibility::Internal; + + // Members of other agg type decls will have their default visibility capped to the parents'. + if (as<NamespaceDecl>(decl)) { return DeclVisibility::Public; } - if (auto parentModule = getModuleDecl(decl)) - return parentModule->isInLegacyLanguage ? DeclVisibility::Public : DeclVisibility::Internal; - - return DeclVisibility::Default; + return defaultVis; } void diagnoseCapabilityProvenance(DiagnosticSink* sink, Decl* decl, CapabilityAtom missingAtom) diff --git a/source/slang/slang-check-modifier.cpp b/source/slang/slang-check-modifier.cpp index a4e906ac9..2d9107431 100644 --- a/source/slang/slang-check-modifier.cpp +++ b/source/slang/slang-check-modifier.cpp @@ -989,7 +989,6 @@ namespace Slang case ASTNodeType::PreciseModifier: case ASTNodeType::IntrinsicOpModifier: case ASTNodeType::InlineModifier: - case ASTNodeType::ExternModifier: case ASTNodeType::HLSLExportModifier: case ASTNodeType::ExternCppModifier: case ASTNodeType::ExportedModifier: diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp index c0be68723..78aa4a18b 100644 --- a/source/slang/slang-compiler.cpp +++ b/source/slang/slang-compiler.cpp @@ -1488,7 +1488,7 @@ namespace Slang // Add all of the module libraries libraries.addRange(linkage->m_libModules.getBuffer(), linkage->m_libModules.getCount()); } - + options.compilerSpecificArguments = allocator.allocate(compilerSpecificArguments); options.requiredCapabilityVersions = SliceUtil::asSlice(requiredCapabilityVersions); options.libraries = SliceUtil::asSlice(libraries); @@ -1879,14 +1879,7 @@ namespace Slang SerialContainerUtil::WriteOptions options; options.compressionType = linkage->m_optionSet.getEnumOption<SerialCompressionType>(CompilerOptionName::IrCompression); - if (linkage->m_optionSet.getBoolOption(CompilerOptionName::Obfuscate)) - { - // If code is obfuscated, we *disable* AST output as it is not obfuscated and will reveal - // too much about IR. - // Also currently only IR is needed. - options.optionFlags &= ~SerialOptionFlag::ASTModule; - } - + // If debug information is enabled, enable writing out source locs if (_shouldWriteSourceLocs(linkage)) { diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h index 6c55a7807..ece552cec 100755 --- a/source/slang/slang-compiler.h +++ b/source/slang/slang-compiler.h @@ -25,12 +25,10 @@ #include "slang-capability.h" #include "slang-diagnostics.h" - #include "slang-preprocessor.h" #include "slang-profile.h" #include "slang-syntax.h" #include "slang-content-assist-info.h" - #include "slang-hlsl-to-vulkan-layout-options.h" #include "slang-compiler-options.h" #include "slang-serialize-ir-types.h" @@ -1475,7 +1473,7 @@ namespace Slang RefPtr<EntryPoint> findEntryPointByName(UnownedStringSlice const& name); - List<RefPtr<EntryPoint>> const& getEntryPoints() { return m_entryPoints; } + List<RefPtr<EntryPoint>>& getEntryPoints() { return m_entryPoints; } void _addEntryPoint(EntryPoint* entryPoint); void _processFindDeclsExportSymbolsRec(Decl* decl); @@ -1551,6 +1549,8 @@ namespace Slang public: TranslationUnitRequest( FrontEndCompileRequest* compileRequest); + TranslationUnitRequest( + FrontEndCompileRequest* compileRequest, Module* m); // The parent compile request FrontEndCompileRequest* compileRequest = nullptr; @@ -1596,6 +1596,8 @@ namespace Slang /// Result of compiling this translation unit (a module) RefPtr<Module> module; + bool isChecked = false; + Module* getModule() { return module; } ModuleDecl* getModuleDecl() { return module->getModuleDecl(); } @@ -1755,6 +1757,8 @@ namespace Slang Source, IR }; + struct SerialContainerDataModule; + /// A context for loading and re-using code modules. class Linkage : public RefObject, public slang::ISession { @@ -1959,6 +1963,11 @@ namespace Slang SourceLoc const& loc, DiagnosticSink* sink, const LoadedModuleDictionary* additionalLoadedModules); + RefPtr<Module> loadDeserializedModule( + Name* name, + const PathInfo& filePathInfo, + SerialContainerDataModule& m, + DiagnosticSink* sink); SourceFile* loadSourceFile(String pathFrom, String path); @@ -1979,7 +1988,7 @@ namespace Slang DiagnosticSink* sink, const LoadedModuleDictionary* loadedModules = nullptr); - void prepareDeserializedModule(Module* module, DiagnosticSink* sink); + void prepareDeserializedModule(SerialContainerDataModule& moduleEntry, const PathInfo& pathInfo, Module* module, DiagnosticSink* sink); SourceFile* findFile(Name* name, SourceLoc loc, IncludeSystem& outIncludeSystem); struct IncludeResult @@ -2661,7 +2670,7 @@ namespace Slang virtual SLANG_NO_THROW void SLANG_MCALL addTranslationUnitPreprocessorDefine(int translationUnitIndex, const char* key, const char* value) SLANG_OVERRIDE; virtual SLANG_NO_THROW void SLANG_MCALL addTranslationUnitSourceFile(int translationUnitIndex, char const* path) SLANG_OVERRIDE; virtual SLANG_NO_THROW void SLANG_MCALL addTranslationUnitSourceString(int translationUnitIndex, char const* path, char const* source) SLANG_OVERRIDE; - virtual SLANG_NO_THROW SlangResult SLANG_MCALL addLibraryReference(const void* libData, size_t libDataSize) SLANG_OVERRIDE; + virtual SLANG_NO_THROW SlangResult SLANG_MCALL addLibraryReference(const char* basePath, const void* libData, size_t libDataSize) SLANG_OVERRIDE; virtual SLANG_NO_THROW void SLANG_MCALL addTranslationUnitSourceStringSpan(int translationUnitIndex, char const* path, char const* sourceBegin, char const* sourceEnd) SLANG_OVERRIDE; virtual SLANG_NO_THROW void SLANG_MCALL addTranslationUnitSourceBlob(int translationUnitIndex, char const* path, ISlangBlob* sourceBlob) SLANG_OVERRIDE; virtual SLANG_NO_THROW int SLANG_MCALL addEntryPoint(int translationUnitIndex, char const* name, SlangStage stage) SLANG_OVERRIDE; diff --git a/source/slang/slang-ir-link.cpp b/source/slang/slang-ir-link.cpp index eb0068657..be0b87b60 100644 --- a/source/slang/slang-ir-link.cpp +++ b/source/slang/slang-ir-link.cpp @@ -1477,14 +1477,7 @@ LinkedIR linkIR( { irModules.add(irModule); }); - for (IArtifact* artifact : linkage->m_libModules) - { - if (auto library = findRepresentation<ModuleLibrary>(artifact)) - { - irModules.addRange(library->m_modules.getBuffer()->readRef(), library->m_modules.getCount()); - } - } - + // Add any modules that were loaded as libraries for (IRModule* irModule : irModules) { diff --git a/source/slang/slang-module-library.cpp b/source/slang/slang-module-library.cpp index 0975d6e8f..02ace07d3 100644 --- a/source/slang/slang-module-library.cpp +++ b/source/slang/slang-module-library.cpp @@ -39,7 +39,7 @@ void* ModuleLibrary::castAs(const Guid& guid) return getObject(guid); } -SlangResult loadModuleLibrary(const Byte* inBytes, size_t bytesCount, EndToEndCompileRequest* req, ComPtr<IModuleLibrary>& outLibrary) +SlangResult loadModuleLibrary(const Byte* inBytes, size_t bytesCount, String path, EndToEndCompileRequest* req, ComPtr<IModuleLibrary>& outLibrary) { auto library = new ModuleLibrary; ComPtr<IModuleLibrary> scopeLibrary(library); @@ -51,10 +51,6 @@ SlangResult loadModuleLibrary(const Byte* inBytes, size_t bytesCount, EndToEndCo SLANG_RETURN_ON_FAIL(RiffUtil::read(&memoryStream, riffContainer)); auto linkage = req->getLinkage(); - - // TODO(JS): May be better to have a ITypeComponent that encapsulates a collection of modules - // For now just add to the linkage - { SerialContainerData containerData; @@ -65,15 +61,29 @@ SlangResult loadModuleLibrary(const Byte* inBytes, size_t bytesCount, EndToEndCo options.sourceManager = linkage->getSourceManager(); options.linkage = req->getLinkage(); options.sink = req->getSink(); - + options.astBuilder = linkage->getASTBuilder(); + options.modulePath = path; SLANG_RETURN_ON_FAIL(SerialContainerUtil::read(&riffContainer, options, nullptr, containerData)); + DiagnosticSink sink; - for (const auto& module : containerData.modules) + // Modules in the container should be serialized in its depedency order, + // so that we always load the dependencies before the consuming module. + for (auto& module : containerData.modules) { // If the irModule is set, add it if (module.irModule) { - library->m_modules.add(module.irModule); + if (module.dependentFiles.getCount() == 0) + return SLANG_FAIL; + if (!module.astRootNode) + return SLANG_FAIL; + auto loadedModule = linkage->loadDeserializedModule( + as<ModuleDecl>(module.astRootNode)->getName(), + PathInfo::makePath(module.dependentFiles.getFirst()), + module, &sink); + if (!loadedModule) + return SLANG_FAIL; + library->m_modules.add(loadedModule); } } @@ -93,7 +103,7 @@ SlangResult loadModuleLibrary(const Byte* inBytes, size_t bytesCount, EndToEndCo return SLANG_OK; } -SlangResult loadModuleLibrary(ArtifactKeep keep, IArtifact* artifact, EndToEndCompileRequest* req, ComPtr<IModuleLibrary>& outLibrary) +SlangResult loadModuleLibrary(ArtifactKeep keep, IArtifact* artifact, String path, EndToEndCompileRequest* req, ComPtr<IModuleLibrary>& outLibrary) { if (auto foundLibrary = findRepresentation<IModuleLibrary>(artifact)) { @@ -107,7 +117,7 @@ SlangResult loadModuleLibrary(ArtifactKeep keep, IArtifact* artifact, EndToEndCo // Load the module ComPtr<IModuleLibrary> library; - SLANG_RETURN_ON_FAIL(loadModuleLibrary((const Byte*)blob->getBufferPointer(), blob->getBufferSize(), req, library)); + SLANG_RETURN_ON_FAIL(loadModuleLibrary((const Byte*)blob->getBufferPointer(), blob->getBufferSize(), path, req, library)); if (canKeep(keep)) { diff --git a/source/slang/slang-module-library.h b/source/slang/slang-module-library.h index 698e4e014..9e3d7a2e8 100644 --- a/source/slang/slang-module-library.h +++ b/source/slang/slang-module-library.h @@ -30,16 +30,16 @@ public: virtual SLANG_NO_THROW bool SLANG_MCALL exists() SLANG_OVERRIDE { return true; } List<FrontEndCompileRequest::ExtraEntryPointInfo> m_entryPoints; - List<RefPtr<IRModule>> m_modules; + List<RefPtr<Module>> m_modules; void* getInterface(const Guid& uuid); void* getObject(const Guid& uuid); }; -SlangResult loadModuleLibrary(const Byte* inBytes, size_t bytesCount, EndToEndCompileRequest* req, ComPtr<IModuleLibrary>& outModule); +SlangResult loadModuleLibrary(const Byte* inBytes, size_t bytesCount, String Path, EndToEndCompileRequest* req, ComPtr<IModuleLibrary>& outModule); // Given a product make available as a module -SlangResult loadModuleLibrary(ArtifactKeep keep, IArtifact* artifact, EndToEndCompileRequest* req, ComPtr<IModuleLibrary>& outModule); +SlangResult loadModuleLibrary(ArtifactKeep keep, IArtifact* artifact, String Path, EndToEndCompileRequest* req, ComPtr<IModuleLibrary>& outModule); } // namespace Slang diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp index 8e94b73cc..39578a1ea 100644 --- a/source/slang/slang-options.cpp +++ b/source/slang/slang-options.cpp @@ -557,7 +557,7 @@ void initCommandOptions(CommandOptions& options) SLANG_ASSERT(options.hasContiguousUserValueRange(CommandOptions::LookupKind::Category, UserValue(0), UserValue(ValueCategory::CountOf))); } -SlangResult _addLibraryReference(EndToEndCompileRequest* req, IArtifact* artifact); +SlangResult _addLibraryReference(EndToEndCompileRequest* req, String path, IArtifact* artifact, bool includeEntryPoint); class ReproPathVisitor : public Slang::Path::Visitor { @@ -650,7 +650,6 @@ struct OptionsParser struct RawTarget { CodeGenTarget format = CodeGenTarget::Unknown; - SlangTargetFlags targetFlags = kDefaultTargetFlags; int targetID = -1; CompilerOptionSet optionSet; @@ -736,6 +735,7 @@ struct OptionsParser void _appendMinimalUsage(StringBuilder& out); void _outputMinimalUsage(); + SlangResult addReferencedModule(String path, SourceLoc loc, bool includeEntryPoint); SlangResult _parseReferenceModule(const CommandLineArg& arg); SlangResult _parseReproFileSystem(const CommandLineArg& arg); SlangResult _parseLoadRepro(const CommandLineArg& arg); @@ -772,9 +772,6 @@ struct OptionsParser // If not, it will be `-1`. int m_slangTranslationUnitIndex = -1; - // The number of input files that have been specified - int m_inputPathCount = 0; - int m_translationUnitCount = 0; int m_currentTranslationUnitIndex = -1; @@ -931,13 +928,15 @@ SlangSourceLanguage findSourceLanguageFromPath(const String& path, Stage& outImp SlangResult OptionsParser::addInputPath(char const* inPath, SourceLanguage langOverride ) { - m_inputPathCount++; - // look at the extension on the file name to determine // how we should handle it. String path = String(inPath); - if (path.endsWith(".slang") || langOverride == SourceLanguage::Slang) + if (path.endsWith(".slang-module") || path.endsWith(".slang-lib")) + { + return addReferencedModule(path, SourceLoc(), false); + } + else if (path.endsWith(".slang") || langOverride == SourceLanguage::Slang) { // Plain old slang code addInputSlangPath(path); @@ -1298,20 +1297,13 @@ SlangResult OptionsParser::_expectInt(const CommandLineArg& initArg, Int& outInt return SLANG_OK; } -SlangResult OptionsParser::_parseReferenceModule(const CommandLineArg& arg) +SlangResult OptionsParser::addReferencedModule(String path, SourceLoc loc, bool includeEntryPoint) { - SLANG_UNUSED(arg); - - CommandLineArg referenceModuleName; - SLANG_RETURN_ON_FAIL(m_reader.expectArg(referenceModuleName)); - - const auto path = referenceModuleName.value; - auto desc = ArtifactDescUtil::getDescFromPath(path.getUnownedSlice()); if (desc.kind == ArtifactKind::Unknown) { - m_sink->diagnose(referenceModuleName.loc, Diagnostics::unknownLibraryKind, Path::getPathExt(path)); + m_sink->diagnose(loc, Diagnostics::unknownLibraryKind, Path::getPathExt(path)); return SLANG_FAIL; } @@ -1329,7 +1321,7 @@ SlangResult OptionsParser::_parseReferenceModule(const CommandLineArg& arg) if (!ArtifactDescUtil::isLinkable(desc)) { - m_sink->diagnose(referenceModuleName.loc, Diagnostics::kindNotLinkable, Path::getPathExt(path)); + m_sink->diagnose(loc, Diagnostics::kindNotLinkable, Path::getPathExt(path)); return SLANG_FAIL; } @@ -1354,16 +1346,36 @@ SlangResult OptionsParser::_parseReferenceModule(const CommandLineArg& arg) fileRep = new OSFileArtifactRepresentation(IOSFileArtifactRepresentation::Kind::Reference, path.getUnownedSlice(), nullptr); if (!fileRep->exists()) { - m_sink->diagnose(referenceModuleName.loc, Diagnostics::libraryDoesNotExist, path); + m_sink->diagnose(loc, Diagnostics::libraryDoesNotExist, path); return SLANG_FAIL; } } artifact->addRepresentation(fileRep); - SLANG_RETURN_ON_FAIL(_addLibraryReference(m_requestImpl, artifact)); + SLANG_RETURN_ON_FAIL(_addLibraryReference(m_requestImpl, path, artifact, includeEntryPoint)); + for (Index i = m_rawTranslationUnits.getCount(); i < m_requestImpl->getTranslationUnitCount(); i++) + { + RawTranslationUnit rawTU; + rawTU.translationUnitID = (int)i; + rawTU.impliedStage = Stage::Unknown; + rawTU.sourceLanguage = SLANG_SOURCE_LANGUAGE_SLANG; + m_rawTranslationUnits.add(rawTU); + } + m_currentTranslationUnitIndex = m_requestImpl->getTranslationUnitCount() - 1; + m_slangTranslationUnitIndex = m_currentTranslationUnitIndex; return SLANG_OK; } +SlangResult OptionsParser::_parseReferenceModule(const CommandLineArg& arg) +{ + SLANG_UNUSED(arg); + + CommandLineArg referenceModuleName; + SLANG_RETURN_ON_FAIL(m_reader.expectArg(referenceModuleName)); + + return addReferencedModule(referenceModuleName.value, referenceModuleName.loc, true); +} + SlangResult OptionsParser::_parseReproFileSystem(const CommandLineArg& arg) { SLANG_UNUSED(arg); @@ -2171,13 +2183,9 @@ SlangResult OptionsParser::_parse( return SLANG_FAIL; } case OptionKind::EmitSpirvViaGLSL: - { - getCurrentTarget()->targetFlags &= ~SLANG_TARGET_FLAG_GENERATE_SPIRV_DIRECTLY; - } - break; case OptionKind::EmitSpirvDirectly: { - getCurrentTarget()->targetFlags |= SLANG_TARGET_FLAG_GENERATE_SPIRV_DIRECTLY; + getCurrentTarget()->optionSet.add(optionKind, true); } break; case OptionKind::SPIRVCoreGrammarJSON: @@ -2367,7 +2375,8 @@ SlangResult OptionsParser::_parse( entryPoint.translationUnitIndex = 0; } } - else + else if (m_frontEndReq->additionalLoadedModules && + m_frontEndReq->additionalLoadedModules->getCount() == 0) { // Otherwise, we require that all entry points be specified after // the translation unit to which tye belong. @@ -2610,21 +2619,7 @@ SlangResult OptionsParser::_parse( if (m_rawTargets.getCount() == 1) { - if (m_defaultTarget.optionSet.getProfileVersion() != ProfileVersion::Unknown) - { - setProfileVersion(getCurrentTarget(), m_defaultTarget.optionSet.getProfileVersion()); - } - for (auto atom : m_defaultTarget.optionSet.getArray(CompilerOptionName::Capability)) - { - addCapabilityAtom(getCurrentTarget(), (CapabilityName)atom.intValue); - } - - getCurrentTarget()->targetFlags |= m_defaultTarget.targetFlags; - - if (defaultTargetFloatingPointMode != FloatingPointMode::Default) - { - setFloatingPointMode(getCurrentTarget(), defaultTargetFloatingPointMode); - } + m_rawTargets[0].optionSet.overrideWith(m_defaultTarget.optionSet); } else { @@ -2648,18 +2643,6 @@ SlangResult OptionsParser::_parse( } } - if (m_defaultTarget.targetFlags != kDefaultTargetFlags) - { - if (m_rawTargets.getCount() == 0) - { - m_sink->diagnose(SourceLoc(), Diagnostics::targetFlagsIgnoredBecauseNoTargets); - } - else - { - m_sink->diagnose(SourceLoc(), Diagnostics::targetFlagsIgnoredBecauseBeforeAllTargets); - } - } - if (defaultTargetFloatingPointMode != FloatingPointMode::Default) { if (m_rawTargets.getCount() == 0) @@ -2705,11 +2688,6 @@ SlangResult OptionsParser::_parse( m_requestImpl->addTargetCapability(targetID, SlangCapabilityID(atom.intValue)); } - if (rawTarget.targetFlags) - { - m_compileRequest->setTargetFlags(targetID, rawTarget.targetFlags); - } - auto floatingPointMode = rawTarget.optionSet.getEnumOption<FloatingPointMode>(CompilerOptionName::FloatingPointMode); if (floatingPointMode != FloatingPointMode::Default) { @@ -2826,7 +2804,7 @@ SlangResult OptionsParser::_parse( break; case CodeGenTarget::SPIRV: case CodeGenTarget::SPIRVAssembly: - if (getCurrentTarget()->targetFlags & SLANG_TARGET_FLAG_GENERATE_SPIRV_DIRECTLY) + if (getCurrentTarget()->optionSet.shouldEmitSPIRVDirectly()) { rawOutput.isWholeProgram = true; } @@ -2857,7 +2835,7 @@ SlangResult OptionsParser::_parse( targetInfo = new EndToEndCompileRequest::TargetInfo(); m_requestImpl->m_targetInfos[target] = targetInfo; } - + target->getOptionSet().overrideWith(m_rawTargets[rawOutput.targetIndex].optionSet); if (rawOutput.isWholeProgram) { if (targetInfo->wholeTargetOutputPath != "") @@ -2874,7 +2852,13 @@ SlangResult OptionsParser::_parse( { if (rawOutput.entryPointIndex == -1) continue; - Int entryPointID = m_rawEntryPoints[rawOutput.entryPointIndex].entryPointID; + auto entryPoint = m_rawEntryPoints[rawOutput.entryPointIndex]; + Int entryPointID = entryPoint.entryPointID; + if (entryPointID == -1) + { + m_sink->diagnose(SourceLoc(), Diagnostics::entryPointFunctionNotFound, entryPoint.name); + continue; + } auto entryPointReq = m_requestImpl->getFrontEndReq()->getEntryPointReqs()[entryPointID]; //String outputPath; diff --git a/source/slang/slang-serialize-container.cpp b/source/slang/slang-serialize-container.cpp index c9db7ff5e..0622c2bd4 100644 --- a/source/slang/slang-serialize-container.cpp +++ b/source/slang/slang-serialize-container.cpp @@ -83,21 +83,29 @@ namespace Slang { DigestBuilder<SHA1> digestBuilder; module->getOptionSet().buildHash(digestBuilder); auto fileDependencies = module->getFileDependencies(); - String canonicalModulePath; + String canonicalModulePath, moduleDir; if (auto modulePath = module->getFilePath()) { - canonicalModulePath = Path::getParentDirectory(modulePath); + canonicalModulePath = modulePath; Path::getCanonical(canonicalModulePath, canonicalModulePath); + moduleDir = Path::getParentDirectory(canonicalModulePath); } for (auto file : fileDependencies) { digestBuilder.append(file->getDigest()); if (file->getPathInfo().hasFoundPath()) { - String canonicalFilePath = file->getPathInfo().foundPath; - Path::getCanonical(file->getPathInfo().foundPath, canonicalFilePath); - canonicalFilePath = Path::getRelativePath(canonicalModulePath, canonicalFilePath); - dstModule.dependentFiles.add(canonicalFilePath); + if (file->getPathInfo().foundPath == canonicalModulePath) + { + dstModule.dependentFiles.add(Path::getFileName(canonicalModulePath)); + } + else + { + String canonicalFilePath = file->getPathInfo().foundPath; + Path::getCanonical(file->getPathInfo().foundPath, canonicalFilePath); + canonicalFilePath = Path::getRelativePath(moduleDir, canonicalFilePath); + dstModule.dependentFiles.add(canonicalFilePath); + } } else { @@ -112,6 +120,20 @@ namespace Slang { } +static SlangResult _addModuleRecursive(HashSet<Module*>& processedModuleSet, const SerialContainerUtil::WriteOptions& options, SerialContainerData& container, Module* module) +{ + if (processedModuleSet.contains(module)) + return SLANG_OK; + for (auto m : module->getModuleDependencies()) + { + if (m != module) + _addModuleRecursive(processedModuleSet, options, container, m); + } + processedModuleSet.add(module); + return SerialContainerUtil::addModuleToData(module, options, container); +} + + /* static */SlangResult SerialContainerUtil::addFrontEndRequestToData(FrontEndCompileRequest* frontEndReq, const WriteOptions& options, SerialContainerData& outData) { // Go through translation units, adding modules @@ -124,12 +146,12 @@ namespace Slang { } /* static */SlangResult SerialContainerUtil::addEndToEndRequestToData(EndToEndCompileRequest* request, const WriteOptions& options, SerialContainerData& out) -{ +{ auto linkage = request->getLinkage(); auto sink = request->getSink(); - // Output the front end request data - SLANG_RETURN_ON_FAIL(addFrontEndRequestToData(request->getFrontEndReq(), options, out)); + // Output the parsed modules. + addFrontEndRequestToData(request->getFrontEndReq(), options, out); // auto program = request->getSpecializedGlobalAndEntryPointsComponentType(); @@ -388,6 +410,19 @@ static List<ExtensionDecl*>& _getCandidateExtensionList( SLANG_RETURN_ON_FAIL(sourceLocReader->read(&sourceLocData, options.sourceManager)); } + // Create a source loc representing the binary module. + SourceLoc binaryModuleLoc = SourceLoc(); + + if (options.modulePath.getLength()) + { + auto srcManager = options.linkage->getSourceManager(); + auto modulePathInfo = PathInfo::makePath(options.modulePath); + auto srcFile = srcManager->createSourceFileWithString(modulePathInfo, String()); + srcManager->addSourceFile(options.modulePath, srcFile); + auto srcView = srcManager->createSourceView(srcFile, &modulePathInfo, SourceLoc()); + binaryModuleLoc = srcView->getRange().begin; + } + // Add modules if (RiffContainer::ListChunk* moduleList = containerChunk->findContainedList(SerialBinary::kModuleListFourCc)) { @@ -400,10 +435,8 @@ static List<ExtensionDecl*>& _getCandidateExtensionList( NodeBase* astRootNode = nullptr; RefPtr<IRModule> irModule; SerialContainerData::Module module; - bool hasHeader = false; if (auto headerChunk = as<RiffContainer::DataChunk>(chunk, SerialBinary::kModuleHeaderFourCc)) { - hasHeader = true; MemoryStreamBase memStream( FileAccess::Read, headerChunk->getSingleData()->getPayload(), @@ -507,10 +540,18 @@ static List<ExtensionDecl*>& _getCandidateExtensionList( const SerialInfo::Entry* entry = entries[i]; if (entry->typeKind == SerialTypeKind::ImportSymbol) { + // Import symbols are always serialized with a mangled name in the form of + // <module_name>!<symbol_mangled_name>. + // As symbol_mangled_name may not contain the name of its parent module + // in the case of an `extern` or `export` symbol. + // UnownedStringSlice mangledName = reader.getStringSlice(SerialIndex(i)); - - String moduleName; - SLANG_RETURN_ON_FAIL(MangledNameParser::parseModuleName(mangledName, moduleName)); + List<UnownedStringSlice> slicesOut; + StringUtil::split(mangledName, '!', slicesOut); + if (slicesOut.getCount() != 2) + return SLANG_FAIL; + auto moduleName = slicesOut[0]; + mangledName = slicesOut[1]; // If we already have looked up this module and it has the same name just use what we have Module* readModule = nullptr; @@ -525,8 +566,7 @@ static List<ExtensionDecl*>& _getCandidateExtensionList( NamePool* namePool = linkage->getNamePool(); Name* moduleNameName = namePool->getName(moduleName); - - readModule = linkage->findOrImportModule(moduleNameName, SourceLoc::fromRaw(0), options.sink, additionalLoadedModules); + readModule = linkage->findOrImportModule(moduleNameName, binaryModuleLoc, options.sink, additionalLoadedModules); if (!readModule) { return SLANG_FAIL; diff --git a/source/slang/slang-serialize-container.h b/source/slang/slang-serialize-container.h index 9b9fbe6a1..4b35e931f 100644 --- a/source/slang/slang-serialize-container.h +++ b/source/slang/slang-serialize-container.h @@ -30,6 +30,15 @@ struct SerialContainerBinary }; }; +struct SerialContainerDataModule +{ + RefPtr<IRModule> irModule; ///< The IR for the module + RefPtr<ASTBuilder> astBuilder; ///< The astBuilder that owns the astRootNode + NodeBase* astRootNode = nullptr; ///< The module decl + List<String> dependentFiles; + SHA1::Digest digest; +}; + /* Struct that holds all the data that can be held in a 'container' */ struct SerialContainerData { @@ -48,14 +57,7 @@ struct SerialContainerData RefPtr<IRModule> irModule; }; - struct Module - { - RefPtr<IRModule> irModule; ///< The IR for the module - RefPtr<ASTBuilder> astBuilder; ///< The astBuilder that owns the astRootNode - NodeBase* astRootNode = nullptr; ///< The module decl - List<String> dependentFiles; - SHA1::Digest digest; - }; + typedef SerialContainerDataModule Module; struct EntryPoint { @@ -95,6 +97,7 @@ struct SerialContainerUtil Linkage* linkage = nullptr; DiagnosticSink* sink = nullptr; bool readHeaderOnly = false; + String modulePath; }; /// Add module to outData diff --git a/source/slang/slang-serialize-factory.cpp b/source/slang/slang-serialize-factory.cpp index 5eae5e740..e8cb82dc1 100644 --- a/source/slang/slang-serialize-factory.cpp +++ b/source/slang/slang-serialize-factory.cpp @@ -78,8 +78,14 @@ SerialIndex ModuleSerialFilter::writePointer(SerialWriter* writer, const NodeBas { ASTBuilder* astBuilder = m_moduleDecl->module->getASTBuilder(); - // It's a reference to a declaration in another module, so first get the symbol name. - String mangledName = getMangledName(astBuilder, decl); + // It's a reference to a declaration in another module, so first get the symbol name. + // Note that we will always name an import symbol in the form of + // <module_name>!<symbol_mangled_name> for serialization. + // This is because <symbol_mangled_name> does not necessarily include the name of its + // parent module when it is qualified as `extern` or `export`. + // + String mangledName = getText(moduleDecl->getName()) +"!"+ getMangledName(astBuilder, decl); + // Add as an import symbol return writer->addImportSymbol(mangledName); } @@ -89,34 +95,6 @@ SerialIndex ModuleSerialFilter::writePointer(SerialWriter* writer, const NodeBas return writer->writeObject(ptr); } } - - // TODO(JS): If I enable this section then the stdlib doesn't work correctly, it appears to be because of - // `addCatchAllIntrinsicDecorationIfNeeded`. If this is enabled when AST is serialized, the 'body' (ie Stmt) - // will not be serialized. When serialized back in, it will appear to be a function without a body. - // In that case `addCatchAllIntrinsicDecorationIfNeeded` will add an intrinsic which in some cases is incorrect. - // This happens during lowering. - // - // So it seems the fix is for some other mechanism. Another solution is perhaps to run something like `addCatchAllIntrinsicDecorationIfNeeded` - // on the stdlib after compilation, and before serialization. Then removing it from lowering. - -#if 0 - // TODO(JS): What we really want to do here is to ignore bodies functions. - // It's not 100% clear if this is even right though - for example does type inference - // imply the body is needed to say infer a return type? - // Also not clear if statements in other scenarios (if there are others) might need to be kept. - // - // For now we just ignore all stmts - - // TODO(yong): We should by default serialize everything. The logic to skip bodies need to be - // behind a option flag. - if (Stmt* stmt = as<Stmt>(ptr)) - { - // - writer->setPointerIndex(stmt, SerialIndex(0)); - return SerialIndex(0); - } -#endif - // For now for everything else just write it return writer->writeObject(ptr); } diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index c0f89b0dc..bc91622f0 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -1559,7 +1559,7 @@ TargetRequest::TargetRequest(Linkage* linkage, CodeGenTarget format) } TargetRequest::TargetRequest(const TargetRequest& other) - : linkage(other.linkage), optionSet(other.optionSet) + : RefObject(), linkage(other.linkage), optionSet(other.optionSet) { } @@ -1721,6 +1721,12 @@ TranslationUnitRequest::TranslationUnitRequest( module = new Module(compileRequest->getLinkage()); } +TranslationUnitRequest::TranslationUnitRequest( + FrontEndCompileRequest* compileRequest, Module* m) + : compileRequest(compileRequest), module(m), isChecked(true) +{ + moduleName = getNamePool()->getName(m->getName()); +} Session* TranslationUnitRequest::getSession() { @@ -2388,6 +2394,9 @@ static void _outputIncludes(const List<SourceFile*>& sourceFiles, SourceManager* void FrontEndCompileRequest::parseTranslationUnit( TranslationUnitRequest* translationUnit) { + if (translationUnit->isChecked) + return; + auto linkage = getLinkage(); SLANG_AST_BUILDER_RAII(linkage->getASTBuilder()); @@ -2549,6 +2558,9 @@ void FrontEndCompileRequest::checkAllTranslationUnits() // apply the semantic checking logic. for( auto& translationUnit : translationUnits ) { + if (translationUnit->isChecked) + continue; + checkTranslationUnit(translationUnit.Ptr(), loadedModules); // Add the checked module to list of loadedModules so that they can be @@ -2577,6 +2589,10 @@ void FrontEndCompileRequest::generateIR() // in isolation. for( auto& translationUnit : translationUnits ) { + // Skip if the module is precompiled. + if (translationUnit->getModule()->getIRModule()) + continue; + // We want to only run generateIRForTranslationUnit once here. This is for two side effects: // * it can dump ir // * it can generate diagnostics @@ -2943,18 +2959,6 @@ SlangResult EndToEndCompileRequest::executeActions() int FrontEndCompileRequest::addTranslationUnit(SourceLanguage language, Name* moduleName) { - if (!moduleName) - { - // We want to ensure that symbols defined in different translation - // units get unique mangled names, so that we can, e.g., tell apart - // a `main()` function in `vertex.hlsl` and a `main()` in `fragment.hlsl`, - // even when they are being compiled together. - // - String generatedName = "tu"; - generatedName.append(translationUnits.getCount()); - moduleName = getNamePool()->getName(generatedName); - } - RefPtr<TranslationUnitRequest> translationUnit = new TranslationUnitRequest(this); translationUnit->compileRequest = this; translationUnit->sourceLanguage = SourceLanguage(language); @@ -2978,6 +2982,14 @@ void FrontEndCompileRequest::addTranslationUnitSourceArtifact( // Add the source file translationUnit->addSourceArtifact(sourceArtifact); + + if (!translationUnit->moduleName) + { + translationUnit->setModuleName( + getNamePool()->getName(Path::getFileNameWithoutExt(sourceArtifact->getName()))); + } + if (translationUnit->module->getFilePath() == nullptr) + translationUnit->module->setPathInfo(PathInfo::makePath(sourceArtifact->getName())); } void FrontEndCompileRequest::addTranslationUnitSourceBlob( @@ -2991,7 +3003,7 @@ void FrontEndCompileRequest::addTranslationUnitSourceBlob( auto artifact = ArtifactUtil::createArtifact(sourceDesc, path.getBuffer()); artifact->addRepresentationUnknown(sourceBlob); - translationUnit->addSourceArtifact(artifact); + addTranslationUnitSourceArtifact(translationUnitIndex, artifact); } void FrontEndCompileRequest::addTranslationUnitSourceFile( @@ -3011,7 +3023,7 @@ void FrontEndCompileRequest::addTranslationUnitSourceFile( auto sourceDesc = ArtifactDescUtil::makeDescForSourceLanguage(asExternal(translationUnit->sourceLanguage)); - auto sourceArtifact = ArtifactUtil::createArtifact(sourceDesc); + auto sourceArtifact = ArtifactUtil::createArtifact(sourceDesc, path.getBuffer()); auto extRep = new ExtFileArtifactRepresentation(path.getUnownedSlice(), fileSystemExt); sourceArtifact->addRepresentation(extRep); @@ -3044,7 +3056,7 @@ void FrontEndCompileRequest::addTranslationUnitSourceFile( return; } - translationUnit->addSourceArtifact(sourceArtifact); + addTranslationUnitSourceArtifact(translationUnitIndex, sourceArtifact); } int FrontEndCompileRequest::addEntryPoint( @@ -3146,6 +3158,27 @@ void Linkage::loadParsedModule( loadedModulesList.add(loadedModule); } +RefPtr<Module> Linkage::loadDeserializedModule(Name* name, + const PathInfo& filePathInfo, + SerialContainerData::Module& moduleEntry, + DiagnosticSink* sink) +{ + SLANG_AST_BUILDER_RAII(m_astBuilder); + RefPtr<Module> resultModule; + if (mapNameToLoadedModules.tryGetValue(name, resultModule)) + return resultModule; + if (mapPathToLoadedModule.tryGetValue(filePathInfo.getMostUniqueIdentity(), resultModule)) + return resultModule; + + resultModule = new Module(this, m_astBuilder); + prepareDeserializedModule(moduleEntry, filePathInfo, resultModule, sink); + + loadedModulesList.add(resultModule); + mapPathToLoadedModule.add(filePathInfo.getMostUniqueIdentity(), resultModule); + mapNameToLoadedModules.add(name, resultModule); + return resultModule; +} + RefPtr<Module> Linkage::loadModuleFromIRBlobImpl( Name* name, const PathInfo& filePathInfo, @@ -3154,6 +3187,8 @@ RefPtr<Module> Linkage::loadModuleFromIRBlobImpl( DiagnosticSink* sink, const LoadedModuleDictionary* additionalLoadedModules) { + SLANG_AST_BUILDER_RAII(m_astBuilder); + RefPtr<Module> resultModule = new Module(this, getASTBuilder()); resultModule->setName(name); ModuleBeingImportedRAII moduleBeingImported( @@ -3195,19 +3230,8 @@ RefPtr<Module> Linkage::loadModuleFromIRBlobImpl( return nullptr; } auto moduleEntry = containerData.modules.getFirst(); - resultModule->setIRModule(moduleEntry.irModule); - resultModule->setModuleDecl(as<ModuleDecl>(moduleEntry.astRootNode)); - resultModule->clearFileDependency(); - for (auto file : moduleEntry.dependentFiles) - { - auto sourceFile = loadSourceFile(filePathInfo.foundPath, file); - if (sourceFile) - { - resultModule->addFileDependency(sourceFile); - } - } - prepareDeserializedModule(resultModule, sink); + prepareDeserializedModule(moduleEntry, filePathInfo, resultModule, sink); loadedModulesList.add(resultModule); resultModule->setPathInfo(filePathInfo); @@ -5062,8 +5086,21 @@ void Linkage::setFileSystem(ISlangFileSystem* inFileSystem) getSourceManager()->setFileSystemExt(m_fileSystemExt); } -void Linkage::prepareDeserializedModule(Module* module, DiagnosticSink* sink) +void Linkage::prepareDeserializedModule(SerialContainerData::Module& moduleEntry, const PathInfo& filePathInfo, Module* module, DiagnosticSink* sink) { + module->setIRModule(moduleEntry.irModule); + module->setModuleDecl(as<ModuleDecl>(moduleEntry.astRootNode)); + module->clearFileDependency(); + for (auto file : moduleEntry.dependentFiles) + { + auto sourceFile = loadSourceFile(filePathInfo.foundPath, file); + if (sourceFile) + { + module->addFileDependency(sourceFile); + } + } + module->setPathInfo(filePathInfo); + module->_collectShaderParams(); module->_discoverEntryPoints(sink); @@ -5472,19 +5509,29 @@ void EndToEndCompileRequest::setDefaultModuleName(const char* defaultModuleName) frontEndReq->m_defaultModuleName = namePool->getName(defaultModuleName); } -SlangResult _addLibraryReference(EndToEndCompileRequest* req, IArtifact* artifact, ModuleLibrary* moduleLibrary) +SlangResult _addLibraryReference(EndToEndCompileRequest* req, ModuleLibrary* moduleLibrary, bool includeEntryPoint) { FrontEndCompileRequest* frontEndRequest = req->getFrontEndReq(); - frontEndRequest->m_extraEntryPoints.addRange(moduleLibrary->m_entryPoints.getBuffer(), moduleLibrary->m_entryPoints.getCount()); - // Add to the m_libModules - auto linkage = req->getLinkage(); - linkage->m_libModules.add(ComPtr<IArtifact>(artifact)); + if (includeEntryPoint) + { + frontEndRequest->m_extraEntryPoints.addRange( + moduleLibrary->m_entryPoints.getBuffer(), moduleLibrary->m_entryPoints.getCount()); + } + for (auto m : moduleLibrary->m_modules) + { + RefPtr<TranslationUnitRequest> tu = new TranslationUnitRequest(frontEndRequest, m); + frontEndRequest->translationUnits.add(tu); + // For modules loaded for EndToEndCompileRequest, + // we don't need the automatically discovered entrypoints. + if (!includeEntryPoint) + m->getEntryPoints().clear(); + } return SLANG_OK; } -SlangResult _addLibraryReference(EndToEndCompileRequest* req, IArtifact* artifact) +SlangResult _addLibraryReference(EndToEndCompileRequest* req, String path, IArtifact* artifact, bool includeEntryPoint) { auto desc = artifact->getDesc(); @@ -5507,7 +5554,7 @@ SlangResult _addLibraryReference(EndToEndCompileRequest* req, IArtifact* artifac } ComPtr<IModuleLibrary> libraryIntf; - SLANG_RETURN_ON_FAIL(loadModuleLibrary(ArtifactKeep::Yes, container, req, libraryIntf)); + SLANG_RETURN_ON_FAIL(loadModuleLibrary(ArtifactKeep::Yes, container, path, req, libraryIntf)); auto library = as<ModuleLibrary>(libraryIntf); @@ -5536,9 +5583,9 @@ SlangResult _addLibraryReference(EndToEndCompileRequest* req, IArtifact* artifac // for leaking. // // That isn't a risk from -r though because, it doesn't create a translation unit(s). - for (auto irModule : library->m_modules) + for (auto module : library->m_modules) { - irModule->setObfuscatedSourceMap(sourceMap); + module->getIRModule()->setObfuscatedSourceMap(sourceMap); } // Look up the source file @@ -5554,7 +5601,7 @@ SlangResult _addLibraryReference(EndToEndCompileRequest* req, IArtifact* artifac } } - SLANG_RETURN_ON_FAIL(_addLibraryReference(req, container, library)); + SLANG_RETURN_ON_FAIL(_addLibraryReference(req, library, includeEntryPoint)); return SLANG_OK; } @@ -5562,7 +5609,7 @@ SlangResult _addLibraryReference(EndToEndCompileRequest* req, IArtifact* artifac { ComPtr<IModuleLibrary> libraryIntf; - SLANG_RETURN_ON_FAIL(loadModuleLibrary(ArtifactKeep::Yes, artifact, req, libraryIntf)); + SLANG_RETURN_ON_FAIL(loadModuleLibrary(ArtifactKeep::Yes, artifact, path, req, libraryIntf)); auto library = as<ModuleLibrary>(libraryIntf); if (!library) @@ -5570,7 +5617,7 @@ SlangResult _addLibraryReference(EndToEndCompileRequest* req, IArtifact* artifac return SLANG_FAIL; } - SLANG_RETURN_ON_FAIL(_addLibraryReference(req, artifact, library)); + SLANG_RETURN_ON_FAIL(_addLibraryReference(req, library, includeEntryPoint)); return SLANG_OK; } @@ -5584,18 +5631,18 @@ SlangResult _addLibraryReference(EndToEndCompileRequest* req, IArtifact* artifac return SLANG_OK; } -SlangResult EndToEndCompileRequest::addLibraryReference(const void* libData, size_t libDataSize) +SlangResult EndToEndCompileRequest::addLibraryReference(const char* basePath, const void* libData, size_t libDataSize) { // We need to deserialize and add the modules ComPtr<IModuleLibrary> library; - SLANG_RETURN_ON_FAIL(loadModuleLibrary((const Byte*)libData, libDataSize, this, library)); + SLANG_RETURN_ON_FAIL(loadModuleLibrary((const Byte*)libData, libDataSize, basePath, this, library)); // Create an artifact without any name (as one is not provided) auto artifact = Artifact::create(ArtifactDesc::make(ArtifactKind::Library, ArtifactPayload::SlangIR)); artifact->addRepresentation(library); - return _addLibraryReference(this, artifact); + return _addLibraryReference(this, basePath, artifact, true); } void EndToEndCompileRequest::addTranslationUnitPreprocessorDefine(int translationUnitIndex, const char* key, const char* value) @@ -5631,7 +5678,7 @@ void EndToEndCompileRequest::addTranslationUnitSourceStringSpan(int translationU const auto slice = UnownedStringSlice(sourceBegin, sourceEnd); auto blob = RawBlob::create(slice.begin(), slice.getLength()); - + frontEndReq->addTranslationUnitSourceBlob(translationUnitIndex, path, blob); } |
