Skip to content

Commit 0e0a2cc

Browse files
committed
Parser: simplify type parsing
* simplify `Parser.parseTypeSpecifier`: always accept qualifier and arrays * simplify `Parser.parseSingleTypeSpecifier()`: always accept qualifier * simplify `Parser.parseOptionalArray()`: always accept arrays, remove base and recursion * simplify `Parser.parseAsType()`, `Parser.parseAsCastType()`, `Parser.isTemplateFunctionCall()`: remove `has_brackets` handling * add `isArray()` and `isPointer()` type functions for `TypeRef` and `TypeRefHolder` for clarity and flexibility * this fixes some problems: * `sizeof(const char*)` was rejected. * `a < i32.max` was interpreted as a template function call * `a < b * c > (d + 1)` was interpreted as a template function call (wrong error) * `sizeof(Handle[3])` now works for array types
1 parent ae78fb1 commit 0e0a2cc

File tree

11 files changed

+154
-131
lines changed

11 files changed

+154
-131
lines changed

analyser/module_analyser_function.c2

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ fn void Analyser.analyseFunction(Analyser* ma, FunctionDecl* fd) {
2727

2828
// check rtype for array-type
2929
TypeRef* rtype = fd.getReturnTypeRef();
30-
if (rtype.getNumArrays()) {
30+
if (rtype.isArray()) {
3131
ma.error(rtype.getLoc(), "functions are not allowed to return array types");
3232
}
3333

@@ -37,7 +37,7 @@ fn void Analyser.analyseFunction(Analyser* ma, FunctionDecl* fd) {
3737
for (u32 i=0; i<num_params; i++) {
3838
VarDecl* v = params[i];
3939
TypeRef* ref = v.getTypeRef();
40-
if (ref.getNumArrays()) {
40+
if (ref.isArray()) {
4141
ma.error(ref.getLoc(), "array types are not allowed here");
4242
}
4343
}

analyser/module_analyser_type.c2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ fn QualType Analyser.analyseUserTypeRef(Analyser* ma, TypeRef* ref) {
157157
//TODO already checked in findSymbolInModule
158158
//if (!ma.scope.checkAccess(d, user.loc)) return QualType_Invalid;
159159

160-
bool full = (ref.getNumPointers() == 0);
160+
bool full = !ref.isPointer();
161161
DeclCheckState state = d.getCheckState();
162162

163163
if (full && state == DeclCheckState.InProgress) {

ast/type_ref.c2

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ public fn void TypeRefHolder.setVolatile(TypeRefHolder* h) {
109109
r.flags.is_volatile = 1;
110110
}
111111

112+
public fn bool TypeRefHolder.isPointer(const TypeRefHolder* h) {
113+
TypeRef* r = cast<TypeRef*>(&h.ref);
114+
return r.flags.num_ptrs != 0;
115+
}
116+
112117
public fn void TypeRefHolder.addPointer(TypeRefHolder* h) {
113118
TypeRef* r = cast<TypeRef*>(&h.ref);
114119
assert(r.flags.num_ptrs != 3);
@@ -130,10 +135,17 @@ public fn u32 TypeRefHolder.getNumArrays(const TypeRefHolder* h) {
130135
return r.getNumArrays();
131136
}
132137

138+
#if 0
133139
public fn u32 TypeRefHolder.getNumPointers(const TypeRefHolder* h) {
134140
TypeRef* r = cast<TypeRef*>(&h.ref);
135141
return r.getNumPointers();
136142
}
143+
#endif
144+
145+
public fn bool TypeRefHolder.isArray(const TypeRefHolder* h) {
146+
TypeRef* r = cast<TypeRef*>(&h.ref);
147+
return r.flags.num_arrays != 0;
148+
}
137149

138150
public fn void TypeRefHolder.addArray(TypeRefHolder* h, Expr* array) {
139151
TypeRef* r = cast<TypeRef*>(&h.ref);
@@ -337,6 +349,10 @@ public fn SrcLoc TypeRef.getLoc(const TypeRef* r) {
337349
return r.loc;
338350
}
339351

352+
public fn bool TypeRef.isPointer(const TypeRef* r) {
353+
return r.flags.num_ptrs != 0;
354+
}
355+
340356
public fn u32 TypeRef.getNumPointers(const TypeRef* r) {
341357
return r.flags.num_ptrs;
342358
}
@@ -369,6 +385,10 @@ public fn void TypeRef.setUser(TypeRef* r, Decl* d) {
369385
r.refs[0].decl = d;
370386
}
371387

388+
public fn bool TypeRef.isArray(const TypeRef* r) {
389+
return r.flags.num_arrays != 0;
390+
}
391+
372392
public fn u32 TypeRef.getNumArrays(const TypeRef* r) {
373393
return r.flags.num_arrays;
374394
}

generator/c/dep_finder.c2

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,11 @@ fn void Finder.handleEnumType(Finder* s, EnumTypeDecl* etd) {
120120
fn void Finder.handleTypeRef(Finder* f, TypeRef* r) {
121121
const Decl* refDecl = r.getUserDecl();
122122
if (refDecl) {
123-
if (r.getNumPointers() && refDecl.isStructType()) {
123+
if (r.isPointer() && refDecl.isStructType()) {
124124
// if pointing to another struct, dont add dep, since we already have a forward decl
125125
// note: this also filters 'self' pointers
126126
} else {
127-
f.onDep(refDecl, r.getNumPointers() == 0);
127+
f.onDep(refDecl, !r.isPointer());
128128
}
129129
}
130130

parser/c2_parser.c2

Lines changed: 27 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ fn void Parser.parseFuncDecl(Parser* p, bool is_public) {
422422

423423
TypeRefHolder rtype.init();
424424
// Note: dont check arrays in this phase, but in Analyser
425-
p.parseTypeSpecifier(&rtype, true, true);
425+
p.parseTypeSpecifier(&rtype);
426426

427427
p.expectIdentifier();
428428
u32 func_name = p.tok.name_idx;
@@ -544,7 +544,7 @@ fn VarDecl* Parser.parseParamDecl(Parser* p, bool is_public, bool accept_default
544544

545545
TypeRefHolder ref.init();
546546
// Note: dont check arrays in this phase, but in Analyser
547-
p.parseTypeSpecifier(&ref, true, true);
547+
p.parseTypeSpecifier(&ref);
548548

549549
u32 name = 0;
550550
SrcLoc loc = p.tok.loc;
@@ -577,51 +577,32 @@ fn VarDecl* Parser.parseParamDecl(Parser* p, bool is_public, bool accept_default
577577
return param;
578578
}
579579

580-
fn void Parser.parseTypeSpecifier(Parser* p,
581-
TypeRefHolder* ref,
582-
bool allow_qualifier,
583-
bool allow_array) {
584-
p.parseSingleTypeSpecifier(ref, allow_qualifier);
585-
p.parseOptionalArray(ref, QualType_Invalid, allow_array);
580+
fn void Parser.parseTypeSpecifier(Parser* p, TypeRefHolder* ref) {
581+
p.parseSingleTypeSpecifier(ref);
582+
p.parseOptionalArray(ref);
586583
}
587584

588-
fn void Parser.parseOptionalArray(Parser* p,
589-
TypeRefHolder* ref,
590-
QualType base,
591-
bool allow_array) {
592-
if (p.tok.kind != Kind.LSquare) return;
585+
fn void Parser.parseOptionalArray(Parser* p, TypeRefHolder* ref) {
586+
while (p.tok.kind == Kind.LSquare) {
587+
if (ref.getNumArrays() == 3) p.error("arrays cannot have more than 3 dimensions");
588+
if (ref.isIncrArray()) p.error("incremental arrays cannot have more than 1 dimension");
593589

594-
if (!allow_array) p.error("array types are not allowed here");
595-
596-
if (ref.getNumArrays() == 3) p.error("arrays cannot have more than 3 dimensions");
597-
if (ref.isIncrArray()) p.error("incremental arrays cannot have more than 1 dimension");
598-
599-
p.consumeToken();
600-
601-
//bool is_incremental = false;
602-
603-
// NOTE: 'inverse' order, so char[2][4] -> 2 x ( 4 x char )
604-
605-
Expr* size = nil;
606-
if (p.tok.kind == Kind.RSquare) {
607-
// []
608-
ref.addArray(nil);
609-
p.consumeToken();
610-
} else if (p.tok.kind == Kind.Plus && p.tokenizer.lookahead(1, nil) == Kind.RSquare) {
611-
// [+]
612-
if (ref.getNumArrays()) p.error("incremental arrays cannot have more than 1 dimension");
613590
p.consumeToken();
614-
ref.setIncrArray();
615-
//is_incremental = true;
616-
p.expectAndConsume(Kind.RSquare);
617-
} else {
618-
// [<expr>]
619-
size = p.parseExpr();
620-
ref.addArray(size);
591+
592+
// NOTE: 'transposed' order, so char[2][4] -> 2 x ( 4 x char )
593+
if (p.tok.kind == Kind.Plus && p.tokenizer.lookahead(1, nil) == Kind.RSquare) {
594+
// [+]
595+
if (ref.isArray()) p.error("incremental arrays cannot have more than 1 dimension");
596+
p.consumeToken();
597+
ref.setIncrArray();
598+
} else {
599+
// [<expr>?]
600+
Expr* size = nil;
601+
if (p.tok.kind != Kind.RSquare) size = p.parseExpr();
602+
ref.addArray(size);
603+
}
621604
p.expectAndConsume(Kind.RSquare);
622605
}
623-
624-
p.parseOptionalArray(ref, base, true);
625606
}
626607

627608
fn void Parser.parseArrayEntry(Parser* p) {
@@ -642,7 +623,7 @@ fn void Parser.parseVarDecl(Parser* p, bool is_public) {
642623

643624
bool need_semi = true;
644625
TypeRefHolder ref.init();
645-
p.parseTypeSpecifier(&ref, true, true);
626+
p.parseTypeSpecifier(&ref);
646627

647628
for (;;) {
648629
p.expectIdentifier();
@@ -674,7 +655,7 @@ fn void Parser.parseVarDecl(Parser* p, bool is_public) {
674655
if (p.tok.kind != Kind.Comma)
675656
break;
676657
p.consumeToken();
677-
if (ref.getNumPointers() || ref.getNumArrays())
658+
if (ref.isPointer() || ref.isArray())
678659
p.error("pointer and array variables must be defined separately");
679660
}
680661
p.consumeSemicolon(need_semi);
@@ -742,12 +723,9 @@ fn BuiltinKind tokKindToBuiltinKind(token.Kind kind) {
742723
return Tok2builtin[kind - Kind.KW_bool];
743724
}
744725

745-
fn void Parser.parseSingleTypeSpecifier(Parser* p, TypeRefHolder* ref, bool allow_qualifier) {
746-
if (allow_qualifier) {
747-
// TODO give error if we get a qualifier
748-
u32 type_qualifier = p.parseOptionalTypeQualifier();
749-
ref.setQualifiers(type_qualifier);
750-
}
726+
fn void Parser.parseSingleTypeSpecifier(Parser* p, TypeRefHolder* ref) {
727+
u32 type_qualifier = p.parseOptionalTypeQualifier();
728+
ref.setQualifiers(type_qualifier);
751729

752730
Kind kind = p.tok.kind;
753731

0 commit comments

Comments
 (0)