File: CodeWeaver.h

package info (click to toggle)
aspectc%2B%2B 1%3A2.0%2Bsvn20160329-1~bpo8.0
  • links: PTS
  • area: main
  • in suites: jessie-backports
  • size: 16,132 kB
  • sloc: cpp: 106,806; ansic: 7,644; sh: 2,188; makefile: 1,269; pascal: 634; python: 402; xml: 349
file content (227 lines) | stat: -rw-r--r-- 8,873 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
// This file is part of the AspectC++ compiler 'ac++'.
// Copyright (C) 1999-2003  The 'ac++' developers (see aspectc.org)
//                                                                
// This program is free software;  you can redistribute it and/or 
// modify it under the terms of the GNU General Public License as 
// published by the Free Software Foundation; either version 2 of 
// the License, or (at your option) any later version.            
//                                                                
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
// GNU General Public License for more details.                   
//                                                                
// You should have received a copy of the GNU General Public      
// License along with this program; if not, write to the Free     
// Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
// MA  02111-1307  USA                                            

#ifndef __CodeWeaver_h__
#define __CodeWeaver_h__

// The code weaver allows AspectC++ specific code manipulation transactions.
// All access to the syntax tree nodes for the transformation is 
// encapsulated here.
// The class does not know about class JoinPoint. It only knows join point
// locations (JPL_*).

#include <iostream>
#include <set>
#include <map>
using namespace std;

#include "ACToken.h"
#include "ACErrorStream.h"
#include "ACProject.h"
#include "ACConfig.h"
#include "ACResultBuffer.h"
#include "WeaverBase.h"
#include "AspectIncludes.h"
#include "SyntacticContext.h"

namespace Puma {
  class CTree;
  class CClassInfo;
  class CRecord;
  class CProject;
} // namespace Puma

#ifdef FRONTEND_CLANG
namespace clang {
  class DeclContext;
}
#endif

class ACM_Any;
class ACM_Class;
class ACM_Execution;
class ACM_Call;
class ACM_Code;
class ACM_CodePlan;

class AspectInfo;
class AdviceInfo;
class ThisJoinPoint;
class TI_MethodCall;

class CodeWeaver : public WeaverBase {

  AspectIncludes _aspect_includes;
  BackEndProblems _problems;
  ACConfig &_conf;
  std::set<void*> _handled_access_nodes;

  set<const WeavePos *> _bypass_blacklist;

  void make_check_function (bool in_checked,
      Puma::CRecord *in, Puma::CRecord *check_for);
  void make_tjp_typename( ostream &out, ACM_Code *loc, int depth, ACResultBuffer &rb, const char *wormhole_type = 0 );

  void make_proceed_code (ostream &out, ACM_Code *loc, bool action,
                          vector<string> *arg_names = 0);
  void make_proceed_to_implicit( ostream &out, ACM_Code *loc, bool action, vector<string> *arg_names = 0 );
  void make_advice_call(ostream &out, ACM_Code *loc, AdviceInfo *ad,
                        bool inter, int depth);
  void make_advice_calls (ostream &out, ACM_CodePlan *plan,
                          ACM_Code *loc, bool inter = false, vector<string> *arg_names = 0);
  void make_action_wrapper(ostream &impl, ACM_Code *jpl, int depth);
  void make_proceed_func( ostream &impl, ACM_Code *loc, ACM_CodePlan *plan, bool has_wormhole = false );
  string wrapper_function_signature (ACM_Code *loc,
      const SyntacticContext &sctxt, bool def);
  void gen_special_member_function (ACM_Code *loc);
  void wrap_function (ACM_Code *loc);
  void wrap_function_def (ACM_Code *loc, const SyntacticContext &sctxt,
    bool wrapped_decl);
  bool wrap_function_decl (ACM_Code *loc, const SyntacticContext &sctxt);
  void wrap_attribute_array (const SyntacticContext &attr_ctxt, list<SyntacticContext> &attrs);
  string gen_wrapped_array (const SyntacticContext &attr_ctxt);
  void gen_binding_templates (ostream &out, ACM_CodePlan *plan, const char *jpname);

#ifdef FRONTEND_PUMA
  void setup_tjp (ThisJoinPoint &tjp, Puma::CTree *node);
#else
  void setup_tjp (ThisJoinPoint &tjp, clang::Stmt* node);
#endif
  void insert_id_class (ACM_Call *loc, ACM_Name *src_obj, const WeavePos &pos,
      ACM_Function &dst_func);

  // scope functions
#ifdef FRONTEND_PUMA
  Puma::CClassInfo *cscope (Puma::CObjectInfo *obj);
#else
  clang::CXXRecordDecl *cscope(clang::DeclContext *obj);
#endif
  ACM_Class *cscope (ACM_Name *obj);
  ACM_Name *nscope (ACM_Function *func);
  string name_qualifier( ACM_Name *entity );
  string cleanup_name(const string& in);
  string strip_template_parameters (const string &in);


#ifdef FRONTEND_PUMA
  // not a very good function
  void print_tree (ostream &out, Puma::CTree *node, bool expand_implicit_calls = false);

  void rename_args (const SyntacticContext &sctxt, const char * new_name,
      vector<string> &arg_names);
  void rename (Puma::CArgumentInfo *arg, const string &new_name);
  Puma::CT_SimpleName *is_name (Puma::CTree *node);
  Puma::CT_FctDeclarator *fct_declarator (Puma::CT_Declarator *declarator);
  Puma::CT_SimpleName *name (Puma::CT_Declarator *&declarator);

  // return LinkageSpec node for extern "C" <decl> like declarations
  Puma::CTree *linkage_adjust (Puma::CT_Decl *decl);
#else
  void rename_args (const SyntacticContext &sctxt, const char * new_name,
                    vector<string> &arg_names);
  void rename (const clang::ParmVarDecl *arg, const string &new_name);
#endif

public:

  CodeWeaver( ACProject& prj, LineDirectiveMgr &ldm, ACConfig &c ) :
    WeaverBase( prj, ldm ), _aspect_includes( prj ), _conf( c ) {}

  // set weaver parameters
  void problems (const BackEndProblems &problems) {
    _problems = problems;
#ifdef FRONTEND_PUMA
    _warn_macro_expansion = problems._warn_macro;
#endif // FRONTEND_PUMA
  }

  // get weaver parameters
  const BackEndProblems &problems () const { return _problems; }

  void open_namespace (ostream &out, const SyntacticContext &ctxt);
  void close_namespace (ostream &out, const SyntacticContext &ctxt);
#ifdef FRONTEND_PUMA
  void setup_tjp (ThisJoinPoint &tjp, Puma::CFunctionInfo* func);
#else
  void setup_tjp (ThisJoinPoint &tjp, clang::FunctionDecl *func);
#endif
  void insert_invocation_functions (ACM_Aspect *jpl_aspect, const string &defs);

  void make_tjp_struct(ostream &out, ACM_Code *loc,
                       ACM_CodePlan *plan, const ThisJoinPoint &tjp);
  void access_join_point (ACM_Access *loc);
#ifdef FRONTEND_CLANG
  void splice_shortcircuit_expr( ACM_Builtin *loc );
  void expand_arrow_operator_chain(TI_CommonCall &ti, const WeavePos &before_pos, const WeavePos &after_pos);
#endif
  bool generate_access_wrapper( ACM_Access *loc, ostream &new_call, ostream &trail_call, const char *name_that = "this",
      int wrapper_number = -1);
  bool splice_access_expr( ACM_Access *loc );
#ifdef FRONTEND_CLANG
  void gen_packed_resulttype( ostream &code, ACM_Access *loc );
  void gen_packed_result_return( ostream &code, ACM_Access *loc );

  void splice_entity_expr( ACM_Access *loc );
  void pack_entity_expr( ACM_Access *loc );
  static bool has_complex_entity( ACM_Access *loc );
  void splice_member_expr( ACM_Access *loc, const char *separator = ", " );
  bool is_wrapped_array( ACM_Name *ent );

  void preplanTransform( ACM_Code &code_jpl );
#endif

  void exec_join_point (ACM_Execution *loc);
  void cons_join_point (ACM_Construction *loc);
  void dest_join_point (ACM_Destruction *loc);
  void add_aspect_include (ACM_Any *jpl, AspectInfo &aspect_info,
                           AspectRef::Kind kind);
  void insert_aspect_includes ();
  AspectIncludes &aspect_includes () { return _aspect_includes; }
  void type_check (const ACM_Class *in, const string &name, bool result);

  void bypass_info_clear ();
  bool bypass_in_blacklist (ACM_Class *cls);
  void bypass_insert (ACM_Class *cls);

  // code transformation functions need for phase 1:
  struct TypeUse {
    bool that;
    bool target;
    bool result;
    bool entity;
    bool memberptr;
    bool array;

    inline TypeUse() : that( false ), target( false ), result( false ), entity( false ), memberptr( false ), array( false ) {};
    inline bool any() { return that || target || result || entity || memberptr || array; }
  };

  void transform_aspect(ACToken start);
  void transform_pointcut_def(ACToken start, ACToken virtual_token,
      ACToken assignment_token, ACToken pct_end_token);
  void transform_advice_code (int no, std::string kind, AdviceCodeContext context, bool has_args, TypeUse &uses_type,
      ACToken arg_begin, ACToken body_begin, ACToken body_end, const string &prot);
  void transform_aspectof (AdviceCodeContext context, TypeUse &uses_type,
      ACToken start, ACToken name, ACToken arg_begin,
      ACToken body_begin, ACToken body_end, const string &prot);
  void transform_delete (ACToken from, ACToken to);
  void transform_anon_class (ACToken name_pos, const string &name);
  void transform_anon_member_class (ACToken end_token, const string &anon_members);
};

#endif // __CodeWeaver_h__