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