Index: src/Concurrency/Actors.cpp
===================================================================
--- src/Concurrency/Actors.cpp	(revision cd5eb4b3e078ce0a3a9774937e96c7e432ebc390)
+++ src/Concurrency/Actors.cpp	(revision d2b94f2b8e57e60c3b3f499bbd0a67444001a97c)
@@ -73,8 +73,9 @@
     const StructDecl ** actorDecl;
     const StructDecl ** msgDecl;
+    std::vector<FunctionDecl *> & forwardDecls;
 
 	void postvisit( const FunctionDecl * decl ) {
-        // return if not of the form receive( param1, param2 )
-        if ( decl->name != "receive" || decl->params.size() != 2 ) return;
+        // return if not of the form receive( param1, param2 ) or if it is a forward decl
+        if ( decl->name != "receive" || decl->params.size() != 2 || !decl->stmts ) return;
 
         // the params should be references
@@ -193,5 +194,5 @@
 
             // put it all together into the complete function decl from above
-            declsToAddAfter.push_back( new FunctionDecl(
+            FunctionDecl * sendOperatorFunction = new FunctionDecl(
                 decl->location,
                 "?|?",
@@ -216,10 +217,16 @@
                     )
                 },
-                sendBody,               // body
+                nullptr,               // body
                 { Storage::Static },    // storage
                 Linkage::Cforall,       // linkage
                 {},                     // attributes
                 { Function::Inline }
-            ));
+            );
+            
+            // forward decls to resolve use before decl problem for '|' routines
+            forwardDecls.push_back( ast::deepCopy( sendOperatorFunction ) );
+
+            sendOperatorFunction->stmts = sendBody;
+            declsToAddAfter.push_back( sendOperatorFunction );
         }
 	}
@@ -227,7 +234,43 @@
   public:
     GenReceiveDecls( std::map<const StructDecl *, int> & actorStructDecls, std::map<const StructDecl *, int> & messageStructDecls,
-        const StructDecl ** requestDecl, const EnumDecl ** allocationDecl, const StructDecl ** actorDecl, const StructDecl ** msgDecl ) 
-        : actorStructDecls( actorStructDecls ), messageStructDecls( messageStructDecls ), requestDecl( requestDecl ), 
-        allocationDecl( allocationDecl ), actorDecl(actorDecl), msgDecl(msgDecl) {}
+        const StructDecl ** requestDecl, const EnumDecl ** allocationDecl, const StructDecl ** actorDecl, const StructDecl ** msgDecl, 
+        std::vector<FunctionDecl *> & forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls), 
+        requestDecl(requestDecl), allocationDecl(allocationDecl), actorDecl(actorDecl), msgDecl(msgDecl), forwardDecls(forwardDecls) {}
+};
+
+struct GenFwdDecls : public ast::WithDeclsToAdd<> {
+    std::map<const StructDecl *, int> & actorStructDecls;
+    std::map<const StructDecl *, int>  & messageStructDecls;
+    std::vector<FunctionDecl *> & forwardDecls;
+    bool done;
+
+    void postvisit( const FunctionDecl * decl ) {
+        if ( done ) return;
+        // return if not of the form receive( param1, param2 ) or if it is a forward decl
+        if ( decl->name != "receive" || decl->params.size() != 2 || !decl->stmts ) return;
+
+        // the params should be references
+        const ReferenceType * derivedActorRef = dynamic_cast<const ReferenceType *>(decl->params.at(0)->get_type());
+        const ReferenceType * derivedMsgRef = dynamic_cast<const ReferenceType *>(decl->params.at(1)->get_type());
+        if ( !derivedActorRef || !derivedMsgRef ) return;
+
+        // the references should be to struct instances
+        const StructInstType * arg1InstType = dynamic_cast<const StructInstType *>(derivedActorRef->base.get());
+        const StructInstType * arg2InstType = dynamic_cast<const StructInstType *>(derivedMsgRef->base.get());
+        if ( !arg1InstType || !arg2InstType ) return;
+
+        // If the struct instances are derived actor and message types then generate the message send routine
+        if ( actorStructDecls.count( arg1InstType->aggr() ) && messageStructDecls.count( arg2InstType->aggr() ) ) {
+            done = true;
+            for ( const auto & func : forwardDecls ) {
+                declsToAddBefore.push_back( func );
+            }
+        }
+    }
+
+  public:
+    GenFwdDecls( std::map<const StructDecl *, int> & actorStructDecls, std::map<const StructDecl *, int> & messageStructDecls, 
+        std::vector<FunctionDecl *> & forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls),
+        forwardDecls(forwardDecls), done(false) {}
 };
 
@@ -236,6 +279,8 @@
     std::map<const StructDecl *, int> actorStructDecls;
     std::map<const StructDecl *, int> messageStructDecls;
-
-    // for setting through the passes
+    std::vector<FunctionDecl *> forwardDecls;
+
+    // for storing through the passes
+    // these are populated with various important struct decls
     const StructDecl * requestDeclPtr = nullptr;
     const EnumDecl * allocationDeclPtr = nullptr;
@@ -257,5 +302,8 @@
     // it then generates the appropriate operator '|' send routines for the receive routines
     Pass<GenReceiveDecls>::run( translationUnit, actorStructDecls, messageStructDecls, requestDecl, 
-        allocationDecl, actorDecl, msgDecl );
+        allocationDecl, actorDecl, msgDecl, forwardDecls );
+
+    // The third pass forward declares operator '|' send routines
+    Pass<GenFwdDecls>::run( translationUnit, actorStructDecls, messageStructDecls, forwardDecls );
 }
 
