summaryrefslogtreecommitdiff
path: root/source/slang/slang-translation-unit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/slang-translation-unit.cpp')
-rw-r--r--source/slang/slang-translation-unit.cpp251
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