From 69450a2be7575aa4f984b9ae2824da0e5634c9f0 Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Wed, 5 Jul 2023 13:23:14 -0400 Subject: Initial sizeof/alignof implementation. (#2954) * Initial sizeof implementation. * Small macro improvement. * Fix some typos. * Refactor NaturalSize. Add more sizeof tests. * Use _makeParseExpr to add sizeof support. * Add size-of.slang diagnostic result. * Fix typo in folding with macro change. * Add a sizeof test of This. * Some more NaturalSize coverage. * Simple alignof support. * Testing for alignof. * Added 8 bit enum to check enums values are correctly sized. * Add alignof to completion. * Lower sizeof/alignof to IR. sizeof/alignof IR pass. Tests for simple generic scenarios. * Make append handle invalid properly. Improve comments. --------- Co-authored-by: Theresa Foley <10618364+tangent-vector@users.noreply.github.com> --- source/slang/slang-ast-val.cpp | 105 ++++++++++++++++++++++------------------- 1 file changed, 57 insertions(+), 48 deletions(-) (limited to 'source/slang/slang-ast-val.cpp') diff --git a/source/slang/slang-ast-val.cpp b/source/slang/slang-ast-val.cpp index d8886f05b..21f876048 100644 --- a/source/slang/slang-ast-val.cpp +++ b/source/slang/slang-ast-val.cpp @@ -1400,13 +1400,6 @@ HashCode FuncCallIntVal::_getHashCodeOverride() return result; } -static bool nameIs(Name* name, const char* val) -{ - if (name && name->text.getUnownedSlice() == val) - return true; - return false; -} - Val* FuncCallIntVal::tryFoldImpl(ASTBuilder* astBuilder, Type* resultType, DeclRef newFuncDecl, List& newArgs, DiagnosticSink* sink) { // Are all args const now? @@ -1428,29 +1421,24 @@ Val* FuncCallIntVal::tryFoldImpl(ASTBuilder* astBuilder, Type* resultType, DeclR { // Evaluate the function. auto opName = newFuncDecl.getName(); + SLANG_ASSERT(opName); + + const auto opNameSlice = opName->text.getUnownedSlice(); + IntegerLiteralValue resultValue = 0; - if (nameIs(opName, "==")) - { - resultValue = constArgs[0]->value / constArgs[1]->value; - } + + // Define convenience macros. + // The last macro used in the list *must* be + // TERMINATING_CASE, as this handles the closing else, and matches if nothing else does. + #define BINARY_OPERATOR_CASE(op) \ - else if (nameIs(opName, #op)) \ + if (opNameSlice == toSlice(#op)) \ { \ resultValue = constArgs[0]->value op constArgs[1]->value; \ - } - BINARY_OPERATOR_CASE(>=) - BINARY_OPERATOR_CASE(<=) - BINARY_OPERATOR_CASE(>) - BINARY_OPERATOR_CASE(<) - BINARY_OPERATOR_CASE(!=) - BINARY_OPERATOR_CASE(<<) - BINARY_OPERATOR_CASE(>>) - BINARY_OPERATOR_CASE(&) - BINARY_OPERATOR_CASE(|) - BINARY_OPERATOR_CASE(^) -#undef BINARY_OPERATOR_CASE + } else + #define DIV_OPERATOR_CASE(op) \ - else if (nameIs(opName, #op)) \ + if (opNameSlice == toSlice(#op)) \ { \ if (constArgs[1]->value == 0) \ { \ @@ -1459,35 +1447,56 @@ Val* FuncCallIntVal::tryFoldImpl(ASTBuilder* astBuilder, Type* resultType, DeclR return nullptr; \ } \ resultValue = constArgs[0]->value op constArgs[1]->value; \ - } - DIV_OPERATOR_CASE(/) - DIV_OPERATOR_CASE(%) -#undef DIV_OPERATOR_CASE + } else + #define LOGICAL_OPERATOR_CASE(op) \ - else if (nameIs(opName, #op)) \ + if (opNameSlice == toSlice(#op)) \ { \ resultValue = (((constArgs[0]->value!=0) op (constArgs[1]->value!=0)) ? 1 : 0); \ + } else + + +#define SPECIAL_OPERATOR_CASE(op, IF_MATCH) \ + if (opNameSlice == toSlice(op)) \ + { \ + IF_MATCH \ + } else + +#define TERMINATING_CASE(MATCH) \ + { \ + MATCH \ } + + // Handle the cases using the macros + BINARY_OPERATOR_CASE(>=) + BINARY_OPERATOR_CASE(<=) + BINARY_OPERATOR_CASE(>) + BINARY_OPERATOR_CASE(<) + BINARY_OPERATOR_CASE(!=) + BINARY_OPERATOR_CASE(==) + BINARY_OPERATOR_CASE(<<) + BINARY_OPERATOR_CASE(>>) + BINARY_OPERATOR_CASE(&) + BINARY_OPERATOR_CASE(|) + BINARY_OPERATOR_CASE(^) + DIV_OPERATOR_CASE(/) + DIV_OPERATOR_CASE(%) LOGICAL_OPERATOR_CASE(&&) - LOGICAL_OPERATOR_CASE(|| ) -#undef LOGICAL_OPERATOR_CASE - else if (nameIs(opName, "!")) - { - resultValue = ((constArgs[0]->value != 0) ? 1 : 0); - } - else if (nameIs(opName, "~")) - { - resultValue = ~constArgs[0]->value; - } - else if (nameIs(opName, "?:")) - { - resultValue = constArgs[0]->value != 0 ? constArgs[1]->value : constArgs[2]->value; - } - else - { - SLANG_UNREACHABLE("constant folding of FuncCallIntVal"); - } + LOGICAL_OPERATOR_CASE(||) + // Special cases need their "operator" names quoted. + SPECIAL_OPERATOR_CASE("!", resultValue = ((constArgs[0]->value != 0) ? 1 : 0);) + SPECIAL_OPERATOR_CASE("~", resultValue = ~constArgs[0]->value;) + SPECIAL_OPERATOR_CASE("?:", resultValue = constArgs[0]->value != 0 ? constArgs[1]->value : constArgs[2]->value;) + TERMINATING_CASE(SLANG_UNREACHABLE("constant folding of FuncCallIntVal");) + return astBuilder->getIntVal(resultType, resultValue); + + // The macros for the cases are no longer needed so undef them all. +#undef BINARY_OPERATOR_CASE +#undef DIV_OPERATOR_CASE +#undef LOGICAL_OPERATOR_CASE +#undef SPECIAL_OPERATOR_CASE +#undef TERMINATING_CASE } return nullptr; } -- cgit v1.2.3