forked from qt-creator/qt-creator
Fixed parsing of ctor-initializers and added a manual test for the AST matchers
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user