changeset 1487:f62347c22d81

Apply changes from r1482 to D2 frontend too. Completely untested, but ldc2 compiles again.
author Frits van Bommel <fvbommel wxs.nl>
date Mon, 08 Jun 2009 13:45:26 +0200
parents 9ed0695cb93c
children ca31a8e9c42b
files dmd2/aggregate.h dmd2/declaration.c dmd2/declaration.h dmd2/func.c dmd2/inline.c dmd2/mars.h dmd2/struct.c
diffstat 7 files changed, 74 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/dmd2/aggregate.h	Mon Jun 08 12:35:55 2009 +0200
+++ b/dmd2/aggregate.h	Mon Jun 08 13:45:26 2009 +0200
@@ -121,6 +121,11 @@
 #endif
 
     AggregateDeclaration *isAggregateDeclaration() { return this; }
+
+#if IN_LLVM
+    // Aggregates that wouldn't have gotten semantic3'ed if we weren't inlining set this flag.
+    bool availableExternally;
+#endif
 };
 
 struct AnonymousAggregateDeclaration : AggregateDeclaration
--- a/dmd2/declaration.c	Mon Jun 08 12:35:55 2009 +0200
+++ b/dmd2/declaration.c	Mon Jun 08 13:45:26 2009 +0200
@@ -638,6 +638,8 @@
     offset2 = 0;
 
     nakedUse = false;
+
+    availableExternally = true; // assume this unless proven otherwise
 #endif
 }
 
@@ -1182,6 +1184,16 @@
     }
 }
 
+void VarDeclaration::semantic3(Scope *sc)
+{
+    // LDC
+    if (!global.params.useAvailableExternally)
+        availableExternally = false;
+
+    // Preserve call chain
+    Declaration::semantic3(sc);
+}
+
 const char *VarDeclaration::kind()
 {
     return "variable";
@@ -1576,6 +1588,9 @@
 void TypeInfoDeclaration::semantic(Scope *sc)
 {
     assert(linkage == LINKc);
+    // LDC
+    if (!global.params.useAvailableExternally)
+        availableExternally = false;
 }
 
 /***************************** TypeInfoConstDeclaration **********************/
--- a/dmd2/declaration.h	Mon Jun 08 12:35:55 2009 +0200
+++ b/dmd2/declaration.h	Mon Jun 08 13:45:26 2009 +0200
@@ -312,6 +312,11 @@
     /// Set during type generation.
     unsigned aggrIndex;
 
+    /// Variables that wouldn't have gotten semantic3'ed if we weren't inlining set this flag.
+    bool availableExternally;
+    /// Override added to set above flag.
+    void semantic3(Scope *sc);
+
     // FIXME: we're not using these anymore!
     AnonDeclaration* anonDecl;
     unsigned offset2;
@@ -777,6 +782,9 @@
     // if this is an array operation it gets a little special attention
     bool isArrayOp;
 
+    // Functions that wouldn't have gotten semantic3'ed if we weren't inlining set this flag.
+    bool availableExternally;
+
     // true if overridden with the pragma(allow_inline); stmt
     bool allowInlining;
 #endif
--- a/dmd2/func.c	Mon Jun 08 12:35:55 2009 +0200
+++ b/dmd2/func.c	Mon Jun 08 13:45:26 2009 +0200
@@ -87,6 +87,8 @@
     isArrayOp = false;
     allowInlining = false;
 
+    availableExternally = true; // assume this unless proven otherwise
+
     // function types in ldc don't merge if the context parameter differs
     // so we actually don't care about the function declaration, but only
     // what kind of context parameter it has.
@@ -672,6 +674,10 @@
 	return;
     semanticRun = 3;
 
+    // LDC
+    if (!global.params.useAvailableExternally)
+        availableExternally = false;
+
     if (!type || type->ty != Tfunction)
 	return;
     f = (TypeFunction *)(type);
--- a/dmd2/inline.c	Mon Jun 08 12:35:55 2009 +0200
+++ b/dmd2/inline.c	Mon Jun 08 13:45:26 2009 +0200
@@ -83,14 +83,17 @@
 {
     int cost;
 
+#if !IN_LLVM
     /* Can't declare variables inside ?: expressions, so
      * we cannot inline if a variable is declared.
      */
     if (arg)
 	return COST_MAX;
+#endif
 
     cost = condition->inlineCost(ics);
 
+#if !IN_LLVM
     /* Specifically allow:
      *	if (condition)
      *	    return exp1;
@@ -108,6 +111,7 @@
 	//printf("cost = %d\n", cost);
     }
     else
+#endif
     {
 	ics->nested += 1;
 	if (ifbody)
@@ -121,9 +125,11 @@
 
 int ReturnStatement::inlineCost(InlineCostState *ics)
 {
+#if !IN_LLVM
     // Can't handle return statements nested in if's
     if (ics->nested)
 	return COST_MAX;
+#endif
     return exp ? exp->inlineCost(ics) : 0;
 }
 
@@ -157,19 +163,23 @@
 
 int ThisExp::inlineCost(InlineCostState *ics)
 {
+#if !IN_LLVM
     FuncDeclaration *fd = ics->fd;
     if (!ics->hdrscan)
 	if (fd->isNested() || !ics->hasthis)
 	    return COST_MAX;
+#endif
     return 1;
 }
 
 int SuperExp::inlineCost(InlineCostState *ics)
 {
+#if !IN_LLVM
     FuncDeclaration *fd = ics->fd;
     if (!ics->hdrscan)
 	if (fd->isNested() || !ics->hasthis)
 	    return COST_MAX;
+#endif
     return 1;
 }
 
@@ -195,12 +205,16 @@
 
 int FuncExp::inlineCost(InlineCostState *ics)
 {
+    // This breaks on LDC too, since nested functions have internal linkage
+    // and thus can't be referenced from other objects.
     // Right now, this makes the function be output to the .obj file twice.
     return COST_MAX;
 }
 
 int DelegateExp::inlineCost(InlineCostState *ics)
 {
+    // This breaks on LDC too, since nested functions have internal linkage
+    // and thus can't be referenced from other objects.
     return COST_MAX;
 }
 
@@ -229,6 +243,8 @@
 	    return td->objects->dim;
 #endif
 	}
+        // This breaks on LDC too, since nested static variables have internal
+        // linkage and thus can't be referenced from other objects.
 	if (!ics->hdrscan && vd->isDataseg())
 	    return COST_MAX;
 	cost += 1;
@@ -246,6 +262,8 @@
     }
 
     // These can contain functions, which when copied, get output twice.
+    // These break on LDC too, since nested static variables and functions have
+    // internal linkage and thus can't be referenced from other objects.
     if (declaration->isStructDeclaration() ||
 	declaration->isClassDeclaration() ||
 	declaration->isFuncDeclaration() ||
@@ -1269,6 +1287,10 @@
     if (type)
     {	assert(type->ty == Tfunction);
 	TypeFunction *tf = (TypeFunction *)(type);
+#if IN_LLVM
+        // LDC: Only extern(C) varargs count.
+        if (tf->linkage != LINKd)
+#endif
 	if (tf->varargs == 1)	// no variadic parameter lists
 	    goto Lno;
 
@@ -1280,12 +1302,15 @@
 	    !hdrscan)
 	    goto Lno;
     }
+#if !IN_LLVM
+    // LDC: Only extern(C) varargs count, and ctors use extern(D).
     else
     {	CtorDeclaration *ctor = isCtorDeclaration();
 
 	if (ctor && ctor->varargs == 1)
 	    goto Lno;
     }
+#endif
 
     if (
 	!fbody ||
@@ -1299,17 +1324,20 @@
 #endif
 	isSynchronized() ||
 	isImportedSymbol() ||
+#if !IN_LLVM
 #if DMDV2
 	closureVars.dim ||	// no nested references to this frame
 #else
 	nestedFrameRef ||	// no nested references to this frame
 #endif
+#endif // !IN_LLVM
 	(isVirtual() && !isFinal())
        ))
     {
 	goto Lno;
     }
 
+#if !IN_LLVM
     /* If any parameters are Tsarray's (which are passed by reference)
      * or out parameters (also passed by reference), don't do inlining.
      */
@@ -1322,6 +1350,7 @@
 		goto Lno;
 	}
     }
+#endif
 
     memset(&ics, 0, sizeof(ics));
     ics.hasthis = hasthis;
@@ -1334,8 +1363,10 @@
     if (cost >= COST_MAX)
 	goto Lno;
 
+#if !IN_LLVM
     if (!hdrscan)    // Don't scan recursively for header content scan
 	inlineScan();
+#endif
 
 Lyes:
     if (!hdrscan)    // Don't modify inlineStatus for header content scan
--- a/dmd2/mars.h	Mon Jun 08 12:35:55 2009 +0200
+++ b/dmd2/mars.h	Mon Jun 08 13:45:26 2009 +0200
@@ -242,6 +242,7 @@
     bool llvmAnnotate;
     bool useInlineAsm;
     bool verbose_cg;
+    bool useAvailableExternally;
 
     // target stuff
     const char* llvmArch;
--- a/dmd2/struct.c	Mon Jun 08 12:35:55 2009 +0200
+++ b/dmd2/struct.c	Mon Jun 08 13:45:26 2009 +0200
@@ -56,6 +56,10 @@
     aliasthis = NULL;
 #endif
     dtor = NULL;
+
+#if IN_LLVM
+    availableExternally = true; // assume this unless proven otherwise
+#endif
 }
 
 enum PROT AggregateDeclaration::prot()
@@ -85,6 +89,10 @@
 void AggregateDeclaration::semantic3(Scope *sc)
 {   int i;
 
+    // LDC
+    if (!global.params.useAvailableExternally)
+        availableExternally = false;
+
     //printf("AggregateDeclaration::semantic3(%s)\n", toChars());
     if (members)
     {