Skip to content
Snippets Groups Projects
Commit e421d321 authored by Roberto Raggi's avatar Roberto Raggi
Browse files

Postpone the parsing of function definitions.

parent aff7d3fd
No related branches found
No related tags found
No related merge requests found
...@@ -85,6 +85,13 @@ void CheckDeclaration::check(DeclarationAST *declaration, ...@@ -85,6 +85,13 @@ void CheckDeclaration::check(DeclarationAST *declaration,
(void) switchScope(previousScope); (void) switchScope(previousScope);
} }
void CheckDeclaration::check(CtorInitializerAST *ast, Scope *scope)
{
Scope *previousScope = switchScope(scope);
accept(ast);
(void) switchScope(previousScope);
}
DeclarationAST *CheckDeclaration::switchDeclaration(DeclarationAST *declaration) DeclarationAST *CheckDeclaration::switchDeclaration(DeclarationAST *declaration)
{ {
DeclarationAST *previousDeclaration = _declaration; DeclarationAST *previousDeclaration = _declaration;
...@@ -352,29 +359,8 @@ bool CheckDeclaration::visit(FunctionDefinitionAST *ast) ...@@ -352,29 +359,8 @@ bool CheckDeclaration::visit(FunctionDefinitionAST *ast)
ast->symbol = fun; ast->symbol = fun;
_scope->enterSymbol(fun); _scope->enterSymbol(fun);
if (! semantic()->skipFunctionBodies()) { if (! semantic()->skipFunctionBodies())
if (ast->ctor_initializer) { semantic()->checkFunctionDefinition(ast);
bool looksLikeCtor = false;
if (ty.isValid() || ! fun->identity())
looksLikeCtor = false;
else if (fun->identity()->isNameId() || fun->identity()->isTemplateNameId())
looksLikeCtor = true;
if (! looksLikeCtor) {
translationUnit()->error(ast->ctor_initializer->firstToken(),
"only constructors take base initializers");
}
accept(ast->ctor_initializer);
}
const int previousVisibility = semantic()->switchVisibility(Symbol::Public);
const int previousMethodKey = semantic()->switchMethodKey(Function::NormalMethod);
semantic()->check(ast->function_body, fun->members());
semantic()->switchMethodKey(previousMethodKey);
semantic()->switchVisibility(previousVisibility);
}
return false; return false;
} }
......
...@@ -62,6 +62,7 @@ public: ...@@ -62,6 +62,7 @@ public:
virtual ~CheckDeclaration(); virtual ~CheckDeclaration();
void check(DeclarationAST *declaration, Scope *scope, TemplateParameters *templateParameters); void check(DeclarationAST *declaration, Scope *scope, TemplateParameters *templateParameters);
void check(CtorInitializerAST *ast, Scope *scope);
protected: protected:
DeclarationAST *switchDeclaration(DeclarationAST *declaration); DeclarationAST *switchDeclaration(DeclarationAST *declaration);
......
...@@ -337,8 +337,13 @@ bool CheckSpecifier::visit(ClassSpecifierAST *ast) ...@@ -337,8 +337,13 @@ bool CheckSpecifier::visit(ClassSpecifierAST *ast)
klass->setClassKey(Class::UnionKey); klass->setClassKey(Class::UnionKey);
klass->setVisibility(semantic()->currentVisibility()); klass->setVisibility(semantic()->currentVisibility());
_scope->enterSymbol(klass); _scope->enterSymbol(klass);
ClassSpecifierAST *previousClassSpecifier = semantic()->switchDeclaringClass(ast);
_fullySpecifiedType.setType(klass); _fullySpecifiedType.setType(klass);
accept(ast->attribute_list); accept(ast->attribute_list);
if (_fullySpecifiedType.isDeprecated()) if (_fullySpecifiedType.isDeprecated())
klass->setDeprecated(true); klass->setDeprecated(true);
...@@ -377,6 +382,8 @@ bool CheckSpecifier::visit(ClassSpecifierAST *ast) ...@@ -377,6 +382,8 @@ bool CheckSpecifier::visit(ClassSpecifierAST *ast)
(void) semantic()->switchMethodKey(previousMethodKey); (void) semantic()->switchMethodKey(previousMethodKey);
(void) semantic()->switchVisibility(previousVisibility); (void) semantic()->switchVisibility(previousVisibility);
(void) semantic()->switchDeclaringClass(previousClassSpecifier);
return false; return false;
} }
......
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
#include "Scope.h" #include "Scope.h"
#include "Symbols.h" #include "Symbols.h"
#include "Token.h" #include "Token.h"
#include "AST.h"
#include "CheckSpecifier.h" #include "CheckSpecifier.h"
#include "CheckDeclaration.h" #include "CheckDeclaration.h"
#include "CheckDeclarator.h" #include "CheckDeclarator.h"
...@@ -61,6 +62,20 @@ ...@@ -61,6 +62,20 @@
using namespace CPlusPlus; using namespace CPlusPlus;
SemanticClient::SemanticClient(Semantic *semantic)
: _semantic(semantic)
{
}
SemanticClient::~SemanticClient()
{
}
Semantic *SemanticClient::semantic() const
{
return _semantic;
}
class Semantic::Data class Semantic::Data
{ {
public: public:
...@@ -68,10 +83,12 @@ public: ...@@ -68,10 +83,12 @@ public:
: semantic(semantic), : semantic(semantic),
translationUnit(translationUnit), translationUnit(translationUnit),
control(translationUnit->control()), control(translationUnit->control()),
semanticClient(0),
skipFunctionBodies(false), skipFunctionBodies(false),
visibility(Symbol::Public), visibility(Symbol::Public),
ojbcVisibility(Symbol::Protected), ojbcVisibility(Symbol::Protected),
methodKey(Function::NormalMethod), methodKey(Function::NormalMethod),
declaringClass(0),
checkSpecifier(0), checkSpecifier(0),
checkDeclaration(0), checkDeclaration(0),
checkDeclarator(0), checkDeclarator(0),
...@@ -93,16 +110,19 @@ public: ...@@ -93,16 +110,19 @@ public:
Semantic *semantic; Semantic *semantic;
TranslationUnit *translationUnit; TranslationUnit *translationUnit;
Control *control; Control *control;
SemanticClient *semanticClient;
bool skipFunctionBodies; bool skipFunctionBodies;
int visibility; int visibility;
int ojbcVisibility; int ojbcVisibility;
int methodKey; int methodKey;
ClassSpecifierAST *declaringClass;
CheckSpecifier *checkSpecifier; CheckSpecifier *checkSpecifier;
CheckDeclaration *checkDeclaration; CheckDeclaration *checkDeclaration;
CheckDeclarator *checkDeclarator; CheckDeclarator *checkDeclarator;
CheckExpression *checkExpression; CheckExpression *checkExpression;
CheckStatement *checkStatement; CheckStatement *checkStatement;
CheckName *checkName; CheckName *checkName;
std::vector<FunctionDefinitionAST *> functionsToProcess;
}; };
Semantic::Semantic(TranslationUnit *translationUnit) Semantic::Semantic(TranslationUnit *translationUnit)
...@@ -119,6 +139,12 @@ Semantic::Semantic(TranslationUnit *translationUnit) ...@@ -119,6 +139,12 @@ Semantic::Semantic(TranslationUnit *translationUnit)
Semantic::~Semantic() Semantic::~Semantic()
{ delete d; } { delete d; }
SemanticClient *Semantic::semanticClient() const
{ return d->semanticClient; }
void Semantic::setSemanticClient(SemanticClient *client)
{ d->semanticClient = client; }
TranslationUnit *Semantic::translationUnit() const TranslationUnit *Semantic::translationUnit() const
{ return d->translationUnit; } { return d->translationUnit; }
...@@ -162,6 +188,27 @@ const Name *Semantic::check(NameAST *name, Scope *scope) ...@@ -162,6 +188,27 @@ const Name *Semantic::check(NameAST *name, Scope *scope)
const Name *Semantic::check(NestedNameSpecifierListAST *name, Scope *scope) const Name *Semantic::check(NestedNameSpecifierListAST *name, Scope *scope)
{ return d->checkName->check(name, scope); } { return d->checkName->check(name, scope); }
void Semantic::checkFunctionDefinition(FunctionDefinitionAST *ast)
{
if (d->declaringClass != 0)
d->functionsToProcess.push_back(ast);
else
finishFunctionDefinition(ast);
}
void Semantic::finishFunctionDefinition(FunctionDefinitionAST *ast)
{
const int previousVisibility = switchVisibility(Symbol::Public);
const int previousMethodKey = switchMethodKey(Function::NormalMethod);
Function *fun = ast->symbol;
d->checkDeclaration->check(ast->ctor_initializer, fun->scope());
check(ast->function_body, fun->members());
switchMethodKey(previousMethodKey);
switchVisibility(previousVisibility);
}
bool Semantic::skipFunctionBodies() const bool Semantic::skipFunctionBodies() const
{ return d->skipFunctionBodies; } { return d->skipFunctionBodies; }
...@@ -198,6 +245,25 @@ int Semantic::switchMethodKey(int methodKey) ...@@ -198,6 +245,25 @@ int Semantic::switchMethodKey(int methodKey)
return previousMethodKey; return previousMethodKey;
} }
ClassSpecifierAST *Semantic::declatingClass() const
{ return d->declaringClass; }
ClassSpecifierAST *Semantic::switchDeclaringClass(ClassSpecifierAST *ast)
{
ClassSpecifierAST *previous = d->declaringClass;
d->declaringClass = ast;
if (! ast && ! d->functionsToProcess.empty()) {
const std::vector<FunctionDefinitionAST *> todo = d->functionsToProcess;
d->functionsToProcess.clear();
for (std::vector<FunctionDefinitionAST *>::const_iterator it = todo.begin(); it != todo.end(); ++it)
finishFunctionDefinition(*it);
}
return previous;
}
int Semantic::visibilityForAccessSpecifier(int tokenKind) const int Semantic::visibilityForAccessSpecifier(int tokenKind) const
{ {
switch (tokenKind) { switch (tokenKind) {
......
...@@ -55,6 +55,22 @@ ...@@ -55,6 +55,22 @@
namespace CPlusPlus { namespace CPlusPlus {
class CPLUSPLUS_EXPORT SemanticClient
{
SemanticClient(const SemanticClient &other);
void operator = (const SemanticClient &other);
public:
SemanticClient(Semantic *semantic);
virtual ~SemanticClient();
Semantic *semantic() const;
private:
Semantic *_semantic;
};
class CPLUSPLUS_EXPORT Semantic class CPLUSPLUS_EXPORT Semantic
{ {
Semantic(const Semantic &other); Semantic(const Semantic &other);
...@@ -67,6 +83,9 @@ public: ...@@ -67,6 +83,9 @@ public:
TranslationUnit *translationUnit() const; TranslationUnit *translationUnit() const;
Control *control() const; Control *control() const;
SemanticClient *semanticClient() const;
void setSemanticClient(SemanticClient *client);
FullySpecifiedType check(SpecifierListAST *specifier, Scope *scope, FullySpecifiedType check(SpecifierListAST *specifier, Scope *scope,
const FullySpecifiedType &type = FullySpecifiedType()); const FullySpecifiedType &type = FullySpecifiedType());
...@@ -93,6 +112,9 @@ public: ...@@ -93,6 +112,9 @@ public:
void check(ObjCMessageArgumentDeclarationAST *arg, Scope *scope); void check(ObjCMessageArgumentDeclarationAST *arg, Scope *scope);
void checkFunctionDefinition(FunctionDefinitionAST *ast);
void finishFunctionDefinition(FunctionDefinitionAST *ast);
bool skipFunctionBodies() const; bool skipFunctionBodies() const;
void setSkipFunctionBodies(bool skipFunctionBodies); void setSkipFunctionBodies(bool skipFunctionBodies);
...@@ -105,6 +127,9 @@ public: ...@@ -105,6 +127,9 @@ public:
int currentMethodKey() const; int currentMethodKey() const;
int switchMethodKey(int methodKey); int switchMethodKey(int methodKey);
ClassSpecifierAST *declatingClass() const;
ClassSpecifierAST *switchDeclaringClass(ClassSpecifierAST *ast);
int visibilityForClassKey(int tokenKind) const; int visibilityForClassKey(int tokenKind) const;
int visibilityForAccessSpecifier(int tokenKind) const; int visibilityForAccessSpecifier(int tokenKind) const;
int visibilityForObjCAccessSpecifier(int tokenKind) const; int visibilityForObjCAccessSpecifier(int tokenKind) const;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment