Skip to content
Open
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
2 changes: 2 additions & 0 deletions common/build_target.c2
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ public fn void Target.disableWarnings(Target* t) {
t.warnings.no_unused_label = true;
t.warnings.no_unused_enum_constant = true;
t.warnings.no_unreachable_code = true;
t.warnings.no_max_identifier_length = true;
}

public fn void Target.enableWarnings(Target* t) {
Expand All @@ -210,6 +211,7 @@ public fn void Target.enableWarnings(Target* t) {
t.warnings.no_unused_label = false;
t.warnings.no_unused_enum_constant = false;
t.warnings.no_unreachable_code = false;
t.warnings.no_max_identifier_length = false;
}

public fn const warning_flags.Flags* Target.getWarnings(const Target* t) {
Expand Down
1 change: 1 addition & 0 deletions common/warning_flags.c2
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public type Flags struct {
bool no_unused_label;
bool no_unused_enum_constant;
bool no_unreachable_code;
bool no_max_identifier_length;
bool are_errors;
}

3 changes: 3 additions & 0 deletions compiler/c2recipe_parser.c2
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,9 @@ fn void Parser.parseWarnings(Parser* p) {
case "unreachable-code":
warnings.no_unreachable_code = disable;
break;
case "max-identifier-length":
warnings.no_max_identifier_length = disable;
break;
case "promote-to-error":
warnings.are_errors = !disable;
break;
Expand Down
10 changes: 7 additions & 3 deletions compiler/compiler.c2
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import string_pool;
import string_utils;
import target_info;
import utils;
import warning_flags;

import c_errno local;
import ctype;
Expand Down Expand Up @@ -115,6 +116,7 @@ type Compiler struct {
build_file.Info* build_info; // no ownership, can be nil
build_target.Target* target; // no ownership
const Options* opts; // no ownership
const warning_flags.Flags* warnings; // no ownership
target_info.Info targetInfo;
PluginHandler* pluginHandler; // no ownership

Expand Down Expand Up @@ -180,8 +182,9 @@ fn void Compiler.build(Compiler* c,
c.target = target;
c.opts = opts;
c.pluginHandler = pluginHandler;
c.warnings = target.getWarnings();

diags.setWarningAsError(target.getWarnings().are_errors);
diags.setWarningAsError(c.warnings.are_errors);
c.diags.clear();

c.context = ast_context.create(16*1024);
Expand Down Expand Up @@ -270,7 +273,8 @@ fn void Compiler.build(Compiler* c,
c.astPool,
c.builder,
&c.kwinfo,
target.getFeatures());
target.getFeatures(),
c.warnings);

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

Expand All @@ -279,7 +283,7 @@ fn void Compiler.build(Compiler* c,
c.astPool,
c.builder,
&c.allmodules,
c.target.getWarnings());
c.warnings);

if (opts.show_libs) {
c.showAllLibs();
Expand Down
17 changes: 13 additions & 4 deletions parser/c2_parser.c2
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import token local;
#if DumpTokens
import utils;
#endif
import warning_flags;

import stdarg local;
import stdlib local;
Expand All @@ -58,8 +59,9 @@ public type Parser struct @(opaque) {
diagnostics.Diags* diags;
string_pool.Pool* pool;
Builder* builder;
const string_list.List* features;
const keywords.Info* kwinfo;
const string_list.List* features;
const warning_flags.Flags* warnings;
bool is_interface;
u32 va_list_idx;
u32 varargs_idx;
Expand All @@ -77,15 +79,17 @@ public fn Parser* create(SourceMgr* sm,
string_pool.Pool* pool,
ast_builder.Builder* builder,
const keywords.Info* kwinfo,
const string_list.List* features)
const string_list.List* features,
const warning_flags.Flags* warnings)
{
Parser* p = calloc(1, sizeof(Parser));
p.sm = sm;
p.diags = diags;
p.pool = pool;
p.builder = builder;
p.features = features;
p.kwinfo = kwinfo;
p.features = features;
p.warnings = warnings;
p.va_list_idx = pool.addStr("va_list", true);
p.varargs_idx = pool.addStr("varargs", true);
p.stdarg_idx = pool.addStr("stdarg", true);
Expand Down Expand Up @@ -120,6 +124,7 @@ public fn void Parser.parse(Parser* p, i32 file_id, bool is_interface, bool is_g
p.sm.get_offset(p.file_id),
p.kwinfo,
p.features,
p.warnings,
nil,
nil,
nil,
Expand All @@ -142,6 +147,7 @@ public fn void Parser.parse(Parser* p, i32 file_id, bool is_interface, bool is_g
p.sm.get_offset(p.file_id),
p.kwinfo,
p.features,
p.warnings,
on_tokenizer_error,
on_tokenizer_warning,
p,
Expand Down Expand Up @@ -370,7 +376,10 @@ fn void Parser.parseTopLevel(Parser* p) {

// returns if embed attribute was seen
fn void Parser.parseOptionalAttributes(Parser* p) {
if (p.tok.kind != Kind.At) return;
if (p.tok.kind == Kind.At) p.parseAttributes();
}

fn void Parser.parseAttributes(Parser* p) {
p.consumeToken();

p.expectAndConsume(Kind.LParen);
Expand Down
21 changes: 17 additions & 4 deletions parser/c2_tokenizer.c2
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import string_list;
import string_pool;
import token local;
import utf8;
import warning_flags;

import string;
import stdlib;
Expand Down Expand Up @@ -265,6 +266,8 @@ public type Tokenizer struct {

string_pool.Pool* pool; // no ownership
string_buffer.Buf* buf; // no ownership, used for strings and character constants
const warning_flags.Flags* warnings;

HandlerFn on_error;
HandlerFn on_warning;
void* fn_arg;
Expand All @@ -278,7 +281,7 @@ public type Tokenizer struct {

char[256] error_msg;
}
static_assert(416, sizeof(Tokenizer));
static_assert(424, sizeof(Tokenizer));

public fn void Tokenizer.init(Tokenizer* t,
string_pool.Pool* pool,
Expand All @@ -287,6 +290,7 @@ public fn void Tokenizer.init(Tokenizer* t,
SrcLoc loc_start,
const keywords.Info* kwinfo,
const string_list.List* features,
const warning_flags.Flags* warnings,
HandlerFn on_error,
HandlerFn on_warning,
void* fn_arg,
Expand All @@ -301,6 +305,7 @@ public fn void Tokenizer.init(Tokenizer* t,
t.line_start = input;
t.pool = pool;
t.buf = buf;
t.warnings = warnings;
t.on_error = on_error;
t.on_warning = on_warning;
t.fn_arg = fn_arg;
Expand Down Expand Up @@ -687,6 +692,15 @@ fn void Tokenizer.error(Tokenizer* t, Token* result, const char* format @(printf
if (t.on_error) t.on_error(t.fn_arg, result.loc);
}

fn void Tokenizer.warning(Tokenizer* t, SrcLoc loc, const char* format @(printf_format), ...) {
va_list args;
va_start(args, format);
vsnprintf(t.error_msg, sizeof(t.error_msg), format, args);
va_end(args);

if (t.on_warning) t.on_warning(t.fn_arg, loc);
}

// generate an error but keep parsing
fn void Tokenizer.num_error(Tokenizer* t, Token* result, const char* p, const char* format @(printf_format), ...) {
va_list args;
Expand Down Expand Up @@ -722,9 +736,8 @@ fn void Tokenizer.lex_identifier(Tokenizer* t, Token* result) {
while (Identifier_char[(u8)(*end)]) end++;

usize len = (usize)(end - start);
if (len > constants.MaxIdentifierLen && !t.raw_mode) {
t.error(result, "identifier too long (max %d chars)", constants.MaxIdentifierLen);
return;
if (len > constants.MaxIdentifierLen && !t.raw_mode && t.warnings && !t.warnings.no_max_identifier_length) {
t.warning(result.loc, "identifier too long (max %d chars)", constants.MaxIdentifierLen);
}
t.cur += len;
result.name_idx = t.pool.add(start, len, true);
Expand Down
1 change: 1 addition & 0 deletions recipe.txt
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@ executable c2cat
common/file/reader.c2
common/string_list.c2
common/utf8.c2
common/warning_flags.c2

parser/c2_tokenizer.c2
parser/keywords.c2
Expand Down
2 changes: 1 addition & 1 deletion test/naming/max_identifier_type.c2
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ type T123456789012345678901234567890 struct {
i32 x;
}

type thirty_two_is_too_long_for_an_id struct { // @error{identifier too long (max 31 chars)}
type Thirty_two_is_too_long_for_an_id struct { // @error{identifier too long (max 31 chars)}
i32 x;
}

12 changes: 12 additions & 0 deletions test/naming/no_max_identifier_type.c2
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// @warnings{no-unused}
// @warnings{no-max-identifier-length}
module test;

type T123456789012345678901234567890 struct {
i32 x;
}

type Very_long_type_names_are_ok_if_requested_for_specific_targets struct {
i32 x;
}

9 changes: 9 additions & 0 deletions test/naming/no_max_identifier_var.c2
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// @warnings{no-unused}
// @warnings{no-max-identifier-length}
module test;

fn void test1() {
i32 thirty_one_is_fine_for_a_name__;
i32 very_long_var_names_are_ok_if_requested_for_specific_targets;
}

2 changes: 1 addition & 1 deletion tools/c2cat.c2
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ public fn i32 c2cat(const char* filename, bool use_color)
keywords.Info kwinfo;
kwinfo.init(ctx.pool);
c2_tokenizer.Tokenizer tokenizer;
tokenizer.init(ctx.pool, buf, ctx.input, 0, &kwinfo, &features, nil, nil, nil, true);
tokenizer.init(ctx.pool, buf, ctx.input, 0, &kwinfo, &features, nil, nil, nil, nil, true);
ctx.tokenizer = &tokenizer;

Token tok;
Expand Down