diff --git a/autotest/makefile b/autotest/makefile index 567d436..15de67c 100644 --- a/autotest/makefile +++ b/autotest/makefile @@ -50,5 +50,11 @@ autorefreturn: autorefreturn.cpp $(OSCAR64_CC) -e -Os -n $< $(OSCAR64_CC) -e -O3 -n $< +copyconstructor: copyconstructor.cpp + $(OSCAR64_CC) -e -O2 -n $< + $(OSCAR64_CC) -e -O0 -n $< + $(OSCAR64_CC) -e -Os -n $< + $(OSCAR64_CC) -e -O3 -n $< + clean: @$(RM) *.asm *.bcs *.int *.lbl *.map *.prg diff --git a/oscar64/Errors.h b/oscar64/Errors.h index 18c7e1c..a4d19bc 100644 --- a/oscar64/Errors.h +++ b/oscar64/Errors.h @@ -127,6 +127,8 @@ enum ErrorID EERR_INVALID_CLASS_INITIALIZER, EERR_CALL_OF_DELETED_FUNCTION, + EERR_STATIC_ASSERT, + EFATAL_GENERIC = 4000, EFATAL_OUT_OF_MEMORY, EFATAL_MACRO_EXPANSION_DEPTH, diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index e6eedbd..e73dec4 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -6231,7 +6231,10 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod proc->mNativeProcedure = true; if (dec->mFlags & DTF_INTERRUPT) + { proc->mInterrupt = true; + proc->mCompilerOptions &= ~COPT_OPTIMIZE_OUTLINE; + } if (dec->mFlags & DTF_HWINTERRUPT) proc->mHardwareInterrupt = true; diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index ea00e2b..ab0fcb6 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -58519,7 +58519,7 @@ void NativeCodeGenerator::OutlineFunctions(void) for (int i = 0; i < mProcedures.Size(); i++) { - if (mProcedures[i]->mCompilerOptions & COPT_OPTIMIZE_OUTLINE) + if ((mProcedures[i]->mCompilerOptions & COPT_OPTIMIZE_OUTLINE)) mProcedures[i]->AddToSuffixTree(mapper, tree); } tree->AddParents(nullptr); diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index e9662d6..c26c25c 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -303,6 +303,10 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt, Declaratio { Declaration * tdec = ParseTemplateDeclaration(pthis); } + else if (ConsumeTokenIf(TK_STATIC_ASSERT)) + { + ParseStaticAssert(); + } else { Declaration* mdec = ParseDeclaration(nullptr, false, false, true, pthis); @@ -9541,6 +9545,32 @@ Expression* Parser::ParseParenthesisExpression(void) return exp; } +void Parser::ParseStaticAssert(void) +{ + if (ConsumeToken(TK_OPEN_PARENTHESIS)) + { + Expression* exp = ParseExpression(false); + exp = exp->ConstantFold(mErrors, mDataSection); + if (exp->mType == EX_CONSTANT && exp->mDecType->IsIntegerType() && exp->mDecValue->mInteger) + { + if (ConsumeTokenIf(TK_COMMA)) + mScanner->NextToken(); + } + else + { + if (ConsumeTokenIf(TK_COMMA) && mScanner->mToken == TK_STRING) + { + mErrors->Error(mScanner->mLocation, EERR_STATIC_ASSERT, "static assertion failed: ", (const char*)mScanner->mTokenString); + mScanner->NextToken(); + } + else + mErrors->Error(mScanner->mLocation, EERR_STATIC_ASSERT, "static assertion failed"); + } + + ConsumeToken(TK_CLOSE_PARENTHESIS); + } +} + Expression* Parser::CheckOperatorOverload(Expression* exp) { if (mCompilerOptions & COPT_CPLUSPLUS) @@ -11094,6 +11124,10 @@ Expression* Parser::ParseStatement(void) exp->mLeft = ParseParenthesisExpression(); ConsumeToken(TK_SEMICOLON); break; + case TK_STATIC_ASSERT: + mScanner->NextToken(); + ParseStaticAssert(); + break; case TK_GOTO: #if 1 exp = new Expression(mScanner->mLocation, EX_GOTO); @@ -14304,6 +14338,11 @@ void Parser::ParseNamespace(void) mScanner->NextToken(); ParseNamespace(); } + else if (mScanner->mToken == TK_STATIC_ASSERT) + { + mScanner->NextToken(); + ParseStaticAssert(); + } else ParseDeclaration(nullptr, true, false, false); } @@ -14419,6 +14458,11 @@ void Parser::Parse(void) mScanner->NextToken(); ParseNamespace(); } + else if (mScanner->mToken == TK_STATIC_ASSERT) + { + mScanner->NextToken(); + ParseStaticAssert(); + } else ParseDeclaration(nullptr, true, false, false); } diff --git a/oscar64/Parser.h b/oscar64/Parser.h index 13e4139..404264e 100644 --- a/oscar64/Parser.h +++ b/oscar64/Parser.h @@ -159,6 +159,7 @@ protected: Expression* ParseListExpression(bool lhs, Declaration * params = nullptr); Expression* ParseParenthesisExpression(void); + void ParseStaticAssert(void); Errors* mErrors; Scanner* mScanner; diff --git a/oscar64/Scanner.cpp b/oscar64/Scanner.cpp index 44caa84..def3ef3 100644 --- a/oscar64/Scanner.cpp +++ b/oscar64/Scanner.cpp @@ -51,6 +51,7 @@ const char* TokenNames[] = "'extern'", "'inline'", "'__assume'", + "'static_assert'", "__asm", "__interrupt", @@ -1832,6 +1833,8 @@ void Scanner::NextRawToken(void) mToken = TK_ASM; else if (!strcmp(tkident, "__assume")) mToken = TK_ASSUME; + else if (!strcmp(tkident, "static_assert")) + mToken = TK_STATIC_ASSERT; else if (!strcmp(tkident, "__interrupt")) mToken = TK_INTERRUPT; else if (!strcmp(tkident, "__hwinterrupt")) diff --git a/oscar64/Scanner.h b/oscar64/Scanner.h index caaf9e7..80e1b0d 100644 --- a/oscar64/Scanner.h +++ b/oscar64/Scanner.h @@ -49,6 +49,7 @@ enum Token TK_EXTERN, TK_INLINE, TK_ASSUME, + TK_STATIC_ASSERT, TK_ASM, TK_INTERRUPT,