From 271d01e2f45e66e66a2075916db96aa9b32a150f Mon Sep 17 00:00:00 2001 From: Marc Auberer Date: Fri, 5 Jan 2024 19:51:46 +0100 Subject: [PATCH] Remove unused resources --- src/CMakeLists.txt | 1 - src/SourceFile.h | 1 - src/ast/ASTBuilder.cpp | 107 +++++++++--------- src/ast/ASTBuilder.h | 4 +- src/ast/ASTNodes.h | 85 +++----------- src/exception/SemanticError.cpp | 4 +- src/exception/SemanticError.h | 2 +- src/irgenerator/GenControlStructures.cpp | 2 +- src/irgenerator/IRGenerator.h | 6 +- src/iroptimizer/IROptimizer.cpp | 10 +- src/iroptimizer/IROptimizer.h | 2 +- src/model/Function.h | 6 +- src/model/Interface.cpp | 5 - src/model/Interface.h | 2 +- src/model/Struct.h | 2 +- src/symboltablebuilder/Lifecycle.h | 7 +- src/symboltablebuilder/Scope.cpp | 26 +---- src/symboltablebuilder/Scope.h | 3 +- src/symboltablebuilder/SymbolTable.cpp | 3 +- src/symboltablebuilder/SymbolTableBuilder.cpp | 1 - src/symboltablebuilder/SymbolType.h | 6 +- src/typechecker/FunctionManager.cpp | 30 ----- src/typechecker/FunctionManager.h | 2 - src/typechecker/OpRuleManager.h | 2 +- src/typechecker/TypeChecker.cpp | 2 +- src/typechecker/TypeChecker.h | 2 +- src/typechecker/TypeCheckerImplicit.cpp | 24 ++-- src/util/CodeLoc.cpp | 2 - src/util/CompilerWarning.h | 3 +- src/util/FileUtil.cpp | 1 - src/util/GlobalDefinitions.h | 6 +- src/visualizer/ASTVisualizer.h | 2 +- .../exception.out | 2 +- 33 files changed, 129 insertions(+), 234 deletions(-) delete mode 100644 src/model/Interface.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8f0686d03..3f9234a05 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -113,7 +113,6 @@ set(SOURCES model/StructBase.h model/Struct.cpp model/Struct.h - model/Interface.cpp model/Interface.h model/GenericType.cpp model/GenericType.h diff --git a/src/SourceFile.h b/src/SourceFile.h index e2f9125ef..d8319176f 100644 --- a/src/SourceFile.h +++ b/src/SourceFile.h @@ -35,7 +35,6 @@ enum CompileStageType : uint8_t { PARSER, CST_VISUALIZER, AST_BUILDER, - AST_OPTIMIZER, AST_VISUALIZER, IMPORT_COLLECTOR, SYMBOL_TABLE_BUILDER, diff --git a/src/ast/ASTBuilder.cpp b/src/ast/ASTBuilder.cpp index 8e6691307..164e2b165 100644 --- a/src/ast/ASTBuilder.cpp +++ b/src/ast/ASTBuilder.cpp @@ -523,7 +523,7 @@ std::any ASTBuilder::visitSpecifier(SpiceParser::SpecifierContext *ctx) { else if (symbolType == SpiceParser::COMPOSE) specifierNode->type = SpecifierNode::TY_COMPOSITION; else - assert(false && "Unknown specifier type"); // GCOV_EXCL_LINE + assert_fail("Unknown specifier type"); // GCOV_EXCL_LINE } return concludeNode(specifierNode); @@ -1182,6 +1182,8 @@ std::any ASTBuilder::visitBaseDataType(SpiceParser::BaseDataTypeContext *ctx) { baseDataTypeNode->type = BaseDataTypeNode::TYPE_CUSTOM; else if (ctx->functionDataType()) baseDataTypeNode->type = BaseDataTypeNode::TYPE_FUNCTION; + else + assert_fail("Unknown base data type"); // Visit children visitChildren(ctx); @@ -1251,7 +1253,7 @@ std::any ASTBuilder::visitAssignOp(SpiceParser::AssignOpContext *ctx) { else if (ctx->XOR_EQUAL()) assignExprNode->op = AssignExprNode::OP_XOR_EQUAL; else - assert(false && "Unknown assign operator"); + assert_fail("Unknown assign operator"); assignExprNode->hasOperator = true; return nullptr; @@ -1261,51 +1263,37 @@ std::any ASTBuilder::visitOverloadableOp(SpiceParser::OverloadableOpContext *ctx auto fctNameNode = spice_pointer_cast(parentStack.top()); // Enrich - if (ctx->PLUS()) { - fctNameNode->overloadedOperator = FctNameNode::OP_PLUS; + if (ctx->PLUS()) fctNameNode->name = OP_FCT_PLUS; - } else if (ctx->MINUS()) { - fctNameNode->overloadedOperator = FctNameNode::OP_MINUS; + else if (ctx->MINUS()) fctNameNode->name = OP_FCT_MINUS; - } else if (ctx->MUL()) { - fctNameNode->overloadedOperator = FctNameNode::OP_MUL; + else if (ctx->MUL()) fctNameNode->name = OP_FCT_MUL; - } else if (ctx->DIV()) { - fctNameNode->overloadedOperator = FctNameNode::OP_DIV; + else if (ctx->DIV()) fctNameNode->name = OP_FCT_DIV; - } else if (ctx->EQUAL()) { - fctNameNode->overloadedOperator = FctNameNode::OP_EQUAL; + else if (ctx->EQUAL()) fctNameNode->name = OP_FCT_EQUAL; - } else if (ctx->NOT_EQUAL()) { - fctNameNode->overloadedOperator = FctNameNode::OP_NOT_EQUAL; + else if (ctx->NOT_EQUAL()) fctNameNode->name = OP_FCT_NOT_EQUAL; - } else if (ctx->LESS().size() == 2) { - fctNameNode->overloadedOperator = FctNameNode::OP_SHL; + else if (ctx->LESS().size() == 2) fctNameNode->name = OP_FCT_SHL; - } else if (ctx->GREATER().size() == 2) { - fctNameNode->overloadedOperator = FctNameNode::OP_SHR; + else if (ctx->GREATER().size() == 2) fctNameNode->name = OP_FCT_SHR; - } else if (ctx->PLUS_EQUAL()) { - fctNameNode->overloadedOperator = FctNameNode::OP_PLUS_EQUAL; + else if (ctx->PLUS_EQUAL()) fctNameNode->name = OP_FCT_PLUS_EQUAL; - } else if (ctx->MINUS_EQUAL()) { - fctNameNode->overloadedOperator = FctNameNode::OP_MINUS_EQUAL; + else if (ctx->MINUS_EQUAL()) fctNameNode->name = OP_FCT_MINUS_EQUAL; - } else if (ctx->MUL_EQUAL()) { - fctNameNode->overloadedOperator = FctNameNode::OP_MUL_EQUAL; + else if (ctx->MUL_EQUAL()) fctNameNode->name = OP_FCT_MUL_EQUAL; - } else if (ctx->DIV_EQUAL()) { - fctNameNode->overloadedOperator = FctNameNode::OP_DIV_EQUAL; + else if (ctx->DIV_EQUAL()) fctNameNode->name = OP_FCT_DIV_EQUAL; - } else if (ctx->PLUS_PLUS()) { - fctNameNode->overloadedOperator = FctNameNode::OP_PLUS_PLUS; + else if (ctx->PLUS_PLUS()) fctNameNode->name = OP_FCT_POSTFIX_PLUS_PLUS; - } else if (ctx->MINUS_MINUS()) { - fctNameNode->overloadedOperator = FctNameNode::OP_MINUS_MINUS; + else if (ctx->MINUS_MINUS()) fctNameNode->name = OP_FCT_POSTFIX_MINUS_MINUS; - } else { - assert(false && "Unsupported overloadable operator"); // GCOV_EXCL_LINE - } + else + assert_fail("Unsupported overloadable operator"); // GCOV_EXCL_LINE + fctNameNode->fqName = fctNameNode->name; fctNameNode->nameFragments.push_back(fctNameNode->name); @@ -1339,21 +1327,35 @@ template T *ASTBuilder::concludeNode(T *node) { } int32_t ASTBuilder::parseInt(ConstantNode *constantNode, TerminalNode *terminal) { - std::function cb = [](const std::string &substr, int base) { - return std::stoi(substr, nullptr, base); + NumericParserCallback cb = [](const std::string &substr, int base, bool isSigned) -> int32_t { + // Prepare limits + const int64_t upperLimit = isSigned ? INT32_MAX : UINT32_MAX; + const int64_t lowerLimit = isSigned ? INT32_MIN : 0; + // Parse number and check for limits + const int64_t number = std::stoll(substr, nullptr, base); + if (number < lowerLimit || number > upperLimit) + throw std::out_of_range("Number out of range"); + return static_cast(number); }; return parseNumeric(constantNode, terminal, cb); } int16_t ASTBuilder::parseShort(ConstantNode *constantNode, TerminalNode *terminal) { - std::function cb = [](const std::string &substr, int base) { - return (int16_t)std::stoi(substr, nullptr, base); + NumericParserCallback cb = [](const std::string &substr, int base, bool isSigned) -> int16_t { + // Prepare limits + const int64_t upperLimit = isSigned ? INT16_MAX : UINT16_MAX; + const int64_t lowerLimit = isSigned ? INT16_MIN : 0; + // Parse number and check for limits + const int64_t number = std::stoll(substr, nullptr, base); + if (number < lowerLimit || number > upperLimit) + throw std::out_of_range("Number out of range"); + return static_cast(number); }; return parseNumeric(constantNode, terminal, cb); } int64_t ASTBuilder::parseLong(ConstantNode *constantNode, TerminalNode *terminal) { - std::function cb = [](const std::string &substr, int base) { + NumericParserCallback cb = [](const std::string &substr, int base, bool isSigned) -> int64_t { return std::stoll(substr, nullptr, base); }; return parseNumeric(constantNode, terminal, cb); @@ -1402,40 +1404,35 @@ std::string ASTBuilder::parseString(std::string input) { } template -T ASTBuilder::parseNumeric(ConstantNode *constantNode, TerminalNode *terminal, std::function cb) { +T ASTBuilder::parseNumeric(ConstantNode *constantNode, TerminalNode *terminal, + std::function cb) { const std::string input = terminal->toString(); - // Set to signed if the input string ends with 'u' - if (constantNode) - constantNode->isSigned = input.ends_with('u'); + // Set to signed if the input string does not end with 'u' + const bool isSigned = !input.ends_with('u'); try { if (input.length() >= 3) { - const char c1 = input[0]; - const char c2 = input[1]; - const std::string subStr = input.substr(2); - if (c1 == '0') { - switch (c2) { - case 'd': - case 'D': - return cb(subStr, 10); + if (input[0] == '0') { + const std::string subStr = input.substr(2); + switch (input[1]) { case 'b': case 'B': - return cb(subStr, 2); + return cb(subStr, 2, isSigned); case 'h': case 'H': case 'x': case 'X': - return cb(subStr, 16); + return cb(subStr, 16, isSigned); case 'o': case 'O': - return cb(subStr, 8); + return cb(subStr, 8, isSigned); default: - return cb(input, 10); + return cb(input, 10, isSigned); } } } - return cb(input, 10); + return cb(input, 10, isSigned); } catch (std::out_of_range &e) { const CodeLoc codeLoc(terminal->getSymbol(), sourceFile); throw ParserError(codeLoc, NUMBER_OUT_OF_RANGE, "The provided number is out of range"); diff --git a/src/ast/ASTBuilder.h b/src/ast/ASTBuilder.h index 7adcebe8a..fdb1d0f3e 100644 --- a/src/ast/ASTBuilder.h +++ b/src/ast/ASTBuilder.h @@ -26,6 +26,7 @@ class ASTBuilder : private CompilerPass, public SpiceVisitor { // Private type defs using TerminalNode = antlr4::tree::TerminalNode; using ParserRuleContext = antlr4::ParserRuleContext; + template using NumericParserCallback = std::function; public: // Constructors @@ -134,8 +135,7 @@ class ASTBuilder : private CompilerPass, public SpiceVisitor { int64_t parseLong(ConstantNode *constantNode, TerminalNode *terminal); int8_t parseChar(TerminalNode *terminal); static std::string parseString(std::string input); - template - T parseNumeric(ConstantNode *constantNode, TerminalNode *terminal, std::function cb); + template T parseNumeric(ConstantNode *constantNode, TerminalNode *terminal, NumericParserCallback cb); static void replaceEscapeChars(std::string &string); std::string getIdentifier(TerminalNode *terminal); }; diff --git a/src/ast/ASTNodes.h b/src/ast/ASTNodes.h index a59742f7f..76a2a5872 100644 --- a/src/ast/ASTNodes.h +++ b/src/ast/ASTNodes.h @@ -21,14 +21,15 @@ namespace spice::compiler { * Saves a constant value for an AST node to realize features like array-out-of-bounds checks */ union CompileTimeValue { - std::double_t doubleValue; - std::int32_t intValue; - std::int16_t shortValue; - std::int64_t longValue; - std::int8_t charValue; + double_t doubleValue; + int32_t intValue; + int16_t shortValue; + int64_t longValue; + int8_t charValue; const char *stringValue; bool boolValue; }; +static_assert(sizeof(CompileTimeValue) == 8); // =========================================================== AstNode =========================================================== @@ -72,35 +73,12 @@ class ASTNode { return nodes; } - ALWAYS_INLINE void reserveChildren(size_t numberOfChildren) { children.reserve(numberOfChildren); } - - void replaceInParent(ASTNode *replacementNode) { - assert(parent != nullptr); - for (auto &child : parent->children) { - if (child == this) [[unlikely]] { - // Replace in children vector - child = replacementNode; - break; - } - } - } - - void removeFromParent() { - assert(parent != nullptr); - for (auto &child : parent->children) { - if (child == this) [[unlikely]] { - // Remove from children vector - child = nullptr; - break; - } - } - } - virtual void resizeToNumberOfManifestations(size_t manifestationCount) { // NOLINT(misc-no-recursion) // Resize children - for (ASTNode *child : children) - if (child != nullptr) - child->resizeToNumberOfManifestations(manifestationCount); + for (ASTNode *child : children) { + assert(child != nullptr); + child->resizeToNumberOfManifestations(manifestationCount); + } // Reserve this node symbolTypes.resize(manifestationCount, SymbolType(TY_INVALID)); // Reserve operator functions @@ -146,17 +124,17 @@ class ASTNode { } [[nodiscard]] virtual std::vector *getFctManifestations(const std::string &fctName) { // LCOV_EXCL_LINE - assert(false && "Must be called on a FctDefNode, ProcDefNode, ExtDeclNode, StructDefNode or SignatureNode"); // LCOV_EXCL_LINE + assert_fail("Must be called on a FctDefNode, ProcDefNode, ExtDeclNode, StructDefNode or SignatureNode"); // LCOV_EXCL_LINE return nullptr; // LCOV_EXCL_LINE } // LCOV_EXCL_LINE [[nodiscard]] virtual std::vector *getStructManifestations() { // LCOV_EXCL_LINE - assert(false && "Must be called on a StructDefNode"); // LCOV_EXCL_LINE + assert_fail("Must be called on a StructDefNode"); // LCOV_EXCL_LINE return nullptr; // LCOV_EXCL_LINE } // LCOV_EXCL_LINE [[nodiscard]] virtual std::vector *getInterfaceManifestations() { // LCOV_EXCL_LINE - assert(false && "Must be called on a InterfaceDefNode"); // LCOV_EXCL_LINE + assert_fail("Must be called on a InterfaceDefNode"); // LCOV_EXCL_LINE return nullptr; // LCOV_EXCL_LINE } // LCOV_EXCL_LINE @@ -178,6 +156,9 @@ class ASTNode { bool unreachable = false; }; +// Make sure we have no unexpected increases in memory consumption +static_assert(sizeof(ASTNode) == 176); + // ========================================================== EntryNode ========================================================== class EntryNode : public ASTNode { @@ -211,7 +192,7 @@ class MainFctDefNode : public ASTNode { [[nodiscard]] StmtLstNode *body() const { return getChild(); } // Other methods - [[nodiscard]] std::string getScopeId() const { return "fct:main"; } + [[nodiscard]] static std::string getScopeId() { return "fct:main"; } [[nodiscard]] std::string getSignature() const { return takesArgs ? "main(int, string[])" : "main()"; } bool returnsOnAllControlPaths(bool *doSetPredecessorsUnreachable) const override; [[nodiscard]] bool isFctOrProcDef() const override { return true; } @@ -229,25 +210,6 @@ class FctNameNode : public ASTNode { // Constructors using ASTNode::ASTNode; - // Enums - enum OverloadedOperator : uint8_t { - OP_NONE, - OP_PLUS, - OP_MINUS, - OP_MUL, - OP_DIV, - OP_EQUAL, - OP_NOT_EQUAL, - OP_SHL, - OP_SHR, - OP_PLUS_EQUAL, - OP_MINUS_EQUAL, - OP_MUL_EQUAL, - OP_DIV_EQUAL, - OP_PLUS_PLUS, - OP_MINUS_MINUS - }; - // Visitor methods std::any accept(AbstractASTVisitor *visitor) override { return visitor->visitFctName(this); } std::any accept(ParallelizableASTVisitor *visitor) const override { return visitor->visitFctName(this); } @@ -257,7 +219,6 @@ class FctNameNode : public ASTNode { std::string structName; std::string fqName; std::vector nameFragments; - OverloadedOperator overloadedOperator = OP_NONE; }; // ======================================================== FctDefBaseNode ======================================================= @@ -813,9 +774,6 @@ class TypeLstNode : public ASTNode { // Public get methods [[nodiscard]] std::vector dataTypes() const { return getChildren(); } - - // Public members - size_t numberOfTypes = 0; }; // ======================================================= TypeAltsLstNode ======================================================= @@ -831,9 +789,6 @@ class TypeAltsLstNode : public ASTNode { // Public get methods [[nodiscard]] std::vector dataTypes() const { return getChildren(); } - - // Public members - size_t numberOfAlts = 0; }; // ======================================================== ParamLstNode ========================================================= @@ -879,9 +834,6 @@ class EnumItemLstNode : public ASTNode { // Public get methods [[nodiscard]] std::vector items() const { return getChildren(); } - - // Public members - EnumDefNode *enumDef = nullptr; }; // ========================================================= EnumItemNode ======================================================== @@ -1611,7 +1563,6 @@ class AdditiveExprNode : public ASTNode { public: // Enums enum AdditiveOp : uint8_t { - OP_NONE, OP_PLUS, OP_MINUS, }; @@ -1643,7 +1594,6 @@ class MultiplicativeExprNode : public ASTNode { public: // Enums enum MultiplicativeOp : uint8_t { - OP_NONE, OP_MUL, OP_DIV, OP_REM, @@ -1849,7 +1799,6 @@ class ConstantNode : public ASTNode { // Public members PrimitiveValueType type = TYPE_NONE; - bool isSigned = true; }; // ====================================================== FctCallNode ============================================================ diff --git a/src/exception/SemanticError.cpp b/src/exception/SemanticError.cpp index 23c8e0bcc..c5799685f 100644 --- a/src/exception/SemanticError.cpp +++ b/src/exception/SemanticError.cpp @@ -146,8 +146,8 @@ std::string SemanticError::getMessagePrefix(SemanticErrorType type) { return "Missing attribute value"; case NUMBER_OF_FIELDS_NOT_MATCHING: return "Number of struct fields not matching declaration"; - case FIELD_DEFAULT_VALUE_NO_COMPILETIME_CONST: - return "Field default value no compiletime constant"; + case FIELD_DEFAULT_VALUE_NO_COMPILE_TIME_CONST: + return "Field default value no compile time constant"; case FIELD_TYPE_NOT_MATCHING: return "The type of a field value does not match the declaration"; case ARRAY_SIZE_INVALID: diff --git a/src/exception/SemanticError.h b/src/exception/SemanticError.h index 7259914d8..4d98c0a7a 100644 --- a/src/exception/SemanticError.h +++ b/src/exception/SemanticError.h @@ -72,7 +72,7 @@ enum SemanticErrorType : uint8_t { INVALID_ATTR_TARGET, MISSING_ATTR_VALUE, NUMBER_OF_FIELDS_NOT_MATCHING, - FIELD_DEFAULT_VALUE_NO_COMPILETIME_CONST, + FIELD_DEFAULT_VALUE_NO_COMPILE_TIME_CONST, FIELD_TYPE_NOT_MATCHING, ARRAY_SIZE_INVALID, FOREACH_IDX_NOT_LONG, diff --git a/src/irgenerator/GenControlStructures.cpp b/src/irgenerator/GenControlStructures.cpp index e2b84a76c..4829078c1 100644 --- a/src/irgenerator/GenControlStructures.cpp +++ b/src/irgenerator/GenControlStructures.cpp @@ -319,7 +319,7 @@ std::any IRGenerator::visitIfStmt(const IfStmtNode *node) { // Switch to exit block switchToBlock(bExit); - // Return conditional value as result for the if stmt + // Return conditional value as result for the 'if' stmt return condValue; } diff --git a/src/irgenerator/IRGenerator.h b/src/irgenerator/IRGenerator.h index ec47ea9b2..a74aa2310 100644 --- a/src/irgenerator/IRGenerator.h +++ b/src/irgenerator/IRGenerator.h @@ -16,7 +16,11 @@ const char *const ANON_GLOBAL_STRING_NAME = "anon.string."; const char *const ANON_GLOBAL_ARRAY_NAME = "anon.array."; const char *const CAPTURES_PARAM_NAME = "captures"; -enum Likeliness { UNSPECIFIED, LIKELY, UNLIKELY }; +enum Likeliness : uint8_t { + UNSPECIFIED, + LIKELY, + UNLIKELY, +}; // Forward declarations class SourceFile; diff --git a/src/iroptimizer/IROptimizer.cpp b/src/iroptimizer/IROptimizer.cpp index 1755b17f7..23678a0bb 100644 --- a/src/iroptimizer/IROptimizer.cpp +++ b/src/iroptimizer/IROptimizer.cpp @@ -64,13 +64,13 @@ void IROptimizer::optimizePostLink(llvm::Module <oModule) { modulePassMgr.run(ltoModule, moduleAnalysisMgr); } -std::string IROptimizer::getOptimizedIRString(llvm::Module *module) const { - if (!module) - module = this->module; - assert(module != nullptr); // Ensure that the module was not moved away +std::string IROptimizer::getOptimizedIRString(llvm::Module *llvmModule) const { + if (!llvmModule) + llvmModule = module; + assert(llvmModule != nullptr); // Ensure that the module was not moved away std::string output; llvm::raw_string_ostream oss(output); - module->print(oss, nullptr); + llvmModule->print(oss, nullptr); return oss.str(); } diff --git a/src/iroptimizer/IROptimizer.h b/src/iroptimizer/IROptimizer.h index df17e1abf..e350b6124 100644 --- a/src/iroptimizer/IROptimizer.h +++ b/src/iroptimizer/IROptimizer.h @@ -25,7 +25,7 @@ class IROptimizer : private CompilerPass { void optimizeDefault(); void optimizePreLink(); void optimizePostLink(llvm::Module <oModule); - [[nodiscard]] std::string getOptimizedIRString(llvm::Module *module = nullptr) const; + [[nodiscard]] std::string getOptimizedIRString(llvm::Module *llvmModule = nullptr) const; private: // Private members diff --git a/src/model/Function.h b/src/model/Function.h index a70a1fe37..394717e3a 100644 --- a/src/model/Function.h +++ b/src/model/Function.h @@ -52,9 +52,9 @@ class Function { [[nodiscard]] ALWAYS_INLINE bool isFunction() const { return !returnType.is(TY_DYN); } [[nodiscard]] ALWAYS_INLINE bool isProcedure() const { return returnType.is(TY_DYN); } [[nodiscard]] ALWAYS_INLINE bool isNormalFunction() const { return isFunction() && !isMethod(); } - [[nodiscard]] ALWAYS_INLINE bool isNormalProcedure() const { return isProcedure() && !isMethod(); } - [[nodiscard]] ALWAYS_INLINE bool isMethodFunction() const { return isFunction() && isMethod(); } - [[nodiscard]] ALWAYS_INLINE bool isMethodProcedure() const { return isProcedure() && isMethod(); } + [[nodiscard]] [[maybe_unused]] ALWAYS_INLINE bool isNormalProcedure() const { return isProcedure() && !isMethod(); } + [[nodiscard]] [[maybe_unused]] ALWAYS_INLINE bool isMethodFunction() const { return isFunction() && isMethod(); } + [[nodiscard]] [[maybe_unused]] ALWAYS_INLINE bool isMethodProcedure() const { return isProcedure() && isMethod(); } [[nodiscard]] ALWAYS_INLINE bool isVirtualMethod() const { return isMethod() && isVirtual; } [[nodiscard]] bool hasSubstantiatedParams() const; [[nodiscard]] bool hasSubstantiatedGenerics() const; diff --git a/src/model/Interface.cpp b/src/model/Interface.cpp deleted file mode 100644 index d49b0e006..000000000 --- a/src/model/Interface.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright (c) 2021-2024 ChilliBits. All rights reserved. - -#include "Interface.h" - -namespace spice::compiler {} // namespace spice::compiler \ No newline at end of file diff --git a/src/model/Interface.h b/src/model/Interface.h index b12e474b3..1b954d09f 100644 --- a/src/model/Interface.h +++ b/src/model/Interface.h @@ -19,7 +19,7 @@ class Interface : public StructBase { // Constructors Interface(std::string name, SymbolTableEntry *entry, Scope *scope, std::vector methods, std::vector templateTypes, ASTNode *declNode) - : StructBase(name, entry, scope, templateTypes, declNode), methods(std::move(methods)) {} + : StructBase(std::move(name), entry, scope, std::move(templateTypes), declNode), methods(std::move(methods)) {} // Public members std::vector methods; diff --git a/src/model/Struct.h b/src/model/Struct.h index 34bfc63c8..967e924f1 100644 --- a/src/model/Struct.h +++ b/src/model/Struct.h @@ -18,7 +18,7 @@ class Struct : public StructBase { // Constructors Struct(std::string name, SymbolTableEntry *entry, Scope *scope, std::vector fieldTypes, std::vector templateTypes, std::vector interfaceTypes, ASTNode *declNode) - : StructBase(name, entry, scope, templateTypes, declNode), fieldTypes(std::move(fieldTypes)), + : StructBase(std::move(name), entry, scope, std::move(templateTypes), declNode), fieldTypes(std::move(fieldTypes)), interfaceTypes(std::move(interfaceTypes)) {} // Public methods diff --git a/src/symboltablebuilder/Lifecycle.h b/src/symboltablebuilder/Lifecycle.h index b3c6ebe8e..d7eb0f7cc 100644 --- a/src/symboltablebuilder/Lifecycle.h +++ b/src/symboltablebuilder/Lifecycle.h @@ -2,6 +2,7 @@ #pragma once +#include #include #include @@ -10,7 +11,7 @@ namespace spice::compiler { // Forward declarations class ASTNode; -enum LifecycleState { +enum LifecycleState : uint8_t { DEAD, DECLARED, INITIALIZED, @@ -40,8 +41,8 @@ class Lifecycle { void addEvent(const LifecycleEvent &event); [[nodiscard]] LifecycleState getCurrentState() const; [[nodiscard]] const char *getCurrentStateName() const; - [[nodiscard]] bool isDead() const; - [[nodiscard]] bool isDeclared() const; + [[nodiscard]] [[maybe_unused]] bool isDead() const; + [[nodiscard]] [[maybe_unused]] bool isDeclared() const; [[nodiscard]] bool isInitialized() const; private: diff --git a/src/symboltablebuilder/Scope.cpp b/src/symboltablebuilder/Scope.cpp index 1a88b2533..9405f1d53 100644 --- a/src/symboltablebuilder/Scope.cpp +++ b/src/symboltablebuilder/Scope.cpp @@ -14,11 +14,11 @@ namespace spice::compiler { * * @param scopeName Name of the child scope * @param scopeType Type of the child scope - * @param codeLoc Code location of the scope + * @param declCodeLoc Code location of the scope * @return Child scope (heap allocated) */ -Scope *Scope::createChildScope(const std::string &scopeName, ScopeType scopeType, const CodeLoc *codeLoc) { - children.insert({scopeName, std::make_shared(this, sourceFile, scopeType, codeLoc)}); +Scope *Scope::createChildScope(const std::string &scopeName, ScopeType scopeType, const CodeLoc *declCodeLoc) { + children.insert({scopeName, std::make_shared(this, sourceFile, scopeType, declCodeLoc)}); return children.at(scopeName).get(); } @@ -50,7 +50,7 @@ void Scope::copyChildScope(const std::string &oldName, const std::string &newNam children.insert({newName, newScope}); } -std::shared_ptr Scope::deepCopyScope() { +std::shared_ptr Scope::deepCopyScope() { // NOLINT(misc-no-recursion) const std::shared_ptr newScope = std::make_shared(*this); for (const auto &[childName, oldChild] : children) { newScope->children[childName] = oldChild->deepCopyScope(); @@ -171,22 +171,6 @@ std::vector Scope::getVirtualMethods() { return methods; } -/** - * Get the number of virtual methods in this scope - * - * @return Number of virtual methods - */ -size_t Scope::getVirtualMethodCount() const { - assert(type == ScopeType::STRUCT || type == ScopeType::INTERFACE); - size_t methodCount = 0; - for (const auto &symbol : symbolTable.symbols) { - const ASTNode *declNode = symbol.second.declNode; - if (declNode->isFctOrProcDef() || declNode->isStructDef()) - methodCount++; - } - return methodCount; -} - /** * Check if this struct has any reference fields * @@ -374,7 +358,7 @@ void Scope::collectWarnings(std::vector &warnings) const { // N * Checks if all variables of this and all child scopes are of an explicit type. * This is executed after type inference to check that all variables could be inferred correctly. */ -void Scope::ensureSuccessfulTypeInference() const { +void Scope::ensureSuccessfulTypeInference() const { // NOLINT(misc-no-recursion) // Check symbols in this scope for (auto &[name, entry] : symbolTable.symbols) if (entry.getType().is(TY_DYN)) diff --git a/src/symboltablebuilder/Scope.h b/src/symboltablebuilder/Scope.h index ec61f6d19..6f20fd5ee 100644 --- a/src/symboltablebuilder/Scope.h +++ b/src/symboltablebuilder/Scope.h @@ -64,7 +64,7 @@ class Scope { // Public methods // Scope management - Scope *createChildScope(const std::string &scopeName, ScopeType scopeType, const CodeLoc *codeLoc); + Scope *createChildScope(const std::string &scopeName, ScopeType scopeType, const CodeLoc *declCodeLoc); void renameChildScope(const std::string &oldName, const std::string &newName); void copyChildScope(const std::string &oldName, const std::string &newName); std::shared_ptr deepCopyScope(); @@ -80,7 +80,6 @@ class Scope { void ensureSuccessfulTypeInference() const; [[nodiscard]] size_t getFieldCount() const; [[nodiscard]] std::vector getVirtualMethods(); - [[nodiscard]] size_t getVirtualMethodCount() const; [[nodiscard]] bool hasRefFields(); [[nodiscard]] size_t getLoopNestingDepth() const; [[nodiscard]] bool isInCaseBranch() const; diff --git a/src/symboltablebuilder/SymbolTable.cpp b/src/symboltablebuilder/SymbolTable.cpp index 27164903b..80a71778a 100644 --- a/src/symboltablebuilder/SymbolTable.cpp +++ b/src/symboltablebuilder/SymbolTable.cpp @@ -131,7 +131,8 @@ SymbolTableEntry *SymbolTable::lookupStrict(const std::string &name) { * @param indexPath How to index the found symbol using order indices (e.g. for GEP) * @return Desired symbol / nullptr if the symbol was not found */ -SymbolTableEntry *SymbolTable::lookupInComposedFields(const std::string &name, std::vector &indexPath) { +SymbolTableEntry *SymbolTable::lookupInComposedFields(const std::string &name, + std::vector &indexPath) { // NOLINT(misc-no-recursion) assert(scope->type == ScopeType::STRUCT); // Check if we have a symbol with this name in the current scope diff --git a/src/symboltablebuilder/SymbolTableBuilder.cpp b/src/symboltablebuilder/SymbolTableBuilder.cpp index 18ffd9c3a..3e7a126a8 100644 --- a/src/symboltablebuilder/SymbolTableBuilder.cpp +++ b/src/symboltablebuilder/SymbolTableBuilder.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include diff --git a/src/symboltablebuilder/SymbolType.h b/src/symboltablebuilder/SymbolType.h index adee019a3..37df712b5 100644 --- a/src/symboltablebuilder/SymbolType.h +++ b/src/symboltablebuilder/SymbolType.h @@ -127,9 +127,11 @@ class SymbolType { [[nodiscard]] ALWAYS_INLINE bool isPtr() const { return getSuperType() == TY_PTR; } [[nodiscard]] ALWAYS_INLINE bool isPtrOf(SymbolSuperType superType) const { return isPtr() && getContainedTy().is(superType); } [[nodiscard]] ALWAYS_INLINE bool isRef() const { return getSuperType() == TY_REF; } - [[nodiscard]] ALWAYS_INLINE bool isRefOf(SymbolSuperType superType) const { return isRef() && getContainedTy().is(superType); } + [[nodiscard]] [[maybe_unused]] ALWAYS_INLINE bool isRefOf(SymbolSuperType superType) const { + return isRef() && getContainedTy().is(superType); + } [[nodiscard]] ALWAYS_INLINE bool isArray() const { return getSuperType() == TY_ARRAY; } - [[nodiscard]] ALWAYS_INLINE bool isArrayOf(SymbolSuperType superType) const { + [[nodiscard]] [[maybe_unused]] ALWAYS_INLINE bool isArrayOf(SymbolSuperType superType) const { return isArray() && getContainedTy().is(superType); } [[nodiscard]] ALWAYS_INLINE bool isArrayOf(const SymbolType &symbolType) const { diff --git a/src/typechecker/FunctionManager.cpp b/src/typechecker/FunctionManager.cpp index 1a7b7fa7b..d97147956 100644 --- a/src/typechecker/FunctionManager.cpp +++ b/src/typechecker/FunctionManager.cpp @@ -437,36 +437,6 @@ void FunctionManager::substantiateReturnType(Function &candidate, TypeMapping &t TypeMatcher::substantiateTypeWithTypeMapping(candidate.returnType, typeMapping); } -/** - * Checks if the matching candidate fulfills the return type requirement - * - * @param candidate Matching candidate function - * @param requestedReturnType Requested return type - * @param typeMapping Concrete template type mapping - * @param strictSpecifierMatching Match specifiers strictly - * @return Fulfilled or not - */ -bool FunctionManager::matchReturnType(Function &candidate, const SymbolType &requestedReturnType, TypeMapping &typeMapping, - bool strictSpecifierMatching) { - SymbolType &candidateReturnType = candidate.returnType; - - // Give the type matcher a way to retrieve instances of GenericType by their name - TypeMatcher::ResolverFct genericTypeResolver = [&](const std::string &genericTypeName) { - return getGenericTypeOfCandidateByName(candidate, genericTypeName); - }; - - // Check if the requested param type matches the candidate param type. The type mapping may be extended - if (!TypeMatcher::matchRequestedToCandidateType(candidateReturnType, requestedReturnType, typeMapping, genericTypeResolver, - strictSpecifierMatching)) - return false; - - // Substantiate the candidate param type, based on the type mapping - if (candidateReturnType.hasAnyGenericParts()) - TypeMatcher::substantiateTypeWithTypeMapping(candidateReturnType, typeMapping); - - return true; -} - /** * Searches the candidate template types for a generic type object with a certain name and return it * diff --git a/src/typechecker/FunctionManager.h b/src/typechecker/FunctionManager.h index a509345a3..362a1de19 100644 --- a/src/typechecker/FunctionManager.h +++ b/src/typechecker/FunctionManager.h @@ -60,8 +60,6 @@ class FunctionManager { [[nodiscard]] static bool matchArgTypes(Function &candidate, const std::vector &requestedArgTypes, TypeMapping &typeMapping, bool strictSpecifierMatching, bool &needsSubstantiation); static void substantiateReturnType(Function &candidate, TypeMapping &typeMapping); - static bool matchReturnType(Function &candidate, const SymbolType &requestedReturnType, TypeMapping &typeMapping, - bool strictSpecifierMatching); [[nodiscard]] static const GenericType *getGenericTypeOfCandidateByName(const Function &candidate, const std::string &templateTypeName); }; diff --git a/src/typechecker/OpRuleManager.h b/src/typechecker/OpRuleManager.h index 3ddcc2509..997e591d3 100644 --- a/src/typechecker/OpRuleManager.h +++ b/src/typechecker/OpRuleManager.h @@ -682,7 +682,7 @@ class OpRuleManager { static SemanticError getExceptionBinary(const ASTNode *node, const char *name, const SymbolType &lhs, const SymbolType &rhs, const char *messagePrefix); void ensureUnsafeAllowed(const ASTNode *node, const char *name, const SymbolType &lhs, const SymbolType &rhs) const; - void ensureNoConstAssign(const ASTNode *node, const SymbolType &lhs); + static void ensureNoConstAssign(const ASTNode *node, const SymbolType &lhs); }; } // namespace spice::compiler \ No newline at end of file diff --git a/src/typechecker/TypeChecker.cpp b/src/typechecker/TypeChecker.cpp index 7d5f8be6b..e647b6b0f 100644 --- a/src/typechecker/TypeChecker.cpp +++ b/src/typechecker/TypeChecker.cpp @@ -397,7 +397,7 @@ std::any TypeChecker::visitField(FieldNode *node) { if (TernaryExprNode *defaultValueNode = node->defaultValue(); defaultValueNode != nullptr) { if (!defaultValueNode->hasCompileTimeValue()) - SOFT_ERROR_ST(node, FIELD_DEFAULT_VALUE_NO_COMPILETIME_CONST, "Default values must be computable at compile time") + SOFT_ERROR_ST(node, FIELD_DEFAULT_VALUE_NO_COMPILE_TIME_CONST, "Default values must be computable at compile time") const SymbolType defaultValueType = std::any_cast(visit(defaultValueNode)).type; HANDLE_UNRESOLVED_TYPE_ST(fieldType) diff --git a/src/typechecker/TypeChecker.h b/src/typechecker/TypeChecker.h index aec435fd7..ade64baec 100644 --- a/src/typechecker/TypeChecker.h +++ b/src/typechecker/TypeChecker.h @@ -15,7 +15,7 @@ namespace spice::compiler { -enum TypeCheckerMode { +enum TypeCheckerMode : bool { TC_MODE_PRE, TC_MODE_POST, }; diff --git a/src/typechecker/TypeCheckerImplicit.cpp b/src/typechecker/TypeCheckerImplicit.cpp index 2f12754cd..63c0d63d4 100644 --- a/src/typechecker/TypeCheckerImplicit.cpp +++ b/src/typechecker/TypeCheckerImplicit.cpp @@ -6,8 +6,6 @@ #include #include -#include - namespace spice::compiler { static const char *const FCT_NAME_DEALLOC = "sDealloc"; @@ -24,8 +22,8 @@ void TypeChecker::createDefaultStructMethod(const Struct &spiceStruct, const std Scope *structScope = spiceStruct.scope; ASTNode *node = spiceStruct.declNode; const SymbolTableEntry *structEntry = spiceStruct.entry; - const SymbolType &thisType = structEntry->getType(); - const std::string fqFctName = thisType.getSubType() + MEMBER_ACCESS_TOKEN + methodName; + const SymbolType &structType = structEntry->getType(); + const std::string fqFctName = structType.getSubType() + MEMBER_ACCESS_TOKEN + methodName; // Procedure type SymbolType procedureType(TY_PROCEDURE); @@ -42,7 +40,7 @@ void TypeChecker::createDefaultStructMethod(const Struct &spiceStruct, const std // Create the default method const std::vector templateTypes = spiceStruct.templateTypes; const SymbolType returnType(TY_DYN); - Function defaultMethod(methodName, fctEntry, thisType, returnType, params, templateTypes, structEntry->declNode); + Function defaultMethod(methodName, fctEntry, structType, returnType, params, templateTypes, structEntry->declNode); defaultMethod.implicitDefault = true; // Create function scope @@ -51,7 +49,7 @@ void TypeChecker::createDefaultStructMethod(const Struct &spiceStruct, const std // Create 'this' symbol in the function scope SymbolTableEntry *thisEntry = fctScope->insert(THIS_VARIABLE_NAME, node); - thisEntry->updateType(thisType.toPointer(node), true); + thisEntry->updateType(structType.toPointer(node), true); thisEntry->used = true; // Always set to used to not print warnings for non-existing code // Hand it off to the function manager to register the function @@ -70,8 +68,8 @@ void TypeChecker::createDefaultCtorIfRequired(const Struct &spiceStruct, Scope * // Abort if the struct already has a user-defined constructor const SymbolTableEntry *structEntry = spiceStruct.entry; - const SymbolType &thisType = structEntry->getType(); - const std::string fqFctName = thisType.getSubType() + MEMBER_ACCESS_TOKEN + CTOR_FUNCTION_NAME; + const SymbolType &structType = structEntry->getType(); + const std::string fqFctName = structType.getSubType() + MEMBER_ACCESS_TOKEN + CTOR_FUNCTION_NAME; if (sourceFile->getNameRegistryEntry(fqFctName)) return; @@ -128,8 +126,8 @@ void TypeChecker::createDefaultCopyCtorIfRequired(const Struct &spiceStruct, Sco // Abort if the struct already has a user-defined constructor const SymbolTableEntry *structEntry = spiceStruct.entry; - const SymbolType &thisType = structEntry->getType(); - const std::string fqFctName = thisType.getSubType() + MEMBER_ACCESS_TOKEN + CTOR_FUNCTION_NAME; + const SymbolType &structType = structEntry->getType(); + const std::string fqFctName = structType.getSubType() + MEMBER_ACCESS_TOKEN + CTOR_FUNCTION_NAME; if (sourceFile->getNameRegistryEntry(fqFctName)) return; @@ -160,7 +158,7 @@ void TypeChecker::createDefaultCopyCtorIfRequired(const Struct &spiceStruct, Sco return; // Create the default copy ctor function - const ParamList paramTypes = {{thisType.toConstReference(node), false}}; + const ParamList paramTypes = {{structType.toConstReference(node), false}}; createDefaultStructMethod(spiceStruct, CTOR_FUNCTION_NAME, paramTypes); } @@ -176,8 +174,8 @@ void TypeChecker::createDefaultDtorIfRequired(const Struct &spiceStruct, Scope * // Abort if the struct already has a user-defined destructor const SymbolTableEntry *structEntry = spiceStruct.entry; - const SymbolType &thisType = structEntry->getType(); - const std::string fqFctName = thisType.getSubType() + MEMBER_ACCESS_TOKEN + DTOR_FUNCTION_NAME; + const SymbolType &structType = structEntry->getType(); + const std::string fqFctName = structType.getSubType() + MEMBER_ACCESS_TOKEN + DTOR_FUNCTION_NAME; if (sourceFile->getNameRegistryEntry(fqFctName)) return; diff --git a/src/util/CodeLoc.cpp b/src/util/CodeLoc.cpp index 6906c3cb8..7959d65dd 100644 --- a/src/util/CodeLoc.cpp +++ b/src/util/CodeLoc.cpp @@ -5,8 +5,6 @@ #include "SourceFile.h" #include -#include - namespace spice::compiler { /** diff --git a/src/util/CompilerWarning.h b/src/util/CompilerWarning.h index ea2921ebf..552931276 100644 --- a/src/util/CompilerWarning.h +++ b/src/util/CompilerWarning.h @@ -2,6 +2,7 @@ #pragma once +#include #include namespace spice::compiler { @@ -9,7 +10,7 @@ namespace spice::compiler { // Forward declaration struct CodeLoc; -enum CompilerWarningType { +enum CompilerWarningType : uint8_t { UNUSED_FUNCTION, UNUSED_PROCEDURE, UNUSED_METHOD, diff --git a/src/util/FileUtil.cpp b/src/util/FileUtil.cpp index d5a0fbfb8..808d9e393 100644 --- a/src/util/FileUtil.cpp +++ b/src/util/FileUtil.cpp @@ -5,7 +5,6 @@ #include #include -#include #include diff --git a/src/util/GlobalDefinitions.h b/src/util/GlobalDefinitions.h index 5894c830e..14cc8995f 100644 --- a/src/util/GlobalDefinitions.h +++ b/src/util/GlobalDefinitions.h @@ -13,13 +13,15 @@ #define ALWAYS_INLINE __attribute__((always_inline)) // Casts a pointer to another pointer type and asserts that the cast was successful in debug mode -template -ALWAYS_INLINE static T spice_pointer_cast(auto source) { +template ALWAYS_INLINE static T spice_pointer_cast(auto source) { static_assert(std::is_pointer_v, "Source is not a pointer type"); assert(dynamic_cast(source) != nullptr); return static_cast(source); } +// Fail with an assertion error message +#define assert_fail(msg) assert(false && msg) + #ifdef __GNUC__ #pragma GCC diagnostic pop #endif diff --git a/src/visualizer/ASTVisualizer.h b/src/visualizer/ASTVisualizer.h index e85414013..51859f258 100644 --- a/src/visualizer/ASTVisualizer.h +++ b/src/visualizer/ASTVisualizer.h @@ -113,7 +113,7 @@ class ASTVisualizer : private CompilerPass, public AbstractASTVisitor { std::string parentNodeId; // Private methods - template >> std::string buildNode(const T *node) { + template std::string buildNode(const T *node) requires std::is_base_of_v { std::stringstream result; // Prepare strings diff --git a/test/test-files/typechecker/structs/error-default-value-not-compiletime/exception.out b/test/test-files/typechecker/structs/error-default-value-not-compiletime/exception.out index 293fe87ba..50757e6dd 100644 --- a/test/test-files/typechecker/structs/error-default-value-not-compiletime/exception.out +++ b/test/test-files/typechecker/structs/error-default-value-not-compiletime/exception.out @@ -2,7 +2,7 @@ Unresolved soft errors: There are unresolved errors. Please fix them and recompile. [Error|Semantic] ./test-files/typechecker/structs/error-default-value-not-compiletime/source.spice:4:5: -Field default value no compiletime constant: Default values must be computable at compile time +Field default value no compile time constant: Default values must be computable at compile time 4 int i = test() ^^^^^^^^^^^^^^