Skip to content

Commit f52f5cd

Browse files
authored
WIP: slang to C++ code generation (shader-slang#997)
* WIP: Emitting Cpp * Added HLSLType instead of using IRInst - because they don't seem to be deduped. * Removed need for lexer to take a String. Added mechansim to lookup intrinsic functions on C++. * A c/c++ cross compilation test. * WIP Cpp output using cloning and slang types. * More work to generate mul funcs. * WIP: Outputting some simple C++. * Expose findOrEmitHoistableInst to IRBuilder to aid cloning, * Simplification for checking for BasicTypes. Test infrastructure compiles output C++ code. * Dot and mat/vec multiplication output. * First pass at swizzling. * First support for binary ops. * Builtin binary and unary functions. * Any and all. * WIP adding support for other functions. Added code to generate function signature. * Add scalar functions to slang-cpp-prelude.h * Support for most built in operations. * Tested first ternary. * Checking the emitting of corner cases functions - normalize, length, any, all, normalize, reflect. * Check asfloat etc work. * Fmod support. * WIP Array handling in C++. * First stage in being able to handl arbitrary type output for CLikeSourceEmitter * Removed Handler/Emitter split - so can implement more easily complex type naming. * Array passing by value first pass. * Rename Array -> FixedArray * Outputs structs in C++. * Emit the thread config. * Dimension -> TypeDimension * SpecializedOperation -> SpecializedIntrinsic Operation -> IntrinsicOp Use shared impl of isNominalOp Commented use of m_uniqueModule etc. * Add code to test slang->cpp when compiled doesn't have errors. Does so by building shared library and exporting the entry point. * Fix linux clang/gcc compile error about override not being specified. * Make sure c-cross-compile is run on linux targets/smoke. * Remove c-cross-compile.slang from smoke. * Fix running tests/cross-compile/c-cross-compile.slang on Ubuntu 16.04 * Only add -std=c++11 for C++ source.
1 parent 691ebae commit f52f5cd

16 files changed

+2200
-188
lines changed

source/core/slang-gcc-compiler-util.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,12 @@ static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParse
338338
/* static */void GCCCompilerUtil::calcArgs(const CompileOptions& options, CommandLine& cmdLine)
339339
{
340340
cmdLine.addArg("-fvisibility=hidden");
341+
342+
if (options.sourceType == SourceType::CPP)
343+
{
344+
cmdLine.addArg("-std=c++11");
345+
}
346+
341347
// Use shared libraries
342348
//cmdLine.addArg("-shared");
343349

@@ -454,6 +460,8 @@ static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParse
454460
{
455461
// Make STD libs available
456462
cmdLine.addArg("-lstdc++");
463+
// Make maths lib available
464+
cmdLine.addArg("-lm");
457465
}
458466
}
459467

source/slang/slang-emit-c-like.cpp

+48-44
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,16 @@ struct CLikeSourceEmitter::EDeclarator
3434
{
3535
enum class Flavor
3636
{
37-
name,
37+
Name,
3838
Array,
3939
UnsizedArray,
4040
};
4141
Flavor flavor;
4242
EDeclarator* next = nullptr;
4343

4444
// Used for `Flavor::name`
45-
Name* name;
46-
SourceLoc loc;
47-
45+
const StringSliceLoc* nameAndLoc;
46+
4847
// Used for `Flavor::Array`
4948
IRInst* elementCount;
5049
};
@@ -149,8 +148,8 @@ void CLikeSourceEmitter::emitDeclarator(EDeclarator* declarator)
149148

150149
switch (declarator->flavor)
151150
{
152-
case EDeclarator::Flavor::name:
153-
m_writer->emitName(declarator->name, declarator->loc);
151+
case EDeclarator::Flavor::Name:
152+
m_writer->emitName(*declarator->nameAndLoc);
154153
break;
155154

156155
case EDeclarator::Flavor::Array:
@@ -250,40 +249,57 @@ void CLikeSourceEmitter::_emitType(IRType* type, EDeclarator* declarator)
250249

251250
}
252251

253-
void CLikeSourceEmitter::emitType(
254-
IRType* type,
255-
SourceLoc const& typeLoc,
256-
Name* name,
257-
SourceLoc const& nameLoc)
252+
void CLikeSourceEmitter::emitTypeImpl(IRType* type, const StringSliceLoc* nameAndLoc)
258253
{
259-
m_writer->advanceToSourceLocation(typeLoc);
254+
if (nameAndLoc)
255+
{
256+
// TODO(JS): No call to the previous version of this method was passing in a typeLoc, so disabled for
257+
// now for simplicity
258+
//m_writer->advanceToSourceLocation(typeLoc);
260259

261-
EDeclarator nameDeclarator;
262-
nameDeclarator.flavor = EDeclarator::Flavor::name;
263-
nameDeclarator.name = name;
264-
nameDeclarator.loc = nameLoc;
265-
_emitType(type, &nameDeclarator);
260+
EDeclarator nameDeclarator;
261+
nameDeclarator.flavor = EDeclarator::Flavor::Name;
262+
nameDeclarator.nameAndLoc = nameAndLoc;
263+
_emitType(type, &nameDeclarator);
264+
}
265+
else
266+
{
267+
_emitType(type, nullptr);
268+
}
266269
}
267270

268271
void CLikeSourceEmitter::emitType(IRType* type, Name* name)
269272
{
270-
emitType(type, SourceLoc(), name, SourceLoc());
273+
SLANG_ASSERT(name);
274+
StringSliceLoc nameAndLoc(name->text.getUnownedSlice());
275+
emitType(type, &nameAndLoc);
271276
}
272277

273278
void CLikeSourceEmitter::emitType(IRType* type, const String& name)
274279
{
275-
// HACK: the rest of the code wants a `Name`,
276-
// so we'll create one for a bit...
277-
Name tempName;
278-
tempName.text = name;
280+
StringSliceLoc nameAndLoc(name.getUnownedSlice());
281+
emitType(type, &nameAndLoc);
282+
}
279283

280-
emitType(type, SourceLoc(), &tempName, SourceLoc());
284+
void CLikeSourceEmitter::emitType(IRType* type)
285+
{
286+
emitType(type, (StringSliceLoc*)nullptr);
281287
}
282288

289+
void CLikeSourceEmitter::emitType(IRType* type, Name* name, SourceLoc const& nameLoc)
290+
{
291+
SLANG_ASSERT(name);
283292

284-
void CLikeSourceEmitter::emitType(IRType* type)
293+
StringSliceLoc nameAndLoc;
294+
nameAndLoc.loc = nameLoc;
295+
nameAndLoc.name = name->text.getUnownedSlice();
296+
297+
emitType(type, &nameAndLoc);
298+
}
299+
300+
void CLikeSourceEmitter::emitType(IRType* type, NameLoc const& nameAndLoc)
285301
{
286-
_emitType(type, nullptr);
302+
emitType(type, nameAndLoc.name, nameAndLoc.loc);
287303
}
288304

289305
//
@@ -324,20 +340,6 @@ bool CLikeSourceEmitter::isTargetIntrinsicModifierApplicable(const String& targe
324340
}
325341
}
326342

327-
void CLikeSourceEmitter::emitType(IRType* type, Name* name, SourceLoc const& nameLoc)
328-
{
329-
emitType(
330-
type,
331-
SourceLoc(),
332-
name,
333-
nameLoc);
334-
}
335-
336-
void CLikeSourceEmitter::emitType(IRType* type, NameLoc const& nameAndLoc)
337-
{
338-
emitType(type, nameAndLoc.name, nameAndLoc.loc);
339-
}
340-
341343
bool CLikeSourceEmitter::isTargetIntrinsicModifierApplicable(IRTargetIntrinsicDecoration* decoration)
342344
{
343345
auto targetName = String(decoration->getTargetName());
@@ -1533,12 +1535,10 @@ void CLikeSourceEmitter::emitIntrinsicCallExpr(
15331535
//
15341536
auto linkageDecoration = valueForName->findDecoration<IRLinkageDecoration>();
15351537
SLANG_ASSERT(linkageDecoration);
1536-
auto mangledName = String(linkageDecoration->getMangledName());
1537-
1538-
1538+
15391539
// We will use the `MangledLexer` to
15401540
// help us split the original name into its pieces.
1541-
MangledLexer lexer(mangledName);
1541+
MangledLexer lexer(linkageDecoration->getMangledName());
15421542

15431543
// We'll read through the qualified name of the
15441544
// symbol (e.g., `Texture2D<T>.Sample`) and then
@@ -1655,15 +1655,19 @@ void CLikeSourceEmitter::emitCallExpr(IRCall* inst, IREmitMode mode, EmitOpInfo
16551655
maybeCloseParens(needClose);
16561656
}
16571657
}
1658-
1658+
16591659
void CLikeSourceEmitter::emitInstExpr(IRInst* inst, IREmitMode mode, const EmitOpInfo& inOuterPrec)
16601660
{
16611661
// Try target specific impl first
16621662
if (tryEmitInstExprImpl(inst, mode, inOuterPrec))
16631663
{
16641664
return;
16651665
}
1666+
defaultEmitInstExpr(inst, mode, inOuterPrec);
1667+
}
16661668

1669+
void CLikeSourceEmitter::defaultEmitInstExpr(IRInst* inst, IREmitMode mode, const EmitOpInfo& inOuterPrec)
1670+
{
16671671
EmitOpInfo outerPrec = inOuterPrec;
16681672
bool needClose = false;
16691673
switch(inst->op)

source/slang/slang-emit-c-like.h

+4-10
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,7 @@ class CLikeSourceEmitter: public RefObject
133133

134134
void emitDeclarator(EDeclarator* declarator);
135135

136-
//void emitVectorTypeName(IRType* elementType, IRIntegerValue elementCount);
137-
//void emitTextureType(IRTextureType* texType);
138-
//void emitTextureSamplerType(IRTextureSamplerType* type);
139-
//void emitImageType(IRGLSLImageType* type);
140-
//void emitSamplerStateType(IRSamplerStateTypeBase* samplerStateType);
141-
//void emitStructuredBufferType(IRHLSLStructuredBufferTypeBase* type);
142-
//void emitUntypedBufferType(IRUntypedBufferResourceType* type);
143-
144-
void emitType(IRType* type, const SourceLoc& typeLoc, Name* name, const SourceLoc& nameLoc);
136+
void emitType(IRType* type, const StringSliceLoc* nameLoc) { emitTypeImpl(type, nameLoc); }
145137
void emitType(IRType* type, Name* name);
146138
void emitType(IRType* type, String const& name);
147139
void emitType(IRType* type);
@@ -226,7 +218,8 @@ class CLikeSourceEmitter: public RefObject
226218
void emitCallExpr(IRCall* inst, IREmitMode mode, EmitOpInfo outerPrec);
227219

228220
void emitInstExpr(IRInst* inst, IREmitMode mode, EmitOpInfo const& inOuterPrec);
229-
221+
void defaultEmitInstExpr(IRInst* inst, IREmitMode mode, EmitOpInfo const& inOuterPrec);
222+
230223
BaseType extractBaseType(IRType* inType);
231224

232225
void emitInst(IRInst* inst, IREmitMode mode);
@@ -353,6 +346,7 @@ class CLikeSourceEmitter: public RefObject
353346
virtual void emitSimpleTypeImpl(IRType* type) = 0;
354347
virtual void emitVarDecorationsImpl(IRInst* varDecl) { SLANG_UNUSED(varDecl); }
355348
virtual void emitMatrixLayoutModifiersImpl(VarLayout* layout) { SLANG_UNUSED(layout); }
349+
virtual void emitTypeImpl(IRType* type, const StringSliceLoc* nameLoc);
356350

357351
// Only needed for glsl output with $ prefix intrinsics - so perhaps removable in the future
358352
virtual void emitTextureOrTextureSamplerTypeImpl(IRTextureTypeBase* type, char const* baseName) { SLANG_UNUSED(type); SLANG_UNUSED(baseName); }

0 commit comments

Comments
 (0)