File: MatchExpr.h

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 (242 lines) | stat: -rw-r--r-- 9,774 bytes parent folder | download
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
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
// 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 __MatchExpr_h__
#define __MatchExpr_h__

#include "Puma/ErrorStream.h"
#include "Puma/CFunctionInfo.h"
#include "Puma/CClassInfo.h"
#include "Puma/Location.h"
using namespace Puma;

#include "MatchType.h"
#include "MatchTemplateArg.h"
#include "MatchName.h"

// This class is an abstraction for a C++ object signature (function, type,
// attribute).

class MatchSignature {

protected:
  // object state 
  enum State {
    NEW    = 0, // this object is not initialized, yet
    NORMAL = 1, // this is a valid match expression, ready for 'match' calls
    // state of the expression ( < 0 means an error code)
    ERR_NO_DECL_SPEC       = -1,  // no declaration specifier given
    ERR_EMPTY_MATCH_EXPR   = -2,  // neither decl spec nor declarator given
    ERR_TOKENS_AFTER_END   = -3,  // tokens after end of match expression
    ERR_INVALID_DOT        = -4,  // invalid use of "..."
    ERR_INVALID_DECLARATOR = -5,  // invalid declarator
    ERR_MISSING_BRACKET    = -6,  // missing bracket
    ERR_MISSING_DECL_ID    = -7,  // missing declarator id (the name)
    ERR_DECL_NOT_ABSTRACT  = -8,  // argument declarator not abstract
    ERR_ARG_AFTER_ELLIPSES = -9,  // argument after "..."
    ERR_INVALID_ARG_LIST   = -10, // invalid argument list
    ERR_INVALID_ARRAY      = -11, // array size is neither "%" nor int constant
    ERR_DUP_CV             = -12, // duplicated const or volatile
    ERR_DUP_SIGN           = -13, // duplicated signed or unsigned
    ERR_CONF_SIZE          = -14, // conflicting short and long
    ERR_INVALID_TYPE       = -15, // invalid type
    ERR_INVALID_OPER       = -16, // invalid operator name
    ERR_TEMPLATE_ARG_LIST  = -17, // error in template arguments
    ERR_DUP_FCT_SPEC       = -18, // duplicate virtual, inline, or explicit
    ERR_INVALID_FCT_SPEC   = -19  // only functions can have function specifiers
  } _state;
  
private:
  // primitive types
  enum PrimType {
    PRIM_NONE, PRIM_CHAR, PRIM_INT, PRIM_VOID, PRIM_BOOL, PRIM_FLOAT,
    PRIM_DOUBLE, PRIM_WCHAR_T
  };                 
  
  // const or volatile qualifiers
  enum CVQualifier { QUAL_NONE = 0, QUAL_CONST = 1, QUAL_VOLATILE = 2 } ;
  
  // function specifiers, currently only 'virtual' is supported by the parser
  enum FctSpec {
    FCT_NONE = 0, FCT_VIRTUAL = 1, FCT_INLINE = 2, FCT_EXPLICIT = 4
  } _fct_spec;
  
  // type used for parsing and analysing the declaration specifier sequence
  struct DeclSpecs {
    CVQualifier _qual; // bitfield with const/volatile qualifiers
    FctSpec _fct_spec; // bitfield with function specifiers
    int _sign; // -1, 0, +1
    int _size; // -1 = short, 0 = no change, 1 = long, 2 = long long, ...
    bool _allow_name;
    PrimType _type;
    MatchName _name;
    DeclSpecs () :
      _qual (QUAL_NONE), _fct_spec (FCT_NONE), _sign (0), _size (0),
      _allow_name (true), _type (PRIM_NONE) {}
  };
  
public:
  //! match expression type
  enum Type { ATTRIBUTE, FUNCTION, TYPE } _expr_type;
  
protected:
  //! the name pattern of the match expression
  MatchName _name;
  //! the type pattern
  MatchTypeRef _type;
  
public:
  // constructors/destructor
  inline MatchSignature ();
  inline MatchSignature (ErrorStream &err, Location loc, const char *str);
  
  // parse a match expression string
  // complain about errors => result false
  bool parse (ErrorStream &err, Location loc, const char *str);
  
  // check the state of this match expression
  inline bool error () const;
  inline bool is_new () const;
  inline bool is_function () const;
  inline bool is_virtual_function () const;
  inline bool is_attribute () const;
  inline bool is_type () const;

  // manipulate the state
  inline void declare_virtual_function ();
  
  // get more detailed infos about the match expression
  inline MatchName &name ();
  inline MatchTypeRef &type ();
  
private:
  // internal parser functions that analyse a match expr string
  bool parse_match_expr (const char *&str);
  bool parse_declaration (const char *&str, bool abstract, MatchTypeRef &type);
  bool parse_decl_spec_seq (const char *&str, MatchTypeRef &type, FctSpec &fs);
  bool parse_decl_spec (const char *&str, DeclSpecs &ds);
  bool parse_nested_name (const char *&str, MatchName &match_name);
  bool parse_nested_name_elem (const char *&str, MatchName &match_name);  
  bool parse_opt_template_argument_list (const char *&str,
                                         MatchTemplateArgList *&mtal);
  bool parse_template_argument_list (const char *&str, 
                                     MatchTemplateArgList &mtal);
  bool parse_template_argument (const char *&str, MatchTemplateArg *&mta);
  bool parse_dec_literal (const char *&str, long long &val);
  bool parse_declarator (const char *&str, bool abstract, MatchTypeRef &type);
  bool skip_nested_declarator (const char *&str);
  bool parse_declarator_post (const char *&str, MatchTypeRef &type);
  bool parse_ptr_operator (const char *&str, MatchTypeRef &type);
  bool parse_declarator_id (const char *&str, MatchName &match_name);
  bool parse_conv_id (const char *&str, MatchTypeRef &type);
  bool parse_operator_id (const char *&str, MatchName::Operator &op);
  bool parse_fct_args (const char *&str, vector<MatchTypeRef> &args, bool &va);
  bool parse_ellipses (const char *&str);
  inline void skip_blanks (const char *&str) const;
  inline bool next_word (const char *word, const char *&str) const;
  inline bool is_id (char c) const;
};

// implementations of inline constructors/destructor
inline MatchSignature::MatchSignature () : _state (NEW) {}
inline MatchSignature::MatchSignature (ErrorStream &err, Location loc,
  const char *str) : _state (NEW) {
  parse (err, loc, str);
}

// check the state of this match expression
inline bool MatchSignature::error () const { return _state < 0; }
inline bool MatchSignature::is_new () const { return _state == NEW; }
inline bool MatchSignature::is_function () const { return _expr_type == FUNCTION; }
inline bool MatchSignature::is_virtual_function () const {
  return is_function () && ((_fct_spec & FCT_VIRTUAL) != 0);
}
inline bool MatchSignature::is_attribute () const { return _expr_type == ATTRIBUTE; }
inline bool MatchSignature::is_type () const { return _expr_type == TYPE; }

// manipulate the state
inline void MatchSignature::declare_virtual_function () {
  assert (is_function ());
  _fct_spec = (FctSpec)(FCT_VIRTUAL | _fct_spec);
}

// get more detailed infos about the match expression
// TODO: const correctness
inline MatchName &MatchSignature::name () { return _name; }
inline MatchTypeRef &MatchSignature::type () { return _type; }

// this is an abstraction for AspectC++ match expressions. These expressions
// describe signature patters, which can be matched agains the signatures
// of C++ objects. Match expressions are 'Signatures' that may contain
// special wildcard symbols ("%", "...").

class MatchExpr : public MatchSignature {
public:
  
  // constructors/destructor
  inline MatchExpr ();
  inline MatchExpr (ErrorStream &err, Location loc, const char *str);

  // check if a certain signature is matched by this expression,
  // obj is passed to check the name part of the signature
  // true is returned if the signature is matched
  inline bool matches (CTypeInfo *type, CObjectInfo *obj);

  // check if the match expression matches a passed match signature
  inline bool matches (MatchSignature &sig);
};

// implementations of inline constructors/destructor
inline MatchExpr::MatchExpr () {}
inline MatchExpr::MatchExpr (ErrorStream &err, Location loc, const char *str)
  : MatchSignature (err, loc, str) {}

// check if a certain signature is matched by this expression
// true is returned if the signature is matched
//inline bool MatchExpr::matches (CTypeInfo *ctype, CObjectInfo *obj) {
//  assert (_state == NORMAL && !_type.is_undefined ());
//  if (!_type.matches (ctype))
//    return false;
//  if (!obj || is_type ())
//    return true;
//  if (!_name.matches (obj))
//    return false;
//  if (is_virtual_function ()) {
//    if (!(obj->isVirtual () || obj->FunctionInfo ()->overridesVirtual ()))
//      return false;
//  }
//  return true;
//}

// check if the match expression matches a passed match signature
inline bool MatchExpr::matches (MatchSignature &sig) {
  assert (_state == NORMAL && _expr_type == sig._expr_type && !_type.is_undefined ());
  if (!_type.matches (sig.type ()))
    return false;
  if (is_type ())
    return true;
  if (!_name.matches (sig.name ()))
    return false;
  if (is_virtual_function ()) {
    if (!sig.is_virtual_function ())
      return false;
  }
  return true;
}

#endif // __MatchExpr_h__