From 040421942f57aedcca73fcda19ba9c59344e16b3 Mon Sep 17 00:00:00 2001 From: Nipunn Koorapati Date: Fri, 20 Apr 2012 14:42:14 -0400 Subject: [PATCH 1/2] Goto statements with a bad label produces error message. Now it also produces a short list of suggestions based on string distance. --- ctx.cpp | 13 +++++++++++++ ctx.h | 4 ++++ stmt.cpp | 22 +++++++++++++++++++--- tests_errors/goto-5.ispc | 6 ++++++ tests_errors/goto-6.ispc | 9 +++++++++ 5 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 tests_errors/goto-5.ispc create mode 100644 tests_errors/goto-6.ispc diff --git a/ctx.cpp b/ctx.cpp index de61ffcb..464b8831 100644 --- a/ctx.cpp +++ b/ctx.cpp @@ -1155,6 +1155,19 @@ FunctionEmitContext::GetLabeledBasicBlock(const std::string &label) { return NULL; } +std::vector +FunctionEmitContext::GetLabels() { + // Initialize vector to the right size + std::vector labels(labelMap.size()); + + // Iterate through labelMap and grab only the keys + std::map::iterator iter; + for (iter=labelMap.begin(); iter != labelMap.end(); iter++) + labels.push_back(iter->first); + + return labels; +} + void FunctionEmitContext::CurrentLanesReturned(Expr *expr, bool doCoherenceCheck) { diff --git a/ctx.h b/ctx.h index 6c3f2887..bdb21ddc 100644 --- a/ctx.h +++ b/ctx.h @@ -248,6 +248,10 @@ public: new basic block that it starts. */ llvm::BasicBlock *GetLabeledBasicBlock(const std::string &label); + /** Returns a vector of all labels in the context. This is + simply the key set of the labelMap */ + std::vector GetLabels(); + /** Called to generate code for 'return' statement; value is the expression in the return statement (if non-NULL), and doCoherenceCheck indicates whether instructions should be generated diff --git a/stmt.cpp b/stmt.cpp index 4f8c0f12..e2b533f3 100644 --- a/stmt.cpp +++ b/stmt.cpp @@ -2281,10 +2281,26 @@ GotoStmt::EmitCode(FunctionEmitContext *ctx) const { llvm::BasicBlock *bb = ctx->GetLabeledBasicBlock(label); if (bb == NULL) { - // TODO: use the string distance stuff to suggest alternatives if - // there are some with names close to the label name we have here.. - Error(identifierPos, "No label named \"%s\" found in current function.", + /* Label wasn't found. Emit an error */ + Error(identifierPos, + "No label named \"%s\" found in current function.", label.c_str()); + + /* Look for suggestions that are close */ + std::vector labels = ctx->GetLabels(); + std::vector matches = MatchStrings(label, labels); + if (! matches.empty()) { + /* Print up to 5 matches. Don't want to spew too much */ + std::string match_output("Did you mean\n"); + for (unsigned int i=0; i Date: Sat, 21 Apr 2012 01:44:10 -0400 Subject: [PATCH 2/2] Error() and Warning() functions for reporting compiler errors/warnings now respects newlines as part of valid error messages. --- lex.ll | 2 +- stmt.cpp | 24 ++++++++++-------------- util.cpp | 18 ++++++++++++++++-- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/lex.ll b/lex.ll index 96c19d1d..026b1b48 100644 --- a/lex.ll +++ b/lex.ll @@ -704,7 +704,7 @@ lEscapeChar(char *str, char *pChar, SourcePos *pos) str = tail - 1; break; default: - Error(*pos, "Bad character escape sequence: '%s'\n.", str); + Error(*pos, "Bad character escape sequence: '%s'.", str); break; } } diff --git a/stmt.cpp b/stmt.cpp index e2b533f3..0c8ed0c8 100644 --- a/stmt.cpp +++ b/stmt.cpp @@ -2281,26 +2281,22 @@ GotoStmt::EmitCode(FunctionEmitContext *ctx) const { llvm::BasicBlock *bb = ctx->GetLabeledBasicBlock(label); if (bb == NULL) { - /* Label wasn't found. Emit an error */ - Error(identifierPos, - "No label named \"%s\" found in current function.", - label.c_str()); - - /* Look for suggestions that are close */ + /* Label wasn't found. Look for suggestions that are close */ std::vector labels = ctx->GetLabels(); std::vector matches = MatchStrings(label, labels); + std::string match_output; if (! matches.empty()) { /* Print up to 5 matches. Don't want to spew too much */ - std::string match_output("Did you mean\n"); + match_output += "\nDid you mean:"; for (unsigned int i=0; i