diff --git a/lib/clangastdump.cpp b/lib/clangastdump.cpp index 30cb1854b..c8e2f13e5 100644 --- a/lib/clangastdump.cpp +++ b/lib/clangastdump.cpp @@ -31,7 +31,9 @@ static const std::string BinaryOperator = "BinaryOperator"; static const std::string CallExpr = "CallExpr"; static const std::string CompoundStmt = "CompoundStmt"; static const std::string DeclRefExpr = "DeclRefExpr"; +static const std::string DeclStmt = "DeclStmt"; static const std::string FieldDecl = "FieldDecl"; +static const std::string ForStmt = "ForStmt"; static const std::string FunctionDecl = "FunctionDecl"; static const std::string IfStmt = "IfStmt"; static const std::string ImplicitCastExpr = "ImplicitCastExpr"; @@ -136,13 +138,19 @@ namespace clangastdump { void setLocations(TokenList *tokenList, int file, int line, int col); void dumpAst(int num = 0, int indent = 0) const; - Token *createTokens(TokenList *tokenList); + void createTokens1(TokenList *tokenList) { + setLocations(tokenList, 0, 1, 1); + createTokens(tokenList); + if (nodeType == VarDecl || nodeType == RecordDecl) + addtoken(tokenList, ";"); + } private: + Token *createTokens(TokenList *tokenList); Token *addtoken(TokenList *tokenList, const std::string &str); void addTypeTokens(TokenList *tokenList, const std::string &str); Scope *createScope(TokenList *tokenList, Scope::ScopeType scopeType, AstNodePtr astNode); Scope *createScope(TokenList *tokenList, Scope::ScopeType scopeType, const std::vector &children); - void createTokensVarDecl(TokenList *tokenList); + Token *createTokensVarDecl(TokenList *tokenList); std::string getSpelling() const; std::string getType() const; const Scope *getNestedInScope(TokenList *tokenList); @@ -312,14 +320,33 @@ Token *clangastdump::AstNode::createTokens(TokenList *tokenList) } return nullptr; } + if (nodeType == DeclStmt) + return children[0]->createTokens(tokenList); if (nodeType == DeclRefExpr) { const std::string addr = mExtTokens[mExtTokens.size() - 3]; Token *reftok = addtoken(tokenList, unquote(mExtTokens[mExtTokens.size() - 2])); mData->ref(addr, reftok); return reftok; } - if (nodeType == FieldDecl) { - createTokensVarDecl(tokenList); + if (nodeType == FieldDecl) + return createTokensVarDecl(tokenList); + if (nodeType == ForStmt) { + Token *forToken = addtoken(tokenList, "for"); + Token *par1 = addtoken(tokenList, "("); + Token *expr1 = children[0]->createTokens(tokenList); + Token *sep1 = addtoken(tokenList, ";"); + Token *expr2 = children[2]->createTokens(tokenList); + Token *sep2 = addtoken(tokenList, ";"); + Token *expr3 = children[3]->createTokens(tokenList); + Token *par2 = addtoken(tokenList, ")"); + par1->link(par2); + par1->astOperand1(forToken); + par1->astOperand2(sep1); + sep1->astOperand1(expr1); + sep1->astOperand2(sep2); + sep2->astOperand1(expr2); + sep2->astOperand2(expr3); + createScope(tokenList, Scope::ScopeType::eFor, children[4]); return nullptr; } if (nodeType == FunctionDecl) { @@ -418,14 +445,12 @@ Token *clangastdump::AstNode::createTokens(TokenList *tokenList) unop->astOperand1(children[0]->createTokens(tokenList)); return unop; } - if (nodeType == VarDecl) { - createTokensVarDecl(tokenList); - return nullptr; - } + if (nodeType == VarDecl) + return createTokensVarDecl(tokenList); return addtoken(tokenList, "?" + nodeType + "?"); } -void clangastdump::AstNode::createTokensVarDecl(TokenList *tokenList) +Token * clangastdump::AstNode::createTokensVarDecl(TokenList *tokenList) { bool isInit = mExtTokens.back() == "cinit"; const std::string addr = mExtTokens.front(); @@ -437,15 +462,13 @@ void clangastdump::AstNode::createTokensVarDecl(TokenList *tokenList) const AccessControl accessControl = (scope->type == Scope::ScopeType::eGlobal) ? (AccessControl::Global) : (AccessControl::Local); scope->varlist.push_back(Variable(vartok1, type, 0, accessControl, nullptr, scope)); mData->varDecl(addr, vartok1, &scope->varlist.back()); - addtoken(tokenList, ";"); if (isInit) { - Token *vartok2 = addtoken(tokenList, name); - mData->ref(addr, vartok2); Token *eq = addtoken(tokenList, "="); - eq->astOperand1(vartok2); + eq->astOperand1(vartok1); eq->astOperand2(children.back()->createTokens(tokenList)); - addtoken(tokenList, ";"); + return eq; } + return vartok1; } void clangastdump::parseClangAstDump(Tokenizer *tokenizer, std::istream &f) @@ -477,10 +500,8 @@ void clangastdump::parseClangAstDump(Tokenizer *tokenizer, std::istream &f) const std::string ext = line.substr(pos2); if (pos1 == 1 && endsWith(nodeType, "Decl", 4) && nodeType != "TypedefDecl") { - if (!tree.empty()) { - tree[0]->setLocations(tokenList, 0, 1, 1); - tree[0]->createTokens(tokenList); - } + if (!tree.empty()) + tree[0]->createTokens1(tokenList); tree.clear(); tree.push_back(std::make_shared(nodeType, ext, &data)); continue; @@ -498,12 +519,8 @@ void clangastdump::parseClangAstDump(Tokenizer *tokenizer, std::istream &f) tree[level] = newNode; } - if (!tree.empty()) { - //if (tokenizer->getSettings()->debugnormal) - // tree[0]->dumpAst(); - tree[0]->setLocations(tokenList, 0, 1, 1); - tree[0]->createTokens(tokenList); - } + if (!tree.empty()) + tree[0]->createTokens1(tokenList); symbolDatabase->clangSetVariables(data.getVariableList()); tokenList->clangSetOrigFiles(); diff --git a/test/testclangastdump.cpp b/test/testclangastdump.cpp index 2878c4e69..be970eca5 100644 --- a/test/testclangastdump.cpp +++ b/test/testclangastdump.cpp @@ -29,6 +29,7 @@ public: private: void run() OVERRIDE { + TEST_CASE(forStmt); TEST_CASE(funcdecl1); TEST_CASE(funcdecl2); TEST_CASE(ifelse); @@ -46,6 +47,25 @@ private: return tokenizer.tokens()->stringifyList(true, false, false, true, false); } + void forStmt() { + const char clang[] = "`-FunctionDecl 0x2f93ae0 <1.c:1:1, col:56> col:5 main 'int ()'\n" + " `-CompoundStmt 0x2f93dc0 \n" + " |-ForStmt 0x2f93d50 \n" + " | |-DeclStmt 0x2f93c58 \n" + " | | `-VarDecl 0x2f93bd8 col:23 used i 'int' cinit\n" + " | | `-IntegerLiteral 0x2f93c38 'int' 0\n" + " | |-<<>>\n" + " | |-BinaryOperator 0x2f93cd0 'int' '<'\n" + " | | |-ImplicitCastExpr 0x2f93cb8 'int' \n" + " | | | `-DeclRefExpr 0x2f93c70 'int' lvalue Var 0x2f93bd8 'i' 'int'\n" + " | | `-IntegerLiteral 0x2f93c98 'int' 10\n" + " | |-UnaryOperator 0x2f93d20 'int' postfix '++'\n" + " | | `-DeclRefExpr 0x2f93cf8 'int' lvalue Var 0x2f93bd8 'i' 'int'\n" + " | `-CompoundStmt 0x2f93d40 \n" + " `-ReturnStmt 0x2f93da8 \n" + " `-IntegerLiteral 0x2f93d88 'int' 0"; + ASSERT_EQUALS("int main ( ) { for ( int i@1 = 0 ; i@1 < 10 ; ++ i@1 ) { } ; return 0 ; }", parse(clang)); + } void funcdecl1() { const char clang[] = "`-FunctionDecl 0x3122c30 <1.c:1:1, col:22> col:6 foo 'void (int, int)'\n" @@ -100,7 +120,7 @@ private: " `-ImplicitCastExpr 0x2441e40 'int' \n" " `-MemberExpr 0x2441e08 'int' lvalue .x 0x2441b48\n" " `-DeclRefExpr 0x2441de0 'struct S':'struct S' lvalue ParmVar 0x2441be8 's' 'struct S':'struct S'"; - ASSERT_EQUALS("struct S { int x@1 ; }\n" + ASSERT_EQUALS("struct S { int x@1 ; } ;\n" "int foo ( struct S s@2 ) { return s@2 . x@1 ; }", parse(clang)); } @@ -111,7 +131,7 @@ private: " `-FieldDecl 0x354ebe8 col:7 y 'int'"; ASSERT_EQUALS("struct S\n" "{ int x@1 ;\n" - "int y@2 ; }", + "int y@2 ; } ;", parse(clang)); } @@ -122,8 +142,8 @@ private: " `-ImplicitCastExpr 0x32b8c00 'int' \n" " `-DeclRefExpr 0x32b8bd8 'int' lvalue Var 0x32b8aa0 'a' 'int'"; - ASSERT_EQUALS("int a@1 ; a@1 = 1 ;\n" - "int b@2 ; b@2 = a@1 ;", + ASSERT_EQUALS("int a@1 = 1 ;\n" + "int b@2 = a@1 ;", parse(clang)); }