https://github.com/shader-slang/slang
Tip revision: 911a4401b08f6199e18b32349c236c186a2dd128 authored by Yong He on 02 November 2023, 21:54:22 UTC
Fix crash when writing to `no_diff` out parameter. (#3308)
Fix crash when writing to `no_diff` out parameter. (#3308)
Tip revision: 911a440
slang-ast-synthesis.h
// slang-ast-synthesis.h
#pragma once
#include "slang-syntax.h"
namespace Slang {
struct ASTEmitScope
{
ContainerDecl* m_parent = nullptr;
SeqStmt* m_parentSeqStmt = nullptr;
Scope* m_scope = nullptr;
};
class ASTSynthesizer
{
private:
ASTBuilder* m_builder;
NamePool* m_namePool;
List<ASTEmitScope> m_scopeStack;
public:
ASTSynthesizer(ASTBuilder* builder, NamePool* namePool)
: m_builder(builder)
, m_namePool(namePool)
{
}
ASTBuilder* getBuilder() { return m_builder; }
Scope* getScope(ContainerDecl* decl)
{
for (auto container = decl; container; container = container->parentDecl)
{
if (container->ownedScope)
{
return container->ownedScope;
}
}
return nullptr;
}
// Create a scope for `decl` and push it to scope stack
void pushScopeForContainer(ContainerDecl* decl)
{
if (decl->ownedScope)
{
// if decl already owns a scope, don't create a new one.
pushContainerScope(decl);
return;
}
auto parentScope = getScope(decl);
decl->ownedScope = m_builder->create<Scope>();
decl->ownedScope->parent = parentScope;
pushContainerScope(decl);
}
// Push `decl` and its associated scope to scope stack
void pushContainerScope(ContainerDecl* decl)
{
ASTEmitScope scope = getCurrentScope();
scope.m_parent = decl;
scope.m_scope = getScope(decl);
m_scopeStack.add(scope);
}
Scope* pushVarScope()
{
ASTEmitScope scope = getCurrentScope();
auto scopeDecl = m_builder->create<ScopeDecl>();
auto newScope = m_builder->create<Scope>();
scopeDecl->parentDecl = scope.m_parent;
if (scope.m_parent)
scope.m_parent->members.add(scopeDecl);
newScope->parent = scope.m_scope;
newScope->containerDecl = scopeDecl;
scope.m_scope = newScope;
m_scopeStack.add(scope);
return newScope;
}
void _addStmtToScope(Stmt* stmt)
{
auto scope = getCurrentScope();
if (scope.m_parentSeqStmt)
{
scope.m_parentSeqStmt->stmts.add(stmt);
}
}
SeqStmt* pushSeqStmtScope()
{
ASTEmitScope scope = getCurrentScope();
scope.m_parentSeqStmt = m_builder->create<SeqStmt>();
m_scopeStack.add(scope);
return scope.m_parentSeqStmt;
}
void popScope()
{
m_scopeStack.removeLast();
}
ASTEmitScope getCurrentScope()
{
if (m_scopeStack.getCount())
return m_scopeStack.getLast();
return ASTEmitScope();
}
ForStmt* emitFor(Expr* initVal, Expr* finalVal, VarDecl*& outIndexVar);
Expr* emitBinaryExpr(UnownedStringSlice operatorToken, Expr* left, Expr* right);
Expr* emitPrefixExpr(UnownedStringSlice operatorToken, Expr* base);
Expr* emitPostfixExpr(UnownedStringSlice operatorToken, Expr* base);
Expr* emitVarExpr(Name* name);
Expr* emitVarExpr(VarDecl* var);
Expr* emitVarExpr(VarDecl* var, Type* type);
Expr* emitVarExpr(DeclStmt* varStmt, Type* type);
Expr* emitIntConst(int value);
Expr* emitGetArrayLengthExpr(Expr* arrayExpr);
Expr* emitMemberExpr(Expr* base, Name* name);
Expr* emitMemberExpr(Type* base, Name* name);
Expr* emitIndexExpr(Expr* base, Expr* index);
Expr* emitAssignExpr(Expr* left, Expr* right);
ExpressionStmt* emitAssignStmt(Expr* left, Expr* right)
{
return emitExprStmt(emitAssignExpr(left, right));
}
Expr* emitInvokeExpr(Expr* callee, List<Expr*>&& args);
Expr* emitGenericAppExpr(Expr* genericExpr, List<Expr*>&& args);
DeclStmt* emitVarDeclStmt(Type* type, Name* name = nullptr, Expr* initVal = nullptr);
ExpressionStmt* emitExprStmt(Expr* expr);
ReturnStmt* emitReturnStmt(Expr* expr);
};
} // namespace Slang