Skip to content

Commit bc3d1c7

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 af4ba19 commit bc3d1c7

File tree

12 files changed

+65
-13
lines changed

12 files changed

+65
-13
lines changed

common/build_target.c2

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

202203
public fn void Target.enableWarnings(Target* t) {
@@ -212,6 +213,7 @@ public fn void Target.enableWarnings(Target* t) {
212213
t.warnings.no_unused_enum_constant = false;
213214
t.warnings.no_unreachable_code = false;
214215
t.warnings.no_unknown_attribute = false;
216+
t.warnings.no_max_identifier_length = false;
215217
}
216218

217219
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
@@ -28,6 +28,7 @@ public type Flags struct {
2828
bool no_unused_enum_constant;
2929
bool no_unreachable_code;
3030
bool no_unknown_attribute;
31+
bool no_max_identifier_length;
3132
bool are_errors;
3233
}
3334

compiler/c2recipe_parser.c2

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,9 @@ fn void Parser.parseWarnings(Parser* p) {
583583
case "unknown-attribute":
584584
warnings.no_unknown_attribute = disable;
585585
break;
586+
case "max-identifier-length":
587+
warnings.no_max_identifier_length = disable;
588+
break;
586589
case "promote-to-error":
587590
warnings.are_errors = !disable;
588591
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);
@@ -272,7 +275,8 @@ fn void Compiler.build(Compiler* c,
272275
c.astPool,
273276
c.builder,
274277
&c.kwinfo,
275-
target.getFeatures());
278+
target.getFeatures(),
279+
c.warnings);
276280

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

@@ -281,7 +285,7 @@ fn void Compiler.build(Compiler* c,
281285
c.astPool,
282286
c.builder,
283287
&c.allmodules,
284-
c.target.getWarnings());
288+
c.warnings);
285289

286290
if (opts.show_libs) {
287291
c.showAllLibs();

parser/c2_parser.c2

Lines changed: 10 additions & 3 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;
@@ -79,15 +81,17 @@ public fn Parser* create(SourceMgr* sm,
7981
string_pool.Pool* pool,
8082
ast_builder.Builder* builder,
8183
const keywords.Info* kwinfo,
82-
const string_list.List* features)
84+
const string_list.List* features,
85+
const warning_flags.Flags* warnings)
8386
{
8487
Parser* p = calloc(1, sizeof(Parser));
8588
p.sm = sm;
8689
p.diags = diags;
8790
p.pool = pool;
8891
p.builder = builder;
89-
p.features = features;
9092
p.kwinfo = kwinfo;
93+
p.features = features;
94+
p.warnings = warnings;
9195
p.va_list_idx = pool.addStr("va_list", true);
9296
p.varargs_idx = pool.addStr("varargs", true);
9397
p.stdarg_idx = pool.addStr("stdarg", true);
@@ -123,6 +127,7 @@ public fn void Parser.parse(Parser* p, i32 file_id, bool is_interface, bool is_g
123127
p.sm.get_offset(p.file_id),
124128
p.kwinfo,
125129
p.features,
130+
p.warnings,
126131
nil,
127132
nil,
128133
nil,
@@ -145,6 +150,7 @@ public fn void Parser.parse(Parser* p, i32 file_id, bool is_interface, bool is_g
145150
p.sm.get_offset(p.file_id),
146151
p.kwinfo,
147152
p.features,
153+
p.warnings,
148154
Parser.on_tokenizer_error,
149155
p,
150156
false);
@@ -386,6 +392,7 @@ fn bool findName(const u32* names, u32 count, u32 name) {
386392
// returns the number of attributes parsed and stored in Builder
387393
fn u32 Parser.parseOptionalAttributes(Parser* p) {
388394
if (p.tok.kind != Kind.At) return 0;
395+
389396
p.consumeToken();
390397

391398
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;
@@ -266,6 +267,8 @@ public type Tokenizer struct {
266267

267268
string_pool.Pool* pool; // no ownership
268269
string_buffer.Buf* buf; // no ownership, used for strings and character constants
270+
const warning_flags.Flags* warnings;
271+
269272
ErrorFn on_error;
270273
void* on_error_arg;
271274

@@ -278,7 +281,7 @@ public type Tokenizer struct {
278281

279282
char[256] error_msg;
280283
}
281-
static_assert(408, sizeof(Tokenizer));
284+
static_assert(416, 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
ErrorFn on_error,
291295
void* on_error_arg,
292296
bool raw_mode)
@@ -300,6 +304,7 @@ public fn void Tokenizer.init(Tokenizer* t,
300304
t.line_start = input;
301305
t.pool = pool;
302306
t.buf = buf;
307+
t.warnings = warnings;
303308
t.on_error = on_error;
304309
t.on_error_arg = on_error_arg;
305310

@@ -685,6 +690,15 @@ fn void Tokenizer.error(Tokenizer* t, Token* result, const char* format @(printf
685690
if (t.on_error) t.on_error(t.on_error_arg, FatalError, result.loc, t.error_msg);
686691
}
687692

693+
fn void Tokenizer.warning(Tokenizer* t, SrcLoc loc, const char* format @(printf_format), ...) {
694+
va_list args;
695+
va_start(args, format);
696+
vsnprintf(t.error_msg, sizeof(t.error_msg), format, args);
697+
va_end(args);
698+
699+
if (t.on_error) t.on_error(t.on_error_arg, Warning, loc, t.error_msg);
700+
}
701+
688702
// generate an error but keep parsing
689703
fn void Tokenizer.num_error(Tokenizer* t, Token* result, const char* p, const char* format @(printf_format), ...) {
690704
va_list args;
@@ -720,9 +734,8 @@ fn void Tokenizer.lex_identifier(Tokenizer* t, Token* result) {
720734
while (Identifier_char[(u8)(*end)]) end++;
721735

722736
usize len = (usize)(end - start);
723-
if (len > constants.MaxIdentifierLen && !t.raw_mode) {
724-
t.error(result, "identifier too long (max %d chars)", constants.MaxIdentifierLen);
725-
return;
737+
if (len > constants.MaxIdentifierLen && !t.raw_mode && t.warnings && !t.warnings.no_max_identifier_length) {
738+
t.warning(result.loc, "identifier too long (max %d chars)", constants.MaxIdentifierLen);
726739
}
727740
t.cur += len;
728741
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
@@ -405,6 +405,7 @@ executable c2cat
405405
common/file/reader.c2
406406
common/string_list.c2
407407
common/utf8.c2
408+
common/warning_flags.c2
408409

409410
parser/c2_tokenizer.c2
410411
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 { // @warning{identifier too long (max 31 chars)}
99
i32 x;
1010
}
1111

test/naming/max_identifier_var.c2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ module test;
33

44
fn void test1() {
55
i32 thirty_one_is_fine_for_a_name__;
6-
i32 thirty_two_is_too_long_for_an_id; // @error{identifier too long (max 31 chars)}
6+
i32 thirty_two_is_too_long_for_an_id; // @warning{identifier too long (max 31 chars)}
77
}
88

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+

0 commit comments

Comments
 (0)