From a08a3140716b89146bf0a22dc014c5470e90e910 Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Tue, 22 Jan 2019 14:57:25 -0800 Subject: 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`). --- source/slang/check.cpp | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) (limited to 'source/slang/check.cpp') diff --git a/source/slang/check.cpp b/source/slang/check.cpp index 9aa5eb689..82936b65d 100644 --- a/source/slang/check.cpp +++ b/source/slang/check.cpp @@ -593,7 +593,7 @@ namespace Slang auto interfaceDecl = interfaceDeclRef.getDecl(); - RefPtr varDecl = new Variable(); + RefPtr varDecl = new VarDecl(); varDecl->ParentDecl = nullptr; // TODO: need to fill this in somehow! varDecl->checkState = DeclCheckState::Checked; varDecl->nameAndLoc.loc = expr->loc; @@ -1039,7 +1039,8 @@ namespace Slang // the scope that was in place *before* the variable was declared, but // this is a quick fix that at least alerts the user to how we are // interpreting their code. - if (auto varDecl = decl.As()) + // + if (auto varDecl = decl.As()) { if (auto parenScope = varDecl->ParentDecl->As()) { @@ -1678,7 +1679,7 @@ namespace Slang // We will go through the fields in order and try to match them // up with initializer arguments. // - for(auto fieldDeclRef : getMembersOfType(toStructDeclRef)) + for(auto fieldDeclRef : getMembersOfType(toStructDeclRef)) { RefPtr coercedArg; bool argResult = tryReadArgFromInitializerList( @@ -2806,11 +2807,6 @@ namespace Slang } } - void visitStructField(StructField* field) - { - CheckVarDeclCommon(field); - } - bool doesSignatureMatchRequirement( DeclRef satisfyingMemberDeclRef, DeclRef requiredMemberDeclRef, @@ -3649,7 +3645,7 @@ namespace Slang IntegerLiteralValue defaultTag = 0; for(auto caseDecl : decl->getMembersOfType()) { - if(auto explicitTagValExpr = caseDecl->initExpr) + if(auto explicitTagValExpr = caseDecl->tagExpr) { // This tag has an initializer, so it should establish // the tag value for a successor case that doesn't @@ -3684,7 +3680,7 @@ namespace Slang tagValExpr->type = QualType(tagType); tagValExpr->value = defaultTag; - caseDecl->initExpr = tagValExpr; + caseDecl->tagExpr = tagValExpr; } // Default tag for the next case will be one more than @@ -3737,7 +3733,7 @@ namespace Slang // Need to check the init expression, if present, since // that represents the explicit tag for this case. - if(auto initExpr = decl->initExpr) + if(auto initExpr = decl->tagExpr) { initExpr = CheckExpr(initExpr); initExpr = Coerce(tagType, initExpr); @@ -3747,7 +3743,7 @@ namespace Slang // the value. CheckIntegerConstantExpression(initExpr); - decl->initExpr = initExpr; + decl->tagExpr = initExpr; } } @@ -4620,7 +4616,7 @@ namespace Slang } } - void visitVariable(Variable* varDecl) + void visitVarDecl(VarDecl* varDecl) { CheckVarDeclCommon(varDecl); } @@ -4895,6 +4891,14 @@ namespace Slang } } + else if(auto enumRef = declRef.As()) + { + // The cases in an `enum` declaration can also be used as constant expressions, + if(auto tagExpr = getTagExpr(enumRef)) + { + return TryConstantFoldExpr(tagExpr.Ptr()); + } + } } if(auto castExpr = dynamic_cast(expr)) @@ -9534,6 +9538,13 @@ namespace Slang qualType.IsLeftValue = isLValue; return qualType; } + else if( auto enumCaseDeclRef = declRef.As() ) + { + QualType qualType; + qualType.type = getType(enumCaseDeclRef); + qualType.IsLeftValue = false; + return qualType; + } else if (auto typeAliasDeclRef = declRef.As()) { auto type = getNamedType(session, typeAliasDeclRef); -- cgit v1.2.3