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