Diff of /cmajor++/Cm/Cm.Core/ClassFun.cpp [r367] .. [r368]  Maximize  Restore

Switch to side-by-side view

--- a/cmajor++/Cm/Cm.Core/ClassFun.cpp
+++ b/cmajor++/Cm/Cm.Core/ClassFun.cpp
@@ -34,8 +34,8 @@
     if (useThisVariable)
     {
         LocalVariablePtr thisVar(new ThisVariable(classType->Pos(), classType->EnclosingScope(), classType->FileScope(), classType));
-        TypeCheckContext body(TypeCheckExtent::body);
-        thisVar->TypeCheck(body);
+        TypeCheckContext signature(TypeCheckExtent::signature);
+        thisVar->TypeCheck(signature);
         GenResult thisResult = thisVar->Gen(ir, GenFlags::none);
         thisPtr = thisResult.MainObject();
     }
@@ -70,7 +70,7 @@
     {
         return "set vtbl ptr statement";
     }
-    virtual ObjectPtr Clone(CloneContext& context) const { CM_CORE_ASSERT(false); return ObjectPtr(); }
+    virtual ObjectPtr Clone(CloneContext& context) const { CM_CORE_ASSERT(false, nullptr); return ObjectPtr(); }
     virtual GenResult Gen(Ir& ir, GenFlags flags)
     {
         GenResult result(ir, flags);
@@ -119,24 +119,20 @@
     {
         return "class default construction statement";
     }
-    virtual ObjectPtr Clone(CloneContext& context) const { CM_CORE_ASSERT(false); return ObjectPtr(); }
-    virtual void TypeCheckSignature(TypeCheckContext& context)
-    {
-        Statement::TypeCheckSignature(context);
+    virtual ObjectPtr Clone(CloneContext& context) const { CM_CORE_ASSERT(false, nullptr); return ObjectPtr(); }
+    virtual void TypeCheckBody(TypeCheckContext& context)
+    {
+        Statement::TypeCheckBody(context);
         bool isNothrow = true;
         if (classType.lock()->HasThrowingStaticConstructor()) 
         {
             isNothrow = false;
         }
         FunctionSetPtr ctor = FunctionSetTable::Instance()->GetFunctionSet(GetConstructorFunctionSetName());
-        CM_CORE_ASSERT(ctor);
+        CM_CORE_ASSERT(ctor, GetFullNameFor(GetFunction()));
         ClassTypePtr baseClass = classType.lock()->BaseClass();
         if (baseClass)
         {
-            if (!baseClass->DeferredMembersTypeChecked())
-            {
-                baseClass->TypeCheckDeferredMembers(context);
-            }
             if (!baseClass->DefaultConstructor())
             {
                 throw TypeCheckException(NO_DEFAULT_CTOR, "base class '" + baseClass->Name() + "' has no default constructor to call", Pos());
@@ -145,6 +141,9 @@
             {
                 throw TypeCheckException(CANNOT_CALL_SUPPRESSED_MEMBER_FUNCTION, "cannot call suppressed member function '" + baseConstructorCall->GetFunction()->FullName() + "'", Pos());
             }
+            context.PushExtent(TypeCheckExtent::signature);
+            baseClass->TypeCheckDeferred(context);
+            context.PopExtent();
             baseConstructorCall = FunctionCallPtr(new FunctionCall(baseClass->DefaultConstructor(), Pos(), ownerFunction, nullptr));
             baseConstructorCall->TypeCheck(context);
             if (!baseConstructorCall->IsNothrow())
@@ -165,18 +164,10 @@
             args.push_back(Argument(MakePointerType(memberVar->GetType(), TypeCheckExtent::signature), ArgumentCategory::lvalue));
             ScopeLookupSet scopes;
             scopes.insert(ScopeLookup(memberVar->GetType()->GetScope(), Lookup::this_scope));
-            if (memberVar->GetType()->IsClassType())
-            {
-                ClassTypePtr memVarClassType = std::static_pointer_cast<ClassType>(memberVar->GetType());
-                if (!memVarClassType->DeferredMembersTypeChecked())
-                {
-                    memVarClassType->TypeCheckDeferredMembers(context);
-                }
-            }
+            context.PushExtent(TypeCheckExtent::signature);
+            memberVar->GetType()->TypeCheckDeferred(context);
+            context.PopExtent();
             FunctionCallPtr memberCtor = ctor->ResolveOverload(args, scopes, ResolutionOption::deny_conversions, Pos(), ResolutionFlags::throw_, ownerFunction, nullptr, context);
-            context.PushExtent(TypeCheckExtent::body);
-            memberCtor->TypeCheck(context);
-            context.PopExtent();
             memberConstructorCalls.push_back(memberCtor);
             if (!memberCtor->IsNothrow())
             {
@@ -186,21 +177,6 @@
         if (isNothrow)
         {
             GetFunction()->SetNothrow();
-        }
-    }
-    virtual void CollectExternalObjects(CompilationUnitPtr compilationUnit, ObjectSet& externalObjects, bool deep)
-    {
-        if (ExternalObjectsCollected(compilationUnit, deep)) return;
-        Statement::CollectExternalObjects(compilationUnit, externalObjects, deep);
-        if (baseConstructorCall)
-        {
-            baseConstructorCall->CollectExternalObjects(compilationUnit, externalObjects, deep);
-        }
-        int n = memberConstructorCalls.size();
-        for (int i = 0; i < n; ++i)
-        {
-            FunctionCallPtr memberConstructorCall = memberConstructorCalls[i];
-            memberConstructorCall->CollectExternalObjects(compilationUnit, externalObjects, deep);
         }
     }
     virtual void GenerateDestructionStatements(DestructionStackPtr destructionStack)
@@ -251,25 +227,6 @@
         }
         return result;
     }
-    virtual void CheckIfCanThrow(bool& canThrow, TypeCheckContext& context)
-    {
-        FunctionPtr staticCtor = classType.lock()->StaticConstructor();
-        if (staticCtor)
-        {
-            staticCtor->CheckIfCanThrow(canThrow, context);
-            if (canThrow) return;
-        }
-        if (baseConstructorCall)
-        {
-            baseConstructorCall->CheckIfCanThrow(canThrow, context);
-            if (canThrow) return;
-        }
-        for (FunctionCallPtr memberCall : memberConstructorCalls)
-        {
-            memberCall->CheckIfCanThrow(canThrow, context);
-            if (canThrow) return;
-        }
-    }
 private:
     WeakClassTypePtr classType;
     WeakClassTypePtr baseClassType;
@@ -280,12 +237,12 @@
     Function* ownerFunction;
 };
 
+CompoundStatementPtr MakeEmptyBody(ClassTypePtr classType, ScopePtr scope)
+{
+    return CompoundStatementPtr(new CompoundStatement("body", classType->Pos(), scope, classType->FileScope(), "", true));
+}
+
 typedef std::shared_ptr<ClassDefaultConstructionStatement> ClassDefaultConstructionStatementPtr;
-
-CompoundStatementPtr MakeEmptyBody(ClassTypePtr classType, ScopePtr scope)
-{
-    return CompoundStatementPtr(new CompoundStatement("body", classType->Pos(), scope, classType->FileScope(), "", true));
-}
 
 ClassDefaultCtor::ClassDefaultCtor(const ClassTypePtr& classType_): Function(MakeOverloadName(GetConstructorFunctionSetName(), MakeParameterList1(MakePointerType(classType_, TypeCheckExtent::name), classType_->GetScope())), 
     classType_->Pos(), classType_->GetScope(), classType_->FileScope(), GetConstructorFunctionSetName(), Specifiers::public_), classType(classType_)
@@ -369,32 +326,31 @@
             memberVars.clear();
         }
     }
-    virtual ObjectPtr Clone(CloneContext& context) const { CM_CORE_ASSERT(false); return ObjectPtr(); }
+    virtual ObjectPtr Clone(CloneContext& context) const { CM_CORE_ASSERT(false, nullptr); return ObjectPtr(); }
     virtual std::string ToString() const
     {
         return "class copy construction statement";
     }
-    virtual void TypeCheckSignature(TypeCheckContext& context)
-    {
-        Statement::TypeCheckSignature(context);
+    virtual void TypeCheckBody(TypeCheckContext& context)
+    {
+        Statement::TypeCheckBody(context);
         bool isNothrow = true;
         if (classType.lock()->HasThrowingStaticConstructor()) 
         {
             isNothrow = false;
         }
         FunctionSetPtr ctor = FunctionSetTable::Instance()->GetFunctionSet(GetConstructorFunctionSetName());
-        CM_CORE_ASSERT(ctor);
+        CM_CORE_ASSERT(ctor, GetFullNameFor(GetFunction()));
         ClassTypePtr baseClass = classType.lock()->BaseClass();
-        if (baseClass && !baseClass->DeferredMembersTypeChecked())
-        {
-            baseClass->TypeCheckDeferredMembers(context);
-        }
         if (baseClass && baseClass->CopyConstructor())
         {
             if (baseClass->CopyConstructor()->IsSuppressed())
             {
                 throw TypeCheckException(CANNOT_CALL_SUPPRESSED_MEMBER_FUNCTION, "cannot call suppressed member function '" + baseClass->CopyConstructor()->FullName() + "'", Pos());
             }
+            context.PushExtent(TypeCheckExtent::signature);
+            baseClass->TypeCheckDeferred(context);
+            context.PopExtent();
             baseCopyConstructorCall = FunctionCallPtr(new FunctionCall(baseClass->CopyConstructor(), Pos(), ownerFunction, nullptr));
             baseCopyConstructorCall->TypeCheck(context);
             if (!baseCopyConstructorCall->IsNothrow())
@@ -413,18 +369,10 @@
             args.push_back(Argument(MakeConstReferenceType(memberVar->GetType(), TypeCheckExtent::signature), ArgumentCategory::lvalue));
             ScopeLookupSet scopes;
             scopes.insert(ScopeLookup(memberVar->GetType()->GetScope(), Lookup::this_scope));
-            if (memberVar->GetType()->IsClassType())
-            {
-                ClassTypePtr memVarClassType = std::static_pointer_cast<ClassType>(memberVar->GetType());
-                if (!memVarClassType->DeferredMembersTypeChecked())
-                {
-                    memVarClassType->TypeCheckDeferredMembers(context);
-                }
-            }
+            context.PushExtent(TypeCheckExtent::signature);
+            memberVar->GetType()->TypeCheckDeferred(context);
+            context.PopExtent();
             FunctionCallPtr memberCtorCall = ctor->ResolveOverload(args, scopes, ResolutionOption::allow_conversions, Pos(), ResolutionFlags::throw_, ownerFunction, nullptr, context);
-            context.PushExtent(TypeCheckExtent::body);
-            memberCtorCall->TypeCheck(context);
-            context.PopExtent();
             if (!memberCtorCall->IsNothrow())
             {
                 isNothrow = false;
@@ -434,21 +382,6 @@
         if (isNothrow)
         {
             GetFunction()->SetNothrow();
-        }
-    }
-    virtual void CollectExternalObjects(CompilationUnitPtr compilationUnit, ObjectSet& externalObjects, bool deep)
-    {
-        if (ExternalObjectsCollected(compilationUnit, deep)) return;
-        Statement::CollectExternalObjects(compilationUnit, externalObjects, deep);
-        if (baseCopyConstructorCall)
-        {
-            baseCopyConstructorCall->CollectExternalObjects(compilationUnit, externalObjects, deep);
-        }
-        int n = memberConstructorCalls.size();
-        for (int i = 0; i < n; ++i)
-        {
-            FunctionCallPtr memberConstructorCall = memberConstructorCalls[i];
-            memberConstructorCall->CollectExternalObjects(compilationUnit, externalObjects, deep);
         }
     }
     virtual GenResult Gen(Ir& ir, GenFlags flags)
@@ -507,25 +440,6 @@
             memberConstructorCall->GenerateDestructionStatements(destructionStack);
         }
     }
-    virtual void CheckIfCanThrow(bool& canThrow, TypeCheckContext& context)
-    {
-        FunctionPtr staticCtor = classType.lock()->StaticConstructor();
-        if (staticCtor)
-        {
-            staticCtor->CheckIfCanThrow(canThrow, context);
-            if (canThrow) return;
-        }
-        if (baseCopyConstructorCall)
-        {
-            baseCopyConstructorCall->CheckIfCanThrow(canThrow, context);
-            if (canThrow) return;
-        }
-        for (FunctionCallPtr memberConstructorCall : memberConstructorCalls)
-        {
-            memberConstructorCall->CheckIfCanThrow(canThrow, context);
-            if (canThrow) return;
-        }
-    }
 private:
     WeakClassTypePtr classType;
     WeakClassTypePtr baseClassType;
@@ -625,28 +539,27 @@
             memberAssignmentCalls.clear();
         }
     }
-    virtual ObjectPtr Clone(CloneContext& context) const { CM_CORE_ASSERT(false); return ObjectPtr(); }
+    virtual ObjectPtr Clone(CloneContext& context) const { CM_CORE_ASSERT(false, nullptr); return ObjectPtr(); }
     virtual std::string ToString() const
     {
         return "class assignment statement";
     }
-    virtual void TypeCheckSignature(TypeCheckContext& context)
-    {
-        Statement::TypeCheckSignature(context);
+    virtual void TypeCheckBody(TypeCheckContext& context)
+    {
+        Statement::TypeCheckBody(context);
         bool isNothrow = true;
         FunctionSetPtr assignment = FunctionSetTable::Instance()->GetFunctionSet("operator=");
-        CM_CORE_ASSERT(assignment);
+        CM_CORE_ASSERT(assignment, GetFullNameFor(GetFunction()));
         ClassTypePtr baseClass = classType.lock()->BaseClass();
-        if (baseClass && !baseClass->DeferredMembersTypeChecked())
-        {
-            baseClass->TypeCheckDeferredMembers(context);
-        }
         if (baseClass && baseClass->Assignment())
         {
             if (baseClass->Assignment()->IsSuppressed())
             {
                 throw TypeCheckException(CANNOT_CALL_SUPPRESSED_MEMBER_FUNCTION, "cannot call suppressed member function '" + baseClass->Assignment()->FullName() + "'", Pos());
             }
+            context.PushExtent(TypeCheckExtent::signature);
+            baseClass->TypeCheckDeferred(context);
+            context.PopExtent();
             baseAssignmentCall = FunctionCallPtr(new FunctionCall(baseClass->Assignment(), Pos(), ownerFunction, nullptr));
             baseAssignmentCall->TypeCheck(context);
             if (!baseAssignmentCall->IsNothrow())
@@ -665,18 +578,10 @@
             args.push_back(Argument(MakeConstReferenceType(memberVar->GetType(), TypeCheckExtent::signature), ArgumentCategory::lvalue));
             ScopeLookupSet scopes;
             scopes.insert(ScopeLookup(memberVar->GetType()->GetScope(), Lookup::this_scope));
-            if (memberVar->GetType()->IsClassType())
-            {
-                ClassTypePtr memVarClassType = std::static_pointer_cast<ClassType>(memberVar->GetType());
-                if (!memVarClassType->DeferredMembersTypeChecked())
-                {
-                    memVarClassType->TypeCheckDeferredMembers(context);
-                }
-            }
+            context.PushExtent(TypeCheckExtent::signature);
+            memberVar->GetType()->TypeCheckDeferred(context);
+            context.PopExtent();
             FunctionCallPtr memberAssignmentCall = assignment->ResolveOverload(args, scopes, ResolutionOption::allow_conversions, Pos(), ResolutionFlags::throw_, ownerFunction, nullptr, context);
-            context.PushExtent(TypeCheckExtent::body);
-            memberAssignmentCall->TypeCheck(context);
-            context.PopExtent();
             if (!memberAssignmentCall->IsNothrow())
             {
                 isNothrow = false;
@@ -686,21 +591,6 @@
         if (isNothrow)
         {
             GetFunction()->SetNothrow();
-        }
-    }
-    virtual void CollectExternalObjects(CompilationUnitPtr compilationUnit, ObjectSet& externalObjects, bool deep)
-    {
-        if (ExternalObjectsCollected(compilationUnit, deep)) return;
-        Statement::CollectExternalObjects(compilationUnit, externalObjects, deep);
-        if (baseAssignmentCall)
-        {
-            baseAssignmentCall->CollectExternalObjects(compilationUnit, externalObjects, deep);
-        }
-        int n = memberAssignmentCalls.size();
-        for (int i = 0; i < n; ++i)
-        {
-            FunctionCallPtr memberAssignmentCall = memberAssignmentCalls[i];
-            memberAssignmentCall->CollectExternalObjects(compilationUnit, externalObjects, deep);
         }
     }
     virtual void GenerateDestructionStatements(DestructionStackPtr destructionStack)
@@ -755,21 +645,6 @@
         }
         return result;
     }
-    virtual void CheckIfCanThrow(bool& canThrow, TypeCheckContext& context)
-    {
-        if (baseAssignmentCall)
-        {
-            baseAssignmentCall->CheckIfCanThrow(canThrow, context);
-            if (canThrow) return;
-        }
-        int n = memberAssignmentCalls.size();
-        for (int i = 0; i < n; ++i)
-        {
-            FunctionCallPtr memberAssignmentCall = memberAssignmentCalls[i];
-            memberAssignmentCall->CheckIfCanThrow(canThrow, context);
-            if (canThrow) return;
-        }
-    }
 private:
     WeakClassTypePtr classType;
     WeakClassTypePtr baseClassType;
@@ -791,6 +666,11 @@
     Body()->AddStatement(ClassAssignmentStatementPtr(new ClassAssignmentStatement(classType.lock(), this)));
 }
 
+void ClassAssignment::TypeCheckBody(TypeCheckContext& context)
+{
+    Function::TypeCheckBody(context);
+}
+
 void ClassAssignment::Generate(Ir& ir, GenResult& result)
 {
     GenResult assignmentResult(ir, result.Flags());
@@ -851,28 +731,27 @@
             memberVars.clear();
         }
     }
-    virtual ObjectPtr Clone(CloneContext& context) const { CM_CORE_ASSERT(false); return ObjectPtr(); }
+    virtual ObjectPtr Clone(CloneContext& context) const { CM_CORE_ASSERT(false, nullptr); return ObjectPtr(); }
     virtual std::string ToString() const
     {
         return "class destruction statement";
     }
-    virtual void TypeCheckSignature(TypeCheckContext& context)
-    {
-        Statement::TypeCheckSignature(context);
+    virtual void TypeCheckBody(TypeCheckContext& context)
+    {
+        Statement::TypeCheckBody(context);
         bool isNothrow = true;
         FunctionSetPtr dtor = FunctionSetTable::Instance()->GetFunctionSet(GetDestructorFunctionSetName());
-        CM_CORE_ASSERT(dtor);
+        CM_CORE_ASSERT(dtor, GetFullNameFor(GetFunction()));
         ClassTypePtr baseClass = classType.lock()->BaseClass();
-        if (baseClass && !baseClass->DeferredMembersTypeChecked())
-        {
-            baseClass->TypeCheckDeferredMembers(context);
-        }
         if (baseClass && baseClass->Destructor())
         {
             if (baseClass->Destructor()->IsSuppressed())
             {
                 throw TypeCheckException(CANNOT_CALL_SUPPRESSED_MEMBER_FUNCTION, "cannot call suppressed member function '" + baseClass->Destructor()->FullName() + "'", Pos());
             }
+            context.PushExtent(TypeCheckExtent::signature);
+            baseClass->TypeCheckDeferred(context);
+            context.PopExtent();
             baseDestructorCall = FunctionCallPtr(new FunctionCall(baseClass->Destructor(), Pos(), ownerFunction, nullptr));
             baseDestructorCall->TypeCheck(context);
             if (!baseDestructorCall->IsNothrow())
@@ -886,14 +765,9 @@
         for (int i = 0; i < n; ++i)
         {
             MemberVariablePtr memberVar = memberVars[i];
-            if (memberVar->GetType()->IsClassType())
-            {
-                ClassTypePtr memVarClassType = std::static_pointer_cast<ClassType>(memberVar->GetType());
-                if (!memVarClassType->DeferredMembersTypeChecked())
-                {
-                    memVarClassType->TypeCheckDeferredMembers(context);
-                }
-            }
+            context.PushExtent(TypeCheckExtent::signature);
+            memberVar->GetType()->TypeCheckDeferred(context);
+            context.PopExtent();
             FunctionCallPtr memberDtorCall;
             if (!memberVar->HasTrivialDestructor())
             {
@@ -902,9 +776,6 @@
                 ScopeLookupSet scopes;
                 scopes.insert(ScopeLookup(memberVar->GetType()->GetScope(), Lookup::this_scope));
                 memberDtorCall = dtor->ResolveOverload(args, scopes, ResolutionOption::deny_conversions, Pos(), ResolutionFlags::throw_, ownerFunction, nullptr, context);
-                context.PushExtent(TypeCheckExtent::body);
-                memberDtorCall->TypeCheck(context);
-                context.PopExtent();
                 if (!memberDtorCall->IsNothrow())
                 {
                     isNothrow = false;
@@ -917,24 +788,6 @@
             GetFunction()->SetNothrow();
         }
     }
-    virtual void CollectExternalObjects(CompilationUnitPtr compilationUnit, ObjectSet& externalObjects, bool deep)
-    {
-        if (ExternalObjectsCollected(compilationUnit, deep)) return;
-        Statement::CollectExternalObjects(compilationUnit, externalObjects, deep);
-        if (baseDestructorCall)
-        {
-            baseDestructorCall->CollectExternalObjects(compilationUnit, externalObjects, deep);
-        }
-        int n = memberDestructorCalls.size();
-        for (int i = 0; i < n; ++i)
-        {
-            FunctionCallPtr memberDestructorCall = memberDestructorCalls[i];
-            if (memberDestructorCall)
-            {
-                memberDestructorCall->CollectExternalObjects(compilationUnit, externalObjects, deep);
-            }
-        }
-    }
     virtual void GenerateDestructionStatements(DestructionStackPtr destructionStack)
     {
         Statement::GenerateDestructionStatements(destructionStack);
@@ -959,8 +812,8 @@
         if (useThisVariable)
         {
             LocalVariablePtr thisVar(new ThisVariable(classType.lock()->Pos(), classType.lock()->EnclosingScope(), classType.lock()->FileScope(), classType.lock()));
-            TypeCheckContext body(TypeCheckExtent::body);
-            thisVar->TypeCheck(body);
+            TypeCheckContext signature(TypeCheckExtent::signature);
+            thisVar->TypeCheck(signature);
             GenResult thisResult = thisVar->Gen(ir, GenFlags::none);
             thisPtr = thisResult.MainObject();
         }
@@ -1022,7 +875,12 @@
     SetContent(ObjectPtr(), MakeParameterList1(MakePointerType(classType_, TypeCheckExtent::name), classType_->GetScope()), TemplateParameterList(), MakeEmptyBody(classType_->GetScope()));
     Parameters()[0]->SetName("this");
     Body()->AddStatement(StatementPtr(new SetVtblPtrStatement(GetClassType(), false)));
-    Body()->AddStatement(StatementPtr(new ClassDestructionStatement(GetClassType(), this, false)));
+    Body()->AddStatement(ClassDestructionStatementPtr(new ClassDestructionStatement(GetClassType(), this, false)));
+}
+
+void ClassDtor::TypeCheckBody(TypeCheckContext& context)
+{
+    DestructorBase::TypeCheckBody(context);
 }
 
 void ClassDtor::Generate(Ir& ir, GenResult& result)