Goto statements with a bad label produces error message.
Now it also produces a short list of suggestions based on string distance.
This commit is contained in:
13
ctx.cpp
13
ctx.cpp
@@ -1155,6 +1155,19 @@ FunctionEmitContext::GetLabeledBasicBlock(const std::string &label) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string>
|
||||||
|
FunctionEmitContext::GetLabels() {
|
||||||
|
// Initialize vector to the right size
|
||||||
|
std::vector<std::string> labels(labelMap.size());
|
||||||
|
|
||||||
|
// Iterate through labelMap and grab only the keys
|
||||||
|
std::map<std::string, llvm::BasicBlock*>::iterator iter;
|
||||||
|
for (iter=labelMap.begin(); iter != labelMap.end(); iter++)
|
||||||
|
labels.push_back(iter->first);
|
||||||
|
|
||||||
|
return labels;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
FunctionEmitContext::CurrentLanesReturned(Expr *expr, bool doCoherenceCheck) {
|
FunctionEmitContext::CurrentLanesReturned(Expr *expr, bool doCoherenceCheck) {
|
||||||
|
|||||||
4
ctx.h
4
ctx.h
@@ -248,6 +248,10 @@ public:
|
|||||||
new basic block that it starts. */
|
new basic block that it starts. */
|
||||||
llvm::BasicBlock *GetLabeledBasicBlock(const std::string &label);
|
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<std::string> GetLabels();
|
||||||
|
|
||||||
/** Called to generate code for 'return' statement; value is the
|
/** Called to generate code for 'return' statement; value is the
|
||||||
expression in the return statement (if non-NULL), and
|
expression in the return statement (if non-NULL), and
|
||||||
doCoherenceCheck indicates whether instructions should be generated
|
doCoherenceCheck indicates whether instructions should be generated
|
||||||
|
|||||||
22
stmt.cpp
22
stmt.cpp
@@ -2281,10 +2281,26 @@ GotoStmt::EmitCode(FunctionEmitContext *ctx) const {
|
|||||||
|
|
||||||
llvm::BasicBlock *bb = ctx->GetLabeledBasicBlock(label);
|
llvm::BasicBlock *bb = ctx->GetLabeledBasicBlock(label);
|
||||||
if (bb == NULL) {
|
if (bb == NULL) {
|
||||||
// TODO: use the string distance stuff to suggest alternatives if
|
/* Label wasn't found. Emit an error */
|
||||||
// there are some with names close to the label name we have here..
|
Error(identifierPos,
|
||||||
Error(identifierPos, "No label named \"%s\" found in current function.",
|
"No label named \"%s\" found in current function.",
|
||||||
label.c_str());
|
label.c_str());
|
||||||
|
|
||||||
|
/* Look for suggestions that are close */
|
||||||
|
std::vector<std::string> labels = ctx->GetLabels();
|
||||||
|
std::vector<std::string> 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<matches.size() && i<5; i++)
|
||||||
|
match_output += " " + matches[i] + "?\n";
|
||||||
|
|
||||||
|
/*TODO. Embed these suggestions IN the error message
|
||||||
|
itself. Currently it looks ugly since line breaks
|
||||||
|
are ignored inside Error() strings. Multiple
|
||||||
|
Error() messages are not an option either */
|
||||||
|
printf("%s", match_output.c_str());
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
6
tests_errors/goto-5.ispc
Normal file
6
tests_errors/goto-5.ispc
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
void func(int x) {
|
||||||
|
completelydifferentlabel:
|
||||||
|
goto label;
|
||||||
|
}
|
||||||
|
|
||||||
9
tests_errors/goto-6.ispc
Normal file
9
tests_errors/goto-6.ispc
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
void func(int x) {
|
||||||
|
libel:
|
||||||
|
babel:
|
||||||
|
lbel:
|
||||||
|
label2:
|
||||||
|
goto label;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user