From aad3a041ad225c8488274a866f281450f6b7004c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= <daniel.marjamaki@gmail.com>
Date: Sun, 16 Dec 2012 10:06:55 +0100
Subject: [PATCH] AST: Handle function calls

---
 lib/token.cpp         | 14 +++++++++++++-
 lib/token.h           |  2 +-
 lib/tokenlist.cpp     |  7 +++++++
 test/testtokenize.cpp |  4 +++-
 4 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/lib/token.cpp b/lib/token.cpp
index 4603b7904..7b6784195 100644
--- a/lib/token.cpp
+++ b/lib/token.cpp
@@ -1080,9 +1080,21 @@ void Token::astOperand2(Token *tok)
     tok->_astParent = this;
 }
 
+void Token::astFunctionCall()
+{
+    _astOperand1 = _next;
+    _next->_astParent = this;
+}
+
 void Token::astHandleParenthesis()
 {
-    Token *innerTop = (_str == "(") ? _next : _previous;
+    Token *innerTop;
+    if (_str != "(")
+        innerTop = _previous;
+    else if (_next && _next->_str == ")")
+        return;
+    else
+        innerTop = _next;
     while (innerTop->_astParent)
         innerTop = innerTop->_astParent;
 
diff --git a/lib/token.h b/lib/token.h
index cc073824f..f3ad4f7b9 100644
--- a/lib/token.h
+++ b/lib/token.h
@@ -550,8 +550,8 @@ private:
 public:
     void astOperand1(Token *tok);
     void astOperand2(Token *tok);
+    void astFunctionCall();
     void astHandleParenthesis();
-    void astHandleBrackets();
 
     const Token * astOperand1() const {
         return _astOperand1;
diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp
index 088fc746f..0a3debd2d 100644
--- a/lib/tokenlist.cpp
+++ b/lib/tokenlist.cpp
@@ -343,6 +343,7 @@ void TokenList::createAst()
 {
     // operators that must be ordered according to C-precedence
     const char * const operators[] = {
+        " , "
         " :: ",
         " [ . ++ -- ",
         "> ++ -- + - ! ~ * & ",  // prefix unary operators, from right to left
@@ -386,6 +387,12 @@ void TokenList::createAst()
         }
     }
 
+    // function calls..
+    for (Token *tok = _front; tok; tok = tok->next()) {
+        if (Token::Match(tok, "%var% ("))
+            tok->astFunctionCall();
+    }
+
     // parentheses..
     for (Token *tok = _front; tok; tok = tok->next()) {
         if (tok->str() == "(" || tok->str() == ")" || tok->str() == "]") {
diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp
index 686c0681a..9b63ebeb8 100644
--- a/test/testtokenize.cpp
+++ b/test/testtokenize.cpp
@@ -7668,7 +7668,9 @@ private:
     }
 
     void astfunction() { // function calls
-        TODO_ASSERT_EQUALS("1f+2+", "1f+", testAst("1+f()+2"));
+        ASSERT_EQUALS("1(f+2+", testAst("1+f()+2"));
+        ASSERT_EQUALS("12f+3+", testAst("1+f(2)+3"));
+        ASSERT_EQUALS("123,f+4+", testAst("1+f(2,3)+4"));
     }
 
     void asttemplate() { // uninstantiated templates will have <,>,etc.. how do we handle them?