Add support for static_assert
Add C11's _Static_assert and static_assert macro. This is like #error, but is handled at a later stage of translation, so it is possible to check sizes of types, values of enums, etc. https://en.cppreference.com/w/c/language/_Static_assert https://port70.net/~nsz/c/c11/n1570.html#6.7.10
This commit is contained in:
committed by
Oliver Schmidt
parent
c72fa735b9
commit
3df6c383c0
@@ -61,6 +61,7 @@
|
||||
#include "pragma.h"
|
||||
#include "preproc.h"
|
||||
#include "standard.h"
|
||||
#include "staticassert.h"
|
||||
#include "symtab.h"
|
||||
|
||||
|
||||
@@ -108,6 +109,12 @@ static void Parse (void)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check for a _Static_assert */
|
||||
if (CurTok.Tok == TOK_STATIC_ASSERT) {
|
||||
ParseStaticAssert ();
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Read variable defs and functions */
|
||||
ParseDeclSpec (&Spec, SC_EXTERN | SC_STATIC, T_INT);
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
#include "pragma.h"
|
||||
#include "scanner.h"
|
||||
#include "standard.h"
|
||||
#include "staticassert.h"
|
||||
#include "symtab.h"
|
||||
#include "wrappedcall.h"
|
||||
#include "typeconv.h"
|
||||
@@ -935,6 +936,13 @@ static SymEntry* ParseStructDecl (const char* Name)
|
||||
|
||||
/* Get the type of the entry */
|
||||
DeclSpec Spec;
|
||||
|
||||
/* Check for a _Static_assert */
|
||||
if (CurTok.Tok == TOK_STATIC_ASSERT) {
|
||||
ParseStaticAssert ();
|
||||
continue;
|
||||
}
|
||||
|
||||
InitDeclSpec (&Spec);
|
||||
ParseTypeSpec (&Spec, -1, T_QUAL_NONE);
|
||||
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include "locals.h"
|
||||
#include "stackptr.h"
|
||||
#include "standard.h"
|
||||
#include "staticassert.h"
|
||||
#include "symtab.h"
|
||||
#include "typeconv.h"
|
||||
#include "input.h"
|
||||
@@ -511,6 +512,13 @@ void DeclareLocals (void)
|
||||
** declarations.
|
||||
*/
|
||||
DeclSpec Spec;
|
||||
|
||||
/* Check for a _Static_assert */
|
||||
if (CurTok.Tok == TOK_STATIC_ASSERT) {
|
||||
ParseStaticAssert ();
|
||||
continue;
|
||||
}
|
||||
|
||||
ParseDeclSpec (&Spec, SC_AUTO, T_INT);
|
||||
if ((Spec.Flags & DS_DEF_STORAGE) != 0 && /* No storage spec */
|
||||
(Spec.Flags & DS_DEF_TYPE) != 0 && /* No type given */
|
||||
|
||||
@@ -86,6 +86,7 @@ static const struct Keyword {
|
||||
unsigned char Std; /* Token supported in which standards? */
|
||||
} Keywords [] = {
|
||||
{ "_Pragma", TOK_PRAGMA, TT_C89 | TT_C99 | TT_CC65 }, /* !! */
|
||||
{ "_Static_assert", TOK_STATIC_ASSERT, TT_CC65 }, /* C11 */
|
||||
{ "__AX__", TOK_AX, TT_C89 | TT_C99 | TT_CC65 },
|
||||
{ "__A__", TOK_A, TT_C89 | TT_C99 | TT_CC65 },
|
||||
{ "__EAX__", TOK_EAX, TT_C89 | TT_C99 | TT_CC65 },
|
||||
|
||||
@@ -173,6 +173,7 @@ typedef enum token_t {
|
||||
TOK_WCSCONST,
|
||||
|
||||
TOK_ATTRIBUTE,
|
||||
TOK_STATIC_ASSERT,
|
||||
TOK_FAR,
|
||||
TOK_NEAR,
|
||||
TOK_A,
|
||||
|
||||
96
src/cc65/staticassert.c
Normal file
96
src/cc65/staticassert.c
Normal file
@@ -0,0 +1,96 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* staticassert.h */
|
||||
/* */
|
||||
/* _Static_assert handling for the cc65 C compiler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* Copyright 2020 Google LLC */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
/* warranty. In no event will the authors be held liable for any damages */
|
||||
/* arising from the use of this software. */
|
||||
/* */
|
||||
/* Permission is granted to anyone to use this software for any purpose, */
|
||||
/* including commercial applications, and to alter it and redistribute it */
|
||||
/* freely, subject to the following restrictions: */
|
||||
/* */
|
||||
/* 1. The origin of this software must not be misrepresented; you must not */
|
||||
/* claim that you wrote the original software. If you use this software */
|
||||
/* in a product, an acknowledgment in the product documentation would be */
|
||||
/* appreciated but is not required. */
|
||||
/* 2. Altered source versions must be plainly marked as such, and must not */
|
||||
/* be misrepresented as being the original software. */
|
||||
/* 3. This notice may not be removed or altered from any source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* cc65 */
|
||||
#include "error.h"
|
||||
#include "expr.h"
|
||||
#include "litpool.h"
|
||||
#include "scanner.h"
|
||||
#include "staticassert.h"
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* _Static_assert handling functions */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
void ParseStaticAssert ()
|
||||
{
|
||||
/*
|
||||
** static_assert-declaration ::=
|
||||
** _Static_assert ( constant-expression , string-literal ) ;
|
||||
*/
|
||||
ExprDesc Expr;
|
||||
int failed;
|
||||
|
||||
/* Skip the _Static_assert token itself */
|
||||
CHECK (CurTok.Tok == TOK_STATIC_ASSERT);
|
||||
NextToken ();
|
||||
|
||||
/* We expect an opening paren */
|
||||
if (!ConsumeLParen ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Parse assertion condition */
|
||||
ConstAbsIntExpr (hie1, &Expr);
|
||||
failed = !Expr.IVal;
|
||||
|
||||
/* We expect a comma */
|
||||
if (!ConsumeComma ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* String literal */
|
||||
if (CurTok.Tok != TOK_SCONST) {
|
||||
Error ("String literal expected for static_assert message");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Issue an error including the message if the static_assert failed. */
|
||||
if (failed) {
|
||||
Error ("static_assert failed '%s'", GetLiteralStr (CurTok.SVal));
|
||||
}
|
||||
|
||||
/* Consume the string constant, now that we don't need it anymore.
|
||||
** This should never fail since we checked the token type above.
|
||||
*/
|
||||
if (!Consume (TOK_SCONST, "String literal expected")) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Closing paren and semi-colon needed */
|
||||
ConsumeRParen ();
|
||||
ConsumeSemi ();
|
||||
}
|
||||
51
src/cc65/staticassert.h
Normal file
51
src/cc65/staticassert.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* staticassert.h */
|
||||
/* */
|
||||
/* _Static_assert handling for the cc65 C compiler */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* Copyright 2020 Google LLC */
|
||||
/* */
|
||||
/* */
|
||||
/* This software is provided 'as-is', without any expressed or implied */
|
||||
/* warranty. In no event will the authors be held liable for any damages */
|
||||
/* arising from the use of this software. */
|
||||
/* */
|
||||
/* Permission is granted to anyone to use this software for any purpose, */
|
||||
/* including commercial applications, and to alter it and redistribute it */
|
||||
/* freely, subject to the following restrictions: */
|
||||
/* */
|
||||
/* 1. The origin of this software must not be misrepresented; you must not */
|
||||
/* claim that you wrote the original software. If you use this software */
|
||||
/* in a product, an acknowledgment in the product documentation would be */
|
||||
/* appreciated but is not required. */
|
||||
/* 2. Altered source versions must be plainly marked as such, and must not */
|
||||
/* be misrepresented as being the original software. */
|
||||
/* 3. This notice may not be removed or altered from any source */
|
||||
/* distribution. */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
#ifndef STATICASSERT_H
|
||||
#define STATICASSERT_H
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
void ParseStaticAssert (void);
|
||||
/* Handle _Static_assert. These are a C11 feature. */
|
||||
|
||||
|
||||
|
||||
/* End of staticassert.h */
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user