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__
|