summaryrefslogtreecommitdiff
path: root/source/slang/lower-to-ir.cpp
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2019-01-22 14:57:25 -0800
committerGitHub <noreply@github.com>2019-01-22 14:57:25 -0800
commita08a3140716b89146bf0a22dc014c5470e90e910 (patch)
tree8033fe6e7bb47dce2a1bca3bb767e6ac7329afb9 /source/slang/lower-to-ir.cpp
parenta005007c2e9132788c92aa5a9c5fed2cb90f7841 (diff)
Clean up variable declaration class hierarchy (#787)
The AST class hierarchy for variable declarations had a few messy bits. First, there are more subclasses of `VarDeclBase` than seem strictly necessary; especially for stuff like `struct` member variable which use `StructField` even for `static` fields (which are effectively globals). Second, the AST node type for the "cases" within an `enum` was made a subclass of `VarDeclBase` for expediency, but this isn't really semantically accurate (and doesn't seem to be paying off much in deduplication of code). This change tries to address both of those problems. First, we replace the existing `Variable` and `StructField` cases with a single `VarDecl` case that covers globals, locals, and member variables. I haven't gone so far as to replace function parameters or generic value parameters, but that might be worth considering as a further clean-up. Second, we change `EnumCaseDecl` to inherit directly from `Decl` instead of `VarDeclBase` and add an explicit case for handling them where they were previously handled as if they were variable declarations (this was done by manually surveying all locations in the code that referenced `VarDeclBase`).
Diffstat (limited to 'source/slang/lower-to-ir.cpp')
-rw-r--r--source/slang/lower-to-ir.cpp71
1 files changed, 48 insertions, 23 deletions
diff --git a/source/slang/lower-to-ir.cpp b/source/slang/lower-to-ir.cpp
index 3e981dbc5..082f16b22 100644
--- a/source/slang/lower-to-ir.cpp
+++ b/source/slang/lower-to-ir.cpp
@@ -768,17 +768,17 @@ LoweredValInfo emitCallToDeclRef(
}
IRInst* getFieldKey(
- IRGenContext* context,
- DeclRef<StructField> field)
+ IRGenContext* context,
+ DeclRef<VarDecl> field)
{
return getSimpleVal(context, emitDeclRef(context, field, context->irBuilder->getKeyType()));
}
LoweredValInfo extractField(
- IRGenContext* context,
- IRType* fieldType,
- LoweredValInfo base,
- DeclRef<StructField> field)
+ IRGenContext* context,
+ IRType* fieldType,
+ LoweredValInfo base,
+ DeclRef<VarDecl> field)
{
IRBuilder* builder = context->irBuilder;
@@ -900,7 +900,7 @@ top:
auto base = materialize(context, boundMemberInfo->base);
auto declRef = boundMemberInfo->declRef;
- if( auto fieldDeclRef = declRef.As<StructField>() )
+ if( auto fieldDeclRef = declRef.As<VarDecl>() )
{
lowered = extractField(context, boundMemberInfo->type, base, fieldDeclRef);
goto top;
@@ -1871,7 +1871,7 @@ struct ExprLoweringVisitorBase : ExprVisitor<Derived, LoweredValInfo>
auto loweredBase = lowerRValueExpr(context, expr->BaseExpression);
auto declRef = expr->declRef;
- if (auto fieldDeclRef = declRef.As<StructField>())
+ if (auto fieldDeclRef = declRef.As<VarDecl>())
{
// Okay, easy enough: we have a reference to a field of a struct type...
return extractField(loweredType, loweredBase, fieldDeclRef);
@@ -2032,7 +2032,7 @@ struct ExprLoweringVisitorBase : ExprVisitor<Derived, LoweredValInfo>
if (auto aggTypeDeclRef = declRef.As<AggTypeDecl>())
{
List<IRInst*> args;
- for (auto ff : getMembersOfType<StructField>(aggTypeDeclRef))
+ for (auto ff : getMembersOfType<VarDecl>(aggTypeDeclRef))
{
if (ff.getDecl()->HasModifier<HLSLStaticModifier>())
continue;
@@ -2050,7 +2050,7 @@ struct ExprLoweringVisitorBase : ExprVisitor<Derived, LoweredValInfo>
UNREACHABLE_RETURN(LoweredValInfo());
}
- LoweredValInfo getDefaultVal(StructField* decl)
+ LoweredValInfo getDefaultVal(VarDeclBase* decl)
{
if(auto initExpr = decl->initExpr)
{
@@ -2156,7 +2156,7 @@ struct ExprLoweringVisitorBase : ExprVisitor<Derived, LoweredValInfo>
if (auto aggTypeDeclRef = declRef.As<AggTypeDecl>())
{
UInt argCounter = 0;
- for (auto ff : getMembersOfType<StructField>(aggTypeDeclRef))
+ for (auto ff : getMembersOfType<VarDecl>(aggTypeDeclRef))
{
if (ff.getDecl()->HasModifier<HLSLStaticModifier>())
continue;
@@ -2596,9 +2596,9 @@ struct ExprLoweringVisitorBase : ExprVisitor<Derived, LoweredValInfo>
}
LoweredValInfo extractField(
- IRType* fieldType,
- LoweredValInfo base,
- DeclRef<StructField> field)
+ IRType* fieldType,
+ LoweredValInfo base,
+ DeclRef<VarDecl> field)
{
return Slang::extractField(context, fieldType, base, field);
}
@@ -3713,7 +3713,7 @@ LoweredValInfo tryGetAddress(
// we care about, and then write it back.
auto declRef = boundMemberInfo->declRef;
- if( auto fieldDeclRef = declRef.As<StructField>() )
+ if( auto fieldDeclRef = declRef.As<VarDecl>() )
{
auto baseVal = boundMemberInfo->base;
auto basePtr = tryGetAddress(context, baseVal, TryGetAddressMode::Aggressive);
@@ -3955,7 +3955,7 @@ top:
// we care about, and then write it back.
auto declRef = boundMemberInfo->declRef;
- if( auto fieldDeclRef = declRef.As<StructField>() )
+ if( auto fieldDeclRef = declRef.As<VarDecl>() )
{
// materialize the base value and move it into
// a mutable temporary if needed
@@ -4321,7 +4321,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
return LoweredValInfo();
}
- bool isGlobalVarDecl(VarDeclBase* decl)
+ bool isGlobalVarDecl(VarDecl* decl)
{
auto parent = decl->ParentDecl;
if (dynamic_cast<ModuleDecl*>(parent))
@@ -4329,11 +4329,31 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
// Variable declared at global scope? -> Global.
return true;
}
+ else if(dynamic_cast<AggTypeDeclBase*>(parent))
+ {
+ if(decl->HasModifier<HLSLStaticModifier>())
+ {
+ // A `static` member variable is effectively global.
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ bool isMemberVarDecl(VarDecl* decl)
+ {
+ auto parent = decl->ParentDecl;
+ if (dynamic_cast<AggTypeDecl*>(parent))
+ {
+ // A variable declared inside of an aggregate type declaration is a member.
+ return true;
+ }
return false;
}
- LoweredValInfo lowerGlobalShaderParam(VarDeclBase* decl)
+ LoweredValInfo lowerGlobalShaderParam(VarDecl* decl)
{
IRType* paramType = lowerType(context, decl->getType());
@@ -4361,7 +4381,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
return paramVal;
}
- LoweredValInfo lowerGlobalVarDecl(VarDeclBase* decl)
+ LoweredValInfo lowerGlobalVarDecl(VarDecl* decl)
{
if(isGlobalShaderParameter(decl))
{
@@ -4716,7 +4736,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
lowerType(context, decl->type));
}
- LoweredValInfo visitVarDeclBase(VarDeclBase* decl)
+ LoweredValInfo visitVarDecl(VarDecl* decl)
{
// Detect global (or effectively global) variables
// and handle them differently.
@@ -4730,6 +4750,11 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
return lowerFunctionStaticVarDecl(decl);
}
+ if(isMemberVarDecl(decl))
+ {
+ return lowerMemberVarDecl(decl);
+ }
+
// A user-defined variable declaration will usually turn into
// an `alloca` operation for the variable's storage,
// plus some code to initialize it and then store to the variable.
@@ -4838,7 +4863,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
// Emit any generics that should wrap the actual type.
emitOuterGenerics(subContext, decl, decl);
- return lowerRValueExpr(subContext, decl->initExpr);
+ return lowerRValueExpr(subContext, decl->tagExpr);
}
LoweredValInfo visitEnumDecl(EnumDecl* decl)
@@ -4902,7 +4927,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
subBuilder->setInsertInto(irStruct);
- for (auto fieldDecl : decl->getMembersOfType<StructField>())
+ for (auto fieldDecl : decl->getMembersOfType<VarDeclBase>())
{
if (fieldDecl->HasModifier<HLSLStaticModifier>())
{
@@ -4946,7 +4971,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
return LoweredValInfo::simple(finishOuterGenerics(subBuilder, irStruct));
}
- LoweredValInfo visitStructField(StructField* fieldDecl)
+ LoweredValInfo lowerMemberVarDecl(VarDecl* fieldDecl)
{
// Each field declaration in the AST translates into
// a "key" that can be used to extract field values