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 @@ -201,6 +201,7 @@ public fn void Target.disableWarnings(Target* t) {
t.warnings.no_unreachable_code = true;
t.warnings.no_unknown_attribute = true;
t.warnings.no_deprecated = true;
t.warnings.no_max_identifier_length = true;
}

public fn void Target.enableWarnings(Target* t) {
Expand All @@ -217,6 +218,7 @@ public fn void Target.enableWarnings(Target* t) {
t.warnings.no_unreachable_code = false;
t.warnings.no_unknown_attribute = false;
t.warnings.no_deprecated = 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 @@ -29,6 +29,7 @@ public type Flags struct {
bool no_unreachable_code;
bool no_unknown_attribute;
bool no_deprecated;
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 @@ -590,6 +590,9 @@ fn void Parser.parseWarnings(Parser* p) {
case "deprecated":
warnings.no_deprecated = disable;
break;
case "max-identifier-length":
warnings.no_max_identifier_length = disable;
break;
case "promote-to-error":
warnings.are_errors = !disable;
break;
Expand Down
11 changes: 8 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 @@ -119,6 +120,7 @@ type Compiler struct {
const Options* opts; // no ownership
target_info.Info targetInfo;
PluginHandler* pluginHandler; // no ownership
const warning_flags.Flags* warnings; // no ownership

ast_context.Context* context;
string_pool.Pool* astPool;
Expand Down Expand Up @@ -182,6 +184,7 @@ fn void Compiler.build(Compiler* c,
c.target = target;
c.opts = opts;
c.pluginHandler = pluginHandler;
c.warnings = target.getWarnings();

if (opts.bootstrap) {
c.target.setBackEnd(C);
Expand All @@ -199,7 +202,8 @@ fn void Compiler.build(Compiler* c,
c.target.disableAsserts();
}

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

c.diags.clear();

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

c.parse_queue.init(false, 64);

c.attr_handler = attr_handler.create(diags, target.getWarnings());
c.attr_handler = attr_handler.create(diags, c.warnings);
c.builder = ast_builder.create(c.context,
diags,
c.auxPool,
Expand Down Expand Up @@ -291,6 +295,7 @@ fn void Compiler.build(Compiler* c,
c.builder,
&c.kwinfo,
c.target.getFeatures(),
c.warnings,
c.target.hasAsserts());

ast.initialize(c.context, c.astPool, c.targetInfo.intWidth / 8, color.useColor());
Expand All @@ -300,7 +305,7 @@ fn void Compiler.build(Compiler* c,
c.astPool,
c.builder,
&c.allmodules,
c.target.getWarnings(),
c.warnings,
c.target.hasAsserts(),
c.opts.check_only);

Expand Down
6 changes: 6 additions & 0 deletions parser/c2_parser.c2
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import value_type local;
#if DumpTokens
import utils;
#endif
import warning_flags;

import csetjmp local;
import ctype local;
Expand All @@ -61,6 +62,7 @@ public type Parser struct @(opaque) {
Builder* builder;
const string_list.List* features;
const keywords.Info* kwinfo;
const warning_flags.Flags* warnings;
bool is_interface;
bool is_generated;
bool has_asserts;
Expand All @@ -86,6 +88,7 @@ public fn Parser* create(SourceMgr* sm,
ast_builder.Builder* builder,
const keywords.Info* kwinfo,
const string_list.List* features,
const warning_flags.Flags* warnings,
bool has_asserts)
{
Parser* p = calloc(1, sizeof(Parser));
Expand All @@ -95,6 +98,7 @@ public fn Parser* create(SourceMgr* sm,
p.builder = builder;
p.features = features;
p.kwinfo = kwinfo;
p.warnings = warnings;
p.has_asserts = has_asserts;
p.va_list_idx = pool.addStr("va_list", true);
p.varargs_idx = pool.addStr("varargs", true);
Expand Down Expand Up @@ -135,6 +139,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 @@ -157,6 +162,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,
Parser.on_tokenizer_error,
p,
false);
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_pool;
import token local;
import utf8;
import value_type local;
import warning_flags;

import ctype local;
import stdarg local;
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;

ErrorFn on_error;
void* on_error_arg;

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

char[256] error_msg;
}
static_assert(408, sizeof(Tokenizer));
static_assert(416, 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,
ErrorFn on_error,
void* on_error_arg,
bool raw_mode)
Expand All @@ -300,6 +304,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_error_arg = on_error_arg;

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

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_error) t.on_error(t.on_error_arg, Warning, loc, t.error_msg);
}

// 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 @@ -720,9 +734,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 @@ -411,6 +411,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 { // @warning{identifier too long (max 31 chars)}
i32 x;
}

2 changes: 1 addition & 1 deletion test/naming/max_identifier_var.c2
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ module test;

fn void test1() {
i32 thirty_one_is_fine_for_a_name__;
i32 thirty_two_is_too_long_for_an_id; // @error{identifier too long (max 31 chars)}
i32 thirty_two_is_too_long_for_an_id; // @warning{identifier too long (max 31 chars)}
}

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 @@ -262,7 +262,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, true);
tokenizer.init(ctx.pool, buf, ctx.input, 0, &kwinfo, &features, nil, nil, nil, true);
ctx.tokenizer = &tokenizer;
ctx.attr_registry.init(ctx.pool);

Expand Down
Loading