Fixed timing of #pragma charmap.
Now it is immediately applied and affects almost all characters and string literals after it. Exceptions: - String literals as the message of a static assertion or inline assembler code (only the required one, not any optional formatted arguments) in an asm() expression are not translated with either #pragma charmap or target presets. - String literals used for preprocessor directives or as the result of stringized macro arguments are never translated.
This commit is contained in:
@@ -417,6 +417,9 @@ void AsmStatement (void)
|
|||||||
** a string literal in parenthesis.
|
** a string literal in parenthesis.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
|
/* Prevent from translating the inline code string literal in asm */
|
||||||
|
NoCharMap = 1;
|
||||||
|
|
||||||
/* Skip the ASM */
|
/* Skip the ASM */
|
||||||
NextToken ();
|
NextToken ();
|
||||||
|
|
||||||
@@ -431,9 +434,15 @@ void AsmStatement (void)
|
|||||||
|
|
||||||
/* Need left parenthesis */
|
/* Need left parenthesis */
|
||||||
if (!ConsumeLParen ()) {
|
if (!ConsumeLParen ()) {
|
||||||
|
NoCharMap = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We have got the inline code string untranslated, now reenable string
|
||||||
|
** literal translation for string arguments (if any).
|
||||||
|
*/
|
||||||
|
NoCharMap = 0;
|
||||||
|
|
||||||
/* String literal */
|
/* String literal */
|
||||||
if (CurTok.Tok != TOK_SCONST) {
|
if (CurTok.Tok != TOK_SCONST) {
|
||||||
|
|
||||||
|
|||||||
@@ -1336,8 +1336,6 @@ static void Primary (ExprDesc* E)
|
|||||||
/* String literal */
|
/* String literal */
|
||||||
if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) {
|
if ((Flags & E_EVAL_UNEVAL) != E_EVAL_UNEVAL) {
|
||||||
E->V.LVal = UseLiteral (CurTok.SVal);
|
E->V.LVal = UseLiteral (CurTok.SVal);
|
||||||
/* Translate into target charset */
|
|
||||||
TranslateLiteral (E->V.LVal);
|
|
||||||
} else {
|
} else {
|
||||||
E->V.LVal = CurTok.SVal;
|
E->V.LVal = CurTok.SVal;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -245,9 +245,6 @@ static void DefineBitFieldData (StructInitData* SI)
|
|||||||
|
|
||||||
static void DefineStrData (Literal* Lit, unsigned Count)
|
static void DefineStrData (Literal* Lit, unsigned Count)
|
||||||
{
|
{
|
||||||
/* Translate into target charset */
|
|
||||||
TranslateLiteral (Lit);
|
|
||||||
|
|
||||||
/* Output the data */
|
/* Output the data */
|
||||||
g_defbytes (GetLiteralStr (Lit), Count);
|
g_defbytes (GetLiteralStr (Lit), Count);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1096,8 +1096,12 @@ void ConsumePragma (void)
|
|||||||
/* Skip the _Pragma token */
|
/* Skip the _Pragma token */
|
||||||
NextToken ();
|
NextToken ();
|
||||||
|
|
||||||
|
/* Prevent from translating string literals in _Pragma */
|
||||||
|
++InPragmaParser;
|
||||||
|
|
||||||
/* We expect an opening paren */
|
/* We expect an opening paren */
|
||||||
if (!ConsumeLParen ()) {
|
if (!ConsumeLParen ()) {
|
||||||
|
--InPragmaParser;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1115,6 +1119,8 @@ void ConsumePragma (void)
|
|||||||
ParsePragmaString ();
|
ParsePragmaString ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--InPragmaParser;
|
||||||
|
|
||||||
/* Closing paren needed */
|
/* Closing paren needed */
|
||||||
ConsumeRParen ();
|
ConsumeRParen ();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,10 +70,12 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static Token SavedTok; /* Saved token */
|
static Token SavedTok; /* Saved token */
|
||||||
Token CurTok; /* The current token */
|
Token CurTok; /* The current token */
|
||||||
Token NextTok; /* The next token */
|
Token NextTok; /* The next token */
|
||||||
int PPParserRunning; /* Is tokenizer used by the preprocessor */
|
int PPParserRunning; /* Is tokenizer used by the preprocessor */
|
||||||
|
int NoCharMap; /* Disable literal translation */
|
||||||
|
unsigned InPragmaParser; /* Depth of pragma parser calling */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -455,7 +457,7 @@ static void CharConst (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Translate into target charset */
|
/* Translate into target charset */
|
||||||
NextTok.IVal = SignExtendChar (TgtTranslateChar (C));
|
NextTok.IVal = SignExtendChar (C);
|
||||||
|
|
||||||
/* Character constants have type int */
|
/* Character constants have type int */
|
||||||
NextTok.Type = type_int;
|
NextTok.Type = type_int;
|
||||||
@@ -798,6 +800,15 @@ static void GetNextInputToken (void)
|
|||||||
{
|
{
|
||||||
ident token;
|
ident token;
|
||||||
|
|
||||||
|
if (!NoCharMap && !InPragmaParser) {
|
||||||
|
/* Translate string and character literals into target charset */
|
||||||
|
if (NextTok.Tok == TOK_SCONST || NextTok.Tok == TOK_WCSCONST) {
|
||||||
|
TranslateLiteral (NextTok.SVal);
|
||||||
|
} else if (NextTok.Tok == TOK_CCONST || NextTok.Tok == TOK_WCCONST) {
|
||||||
|
NextTok.IVal = SignExtendChar (TgtTranslateChar (NextTok.IVal));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Current token is the lookahead token */
|
/* Current token is the lookahead token */
|
||||||
if (CurTok.LI) {
|
if (CurTok.LI) {
|
||||||
ReleaseLineInfo (CurTok.LI);
|
ReleaseLineInfo (CurTok.LI);
|
||||||
|
|||||||
@@ -219,9 +219,11 @@ struct Token {
|
|||||||
const Type* Type; /* Type if integer or float constant */
|
const Type* Type; /* Type if integer or float constant */
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Token CurTok; /* The current token */
|
extern Token CurTok; /* The current token */
|
||||||
extern Token NextTok; /* The next token */
|
extern Token NextTok; /* The next token */
|
||||||
extern int PPParserRunning; /* Is tokenizer used by the preprocessor */
|
extern int PPParserRunning; /* Is tokenizer used by the preprocessor */
|
||||||
|
extern int NoCharMap; /* Disable literal translation */
|
||||||
|
extern unsigned InPragmaParser; /* Depth of pragma parser calling */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -72,9 +72,15 @@ void ParseStaticAssert ()
|
|||||||
** support the C2X syntax with only an expression.
|
** support the C2X syntax with only an expression.
|
||||||
*/
|
*/
|
||||||
if (CurTok.Tok == TOK_COMMA) {
|
if (CurTok.Tok == TOK_COMMA) {
|
||||||
/* Skip the comma. */
|
/* Prevent from translating the message string literal */
|
||||||
|
NoCharMap = 1;
|
||||||
|
|
||||||
|
/* Skip the comma and get the next token */
|
||||||
NextToken ();
|
NextToken ();
|
||||||
|
|
||||||
|
/* Reenable string literal translation */
|
||||||
|
NoCharMap = 0;
|
||||||
|
|
||||||
/* String literal */
|
/* String literal */
|
||||||
if (CurTok.Tok != TOK_SCONST) {
|
if (CurTok.Tok != TOK_SCONST) {
|
||||||
Error ("String literal expected for static_assert message");
|
Error ("String literal expected for static_assert message");
|
||||||
|
|||||||
@@ -1,9 +1,39 @@
|
|||||||
/* Bug #2151 - #pragma causes errors when used within functions */
|
/* Bug #2151 - #pragma causes errors when used within functions */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#pragma charmap(0x61, 0x61)
|
||||||
|
_Static_assert('A'==
|
||||||
|
#pragma charmap(0x61, 0x41)
|
||||||
|
'a'
|
||||||
|
#pragma charmap(0x61, 0x42)
|
||||||
|
,
|
||||||
|
#pragma charmap(0x61, 0x61)
|
||||||
|
"charmap failed");
|
||||||
|
|
||||||
|
char str[] =
|
||||||
|
"a"
|
||||||
|
#pragma charmap(0x61, 0x42)
|
||||||
|
"a"
|
||||||
|
#pragma charmap(0x61, 0x43)
|
||||||
|
"a"
|
||||||
|
#pragma charmap(0x61, 0x61)
|
||||||
|
;
|
||||||
|
|
||||||
|
unsigned failures;
|
||||||
|
|
||||||
#pragma bss-name("BSS1")
|
#pragma bss-name("BSS1")
|
||||||
int
|
int
|
||||||
#pragma code-name("CODE_WUT")
|
#pragma code-name("CODE_WUT")
|
||||||
main _Pragma("message(\"_Pragma note\")")
|
main _Pragma
|
||||||
|
#pragma charmap(0x61, 0x32)
|
||||||
|
(
|
||||||
|
"message(\"_Pragma string"
|
||||||
|
/* Concatenated string literals in _Pragma is a cc65 extension */
|
||||||
|
" unaffected by charmap\")"
|
||||||
|
)
|
||||||
|
#pragma charmap(0x61, 0x61)
|
||||||
(
|
(
|
||||||
void
|
void
|
||||||
_Pragma _Pragma (
|
_Pragma _Pragma (
|
||||||
@@ -20,9 +50,27 @@ _Pragma _Pragma (
|
|||||||
#pragma bss-name("BSS2")
|
#pragma bss-name("BSS2")
|
||||||
static
|
static
|
||||||
#pragma zpsym ("y")
|
#pragma zpsym ("y")
|
||||||
int x; // TODO: currently in "BSS", but supposed to be in "BSS2"?
|
int x; // TODO: currently in "BSS", but supposed to be in "BSS2"?
|
||||||
x = 0;
|
x = 0;
|
||||||
return x + y;
|
|
||||||
|
if (memcmp(str, "aBC", 3))
|
||||||
|
{
|
||||||
|
++failures;
|
||||||
|
printf("%3s\n", str);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x + y != 0)
|
||||||
|
{
|
||||||
|
++failures;
|
||||||
|
printf("%d\n", x + y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failures != 0)
|
||||||
|
{
|
||||||
|
printf("faiures: %d\n", failures);
|
||||||
|
}
|
||||||
|
|
||||||
|
return failures;
|
||||||
#pragma bss-name("BSS")
|
#pragma bss-name("BSS")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user