ClangImport: Improved error handling

This commit is contained in:
Daniel Marjamäki 2020-12-31 17:37:02 +01:00
parent fb35756126
commit f37274a5c0
2 changed files with 69 additions and 45 deletions

View File

@ -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;
}

View File

@ -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;
}