1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
|
// slang-check.cpp
#include "slang-check.h"
// This file provides general facilities related to semantic
// checking that don't cleanly land in one of the more
// specialized `slang-check-*` files.
#include "slang-check-impl.h"
namespace Slang
{
namespace { // anonymous
struct FunctionInfo
{
const char* name;
SharedLibraryType libraryType;
};
} // anonymous
static FunctionInfo _getFunctionInfo(Session::SharedLibraryFuncType funcType)
{
typedef Session::SharedLibraryFuncType FuncType;
typedef SharedLibraryType LibType;
switch (funcType)
{
case FuncType::Glslang_Compile: return { "glslang_compile", LibType::Glslang } ;
case FuncType::Fxc_D3DCompile: return { "D3DCompile", LibType::Fxc };
case FuncType::Fxc_D3DDisassemble: return { "D3DDisassemble", LibType::Fxc };
case FuncType::Dxc_DxcCreateInstance: return { "DxcCreateInstance", LibType::Dxc };
default: return { nullptr, LibType::Unknown };
}
}
static PassThroughMode _toPassThroughMode(SharedLibraryType type)
{
switch (type)
{
case SharedLibraryType::Dxil:
case SharedLibraryType::Dxc:
{
return PassThroughMode::Dxc;
}
case SharedLibraryType::Fxc: return PassThroughMode::Fxc;
case SharedLibraryType::Glslang: return PassThroughMode::Glslang;
default: break;
}
return PassThroughMode::None;
}
void Session::setSharedLibrary(SharedLibraryType type, ISlangSharedLibrary* library)
{
sharedLibraries[int(type)] = library;
}
ISlangSharedLibrary* Session::getOrLoadSharedLibrary(SharedLibraryType type, DiagnosticSink* sink)
{
// If not loaded, try loading it
if (!sharedLibraries[int(type)])
{
// Try to preload dxil first, if loading dxc
if (type == SharedLibraryType::Dxc)
{
// Pass nullptr as the sink, because if it fails we don't want to report as error
getOrLoadSharedLibrary(SharedLibraryType::Dxil, nullptr);
}
const char* libName = DefaultSharedLibraryLoader::getSharedLibraryNameFromType(type);
StringBuilder builder;
PassThroughMode passThrough = _toPassThroughMode(type);
if (passThrough != PassThroughMode::None && m_downstreamCompilerPaths[int(passThrough)].getLength() > 0)
{
Path::combineIntoBuilder(m_downstreamCompilerPaths[int(passThrough)].getUnownedSlice(), UnownedStringSlice(libName), builder);
libName = builder.getBuffer();
}
if (SLANG_FAILED(sharedLibraryLoader->loadSharedLibrary(libName, sharedLibraries[int(type)].writeRef())))
{
if (sink)
{
sink->diagnose(SourceLoc(), Diagnostics::failedToLoadDynamicLibrary, libName);
}
return nullptr;
}
}
return sharedLibraries[int(type)];
}
SlangFuncPtr Session::getSharedLibraryFunc(SharedLibraryFuncType type, DiagnosticSink* sink)
{
if (sharedLibraryFunctions[int(type)])
{
return sharedLibraryFunctions[int(type)];
}
// do we have the library
FunctionInfo info = _getFunctionInfo(type);
if (info.name == nullptr)
{
return nullptr;
}
// Try loading the library
ISlangSharedLibrary* sharedLib = getOrLoadSharedLibrary(info.libraryType, sink);
if (!sharedLib)
{
return nullptr;
}
// Okay now access the func
SlangFuncPtr func = sharedLib->findFuncByName(info.name);
if (!func)
{
const char* libName = DefaultSharedLibraryLoader::getSharedLibraryNameFromType(info.libraryType);
sink->diagnose(SourceLoc(), Diagnostics::failedToFindFunctionInSharedLibrary, info.name, libName);
return nullptr;
}
// Store in the function cache
sharedLibraryFunctions[int(type)] = func;
return func;
}
CPPCompilerSet* Session::requireCPPCompilerSet()
{
if (cppCompilerSet == nullptr)
{
cppCompilerSet = new CPPCompilerSet;
typedef CPPCompiler::CompilerType CompilerType;
CPPCompilerUtil::InitializeSetDesc desc;
desc.paths[int(CompilerType::GCC)] = m_downstreamCompilerPaths[int(PassThroughMode::Gcc)];
desc.paths[int(CompilerType::Clang)] = m_downstreamCompilerPaths[int(PassThroughMode::Clang)];
desc.paths[int(CompilerType::VisualStudio)] = m_downstreamCompilerPaths[int(PassThroughMode::VisualStudio)];
CPPCompilerUtil::initializeSet(desc, cppCompilerSet);
}
SLANG_ASSERT(cppCompilerSet);
return cppCompilerSet;
}
TypeCheckingCache* Session::getTypeCheckingCache()
{
if (!typeCheckingCache)
typeCheckingCache = new TypeCheckingCache();
return typeCheckingCache;
}
void Session::destroyTypeCheckingCache()
{
delete typeCheckingCache;
typeCheckingCache = nullptr;
}
void checkTranslationUnit(
TranslationUnitRequest* translationUnit)
{
SemanticsVisitor visitor(
translationUnit->compileRequest->getLinkage(),
translationUnit->compileRequest->getSink());
// Apply the visitor to do the main semantic
// checking that is required on all declarations
// in the translation unit.
visitor.checkDecl(translationUnit->getModuleDecl());
translationUnit->getModule()->_collectShaderParams();
}
void SemanticsVisitor::dispatchDecl(DeclBase* decl)
{
try
{
DeclVisitor::dispatch(decl);
}
// Don't emit any context message for an explicit `AbortCompilationException`
// because it should only happen when an error is already emitted.
catch(AbortCompilationException&) { throw; }
catch(...)
{
getSink()->noteInternalErrorLoc(decl->loc);
throw;
}
}
void SemanticsVisitor::dispatchStmt(Stmt* stmt)
{
try
{
StmtVisitor::dispatch(stmt);
}
catch(AbortCompilationException&) { throw; }
catch(...)
{
getSink()->noteInternalErrorLoc(stmt->loc);
throw;
}
}
void SemanticsVisitor::dispatchExpr(Expr* expr)
{
try
{
ExprVisitor::dispatch(expr);
}
catch(AbortCompilationException&) { throw; }
catch(...)
{
getSink()->noteInternalErrorLoc(expr->loc);
throw;
}
}
}
|