commit 1c925d70a8145ed26506926dc92c1afa4c92fb11
parent 0916935c02c6513acbb0f36d625c7cb25315236f
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Sat, 8 Aug 2015 21:18:18 +0200
Fix storage for functions in IR
There are three kind os static variables:
- GLOBAL: Variable visibles to the full program
- PRIVATE: Variable visible only in the current module
- LOCAL: Variable visible only in the current function.
This patch adds different flags for every one of them, and
independent of the IS_STATIC flag.
Diffstat:
5 files changed, 23 insertions(+), 17 deletions(-)
diff --git a/cc1/cc1.h b/cc1/cc1.h
@@ -125,15 +125,17 @@ enum {
/* symbol flags */
enum {
- ISGLOBAL = 1,
- ISSTATIC = 2,
- ISAUTO = 4,
- ISREGISTER = 8,
- ISDEFINED = 16,
- ISFIELD = 32,
- ISEXTERN = 64,
- ISUSED = 128,
- ISCONSTANT = 256
+ ISSTATIC = 1,
+ ISAUTO = 2,
+ ISREGISTER = 4,
+ ISDEFINED = 8,
+ ISFIELD = 16,
+ ISEXTERN = 32,
+ ISUSED = 64,
+ ISCONSTANT = 128,
+ ISGLOBAL = 256,
+ ISPRIVATE = 512,
+ ISLOCAL = 1024
};
diff --git a/cc1/code.c b/cc1/code.c
@@ -151,14 +151,17 @@ static void
emitvar(Symbol *sym)
{
char c;
+ short flags = sym->flags;
- if (sym->flags & ISSTATIC)
- c = (sym->flags & ISGLOBAL) ? L_PRIVATE : L_STATIC;
- else if (sym->flags & ISGLOBAL)
+ if (flags & ISLOCAL)
+ c = L_LOCAL;
+ else if (flags & ISPRIVATE)
+ c = L_PRIVATE;
+ else if (flags & ISGLOBAL)
c = L_PUBLIC;
- else if (sym->flags & ISREGISTER)
+ else if (flags & ISREGISTER)
c = L_REGISTER;
- else if (sym->flags & ISFIELD)
+ else if (flags & ISFIELD)
c = L_FIELD;
else
c = L_AUTO;
diff --git a/cc1/decl.c b/cc1/decl.c
@@ -461,6 +461,8 @@ internal(Symbol *sym, int sclass, Type *data)
initializer(sym);
/* TODO: check if the variable is extern and has initializer */
}
+ if (sym->flags & ISSTATIC)
+ sym->flags |= ISLOCAL;
emit(ODECL, sym);
}
@@ -471,10 +473,10 @@ external(Symbol *sym, int sclass, Type *data)
warn("empty declaration");
return;
}
- sym->flags |= ISSTATIC|ISGLOBAL;
if (sym->flags & (ISREGISTER|ISAUTO))
error("incorrect storage class for file-scope declaration");
+ sym->flags |= (sym->flags & ISSTATIC) ? ISPRIVATE : ISGLOBAL;
if (sym->type->op == FTN && yytoken == '{') {
if (sym->token == TYPEIDEN)
diff --git a/cc1/symbol.c b/cc1/symbol.c
@@ -191,7 +191,6 @@ install(unsigned ns, Symbol *sym)
if (sym->flags & ISDEFINED)
return NULL;
sym->flags |= ISDEFINED;
- sym = yylval.sym;
} else {
char *name = sym->name;
Symbol **h;
diff --git a/inc/cc.h b/inc/cc.h
@@ -61,7 +61,7 @@ typedef unsigned bool;
#define L_PUBLIC 'G'
#define L_PRIVATE 'Y'
-#define L_STATIC 'T'
+#define L_LOCAL 'T'
#define L_REGISTER 'R'
#define L_FIELD 'M'
#define L_AUTO 'A'