Fix flat initializer for stacked arrays
This commit is contained in:
parent
b3be121f41
commit
47531ac5e8
|
@ -1658,7 +1658,7 @@ uint8* Parser::ParseStringLiteral(int & msize)
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression* Parser::ParseInitExpression(Declaration* dtype)
|
Expression* Parser::ParseInitExpression(Declaration* dtype, bool inner)
|
||||||
{
|
{
|
||||||
Expression* exp = nullptr;
|
Expression* exp = nullptr;
|
||||||
Declaration* dec;
|
Declaration* dec;
|
||||||
|
@ -1676,8 +1676,33 @@ Expression* Parser::ParseInitExpression(Declaration* dtype)
|
||||||
else
|
else
|
||||||
mErrors->Error(mScanner->mLocation, EERR_UNDEFINED_OBJECT, "Constant for undefined anonymous type");
|
mErrors->Error(mScanner->mLocation, EERR_UNDEFINED_OBJECT, "Constant for undefined anonymous type");
|
||||||
}
|
}
|
||||||
if (ConsumeTokenIf(TK_OPEN_BRACE))
|
|
||||||
|
if (mScanner->mToken == TK_STRING && dtype->mType == DT_TYPE_ARRAY && dtype->mBase->mType == DT_TYPE_INTEGER && dtype->mBase->mSize == 1)
|
||||||
{
|
{
|
||||||
|
int ds = dtype->mSize;
|
||||||
|
uint8* d = ParseStringLiteral(ds);
|
||||||
|
|
||||||
|
if (!(dtype->mFlags & DTF_DEFINED))
|
||||||
|
{
|
||||||
|
dtype->mFlags |= DTF_DEFINED;
|
||||||
|
dtype->mSize = int(ds);
|
||||||
|
}
|
||||||
|
|
||||||
|
dec = new Declaration(mScanner->mLocation, DT_CONST_DATA);
|
||||||
|
dec->mBase = dtype;
|
||||||
|
dec->mSize = dtype->mSize;
|
||||||
|
dec->mSection = mDataSection;
|
||||||
|
|
||||||
|
dec->mData = d;
|
||||||
|
|
||||||
|
if (ds > dtype->mSize + 1)
|
||||||
|
mErrors->Error(mScanner->mLocation, EERR_CONSTANT_INITIALIZER, "String constant is too large for char array");
|
||||||
|
}
|
||||||
|
else if ((inner && !dtype->mDefaultConstructor) || ConsumeTokenIf(TK_OPEN_BRACE))
|
||||||
|
{
|
||||||
|
if (inner && ConsumeTokenIf(TK_OPEN_BRACE))
|
||||||
|
inner = false;
|
||||||
|
|
||||||
dec = new Declaration(mScanner->mLocation, DT_CONST_STRUCT);
|
dec = new Declaration(mScanner->mLocation, DT_CONST_STRUCT);
|
||||||
dec->mBase = dtype;
|
dec->mBase = dtype;
|
||||||
dec->mSize = dtype->mSize;
|
dec->mSize = dtype->mSize;
|
||||||
|
@ -1732,7 +1757,7 @@ Expression* Parser::ParseInitExpression(Declaration* dtype)
|
||||||
ConsumeToken(TK_ASSIGN);
|
ConsumeToken(TK_ASSIGN);
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression* texp = ParseInitExpression(dtype->mBase);
|
Expression* texp = ParseInitExpression(dtype->mBase, true);
|
||||||
texp = texp->ConstantFold(mErrors, mDataSection);
|
texp = texp->ConstantFold(mErrors, mDataSection);
|
||||||
for (int i = 0; i < nrep; i++)
|
for (int i = 0; i < nrep; i++)
|
||||||
{
|
{
|
||||||
|
@ -1748,8 +1773,15 @@ Expression* Parser::ParseInitExpression(Declaration* dtype)
|
||||||
size += dtype->mBase->mSize;
|
size += dtype->mBase->mSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (inner && (dtype->mFlags & DTF_DEFINED) && size >= dtype->mSize)
|
||||||
|
break;
|
||||||
if (!ConsumeTokenIf(TK_COMMA))
|
if (!ConsumeTokenIf(TK_COMMA))
|
||||||
break;
|
break;
|
||||||
|
if (inner && mScanner->mToken == TK_OPEN_BRACKET)
|
||||||
|
{
|
||||||
|
mScanner->UngetToken(TK_COMMA);
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (mScanner->mToken == TK_CLOSE_BRACE)
|
if (mScanner->mToken == TK_CLOSE_BRACE)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1826,6 +1858,8 @@ Expression* Parser::ParseInitExpression(Declaration* dtype)
|
||||||
while (!mdec && path.Size())
|
while (!mdec && path.Size())
|
||||||
mdec = path.Pop()->mParams;
|
mdec = path.Pop()->mParams;
|
||||||
}
|
}
|
||||||
|
else if (inner)
|
||||||
|
break;
|
||||||
else if (!ConsumeTokenIf(TK_COMMA))
|
else if (!ConsumeTokenIf(TK_COMMA))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1834,34 +1868,17 @@ Expression* Parser::ParseInitExpression(Declaration* dtype)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!inner)
|
||||||
|
{
|
||||||
|
ConsumeTokenIf(TK_COMMA);
|
||||||
ConsumeToken(TK_CLOSE_BRACE);
|
ConsumeToken(TK_CLOSE_BRACE);
|
||||||
|
}
|
||||||
|
|
||||||
if (last)
|
if (last)
|
||||||
last->mNext = nullptr;
|
last->mNext = nullptr;
|
||||||
else
|
else
|
||||||
dec->mParams = nullptr;
|
dec->mParams = nullptr;
|
||||||
}
|
}
|
||||||
else if (mScanner->mToken == TK_STRING && dtype->mType == DT_TYPE_ARRAY && dtype->mBase->mType == DT_TYPE_INTEGER && dtype->mBase->mSize == 1)
|
|
||||||
{
|
|
||||||
int ds = dtype->mSize;
|
|
||||||
uint8* d = ParseStringLiteral(ds);
|
|
||||||
|
|
||||||
if (!(dtype->mFlags & DTF_DEFINED))
|
|
||||||
{
|
|
||||||
dtype->mFlags |= DTF_DEFINED;
|
|
||||||
dtype->mSize = int(ds);
|
|
||||||
}
|
|
||||||
|
|
||||||
dec = new Declaration(mScanner->mLocation, DT_CONST_DATA);
|
|
||||||
dec->mBase = dtype;
|
|
||||||
dec->mSize = dtype->mSize;
|
|
||||||
dec->mSection = mDataSection;
|
|
||||||
|
|
||||||
dec->mData = d;
|
|
||||||
|
|
||||||
if (ds > dtype->mSize + 1)
|
|
||||||
mErrors->Error(mScanner->mLocation, EERR_CONSTANT_INITIALIZER, "String constant is too large for char array");
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
exp = ParseRExpression();
|
exp = ParseRExpression();
|
||||||
|
|
|
@ -71,7 +71,7 @@ protected:
|
||||||
Declaration* ParseStructDeclaration(uint64 flags, DecType dt, Declaration* ptempl = nullptr);
|
Declaration* ParseStructDeclaration(uint64 flags, DecType dt, Declaration* ptempl = nullptr);
|
||||||
|
|
||||||
Declaration* CopyConstantInitializer(int offset, Declaration* dtype, Expression* exp);
|
Declaration* CopyConstantInitializer(int offset, Declaration* dtype, Expression* exp);
|
||||||
Expression* ParseInitExpression(Declaration* dtype);
|
Expression* ParseInitExpression(Declaration* dtype, bool inner = false);
|
||||||
Expression* ParseDeclarationExpression(Declaration* pdec);
|
Expression* ParseDeclarationExpression(Declaration* pdec);
|
||||||
|
|
||||||
Declaration* ParsePostfixDeclaration(void);
|
Declaration* ParsePostfixDeclaration(void);
|
||||||
|
|
|
@ -478,6 +478,12 @@ bool Scanner::IsIntegerToken(void) const
|
||||||
return mToken == TK_INTEGER || mToken == TK_INTEGERU || mToken == TK_INTEGERL || mToken == TK_INTEGERUL;
|
return mToken == TK_INTEGER || mToken == TK_INTEGERU || mToken == TK_INTEGERL || mToken == TK_INTEGERUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Scanner::UngetToken(Token token)
|
||||||
|
{
|
||||||
|
mUngetToken = mToken;
|
||||||
|
mToken = token;
|
||||||
|
}
|
||||||
|
|
||||||
void Scanner::NextToken(void)
|
void Scanner::NextToken(void)
|
||||||
{
|
{
|
||||||
if (mReplay)
|
if (mReplay)
|
||||||
|
|
|
@ -240,6 +240,7 @@ public:
|
||||||
const char* TokenName(Token token) const;
|
const char* TokenName(Token token) const;
|
||||||
|
|
||||||
void NextToken(void);
|
void NextToken(void);
|
||||||
|
void UngetToken(Token token);
|
||||||
|
|
||||||
void BeginRecord(void);
|
void BeginRecord(void);
|
||||||
TokenSequence* CompleteRecord(void);
|
TokenSequence* CompleteRecord(void);
|
||||||
|
@ -266,6 +267,7 @@ public:
|
||||||
uint8 * mTokenEmbed;
|
uint8 * mTokenEmbed;
|
||||||
int mTokenEmbedSize;
|
int mTokenEmbedSize;
|
||||||
|
|
||||||
|
Token mUndoToken;
|
||||||
Token mToken;
|
Token mToken;
|
||||||
double mTokenNumber;
|
double mTokenNumber;
|
||||||
int64 mTokenInteger;
|
int64 mTokenInteger;
|
||||||
|
|
Loading…
Reference in New Issue