69
64
paste (pos, code.str ());
72
void CodeWeaver::add_intro_include (JPL_Class *jpl, IntroductionInfo *ii) {
74
assert (jpl && (jpl->type() == JoinPointLoc::Class ||
75
jpl->type () == JoinPointLoc::Aspect));
77
if (ii->type () == IntroductionInfo::INTRO_SLICE_DECL ||
78
ii->type () == IntroductionInfo::INTRO_SLICE_REF) {
79
CObjectInfo *obj = ii->object (0);
80
assert (obj && obj->Tree ());
81
assert (obj->Tree ()->NodeName () == CT_ClassSliceDecl::NodeId ());
82
CT_ClassSliceDecl *csd = (CT_ClassSliceDecl*)obj->Tree ();
83
// first the includes for the class decl intros
84
Unit *su = (Unit*)csd->token ()->belonging_to ();
85
Unit *iu = jpl->unit ();
86
if (IntroductionUnit::cast (iu) == 0) // TODO: no intros into intros
87
_slice_includes.insert (iu, su);
88
// now the intros for the non-inline slice members
89
CClassDatabase *db = obj->ClassDB ();
90
ACSliceInfo *acsi = db->SliceInfo (obj);
92
for (int m = 0; m < acsi->members (); m++) {
93
CT_Intro *intro = acsi->member (m);
94
CSourceInfo *si = jpl->class_info ()->SourceInfo ();
95
bool in_header = (strcmp (si->FileName (),
96
si->FileInfo ()->Primary ()->name ()) != 0);
98
// check if there is a link-once code element in the class
99
CObjectInfo *loo = jpl->link_once_object ();
100
// return silently if this is only a declaration
101
if (!loo || loo->Scope () == jpl->class_info ())
104
iu = si->FileInfo ()->Primary ();
105
su = (Unit*)intro->token ()->belonging_to ();
106
if (IntroductionUnit::cast (iu) == 0) // TODO: no intros into intros
107
_slice_includes.insert (iu, su);
112
// old-style intros ...
113
Unit *su = (Unit*)&ii->unit ();
114
Unit *iu = jpl->unit ();
116
// handle the case of non-inline introductions
117
if (ii->prot () == CProtection::PROT_NONE) {
118
CSourceInfo *si = jpl->class_info ()->SourceInfo ();
119
bool in_header = (strcmp (si->FileName (),
120
si->FileInfo ()->Primary ()->name ()) != 0);
123
// check if there is a link-once code element in the class
124
CObjectInfo *loo = jpl->link_once_object ();
126
// TODO: for now loo has to != 0, later we can exploit the proj. repo
128
// error handling in introduce ()
132
// return silently if this is only a declaration
133
if (loo->Scope () == jpl->class_info ())
137
iu = si->FileInfo ()->Primary ();
140
// Introductions into introductions are not supported, yet
141
if (IntroductionUnit::cast (iu) != 0)
144
_slice_includes.insert (iu, su);
147
void CodeWeaver::add_aspect_include (JoinPointLoc *jpl, AspectInfo *ai,
148
ACAspectInfo *acai, AspectRef::Kind kind) {
67
void CodeWeaver::add_aspect_include (JoinPointLoc *jpl, AspectInfo &aspect_info,
68
AspectRef::Kind kind) {
151
71
if (jpl && jpl->type () == JoinPointLoc::MethodCall &&
152
72
((JPL_Code*)jpl)->is_pseudo ())
75
JPL_Aspect &jpl_aspect = aspect_info.loc ();
155
76
// TODO: find out what this 'if' is good for ;-)
157
iu = acai->ClassInfo ()->SourceInfo ()->FileInfo ()->Primary ();
78
// TODO: isn't there a _primary?
79
iu = TI_Aspect::of (jpl_aspect)->ClassInfo ()->SourceInfo ()->FileInfo ()->Primary ();
81
iu = TransformInfo::unit (*jpl);
162
84
// if the 'insert unit' is an 'introduction unit', find the intro target unit
373
295
ostringstream ns_close;
374
296
while (!obj->Scope ()->GlobalScope () && obj->Scope ()->NamespaceInfo ()) {
375
297
obj = obj->Scope ();
376
out << "} // closed " << obj->QualName () << endl;
381
void CodeWeaver::introduce (JPL_Class *loc, CTree *decl,
382
CProtection::Type prot, Token *primary_end) {
383
// name of the target class
384
ostringstream target;
385
target << " " << loc->class_info ()->QualName () << " " << ends;
387
if (prot != CProtection::PROT_NONE) {
388
// // An introduction inside the class
389
// CClassInfo *cls = loc->class_info ();
391
// // paste declaration before "}" of the class definition
392
// Token *inspos = ((CT_ClassDef*)cls->DefObject ()->
393
// Tree ())->Members ()->end_token ();
394
// const WeavePos &pos = weave_pos (inspos, WeavePos::WP_BEFORE);
395
//g++" -v -Dslice=_slice -I"../include" -O2 -Wall -D_REENTRANT -D_GNU_SOURCE -DPIC -fPIC -c -xc++ "os-unix.acc" -xnone -I"." -o "os-unix.pic.o"
396
// // paste 'private:', 'protected', or 'public'
397
// paste (pos, protection_string (prot));
399
// // copy the declaration
400
// // replace all names of the aspect in the introduction with the name
401
// // of the target class
402
// CT_Intro *intro = (CT_Intro*)decl;
404
// for (int i = 0; i < intro->NameIndices (); i++) {
405
// int index = intro->NameIndex (i);
406
// if (index > start) {
407
// copy (weave_pos (intro->Entry (start)->token (),
408
// WeavePos::WP_BEFORE),
409
// weave_pos (intro->Entry (index - 1)->end_token (),
410
// WeavePos::WP_AFTER),
413
// paste (pos, target.str ());
414
// start = index + 1;
416
// if (start < intro->Entries ()) {
417
// copy (weave_pos (intro->Entry (start)->token (),
418
// WeavePos::WP_BEFORE),
419
// weave_pos (intro->Entry (intro->Entries () - 1)->end_token (),
420
// WeavePos::WP_AFTER),
424
// // paste 'private:' afterwards
425
// paste (pos, protection_string (CProtection::PROT_PRIVATE));
428
// an external introduction
430
CSourceInfo *si = loc->class_info ()->SourceInfo ();
431
bool in_header = (strcmp (si->FileName (),
432
si->FileInfo ()->Primary ()->name ()) != 0);
435
// check if there is a link-once code element in the class
436
CObjectInfo *loo = loc->link_once_object ();
438
// TODO: for now loo has to != 0, later we can exploit the proj. repo
440
_err << sev_warning << decl->token ()->location ()
441
<< "cannot introduce non-inline function or static attribute"
442
<< " into \"class " << loc->class_info ()->QualName ()
443
<< "\". It has to contain link-once code." << endMessage;
447
// return silently if this is only a declaration
448
if (loo->Scope () == loc->class_info ())
452
// insert the copy of the declaration at the end of the translation unit
453
const WeavePos &pos = weave_pos (primary_end, WeavePos::WP_AFTER);
455
// TODO: this loop has to be executed in a different order than the loop
456
// for the introduction of inline members. The reason is the
457
// tranformation system: here we have an WP_AFTER position while
458
// the other loop has a WP_BEFORE position. That's ugly!
460
// replace all names of the aspect in the introduction with the name
461
// of the target class
462
CT_Intro *intro = (CT_Intro*)decl;
463
ostringstream target_qual, target_unqual;
464
target_unqual << " " << loc->class_info ()->Name () << " " << ends;
465
target_qual << " " << loc->class_info ()->QualName () << " " << ends;
466
int start = intro->Entries () - 1;
467
for (int i = intro->NameIndices () - 1; i >= 0; i--) {
468
int index = intro->NameToIndex (i);
470
copy (weave_pos (intro->Entry (index + 1)->token (),
471
WeavePos::WP_BEFORE),
472
weave_pos (intro->Entry (start)->end_token (),
476
if (intro->NameQual (i))
477
paste (pos, target_qual.str ());
479
paste (pos, target_unqual.str ());
480
start = intro->NameIndex (i) - 1;
483
copy (weave_pos (intro->Entry (0)->token (),
484
WeavePos::WP_BEFORE),
485
weave_pos (intro->Entry (start)->end_token (),
492
void CodeWeaver::baseclass (JPL_Class &loc, JPP_Class &plan) {
493
CClassInfo *cls = loc.class_info ();
495
// let the plan generate the baseclass list
496
string bcl = plan.gen_baseclass_list ();
498
bcl = string (cls->BaseClasses () == 0 ? " :" : ",") + bcl;
499
// paste the new base before "{" of the class definition's member list
500
const WeavePos &pos = weave_pos (((CT_ClassDef*)cls->DefObject ()->
501
Tree ())->Members ()->token (),
502
WeavePos::WP_BEFORE);
507
// void CodeWeaver::inherited (JPL_Class *loc, IntroductionInfo *intro)
509
// TN_ClassInfo *cls = loc->class_info ();
511
// const char *prot = intro->def_node ()->protection ();
513
// for (unsigned f = 0; f < cls->Functions (); f++)
515
// TN_FunctionInfo *func = cls->Function (f);
516
// if (!func->isInherited () || func->isVirtual ())
519
// if(!((strcmp (prot, "private") == 0 &&
520
// func->Protection () == TN_ObjectInfo::PRIVATE) ||
521
// (strcmp (prot, "protected") == 0 &&
522
// func->Protection () == TN_ObjectInfo::PROTECTED) ||
523
// (strcmp (prot, "public") == 0 &&
524
// func->Protection () == TN_ObjectInfo::PUBLIC)))
527
// // This check is too simple, it forgets the argument types
528
// unsigned args = func->BaseObject ()->FunctionInfo ()->Arguments ();
530
// for (unsigned l = 0; l < cls->Functions (); l++)
532
// TN_FunctionInfo *cmp = cls->Function (l);
533
// if (cmp->isInherited ())
534
// cmp = cmp->BaseObject ()->FunctionInfo ();
537
// strcmp (func->Name (), cmp->Name ()) == 0 &&
538
// args == cmp->Arguments ())
547
// _err << sev_warning << "Function " << func->Name ()
548
// << " is inherited more than once by class "
549
// << cls->Name () << ": "
550
// << cls->Function (number)->BaseObject ()->QualName ()
551
// << " and " << func->BaseObject ()->QualName ()
556
// CUnit *out = new_intro_unit (intro);
558
// *out << prot << ":" << endl;
560
// func = func->BaseObject ();
561
// TN_TypeInfo *ftype = func->TypeInfo ();
563
// *out << "inline ";
564
// if (func->isVirtual ())
565
// *out << "virtual ";
566
// else if (func->defStatic ())
567
// *out << "static ";
569
// if (func->isOperator ())
570
// sig << "operator ";
571
// sig << func->Name ();
573
// replacement_fct_args (sig, func, true, true);
575
// if (ftype->isConst ())
577
// if (ftype->isVolatile ())
578
// sig << " volatile";
580
// TN_TypeInfo *result_type = ftype->BaseType ();
581
// result_type->TypeText (*out, sig.str ().data ());
583
// // generate the function body
585
// *out << " {" << endl;
587
// if (!result_type->isVoid ())
588
// *out << "return ";
589
// if (func->Scope ()->ClassInfo ())
590
// *out << "::" << func->Scope ()->ClassInfo ()->QualName () << "::";
591
// if (func->isOperator ())
592
// *out << "operator ";
593
// *out << func->Name () << "(";
594
// for (unsigned a = 0; a < func->Arguments (); a++)
598
// *out << "arg" << a;
600
// *out << ");" << endl;
601
// *out << " }" << endl;
604
// // paste the function behind "{" of the class definition
605
// Token *inspos = cls->DefNode ()->son (2)->token ();
607
// _commander.paste (inspos, out);
298
out << "} // closed " << (obj->isAnonymous () ? "" : obj->QualName ()) << endl;
611
303
void CodeWeaver::singleton (ACAspectInfo *ai) {
612
304
if (ai->aspect_of ()) {
687
383
cflows.gen_trigger_obj (out);
690
// generate the 'result =' code
691
CTypeInfo *result_type =
692
dstfunc->isConversion () ? dstfunc->ConversionType () :
693
dstfunc->TypeInfo ()->BaseType ();
696
make_action_result_assignment(out, result_type);
698
make_result_assignment(out, result_type);
386
// generate the expression that calculates the result
700
389
// if we call the function with a function pointer there must be one more br.
704
393
// if an object is needed for the call, issue 'obj->'
705
394
if (obj_needed) {
709
Naming::tjp_struct (out, loc, 0);
710
out << "::Target*)_target)->";
397
res << "__TJP::target ()->";
716
402
else if (is_exec || is_cons || is_dest) {
719
Naming::tjp_struct (out, loc, 0);
720
out << "::That*)_that)->";
404
res << "__TJP::that ()->";
728
410
// generate the function name
729
411
if (is_exec || (!dstfunc->isBuiltin () && (is_cons || is_dest))) {
730
412
if (!obj_needed && nscope (dstfunc))
731
out << "::" << nscope (dstfunc)->QualName () << "::";
413
res << "::" << nscope (dstfunc)->QualName () << "::";
732
414
// use __old_<name> for execution join points
733
Naming::exec_inner (out, loc);
415
Naming::exec_inner (res, loc);
734
416
} else if (is_call) {
735
417
if (havefuncptr) {
738
// if (dstfunc->isMethod () && !dstfunc->isStaticMethod ())
739
// CTypeMemberPointer (dstfunc->TypeInfo (),
740
// dstfunc->Record ()).TypeText (out, "*",
743
// CTypePointer (dstfunc->TypeInfo ()).TypeText (out, "*", true, true);
744
if (dstfunc->isMethod ())
745
CTypePointer (dstfunc->TypeInfo ()).TypeText (out, "*", false, true);
420
CObjectInfo *srcobj = TransformInfo::of (*loc)->assoc_obj();
421
CFunctionInfo *srcfunc = srcobj->FunctionInfo ();
422
CClassInfo *srccls = cscope (srcfunc);
423
CClassInfo *dstcls = cscope (dstfunc);
425
(srccls && dstcls && dstcls->isDerivedClass (srccls, true));
427
CTypePointer (srcfunc->TypeInfo ()).TypeText (res, "*", true, true);
429
CTypePointer (dstfunc->TypeInfo ()).TypeText (res, "*", true, true);
752
436
// destination function name
753
if (((JPL_MethodCall*)loc)->is_qualified () ||
754
dstfunc->isStaticMethod () || !dstfunc->isMethod ()) {
756
if (nscope (dstfunc))
757
out << nscope (dstfunc)->QualName () << "::";
760
out << dstfunc->Name ();
437
if (((TI_MethodCall*)TransformInfo::of (*loc))->is_qualified () ||
438
dstfunc->isStaticMethod () || !dstfunc->isMethod ())
439
res << dstfunc->QualName (true, true);
441
res << dstfunc->Name ();
443
// add the template arguments if it is a function template instance
444
CTemplateInstance *instance = dstfunc->TemplateInstance ();
447
for (unsigned a = 0; a < instance->DeducedArgs (); a++) {
448
if (a > 0) res << ",";
449
DeducedArgument *arg = instance->DeducedArg (a);
451
arg->Type ()->TypeText (res, "", true, true);
452
else if (arg->Value ()) {
453
if (arg->Value ()->isSigned ())
454
res << arg->Value ()->convert_to_int ();
455
else if (arg->Value ()->isUnsigned ())
456
res << arg->Value ()->convert_to_uint ();
457
else if (arg->Value ()->isFloat ())
458
res << arg->Value ()->convert_to_float ();
461
res << "*invalid template arg*";
764
469
// if this was a call via pointer we need a closing bracket
768
473
// destination function arguments
770
475
for (int a = 0 ; a < loc->arg_count (); a++) {
771
if (a > 0) out << ", ";
476
if (a > 0) res << ", ";
773
478
// make sure that if the argument type was a reference we use the
774
479
// referred type here
776
Naming::tjp_struct (out, loc, 0);
777
out << "::Arg<" << a << ">::ReferredType*)_args[" << a << "])";
480
res << "*(typename __TJP::template Arg<" << a
481
<< ">::ReferredType*)__TJP::arg(" << a << ")";
783
// new: bracket if we have a result assignment
784
if (!(result_type->isVoid () || result_type->isUndefined ()))
488
// generate the 'result =' code
489
CTypeInfo *result_type =
490
dstfunc->isConversion () ? dstfunc->ConversionType () :
491
dstfunc->TypeInfo ()->BaseType ();
493
ResultBuffer result_buffer (result_type);
496
out << result_buffer.action_result_assignment(res.str ());
498
out << result_buffer.result_assignment(res.str ());
787
500
out << ";" << endl;
824
535
make_proceed_code (impl, loc, true, jpa->max_depth ());
538
// generate __TJP type (for the next level)
540
Naming::tjp_struct (impl, (JPL_Code*)loc, jpa->depth () - 1);
541
impl << "<TResult, TThat, TTarget, TArgs> __TJP;" << endl;
827
542
// generate advice calls
828
543
make_advice_calls (impl, jpa->next (), loc, true);
830
545
impl << " }" << endl;
548
// generate the name of the joinpoint-specific TJP type
549
void CodeWeaver::make_tjp_typename (ostream &out, JPL_Code *loc, int depth) {
550
TI_Code *ti = (TI_Code*)TransformInfo::of (*loc);
551
Naming::tjp_struct (out, loc, depth);
552
out << "< " << ThisJoinPoint::gen_result_type (loc) << ", ";
553
ti->that_type ()->TypeText (out, "", true, true);
555
ti->target_type ()->TypeText (out, "", true, true);
557
unsigned arg_count = loc->arg_count ();
559
for (unsigned a = 0; a < arg_count; a++) {
560
CTypeInfo *argtype = TI_Type::of (loc->arg_type (a))->type_info ();
562
argtype->TypeText (out, "", true, true);
566
for (unsigned a = 0; a < arg_count; a++)
833
571
// insert TJP class definition before join point
834
void CodeWeaver::make_tjp_struct(ostream &out, JoinPointLoc *loc,
572
void CodeWeaver::make_tjp_struct(ostream &out, JoinPointLoc *ploc,
574
JPL_Code *loc = (JPL_Code*)ploc;
837
576
// recursively call the function for the previous TJP classes
838
577
if (jpa->depth () > 0) {
839
578
make_tjp_struct (out, loc, jpa->next ());
845
584
tjp.gen_tjp_struct (out, (JPL_Code*)loc, _problems, jpa->depth ());
847
586
// generate the proceed function for the current structure
848
if (jpa->around () &&
849
(jpa->around ()->code ().this_join_point ().proceed () ||
850
jpa->around ()->code ().this_join_point ().action() ||
851
!jpa->around ()->pointcut ().cflow_triggers ().empty ()))
852
make_proceed_func (out, loc, jpa);
854
// generate action wrapper if needed
855
if (jpa->around () && jpa->around ()->code ().this_join_point ().action())
856
make_action_wrapper (out, loc, jpa);
858
// closing bracket of the TJP class! Opened in gen_tjp_struct.
587
if (jpa->around ()) {
588
const ThisJoinPoint &curr_tjp =
589
TI_AdviceCode::of (jpa->around ()->code ())->this_join_point ();
590
if (curr_tjp.proceed () || curr_tjp.action() ||
591
!jpa->around ()->pointcut ().cflow_triggers ().empty ())
592
make_proceed_func (out, loc, jpa);
594
// generate action wrapper if needed
595
if (curr_tjp.action())
596
make_action_wrapper (out, loc, jpa);
861
599
if (jpa->depth () == 0) {
862
600
stringstream jpname;
863
Naming::tjp_struct (jpname, loc, 0);
601
Naming::tjp_struct(jpname, loc, 0);
865
602
jpa->root ()->gen_binding_templates (out, jpname.str ().data (), _problems);
605
// closing bracket of the TJP class! Opened in gen_tjp_struct.
871
611
void CodeWeaver::make_tjp_common_init(ostream &code, JoinPointLoc *badly_typed_loc,
873
JPL_Code *loc = (JPL_Code*)badly_typed_loc;
874
const ThisJoinPoint &tjp = jpa->tjp ();
875
JoinPointLoc::join_point_type jptype = loc->type ();
877
bool local_class = false, havefuncptr = false;
878
// determine the weaving parameters
879
if (jptype == JoinPointLoc::MethodCall) {
880
local_class = (!_problems._local_class &&
881
!((JPL_MethodCall*)loc)->in_member_init () &&
882
((JPL_MethodCall*)loc)->needs_rights ());
883
havefuncptr = (((JPL_MethodCall*)loc)->needs_rights () &&
884
(!local_class || jpa->depth () > 0));
887
if (tjp.pointer_needed ()) {
889
int args = ((JPL_Code*)loc)->arg_count ();
890
if (tjp.arg() || tjp.useAction() ||
891
(tjp.proceed () && loc->proceed_needs_args ())) {
894
Naming::tjp_args_array(code, loc);
896
for (int i = 0; i < args; i++) {
897
if (i > 0) code << ", ";
898
code << "(void*)&arg" << i;
900
code << " };" << endl;
905
Naming::tjp_struct(code, loc, jpa->depth ());
907
Naming::tjp_instance(code, loc);
910
if (tjp.arg() || tjp.useAction() ||
911
(tjp.proceed () && loc->proceed_needs_args ())) {
913
Naming::tjp_instance(code, loc);
916
Naming::tjp_args_array(code, loc);
922
if (tjp.result() || tjp.useAction() ||
923
(tjp.proceed () && loc->proceed_needs_result ())) {
925
Naming::tjp_instance(code, loc);
926
code << "._result = ";
927
CTypeInfo *rtype = ((JPL_Code*)loc)->result_type ().type_info ();
928
if (!(rtype->isVoid() || rtype->isUndefined ())) {
929
if (tjp.useAction ())
932
Naming::tjp_struct (code, loc, jpa->depth ());
933
code << "::Result&)result";
940
if (tjp.target() || tjp.useAction() ||
941
(tjp.proceed () && loc->proceed_needs_target ())) {
943
Naming::tjp_instance(code, loc);
944
code << "._target = ";
945
if (loc->tjp_target () && needs_this (loc->tjp_target())) {
947
if (tjp.useAction ())
950
Naming::tjp_struct(code, loc, jpa->depth ());
951
code << "::Target*)";
954
case JoinPointLoc::Construction:
955
case JoinPointLoc::Destruction:
956
case JoinPointLoc::Method:
959
case JoinPointLoc::MethodCall:
971
if (tjp.that() || tjp.useAction() ||
972
(tjp.proceed () && loc->proceed_needs_that ())) {
974
Naming::tjp_instance(code, loc);
976
if (loc->tjp_that () && needs_this (loc->tjp_that())) {
978
if (tjp.useAction ())
981
Naming::tjp_struct(code, loc, jpa->depth ());
985
case JoinPointLoc::Construction:
986
case JoinPointLoc::Destruction:
987
case JoinPointLoc::Method:
990
case JoinPointLoc::MethodCall:
1002
if (tjp.useAction () ||
1003
(tjp.proceed () && loc->proceed_needs_fptr ())) {
1005
Naming::tjp_instance(code, loc);
1006
code << "._fptr = ";
1011
code << ";" << endl;
1016
void CodeWeaver::make_result_type (ostream &out, CTypeInfo *type,
1018
if (type->isVoid () || type->isUndefined ())
1020
else if (type->isAddress ())
1021
type->BaseType ()->TypeText (out, reference ? "*&" : "*", true, true);
1023
type->TypeText (out, reference ? "&" : "", true, true);
1026
void CodeWeaver::make_result_declaration(ostream &out, CTypeInfo *type) {
1027
if (!(type->isVoid () || type->isUndefined ())) {
1028
out << " AC::ResultBuffer< ";
1029
make_result_type (out, type, false);
1030
out << " > result;" << endl;
1034
void CodeWeaver::make_result_assignment(ostream &out, CTypeInfo *type) {
1035
if (!(type->isVoid() || type->isUndefined ())) {
1036
out << " ::new (&result) ";
1037
make_result_type (out, type->UnqualType (), false);
1039
if (type->isAddress ())
1044
void CodeWeaver::make_action_result_assignment(ostream &out, CTypeInfo *type) {
1045
if (!(type->isVoid() || type->isUndefined ())) {
1046
out << " ::new ((AC::ResultBuffer< ";
1047
make_result_type (out, type, false);
1048
out << " >*)_result) ";
1049
make_result_type (out, type, false);
1051
if (type->isAddress ())
1056
void CodeWeaver::make_result_return(ostream &out, CTypeInfo *type) {
1057
if (!(type->isVoid () || type->isUndefined ())) {
1059
if (type->isAddress ())
1062
make_result_type (out, type, true);
1063
out << ")result;" << endl;
613
jpa->tjp ().gen_tjp_init(code, (JPL_Code*)badly_typed_loc,
614
_problems, jpa->depth ());
617
// generates the signature of a wrapper function for exec/cons/dest join pts
618
string CodeWeaver::wrapper_function_signature (JPL_Code *loc,
619
CFunctionInfo *func, bool def) {
622
stringstream name_args;
623
if (func->CObjectInfo::QualifiedScope () &&
624
func->Scope () != func->CObjectInfo::QualifiedScope ())
625
name_args << func->CObjectInfo::QualifiedScope ()->QualName () << "::";
626
Naming::exec_inner (name_args, loc);
628
for (unsigned a = 0; a < func->Arguments (); a++) {
629
CArgumentInfo *arg = func->Argument (a);
630
if (arg->TypeInfo ()->is_void ())
632
if (a > 0) name_args << ",";
633
arg->TypeInfo ()->TypeText (name_args,
634
arg->isAnonymous () ? "" : arg->Name (),
639
ostringstream wrapped;
641
if (_problems._use_always_inline) // GNU extension
642
wrapped << "__attribute__((always_inline)) ";
643
wrapped << "inline "; // the wrapped function should always be inlined
644
if (func->isStaticMethod () && func->ClassScope () == func->Scope ())
645
wrapped << "static ";
647
if (func->isConstructor () || func->isDestructor ())
648
wrapped << "void " << name_args.str ().c_str ();
650
CTypeInfo *type = func->isConversion () ? func->ConversionType () :
651
func->TypeInfo ()->BaseType ();
652
type->TypeText (wrapped, name_args.str ().c_str (), true, true);
653
if (func->TypeInfo ()->isConst ())
655
if (func->TypeInfo ()->isVolatile ())
656
wrapped << " volatile";
659
return wrapped.str ();
1067
662
void CodeWeaver::cons_join_point (JPL_Construction *loc, JPP_Code &plan) {
1068
if (loc->assoc_obj ()->FunctionInfo ()->isBuiltin ())
663
if (loc->function ()->is_built_in())
1069
664
gen_special_member_function (loc, plan);
1071
666
wrap_function (loc, plan);
1074
669
void CodeWeaver::dest_join_point (JPL_Destruction *loc, JPP_Code &plan) {
1075
if (loc->assoc_obj ()->FunctionInfo ()->isBuiltin ())
670
if (loc->function ()->is_built_in())
1076
671
gen_special_member_function (loc, plan);
1078
673
wrap_function (loc, plan);
1843
1480
code << "};" << endl;
1848
1483
// now we perform the code manipulation
1850
1485
// insert the call wrapper body
1853
Token *inspos = ((CT_FctDef*)srcfunc->Tree ())->Body ()->token ();
1854
paste (weave_pos (inspos, WeavePos::WP_AFTER), code.str ());
1859
CT_FctDef *fctdef = (CT_FctDef*)srcfunc->Tree ();
1860
pos = linkage_adjust (fctdef);
1863
pos = ((CT_InitDeclarator*)srcobj->Tree ())->ObjDecl ();
1864
paste (weave_pos (pos->token (), WeavePos::WP_BEFORE), code.str ());
1486
paste (*pos, code.str ());
1867
1488
// replace call with call to replacement function
1869
1490
// paste the first (generated) part of the call (in front)
1870
paste (weave_pos (loc->CallExprNode ()->token (), WeavePos::WP_BEFORE),
1491
paste (weave_pos (ti.CallNode ()->token (), WeavePos::WP_BEFORE),
1871
1492
new_call.str ());
1873
1494
// paste a closing bracket behind the call
1874
paste (weave_pos (loc->CallExprNode ()->end_token (), WeavePos::WP_AFTER),
1495
paste (weave_pos (ti.CallNode ()->end_token (), WeavePos::WP_AFTER),
1877
1498
// provide the other arguments
1880
// the destination function is a conversion function
1881
if (dstfunc->isConversion ()) {
1884
paste (weave_pos (node->end_token (), WeavePos::WP_AFTER), ")");
1886
1501
// call was a binary operator call
1887
else if (calltype == CT_BinaryExpr::NodeId ()) {
1888
node = ((CT_BinaryExpr*)loc->CallExprNode ()->Son (0))->Son (0);
1502
if (calltype == CT_BinaryExpr::NodeId ()) {
1503
node = ((CT_BinaryExpr*)ti.CallNode ())->Son (0);
1889
1504
if (target_expr) {
1890
1505
if (!target_is_ptr)
1891
1506
paste (weave_pos (node->end_token (), WeavePos::WP_AFTER), ")");
1893
1508
else if ((havesrcthis || havefuncptr) && !havedstthis)
1894
1509
paste (weave_pos (node->token (), WeavePos::WP_BEFORE), ",");
1895
node = ((CT_BinaryExpr*)loc->CallExprNode ()->Son (0))->Son (1);
1510
node = ((CT_BinaryExpr*)ti.CallNode ())->Son (1);
1896
1511
paste (weave_pos (node->end_token (), WeavePos::WP_AFTER), ",");
1899
1514
// call was a unary operator call
1900
1515
else if (calltype == CT_UnaryExpr::NodeId ()) {
1901
node = ((CT_BinaryExpr*)loc->CallExprNode ()->Son (0))->Son (0);
1516
node = ((CT_BinaryExpr*)ti.CallNode ())->Son (0);
1903
node = ((CT_BinaryExpr*)loc->CallExprNode ()->Son (0))->Son (1);
1518
node = ((CT_BinaryExpr*)ti.CallNode ())->Son (1);
1904
1519
if (target_expr) {
1905
1520
if (!target_is_ptr)
1906
1521
paste (weave_pos (node->end_token (), WeavePos::WP_AFTER), ")");
1922
1537
// call was an index operator call
1923
1538
else if (calltype == CT_IndexExpr::NodeId ()) {
1924
node = ((CT_BinaryExpr*)loc->CallExprNode ()->Son (0))->Son (0);
1539
node = ((CT_BinaryExpr*)ti.CallNode ())->Son (0);
1925
1540
if (target_expr && !target_is_ptr)
1926
1541
paste (weave_pos (node->end_token (), WeavePos::WP_AFTER), ")");
1927
1542
// replace the opening '[' with ','
1928
node = ((CT_BinaryExpr*)loc->CallExprNode ()->Son (0))->Son (1);
1543
node = ((CT_BinaryExpr*)ti.CallNode ())->Son (1);
1929
1544
paste (weave_pos (node->end_token (), WeavePos::WP_AFTER), ",");
1931
1546
// delete the closing ']'
1932
node = ((CT_BinaryExpr*)loc->CallExprNode ()->Son (0))->Son (3);
1547
node = ((CT_BinaryExpr*)ti.CallNode ())->Son (3);
1550
// the destination function is a conversion function
1551
else if (calltype == CT_ImplicitCall::NodeId ()) {
1554
paste (weave_pos (node->end_token (), WeavePos::WP_AFTER), ")");
1935
1556
// call was an ordinary function call
1558
const char *fctnodetype = ti.CallNode()->Son (0)->NodeName ();
1937
1559
if ((target_expr && !target_is_ptr) &&
1938
(calltype == CT_MembRefExpr::NodeId () ||
1939
calltype == CT_MembPtrExpr::NodeId ())) {
1940
node = loc->CallExprNode ()->Son (0);
1560
(fctnodetype == CT_MembRefExpr::NodeId () ||
1561
fctnodetype == CT_MembPtrExpr::NodeId ())) {
1562
node = ti.CallNode ()->Son (0);
1941
1563
paste (weave_pos (node->end_token (), WeavePos::WP_AFTER), ")");
1943
if (calltype == CT_MembRefExpr::NodeId () && havedstthis) {
1944
kill (((CT_MembRefExpr*)loc->CallExprNode ()->Son (0))->Son (1));
1945
kill (((CT_MembRefExpr*)loc->CallExprNode ()->Son (0))->Son (2));
1565
if (fctnodetype == CT_MembRefExpr::NodeId () && havedstthis) {
1566
kill (((CT_MembRefExpr*)ti.CallNode ()->Son (0))->Son (1));
1567
kill (((CT_MembRefExpr*)ti.CallNode ()->Son (0))->Son (2));
1947
else if (calltype == CT_MembPtrExpr::NodeId () && havedstthis) {
1948
kill (((CT_MembPtrExpr*)loc->CallExprNode ()->Son (0))->Son (1));
1949
kill (((CT_MembPtrExpr*)loc->CallExprNode ()->Son (0))->Son (2));
1569
else if (fctnodetype == CT_MembPtrExpr::NodeId () && havedstthis) {
1570
kill (((CT_MembPtrExpr*)ti.CallNode ()->Son (0))->Son (1));
1571
kill (((CT_MembPtrExpr*)ti.CallNode ()->Son (0))->Son (2));
1952
kill (loc->CallExprNode ()->Son (0));
1953
CT_ExprList *args = loc->CallExprNode ()->Arguments ();
1574
kill (ti.CallNode ()->Son (0));
1575
CT_ExprList *args = ((CT_CallExpr*)ti.CallNode ())->Arguments ();
1955
_err << sev_warning << loc->CallExprNode ()->token ()->location ()
1577
_err << sev_warning << ti.CallNode ()->token ()->location ()
1956
1578
<< "unsupported kind of call, cannot weave advice code"