Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@

- [x] 有三个移入/规约冲突(关于 `annon-right-type` ) 这些冲突是因为这个标注类型可能为空导致的。
- [ ] 利用 `lib.h` 给的哈希表存放一些类型前置定义
- [ ] 检查在全局变量/Struct/Union/Enum/Typedef声明中出现的标识符是否已经在全局出现过
- [ ] 检查Struct/Union/Enum/Typedef被使用时是否已经有前置定义
- [x] 检查在全局变量/Struct/Union/Enum/Typedef声明中出现的标识符是否已经在全局出现过
- [x] 检查Struct/Union/Enum/Typedef被使用时是否已经有前置定义
- [ ] 检查Struct/Union的字段内是否有变量名重复
- [ ] 完善build、test、使用文档

13 changes: 13 additions & 0 deletions resource/test/test-identifier-predeclared/testcase1.jtl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
struct Foo;

struct Foo a; // OK: Foo is registered as struct at line 1

enum Foo b; // Warning: Identifier Foo has been registered as struct, not enum

union Foo c; // Warning: Identifier Foo has been registered as struct, not union


typedef Foo foo_t;
foo_t d; // OK: foo_t has been registered as typedef
bar_t e; // Warning: Identifier bar_t has never been registered

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// redefine a variable-registered identifier as other types

// some variables to be used in the test
char var1;
char var2;
char var3;
char var4;
char var5;
char var6;

// 1. redefine as a variable
int var1; // Warning

// 2. redefine as an enumerator
enum SomeEnum { var2 }; // Warning

// 3. redefine as a struct
struct var3 { int a; }; // OK

// 4. redefine as a union
union var4 { int a; }; // OK

// 5. redefine as an enum
enum var5 { a, b, c }; // OK

// 6. redefine as a typedef
typedef int var6; // Warning
81 changes: 81 additions & 0 deletions src/lang.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "lang.h"
#include "lib.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Expand Down Expand Up @@ -78,13 +79,19 @@ struct enum_ele_list* TECons(char* name, struct enum_ele_list* next) {
struct enum_ele_list* res = new_enum_ele_list_ptr();
res->name = name;
res->next = next;

register_identifier_enumerator(name);

return res;
}

struct left_type* TStructType(char* name) {
struct left_type* res = new_left_type_ptr();
res->t = T_STRUCT_TYPE;
res->d.STRUCT_TYPE.name = name;

check_identifier_struct(name);

return res;
}

Expand All @@ -93,13 +100,18 @@ struct left_type* TNewStructType(char* name, struct type_list* fld) {
res->t = T_NEW_STRUCT_TYPE;
res->d.NEW_STRUCT_TYPE.name = name;
res->d.NEW_STRUCT_TYPE.fld = fld;

register_identifier_struct(name);
return res;
}

struct left_type* TUnionType(char* name) {
struct left_type* res = new_left_type_ptr();
res->t = T_UNION_TYPE;
res->d.UNION_TYPE.name = name;

check_identifier_union(name);

return res;
}

Expand All @@ -108,13 +120,19 @@ struct left_type* TNewUnionType(char* name, struct type_list* fld) {
res->t = T_NEW_UNION_TYPE;
res->d.NEW_UNION_TYPE.name = name;
res->d.NEW_UNION_TYPE.fld = fld;

register_identifier_union(name);

return res;
}

struct left_type* TEnumType(char* name) {
struct left_type* res = new_left_type_ptr();
res->t = T_ENUM_TYPE;
res->d.ENUM_TYPE.name = name;

check_identifier_enum(name);

return res;
}

Expand All @@ -123,6 +141,9 @@ struct left_type* TNewEnumType(char* name, struct enum_ele_list* ele) {
res->t = T_NEW_ENUM_TYPE;
res->d.NEW_ENUM_TYPE.name = name;
res->d.NEW_ENUM_TYPE.ele = ele;

register_identifier_enum(name);

return res;
}

Expand All @@ -142,6 +163,9 @@ struct left_type* TDefinedType(char* name) {
struct left_type* res = new_left_type_ptr();
res->t = T_DEFINED_TYPE;
res->d.DEFINED_TYPE.name = name;

check_identifier_typedef(name);

return res;
}

Expand Down Expand Up @@ -182,13 +206,19 @@ struct glob_item* TStructDef(char* name, struct type_list* fld) {
res->t = T_STRUCT_DEF;
res->d.STRUCT_DEF.name = name;
res->d.STRUCT_DEF.fld = fld;

register_identifier_struct(name);

return res;
}

struct glob_item* TStructDecl(char* name) {
struct glob_item* res = new_glob_item_ptr();
res->t = T_STRUCT_DECL;
res->d.STRUCT_DECL.name = name;

register_identifier_struct(name);

return res;
}

Expand All @@ -197,13 +227,19 @@ struct glob_item* TUnionDef(char* name, struct type_list* fld) {
res->t = T_UNION_DEF;
res->d.UNION_DEF.name = name;
res->d.UNION_DEF.fld = fld;

register_identifier_union(name);

return res;
}

struct glob_item* TUnionDecl(char* name) {
struct glob_item* res = new_glob_item_ptr();
res->t = T_UNION_DECL;
res->d.UNION_DECL.name = name;

register_identifier_union(name);

return res;
}

Expand All @@ -212,13 +248,19 @@ struct glob_item* TEnumDef(char* name, struct enum_ele_list* ele) {
res->t = T_ENUM_DEF;
res->d.ENUM_DEF.name = name;
res->d.ENUM_DEF.ele = ele;

register_identifier_enum(name);

return res;
}

struct glob_item* TEnumDecl(char* name) {
struct glob_item* res = new_glob_item_ptr();
res->t = T_ENUM_DECL;
res->d.ENUM_DECL.name = name;

register_identifier_enum(name);

return res;
}

Expand All @@ -227,6 +269,26 @@ struct glob_item* TTypeDef(struct left_type* t, struct var_decl_expr* e) {
res->t = T_TYPE_DEF;
res->d.TYPE_DEF.t = t;
res->d.TYPE_DEF.e = e;

// get the core type name and register it
struct var_decl_expr* ptr = e;
while (ptr->t != T_ORIG_TYPE) {
switch (ptr->t) {
case T_PTR_TYPE:
ptr = ptr->d.PTR_TYPE.base;
break;
case T_ARRAY_TYPE:
ptr = ptr->d.ARRAY_TYPE.base;
break;
case T_FUNC_TYPE:
ptr = ptr->d.FUNC_TYPE.ret;
break;
case T_ORIG_TYPE:
break;
}
}
register_identifier_typedef(ptr->d.ORIG_TYPE.name);

return res;
}

Expand All @@ -235,6 +297,25 @@ struct glob_item* TVarDef(struct left_type* t, struct var_decl_expr* e) {
res->t = T_VAR_DEF;
res->d.VAR_DEF.t = t;
res->d.VAR_DEF.e = e;

// get the core type name and register it
struct var_decl_expr* ptr = e;
while (ptr->t != T_ORIG_TYPE) {
switch (ptr->t) {
case T_PTR_TYPE:
ptr = ptr->d.PTR_TYPE.base;
break;
case T_ARRAY_TYPE:
ptr = ptr->d.ARRAY_TYPE.base;
break;
case T_FUNC_TYPE:
ptr = ptr->d.FUNC_TYPE.ret;
break;
case T_ORIG_TYPE:
break;
}
}
register_identifier_variable(ptr->d.ORIG_TYPE.name);
return res;
}

Expand Down
Loading
Loading