Commit da817310 authored by Roberto Raggi's avatar Roberto Raggi

Get rid of PostfixExpressionAST and store the base expression together with the PostfixAST nodes.

parent ed2862ac
......@@ -194,27 +194,12 @@ bool FindUsages::visit(MemInitializerAST *ast)
return false;
}
bool FindUsages::visit(PostfixExpressionAST *ast)
{
_postfixExpressionStack.append(ast);
return true;
}
void FindUsages::endVisit(PostfixExpressionAST *)
{
_postfixExpressionStack.removeLast();
}
bool FindUsages::visit(MemberAccessAST *ast)
{
if (ast->member_name) {
if (SimpleNameAST *simple = ast->member_name->asSimpleName()) {
if (identifier(simple->identifier_token) == _id) {
Q_ASSERT(! _postfixExpressionStack.isEmpty());
checkExpression(_postfixExpressionStack.last()->firstToken(),
simple->identifier_token);
checkExpression(ast->firstToken(), simple->identifier_token);
return false;
}
}
......
......@@ -83,8 +83,6 @@ protected:
void ensureNameIsValid(NameAST *ast);
virtual bool visit(MemInitializerAST *ast);
virtual bool visit(PostfixExpressionAST *ast);
virtual void endVisit(PostfixExpressionAST *);
virtual bool visit(MemberAccessAST *ast);
virtual bool visit(QualifiedNameAST *ast);
virtual bool visit(EnumeratorAST *ast);
......@@ -116,7 +114,6 @@ private:
QByteArray _source;
Document::Ptr _exprDoc;
Semantic _sem;
QList<PostfixExpressionAST *> _postfixExpressionStack;
QList<QualifiedNameAST *> _qualifiedNameStack;
QList<TemplateDeclarationAST *> _templateDeclarationStack;
QList<int> _references;
......
......@@ -244,16 +244,6 @@ bool ResolveExpression::visit(TypeConstructorCallAST *)
return false;
}
bool ResolveExpression::visit(PostfixExpressionAST *ast)
{
accept(ast->base_expression);
for (PostfixListAST *it = ast->postfix_expression_list; it; it = it->next)
accept(it->value);
return false;
}
bool ResolveExpression::visit(SizeofExpressionAST *)
{
FullySpecifiedType ty(control()->integerType(IntegerType::Int));
......@@ -468,8 +458,7 @@ bool ResolveExpression::maybeValidPrototype(Function *funTy, unsigned actualArgu
bool ResolveExpression::visit(CallAST *ast)
{
const QList<LookupItem> baseResults = _results;
_results.clear();
const QList<LookupItem> baseResults = resolve(ast->base_expression, _scope);
// Compute the types of the actual arguments.
int actualArgumentCount = 0;
......@@ -514,9 +503,7 @@ bool ResolveExpression::visit(CallAST *ast)
bool ResolveExpression::visit(ArrayAccessAST *ast)
{
const QList<LookupItem> baseResults = _results;
_results.clear();
const QList<LookupItem> baseResults = resolve(ast->base_expression, _scope);
const QList<LookupItem> indexResults = resolve(ast->expression);
const Name *arrayAccessOp = control()->operatorNameId(OperatorNameId::ArrayAccessOp);
......@@ -551,8 +538,7 @@ bool ResolveExpression::visit(MemberAccessAST *ast)
{
// The candidate types for the base expression are stored in
// _results.
const QList<LookupItem> baseResults = _results;
_results.clear();
const QList<LookupItem> baseResults = resolve(ast->base_expression, _scope);
// Evaluate the expression-id that follows the access operator.
const Name *memberName = 0;
......@@ -644,8 +630,10 @@ FullySpecifiedType ResolveExpression::instantiate(const Name *className, Symbol
return DeprecatedGenTemplateInstance::instantiate(className, candidate, _context.control());
}
bool ResolveExpression::visit(PostIncrDecrAST *)
bool ResolveExpression::visit(PostIncrDecrAST *ast)
{
const QList<LookupItem> baseResults = resolve(ast->base_expression, _scope);
_results = baseResults;
return false;
}
......
......@@ -79,7 +79,6 @@ protected:
virtual bool visit(TypeidExpressionAST *ast);
virtual bool visit(TypenameCallExpressionAST *ast);
virtual bool visit(TypeConstructorCallAST *ast);
virtual bool visit(PostfixExpressionAST *ast);
virtual bool visit(SizeofExpressionAST *ast);
virtual bool visit(NumericLiteralAST *ast);
virtual bool visit(BoolLiteralAST *ast);
......
......@@ -346,15 +346,11 @@ protected:
return false;
}
virtual bool visit(PostfixExpressionAST *ast)
virtual bool visit(MemberAccessAST *ast)
{
// accept only the base expression
accept(ast->base_expression);
for (PostfixListAST *it = ast->postfix_expression_list; it; it = it->next) {
PostfixAST *fx = it->value;
if (fx->asMemberAccess() != 0)
continue; // skip members
accept(fx);
}
// and ignore the member name.
return false;
}
......
......@@ -783,40 +783,32 @@ public:
virtual int match(const QList<AST *> &path)
{
stringLiteral = 0;
isObjCStringLiteral = false;
if (path.isEmpty())
return -1;
return -1; // nothing to do
int index = path.size() - 1;
stringLiteral = path[index]->asStringLiteral();
stringLiteral = path.last()->asStringLiteral();
if (!stringLiteral)
if (! stringLiteral)
return -1;
isObjCStringLiteral = charAt(startOf(stringLiteral)) == QLatin1Char('@');
// check if it is already wrapped in QLatin1String or -Literal
if (index-2 < 0)
return index;
else if (path.size() > 1) {
if (CallAST *call = path.at(path.size() - 2)->asCall()) {
if (call->base_expression) {
if (SimpleNameAST *functionName = call->base_expression->asSimpleName()) {
const QByteArray id(tokenAt(functionName->identifier_token).identifier->chars());
CallAST *call = path[index-1]->asCall();
PostfixExpressionAST *postfixExp = path[index-2]->asPostfixExpression();
if (call && postfixExp
&& postfixExp->base_expression
&& postfixExp->postfix_expression_list
&& postfixExp->postfix_expression_list->value == call)
{
NameAST *callName = postfixExp->base_expression->asName();
if (!callName)
return index;
QByteArray callNameString(tokenAt(callName->firstToken()).spell());
if (callNameString == "QLatin1String"
|| callNameString == "QLatin1Literal"
)
return -1;
if (id == "QLatin1String" || id == "QLatin1Literal")
return -1; // skip it
}
}
}
}
return index;
isObjCStringLiteral = charAt(startOf(stringLiteral)) == QLatin1Char('@');
return path.size() - 1; // very high priority
}
virtual void createChanges()
......@@ -845,7 +837,9 @@ class CStringToNSString: public CppQuickFixOperation
{
public:
CStringToNSString(TextEditor::BaseTextEditor *editor)
: CppQuickFixOperation(editor), stringLiteral(0), qlatin1Call(0)
: CppQuickFixOperation(editor)
, stringLiteral(0)
, qlatin1Call(0)
{}
virtual QString description() const
......@@ -855,43 +849,34 @@ public:
virtual int match(const QList<AST *> &path)
{
stringLiteral = 0;
qlatin1Call = 0;
if (path.isEmpty())
return -1;
return -1; // nothing to do
int index = path.size() - 1;
stringLiteral = path[index]->asStringLiteral();
stringLiteral = path.last()->asStringLiteral();
if (!stringLiteral)
if (! stringLiteral)
return -1;
if (charAt(startOf(stringLiteral)) == QLatin1Char('@'))
return -1;
else if (charAt(startOf(stringLiteral)) == QLatin1Char('@'))
return -1; // it's already an objc string literal.
// check if it is already wrapped in QLatin1String or -Literal
if (index-2 < 0)
return index;
CallAST *call = path[index-1]->asCall();
PostfixExpressionAST *postfixExp = path[index-2]->asPostfixExpression();
if (call && postfixExp
&& postfixExp->base_expression
&& postfixExp->postfix_expression_list
&& postfixExp->postfix_expression_list->value == call)
{
NameAST *callName = postfixExp->base_expression->asName();
if (!callName)
return index;
else if (path.size() > 1) {
if (CallAST *call = path.at(path.size() - 2)->asCall()) {
if (call->base_expression) {
if (SimpleNameAST *functionName = call->base_expression->asSimpleName()) {
const QByteArray id(tokenAt(functionName->identifier_token).identifier->chars());
if (!(postfixExp->postfix_expression_list->next)) {
QByteArray callNameString(tokenAt(callName->firstToken()).spell());
if (callNameString == "QLatin1String"
|| callNameString == "QLatin1Literal"
)
qlatin1Call = postfixExp;
if (id == "QLatin1String" || id == "QLatin1Literal")
qlatin1Call = call;
}
}
}
}
return index;
return path.size() - 1; // very high priority
}
virtual void createChanges()
......@@ -910,7 +895,7 @@ public:
private:
StringLiteralAST *stringLiteral;
PostfixExpressionAST *qlatin1Call;
CallAST *qlatin1Call;
};
} // end of anonymous namespace
......
......@@ -287,6 +287,9 @@ unsigned QtInterfacesDeclarationAST::lastToken() const
unsigned ArrayAccessAST::firstToken() const
{
if (base_expression)
return base_expression->firstToken();
return lbracket_token;
}
......@@ -296,7 +299,9 @@ unsigned ArrayAccessAST::lastToken() const
return rbracket_token + 1;
else if (expression)
return expression->lastToken();
return lbracket_token + 1;
if (lbracket_token)
return lbracket_token + 1;
return base_expression->lastToken();
}
......@@ -474,6 +479,9 @@ unsigned BreakStatementAST::lastToken() const
unsigned CallAST::firstToken() const
{
if (base_expression)
return base_expression->firstToken();
return lparen_token;
}
......@@ -485,7 +493,10 @@ unsigned CallAST::lastToken() const
else if (expression_list)
return expression_list->lastToken();
return lparen_token + 1;
if (lparen_token)
return lparen_token + 1;
return base_expression->lastToken();
}
......@@ -1183,6 +1194,8 @@ unsigned MemInitializerAST::lastToken() const
unsigned MemberAccessAST::firstToken() const
{
if (base_expression)
return base_expression->firstToken();
return access_token;
}
......@@ -1192,7 +1205,9 @@ unsigned MemberAccessAST::lastToken() const
return member_name->lastToken();
else if (template_token)
return template_token + 1;
return access_token + 1;
else if (access_token)
return access_token + 1;
return base_expression->lastToken();
}
......@@ -1488,24 +1503,15 @@ unsigned PointerToMemberAST::lastToken() const
unsigned PostIncrDecrAST::firstToken() const
{
if (base_expression)
return base_expression->firstToken();
return incr_decr_token;
}
unsigned PostIncrDecrAST::lastToken() const
{
return incr_decr_token + 1;
}
unsigned PostfixExpressionAST::firstToken() const
{
return base_expression->firstToken();
}
unsigned PostfixExpressionAST::lastToken() const
{
if (postfix_expression_list)
return postfix_expression_list->lastToken();
if (incr_decr_token)
return incr_decr_token + 1;
return base_expression->lastToken();
}
......
......@@ -258,7 +258,6 @@ public:
virtual PostIncrDecrAST *asPostIncrDecr() { return 0; }
virtual PostfixAST *asPostfix() { return 0; }
virtual PostfixDeclaratorAST *asPostfixDeclarator() { return 0; }
virtual PostfixExpressionAST *asPostfixExpression() { return 0; }
virtual PtrOperatorAST *asPtrOperator() { return 0; }
virtual QtEnumDeclarationAST *asQtEnumDeclaration() { return 0; }
virtual QtFlagsDeclarationAST *asQtFlagsDeclaration() { return 0; }
......@@ -375,7 +374,7 @@ public:
virtual PtrOperatorAST *clone(MemoryPool *pool) const = 0;
};
class CPLUSPLUS_EXPORT PostfixAST: public AST
class CPLUSPLUS_EXPORT PostfixAST: public ExpressionAST
{
public:
PostfixAST()
......@@ -2503,13 +2502,15 @@ protected:
class CPLUSPLUS_EXPORT CallAST: public PostfixAST
{
public:
ExpressionAST *base_expression;
unsigned lparen_token;
ExpressionListAST *expression_list;
unsigned rparen_token;
public:
CallAST()
: lparen_token(0)
: base_expression(0)
, lparen_token(0)
, expression_list(0)
, rparen_token(0)
{}
......@@ -2529,13 +2530,15 @@ protected:
class CPLUSPLUS_EXPORT ArrayAccessAST: public PostfixAST
{
public:
ExpressionAST *base_expression;
unsigned lbracket_token;
ExpressionAST *expression;
unsigned rbracket_token;
public:
ArrayAccessAST()
: lbracket_token(0)
: base_expression(0)
, lbracket_token(0)
, expression(0)
, rbracket_token(0)
{}
......@@ -2555,11 +2558,13 @@ protected:
class CPLUSPLUS_EXPORT PostIncrDecrAST: public PostfixAST
{
public:
ExpressionAST *base_expression;
unsigned incr_decr_token;
public:
PostIncrDecrAST()
: incr_decr_token(0)
: base_expression(0)
, incr_decr_token(0)
{}
virtual PostIncrDecrAST *asPostIncrDecr() { return this; }
......@@ -2577,13 +2582,15 @@ protected:
class CPLUSPLUS_EXPORT MemberAccessAST: public PostfixAST
{
public:
ExpressionAST *base_expression;
unsigned access_token;
unsigned template_token;
NameAST *member_name;
public:
MemberAccessAST()
: access_token(0)
: base_expression(0)
, access_token(0)
, template_token(0)
, member_name(0)
{}
......@@ -2686,30 +2693,6 @@ protected:
virtual bool match0(AST *, ASTMatcher *);
};
class CPLUSPLUS_EXPORT PostfixExpressionAST: public ExpressionAST
{
public:
ExpressionAST *base_expression;
PostfixListAST *postfix_expression_list;
public:
PostfixExpressionAST()
: base_expression(0)
, postfix_expression_list(0)
{}
virtual PostfixExpressionAST *asPostfixExpression() { return this; }
virtual unsigned firstToken() const;
virtual unsigned lastToken() const;
virtual PostfixExpressionAST *clone(MemoryPool *pool) const;
protected:
virtual void accept0(ASTVisitor *visitor);
virtual bool match0(AST *, ASTMatcher *);
};
class CPLUSPLUS_EXPORT PointerToMemberAST: public PtrOperatorAST
{
public:
......
......@@ -928,6 +928,8 @@ ParameterDeclarationClauseAST *ParameterDeclarationClauseAST::clone(MemoryPool *
CallAST *CallAST::clone(MemoryPool *pool) const
{
CallAST *ast = new (pool) CallAST;
if (base_expression)
ast->base_expression = base_expression->clone(pool);
ast->lparen_token = lparen_token;
for (ExpressionListAST *iter = expression_list, **ast_iter = &ast->expression_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
......@@ -939,6 +941,8 @@ CallAST *CallAST::clone(MemoryPool *pool) const
ArrayAccessAST *ArrayAccessAST::clone(MemoryPool *pool) const
{
ArrayAccessAST *ast = new (pool) ArrayAccessAST;
if (base_expression)
ast->base_expression = base_expression->clone(pool);
ast->lbracket_token = lbracket_token;
if (expression)
ast->expression = expression->clone(pool);
......@@ -949,6 +953,8 @@ ArrayAccessAST *ArrayAccessAST::clone(MemoryPool *pool) const
PostIncrDecrAST *PostIncrDecrAST::clone(MemoryPool *pool) const
{
PostIncrDecrAST *ast = new (pool) PostIncrDecrAST;
if (base_expression)
ast->base_expression = base_expression->clone(pool);
ast->incr_decr_token = incr_decr_token;
return ast;
}
......@@ -956,6 +962,8 @@ PostIncrDecrAST *PostIncrDecrAST::clone(MemoryPool *pool) const
MemberAccessAST *MemberAccessAST::clone(MemoryPool *pool) const
{
MemberAccessAST *ast = new (pool) MemberAccessAST;
if (base_expression)
ast->base_expression = base_expression->clone(pool);
ast->access_token = access_token;
ast->template_token = template_token;
if (member_name)
......@@ -1002,17 +1010,6 @@ TypeConstructorCallAST *TypeConstructorCallAST::clone(MemoryPool *pool) const
return ast;
}
PostfixExpressionAST *PostfixExpressionAST::clone(MemoryPool *pool) const
{
PostfixExpressionAST *ast = new (pool) PostfixExpressionAST;
if (base_expression)
ast->base_expression = base_expression->clone(pool);
for (PostfixListAST *iter = postfix_expression_list, **ast_iter = &ast->postfix_expression_list;
iter; iter = iter->next, ast_iter = &(*ast_iter)->next)
*ast_iter = new (pool) PostfixListAST((iter->value) ? iter->value->clone(pool) : 0);
return ast;
}
PointerToMemberAST *PointerToMemberAST::clone(MemoryPool *pool) const
{
PointerToMemberAST *ast = new (pool) PointerToMemberAST;
......
......@@ -689,14 +689,6 @@ bool TypeConstructorCallAST::match0(AST *pattern, ASTMatcher *matcher)
return false;
}
bool PostfixExpressionAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (PostfixExpressionAST *_other = pattern->asPostfixExpression())
return matcher->match(this, _other);
return false;
}
bool PointerToMemberAST::match0(AST *pattern, ASTMatcher *matcher)
{
if (PointerToMemberAST *_other = pattern->asPointerToMember())
......
......@@ -1560,6 +1560,11 @@ bool ASTMatcher::match(CallAST *node, CallAST *pattern)
(void) node;
(void) pattern;
if (! pattern->base_expression)
pattern->base_expression = node->base_expression;
else if (! AST::match(node->base_expression, pattern->base_expression, this))
return false;
pattern->lparen_token = node->lparen_token;
if (! pattern->expression_list)
......@@ -1577,6 +1582,11 @@ bool ASTMatcher::match(ArrayAccessAST *node, ArrayAccessAST *pattern)
(void) node;
(void) pattern;
if (! pattern->base_expression)
pattern->base_expression = node->base_expression;
else if (! AST::match(node->base_expression, pattern->base_expression, this))
return false;
pattern->lbracket_token = node->lbracket_token;
if (! pattern->expression)
......@@ -1594,6 +1604,11 @@ bool ASTMatcher::match(PostIncrDecrAST *node, PostIncrDecrAST *pattern)
(void) node;
(void) pattern;
if (! pattern->base_expression)
pattern->base_expression = node->base_expression;
else if (! AST::match(node->base_expression, pattern->base_expression, this))
return false;
pattern->incr_decr_token = node->incr_decr_token;
return true;
......@@ -1604,6 +1619,11 @@ bool ASTMatcher::match(MemberAccessAST *node, MemberAccessAST *pattern)
(void) node;
(void) pattern;
if (! pattern->base_expression)
pattern->base_expression = node->base_expression;
else if (! AST::match(node->base_expression, pattern->base_expression, this))
return false;
pattern->access_token = node->access_token;
pattern->template_token = node->template_token;
......@@ -1681,24 +1701,6 @@ bool ASTMatcher::match(TypeConstructorCallAST *node, TypeConstructorCallAST *pat
return true;
}
bool ASTMatcher::match(PostfixExpressionAST *node, PostfixExpressionAST *pattern)
{
(void) node;
(void) pattern;
if (! pattern->base_expression)
pattern->base_expression = node->base_expression;
else if (! AST::match(node->base_expression, pattern->base_expression, this))
return false;
if (! pattern->postfix_expression_list)
pattern->postfix_expression_list = node->postfix_expression_list;