Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion C/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 2.8)
cmake_minimum_required(VERSION 3.5)

project(cfe)

Expand Down
22 changes: 17 additions & 5 deletions C/sema/DiagnosticsReporter_TypeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,12 @@ const std::string TypeChecker::DiagnosticsReporter::ID_of_ExpectedExpression = "
const std::string TypeChecker::DiagnosticsReporter::ID_of_UnknownMemberOfTag = "TypeChecker-011";
const std::string TypeChecker::DiagnosticsReporter::ID_of_IncompatibleTypesInAssignment = "TypeChecker-012";
const std::string TypeChecker::DiagnosticsReporter::ID_of_IncompatibleTypesInArgumentToParameterAssignment = "TypeChecker-013";
const std::string TypeChecker::DiagnosticsReporter::ID_of_CannotAssignToExpressionOfConstQualifiedType = "TypeChecker-014";
const std::string TypeChecker::DiagnosticsReporter::ID_of_CannotAssignToExpressionOfArrayType = "TypeChecker-015";
const std::string TypeChecker::DiagnosticsReporter::ID_of_ConversionBetweenIntegerAndPointerTypesInAssignment = "TypeChecker-016";
const std::string TypeChecker::DiagnosticsReporter::ID_of_TooFewArgumentsToFunctionCall = "TypeChecker-017";
const std::string TypeChecker::DiagnosticsReporter::ID_of_TooManyArgumentsToFunctionCall = "TypeChecker-018";
const std::string TypeChecker::DiagnosticsReporter::ID_of_IncompatibleTypesInInitialization = "TypeChecker-014";
const std::string TypeChecker::DiagnosticsReporter::ID_of_CannotAssignToExpressionOfConstQualifiedType = "TypeChecker-015";
const std::string TypeChecker::DiagnosticsReporter::ID_of_CannotAssignToExpressionOfArrayType = "TypeChecker-016";
const std::string TypeChecker::DiagnosticsReporter::ID_of_ConversionBetweenIntegerAndPointerTypesInAssignment = "TypeChecker-017";
const std::string TypeChecker::DiagnosticsReporter::ID_of_TooFewArgumentsToFunctionCall = "TypeChecker-018";
const std::string TypeChecker::DiagnosticsReporter::ID_of_TooManyArgumentsToFunctionCall = "TypeChecker-019";

void TypeChecker::DiagnosticsReporter::diagnose(DiagnosticDescriptor&& desc, SyntaxToken tk)
{
Expand Down Expand Up @@ -194,6 +195,17 @@ void TypeChecker::DiagnosticsReporter::IncompatibleTypesInArgumentToParameterAss
tk);
}

void TypeChecker::DiagnosticsReporter::IncompatibleTypesInInitialization(SyntaxToken tk)
{
diagnose(DiagnosticDescriptor(
ID_of_IncompatibleTypesInInitialization,
"[[incompatible types in initialization]]",
"incompatible types in initialization",
DiagnosticSeverity::Error,
DiagnosticCategory::TypeChecking),
tk);
}

void TypeChecker::DiagnosticsReporter::CannotAssignToExpressionOfConstQualifiedType(SyntaxToken tk)
{
diagnose(DiagnosticDescriptor(
Expand Down
52 changes: 47 additions & 5 deletions C/sema/TypeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include "syntax/SyntaxTree.h"

#include "parser/Unparser.h"
#include "sema/Scope.h"
#include "sema/PlatformOptions.h"
#include "sema/Compilation.h"
Expand Down Expand Up @@ -651,7 +652,7 @@ bool TypeChecker::isNULLPointerConstant(const SyntaxNode* node)
void TypeChecker::createTypeInfo(
const SyntaxNode* node,
const Type* ty,
TypeInfo::Origin tyOrig)
TypeInfo::Origin orig)
{
auto undergoneConv = TypeInfo::UndergoneConversion::No;
if (ty->kind() == TypeKind::Function) {
Expand All @@ -660,17 +661,17 @@ void TypeChecker::createTypeInfo(
undergoneConv = TypeInfo::UndergoneConversion::Yes;
}
ty_ = ty;
TypeInfo tyInfo(ty_, tyOrig, undergoneConv);
TypeInfo tyInfo(ty_, orig, undergoneConv);
semaModel_->setTypeInfoOf(node, std::move(tyInfo));
}

SyntaxVisitor::Action TypeChecker::typeChecked(
const ExpressionSyntax* node,
const Type* ty,
TypeInfo::Origin tyOrig)
TypeInfo::Origin orig)
{
PSY_ASSERT_2(ty, return Action::Quit);
createTypeInfo(node, ty, tyOrig);
createTypeInfo(node, ty, orig);
return Action::Skip;
}

Expand All @@ -690,7 +691,26 @@ SyntaxVisitor::Action TypeChecker::typeCheckError(const SyntaxNode* node)
SyntaxVisitor::Action TypeChecker::visitVariableAndOrFunctionDeclaration(
const VariableAndOrFunctionDeclarationSyntax* node)
{
return Action::Visit;
for (auto iter = node->declarators(); iter; iter = iter->next) {
auto decltor = iter->value;
auto decl = semaModel_->declarationBy(decltor);
PSY_ASSERT_2(decl, continue);
switch (decl->category()) {
case DeclarationCategory::Member:
case DeclarationCategory::Function:
case DeclarationCategory::Object: {
auto typeableDecl = MIXIN_TypeableDeclarationSymbol::from(decl);
PSY_ASSERT_2(typeableDecl, return Action::Quit);
ty_ = typeableDecl->type();
break;
}
case DeclarationCategory::Type:
return typeCheckError(node);
}
VISIT(decltor);
}

return Action::Skip;
}

SyntaxVisitor::Action TypeChecker::visitFunctionDefinition(
Expand All @@ -699,11 +719,33 @@ SyntaxVisitor::Action TypeChecker::visitFunctionDefinition(
return Action::Visit;
}

/* Specifiers */

SyntaxVisitor::Action TypeChecker::visitExtGNU_Attribute(const ExtGNU_AttributeSyntax*)
{
return Action::Quit;
}

/* Initializers */

SyntaxVisitor::Action TypeChecker::visitExpressionInitializer(
const ExpressionInitializerSyntax* node)
{
auto leftTy = unqualifiedAndResolved(ty_);
VISIT(node->expression());
auto rightTy = unqualifiedAndResolved(ty_);
if (!isTypeAssignableFromOtherType(leftTy, rightTy, node->expression()))
diagReporter_.IncompatibleTypesInInitialization(node->expression()->firstToken());

return Action::Quit;
}

SyntaxVisitor::Action TypeChecker::visitBraceEnclosedInitializer(
const BraceEnclosedInitializerSyntax* node) {
// TODO
return Action::Quit;
}

//-------------//
// Expressions //
//-------------//
Expand Down
6 changes: 6 additions & 0 deletions C/sema/TypeChecker.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class PSY_C_INTERNAL_API TypeChecker final : protected SyntaxVisitor
void UnknownMemberOfTag(SyntaxToken tk);
void IncompatibleTypesInAssignment(SyntaxToken tk);
void IncompatibleTypesInArgumentToParameterAssignment(SyntaxToken tk);
void IncompatibleTypesInInitialization(SyntaxToken tk);
void CannotAssignToExpressionOfConstQualifiedType(SyntaxToken tk);
void CannotAssignToExpressionOfArrayType(SyntaxToken tk);
void ConversionBetweenIntegerAndPointerTypesInAssignment(SyntaxToken tk);
Expand All @@ -112,6 +113,7 @@ class PSY_C_INTERNAL_API TypeChecker final : protected SyntaxVisitor
static const std::string ID_of_UnknownMemberOfTag;
static const std::string ID_of_IncompatibleTypesInAssignment;
static const std::string ID_of_IncompatibleTypesInArgumentToParameterAssignment;
static const std::string ID_of_IncompatibleTypesInInitialization;
static const std::string ID_of_CannotAssignToExpressionOfConstQualifiedType;
static const std::string ID_of_CannotAssignToExpressionOfArrayType;
static const std::string ID_of_ConversionBetweenIntegerAndPointerTypesInAssignment;
Expand All @@ -130,6 +132,10 @@ class PSY_C_INTERNAL_API TypeChecker final : protected SyntaxVisitor
/* Specifiers */
virtual Action visitExtGNU_Attribute(const ExtGNU_AttributeSyntax*) override;

/* Initializers */
virtual Action visitExpressionInitializer(const ExpressionInitializerSyntax*) override;
virtual Action visitBraceEnclosedInitializer(const BraceEnclosedInitializerSyntax*) override;

//-------------//
// Expressions //
//-------------//
Expand Down
2 changes: 1 addition & 1 deletion C/stdlib-support/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 2.8)
cmake_minimum_required(VERSION 3.5)

project(psychecstd)

Expand Down
173 changes: 173 additions & 0 deletions C/tests/TypeCheckerTester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4472,3 +4472,176 @@ void TypeCheckerTester::case0756(){}
void TypeCheckerTester::case0757(){}
void TypeCheckerTester::case0758(){}
void TypeCheckerTester::case0759(){}

void TypeCheckerTester::case0800()
{
auto s = R"(
void _ ()
{
int x ;
int y = x;
}
)";

checkTypes(s, Expectation());
}

void TypeCheckerTester::case0801()
{
auto s = R"(
void _ ()
{
int x ;
long y = x;
}
)";

checkTypes(s, Expectation());
}

void TypeCheckerTester::case0802()
{
auto s = R"(
void _ ()
{
int x ;
int * y = x;
}
)";

checkTypes(
s,
Expectation()
.diagnostic(
Expectation::ErrorOrWarn::Error,
TypeChecker::DiagnosticsReporter::ID_of_IncompatibleTypesInInitialization));
}

void TypeCheckerTester::case0803()
{
auto s = R"(
void _ ()
{
long x ;
int * y = x;
}
)";

checkTypes(
s,
Expectation()
.diagnostic(
Expectation::ErrorOrWarn::Error,
TypeChecker::DiagnosticsReporter::ID_of_IncompatibleTypesInInitialization));
}

void TypeCheckerTester::case0804()
{
auto s = R"(
struct s { int m ; } v ;
void _ ()
{
int x = v ;
}
)";

checkTypes(
s,
Expectation()
.diagnostic(
Expectation::ErrorOrWarn::Error,
TypeChecker::DiagnosticsReporter::ID_of_IncompatibleTypesInInitialization));
}

void TypeCheckerTester::case0805()
{
auto s = R"(
struct s { int m ; } ;
void _ ()
{
int x ;
struct s y = x ;
}
)";

checkTypes(
s,
Expectation()
.diagnostic(
Expectation::ErrorOrWarn::Error,
TypeChecker::DiagnosticsReporter::ID_of_IncompatibleTypesInInitialization));
}

void TypeCheckerTester::case0806()
{
auto s = R"(
struct s { int m ; } x ;
void _ ()
{
struct s y = x ;
}
)";

checkTypes(s, Expectation());
}

void TypeCheckerTester::case0807()
{
auto s = R"(
typedef struct a {
struct b {
struct c {
const int m ;
} xx ;
} yy;
} t;
void _ ()
{
t x = { { { 42 } } };
}
)";

checkTypes(s, Expectation());
}

void TypeCheckerTester::case0808()
{
auto s = R"(
typedef struct a {
struct b {
struct c {
int m ;
} xx ;
} yy;
} t;
void _ ()
{
t x = { { { 42 } } };
}
)";

checkTypes(s, Expectation());
}

void TypeCheckerTester::case0809(){}
void TypeCheckerTester::case0810(){}
void TypeCheckerTester::case0811(){}
void TypeCheckerTester::case0812(){}
void TypeCheckerTester::case0813(){}
void TypeCheckerTester::case0814(){}
void TypeCheckerTester::case0815(){}
void TypeCheckerTester::case0816(){}
void TypeCheckerTester::case0817(){}
void TypeCheckerTester::case0818(){}
void TypeCheckerTester::case0819(){}
void TypeCheckerTester::case0820(){}
void TypeCheckerTester::case0821(){}
void TypeCheckerTester::case0822(){}
void TypeCheckerTester::case0823(){}
void TypeCheckerTester::case0824(){}
void TypeCheckerTester::case0825(){}
void TypeCheckerTester::case0826(){}
void TypeCheckerTester::case0827(){}
void TypeCheckerTester::case0828(){}
void TypeCheckerTester::case0829(){}
void TypeCheckerTester::case0830(){}
Loading