File: PointCutContext.cc

package info (click to toggle)
aspectc%2B%2B 1.0pre4~svn.20090918-1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 117,308 kB
  • ctags: 410,601
  • sloc: cpp: 1,883,007; ansic: 17,279; sh: 2,190; makefile: 1,088
file content (130 lines) | stat: -rw-r--r-- 4,765 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
// 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                                            

#include "PointCutContext.h"
#include "JoinPoint.h"
#include "IntroductionUnit.h"
#include "TransformInfo.h"

#include "Puma/ErrorStream.h"
#include "Puma/CFunctionInfo.h"
#include "Puma/CClassInfo.h"
#include "Puma/ACPointcutInfo.h"
#include "Puma/ACAspectInfo.h"
#include "Puma/CSemDatabase.h"
#include "Puma/CTree.h"

CFunctionInfo *PointCutContext::lookup_pointcut(ACAspectInfo *ai,
                                                CFunctionInfo *fi) {
  CFunctionInfo *result = 0;
  const char *name = fi->Name ();
  CSemDatabase *db = (CSemDatabase*)fi->SemDB ();
  
  // think about it!
  // What happens with 3 level aspect hierarchies?
  // What about overloading?
  // What about fully qualified pointcut names? 
  for (int p = 0; p < ai->PointcutInfos (); p++) {
    ACPointcutInfo *pi = ai->PointcutInfo (p);
    if (strcmp (pi->name (), name) == 0) {
      result = pi->function ();
      break;
    }
  }
  
  // if the pointcut is not defined in this aspect it has to be defined in a
  // base aspect that is derived from the aspect in which the virtual pointcut
  // is defined
  if (!result) {
    // the aspect/class in which we are searching
    CClassInfo *ci = ai->ClassInfo ();

    // the class where the referenced pointcut is located in ...
    CClassInfo *ref_class = fi->ClassScope ()->ClassInfo ();

    // search the function in base aspects
    for (int b = ci->BaseClasses () - 1; b >= 0; b--) {
      CClassInfo *bci   = ci->BaseClass (b)->Class ();
      ACAspectInfo *bai = db->AspectInfo (bci);
      // the class is relevant if it is an aspect an derived from ref_class
      if (bai && bci->isBaseClass (ref_class, true)) {
        result = lookup_pointcut (bai, fi);
        if (result)
          break;
      }
    }
  }
  
  return result;
}

 
CFunctionInfo *PointCutContext::lookup_pointcut (CFunctionInfo *func,
						 ErrorStream &err, 
						 CTree *node) {
  CFunctionInfo *result = func; // default: out = in
  const char *name = func->Name ();
  CSemDatabase *db = (CSemDatabase*)func->SemDB ();

  // check if the name really corresponds to a pointcut
  if (!db->PointcutInfo (func)) {
    err << sev_error << node->token ()->location ()
	<< "'" << name << "' is no named pointcut" 
	<< endMessage;
    return 0;
  }

  // everything ok, if the pointcut is not member of a class or aspect
  if (!func->ClassScope ())
    return result;

  // the class where the referenced pointcut is located in ...
  CClassInfo *ref_class = func->ClassScope ()->ClassInfo ();

  ACAspectInfo *ai = TI_Aspect::of (*_aspect)->aspect_info ();
  // if the pointcut is declared virtual, find the real definition
  if (ref_class != ai->ClassInfo () && func->isVirtual ()) {
    result = lookup_pointcut (ai, func);
    if (!result)
      result = func;
  }
	
  if (result->isPureVirtual ()) {
    err << sev_error << node->token ()->location ()
	<< "no definition for pure virtual pointcut '" << name << "'"
	<< endMessage;
    return 0;
  }

  return result;
}

bool PointCutContext::in_project (CObjectInfo *obj) {
  // built-in (generated constructors/destructors belong to the project if
  // the corresponding class belongs to the project
  if (obj->isBuiltin () && obj->FunctionInfo () &&
    (obj->FunctionInfo ()->isConstructor () ||
     obj->FunctionInfo ()->isDestructor ())) {
    Unit *unit = obj->FunctionInfo ()->Record ()->SourceInfo ()->SrcUnit ();
    return obj->SemDB()->Project ()->isBelow (unit) ||
           IntroductionUnit::cast (unit);
  }
  Unit *unit = obj->SourceInfo ()->SrcUnit ();
  return obj->SemDB()->Project ()->isBelow (unit) ||
         IntroductionUnit::cast (unit);
}