ClangImport: Improved error handling
This commit is contained in:
parent
fb35756126
commit
f37274a5c0
|
@ -320,6 +320,17 @@ namespace clangimport {
|
|||
addtoken(tokenList, ";");
|
||||
mData->mNotScope.clear();
|
||||
}
|
||||
|
||||
AstNodePtr getChild(int c) {
|
||||
if (c >= children.size()) {
|
||||
std::ostringstream err;
|
||||
err << "ClangImport: AstNodePtr::getChild(" << c << ") out of bounds. children.size=" << children.size() << " " << nodeType;
|
||||
for (const std::string &s: mExtTokens)
|
||||
err << " " << s;
|
||||
throw InternalError(nullptr, err.str());
|
||||
}
|
||||
return children[c];
|
||||
}
|
||||
private:
|
||||
Token *createTokens(TokenList *tokenList);
|
||||
Token *addtoken(TokenList *tokenList, const std::string &str, bool valueType=true);
|
||||
|
@ -647,7 +658,7 @@ Scope *clangimport::AstNode::createScope(TokenList *tokenList, Scope::ScopeType
|
|||
Token *clangimport::AstNode::createTokens(TokenList *tokenList)
|
||||
{
|
||||
if (nodeType == ArraySubscriptExpr) {
|
||||
Token *array = children[0]->createTokens(tokenList);
|
||||
Token *array = getChild(0)->createTokens(tokenList);
|
||||
Token *bracket1 = addtoken(tokenList, "[");
|
||||
Token *index = children[1]->createTokens(tokenList);
|
||||
Token *bracket2 = addtoken(tokenList, "]");
|
||||
|
@ -658,7 +669,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
|
|||
return bracket1;
|
||||
}
|
||||
if (nodeType == BinaryOperator) {
|
||||
Token *tok1 = children[0]->createTokens(tokenList);
|
||||
Token *tok1 = getChild(0)->createTokens(tokenList);
|
||||
Token *binop = addtoken(tokenList, unquote(mExtTokens.back()));
|
||||
Token *tok2 = children[1]->createTokens(tokenList);
|
||||
binop->astOperand1(tok1);
|
||||
|
@ -690,7 +701,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
|
|||
return createTokensCall(tokenList);
|
||||
if (nodeType == CaseStmt) {
|
||||
Token *caseToken = addtoken(tokenList, "case");
|
||||
Token *exprToken = children[0]->createTokens(tokenList);
|
||||
Token *exprToken = getChild(0)->createTokens(tokenList);
|
||||
caseToken->astOperand1(exprToken);
|
||||
addtoken(tokenList, ":");
|
||||
children.back()->createTokens(tokenList);
|
||||
|
@ -708,7 +719,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
|
|||
return nullptr;
|
||||
}
|
||||
if (nodeType == ConditionalOperator) {
|
||||
Token *expr1 = children[0]->createTokens(tokenList);
|
||||
Token *expr1 = getChild(0)->createTokens(tokenList);
|
||||
Token *tok1 = addtoken(tokenList, "?");
|
||||
Token *expr2 = children[1]->createTokens(tokenList);
|
||||
Token *tok2 = addtoken(tokenList, ":");
|
||||
|
@ -720,7 +731,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
|
|||
return tok1;
|
||||
}
|
||||
if (nodeType == CompoundAssignOperator) {
|
||||
Token *lhs = children[0]->createTokens(tokenList);
|
||||
Token *lhs = getChild(0)->createTokens(tokenList);
|
||||
Token *assign = addtoken(tokenList, getSpelling());
|
||||
Token *rhs = children[1]->createTokens(tokenList);
|
||||
assign->astOperand1(lhs);
|
||||
|
@ -745,11 +756,11 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
|
|||
Token *par2 = addtoken(tokenList, ")");
|
||||
par1->link(par2);
|
||||
par2->link(par1);
|
||||
par1->astOperand1(children[0]->createTokens(tokenList));
|
||||
par1->astOperand1(getChild(0)->createTokens(tokenList));
|
||||
return par1;
|
||||
}
|
||||
if (nodeType == CXXBindTemporaryExpr)
|
||||
return children[0]->createTokens(tokenList);
|
||||
return getChild(0)->createTokens(tokenList);
|
||||
if (nodeType == CXXBoolLiteralExpr) {
|
||||
addtoken(tokenList, mExtTokens.back());
|
||||
tokenList->back()->setValueType(new ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::BOOL, 0));
|
||||
|
@ -757,7 +768,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
|
|||
}
|
||||
if (nodeType == CXXConstructExpr) {
|
||||
if (!children.empty())
|
||||
return children[0]->createTokens(tokenList);
|
||||
return getChild(0)->createTokens(tokenList);
|
||||
addTypeTokens(tokenList, '\'' + getType() + '\'');
|
||||
Token *type = tokenList->back();
|
||||
Token *par1 = addtoken(tokenList, "(");
|
||||
|
@ -773,7 +784,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
|
|||
}
|
||||
if (nodeType == CXXDeleteExpr) {
|
||||
addtoken(tokenList, "delete");
|
||||
children[0]->createTokens(tokenList);
|
||||
getChild(0)->createTokens(tokenList);
|
||||
return nullptr;
|
||||
}
|
||||
if (nodeType == CXXDestructorDecl) {
|
||||
|
@ -785,17 +796,17 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
|
|||
Token *par1 = addtoken(tokenList, "(");
|
||||
AstNodePtr varDecl;
|
||||
if (children[6]->nodeType == DeclStmt)
|
||||
varDecl = children[6]->children[0];
|
||||
varDecl = getChild(6)->getChild(0);
|
||||
else
|
||||
varDecl = children[5]->children[0];
|
||||
varDecl = getChild(5)->getChild(0);
|
||||
varDecl->mExtTokens.pop_back();
|
||||
varDecl->children.clear();
|
||||
Token *expr1 = varDecl->createTokens(tokenList);
|
||||
Token *colon = addtoken(tokenList, ":");
|
||||
AstNodePtr range;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (children[i] && children[i]->nodeType == DeclStmt && children[i]->children[0]->nodeType == VarDecl) {
|
||||
range = children[i]->children[0]->children[0];
|
||||
if (children[i] && children[i]->nodeType == DeclStmt && children[i]->getChild(0)->nodeType == VarDecl) {
|
||||
range = children[i]->getChild(0)->getChild(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -825,8 +836,8 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
|
|||
return createTokensCall(tokenList);
|
||||
if (nodeType == CXXNewExpr) {
|
||||
Token *newtok = addtoken(tokenList, "new");
|
||||
if (children.size() == 1 && children[0]->nodeType == CXXConstructExpr) {
|
||||
newtok->astOperand1(children[0]->createTokens(tokenList));
|
||||
if (children.size() == 1 && getChild(0)->nodeType == CXXConstructExpr) {
|
||||
newtok->astOperand1(getChild(0)->createTokens(tokenList));
|
||||
return newtok;
|
||||
}
|
||||
std::string type = getType();
|
||||
|
@ -835,7 +846,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
|
|||
addTypeTokens(tokenList, type);
|
||||
if (!children.empty()) {
|
||||
Token *bracket1 = addtoken(tokenList, "[");
|
||||
children[0]->createTokens(tokenList);
|
||||
getChild(0)->createTokens(tokenList);
|
||||
Token *bracket2 = addtoken(tokenList, "]");
|
||||
bracket1->link(bracket2);
|
||||
bracket2->link(bracket1);
|
||||
|
@ -853,7 +864,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
|
|||
if (nodeType == CXXStaticCastExpr || nodeType == CXXFunctionalCastExpr) {
|
||||
Token *cast = addtoken(tokenList, getSpelling());
|
||||
Token *par1 = addtoken(tokenList, "(");
|
||||
Token *expr = children[0]->createTokens(tokenList);
|
||||
Token *expr = getChild(0)->createTokens(tokenList);
|
||||
Token *par2 = addtoken(tokenList, ")");
|
||||
par1->link(par2);
|
||||
par2->link(par1);
|
||||
|
@ -863,14 +874,14 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
|
|||
return par1;
|
||||
}
|
||||
if (nodeType == CXXStdInitializerListExpr)
|
||||
return children[0]->createTokens(tokenList);
|
||||
return getChild(0)->createTokens(tokenList);
|
||||
if (nodeType == CXXTemporaryObjectExpr && !children.empty())
|
||||
return children[0]->createTokens(tokenList);
|
||||
return getChild(0)->createTokens(tokenList);
|
||||
if (nodeType == CXXThisExpr)
|
||||
return addtoken(tokenList, "this");
|
||||
if (nodeType == CXXThrowExpr) {
|
||||
Token *t = addtoken(tokenList, "throw");
|
||||
t->astOperand1(children[0]->createTokens(tokenList));
|
||||
t->astOperand1(getChild(0)->createTokens(tokenList));
|
||||
return t;
|
||||
}
|
||||
if (nodeType == DeclRefExpr) {
|
||||
|
@ -881,7 +892,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
|
|||
return reftok;
|
||||
}
|
||||
if (nodeType == DeclStmt)
|
||||
return children[0]->createTokens(tokenList);
|
||||
return getChild(0)->createTokens(tokenList);
|
||||
if (nodeType == DefaultStmt) {
|
||||
addtoken(tokenList, "default");
|
||||
addtoken(tokenList, ":");
|
||||
|
@ -890,7 +901,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
|
|||
}
|
||||
if (nodeType == DoStmt) {
|
||||
addtoken(tokenList, "do");
|
||||
createScope(tokenList, Scope::ScopeType::eDo, children[0], tokenList->back());
|
||||
createScope(tokenList, Scope::ScopeType::eDo, getChild(0), tokenList->back());
|
||||
Token *tok1 = addtoken(tokenList, "while");
|
||||
Token *par1 = addtoken(tokenList, "(");
|
||||
Token *expr = children[1]->createTokens(tokenList);
|
||||
|
@ -948,7 +959,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
|
|||
return nullptr;
|
||||
}
|
||||
if (nodeType == ExprWithCleanups)
|
||||
return children[0]->createTokens(tokenList);
|
||||
return getChild(0)->createTokens(tokenList);
|
||||
if (nodeType == FieldDecl)
|
||||
return createTokensVarDecl(tokenList);
|
||||
if (nodeType == FloatingLiteral)
|
||||
|
@ -956,7 +967,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
|
|||
if (nodeType == ForStmt) {
|
||||
Token *forToken = addtoken(tokenList, "for");
|
||||
Token *par1 = addtoken(tokenList, "(");
|
||||
Token *expr1 = children[0] ? children[0]->createTokens(tokenList) : nullptr;
|
||||
Token *expr1 = getChild(0) ? children[0]->createTokens(tokenList) : nullptr;
|
||||
Token *sep1 = addtoken(tokenList, ";");
|
||||
Token *expr2 = children[2] ? children[2]->createTokens(tokenList) : nullptr;
|
||||
Token *sep2 = addtoken(tokenList, ";");
|
||||
|
@ -1022,7 +1033,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
|
|||
return nullptr;
|
||||
}
|
||||
if (nodeType == ImplicitCastExpr) {
|
||||
Token *expr = children[0]->createTokens(tokenList);
|
||||
Token *expr = getChild(0)->createTokens(tokenList);
|
||||
if (!expr->valueType() || contains(mExtTokens, "<ArrayToPointerDecay>"))
|
||||
setValueType(expr);
|
||||
return expr;
|
||||
|
@ -1055,9 +1066,9 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
|
|||
if (nodeType == LinkageSpecDecl)
|
||||
return nullptr;
|
||||
if (nodeType == MaterializeTemporaryExpr)
|
||||
return children[0]->createTokens(tokenList);
|
||||
return getChild(0)->createTokens(tokenList);
|
||||
if (nodeType == MemberExpr) {
|
||||
Token *s = children[0]->createTokens(tokenList);
|
||||
Token *s = getChild(0)->createTokens(tokenList);
|
||||
Token *dot = addtoken(tokenList, ".");
|
||||
std::string memberName = getSpelling();
|
||||
if (memberName.compare(0, 2, "->") == 0) {
|
||||
|
@ -1090,7 +1101,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
|
|||
return addtoken(tokenList, ";");
|
||||
if (nodeType == ParenExpr) {
|
||||
Token *par1 = addtoken(tokenList, "(");
|
||||
Token *expr = children[0]->createTokens(tokenList);
|
||||
Token *expr = getChild(0)->createTokens(tokenList);
|
||||
Token *par2 = addtoken(tokenList, ")");
|
||||
par1->link(par2);
|
||||
par2->link(par1);
|
||||
|
@ -1119,8 +1130,8 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
|
|||
if (nodeType == ReturnStmt) {
|
||||
Token *tok1 = addtoken(tokenList, "return");
|
||||
if (!children.empty()) {
|
||||
children[0]->setValueType(tok1);
|
||||
tok1->astOperand1(children[0]->createTokens(tokenList));
|
||||
getChild(0)->setValueType(tok1);
|
||||
tok1->astOperand1(getChild(0)->createTokens(tokenList));
|
||||
}
|
||||
return tok1;
|
||||
}
|
||||
|
@ -1148,7 +1159,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
|
|||
while (index > 0 && mExtTokens[index][0] != '\'')
|
||||
--index;
|
||||
Token *unop = addtoken(tokenList, unquote(mExtTokens[index]));
|
||||
unop->astOperand1(children[0]->createTokens(tokenList));
|
||||
unop->astOperand1(getChild(0)->createTokens(tokenList));
|
||||
return unop;
|
||||
}
|
||||
if (nodeType == UnaryExprOrTypeTraitExpr) {
|
||||
|
@ -1157,7 +1168,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
|
|||
if (children.empty())
|
||||
addTypeTokens(tokenList, mExtTokens.back());
|
||||
else
|
||||
addTypeTokens(tokenList, children[0]->getType());
|
||||
addTypeTokens(tokenList, getChild(0)->getType());
|
||||
Token *par2 = addtoken(tokenList, ")");
|
||||
par1->link(par2);
|
||||
par2->link(par1);
|
||||
|
@ -1192,13 +1203,13 @@ Token * clangimport::AstNode::createTokensCall(TokenList *tokenList)
|
|||
firstParam = 2;
|
||||
Token *obj = children[1]->createTokens(tokenList);
|
||||
Token *dot = addtoken(tokenList, ".");
|
||||
Token *op = children[0]->createTokens(tokenList);
|
||||
Token *op = getChild(0)->createTokens(tokenList);
|
||||
dot->astOperand1(obj);
|
||||
dot->astOperand2(op);
|
||||
f = dot;
|
||||
} else {
|
||||
firstParam = 1;
|
||||
f = children[0]->createTokens(tokenList);
|
||||
f = getChild(0)->createTokens(tokenList);
|
||||
}
|
||||
f->setValueType(nullptr);
|
||||
Token *par1 = addtoken(tokenList, "(");
|
||||
|
@ -1421,13 +1432,13 @@ Token * clangimport::AstNode::createTokensVarDecl(TokenList *tokenList)
|
|||
} else if (mExtTokens.back() == "callinit") {
|
||||
Token *par1 = addtoken(tokenList, "(");
|
||||
par1->astOperand1(vartok1);
|
||||
par1->astOperand2(children[0]->createTokens(tokenList));
|
||||
par1->astOperand2(getChild(0)->createTokens(tokenList));
|
||||
Token *par2 = addtoken(tokenList, ")");
|
||||
par1->link(par2);
|
||||
par2->link(par1);
|
||||
return par1;
|
||||
} else if (mExtTokens.back() == "listinit") {
|
||||
return children[0]->createTokens(tokenList);
|
||||
return getChild(0)->createTokens(tokenList);
|
||||
}
|
||||
return vartok1;
|
||||
}
|
||||
|
|
|
@ -328,6 +328,7 @@ unsigned int CppCheck::check(const std::string &path)
|
|||
const std::string analyzerInfo = mSettings.buildDir.empty() ? std::string() : AnalyzerInformation::getAnalyzerInfoFile(mSettings.buildDir, path, "");
|
||||
const std::string clangcmd = analyzerInfo + ".clang-cmd";
|
||||
const std::string clangStderr = analyzerInfo + ".clang-stderr";
|
||||
const std::string clangAst = analyzerInfo + ".clang-ast";
|
||||
std::string exe = mSettings.clangExecutable;
|
||||
#ifdef _WIN32
|
||||
// append .exe if it is not a path
|
||||
|
@ -377,15 +378,27 @@ unsigned int CppCheck::check(const std::string &path)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//std::cout << "Checking Clang ast dump:\n" << result2.second << std::endl;
|
||||
std::istringstream ast(output2);
|
||||
Tokenizer tokenizer(&mSettings, this);
|
||||
tokenizer.list.appendFileIfNew(path);
|
||||
clangimport::parseClangAstDump(&tokenizer, ast);
|
||||
ValueFlow::setValues(&tokenizer.list, const_cast<SymbolDatabase *>(tokenizer.getSymbolDatabase()), this, &mSettings);
|
||||
if (mSettings.debugnormal)
|
||||
tokenizer.printDebugOutput(1);
|
||||
checkNormalTokens(tokenizer);
|
||||
if (!mSettings.buildDir.empty()) {
|
||||
std::ofstream fout(clangAst);
|
||||
fout << output2 << std::endl;
|
||||
}
|
||||
|
||||
try {
|
||||
std::istringstream ast(output2);
|
||||
Tokenizer tokenizer(&mSettings, this);
|
||||
tokenizer.list.appendFileIfNew(path);
|
||||
clangimport::parseClangAstDump(&tokenizer, ast);
|
||||
ValueFlow::setValues(&tokenizer.list, const_cast<SymbolDatabase *>(tokenizer.getSymbolDatabase()), this, &mSettings);
|
||||
if (mSettings.debugnormal)
|
||||
tokenizer.printDebugOutput(1);
|
||||
checkNormalTokens(tokenizer);
|
||||
} catch (const InternalError &e) {
|
||||
internalError(path, e.errorMessage);
|
||||
mExitCode = 1; // e.g. reflect a syntax error
|
||||
} catch (const std::exception &e) {
|
||||
internalError(path, e.what());
|
||||
}
|
||||
|
||||
return mExitCode;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue