From baffd97efb1fd6da004fedf620577f8a97445793 Mon Sep 17 00:00:00 2001
From: Roberto Raggi <roberto.raggi@nokia.com>
Date: Fri, 13 Nov 2009 12:36:51 +0100
Subject: [PATCH] Fixed parsing of ctor-initializers and added a manual test
 for the AST matchers

---
 src/libs/cplusplus/FindUsages.cpp         |  2 +-
 src/shared/cplusplus/AST.cpp              |  4 +-
 src/shared/cplusplus/AST.h                |  2 +-
 src/shared/cplusplus/ASTMatcher.cpp       |  5 +-
 src/shared/cplusplus/ASTVisit.cpp         |  2 +-
 src/shared/cplusplus/CheckDeclaration.cpp |  4 +-
 src/shared/cplusplus/Parser.cpp           |  4 +-
 tests/manual/cplusplus/c++                |  4 +-
 tests/manual/cplusplus/conf.c++           |  2 +-
 tests/manual/cplusplus/cplusplus.pro      |  4 +-
 tests/manual/cplusplus/main.cpp           | 83 +++++++++++++----------
 11 files changed, 65 insertions(+), 51 deletions(-)

diff --git a/src/libs/cplusplus/FindUsages.cpp b/src/libs/cplusplus/FindUsages.cpp
index 8d501625019..5914322404e 100644
--- a/src/libs/cplusplus/FindUsages.cpp
+++ b/src/libs/cplusplus/FindUsages.cpp
@@ -221,7 +221,7 @@ bool FindUsages::visit(MemInitializerAST *ast)
             reportResult(simple->identifier_token, candidates);
         }
     }
-    accept(ast->expression);
+    accept(ast->expression_list);
     return false;
 }
 
diff --git a/src/shared/cplusplus/AST.cpp b/src/shared/cplusplus/AST.cpp
index 1e6cae8969e..9df97aa16f8 100644
--- a/src/shared/cplusplus/AST.cpp
+++ b/src/shared/cplusplus/AST.cpp
@@ -983,8 +983,8 @@ unsigned MemInitializerAST::lastToken() const
 {
     if (rparen_token)
         return rparen_token + 1;
-    else if (expression)
-        return expression->lastToken();
+    else if (expression_list)
+        return expression_list->lastToken();
     else if (lparen_token)
         return lparen_token + 1;
     return name->lastToken();
diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h
index d30858f0507..559932843bb 100644
--- a/src/shared/cplusplus/AST.h
+++ b/src/shared/cplusplus/AST.h
@@ -1187,7 +1187,7 @@ class CPLUSPLUS_EXPORT MemInitializerAST: public AST
 public:
     NameAST *name;
     unsigned lparen_token;
-    ExpressionAST *expression;
+    ExpressionListAST *expression_list;
     unsigned rparen_token;
 
 public:
diff --git a/src/shared/cplusplus/ASTMatcher.cpp b/src/shared/cplusplus/ASTMatcher.cpp
index ec31e0e3d98..47dac58232a 100644
--- a/src/shared/cplusplus/ASTMatcher.cpp
+++ b/src/shared/cplusplus/ASTMatcher.cpp
@@ -31,6 +31,7 @@
 #include "ASTMatcher.h"
 #include "Control.h"
 #include "TranslationUnit.h"
+#include "Literals.h"
 
 using namespace CPlusPlus;
 
@@ -54,7 +55,7 @@ bool ASTMatcher::matchToken(unsigned tokenIndex, unsigned patternTokenIndex) con
     if (token.f.kind != otherToken.f.kind)
         return false;
     else if (token.is(T_IDENTIFIER)) {
-        if (token.identifier != otherToken.identifier)
+        if (! token.identifier->isEqualTo(otherToken.identifier))
             return false;
     }
     return true;
@@ -636,7 +637,7 @@ bool ASTMatcher::match(MemInitializerAST *node, MemInitializerAST *pattern)
         return false;
     if (! matchToken(node->lparen_token, pattern->lparen_token))
         return false;
-    if (! AST::match(node->expression, pattern->expression, this))
+    if (! AST::match(node->expression_list, pattern->expression_list, this))
         return false;
     if (! matchToken(node->rparen_token, pattern->rparen_token))
         return false;
diff --git a/src/shared/cplusplus/ASTVisit.cpp b/src/shared/cplusplus/ASTVisit.cpp
index 2d5d618ddae..6e26f772b24 100644
--- a/src/shared/cplusplus/ASTVisit.cpp
+++ b/src/shared/cplusplus/ASTVisit.cpp
@@ -420,7 +420,7 @@ void MemInitializerAST::accept0(ASTVisitor *visitor)
 {
     if (visitor->visit(this)) {
         accept(name, visitor);
-        accept(expression, visitor);
+        accept(expression_list, visitor);
     }
     visitor->endVisit(this);
 }
diff --git a/src/shared/cplusplus/CheckDeclaration.cpp b/src/shared/cplusplus/CheckDeclaration.cpp
index 04ee291aef5..d7d7029fa21 100644
--- a/src/shared/cplusplus/CheckDeclaration.cpp
+++ b/src/shared/cplusplus/CheckDeclaration.cpp
@@ -356,7 +356,9 @@ bool CheckDeclaration::visit(FunctionDefinitionAST *ast)
 bool CheckDeclaration::visit(MemInitializerAST *ast)
 {
     (void) semantic()->check(ast->name, _scope);
-    FullySpecifiedType ty = semantic()->check(ast->expression, _scope);
+    for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
+        FullySpecifiedType ty = semantic()->check(it->value, _scope);
+    }
     return false;
 }
 
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index 36b7d03e1cf..5614355ab43 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -1849,7 +1849,7 @@ bool Parser::parseMemInitializer(MemInitializerListAST *&node)
         MemInitializerAST *ast = new (_pool) MemInitializerAST;
         ast->name = name;
         ast->lparen_token = consumeToken();
-        parseExpression(ast->expression);
+        parseExpressionList(ast->expression_list);
         if (LA() == T_RPAREN)
             ast->rparen_token = consumeToken();
 
@@ -1896,7 +1896,7 @@ bool Parser::parseExpressionList(ExpressionListAST *&node)
         while (LA() == T_COMMA) {
             consumeToken(); // consume T_COMMA
 
-            if (parseExpression(expression)) {
+            if (parseAssignmentExpression(expression)) {
                 *expression_list_ptr = new (_pool) ExpressionListAST;
                 (*expression_list_ptr)->value = expression;
                 expression_list_ptr = &(*expression_list_ptr)->next;
diff --git a/tests/manual/cplusplus/c++ b/tests/manual/cplusplus/c++
index f4cbb4fe5ca..a5908b79ff1 100755
--- a/tests/manual/cplusplus/c++
+++ b/tests/manual/cplusplus/c++
@@ -1,3 +1,5 @@
 #!/bin/sh
 me=$(dirname $0)
-${CPP-gcc} -xc++ -E -include $me/conf.c++ $* | $me/cplusplus0
+${CPP-gcc} -U__BLOCKS__ -xc++ -E -include $me/conf.c++ $* > $me/file.i
+$me/cplusplus0 $me/file.i
+
diff --git a/tests/manual/cplusplus/conf.c++ b/tests/manual/cplusplus/conf.c++
index 3cec3f4693d..69bafe0459c 100644
--- a/tests/manual/cplusplus/conf.c++
+++ b/tests/manual/cplusplus/conf.c++
@@ -6,7 +6,7 @@
 #define   restrict
 #define __restrict
 #define __restrict__
-#define __weak
+// #define __weak
 #define __builtin_va_arg(a,b) ((b)0)
 #define __stdcall
 #define __fastcall
diff --git a/tests/manual/cplusplus/cplusplus.pro b/tests/manual/cplusplus/cplusplus.pro
index 11dd08f6fbd..4964d9c5ea7 100644
--- a/tests/manual/cplusplus/cplusplus.pro
+++ b/tests/manual/cplusplus/cplusplus.pro
@@ -1,8 +1,8 @@
-QT = core
+QT = core gui
 macx:CONFIG -= app_bundle
 TARGET = cplusplus0
 
-include(../../../src/shared/cplusplus/cplusplus.pri)
+include(../../../src/libs/cplusplus/cplusplus-lib.pri)
 
 # Input
 SOURCES += main.cpp
diff --git a/tests/manual/cplusplus/main.cpp b/tests/manual/cplusplus/main.cpp
index 6c2596eeee1..a1054afee80 100644
--- a/tests/manual/cplusplus/main.cpp
+++ b/tests/manual/cplusplus/main.cpp
@@ -38,6 +38,7 @@
 #include <Symbols.h>
 #include <Names.h>
 #include <CoreTypes.h>
+#include <CppDocument.h>
 
 #include <QFile>
 #include <QList>
@@ -50,54 +51,62 @@
 #include <cstdio>
 #include <cstdlib>
 #include <iostream>
-#include <sstream>
 
 using namespace CPlusPlus;
 
-int main(int argc, char *argv[])
+class ForEachBinaryExpression: protected ASTVisitor
 {
-    QCoreApplication app(argc, argv);
+    Document::Ptr doc;
+    Document::Ptr pattern;
 
-    QStringList args = app.arguments();
-    const QString appName = args.first();
-    args.removeFirst();
+public:
+    ForEachBinaryExpression(Document::Ptr doc, Document::Ptr pattern)
+        : ASTVisitor(doc->control()), doc(doc), pattern(pattern) {}
 
-    foreach (const QString &arg, args) {
-        if (arg == QLatin1String("--help")) {
-            const QFileInfo appInfo(appName);
-            const QByteArray appFileName = QFile::encodeName(appInfo.fileName());
+    void operator()() { accept(doc->translationUnit()->ast()); }
 
-            printf("Usage: %s [options]\n"
-                   "  --help                    Display this information\n",
-                   appFileName.constData());
+protected:
+    using ASTVisitor::visit;
 
-            return EXIT_SUCCESS;
+    virtual bool visit(BinaryExpressionAST *ast)
+    {
+        ASTMatcher matcher(doc->translationUnit(), pattern->translationUnit());
+
+        if (ast->match(ast, pattern->translationUnit()->ast(), &matcher)) {
+            translationUnit()->warning(ast->binary_op_token, "binary expression");
         }
+
+        return true;
     }
+};
+
+int main(int argc, char *argv[])
+{
+    QCoreApplication app(argc, argv);
+
+    QStringList files = app.arguments();
+    files.removeFirst();
+
+    Document::Ptr pattern = Document::create("<pattern>");
+    pattern->setSource("__y < __x");
+    pattern->parse(Document::ParseExpression);
+
+    foreach (const QString &fileName, files) {
+        QFile file(fileName);
+        if (! file.open(QFile::ReadOnly))
+            continue;
+
+        const QByteArray source = file.readAll();
+        file.close();
+
+        Document::Ptr doc = Document::create(fileName);
+        doc->control()->setDiagnosticClient(0);
+        doc->setSource(source);
+        doc->parse();
+
+        ForEachBinaryExpression forEachBinaryExpression(doc, pattern);
 
-    QFile in;
-    if (! in.open(stdin, QFile::ReadOnly))
-        return EXIT_FAILURE;
-
-    const QByteArray source = in.readAll();
-
-    Control control;
-    StringLiteral *fileId = control.findOrInsertStringLiteral("<stdin>");
-    TranslationUnit unit(&control, fileId);
-    unit.setObjCEnabled(true);
-    unit.setSource(source.constData(), source.size());
-    unit.parse();
-    if (! unit.ast())
-        return EXIT_FAILURE;
-
-    TranslationUnitAST *ast = unit.ast()->asTranslationUnit();
-    Q_ASSERT(ast != 0);
-
-    Namespace *globalNamespace = control.newNamespace(0, 0);
-    Semantic sem(&control);
-    for (DeclarationListAST *it = ast->declaration_list; it; it = it->next) {
-        DeclarationAST *declaration = it->value;
-        sem.check(declaration, globalNamespace->members());
+        forEachBinaryExpression();
     }
 
     return EXIT_SUCCESS;
-- 
GitLab