Merge pull request #248 from nipunn1313/master
Goto with incorrect label now suggests labels 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
|
||||||
|
|||||||
2
lex.ll
2
lex.ll
@@ -704,7 +704,7 @@ lEscapeChar(char *str, char *pChar, SourcePos *pos)
|
|||||||
str = tail - 1;
|
str = tail - 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Error(*pos, "Bad character escape sequence: '%s'\n.", str);
|
Error(*pos, "Bad character escape sequence: '%s'.", str);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
20
stmt.cpp
20
stmt.cpp
@@ -2281,10 +2281,22 @@ 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. Look for suggestions that are close */
|
||||||
// there are some with names close to the label name we have here..
|
std::vector<std::string> labels = ctx->GetLabels();
|
||||||
Error(identifierPos, "No label named \"%s\" found in current function.",
|
std::vector<std::string> matches = MatchStrings(label, labels);
|
||||||
label.c_str());
|
std::string match_output;
|
||||||
|
if (! matches.empty()) {
|
||||||
|
/* Print up to 5 matches. Don't want to spew too much */
|
||||||
|
match_output += "\nDid you mean:";
|
||||||
|
for (unsigned int i=0; i<matches.size() && i<5; i++)
|
||||||
|
match_output += "\n " + matches[i] + "?";
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Label wasn't found. Emit an error */
|
||||||
|
Error(identifierPos,
|
||||||
|
"No label named \"%s\" found in current function.%s",
|
||||||
|
label.c_str(), 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;
|
||||||
|
}
|
||||||
|
|
||||||
18
util.cpp
18
util.cpp
@@ -237,6 +237,20 @@ lPrintWithWordBreaks(const char *buf, int indent, int columnWidth, FILE *out) {
|
|||||||
} while (*msgPos != '\0' && *msgPos != 'm');
|
} while (*msgPos != '\0' && *msgPos != 'm');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
else if (*msgPos == '\n') {
|
||||||
|
// Handle newlines cleanly
|
||||||
|
column = indent;
|
||||||
|
outStr.push_back('\n');
|
||||||
|
for (int i = 0; i < indent; ++i)
|
||||||
|
outStr.push_back(' ');
|
||||||
|
// Respect spaces after newlines
|
||||||
|
++msgPos;
|
||||||
|
while (*msgPos == ' ') {
|
||||||
|
outStr.push_back(' ');
|
||||||
|
++msgPos;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
while (*msgPos != '\0' && isspace(*msgPos))
|
while (*msgPos != '\0' && isspace(*msgPos))
|
||||||
++msgPos;
|
++msgPos;
|
||||||
@@ -314,7 +328,7 @@ lPrint(const char *type, bool isError, SourcePos p, const char *fmt,
|
|||||||
int indent = 0;
|
int indent = 0;
|
||||||
if (p.first_line == 0) {
|
if (p.first_line == 0) {
|
||||||
// We don't have a valid SourcePos, so create a message without it
|
// We don't have a valid SourcePos, so create a message without it
|
||||||
if (asprintf(&formattedBuf, "%s%s%s%s%s: %s%s\n", lStartBold(),
|
if (asprintf(&formattedBuf, "%s%s%s%s%s: %s%s", lStartBold(),
|
||||||
isError ? lStartRed() : lStartBlue(), type,
|
isError ? lStartRed() : lStartBlue(), type,
|
||||||
lResetColor(), lStartBold(), errorBuf,
|
lResetColor(), lStartBold(), errorBuf,
|
||||||
lResetColor()) == -1) {
|
lResetColor()) == -1) {
|
||||||
@@ -325,7 +339,7 @@ lPrint(const char *type, bool isError, SourcePos p, const char *fmt,
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Create an error message that includes the file and line number
|
// Create an error message that includes the file and line number
|
||||||
if (asprintf(&formattedBuf, "%s%s:%d:%d: %s%s%s%s: %s%s\n",
|
if (asprintf(&formattedBuf, "%s%s:%d:%d: %s%s%s%s: %s%s",
|
||||||
lStartBold(), p.name, p.first_line, p.first_column,
|
lStartBold(), p.name, p.first_line, p.first_column,
|
||||||
isError ? lStartRed() : lStartBlue(), type,
|
isError ? lStartRed() : lStartBlue(), type,
|
||||||
lResetColor(), lStartBold(), errorBuf,
|
lResetColor(), lStartBold(), errorBuf,
|
||||||
|
|||||||
Reference in New Issue
Block a user