From bd6db608023d3f53c1f52dd25c3f5ef4b2dd46c7 Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Thu, 20 Jul 2023 14:46:10 +0200 Subject: [PATCH] Add iostream library --- include/opp/iostream.cpp | 1046 +++++++++++++++++++++++++++++++ include/opp/iostream.h | 238 +++++++ oscar64/Declaration.cpp | 13 +- oscar64/NativeCodeGenerator.cpp | 13 +- oscar64/Parser.cpp | 29 +- 5 files changed, 1325 insertions(+), 14 deletions(-) create mode 100644 include/opp/iostream.cpp create mode 100644 include/opp/iostream.h diff --git a/include/opp/iostream.cpp b/include/opp/iostream.cpp new file mode 100644 index 0000000..88cc988 --- /dev/null +++ b/include/opp/iostream.cpp @@ -0,0 +1,1046 @@ +#include "iostream.h" + +ios::ios(void) + : mFlags(0), mState(0), mWidth(0), mPrecision(6), mFill(' ') +{} + +ios::~ios(void) +{ + +} + +char ios::fill(void) +{ + return mFill; +} + +char ios::fill(char fillch) +{ + char c = mFill; + mFill = fillch; + return c; +} + +char ios::width() const +{ + return mWidth; +} + +char ios::width(char wide) +{ + char w = mWidth; + mWidth = wide; + return w; +} + +char ios::precision() const +{ + return mPrecision; +} + +char ios::precision(char wide) +{ + char w = mPrecision; + mPrecision = wide; + return w; +} + +ios::fmtflags ios::flags(void) const +{ + return mFlags; +} + +ios::fmtflags ios::flags(ios::fmtflags f) +{ + fmtflags pf = mFlags; + mFlags = f; + return pf; +} + +ios::fmtflags ios::setf(ios::fmtflags f) +{ + fmtflags pf = mFlags; + mFlags |= f; + return pf; +} + +ios::fmtflags ios::setf(ios::fmtflags f, ios::fmtflags m) +{ + fmtflags pf = mFlags; + mFlags = (mFlags & ~m) | f; + return pf; +} + +ios::fmtflags ios::unsetf(ios::fmtflags f) +{ + fmtflags pf = mFlags; + mFlags &= ~f; + return pf; +} + +bool ios::good(void) const +{ + return mState == goodbit; +} + +bool ios::eof(void) const +{ + return (mState & eofbit) != 0; +} + +bool ios::fail(void) const +{ + return (mState & (badbit | failbit)) != 0; +} + +bool ios::bad(void) const +{ + return (mState & badbit) != 0; +} + +bool ios::operator!(void) const +{ + return fail(); +} + +ios::operator bool(void) +{ + return !fail(); +} + + +ios::statebits ios::rdstate(void) const +{ + return mState; +} + +void ios::clear(void) +{ + mState = goodbit; +} + + + + +ostream & endl(ostream & os) +{ + os.put('\n'); + return os; +} + + +iosetf setf(ios::fmtflags flags) +{ + return iosetf(flags); +} + +ostream & operator<<(ostream & os, const iosetf & s) +{ + os.setf(s.flags); + return os; +} + +iosetw setw(char width) +{ + return iosetw(width); +} + +ostream & operator<<(ostream & os, const iosetw & s) +{ + os.width(s.width); + return os; +} + + +iosetprecision setprecision(char precision) +{ + return iosetprecision(precision); +} + +ostream & operator<<(ostream & os, const iosetprecision & s) +{ + os.precision(s.precision); + return os; +} + + +iosetfill setfill(char fill) +{ + return iosetfill(fill); +} + +ostream & operator<<(ostream & os, const iosetfill & s) +{ + os.fill(s.fill); + return os; +} + +ostream::ostream(void) + {} + + +void ostream::bput(char ch) +{ +} + +ostream & ostream::put(char c) +{ + bput(c); + return * this; +} + +ostream & ostream::write(const char * s, int n) +{ + for(int i=0; i prefix) + bput(buffer[--size]); + } + + if (adj != left) + { + while (r > 0) + { + bput(mFill); + r--; + } + } + + while (size > 0) + bput(buffer[--size]); + + while (r > 0) + { + bput(mFill); + r--; + } + + mFlags = 0; + mWidth = 0; + mFill = ' '; +} + +void ostream::numput(unsigned n, char sign) +{ + char buffer[10]; + + char base = 10; + if (mFlags & hex) + base = 16; + else if (mFlags & oct) + base = 8; + + char i = 0; + char o = 'a' - 10; + if (mFlags & uppercase) + o = 'A' - 10; + + while (n) + { + char d = n % base; + n /= base; + + if (d < 10) + d += '0'; + else + d += o; + buffer[i++] = d; + } + + if (!i) + buffer[i++] = '0'; + char prefix = i; + if (sign) + buffer[i++] = sign; + + putnum(buffer, prefix, i); +} + +void ostream::numput(unsigned long n, char sign) +{ + char buffer[20]; + + char base = 10; + if (mFlags & hex) + base = 16; + else if (mFlags & oct) + base = 8; + + char i = 0; + char o = 'a' - 10; + if (mFlags & uppercase) + o = 'A' - 10; + + while (n) + { + char d = n % base; + n /= base; + + if (d < 10) + d += '0'; + else + d += o; + buffer[i++] = d; + } + + if (!i) + buffer[i++] = '0'; + char prefix = i; + if (sign) + buffer[i++] = sign; + + putnum(buffer, prefix, i); +} + + +ostream & ostream::operator<<(bool val) +{ + if (val) + bput('1'); + else + bput('0'); + return *this; +} + +ostream & ostream::operator<<(int val) +{ + if (val < 0) + numput((unsigned)-val, '-'); + else if (mFlags & showpos) + numput((unsigned)val, '+'); + else + numput((unsigned)val, 0); + return *this; +} + +ostream & ostream::operator<<(unsigned val) +{ + numput(val, 0); + return *this; +} + +ostream & ostream::operator<<(long val) +{ + if (val < 0) + numput(-val, '-'); + else if (mFlags & showpos) + numput(val, '+'); + else + numput(val, 0); + return *this; +} + +ostream & ostream::operator<<(unsigned long val) +{ + numput(val, 0); + return *this; +} + +static float fround5[] = { + 0.5e-0, 0.5e-1, 0.5e-2, 0.5e-3, 0.5e-4, 0.5e-5, 0.5e-6 +}; + +ostream & ostream::operator<<(float val) +{ + char buffer[20]; + + char d = 0; + + float f = val; + + if (f < 0.0) + { + f = -f; + buffer[d++] = '-'; + } + else if (mFlags & showpos) + buffer[d++] = '+'; + + char prefix = d; + + if (isinf(f)) + { + buffer[d++] = 'I'; + buffer[d++] = 'N'; + buffer[d++] = 'F'; + } + else + { + int exp = 0; + + char fdigits = mPrecision; + + if (f != 0.0) + { + while (f >= 1000.0) + { + f /= 1000; + exp += 3; + } + + while (f < 1.0) + { + f *= 1000; + exp -= 3; + } + + while (f >= 10.0) + { + f /= 10; + exp ++; + } + + } + + char digits = fdigits + 1; + bool fexp = mFlags & scientific; + + if (!(mFlags & fixed)) + { + if (exp > 3 || exp < 0) + fexp = true; + } + + if (!fexp) + { + while (exp < 0) + { + f /= 10.0; + exp++; + } + + digits = fdigits + exp + 1; + + if (digits < 7) + f += fround5[digits - 1]; + else + f += fround5[6]; + + if (f >= 10.0) + { + f /= 10.0; + fdigits--; + } + } + else + { + if (digits < 7) + f += fround5[digits - 1]; + else + f += fround5[6]; + + if (f >= 10.0) + { + f /= 10.0; + exp ++; + } + } + + + char pdigits = digits - fdigits; + + if (digits > 20) + digits = 20; + + if (pdigits == 0) + buffer[d++] = '0'; + + for(char i=0; i 6) + buffer[d++] = '0'; + else + { + int c = (int)f; + f -= (float)c; + f *= 10.0; + buffer[d++] = c + '0'; + } + } + + if (fexp) + { + buffer[d++] = 'E'; + if (exp < 0) + { + buffer[d++] = '-'; + exp = -exp; + } + else + buffer[d++] = '+'; + + buffer[d++] = exp / 10 + '0'; + buffer[d++] = exp % 10 + '0'; + } + } + + char r = 0; + if (d < mWidth) + r = mWidth - d; + + fmtflags adj = mFlags & adjustfield; + + char i = 0; + if (adj == internal) + { + while (i < prefix) + bput(buffer[i++]); + } + + if (adj != left) + { + while (r > 0) + { + bput(mFill); + r--; + } + } + + while (i < d) + bput(buffer[i++]); + + while (r > 0) + { + bput(mFill); + r--; + } + + mFlags = 0; + mWidth = 0; + mFill = ' '; + + return *this; +} + +ostream & ostream::operator<<(const char * p) +{ + char i = 0; + while (p[i]) + bput(p[i++]); + return *this; +} + +ostream & ostream::operator<<(const string & s) +{ + for(char i=0; i ' ') + { + unget(); + return; + } + } +} + + + +istream & istream::get(char & c) +{ + c = get(); + return *this; +} + +istream & istream::get(char * s, char size) +{ + return get(s, size, '\n'); +} + +istream & istream::get(char * s, char size, char delim) +{ + char i = 0; + while (i + 1 < size) + { + char c = get(); + if (c == delim) + { + unget(); + break; + } + s[i++] = c; + } + if (size) + s[i++] = 0; + return *this; +} + +istream & istream::getline(char * s, char size) +{ + return getline(s, size, '\n'); +} + +istream & istream::getline(char * s, char size, char delim) +{ + char i = 0; + while (i + 1 < size) + { + char c = get(); + if (c == delim) + break; + s[i++] = c; + } + if (size) + s[i++] = 0; + return *this; +} + +istream & istream::ignore(char size) +{ + ignore(size, '\n'); + return *this; +} + +istream & istream::ignore(char size, char delim) +{ + while (size) + { + char c = get(); + if (c == delim) + break; + size--; + } + + return *this; +} + +istream & istream::operator>>(bool & val) +{ + return *this; +} + +unsigned istream::getnum(void) +{ + doskipws(); + + fmtflags bflags = mFlags & basefield; + + char base = 10; + if (bflags == hex) + base = 16; + else if (bflags == oct) + base = 8; + + unsigned n = 0; + bool sign = false; + + char ch = get(); + if (ch == '-') + { + sign = true; + ch = get(); + } + else if (ch == '+') + ch = get(); + + if (ch == '0') + { + if (bflags == 0) + { + base = 8; + ch = get(); + if (ch == 'x' || ch == 'X') + { + base = 16; + ch = get(); + } + } + } + + bool digits = false; + for(;;) + { + if (ch >= '0' && ch <= '9') + n = n * base + (ch - '0'); + else if (base > 10 && ch >= 'A' && ch <= 'F') + n = n * base + (ch - 'A' + 10); + else if (base > 10 && ch >= 'a' && ch <= 'f') + n = n * base + (ch - 'a' + 10); + else + break; + ch = get(); + digits = true; + } + unget(); + + if (!digits) + mState |= failbit; + + if (sign) + return -n; + else + return n; +} + +unsigned long istream::getnuml(void) +{ + doskipws(); + + fmtflags bflags = mFlags & basefield; + + char base = 10; + if (bflags == hex) + base = 16; + else if (bflags == oct) + base = 8; + + unsigned long n = 0; + bool sign = false; + + char ch = get(); + if (ch == '-') + { + sign = true; + ch = get(); + } + else if (ch == '+') + ch = get(); + + if (ch == '0') + { + if (bflags == 0) + { + base = 8; + ch = get(); + if (ch == 'x' || ch == 'X') + { + base = 16; + ch = get(); + } + } + } + + bool digits = false; + for(;;) + { + if (ch >= '0' && ch <= '9') + n = n * base + (ch - '0'); + else if (base > 10 && ch >= 'A' && ch <= 'F') + n = n * base + (ch - 'A' + 10); + else if (base > 10 && ch >= 'a' && ch <= 'f') + n = n * base + (ch - 'a' + 10); + else + break; + ch = get(); + digits = true; + } + unget(); + + if (!digits) + mState |= failbit; + + if (sign) + return -n; + else + return n; +} + +float istream::getnumf(void) +{ + doskipws(); + + char cs = get(); + + bool sign = false; + if (cs == '-') + { + sign = true; + cs = get(); + } + else if (cs == '+') + cs = get(); + + if (cs >= '0' && cs <= '9' || cs == '.') + { + float vf = 0; + while (cs >= '0' && cs <= '9') + { + vf = vf * 10 + (int)(cs - '0'); + cs = get(); + } + + if (cs == '.') + { + float digits = 1.0; + cs = get(); + while (cs >= '0' && cs <= '9') + { + vf = vf * 10 + (int)(cs - '0'); + digits *= 10; + cs = get(); + } + vf /= digits; + } + + char e = 0; + bool eneg = false; + + if (cs == 'e' || cs == 'E') + { + cs = get(); + if (cs == '-') + { + eneg = true; + cs = get(); + } + else if (cs == '+') + { + cs = get(); + } + + while (cs >= '0' && cs <= '9') + { + e = e * 10 + cs - '0'; + cs = get(); + } + + } + + if (e) + { + if (eneg) + { + while (e > 6) + { + vf /= 1000000.0; + e -= 6; + } + vf /= tpow10[e]; + } + else + { + while (e > 6) + { + vf *= 1000000.0; + e -= 6; + } + vf *= tpow10[e]; + } + } + + if (sign) + return -vf; + else + return vf; + } + else + mState |= failbit; + + return 0; +} + +istream & istream::operator>>(int & val) +{ + val = getnum(); + return *this; +} + +istream & istream::operator>>(unsigned & val) +{ + val = getnum(); + return *this; +} + +istream & istream::operator>>(long & val) +{ + val = getnuml(); + return *this; +} + +istream & istream::operator>>(unsigned long & val) +{ + val = getnuml(); + return *this; +} + +istream & istream::operator>>(float & val) +{ + val = getnumf(); + return *this; +} + +istream & istream::operator>>(char * p) +{ + doskipws(); + char i = 0; + char c = get(); + while (c > ' ') + { + p[i++] = c; + c = get(); + } + return *this; +} + +cistream::cistream(void) +{} + +void cistream::refill(void) +{ + mBufferFill = 0; + mBufferPos = 0; + + char ch; + while (mBufferFill < 32) + { + char ch = getchar(); + mBuffer[mBufferFill++] = ch; + if (ch == '\n') + break; + } +} + +ostringstream::ostringstream(void) +{ + mBuffer = nullptr; + mBFill = mBSize = 0; +} + +ostringstream::~ostringstream(void) +{ + free(mBuffer); +} + +void ostringstream::bput(char ch) +{ + if (!mBuffer) + { + mBSize = 16; + mBFill = 0; + mBuffer = malloc(16); + } + else if (mBFill == mBSize) + { + mBSize *= 2; + char * b = malloc(mBSize); + for(char i=0; i mBSize) + { + free(mBuffer); + mBSize = mBFill; + mBuffer = malloc(mBSize); + } + str.copyseg(mBuffer, 0, mBFill); +} + +istringstream::istringstream(const string & str) + : mString(str), mSPos(0) +{} + +istringstream::~istringstream(void) +{} + +string istringstream::str(void) const +{ + return mString; +} + +void istringstream::str(const string & str) +{ + mString = str; + mSPos = 0; +} + + +void istringstream::refill(void) +{ + mBufferFill = 0; + mBufferPos = 0; + + char ch; + while (mSPos < mString.size() && mBufferFill < 32) + { + mBuffer[mBufferFill++] = mString[mSPos++]; + } +} diff --git a/include/opp/iostream.h b/include/opp/iostream.h new file mode 100644 index 0000000..b2cb0eb --- /dev/null +++ b/include/opp/iostream.h @@ -0,0 +1,238 @@ +#ifndef OPP_IOSTREAM_H +#define OPP_IOSTREAM_H + +#include + +class ios +{ +public: + + ios(void); + virtual ~ios(void); + + char fill() const; + char fill(char cillch); + + char width() const; + char width(char wide); + + char precision() const; + char precision(char prec); + + enum fmtflags + { + boolalpha = 0x0001, + dec = 0x0002, + fixed = 0x0004, + hex = 0x0008, + internal = 0x0010, + left = 0x0020, + oct = 0x0040, + right = 0x0080, + scientific = 0x0100, + showbase = 0x0200, + showpoint = 0x0400, + showpos = 0x0800, + skipws = 0x1000, + unitbuf = 0x2000, + uppercase = 0x3000, + + adjustfield = 0x00b0, + basefield = 0x004a, + floatfield = 0x0104 + }; + + enum statebits + { + goodbit = 0, + badbit = 1, + eofbit = 2, + failbit = 4, + }; + + fmtflags flags(void) const; + fmtflags flags(fmtflags f); + + fmtflags setf(fmtflags f); + fmtflags setf(fmtflags f, fmtflags m); + fmtflags unsetf(fmtflags f); + + bool good(void) const; + bool eof(void) const; + bool fail(void) const; + bool bad(void) const; + + bool operator!(void) const; + operator bool(void); + + statebits rdstate(void) const; + void clear(void); + +protected: + fmtflags mFlags; + statebits mState; + char mWidth; + char mPrecision; + char mFill; +}; + +class ostream; + +typedef ostream & (* manip)(ostream &); + +class ostream : public ios +{ +public: + ostream(void); + + ostream & put(char c); + ostream & write(const char * s, int n); + + ostream & operator<<(bool val); + ostream & operator<<(int val); + ostream & operator<<(unsigned val); + ostream & operator<<(long val); + ostream & operator<<(unsigned long val); + ostream & operator<<(float val); + + ostream & operator<<(const char * p); + ostream & operator<<(const string & s); + + ostream & operator<<(manip m); +protected: + void putnum(const char * buffer, char prefix, char size); + void numput(unsigned n, char sign); + void numput(unsigned long n, char sign); + + virtual void bput(char ch); +}; + +class istream : public ios +{ +public: + char get(void); + istream & get(char & c); + istream & get(char * s, char size); + istream & get(char * s, char size, char delim); + istream & getline(char * s, char size); + istream & getline(char * s, char size, char delim); + istream & ignore(char size); + istream & ignore(char size, char delim); + istream & putback(char c); + istream & unget(void); + + istream & operator>>(bool & val); + istream & operator>>(int & val); + istream & operator>>(unsigned & val); + istream & operator>>(long & val); + istream & operator>>(unsigned long & val); + istream & operator>>(float & val); + + istream & operator>>(char * p); + + istream(void); +protected: + char mBuffer[32]; + char mBufferPos, mBufferFill; + + virtual void refill(void); + + unsigned getnum(void); + unsigned long getnuml(void); + float getnumf(void); + + void doskipws(void); +}; + +class costream : public ostream +{ +public: + costream(void); + +protected: + void bput(char ch); +}; + +class cistream : public istream +{ +public: + cistream(void); + +protected: + void refill(void); +}; + +class ostringstream : public ostream +{ +public: + ostringstream(void); + ~ostringstream(void); + + string str(void) const; + void str(const string & str); +protected: + void bput(char ch); + + char * mBuffer; + char mBFill, mBSize; +}; + +class istringstream : public istream +{ +public: + istringstream(const string & str); + ~istringstream(void); + + string str(void) const; + void str(const string & str); +protected: + virtual void refill(void); + + string mString; + char mSPos; +}; + +ostream & endl(ostream & os); + +struct iosetf { + ios::fmtflags flags; + iosetf(ios::fmtflags flags_) : flags(flags_) {} +}; + +ostream & operator<<(ostream & os, const iosetf & s); + +iosetf setf(ios::fmtflags flags); + +struct iosetw { + char width; + iosetw(char width_) : width(width_) {} +}; + +iosetw setw(char width); + +ostream & operator<<(ostream & os, const iosetw & s); + +struct iosetprecision { + char precision; + iosetprecision(char precision_) : precision(precision_) {} +}; + +iosetprecision setprecision(char precision); + +ostream & operator<<(ostream & os, const iosetprecision & s); + + +struct iosetfill { + char fill; + iosetfill(char fill_) : fill(fill_) {} +}; + +iosetfill setfill(char fill); + +ostream & operator<<(ostream & os, const iosetfill & s); + + + +#pragma compile("iostream.cpp"); + +#endif diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index 21953ac..240ffb2 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -1284,7 +1284,18 @@ bool Declaration::IsSame(const Declaration* dec) const else if (mType == DT_TYPE_ENUM) return mIdent == dec->mIdent; else if (mType == DT_TYPE_POINTER || mType == DT_TYPE_ARRAY) - return this->Stride() == dec->Stride() && mBase->IsSame(dec->mBase); + { + if (mBase->mType == DT_TYPE_STRUCT && dec->mBase->mType == DT_TYPE_STRUCT) + { + if (mBase->mQualIdent == dec->mBase->mQualIdent && + (mBase->mFlags & (DTF_CONST | DTF_VOLATILE)) == (dec->mBase->mFlags & (DTF_CONST | DTF_VOLATILE))) + return true; + else + return false; + } + else + return this->Stride() == dec->Stride() && mBase->IsSame(dec->mBase); + } else if (mType == DT_TYPE_REFERENCE) return mBase->IsSame(dec->mBase); else if (mType == DT_TYPE_STRUCT) diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index c854b74..2f78137 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -478,6 +478,9 @@ bool NativeCodeInstruction::IsUsedResultInstructions(NumberSet& requiredTemps) if (mType == ASMIT_RTS) { #if 1 + if (mFlags & NCIF_USE_CPU_REG_A) + requiredTemps += CPU_REG_A; + if (mFlags & NCIF_LOWER) { requiredTemps += BC_REG_ACCU; @@ -4189,6 +4192,12 @@ void NativeCodeInstruction::FilterRegUsage(NumberSet& requiredTemps, NumberSet& if (mType == ASMIT_RTS) { #if 1 + if (mFlags & NCIF_USE_CPU_REG_A) + { + if (!providedTemps[CPU_REG_A]) + requiredTemps += CPU_REG_A; + } + if (mFlags & NCIF_LOWER) { if (!providedTemps[BC_REG_ACCU + 0]) requiredTemps += BC_REG_ACCU + 0; @@ -15800,7 +15809,7 @@ bool NativeCodeBasicBlock::CrossBlockStoreLoadBypass(NativeCodeProcedure* proc) { mVisited = true; - if (mTrueJump && !mFalseJump && mIns.Size() > 0 && mTrueJump->mIns.Size() > 0) + if (mTrueJump && mTrueJump->mTrueJump && !mFalseJump && mIns.Size() > 0 && mTrueJump->mIns.Size() > 0) { int sz = mIns.Size(); @@ -40463,7 +40472,7 @@ void NativeCodeProcedure::Compile(InterCodeProcedure* proc) #if 1 if (mExitBlock->mIns[0].mFlags == NCIF_LOWER) { - mExitBlock->mIns[0].mFlags = 0; + mExitBlock->mIns[0].mFlags = NCIF_USE_CPU_REG_A; mExitBlock->mIns.Insert(0, NativeCodeInstruction(nullptr, ASMIT_LDA, ASMIM_ZERO_PAGE, BC_REG_ACCU)); mExitBlock->mExitRegA = true; proc->mLinkerObject->mFlags |= LOBJF_RET_REG_A; diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 8edbff8..4ececfa 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -207,6 +207,8 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt) Declaration* mlast = nullptr; for (;;) { + do {} while (ConsumeTokenIf(TK_SEMICOLON)); + if (ConsumeTokenIf(TK_PUBLIC)) { flags &= ~(DTF_PRIVATE | DTF_PROTECTED); @@ -252,9 +254,6 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt) if (mCompilerOptions & COPT_NATIVE) mdec->mFlags |= DTF_NATIVE; - if (!(mdec->mFlags & DTF_DEFINED)) - ConsumeToken(TK_SEMICOLON); - AddMemberFunction(dec, mdec); } else if ((mCompilerOptions & COPT_CPLUSPLUS) && mdec->mType == DT_ANON) @@ -329,14 +328,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt) } else { - Declaration* mdec = dec->mParams; - while (mdec) - { - mdec->mOffset++; - mdec = mdec->mNext; - } vdec->mOffset = 0; - dec->mSize++; } vdec->mDefaultConstructor = new Declaration(dec->mLocation, DT_CONST_INTEGER); @@ -349,8 +341,19 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt) vdec->mIdent = dec->mIdent; vdec->mQualIdent = dec->mQualIdent; mCompilationUnits->mVTableScope->Insert(vdec->mQualIdent, vdec); + } - dec->mVTable = vdec; + dec->mVTable = vdec; + + if (!dec->mBase) + { + Declaration* mdec = dec->mParams; + while (mdec) + { + mdec->mOffset++; + mdec = mdec->mNext; + } + dec->mSize++; } dec->mScope->Iterate([=](const Ident* ident, Declaration* mdec) @@ -3636,7 +3639,11 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex if (pdec) { if (!ndec->mBase->IsSame(pdec->mBase)) + { + ndec->mBase->IsSameParams(pdec->mBase); + ndec->mBase->IsSame(pdec->mBase); mErrors->Error(ndec->mLocation, EERR_DECLARATION_DIFFERS, "Function declaration differs", ndec->mIdent); + } else if (ndec->mFlags & ~pdec->mFlags & (DTF_HWINTERRUPT | DTF_INTERRUPT | DTF_FASTCALL | DTF_NATIVE)) mErrors->Error(ndec->mLocation, EERR_DECLARATION_DIFFERS, "Function call type declaration differs", ndec->mIdent); else