Skip to content

Commit 9748a7a

Browse files
committed
Compiler: add warning control over max_identifier_length
* pass warning flags to parser and tokenizer * let specific projects allow longer identifiers with `$warnings no-max-identifier-length`
1 parent c2234fd commit 9748a7a

File tree

11 files changed

+67
-13
lines changed

11 files changed

+67
-13
lines changed

common/build_target.c2

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ public fn void Target.disableWarnings(Target* t) {
196196
t.warnings.no_unused_label = true;
197197
t.warnings.no_unused_enum_constant = true;
198198
t.warnings.no_unreachable_code = true;
199+
t.warnings.no_max_identifier_length = true;
199200
}
200201

201202
public fn void Target.enableWarnings(Target* t) {
@@ -210,6 +211,7 @@ public fn void Target.enableWarnings(Target* t) {
210211
t.warnings.no_unused_label = false;
211212
t.warnings.no_unused_enum_constant = false;
212213
t.warnings.no_unreachable_code = false;
214+
t.warnings.no_max_identifier_length = false;
213215
}
214216

215217
public fn const warning_flags.Flags* Target.getWarnings(const Target* t) {

common/warning_flags.c2

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public type Flags struct {
2727
bool no_unused_label;
2828
bool no_unused_enum_constant;
2929
bool no_unreachable_code;
30+
bool no_max_identifier_length;
3031
bool are_errors;
3132
}
3233

compiler/c2recipe_parser.c2

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,9 @@ fn void Parser.parseWarnings(Parser* p) {
580580
case "unreachable-code":
581581
warnings.no_unreachable_code = disable;
582582
break;
583+
case "max-identifier-length":
584+
warnings.no_max_identifier_length = disable;
585+
break;
583586
case "promote-to-error":
584587
warnings.are_errors = !disable;
585588
break;

compiler/compiler.c2

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import string_pool;
4040
import string_utils;
4141
import target_info;
4242
import utils;
43+
import warning_flags;
4344

4445
import c_errno local;
4546
import ctype;
@@ -115,6 +116,7 @@ type Compiler struct {
115116
build_file.Info* build_info; // no ownership, can be nil
116117
build_target.Target* target; // no ownership
117118
const Options* opts; // no ownership
119+
const warning_flags.Flags* warnings; // no ownership
118120
target_info.Info targetInfo;
119121
PluginHandler* pluginHandler; // no ownership
120122

@@ -180,8 +182,9 @@ fn void Compiler.build(Compiler* c,
180182
c.target = target;
181183
c.opts = opts;
182184
c.pluginHandler = pluginHandler;
185+
c.warnings = target.getWarnings();
183186

184-
diags.setWarningAsError(target.getWarnings().are_errors);
187+
diags.setWarningAsError(c.warnings.are_errors);
185188
c.diags.clear();
186189

187190
c.context = ast_context.create(16*1024);
@@ -270,7 +273,8 @@ fn void Compiler.build(Compiler* c,
270273
c.astPool,
271274
c.builder,
272275
&c.kwinfo,
273-
target.getFeatures());
276+
target.getFeatures(),
277+
c.warnings);
274278

275279
ast.initialize(c.context, c.astPool, c.targetInfo.intWidth / 8, color.useColor());
276280

@@ -279,7 +283,7 @@ fn void Compiler.build(Compiler* c,
279283
c.astPool,
280284
c.builder,
281285
&c.allmodules,
282-
c.target.getWarnings());
286+
c.warnings);
283287

284288
if (opts.show_libs) {
285289
c.showAllLibs();

parser/c2_parser.c2

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import token local;
3434
#if DumpTokens
3535
import utils;
3636
#endif
37+
import warning_flags;
3738

3839
import stdarg local;
3940
import stdlib local;
@@ -58,8 +59,9 @@ public type Parser struct @(opaque) {
5859
diagnostics.Diags* diags;
5960
string_pool.Pool* pool;
6061
Builder* builder;
61-
const string_list.List* features;
6262
const keywords.Info* kwinfo;
63+
const string_list.List* features;
64+
const warning_flags.Flags* warnings;
6365
bool is_interface;
6466
u32 va_list_idx;
6567
u32 varargs_idx;
@@ -77,15 +79,17 @@ public fn Parser* create(SourceMgr* sm,
7779
string_pool.Pool* pool,
7880
ast_builder.Builder* builder,
7981
const keywords.Info* kwinfo,
80-
const string_list.List* features)
82+
const string_list.List* features,
83+
const warning_flags.Flags* warnings)
8184
{
8285
Parser* p = calloc(1, sizeof(Parser));
8386
p.sm = sm;
8487
p.diags = diags;
8588
p.pool = pool;
8689
p.builder = builder;
87-
p.features = features;
8890
p.kwinfo = kwinfo;
91+
p.features = features;
92+
p.warnings = warnings;
8993
p.va_list_idx = pool.addStr("va_list", true);
9094
p.varargs_idx = pool.addStr("varargs", true);
9195
p.stdarg_idx = pool.addStr("stdarg", true);
@@ -120,6 +124,7 @@ public fn void Parser.parse(Parser* p, i32 file_id, bool is_interface, bool is_g
120124
p.sm.get_offset(p.file_id),
121125
p.kwinfo,
122126
p.features,
127+
p.warnings,
123128
nil,
124129
nil,
125130
nil,
@@ -142,6 +147,7 @@ public fn void Parser.parse(Parser* p, i32 file_id, bool is_interface, bool is_g
142147
p.sm.get_offset(p.file_id),
143148
p.kwinfo,
144149
p.features,
150+
p.warnings,
145151
on_tokenizer_error,
146152
on_tokenizer_warning,
147153
p,
@@ -370,7 +376,10 @@ fn void Parser.parseTopLevel(Parser* p) {
370376

371377
// returns if embed attribute was seen
372378
fn void Parser.parseOptionalAttributes(Parser* p) {
373-
if (p.tok.kind != Kind.At) return;
379+
if (p.tok.kind == Kind.At) p.parseAttributes();
380+
}
381+
382+
fn void Parser.parseAttributes(Parser* p) {
374383
p.consumeToken();
375384

376385
p.expectAndConsume(Kind.LParen);

parser/c2_tokenizer.c2

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import string_list;
2424
import string_pool;
2525
import token local;
2626
import utf8;
27+
import warning_flags;
2728

2829
import string;
2930
import stdlib;
@@ -265,6 +266,8 @@ public type Tokenizer struct {
265266

266267
string_pool.Pool* pool; // no ownership
267268
string_buffer.Buf* buf; // no ownership, used for strings and character constants
269+
const warning_flags.Flags* warnings;
270+
268271
HandlerFn on_error;
269272
HandlerFn on_warning;
270273
void* fn_arg;
@@ -278,7 +281,7 @@ public type Tokenizer struct {
278281

279282
char[256] error_msg;
280283
}
281-
static_assert(416, sizeof(Tokenizer));
284+
static_assert(424, sizeof(Tokenizer));
282285

283286
public fn void Tokenizer.init(Tokenizer* t,
284287
string_pool.Pool* pool,
@@ -287,6 +290,7 @@ public fn void Tokenizer.init(Tokenizer* t,
287290
SrcLoc loc_start,
288291
const keywords.Info* kwinfo,
289292
const string_list.List* features,
293+
const warning_flags.Flags* warnings,
290294
HandlerFn on_error,
291295
HandlerFn on_warning,
292296
void* fn_arg,
@@ -301,6 +305,7 @@ public fn void Tokenizer.init(Tokenizer* t,
301305
t.line_start = input;
302306
t.pool = pool;
303307
t.buf = buf;
308+
t.warnings = warnings;
304309
t.on_error = on_error;
305310
t.on_warning = on_warning;
306311
t.fn_arg = fn_arg;
@@ -687,6 +692,15 @@ fn void Tokenizer.error(Tokenizer* t, Token* result, const char* format @(printf
687692
if (t.on_error) t.on_error(t.fn_arg, result.loc);
688693
}
689694

695+
fn void Tokenizer.warning(Tokenizer* t, SrcLoc loc, const char* format @(printf_format), ...) {
696+
va_list args;
697+
va_start(args, format);
698+
vsnprintf(t.error_msg, sizeof(t.error_msg), format, args);
699+
va_end(args);
700+
701+
if (t.on_warning) t.on_warning(t.fn_arg, loc);
702+
}
703+
690704
// generate an error but keep parsing
691705
fn void Tokenizer.num_error(Tokenizer* t, Token* result, const char* p, const char* format @(printf_format), ...) {
692706
va_list args;
@@ -722,9 +736,8 @@ fn void Tokenizer.lex_identifier(Tokenizer* t, Token* result) {
722736
while (Identifier_char[(u8)(*end)]) end++;
723737

724738
usize len = (usize)(end - start);
725-
if (len > constants.MaxIdentifierLen && !t.raw_mode) {
726-
t.error(result, "identifier too long (max %d chars)", constants.MaxIdentifierLen);
727-
return;
739+
if (len > constants.MaxIdentifierLen && !t.raw_mode && t.warnings && !t.warnings.no_max_identifier_length) {
740+
t.warning(result.loc, "identifier too long (max %d chars)", constants.MaxIdentifierLen);
728741
}
729742
t.cur += len;
730743
result.name_idx = t.pool.add(start, len, true);

recipe.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -401,6 +401,7 @@ executable c2cat
401401
common/file/reader.c2
402402
common/string_list.c2
403403
common/utf8.c2
404+
common/warning_flags.c2
404405

405406
parser/c2_tokenizer.c2
406407
parser/keywords.c2

test/naming/max_identifier_type.c2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ type T123456789012345678901234567890 struct {
55
i32 x;
66
}
77

8-
type thirty_two_is_too_long_for_an_id struct { // @error{identifier too long (max 31 chars)}
8+
type Thirty_two_is_too_long_for_an_id struct { // @error{identifier too long (max 31 chars)}
99
i32 x;
1010
}
1111

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// @warnings{no-unused}
2+
// @warnings{no-max-identifier-length}
3+
module test;
4+
5+
type T123456789012345678901234567890 struct {
6+
i32 x;
7+
}
8+
9+
type Very_long_type_names_are_ok_if_requested_for_specific_targets struct {
10+
i32 x;
11+
}
12+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// @warnings{no-unused}
2+
// @warnings{no-max-identifier-length}
3+
module test;
4+
5+
fn void test1() {
6+
i32 thirty_one_is_fine_for_a_name__;
7+
i32 very_long_var_names_are_ok_if_requested_for_specific_targets;
8+
}
9+

0 commit comments

Comments
 (0)