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