Skip to content

Commit

Permalink
Add tentative definition
Browse files Browse the repository at this point in the history
  • Loading branch information
rui314 committed Dec 7, 2020
1 parent 1b99bad commit 85e46b1
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 0 deletions.
1 change: 1 addition & 0 deletions chibicc.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ struct Obj {
bool is_static;

// Global variable
bool is_tentative;
char *init_data;
Relocation *rel;

Expand Down
5 changes: 5 additions & 0 deletions codegen.c
Original file line number Diff line number Diff line change
Expand Up @@ -1136,6 +1136,11 @@ static void emit_data(Obj *prog) {
? MAX(16, var->align) : var->align;
println(" .align %d", align);

if (var->is_tentative) {
println(" .comm %s, %d, %d", var->name, var->ty->size, align);
continue;
}

if (var->init_data) {
println(" .data");
println("%s:", var->name);
Expand Down
31 changes: 31 additions & 0 deletions parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -2947,6 +2947,8 @@ static Token *global_variable(Token *tok, Type *basety, VarAttr *attr) {

if (equal(tok, "="))
gvar_initializer(&tok, tok->next, var);
else if (!attr->is_extern)
var->is_tentative = true;
}
return tok;
}
Expand All @@ -2962,6 +2964,33 @@ static bool is_function(Token *tok) {
return ty->kind == TY_FUNC;
}

// Remove redundant tentative definitions.
static void scan_globals(void) {
Obj head;
Obj *cur = &head;

for (Obj *var = globals; var; var = var->next) {
if (!var->is_tentative) {
cur = cur->next = var;
continue;
}

// Find another definition of the same identifier.
Obj *var2 = globals;
for (; var2; var2 = var2->next)
if (var != var2 && var2->is_definition && !strcmp(var->name, var2->name))
break;

// If there's another definition, the tentative definition
// is redundant
if (!var2)
cur = cur->next = var;
}

cur->next = NULL;
globals = head.next;
}

// program = (typedef | function-definition | global-variable)*
Obj *parse(Token *tok) {
globals = NULL;
Expand Down Expand Up @@ -2990,5 +3019,7 @@ Obj *parse(Token *tok) {
if (var->is_root)
mark_live(var);

// Remove redundant tentative definitions.
scan_globals();
return globals;
}
2 changes: 2 additions & 0 deletions test/common
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ int *ext2 = &ext1;
int ext3 = 7;
int ext_fn1(int x) { return x; }
int ext_fn2(int x) { return x; }
int common_ext2 = 3;
static int common_local;

int false_fn() { return 512; }
int true_fn() { return 513; }
Expand Down
19 changes: 19 additions & 0 deletions test/commonsym.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "test.h"

int x;
int x = 5;
int y = 7;
int y;
int common_ext1;
int common_ext2;
static int common_local;

int main() {
ASSERT(5, x);
ASSERT(7, y);
ASSERT(0, common_ext1);
ASSERT(3, common_ext2);

printf("OK\n");
return 0;
}

0 comments on commit 85e46b1

Please sign in to comment.