diff --git a/src/backend/analysis/address.cpp b/src/backend/analysis/address.cpp index 6ec0a88..ffb6e93 100644 --- a/src/backend/analysis/address.cpp +++ b/src/backend/analysis/address.cpp @@ -21,7 +21,7 @@ namespace rat { return n->getType() && n->getType()->isInt() && n->getType()->getIntWidth() == 64; } - bool termLess(const Pair& a, const Pair& b) { + B32 termLess(const Pair& a, const Pair& b) { return a.first->getId() < b.first->getId(); } diff --git a/src/backend/ir/text_parser.cpp b/src/backend/ir/text_parser.cpp index 06538d7..c505296 100644 --- a/src/backend/ir/text_parser.cpp +++ b/src/backend/ir/text_parser.cpp @@ -338,7 +338,7 @@ namespace rat { if(lhs.empty() || lhs[0] != 'v' || !allDigits(lhs.substr(1))) return fail("bad result name '" + lhs + "'"); errno = 0; - unsigned long idv = std::strtoul(lhs.c_str() + 1, nullptr, 10); + U64 idv = std::strtoul(lhs.c_str() + 1, nullptr, 10); if(errno == ERANGE || idv > 0xffffffffUL) return fail("result id out of range '" + lhs + "'"); pn.id = (U32)idv; @@ -366,7 +366,7 @@ namespace rat { if(remainder.empty()) return fail("constant is missing its value: " + line); errno = 0; - char* cend = nullptr; + C8* cend = nullptr; pn.cval = (I64)std::strtoll(remainder.c_str(), &cend, 10); if(cend == remainder.c_str() || errno == ERANGE) return fail("bad constant value '" + remainder + "'"); @@ -383,7 +383,7 @@ namespace rat { if(!allDigits(toks[0].substr(1))) return fail("bad proj index '" + toks[0] + "'"); errno = 0; - unsigned long pj = std::strtoul(toks[0].c_str() + 1, nullptr, 10); + U64 pj = std::strtoul(toks[0].c_str() + 1, nullptr, 10); if(errno == ERANGE || pj > 0xffffffffUL) return fail("proj index out of range '" + toks[0] + "'"); pn.projIndex = (U32)pj; @@ -447,7 +447,7 @@ namespace rat { if(laneTok.size() < 2 || laneTok[0] != '#' || !allDigits(laneTok.substr(1))) return fail("malformed lane selector (expected #index): " + line); errno = 0; - unsigned long lane = std::strtoul(laneTok.c_str() + 1, nullptr, 10); + U64 lane = std::strtoul(laneTok.c_str() + 1, nullptr, 10); if(errno == ERANGE || lane > 0xffffffffUL) return fail("lane selector out of range: " + line); pn.projIndex = (U32)lane; // reuse the proj payload slot for the selector diff --git a/src/backend/pass/emit/x86/x86_encode.cpp b/src/backend/pass/emit/x86/x86_encode.cpp index bd1e2eb..5de28cc 100644 --- a/src/backend/pass/emit/x86/x86_encode.cpp +++ b/src/backend/pass/emit/x86/x86_encode.cpp @@ -559,7 +559,7 @@ namespace rat { U32 instCount = 0; for(const MachineBlock& blk : mf.blocks) instCount += (U32)blk.insts.size(); - code.reserve((size_t)instCount * 16u + 64u); // cheap upper estimate + code.reserve((U64)instCount * 16u + 64u); // cheap upper estimate Asm a(code, relocs); reset(mf, fl, a, mf.usedCalleeSaved); diff --git a/src/backend/pass/emit/x86/x86_lower_ops.cpp b/src/backend/pass/emit/x86/x86_lower_ops.cpp index 82b938c..99929a3 100644 --- a/src/backend/pass/emit/x86/x86_lower_ops.cpp +++ b/src/backend/pass/emit/x86/x86_lower_ops.cpp @@ -278,7 +278,7 @@ namespace rat { h ^= x; h *= 1099511628211ull; } - std::snprintf(buf, sizeof buf, "__rat_vec_%016llx", (unsigned long long)h); + std::snprintf(buf, sizeof buf, "__rat_vec_%016lx", (U64)h); String name(buf); if(!mod->getGlobal(name)) { List init = bytes; diff --git a/src/backend/pass/opt/fold.h b/src/backend/pass/opt/fold.h index f7e8cab..675bcd4 100644 --- a/src/backend/pass/opt/fold.h +++ b/src/backend/pass/opt/fold.h @@ -75,7 +75,7 @@ namespace rat { static B32 matchVarConst(Node* n, Opcode want, Node*& base, I64& c); private: List work; - List queued; + List queued; List stack; }; } // namespace rat diff --git a/src/backend/pass/opt/gvn.h b/src/backend/pass/opt/gvn.h index 971cf1d..c012858 100644 --- a/src/backend/pass/opt/gvn.h +++ b/src/backend/pass/opt/gvn.h @@ -31,7 +31,7 @@ namespace rat { }; struct GVNKeyHash { - size_t operator()(const GVNKey& k) const { + U64 operator()(const GVNKey& k) const { U64 h = 1469598103934665603ull; auto mix = [&](U64 v) { h ^= v; @@ -44,7 +44,7 @@ namespace rat { mix(((U64)k.in1) << 32); if(k.sym) mix(std::hash{}(*k.sym)); - return (size_t)h; + return (U64)h; } }; diff --git a/src/backend/pass/opt/sccp.h b/src/backend/pass/opt/sccp.h index c2920ab..963bac6 100644 --- a/src/backend/pass/opt/sccp.h +++ b/src/backend/pass/opt/sccp.h @@ -59,7 +59,7 @@ namespace rat { U32 rewrite(Function& fn); private: List values; // lattice for value producing nodes, Top when unset - List exec; // control nodes proven executable + List exec; // control nodes proven executable List flowWork; // executable control nodes to propagate List ssaWork; // value / if nodes to re-evaluate }; diff --git a/src/backend/pass/opt/slp/slp_packer.cpp b/src/backend/pass/opt/slp/slp_packer.cpp index 1a2b49b..27f11aa 100644 --- a/src/backend/pass/opt/slp/slp_packer.cpp +++ b/src/backend/pass/opt/slp/slp_packer.cpp @@ -295,7 +295,7 @@ namespace rat { // each broadcast then picks its lane in-register instead of touching memory void slp::Packer::coalesceSplats() { struct Cand { - bool operator<(const Cand& o) const { + B32 operator<(const Cand& o) const { if(sig != o.sig) return sig < o.sig; return c < o.c; diff --git a/src/backend/pass/opt/slp/slp_reduce.cpp b/src/backend/pass/opt/slp/slp_reduce.cpp index 48df181..b5f6b53 100644 --- a/src/backend/pass/opt/slp/slp_reduce.cpp +++ b/src/backend/pass/opt/slp/slp_reduce.cpp @@ -36,7 +36,7 @@ namespace rat { // canonical term order: sort by the first leaf load's refined address so // grouping is robust against source-level reassociation struct Keyed { - bool operator<(const Keyed& o) const { + B32 operator<(const Keyed& o) const { if(sig != o.sig) return sig < o.sig; return c < o.c; diff --git a/src/base/core.h b/src/base/core.h index a8dc02a..0a5fe88 100644 --- a/src/base/core.h +++ b/src/base/core.h @@ -34,6 +34,7 @@ namespace rat { using F32 = float; using F64 = double; + using F80 = long double; using C8 = char; using B32 = uint32_t; diff --git a/src/base/test_harness.cpp b/src/base/test_harness.cpp index df840da..14786ea 100644 --- a/src/base/test_harness.cpp +++ b/src/base/test_harness.cpp @@ -7,12 +7,12 @@ namespace rat { namespace detail { - B32 hasSuffix(const String& s, const char* suffix) { + B32 hasSuffix(const String& s, const C8* suffix) { String suf = suffix; return s.size() >= suf.size() && s.compare(s.size() - suf.size(), suf.size(), suf) == 0; } - void collectCases(const String& dir, const char* ext, List& out) { + void collectCases(const String& dir, const C8* ext, List& out) { std::error_code ec; List subdirs; List files; @@ -40,7 +40,7 @@ namespace rat { } } // namespace detail - I32 runTestSuite(I32 argc, char** argv, const TestSuiteSpec& spec) { + I32 runTestSuite(I32 argc, C8** argv, const TestSuiteSpec& spec) { U32 jobs = 1; B32 quiet = false; // -q: only the per-case lines, the caller tallies them List cases; diff --git a/src/base/test_harness.h b/src/base/test_harness.h index c9d88f9..2223696 100644 --- a/src/base/test_harness.h +++ b/src/base/test_harness.h @@ -5,21 +5,21 @@ namespace rat { namespace detail { - B32 hasSuffix(const String& s, const char* suffix); - void collectCases(const String& dir, const char* ext, List& out); + B32 hasSuffix(const String& s, const C8* suffix); + void collectCases(const String& dir, const C8* ext, List& out); String findDir(const List& candidates); } // namespace detail using CaseRunner = Delegate; struct TestSuiteSpec { - const char* tool; // program name - const char* extension; // case file suffix + const C8* tool; // program name + const C8* extension; // case file suffix List dirCandidates; // searched when no paths are given CaseRunner run; // executes a single case }; - I32 runTestSuite(I32 argc, char** argv, const TestSuiteSpec& spec); + I32 runTestSuite(I32 argc, C8** argv, const TestSuiteSpec& spec); } // namespace rat #endif diff --git a/src/compiler/emit/emit.h b/src/compiler/emit/emit.h index 4e0330b..63da2de 100644 --- a/src/compiler/emit/emit.h +++ b/src/compiler/emit/emit.h @@ -106,8 +106,8 @@ namespace rat::cc { B32 evalConstTyped(const Expr* expr, I64& out, CType& ty); B32 evalConstUnary(ExprOp op, I64 v, CType opTy, I64& out, CType& ty); B32 evalConstBinary(ExprOp op, I64 a, CType aTy, I64 b, CType bTy, I64& out, CType& ty); - B32 evalFloatConst(const Expr* expr, long double& out); - void encodeFloatBytes(CType dt, long double v, List& out); + B32 evalFloatConst(const Expr* expr, F80& out); + void encodeFloatBytes(CType dt, F80 v, List& out); B32 evalAddrConst(const Expr* expr, String& symbol, I64& addend); B32 addrConstOf(const Expr* lv, String& symbol, I64& addend); String internString(const Expr* strLit); diff --git a/src/compiler/emit/emit_const.cpp b/src/compiler/emit/emit_const.cpp index 81ce287..20aca9f 100644 --- a/src/compiler/emit/emit_const.cpp +++ b/src/compiler/emit/emit_const.cpp @@ -158,7 +158,7 @@ namespace rat::cc { return false; CType opTy; if(!evalConstTyped(e->cast.operand, out, opTy)) { - long double fv; + F80 fv; if(isFloating(ty) || isPointer(ty) || isAggregate(ty) || ty.isVoid()) return false; if(!evalFloatConst(e->cast.operand, fv)) @@ -211,12 +211,12 @@ namespace rat::cc { return evalConstTyped(e, out, ty); } - B32 Emitter::evalFloatConst(const Expr* e, long double& out) { + B32 Emitter::evalFloatConst(const Expr* e, F80& out) { if(e->kind == ExprKind::IntLit || e->kind == ExprKind::Cast) { I64 iv; CType it; if(evalConstTyped(e, iv, it) && isInteger(it)) { - out = it.isUnsigned() ? (long double)(U64)iv : (long double)iv; + out = it.isUnsigned() ? (F80)(U64)iv : (F80)iv; return true; } } @@ -227,7 +227,7 @@ namespace rat::cc { case ExprKind::Cast: return evalFloatConst(e->cast.operand, out); case ExprKind::Unary: { - long double v; + F80 v; if(!evalFloatConst(e->unary.operand, v)) return false; switch(e->unary.op) { @@ -242,7 +242,7 @@ namespace rat::cc { } } case ExprKind::Binary: { - long double a, b; + F80 a, b; if(!evalFloatConst(e->binary.lhs, a) || !evalFloatConst(e->binary.rhs, b)) return false; switch(e->binary.op) { @@ -268,7 +268,7 @@ namespace rat::cc { if(evalConst(e->ternary.cond, ci)) { taken = ci != 0; } else { - long double cf; + F80 cf; if(!evalFloatConst(e->ternary.cond, cf)) return false; taken = cf != 0; diff --git a/src/compiler/emit/emit_expr.cpp b/src/compiler/emit/emit_expr.cpp index c051a69..836d421 100644 --- a/src/compiler/emit/emit_expr.cpp +++ b/src/compiler/emit/emit_expr.cpp @@ -241,7 +241,7 @@ namespace rat::cc { CType t; t.base = CType::Base::Float; t.bits = e->floatLit.bits; - Node* lit = fn.constFloat(irType(t), (double)e->floatLit.value); + Node* lit = fn.constFloat(irType(t), (F64)e->floatLit.value); if(e->floatLit.imaginary) { CType ct = t; ct.set(CType::Complex); diff --git a/src/compiler/emit/emit_global.cpp b/src/compiler/emit/emit_global.cpp index 1994ab7..65043b9 100644 --- a/src/compiler/emit/emit_global.cpp +++ b/src/compiler/emit/emit_global.cpp @@ -11,7 +11,7 @@ namespace rat::cc { String name = "__ratcc_str" + std::to_string(strCounter++); List init; init.reserve(bytes.size() + cw); - for(char c : bytes) + for(C8 c : bytes) init.push_back((U8)c); for(U32 i = 0; i < cw; ++i) init.push_back(0); @@ -288,7 +288,7 @@ namespace rat::cc { List fbytes; if(dinit) { if(isFloating(d.type)) { - long double dv = 0; + F80 dv = 0; if(!evalFloatConst(dinit, dv)) { fail("initializer for '" + *d.name + "' is not a constant expression"); return false; diff --git a/src/compiler/emit/emit_init_flat.cpp b/src/compiler/emit/emit_init_flat.cpp index 568d560..7a89f4a 100644 --- a/src/compiler/emit/emit_init_flat.cpp +++ b/src/compiler/emit/emit_init_flat.cpp @@ -156,21 +156,21 @@ namespace rat::cc { return true; } - void Emitter::encodeFloatBytes(CType dt, long double v, List& out) { + void Emitter::encodeFloatBytes(CType dt, F80 v, List& out) { if(dt.bits == 32) { - float f = (float)v; + F32 f = (F32)v; const U8* p = (const U8*)&f; for(U32 i = 0; i < sizeof(f); ++i) out.push_back(p[i]); } else if(dt.bits == 128) { // x86 extended precision - long double ld = v; + F80 ld = v; const U8* p = (const U8*)&ld; U32 n = byteSize(dt); // 16 for(U32 i = 0; i < n; ++i) out.push_back(i < 10 ? p[i] : (U8)0); } else { - double d = (double)v; + F64 d = (F64)v; const U8* p = (const U8*)&d; for(U32 i = 0; i < sizeof(d); ++i) out.push_back(p[i]); @@ -185,7 +185,7 @@ namespace rat::cc { return true; U64 bits = 0; if(isFloating(dt)) { - long double d = 0; + F80 d = 0; if(!emit.evalFloatConst(e, d)) { emit.failNonConstInit(); return false; diff --git a/src/compiler/lex/lexer.cpp b/src/compiler/lex/lexer.cpp index 76d7a7f..777b216 100644 --- a/src/compiler/lex/lexer.cpp +++ b/src/compiler/lex/lexer.cpp @@ -5,7 +5,7 @@ namespace rat::cc { namespace detail { // clang-format off - const char* const kTokNames[] = { + const C8* const kTokNames[] = { // literals and specials "eof", "error", "identifier", "int-constant", "float-constant", "char-constant", "string-literal", @@ -26,11 +26,11 @@ namespace rat::cc { static_assert(sizeof(kTokNames) / sizeof(kTokNames[0]) == (U32)TokKind::ShrEq + 1, "kTokNames must cover every TokKind"); - B32 validIntSuffix(const char* s, U32 n) { + B32 validIntSuffix(const C8* s, U32 n) { B32 haveU = false, haveL = false; U32 i = 0; while(i < n) { - char c = s[i]; + C8 c = s[i]; if((c == 'u' || c == 'U') && !haveU) { haveU = true; ++i; @@ -48,10 +48,10 @@ namespace rat::cc { return true; } - B32 validFloatSuffix(const char* s, U32 n) { + B32 validFloatSuffix(const C8* s, U32 n) { B32 haveSize = false, imag = false; for(U32 i = 0; i < n; ++i) { - char c = s[i]; + C8 c = s[i]; if(c == 'f' || c == 'F' || c == 'l' || c == 'L') { if(haveSize) return false; @@ -66,14 +66,14 @@ namespace rat::cc { return true; } - B32 spellingIs(const char* k, const char* s, U32 n) { + B32 spellingIs(const C8* k, const C8* s, U32 n) { U32 i = 0; for(; i < n && k[i] && k[i] == s[i]; ++i) ; return i == n && k[i] == '\0'; } - TokKind keywordKind(const char* s, U32 n) { + TokKind keywordKind(const C8* s, U32 n) { for(U32 k = (U32)TokKind::KwAuto; k <= (U32)TokKind::KwAlignas; ++k) if(spellingIs(kTokNames[k], s, n)) return (TokKind)k; @@ -83,7 +83,7 @@ namespace rat::cc { } } // namespace detail - Lexer::Lexer(const char* src, U32 len) + Lexer::Lexer(const C8* src, U32 len) : src(src), len(len) {} @@ -97,7 +97,7 @@ namespace rat::cc { void Lexer::skipTrivia() { for(;;) { - char c = cur(); + C8 c = cur(); if(c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v') { bump(); } else if(c == '/' && at(pos + 1) == '/') { @@ -146,9 +146,9 @@ namespace rat::cc { if(pos >= len) return finish(tok, TokKind::Eof); - char c = cur(); + C8 c = cur(); if(c == 'L' || c == 'u' || c == 'U') { - char n1 = at(pos + 1); + C8 n1 = at(pos + 1); if(c == 'u' && n1 == '8' && at(pos + 2) == '"') { bump(); // 'u' bump(); // '8' @@ -177,7 +177,7 @@ namespace rat::cc { B32 Lexer::isUcnStart(U32 p) const { if(at(p) != '\\') return false; - char n = at(p + 1); + C8 n = at(p + 1); return n == 'u' || n == 'U'; } @@ -187,7 +187,7 @@ namespace rat::cc { bump(); } else if(isUcnStart(pos)) { bump(); // backslash - char kind = cur(); + C8 kind = cur(); bump(); // 'u' or 'U' U32 ndigits = (kind == 'u') ? 4 : 8; for(U32 k = 0; k < ndigits; ++k) { @@ -283,7 +283,7 @@ namespace rat::cc { return finish(tok, TokKind::FloatConstant); } - Token Lexer::lexQuoted(Token tok, char quote, const char* unterminated, TokKind kind) { + Token Lexer::lexQuoted(Token tok, C8 quote, const C8* unterminated, TokKind kind) { bump(); // opening quote while(pos < len && cur() != quote && cur() != '\n') { if(cur() == '\\') @@ -315,10 +315,10 @@ namespace rat::cc { } Token Lexer::lexPunct(Token tok) { - char c = cur(); + C8 c = cur(); struct Simple { - char c; + C8 c; TokKind kind; }; static const Simple kSimple[] = { @@ -409,5 +409,5 @@ namespace rat::cc { String Lexer::text(const Token& tok) const { return String(src + tok.offset, tok.length); } - const char* tokKindName(TokKind kind) { return detail::kTokNames[(U32)kind]; } + const C8* tokKindName(TokKind kind) { return detail::kTokNames[(U32)kind]; } } // namespace rat::cc diff --git a/src/compiler/lex/lexer.h b/src/compiler/lex/lexer.h index d91173b..26d0050 100644 --- a/src/compiler/lex/lexer.h +++ b/src/compiler/lex/lexer.h @@ -58,11 +58,11 @@ namespace rat::cc { KwReal, // __real__ (extract the real part of a complex value) KwImag, // __imag__ (extract the imaginary part of a complex value) KwTypeof, // typeof / __typeof / __typeof__ (GCC: type of an expr) - KwNoinline, // __rat_noinline__ (marker the preprocessor leaves for __attribute__((noinline))) - KwAlias, // __rat_alias__ (marker the preprocessor leaves for __attribute__((alias(...)))) - KwAsm, // asm / __asm / __asm__ (GNU inline assembly) - KwAlignof, // _Alignof (__alignof__ / __alignof are macros for it) - KwAlignas, // _Alignas (__attribute__((aligned(n))) expands to it too) + KwNoinline, // __rat_noinline__ (marker the preprocessor leaves for __attribute__((noinline))) + KwAlias, // __rat_alias__ (marker the preprocessor leaves for __attribute__((alias(...)))) + KwAsm, // asm / __asm / __asm__ (GNU inline assembly) + KwAlignof, // _Alignof (__alignof__ / __alignof are macros for it) + KwAlignas, // _Alignas (__attribute__((aligned(n))) expands to it too) // punctuators LParen, @@ -122,14 +122,14 @@ namespace rat::cc { }; namespace detail { - B32 validIntSuffix(const char* s, U32 n); - B32 validFloatSuffix(const char* s, U32 n); - B32 spellingIs(const char* k, const char* s, U32 n); - TokKind keywordKind(const char* s, U32 n); + B32 validIntSuffix(const C8* s, U32 n); + B32 validFloatSuffix(const C8* s, U32 n); + B32 spellingIs(const C8* k, const C8* s, U32 n); + TokKind keywordKind(const C8* s, U32 n); } // namespace detail struct Lexer { - Lexer(const char* src, U32 len); + Lexer(const C8* src, U32 len); Token next(); @@ -146,9 +146,9 @@ namespace rat::cc { Token lexFloatSuffix(Token tok); Token lexChar(Token tok); Token lexString(Token tok); - Token lexQuoted(Token tok, char quote, const char* unterminated, TokKind kind); + Token lexQuoted(Token tok, C8 quote, const C8* unterminated, TokKind kind); struct PunctAlt { - char c; + C8 c; TokKind kind; }; Token lexPunct(Token tok); @@ -157,11 +157,11 @@ namespace rat::cc { Token finish(Token tok, TokKind kind); Token fail(Token tok, const String& msg); - char at(U32 i) const { return i < len ? src[i] : '\0'; } - char cur() const { return at(pos); } + C8 at(U32 i) const { return i < len ? src[i] : '\0'; } + C8 cur() const { return at(pos); } B32 isUcnStart(U32 p) const; - const char* src; + const C8* src; U32 len; U32 pos = 0; U32 line = 1; @@ -170,7 +170,7 @@ namespace rat::cc { String errMsg; }; - const char* tokKindName(TokKind kind); + const C8* tokKindName(TokKind kind); } // namespace rat::cc #endif diff --git a/src/compiler/lex/preprocess.cpp b/src/compiler/lex/preprocess.cpp index 82a6931..4e6ecae 100644 --- a/src/compiler/lex/preprocess.cpp +++ b/src/compiler/lex/preprocess.cpp @@ -15,7 +15,7 @@ namespace rat::cc { } String Preprocessor::dirOf(const String& path) { - size_t s = path.find_last_of('/'); + U64 s = path.find_last_of('/'); return s == String::npos ? String() : path.substr(0, s + 1); } @@ -44,7 +44,7 @@ namespace rat::cc { if(isPunct(toks[0], "<")) { angled = true; fname.clear(); - for(size_t k = 1; k < toks.size(); ++k) { + for(U64 k = 1; k < toks.size(); ++k) { if(isPunct(toks[k], ">")) return true; if(k > 1 && toks[k].spaceBefore) @@ -70,9 +70,9 @@ namespace rat::cc { if(isAbsPath(fname)) { tries.push_back(fname); } else { - size_t startDir = 0, best = 0; + U64 startDir = 0, best = 0; if(next) { - for(size_t k = 0; k < opts.includeDirs.size(); ++k) { + for(U64 k = 0; k < opts.includeDirs.size(); ++k) { String d = opts.includeDirs[k]; if(!d.empty() && d.back() != '/') d += '/'; @@ -85,7 +85,7 @@ namespace rat::cc { } else if(!angled) { tries.push_back(curDir.empty() ? fname : curDir + fname); } - for(size_t k = startDir; k < opts.includeDirs.size(); ++k) { + for(U64 k = startDir; k < opts.includeDirs.size(); ++k) { String base = opts.includeDirs[k]; if(!base.empty() && base.back() != '/') base += '/'; @@ -133,7 +133,7 @@ namespace rat::cc { } else if(rest.size() >= 1 && rest[0].kind == Pk::Id && (*rest[0].text == "push_macro" || *rest[0].text == "pop_macro")) { String mname; - for(size_t k = 1; k < rest.size(); ++k) { + for(U64 k = 1; k < rest.size(); ++k) { if(rest[k].kind == Pk::Str) { mname = unquote(*rest[k].text); break; @@ -164,7 +164,7 @@ namespace rat::cc { } String Preprocessor::destringize(const String& lit) { - size_t b = 0, e = lit.size(); + U64 b = 0, e = lit.size(); while(b < e && lit[b] != '"') ++b; // skip optional L prefix if(b < e && lit[b] == '"') @@ -172,7 +172,7 @@ namespace rat::cc { if(e > b && lit[e - 1] == '"') --e; String out; - for(size_t i = b; i < e; ++i) { + for(U64 i = b; i < e; ++i) { if(lit[i] == '\\' && i + 1 < e && (lit[i + 1] == '"' || lit[i + 1] == '\\')) ++i; out += lit[i]; @@ -190,7 +190,7 @@ namespace rat::cc { if(!any) return std::move(toks); List out; - for(size_t i = 0; i < toks.size();) { + for(U64 i = 0; i < toks.size();) { if(toks[i].kind == Pk::Id && *toks[i].text == "_Pragma" && i + 3 < toks.size() && isPunct(toks[i + 1], "(") && toks[i + 2].kind == Pk::Str && isPunct(toks[i + 3], ")")) { List body = lexFragment(destringize(*toks[i + 2].text), intern(path)); @@ -305,10 +305,10 @@ namespace rat::cc { List stack; List textBuf; - size_t i = 0, n = toks.size(); + U64 i = 0, n = toks.size(); while(i < n && ok) { - size_t start = i; - size_t j = i + 1; + U64 start = i; + U64 j = i + 1; while(j < n && !toks[j].bol) ++j; i = j; @@ -324,7 +324,7 @@ namespace rat::cc { flush(textBuf); - size_t d = start + 1; + U64 d = start + 1; if(d >= j) // null directive continue; @@ -368,7 +368,7 @@ namespace rat::cc { doInclude(rest, curDir, true); } else if(name == "error") { String msg; - for(size_t k = 0; k < rest.size(); ++k) { + for(U64 k = 0; k < rest.size(); ++k) { if(k && rest[k].spaceBefore) msg += ' '; msg += *rest[k].text; @@ -402,7 +402,7 @@ namespace rat::cc { time_t now = ::time(nullptr); struct tm* lt = std::localtime(&now); if(lt) { - char buf[64]; + C8 buf[64]; std::strftime(buf, sizeof buf, "%b %e %Y", lt); s.date = String("\"") + buf + "\""; std::strftime(buf, sizeof buf, "%H:%M:%S", lt); @@ -417,7 +417,7 @@ namespace rat::cc { defineSimple("__STDC_VERSION__", "199901L"); // GNU C extensions - auto defineFrag = [&](const char* text) { doDefine(lexFragment(text, intern(""))); }; + auto defineFrag = [&](const C8* text) { doDefine(lexFragment(text, intern(""))); }; defineFrag("__attribute__(x)"); defineFrag("__attribute(x)"); defineFrag("__asm__ asm"); @@ -448,7 +448,7 @@ namespace rat::cc { void Preprocessor::applyCommandLine() { for(const String& d : opts.defines) { - size_t eq = d.find('='); + U64 eq = d.find('='); String left = eq == String::npos ? d : d.substr(0, eq); String right = eq == String::npos ? String("1") : d.substr(eq + 1); List all = lexFragment(left, intern("")); @@ -462,7 +462,7 @@ namespace rat::cc { String Preprocessor::serialize() { String s; - size_t total = 0; + U64 total = 0; for(const PpToken& t : out) if(t.kind != Pk::Placemarker && t.kind != Pk::Eof) total += t.text->size() + 1; diff --git a/src/compiler/lex/preprocess_detail.h b/src/compiler/lex/preprocess_detail.h index e2be74a..ca745b5 100644 --- a/src/compiler/lex/preprocess_detail.h +++ b/src/compiler/lex/preprocess_detail.h @@ -51,7 +51,7 @@ namespace rat::cc { constexpr U32 kMaxIncludeDepth = 200; // 1-2 char fast paths avoid strlen/memcmp - inline B32 isPunct(const PpToken& t, const char* s) { + inline B32 isPunct(const PpToken& t, const C8* s) { if(t.kind != Pk::Punct) return false; const String& x = *t.text; @@ -63,7 +63,7 @@ namespace rat::cc { } String unquote(const String& s); B32 isAbsPath(const String& s); - size_t ucnLen(const String& s, size_t i); + U64 ucnLen(const String& s, U64 i); Pk classify(const String& s); // absolute line correction at an output offset (emitted at splices) @@ -85,9 +85,9 @@ namespace rat::cc { PpSpan(const PpToken* pb, const PpToken* pe) : b(pb), e(pe) {} - size_t size() const { return (size_t)(e - b); } + U64 size() const { return (U64)(e - b); } B32 empty() const { return b == e; } - const PpToken& operator[](size_t i) const { return b[i]; } + const PpToken& operator[](U64 i) const { return b[i]; } }; struct LexResult { @@ -122,7 +122,7 @@ namespace rat::cc { // #if expression evaluator struct Eval { const List& t; - size_t i = 0; + U64 i = 0; String& err; B32 ok = true; B32 live = true; @@ -132,15 +132,15 @@ namespace rat::cc { err(e) {} const PpToken& cur() { return t[i]; } - B32 isOp(const char* s) { return isPunct(cur(), s); } + B32 isOp(const C8* s) { return isPunct(cur(), s); } B32 atEnd() { return cur().kind == Pk::Eof; } void fail(const String& m); Val parsePrimary(); Val parseUnary(); - int prec(const String& op); + I32 prec(const String& op); Val apply(const String& op, Val a, Val b); - Val parseBinary(int minPrec); + Val parseBinary(I32 minPrec); Val parseExpr(); Val run(); }; diff --git a/src/compiler/lex/preprocess_eval.cpp b/src/compiler/lex/preprocess_eval.cpp index 152b5a6..dd2c1a8 100644 --- a/src/compiler/lex/preprocess_eval.cpp +++ b/src/compiler/lex/preprocess_eval.cpp @@ -61,7 +61,7 @@ namespace rat::cc { return parsePrimary(); } - int Eval::prec(const String& op) { + I32 Eval::prec(const String& op) { if(op == "*" || op == "/" || op == "%") return 10; if(op == "+" || op == "-") @@ -140,10 +140,10 @@ namespace rat::cc { return {}; } - Val Eval::parseBinary(int minPrec) { + Val Eval::parseBinary(I32 minPrec) { Val left = parseUnary(); while(cur().kind == Pk::Punct) { - int p = prec(*cur().text); + I32 p = prec(*cur().text); if(p < minPrec || p < 0) break; String op = *cur().text; @@ -190,7 +190,7 @@ namespace rat::cc { List Preprocessor::replaceDefined(PpSpan in) { List r; r.reserve(in.size()); - size_t i = 0, n = in.size(); + U64 i = 0, n = in.size(); while(i < n) { const PpToken& t = in[i]; if(t.kind == Pk::Id && t.text == idDefined) { diff --git a/src/compiler/lex/preprocess_lex.cpp b/src/compiler/lex/preprocess_lex.cpp index fc0ae59..c2cc5c7 100644 --- a/src/compiler/lex/preprocess_lex.cpp +++ b/src/compiler/lex/preprocess_lex.cpp @@ -15,15 +15,15 @@ namespace rat::cc { return drive && s.size() >= 3 && s[1] == ':' && (s[2] == '/' || s[2] == '\\'); } - size_t ucnLen(const String& s, size_t i) { - size_t n = s.size(); + U64 ucnLen(const String& s, U64 i) { + U64 n = s.size(); if(i + 1 >= n || s[i] != '\\') return 0; - char k = s[i + 1]; - size_t ndig = (k == 'u') ? 4 : (k == 'U') ? 8 : 0; + C8 k = s[i + 1]; + U64 ndig = (k == 'u') ? 4 : (k == 'U') ? 8 : 0; if(ndig == 0 || i + 2 + ndig > n) return 0; - for(size_t d = 0; d < ndig; ++d) + for(U64 d = 0; d < ndig; ++d) if(!isHexDigit(s[i + 2 + d])) return 0; return 2 + ndig; @@ -33,8 +33,8 @@ namespace rat::cc { if(s.empty()) return Pk::Punct; if(isIdentStart(s[0]) || ucnLen(s, 0)) { - for(size_t i = 0; i < s.size();) { - if(size_t u = ucnLen(s, i)) { + for(U64 i = 0; i < s.size();) { + if(U64 u = ucnLen(s, i)) { i += u; } else if(isIdentCont(s[i])) { ++i; @@ -53,14 +53,14 @@ namespace rat::cc { void splice(const String& src, String& out, List& marks) { U32 line = 1; B32 pendingMark = false; - size_t i = 0, n = src.size(); + U64 i = 0, n = src.size(); out.reserve(n + 1); // decode one logical char at p (trigraph-aware); returns length - auto decode = [&](size_t p, char& c) -> size_t { + auto decode = [&](U64 p, C8& c) -> U64 { c = src[p]; if(c == '?' && p + 2 < n && src[p + 1] == '?') { - char r = 0; + C8 r = 0; switch(src[p + 2]) { case '=': r = '#'; @@ -100,7 +100,7 @@ namespace rat::cc { return 1; }; - auto emit = [&](char c) { + auto emit = [&](C8 c) { if(pendingMark) { marks.push_back({(U32)out.size(), line}); pendingMark = false; @@ -108,13 +108,13 @@ namespace rat::cc { out.push_back(c); }; - const char* data = src.data(); + const C8* data = src.data(); while(i < n) { // fast path: bulk-copy a run with no splice/trigraph/CR triggers - size_t start = i; - U32 startLine = line; // line of first char in run + U64 start = i; + U32 startLine = line; // line of first C8 in run while(i < n) { - char c = data[i]; + C8 c = data[i]; if(c == '\\' || c == '\r' || c == '?') break; if(c == '\n') @@ -131,11 +131,11 @@ namespace rat::cc { if(i >= n) break; - char c; - size_t len = decode(i, c); + C8 c; + U64 len = decode(i, c); if(c == '\\') { // backslash-newline splice (backslash may be a trigraph) - size_t j = i + len; + U64 j = i + len; if(j < n) { if(src[j] == '\n') { i = j + 1; @@ -172,10 +172,10 @@ namespace rat::cc { } // longest-match punctuator length at s[i]; assumes s[i] starts one - inline size_t punctLen(const String& s, size_t i, size_t n) { - char c = s[i]; - char d = i + 1 < n ? s[i + 1] : '\0'; - char e = i + 2 < n ? s[i + 2] : '\0'; + inline U64 punctLen(const String& s, U64 i, U64 n) { + C8 c = s[i]; + C8 d = i + 1 < n ? s[i + 1] : '\0'; + C8 e = i + 2 < n ? s[i + 2] : '\0'; switch(c) { case '.': return (d == '.' && e == '.') ? 3 : 1; @@ -217,22 +217,22 @@ namespace rat::cc { LexResult lexAll(const String& s, const List& marks, const String* file, Interner& in) { LexResult r; - size_t i = 0, n = s.size(); + U64 i = 0, n = s.size(); r.toks.reserve(n / 3 + 8); B32 bolPending = true; B32 spacePending = false; U32 line = 1; - size_t mi = 0, mn = marks.size(); + U64 mi = 0, mn = marks.size(); // apply splice line-corrections at offsets <= p - auto advanceTo = [&](size_t p) { + auto advanceTo = [&](U64 p) { while(mi < mn && marks[mi].off <= p) { line = marks[mi].line; ++mi; } }; - auto pushTok = [&](Pk kind, size_t start, size_t end) { + auto pushTok = [&](Pk kind, U64 start, U64 end) { PpToken t; t.kind = kind; std::string_view sv(s.data() + start, end - start); @@ -263,7 +263,7 @@ namespace rat::cc { while(i < n) { advanceTo(i); - char c = s[i]; + C8 c = s[i]; if(c == '\n') { bolPending = true; spacePending = true; @@ -304,11 +304,11 @@ namespace rat::cc { } // string / char literal, with optional prefix - size_t pfx = i; + U64 pfx = i; if(isIdentStart(c) || ucnLen(s, i)) { - size_t j = i; + U64 j = i; for(;;) { - if(size_t u = ucnLen(s, j)) + if(U64 u = ucnLen(s, j)) j += u; else if(j < n && isIdentCont(s[j])) ++j; @@ -329,8 +329,8 @@ namespace rat::cc { } if(c == '"' || c == '\'') { - char quote = c; - size_t j = i + 1; + C8 quote = c; + U64 j = i + 1; while(j < n && s[j] != quote) { if(s[j] == '\\' && j + 1 < n) j += 2; @@ -352,9 +352,9 @@ namespace rat::cc { // pp-number if(isDigit(c) || (c == '.' && i + 1 < n && isDigit(s[i + 1]))) { - size_t j = i + 1; + U64 j = i + 1; while(j < n) { - char d = s[j]; + C8 d = s[j]; if((d == 'e' || d == 'E' || d == 'p' || d == 'P') && j + 1 < n && (s[j + 1] == '+' || s[j + 1] == '-')) { j += 2; @@ -372,7 +372,7 @@ namespace rat::cc { } // punctuator - size_t plen = punctLen(s, i, n); + U64 plen = punctLen(s, i, n); pushTok(Pk::Punct, i, i + plen); i += plen; } @@ -387,16 +387,16 @@ namespace rat::cc { } I64 parseCharConst(const String& txt) { - size_t i = 0; + U64 i = 0; while(i < txt.size() && txt[i] != '\'') ++i; ++i; // skip opening quote if(i >= txt.size()) return 0; if(txt[i] != '\\') - return (I64)(unsigned char)txt[i]; + return (I64)(U8)txt[i]; ++i; - char e = txt[i++]; + C8 e = txt[i++]; U8 simple = 0; if(simpleEscape(e, simple)) return (I64)simple; @@ -414,14 +414,14 @@ namespace rat::cc { v = v * 8 + (txt[i] - '0'); return v; } - return (I64)(unsigned char)e; + return (I64)(U8)e; } } Val parseNumLit(const String& txt) { Val v; - size_t p = 0; - int base = 10; + U64 p = 0; + I32 base = 10; if(txt.size() >= 2 && txt[0] == '0' && (txt[1] == 'x' || txt[1] == 'X')) { base = 16; p = 2; @@ -431,13 +431,13 @@ namespace rat::cc { } U64 acc = 0; for(; p < txt.size(); ++p) { - int d = hexVal(txt[p]); + I32 d = hexVal(txt[p]); if(d < 0 || d >= base) break; acc = acc * (U64)base + (U64)d; } for(; p < txt.size(); ++p) { - char c = (char)std::tolower(txt[p]); + C8 c = (C8)std::tolower(txt[p]); if(c == 'u') v.isU = true; } diff --git a/src/compiler/lex/preprocess_macro.cpp b/src/compiler/lex/preprocess_macro.cpp index 1618e89..b317437 100644 --- a/src/compiler/lex/preprocess_macro.cpp +++ b/src/compiler/lex/preprocess_macro.cpp @@ -124,12 +124,12 @@ namespace rat::cc { PpToken Preprocessor::stringize(const List& a, B32 spaceBefore) { String s = "\""; - for(size_t k = 0; k < a.size(); ++k) { + for(U64 k = 0; k < a.size(); ++k) { const PpToken& t = a[k]; if(k > 0 && t.spaceBefore) s += ' '; if(t.kind == Pk::Str || t.kind == Pk::Char) { - for(char c : *t.text) { + for(C8 c : *t.text) { if(c == '"' || c == '\\') s += '\\'; s += c; @@ -147,7 +147,7 @@ namespace rat::cc { } void Preprocessor::appendList(List& os, List src, B32 firstSpace) { - for(size_t k = 0; k < src.size(); ++k) { + for(U64 k = 0; k < src.size(); ++k) { src[k].bol = false; if(k == 0) src[k].spaceBefore = firstSpace; @@ -159,14 +159,14 @@ namespace rat::cc { Preprocessor::substitute(const Macro& m, const List>& args, const HideSet* hs) { List os; const List& body = m.body; - auto idxOf = [&](const String* s) -> int { - for(size_t k = 0; k < m.formals.size(); ++k) + auto idxOf = [&](const String* s) -> I32 { + for(U64 k = 0; k < m.formals.size(); ++k) if(m.formals[k] == s) - return (int)k; + return (I32)k; return -1; }; - size_t i = 0; + U64 i = 0; while(i < body.size()) { const PpToken& T = body[i]; B32 isHash = isPunct(T, "#"); @@ -174,7 +174,7 @@ namespace rat::cc { // # param -> stringize if(m.isFunc && isHash && i + 1 < body.size()) { - int p = idxOf(body[i + 1].text); + I32 p = idxOf(body[i + 1].text); if(p >= 0) { os.push_back(stringize(args[p], T.spaceBefore)); i += 2; @@ -185,7 +185,7 @@ namespace rat::cc { // ## token -> paste onto the previous token if(isPaste && !os.empty() && i + 1 < body.size()) { const PpToken& R = body[i + 1]; - int p = idxOf(R.text); + I32 p = idxOf(R.text); if(p >= 0) { const List& a = args[p]; // GNU comma elision @@ -199,7 +199,7 @@ namespace rat::cc { // paste with empty operand -> previous unchanged } else { pasteInto(os.back(), a.front()); - for(size_t k = 1; k < a.size(); ++k) + for(U64 k = 1; k < a.size(); ++k) os.push_back(a[k]); } } else { @@ -209,7 +209,7 @@ namespace rat::cc { continue; } - int p = idxOf(T.text); + I32 p = idxOf(T.text); if(p >= 0) { B32 nextPaste = i + 1 < body.size() && isPunct(body[i + 1], "##"); if(nextPaste) { @@ -252,7 +252,7 @@ namespace rat::cc { } U32 Preprocessor::matchParen(const List& arg, U32 open) { - int depth = 0; + I32 depth = 0; for(U32 i = open; i < arg.size(); ++i) { if(isPunct(arg[i], "(")) ++depth; @@ -263,7 +263,7 @@ namespace rat::cc { } B32 Preprocessor::gatherArgs(List& work, List>& raw, PpToken& rparen) { - int depth = 1; + I32 depth = 1; List cur; for(;;) { if(work.empty() || work.back().kind == Pk::Eof) { @@ -295,7 +295,7 @@ namespace rat::cc { B32 Preprocessor::mapArgs(const Macro& m, const List>& raw, List>& actuals) { - size_t np = m.params.size(); + U64 np = m.params.size(); if(!m.variadic) { if(np == 0 && raw.size() == 1 && raw[0].empty()) return true; @@ -314,10 +314,10 @@ namespace rat::cc { fail("macro invoked with too few arguments"); return false; } - for(size_t k = 0; k < np; ++k) + for(U64 k = 0; k < np; ++k) actuals.push_back(raw[k]); List va; - for(size_t j = np; j < raw.size(); ++j) { + for(U64 j = np; j < raw.size(); ++j) { if(j > np) va.push_back(makePunct(",")); for(const PpToken& t : raw[j]) @@ -373,7 +373,7 @@ namespace rat::cc { List Preprocessor::expand(PpSpan in) { List work; work.reserve(in.size()); - for(size_t k = in.size(); k > 0; --k) + for(U64 k = in.size(); k > 0; --k) work.push_back(in[k - 1]); List os; while(!work.empty()) { @@ -480,7 +480,7 @@ namespace rat::cc { fail("'defined' cannot be used as a macro name"); return; } - size_t i = 1; + U64 i = 1; if(i < toks.size() && isPunct(toks[i], "(") && !toks[i].spaceBefore) { m.isFunc = true; ++i; // ( @@ -535,7 +535,7 @@ namespace rat::cc { return; } if(m.isFunc) { - for(size_t k = 0; k < m.body.size(); ++k) { + for(U64 k = 0; k < m.body.size(); ++k) { if(!isPunct(m.body[k], "#")) continue; B32 okOperand = false; diff --git a/src/compiler/lex/token_stream.cpp b/src/compiler/lex/token_stream.cpp index b7c8434..523848c 100644 --- a/src/compiler/lex/token_stream.cpp +++ b/src/compiler/lex/token_stream.cpp @@ -16,7 +16,7 @@ namespace rat::cc { err = lx.error(); return TokKind::Error; } - if((size_t)t.length != text.size()) { + if((U64)t.length != text.size()) { err = "malformed token '" + text + "'"; return TokKind::Error; } diff --git a/src/compiler/lex/token_stream.h b/src/compiler/lex/token_stream.h index 039242d..f2a33c4 100644 --- a/src/compiler/lex/token_stream.h +++ b/src/compiler/lex/token_stream.h @@ -19,7 +19,7 @@ namespace rat::cc { std::deque ownedText; // storage backing texts String fileName; String errMsg; // first conversion error - size_t pos = 0; + U64 pos = 0; Token next() { Token t = toks[pos]; @@ -30,7 +30,7 @@ namespace rat::cc { const Token& peek() { return toks[pos]; } const Token& peek2() { return toks[pos + 1 < toks.size() ? pos + 1 : pos]; } - String text(const Token& tok) const { return *texts[tok.offset]; } + const String& text(const Token& tok) const { return *texts[tok.offset]; } const String& file() const { return fileName; } const String& error() const { return errMsg; } void reset() { pos = 0; } diff --git a/src/compiler/parse/ast.cpp b/src/compiler/parse/ast.cpp index e6f2cdb..52c7f66 100644 --- a/src/compiler/parse/ast.cpp +++ b/src/compiler/parse/ast.cpp @@ -160,8 +160,8 @@ namespace rat::cc { return s; } - const char* exprOpName(ExprOp op) { - static const char* const kNames[] = { + const C8* exprOpName(ExprOp op) { + static const C8* const kNames[] = { "+", "-", "!", "~", "&", "*", "__real__", "__imag__", "++", "--", "++", "--", "+", "-", "*", "/", "%", "<<", ">>", "<", ">", "<=", ">=", "==", "!=", "&", "|", "^", "&&", "||", "=", "+=", "-=", diff --git a/src/compiler/parse/ast.h b/src/compiler/parse/ast.h index ca92864..b11cade 100644 --- a/src/compiler/parse/ast.h +++ b/src/compiler/parse/ast.h @@ -292,7 +292,7 @@ namespace rat::cc { U8 mods; } intLit; struct { - long double value; + F80 value; U32 bits; B32 imaginary; } floatLit; @@ -480,7 +480,7 @@ namespace rat::cc { void dumpExpr(const Expr* e, U32 depth, std::ostream& os); } // namespace detail - const char* exprOpName(ExprOp op); + const C8* exprOpName(ExprOp op); void dumpAst(const TransUnit& unit, std::ostream& os); } // namespace rat::cc diff --git a/src/compiler/parse/parse_literal.cpp b/src/compiler/parse/parse_literal.cpp index da16209..f38c86d 100644 --- a/src/compiler/parse/parse_literal.cpp +++ b/src/compiler/parse/parse_literal.cpp @@ -7,19 +7,19 @@ namespace rat::cc { namespace detail { void utf8Encode(String& out, U32 cp) { if(cp < 0x80) { - out.push_back((char)cp); + out.push_back((C8)cp); } else if(cp < 0x800) { - out.push_back((char)(0xC0 | (cp >> 6))); - out.push_back((char)(0x80 | (cp & 0x3F))); + out.push_back((C8)(0xC0 | (cp >> 6))); + out.push_back((C8)(0x80 | (cp & 0x3F))); } else if(cp < 0x10000) { - out.push_back((char)(0xE0 | (cp >> 12))); - out.push_back((char)(0x80 | ((cp >> 6) & 0x3F))); - out.push_back((char)(0x80 | (cp & 0x3F))); + out.push_back((C8)(0xE0 | (cp >> 12))); + out.push_back((C8)(0x80 | ((cp >> 6) & 0x3F))); + out.push_back((C8)(0x80 | (cp & 0x3F))); } else { - out.push_back((char)(0xF0 | (cp >> 18))); - out.push_back((char)(0x80 | ((cp >> 12) & 0x3F))); - out.push_back((char)(0x80 | ((cp >> 6) & 0x3F))); - out.push_back((char)(0x80 | (cp & 0x3F))); + out.push_back((C8)(0xF0 | (cp >> 18))); + out.push_back((C8)(0x80 | ((cp >> 12) & 0x3F))); + out.push_back((C8)(0x80 | ((cp >> 6) & 0x3F))); + out.push_back((C8)(0x80 | (cp & 0x3F))); } } @@ -49,7 +49,7 @@ namespace rat::cc { return; } for(U32 k = 0; k < unitBytes; ++k) - out.push_back((char)(U8)(cp >> (8 * k))); + out.push_back((C8)(U8)(cp >> (8 * k))); } } // namespace detail @@ -60,7 +60,7 @@ namespace rat::cc { U32 end = (U32)s.size(); while(end > 0) { - char c = s[end - 1]; + C8 c = s[end - 1]; if(c == 'u' || c == 'U') { isUnsigned = true; --end; @@ -147,7 +147,7 @@ namespace rat::cc { return true; } - static U32 escapeMaxVal(char prefix) { + static U32 escapeMaxVal(C8 prefix) { switch(prefix) { case 'u': return 0xFFFFu; @@ -165,7 +165,7 @@ namespace rat::cc { fail(tok, "unterminated escape"); return false; } - char e = s[i++]; + C8 e = s[i++]; U8 simple = 0; if(simpleEscape(e, simple)) { out = simple; @@ -209,7 +209,7 @@ namespace rat::cc { } B32 Parser::decodeUcn(const String& s, U32& i, U32 end, const Token& tok, U32& cp) { - char kind = s[i++]; // 'u' or 'U' + C8 kind = s[i++]; // 'u' or 'U' U32 ndigits = (kind == 'u') ? 4 : 8; if(i + ndigits > end) { fail(tok, "incomplete universal character name"); @@ -295,7 +295,7 @@ namespace rat::cc { if(end > 0 && s[end - 1] == '"') --end; while(i < end) { - char c = s[i++]; + C8 c = s[i++]; if(c != '\\') { out.push_back(c); continue; @@ -313,7 +313,7 @@ namespace rat::cc { if(maxVal > 0xFFu) detail::utf8Encode(out, val); else - out.push_back((char)(U8)val); + out.push_back((C8)(U8)val); } return true; } diff --git a/src/compiler/parse/parse_primary.cpp b/src/compiler/parse/parse_primary.cpp index 89663da..5431e9c 100644 --- a/src/compiler/parse/parse_primary.cpp +++ b/src/compiler/parse/parse_primary.cpp @@ -176,7 +176,7 @@ namespace rat::cc { String text = lex.text(lit); B32 isFloat = false, isLongDouble = false, isImaginary = false; while(!text.empty()) { - char c = text.back(); + C8 c = text.back(); if(c == 'f' || c == 'F') isFloat = true; else if(c == 'l' || c == 'L') @@ -188,8 +188,8 @@ namespace rat::cc { text.pop_back(); } errno = 0; - char* end = nullptr; - long double value = std::strtold(text.c_str(), &end); + C8* end = nullptr; + F80 value = std::strtold(text.c_str(), &end); if(end == text.c_str() || *end != '\0') { fail(lit, "invalid floating constant '" + text + "'"); return nullptr; @@ -211,9 +211,8 @@ namespace rat::cc { // __builtin_offsetof(type, member) if(lex.text(id) == "__builtin_offsetof") return parseBuiltinOffsetof(id); - auto ec = enumConstants.find(lex.text(id)); - if(ec != enumConstants.end()) - return makeInt(id, ec->second, 32); + if(const I64* ec = enumConstants.get(lex.text(id))) + return makeInt(id, *ec, 32); return makeIdent(id); } if(tok.kind == TokKind::LParen) { diff --git a/src/compiler/parse/parse_stmt.cpp b/src/compiler/parse/parse_stmt.cpp index 2c35c53..590b9c5 100644 --- a/src/compiler/parse/parse_stmt.cpp +++ b/src/compiler/parse/parse_stmt.cpp @@ -63,9 +63,9 @@ namespace rat::cc { fail(peek(), "expected type specifier"); return nullptr; } - B32 isStatic = sawStatic; - B32 isExtern = sawExtern; - U32 align = sawAlignas; + B32 isStatic = specs.isStatic; + B32 isExtern = specs.isExtern; + U32 align = specAlign; Stmt* s = makeStmt(StmtKind::Decl, start.offset); if(peek().kind == TokKind::Semicolon) { advance(); @@ -409,25 +409,33 @@ namespace rat::cc { if(!expect(TokKind::LBrace, "'{'")) return nullptr; Stmt* block = makeStmt(StmtKind::Compound, open.offset); - Map savedTypedefs = typedefs; - Map savedEnumConstants = enumConstants; - Map savedEnumSignedTags = enumSignedTags; - Map savedStructTypes = structTypes; - ++scopeDepth; + pushScope(); while(!failed && peek().kind != TokKind::RBrace && peek().kind != TokKind::Eof) { Stmt* s = parseStatement(); if(!s) return nullptr; block->body.push_back(s); } - --scopeDepth; - typedefs = std::move(savedTypedefs); - enumConstants = std::move(savedEnumConstants); - enumSignedTags = std::move(savedEnumSignedTags); - structTypes = std::move(savedStructTypes); + popScope(); if(!expect(TokKind::RBrace, "'}'")) return nullptr; return block; } + void Parser::pushScope() { + typedefs.push(); + enumConstants.push(); + enumSignedTags.push(); + structTypes.push(); + ++scopeDepth; + } + + void Parser::popScope() { + --scopeDepth; + typedefs.pop(); + enumConstants.pop(); + enumSignedTags.pop(); + structTypes.pop(); + } + } // namespace rat::cc diff --git a/src/compiler/parse/parse_struct.cpp b/src/compiler/parse/parse_struct.cpp index aa5610c..33f26e3 100644 --- a/src/compiler/parse/parse_struct.cpp +++ b/src/compiler/parse/parse_struct.cpp @@ -20,7 +20,7 @@ namespace rat::cc { fail(peek(), "expected member type"); return false; } - U32 baseAlign = sawAlignas; + U32 baseAlign = specAlign; if(peek().kind == TokKind::Semicolon && isStruct(base)) { advance(); const StructType* inner = base.strukt; @@ -220,14 +220,14 @@ namespace rat::cc { B32 hasBody = peek().kind == TokKind::LBrace; StructType* st = nullptr; if(tag) { - auto it = structTypes.find(*tag); - if(it != structTypes.end() && !(hasBody && it->second.depth < scopeDepth)) - st = it->second.type; + const TagBinding* bound = structTypes.get(*tag); + if(bound && !(hasBody && bound->depth < scopeDepth)) + st = bound->type; else { st = arena.make(); st->tag = *tag; st->isUnion = isUnion; - structTypes[*tag] = TagBinding{st, scopeDepth}; + structTypes.set(*tag, TagBinding{st, scopeDepth}); } } @@ -307,7 +307,7 @@ namespace rat::cc { } if(value < 0) anyNegative = true; - enumConstants[lex.text(name)] = value; + enumConstants.set(lex.text(name), value); next = value + 1; if(!accept(TokKind::Comma)) break; @@ -317,11 +317,10 @@ namespace rat::cc { } if(!tag.empty()) { if(haveList) - enumSignedTags[tag] = anyNegative; + enumSignedTags.set(tag, anyNegative); else { - auto seen = enumSignedTags.find(tag); - if(seen != enumSignedTags.end()) - anyNegative = seen->second; + if(const B32* seen = enumSignedTags.get(tag)) + anyNegative = *seen; } } out = ctInt(); diff --git a/src/compiler/parse/parse_type.cpp b/src/compiler/parse/parse_type.cpp index 78706e5..8aff535 100644 --- a/src/compiler/parse/parse_type.cpp +++ b/src/compiler/parse/parse_type.cpp @@ -62,7 +62,7 @@ namespace rat::cc { B32 Parser::startsType(const Token& tok) { if(detail::isTypeStart(tok.kind)) return true; - return tok.kind == TokKind::Identifier && typedefs.count(lex.text(tok)) != 0; + return tok.kind == TokKind::Identifier && typedefs.get(lex.text(tok)) != nullptr; } B32 Parser::parseTypedef() { @@ -89,7 +89,7 @@ namespace rat::cc { U32 ignored = 0; if(!acceptTrailingAlignas(ignored)) return false; - typedefs[lex.text(nameTok)] = t; + typedefs.set(lex.text(nameTok), t); if(!accept(TokKind::Comma)) break; } @@ -148,35 +148,29 @@ namespace rat::cc { } B32 Parser::parseTypeSpec(CType& out) { - B32 isStatic = false; - B32 isExtern = false; - B32 isInline = false; + DeclSpecs seen; B32 isConst = false; - B32 isNoInline = false; I32 storageCount = 0; - sawStatic = false; - sawExtern = false; - sawInline = false; - sawNoinline = false; - sawAlignas = 0; + specs = DeclSpecs{}; + specAlign = 0; auto applyQualStorage = [&](TokKind sk) { if(sk == TokKind::KwStatic) - isStatic = true; + seen.isStatic = true; if(sk == TokKind::KwExtern) - isExtern = true; + seen.isExtern = true; if(sk == TokKind::KwInline) - isInline = true; + seen.isInline = true; if(sk == TokKind::KwConst) isConst = true; if(sk == TokKind::KwNoinline) - isNoInline = true; + seen.isNoInline = true; if(sk == TokKind::KwStatic || sk == TokKind::KwExtern || sk == TokKind::KwAuto || sk == TokKind::KwRegister) ++storageCount; }; while(detail::isQualOrStorage(peek().kind) || peek().kind == TokKind::KwAlignas) { if(peek().kind == TokKind::KwAlignas) { - if(!parseAlignasSpec(sawAlignas)) + if(!parseAlignasSpec(specAlign)) return false; continue; } @@ -187,15 +181,15 @@ namespace rat::cc { // an attribute marker may trail the spec while(peek().kind == TokKind::KwNoinline || peek().kind == TokKind::KwAlignas) { if(peek().kind == TokKind::KwAlignas) { - parseAlignasSpec(sawAlignas); + parseAlignasSpec(specAlign); continue; } - isNoInline = true; + seen.isNoInline = true; advance(); } if(isConst) out.quals |= 1u; - setStorage(isStatic, isExtern, isInline, isNoInline); + specs = seen; }; if(storageCount > 1) { fail(peek(), "more than one storage-class specifier"); @@ -217,10 +211,9 @@ namespace rat::cc { return ok; } if(peek().kind == TokKind::Identifier) { - auto it = typedefs.find(lex.text(peek())); - if(it != typedefs.end()) { + if(const CType* td = typedefs.get(lex.text(peek()))) { advance(); - out = it->second; + out = *td; finishSpec(); return true; } @@ -257,7 +250,7 @@ namespace rat::cc { else if(k == TokKind::KwInt) ; // base int else if(k == TokKind::KwAlignas) { - if(!parseAlignasSpec(sawAlignas)) + if(!parseAlignasSpec(specAlign)) return false; continue; } else if(detail::isQualOrStorage(k)) { @@ -304,12 +297,12 @@ namespace rat::cc { } else t.bits = 32; } - if(!acceptTrailingAlignas(sawAlignas)) + if(!acceptTrailingAlignas(specAlign)) return false; if(isConst) t.quals |= 1u; out = t; - setStorage(isStatic, isExtern, isInline, isNoInline); + specs = seen; return true; } } // namespace rat::cc diff --git a/src/compiler/parse/parser.cpp b/src/compiler/parse/parser.cpp index ce3dbd8..98df1b3 100644 --- a/src/compiler/parse/parser.cpp +++ b/src/compiler/parse/parser.cpp @@ -28,8 +28,8 @@ namespace rat::cc { vl->count = lay.ptrBytes * 4; vaList.array = vl; } - typedefs["va_list"] = vaList; - typedefs["__builtin_va_list"] = vaList; + typedefs.set("va_list", vaList); + typedefs.set("__builtin_va_list", vaList); } void Parser::fail(const Token& at, const String& msg) { @@ -49,7 +49,7 @@ namespace rat::cc { return false; } - B32 Parser::expect(TokKind kind, const char* what) { + B32 Parser::expect(TokKind kind, const C8* what) { if(peek().kind == kind) { advance(); return true; @@ -397,11 +397,11 @@ namespace rat::cc { fail(peek(), "expected type specifier"); return nullptr; } - B32 gExtern = sawExtern; - B32 gExternInline = sawExtern && sawInline; - B32 gStatic = sawStatic; - B32 gNoinline = sawNoinline; - U32 gAlign = sawAlignas; + B32 gExtern = specs.isExtern; + B32 gExternInline = specs.isExtern && specs.isInline; + B32 gStatic = specs.isStatic; + B32 gNoinline = specs.isNoInline; + U32 gAlign = specAlign; CType first = base; parsePointers(first); if(first.ptr == 0 && peek().kind == TokKind::Semicolon) { diff --git a/src/compiler/parse/parser.h b/src/compiler/parse/parser.h index 8b5b5bf..94e0ac9 100644 --- a/src/compiler/parse/parser.h +++ b/src/compiler/parse/parser.h @@ -6,6 +6,62 @@ #include "target_layout.h" namespace rat::cc { + template struct ScopeMap { + struct Undo { + String name; + V prev; + B32 hadPrev; + }; + Map table; + List undo; + List marks; + + const V* get(const String& key) const; // null when absent + void push() { marks.push_back((U32)undo.size()); } + void pop(); + void set(const String& key, V value); + void erase(const String& key); + }; + + template const V* ScopeMap::get(const String& key) const { + auto it = table.find(key); + return it == table.end() ? nullptr : &it->second; + } + + template void ScopeMap::pop() { + U32 mark = marks.back(); + marks.pop_back(); + while(undo.size() > mark) { + Undo& u = undo.back(); + if(u.hadPrev) + table.insert_or_assign(u.name, u.prev); + else + table.erase(u.name); + undo.pop_back(); + } + } + + template void ScopeMap::set(const String& key, V value) { + auto [it, inserted] = table.try_emplace(key, value); + if(inserted) { + if(!marks.empty()) + undo.push_back({key, V{}, false}); + } else { + if(!marks.empty()) + undo.push_back({key, it->second, true}); + it->second = value; + } + } + + template void ScopeMap::erase(const String& key) { + auto it = table.find(key); + if(it == table.end()) + return; + if(!marks.empty()) + undo.push_back({key, it->second, true}); + table.erase(it); + } + struct Parser { Parser(TokenStream& lexer, Arena& arena, const TargetLayout& layout); @@ -19,7 +75,7 @@ namespace rat::cc { Token advance() { return lex.next(); } B32 check(TokKind kind) { return peek().kind == kind; } B32 accept(TokKind kind); - B32 expect(TokKind kind, const char* what); + B32 expect(TokKind kind, const C8* what); void fail(const Token& at, const String& msg); // grammar @@ -27,12 +83,6 @@ namespace rat::cc { B32 parseTypeSpec(CType& out); B32 parseAlignasSpec(U32& align); B32 acceptTrailingAlignas(U32& align); - void setStorage(B32 isStatic, B32 isExtern, B32 isInline, B32 isNoInline) { - sawStatic = isStatic; - sawExtern = isExtern; - sawInline = isInline; - sawNoinline = isNoInline; - } FuncDef* parseFunctionRest(CType ret, const Token& nameTok, const Token& start, @@ -65,6 +115,8 @@ namespace rat::cc { void adjustParamType(CType& t, const Expr** vlaBound = nullptr); B32 parseParamTypeList(FuncType* ft); Stmt* parseCompound(); + void pushScope(); + void popScope(); Stmt* parseStatement(); Stmt* parseAsmStatement(); B32 parseAsmOperands(List& out); @@ -140,31 +192,42 @@ namespace rat::cc { U32 fieldAlign(CType t) const { return isAggregate(t) ? t.strukt->align : (U32)typeSizeBytes(t); } + private: + struct DeclSpecs { + B32 isStatic = false; + B32 isExtern = false; + B32 isInline = false; + B32 isNoInline = false; + }; + struct TagBinding { + StructType* type = nullptr; + U32 depth = 0; + }; + // input TokenStream& lex; Arena& arena; TargetLayout lay; + + // parse state U32 parseDepth = 0; B32 failed = false; - B32 sawStatic = false; - B32 sawExtern = false; - B32 sawInline = false; - B32 sawNoinline = false; - U32 sawAlignas = 0; String errMsg; String curFuncName; - Map enumConstants; - Map enumSignedTags; - struct TagBinding { - StructType* type = nullptr; - U32 depth = 0; - }; - Map structTypes; + DeclSpecs specs; // storage of the last parsed type spec + U32 specAlign = 0; + + // scopes U32 scopeDepth = 0; + ScopeMap typedefs; + ScopeMap enumConstants; + ScopeMap enumSignedTags; + ScopeMap structTypes; + + // unit-wide tables Map complexLayouts; - Map typedefs; - List blockProtos; Map funcDefs; + List blockProtos; }; } // namespace rat::cc diff --git a/src/compiler/predef.h b/src/compiler/predef.h index 54c7414..09a2520 100644 --- a/src/compiler/predef.h +++ b/src/compiler/predef.h @@ -8,8 +8,8 @@ namespace rat::cc { namespace detail { struct Def { - const char* name; - const char* value; + const C8* name; + const C8* value; }; void append(String& out, const Def* defs, U32 n); diff --git a/src/linker/elf_file.h b/src/linker/elf_file.h index 95dde50..73c051e 100644 --- a/src/linker/elf_file.h +++ b/src/linker/elf_file.h @@ -120,7 +120,7 @@ namespace rat { inline void wrPad(List& b, U64 to) { le::padTo(b, to); } // sysv symbol hash - inline U32 sysvHash(const char* name) { + inline U32 sysvHash(const C8* name) { U32 h = 0, g; for(const U8* s = (const U8*)name; *s; ++s) { h = (h << 4) + *s; diff --git a/src/linker/elf_read.cpp b/src/linker/elf_read.cpp index b773049..89b848f 100644 --- a/src/linker/elf_read.cpp +++ b/src/linker/elf_read.cpp @@ -78,7 +78,7 @@ namespace rat { f.seekg(0, std::ios::beg); out.resize((U64)n); if(n > 0) - f.read((char*)out.data(), n); + f.read((C8*)out.data(), n); return (B32)f.good() || f.eof(); } @@ -101,7 +101,7 @@ namespace rat { for(U32 i = 0; i < shdrs.size(); ++i) { const detail::Shdr& sh = shdrs[i]; InSection& s = obj.sections[i]; - s.name = (const char*)(shstr + sh.name); + s.name = (const C8*)(shstr + sh.name); s.align = sh.addralign ? sh.addralign : 1; s.fileOff = sh.offset; s.size = sh.size; @@ -130,7 +130,7 @@ namespace rat { const detail::Shdr& st = shdrs[sh.link]; const U8* sp = &im[st.offset + (U64)sh.info * 24]; const U8* gstr = &im[shdrs[st.link].offset]; - sig = (const char*)(gstr + rd32(sp)); + sig = (const C8*)(gstr + rd32(sp)); } if(sig.empty() || seenGroups.insert(sig).second) continue; // first or unnamed, keep whole @@ -158,7 +158,7 @@ namespace rat { for(U32 i = 0; i < nsym; ++i) { const U8* p = &im[sym.offset + (U64)i * 24]; InSym s; - s.name = (const char*)(strtab + rd32(p)); + s.name = (const C8*)(strtab + rd32(p)); U8 info = p[4]; s.bind = (U8)(info >> 4); s.type = (U8)(info & 0xf); @@ -206,7 +206,7 @@ namespace rat { } U64 arMemberSize(const List& d, U64 hdrOff) { - String s((const char*)&d[hdrOff + 48], 10); + String s((const C8*)&d[hdrOff + 48], 10); return (U64)strtoull(s.c_str(), nullptr, 10); } @@ -220,7 +220,7 @@ namespace rat { } U64 o = 8; while(o + 60 <= d.size()) { - char nm0 = (char)d[o], nm1 = (char)d[o + 1]; + C8 nm0 = (C8)d[o], nm1 = (C8)d[o + 1]; U64 sz = arMemberSize(d, o); U64 dataOff = o + 60; if(nm0 == '/' && nm1 == ' ') { @@ -228,7 +228,7 @@ namespace rat { const U8* p = &d[dataOff]; U32 count = (U32)((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]); const U8* offs = p + 4; - const char* names = (const char*)(offs + (U64)count * 4); + const C8* names = (const C8*)(offs + (U64)count * 4); U64 nameCursor = 0; for(U32 i = 0; i < count; ++i) { const U8* q = offs + (U64)i * 4; @@ -248,7 +248,7 @@ namespace rat { B32 loadLibrary(const String& path, Lib& lib, String& err) { std::ifstream f(path, std::ios::binary); - auto fail = [&](const char* what) { + auto fail = [&](const C8* what) { err = String(what) + " '" + path + "'"; return false; }; @@ -256,7 +256,7 @@ namespace rat { return fail("cannot read library"); U8 eh[64]; - f.read((char*)eh, 64); + f.read((C8*)eh, 64); if(!f || eh[0] != 0x7f || eh[1] != 'E' || eh[2] != 'L' || eh[3] != 'F' || eh[4] != ELFCLASS64 || eh[5] != ELFDATA2LSB) return fail("not a 64-bit LE ELF library"); @@ -267,7 +267,7 @@ namespace rat { List sh(shnum * 64); f.seekg((std::streamoff)shoff); - f.read((char*)sh.data(), (std::streamsize)sh.size()); + f.read((C8*)sh.data(), (std::streamsize)sh.size()); if(!f) return fail("truncated section headers in"); @@ -291,10 +291,10 @@ namespace rat { lib.dynsym.resize(symSize); f.seekg((std::streamoff)symOff); - f.read((char*)lib.dynsym.data(), (std::streamsize)symSize); + f.read((C8*)lib.dynsym.data(), (std::streamsize)symSize); lib.dynstr.resize(strSize); f.seekg((std::streamoff)strOff); - f.read((char*)lib.dynstr.data(), (std::streamsize)strSize); + f.read((C8*)lib.dynstr.data(), (std::streamsize)strSize); if(!f) return fail("truncated dynamic tables in"); @@ -303,12 +303,12 @@ namespace rat { } B32 findLibrary(const String& l, const List& paths, String& found) { - const char* suffixes[] = {".so.6", ".so.1", ".so"}; + const C8* suffixes[] = {".so.6", ".so.1", ".so"}; for(const String& dir : paths) { String base = dir; if(!base.empty() && base.back() != '/') base += '/'; - for(const char* suf : suffixes) { + for(const C8* suf : suffixes) { String cand = base + "lib" + l + suf; struct stat st; if(stat(cand.c_str(), &st) == 0) { @@ -329,7 +329,7 @@ namespace rat { if(!f) return String(); U8 eh[64]; - if(!f.read((char*)eh, 64)) + if(!f.read((C8*)eh, 64)) return String(); U64 phoff = rd64(eh + 32); U16 phentsize = rd16(eh + 54); @@ -337,7 +337,7 @@ namespace rat { for(U16 i = 0; i < phnum; ++i) { U8 ph[56]; f.seekg((std::streamoff)(phoff + (U64)i * phentsize)); - if(!f.read((char*)ph, 56)) + if(!f.read((C8*)ph, 56)) break; if(rd32(ph) != PT_INTERP) continue; diff --git a/src/linker/elf_write.cpp b/src/linker/elf_write.cpp index 6102666..ccca219 100644 --- a/src/linker/elf_write.cpp +++ b/src/linker/elf_write.cpp @@ -123,7 +123,7 @@ namespace rat { // cie: parse augmentation for 'R' fde ptr enc U64 i = idOff + 4; ++i; // version - const char* aug = (const char*)&m[i]; + const C8* aug = (const C8*)&m[i]; U64 augLen = 0; while(m[i + augLen]) ++augLen; @@ -132,11 +132,11 @@ namespace rat { detail::readUleb(m.data(), i); // code align detail::readSleb(m.data(), i); // data align detail::readUleb(m.data(), i); // ra reg - U8 fdeEnc = 0x00; // absptr default + U8 fdeEnc = 0x00; // absptr default if(aug[0] == 'z') { detail::readUleb(m.data(), i); // aug data len for(U64 a = 1; a < augLen; ++a) { - char c = ((const char*)&m[augStart])[a]; + C8 c = ((const C8*)&m[augStart])[a]; if(c == 'L') { ++i; // lsda enc byte } else if(c == 'P') { @@ -827,7 +827,7 @@ namespace rat { err = "cannot write '" + opt.output + "'"; return false; } - os.write((const char*)out.data(), (std::streamsize)out.size()); + os.write((const C8*)out.data(), (std::streamsize)out.size()); os.close(); if(!os) { err = "write to '" + opt.output + "' failed"; diff --git a/src/linker/linker.cpp b/src/linker/linker.cpp index 1f7a9ea..6be1add 100644 --- a/src/linker/linker.cpp +++ b/src/linker/linker.cpp @@ -8,7 +8,7 @@ namespace rat { using namespace elf; namespace detail { - constexpr const char* kInterp = "/lib64/ld-linux-x86-64.so.2"; + constexpr const C8* kInterp = "/lib64/ld-linux-x86-64.so.2"; B32 isGotReloc(U32 t) { return t == R_X86_64_GOTPCREL || t == R_X86_64_GOTPCRELX || t == R_X86_64_REX_GOTPCRELX || @@ -16,26 +16,26 @@ namespace rat { } B32 isLinkerSym(const String& n) { - static const char* names[] = {"__dso_handle", - "_GLOBAL_OFFSET_TABLE_", - "__init_array_start", - "__init_array_end", - "__preinit_array_start", - "__preinit_array_end", - "__fini_array_start", - "__fini_array_end", - "__bss_start", - "_edata", - "edata", - "_end", - "end", - "__end__", - "__ehdr_start", - "_DYNAMIC", - "__data_start", - "data_start", - "__TMC_END__"}; - for(const char* s : names) + static const C8* names[] = {"__dso_handle", + "_GLOBAL_OFFSET_TABLE_", + "__init_array_start", + "__init_array_end", + "__preinit_array_start", + "__preinit_array_end", + "__fini_array_start", + "__fini_array_end", + "__bss_start", + "_edata", + "edata", + "_end", + "end", + "__end__", + "__ehdr_start", + "_DYNAMIC", + "__data_start", + "data_start", + "__TMC_END__"}; + for(const C8* s : names) if(n == s) return true; return false; @@ -255,7 +255,7 @@ namespace rat { B32 used = false; U32 n = (U32)(lib.dynsym.size() / 24); const U8* syms = lib.dynsym.data(); - const char* strs = (const char*)lib.dynstr.data(); + const C8* strs = (const C8*)lib.dynstr.data(); U64 strMax = lib.dynstr.size(); for(U32 i = 0; i < n; ++i) { const U8* p = syms + (U64)i * 24;