diff --git a/C/sema/Compilation.cpp b/C/sema/Compilation.cpp index 3bca2ca77..336dc6b24 100644 --- a/C/sema/Compilation.cpp +++ b/C/sema/Compilation.cpp @@ -182,10 +182,10 @@ void Compilation::computeSemanticModel(const SyntaxTree* tree) { PSY_ASSERT_2(P->isDirty_.count(tree), return); if (P->isDirty_[tree]) { - bindDeclarations(); - canonicalizerTypes(); - resolveTypedefNameTypes(); - checkTypes(); + bindDeclarations(tree); + canonicalizeTypes(tree); + resolveTypedefNameTypes(tree); + checkTypes(tree); P->isDirty_[tree] = false; } } @@ -244,6 +244,14 @@ const BasicType* Compilation::canonicalBasicType(BasicTypeKind basicTyK) const return P->tyIntU_.get(); } +void Compilation::bindDeclarations(const SyntaxTree* tree) const +{ + PSY_ASSERT_2(P->semaModels_.count(tree), return); + auto model = P->semaModels_[tree].get(); + DeclarationBinder binder(model, tree); + binder.bindDeclarations(); +} + void Compilation::bindDeclarations() const { for (const auto& p : P->semaModels_) { @@ -252,7 +260,15 @@ void Compilation::bindDeclarations() const } } -void Compilation::canonicalizerTypes() const +void Compilation::canonicalizeTypes(const SyntaxTree* tree) const +{ + PSY_ASSERT_2(P->semaModels_.count(tree), return); + auto model = P->semaModels_[tree].get(); + TypeCanonicalizer canonicalizer(model, tree); + canonicalizer.canonicalizeTypes(); +} + +void Compilation::canonicalizeTypes() const { for (const auto& p : P->semaModels_) { TypeCanonicalizer canonicalizer(p.second.get(), p.first); @@ -261,6 +277,14 @@ void Compilation::canonicalizerTypes() const } +void Compilation::resolveTypedefNameTypes(const SyntaxTree* tree) const +{ + PSY_ASSERT_2(P->semaModels_.count(tree), return); + auto model = P->semaModels_[tree].get(); + TypedefNameTypeResolver resolver(model, tree); + resolver.resolveTypedefNameTypes(); +} + void Compilation::resolveTypedefNameTypes() const { for (const auto& p : P->semaModels_) { @@ -269,6 +293,14 @@ void Compilation::resolveTypedefNameTypes() const } } +void Compilation::checkTypes(const SyntaxTree* tree) const +{ + PSY_ASSERT_2(P->semaModels_.count(tree), return); + auto model = P->semaModels_[tree].get(); + TypeChecker checker(model, tree); + checker.checkTypes(); +} + void Compilation::checkTypes() const { for (const auto& p : P->semaModels_) { diff --git a/C/sema/Compilation.h b/C/sema/Compilation.h index ffeae8cc6..19ddcc6e2 100644 --- a/C/sema/Compilation.h +++ b/C/sema/Compilation.h @@ -130,9 +130,13 @@ class PSY_C_API Compilation ProgramSymbol* program(); + void bindDeclarations(const SyntaxTree* tree) const; void bindDeclarations() const; - void canonicalizerTypes() const; + void canonicalizeTypes(const SyntaxTree* tree) const; + void canonicalizeTypes() const; + void resolveTypedefNameTypes(const SyntaxTree* tree) const; void resolveTypedefNameTypes() const; + void checkTypes(const SyntaxTree* tree) const; void checkTypes() const; private: diff --git a/C/sema/DeclarationBinder.cpp b/C/sema/DeclarationBinder.cpp index 04cb65eb3..4c6d9a21d 100644 --- a/C/sema/DeclarationBinder.cpp +++ b/C/sema/DeclarationBinder.cpp @@ -124,12 +124,13 @@ DeclarationSymbol* DeclarationBinder::popDeclaration() } -void DeclarationBinder::finishDeclaration() +DeclarationSymbol* DeclarationBinder::finishDeclaration() { auto decl = popDeclaration(); - PSY_ASSERT_2(decl, return); - SCOPE_AT_TOP(auto scope, ); + PSY_ASSERT_2(decl, return nullptr); + SCOPE_AT_TOP(auto scope, nullptr); scope->addDeclaration(decl->asDeclaration()); + return decl; } void DeclarationBinder::pushType(Type* ty) diff --git a/C/sema/DeclarationBinder.h b/C/sema/DeclarationBinder.h index b9d63001d..b14c64a89 100644 --- a/C/sema/DeclarationBinder.h +++ b/C/sema/DeclarationBinder.h @@ -81,8 +81,8 @@ class PSY_C_INTERNAL_API DeclarationBinder final : protected SyntaxVisitor void bindAnonymousFieldDeclaration(const SyntaxNode* node); void nameDeclarationAtTop(const Identifier* name); void typeDeclarationAtTopWithTypeAtTop(); - void finishDeclaration(); void handleNonTypedefDeclarator(const DeclaratorSyntax* node); + DeclarationSymbol* finishDeclaration(); using TypeStack = std::stack; TypeStack tys_; diff --git a/C/sema/DeclarationBinder_End.cpp b/C/sema/DeclarationBinder_End.cpp index 288886c35..47c23a24b 100644 --- a/C/sema/DeclarationBinder_End.cpp +++ b/C/sema/DeclarationBinder_End.cpp @@ -99,7 +99,10 @@ SyntaxVisitor::Action DeclarationBinder::visitParameterDeclaration_AtEnd( SyntaxVisitor::Action DeclarationBinder::visitFunctionDefinition_AtEnd( const FunctionDefinitionSyntax* node) { - finishDeclaration(); + auto decl = finishDeclaration(); + PSY_ASSERT_2(decl->kind() == SymbolKind::FunctionDeclaration, return Action::Quit); + auto funcDecl = decl->asFunctionDeclaration(); + funcDecl->setIsDefinition(true); popType(); /* diff --git a/C/symbols/Declaration_Function.cpp b/C/symbols/Declaration_Function.cpp index 8bf55a727..eae8f4568 100644 --- a/C/symbols/Declaration_Function.cpp +++ b/C/symbols/Declaration_Function.cpp @@ -42,7 +42,9 @@ struct FunctionDeclarationSymbol::FunctionImpl : DeclarationImpl NameSpace::OrdinaryIdentifiers) , name_(nullptr) , ty_(nullptr) - {} + { + F_.isDef_ = 0; + } const Identifier* name_; const Type* ty_; @@ -83,6 +85,16 @@ void FunctionDeclarationSymbol::setType(const Type* ty) P_CAST->ty_ = ty; } +bool FunctionDeclarationSymbol::isDefinition() const +{ + return P_CAST->F_.isDef_; +} + +void FunctionDeclarationSymbol::setIsDefinition(bool isDef) +{ + P_CAST->F_.isDef_ = static_cast(isDef); +} + namespace psy { namespace C { diff --git a/C/symbols/Declaration_Function.h b/C/symbols/Declaration_Function.h index 64e1ad278..697f1339a 100644 --- a/C/symbols/Declaration_Function.h +++ b/C/symbols/Declaration_Function.h @@ -60,6 +60,11 @@ class PSY_C_API FunctionDeclarationSymbol final */ const Type* type() const override; + /** + * Whether \c this FunctionDeclarationSymbol is of a definition. + */ + bool isDefinition() const; + PSY_INTERNAL: PSY_GRANT_INTERNAL_ACCESS(DeclarationBinder); PSY_GRANT_INTERNAL_ACCESS(TypeChecker); @@ -73,6 +78,7 @@ class PSY_C_API FunctionDeclarationSymbol final virtual void setName(const Identifier* name) override; virtual void setType(const Type* ty) override; Type* type(); + void setIsDefinition(bool isDef); }; PSY_C_API std::ostream& operator<<(std::ostream& os, const FunctionDeclarationSymbol* func); diff --git a/C/symbols/Symbol_Declaration.cpp b/C/symbols/Symbol_Declaration.cpp index 8e1ea0a2b..bcda967e8 100644 --- a/C/symbols/Symbol_Declaration.cpp +++ b/C/symbols/Symbol_Declaration.cpp @@ -49,6 +49,11 @@ const NameSpace DeclarationSymbol::nameSpace() const return NameSpace(P->F_.ns_); } +const SyntaxTree *DeclarationSymbol::declaringTree() const +{ + return P_CAST->tree_; +} + DeclarationCategory DeclarationSymbol::category() const { switch (kind()) { diff --git a/C/symbols/Symbol_Declaration.h b/C/symbols/Symbol_Declaration.h index 302086ecf..2b9fe7951 100644 --- a/C/symbols/Symbol_Declaration.h +++ b/C/symbols/Symbol_Declaration.h @@ -68,6 +68,11 @@ class PSY_C_API DeclarationSymbol : public Symbol */ const NameSpace nameSpace() const; + /** + * The declaring SyntaxTree of \c this DeclarationSymbol. + */ + const SyntaxTree* declaringTree() const; + protected: DECL_PIMPL_SUB(Declaration); DeclarationSymbol(DeclarationImpl* p); diff --git a/C/symbols/Symbol__IMPL__.inc b/C/symbols/Symbol__IMPL__.inc index 95c4c4cf5..aadd127df 100644 --- a/C/symbols/Symbol__IMPL__.inc +++ b/C/symbols/Symbol__IMPL__.inc @@ -40,9 +40,12 @@ struct Symbol::SymbolImpl { std::uint32_t symK_ : 8; - // DeclarationSymbol. + // DeclarationSymbol std::uint32_t ns_ : 2; std::uint32_t static_ : 1; + + // FunctionDeclarationSymbol + std::uint32_t isDef_ : 1; }; union { diff --git a/C/tests/TestSuite_Internals.cpp b/C/tests/TestSuite_Internals.cpp index b6a1095f5..9bcc2bc21 100644 --- a/C/tests/TestSuite_Internals.cpp +++ b/C/tests/TestSuite_Internals.cpp @@ -932,7 +932,7 @@ void InternalsTestSuite::canonicalizerAndResolveTypes(std::string text, Expectat auto compilation = Compilation::create(tree->filePath()); compilation->addSyntaxTree(std::unique_ptr(tree)); compilation->bindDeclarations(); - compilation->canonicalizerTypes(); + compilation->canonicalizeTypes(); compilation->resolveTypedefNameTypes(); auto semaModel = compilation->semanticModel(tree); checkSemanticModel(tree, semaModel, X); @@ -944,7 +944,7 @@ void InternalsTestSuite::checkTypes(std::string text, Expectation X) auto compilation = Compilation::create(tree->filePath()); compilation->addSyntaxTree(std::unique_ptr(tree)); compilation->bindDeclarations(); - compilation->canonicalizerTypes(); + compilation->canonicalizeTypes(); compilation->resolveTypedefNameTypes(); compilation->checkTypes(); auto semaModel = compilation->semanticModel(tree);