Fixed parsing of ctor-initializers and added a manual test for the AST matchers

This commit is contained in:
Roberto Raggi
2009-11-13 12:36:51 +01:00
parent 28ab85b137
commit baffd97efb
11 changed files with 63 additions and 49 deletions

View File

@@ -221,7 +221,7 @@ bool FindUsages::visit(MemInitializerAST *ast)
reportResult(simple->identifier_token, candidates); reportResult(simple->identifier_token, candidates);
} }
} }
accept(ast->expression); accept(ast->expression_list);
return false; return false;
} }

View File

@@ -983,8 +983,8 @@ unsigned MemInitializerAST::lastToken() const
{ {
if (rparen_token) if (rparen_token)
return rparen_token + 1; return rparen_token + 1;
else if (expression) else if (expression_list)
return expression->lastToken(); return expression_list->lastToken();
else if (lparen_token) else if (lparen_token)
return lparen_token + 1; return lparen_token + 1;
return name->lastToken(); return name->lastToken();

View File

@@ -1187,7 +1187,7 @@ class CPLUSPLUS_EXPORT MemInitializerAST: public AST
public: public:
NameAST *name; NameAST *name;
unsigned lparen_token; unsigned lparen_token;
ExpressionAST *expression; ExpressionListAST *expression_list;
unsigned rparen_token; unsigned rparen_token;
public: public:

View File

@@ -31,6 +31,7 @@
#include "ASTMatcher.h" #include "ASTMatcher.h"
#include "Control.h" #include "Control.h"
#include "TranslationUnit.h" #include "TranslationUnit.h"
#include "Literals.h"
using namespace CPlusPlus; using namespace CPlusPlus;
@@ -54,7 +55,7 @@ bool ASTMatcher::matchToken(unsigned tokenIndex, unsigned patternTokenIndex) con
if (token.f.kind != otherToken.f.kind) if (token.f.kind != otherToken.f.kind)
return false; return false;
else if (token.is(T_IDENTIFIER)) { else if (token.is(T_IDENTIFIER)) {
if (token.identifier != otherToken.identifier) if (! token.identifier->isEqualTo(otherToken.identifier))
return false; return false;
} }
return true; return true;
@@ -636,7 +637,7 @@ bool ASTMatcher::match(MemInitializerAST *node, MemInitializerAST *pattern)
return false; return false;
if (! matchToken(node->lparen_token, pattern->lparen_token)) if (! matchToken(node->lparen_token, pattern->lparen_token))
return false; return false;
if (! AST::match(node->expression, pattern->expression, this)) if (! AST::match(node->expression_list, pattern->expression_list, this))
return false; return false;
if (! matchToken(node->rparen_token, pattern->rparen_token)) if (! matchToken(node->rparen_token, pattern->rparen_token))
return false; return false;

View File

@@ -420,7 +420,7 @@ void MemInitializerAST::accept0(ASTVisitor *visitor)
{ {
if (visitor->visit(this)) { if (visitor->visit(this)) {
accept(name, visitor); accept(name, visitor);
accept(expression, visitor); accept(expression_list, visitor);
} }
visitor->endVisit(this); visitor->endVisit(this);
} }

View File

@@ -356,7 +356,9 @@ bool CheckDeclaration::visit(FunctionDefinitionAST *ast)
bool CheckDeclaration::visit(MemInitializerAST *ast) bool CheckDeclaration::visit(MemInitializerAST *ast)
{ {
(void) semantic()->check(ast->name, _scope); (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; return false;
} }

View File

@@ -1849,7 +1849,7 @@ bool Parser::parseMemInitializer(MemInitializerListAST *&node)
MemInitializerAST *ast = new (_pool) MemInitializerAST; MemInitializerAST *ast = new (_pool) MemInitializerAST;
ast->name = name; ast->name = name;
ast->lparen_token = consumeToken(); ast->lparen_token = consumeToken();
parseExpression(ast->expression); parseExpressionList(ast->expression_list);
if (LA() == T_RPAREN) if (LA() == T_RPAREN)
ast->rparen_token = consumeToken(); ast->rparen_token = consumeToken();
@@ -1896,7 +1896,7 @@ bool Parser::parseExpressionList(ExpressionListAST *&node)
while (LA() == T_COMMA) { while (LA() == T_COMMA) {
consumeToken(); // consume T_COMMA consumeToken(); // consume T_COMMA
if (parseExpression(expression)) { if (parseAssignmentExpression(expression)) {
*expression_list_ptr = new (_pool) ExpressionListAST; *expression_list_ptr = new (_pool) ExpressionListAST;
(*expression_list_ptr)->value = expression; (*expression_list_ptr)->value = expression;
expression_list_ptr = &(*expression_list_ptr)->next; expression_list_ptr = &(*expression_list_ptr)->next;

View File

@@ -1,3 +1,5 @@
#!/bin/sh #!/bin/sh
me=$(dirname $0) 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

View File

@@ -6,7 +6,7 @@
#define restrict #define restrict
#define __restrict #define __restrict
#define __restrict__ #define __restrict__
#define __weak // #define __weak
#define __builtin_va_arg(a,b) ((b)0) #define __builtin_va_arg(a,b) ((b)0)
#define __stdcall #define __stdcall
#define __fastcall #define __fastcall

View File

@@ -1,8 +1,8 @@
QT = core QT = core gui
macx:CONFIG -= app_bundle macx:CONFIG -= app_bundle
TARGET = cplusplus0 TARGET = cplusplus0
include(../../../src/shared/cplusplus/cplusplus.pri) include(../../../src/libs/cplusplus/cplusplus-lib.pri)
# Input # Input
SOURCES += main.cpp SOURCES += main.cpp

View File

@@ -38,6 +38,7 @@
#include <Symbols.h> #include <Symbols.h>
#include <Names.h> #include <Names.h>
#include <CoreTypes.h> #include <CoreTypes.h>
#include <CppDocument.h>
#include <QFile> #include <QFile>
#include <QList> #include <QList>
@@ -50,54 +51,62 @@
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <iostream> #include <iostream>
#include <sstream>
using namespace CPlusPlus; using namespace CPlusPlus;
class ForEachBinaryExpression: protected ASTVisitor
{
Document::Ptr doc;
Document::Ptr pattern;
public:
ForEachBinaryExpression(Document::Ptr doc, Document::Ptr pattern)
: ASTVisitor(doc->control()), doc(doc), pattern(pattern) {}
void operator()() { accept(doc->translationUnit()->ast()); }
protected:
using ASTVisitor::visit;
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[]) int main(int argc, char *argv[])
{ {
QCoreApplication app(argc, argv); QCoreApplication app(argc, argv);
QStringList args = app.arguments(); QStringList files = app.arguments();
const QString appName = args.first(); files.removeFirst();
args.removeFirst();
foreach (const QString &arg, args) { Document::Ptr pattern = Document::create("<pattern>");
if (arg == QLatin1String("--help")) { pattern->setSource("__y < __x");
const QFileInfo appInfo(appName); pattern->parse(Document::ParseExpression);
const QByteArray appFileName = QFile::encodeName(appInfo.fileName());
printf("Usage: %s [options]\n" foreach (const QString &fileName, files) {
" --help Display this information\n", QFile file(fileName);
appFileName.constData()); if (! file.open(QFile::ReadOnly))
continue;
return EXIT_SUCCESS; const QByteArray source = file.readAll();
} file.close();
}
QFile in; Document::Ptr doc = Document::create(fileName);
if (! in.open(stdin, QFile::ReadOnly)) doc->control()->setDiagnosticClient(0);
return EXIT_FAILURE; doc->setSource(source);
doc->parse();
const QByteArray source = in.readAll(); ForEachBinaryExpression forEachBinaryExpression(doc, pattern);
Control control; forEachBinaryExpression();
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());
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;