Merge pull request #47 from alexfru/master

Smaller C: Improve initialization of variables
This commit is contained in:
Serge Vakulenko
2015-05-23 01:50:17 -07:00
2 changed files with 137 additions and 70 deletions

View File

@@ -483,7 +483,6 @@ void GenJumpUncond(int label)
extern int GenWreg; // GenWreg is defined below
#ifndef USE_SWITCH_TAB
STATIC
void GenJumpIfEqual(int val, int label)
{
@@ -495,7 +494,6 @@ void GenJumpIfEqual(int val, int label)
TEMP_REG_B, 0,
MipsOpNumLabel, label);
}
#endif
STATIC
void GenJumpIfZero(int label)

View File

@@ -200,6 +200,8 @@ int vfprintf(FILE*, char*, void*);
#define MAX_INCLUDES 1
#define PREP_STACK_SIZE 1
#define MAX_SEARCH_PATH 1
#undef MAX_STRING_LEN
#define MAX_STRING_LEN (MAX_FILE_NAME_LEN + 3)
#endif
/* +-~* /% &|^! << >> && || < <= > >= == != () *[] ++ -- = += -= ~= *= /= %= &= |= ^= <<= >>= {} ,;: -> ... */
@@ -1301,9 +1303,8 @@ void GetIdent(void)
}
STATIC
int GetString(char terminator, int option)
void GetString(char terminator, int option)
{
int res = tokEof;
char* p = CharQueue;
int ch = '\0';
@@ -1401,11 +1402,11 @@ int GetString(char terminator, int option)
case 'd': // string literal / array of char in expression or initializer
// Dump the char data to the appropriate data section
GenDumpChar(ch & 0xFFu);
// fallthrough
default: // skipped string literal (we may still need the size)
if (TokenStringLen++ == UINT_MAX)
errorStrLen();
break;
default: // skipped string literal
break;
} // endof switch (option)
} // endof while (!(*p == '\0' || *p == terminator || strchr("\n\r", *p)))
@@ -1421,7 +1422,6 @@ int GetString(char terminator, int option)
TokenValueInt = ch & 0xFFu;
TokenValueInt -= (CharIsSigned && TokenValueInt >= 0x80) * 0x100;
res = tokNumInt;
}
else if (option == 'd')
{
@@ -1431,8 +1431,6 @@ int GetString(char terminator, int option)
ShiftCharN(1);
SkipSpace(option != '#');
return res;
}
#ifndef NO_PREPROCESSOR
@@ -1657,7 +1655,8 @@ int GetTokenInner(void)
// parse character and string constants
if (ch == '\'')
{
return GetString(ch, 'd');
GetString(ch, 'd');
return tokNumInt;
}
else if (ch == '"')
{
@@ -2312,13 +2311,20 @@ char* lab2str(char* p, int n)
STATIC
int exprUnary(int tok, int* gotUnary, int commaSeparator, int argOfSizeOf)
{
static int sizeofLevel = 0;
int decl = 0;
*gotUnary = 0;
if (isop(tok) && (isunary(tok) || strchr("&*+-", tok)))
{
int lastTok = tok;
tok = exprUnary(GetToken(), gotUnary, commaSeparator, lastTok == tokSizeof);
int sizeofLevelInc = lastTok == tokSizeof;
sizeofLevel += sizeofLevelInc;
tok = exprUnary(GetToken(), gotUnary, commaSeparator, sizeofLevelInc);
sizeofLevel -= sizeofLevelInc;
if (!*gotUnary)
//error("exprUnary(): primary expression expected after token %s\n", GetTokenName(lastTok));
errorUnexpectedToken(tok);
@@ -2368,15 +2374,18 @@ int exprUnary(int tok, int* gotUnary, int commaSeparator, int argOfSizeOf)
// imitate definition: char #[len] = "...";
if (CurHeaderFooter)
puts2(CurHeaderFooter[1]);
puts2(RoDataHeaderFooter[0]);
if (!sizeofLevel)
{
if (CurHeaderFooter)
puts2(CurHeaderFooter[1]);
puts2(RoDataHeaderFooter[0]);
GenNumLabel(lbl);
GenNumLabel(lbl);
}
do
{
GetString('"', 'd');
GetString('"', sizeofLevel ? 0 : 'd'); // throw away string data inside sizeof, e.g. sizeof "a" or sizeof("a" + 1)
if (len + TokenStringLen < len ||
len + TokenStringLen >= truncUint(-1))
errorStrLen();
@@ -2384,11 +2393,14 @@ int exprUnary(int tok, int* gotUnary, int commaSeparator, int argOfSizeOf)
tok = GetToken();
} while (tok == tokLitStr); // concatenate adjacent string literals
GenZeroData(1, 0);
if (!sizeofLevel)
{
GenZeroData(1, 0);
puts2(RoDataHeaderFooter[1]);
if (CurHeaderFooter)
puts2(CurHeaderFooter[0]);
puts2(RoDataHeaderFooter[1]);
if (CurHeaderFooter)
puts2(CurHeaderFooter[0]);
}
// DONE: can this break incomplete yet declarations???, e.g.: int x[sizeof("az")][5];
PushSyntax2(tokIdent, id = AddNumericIdent(lbl));
@@ -6138,16 +6150,33 @@ int InitVar(int synPtr, int tok)
int p = synPtr, t;
int undoIdents = IdentTableLen;
while ((SyntaxStack[p][0] == tokIdent) | (SyntaxStack[p][0] == tokLocalOfs))
while ((t = SyntaxStack[p][0]), (t == tokIdent) | (t == tokLocalOfs))
p++;
t = SyntaxStack[p][0];
if (t == '[')
switch (t)
{
case '[':
// Initializers for aggregates must be enclosed in braces,
// except for arrays of char initialized with string literals,
// in which case braces are optional
if (tok != '{')
{
t = SyntaxStack[p + 3][0];
if ((tok != tokLitStr) | ((t != tokChar) & (t != tokUChar) & (t != tokSChar)))
errorUnexpectedToken(tok);
}
tok = InitArray(p, tok);
else if (t == tokStructPtr)
break;
case tokStructPtr:
// Initializers for aggregates must be enclosed in braces
if (tok != '{')
errorUnexpectedToken(tok);
tok = InitStruct(p, tok);
else
break;
default:
tok = InitScalar(p, tok);
break;
}
if (!strchr(",;", tok))
errorUnexpectedToken(tok);
@@ -6165,12 +6194,27 @@ int InitScalar(int synPtr, int tok)
int oldssp = SyntaxStackCnt;
int undoIdents = IdentTableLen;
int ttop;
int braces = 0;
// Initializers for scalars can be optionally enclosed in braces
if (tok == '{')
{
braces = 1;
tok = GetToken();
}
tok = ParseExpr(tok, &gotUnary, &synPtr2, &constExpr, &exprVal, ',', 0);
if (!gotUnary)
errorUnexpectedToken(tok);
if (braces)
{
if (tok != '}')
errorUnexpectedToken(tok);
tok = GetToken();
}
scalarTypeCheck(synPtr2);
ttop = stack[sp - 1][0];
@@ -6236,14 +6280,6 @@ int InitArray(int synPtr, int tok)
braces = 1;
tok = GetToken();
}
else
{
// Only fully-bracketed (sic) initialization of arrays is supported,
// except for arrays of char initialized with string literals
// (the string literals may be optionally enclosed in braces)
if (!(arrOfChar & (tok == tokLitStr)))
errorUnexpectedToken(tok);
}
if (arrOfChar & (tok == tokLitStr))
{
@@ -6292,8 +6328,13 @@ int InitArray(int synPtr, int tok)
tok = InitScalar(elementTypePtr, tok);
}
if (++elementCnt > elementsRequired && elementsRequired)
error("Too many array initializers\n");
// Last element?
if (++elementCnt >= elementsRequired && elementsRequired)
{
if (braces & (tok == ','))
tok = GetToken();
break;
}
if (tok == ',')
tok = GetToken();
@@ -6301,13 +6342,15 @@ int InitArray(int synPtr, int tok)
errorUnexpectedToken(tok);
}
if (!elementCnt)
errorUnexpectedToken('}');
if (braces)
{
if ((!elementCnt) | (tok != '}'))
errorUnexpectedToken(tok);
tok = GetToken();
}
if (elementCnt < elementsRequired)
GenZeroData((elementsRequired - elementCnt) * elementSz, 0);
tok = GetToken();
}
// Store the element count if it's an incomplete array
@@ -6322,15 +6365,29 @@ int InitStruct(int synPtr, int tok)
{
int isUnion;
unsigned size, ofs = 0;
int braces = 0;
int c = 1;
synPtr = SyntaxStack[synPtr][1];
isUnion = SyntaxStack[synPtr++][0] == tokUnion;
size = SyntaxStack[++synPtr][1];
synPtr += 3; // step inside the {} body of the struct/union
if (tok != '{')
errorUnexpectedToken(tok);
tok = GetToken();
if (tok == '{')
{
braces = 1;
tok = GetToken();
}
// Find the first member
while (c)
{
int t = SyntaxStack[synPtr][0];
c += (t == '(') - (t == ')') + (t == '{') - (t == '}');
if (c == 1 && t == tokMemberIdent)
break;
synPtr++;
}
while (tok != '}')
{
@@ -6338,18 +6395,6 @@ int InitStruct(int synPtr, int tok)
int elementTypePtr, elementType;
unsigned elementOfs, elementSz;
// Find the next member or the closing brace
while (c)
{
int t = SyntaxStack[synPtr][0];
c += (t == '(') - (t == ')') + (t == '{') - (t == '}');
if (c == 1 && t == tokMemberIdent)
break;
synPtr++;
}
if (!c)
errorUnexpectedToken(tok); // too many initializers
elementOfs = SyntaxStack[++synPtr][1];
elementTypePtr = ++synPtr;
elementType = SyntaxStack[elementTypePtr][0];
@@ -6374,25 +6419,42 @@ int InitStruct(int synPtr, int tok)
ofs = elementOfs + elementSz;
// Find the next member or the closing brace
while (c)
{
int t = SyntaxStack[synPtr][0];
c += (t == '(') - (t == ')') + (t == '{') - (t == '}');
if (c == 1 && t == tokMemberIdent)
break;
synPtr++;
}
// Last member?
// Only one member (first) is initialized in unions explicitly
if ((!c) | isUnion)
{
if (braces & (tok == ','))
tok = GetToken();
break;
}
if (tok == ',')
tok = GetToken();
else if (tok != '}')
errorUnexpectedToken(tok);
// Only one member (first) is initialized in unions explicitly
if (isUnion && tok != '}')
errorUnexpectedToken(tok);
}
if (!ofs)
errorUnexpectedToken('}');
if (braces)
{
if ((!ofs) | (tok != '}'))
errorUnexpectedToken(tok);
tok = GetToken();
}
// Implicit initialization of the rest and trailing padding
if (ofs < size)
GenZeroData(size - ofs, 0);
tok = GetToken();
return tok;
}
@@ -6808,21 +6870,13 @@ int ParseDecl(int tok, unsigned structInfo[4], int cast, int label)
sp = 0;
push2('(', SizeOfWord * 3);
push2(tokLocalOfs, SyntaxStack[lastSyntaxPtr + 1][1]);
push(',');
push2(tokIdent, AddNumericIdent(initLabel));
push(',');
push2(tokNumUint, sz);
push(',');
push2(tokIdent, AddNumericIdent(StructCpyLabel));
push2(')', SizeOfWord * 3);
GenExpr();
@@ -6831,6 +6885,14 @@ int ParseDecl(int tok, unsigned structInfo[4], int cast, int label)
else if (hasInit & !needsGlobalInit)
{
int gotUnary, synPtr, constExpr, exprVal;
int brace = 0;
// Initializers for scalars can be optionally enclosed in braces
if ((!isStruct) & (tok == '{'))
{
brace = 1;
tok = GetToken();
}
// ParseExpr() will transform the initializer expression into an assignment expression here
tok = ParseExpr(tok, &gotUnary, &synPtr, &constExpr, &exprVal, '=', SyntaxStack[lastSyntaxPtr][1]);
@@ -6838,6 +6900,13 @@ int ParseDecl(int tok, unsigned structInfo[4], int cast, int label)
if (!gotUnary)
errorUnexpectedToken(tok);
if (brace)
{
if (tok != '}')
errorUnexpectedToken(tok);
tok = GetToken();
}
if (!isStruct)
{
// This is a special case for initialization of integers smaller than int.