Skip to content

Commit f37274a

Browse files
committed
ClangImport: Improved error handling
1 parent fb35756 commit f37274a

2 files changed

Lines changed: 69 additions & 45 deletions

File tree

lib/clangimport.cpp

Lines changed: 47 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,17 @@ namespace clangimport {
320320
addtoken(tokenList, ";");
321321
mData->mNotScope.clear();
322322
}
323+
324+
AstNodePtr getChild(int c) {
325+
if (c >= children.size()) {
326+
std::ostringstream err;
327+
err << "ClangImport: AstNodePtr::getChild(" << c << ") out of bounds. children.size=" << children.size() << " " << nodeType;
328+
for (const std::string &s: mExtTokens)
329+
err << " " << s;
330+
throw InternalError(nullptr, err.str());
331+
}
332+
return children[c];
333+
}
323334
private:
324335
Token *createTokens(TokenList *tokenList);
325336
Token *addtoken(TokenList *tokenList, const std::string &str, bool valueType=true);
@@ -647,7 +658,7 @@ Scope *clangimport::AstNode::createScope(TokenList *tokenList, Scope::ScopeType
647658
Token *clangimport::AstNode::createTokens(TokenList *tokenList)
648659
{
649660
if (nodeType == ArraySubscriptExpr) {
650-
Token *array = children[0]->createTokens(tokenList);
661+
Token *array = getChild(0)->createTokens(tokenList);
651662
Token *bracket1 = addtoken(tokenList, "[");
652663
Token *index = children[1]->createTokens(tokenList);
653664
Token *bracket2 = addtoken(tokenList, "]");
@@ -658,7 +669,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
658669
return bracket1;
659670
}
660671
if (nodeType == BinaryOperator) {
661-
Token *tok1 = children[0]->createTokens(tokenList);
672+
Token *tok1 = getChild(0)->createTokens(tokenList);
662673
Token *binop = addtoken(tokenList, unquote(mExtTokens.back()));
663674
Token *tok2 = children[1]->createTokens(tokenList);
664675
binop->astOperand1(tok1);
@@ -690,7 +701,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
690701
return createTokensCall(tokenList);
691702
if (nodeType == CaseStmt) {
692703
Token *caseToken = addtoken(tokenList, "case");
693-
Token *exprToken = children[0]->createTokens(tokenList);
704+
Token *exprToken = getChild(0)->createTokens(tokenList);
694705
caseToken->astOperand1(exprToken);
695706
addtoken(tokenList, ":");
696707
children.back()->createTokens(tokenList);
@@ -708,7 +719,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
708719
return nullptr;
709720
}
710721
if (nodeType == ConditionalOperator) {
711-
Token *expr1 = children[0]->createTokens(tokenList);
722+
Token *expr1 = getChild(0)->createTokens(tokenList);
712723
Token *tok1 = addtoken(tokenList, "?");
713724
Token *expr2 = children[1]->createTokens(tokenList);
714725
Token *tok2 = addtoken(tokenList, ":");
@@ -720,7 +731,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
720731
return tok1;
721732
}
722733
if (nodeType == CompoundAssignOperator) {
723-
Token *lhs = children[0]->createTokens(tokenList);
734+
Token *lhs = getChild(0)->createTokens(tokenList);
724735
Token *assign = addtoken(tokenList, getSpelling());
725736
Token *rhs = children[1]->createTokens(tokenList);
726737
assign->astOperand1(lhs);
@@ -745,19 +756,19 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
745756
Token *par2 = addtoken(tokenList, ")");
746757
par1->link(par2);
747758
par2->link(par1);
748-
par1->astOperand1(children[0]->createTokens(tokenList));
759+
par1->astOperand1(getChild(0)->createTokens(tokenList));
749760
return par1;
750761
}
751762
if (nodeType == CXXBindTemporaryExpr)
752-
return children[0]->createTokens(tokenList);
763+
return getChild(0)->createTokens(tokenList);
753764
if (nodeType == CXXBoolLiteralExpr) {
754765
addtoken(tokenList, mExtTokens.back());
755766
tokenList->back()->setValueType(new ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::BOOL, 0));
756767
return tokenList->back();
757768
}
758769
if (nodeType == CXXConstructExpr) {
759770
if (!children.empty())
760-
return children[0]->createTokens(tokenList);
771+
return getChild(0)->createTokens(tokenList);
761772
addTypeTokens(tokenList, '\'' + getType() + '\'');
762773
Token *type = tokenList->back();
763774
Token *par1 = addtoken(tokenList, "(");
@@ -773,7 +784,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
773784
}
774785
if (nodeType == CXXDeleteExpr) {
775786
addtoken(tokenList, "delete");
776-
children[0]->createTokens(tokenList);
787+
getChild(0)->createTokens(tokenList);
777788
return nullptr;
778789
}
779790
if (nodeType == CXXDestructorDecl) {
@@ -785,17 +796,17 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
785796
Token *par1 = addtoken(tokenList, "(");
786797
AstNodePtr varDecl;
787798
if (children[6]->nodeType == DeclStmt)
788-
varDecl = children[6]->children[0];
799+
varDecl = getChild(6)->getChild(0);
789800
else
790-
varDecl = children[5]->children[0];
801+
varDecl = getChild(5)->getChild(0);
791802
varDecl->mExtTokens.pop_back();
792803
varDecl->children.clear();
793804
Token *expr1 = varDecl->createTokens(tokenList);
794805
Token *colon = addtoken(tokenList, ":");
795806
AstNodePtr range;
796807
for (int i = 0; i < 2; i++) {
797-
if (children[i] && children[i]->nodeType == DeclStmt && children[i]->children[0]->nodeType == VarDecl) {
798-
range = children[i]->children[0]->children[0];
808+
if (children[i] && children[i]->nodeType == DeclStmt && children[i]->getChild(0)->nodeType == VarDecl) {
809+
range = children[i]->getChild(0)->getChild(0);
799810
break;
800811
}
801812
}
@@ -825,8 +836,8 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
825836
return createTokensCall(tokenList);
826837
if (nodeType == CXXNewExpr) {
827838
Token *newtok = addtoken(tokenList, "new");
828-
if (children.size() == 1 && children[0]->nodeType == CXXConstructExpr) {
829-
newtok->astOperand1(children[0]->createTokens(tokenList));
839+
if (children.size() == 1 && getChild(0)->nodeType == CXXConstructExpr) {
840+
newtok->astOperand1(getChild(0)->createTokens(tokenList));
830841
return newtok;
831842
}
832843
std::string type = getType();
@@ -835,7 +846,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
835846
addTypeTokens(tokenList, type);
836847
if (!children.empty()) {
837848
Token *bracket1 = addtoken(tokenList, "[");
838-
children[0]->createTokens(tokenList);
849+
getChild(0)->createTokens(tokenList);
839850
Token *bracket2 = addtoken(tokenList, "]");
840851
bracket1->link(bracket2);
841852
bracket2->link(bracket1);
@@ -853,7 +864,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
853864
if (nodeType == CXXStaticCastExpr || nodeType == CXXFunctionalCastExpr) {
854865
Token *cast = addtoken(tokenList, getSpelling());
855866
Token *par1 = addtoken(tokenList, "(");
856-
Token *expr = children[0]->createTokens(tokenList);
867+
Token *expr = getChild(0)->createTokens(tokenList);
857868
Token *par2 = addtoken(tokenList, ")");
858869
par1->link(par2);
859870
par2->link(par1);
@@ -863,14 +874,14 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
863874
return par1;
864875
}
865876
if (nodeType == CXXStdInitializerListExpr)
866-
return children[0]->createTokens(tokenList);
877+
return getChild(0)->createTokens(tokenList);
867878
if (nodeType == CXXTemporaryObjectExpr && !children.empty())
868-
return children[0]->createTokens(tokenList);
879+
return getChild(0)->createTokens(tokenList);
869880
if (nodeType == CXXThisExpr)
870881
return addtoken(tokenList, "this");
871882
if (nodeType == CXXThrowExpr) {
872883
Token *t = addtoken(tokenList, "throw");
873-
t->astOperand1(children[0]->createTokens(tokenList));
884+
t->astOperand1(getChild(0)->createTokens(tokenList));
874885
return t;
875886
}
876887
if (nodeType == DeclRefExpr) {
@@ -881,7 +892,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
881892
return reftok;
882893
}
883894
if (nodeType == DeclStmt)
884-
return children[0]->createTokens(tokenList);
895+
return getChild(0)->createTokens(tokenList);
885896
if (nodeType == DefaultStmt) {
886897
addtoken(tokenList, "default");
887898
addtoken(tokenList, ":");
@@ -890,7 +901,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
890901
}
891902
if (nodeType == DoStmt) {
892903
addtoken(tokenList, "do");
893-
createScope(tokenList, Scope::ScopeType::eDo, children[0], tokenList->back());
904+
createScope(tokenList, Scope::ScopeType::eDo, getChild(0), tokenList->back());
894905
Token *tok1 = addtoken(tokenList, "while");
895906
Token *par1 = addtoken(tokenList, "(");
896907
Token *expr = children[1]->createTokens(tokenList);
@@ -948,15 +959,15 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
948959
return nullptr;
949960
}
950961
if (nodeType == ExprWithCleanups)
951-
return children[0]->createTokens(tokenList);
962+
return getChild(0)->createTokens(tokenList);
952963
if (nodeType == FieldDecl)
953964
return createTokensVarDecl(tokenList);
954965
if (nodeType == FloatingLiteral)
955966
return addtoken(tokenList, mExtTokens.back());
956967
if (nodeType == ForStmt) {
957968
Token *forToken = addtoken(tokenList, "for");
958969
Token *par1 = addtoken(tokenList, "(");
959-
Token *expr1 = children[0] ? children[0]->createTokens(tokenList) : nullptr;
970+
Token *expr1 = getChild(0) ? children[0]->createTokens(tokenList) : nullptr;
960971
Token *sep1 = addtoken(tokenList, ";");
961972
Token *expr2 = children[2] ? children[2]->createTokens(tokenList) : nullptr;
962973
Token *sep2 = addtoken(tokenList, ";");
@@ -1022,7 +1033,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
10221033
return nullptr;
10231034
}
10241035
if (nodeType == ImplicitCastExpr) {
1025-
Token *expr = children[0]->createTokens(tokenList);
1036+
Token *expr = getChild(0)->createTokens(tokenList);
10261037
if (!expr->valueType() || contains(mExtTokens, "<ArrayToPointerDecay>"))
10271038
setValueType(expr);
10281039
return expr;
@@ -1055,9 +1066,9 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
10551066
if (nodeType == LinkageSpecDecl)
10561067
return nullptr;
10571068
if (nodeType == MaterializeTemporaryExpr)
1058-
return children[0]->createTokens(tokenList);
1069+
return getChild(0)->createTokens(tokenList);
10591070
if (nodeType == MemberExpr) {
1060-
Token *s = children[0]->createTokens(tokenList);
1071+
Token *s = getChild(0)->createTokens(tokenList);
10611072
Token *dot = addtoken(tokenList, ".");
10621073
std::string memberName = getSpelling();
10631074
if (memberName.compare(0, 2, "->") == 0) {
@@ -1090,7 +1101,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
10901101
return addtoken(tokenList, ";");
10911102
if (nodeType == ParenExpr) {
10921103
Token *par1 = addtoken(tokenList, "(");
1093-
Token *expr = children[0]->createTokens(tokenList);
1104+
Token *expr = getChild(0)->createTokens(tokenList);
10941105
Token *par2 = addtoken(tokenList, ")");
10951106
par1->link(par2);
10961107
par2->link(par1);
@@ -1119,8 +1130,8 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
11191130
if (nodeType == ReturnStmt) {
11201131
Token *tok1 = addtoken(tokenList, "return");
11211132
if (!children.empty()) {
1122-
children[0]->setValueType(tok1);
1123-
tok1->astOperand1(children[0]->createTokens(tokenList));
1133+
getChild(0)->setValueType(tok1);
1134+
tok1->astOperand1(getChild(0)->createTokens(tokenList));
11241135
}
11251136
return tok1;
11261137
}
@@ -1148,7 +1159,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
11481159
while (index > 0 && mExtTokens[index][0] != '\'')
11491160
--index;
11501161
Token *unop = addtoken(tokenList, unquote(mExtTokens[index]));
1151-
unop->astOperand1(children[0]->createTokens(tokenList));
1162+
unop->astOperand1(getChild(0)->createTokens(tokenList));
11521163
return unop;
11531164
}
11541165
if (nodeType == UnaryExprOrTypeTraitExpr) {
@@ -1157,7 +1168,7 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
11571168
if (children.empty())
11581169
addTypeTokens(tokenList, mExtTokens.back());
11591170
else
1160-
addTypeTokens(tokenList, children[0]->getType());
1171+
addTypeTokens(tokenList, getChild(0)->getType());
11611172
Token *par2 = addtoken(tokenList, ")");
11621173
par1->link(par2);
11631174
par2->link(par1);
@@ -1192,13 +1203,13 @@ Token * clangimport::AstNode::createTokensCall(TokenList *tokenList)
11921203
firstParam = 2;
11931204
Token *obj = children[1]->createTokens(tokenList);
11941205
Token *dot = addtoken(tokenList, ".");
1195-
Token *op = children[0]->createTokens(tokenList);
1206+
Token *op = getChild(0)->createTokens(tokenList);
11961207
dot->astOperand1(obj);
11971208
dot->astOperand2(op);
11981209
f = dot;
11991210
} else {
12001211
firstParam = 1;
1201-
f = children[0]->createTokens(tokenList);
1212+
f = getChild(0)->createTokens(tokenList);
12021213
}
12031214
f->setValueType(nullptr);
12041215
Token *par1 = addtoken(tokenList, "(");
@@ -1421,13 +1432,13 @@ Token * clangimport::AstNode::createTokensVarDecl(TokenList *tokenList)
14211432
} else if (mExtTokens.back() == "callinit") {
14221433
Token *par1 = addtoken(tokenList, "(");
14231434
par1->astOperand1(vartok1);
1424-
par1->astOperand2(children[0]->createTokens(tokenList));
1435+
par1->astOperand2(getChild(0)->createTokens(tokenList));
14251436
Token *par2 = addtoken(tokenList, ")");
14261437
par1->link(par2);
14271438
par2->link(par1);
14281439
return par1;
14291440
} else if (mExtTokens.back() == "listinit") {
1430-
return children[0]->createTokens(tokenList);
1441+
return getChild(0)->createTokens(tokenList);
14311442
}
14321443
return vartok1;
14331444
}

lib/cppcheck.cpp

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ unsigned int CppCheck::check(const std::string &path)
328328
const std::string analyzerInfo = mSettings.buildDir.empty() ? std::string() : AnalyzerInformation::getAnalyzerInfoFile(mSettings.buildDir, path, "");
329329
const std::string clangcmd = analyzerInfo + ".clang-cmd";
330330
const std::string clangStderr = analyzerInfo + ".clang-stderr";
331+
const std::string clangAst = analyzerInfo + ".clang-ast";
331332
std::string exe = mSettings.clangExecutable;
332333
#ifdef _WIN32
333334
// append .exe if it is not a path
@@ -377,15 +378,27 @@ unsigned int CppCheck::check(const std::string &path)
377378
return 0;
378379
}
379380

380-
//std::cout << "Checking Clang ast dump:\n" << result2.second << std::endl;
381-
std::istringstream ast(output2);
382-
Tokenizer tokenizer(&mSettings, this);
383-
tokenizer.list.appendFileIfNew(path);
384-
clangimport::parseClangAstDump(&tokenizer, ast);
385-
ValueFlow::setValues(&tokenizer.list, const_cast<SymbolDatabase *>(tokenizer.getSymbolDatabase()), this, &mSettings);
386-
if (mSettings.debugnormal)
387-
tokenizer.printDebugOutput(1);
388-
checkNormalTokens(tokenizer);
381+
if (!mSettings.buildDir.empty()) {
382+
std::ofstream fout(clangAst);
383+
fout << output2 << std::endl;
384+
}
385+
386+
try {
387+
std::istringstream ast(output2);
388+
Tokenizer tokenizer(&mSettings, this);
389+
tokenizer.list.appendFileIfNew(path);
390+
clangimport::parseClangAstDump(&tokenizer, ast);
391+
ValueFlow::setValues(&tokenizer.list, const_cast<SymbolDatabase *>(tokenizer.getSymbolDatabase()), this, &mSettings);
392+
if (mSettings.debugnormal)
393+
tokenizer.printDebugOutput(1);
394+
checkNormalTokens(tokenizer);
395+
} catch (const InternalError &e) {
396+
internalError(path, e.errorMessage);
397+
mExitCode = 1; // e.g. reflect a syntax error
398+
} catch (const std::exception &e) {
399+
internalError(path, e.what());
400+
}
401+
389402
return mExitCode;
390403
}
391404

0 commit comments

Comments
 (0)