Commits

Iain Buclaw  committed a736ae4

Issue #78 D1/D2 - in/out contract inheritance

  • Participants
  • Parent commits 0d65aed

Comments (0)

Files changed (5)

File d/d-codegen.cc

                 ClassDeclaration * cd;
                 StructDeclaration * sd;
 
+                // Special case for __ensure and __require.
+                if (nested_func->ident == Id::ensure || nested_func->ident == Id::require)
+                    break;
+
                 if ((fd = this_func->isFuncDeclaration()))
                 {
                     if (outer_func == fd->toParent2())

File d/d-decls.cc

                 DECL_ARTIFICIAL(fn_decl) = 1;
                 D_DECL_ONE_ONLY(fn_decl) = 1;
             }
+            // So are ensure and require contracts.
+            if (ident == Id::ensure || ident == Id::require)
+            {
+                // Maybe fix decl context so inherited in/out contracts are reachable.
+                AggregateDeclaration * ad = parent->isMember();
+                if (ad)
+                {
+                    tree context = ad->type->toCtype();
+                    DECL_CONTEXT(fn_decl) = ad->isClassDeclaration()
+                        ? TREE_TYPE(context)
+                        : context;
+                }
+                DECL_ARTIFICIAL(fn_decl) = 1;
+                D_DECL_INOUT_CONTRACT(fn_decl) = 1;
+            }
 #if V2
             // %% Pure functions don't imply nothrow
             DECL_PURE_P(fn_decl) = (isPure() == PUREstrong && func_type->isnothrow);

File d/d-lang-45.h

 /* True if the symbol has been marked "static const".  */
 #define D_DECL_READONLY_STATIC(NODE) (DECL_LANG_FLAG_3(NODE))
 
+/* True if the decl is a compiler generated function for the in and out contracts.  */
+#define D_DECL_INOUT_CONTRACT(NODE) (DECL_LANG_FLAG_4(NODE))
+
 /* True if the decl has been used except for being set.  */
 #if D_GCC_VER >= 46
 #define D_DECL_READ(NODE) (DECL_READ_P(NODE))
 #else
-#define D_DECL_READ(NODE) (DECL_LANG_FLAG_4(NODE))
+#define D_DECL_READ(NODE) (DECL_LANG_FLAG_5(NODE))
 #endif
 
 /* The D front-end does not use the 'binding level' system for a symbol table,
 /* True if the symbol has been marked "static const".  */
 #define D_DECL_READONLY_STATIC(NODE) (DECL_LANG_FLAG_3(NODE))
 
+/* True if the decl is a compiler generated function for the in and out contracts.  */
+#define D_DECL_INOUT_CONTRACT(NODE) (DECL_LANG_FLAG_4(NODE))
+
 /* True if the decl has been used except for being set.  */
-#define D_DECL_READ(NODE) (DECL_LANG_FLAG_4(NODE))
+#define D_DECL_READ(NODE) (DECL_LANG_FLAG_5(NODE))
 
 /* The D front-end does not use the 'binding level' system for a symbol table,
    It is only needed to get debugging information for local variables and

File d/d-objfile.cc

         }
     }
 
-    if (! gen.functionNeedsChain(f))
+    if (! gen.functionNeedsChain(f) || D_DECL_INOUT_CONTRACT(t))
     {
         bool context = decl_function_context(t) != NULL;
         cgraph_finalize_function(t, context);