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
12 changes: 6 additions & 6 deletions analyser/module_analyser.c2
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import name_vector local;
import src_loc local;
import scope;
import string_pool;
import warning_flags;
import warning_flags local;
import struct_func_list as sf_list;
import incr_array_list as ia_list;

Expand All @@ -48,7 +48,7 @@ public type Analyser struct @(opaque) {
string_pool.Pool* astPool;
ast_builder.Builder* builder;
module_list.List* allmodules;
const warning_flags.Flags* warnings;
const WarningFlags* warnings;

// variables below differs per run
Module* mod;
Expand Down Expand Up @@ -84,7 +84,7 @@ public fn Analyser* create(diagnostics.Diags* diags,
string_pool.Pool* astPool,
ast_builder.Builder* builder,
module_list.List* allmodules,
const warning_flags.Flags* warnings)
const WarningFlags* warnings)
{
Analyser* ma = stdlib.calloc(1, sizeof(Analyser));
ma.diags = diags;
Expand Down Expand Up @@ -296,10 +296,10 @@ fn void Analyser.note(Analyser* ma, SrcLoc loc, const char* format @(printf_form
va_end(args);
}

fn void Analyser.warn(Analyser* ma, SrcLoc loc, const char* format @(printf_format), ...) {
fn void Analyser.warn(Analyser* ma, WarningKind wk, SrcLoc loc, const char* format @(printf_format), ...) {
va_list args;
va_start(args, format);
ma.diags.warn2(loc, format, args);
ma.diags.warn2(wk, loc, format, args);
va_end(args);
}

Expand Down Expand Up @@ -330,7 +330,7 @@ fn void Analyser.createGlobalScope(void* arg, AST* a) {
a.getImports(),
ma.mod,
ma.mod.getSymbols(),
!ma.warnings.no_unused_variable);
ma.warnings.test(W_unused_variable));
a.setPtr(s);
}

Expand Down
6 changes: 3 additions & 3 deletions analyser/module_analyser_call.c2
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@ fn QualType Analyser.analyseCallExpr(Analyser* ma, Expr** e_ptr) {
}
}

if (fd.hasAttrDeprecated() && !ma.warnings.no_deprecated) {
if (fd.hasAttrDeprecated() && ma.warnings.test(W_deprecated)) {
const AST* a = ((Decl*)fd).getAST();
const Attr* deprecated = a.getAttr(((Decl*)fd), Deprecated);
const char* msg = ma.astPool.idx2str(deprecated.value.text);
ma.warn(origFn.getLoc(), "function %s is deprecated: %s", fd.asDecl().getFullName(), msg);
ma.warn(W_deprecated, origFn.getLoc(), "function %s is deprecated: %s", fd.asDecl().getFullName(), msg);
//return QualType_Invalid;
}

Expand Down Expand Up @@ -663,7 +663,7 @@ fn FunctionDecl* Analyser.instantiateTemplateFunction(Analyser* ma, CallExpr* ca
d.getAST().getImports(),
template_mod,
template_mod.getSymbols(),
!ma.warnings.no_unused_variable);
ma.warnings.test(W_unused_variable));
analyser.analyseFunctionBody(instance, tmpScope);
tmpScope.free();
analyser.free();
Expand Down
10 changes: 5 additions & 5 deletions analyser/module_analyser_function.c2
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ fn void Analyser.analyseFunction(Analyser* ma, FunctionDecl* fd) {
}

if (canon.isConst() && !canon.isPointer()) {
ma.warn(rtype.getLoc(), "'const' type qualifier on return type has no effect");
ma.warn(W_const_return_type, rtype.getLoc(), "'const' type qualifier on return type has no effect");
}

bool is_public = fd.asDecl().isPublic();
Expand Down Expand Up @@ -256,12 +256,12 @@ fn void Analyser.analyseFunctionBody(Analyser* ma, FunctionDecl* fd, scope.Scope
}
}

if (!ma.warnings.no_unused_parameter && !fd.hasAttrUnusedParams()) {
if (ma.warnings.test(W_unused_parameter) && !fd.hasAttrUnusedParams()) {
for (u32 i=0; i<num_params; i++) {
Decl* p = (Decl*)params[i];
if (!p.isUsed() && p.getNameIdx()) {
// TODO check attribute?
ma.warn(p.getLoc(), "unused parameter '%s'", p.getName());
ma.warn(W_unused_parameter, p.getLoc(), "unused parameter '%s'", p.getName());
}
}
}
Expand All @@ -273,8 +273,8 @@ fn void Analyser.analyseFunctionBody(Analyser* ma, FunctionDecl* fd, scope.Scope
for (u32 i=0; i<num_labels; i++) {
const Label* l = &labels[i];
if (l.is_label) {
if (!l.used && !ma.warnings.no_unused_label) {
ma.warn(l.loc, "unused label '%s'", ast.idx2name(l.name_idx));
if (!l.used) {
ma.warn(W_unused_label, l.loc, "unused label '%s'", ast.idx2name(l.name_idx));
}
} else {
ma.error(l.loc, "use of undeclared label '%s'", ast.idx2name(l.name_idx));
Expand Down
6 changes: 3 additions & 3 deletions analyser/module_analyser_stmt.c2
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ fn bool Analyser.isNoReturn(Analyser* ma, Expr* e) {
fn FlowBits Analyser.analyseStmt(Analyser* ma, Stmt* s, bool checkEffect) {
FlowBits flow = 0;
if (ma.scope.isUnreachable()) {
if (s.getKind() != StmtKind.Label && !ma.warnings.no_unreachable_code) {
ma.warn(s.getLoc(), "unreachable code");
if (s.getKind() != StmtKind.Label) {
ma.warn(W_unreachable_code, s.getLoc(), "unreachable code");
}
ma.scope.setReachable(); // prevent multiple warnings
}
Expand Down Expand Up @@ -219,7 +219,7 @@ fn QualType Analyser.analyseCondition(Analyser* ma, Stmt** s_ptr, bool check_ass
e = (Expr*)*s_ptr; // re-read in case of ImplicitCast insertions

if (check_assign && e.isAssignment()) {
ma.warn(e.getLoc(), "using the result of an assignment as a condition without parentheses");
ma.warn(W_idiomatic_parentheses, e.getLoc(), "using the result of an assignment as a condition without parentheses");
}

return qt;
Expand Down
3 changes: 2 additions & 1 deletion analyser/scope.c2
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import diagnostics;
import module_list;
import constants;
import src_loc local;
//import warning_flags local;

import stdlib;
import string;
Expand Down Expand Up @@ -163,7 +164,7 @@ public fn void Scope.exit(Scope* s, bool has_error) {
if (!d.isUsed()) {
ast.VarDecl* vd = (ast.VarDecl*)d;
// Note: params are handled by function
if (vd.isLocal()) s.diags.warn(d.getLoc(), "unused variable '%s'", d.getName());
if (vd.isLocal()) s.diags.warn(W_unused_variable, d.getLoc(), "unused variable '%s'", d.getName());
}
}
}
Expand Down
39 changes: 21 additions & 18 deletions analyser/unused_checker.c2
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@

module unused_checker;

import warning_flags;
import ast local;
import diagnostics;
import warning_flags local;

public fn void check(diagnostics.Diags* diags,
const warning_flags.Flags* warnings,
const WarningFlags* warnings,
Module* mod)
{
Checker c = {
Expand All @@ -37,54 +37,57 @@ public fn void check(diagnostics.Diags* diags,

type Checker struct {
diagnostics.Diags* diags;
const warning_flags.Flags* warnings;
const WarningFlags* warnings;
}

fn void Checker.unused_module(void* arg, AST* a) {
Checker* c = arg;
c.diags.warn(a.getLoc(), "unused module '%s'", a.getName());
c.diags.warn(W_unused_module, a.getLoc(), "unused module '%s'", a.getName());
}

fn void Checker.check(void* arg, Decl* d) {
Checker* c = arg;
bool used = d.isUsed();
if (used && d.isPublic() && !d.isUsedPublic() && !c.warnings.no_unused_public && !d.hasAttrUnused()) {
c.diags.warn(d.getLoc(), "%s '%s' is not used public", d.getKindName(), d.getFullName());
if (used && d.isPublic() && !d.isUsedPublic() && !d.hasAttrUnused()) {
c.diags.warn(W_unused_public, d.getLoc(), "%s '%s' is not used public", d.getKindName(), d.getFullName());
}

WarningKind wk = W_unknown;
switch (d.getKind()) {
case Function:
if (c.warnings.no_unused_function) return;
if (d.hasAttrUnused()) return;
wk = W_unused_function;
break;
case Import:
if (c.warnings.no_unused_import) return;
wk = W_unused_import;
break;
case StructType:
if (used) {
c.checkStructMembers(d);
}
if (c.warnings.no_unused_type) return;
wk = W_unused_type;
break;
case EnumType:
if (used && !c.warnings.no_unused_enum_constant) {
c.checkEnum((EnumTypeDecl*)d);
if (used && c.warnings.test(W_unused_enum_constant)) {
c.checkEnum((EnumTypeDecl*)(d));
}
wk = W_unused_enum_constant;
break;
case EnumConstant:
wk = W_unused_enum_constant;
break;
case FunctionType:
if (c.warnings.no_unused_type) return;
wk = W_unused_type;
break;
case AliasType:
if (c.warnings.no_unused_type) return;
wk = W_unused_type;
break;
case Variable:
if (c.warnings.no_unused_variable) return;
wk = W_unused_variable;
break;
}
if (!used && !d.hasAttrUnused() && !d.isExported()) {
c.diags.warn(d.getLoc(), "unused %s '%s'", d.getKindName(), d.getFullName());
c.diags.warn(wk, d.getLoc(), "unused %s '%s'", d.getKindName(), d.getFullName());
return;
}
}
Expand All @@ -96,7 +99,7 @@ fn void Checker.checkEnum(Checker* c, EnumTypeDecl* d) {
EnumConstantDecl* ecd = constants[i];
Decl* dd = (Decl*)ecd;
if (!dd.isUsed()) {
c.diags.warn(dd.getLoc(), "unused %s '%s'", dd.getKindName(), dd.getName());
c.diags.warn(W_unused_enum_constant, dd.getLoc(), "unused %s '%s'", dd.getKindName(), dd.getName());
}
}
}
Expand All @@ -110,8 +113,8 @@ fn void Checker.checkStructMembers(Checker* c, Decl* d) {
if (member.isStructType()) {
c.checkStructMembers(member);
} else {
if (!member.isUsed() && !c.warnings.no_unused_variable) {
c.diags.warn(member.getLoc(), "unused %s member '%s'", std.isStruct() ? "struct" : "union", member.getName());
if (!member.isUsed()) {
c.diags.warn(W_unused_variable, member.getLoc(), "unused %s member '%s'", std.isStruct() ? "struct" : "union", member.getName());
}
}
}
Expand Down
10 changes: 4 additions & 6 deletions common/attr_handler.c2
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ module attr_handler;
import ast;
import attr local;
import diagnostics;
import warning_flags;
import warning_flags local;

import stdlib;
import string;
Expand All @@ -31,15 +31,15 @@ type Entry struct {

public type Handler struct @(opaque) {
diagnostics.Diags* diags; // no ownership
const warning_flags.Flags* warnings;
const WarningFlags* warnings;

Entry* entries;
u32 count;
u32 capacity;
}

public fn Handler* create(diagnostics.Diags* diags,
const warning_flags.Flags* warnings) {
const WarningFlags* warnings) {
Handler* h = stdlib.calloc(1, sizeof(Handler));
h.diags = diags;
h.warnings = warnings;
Expand Down Expand Up @@ -77,9 +77,7 @@ public fn bool Handler.handle(Handler* h, ast.Decl* d, const Attr* a) {
Entry* e = &h.entries[i];
if (e.name == a.name) return e.func(e.arg, d, a);
}
if (!h.warnings.no_unknown_attribute) {
h.diags.warn(a.loc, "unknown attribute '%s'", ast.idx2name(a.name));
}
h.diags.warn(W_unknown_attribute, a.loc, "unknown attribute '%s'", ast.idx2name(a.name));
return false;
}

45 changes: 10 additions & 35 deletions common/build_target.c2
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import file_list local;
import src_loc local;
import string_list;
import string_pool;
import warning_flags;
import warning_flags local;

import stdlib;
import string;
Expand Down Expand Up @@ -100,7 +100,7 @@ public fn void PluginList.add(PluginList* l, u32 name, u32 options, SrcLoc loc)
public type Target struct @(opaque) {
u32 name_idx; // index into auxPool
SrcLoc loc;
warning_flags.Flags warnings;
WarningFlags warnings;
Kind kind;

bool disable_asserts;
Expand All @@ -122,14 +122,13 @@ public fn Target* create(u32 name_idx, SrcLoc loc, Kind kind, string_pool.Pool*
Target* t = stdlib.calloc(1, sizeof(Target));
t.name_idx = name_idx;
t.loc = loc;
// remove this once the bootstrap handles improved flow analysis
t.warnings.no_unreachable_code = true;
t.kind = kind;
t.features.init(pool);
t.libs.init();
t.exports.init(pool);
t.files.init(8);
t.asm_files.init(0);
t.enableWarnings();
return t;
}

Expand Down Expand Up @@ -184,43 +183,19 @@ public fn void Target.addLib(Target* t, u32 lib, Kind kind) {
t.libs.add(lib, kind);
}

public fn void Target.disableWarnings(Target* t) {
t.warnings.no_unused = true;
t.warnings.no_unused_variable = true;
t.warnings.no_unused_function = true;
t.warnings.no_unused_parameter = true;
t.warnings.no_unused_type = true;
t.warnings.no_unused_module = true;
t.warnings.no_unused_import = true;
t.warnings.no_unused_public = true;
t.warnings.no_unused_label = true;
t.warnings.no_unused_enum_constant = true;
t.warnings.no_unreachable_code = true;
t.warnings.no_unknown_attribute = true;
t.warnings.no_deprecated = true;
public fn void Target.disableWarnings(Target* t) @(unused) {
t.warnings.clearAll();
}

public fn void Target.enableWarnings(Target* t) {
t.warnings.no_unused = false;
t.warnings.no_unused_variable = false;
t.warnings.no_unused_function = false;
t.warnings.no_unused_parameter = false;
t.warnings.no_unused_type = false;
t.warnings.no_unused_module = false;
t.warnings.no_unused_import = false;
t.warnings.no_unused_public = false;
t.warnings.no_unused_label = false;
t.warnings.no_unused_enum_constant = false;
t.warnings.no_unreachable_code = false;
t.warnings.no_unknown_attribute = false;
t.warnings.no_deprecated = false;
}

public fn const warning_flags.Flags* Target.getWarnings(const Target* t) {
t.warnings.setAll();
}

public fn const WarningFlags* Target.getWarnings(const Target* t) {
return &t.warnings;
}

public fn warning_flags.Flags* Target.getWarnings2(Target* t) {
public fn WarningFlags* Target.getWarnings2(Target* t) {
return &t.warnings;
}

Expand Down
Loading