[spirv] Support function foward declaration (#847)

This commit is contained in:
Lei Zhang 2017-11-24 15:52:47 -05:00 коммит произвёл GitHub
Родитель fa0674829b
Коммит 04a5269451
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 40 добавлений и 2 удалений

Просмотреть файл

@ -445,8 +445,8 @@ void SPIRVEmitter::doStmt(const Stmt *stmt,
SpirvEvalInfo SPIRVEmitter::doExpr(const Expr *expr) {
expr = expr->IgnoreParens();
if (const auto *delRefExpr = dyn_cast<DeclRefExpr>(expr)) {
return declIdMapper.getDeclResultId(delRefExpr->getFoundDecl());
if (const auto *declRefExpr = dyn_cast<DeclRefExpr>(expr)) {
return declIdMapper.getDeclResultId(declRefExpr->getDecl());
}
if (const auto *memberExpr = dyn_cast<MemberExpr>(expr)) {
@ -557,6 +557,8 @@ uint32_t SPIRVEmitter::castToType(uint32_t value, QualType fromType,
}
void SPIRVEmitter::doFunctionDecl(const FunctionDecl *decl) {
assert(decl->isThisDeclarationADefinition());
// A RAII class for maintaining the current function under traversal.
class FnEnvRAII {
public:
@ -1391,6 +1393,20 @@ SpirvEvalInfo SPIRVEmitter::doCallExpr(const CallExpr *callExpr) {
SpirvEvalInfo SPIRVEmitter::processCall(const CallExpr *callExpr) {
const FunctionDecl *callee = callExpr->getDirectCallee();
// If we are calling a forward-declared function, callee will be the
// FunctionDecl for the foward-declared function, not the actual
// definition. The foward-delcaration and defintion are two completely
// different AST nodes.
// Note that we always want the defintion because Stmts/Exprs in the
// function body references the parameters in the definition.
if (!callee->isThisDeclarationADefinition()) {
// We need to update callee to the actual definition here
if (!callee->isDefined(callee)) {
emitError("found undefined function", callExpr->getExprLoc());
return 0;
}
}
if (callee) {
const auto numParams = callee->getNumParams();
bool isNonStaticMemberCall = false;

Просмотреть файл

@ -0,0 +1,19 @@
// Run: %dxc -T ps_6_0 -E main
float4 foo(float4 input);
float4 main(float4 input: A) : SV_Target0
{
return foo(input);
}
float4 foo(float4 input)
{
return input;
}
// CHECK: %src_main = OpFunction %v4float None {{%\d+}}
// CHECK: OpFunctionCall %v4float %foo
// CHECK: %foo = OpFunction %v4float None {{%\d+}}

Просмотреть файл

@ -367,6 +367,9 @@ TEST_F(FileTest, ControlFlowConditionalOp) { runFileTest("cf.cond-op.hlsl"); }
TEST_F(FileTest, FunctionCall) { runFileTest("fn.call.hlsl"); }
TEST_F(FileTest, FunctionDefaultArg) { runFileTest("fn.default-arg.hlsl"); }
TEST_F(FileTest, FunctionInOutParam) { runFileTest("fn.param.inout.hlsl"); }
TEST_F(FileTest, FunctionFowardDeclaration) {
runFileTest("fn.foward-declaration.hlsl");
}
// For OO features
TEST_F(FileTest, StructMethodCall) { runFileTest("oo.struct.method.hlsl"); }