diff options
| author | Theresa Foley <10618364+tangent-vector@users.noreply.github.com> | 2025-07-24 12:59:58 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-24 19:59:58 +0000 |
| commit | 8ccd495d5eaa82cb831378c28dd190e657b6c999 (patch) | |
| tree | c39dc364d95f78984fd4ba2776d259ff944d2596 /source/slang/slang-translation-unit.cpp | |
| parent | 2d23a962766a97cbb11bcee5483a66aec923da49 (diff) | |
Organize code better by splitting some big files (#7890)
* Organize code better by splitting some big files
The basic change here is that the majority of the declarations in `slang-compiler.h` have been split out into a set of smaller and more focused files.
As a result, the implement of those declarations have been moved from `slang-compiler.cpp` and `slang.cpp` over to those new files when the proper home for code is obvious.
I have tried as much as possible to *not* make any edits to the code along the way, and just copy-paste declarations from one place to another as-is.
The exceptions I am aware of are:
* In some cases a function that used to be file-scope `static` was used by code that landed in two or more different `.cpp` files. In these cases, I changed the function to be non-`static` (removing the `_` prefix from its name, if it had one, per our naming conventions), and put a declaration for the function into the most appropriate header I could identify.
* I added a few comments in places where I saw ugly or unfortunate things in the code I was moving, and wanted to tag them with `TODO`s so we can hopefully get to them in the fullness of time.
* I added top-level comments to each of the new `.h` files that was introduced to try to explain the logic for what goes into that file.
* In cases where one of the new header files mostly existed to declare a single type, I sometimes added more detail to the doc comment on that type, to better explain the type and its role in the compiler (this is text that otherwise might have gone into the comment at the top leve lof the file, but I figured that the doc comment would have higher discoverability).
I expect that the most contentious choice here is that the `Session` class lands in `slang-global-session.h` while `slang-session.h` holds the `Linkage` class.
The names used in this change are consistent with how the relevant concepts in the public Slang API are named, and are consistent with how we *intend* to rename the classes themselves in time.
* format code
* fixup
---------
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
Diffstat (limited to 'source/slang/slang-translation-unit.cpp')
| -rw-r--r-- | source/slang/slang-translation-unit.cpp | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/source/slang/slang-translation-unit.cpp b/source/slang/slang-translation-unit.cpp new file mode 100644 index 000000000..049de01eb --- /dev/null +++ b/source/slang/slang-translation-unit.cpp @@ -0,0 +1,251 @@ +// slang-translation-unit.cpp +#include "slang-translation-unit.h" + +#include "slang-compiler.h" + +namespace Slang +{ + +// +// TranslationUnitRequest +// + +TranslationUnitRequest::TranslationUnitRequest(FrontEndCompileRequest* compileRequest) + : compileRequest(compileRequest) +{ + 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() +{ + return compileRequest->getSession(); +} + +NamePool* TranslationUnitRequest::getNamePool() +{ + return compileRequest->getNamePool(); +} + +SourceManager* TranslationUnitRequest::getSourceManager() +{ + return compileRequest->getSourceManager(); +} + +Scope* TranslationUnitRequest::getLanguageScope() +{ + Scope* languageScope = nullptr; + switch (sourceLanguage) + { + case SourceLanguage::HLSL: + languageScope = getSession()->hlslLanguageScope; + break; + case SourceLanguage::GLSL: + languageScope = getSession()->glslLanguageScope; + break; + case SourceLanguage::Slang: + default: + languageScope = getSession()->slangLanguageScope; + break; + } + return languageScope; +} + +Dictionary<String, String> TranslationUnitRequest::getCombinedPreprocessorDefinitions() +{ + Dictionary<String, String> combinedPreprocessorDefinitions; + for (const auto& def : preprocessorDefinitions) + combinedPreprocessorDefinitions.addIfNotExists(def); + for (const auto& def : compileRequest->optionSet.getArray(CompilerOptionName::MacroDefine)) + combinedPreprocessorDefinitions.addIfNotExists(def.stringValue, def.stringValue2); + + // Define standard macros, if not already defined. This style assumes using `#if __SOME_VAR` + // style, as in + // + // ``` + // #if __SLANG_COMPILER__ + // ``` + // + // This choice is made because slang outputs a warning on using a variable in an #if if not + // defined + // + // Of course this means using #ifndef/#ifdef/defined() is probably not appropraite with thes + // variables. + { + // Used to identify level of HLSL language compatibility + combinedPreprocessorDefinitions.addIfNotExists("__HLSL_VERSION", "2018"); + + // Indicates this is being compiled by the slang *compiler* + combinedPreprocessorDefinitions.addIfNotExists("__SLANG_COMPILER__", "1"); + + // Set macro depending on source type + switch (sourceLanguage) + { + case SourceLanguage::HLSL: + // Used to indicate compiled as HLSL language + combinedPreprocessorDefinitions.addIfNotExists("__HLSL__", "1"); + break; + case SourceLanguage::Slang: + // Used to indicate compiled as Slang language + combinedPreprocessorDefinitions.addIfNotExists("__SLANG__", "1"); + break; + default: + break; + } + + // If not set, define as 0. + combinedPreprocessorDefinitions.addIfNotExists("__HLSL__", "0"); + combinedPreprocessorDefinitions.addIfNotExists("__SLANG__", "0"); + } + + return combinedPreprocessorDefinitions; +} + +void TranslationUnitRequest::addSourceArtifact(IArtifact* sourceArtifact) +{ + SLANG_ASSERT(sourceArtifact); + m_sourceArtifacts.add(ComPtr<IArtifact>(sourceArtifact)); +} + + +void TranslationUnitRequest::addSource(IArtifact* sourceArtifact, SourceFile* sourceFile) +{ + SLANG_ASSERT(sourceArtifact && sourceFile); + // Must be in sync! + SLANG_ASSERT(m_sourceFiles.getCount() == m_sourceArtifacts.getCount()); + + addSourceArtifact(sourceArtifact); + _addSourceFile(sourceFile); +} + +void TranslationUnitRequest::addIncludedSourceFileIfNotExist(SourceFile* sourceFile) +{ + if (m_includedFileSet.contains(sourceFile)) + return; + + sourceFile->setIncludedFile(); + m_sourceFiles.add(sourceFile); + m_includedFileSet.add(sourceFile); +} + +PathInfo TranslationUnitRequest::_findSourcePathInfo(IArtifact* artifact) +{ + auto pathRep = findRepresentation<IPathArtifactRepresentation>(artifact); + + if (pathRep && pathRep->getPathType() == SLANG_PATH_TYPE_FILE) + { + // See if we have a unique identity set with the path + if (const auto uniqueIdentity = pathRep->getUniqueIdentity()) + { + return PathInfo::makeNormal(pathRep->getPath(), uniqueIdentity); + } + + // If we couldn't get a unique identity, just use the path + return PathInfo::makePath(pathRep->getPath()); + } + + // If there isn't a path, we can try with the name + const char* name = artifact->getName(); + if (name && name[0] != 0) + { + return PathInfo::makeFromString(name); + } + + return PathInfo::makeUnknown(); +} + +SlangResult TranslationUnitRequest::requireSourceFiles() +{ + SLANG_ASSERT(m_sourceFiles.getCount() <= m_sourceArtifacts.getCount()); + + if (m_sourceFiles.getCount() == m_sourceArtifacts.getCount()) + { + return SLANG_OK; + } + + auto sink = compileRequest->getSink(); + SourceManager* sourceManager = compileRequest->getSourceManager(); + + for (Index i = m_sourceFiles.getCount(); i < m_sourceArtifacts.getCount(); ++i) + { + IArtifact* artifact = m_sourceArtifacts[i]; + + const PathInfo pathInfo = _findSourcePathInfo(artifact); + + SourceFile* sourceFile = nullptr; + ComPtr<ISlangBlob> blob; + + // If we have a unique identity see if we have it already + if (pathInfo.hasUniqueIdentity()) + { + // See if this an already loaded source file + sourceFile = sourceManager->findSourceFileRecursively(pathInfo.uniqueIdentity); + // If we have a sourceFile see if it has a blob + if (sourceFile) + { + blob = sourceFile->getContentBlob(); + } + } + + // If we *don't* have a blob try and get a blob from the artifact + if (!blob) + { + const SlangResult res = artifact->loadBlob(ArtifactKeep::Yes, blob.writeRef()); + if (SLANG_FAILED(res)) + { + // Report couldn't load + sink->diagnose(SourceLoc(), Diagnostics::cannotOpenFile, pathInfo.getName()); + return res; + } + } + + // If we don't have a blob on the artifact we can now add the one we have + if (!findRepresentation<ISlangBlob>(artifact)) + { + artifact->addRepresentationUnknown(blob); + } + + // If we have a sourceFile check if it has contents, and set the blob if doesn't + if (sourceFile) + { + if (!sourceFile->getContentBlob()) + { + sourceFile->setContents(blob); + } + } + else + { + // Create a new source file, using the pathInfo and blob + sourceFile = sourceManager->createSourceFileWithBlob(pathInfo, blob); + } + + auto uniqueIdentity = pathInfo.getMostUniqueIdentity(); + if (uniqueIdentity.getLength()) + sourceManager->addSourceFileIfNotExist(uniqueIdentity, sourceFile); + + // Finally add the source file + _addSourceFile(sourceFile); + } + + return SLANG_OK; +} + +void TranslationUnitRequest::_addSourceFile(SourceFile* sourceFile) +{ + m_sourceFiles.add(sourceFile); + + getModule()->addFileDependency(sourceFile); + getModule()->getIncludedSourceFileMap().add(sourceFile, nullptr); +} + +List<SourceFile*> const& TranslationUnitRequest::getSourceFiles() +{ + return m_sourceFiles; +} + +} // namespace Slang |
