Skip to content

Commit ab9fc0b

Browse files
committed
Compiler: move c2_trace functions to libs/c2/c2_trace.c2
* add c2_trace.c2 source module in libs/c2 (will later incorporate all libs/c2 files in an internal embedded library * fix stack overflow on recursive inline functions * generate call tracing tables in **c2_trace_tables.c** for fast builds Fix external array definitions: * accept array definitions without size in interface files * fix external array definitions in C generator * fix test/interface/incremental_array.c2t: fix external array definition * fix test/interface/public_by_array_expr.c2t: fix external array definition * fix test/interface/muti_dimensional_array.c2t: `Row` and `Columns` definitions were reversed, 2D external array definition in C was incorrect
1 parent 9366a4d commit ab9fc0b

16 files changed

+285
-247
lines changed

analyser/module_analyser.c2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ fn void Analyser.analyseGlobalVarDecl(Analyser* ma, VarDecl* v) {
563563
return;
564564
}
565565
} else {
566-
if (!init_expr) {
566+
if (!init_expr && !d.isExternal()) {
567567
ma.error(d.getLoc(), "array-type variable '%s' needs an explicit size or an initializer", d.getFullName());
568568
return;
569569
}

ast/type_ref.c2

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -350,8 +350,9 @@ public fn void TypeRef.printLiteral(const TypeRef* r, string_buffer.Buf* out, bo
350350

351351
for (u32 i=0; i<r.flags.num_ptrs; i++) out.add1('*');
352352

353-
// note: convert arrays into pointers
354-
if (r.flags.incr_array) out.add("*");
353+
// TODO need the actual array length
354+
// should update the type with current array length
355+
if (r.flags.incr_array) out.add("[]");
355356

356357
if (decay) {
357358
// TODO: this seems incorrect: char[10][10] does not decay as char**

compiler/compiler.c2

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,13 @@ fn void Compiler.build(Compiler* c,
295295
if (opts.msan) c.addFeature("__MSAN__", "1");
296296
if (opts.ubsan) c.addFeature("__UBSAN__", "1");
297297

298+
target.addLib(c.auxPool.add("c2", 2, true), false);
299+
300+
if (c.opts.trace_calls) {
301+
if (!c.addLibFile("c2", "c2_trace.c2"))
302+
stdlib.exit(-1);
303+
}
304+
298305
c.parser = c2_parser.create(sm,
299306
diags,
300307
c.astPool,

compiler/compiler_libs.c2

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,20 @@ fn bool Compiler.has_component(Compiler* c, u32 name) {
148148
return false;
149149
}
150150

151+
fn bool Compiler.addLibFile(Compiler* c, const char* libname, const char* filename) {
152+
char[512] dirname;
153+
char[512] fullname;
154+
155+
if (c.find_lib(libname, dirname)) {
156+
stdio.snprintf(fullname, elemsof(fullname), "%s/%s", dirname, filename);
157+
c.target.addFile(c.auxPool.addStr(fullname, true), 0);
158+
return true;
159+
} else {
160+
console.error("c2c: find library file %s/%s", libname, filename);
161+
return false;
162+
}
163+
}
164+
151165
fn bool Compiler.find_lib(const Compiler* c, const char* libname, char* fullpath) {
152166
for (u32 i=0; i<c.libdirs.length(); i++) {
153167
const char* dirname = c.libdirs.get(i);

compiler/main.c2

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -589,8 +589,6 @@ fn bool Context.build_target(Context* c,
589589
}
590590
}
591591

592-
target.addLib(c.auxPool.add("c2", 2, true), false);
593-
594592
compiler.build(c.auxPool, c.sm, c.diags, c.build_info, target, &c.comp_opts, &c.pluginHandler);
595593

596594
// TODO unload target-specific plugins?

generator/c/c2i_generator_decl.c2

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,14 @@ fn void Generator.emitTypeRef(Generator* gen, const TypeRef* ref) {
8080
if (d) is_external = (d.getModule() != gen.mod);
8181

8282
// On globals print arrays as pointers, on inline function bodies, print as [..]
83+
// TODO external arrays must be defined as such at least for static libraries,
84+
// what is the use case for defining them as pointers? Which is obviously
85+
// incorrect for multi-dimensional arrays.
8386
if (gen.in_body) {
8487
ref.printLiteral2(gen.out, is_external, print_expr, gen);
8588
} else {
86-
ref.printLiteral(gen.out, is_external, true);
89+
// TODO add the actual array size for incremental arrays
90+
ref.printLiteral(gen.out, is_external, false);
8791
}
8892
}
8993

generator/c/c_generator.c2

Lines changed: 64 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ type Generator struct {
7979
bool msan;
8080
bool ubsan;
8181
bool trace_calls;
82+
bool no_trace; //to disable tracing on c2_trace module
8283

8384
// set during generation
8485
bool cur_external; // whether current component is external
@@ -265,14 +266,17 @@ const char*[] builtinType_cnames = {
265266
static_assert(elemsof(BuiltinKind), elemsof(builtinType_cnames));
266267

267268
fn void Generator.emitGlobalVarTypePre(Generator* gen, string_buffer.Buf* out, QualType qt) {
269+
#if 0
270+
// TODO this seems incorrect
268271
if (gen.cur_external && qt.isArray()) {
269272
// convert to pointer
270273
ArrayType* at = cast<ArrayType*>(qt.getType());
271274
gen.emitGlobalVarTypePre(out, at.getElemType());
272275
out.add1('*');
273-
} else {
274-
gen.emitTypePre(out, qt);
276+
return;
275277
}
278+
#endif
279+
gen.emitTypePre(out, qt);
276280
}
277281

278282
fn void Generator.emitTypePre(Generator* gen, string_buffer.Buf* out, QualType qt) {
@@ -326,7 +330,9 @@ fn void Generator.emitTypePre(Generator* gen, string_buffer.Buf* out, QualType q
326330

327331
fn void Generator.emitGlobalVarTypePost(Generator* gen, string_buffer.Buf* out, QualType qt) {
328332
if (!qt.isArray()) return;
333+
#if 0
329334
if (gen.cur_external) return;
335+
#endif
330336
gen.emitTypePost(out, qt);
331337
}
332338

@@ -526,10 +532,29 @@ fn void Generator.emitConstExpr(Generator* gen, string_buffer.Buf* out, Expr* e)
526532
gen.need_const_expr--;
527533
}
528534

529-
fn bool Generator.emitGlobalVarDecl(Generator* gen, string_buffer.Buf* out, Decl* d) {
535+
fn void Generator.emitGlobalVarDeclCommon(Generator* gen, string_buffer.Buf* out, Decl* d) {
536+
const char* cdef = d.getCDef();
537+
if (cdef) {
538+
out.add(cdef);
539+
} else {
540+
QualType qt = d.getType();
541+
gen.emitGlobalVarTypePre(out, qt);
542+
out.space();
543+
gen.emitCName(out, d);
544+
gen.emitGlobalVarTypePost(out, qt);
545+
}
530546
VarDecl* vd = cast<VarDecl*>(d);
547+
if (vd.hasAttrWeak()) out.add(" __attribute__((weak))");
531548

532-
QualType qt = d.getType();
549+
const char* section = d.getSection();
550+
if (section) {
551+
out.space();
552+
gen.emitSectionAttr(out, section);
553+
}
554+
}
555+
556+
fn bool Generator.emitGlobalVarDecl(Generator* gen, string_buffer.Buf* out, Decl* d) {
557+
VarDecl* vd = cast<VarDecl*>(d);
533558

534559
// emit 'simple'-constants as a defines
535560
if (emitAsDefine(vd)) {
@@ -555,64 +580,38 @@ fn bool Generator.emitGlobalVarDecl(Generator* gen, string_buffer.Buf* out, Decl
555580

556581
bool emit_header = gen.fast_build && d.isPublic();
557582

558-
if (gen.cur_external) {
559-
out.add("extern ");
560-
} else {
561-
if (!d.isExported() && !emit_header) out.add("static ");
562-
}
563-
564-
const char* cdef = d.getCDef();
565-
if (cdef) {
566-
out.add(cdef);
567-
} else {
568-
gen.emitGlobalVarTypePre(out, qt);
569-
out.space();
570-
gen.emitCName(out, d);
571-
gen.emitGlobalVarTypePost(out, qt);
583+
if (emit_header) {
584+
// generate extern declaration to header file
585+
Fragment* f = gen.getFragment();
586+
f.buf.add("extern ");
587+
gen.emitGlobalVarDeclCommon(f.buf, d);
588+
f.buf.add(";\n");
589+
gen.addFragment(f, true);
572590
}
573-
if (vd.hasAttrWeak()) out.add(" __attribute__((weak))");
574591

575-
const char* section = d.getSection();
576-
if (section) {
577-
out.space();
578-
gen.emitSectionAttr(out, section);
592+
if (gen.cur_external) {
593+
// generate extern declaration for interface file
594+
out.add("extern ");
595+
gen.emitGlobalVarDeclCommon(out, d);
596+
out.add(";\n");
597+
return false; // put this part in .c file
579598
}
580599

581-
if (!gen.cur_external) {
600+
if (!d.isExternal()) {
601+
// generate definition to c file
602+
if (!d.isExported() && !emit_header) out.add("static ");
603+
gen.emitGlobalVarDeclCommon(out, d);
582604
out.add(" = ");
583605
Expr* ie = vd.getInit();
584606
if (ie) {
585607
gen.emitConstExpr(out, ie);
586608
} else {
587-
// auto-initialize
609+
// auto-initialize (only required for embedded targets)
610+
QualType qt = d.getType();
588611
gen.emitAutoInit(out, qt);
589612
}
613+
out.add(";\n\n");
590614
}
591-
out.add(";\n\n");
592-
593-
if (emit_header) {
594-
Fragment* f = gen.getFragment();
595-
out = f.buf;
596-
597-
out.add("extern ");
598-
if (cdef) {
599-
out.add(cdef);
600-
} else {
601-
gen.emitGlobalVarTypePre(out, qt);
602-
out.space();
603-
gen.emitCName(out, d);
604-
gen.emitGlobalVarTypePost(out, qt);
605-
}
606-
if (vd.hasAttrWeak()) out.add(" __attribute__((weak))");
607-
608-
if (section) {
609-
out.space();
610-
gen.emitSectionAttr(out, section);
611-
}
612-
out.add(";\n");
613-
gen.addFragment(f, true);
614-
}
615-
616615
return false; // put this part in .c file
617616
}
618617

@@ -682,6 +681,7 @@ fn void Generator.emitGlobalDecl(Generator* gen, Decl* d) {
682681
string_buffer.Buf* out = gen.getBuf(d.isPublic());
683682
gen.gen_func_proto(fd, out);
684683
if (fd.isInline()) {
684+
d.setGenerated(); // for recursive inline functions
685685
out.newline();
686686
string_buffer.Buf* saved = gen.out;
687687
gen.out = out;
@@ -1079,6 +1079,9 @@ fn void Generator.on_module(void* arg, Module* m) {
10791079
gen.mod_name = m.getName();
10801080
gen.mod = m;
10811081

1082+
// Temporary disable call tracing when compiling the c2_trace module
1083+
gen.no_trace = !string.strcmp(gen.mod_name, "c2_trace");
1084+
10821085
if (gen.fast_build) {
10831086
out.clear();
10841087
gen.header.clear();
@@ -1276,9 +1279,17 @@ public fn void generate(string_pool.Pool* astPool,
12761279

12771280
mainComp.visitModules(Generator.on_module, &gen);
12781281

1279-
if (fast_build) gen.out.clear();
1280-
if (gen.trace_calls) gen.writeCalls(gen.out);
1281-
if (!fast_build || gen.trace_calls) {
1282+
if (fast_build) {
1283+
if (gen.trace_calls) {
1284+
gen.out.clear();
1285+
gen.out.add("#include \"c2_trace_tables.h\"\n\n");
1286+
gen.writeCalls(gen.out);
1287+
gen.write(dir, "c2_trace_tables.c", gen.out);
1288+
}
1289+
} else {
1290+
if (gen.trace_calls) {
1291+
gen.writeCalls(gen.out);
1292+
}
12821293
gen.write(dir, "build.c", gen.out);
12831294
}
12841295

generator/c/c_generator_call.c2

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ fn void Generator.emitCall(Generator* gen, string_buffer.Buf* out, Expr* e) {
5454
assert(func.getKind() == ExprKind.Member);
5555
MemberExpr* m = cast<MemberExpr*>(func);
5656
dest = m.getFullDecl();
57-
if (gen.trace_calls) {
57+
if (gen.trace_calls && !gen.no_trace) {
5858
out.print("(c2_trace_counts[%d]++, ",
5959
gen.addCall(dest.getFullName(), call.getStartLoc()));
6060
gen.emitCNameMod(out, dest, dest.getModule());
@@ -78,7 +78,7 @@ fn void Generator.emitCall(Generator* gen, string_buffer.Buf* out, Expr* e) {
7878
gen.emitMemberExprBase(out, func);
7979
}
8080
} else {
81-
bool no_trace = false;
81+
bool no_trace = gen.no_trace;
8282
// can be Member or Identifier
8383
if (func.getKind() == ExprKind.Identifier) {
8484
IdentifierExpr* i = cast<IdentifierExpr*>(func);

generator/c/c_generator_special.c2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ fn void Generator.createMakefile(Generator* gen,
105105
if (!m.isExternal() && m.isUsed()) out.print(" %s.o", m.getName());
106106
}
107107
if (gen.trace_calls) {
108-
out.add(" build.o");
108+
out.add(" c2_trace_tables.o");
109109
}
110110
out.newline();
111111
} else {

0 commit comments

Comments
 (0)