Skip to content

Commit b3b9951

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 13135ea commit b3b9951

File tree

12 files changed

+62
-10
lines changed

12 files changed

+62
-10
lines changed

common/build_target.c2

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ public fn void Target.disableWarnings(Target* t) {
203203
t.warnings.no_unreachable_code = true;
204204
t.warnings.no_unknown_attribute = true;
205205
t.warnings.no_deprecated = true;
206+
t.warnings.no_max_identifier_length = true;
206207
}
207208

208209
public fn void Target.enableWarnings(Target* t) {
@@ -219,6 +220,7 @@ public fn void Target.enableWarnings(Target* t) {
219220
t.warnings.no_unreachable_code = false;
220221
t.warnings.no_unknown_attribute = false;
221222
t.warnings.no_deprecated = false;
223+
t.warnings.no_max_identifier_length = false;
222224
}
223225

224226
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
@@ -29,6 +29,7 @@ public type Flags struct {
2929
bool no_unreachable_code;
3030
bool no_unknown_attribute;
3131
bool no_deprecated;
32+
bool no_max_identifier_length;
3233
bool are_errors;
3334
}
3435

compiler/c2recipe_parser.c2

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,9 @@ fn void Parser.parseWarnings(Parser* p) {
590590
case "deprecated":
591591
warnings.no_deprecated = disable;
592592
break;
593+
case "max-identifier-length":
594+
warnings.no_max_identifier_length = disable;
595+
break;
593596
case "promote-to-error":
594597
warnings.are_errors = !disable;
595598
break;

compiler/compiler.c2

Lines changed: 8 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;
@@ -119,6 +120,7 @@ type Compiler struct {
119120
const Options* opts; // no ownership
120121
target_info.Info targetInfo;
121122
PluginHandler* pluginHandler; // no ownership
123+
const warning_flags.Flags* warnings; // no ownership
122124

123125
ast_context.Context* context;
124126
string_pool.Pool* astPool;
@@ -182,6 +184,7 @@ fn void Compiler.build(Compiler* c,
182184
c.target = target;
183185
c.opts = opts;
184186
c.pluginHandler = pluginHandler;
187+
c.warnings = target.getWarnings();
185188

186189
if (opts.bootstrap) {
187190
c.target.setBackEnd(C);
@@ -199,7 +202,8 @@ fn void Compiler.build(Compiler* c,
199202
c.target.disableAsserts();
200203
}
201204

202-
diags.setWarningAsError(target.getWarnings().are_errors);
205+
diags.setWarningAsError(c.warnings.are_errors);
206+
203207
c.diags.clear();
204208

205209
c.context = ast_context.create(16*1024);
@@ -215,7 +219,7 @@ fn void Compiler.build(Compiler* c,
215219

216220
c.parse_queue.init(false, 64);
217221

218-
c.attr_handler = attr_handler.create(diags, target.getWarnings());
222+
c.attr_handler = attr_handler.create(diags, c.warnings);
219223
c.builder = ast_builder.create(c.context,
220224
diags,
221225
c.auxPool,
@@ -291,6 +295,7 @@ fn void Compiler.build(Compiler* c,
291295
c.builder,
292296
&c.kwinfo,
293297
c.target.getFeatures(),
298+
c.warnings,
294299
c.target.hasAsserts());
295300

296301
ast.initialize(c.context, c.astPool, c.targetInfo.intWidth / 8, color.useColor());
@@ -300,7 +305,7 @@ fn void Compiler.build(Compiler* c,
300305
c.astPool,
301306
c.builder,
302307
&c.allmodules,
303-
c.target.getWarnings(),
308+
c.warnings,
304309
c.target.hasAsserts(),
305310
c.opts.check_only);
306311

parser/c2_parser.c2

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import value_type local;
3535
#if DumpTokens
3636
import utils;
3737
#endif
38+
import warning_flags;
3839

3940
import csetjmp local;
4041
import ctype local;
@@ -61,6 +62,7 @@ public type Parser struct @(opaque) {
6162
Builder* builder;
6263
const string_list.List* features;
6364
const keywords.Info* kwinfo;
65+
const warning_flags.Flags* warnings;
6466
bool is_interface;
6567
bool is_generated;
6668
bool has_asserts;
@@ -86,6 +88,7 @@ public fn Parser* create(SourceMgr* sm,
8688
ast_builder.Builder* builder,
8789
const keywords.Info* kwinfo,
8890
const string_list.List* features,
91+
const warning_flags.Flags* warnings,
8992
bool has_asserts)
9093
{
9194
Parser* p = calloc(1, sizeof(Parser));
@@ -95,6 +98,7 @@ public fn Parser* create(SourceMgr* sm,
9598
p.builder = builder;
9699
p.features = features;
97100
p.kwinfo = kwinfo;
101+
p.warnings = warnings;
98102
p.has_asserts = has_asserts;
99103
p.va_list_idx = pool.addStr("va_list", true);
100104
p.varargs_idx = pool.addStr("varargs", true);
@@ -135,6 +139,7 @@ public fn void Parser.parse(Parser* p, i32 file_id, bool is_interface, bool is_g
135139
p.sm.get_offset(p.file_id),
136140
p.kwinfo,
137141
p.features,
142+
p.warnings,
138143
nil,
139144
nil,
140145
nil,
@@ -157,6 +162,7 @@ public fn void Parser.parse(Parser* p, i32 file_id, bool is_interface, bool is_g
157162
p.sm.get_offset(p.file_id),
158163
p.kwinfo,
159164
p.features,
165+
p.warnings,
160166
Parser.on_tokenizer_error,
161167
p,
162168
false);

parser/c2_tokenizer.c2

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

2829
import ctype local;
2930
import stdarg local;
@@ -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
ErrorFn on_error;
269272
void* on_error_arg;
270273

@@ -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
@@ -411,6 +411,7 @@ executable c2cat
411411
common/file/reader.c2
412412
common/string_list.c2
413413
common/utf8.c2
414+
common/warning_flags.c2
414415

415416
parser/c2_tokenizer.c2
416417
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)