summaryrefslogtreecommitdiff
path: root/src/shared/cplusplus
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared/cplusplus')
-rw-r--r--src/shared/cplusplus/AST.h17
-rw-r--r--src/shared/cplusplus/CheckExpression.cpp5
-rw-r--r--src/shared/cplusplus/CheckStatement.cpp51
-rw-r--r--src/shared/cplusplus/CheckStatement.h8
-rw-r--r--src/shared/cplusplus/Parser.cpp8
-rw-r--r--src/shared/cplusplus/Semantic.cpp4
-rw-r--r--src/shared/cplusplus/Semantic.h2
7 files changed, 69 insertions, 26 deletions
diff --git a/src/shared/cplusplus/AST.h b/src/shared/cplusplus/AST.h
index c719f31160..1766891cd7 100644
--- a/src/shared/cplusplus/AST.h
+++ b/src/shared/cplusplus/AST.h
@@ -81,6 +81,17 @@ public:
unsigned lastToken() const
{
+ _Tp lv = lastValue();
+
+ if (lv)
+ return lv->lastToken();
+
+ // ### assert(0);
+ return 0;
+ }
+
+ _Tp lastValue() const
+ {
_Tp lastValue = 0;
for (const List *it = this; it; it = it->next) {
@@ -88,11 +99,7 @@ public:
lastValue = it->value;
}
- if (lastValue)
- return lastValue->lastToken();
-
- // ### assert(0);
- return 0;
+ return lastValue;
}
_Tp value;
diff --git a/src/shared/cplusplus/CheckExpression.cpp b/src/shared/cplusplus/CheckExpression.cpp
index c971204c2e..748fa9c901 100644
--- a/src/shared/cplusplus/CheckExpression.cpp
+++ b/src/shared/cplusplus/CheckExpression.cpp
@@ -289,12 +289,13 @@ bool CheckExpression::visit(ThisExpressionAST *)
bool CheckExpression::visit(CompoundExpressionAST *ast)
{
- return true; // ###
+ _fullySpecifiedType = semantic()->check(ast->compoundStatement, _scope);
+ return false;
}
bool CheckExpression::visit(NestedExpressionAST *ast)
{
- FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope);
+ _fullySpecifiedType = semantic()->check(ast->expression, _scope);
return false;
}
diff --git a/src/shared/cplusplus/CheckStatement.cpp b/src/shared/cplusplus/CheckStatement.cpp
index 41ccdf1c27..26e4e7c835 100644
--- a/src/shared/cplusplus/CheckStatement.cpp
+++ b/src/shared/cplusplus/CheckStatement.cpp
@@ -69,13 +69,22 @@ CheckStatement::CheckStatement(Semantic *semantic)
CheckStatement::~CheckStatement()
{ }
-void CheckStatement::check(StatementAST *statement, Scope *scope)
+FullySpecifiedType CheckStatement::check(StatementAST *statement, Scope *scope)
{
+ FullySpecifiedType previousExprType = switchExprType(FullySpecifiedType());
Scope *previousScope = switchScope(scope);
StatementAST *previousStatement = switchStatement(statement);
accept(statement);
(void) switchStatement(previousStatement);
(void) switchScope(previousScope);
+ return switchExprType(previousExprType);
+}
+
+FullySpecifiedType CheckStatement::switchExprType(const FullySpecifiedType &type)
+{
+ const FullySpecifiedType &previousExprType = _exprType;
+ _exprType = type;
+ return previousExprType;
}
StatementAST *CheckStatement::switchStatement(StatementAST *statement)
@@ -94,8 +103,8 @@ Scope *CheckStatement::switchScope(Scope *scope)
bool CheckStatement::visit(CaseStatementAST *ast)
{
- FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope);
- semantic()->check(ast->statement, _scope);
+ (void) semantic()->check(ast->expression, _scope);
+ _exprType = semantic()->check(ast->statement, _scope);
return false;
}
@@ -110,7 +119,7 @@ bool CheckStatement::visit(CompoundStatementAST *ast)
StatementAST *previousStatement = 0;
for (StatementListAST *it = ast->statement_list; it; it = it->next) {
StatementAST *statement = it->value;
- semantic()->check(statement, _scope);
+ _exprType = semantic()->check(statement, _scope);
if (statement && previousStatement) {
ExpressionStatementAST *expressionStatement = statement->asExpressionStatement();
@@ -128,13 +137,15 @@ bool CheckStatement::visit(CompoundStatementAST *ast)
bool CheckStatement::visit(DeclarationStatementAST *ast)
{
semantic()->check(ast->declaration, _scope);
+ _exprType = FullySpecifiedType();
return false;
}
bool CheckStatement::visit(DoStatementAST *ast)
{
semantic()->check(ast->statement, _scope);
- FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope);
+ (void) semantic()->check(ast->expression, _scope);
+ _exprType = FullySpecifiedType();
return false;
}
@@ -142,16 +153,18 @@ bool CheckStatement::visit(ExpressionOrDeclarationStatementAST *ast)
{
// translationUnit()->warning(ast->firstToken(),
// "ambiguous expression or declaration statement");
- if (ast->declaration)
+ if (ast->declaration) {
semantic()->check(ast->declaration, _scope);
- else
- semantic()->check(ast->expression, _scope);
+ _exprType = FullySpecifiedType();
+ } else {
+ _exprType = semantic()->check(ast->expression, _scope);
+ }
return false;
}
bool CheckStatement::visit(ExpressionStatementAST *ast)
{
- FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope);
+ _exprType = semantic()->check(ast->expression, _scope);
return false;
}
@@ -181,13 +194,13 @@ bool CheckStatement::forEachFastEnum(unsigned firstToken,
decl->setType(ty);
_scope->enterSymbol(decl);
} else {
- FullySpecifiedType exprTy = semantic()->check(initializer, _scope);
- (void) exprTy;
+ (void) semantic()->check(initializer, _scope);
}
- FullySpecifiedType exprTy = semantic()->check(expression, _scope);
+ (void) semantic()->check(expression, _scope);
semantic()->check(statement, _scope);
(void) switchScope(previousScope);
+ _exprType = FullySpecifiedType();
return false;
}
@@ -228,6 +241,7 @@ bool CheckStatement::visit(ForStatementAST *ast)
FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope);
semantic()->check(ast->statement, _scope);
(void) switchScope(previousScope);
+ _exprType = FullySpecifiedType();
return false;
}
@@ -243,33 +257,38 @@ bool CheckStatement::visit(IfStatementAST *ast)
semantic()->check(ast->statement, _scope);
semantic()->check(ast->else_statement, _scope);
(void) switchScope(previousScope);
+ _exprType = FullySpecifiedType();
return false;
}
bool CheckStatement::visit(LabeledStatementAST *ast)
{
semantic()->check(ast->statement, _scope);
+ _exprType = FullySpecifiedType();
return false;
}
bool CheckStatement::visit(BreakStatementAST *)
{
+ _exprType = FullySpecifiedType();
return false;
}
bool CheckStatement::visit(ContinueStatementAST *)
{
+ _exprType = FullySpecifiedType();
return false;
}
bool CheckStatement::visit(GotoStatementAST *)
{
+ _exprType = FullySpecifiedType();
return false;
}
bool CheckStatement::visit(ReturnStatementAST *ast)
{
- FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope);
+ _exprType = semantic()->check(ast->expression, _scope);
return false;
}
@@ -284,6 +303,7 @@ bool CheckStatement::visit(SwitchStatementAST *ast)
FullySpecifiedType condTy = semantic()->check(ast->condition, _scope);
semantic()->check(ast->statement, _scope);
(void) switchScope(previousScope);
+ _exprType = FullySpecifiedType();
return false;
}
@@ -293,6 +313,7 @@ bool CheckStatement::visit(TryBlockStatementAST *ast)
for (CatchClauseListAST *it = ast->catch_clause_list; it; it = it->next) {
semantic()->check(it->value, _scope);
}
+ _exprType = FullySpecifiedType();
return false;
}
@@ -307,6 +328,7 @@ bool CheckStatement::visit(CatchClauseAST *ast)
semantic()->check(ast->exception_declaration, _scope);
semantic()->check(ast->statement, _scope);
(void) switchScope(previousScope);
+ _exprType = FullySpecifiedType();
return false;
}
@@ -321,6 +343,7 @@ bool CheckStatement::visit(WhileStatementAST *ast)
FullySpecifiedType condTy = semantic()->check(ast->condition, _scope);
semantic()->check(ast->statement, _scope);
(void) switchScope(previousScope);
+ _exprType = FullySpecifiedType();
return false;
}
@@ -353,6 +376,6 @@ bool CheckStatement::visit(QtMemberDeclarationAST *ast)
symbol->setType(control()->pointerType(declTy));
_scope->enterSymbol(symbol);
-
+ _exprType = FullySpecifiedType();
return false;
}
diff --git a/src/shared/cplusplus/CheckStatement.h b/src/shared/cplusplus/CheckStatement.h
index 5c1b1ff02d..dc8447f37e 100644
--- a/src/shared/cplusplus/CheckStatement.h
+++ b/src/shared/cplusplus/CheckStatement.h
@@ -50,9 +50,9 @@
#define CPLUSPLUS_CHECKSTATEMENT_H
#include "CPlusPlusForwardDeclarations.h"
+#include "FullySpecifiedType.h"
#include "SemanticCheck.h"
-
namespace CPlusPlus {
class CPLUSPLUS_EXPORT CheckStatement: public SemanticCheck
@@ -61,9 +61,10 @@ public:
CheckStatement(Semantic *semantic);
virtual ~CheckStatement();
- void check(StatementAST *statement, Scope *scope);
+ FullySpecifiedType check(StatementAST *statement, Scope *scope);
protected:
+ FullySpecifiedType switchExprType(const FullySpecifiedType &type);
StatementAST *switchStatement(StatementAST *statement);
Scope *switchScope(Scope *scope);
@@ -98,9 +99,12 @@ protected:
ExpressionAST *expression,
StatementAST *statement,
Block *&symbol);
+ FullySpecifiedType checkCompoundStmt(CompoundStatementAST *stmt);
+
private:
StatementAST *_statement;
Scope *_scope;
+ FullySpecifiedType _exprType;
};
} // end of namespace CPlusPlus
diff --git a/src/shared/cplusplus/Parser.cpp b/src/shared/cplusplus/Parser.cpp
index 84a92a186a..864ec779ab 100644
--- a/src/shared/cplusplus/Parser.cpp
+++ b/src/shared/cplusplus/Parser.cpp
@@ -3446,6 +3446,14 @@ bool Parser::parsePrimaryExpression(ExpressionAST *&node)
ast->compoundStatement = statement->asCompoundStatement();
match(T_RPAREN, &ast->rparen_token);
node = ast;
+ if (ast->compoundStatement && ast->compoundStatement->statement_list) {
+ // check that the last statement is an expression-statement
+ StatementAST *lastStmt = ast->compoundStatement->statement_list->lastValue();
+ if (!lastStmt || ! ast->asExpressionStatement())
+ _translationUnit->error(cursor(),
+ "expected an expression statement before token `%s'",
+ tok().spell());
+ }
return true;
} else {
return parseNestedExpression(node);
diff --git a/src/shared/cplusplus/Semantic.cpp b/src/shared/cplusplus/Semantic.cpp
index 57ac5fe99f..d8d6d6617e 100644
--- a/src/shared/cplusplus/Semantic.cpp
+++ b/src/shared/cplusplus/Semantic.cpp
@@ -151,8 +151,8 @@ void Semantic::check(ObjCMessageArgumentDeclarationAST *arg, Scope *scope)
FullySpecifiedType Semantic::check(ExpressionAST *expression, Scope *scope)
{ return d->checkExpression->check(expression, scope); }
-void Semantic::check(StatementAST *statement, Scope *scope)
-{ d->checkStatement->check(statement, scope); }
+FullySpecifiedType Semantic::check(StatementAST *statement, Scope *scope)
+{ return d->checkStatement->check(statement, scope); }
const Name *Semantic::check(NameAST *name, Scope *scope)
{ return d->checkName->check(name, scope); }
diff --git a/src/shared/cplusplus/Semantic.h b/src/shared/cplusplus/Semantic.h
index 98c6450520..60f82b892e 100644
--- a/src/shared/cplusplus/Semantic.h
+++ b/src/shared/cplusplus/Semantic.h
@@ -81,7 +81,7 @@ public:
void check(DeclarationAST *declaration, Scope *scope, TemplateParameters *templateParameters = 0);
- void check(StatementAST *statement, Scope *scope);
+ FullySpecifiedType check(StatementAST *statement, Scope *scope);
const Name *check(NameAST *name, Scope *scope);