charmxi: factor out more loop-over-elements constructs
[charm.git] / src / xlat-i / xi-symbol.C
1 #include <list>
2 using std::list;
3 #include <algorithm>
4 using std::for_each;
5 #include <stdlib.h>
6 #include "xi-symbol.h"
7 #include "CParsedFile.h"
8 #include <ctype.h> // for tolower()
9 #include <iostream>
10 using std::cerr;
11 using std::cout;
12 using std::endl;
13
14 #if ! CMK_BOOL_DEFINED
15 typedef enum {false = 0, true = 1} bool;
16 #endif
17
18 #include <fstream>
19
20 namespace xi {
21    
22 int fortranMode;
23 int internalMode;
24 const char *cur_file;
25 const char *python_doc;
26
27 const char *Prefix::Proxy="CProxy_";
28 const char *Prefix::ProxyElement="CProxyElement_";
29 const char *Prefix::ProxySection="CProxySection_";
30 const char *Prefix::Message="CMessage_";
31 const char *Prefix::Index="CkIndex_";
32 const char *Prefix::Python="CkPython_";
33
34
35 //Fatal error function
36 void die(const char *why,int line)
37 {
38         if (line==-1)
39                 fprintf(stderr,"%s: Charmxi fatal error> %s\n",cur_file,why);
40         else
41                 fprintf(stderr,"%s:%d: Charmxi fatal error> %s\n",cur_file,line,why);
42         exit(1);
43 }
44
45 // Make the name lower case
46 char* fortranify(const char *s, const char *suff1="", const char *suff2="", const char *suff3="")
47 {
48   int i, len1 = strlen(s), len2 = strlen(suff1),
49          len3 = strlen(suff2), len4 = strlen(suff3);
50   int c = len1+len2+len3+len4;
51   char str[1024], strUpper[1024];
52   strcpy(str, s);
53   strcat(str, suff1);
54   strcat(str, suff2);
55   strcat(str, suff3);
56   for(i = 0; i < c+1; i++)
57     str[i] = tolower(str[i]);
58   for(i = 0; i < c+1; i++)
59     strUpper[i] = toupper(str[i]);
60   char *retVal;
61   retVal = new char[2*c+20];
62   strcpy(retVal, "FTN_NAME(");
63   strcat(retVal, strUpper);
64   strcat(retVal, ",");
65   strcat(retVal, str);
66   strcat(retVal, ")");
67
68   return retVal;
69 }
70
71 void templateGuardBegin(bool templateOnly, XStr &str) {
72   if (templateOnly)
73     str << "#ifdef " << "CK_TEMPLATES_ONLY\n";
74   else
75     str << "#ifndef " << "CK_TEMPLATES_ONLY\n";
76 }
77 void templateGuardEnd(XStr &str) {
78   str << "#endif /* CK_TEMPLATES_ONLY */\n";
79 }
80
81 Value::Value(const char *s)
82 {
83   factor = 1;
84   val=s;
85   if(val == 0 || strlen(val)==0 ) return;
86   char *v = (char *)malloc(strlen(val)+5);
87   strcpy(v,val);
88   int pos = strlen(v)-1;
89   if(v[pos]=='K' || v[pos]=='k') {
90     v[pos] = '\0';
91     factor = 1024;
92   }
93   if(v[pos]=='M' || v[pos]=='m') {
94     v[pos] = '\0';
95     factor = 1024*1024;
96   }
97   val=v;
98 }
99
100
101 int
102 Value::getIntVal(void)
103 {
104   if(val==0 || strlen(val)==0) return 0;
105   return (atoi((const char *)val)*factor);
106 }
107
108
109 /**
110    Apply fn_ on each Construct in the list l, passing it arg as
111    the target. If between_ is passed, do that to arg between each
112    element.
113  */
114 template<typename T, typename U, typename A>
115 class perElemGenC
116 {
117     void (U::*fn)(A);
118     void (*between)(A);
119     A arg;
120 public:
121     perElemGenC(list<T*> &l,
122                A arg_,
123                void (U::*fn_)(A),
124                void (*between_)(A) = NULL)
125         : fn(fn_), between(between_), arg(arg_)
126         {
127             for_each(l.begin(), l.end(), *this);
128         }
129     void operator()(T* m)
130         {
131             if (m)
132             {
133                 (m->*fn)(arg);
134                 if (between)
135                     between(arg);
136             }
137         }
138 };
139
140 template<typename T, typename U, typename A>
141 void perElemGen(list<T*> &l, A& arg_, void (U::*fn_)(A&),
142 // Sun Studio 7 (C++ compiler version 5.4) can't handle this
143 //              void (*between_)(A&) = NULL)
144                 void (*between_)(A&))
145 {
146     perElemGenC<T, U, A&>(l, arg_, fn_, between_);
147 }
148
149 template<typename T, typename U, typename A>
150 void perElemGen(list<T*> &l, A& arg_, void (U::*fn_)(A&))
151 {
152     perElemGenC<T, U, A&>(l, arg_, fn_, NULL);
153 }
154
155 template<typename T, typename U, typename A>
156 void perElemGen(list<T*> &l, A* arg_, void (U::*fn_)(A*),
157 // See above
158 //              void (*between_)(A*) = NULL)
159                 void (*between_)(A*))
160 {
161     perElemGenC<T, U, A*>(l, arg_, fn_, between_);
162 }
163
164 template<typename T, typename U, typename A>
165 void perElemGen(list<T*> &l, A* arg_, void (U::*fn_)(A*))
166 {
167     perElemGenC<T, U, A*>(l, arg_, fn_, NULL);
168 }
169
170 /**
171    Apply fn_ on each non-NULL element in the list l.
172    If between_ is passed, do that between each element.
173  */
174 template<typename T, typename U>
175 class perElemC
176 {
177     void (U::*fn)();
178 public:
179     perElemC(list<T*> &l,
180                void (U::*fn_)())
181         : fn(fn_)
182         {
183             for_each(l.begin(), l.end(), *this);
184         }
185     void operator()(T* m)
186         {
187             if (m) {
188                 (m->*fn)();
189             }
190         }
191 };
192
193 template<typename T, typename U>
194 void perElem(list<T*> &l, void (U::*fn_)())
195 {
196     perElemC<T, U>(l, fn_);
197 }
198
199 void newLine(XStr &str)
200 {
201     str << endx;
202 }
203
204 ConstructList::ConstructList(int l, Construct *c, ConstructList *n)
205 {
206     constructs.push_back(c);
207     if (n)
208         constructs.insert(constructs.end(),
209                           n->constructs.begin(), n->constructs.end());
210     line = l;
211 }
212
213 void
214 ConstructList::setExtern(int e)
215 {
216   Construct::setExtern(e);
217   perElemGen(constructs, e, &Construct::setExtern);
218 }
219
220 void
221 ConstructList::setModule(Module *m)
222 {
223   Construct::setModule(m);
224   perElemGen(constructs, m, &Construct::setModule);
225 }
226
227 void
228 ConstructList::print(XStr& str)
229 {
230     perElemGen(constructs, str, &Construct::print);
231 }
232
233 int ConstructList::genAccels_spe_c_funcBodies(XStr& str) {
234     int rtn = 0;
235     for (list<Construct *>::iterator i = constructs.begin();
236          i != constructs.end(); ++i)
237         if (*i) rtn += (*i)->genAccels_spe_c_funcBodies(str);
238     return rtn;
239 }
240 void ConstructList::genAccels_spe_c_regFuncs(XStr& str) {
241     perElemGen(constructs, str, &Construct::genAccels_spe_c_regFuncs);
242 }
243 void ConstructList::genAccels_spe_c_callInits(XStr& str) {
244     perElemGen(constructs, str, &Construct::genAccels_spe_c_callInits);
245 }
246 void ConstructList::genAccels_spe_h_includes(XStr& str) {
247     perElemGen(constructs, str, &Construct::genAccels_spe_h_includes);
248 }
249 void ConstructList::genAccels_spe_h_fiCountDefs(XStr& str) {
250     perElemGen(constructs, str, &Construct::genAccels_spe_h_fiCountDefs);
251 }
252 void ConstructList::genAccels_ppe_c_regFuncs(XStr& str) {
253     perElemGen(constructs, str, &Construct::genAccels_ppe_c_regFuncs);
254 }
255
256
257 void
258 TParamList::print(XStr& str)
259 {
260   tparam->print(str);
261   if(next) {
262     str << ",";
263     next->print(str);
264   }
265 }
266
267 std::string TParamList::to_string()
268 {
269     XStr s;
270     print(s);
271     return s.get_string();
272 }
273
274
275 void
276 Type::genProxyName(XStr &str,forWhom forElement)
277 {
278   (void)str; (void)forElement;
279   die("type::genProxyName called (INTERNAL ERROR)");
280 }
281 void
282 Type::genIndexName(XStr &str)
283 {
284   (void)str;
285   die("type::genIndexName called (INTERNAL ERROR)");
286 }
287 void
288 Type::genMsgProxyName(XStr &str)
289 {
290   (void)str;
291   die("type::genMsgProxyName called (INTERNAL ERROR)");
292 }
293
294 void
295 NamedType::print(XStr& str)
296 {
297   if (scope) str << scope;
298   str << name;
299   if (tparams) str << "<"<<tparams<<" >";
300 }
301
302 void NamedType::genIndexName(XStr& str) { 
303     if (scope) str << scope;
304     str << Prefix::Index; 
305     str << name;
306     if (tparams) str << "<"<<tparams<<" >";
307 }
308
309 void NamedType::genMsgProxyName(XStr& str) { 
310     if (scope) str << scope;
311     str << Prefix::Message;
312     str << name;
313     if (tparams) str << "<"<<tparams<<" >";
314 }
315
316 void
317 PtrType::print(XStr& str)
318 {
319   type->print(str);
320   for(int i=0;i<numstars;i++)
321     str << "*";
322 }
323
324 void
325 TypeList::print(XStr& str)
326 {
327   type->print(str);
328   if(next) {
329     str << ", ";
330     next->print(str);
331   }
332 }
333
334 int TypeList::length(void) const
335 {
336   if (next) return next->length()+1;
337   else return 1;
338 }
339
340 MemberList::MemberList(Member *m, MemberList *n)
341 {
342     members.push_back(m);
343     if (n)
344         members.insert(members.end(), n->members.begin(), n->members.end());
345 }
346
347
348 void
349 MemberList::print(XStr& str)
350 {
351     perElemGen(members, str, &Member::print);
352 }
353
354 void
355 MemberList::appendMember(Member *m)
356 {
357     members.push_back(m);
358 }
359
360 int MemberList::genAccels_spe_c_funcBodies(XStr& str) {
361     int rtn = 0;
362     for (list<Member*>::iterator i = members.begin(); i != members.end(); ++i)
363         if (*i)
364             rtn += (*i)->genAccels_spe_c_funcBodies(str);
365     return rtn;
366 }
367 void MemberList::genAccels_spe_c_regFuncs(XStr& str) {
368     perElemGen(members, str, &Member::genAccels_spe_c_regFuncs);
369 }
370 void MemberList::genAccels_spe_c_callInits(XStr& str) {
371     perElemGen(members, str, &Member::genAccels_spe_c_callInits);
372 }
373 void MemberList::genAccels_spe_h_includes(XStr& str) {
374     perElemGen(members, str, &Member::genAccels_spe_h_includes);
375 }
376 void MemberList::genAccels_spe_h_fiCountDefs(XStr& str) {
377     perElemGen(members, str, &Member::genAccels_spe_h_fiCountDefs);
378 }
379 void MemberList::genAccels_ppe_c_regFuncs(XStr& str) {
380     perElemGen(members, str, &Member::genAccels_ppe_c_regFuncs);
381 }
382
383
384 void
385 Chare::print(XStr& str)
386 {
387   if(external)
388     str << "extern ";
389   if(templat)
390     templat->genSpec(str);
391
392   str << chareTypeName()<<" "<<type;
393   if(bases) { str << ": "; bases->print(str); }
394   if(list) {
395     str << "{\n"; list->print(str); str << "};\n";
396   } else {
397     str << ";\n";
398   }
399 }
400
401 void
402 Message::print(XStr& str)
403 {
404   if(external)
405     str << "extern ";
406   if(templat)
407     templat->genSpec(str);
408   str << "message ";
409   type->print(str);
410   printVars(str);
411   str << ";\n";
412 }
413
414 void
415 TType::print(XStr& str)
416 {
417   str << "class ";
418   type->print(str);
419   if(init) {
420     str << "=";
421     init->print(str);
422   }
423 }
424
425 void
426 TName::print(XStr& str)
427 {
428   type->print(str);
429   str << " "<<name;
430   if(val) {
431     str << "=";
432     str << val;
433   }
434 }
435
436
437 void
438 TVarList::print(XStr& str)
439 {
440   tvar->print(str);
441   if(next) {
442     str << ", ";
443     next->print(str);
444   }
445 }
446
447 void
448 Template::print(XStr& str)
449 {
450   if(entity)
451     entity->print(str);
452 }
453
454 void
455 Entry::print(XStr& str)
456 {
457   if(isThreaded())
458     str << "threaded ";
459   if(isSync())
460     str << "sync ";
461   if(retType) {
462     retType->print(str);
463     str << " ";
464   }
465   str << name<<"(";
466   if(param)
467     param->print(str);
468   str << ")";
469   if(stacksize) {
470     str << " stacksize = ";
471     stacksize->print(str);
472   }
473   str << ";\n";
474 }
475
476 void
477 Module::print(XStr& str)
478 {
479   if(external)
480     str << "extern ";
481   str << "module "<<name;
482   if(clist) {
483     str << " {\n";
484     clist->print(str);
485     str << "}\n";
486   } else {
487     str << ";\n";
488   }
489 }
490
491 void
492 Module::generate()
493 {
494   using std::ofstream;
495   XStr declstr, defstr;
496   XStr pubDeclStr, pubDefStr, pubDefConstr;
497
498   // DMK - Accel Support
499   #if CMK_CELL != 0
500   XStr accelstr_spe_c, accelstr_spe_h;
501   #endif
502
503   declstr <<
504   "#ifndef _DECL_"<<name<<"_H_\n"
505   "#define _DECL_"<<name<<"_H_\n"
506   "#include \"charm++.h\"\n";
507   if (fortranMode) declstr << "#include \"charm-api.h\"\n";
508   if (clist) clist->genDecls(declstr);
509   declstr << "extern void _register"<<name<<"(void);\n";
510   if(isMain()) {
511     declstr << "extern \"C\" void CkRegisterMainModule(void);\n";
512   }
513   declstr << "#endif"<<endx;
514   // Generate the publish class if there are structured dagger connect entries
515   int connectPresent = 0;
516   if (clist) clist->genPub(pubDeclStr, pubDefStr, pubDefConstr, connectPresent);
517   if (connectPresent == 1) {
518      pubDeclStr << "};\n\n";
519      pubDefConstr <<"}\n\n";
520   }
521
522   // defstr << "#ifndef _DEFS_"<<name<<"_H_"<<endx;
523   // defstr << "#define _DEFS_"<<name<<"_H_"<<endx;
524   genDefs(defstr);
525   templateGuardBegin(false, defstr);
526   defstr <<
527   "void _register"<<name<<"(void)\n"
528   "{\n"
529   "  static int _done = 0; if(_done) return; _done = 1;\n";
530   if (clist) clist->genReg(defstr);
531   defstr << "}\n";
532   if(isMain()) {
533     if (fortranMode) defstr << "extern void _registerf90main(void);\n";
534     defstr << "extern \"C\" void CkRegisterMainModule(void) {\n";
535     if (fortranMode) { // For Fortran90
536       defstr << "  // FORTRAN\n";
537       defstr << "  _registerf90main();\n";
538     }
539     defstr <<
540     "  _register"<<name<<"();\n"
541     "}\n";
542   }
543   templateGuardEnd(defstr);
544   // defstr << "#endif"<<endx;
545
546
547   // DMK - Accel Support
548   #if CMK_CELL != 0
549
550   /// Generate the SPE code file contents ///
551   accelstr_spe_c << "#ifndef __ACCEL_" << name << "_C__\n"
552                  << "#define __ACCEL_" << name << "_C__\n\n\n";
553   int numAccelEntries = genAccels_spe_c_funcBodies(accelstr_spe_c);
554   accelstr_spe_c << "\n\n#endif //__ACCEL_" << name << "_C__\n";
555
556   /// Generate the SPE header file contents ///
557   accelstr_spe_h << "#ifndef __ACCEL_" << name << "_H__\n"
558                  << "#define __ACCEL_" << name << "_H__\n\n\n";
559   genAccels_spe_h_includes(accelstr_spe_h);
560   accelstr_spe_h << "\n\n";
561   accelstr_spe_h << "#define MODULE_" << name << "_FUNC_INDEX_COUNT (" << numAccelEntries;
562   genAccels_spe_h_fiCountDefs(accelstr_spe_h);
563   accelstr_spe_h << ")\n\n\n";
564   accelstr_spe_h << "#endif //__ACCEL_" << name << "_H__\n";
565
566   #endif
567
568
569   XStr topname, botname;
570   topname<<name<<".decl.h";
571   botname<<name<<".def.h";
572   ofstream decl(topname.get_string()), def(botname.get_string());
573   if(!decl || !def) {
574     cerr<<"Cannot open "<<topname.get_string()<<"or "
575         <<botname.get_string()<<" for writing!!\n";
576     die("cannot create output files (check directory permissions)\n");
577   }
578   decl<<declstr.get_string();
579   def<<defstr.get_string();
580   if (connectPresent == 1) {
581     decl << pubDeclStr.charstar();
582     def << pubDefConstr.charstar();
583     def << pubDefStr.charstar();
584   }
585
586   // DMK - Accel Support
587   #if CMK_CELL != 0
588
589   /// Generate this module's code (actually create the files) ///
590   XStr accelname_c, accelname_h;
591   accelname_c << name << ".genSPECode.c";
592   accelname_h << name << ".genSPECode.h";
593   ofstream accel_c(accelname_c.get_string()), accel_h(accelname_h.get_string());
594   if (!accel_c) {
595     cerr << "Cannot open " << accelname_c.get_string() << " for writing!!\n";
596     die("Cannot create output files (check directory permissions)\n");
597   }
598   if (!accel_h) {
599     cerr << "Cannot open " << accelname_h.get_string() << " for writing!!\n";
600     die("Cannot create output files (check directory permissions)\n");
601   }
602   accel_c << accelstr_spe_c.get_string();
603   accel_h << accelstr_spe_h.get_string();
604   
605   // If this is the main module, generate the general C file and include this modules accel.h file
606   if (isMain()) {
607
608     XStr mainAccelStr_c;
609     mainAccelStr_c << "#include \"main__funcLookup__.genSPECode.h" << "\"\n"
610                    << "#include \"" << name << ".genSPECode.c" << "\"\n";
611     ofstream mainAccel_c("main__funcLookup__.genSPECode.c");
612     if (!mainAccel_c) {
613       cerr << "Cannot open main__funcLookup__.genSPECode.c for writing!!\n";
614       die("Cannot create output files (check directory permissions)");
615     }
616     mainAccel_c << mainAccelStr_c.get_string();
617
618     XStr mainAccelStr_h;
619     mainAccelStr_h << "#ifndef __MAIN_FUNCLOOKUP_H__\n"
620                    << "#define __MAIN_FUNCLOOKUP_H__\n\n"
621                    << "#include <spu_intrinsics.h>\n"
622                    << "#include <stdlib.h>\n"
623                    << "#include <stdio.h>\n"
624                    << "#include \"spert.h\"\n\n"
625                    << "#include \"simd.h\"\n"
626                    << "#include \"" << name << ".genSPECode.h" << "\"\n\n"
627                    << "#endif //__MAIN_FUNCLOOKUP_H__\n";
628     ofstream mainAccel_h("main__funcLookup__.genSPECode.h");
629     if (!mainAccel_h) {
630       cerr << "Cannot open main__funcLookup__.genSPECode.h for writing!!\n";
631       die("Cannot create output files (check directory permissions)");
632     }
633     mainAccel_h << mainAccelStr_h.get_string();
634
635   }
636
637   #endif
638 }
639
640 void
641 Module::preprocess()
642 {
643   if (clist!=NULL) clist->preprocess();
644 }
645
646 void
647 Module::genDepend(const char *cifile)
648 {
649   cout << name << ".decl.h " << name << ".def.h: "
650        << cifile << ".stamp" << endl;
651 }
652
653 void
654 ModuleList::print(XStr& str)
655 {
656     perElemGen(modules, str, &Module::print);
657 }
658
659 void
660 ModuleList::generate()
661 {
662   perElem(modules, &Module::generate);
663 }
664
665 void
666 ModuleList::preprocess()
667 {
668   perElem(modules, &Module::preprocess);
669 }
670
671 void
672 ModuleList::genDepends(std::string ciFileBaseName)
673 {
674     perElemGen(modules, ciFileBaseName.c_str(), &Module::genDepend);
675 }
676
677 void
678 Readonly::print(XStr& str)
679 {
680   if(external)
681     str << "extern ";
682   str << "readonly ";
683   if(msg)
684     str << "message ";
685   type->print(str);
686   if(msg)
687     str << " *";
688   else
689     str << " ";
690   str << name;
691   if(dims)
692     dims->print(str);
693   str << ";\n";
694 }
695
696 void
697 MemberList::setChare(Chare *c)
698 {
699     perElemGen(members, c, &Member::setChare);
700 }
701
702 void
703 ConstructList::genPub(XStr& declstr, XStr& defstr, XStr& defconstr, int& connectPresent)
704 {
705     for (list<Construct*>::iterator i = constructs.begin(); 
706          i != constructs.end(); ++i)
707         if (*i) {
708             (*i)->genPub(declstr, defstr, defconstr, connectPresent);
709             declstr << endx;
710         }
711 }
712
713 void
714 ConstructList::genDecls(XStr& str)
715 {
716     perElemGen(constructs, str, &Construct::genDecls, newLine);
717 }
718
719 void
720 ConstructList::genDefs(XStr& str)
721 {
722     perElemGen(constructs, str, &Construct::genDefs, newLine);
723 }
724
725 void
726 ConstructList::genReg(XStr& str)
727 {
728     perElemGen(constructs, str, &Construct::genReg, newLine);
729 }
730
731 void
732 ConstructList::preprocess()
733 {
734   perElem(constructs, &Construct::preprocess);
735 }
736
737 XStr Chare::proxyName(int withTemplates)
738 {
739   XStr str;
740   str<<proxyPrefix()<<type;
741   if (withTemplates) str<<tvars();
742   return str;
743 }
744
745 XStr Chare::indexName(int withTemplates)
746 {
747   XStr str;
748   str<<Prefix::Index<<type;
749   if (withTemplates) str<<tvars();
750   return str;
751 }
752
753 XStr Chare::indexList()
754 {
755   // generating "int *index1, int *index2, int *index3"
756   XStr str;
757   if (!isArray()) { // Currently, only arrays are supported
758       cerr << (char *)baseName() << ": only chare arrays are currently supported\n";
759       exit(1);
760   }
761   XStr dim = ((Array*)this)->dim();
762   if (dim==(const char*)"1D")
763     str << "const int *index1";
764   else if (dim==(const char*)"2D")
765     str << "const int *index1, const int *index2";
766   else if (dim==(const char*)"3D")
767     str << "const int *index1, const int *index2, const int *index3";
768   else {
769       cerr << (char *)baseName() << ": only up to 3 dimension chare arrays are currently supported\n";
770       exit(1);
771   }
772   return str;
773 }
774
775 static const char *forWhomStr(forWhom w)
776 {
777   switch(w) {
778   case forAll: return Prefix::Proxy;
779   case forIndividual: return Prefix::ProxyElement;
780   case forSection: return Prefix::ProxySection;
781   case forIndex: return Prefix::Index;
782   case forPython: return "";
783   default: return NULL;
784   };
785 }
786
787 void NamedType::genProxyName(XStr& str,forWhom forElement)
788 {
789     const char *prefix=forWhomStr(forElement);
790     if (prefix==NULL)
791         die("Unrecognized forElement type passed to NamedType::genProxyName");
792     if (scope) str << scope;
793     str << prefix;
794     str << name;
795     if (tparams) str << "<"<<tparams<<" >";
796 }
797
798 void TypeList::genProxyNames(XStr& str, const char *prefix, const char *middle,
799                              const char *suffix, const char *sep,forWhom forElement)
800 {
801   if(type) {
802     str << prefix;
803     type->genProxyName(str,forElement);
804     if (middle!=NULL) {
805       str << middle;
806       type->genProxyName(str,forElement);
807     }
808     str << suffix;
809   }
810   if(next) {
811     str << sep;
812     next->genProxyNames(str, prefix, middle, suffix, sep,forElement);
813   }
814 }
815 void Chare::genProxyNames(XStr& str, const char *prefix,const char *middle,
816         const char *suffix, const char *sep)
817 {
818         bases->genProxyNames(str,prefix,middle,suffix,sep,forElement);
819 }
820 void Chare::genIndexNames(XStr& str, const char *prefix,const char *middle,
821         const char *suffix, const char *sep)
822 {
823         bases->genProxyNames(str,prefix,middle,suffix,sep,forIndex);
824 }
825 char *Chare::proxyPrefix(void)
826 {
827   return (char *)forWhomStr(forElement);
828 }
829
830 //Common multiple inheritance disambiguation code
831 void Chare::sharedDisambiguation(XStr &str,const XStr &super)
832 {
833     (void)super;
834     str << "\n    void ckDelegate(CkDelegateMgr *dTo,CkDelegateData *dPtr=NULL)"
835         << "\n    { ";
836     genProxyNames(str,"      ",NULL,"::ckDelegate(dTo,dPtr); ","");
837     str << "}"
838         << "\n    void ckUndelegate(void)"
839         << "\n    { ";
840     genProxyNames(str,"      ",NULL,"::ckUndelegate(); ","");
841     str << "}"
842         << "\n    void pup(PUP::er &p)"
843         << "\n    { ";
844     genProxyNames(str,"      ",NULL,"::pup(p); ","");
845     str << "}";
846     if (isPython()) {
847       str << "\n    void registerPython(const char *str)"
848           << "\n    { CcsRegisterHandler(str, CkCallback("<<Prefix::Index<<type<<"::pyRequest(0), *this)); }";
849     }
850     str << "\n";
851 }
852
853
854 static const char *CIClassStart = // prefix, name
855 "{\n"
856 "  public:\n"
857 ;
858
859 static const char *CIClassEnd =
860 "};\n"
861 ;
862
863 Chare::Chare(int ln, attrib_t Nattr, NamedType *t, TypeList *b, MemberList *l)
864          : attrib(Nattr), type(t), list(l), bases(b)
865 {
866         line = ln;
867         entryCount=1;
868         hasElement=0;
869         forElement=forAll;
870         hasSection=0;
871         bases_CBase=NULL;
872         setTemplate(0);
873         hasSdagEntry=0;
874         if (list)
875         {
876                 list->setChare(this);
877                 //Add migration constructor to MemberList
878                 if(isMigratable()) {
879                         Entry *e=new Entry(ln,SMIGRATE,NULL,
880                           (char *)type->getBaseName(),
881                           new ParamList(new Parameter(line,
882                                 new PtrType(new NamedType("CkMigrateMessage")))),0,0,0);
883                         e->setChare(this);
884                         list=new MemberList(e,list);
885                 }
886         }
887         if (bases==NULL) //Always add Chare as a base class
888                 bases = new TypeList(new NamedType("Chare"), NULL);
889 }
890
891 void
892 Chare::genRegisterMethodDef(XStr& str)
893 {
894   if(external || type->isTemplated())
895     return;
896   templateGuardBegin(isTemplated(), str);
897   str <<  tspec() <<
898   "void "<<indexName()<<"::__register(const char *s, size_t size) {\n"
899   "  __idx = CkRegisterChare(s, size,";
900   if (isMainChare()) str << " TypeMainChare";
901   else if (isGroup()) str << " TypeGroup";
902   else if (isNodeGroup()) str << " TypeNodeGroup";
903   else if (isArray()) str << " TypeArray";
904   else if (isChare()) str << " TypeChare";
905   else str << " TypeInvalid";
906   str << ");\n";
907   if (internalMode) str << "  CkRegisterChareInCharm(__idx);\n";
908   // register all bases
909   genIndexNames(str, "  CkRegisterBase(__idx, ",NULL, "::__idx);\n", "");
910   genSubRegisterMethodDef(str);
911   if(list)
912     list->genReg(str);
913   if (hasSdagEntry) {
914       str << "  " << baseName() << "::__sdag_register(); \n";
915   }
916   str << "}\n";
917   templateGuardEnd(str);
918 }
919
920 void
921 Chare::genPub(XStr& declstr, XStr& defstr, XStr& defconstr, int& connectPresent)
922 {
923   if(type->isTemplated())
924     return;
925   else
926   {
927     if(list)
928       list->genPub(declstr, defstr, defconstr, connectPresent);
929   }
930 }
931
932 void
933 Chare::genDecls(XStr& str)
934 {
935   if(type->isTemplated())
936     return;
937   str << "/* DECLS: "; print(str); str << " */\n";
938
939   // include python header and add two methods called execute and iterate.
940   // these cannot be added to the .ci file of the PythonCCS interface since
941   // different charm object require different definitions...
942   if (isPython()) {
943     str << "#include \"PythonCCS.h\"\n";
944     if (list) {
945       Entry *etemp = new Entry(0,0,new BuiltinType("void"),"pyRequest",new ParamList(new Parameter(0,new PtrType(new NamedType("CkCcsRequestMsg",0)),"msg")),0,0,0,0);
946       list->appendMember(etemp);
947       etemp->setChare(this);
948       //etemp = new Entry(0,0,new BuiltinType("void"),"getPrint",new ParamList(new Parameter(0,new PtrType(new NamedType("CkCcsRequestMsg",0)),"msg")),0,0,0,0);
949       //list->appendMember(etemp);
950       //etemp->setChare(this);
951     }
952   }
953
954   //Forward declaration of the user-defined implementation class*/
955   str << tspec()<<" class "<<type<<";\n";
956   str << tspec()<<" class "<<Prefix::Index<<type<<";\n";
957   str << tspec()<<" class "<<Prefix::Proxy<<type<<";\n";
958   if (hasElement)
959     str << tspec()<<" class "<<Prefix::ProxyElement<<type<<";\n";
960   if (hasSection)
961     str << tspec()<<" class "<<Prefix::ProxySection<<type<<";\n";
962   if (isPython())
963     str << tspec()<<" class "<<Prefix::Python<<type<<";\n";
964
965  //Generate index class
966   str << "/* --------------- index object ------------------ */\n";
967   str << tspec()<< "class "<<Prefix::Index<<type;
968   str << ":";
969   genProxyNames(str, "public ",NULL, "", ", ");
970   if(external || type->isTemplated())
971   { //Just a template instantiation/forward declaration
972     str << ";";
973   }
974   else
975   { //Actual implementation
976     str << CIClassStart;
977     genTypedefs(str);
978     str << "    static int __idx;\n";
979     str << "    static void __register(const char *s, size_t size);\n";
980     if(list)
981       list->genIndexDecls(str);
982     str << CIClassEnd;
983   }
984   str << "/* --------------- element proxy ------------------ */\n";
985   genSubDecls(str);
986   if (hasElement) {
987     str << "/* ---------------- collective proxy -------------- */\n";
988     forElement=forAll; genSubDecls(str); forElement=forIndividual;
989   }
990   if (hasSection) {
991     str << "/* ---------------- section proxy -------------- */\n";
992     forElement=forSection; genSubDecls(str); forElement=forIndividual;
993   }
994   if (isPython()) {
995     str << "/* ---------------- python wrapper -------------- */\n";
996     genPythonDecls(str);
997   }
998
999   if(list) {
1000     //handle the case that some of the entries may be sdag Entries
1001     int sdagPresent = 0;
1002     XStr sdagStr;
1003     CParsedFile myParsedFile(this);
1004     list->collectSdagCode(&myParsedFile, sdagPresent);
1005     if(sdagPresent) {
1006       XStr classname;
1007       XStr sdagDecls;
1008       classname << baseName(0);
1009       resetNumbers();
1010       myParsedFile.doProcess(classname, sdagDecls, sdagDefs);
1011       str << sdagDecls;
1012     }
1013   }
1014
1015   // Create CBase_Whatever convenience type so that chare implementations can
1016   // avoid inheriting from a complex CBaseT templated type.
1017   TypeList *b=bases_CBase;
1018   if (b==NULL) b=bases; //Fall back to normal bases list if no CBase available
1019   if (templat) {
1020     templat->genSpec(str);
1021     str << "\nclass CBase_" << type << " : public ";
1022   } else {
1023     str << "typedef ";
1024   }
1025   str << "CBaseT" << b->length() << "<";
1026   if (isPython()) {
1027     str << Prefix::Python << type;
1028   } else {
1029     str << b;
1030   }
1031   str << ", CProxy_" << type;
1032   if (templat) {
1033     templat->genVars(str);
1034     str << " > { };\n";
1035   } else {
1036     str << "> CBase_" << type << ";\n";
1037   }
1038 }
1039
1040 void
1041 Chare::preprocess()
1042 {
1043   if(list) list->preprocess();
1044 }
1045
1046 /*This disambiguation code is needed to support
1047   multiple inheritance in Chares (Groups, Arrays).
1048   They resolve ambiguous accessor calls to the parent "super".
1049   Because mutator routines need to change *all* the base
1050   classes, mutators are generated in xi-symbol.C.
1051 */
1052 static void
1053 disambig_proxy(XStr &str, const XStr &super)
1054 {
1055   str << "\n    int ckIsDelegated(void) const"
1056       << "\n    { return " << super << "::ckIsDelegated(); }"
1057       << "\n    inline CkDelegateMgr *ckDelegatedTo(void) const"
1058       << "\n    { return " << super << "::ckDelegatedTo(); }"
1059       << "\n    inline CkDelegateData *ckDelegatedPtr(void) const"
1060       << "\n    { return " << super << "::ckDelegatedPtr(); }"
1061       << "\n    CkGroupID ckDelegatedIdx(void) const"
1062       << "\n    { return " << super << "::ckDelegatedIdx(); }"
1063       << "\n";
1064 }
1065
1066 void
1067 Chare::genSubDecls(XStr& str)
1068 {
1069   XStr ptype;
1070   ptype<<proxyPrefix()<<type;
1071
1072   // Class declaration
1073   str << tspec()<< "class "<<ptype;
1074   if(external || type->isTemplated()) {
1075     str << ";";
1076     return;
1077   }
1078   str << ":";
1079   genProxyNames(str, "public ",NULL, "", ", ");
1080   str << CIClassStart;
1081
1082   genTypedefs(str);
1083
1084   // Various constructors:
1085   str << "    "<<ptype<<"(void) {};\n";
1086
1087   str << "    "<<ptype<<"(CkChareID __cid) : ";
1088   genProxyNames(str, "",NULL, "(__cid)", ", ");
1089   str << "{  }\n";
1090
1091   str << "    "<<ptype<<"(const Chare *c) : ";
1092   genProxyNames(str, "",NULL, "(c)", ", ");
1093   str << "{  }\n";
1094
1095   //Multiple inheritance-- resolve inheritance ambiguity
1096     XStr super;
1097     bases->getFirst()->genProxyName(super,forElement);
1098     disambig_proxy(str, super);
1099     str << "\n    inline void ckCheck(void) const"
1100         << "\n    { "<< super << "::ckCheck(); }"
1101         << "\n    const CkChareID &ckGetChareID(void) const"
1102         << "\n    { return " << super << "::ckGetChareID(); }"
1103         << "\n    operator const CkChareID &(void) const"
1104         << "\n    { return ckGetChareID(); }"
1105         << "\n";
1106
1107     sharedDisambiguation(str,super);
1108     str << "\n    void ckSetChareID(const CkChareID &c)"
1109         << "\n    {";
1110     genProxyNames(str,"      ",NULL,"::ckSetChareID(c); ","");
1111     str << "}"
1112         << "\n    "<<type<<tvars()<<" *ckLocal(void) const"
1113         << "\n    { return ("<<type<<tvars()<<" *)CkLocalChare(&ckGetChareID()); }"
1114         << "\n";
1115
1116   if(list)
1117     list->genDecls(str);
1118   str << CIClassEnd;
1119   if (!isTemplated()) str << "PUPmarshall("<<ptype<<")\n";
1120 }
1121
1122 void Chare::genPythonDecls(XStr& str) {
1123
1124   XStr ptype;
1125   ptype<<Prefix::Python<<type;
1126
1127   // Class declaration
1128   str << tspec()<< "class "<<ptype;
1129   if(external || type->isTemplated()) {
1130     str << ";";
1131     return;
1132   }
1133   str << ":";
1134   TypeList *b=bases_CBase;
1135   if (b==NULL) b=bases; //Fall back to normal bases list if no CBase available
1136   b->genProxyNames(str,"public ",NULL,"",", ",forPython);
1137   str << ", public PythonObject ";
1138   str << CIClassStart;
1139
1140   // default constructor methods
1141   str << "    "<<ptype<<"(void) {}\n";
1142   str << "    "<<ptype<<"(CkMigrateMessage *msg): ";
1143   b->genProxyNames(str,"",NULL,"(msg)",", ",forPython);
1144   str << " {}\n";
1145
1146   // define pupper
1147   str << "    void pup(PUP::er &p) {\n";
1148   b->genProxyNames(str,"      ",NULL,"::pup(p);","\n",forPython);
1149   str << "\n    }\n";
1150
1151   // define the python custom methods and their documentation
1152   str << "    static PyMethodDef CkPy_MethodsCustom[];\n";
1153   str << "    PyMethodDef *getMethods(void) {return CkPy_MethodsCustom;}\n";
1154   str << "    static const char *CkPy_MethodsCustomDoc;\n";
1155   str << "    const char *getMethodsDoc(void) {return CkPy_MethodsCustomDoc;}\n";
1156
1157   str << CIClassEnd;
1158
1159   // declare all static python methods and CkPy_MethodsCustom
1160   if (list)
1161     list->genPythonDecls(str);
1162   str << "\n";
1163
1164   if (!isTemplated()) str << "PUPmarshall("<<ptype<<")\n";
1165 }
1166
1167 void Chare::genPythonDefs(XStr& str) {
1168
1169   XStr ptype;
1170   ptype<<Prefix::Python<<type;
1171
1172   // generate the python methods array
1173   str << "PyMethodDef "<<ptype<<"::CkPy_MethodsCustom[] = {\n";
1174   if (list)
1175     list->genPythonStaticDefs(str);
1176   str << "  {NULL, NULL}\n};\n\n";
1177   // generate documentaion for the methods
1178   str << "const char * "<<ptype<<"::CkPy_MethodsCustomDoc = \"charm.__doc__ = \\\"Available methods for object "<<type<<":\\\\n\"";
1179   if (list)
1180     list->genPythonStaticDocs(str);
1181   str << "\n  \"\\\"\";\n\n";
1182
1183   if (list)
1184     list->genPythonDefs(str);
1185
1186 }
1187
1188 Group::Group(int ln, attrib_t Nattr,
1189         NamedType *t, TypeList *b, MemberList *l)
1190         :Chare(ln,Nattr|CGROUP,t,b,l)
1191 {
1192         hasElement=1;
1193         forElement=forIndividual;
1194         hasSection=1;
1195         bases_CBase=NULL;
1196         if (b==NULL) {//Add Group as a base class
1197                 delete bases;
1198                 if (isNodeGroup())
1199                         bases = new TypeList(new NamedType("NodeGroup"), NULL);
1200                 else {
1201                         bases = new TypeList(new NamedType("IrrGroup"), NULL);
1202                         bases_CBase = new TypeList(new NamedType("Group"), NULL);
1203                 }
1204         }
1205 }
1206
1207 void Group::genSubRegisterMethodDef(XStr& str) {
1208         if(!isTemplated()){
1209                 str << "   CkRegisterGroupIrr(__idx,"<<type<<"::isIrreducible());\n";
1210         }else{
1211                 str << "   CkRegisterGroupIrr(__idx," <<type<<tvars() <<"::isIrreducible());\n";
1212         }
1213 }
1214
1215 static void
1216 disambig_reduction_client(XStr &str, const XStr &super)
1217 {
1218   str << "\n    inline void setReductionClient(CkReductionClientFn fn,void *param=NULL) const"
1219       << "\n    { " << super << "::setReductionClient(fn,param); }"
1220       << "\n    inline void ckSetReductionClient(CkReductionClientFn fn,void *param=NULL) const"
1221       << "\n    { " << super << "::ckSetReductionClient(fn,param); }"
1222       << "\n    inline void ckSetReductionClient(CkCallback *cb) const"
1223       << "\n    { " << super << "::ckSetReductionClient(cb); }"
1224       << "\n";
1225 }
1226
1227 static void
1228 disambig_group(XStr &str, const XStr &super)
1229 {
1230   disambig_proxy(str, super);
1231   str << "inline void ckCheck(void) const {" << super << "::ckCheck();}\n"
1232       << "CkChareID ckGetChareID(void) const\n"
1233       << "   {return " << super << "::ckGetChareID();}\n"
1234       << "CkGroupID ckGetGroupID(void) const\n"
1235       << "   {return " << super << "::ckGetGroupID();}\n"
1236       << "operator CkGroupID () const { return ckGetGroupID(); }\n";
1237   disambig_reduction_client(str, super);
1238 }
1239
1240 void
1241 Group::genSubDecls(XStr& str)
1242 {
1243   XStr ptype; ptype<<proxyPrefix()<<type;
1244   XStr ttype; ttype<<type<<tvars();
1245   XStr super;
1246   bases->getFirst()->genProxyName(super,forElement);
1247
1248   // Class declaration:
1249   str << tspec()<< "class "<<ptype;
1250   if(external || type->isTemplated()) {
1251     str << ";";
1252     return;
1253   }
1254   str << ": ";
1255   genProxyNames(str, "public ",NULL, "", ", ");
1256   str << CIClassStart;
1257
1258   genTypedefs(str);
1259
1260   // Basic constructors:
1261   str << "    "<<ptype<<"(void) {}\n";
1262   str << "    "<<ptype<<"(const IrrGroup *g) : ";
1263   genProxyNames(str, "", NULL,"(g)", ", ");
1264   str << "{  }\n";
1265
1266   if (forElement==forIndividual)
1267   {//For a single element
1268     str << "    "<<ptype<<"(CkGroupID _gid,int _onPE,CK_DELCTOR_PARAM) : ";
1269     genProxyNames(str, "", NULL,"(_gid,_onPE,CK_DELCTOR_ARGS)", ", ");
1270     str << "{  }\n";
1271     str << "    "<<ptype<<"(CkGroupID _gid,int _onPE) : ";
1272     genProxyNames(str, "", NULL,"(_gid,_onPE)", ", ");
1273     str << "{  }\n";
1274
1275     disambig_group(str, super);
1276     str << "int ckGetGroupPe(void) const\n"
1277         << "{return " << super << "::ckGetGroupPe();}\n";
1278
1279   }
1280   else if (forElement==forSection)
1281   {//For a section of the group
1282     str << "    "<<ptype<<"(const CkGroupID &_gid,const int *_pelist,int _npes,CK_DELCTOR_PARAM) : ";
1283     genProxyNames(str, "", NULL,"(_gid,_pelist,_npes,CK_DELCTOR_ARGS)", ", ");
1284     str << "{  }\n";
1285     str << "    "<<ptype<<"(const CkGroupID &_gid,const int *_pelist,int _npes) : ";
1286     genProxyNames(str, "", NULL,"(_gid,_pelist,_npes)", ", ");
1287     str << "{  }\n";
1288     str << "    "<<ptype<<"(int n,const CkGroupID *_gid, int const * const *_pelist,const int *_npes) : ";
1289     genProxyNames(str, "", NULL,"(n,_gid,_pelist,_npes)", ", ");
1290     str << "{  }\n";
1291     str << "    "<<ptype<<"(int n,const CkGroupID *_gid, int const * const *_pelist,const int *_npes,CK_DELCTOR_PARAM) : ";
1292     genProxyNames(str, "", NULL,"(n,_gid,_pelist,_npes,CK_DELCTOR_ARGS)", ", ");
1293     str << "{  }\n";
1294     
1295     disambig_group(str, super);
1296     str << "inline int ckGetNumSections() const\n" <<
1297       "{ return " << super << "::ckGetNumSections(); }\n" <<
1298       "inline CkSectionInfo &ckGetSectionInfo()\n" <<
1299       "{ return " << super << "::ckGetSectionInfo(); }\n" <<
1300       "inline CkSectionID *ckGetSectionIDs()\n" <<
1301       "{ return " << super << "::ckGetSectionIDs(); }\n" <<
1302       "inline CkSectionID &ckGetSectionID()\n" <<
1303       "{ return " << super << "::ckGetSectionID(); }\n" <<
1304       "inline CkSectionID &ckGetSectionID(int i)\n" <<
1305       "{ return " << super << "::ckGetSectionID(i); }\n" <<
1306       "inline CkGroupID ckGetGroupIDn(int i) const\n" <<
1307       "{ return " << super << "::ckGetGroupIDn(i); }\n" <<
1308       "inline int *ckGetElements() const\n" <<
1309       "{ return " << super << "::ckGetElements(); }\n" <<
1310       "inline int *ckGetElements(int i) const\n" <<
1311       "{ return " << super << "::ckGetElements(i); }\n" <<
1312       "inline int ckGetNumElements() const\n" <<
1313       "{ return " << super << "::ckGetNumElements(); } \n" <<
1314       "inline int ckGetNumElements(int i) const\n" <<
1315       "{ return " << super << "::ckGetNumElements(i); }\n";
1316   }
1317   else if (forElement==forAll)
1318   {//For whole group
1319     str << "    "<<ptype<<"(CkGroupID _gid,CK_DELCTOR_PARAM) : ";
1320     genProxyNames(str, "", NULL,"(_gid,CK_DELCTOR_ARGS)", ", ");
1321     str << "{  }\n";
1322     str << "    "<<ptype<<"(CkGroupID _gid) : ";
1323     genProxyNames(str, "", NULL,"(_gid)", ", ");
1324     str << "{  }\n";
1325
1326     //Group proxy can be indexed into an element proxy:
1327     forElement=forIndividual;//<- for the proxyName below
1328     str << "    "<<proxyName(1)<<" operator[](int onPE) const\n";
1329     str << "      {return "<<proxyName(1)<<"(ckGetGroupID(),onPE,CK_DELCTOR_CALL);}\n";
1330     forElement=forAll;
1331
1332     disambig_group(str, super);
1333   }
1334
1335   //Multiple inheritance-- resolve inheritance ambiguity
1336   sharedDisambiguation(str,super);
1337   str<<"    void ckSetGroupID(CkGroupID g) {\n";
1338   genProxyNames(str,"      ",NULL,"::ckSetGroupID(g);\n","");
1339   str<<"    }\n";
1340
1341   str << "    "<<ttype<<"* ckLocalBranch(void) const {\n";
1342   str << "      return ckLocalBranch(ckGetGroupID());\n";
1343   str << "    }\n";
1344   str << "    static "<<ttype<< "* ckLocalBranch(CkGroupID gID) {\n";
1345   str << "      return ("<<ttype<<"*)";
1346   if(isNodeGroup())
1347     str << "CkLocalNodeBranch(gID);\n";
1348   else
1349     str << "CkLocalBranch(gID);\n";
1350   str << "    }\n";
1351   if(list)
1352     list->genDecls(str);
1353   str << CIClassEnd;
1354   if (!isTemplated()) str << "PUPmarshall("<<ptype<<")\n";
1355
1356 }
1357
1358 XStr indexSuffix2object(const XStr &indexSuffix) {
1359         if (indexSuffix==(const char*)"1D") return "CkIndex1D";
1360         if (indexSuffix==(const char*)"2D") return "CkIndex2D";
1361         if (indexSuffix==(const char*)"3D") return "CkIndex3D";
1362         if (indexSuffix==(const char*)"4D") return "CkIndex4D";
1363         if (indexSuffix==(const char*)"5D") return "CkIndex5D";
1364         if (indexSuffix==(const char*)"6D") return "CkIndex6D";
1365         if (indexSuffix==(const char*)"Max") return "CkIndexMax";
1366         else return indexSuffix;
1367 }
1368
1369 //Array Constructor
1370 Array::Array(int ln, attrib_t Nattr, NamedType *index,
1371         NamedType *t, TypeList *b, MemberList *l)
1372     : Chare(ln,Nattr|CARRAY|CMIGRATABLE,t,b,l)
1373 {
1374         hasElement=1;
1375         forElement=forIndividual;
1376         hasSection=1;
1377         index->print(indexSuffix);
1378       //printf("indexSuffix = %s\n", indexSuffix.charstar());
1379         if (indexSuffix!=(const char*)"none")
1380                 indexType<<"CkArrayIndex"<<indexSuffix;
1381         else indexType<<"CkArrayIndex";
1382
1383         if(b==0) { //No other base class:
1384                 delete bases;
1385                 if (0==strcmp(type->getBaseName(),"ArrayElement"))
1386                         //ArrayElement has special "ArrayBase" superclass
1387                         bases = new TypeList(new NamedType("ArrayBase"), NULL);
1388                 else {//Everybody else inherits from ArrayElementT<indexType>
1389                         bases=new TypeList(new NamedType("ArrayElement"),NULL);
1390                         XStr indexObject(indexSuffix2object(indexSuffix));
1391                         XStr parentClass;
1392                         parentClass<<"ArrayElementT<"<<indexObject<<">";
1393                         char *parentClassName=strdup(parentClass);
1394                         bases_CBase = new TypeList(new NamedType(parentClassName), NULL);
1395                 }
1396         }
1397 }
1398
1399 static void
1400 disambig_array(XStr &str, const XStr &super)
1401 {
1402   disambig_proxy(str, super);
1403   str << "\n    inline void ckCheck(void) const"
1404       << "\n    { " << super << "::ckCheck(); }"
1405       << "\n    inline operator CkArrayID () const"
1406       << "\n    { return ckGetArrayID(); }"
1407       << "\n    inline CkArrayID ckGetArrayID(void) const"
1408       << "\n    { return " << super << "::ckGetArrayID(); }"
1409       << "\n    inline CkArray *ckLocalBranch(void) const"
1410       << "\n    { return " << super << "::ckLocalBranch(); }"
1411       << "\n    inline CkLocMgr *ckLocMgr(void) const"
1412       << "\n    { return " << super << "::ckLocMgr(); }"
1413       << "\n"
1414       << "\n    inline static CkArrayID ckCreateEmptyArray(void)"
1415       << "\n    { return " << super << "::ckCreateEmptyArray(); }"
1416       << "\n    inline static CkArrayID ckCreateArray(CkArrayMessage *m,int ctor,const CkArrayOptions &opts)"
1417       << "\n    { return " << super << "::ckCreateArray(m,ctor,opts); }"
1418       << "\n    inline void ckInsertIdx(CkArrayMessage *m,int ctor,int onPe,const CkArrayIndex &idx)"
1419       << "\n    { " << super << "::ckInsertIdx(m,ctor,onPe,idx); }"
1420       << "\n    inline void doneInserting(void)"
1421       << "\n    { " << super << "::doneInserting(); }"
1422       << "\n"
1423       << "\n    inline void ckBroadcast(CkArrayMessage *m, int ep, int opts=0) const"
1424       << "\n    { " << super << "::ckBroadcast(m,ep,opts); }";
1425   disambig_reduction_client(str, super);
1426 }
1427
1428 void
1429 Array::genSubDecls(XStr& str)
1430 {
1431   XStr ptype; ptype<<proxyPrefix()<<type;
1432
1433   // Class declaration:
1434   str << tspec()<< " class "<<ptype;
1435   if(external || type->isTemplated()) {
1436     str << ";";
1437     return;
1438   }
1439   str << " : ";
1440   genProxyNames(str, "public ",NULL, "", ", ");
1441   str << CIClassStart;
1442
1443   genTypedefs(str);
1444
1445   str << "    "<<ptype<<"(void) {}\n";//An empty constructor
1446   if (forElement!=forSection)
1447   { //Generate constructor based on array element
1448           str << "    "<<ptype<<"(const ArrayElement *e) : ";
1449     genProxyNames(str, "", NULL,"(e)", ", ");
1450     str << "{  }\n";
1451   }
1452
1453   //Resolve multiple inheritance ambiguity
1454   XStr super;
1455   bases->getFirst()->genProxyName(super,forElement);
1456   sharedDisambiguation(str,super);
1457
1458   if (forElement==forIndividual)
1459   {/*For an individual element (no indexing)*/
1460     disambig_array(str, super);
1461     str << "\n    inline void ckInsert(CkArrayMessage *m,int ctor,int onPe)"
1462         << "\n    { " << super << "::ckInsert(m,ctor,onPe); }"
1463         << "\n    inline void ckSend(CkArrayMessage *m, int ep, int opts = 0) const"
1464         << "\n    { " << super << "::ckSend(m,ep,opts); }"
1465         << "\n    inline void *ckSendSync(CkArrayMessage *m, int ep) const"
1466         << "\n    { return " << super << "::ckSendSync(m,ep); }"
1467         << "\n    inline const CkArrayIndex &ckGetIndex() const"
1468         << "\n    { return " << super << "::ckGetIndex(); }"
1469         << "\n"
1470         << "\n    " << type << tvars() << " *ckLocal(void) const"
1471         << "\n    { return ("<<type<<tvars()<<" *)"<<super<<"::ckLocal(); }"
1472         << "\n";
1473
1474     //This constructor is used for array indexing
1475     str << "\n    " <<ptype<<"(const CkArrayID &aid,const "<<indexType<<" &idx,CK_DELCTOR_PARAM)"
1476         << "\n        :";
1477     genProxyNames(str, "",NULL, "(aid,idx,CK_DELCTOR_ARGS)", ", ");
1478     str << "\n    {}"
1479         << "\n    " <<ptype<<"(const CkArrayID &aid,const "<<indexType<<" &idx)"
1480         << "\n        :";
1481     genProxyNames(str, "",NULL, "(aid,idx)", ", ");
1482     str << "\n    {}"
1483         << "\n";
1484
1485     if ((indexType != (const char*)"CkArrayIndex") && (indexType != (const char*)"CkArrayIndexMax"))
1486     {
1487       // Emit constructors that take the base class array index too.  This proves
1488       // useful for runtime code that needs to access an element via a CkArrayIndex and
1489       // an array proxy. This might compromise type safety a wee bit and is hence not
1490       // propagated throughout.  For eg, CProxy_Foo::operator[] still accepts only the
1491       // appropriate CkArrayIndexND.
1492       str << "\n    " <<ptype<<"(const CkArrayID &aid,const CkArrayIndex &idx,CK_DELCTOR_PARAM)"
1493           << "\n        :";
1494       genProxyNames(str, "",NULL, "(aid,idx,CK_DELCTOR_ARGS)", ", ");
1495       str << "\n    {}"
1496           << "\n    " << ptype<<"(const CkArrayID &aid,const CkArrayIndex &idx)"
1497           << "\n        :";
1498       genProxyNames(str, "",NULL, "(aid,idx)", ", ");
1499       str << "\n    {}"
1500           << "\n";
1501     }
1502   }
1503   else if (forElement==forAll)
1504   {/*Collective, indexible version*/
1505     disambig_array(str, super);
1506
1507     //Build a simple, empty array
1508     str << "\n    static CkArrayID ckNew(void) { return ckCreateEmptyArray(); }";
1509
1510     XStr etype; etype<<Prefix::ProxyElement<<type<<tvars();
1511     if (indexSuffix!=(const char*)"none")
1512     {
1513       str << "\n    // Generalized array indexing:"
1514           << "\n    "<<etype<<" operator [] (const "<<indexType<<" &idx) const"
1515           << "\n    { return "<<etype<<"(ckGetArrayID(), idx, CK_DELCTOR_CALL); }"
1516           << "\n    "<<etype<<" operator() (const "<<indexType<<" &idx) const"
1517           << "\n    { return "<<etype<<"(ckGetArrayID(), idx, CK_DELCTOR_CALL); }"
1518           << "\n";
1519     }
1520
1521   //Add specialized indexing for these common types
1522     if (indexSuffix==(const char*)"1D")
1523     {
1524     str << "    " << etype << " operator [] (int idx) const \n"
1525         << "        {return "<< etype <<"(ckGetArrayID(), CkArrayIndex1D(idx), CK_DELCTOR_CALL);}\n"
1526         << "    " << etype <<" operator () (int idx) const \n"
1527         << "        {return "<< etype <<"(ckGetArrayID(), CkArrayIndex1D(idx), CK_DELCTOR_CALL);}\n";
1528     } else if (indexSuffix==(const char*)"2D") {
1529     str <<
1530     "    "<<etype<<" operator () (int i0,int i1) const \n"
1531     "        {return "<<etype<<"(ckGetArrayID(), CkArrayIndex2D(i0,i1), CK_DELCTOR_CALL);}\n"
1532     "    "<<etype<<" operator () (CkIndex2D idx) const \n"
1533     "        {return "<<etype<<"(ckGetArrayID(), CkArrayIndex2D(idx), CK_DELCTOR_CALL);}\n";
1534     } else if (indexSuffix==(const char*)"3D") {
1535     str <<
1536     "    "<<etype<<" operator () (int i0,int i1,int i2) const \n"
1537     "        {return "<<etype<<"(ckGetArrayID(), CkArrayIndex3D(i0,i1,i2), CK_DELCTOR_CALL);}\n"
1538     "    "<<etype<<" operator () (CkIndex3D idx) const \n"
1539     "        {return "<<etype<<"(ckGetArrayID(), CkArrayIndex3D(idx), CK_DELCTOR_CALL);}\n";
1540     } else if (indexSuffix==(const char*)"4D") {
1541     str <<
1542     "    "<<etype<<" operator () (short int i0,short int i1,short int i2,short int i3) const \n"
1543     "        {return "<<etype<<"(ckGetArrayID(), CkArrayIndex4D(i0,i1,i2,i3), CK_DELCTOR_CALL);}\n"
1544     "    "<<etype<<" operator () (CkIndex4D idx) const \n"
1545     "        {return "<<etype<<"(ckGetArrayID(), CkArrayIndex4D(idx), CK_DELCTOR_CALL);}\n";
1546     } else if (indexSuffix==(const char*)"5D") {
1547     str <<
1548     "    "<<etype<<" operator () (short int i0,short int i1,short int i2,short int i3,short int i4) const \n"
1549     "        {return "<<etype<<"(ckGetArrayID(), CkArrayIndex5D(i0,i1,i2,i3,i4), CK_DELCTOR_CALL);}\n"
1550     "    "<<etype<<" operator () (CkIndex5D idx) const \n"
1551     "        {return "<<etype<<"(ckGetArrayID(), CkArrayIndex5D(idx), CK_DELCTOR_CALL);}\n";
1552     } else if (indexSuffix==(const char*)"6D") {
1553     str <<
1554     "    "<<etype<<" operator () (short int i0,short int i1,short int i2,short int i3,short int i4,short int i5) const \n"
1555     "        {return "<<etype<<"(ckGetArrayID(), CkArrayIndex6D(i0,i1,i2,i3,i4,i5), CK_DELCTOR_CALL);}\n"
1556     "    "<<etype<<" operator () (CkIndex6D idx) const \n"
1557     "        {return "<<etype<<"(ckGetArrayID(), CkArrayIndex6D(idx), CK_DELCTOR_CALL);}\n";
1558     }
1559     str <<"    "<<ptype<<"(const CkArrayID &aid,CK_DELCTOR_PARAM) \n"
1560          "        :";genProxyNames(str, "",NULL, "(aid,CK_DELCTOR_ARGS)", ", ");str<<" {}\n";
1561     str <<"    "<<ptype<<"(const CkArrayID &aid) \n"
1562          "        :";genProxyNames(str, "",NULL, "(aid)", ", ");str<<" {}\n";
1563   }
1564   else if (forElement==forSection)
1565   { /* for Section, indexible version*/
1566     disambig_array(str, super);
1567     str << "\n    inline void ckSend(CkArrayMessage *m, int ep, int opts = 0)"
1568         << "\n    { " << super << "::ckSend(m,ep,opts); }"
1569         << "\n    inline CkSectionInfo &ckGetSectionInfo()"
1570         << "\n    { return " << super << "::ckGetSectionInfo(); }"
1571         << "\n    inline CkSectionID *ckGetSectionIDs()"
1572         << "\n    { return " << super << "::ckGetSectionIDs(); }"
1573         << "\n    inline CkSectionID &ckGetSectionID()"
1574         << "\n    { return " << super << "::ckGetSectionID(); }"
1575         << "\n    inline CkSectionID &ckGetSectionID(int i)"
1576         << "\n    { return " << super << "::ckGetSectionID(i); }"
1577         << "\n    inline CkArrayID ckGetArrayIDn(int i) const"
1578         << "\n    { return " << super << "::ckGetArrayIDn(i); } "
1579         << "\n    inline CkArrayIndex *ckGetArrayElements() const"
1580         << "\n    { return " << super << "::ckGetArrayElements(); }"
1581         << "\n    inline CkArrayIndex *ckGetArrayElements(int i) const"
1582         << "\n    { return " << super << "::ckGetArrayElements(i); }"
1583         << "\n    inline int ckGetNumElements() const"
1584         << "\n    { return " << super << "::ckGetNumElements(); } "
1585         << "\n    inline int ckGetNumElements(int i) const"
1586         << "\n    { return " << super << "::ckGetNumElements(i); }";
1587
1588     XStr etype; etype<<Prefix::ProxyElement<<type<<tvars();
1589     if (indexSuffix!=(const char*)"none")
1590     {
1591       str <<
1592     "    // Generalized array indexing:\n"
1593     "    "<<etype<<" operator [] (const "<<indexType<<" &idx) const\n"
1594     "        {return "<<etype<<"(ckGetArrayID(), idx, CK_DELCTOR_CALL);}\n"
1595     "    "<<etype<<" operator() (const "<<indexType<<" &idx) const\n"
1596     "        {return "<<etype<<"(ckGetArrayID(), idx, CK_DELCTOR_CALL);}\n";
1597     }
1598
1599   //Add specialized indexing for these common types
1600     if (indexSuffix==(const char*)"1D")
1601     {
1602     str <<
1603     "    "<<etype<<" operator [] (int idx) const \n"
1604     "        {return "<<etype<<"(ckGetArrayID(), *(CkArrayIndex1D*)&ckGetArrayElements()[idx], CK_DELCTOR_CALL);}\n"
1605     "    "<<etype<<" operator () (int idx) const \n"
1606     "        {return "<<etype<<"(ckGetArrayID(), *(CkArrayIndex1D*)&ckGetArrayElements()[idx], CK_DELCTOR_CALL);}\n"
1607     "    static CkSectionID ckNew(const CkArrayID &aid, CkArrayIndex1D *elems, int nElems) {\n"
1608     "      return CkSectionID(aid, elems, nElems);\n"
1609     "    } \n"
1610     "    static CkSectionID ckNew(const CkArrayID &aid, int l, int u, int s) {\n"
1611     "      CkVec<CkArrayIndex1D> al;\n"
1612     "      for (int i=l; i<=u; i+=s) al.push_back(CkArrayIndex1D(i));\n"
1613     "      return CkSectionID(aid, al.getVec(), al.size());\n"
1614     "    } \n";
1615     } else if (indexSuffix==(const char*)"2D") {
1616     str <<
1617     "    "<<etype<<" operator () (int idx) const \n"
1618     "        {return "<<etype<<"(ckGetArrayID(), *(CkArrayIndex2D*)&ckGetArrayElements()[idx], CK_DELCTOR_CALL);}\n"
1619     "    static CkSectionID ckNew(const CkArrayID &aid, CkArrayIndex2D *elems, int nElems) {\n"
1620     "      return CkSectionID(aid, elems, nElems);\n"
1621     "    } \n"
1622     "    static CkSectionID ckNew(const CkArrayID &aid, int l1, int u1, int s1, int l2, int u2, int s2) {\n"
1623     "      CkVec<CkArrayIndex2D> al;\n"
1624     "      for (int i=l1; i<=u1; i+=s1) \n"
1625     "        for (int j=l2; j<=u2; j+=s2) \n"
1626     "          al.push_back(CkArrayIndex2D(i, j));\n"
1627     "      return CkSectionID(aid, al.getVec(), al.size());\n"
1628     "    } \n";
1629     } else if (indexSuffix==(const char*)"3D") {
1630     str <<
1631     "    "<<etype<<" operator () (int idx) const \n"
1632     "        {return "<<etype<<"(ckGetArrayID(), *(CkArrayIndex3D*)&ckGetArrayElements()[idx], CK_DELCTOR_CALL);}\n"
1633     "    static CkSectionID ckNew(const CkArrayID &aid, CkArrayIndex3D *elems, int nElems) {\n"
1634     "      return CkSectionID(aid, elems, nElems);\n"
1635     "    } \n"
1636     "    static CkSectionID ckNew(const CkArrayID &aid, int l1, int u1, int s1, int l2, int u2, int s2, int l3, int u3, int s3) {\n"
1637     "      CkVec<CkArrayIndex3D> al;\n"
1638     "      for (int i=l1; i<=u1; i+=s1) \n"
1639     "        for (int j=l2; j<=u2; j+=s2) \n"
1640     "          for (int k=l3; k<=u3; k+=s3) \n"
1641     "          al.push_back(CkArrayIndex3D(i, j, k));\n"
1642     "      return CkSectionID(aid, al.getVec(), al.size());\n"
1643     "    } \n";
1644     } else if (indexSuffix==(const char*)"4D") {
1645     str <<
1646     "    "<<etype<<" operator () (int idx) const \n"
1647     "        {return "<<etype<<"(ckGetArrayID(), *(CkArrayIndex4D*)&ckGetArrayElements()[idx], CK_DELCTOR_CALL);}\n"
1648     "    static CkSectionID ckNew(const CkArrayID &aid, CkArrayIndex4D *elems, int nElems) {\n"
1649     "      return CkSectionID(aid, elems, nElems);\n"
1650     "    } \n"
1651     "    static CkSectionID ckNew(const CkArrayID &aid, int l1, int u1, int s1, int l2, int u2, int s2, int l3, int u3, int s3, int l4, int u4, int s4) {\n"
1652     "      CkVec<CkArrayIndex4D> al;\n"
1653     "      for (int i=l1; i<=u1; i+=s1) \n"
1654     "        for (int j=l2; j<=u2; j+=s2) \n"
1655     "          for (int k=l3; k<=u3; k+=s3) \n"
1656     "            for (int l=l4; l<=u4; l+=s4) \n"
1657     "              al.push_back(CkArrayIndex4D(i, j, k, l));\n"
1658     "      return CkSectionID(aid, al.getVec(), al.size());\n"
1659     "    } \n";
1660     } else if (indexSuffix==(const char*)"5D") {
1661     str <<
1662     "    "<<etype<<" operator () (int idx) const \n"
1663     "        {return "<<etype<<"(ckGetArrayID(), *(CkArrayIndex5D*)&ckGetArrayElements()[idx], CK_DELCTOR_CALL);}\n"
1664     "    static CkSectionID ckNew(const CkArrayID &aid, CkArrayIndex5D *elems, int nElems) {\n"
1665     "      return CkSectionID(aid, elems, nElems);\n"
1666     "    } \n"
1667     "    static CkSectionID ckNew(const CkArrayID &aid, int l1, int u1, int s1, int l2, int u2, int s2, int l3, int u3, int s3, int l4, int u4, int s4, int l5, int u5, int s5) {\n"
1668     "      CkVec<CkArrayIndex5D> al;\n"
1669     "      for (int i=l1; i<=u1; i+=s1) \n"
1670     "        for (int j=l2; j<=u2; j+=s2) \n"
1671     "          for (int k=l3; k<=u3; k+=s3) \n"
1672     "            for (int l=l4; l<=u4; l+=s4) \n"
1673     "              for (int m=l5; m<=u5; m+=s5) \n"
1674     "                al.push_back(CkArrayIndex5D(i, j, k, l, m));\n"
1675     "      return CkSectionID(aid, al.getVec(), al.size());\n"
1676     "    } \n";
1677     } else if (indexSuffix==(const char*)"6D") {
1678     str <<
1679     "    "<<etype<<" operator () (int idx) const \n"
1680     "        {return "<<etype<<"(ckGetArrayID(), *(CkArrayIndex6D*)&ckGetArrayElements()[idx], CK_DELCTOR_CALL);}\n"
1681     "    static CkSectionID ckNew(const CkArrayID &aid, CkArrayIndex6D *elems, int nElems) {\n"
1682     "      return CkSectionID(aid, elems, nElems);\n"
1683     "    } \n"
1684     "    static CkSectionID ckNew(const CkArrayID &aid, int l1, int u1, int s1, int l2, int u2, int s2, int l3, int u3, int s3, int l4, int u4, int s4, int l5, int u5, int s5, int l6, int u6, int s6) {\n"
1685     "      CkVec<CkArrayIndex6D> al;\n"
1686     "      for (int i=l1; i<=u1; i+=s1) \n"
1687     "        for (int j=l2; j<=u2; j+=s2) \n"
1688     "          for (int k=l3; k<=u3; k+=s3) \n"
1689     "            for (int l=l4; l<=u4; l+=s4) \n"
1690     "              for (int m=l5; m<=u5; m+=s5) \n"
1691     "                for (int n=l6; n<=u6; n+=s6) \n"
1692     "                  al.push_back(CkArrayIndex6D(i, j, k, l, m, n));\n"
1693     "      return CkSectionID(aid, al.getVec(), al.size());\n"
1694     "    } \n";
1695     }
1696
1697     str <<"    "<<ptype<<"(const CkArrayID &aid, CkArrayIndex *elems, int nElems, CK_DELCTOR_PARAM) \n"
1698          "        :";genProxyNames(str, "",NULL, "(aid,elems,nElems,CK_DELCTOR_ARGS)", ", ");str << " {}\n";
1699     str <<"    "<<ptype<<"(const CkArrayID &aid, CkArrayIndex *elems, int nElems) \n"
1700          "        :";genProxyNames(str, "",NULL, "(aid,elems,nElems)", ", ");str<<" {}\n";
1701     str <<"    "<<ptype<<"(const CkSectionID &sid)"
1702           "       :";genProxyNames(str, "",NULL, "(sid)", ", ");str<< " {}\n";
1703         str <<"    "<<ptype<<"(int n, const CkArrayID *aid, CkArrayIndex const * const *elems, const int *nElems, CK_DELCTOR_PARAM) \n"
1704           "        :";genProxyNames(str, "",NULL, "(n,aid,elems,nElems,CK_DELCTOR_ARGS)", ", ");str << " {}\n";
1705         str <<"    "<<ptype<<"(int n, const CkArrayID *aid, CkArrayIndex const * const *elems, const int *nElems) \n"
1706           "        :";genProxyNames(str, "",NULL, "(n,aid,elems,nElems)", ", ");str<<" {}\n";
1707     str <<
1708     "    static CkSectionID ckNew(const CkArrayID &aid, CkArrayIndex *elems, int nElems) {\n"
1709     "      return CkSectionID(aid, elems, nElems);\n"
1710     "    } \n";
1711   }
1712
1713   if(list){
1714     list->genDecls(str);
1715   }
1716   str << CIClassEnd;
1717   if (!isTemplated()) str << "PUPmarshall("<<ptype<<")\n";
1718 }
1719
1720 void
1721 Chare::genTypedefs(XStr &str) {
1722    str << "    typedef "<<baseName(1)<<" local_t;\n";
1723    str << "    typedef "<<Prefix::Index<<baseName(1)<<" index_t;\n";
1724    str << "    typedef "<<Prefix::Proxy<<baseName(1)<<" proxy_t;\n";
1725
1726    if (hasElement)
1727      str << "    typedef "<<Prefix::ProxyElement<<baseName(1)<<" element_t;\n";
1728    else /* !hasElement, so generic proxy is element type */
1729      str << "    typedef "<<Prefix::Proxy<<baseName(1)<<" element_t;\n";
1730
1731    if (hasSection)
1732      str << "    typedef "<<Prefix::ProxySection<<baseName(1)<<" section_t;\n";
1733    str << "\n";
1734 }
1735
1736
1737
1738 void
1739 Chare::genDefs(XStr& str)
1740 {
1741   str << "/* DEFS: "; print(str); str << " */\n";
1742   if (fortranMode) { // For Fortran90
1743     if (!isArray()) { // Currently, only arrays are supported
1744       cerr << (char *)baseName() << ": only chare arrays are currently supported\n";
1745       exit(1);
1746     }
1747     // We have to generate the chare array itself
1748     str << "/* FORTRAN */\n";
1749     str << "extern \"C\" void " << fortranify(baseName(), "_allocate") << "(char **, void *, " << indexList() << ");\n";
1750     str << "extern \"C\" void " << fortranify(baseName(), "_pup") << "(pup_er p, char **, void *);\n";
1751     str << "extern \"C\" void " << fortranify(baseName(), "_resumefromsync") << "(char **, void *, " << indexList() << ");\n";
1752     str << "\n";
1753     XStr dim = ((Array*)this)->dim();
1754     str << "class " << baseName() << " : public ArrayElement" << dim << "\n";
1755     str << "{\n";
1756     str << "public:\n";
1757     str << "  char user_data[64];\n";
1758     str << "public:\n";
1759     str << "  " << baseName() << "()\n";
1760     str << "  {\n";
1761 //    str << "    CkPrintf(\"" << baseName() << " %d created\\n\",thisIndex);\n";
1762     str << "    CkArrayID *aid = &thisArrayID;\n";
1763     if (dim==(const char*)"1D")
1764       str << "    " << fortranify(baseName(), "_allocate") << "((char **)&user_data, &aid, &thisIndex);\n";
1765     else if (dim==(const char*)"2D")
1766       str << "    " << fortranify(baseName(), "_allocate") << "((char **)&user_data, &aid, &thisIndex.x, &thisIndex.y);\n";
1767     else if (dim==(const char*)"3D")
1768       str << "    " << fortranify(baseName(), "_allocate") << "((char **)&user_data, &aid, &thisIndex.x, &thisIndex.y, &thisIndex.z);\n";
1769     str << "      usesAtSync = CmiTrue;\n";
1770     str << "  }\n";
1771     str << "\n";
1772     str << "  " << baseName() << "(CkMigrateMessage *m)\n";
1773     str << "  {\n";
1774     str << "    /* CkPrintf(\"" << baseName() << " %d migrating\\n\",thisIndex);*/ \n";
1775     str << "  }\n";
1776     str << "\n";
1777
1778     str << "  virtual void pup(PUP::er &p)\n";
1779     str << "  {\n";
1780     str << "    ArrayElement" << dim << "::pup(p);\n";
1781     str << "    p(user_data, 64);\n";
1782     str << "    CkArrayID *aid = &thisArrayID;\n";
1783     str << "    ::" << fortranify(baseName(), "_pup") << "(&p, (char **)&user_data, &aid); \n";
1784     str << "  }\n";
1785     str << "\n";
1786
1787       // Define the Fortran interface function for ResumeFromSync
1788     str << "  void ResumeFromSync()\n";
1789     str << "  {\n";
1790     str << "    CkArrayID *aid = &thisArrayID;\n";
1791     str << "    ::" << fortranify(baseName(), "_resumefromSync");
1792     if (dim == (const char*)"1D") {
1793       str << "((char **)&user_data, &aid, &thisIndex);\n";
1794     }
1795     else if (dim == (const char*)"2D") {
1796       str << "((char **)&user_data, &aid, &thisIndex.x, &thisIndex.y);\n";
1797     }
1798     else if (dim == (const char*)"3D") {
1799       str << "((char **)&user_data, &aid, &thisIndex.x, &thisIndex.y, &thisIndex.z);\n";
1800     }
1801     str << "  }\n";
1802
1803     str << "};\n";
1804     str << "\n";
1805     if (dim==(const char*)"1D") {
1806       str << "extern \"C\" void " << fortranify(baseName(), "_cknew") << "(int *numElem, long *aindex)\n";
1807       str << "{\n";
1808       str << "    CkArrayID *aid = new CkArrayID;\n";
1809       str << "    *aid = CProxy_" << baseName() << "::ckNew(*numElem); \n";
1810     }
1811     else if (dim==(const char*)"2D") {
1812       str << "extern \"C\" void " << fortranify(baseName(), "_cknew") << "(int *numx, int *numy, long *aindex)\n";
1813       str << "{\n";
1814       str << "    CkArrayID *aid = new CkArrayID;\n";
1815       str << "    *aid = CProxy_" << baseName() << "::ckNew(); \n";
1816       str << "    CProxy_" << baseName() << " p(*aid);\n";
1817       str << "    for (int i=0; i<*numx; i++) \n";
1818       str << "      for (int j=0; j<*numy; j++) \n";
1819       str << "        p[CkArrayIndex2D(i, j)].insert(); \n";
1820       str << "    p.doneInserting(); \n";
1821     }
1822     else if (dim==(const char*)"3D") {
1823       str << "extern \"C\" void " << fortranify(baseName(), "_cknew") << "(int *numx, int *numy, int *numz, long *aindex)\n";
1824       str << "{\n";
1825       str << "    CkArrayID *aid = new CkArrayID;\n";
1826       str << "    *aid = CProxy_" << baseName() << "::ckNew(); \n";
1827       str << "    CProxy_" << baseName() << " p(*aid);\n";
1828       str << "    for (int i=0; i<*numx; i++) \n";
1829       str << "      for (int j=0; j<*numy; j++) \n";
1830       str << "        for (int k=0; k<*numz; k++) \n";
1831       str << "          p[CkArrayIndex3D(i, j, k)].insert(); \n";
1832       str << "    p.doneInserting(); \n";
1833     }
1834     str << "    *aindex = (long)aid;\n";
1835     str << "}\n";
1836
1837       // Define the Fortran interface function for AtSync
1838     if (dim == (const char*)"1D") {
1839       str << "extern \"C\" void "
1840           << fortranify(baseName(), "_atsync")
1841           << "(long* aindex, int *index1)\n";
1842       str << "{\n";
1843       str << "  CkArrayID *aid = (CkArrayID *)*aindex;\n";
1844       str << "\n";
1845       str << "  CProxy_" << baseName() << " h(*aid);\n";
1846       str << "  h[*index1].ckLocal()->AtSync();\n";
1847     }
1848     else if (dim == (const char*)"2D") {
1849       str << "extern \"C\" void "
1850           << fortranify(baseName(), "_atsync")
1851           << "(long* aindex, int *index1, int *index2)\n";
1852       str << "{\n";
1853       str << "  CkArrayID *aid = (CkArrayID *)*aindex;\n";
1854       str << "\n";
1855       str << "  CProxy_" << baseName() << " h(*aid);\n";
1856       str << "  h[CkArrayIndex2D(*index1, *index2)].ckLocal()->AtSync();\n";
1857     }
1858     else if (dim == (const char*)"3D") {
1859       str << "extern \"C\" void "
1860           << fortranify(baseName(), "_atsync")
1861           << "(long* aindex, int *index1, int *index2, int *index3)\n";
1862       str << "{\n";
1863       str << "  CkArrayID *aid = (CkArrayID *)*aindex;\n";
1864       str << "\n";
1865       str << "  CProxy_" << baseName() << " h(*aid);\n";
1866       str << "  h[CkArrayIndex3D(*index1, *index2, *index3)].ckLocal()->AtSync();\n";
1867     }
1868     str << "}\n";
1869
1870   }
1871
1872   templateGuardBegin(isTemplated(), str);
1873   if(!type->isTemplated()) {
1874     if(external) str << "extern ";
1875     str << tspec()<<" int "<<indexName()<<"::__idx";
1876     if(!external) str << "=0";
1877     str << ";\n";
1878   }
1879   templateGuardEnd(str);
1880
1881   if(list)
1882   {//Add definitions for all entry points
1883     list->genDefs(str);
1884     if (hasElement)
1885     { //Define the entry points for the element
1886       forElement=forAll;
1887       list->genDefs(str);
1888       if (hasSection) {  // for Section
1889         forElement=forSection;
1890         list->genDefs(str);
1891       }
1892       forElement=forIndividual;
1893     }
1894   }
1895
1896   templateGuardBegin(isTemplated(), str);
1897   // define the python routines
1898   if (isPython()) {
1899     str << "/* ---------------- python wrapper -------------- */\n";
1900
1901     // write CkPy_MethodsCustom
1902     genPythonDefs(str);
1903   }
1904   templateGuardEnd(str);
1905
1906   if(!external && !type->isTemplated())
1907     genRegisterMethodDef(str);
1908   if (hasSdagEntry) {
1909     str << "\n";
1910     str << sdagDefs;
1911   }
1912 }
1913
1914 void
1915 Chare::genReg(XStr& str)
1916 {
1917   str << "/* REG: "; print(str); str << "*/\n";
1918   if(external || templat)
1919     return;
1920   str << "  "<<indexName()<<"::__register(\""<<type<<"\", sizeof("<<type<<"));\n";
1921 }
1922
1923 static const char *CIMsgClassAnsi =
1924 "{\n"
1925 "  public:\n"
1926 "    static int __idx;\n"
1927 "    void* operator new(size_t, void*p) { return p; }\n"
1928 "    void* operator new(size_t);\n"
1929 "    void* operator new(size_t, int*, const int);\n"
1930 "    void* operator new(size_t, int*);\n"
1931 "#if CMK_MULTIPLE_DELETE\n"
1932 "    void operator delete(void*p, void*){dealloc(p);}\n"
1933 "    void operator delete(void*p){dealloc(p);}\n"
1934 "    void operator delete(void*p, int*, const int){dealloc(p);}\n"
1935 "    void operator delete(void*p, int*){dealloc(p);}\n"
1936 "#endif\n"
1937 "    void operator delete(void*p, size_t){dealloc(p);}\n"
1938 "    static void* alloc(int,size_t, int*, int);\n"
1939 "    static void dealloc(void *p);\n"
1940 ;
1941
1942 void
1943 Message::genAllocDecl(XStr &str)
1944 {
1945   int i, num;
1946   XStr mtype;
1947   mtype << type;
1948   if(templat) templat->genVars(mtype);
1949   str << CIMsgClassAnsi;
1950   str << "    CMessage_" << mtype << "();\n";
1951   str << "    static void *pack(" << mtype << " *p);\n";
1952   str << "    static " << mtype << "* unpack(void* p);\n";
1953   num = numArrays();
1954   if(num>0) {
1955     str << "    void *operator new(size_t";
1956     for(i=0;i<num;i++)
1957       str << ", int";
1958     str << ");\n";
1959   }
1960   str << "    void *operator new(size_t, ";
1961   for(i=0;i<num;i++)
1962     str << "int, ";
1963   str << "const int);\n";
1964   str << "#if CMK_MULTIPLE_DELETE\n";
1965   if(num>0) {
1966     str << "    void operator delete(void *p";
1967     for(i=0;i<num;i++)
1968         str << ", int";
1969     str << "){dealloc(p);}\n";
1970   }
1971   str << "    void operator delete(void *p, ";
1972   for(i=0;i<num;i++)
1973     str << "int, ";
1974   str << "const int){dealloc(p);}\n";
1975   str << "#endif\n";
1976 }
1977
1978 void
1979 Message::genDecls(XStr& str)
1980 {
1981   XStr ptype;
1982   ptype<<proxyPrefix()<<type;
1983   if(type->isTemplated())
1984     return;
1985   str << "/* DECLS: "; print(str); str << " */\n";
1986   if(templat)
1987     templat->genSpec(str);
1988   str << "class ";
1989   type->print(str);
1990   str << ";\n";
1991   if(templat)
1992     templat->genSpec(str);
1993   str << "class "<<ptype;
1994   if(external || type->isTemplated()) {
1995     str << ";\n";
1996     return;
1997   }
1998   str << ":public CkMessage";
1999
2000   genAllocDecl(str);
2001
2002   if(!(external||type->isTemplated())) {
2003    // generate register function
2004     str << "    static void __register(const char *s, size_t size, CkPackFnPtr pack, CkUnpackFnPtr unpack) {\n";
2005     str << "      __idx = CkRegisterMsg(s, pack, unpack, dealloc, size);\n";
2006     str << "    }\n";
2007   }
2008   str << "};\n";
2009   
2010   if (strncmp(type->getBaseName(), "MarshallMsg_", 12) == 0) {
2011     MsgVarList *ml;
2012     MsgVar *mv;
2013     int i;
2014     str << "class " << type << " : public " << ptype << " {\n";
2015     str << "  public:\n";
2016     int num = numVars();
2017     for(i=0, ml=mvlist; i<num; i++, ml=ml->next) {
2018       mv = ml->msg_var;
2019       if (mv->isConditional() || mv->isArray()) {
2020         str << "    /* "; mv->print(str); str << " */\n";
2021         str << "    " << mv->type << " *" << mv->name << ";\n";
2022       }
2023     }
2024     str <<"};\n";
2025   }
2026 }
2027
2028 void
2029 Message::genDefs(XStr& str)
2030 {
2031   int i, count, num = numVars();
2032   int numArray = numArrays();
2033   MsgVarList *ml;
2034   MsgVar *mv;
2035   XStr ptype, mtype, tspec;
2036   ptype<<proxyPrefix()<<type;
2037   if(templat) templat->genVars(ptype);
2038   mtype << type;
2039   if(templat) templat->genVars(mtype);
2040   if(templat) { templat->genSpec(tspec); tspec << " "; }
2041
2042   str << "/* DEFS: "; print(str); str << " */\n";
2043
2044   templateGuardBegin(templat, str);
2045   if(!(external||type->isTemplated())) {
2046
2047     // new (size_t)
2048     str << tspec << "void *" << ptype << "::operator new(size_t s){\n";
2049     str << "  return " << mtype << "::alloc(__idx, s, 0, 0);\n}\n";
2050     // new (size_t, int*)
2051     str << tspec << "void *" << ptype << "::operator new(size_t s, int* sz){\n";
2052     str << "  return " << mtype << "::alloc(__idx, s, sz, 0);\n}\n";
2053     // new (size_t, int*, priobits)
2054     str << tspec << "void *" << ptype << "::operator new(size_t s, int* sz,";
2055     str << "const int pb){\n";
2056     str << "  return " << mtype << "::alloc(__idx, s, sz, pb);\n}\n";
2057     // new (size_t, int, int, ..., int)
2058     if(numArray>0) {
2059       str << tspec << "void *" << ptype << "::operator new(size_t s";
2060       for(i=0;i<numArray;i++)
2061         str << ", int sz" << i;
2062       str << ") {\n";
2063       str << "  int sizes[" << numArray << "];\n";
2064       for(i=0;i<numArray;i++)
2065         str << "  sizes[" << i << "] = sz" << i << ";\n";
2066       str << "  return " << mtype << "::alloc(__idx, s, sizes, 0);\n";
2067       str << "}\n";
2068     }
2069     // new (size_t, int, int, ..., int, priobits)
2070     // degenerates to  new(size_t, priobits)  if no varsize
2071     str << tspec << "void *"<< ptype << "::operator new(size_t s, ";
2072     for(i=0;i<numArray;i++)
2073       str << "int sz" << i << ", ";
2074     str << "const int p) {\n";
2075     if (numArray>0) str << "  int sizes[" << numArray << "];\n";
2076     for(i=0, count=0, ml=mvlist ;i<num; i++, ml=ml->next)
2077       if (ml->msg_var->isArray()) {
2078         str << "  sizes[" << count << "] = sz" << count << ";\n";
2079         count ++;
2080       }
2081     str << "  return " << mtype << "::alloc(__idx, s, " << (numArray>0?"sizes":"0") << ", p);\n";
2082     str << "}\n";
2083     // alloc(int, size_t, int*, priobits)
2084     str << tspec << "void* " << ptype;
2085     str << "::alloc(int msgnum, size_t sz, int *sizes, int pb) {\n";
2086     str << "  CkpvAccess(_offsets)[0] = ALIGN8(sz);\n";
2087     for(i=0, count=0, ml=mvlist; i<num; i++, ml=ml->next) {
2088       mv = ml->msg_var;
2089       if (mv->isArray()) {
2090         str << "  if(sizes==0)\n";
2091         str << "    CkpvAccess(_offsets)[" << count+1 << "] = CkpvAccess(_offsets)[0];\n";
2092         str << "  else\n";
2093         str << "    CkpvAccess(_offsets)[" << count+1 << "] = CkpvAccess(_offsets)[" << count << "] + ";
2094         str << "ALIGN8(sizeof(" << mv->type << ")*sizes[" << count << "]);\n";
2095         count ++;
2096       }
2097     }
2098     str << "  return CkAllocMsg(msgnum, CkpvAccess(_offsets)[" << numArray << "], pb);\n";
2099     str << "}\n";
2100
2101     str << tspec << ptype << "::" << proxyPrefix() << type << "() {\n";
2102     str << mtype << " *newmsg = (" << mtype << " *)this;\n";
2103     for(i=0, count=0, ml=mvlist; i<num; i++,ml=ml->next) {
2104       mv = ml->msg_var;
2105       if (mv->isArray()) {
2106         str << "  newmsg->" << mv->name << " = (" << mv->type << " *) ";
2107         str << "((char *)newmsg + CkpvAccess(_offsets)[" << count << "]);\n";
2108         count ++;
2109       }
2110     }
2111     str << "}\n";
2112
2113     int numCond = numConditional();
2114     str << tspec << "void " << ptype << "::dealloc(void *p) {\n";
2115     if (numCond > 0) {
2116       str << "  " << mtype << " *msg = (" << mtype << "*) p;\n";
2117       for(i=0, count=0, ml=mvlist; i<num; i++, ml=ml->next) {
2118         mv = ml->msg_var;
2119         if (mv->isConditional()) {
2120           if (mv->type->isPointer()) die("conditional variable cannot be a pointer", line);
2121           str << "  CkConditional *cond_" << mv->name << " = static_cast<CkConditional*>(msg->" << mv->name << ");\n";
2122           str << "  if (cond_" << mv->name << "!=NULL) cond_" << mv->name << "->deallocate();\n";
2123         }
2124       }
2125     }
2126     str << "  CkFreeMsg(p);\n";
2127     str << "}\n";
2128     // pack
2129     str << tspec << "void* " << ptype << "::pack(" << mtype << " *msg) {\n";
2130     for(i=0, ml=mvlist; i<num; i++, ml=ml->next) {
2131       mv = ml->msg_var;
2132       if (mv->isArray()) {
2133         str << "  msg->" << mv->name << " = (" <<mv->type << " *) ";
2134         str << "((char *)msg->" << mv->name << " - (char *)msg);\n";
2135       }
2136     }
2137     if (numCond > 0) {
2138       str << "  int impl_off[" <<  numCond+1 << "];\n";
2139       str << "  impl_off[0] = UsrToEnv(msg)->getUsersize();\n";
2140       for(i=0, count=0, ml=mvlist; i<num; i++, ml=ml->next) {
2141         mv = ml->msg_var;
2142         if (mv->isConditional()) {
2143           str << "  if (msg->" << mv->name << "!=NULL) { /* conditional packing of ";
2144           mv->type->print(str); str << " " << mv->name << " */\n";
2145           str << "    PUP::sizer implP;\n";
2146           str << "    implP|*msg->" << mv->name << ";\n";
2147           str << "    impl_off[" << count+1 << "] = impl_off[" << count << "] + implP.size();\n";
2148           str << "  } else {\n";
2149           str << "    impl_off[" << count+1 << "] = impl_off[" << count << "];\n";
2150           str << "  }\n";
2151           count ++;
2152         }
2153       }
2154       str << "  " << mtype << " *newmsg = (" << mtype << "*) CkAllocMsg(__idx, impl_off["
2155           << numCond << "], UsrToEnv(msg)->getPriobits());\n";
2156       str << "  envelope *newenv = UsrToEnv(newmsg);\n";
2157       str << "  UInt newSize = newenv->getTotalsize();\n";
2158       str << "  CmiMemcpy(newenv, UsrToEnv(msg), impl_off[0]+sizeof(envelope));\n";
2159       str << "  newenv->setTotalsize(newSize);\n";
2160       str << "  if (UsrToEnv(msg)->getPriobits() > 0) CmiMemcpy(newenv->getPrioPtr(), UsrToEnv(msg)->getPrioPtr(), newenv->getPrioBytes());\n";
2161       for(i=0, count=0, ml=mvlist; i<num; i++, ml=ml->next) {
2162         mv = ml->msg_var;
2163         if (mv->isConditional()) {
2164           str << "  if (msg->" << mv->name << "!=NULL) { /* conditional packing of ";
2165           mv->type->print(str); str << " " << mv->name << " */\n";
2166           str << "    newmsg->" << mv->name << " = ("; mv->type->print(str);
2167           str << "*)(((char*)newmsg)+impl_off[" << count << "]);\n";
2168           str << "    PUP::toMem implP((void *)newmsg->" << mv->name << ");\n";
2169           str << "    implP|*msg->" << mv->name << ";\n";
2170           str << "    newmsg->" << mv->name << " = (" << mv->type << "*) ((char *)newmsg->" << mv->name << " - (char *)newmsg);\n";
2171           str << "  }\n";
2172           count++;
2173         }
2174       }
2175       str << "  CkFreeMsg(msg);\n";
2176       str << "  msg = newmsg;\n";
2177     }
2178     str << "  return (void *) msg;\n}\n";
2179     // unpack
2180     str << tspec << mtype << "* " << ptype << "::unpack(void* buf) {\n";
2181     str << "  " << mtype << " *msg = (" << mtype << " *) buf;\n";
2182     for(i=0, ml=mvlist; i<num; i++, ml=ml->next) {
2183       mv = ml->msg_var;
2184       if (mv->isArray()) {
2185         str << "  msg->" << mv->name << " = (" <<mv->type << " *) ";
2186         str << "((size_t)msg->" << mv->name << " + (char *)msg);\n";
2187       }
2188     }
2189     if (numCond > 0) {
2190       for(i=0, count=0, ml=mvlist; i<num; i++, ml=ml->next) {
2191         mv = ml->msg_var;
2192         if (mv->isConditional()) {
2193           str << "  if (msg->" << mv->name << "!=NULL) { /* conditional packing of ";
2194           mv->type->print(str); str << " " << mv->name << " */\n";
2195           str << "    PUP::fromMem implP((char*)msg + (size_t)msg->" << mv->name << ");\n";
2196           str << "    msg->" << mv->name << " = new " << mv->type << ";\n";
2197           str << "    implP|*msg->" << mv->name << ";\n";
2198           str << "  }\n";
2199           count ++;
2200         }
2201       }
2202     }
2203     str << "  return msg;\n}\n";
2204   }
2205   if(!templat) {
2206     if(!external && !type->isTemplated()) {
2207       str << "int "<< ptype <<"::__idx=0;\n";
2208     }
2209   } else {
2210     str << tspec << "int "<< ptype <<"::__idx=0;\n";
2211   }
2212   templateGuardEnd(str);
2213 }
2214
2215 void
2216 Message::genReg(XStr& str)
2217 {
2218   str << "/* REG: "; print(str); str << "*/\n";
2219   if(!templat && !external) {
2220     XStr ptype, mtype, tspec;
2221     ptype<<proxyPrefix()<<type;
2222     str << ptype << "::__register(\"" << type << "\", sizeof(" << type <<"),";
2223     str << "(CkPackFnPtr) " << type << "::pack,";
2224     str << "(CkUnpackFnPtr) " << type << "::unpack);\n";
2225   }
2226 }
2227
2228 void
2229 Template::setExtern(int e)
2230 {
2231   Construct::setExtern(e);
2232   entity->setExtern(e);
2233 }
2234
2235 void
2236 Template::genVars(XStr& str)
2237 {
2238   str << " < ";
2239   if(tspec)
2240     tspec->genShort(str);
2241   str << " > ";
2242 }
2243
2244 XStr generateTemplateSpec(TVarList* tspec)
2245 {
2246   XStr str;
2247
2248   if(tspec) {
2249     str << "template < ";
2250     tspec->genLong(str);
2251     str << " > ";
2252   }
2253
2254   return str;
2255 }
2256
2257 void
2258 Template::genSpec(XStr& str)
2259 {
2260   str << generateTemplateSpec(tspec);
2261 }
2262
2263 void
2264 Template::genPub(XStr& declstr, XStr& defstr, XStr& defconstr, int& connectPresent)
2265 {
2266   if(!external && entity) {
2267     entity->genPub(declstr, defstr, defconstr, connectPresent);
2268   }
2269 }
2270
2271 void
2272 Template::genDecls(XStr& str)
2273 {
2274   if(!external && entity) {
2275     entity->genDecls(str);
2276   }
2277 }
2278
2279 void
2280 Template::genDefs(XStr& str)
2281 {
2282   if(!external && entity)
2283     entity->genDefs(str);
2284 }
2285
2286 int Template::genAccels_spe_c_funcBodies(XStr& str) {
2287   int rtn = 0;
2288   if (!external && entity) { rtn += entity->genAccels_spe_c_funcBodies(str); }
2289   return rtn;
2290 }
2291
2292 void Template::genAccels_spe_c_regFuncs(XStr& str) {
2293   if (!external && entity) { entity->genAccels_spe_c_regFuncs(str); }
2294 }
2295
2296 void Template::genAccels_spe_c_callInits(XStr& str) {
2297   if (!external && entity) { entity->genAccels_spe_c_callInits(str); }
2298 }
2299
2300 void Template::genAccels_spe_h_includes(XStr& str) {
2301   if (!external && entity) { entity->genAccels_spe_h_includes(str); }
2302 }
2303
2304 void Template::genAccels_spe_h_fiCountDefs(XStr& str) {
2305   if (!external && entity) { entity->genAccels_spe_h_fiCountDefs(str); }
2306 }
2307
2308 void Template::genAccels_ppe_c_regFuncs(XStr& str) {
2309   if (!external && entity) { entity->genAccels_ppe_c_regFuncs(str); }
2310 }
2311
2312 void
2313 TVarList::genLong(XStr& str)
2314 {
2315   if(tvar)
2316     tvar->genLong(str);
2317   if(next) {
2318     str << ", ";
2319     next->genLong(str);
2320   }
2321 }
2322
2323 void
2324 TVarList::genShort(XStr& str)
2325 {
2326   if(tvar)
2327     tvar->genShort(str);
2328   if(next) {
2329     str << ", ";
2330     next->genShort(str);
2331   }
2332 }
2333
2334 void TType::genLong(XStr& str)
2335 {
2336   str << "class ";
2337   if(type)
2338     type->print(str);
2339   if(init) {
2340     str << "=";
2341     init->print(str);
2342   }
2343 }
2344
2345 void TType::genShort(XStr& str)
2346 {
2347   if(type)
2348     type->print(str);
2349 }
2350
2351 void TName::genLong(XStr& str)
2352 {
2353   if(type)
2354     type->print(str);
2355   str << " "<<name;
2356   if(val) {
2357     str << "="<<val;
2358   }
2359 }
2360
2361 void TName::genShort(XStr& str)
2362 {
2363   str << name;
2364 }
2365
2366 void
2367 Module::genPub(XStr& declstr, XStr& defstr, XStr& defconstr, int& connectPresent)
2368 {
2369   if(!external) {
2370     if (clist) clist->genPub(declstr, defstr, defconstr, connectPresent);
2371   }
2372 }
2373
2374
2375 void
2376 Module::genDecls(XStr& str)
2377 {
2378   if(external) {
2379     str << "#include \""<<name<<".decl.h\"\n";
2380   } else {
2381     if (clist) clist->genDecls(str);
2382   }
2383
2384   #if CMK_CELL != 0
2385     str << "extern int register_accel_spe_funcs__module_" << name << "(int curIndex);\n";
2386     if (isMain()) {
2387       str << "extern \"C\" void register_accel_spe_funcs(void);\n";
2388     }
2389   #endif
2390 }
2391
2392 void
2393 Module::genDefs(XStr& str)
2394 {
2395   if(!external)
2396     if (clist)
2397       clist->genDefs(str);
2398
2399   // DMK - Accel Support
2400   #if CMK_CELL != 0
2401
2402     if (!external) {
2403       templateGuardBegin(false, str);
2404
2405       // Create the registration function
2406       // NOTE: Add a check so modules won't register more than once.  It is possible that to modules
2407       //   could have 'extern' references to each other, creating infinite loops in the registration
2408       //   process.  Avoid this problem.
2409       str << "int register_accel_spe_funcs__module_" << name << "(int curIndex) {\n"
2410           << "  static int hasAlreadyRegisteredFlag = 0;\n"
2411           << "  if (hasAlreadyRegisteredFlag) { return curIndex; };\n"
2412           << "  hasAlreadyRegisteredFlag = 1;\n";
2413       genAccels_ppe_c_regFuncs(str);
2414       str << "  return curIndex;\n"
2415           << "}\n";
2416
2417       // Check to see if this is the main module (create top register function if so)
2418       if (isMain()) {
2419         str << "#include\"spert.h\"\n"  // NOTE: Make sure SPE_FUNC_INDEX_USER is defined
2420             << "extern \"C\" void register_accel_spe_funcs(void) {\n"
2421             << "  register_accel_spe_funcs__module_" << name << "(SPE_FUNC_INDEX_USER);\n"
2422             << "}\n";
2423       }
2424
2425       templateGuardEnd(str);
2426     }
2427
2428   #endif
2429 }
2430
2431 void
2432 Module::genReg(XStr& str)
2433 {
2434   if(external) {
2435     str << "  _register"<<name<<"();"<<endx;
2436   } else {
2437     if (clist) clist->genDefs(str);
2438   }
2439 }
2440
2441
2442 int Module::genAccels_spe_c_funcBodies(XStr& str) {
2443
2444   // If this is an external module decloration, just place an include
2445   if (external) {
2446     str << "#include \"" << name << ".genSPECode.c\"\n";
2447     return 0;
2448   }
2449
2450   // If this is the main module, generate the function lookup table
2451   if (isMain()) {
2452     str << "typedef void(*AccelFuncPtr)(DMAListEntry*);\n\n"
2453         << "typedef struct __func_lookup_table_entry {\n"
2454         << "  int funcIndex;\n"
2455         << "  AccelFuncPtr funcPtr;\n"
2456         << "} FuncLookupTableEntry;\n\n"
2457         << "FuncLookupTableEntry funcLookupTable[MODULE_" << name << "_FUNC_INDEX_COUNT];\n\n\n";
2458   }
2459
2460   // Process each of the sub-constructs
2461   int rtn = 0;
2462   if (clist) { rtn += clist->genAccels_spe_c_funcBodies(str); }
2463
2464   // Create the accelerated function registration function for accelerated entries local to this module
2465   // NOTE: Add a check so modules won't register more than once.  It is possible that to modules
2466   //   could have 'extern' references to each other, creating infinite loops in the registration
2467   //   process.  Avoid this problem.
2468   str << "int register_accel_funcs_" << name << "(int curIndex) {\n"
2469       << "  static int hasAlreadyRegisteredFlag = 0;\n"
2470       << "  if (hasAlreadyRegisteredFlag) { return curIndex; };\n"
2471       << "  hasAlreadyRegisteredFlag = 1;\n";
2472   genAccels_spe_c_regFuncs(str);
2473   str << "  return curIndex;\n"
2474       << "}\n\n\n";
2475
2476   // If this is the main module, generate the funcLookup function
2477   if (isMain()) {
2478
2479     str << "\n\n";
2480     str << "#ifdef __cplusplus\n"
2481         << "extern \"C\"\n"
2482         << "#endif\n"
2483         << "void funcLookup(int funcIndex,\n"
2484         << "                void* readWritePtr, int readWriteLen,\n"
2485         << "                void* readOnlyPtr, int readOnlyLen,\n"
2486         << "                void* writeOnlyPtr, int writeOnlyLen,\n"
2487         << "                DMAListEntry* dmaList\n"
2488         << "               ) {\n\n";
2489
2490     str << "  if ((funcIndex >= SPE_FUNC_INDEX_USER) && (funcIndex < (SPE_FUNC_INDEX_USER + MODULE_" << name << "_FUNC_INDEX_COUNT))) {\n"
2491
2492         //<< "    // DMK - DEBUG\n"
2493         //<< "    printf(\"[DEBUG-ACCEL] :: [SPE_%d] - Calling funcIndex %d...\\n\", (int)getSPEID(), funcIndex);\n"
2494
2495         << "    (funcLookupTable[funcIndex - SPE_FUNC_INDEX_USER].funcPtr)(dmaList);\n"
2496         << "  } else if (funcIndex == SPE_FUNC_INDEX_INIT) {\n"
2497         << "    if (register_accel_funcs_" << name << "(0) != MODULE_" << name << "_FUNC_INDEX_COUNT) {\n"
2498         << "      printf(\"ERROR : register_accel_funcs_" << name << "() returned an invalid value.\\n\");\n"
2499         << "    };\n";
2500     genAccels_spe_c_callInits(str);
2501     str << "  } else if (funcIndex == SPE_FUNC_INDEX_CLOSE) {\n"
2502         << "    // NOTE : Do nothing on close, but handle case...\n"
2503         << "  } else {\n"
2504         << "    printf(\"ERROR : Unknown funcIndex (%d) passed to funcLookup()... ignoring.\\n\", funcIndex);\n"
2505         << "  }\n";
2506
2507     str << "}\n";
2508   }
2509
2510   return rtn;
2511 }
2512
2513 void Module::genAccels_spe_c_regFuncs(XStr& str) {
2514   if (external) {
2515     str << "  curIndex = register_accel_funcs_" << name << "(curIndex);\n";
2516   } else {
2517     if (clist) { clist->genAccels_spe_c_regFuncs(str); }
2518   }
2519 }
2520
2521 void Module::genAccels_spe_c_callInits(XStr& str) {
2522   if (clist) { clist->genAccels_spe_c_callInits(str); }
2523 }
2524
2525 void Module::genAccels_spe_h_includes(XStr& str) {
2526   if (external) {
2527     str << "#include \"" << name << ".genSPECode.h\"\n";
2528   }
2529   if (clist) { clist->genAccels_spe_h_includes(str); }
2530 }
2531
2532 void Module::genAccels_spe_h_fiCountDefs(XStr& str) {
2533   if (external) {
2534     str << " + MODULE_" << name << "_FUNC_INDEX_COUNT";
2535   }
2536   if (clist) { clist->genAccels_spe_h_fiCountDefs(str); }
2537 }
2538
2539 void Module::genAccels_ppe_c_regFuncs(XStr& str) {
2540   if (external) {
2541     str << "  curIndex = register_accel_spe_funcs__module_" << name << "(curIndex);\n";
2542   } else {
2543     if (clist) { clist->genAccels_ppe_c_regFuncs(str); }
2544   }
2545 }
2546
2547 void
2548 Readonly::genDecls(XStr& str)
2549 {
2550   str << "/* DECLS: "; print(str); str << " */\n";
2551 }
2552
2553 void
2554 Readonly::genIndexDecls(XStr& str)
2555 {
2556   str << "/* DECLS: "; print(str); str << " */\n";
2557 }
2558
2559 //Turn this string into a valid identifier
2560 XStr makeIdent(const XStr &in)
2561 {
2562   XStr ret;
2563   const char *i=in.get_string_const();
2564   while (*i!=0) {
2565     //Quote all "special" characters
2566     if (*i==':') ret<<"_QColon_";
2567     else if (*i==' ') ret<<"_QSpace_";
2568     else if (*i=='+') ret<<"_QPlus_";
2569     else if (*i=='-') ret<<"_QMinus_";
2570     else if (*i=='*') ret<<"_QTimes_";
2571     else if (*i=='/') ret<<"_QSlash_";
2572     else if (*i=='%') ret<<"_QPercent_";
2573     else if (*i=='&') ret<<"_QAmpersand_";
2574     else if (*i=='.') ret<<"_QDot_";
2575     else if (*i==',') ret<<"_QComma_";
2576     else if (*i=='\'') ret<<"_QSQuote_";
2577     else if (*i=='\"') ret<<"_QQuote_";
2578     else if (*i=='(') ret<<"_QLparen_";
2579     else if (*i==')') ret<<"_QRparen_";
2580     else if (*i=='<') ret<<"_QLess_";
2581     else if (*i=='>') ret<<"_QGreater_";
2582     else if (*i=='{') ret<<"_QLbrace_";
2583     else if (*i=='}') ret<<"_QRbrace_";
2584     else ret << *i; //Copy character unmodified
2585     i++; //Advance to next
2586   }
2587   return ret;
2588 }
2589
2590 void
2591 Readonly::genDefs(XStr& str)
2592 {
2593   str << "/* DEFS: "; print(str); str << " */\n";
2594   if(!container && !strchr(name, ':')) {
2595     str << "extern ";
2596     type->print(str);
2597     if(msg)
2598       str << "*";
2599     str << " "<<name;
2600     if(dims)
2601       dims->print(str);
2602     str << ";\n";
2603   }
2604
2605   if (!msg) { //Generate a pup for this readonly
2606     templateGuardBegin(false, str);
2607     str << "extern \"C\" void __xlater_roPup_"<<makeIdent(qName());
2608     str <<    "(void *_impl_pup_er) {\n";
2609     str << "  PUP::er &_impl_p=*(PUP::er *)_impl_pup_er;\n";
2610     if(dims){
2611             str << "  _impl_p("<<qName()<<","; dims->printValue(str); str<<");\n";
2612     }else{
2613             str << "  _impl_p|"<<qName()<<";\n";
2614     }
2615     str << "}\n";
2616     templateGuardEnd(str);
2617   }
2618
2619   if (fortranMode) {
2620       str << "extern \"C\" void "
2621           << fortranify("set_", name)
2622           << "(int *n) { " << name << " = *n; }\n";
2623       str << "extern \"C\" void "
2624           << fortranify("get_", name)
2625           << "(int *n) { *n = " << name << "; }\n";
2626   }
2627 }
2628
2629 void
2630 Readonly::genReg(XStr& str)
2631 {
2632   if(external)
2633     return;
2634   if(msg) {
2635     if(dims) die("readonly Message cannot be an array",line);
2636     str << "  CkRegisterReadonlyMsg(\""<<qName()<<"\",\""<<type<<"\",";
2637     str << "(void **)&"<<qName()<<");\n";
2638   } else {
2639     str << "  CkRegisterReadonly(\""<<qName()<<"\",\""<<type<<"\",";
2640     str << "sizeof("<<qName()<<"),(void *) &"<<qName()<<",";
2641     str << "__xlater_roPup_"<<makeIdent(qName())<<");\n";
2642   }
2643 }
2644
2645 void TParamList::genSpec(XStr& str)
2646 {
2647   if(tparam)
2648     tparam->genSpec(str);
2649   if(next) {
2650     str << ", ";
2651     next->genSpec(str);
2652   }
2653 }
2654
2655 void MemberList::genIndexDecls(XStr& str)
2656 {
2657     perElemGen(members, str, &Member::genIndexDecls, newLine);
2658 }
2659
2660 void MemberList::genPub(XStr& declstr, XStr& defstr, XStr& defconstr, int& connectPresent)
2661 {
2662     for (list<Member*>::iterator i = members.begin(); i != members.end(); ++i)
2663         if (*i) {
2664             (*i)->genPub(declstr, defstr, defconstr, connectPresent);
2665             declstr << endx;
2666         }
2667 }
2668
2669 void MemberList::genDecls(XStr& str)
2670 {
2671     perElemGen(members, str, &Member::genDecls, newLine);
2672 }
2673
2674 void MemberList::collectSdagCode(CParsedFile *pf, int& sdagPresent)
2675 {
2676     for (list<Member*>::iterator i = members.begin(); i != members.end(); ++i)
2677         if (*i)
2678             (*i)->collectSdagCode(pf, sdagPresent);
2679 }
2680
2681 void MemberList::genDefs(XStr& str)
2682 {
2683     perElemGen(members, str, &Member::genDefs, newLine);
2684 }
2685
2686 void MemberList::genReg(XStr& str)
2687 {
2688     perElemGen(members, str, &Member::genReg, newLine);
2689 }
2690
2691 void MemberList::preprocess()
2692 {
2693   perElem(members, &Member::preprocess);
2694 }
2695
2696 void MemberList::lookforCEntry(CEntry *centry)
2697 {
2698     perElemGen(members, centry, &Member::lookforCEntry);
2699 }
2700
2701 void MemberList::genPythonDecls(XStr& str) {
2702     perElemGen(members, str, &Member::genPythonDecls, newLine);
2703 }
2704
2705 void MemberList::genPythonDefs(XStr& str) {
2706     perElemGen(members, str, &Member::genPythonDefs, newLine);
2707 }
2708
2709 void MemberList::genPythonStaticDefs(XStr& str) {
2710     perElemGen(members, str, &Member::genPythonStaticDefs);
2711 }
2712
2713 void MemberList::genPythonStaticDocs(XStr& str) {
2714     perElemGen(members, str, &Member::genPythonStaticDocs);
2715 }
2716
2717 void Entry::lookforCEntry(CEntry *centry)
2718 {
2719    // compare name
2720    if (strcmp(name, *centry->entry) != 0) return;
2721    // compare param
2722    if (param && !centry->paramlist) return;
2723    if (!param && centry->paramlist) return;
2724    if (param && !(*param == *centry->paramlist)) return;
2725
2726    isWhenEntry = 1;
2727    centry->decl_entry = this;
2728 }
2729
2730 void Chare::lookforCEntry(CEntry *centry)
2731 {
2732   if(list)
2733     list->lookforCEntry(centry);
2734   if (centry->decl_entry == NULL)  {
2735     cerr<<"Function \""<<centry->entry->get_string_const()
2736         <<"\" appears in Sdag When construct, but not defined as an entry function. "
2737         << endl;
2738     die("(FATAL ERROR)");
2739   }
2740 }
2741
2742 ///////////////////////////// ENTRY ////////////////////////////
2743
2744 void ParamList::checkParamList(){
2745   if(manyPointers){ 
2746     die("You may pass only a single pointer to a non-local entry method. It should point to a message.", param->line);
2747     abort();
2748   }
2749 }
2750
2751 Entry::Entry(int l, int a, Type *r, const char *n, ParamList *p, Value *sz, SdagConstruct *sc, const char *e, int connect, ParamList *connectPList) :
2752       attribs(a), retType(r), stacksize(sz), sdagCon(sc), name((char *)n), targs(0), intExpr(e), param(p), connectParam(connectPList), isConnect(connect)
2753 {
2754   line=l; container=NULL;
2755   entryCount=-1;
2756   isWhenEntry=0;
2757   if (param && param->isMarshalled() && !isThreaded()) attribs|=SNOKEEP;
2758
2759   if(!isThreaded() && stacksize) die("Non-Threaded methods cannot have stacksize",line);
2760   if(retType && !isSync() && !isIget() && !isLocal() && !retType->isVoid())
2761     die("A remote method normally returns void.  To return non-void, you need to declare the method as [sync], which means it has blocking semantics.",line);
2762   if (isPython()) pythonDoc = python_doc;
2763   if(!isLocal() && p){
2764     p->checkParamList();
2765   }
2766
2767 }
2768 void Entry::setChare(Chare *c) {
2769         Member::setChare(c);
2770         // mainchare constructor parameter is not allowed
2771         /* ****************** REMOVED 10/8/2002 ************************
2772         if (isConstructor()&&container->isMainChare() && param != NULL)
2773           if (!param->isCkArgMsgPtr())
2774            die("MainChare Constructor doesn't allow parameter!", line);
2775         Removed old treatment for CkArgMsg to allow argc, argv or void
2776         constructors for mainchares.
2777         * **************************************************************/
2778         if (isConstructor() && container->isMainChare() && param->isVoid()) {
2779           //Main chare always magically takes CkArgMsg
2780           Type *t = new PtrType(new NamedType("CkArgMsg"));
2781           param=new ParamList(new Parameter(line,t));
2782           std::cerr << "Charmxi> " << line << ": Deprecation warning: mainchare constructors should explicitly take CkArgMsg* if that's how they're implemented.\n";
2783         }
2784
2785         entryCount=c->nextEntry();
2786
2787         //Make a special "callmarshall" method, for communication optimizations to use:
2788         hasCallMarshall=param->isMarshalled() && !isThreaded() && !isSync() && !isExclusive() && !fortranMode;
2789         if (isSdag()) container->setSdag(1);
2790 }
2791
2792 // "parameterType *msg" or "void".
2793 // Suitable for use as the only parameter
2794 XStr Entry::paramType(int withDefaultVals,int withEO,int useConst)
2795 {
2796   XStr str;
2797   param->print(str,withDefaultVals,useConst);
2798   if (withEO) str<<eo(withDefaultVals,!param->isVoid());
2799   return str;
2800 }
2801
2802 // "parameterType *msg," if there is a non-void parameter,
2803 // else empty.  Suitable for use with another parameter following.
2804 XStr Entry::paramComma(int withDefaultVals,int withEO)
2805 {
2806   XStr str;
2807   if (!param->isVoid()) {
2808     str << paramType(withDefaultVals,withEO);
2809     str << ", ";
2810   }
2811   return str;
2812 }
2813 XStr Entry::eo(int withDefaultVals,int priorComma) {
2814   XStr str;
2815   if (param->isMarshalled()) {//FIXME: add options for void methods, too...
2816     if (priorComma) str<<", ";
2817     str<<"const CkEntryOptions *impl_e_opts";
2818     if (withDefaultVals) str<<"=NULL";
2819   }
2820   return str;
2821 }
2822
2823 void Entry::collectSdagCode(CParsedFile *pf, int& sdagPresent)
2824 {
2825   if (isSdag()) {
2826     sdagPresent = 1;
2827     pf->addNode(this);
2828   }
2829 }
2830
2831 XStr Entry::marshallMsg(void)
2832 {
2833   XStr ret;
2834   XStr epName = epStr();
2835   param->marshall(ret, epName);
2836   return ret;
2837 }
2838
2839 XStr Entry::epStr(bool isForRedn, bool templateCall)
2840 {
2841   XStr str;
2842   if (isForRedn)
2843     str<<"redn_wrapper_";
2844   str << name << "_";
2845
2846   if (param->isMessage()) {
2847     str<<param->getBaseName();
2848     str.replace(':', '_');
2849   }
2850   else if (param->isVoid())
2851     str<<"void";
2852   else
2853     str<<"marshall"<<entryCount;
2854
2855   if (tspec && templateCall) {
2856     str << "< ";
2857     tspec->genShort(str);
2858     str << " >";
2859   }
2860
2861   return str;
2862 }
2863
2864 XStr Entry::epIdx(int fromProxy, bool isForRedn)
2865 {
2866   XStr str;
2867   if (fromProxy) {
2868     str << indexName()<<"::";
2869     // If the chare is also templated, then we must avoid a parsing ambiguity
2870     if (tspec)
2871       str << "template ";
2872   }
2873   str << "idx_" << epStr(isForRedn, true) << "()";
2874   return str;
2875 }
2876
2877 XStr Entry::epRegFn(int fromProxy, bool isForRedn)
2878 {
2879   XStr str;
2880   if (fromProxy)
2881     str << indexName() << "::";
2882   str << "reg_" << epStr(isForRedn, true) << "()";
2883   return str;
2884 }
2885
2886 XStr Entry::chareIdx(int fromProxy)
2887 {
2888   XStr str;
2889   if (fromProxy)
2890     str << indexName()<<"::";
2891   str << "__idx";
2892   return str;
2893 }
2894
2895 //Return a templated proxy declaration string for
2896 // this Member's container with the given return type, e.g.
2897 // template<int N,class foo> void CProxy_bar<N,foo>
2898 // Works with non-templated Chares as well.
2899 XStr Member::makeDecl(const XStr &returnType, int forProxy, bool isStatic)
2900 {
2901   XStr str;
2902
2903   if (container->isTemplated())
2904     str << container->tspec() << "\n";
2905   str << generateTemplateSpec(tspec) << "\n";
2906   if (isStatic)
2907     str << "static ";
2908   str << returnType<<" ";
2909   if (forProxy)
2910         str<<container->proxyName();
2911   else
2912         str<<container->indexName();
2913   return str;
2914 }
2915
2916 XStr Entry::syncReturn(void) {
2917   XStr str;
2918   if(retType->isVoid())
2919     str << "  CkFreeSysMsg(";
2920   else
2921     str << "  return ("<<retType<<") (";
2922   return str;
2923 }
2924
2925 /*************************** Chare Entry Points ******************************/
2926
2927 void Entry::genChareDecl(XStr& str)
2928 {
2929   if(isConstructor()) {
2930     genChareStaticConstructorDecl(str);
2931   } else {
2932     // entry method declaration
2933     str << "    " << generateTemplateSpec(tspec) << "\n"
2934         << "    " << retType << " " << name << "(" << paramType(1,1) << ");\n";
2935   }
2936 }
2937
2938 void Entry::genChareDefs(XStr& str)
2939 {
2940   if (isImmediate()) {
2941       cerr << (char *)container->baseName() << ": Chare does not allow immediate message.\n";
2942       exit(1);
2943   }
2944   if (isLocal()) {
2945     cerr << (char*)container->baseName() << ": Chare does not allow LOCAL entry methods.\n";
2946     exit(1);
2947   }
2948
2949   if(isConstructor()) {
2950     genChareStaticConstructorDefs(str);
2951   } else {
2952     XStr params; params<<epIdx()<<", impl_msg, &ckGetChareID()";
2953     // entry method definition
2954     XStr retStr; retStr<<retType;
2955     str << makeDecl(retStr,1)<<"::"<<name<<"("<<paramType(0,1)<<")\n";
2956     str << "{\n  ckCheck();\n"<<marshallMsg();
2957     if(isSync()) {
2958       str << syncReturn() << "CkRemoteCall("<<params<<"));\n";
2959     } else {//Regular, non-sync message
2960       str << "  if (ckIsDelegated()) {\n";
2961       str << "    int destPE=CkChareMsgPrep("<<params<<");\n";
2962       str << "    if (destPE!=-1) ckDelegatedTo()->ChareSend(ckDelegatedPtr(),"<<params<<",destPE);\n";
2963       str << "  }\n";
2964       XStr opts;
2965       opts << ",0";
2966       if (isSkipscheduler())  opts << "+CK_MSG_EXPEDITED";
2967       if (isInline())  opts << "+CK_MSG_INLINE";
2968       str << "  else CkSendMsg("<<params<<opts<<");\n";
2969     }
2970     str << "}\n";
2971   }
2972 }
2973
2974 void Entry::genChareStaticConstructorDecl(XStr& str)
2975 {
2976   str << "    static CkChareID ckNew("<<paramComma(1)<<"int onPE=CK_PE_ANY"<<eo(1)<<");\n";
2977   str << "    static void ckNew("<<paramComma(1)<<"CkChareID* pcid, int onPE=CK_PE_ANY"<<eo(1)<<");\n";
2978   if (!param->isVoid())
2979     str << "    "<<container->proxyName(0)<<"("<<paramComma(1)<<"int onPE=CK_PE_ANY"<<eo(1)<<");\n";
2980 }
2981
2982 void Entry::genChareStaticConstructorDefs(XStr& str)
2983 {
2984   str << makeDecl("CkChareID",1)<<"::ckNew("<<paramComma(0)<<"int impl_onPE"<<eo(0)<<")\n";
2985   str << "{\n"<<marshallMsg();
2986   str << "  CkChareID impl_ret;\n";
2987   str << "  CkCreateChare("<<chareIdx()<<", "<<epIdx()<<", impl_msg, &impl_ret, impl_onPE);\n";
2988   str << "  return impl_ret;\n";
2989   str << "}\n";
2990
2991   str << makeDecl("void",1)<<"::ckNew("<<paramComma(0)<<"CkChareID* pcid, int impl_onPE"<<eo(0)<<")\n";
2992   str << "{\n"<<marshallMsg();
2993   str << "  CkCreateChare("<<chareIdx()<<", "<<epIdx()<<", impl_msg, pcid, impl_onPE);\n";
2994   str << "}\n";
2995
2996   if (!param->isVoid()) {
2997     str << makeDecl(" ",1)<<"::"<<container->proxyName(0)<<"("<<paramComma(0)<<"int impl_onPE"<<eo(0)<<")\n";
2998     str << "{\n"<<marshallMsg();
2999     str << "  CkChareID impl_ret;\n";
3000     str << "  CkCreateChare("<<chareIdx()<<", "<<epIdx()<<", impl_msg, &impl_ret, impl_onPE);\n";
3001     str << "  ckSetChareID(impl_ret);\n";
3002     str << "}\n";
3003   }
3004 }
3005
3006 /***************************** Array Entry Points **************************/
3007
3008 void Entry::genArrayDecl(XStr& str)
3009 {
3010   if(isConstructor()) {
3011     str << "    " << generateTemplateSpec(tspec) << "\n";
3012     genArrayStaticConstructorDecl(str);
3013   } else {
3014     if ((isSync() || isLocal()) && !container->isForElement()) return; //No sync broadcast
3015     str << "    " << generateTemplateSpec(tspec) << "\n";
3016     if(isIget())
3017       str << "    "<<"CkFutureID"<<" "<<name<<"("<<paramType(1,1)<<") ;\n"; //no const
3018     else if(isLocal())
3019       str << "    "<<retType<<" "<<name<<"("<<paramType(1,1,0)<<") ;\n";
3020     else
3021       str << "    "<<retType<<" "<<name<<"("<<paramType(1,1)<<") ;\n"; //no const
3022   }
3023 }
3024
3025 void Entry::genArrayDefs(XStr& str)
3026 {
3027   if(isIget() && !container->isForElement()) return;
3028   if (isImmediate()) {
3029       cerr << (char *)container->baseName() << ": Chare Array does not allow immediate message.\n";
3030       exit(1);
3031   }
3032
3033   if (isConstructor())
3034     genArrayStaticConstructorDefs(str);
3035   else
3036   {//Define array entry method
3037     const char *ifNot="CkArray_IfNotThere_buffer";
3038     if (isCreateHere()) ifNot="CkArray_IfNotThere_createhere";
3039     if (isCreateHome()) ifNot="CkArray_IfNotThere_createhome";
3040
3041     if ((isSync() || isLocal()) && !container->isForElement()) return; //No sync broadcast
3042
3043     XStr retStr; retStr<<retType;
3044     if(isIget())
3045       str << makeDecl("CkFutureID ",1)<<"::"<<name<<"("<<paramType(0,1)<<") \n"; //no const
3046     else if(isLocal())
3047       str << makeDecl(retStr,1)<<"::"<<name<<"("<<paramType(0,1,0)<<") \n";
3048     else
3049       str << makeDecl(retStr,1)<<"::"<<name<<"("<<paramType(0,1)<<") \n"; //no const
3050     str << "{\n  ckCheck();\n";
3051     if (!isLocal()) {
3052       str << marshallMsg();
3053       str << "  CkArrayMessage *impl_amsg=(CkArrayMessage *)impl_msg;\n";
3054       str << "  impl_amsg->array_setIfNotThere("<<ifNot<<");\n";
3055     } else {
3056       XStr unmarshallStr; param->unmarshall(unmarshallStr);
3057       str << "  LDObjHandle objHandle;\n  int objstopped=0;\n";
3058       str << "  "<<container->baseName()<<" *obj = ckLocal();\n";
3059       str << "#if CMK_ERROR_CHECKING\n";
3060       str << "  if (obj==NULL) CkAbort(\"Trying to call a LOCAL entry method on a non-local element\");\n";
3061       str << "#endif\n";
3062       if (!isNoTrace())
3063           str << "  _TRACE_BEGIN_EXECUTE_DETAILED(0,ForArrayEltMsg,(" << epIdx()
3064               << "),CkMyPe(), 0, ((CkArrayIndex&)ckGetIndex()).getProjectionID(((CkGroupID)ckGetArrayID()).idx));\n";
3065       str << "#if CMK_LBDB_ON\n  objHandle = obj->timingBeforeCall(&objstopped);\n#endif\n";
3066       str << "#if CMK_CHARMDEBUG\n"
3067       "  CpdBeforeEp("<<epIdx()<<", obj, NULL);\n"
3068       "#endif\n   ";
3069       if (!retType->isVoid()) str << retType<< " retValue = ";
3070       str << "obj->"<<name<<"("<<unmarshallStr<<");\n";
3071       str << "#if CMK_CHARMDEBUG\n"
3072       "  CpdAfterEp("<<epIdx()<<");\n"
3073       "#endif\n";
3074       str << "#if CMK_LBDB_ON\n  obj->timingAfterCall(objHandle,&objstopped);\n#endif\n";
3075       if (!isNoTrace()) str << "  _TRACE_END_EXECUTE();\n";
3076       if (!retType->isVoid()) str << "  return retValue;\n";
3077     }
3078     if(isIget()) {
3079             str << "  CkFutureID f=CkCreateAttachedFutureSend(impl_amsg,"<<epIdx()<<",ckGetArrayID(),ckGetIndex(),&CProxyElement_ArrayBase::ckSendWrapper);"<<"\n";
3080     }
3081
3082     if(isSync()) {
3083       str << syncReturn() << "ckSendSync(impl_amsg, "<<epIdx()<<"));\n";
3084     }
3085     else if (!isLocal())
3086     {
3087       XStr opts;
3088       opts << ",0";
3089       if (isSkipscheduler())  opts << "+CK_MSG_EXPEDITED";
3090       if (isInline())  opts << "+CK_MSG_INLINE";
3091       if(!isIget()) {
3092       if (container->isForElement() || container->isForSection()) {
3093         str << "  ckSend(impl_amsg, "<<epIdx()<<opts<<");\n";
3094       }
3095       else
3096         str << "  ckBroadcast(impl_amsg, "<<epIdx()<<opts<<");\n";
3097       }
3098     }
3099     if(isIget()) {
3100             str << "  return f;\n";
3101     }
3102     str << "}\n";
3103   }
3104 }
3105
3106 void Entry::genArrayStaticConstructorDecl(XStr& str)
3107 {
3108   if (container->getForWhom()==forIndividual)
3109       str<< //Element insertion routine
3110       "    void insert("<<paramComma(1,0)<<"int onPE=-1"<<eo(1)<<");";
3111   else if (container->getForWhom()==forAll) {
3112       str<< //With options
3113       "    static CkArrayID ckNew("<<paramComma(1,0)<<"const CkArrayOptions &opts"<<eo(1)<<");\n";
3114       if (container->isArray()) {
3115         XStr dim = ((Array*)container)->dim();
3116         if (dim==(const char*)"1D") {
3117           str<<"    static CkArrayID ckNew("<<paramComma(1,0)<<"const int s1"<<eo(1)<<");\n";
3118         } else if (dim==(const char*)"2D") {
3119           str<<"    static CkArrayID ckNew("<<paramComma(1,0)<<"const int s1, const int s2"<<eo(1)<<");\n";
3120         } else if (dim==(const char*)"3D") {
3121           str<<"    static CkArrayID ckNew("<<paramComma(1,0)<<"const int s1, const int s2, const int s3"<<eo(1)<<");\n";
3122         /*} else if (dim==(const char*)"4D") {
3123           str<<"    static CkArrayID ckNew("<<paramComma(1,0)<<"const short s1, const short s2, const short s3, const short s4"<<eo(1)<<");\n";
3124         } else if (dim==(const char*)"5D") {
3125           str<<"    static CkArrayID ckNew("<<paramComma(1,0)<<"const short s1, const short s2, const short s3, const short s4, const short s5"<<eo(1)<<");\n";
3126         } else if (dim==(const char*)"6D") {
3127           str<<"    static CkArrayID ckNew("<<paramComma(1,0)<<"const short s1, const short s2, const short s3, const short s4, const short s5, const short s6"<<eo(1)<<");\n"; */
3128         }
3129       }
3130   }
3131   else if (container->getForWhom()==forSection) { }
3132 }
3133
3134 void Entry::genArrayStaticConstructorDefs(XStr& str)
3135 {
3136   if (container->getForWhom()==forIndividual)
3137       str<<
3138       makeDecl("void",1)<<"::insert("<<paramComma(0,0)<<"int onPE"<<eo(0)<<")\n"
3139       "{ \n"<<marshallMsg()<<
3140       "   ckInsert((CkArrayMessage *)impl_msg,"<<epIdx()<<",onPE);\n}\n";
3141   else if (container->getForWhom()==forAll){
3142       str<<
3143       makeDecl("CkArrayID",1)<<"::ckNew("<<paramComma(0)<<"const CkArrayOptions &opts"<<eo(0)<<")\n"
3144        "{ \n"<<marshallMsg()<<
3145          "   return ckCreateArray((CkArrayMessage *)impl_msg,"<<epIdx()<<",opts);\n"
3146        "}\n";
3147       if (container->isArray()) {
3148         XStr dim = ((Array*)container)->dim();
3149         if (dim==(const char*)"1D") {
3150           str<<
3151             makeDecl("CkArrayID",1)<<"::ckNew("<<paramComma(0)<<"const int s1"<<eo(0)<<")\n"
3152             "{ \n"<<marshallMsg()<<
3153             "   return ckCreateArray((CkArrayMessage *)impl_msg,"<<epIdx()<<",CkArrayOptions(s1));\n"
3154             "}\n";
3155         } else if (dim==(const char*)"2D") {
3156           str<<
3157             makeDecl("CkArrayID",1)<<"::ckNew("<<paramComma(0)<<"const int s1, const int s2"<<eo(0)<<")\n"
3158             "{ \n"<<marshallMsg()<<
3159             "   return ckCreateArray((CkArrayMessage *)impl_msg,"<<epIdx()<<",CkArrayOptions(s1, s2));\n"
3160             "}\n";
3161         } else if (dim==(const char*)"3D") {
3162           str<<
3163             makeDecl("CkArrayID",1)<<"::ckNew("<<paramComma(0)<<"const int s1, const int s2, const int s3"<<eo(0)<<")\n"
3164             "{ \n"<<marshallMsg()<<
3165             "   return ckCreateArray((CkArrayMessage *)impl_msg,"<<epIdx()<<",CkArrayOptions(s1, s2, s3));\n"
3166             "}\n";
3167         /*} else if (dim==(const char*)"4D") {
3168           str<<"    static CkArrayID ckNew("<<paramComma(1,0)<<"const short s1, const short s2, const short s3, const short s4"<<eo(1)<<");\n";
3169         } else if (dim==(const char*)"5D") {
3170           str<<"    static CkArrayID ckNew("<<paramComma(1,0)<<"const short s1, const short s2, const short s3, const short s4, const short s5"<<eo(1)<<");\n";
3171         } else if (dim==(const char*)"6D") {
3172           str<<"    static CkArrayID ckNew("<<paramComma(1,0)<<"const short s1, const short s2, const short s3, const short s4, const short s5, const short s6"<<eo(1)<<");\n";
3173         */
3174         }
3175       }
3176   }
3177
3178 }
3179
3180
3181 /******************************** Group Entry Points *********************************/
3182
3183 void Entry::genGroupDecl(XStr& str)
3184 {
3185 #if 0
3186   if (isImmediate() && !container->isNodeGroup()) {
3187       cerr << (char *)container->baseName() << ": Group does not allow immediate message.\n";
3188       exit(1);
3189   }
3190 #endif
3191   if (isLocal() && container->isNodeGroup()) {
3192     cerr << (char*)container->baseName() << ": Nodegroup does not allow LOCAL entry methods.\n";
3193     exit(1);
3194   }
3195
3196   if(isConstructor()) {
3197     str << "    " << generateTemplateSpec(tspec) << "\n";
3198     genGroupStaticConstructorDecl(str);
3199   } else {
3200     if ((isSync() || isLocal()) && !container->isForElement()) return; //No sync broadcast
3201     str << "    " << generateTemplateSpec(tspec) << "\n";
3202     if (isLocal())
3203       str << "    "<<retType<<" "<<name<<"("<<paramType(1,1,0)<<");\n";
3204     else
3205       str << "    "<<retType<<" "<<name<<"("<<paramType(1,1)<<");\n";
3206     // entry method on multiple PEs declaration
3207     if(!container->isForElement() && !container->isForSection() && !isSync() && !isLocal() && !container->isNodeGroup()) {
3208       str << "    " << generateTemplateSpec(tspec) << "\n";
3209       str << "    "<<retType<<" "<<name<<"("<<paramComma(1,0)<<"int npes, int *pes"<<eo(1)<<");\n";
3210       str << "    " << generateTemplateSpec(tspec) << "\n";
3211       str << "    "<<retType<<" "<<name<<"("<<paramComma(1,0)<<"CmiGroup &grp"<<eo(1)<<");\n";
3212     }
3213   }
3214 }
3215
3216 void Entry::genGroupDefs(XStr& str)
3217 {
3218   //Selects between NodeGroup and Group
3219   char *node = (char *)(container->isNodeGroup()?"Node":"");
3220
3221   if(isConstructor()) {
3222     genGroupStaticConstructorDefs(str);
3223   } else {
3224     int forElement=container->isForElement();
3225     XStr params; params<<epIdx()<<", impl_msg";
3226     XStr paramg; paramg<<epIdx()<<", impl_msg, ckGetGroupID()";
3227     XStr parampg; parampg<<epIdx()<<", impl_msg, ckGetGroupPe(), ckGetGroupID()";
3228     // append options parameter
3229     XStr opts; opts<<",0";
3230     if (isImmediate()) opts << "+CK_MSG_IMMEDIATE";
3231     if (isInline())  opts << "+CK_MSG_INLINE";
3232     if (isSkipscheduler())  opts << "+CK_MSG_EXPEDITED";
3233
3234     if ((isSync() || isLocal()) && !container->isForElement()) return; //No sync broadcast
3235
3236     XStr retStr; retStr<<retType;
3237     XStr msgTypeStr;
3238     if (isLocal())
3239       msgTypeStr<<paramType(0,1,0);
3240     else
3241       msgTypeStr<<paramType(0,1);
3242     str << makeDecl(retStr,1)<<"::"<<name<<"("<<msgTypeStr<<")\n";
3243     str << "{\n  ckCheck();\n";
3244     if (!isLocal()) str <<marshallMsg();
3245
3246     if (isLocal()) {
3247       XStr unmarshallStr; param->unmarshall(unmarshallStr);
3248       str << "  "<<container->baseName()<<" *obj = ckLocalBranch();\n";
3249       str << "  CkAssert(obj);\n";
3250       if (!isNoTrace()) str << "  _TRACE_BEGIN_EXECUTE_DETAILED(0,ForBocMsg,("<<epIdx()<<"),CkMyPe(),0,NULL);\n";
3251       str << "#if CMK_LBDB_ON\n"
3252 "  // if there is a running obj being measured, stop it temporarily\n"
3253 "  LDObjHandle objHandle;\n"
3254 "  int objstopped = 0;\n"
3255 "  LBDatabase *the_lbdb = (LBDatabase *)CkLocalBranch(_lbdb);\n"
3256 "  if (the_lbdb->RunningObject(&objHandle)) {\n"
3257 "    objstopped = 1;\n"
3258 "    the_lbdb->ObjectStop(objHandle);\n"
3259 "  }\n"
3260 "#endif\n";
3261       str << "#if CMK_CHARMDEBUG\n"
3262       "  CpdBeforeEp("<<epIdx()<<", obj, NULL);\n"
3263       "#endif\n  ";
3264       if (!retType->isVoid()) str << retType << " retValue = ";
3265       str << "obj->"<<name<<"("<<unmarshallStr<<");\n";
3266       str << "#if CMK_CHARMDEBUG\n"
3267       "  CpdAfterEp("<<epIdx()<<");\n"
3268       "#endif\n";
3269       str << "#if CMK_LBDB_ON\n"
3270 "  if (objstopped) the_lbdb->ObjectStart(objHandle);\n"
3271 "#endif\n";
3272       if (!isNoTrace()) str << "  _TRACE_END_EXECUTE();\n";
3273       if (!retType->isVoid()) str << "  return retValue;\n";
3274     } else if(isSync()) {
3275       str << syncReturn() <<
3276         "CkRemote"<<node<<"BranchCall("<<paramg<<", ckGetGroupPe()));\n";
3277     }
3278     else
3279     { //Non-sync entry method
3280       if (forElement)
3281       {// Send
3282         str << "  if (ckIsDelegated()) {\n";
3283         str << "     Ck"<<node<<"GroupMsgPrep("<<paramg<<");\n";
3284         str << "     ckDelegatedTo()->"<<node<<"GroupSend(ckDelegatedPtr(),"<<parampg<<");\n";
3285         str << "  } else CkSendMsg"<<node<<"Branch"<<"("<<parampg<<opts<<");\n";
3286       }
3287       else if (container->isForSection())
3288       {// Multicast
3289         str << "  if (ckIsDelegated()) {\n";
3290         str << "     Ck"<<node<<"GroupMsgPrep("<<paramg<<");\n";
3291         str << "     ckDelegatedTo()->"<<node<<"GroupSectionSend(ckDelegatedPtr(),"<<params<<", ckGetNumSections(), ckGetSectionIDs());\n";
3292         str << "  } else {\n";
3293         str << "    void *impl_msg_tmp = (ckGetNumSections()>1) ? CkCopyMsg((void **) &impl_msg) : impl_msg;\n";
3294         str << "    for (int i=0; i<ckGetNumSections(); ++i) {\n";
3295         str << "       impl_msg_tmp= (i<ckGetNumSections()-1) ? CkCopyMsg((void **) &impl_msg):impl_msg;\n";
3296         str << "       CkSendMsg"<<node<<"BranchMulti("<<epIdx()<<", impl_msg_tmp, ckGetGroupIDn(i), ckGetNumElements(i), ckGetElements(i)"<<opts<<");\n";
3297         str << "    }\n";
3298         str << "  }\n";
3299       }
3300       else
3301       {// Broadcast
3302         str << "  if (ckIsDelegated()) {\n";
3303         str << "     Ck"<<node<<"GroupMsgPrep("<<paramg<<");\n";
3304         str << "     ckDelegatedTo()->"<<node<<"GroupBroadcast(ckDelegatedPtr(),"<<paramg<<");\n";
3305         str << "  } else CkBroadcastMsg"<<node<<"Branch("<<paramg<<opts<<");\n";
3306       }
3307     }
3308     str << "}\n";
3309
3310     // entry method on multiple PEs declaration
3311     if(!forElement && !container->isForSection() && !isSync() && !isLocal() && !container->isNodeGroup()) {
3312       str << ""<<makeDecl(retStr,1)<<"::"<<name<<"("<<paramComma(1,0)<<"int npes, int *pes"<<eo(0)<<") {\n";
3313       str << marshallMsg();
3314       str << "  CkSendMsg"<<node<<"BranchMulti("<<paramg<<", npes, pes"<<opts<<");\n";
3315       str << "}\n";
3316       str << ""<<makeDecl(retStr,1)<<"::"<<name<<"("<<paramComma(1,0)<<"CmiGroup &grp"<<eo(0)<<") {\n";
3317       str << marshallMsg();
3318       str << "  CkSendMsg"<<node<<"BranchGroup("<<paramg<<", grp"<<opts<<");\n";
3319       str << "}\n";
3320     }
3321   }
3322 }
3323
3324 void Entry::genGroupStaticConstructorDecl(XStr& str)
3325 {
3326   if (container->isForElement()) return;
3327   if (container->isForSection()) return;
3328
3329   str << "    static CkGroupID ckNew("<<paramType(1,1)<<");\n";
3330   if (!param->isVoid()) {
3331     str << "    "<<container->proxyName(0)<<"("<<paramType(1,1)<<");\n";
3332   }
3333 }
3334
3335 void Entry::genGroupStaticConstructorDefs(XStr& str)
3336 {
3337   if (container->isForElement()) return;
3338   if (container->isForSection()) return;
3339
3340   //Selects between NodeGroup and Group
3341   char *node = (char *)(container->isNodeGroup()?"Node":"");
3342   str << makeDecl("CkGroupID",1)<<"::ckNew("<<paramType(0,1)<<")\n";
3343   str << "{\n"<<marshallMsg();
3344   str << "  return CkCreate"<<node<<"Group("<<chareIdx()<<", "<<epIdx()<<", impl_msg);\n";
3345   str << "}\n";
3346
3347   if (!param->isVoid()) {
3348     str << makeDecl(" ",1)<<"::"<<container->proxyName(0)<<"("<<paramType(0,1)<<")\n";
3349     str << "{\n"<<marshallMsg();
3350     str << "  ckSetGroupID(CkCreate"<<node<<"Group("<<chareIdx()<<", "<<epIdx()<<", impl_msg));\n";
3351     str << "}\n";
3352   }
3353 }
3354
3355 /******************* Python Entry Point Code **************************/
3356 void Entry::genPythonDecls(XStr& str) {
3357   str <<"/* STATIC DECLS: "; print(str); str << " */\n";
3358   if (isPython()) {
3359     // check the parameter passed to the function, it must be only an integer
3360     if (!param || param->next || !param->param->getType()->isBuiltin() || !((BuiltinType*)param->param->getType())->isInt()) {
3361       die("A python entry method must accept only one parameter of type `int`");
3362     }
3363
3364     str << "PyObject *_Python_"<<container->baseName()<<"_"<<name<<"(PyObject *self, PyObject *arg);\n";
3365   }
3366 }
3367
3368 void Entry::genPythonDefs(XStr& str) {
3369   str <<"/* DEFS: "; print(str); str << " */\n";
3370   if (isPython()) {
3371
3372     str << "PyObject *_Python_"<<container->baseName()<<"_"<<name<<"(PyObject *self, PyObject *arg) {\n";
3373     str << "  PyObject *dict = PyModule_GetDict(PyImport_AddModule(\"__main__\"));\n";
3374     str << "  int pyNumber = PyInt_AsLong(PyDict_GetItemString(dict,\"__charmNumber__\"));\n";
3375     str << "  PythonObject *pythonObj = (PythonObject *)PyLong_AsVoidPtr(PyDict_GetItemString(dict,\"__charmObject__\"));\n";
3376     str << "  "<<container->baseName()<<" *object = static_cast<"<<container->baseName()<<" *>(pythonObj);\n";
3377     str << "  object->pyWorkers[pyNumber].arg=arg;\n";
3378     str << "  object->pyWorkers[pyNumber].result=&CtvAccess(pythonReturnValue);\n";
3379     str << "  object->pyWorkers[pyNumber].pythread=PyThreadState_Get();\n";
3380     str << "  CtvAccess(pythonReturnValue) = 0;\n";
3381
3382     str << "  //pyWorker->thisProxy."<<name<<"(pyNumber);\n";
3383     str << "  object->"<<name<<"(pyNumber);\n";
3384
3385     str << "  //CthSuspend();\n";
3386
3387     str << "  if (CtvAccess(pythonReturnValue)) {\n";
3388     str << "    return CtvAccess(pythonReturnValue);\n";
3389     str << "  } else {\n";
3390     str << "    Py_INCREF(Py_None); return Py_None;\n";
3391     str << "  }\n";
3392     str << "}\n";
3393   }
3394 }
3395
3396 void Entry::genPythonStaticDefs(XStr& str) {
3397   if (isPython()) {
3398     str << "  {\""<<name<<"\",_Python_"<<container->baseName()<<"_"<<name<<",METH_VARARGS},\n";
3399   }
3400 }
3401
3402 void Entry::genPythonStaticDocs(XStr& str) {
3403   if (isPython()) {
3404     str << "\n  \""<<name<<" -- \"";
3405     if (pythonDoc) str <<(char*)pythonDoc;
3406     str <<"\"\\\\n\"";
3407   }
3408 }
3409
3410
3411 /******************* Accelerator (Accel) Entry Point Code ********************/
3412
3413 void Entry::genAccelFullParamList(XStr& str, int makeRefs) {
3414
3415   if (!isAccel()) return;
3416
3417   ParamList* curParam = NULL;
3418   int isFirst = 1;
3419
3420   // Parameters (which are read only by default)
3421   curParam = param;
3422   if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) { curParam = curParam->next; }
3423   while (curParam != NULL) {
3424
3425     if (!isFirst) { str << ", "; }
3426
3427     Parameter* param = curParam->param;
3428
3429     if (param->isArray()) {
3430       str << param->getType()->getBaseName() << "* " << param->getName();
3431     } else {
3432       str << param->getType()->getBaseName() << " " << param->getName();
3433     }
3434
3435     isFirst = 0;
3436     curParam = curParam->next;
3437   }
3438
3439   // Accel parameters
3440   curParam = accelParam;
3441   while (curParam != NULL) {
3442
3443     if (!isFirst) { str << ", "; }
3444
3445     Parameter* param = curParam->param;
3446     int bufType = param->getAccelBufferType();
3447     int needWrite = makeRefs && ((bufType == Parameter::ACCEL_BUFFER_TYPE_READWRITE) || (bufType == Parameter::ACCEL_BUFFER_TYPE_WRITEONLY));
3448     if (param->isArray()) {
3449       str << param->getType()->getBaseName() << "* " << param->getName();
3450     } else {
3451       str << param->getType()->getBaseName() << ((needWrite) ? (" &") : (" ")) << param->getName();
3452     }
3453
3454     isFirst = 0;
3455     curParam = curParam->next;
3456   }
3457
3458   // Implied object pointer
3459   if (!isFirst) { str << ", "; }
3460   str << container->baseName() << "* impl_obj";
3461 }
3462
3463 void Entry::genAccelFullCallList(XStr& str) {
3464   if (!isAccel()) return;
3465
3466   int isFirstFlag = 1;
3467
3468   // Marshalled parameters to entry method
3469   ParamList* curParam = param;
3470   if ((curParam->param->getType()->isVoid()) && (curParam->param->getName() == NULL)) { curParam = curParam->next; }
3471   while (curParam != NULL) {
3472     if (!isFirstFlag) str << ", ";
3473     isFirstFlag = 0;
3474     str << curParam->param->getName();
3475     curParam = curParam->next;
3476   }
3477
3478   // General variables (prefix with "impl_obj->" for member variables of the current object)
3479   curParam = accelParam;
3480   while (curParam != NULL) {
3481     if (!isFirstFlag) str << ", ";
3482     isFirstFlag = 0;
3483     str << (*(curParam->param->getAccelInstName()));
3484     curParam = curParam->next;
3485   }
3486
3487   // Implied object
3488   if (!isFirstFlag) str << ", ";
3489   isFirstFlag = 0;
3490   str << "impl_obj";
3491 }
3492
3493 void Entry::genAccelIndexWrapperDecl_general(XStr& str) {
3494   str << "    static void _accelCall_general_" << epStr() << "(";
3495   genAccelFullParamList(str, 1);
3496   str << ");\n";
3497 }
3498
3499 void Entry::genAccelIndexWrapperDef_general(XStr& str) {
3500   str << makeDecl("void") << "::_accelCall_general_" << epStr() << "(";
3501   genAccelFullParamList(str, 1);
3502   str << ") {\n\n";
3503
3504   //// DMK - DEBUG
3505   //str << "  // DMK - DEBUG\n";
3506   //str << "  CkPrintf(\"[DEBUG-ACCEL] :: [PPE] - "
3507   //    << makeDecl("void") << "::_accelCall_general_" << epStr()
3508   //    << "(...) - Called...\\n\");\n\n";
3509
3510   str << (*accelCodeBody);
3511
3512   str << "\n\n";
3513   str << "  impl_obj->" << (*accelCallbackName) << "();\n";
3514   str << "}\n";
3515 }
3516
3517 void Entry::genAccelIndexWrapperDecl_spe(XStr& str) {
3518
3519   // Function to issue work request
3520   str << "    static void _accelCall_spe_" << epStr() << "(";
3521   genAccelFullParamList(str, 0);
3522   str << ");\n";
3523
3524   // Callback function that is a member of CkIndex_xxx
3525   str << "    static void _accelCall_spe_callback_" << epStr() << "(void* userPtr);\n";
3526 }
3527
3528 // DMK - Accel Support
3529 #if CMK_CELL != 0
3530   #include "spert.h"
3531 #endif
3532
3533 void Entry::genAccelIndexWrapperDef_spe(XStr& str) {