1#
2#   Symbol Table
3#
4
5import copy
6import re
7from Errors import warning, error, InternalError
8from StringEncoding import EncodedString
9import Options, Naming
10import PyrexTypes
11from PyrexTypes import py_object_type, unspecified_type
12from TypeSlots import \
13    pyfunction_signature, pymethod_signature, \
14    get_special_method_signature, get_property_accessor_signature
15import Code
16import __builtin__ as builtins
17
18iso_c99_keywords = set(
19['auto', 'break', 'case', 'char', 'const', 'continue', 'default', 'do',
20    'double', 'else', 'enum', 'extern', 'float', 'for', 'goto', 'if',
21    'int', 'long', 'register', 'return', 'short', 'signed', 'sizeof',
22    'static', 'struct', 'switch', 'typedef', 'union', 'unsigned', 'void',
23    'volatile', 'while',
24    '_Bool', '_Complex'', _Imaginary', 'inline', 'restrict'])
25
26def c_safe_identifier(cname):
27    # There are some C limitations on struct entry names.
28    if ((cname[:2] == '__'
29         and not (cname.startswith(Naming.pyrex_prefix)
30                  or cname == '__weakref__'))
31        or cname in iso_c99_keywords):
32        cname = Naming.pyrex_prefix + cname
33    return cname
34
35class BufferAux(object):
36    writable_needed = False
37
38    def __init__(self, buflocal_nd_var, rcbuf_var):
39        self.buflocal_nd_var = buflocal_nd_var
40        self.rcbuf_var = rcbuf_var
41
42    def __repr__(self):
43        return "<BufferAux %r>" % self.__dict__
44
45
46class Entry(object):
47    # A symbol table entry in a Scope or ModuleNamespace.
48    #
49    # name             string     Python name of entity
50    # cname            string     C name of entity
51    # type             PyrexType  Type of entity
52    # doc              string     Doc string
53    # init             string     Initial value
54    # visibility       'private' or 'public' or 'extern'
55    # is_builtin       boolean    Is an entry in the Python builtins dict
56    # is_cglobal       boolean    Is a C global variable
57    # is_pyglobal      boolean    Is a Python module-level variable
58    #                               or class attribute during
59    #                               class construction
60    # is_member        boolean    Is an assigned class member
61    # is_pyclass_attr  boolean    Is a name in a Python class namespace
62    # is_variable      boolean    Is a variable
63    # is_cfunction     boolean    Is a C function
64    # is_cmethod       boolean    Is a C method of an extension type
65    # is_builtin_cmethod boolean  Is a C method of a builtin type (implies is_cmethod)
66    # is_unbound_cmethod boolean  Is an unbound C method of an extension type
67    # is_final_cmethod   boolean  Is non-overridable C method
68    # is_inline_cmethod  boolean  Is inlined C method
69    # is_anonymous     boolean    Is a anonymous pyfunction entry
70    # is_type          boolean    Is a type definition
71    # is_cclass        boolean    Is an extension class
72    # is_cpp_class     boolean    Is a C++ class
73    # is_const         boolean    Is a constant
74    # is_property      boolean    Is a property of an extension type:
75    # doc_cname        string or None  C const holding the docstring
76    # getter_cname     string          C func for getting property
77    # setter_cname     string          C func for setting or deleting property
78    # is_self_arg      boolean    Is the "self" arg of an exttype method
79    # is_arg           boolean    Is the arg of a method
80    # is_local         boolean    Is a local variable
81    # in_closure       boolean    Is referenced in an inner scope
82    # is_readonly      boolean    Can't be assigned to
83    # func_cname       string     C func implementing Python func
84    # func_modifiers   [string]   C function modifiers ('inline')
85    # pos              position   Source position where declared
86    # namespace_cname  string     If is_pyglobal, the C variable
87    #                               holding its home namespace
88    # pymethdef_cname  string     PyMethodDef structure
89    # signature        Signature  Arg & return types for Python func
90    # as_variable      Entry      Alternative interpretation of extension
91    #                               type name or builtin C function as a variable
92    # xdecref_cleanup  boolean    Use Py_XDECREF for error cleanup
93    # in_cinclude      boolean    Suppress C declaration code
94    # enum_values      [Entry]    For enum types, list of values
95    # qualified_name   string     "modname.funcname" or "modname.classname"
96    #                               or "modname.classname.funcname"
97    # is_declared_generic  boolean  Is declared as PyObject * even though its
98    #                                 type is an extension type
99    # as_module        None       Module scope, if a cimported module
100    # is_inherited     boolean    Is an inherited attribute of an extension type
101    # pystring_cname   string     C name of Python version of string literal
102    # is_interned      boolean    For string const entries, value is interned
103    # is_identifier    boolean    For string const entries, value is an identifier
104    # used             boolean
105    # is_special       boolean    Is a special method or property accessor
106    #                               of an extension type
107    # defined_in_pxd   boolean    Is defined in a .pxd file (not just declared)
108    # api              boolean    Generate C API for C class or function
109    # utility_code     string     Utility code needed when this entry is used
110    #
111    # buffer_aux       BufferAux or None  Extra information needed for buffer variables
112    # inline_func_in_pxd boolean  Hacky special case for inline function in pxd file.
113    #                             Ideally this should not be necesarry.
114    # might_overflow   boolean    In an arithmetic expression that could cause
115    #                             overflow (used for type inference).
116    # utility_code_definition     For some Cython builtins, the utility code
117    #                             which contains the definition of the entry.
118    #                             Currently only supported for CythonScope entries.
119    # error_on_uninitialized      Have Control Flow issue an error when this entry is
120    #                             used uninitialized
121    # cf_used          boolean    Entry is used
122    # is_fused_specialized boolean Whether this entry of a cdef or def function
123    #                              is a specialization
124
125    # TODO: utility_code and utility_code_definition serves the same purpose...
126
127    inline_func_in_pxd = False
128    borrowed = 0
129    init = ""
130    visibility = 'private'
131    is_builtin = 0
132    is_cglobal = 0
133    is_pyglobal = 0
134    is_member = 0
135    is_pyclass_attr = 0
136    is_variable = 0
137    is_cfunction = 0
138    is_cmethod = 0
139    is_builtin_cmethod = False
140    is_unbound_cmethod = 0
141    is_final_cmethod = 0
142    is_inline_cmethod = 0
143    is_anonymous = 0
144    is_type = 0
145    is_cclass = 0
146    is_cpp_class = 0
147    is_const = 0
148    is_property = 0
149    doc_cname = None
150    getter_cname = None
151    setter_cname = None
152    is_self_arg = 0
153    is_arg = 0
154    is_local = 0
155    in_closure = 0
156    from_closure = 0
157    is_declared_generic = 0
158    is_readonly = 0
159    pyfunc_cname = None
160    func_cname = None
161    func_modifiers = []
162    final_func_cname = None
163    doc = None
164    as_variable = None
165    xdecref_cleanup = 0
166    in_cinclude = 0
167    as_module = None
168    is_inherited = 0
169    pystring_cname = None
170    is_identifier = 0
171    is_interned = 0
172    used = 0
173    is_special = 0
174    defined_in_pxd = 0
175    is_implemented = 0
176    api = 0
177    utility_code = None
178    is_overridable = 0
179    buffer_aux = None
180    prev_entry = None
181    might_overflow = 0
182    fused_cfunction = None
183    is_fused_specialized = False
184    utility_code_definition = None
185    needs_property = False
186    in_with_gil_block = 0
187    from_cython_utility_code = None
188    error_on_uninitialized = False
189    cf_used = True
190    outer_entry = None
191
192    def __init__(self, name, cname, type, pos = None, init = None):
193        self.name = name
194        self.cname = cname
195        self.type = type
196        self.pos = pos
197        self.init = init
198        self.overloaded_alternatives = []
199        self.cf_assignments = []
200        self.cf_references = []
201        self.inner_entries = []
202        self.defining_entry = self
203
204    def __repr__(self):
205        return "%s(<%x>, name=%s, type=%s)" % (type(self).__name__, id(self), self.name, self.type)
206
207    def redeclared(self, pos):
208        error(pos, "'%s' does not match previous declaration" % self.name)
209        error(self.pos, "Previous declaration is here")
210
211    def all_alternatives(self):
212        return [self] + self.overloaded_alternatives
213
214    def all_entries(self):
215        return [self] + self.inner_entries
216
217
218class InnerEntry(Entry):
219    """
220    An entry in a closure scope that represents the real outer Entry.
221    """
222    from_closure = True
223
224    def __init__(self, outer_entry, scope):
225        Entry.__init__(self, outer_entry.name,
226                       outer_entry.cname,
227                       outer_entry.type,
228                       outer_entry.pos)
229        self.outer_entry = outer_entry
230        self.scope = scope
231
232        # share state with (outermost) defining entry
233        outermost_entry = outer_entry
234        while outermost_entry.outer_entry:
235            outermost_entry = outermost_entry.outer_entry
236        self.defining_entry = outermost_entry
237        self.inner_entries = outermost_entry.inner_entries
238        self.cf_assignments = outermost_entry.cf_assignments
239        self.cf_references = outermost_entry.cf_references
240        self.overloaded_alternatives = outermost_entry.overloaded_alternatives
241        self.inner_entries.append(self)
242
243    def __getattr__(self, name):
244        if name.startswith('__'):
245            # we wouldn't have been called if it was there
246            raise AttributeError(name)
247        return getattr(self.defining_entry, name)
248
249    def all_entries(self):
250        return self.defining_entry.all_entries()
251
252
253class Scope(object):
254    # name              string             Unqualified name
255    # outer_scope       Scope or None      Enclosing scope
256    # entries           {string : Entry}   Python name to entry, non-types
257    # const_entries     [Entry]            Constant entries
258    # type_entries      [Entry]            Struct/union/enum/typedef/exttype entries
259    # sue_entries       [Entry]            Struct/union/enum entries
260    # arg_entries       [Entry]            Function argument entries
261    # var_entries       [Entry]            User-defined variable entries
262    # pyfunc_entries    [Entry]            Python function entries
263    # cfunc_entries     [Entry]            C function entries
264    # c_class_entries   [Entry]            All extension type entries
265    # cname_to_entry    {string : Entry}   Temp cname to entry mapping
266    # return_type       PyrexType or None  Return type of function owning scope
267    # is_builtin_scope  boolean            Is the builtin scope of Python/Cython
268    # is_py_class_scope boolean            Is a Python class scope
269    # is_c_class_scope  boolean            Is an extension type scope
270    # is_closure_scope  boolean            Is a closure scope
271    # is_passthrough    boolean            Outer scope is passed directly
272    # is_cpp_class_scope  boolean          Is a C++ class scope
273    # is_property_scope boolean            Is a extension type property scope
274    # scope_prefix      string             Disambiguator for C names
275    # in_cinclude       boolean            Suppress C declaration code
276    # qualified_name    string             "modname" or "modname.classname"
277    #                                        Python strings in this scope
278    # nogil             boolean            In a nogil section
279    # directives        dict               Helper variable for the recursive
280    #                                      analysis, contains directive values.
281    # is_internal       boolean            Is only used internally (simpler setup)
282
283    is_builtin_scope = 0
284    is_py_class_scope = 0
285    is_c_class_scope = 0
286    is_closure_scope = 0
287    is_passthrough = 0
288    is_cpp_class_scope = 0
289    is_property_scope = 0
290    is_module_scope = 0
291    is_internal = 0
292    scope_prefix = ""
293    in_cinclude = 0
294    nogil = 0
295    fused_to_specific = None
296
297    def __init__(self, name, outer_scope, parent_scope):
298        # The outer_scope is the next scope in the lookup chain.
299        # The parent_scope is used to derive the qualified name of this scope.
300        self.name = name
301        self.outer_scope = outer_scope
302        self.parent_scope = parent_scope
303        mangled_name = "%d%s_" % (len(name), name)
304        qual_scope = self.qualifying_scope()
305        if qual_scope:
306            self.qualified_name = qual_scope.qualify_name(name)
307            self.scope_prefix = qual_scope.scope_prefix + mangled_name
308        else:
309            self.qualified_name = EncodedString(name)
310            self.scope_prefix = mangled_name
311        self.entries = {}
312        self.const_entries = []
313        self.type_entries = []
314        self.sue_entries = []
315        self.arg_entries = []
316        self.var_entries = []
317        self.pyfunc_entries = []
318        self.cfunc_entries = []
319        self.c_class_entries = []
320        self.defined_c_classes = []
321        self.imported_c_classes = {}
322        self.cname_to_entry = {}
323        self.string_to_entry = {}
324        self.identifier_to_entry = {}
325        self.num_to_entry = {}
326        self.obj_to_entry = {}
327        self.buffer_entries = []
328        self.lambda_defs = []
329        self.return_type = None
330        self.id_counters = {}
331
332    def __deepcopy__(self, memo):
333        return self
334
335    def merge_in(self, other, merge_unused=True, whitelist=None):
336        # Use with care...
337        entries = []
338        for name, entry in other.entries.iteritems():
339            if not whitelist or name in whitelist:
340                if entry.used or merge_unused:
341                    entries.append((name, entry))
342
343        self.entries.update(entries)
344
345        for attr in ('const_entries',
346                     'type_entries',
347                     'sue_entries',
348                     'arg_entries',
349                     'var_entries',
350                     'pyfunc_entries',
351                     'cfunc_entries',
352                     'c_class_entries'):
353            self_entries = getattr(self, attr)
354            names = set([e.name for e in self_entries])
355            for entry in getattr(other, attr):
356                if (entry.used or merge_unused) and entry.name not in names:
357                    self_entries.append(entry)
358
359    def __str__(self):
360        return "<%s %s>" % (self.__class__.__name__, self.qualified_name)
361
362    def qualifying_scope(self):
363        return self.parent_scope
364
365    def mangle(self, prefix, name = None):
366        if name:
367            return "%s%s%s" % (prefix, self.scope_prefix, name)
368        else:
369            return self.parent_scope.mangle(prefix, self.name)
370
371    def mangle_internal(self, name):
372        # Mangle an internal name so as not to clash with any
373        # user-defined name in this scope.
374        prefix = "%s%s_" % (Naming.pyrex_prefix, name)
375        return self.mangle(prefix)
376        #return self.parent_scope.mangle(prefix, self.name)
377
378    def mangle_class_private_name(self, name):
379        if self.parent_scope:
380            return self.parent_scope.mangle_class_private_name(name)
381        return name
382
383    def next_id(self, name=None):
384        # Return a cname fragment that is unique for this module
385        counters = self.global_scope().id_counters
386        try:
387            count = counters[name] + 1
388        except KeyError:
389            count = 0
390        counters[name] = count
391        if name:
392            if not count:
393                # unique names don't need a suffix, reoccurrences will get one
394                return name
395            return '%s%d' % (name, count)
396        else:
397            return '%d' % count
398
399    def global_scope(self):
400        """ Return the module-level scope containing this scope. """
401        return self.outer_scope.global_scope()
402
403    def builtin_scope(self):
404        """ Return the module-level scope containing this scope. """
405        return self.outer_scope.builtin_scope()
406
407    def declare(self, name, cname, type, pos, visibility, shadow = 0, is_type = 0):
408        # Create new entry, and add to dictionary if
409        # name is not None. Reports a warning if already
410        # declared.
411        if type.is_buffer and not isinstance(self, LocalScope): # and not is_type:
412            error(pos, 'Buffer types only allowed as function local variables')
413        if not self.in_cinclude and cname and re.match("^_[_A-Z]+$", cname):
414            # See http://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html#Reserved-Names
415            warning(pos, "'%s' is a reserved name in C." % cname, -1)
416        entries = self.entries
417        if name and name in entries and not shadow:
418            if visibility == 'extern':
419                warning(pos, "'%s' redeclared " % name, 0)
420            elif visibility != 'ignore':
421                error(pos, "'%s' redeclared " % name)
422        entry = Entry(name, cname, type, pos = pos)
423        entry.in_cinclude = self.in_cinclude
424        if name:
425            entry.qualified_name = self.qualify_name(name)
426#            if name in entries and self.is_cpp():
427#                entries[name].overloaded_alternatives.append(entry)
428#            else:
429#                entries[name] = entry
430            if not shadow:
431                entries[name] = entry
432
433        if type.is_memoryviewslice:
434            import MemoryView
435            entry.init = MemoryView.memslice_entry_init
436
437        entry.scope = self
438        entry.visibility = visibility
439        return entry
440
441    def qualify_name(self, name):
442        return EncodedString("%s.%s" % (self.qualified_name, name))
443
444    def declare_const(self, name, type, value, pos, cname = None, visibility = 'private', api = 0):
445        # Add an entry for a named constant.
446        if not cname:
447            if self.in_cinclude or (visibility == 'public' or api):
448                cname = name
449            else:
450                cname = self.mangle(Naming.enum_prefix, name)
451        entry = self.declare(name, cname, type, pos, visibility)
452        entry.is_const = 1
453        entry.value_node = value
454        return entry
455
456    def declare_type(self, name, type, pos,
457            cname = None, visibility = 'private', api = 0, defining = 1,
458            shadow = 0, template = 0):
459        # Add an entry for a type definition.
460        if not cname:
461            cname = name
462        entry = self.declare(name, cname, type, pos, visibility, shadow,
463                             is_type=True)
464        entry.is_type = 1
465        entry.api = api
466        if defining:
467            self.type_entries.append(entry)
468
469        if not template:
470            type.entry = entry
471
472        # here we would set as_variable to an object representing this type
473        return entry
474
475    def declare_typedef(self, name, base_type, pos, cname = None,
476                        visibility = 'private', api = 0):
477        if not cname:
478            if self.in_cinclude or (visibility == 'public' or api):
479                cname = name
480            else:
481                cname = self.mangle(Naming.type_prefix, name)
482        try:
483            type = PyrexTypes.create_typedef_type(name, base_type, cname,
484                                                  (visibility == 'extern'))
485        except ValueError, e:
486            error(pos, e.args[0])
487            type = PyrexTypes.error_type
488        entry = self.declare_type(name, type, pos, cname,
489                                  visibility = visibility, api = api)
490        type.qualified_name = entry.qualified_name
491        return entry
492
493    def declare_struct_or_union(self, name, kind, scope,
494                                typedef_flag, pos, cname = None,
495                                visibility = 'private', api = 0,
496                                packed = False):
497        # Add an entry for a struct or union definition.
498        if not cname:
499            if self.in_cinclude or (visibility == 'public' or api):
500                cname = name
501            else:
502                cname = self.mangle(Naming.type_prefix, name)
503        entry = self.lookup_here(name)
504        if not entry:
505            type = PyrexTypes.CStructOrUnionType(
506                name, kind, scope, typedef_flag, cname, packed)
507            entry = self.declare_type(name, type, pos, cname,
508                visibility = visibility, api = api,
509                defining = scope is not None)
510            self.sue_entries.append(entry)
511            type.entry = entry
512        else:
513            if not (entry.is_type and entry.type.is_struct_or_union
514                    and entry.type.kind == kind):
515                warning(pos, "'%s' redeclared  " % name, 0)
516            elif scope and entry.type.scope:
517                warning(pos, "'%s' already defined  (ignoring second definition)" % name, 0)
518            else:
519                self.check_previous_typedef_flag(entry, typedef_flag, pos)
520                self.check_previous_visibility(entry, visibility, pos)
521                if scope:
522                    entry.type.scope = scope
523                    self.type_entries.append(entry)
524        return entry
525
526    def declare_cpp_class(self, name, scope,
527            pos, cname = None, base_classes = (),
528            visibility = 'extern', templates = None):
529        if cname is None:
530            if self.in_cinclude or (visibility != 'private'):
531                cname = name
532            else:
533                cname = self.mangle(Naming.type_prefix, name)
534        base_classes = list(base_classes)
535        entry = self.lookup_here(name)
536        if not entry:
537            type = PyrexTypes.CppClassType(
538                name, scope, cname, base_classes, templates = templates)
539            entry = self.declare_type(name, type, pos, cname,
540                visibility = visibility, defining = scope is not None)
541            self.sue_entries.append(entry)
542        else:
543            if not (entry.is_type and entry.type.is_cpp_class):
544                error(pos, "'%s' redeclared " % name)
545                return None
546            elif scope and entry.type.scope:
547                warning(pos, "'%s' already defined  (ignoring second definition)" % name, 0)
548            else:
549                if scope:
550                    entry.type.scope = scope
551                    self.type_entries.append(entry)
552            if base_classes:
553                if entry.type.base_classes and entry.type.base_classes != base_classes:
554                    error(pos, "Base type does not match previous declaration")
555                else:
556                    entry.type.base_classes = base_classes
557            if templates or entry.type.templates:
558                if templates != entry.type.templates:
559                    error(pos, "Template parameters do not match previous declaration")
560
561        def declare_inherited_attributes(entry, base_classes):
562            for base_class in base_classes:
563                if base_class is PyrexTypes.error_type:
564                    continue
565                if base_class.scope is None:
566                    error(pos, "Cannot inherit from incomplete type")
567                else:
568                    declare_inherited_attributes(entry, base_class.base_classes)
569                    entry.type.scope.declare_inherited_cpp_attributes(base_class.scope)
570        if entry.type.scope:
571            declare_inherited_attributes(entry, base_classes)
572            entry.type.scope.declare_var(name="this", cname="this", type=PyrexTypes.CPtrType(entry.type), pos=entry.pos)
573        if self.is_cpp_class_scope:
574            entry.type.namespace = self.outer_scope.lookup(self.name).type
575        return entry
576
577    def check_previous_typedef_flag(self, entry, typedef_flag, pos):
578        if typedef_flag != entry.type.typedef_flag:
579            error(pos, "'%s' previously declared using '%s'" % (
580                entry.name, ("cdef", "ctypedef")[entry.type.typedef_flag]))
581
582    def check_previous_visibility(self, entry, visibility, pos):
583        if entry.visibility != visibility:
584            error(pos, "'%s' previously declared as '%s'" % (
585                entry.name, entry.visibility))
586
587    def declare_enum(self, name, pos, cname, typedef_flag,
588            visibility = 'private', api = 0):
589        if name:
590            if not cname:
591                if self.in_cinclude or (visibility == 'public' or api):
592                    cname = name
593                else:
594                    cname = self.mangle(Naming.type_prefix, name)
595            type = PyrexTypes.CEnumType(name, cname, typedef_flag)
596        else:
597            type = PyrexTypes.c_anon_enum_type
598        entry = self.declare_type(name, type, pos, cname = cname,
599            visibility = visibility, api = api)
600        entry.enum_values = []
601        self.sue_entries.append(entry)
602        return entry
603
604    def declare_var(self, name, type, pos,
605                    cname = None, visibility = 'private',
606                    api = 0, in_pxd = 0, is_cdef = 0):
607        # Add an entry for a variable.
608        if not cname:
609            if visibility != 'private' or api:
610                cname = name
611            else:
612                cname = self.mangle(Naming.var_prefix, name)
613        if type.is_cpp_class and visibility != 'extern':
614            type.check_nullary_constructor(pos)
615        entry = self.declare(name, cname, type, pos, visibility)
616        entry.is_variable = 1
617        if in_pxd and visibility != 'extern':
618            entry.defined_in_pxd = 1
619            entry.used = 1
620        if api:
621            entry.api = 1
622            entry.used = 1
623        return entry
624
625    def declare_builtin(self, name, pos):
626        return self.outer_scope.declare_builtin(name, pos)
627
628    def _declare_pyfunction(self, name, pos, visibility='extern', entry=None):
629        if entry and not entry.type.is_cfunction:
630            error(pos, "'%s' already declared" % name)
631            error(entry.pos, "Previous declaration is here")
632        entry = self.declare_var(name, py_object_type, pos, visibility=visibility)
633        entry.signature = pyfunction_signature
634        self.pyfunc_entries.append(entry)
635        return entry
636
637    def declare_pyfunction(self, name, pos, allow_redefine=False, visibility='extern'):
638        # Add an entry for a Python function.
639        entry = self.lookup_here(name)
640        if not allow_redefine:
641            return self._declare_pyfunction(name, pos, visibility=visibility, entry=entry)
642        if entry:
643            if entry.type.is_unspecified:
644                entry.type = py_object_type
645            elif entry.type is not py_object_type:
646                return self._declare_pyfunction(name, pos, visibility=visibility, entry=entry)
647        else: # declare entry stub
648            self.declare_var(name, py_object_type, pos, visibility=visibility)
649        entry = self.declare_var(None, py_object_type, pos,
650                                 cname=name, visibility='private')
651        entry.name = EncodedString(name)
652        entry.qualified_name = self.qualify_name(name)
653        entry.signature = pyfunction_signature
654        entry.is_anonymous = True
655        return entry
656
657    def declare_lambda_function(self, lambda_name, pos):
658        # Add an entry for an anonymous Python function.
659        func_cname = self.mangle(Naming.lambda_func_prefix + u'funcdef_', lambda_name)
660        pymethdef_cname = self.mangle(Naming.lambda_func_prefix + u'methdef_', lambda_name)
661        qualified_name = self.qualify_name(lambda_name)
662
663        entry = self.declare(None, func_cname, py_object_type, pos, 'private')
664        entry.name = lambda_name
665        entry.qualified_name = qualified_name
666        entry.pymethdef_cname = pymethdef_cname
667        entry.func_cname = func_cname
668        entry.signature = pyfunction_signature
669        entry.is_anonymous = True
670        return entry
671
672    def add_lambda_def(self, def_node):
673        self.lambda_defs.append(def_node)
674
675    def register_pyfunction(self, entry):
676        self.pyfunc_entries.append(entry)
677
678    def declare_cfunction(self, name, type, pos,
679                          cname = None, visibility = 'private', api = 0, in_pxd = 0,
680                          defining = 0, modifiers = (), utility_code = None):
681        # Add an entry for a C function.
682        if not cname:
683            if visibility != 'private' or api:
684                cname = name
685            else:
686                cname = self.mangle(Naming.func_prefix, name)
687        entry = self.lookup_here(name)
688        if entry:
689            if visibility != 'private' and visibility != entry.visibility:
690                warning(pos, "Function '%s' previously declared as '%s'" % (name, entry.visibility), 1)
691            if not entry.type.same_as(type):
692                if visibility == 'extern' and entry.visibility == 'extern':
693                    can_override = False
694                    if self.is_cpp():
695                        can_override = True
696                    elif cname:
697                        # if all alternatives have different cnames,
698                        # it's safe to allow signature overrides
699                        for alt_entry in entry.all_alternatives():
700                            if not alt_entry.cname or cname == alt_entry.cname:
701                                break # cname not unique!
702                        else:
703                            can_override = True
704                    if can_override:
705                        temp = self.add_cfunction(name, type, pos, cname, visibility, modifiers)
706                        temp.overloaded_alternatives = entry.all_alternatives()
707                        entry = temp
708                    else:
709                        warning(pos, "Function signature does not match previous declaration", 1)
710                        entry.type = type
711                else:
712                    error(pos, "Function signature does not match previous declaration")
713        else:
714            entry = self.add_cfunction(name, type, pos, cname, visibility, modifiers)
715            entry.func_cname = cname
716        if in_pxd and visibility != 'extern':
717            entry.defined_in_pxd = 1
718        if api:
719            entry.api = 1
720        if not defining and not in_pxd and visibility != 'extern':
721            error(pos, "Non-extern C function '%s' declared but not defined" % name)
722        if defining:
723            entry.is_implemented = True
724        if modifiers:
725            entry.func_modifiers = modifiers
726        if utility_code:
727            assert not entry.utility_code, "duplicate utility code definition in entry %s (%s)" % (name, cname)
728            entry.utility_code = utility_code
729        type.entry = entry
730        return entry
731
732    def add_cfunction(self, name, type, pos, cname, visibility, modifiers):
733        # Add a C function entry without giving it a func_cname.
734        entry = self.declare(name, cname, type, pos, visibility)
735        entry.is_cfunction = 1
736        if modifiers:
737            entry.func_modifiers = modifiers
738        self.cfunc_entries.append(entry)
739        return entry
740
741    def find(self, name, pos):
742        # Look up name, report error if not found.
743        entry = self.lookup(name)
744        if entry:
745            return entry
746        else:
747            error(pos, "'%s' is not declared" % name)
748
749    def find_imported_module(self, path, pos):
750        # Look up qualified name, must be a module, report error if not found.
751        # Path is a list of names.
752        scope = self
753        for name in path:
754            entry = scope.find(name, pos)
755            if not entry:
756                return None
757            if entry.as_module:
758                scope = entry.as_module
759            else:
760                error(pos, "'%s' is not a cimported module" % '.'.join(path))
761                return None
762        return scope
763
764    def lookup(self, name):
765        # Look up name in this scope or an enclosing one.
766        # Return None if not found.
767        return (self.lookup_here(name)
768            or (self.outer_scope and self.outer_scope.lookup(name))
769            or None)
770
771    def lookup_here(self, name):
772        # Look up in this scope only, return None if not found.
773        return self.entries.get(name, None)
774
775    def lookup_target(self, name):
776        # Look up name in this scope only. Declare as Python
777        # variable if not found.
778        entry = self.lookup_here(name)
779        if not entry:
780            entry = self.declare_var(name, py_object_type, None)
781        return entry
782
783    def lookup_type(self, name):
784        entry = self.lookup(name)
785        if entry and entry.is_type:
786            if entry.type.is_fused and self.fused_to_specific:
787                return entry.type.specialize(self.fused_to_specific)
788            return entry.type
789
790    def lookup_operator(self, operator, operands):
791        if operands[0].type.is_cpp_class:
792            obj_type = operands[0].type
793            method = obj_type.scope.lookup("operator%s" % operator)
794            if method is not None:
795                res = PyrexTypes.best_match(operands[1:], method.all_alternatives())
796                if res is not None:
797                    return res
798        function = self.lookup("operator%s" % operator)
799        if function is None:
800            return None
801        return PyrexTypes.best_match(operands, function.all_alternatives())
802
803    def lookup_operator_for_types(self, pos, operator, types):
804        from Nodes import Node
805        class FakeOperand(Node):
806            pass
807        operands = [FakeOperand(pos, type=type) for type in types]
808        return self.lookup_operator(operator, operands)
809
810    def use_utility_code(self, new_code):
811        self.global_scope().use_utility_code(new_code)
812
813    def generate_library_function_declarations(self, code):
814        # Generate extern decls for C library funcs used.
815        pass
816
817    def defines_any(self, names):
818        # Test whether any of the given names are
819        # defined in this scope.
820        for name in names:
821            if name in self.entries:
822                return 1
823        return 0
824
825    def infer_types(self):
826        from TypeInference import get_type_inferer
827        get_type_inferer().infer_types(self)
828
829    def is_cpp(self):
830        outer = self.outer_scope
831        if outer is None:
832            return False
833        else:
834            return outer.is_cpp()
835
836    def add_include_file(self, filename):
837        self.outer_scope.add_include_file(filename)
838
839
840class PreImportScope(Scope):
841
842    namespace_cname = Naming.preimport_cname
843
844    def __init__(self):
845        Scope.__init__(self, Options.pre_import, None, None)
846
847    def declare_builtin(self, name, pos):
848        entry = self.declare(name, name, py_object_type, pos, 'private')
849        entry.is_variable = True
850        entry.is_pyglobal = True
851        return entry
852
853
854class BuiltinScope(Scope):
855    #  The builtin namespace.
856
857    is_builtin_scope = True
858
859    def __init__(self):
860        if Options.pre_import is None:
861            Scope.__init__(self, "__builtin__", None, None)
862        else:
863            Scope.__init__(self, "__builtin__", PreImportScope(), None)
864        self.type_names = {}
865
866        for name, definition in self.builtin_entries.iteritems():
867            cname, type = definition
868            self.declare_var(name, type, None, cname)
869
870    def lookup(self, name, language_level=None):
871        # 'language_level' is passed by ModuleScope
872        if language_level == 3:
873            if name == 'str':
874                name = 'unicode'
875        return Scope.lookup(self, name)
876
877    def declare_builtin(self, name, pos):
878        if not hasattr(builtins, name):
879            if self.outer_scope is not None:
880                return self.outer_scope.declare_builtin(name, pos)
881            else:
882                if Options.error_on_unknown_names:
883                    error(pos, "undeclared name not builtin: %s" % name)
884                else:
885                    warning(pos, "undeclared name not builtin: %s" % name, 2)
886
887    def declare_builtin_cfunction(self, name, type, cname, python_equiv = None,
888            utility_code = None):
889        # If python_equiv == "*", the Python equivalent has the same name
890        # as the entry, otherwise it has the name specified by python_equiv.
891        name = EncodedString(name)
892        entry = self.declare_cfunction(name, type, None, cname, visibility='extern',
893                                       utility_code = utility_code)
894        if python_equiv:
895            if python_equiv == "*":
896                python_equiv = name
897            else:
898                python_equiv = EncodedString(python_equiv)
899            var_entry = Entry(python_equiv, python_equiv, py_object_type)
900            var_entry.is_variable = 1
901            var_entry.is_builtin = 1
902            var_entry.utility_code = utility_code
903            entry.as_variable = var_entry
904        return entry
905
906    def declare_builtin_type(self, name, cname, utility_code = None, objstruct_cname = None):
907        name = EncodedString(name)
908        type = PyrexTypes.BuiltinObjectType(name, cname, objstruct_cname)
909        scope = CClassScope(name, outer_scope=None, visibility='extern')
910        scope.directives = {}
911        if name == 'bool':
912            type.is_final_type = True
913        type.set_scope(scope)
914        self.type_names[name] = 1
915        entry = self.declare_type(name, type, None, visibility='extern')
916        entry.utility_code = utility_code
917
918        var_entry = Entry(name = entry.name,
919            type = self.lookup('type').type, # make sure "type" is the first type declared...
920            pos = entry.pos,
921            cname = "((PyObject*)%s)" % entry.type.typeptr_cname)
922        var_entry.is_variable = 1
923        var_entry.is_cglobal = 1
924        var_entry.is_readonly = 1
925        var_entry.is_builtin = 1
926        var_entry.utility_code = utility_code
927        if Options.cache_builtins:
928            var_entry.is_const = True
929        entry.as_variable = var_entry
930
931        return type
932
933    def builtin_scope(self):
934        return self
935
936    builtin_entries = {
937
938        "type":   ["((PyObject*)&PyType_Type)", py_object_type],
939
940        "bool":   ["((PyObject*)&PyBool_Type)", py_object_type],
941        "int":    ["((PyObject*)&PyInt_Type)", py_object_type],
942        "long":   ["((PyObject*)&PyLong_Type)", py_object_type],
943        "float":  ["((PyObject*)&PyFloat_Type)", py_object_type],
944        "complex":["((PyObject*)&PyComplex_Type)", py_object_type],
945
946        "bytes":  ["((PyObject*)&PyBytes_Type)", py_object_type],
947        "bytearray":   ["((PyObject*)&PyByteArray_Type)", py_object_type],
948        "str":    ["((PyObject*)&PyString_Type)", py_object_type],
949        "unicode":["((PyObject*)&PyUnicode_Type)", py_object_type],
950
951        "tuple":  ["((PyObject*)&PyTuple_Type)", py_object_type],
952        "list":   ["((PyObject*)&PyList_Type)", py_object_type],
953        "dict":   ["((PyObject*)&PyDict_Type)", py_object_type],
954        "set":    ["((PyObject*)&PySet_Type)", py_object_type],
955        "frozenset":   ["((PyObject*)&PyFrozenSet_Type)", py_object_type],
956
957        "slice":  ["((PyObject*)&PySlice_Type)", py_object_type],
958#        "file":   ["((PyObject*)&PyFile_Type)", py_object_type],  # not in Py3
959
960        "None":   ["Py_None", py_object_type],
961        "False":  ["Py_False", py_object_type],
962        "True":   ["Py_True", py_object_type],
963    }
964
965const_counter = 1 # As a temporary solution for compiling code in pxds
966
967class ModuleScope(Scope):
968    # module_name          string             Python name of the module
969    # module_cname         string             C name of Python module object
970    # #module_dict_cname   string             C name of module dict object
971    # method_table_cname   string             C name of method table
972    # doc                  string             Module doc string
973    # doc_cname            string             C name of module doc string
974    # utility_code_list    [UtilityCode]      Queuing utility codes for forwarding to Code.py
975    # python_include_files [string]           Standard  Python headers to be included
976    # include_files        [string]           Other C headers to be included
977    # string_to_entry      {string : Entry}   Map string const to entry
978    # identifier_to_entry  {string : Entry}   Map identifier string const to entry
979    # context              Context
980    # parent_module        Scope              Parent in the import namespace
981    # module_entries       {string : Entry}   For cimport statements
982    # type_names           {string : 1}       Set of type names (used during parsing)
983    # included_files       [string]           Cython sources included with 'include'
984    # pxd_file_loaded      boolean            Corresponding .pxd file has been processed
985    # cimported_modules    [ModuleScope]      Modules imported with cimport
986    # types_imported       {PyrexType}        Set of types for which import code generated
987    # has_import_star      boolean            Module contains import *
988    # cpp                  boolean            Compiling a C++ file
989    # is_cython_builtin    boolean            Is this the Cython builtin scope (or a child scope)
990    # is_package           boolean            Is this a package module? (__init__)
991
992    is_module_scope = 1
993    has_import_star = 0
994    is_cython_builtin = 0
995
996    def __init__(self, name, parent_module, context):
997        import Builtin
998        self.parent_module = parent_module
999        outer_scope = Builtin.builtin_scope
1000        Scope.__init__(self, name, outer_scope, parent_module)
1001        if name == "__init__":
1002            # Treat Spam/__init__.pyx specially, so that when Python loads
1003            # Spam/__init__.so, initSpam() is defined.
1004            self.module_name = parent_module.module_name
1005            self.is_package = True
1006        else:
1007            self.module_name = name
1008            self.is_package = False
1009        self.module_name = EncodedString(self.module_name)
1010        self.context = context
1011        self.module_cname = Naming.module_cname
1012        self.module_dict_cname = Naming.moddict_cname
1013        self.method_table_cname = Naming.methtable_cname
1014        self.doc = ""
1015        self.doc_cname = Naming.moddoc_cname
1016        self.utility_code_list = []
1017        self.module_entries = {}
1018        self.python_include_files = ["Python.h"]
1019        self.include_files = []
1020        self.type_names = dict(outer_scope.type_names)
1021        self.pxd_file_loaded = 0
1022        self.cimported_modules = []
1023        self.types_imported = set()
1024        self.included_files = []
1025        self.has_extern_class = 0
1026        self.cached_builtins = []
1027        self.undeclared_cached_builtins = []
1028        self.namespace_cname = self.module_cname
1029        for var_name in ['__builtins__', '__name__', '__file__', '__doc__', '__path__']:
1030            self.declare_var(EncodedString(var_name), py_object_type, None)
1031
1032    def qualifying_scope(self):
1033        return self.parent_module
1034
1035    def global_scope(self):
1036        return self
1037
1038    def lookup(self, name):
1039        entry = self.lookup_here(name)
1040        if entry is not None:
1041            return entry
1042
1043        if self.context is not None:
1044            language_level = self.context.language_level
1045        else:
1046            language_level = 3
1047
1048        return self.outer_scope.lookup(name, language_level=language_level)
1049
1050    def declare_builtin(self, name, pos):
1051        if not hasattr(builtins, name) \
1052               and name not in Code.non_portable_builtins_map \
1053               and name not in Code.uncachable_builtins:
1054            if self.has_import_star:
1055                entry = self.declare_var(name, py_object_type, pos)
1056                return entry
1057            else:
1058                if Options.error_on_unknown_names:
1059                    error(pos, "undeclared name not builtin: %s" % name)
1060                else:
1061                    warning(pos, "undeclared name not builtin: %s" % name, 2)
1062                # unknown - assume it's builtin and look it up at runtime
1063                entry = self.declare(name, None, py_object_type, pos, 'private')
1064                entry.is_builtin = 1
1065                return entry
1066        if Options.cache_builtins:
1067            for entry in self.cached_builtins:
1068                if entry.name == name:
1069                    return entry
1070        entry = self.declare(None, None, py_object_type, pos, 'private')
1071        if Options.cache_builtins and name not in Code.uncachable_builtins:
1072            entry.is_builtin = 1
1073            entry.is_const = 1 # cached
1074            entry.name = name
1075            entry.cname = Naming.builtin_prefix + name
1076            self.cached_builtins.append(entry)
1077            self.undeclared_cached_builtins.append(entry)
1078        else:
1079            entry.is_builtin = 1
1080            entry.name = name
1081        return entry
1082
1083    def find_module(self, module_name, pos):
1084        # Find a module in the import namespace, interpreting
1085        # relative imports relative to this module's parent.
1086        # Finds and parses the module's .pxd file if the module
1087        # has not been referenced before.
1088        return self.global_scope().context.find_module(
1089            module_name, relative_to = self.parent_module, pos = pos)
1090
1091    def find_submodule(self, name):
1092        # Find and return scope for a submodule of this module,
1093        # creating a new empty one if necessary. Doesn't parse .pxd.
1094        scope = self.lookup_submodule(name)
1095        if not scope:
1096            scope = ModuleScope(name,
1097                parent_module = self, context = self.context)
1098            self.module_entries[name] = scope
1099        return scope
1100
1101    def lookup_submodule(self, name):
1102        # Return scope for submodule of this module, or None.
1103        return self.module_entries.get(name, None)
1104
1105    def add_include_file(self, filename):
1106        if filename not in self.python_include_files \
1107            and filename not in self.include_files:
1108                self.include_files.append(filename)
1109
1110    def add_imported_module(self, scope):
1111        if scope not in self.cimported_modules:
1112            for filename in scope.include_files:
1113                self.add_include_file(filename)
1114            self.cimported_modules.append(scope)
1115            for m in scope.cimported_modules:
1116                self.add_imported_module(m)
1117
1118    def add_imported_entry(self, name, entry, pos):
1119        if entry not in self.entries:
1120            self.entries[name] = entry
1121        else:
1122            warning(pos, "'%s' redeclared  " % name, 0)
1123
1124    def declare_module(self, name, scope, pos):
1125        # Declare a cimported module. This is represented as a
1126        # Python module-level variable entry with a module
1127        # scope attached to it. Reports an error and returns
1128        # None if previously declared as something else.
1129        entry = self.lookup_here(name)
1130        if entry:
1131            if entry.is_pyglobal and entry.as_module is scope:
1132                return entry # Already declared as the same module
1133            if not (entry.is_pyglobal and not entry.as_module):
1134                # SAGE -- I put this here so Pyrex
1135                # cimport's work across directories.
1136                # Currently it tries to multiply define
1137                # every module appearing in an import list.
1138                # It shouldn't be an error for a module
1139                # name to appear again, and indeed the generated
1140                # code compiles fine.
1141                return entry
1142        else:
1143            entry = self.declare_var(name, py_object_type, pos)
1144        entry.as_module = scope
1145        self.add_imported_module(scope)
1146        return entry
1147
1148    def declare_var(self, name, type, pos,
1149                    cname = None, visibility = 'private',
1150                    api = 0, in_pxd = 0, is_cdef = 0):
1151        # Add an entry for a global variable. If it is a Python
1152        # object type, and not declared with cdef, it will live
1153        # in the module dictionary, otherwise it will be a C
1154        # global variable.
1155        if not visibility in ('private', 'public', 'extern'):
1156            error(pos, "Module-level variable cannot be declared %s" % visibility)
1157        if not is_cdef:
1158            if type is unspecified_type:
1159                type = py_object_type
1160            if not (type.is_pyobject and not type.is_extension_type):
1161                raise InternalError(
1162                    "Non-cdef global variable is not a generic Python object")
1163
1164        if not cname:
1165            defining = not in_pxd
1166            if visibility == 'extern' or (visibility == 'public' and defining):
1167                cname = name
1168            else:
1169                cname = self.mangle(Naming.var_prefix, name)
1170
1171        entry = self.lookup_here(name)
1172        if entry and entry.defined_in_pxd:
1173            #if visibility != 'private' and visibility != entry.visibility:
1174            #    warning(pos, "Variable '%s' previously declared as '%s'" % (name, entry.visibility), 1)
1175            if not entry.type.same_as(type):
1176                if visibility == 'extern' and entry.visibility == 'extern':
1177                    warning(pos, "Variable '%s' type does not match previous declaration" % name, 1)
1178                    entry.type = type
1179                #else:
1180                #    error(pos, "Variable '%s' type does not match previous declaration" % name)
1181            if entry.visibility != "private":
1182                mangled_cname = self.mangle(Naming.var_prefix, name)
1183                if entry.cname == mangled_cname:
1184                    cname = name
1185                    entry.cname = name
1186            if not entry.is_implemented:
1187                entry.is_implemented = True
1188                return entry
1189
1190        entry = Scope.declare_var(self, name, type, pos,
1191                                  cname=cname, visibility=visibility,
1192                                  api=api, in_pxd=in_pxd, is_cdef=is_cdef)
1193        if is_cdef:
1194            entry.is_cglobal = 1
1195            if entry.type.is_pyobject:
1196                entry.init = 0
1197            self.var_entries.append(entry)
1198        else:
1199            entry.is_pyglobal = 1
1200        if Options.cimport_from_pyx:
1201            entry.used = 1
1202        return entry
1203
1204    def declare_cfunction(self, name, type, pos,
1205                          cname = None, visibility = 'private', api = 0, in_pxd = 0,
1206                          defining = 0, modifiers = (), utility_code = None):
1207        # Add an entry for a C function.
1208        if not cname:
1209            if visibility == 'extern' or (visibility == 'public' and defining):
1210                cname = name
1211            else:
1212                cname = self.mangle(Naming.func_prefix, name)
1213        entry = self.lookup_here(name)
1214        if entry and entry.defined_in_pxd:
1215            if entry.visibility != "private":
1216                mangled_cname = self.mangle(Naming.var_prefix, name)
1217                if entry.cname == mangled_cname:
1218                    cname = name
1219                    entry.cname = cname
1220                    entry.func_cname = cname
1221        entry = Scope.declare_cfunction(
1222            self, name, type, pos,
1223            cname = cname, visibility = visibility, api = api, in_pxd = in_pxd,
1224            defining = defining, modifiers = modifiers, utility_code = utility_code)
1225        return entry
1226
1227    def declare_global(self, name, pos):
1228        entry = self.lookup_here(name)
1229        if not entry:
1230            self.declare_var(name, py_object_type, pos)
1231
1232    def use_utility_code(self, new_code):
1233        if new_code is not None:
1234            self.utility_code_list.append(new_code)
1235
1236    def declare_c_class(self, name, pos, defining = 0, implementing = 0,
1237        module_name = None, base_type = None, objstruct_cname = None,
1238        typeobj_cname = None, typeptr_cname = None, visibility = 'private', typedef_flag = 0, api = 0,
1239        buffer_defaults = None, shadow = 0):
1240        # If this is a non-extern typedef class, expose the typedef, but use
1241        # the non-typedef struct internally to avoid needing forward
1242        # declarations for anonymous structs.
1243        if typedef_flag and visibility != 'extern':
1244            if not (visibility == 'public' or api):
1245                warning(pos, "ctypedef only valid for 'extern' , 'public', and 'api'", 2)
1246            objtypedef_cname = objstruct_cname
1247            typedef_flag = 0
1248        else:
1249            objtypedef_cname = None
1250        #
1251        #  Look for previous declaration as a type
1252        #
1253        entry = self.lookup_here(name)
1254        if entry and not shadow:
1255            type = entry.type
1256            if not (entry.is_type and type.is_extension_type):
1257                entry = None # Will cause redeclaration and produce an error
1258            else:
1259                scope = type.scope
1260                if typedef_flag and (not scope or scope.defined):
1261                    self.check_previous_typedef_flag(entry, typedef_flag, pos)
1262                if (scope and scope.defined) or (base_type and type.base_type):
1263                    if base_type and base_type is not type.base_type:
1264                        error(pos, "Base type does not match previous declaration")
1265                if base_type and not type.base_type:
1266                    type.base_type = base_type
1267        #
1268        #  Make a new entry if needed
1269        #
1270        if not entry or shadow:
1271            type = PyrexTypes.PyExtensionType(name, typedef_flag, base_type, visibility == 'extern')
1272            type.pos = pos
1273            type.buffer_defaults = buffer_defaults
1274            if objtypedef_cname is not None:
1275                type.objtypedef_cname = objtypedef_cname
1276            if visibility == 'extern':
1277                type.module_name = module_name
1278            else:
1279                type.module_name = self.qualified_name
1280            if typeptr_cname:
1281                type.typeptr_cname = typeptr_cname
1282            else:
1283                type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name)
1284            entry = self.declare_type(name, type, pos, visibility = visibility,
1285                defining = 0, shadow = shadow)
1286            entry.is_cclass = True
1287            if objstruct_cname:
1288                type.objstruct_cname = objstruct_cname
1289            elif not entry.in_cinclude:
1290                type.objstruct_cname = self.mangle(Naming.objstruct_prefix, name)
1291            else:
1292                error(entry.pos,
1293                    "Object name required for 'public' or 'extern' C class")
1294            self.attach_var_entry_to_c_class(entry)
1295            self.c_class_entries.append(entry)
1296        #
1297        #  Check for re-definition and create scope if needed
1298        #
1299        if not type.scope:
1300            if defining or implementing:
1301                scope = CClassScope(name = name, outer_scope = self,
1302                    visibility = visibility)
1303                scope.directives = self.directives.copy()
1304                if base_type and base_type.scope:
1305                    scope.declare_inherited_c_attributes(base_type.scope)
1306                type.set_scope(scope)
1307                self.type_entries.append(entry)
1308        else:
1309            if defining and type.scope.defined:
1310                error(pos, "C class '%s' already defined" % name)
1311            elif implementing and type.scope.implemented:
1312                error(pos, "C class '%s' already implemented" % name)
1313        #
1314        #  Fill in options, checking for compatibility with any previous declaration
1315        #
1316        if defining:
1317            entry.defined_in_pxd = 1
1318        if implementing:   # So that filenames in runtime exceptions refer to
1319            entry.pos = pos  # the .pyx file and not the .pxd file
1320        if visibility != 'private' and entry.visibility != visibility:
1321            error(pos, "Class '%s' previously declared as '%s'"
1322                % (name, entry.visibility))
1323        if api:
1324            entry.api = 1
1325        if objstruct_cname:
1326            if type.objstruct_cname and type.objstruct_cname != objstruct_cname:
1327                error(pos, "Object struct name differs from previous declaration")
1328            type.objstruct_cname = objstruct_cname
1329        if typeobj_cname:
1330            if type.typeobj_cname and type.typeobj_cname != typeobj_cname:
1331                    error(pos, "Type object name differs from previous declaration")
1332            type.typeobj_cname = typeobj_cname
1333
1334        if self.directives.get('final'):
1335            entry.type.is_final_type = True
1336
1337        # cdef classes are always exported, but we need to set it to
1338        # distinguish between unused Cython utility code extension classes
1339        entry.used = True
1340
1341        #
1342        # Return new or existing entry
1343        #
1344        return entry
1345
1346    def allocate_vtable_names(self, entry):
1347        #  If extension type has a vtable, allocate vtable struct and
1348        #  slot names for it.
1349        type = entry.type
1350        if type.base_type and type.base_type.vtabslot_cname:
1351            #print "...allocating vtabslot_cname because base type has one" ###
1352            type.vtabslot_cname = "%s.%s" % (
1353                Naming.obj_base_cname, type.base_type.vtabslot_cname)
1354        elif type.scope and type.scope.cfunc_entries:
1355            # one special case here: when inheriting from builtin
1356            # types, the methods may also be built-in, in which
1357            # case they won't need a vtable
1358            entry_count = len(type.scope.cfunc_entries)
1359            base_type = type.base_type
1360            while base_type:
1361                # FIXME: this will break if we ever get non-inherited C methods
1362                if not base_type.scope or entry_count > len(base_type.scope.cfunc_entries):
1363                    break
1364                if base_type.is_builtin_type:
1365                    # builtin base type defines all methods => no vtable needed
1366                    return
1367                base_type = base_type.base_type
1368            #print "...allocating vtabslot_cname because there are C methods" ###
1369            type.vtabslot_cname = Naming.vtabslot_cname
1370        if type.vtabslot_cname:
1371            #print "...allocating other vtable related cnames" ###
1372            type.vtabstruct_cname = self.mangle(Naming.vtabstruct_prefix, entry.name)
1373            type.vtabptr_cname = self.mangle(Naming.vtabptr_prefix, entry.name)
1374
1375    def check_c_classes_pxd(self):
1376        # Performs post-analysis checking and finishing up of extension types
1377        # being implemented in this module. This is called only for the .pxd.
1378        #
1379        # Checks all extension types declared in this scope to
1380        # make sure that:
1381        #
1382        #    * The extension type is fully declared
1383        #
1384        # Also allocates a name for the vtable if needed.
1385        #
1386        for entry in self.c_class_entries:
1387            # Check defined
1388            if not entry.type.scope:
1389                error(entry.pos, "C class '%s' is declared but not defined" % entry.name)
1390
1391    def check_c_class(self, entry):
1392        type = entry.type
1393        name = entry.name
1394        visibility = entry.visibility
1395        # Check defined
1396        if not type.scope:
1397            error(entry.pos, "C class '%s' is declared but not defined" % name)
1398        # Generate typeobj_cname
1399        if visibility != 'extern' and not type.typeobj_cname:
1400            type.typeobj_cname = self.mangle(Naming.typeobj_prefix, name)
1401        ## Generate typeptr_cname
1402        #type.typeptr_cname = self.mangle(Naming.typeptr_prefix, name)
1403        # Check C methods defined
1404        if type.scope:
1405            for method_entry in type.scope.cfunc_entries:
1406                if not method_entry.is_inherited and not method_entry.func_cname:
1407                    error(method_entry.pos, "C method '%s' is declared but not defined" %
1408                        method_entry.name)
1409        # Allocate vtable name if necessary
1410        if type.vtabslot_cname:
1411            #print "ModuleScope.check_c_classes: allocating vtable cname for", self ###
1412            type.vtable_cname = self.mangle(Naming.vtable_prefix, entry.name)
1413
1414    def check_c_classes(self):
1415        # Performs post-analysis checking and finishing up of extension types
1416        # being implemented in this module. This is called only for the main
1417        # .pyx file scope, not for cimported .pxd scopes.
1418        #
1419        # Checks all extension types declared in this scope to
1420        # make sure that:
1421        #
1422        #    * The extension type is implemented
1423        #    * All required object and type names have been specified or generated
1424        #    * All non-inherited C methods are implemented
1425        #
1426        # Also allocates a name for the vtable if needed.
1427        #
1428        debug_check_c_classes = 0
1429        if debug_check_c_classes:
1430            print("Scope.check_c_classes: checking scope " + self.qualified_name)
1431        for entry in self.c_class_entries:
1432            if debug_check_c_classes:
1433                print("...entry %s %s" % (entry.name, entry))
1434                print("......type = ",  entry.type)
1435                print("......visibility = ", entry.visibility)
1436            self.check_c_class(entry)
1437
1438    def check_c_functions(self):
1439        # Performs post-analysis checking making sure all
1440        # defined c functions are actually implemented.
1441        for name, entry in self.entries.items():
1442            if entry.is_cfunction:
1443                if (entry.defined_in_pxd
1444                        and entry.scope is self
1445                        and entry.visibility != 'extern'
1446                        and not entry.in_cinclude
1447                        and not entry.is_implemented):
1448                    error(entry.pos, "Non-extern C function '%s' declared but not defined" % name)
1449
1450    def attach_var_entry_to_c_class(self, entry):
1451        # The name of an extension class has to serve as both a type
1452        # name and a variable name holding the type object. It is
1453        # represented in the symbol table by a type entry with a
1454        # variable entry attached to it. For the variable entry,
1455        # we use a read-only C global variable whose name is an
1456        # expression that refers to the type object.
1457        import Builtin
1458        var_entry = Entry(name = entry.name,
1459            type = Builtin.type_type,
1460            pos = entry.pos,
1461            cname = "((PyObject*)%s)" % entry.type.typeptr_cname)
1462        var_entry.is_variable = 1
1463        var_entry.is_cglobal = 1
1464        var_entry.is_readonly = 1
1465        entry.as_variable = var_entry
1466
1467    def is_cpp(self):
1468        return self.cpp
1469
1470    def infer_types(self):
1471        from TypeInference import PyObjectTypeInferer
1472        PyObjectTypeInferer().infer_types(self)
1473
1474
1475class LocalScope(Scope):
1476
1477    # Does the function have a 'with gil:' block?
1478    has_with_gil_block = False
1479
1480    # Transient attribute, used for symbol table variable declarations
1481    _in_with_gil_block = False
1482
1483    def __init__(self, name, outer_scope, parent_scope = None):
1484        if parent_scope is None:
1485            parent_scope = outer_scope
1486        Scope.__init__(self, name, outer_scope, parent_scope)
1487
1488    def mangle(self, prefix, name):
1489        return prefix + name
1490
1491    def declare_arg(self, name, type, pos):
1492        # Add an entry for an argument of a function.
1493        cname = self.mangle(Naming.var_prefix, name)
1494        entry = self.declare(name, cname, type, pos, 'private')
1495        entry.is_variable = 1
1496        if type.is_pyobject:
1497            entry.init = "0"
1498        entry.is_arg = 1
1499        #entry.borrowed = 1 # Not using borrowed arg refs for now
1500        self.arg_entries.append(entry)
1501        return entry
1502
1503    def declare_var(self, name, type, pos,
1504                    cname = None, visibility = 'private',
1505                    api = 0, in_pxd = 0, is_cdef = 0):
1506        # Add an entry for a local variable.
1507        if visibility in ('public', 'readonly'):
1508            error(pos, "Local variable cannot be declared %s" % visibility)
1509        entry = Scope.declare_var(self, name, type, pos,
1510                                  cname=cname, visibility=visibility,
1511                                  api=api, in_pxd=in_pxd, is_cdef=is_cdef)
1512        if type.is_pyobject:
1513            entry.init = "0"
1514        entry.is_local = 1
1515
1516        entry.in_with_gil_block = self._in_with_gil_block
1517        self.var_entries.append(entry)
1518        return entry
1519
1520    def declare_global(self, name, pos):
1521        # Pull entry from global scope into local scope.
1522        if self.lookup_here(name):
1523            warning(pos, "'%s' redeclared  ", 0)
1524        else:
1525            entry = self.global_scope().lookup_target(name)
1526            self.entries[name] = entry
1527
1528    def declare_nonlocal(self, name, pos):
1529        # Pull entry from outer scope into local scope
1530        orig_entry = self.lookup_here(name)
1531        if orig_entry and orig_entry.scope is self and not orig_entry.from_closure:
1532            error(pos, "'%s' redeclared as nonlocal" % name)
1533        else:
1534            entry = self.lookup(name)
1535            if entry is None or not entry.from_closure:
1536                error(pos, "no binding for nonlocal '%s' found" % name)
1537
1538    def lookup(self, name):
1539        # Look up name in this scope or an enclosing one.
1540        # Return None if not found.
1541        entry = Scope.lookup(self, name)
1542        if entry is not None:
1543            if entry.scope is not self and entry.scope.is_closure_scope:
1544                if hasattr(entry.scope, "scope_class"):
1545                    raise InternalError("lookup() after scope class created.")
1546                # The actual c fragment for the different scopes differs
1547                # on the outside and inside, so we make a new entry
1548                entry.in_closure = True
1549                inner_entry = InnerEntry(entry, self)
1550                inner_entry.is_variable = True
1551                self.entries[name] = inner_entry
1552                return inner_entry
1553        return entry
1554
1555    def mangle_closure_cnames(self, outer_scope_cname):
1556        for entry in self.entries.values():
1557            if entry.from_closure:
1558                cname = entry.outer_entry.cname
1559                if self.is_passthrough:
1560                    entry.cname = cname
1561                else:
1562                    if cname.startswith(Naming.cur_scope_cname):
1563                        cname = cname[len(Naming.cur_scope_cname)+2:]
1564                    entry.cname = "%s->%s" % (outer_scope_cname, cname)
1565            elif entry.in_closure:
1566                entry.original_cname = entry.cname
1567                entry.cname = "%s->%s" % (Naming.cur_scope_cname, entry.cname)
1568
1569
1570class GeneratorExpressionScope(Scope):
1571    """Scope for generator expressions and comprehensions.  As opposed
1572    to generators, these can be easily inlined in some cases, so all
1573    we really need is a scope that holds the loop variable(s).
1574    """
1575    def __init__(self, outer_scope):
1576        name = outer_scope.global_scope().next_id(Naming.genexpr_id_ref)
1577        Scope.__init__(self, name, outer_scope, outer_scope)
1578        self.directives = outer_scope.directives
1579        self.genexp_prefix = "%s%d%s" % (Naming.pyrex_prefix, len(name), name)
1580
1581    def mangle(self, prefix, name):
1582        return '%s%s' % (self.genexp_prefix, self.parent_scope.mangle(prefix, name))
1583
1584    def declare_var(self, name, type, pos,
1585                    cname = None, visibility = 'private',
1586                    api = 0, in_pxd = 0, is_cdef = True):
1587        if type is unspecified_type:
1588            # if the outer scope defines a type for this variable, inherit it
1589            outer_entry = self.outer_scope.lookup(name)
1590            if outer_entry and outer_entry.is_variable:
1591                type = outer_entry.type # may still be 'unspecified_type' !
1592        # the parent scope needs to generate code for the variable, but
1593        # this scope must hold its name exclusively
1594        cname = '%s%s' % (self.genexp_prefix, self.parent_scope.mangle(Naming.var_prefix, name or self.next_id()))
1595        entry = self.declare(name, cname, type, pos, visibility)
1596        entry.is_variable = 1
1597        entry.is_local = 1
1598        self.var_entries.append(entry)
1599        self.entries[name] = entry
1600        return entry
1601
1602    def declare_pyfunction(self, name, pos, allow_redefine=False):
1603        return self.outer_scope.declare_pyfunction(
1604            name, pos, allow_redefine)
1605
1606    def declare_lambda_function(self, func_cname, pos):
1607        return self.outer_scope.declare_lambda_function(func_cname, pos)
1608
1609    def add_lambda_def(self, def_node):
1610        return self.outer_scope.add_lambda_def(def_node)
1611
1612
1613class ClosureScope(LocalScope):
1614
1615    is_closure_scope = True
1616
1617    def __init__(self, name, scope_name, outer_scope, parent_scope=None):
1618        LocalScope.__init__(self, name, outer_scope, parent_scope)
1619        self.closure_cname = "%s%s" % (Naming.closure_scope_prefix, scope_name)
1620
1621#    def mangle_closure_cnames(self, scope_var):
1622#        for entry in self.entries.values() + self.temp_entries:
1623#            entry.in_closure = 1
1624#        LocalScope.mangle_closure_cnames(self, scope_var)
1625
1626#    def mangle(self, prefix, name):
1627#        return "%s->%s" % (self.cur_scope_cname, name)
1628#        return "%s->%s" % (self.closure_cname, name)
1629
1630    def declare_pyfunction(self, name, pos, allow_redefine=False):
1631        return LocalScope.declare_pyfunction(self, name, pos, allow_redefine, visibility='private')
1632
1633
1634class StructOrUnionScope(Scope):
1635    #  Namespace of a C struct or union.
1636
1637    def __init__(self, name="?"):
1638        Scope.__init__(self, name, None, None)
1639
1640    def declare_var(self, name, type, pos,
1641                    cname = None, visibility = 'private',
1642                    api = 0, in_pxd = 0, is_cdef = 0,
1643                    allow_pyobject = 0):
1644        # Add an entry for an attribute.
1645        if not cname:
1646            cname = name
1647            if visibility == 'private':
1648                cname = c_safe_identifier(cname)
1649        if type.is_cfunction:
1650            type = PyrexTypes.CPtrType(type)
1651        entry = self.declare(name, cname, type, pos, visibility)
1652        entry.is_variable = 1
1653        self.var_entries.append(entry)
1654        if type.is_pyobject and not allow_pyobject:
1655            error(pos,
1656                  "C struct/union member cannot be a Python object")
1657        if visibility != 'private':
1658            error(pos,
1659                  "C struct/union member cannot be declared %s" % visibility)
1660        return entry
1661
1662    def declare_cfunction(self, name, type, pos,
1663                          cname = None, visibility = 'private', api = 0, in_pxd = 0,
1664                          defining = 0, modifiers = ()): # currently no utility code ...
1665        return self.declare_var(name, type, pos,
1666                                cname=cname, visibility=visibility)
1667
1668
1669class ClassScope(Scope):
1670    #  Abstract base class for namespace of
1671    #  Python class or extension type.
1672    #
1673    #  class_name     string   Python name of the class
1674    #  scope_prefix   string   Additional prefix for names
1675    #                          declared in the class
1676    #  doc    string or None   Doc string
1677
1678    def __init__(self, name, outer_scope):
1679        Scope.__init__(self, name, outer_scope, outer_scope)
1680        self.class_name = name
1681        self.doc = None
1682
1683    def lookup(self, name):
1684        entry = Scope.lookup(self, name)
1685        if entry:
1686            return entry
1687        if name == "classmethod":
1688            # We don't want to use the builtin classmethod here 'cause it won't do the
1689            # right thing in this scope (as the class members aren't still functions).
1690            # Don't want to add a cfunction to this scope 'cause that would mess with
1691            # the type definition, so we just return the right entry.
1692            entry = Entry(
1693                "classmethod",
1694                "__Pyx_Method_ClassMethod",
1695                PyrexTypes.CFuncType(
1696                    py_object_type,
1697                    [PyrexTypes.CFuncTypeArg("", py_object_type, None)], 0, 0))
1698            entry.utility_code_definition = Code.UtilityCode.load_cached("ClassMethod", "CythonFunction.c")
1699            entry.is_cfunction = 1
1700        return entry
1701
1702
1703class PyClassScope(ClassScope):
1704    #  Namespace of a Python class.
1705    #
1706    #  class_obj_cname     string   C variable holding class object
1707
1708    is_py_class_scope = 1
1709
1710    def mangle_class_private_name(self, name):
1711        return self.mangle_special_name(name)
1712
1713    def mangle_special_name(self, name):
1714        if name and name.startswith('__') and not name.endswith('__'):
1715            name = EncodedString('_%s%s' % (self.class_name.lstrip('_'), name))
1716        return name
1717
1718    def lookup_here(self, name):
1719        name = self.mangle_special_name(name)
1720        return ClassScope.lookup_here(self, name)
1721
1722    def declare_var(self, name, type, pos,
1723                    cname = None, visibility = 'private',
1724                    api = 0, in_pxd = 0, is_cdef = 0):
1725        name = self.mangle_special_name(name)
1726        if type is unspecified_type:
1727            type = py_object_type
1728        # Add an entry for a class attribute.
1729        entry = Scope.declare_var(self, name, type, pos,
1730                                  cname=cname, visibility=visibility,
1731                                  api=api, in_pxd=in_pxd, is_cdef=is_cdef)
1732        entry.is_pyglobal = 1
1733        entry.is_pyclass_attr = 1
1734        return entry
1735
1736    def declare_nonlocal(self, name, pos):
1737        # Pull entry from outer scope into local scope
1738        orig_entry = self.lookup_here(name)
1739        if orig_entry and orig_entry.scope is self and not orig_entry.from_closure:
1740            error(pos, "'%s' redeclared as nonlocal" % name)
1741        else:
1742            entry = self.lookup(name)
1743            if entry is None:
1744                error(pos, "no binding for nonlocal '%s' found" % name)
1745            else:
1746                # FIXME: this works, but it's unclear if it's the
1747                # right thing to do
1748                self.entries[name] = entry
1749
1750    def declare_global(self, name, pos):
1751        # Pull entry from global scope into local scope.
1752        if self.lookup_here(name):
1753            warning(pos, "'%s' redeclared  ", 0)
1754        else:
1755            entry = self.global_scope().lookup_target(name)
1756            self.entries[name] = entry
1757
1758    def add_default_value(self, type):
1759        return self.outer_scope.add_default_value(type)
1760
1761
1762class CClassScope(ClassScope):
1763    #  Namespace of an extension type.
1764    #
1765    #  parent_type           CClassType
1766    #  #typeobj_cname        string or None
1767    #  #objstruct_cname      string
1768    #  method_table_cname    string
1769    #  getset_table_cname    string
1770    #  has_pyobject_attrs    boolean  Any PyObject attributes?
1771    #  has_memoryview_attrs  boolean  Any memory view attributes?
1772    #  has_cyclic_pyobject_attrs    boolean  Any PyObject attributes that may need GC?
1773    #  property_entries      [Entry]
1774    #  defined               boolean  Defined in .pxd file
1775    #  implemented           boolean  Defined in .pyx file
1776    #  inherited_var_entries [Entry]  Adapted var entries from base class
1777
1778    is_c_class_scope = 1
1779
1780    has_pyobject_attrs = False
1781    has_memoryview_attrs = False
1782    has_cyclic_pyobject_attrs = False
1783    defined = False
1784    implemented = False
1785
1786    def __init__(self, name, outer_scope, visibility):
1787        ClassScope.__init__(self, name, outer_scope)
1788        if visibility != 'extern':
1789            self.method_table_cname = outer_scope.mangle(Naming.methtab_prefix, name)
1790            self.getset_table_cname = outer_scope.mangle(Naming.gstab_prefix, name)
1791        self.property_entries = []
1792        self.inherited_var_entries = []
1793
1794    def needs_gc(self):
1795        # If the type or any of its base types have Python-valued
1796        # C attributes, then it needs to participate in GC.
1797        if self.has_cyclic_pyobject_attrs:
1798            return True
1799        base_type = self.parent_type.base_type
1800        if base_type and base_type.scope is not None:
1801            return base_type.scope.needs_gc()
1802        elif self.parent_type.is_builtin_type:
1803            return not self.parent_type.is_gc_simple
1804        return False
1805
1806    def needs_tp_clear(self):
1807        """
1808        Do we need to generate an implementation for the tp_clear slot? Can
1809        be disabled to keep references for the __dealloc__ cleanup function.
1810        """
1811        return self.needs_gc() and not self.directives.get('no_gc_clear', False)
1812
1813    def get_refcounted_entries(self, include_weakref=False,
1814                               include_gc_simple=True):
1815        py_attrs = []
1816        py_buffers = []
1817        memoryview_slices = []
1818
1819        for entry in self.var_entries:
1820            if entry.type.is_pyobject:
1821                if include_weakref or entry.name != "__weakref__":
1822                    if include_gc_simple or not entry.type.is_gc_simple:
1823                        py_attrs.append(entry)
1824            elif entry.type == PyrexTypes.c_py_buffer_type:
1825                py_buffers.append(entry)
1826            elif entry.type.is_memoryviewslice:
1827                memoryview_slices.append(entry)
1828
1829        have_entries = py_attrs or py_buffers or memoryview_slices
1830        return have_entries, (py_attrs, py_buffers, memoryview_slices)
1831
1832    def declare_var(self, name, type, pos,
1833                    cname = None, visibility = 'private',
1834                    api = 0, in_pxd = 0, is_cdef = 0):
1835        if is_cdef:
1836            # Add an entry for an attribute.
1837            if self.defined:
1838                error(pos,
1839                    "C attributes cannot be added in implementation part of"
1840                    " extension type defined in a pxd")
1841            if get_special_method_signature(name):
1842                error(pos,
1843                    "The name '%s' is reserved for a special method."
1844                        % name)
1845            if not cname:
1846                cname = name
1847                if visibility == 'private':
1848                    cname = c_safe_identifier(cname)
1849            if type.is_cpp_class and visibility != 'extern':
1850                type.check_nullary_constructor(pos)
1851                self.use_utility_code(Code.UtilityCode("#include <new>"))
1852            entry = self.declare(name, cname, type, pos, visibility)
1853            entry.is_variable = 1
1854            self.var_entries.append(entry)
1855            if type.is_memoryviewslice:
1856                self.has_memoryview_attrs = True
1857            elif type.is_pyobject and name != '__weakref__':
1858                self.has_pyobject_attrs = True
1859                if (not type.is_builtin_type
1860                        or not type.scope or type.scope.needs_gc()):
1861                    self.has_cyclic_pyobject_attrs = True
1862            if visibility not in ('private', 'public', 'readonly'):
1863                error(pos,
1864                    "Attribute of extension type cannot be declared %s" % visibility)
1865            if visibility in ('public', 'readonly'):
1866                # If the field is an external typedef, we cannot be sure about the type,
1867                # so do conversion ourself rather than rely on the CPython mechanism (through
1868                # a property; made in AnalyseDeclarationsTransform).
1869                entry.needs_property = True
1870                if name == "__weakref__":
1871                    error(pos, "Special attribute __weakref__ cannot be exposed to Python")
1872                if not type.is_pyobject:
1873                    if (not type.create_to_py_utility_code(self) or
1874                        (visibility=='public' and not
1875                         type.create_from_py_utility_code(self))):
1876                        error(pos,
1877                              "C attribute of type '%s' cannot be accessed from Python" % type)
1878            else:
1879                entry.needs_property = False
1880            return entry
1881        else:
1882            if type is unspecified_type:
1883                type = py_object_type
1884            # Add an entry for a class attribute.
1885            entry = Scope.declare_var(self, name, type, pos,
1886                                      cname=cname, visibility=visibility,
1887                                      api=api, in_pxd=in_pxd, is_cdef=is_cdef)
1888            entry.is_member = 1
1889            entry.is_pyglobal = 1 # xxx: is_pyglobal changes behaviour in so many places that
1890                                  # I keep it in for now. is_member should be enough
1891                                  # later on
1892            self.namespace_cname = "(PyObject *)%s" % self.parent_type.typeptr_cname
1893            return entry
1894
1895    def declare_pyfunction(self, name, pos, allow_redefine=False):
1896        # Add an entry for a method.
1897        if name in ('__eq__', '__ne__', '__lt__', '__gt__', '__le__', '__ge__'):
1898            error(pos, "Special method %s must be implemented via __richcmp__" % name)
1899        if name == "__new__":
1900            error(pos, "__new__ method of extension type will change semantics "
1901                "in a future version of Pyrex and Cython. Use __cinit__ instead.")
1902        entry = self.declare_var(name, py_object_type, pos,
1903                                 visibility='extern')
1904        special_sig = get_special_method_signature(name)
1905        if special_sig:
1906            # Special methods get put in the method table with a particular
1907            # signature declared in advance.
1908            entry.signature = special_sig
1909            entry.is_special = 1
1910        else:
1911            entry.signature = pymethod_signature
1912            entry.is_special = 0
1913
1914        self.pyfunc_entries.append(entry)
1915        return entry
1916
1917    def lookup_here(self, name):
1918        if name == "__new__":
1919            name = EncodedString("__cinit__")
1920        entry = ClassScope.lookup_here(self, name)
1921        if entry and entry.is_builtin_cmethod:
1922            if not self.parent_type.is_builtin_type:
1923                # For subtypes of builtin types, we can only return
1924                # optimised C methods if the type if final.
1925                # Otherwise, subtypes may choose to override the
1926                # method, but the optimisation would prevent the
1927                # subtype method from being called.
1928                if not self.parent_type.is_final_type:
1929                    return None
1930        return entry
1931
1932    def declare_cfunction(self, name, type, pos,
1933                          cname = None, visibility = 'private', api = 0, in_pxd = 0,
1934                          defining = 0, modifiers = (), utility_code = None):
1935        if get_special_method_signature(name) and not self.parent_type.is_builtin_type:
1936            error(pos, "Special methods must be declared with 'def', not 'cdef'")
1937        args = type.args
1938        if not args:
1939            error(pos, "C method has no self argument")
1940        elif not self.parent_type.assignable_from(args[0].type):
1941            error(pos, "Self argument (%s) of C method '%s' does not match parent type (%s)" %
1942                  (args[0].type, name, self.parent_type))
1943        entry = self.lookup_here(name)
1944        if cname is None:
1945            cname = c_safe_identifier(name)
1946        if entry:
1947            if not entry.is_cfunction:
1948                warning(pos, "'%s' redeclared  " % name, 0)
1949            else:
1950                if defining and entry.func_cname:
1951                    error(pos, "'%s' already defined" % name)
1952                #print "CClassScope.declare_cfunction: checking signature" ###
1953                if entry.is_final_cmethod and entry.is_inherited:
1954                    error(pos, "Overriding final methods is not allowed")
1955                elif type.same_c_signature_as(entry.type, as_cmethod = 1) and type.nogil == entry.type.nogil:
1956                    pass
1957                elif type.compatible_signature_with(entry.type, as_cmethod = 1) and type.nogil == entry.type.nogil:
1958                    entry = self.add_cfunction(name, type, pos, cname, visibility='ignore', modifiers=modifiers)
1959                    defining = 1
1960                else:
1961                    error(pos, "Signature not compatible with previous declaration")
1962                    error(entry.pos, "Previous declaration is here")
1963        else:
1964            if self.defined:
1965                error(pos,
1966                    "C method '%s' not previously declared in definition part of"
1967                    " extension type" % name)
1968            entry = self.add_cfunction(name, type, pos, cname,
1969                                       visibility, modifiers)
1970        if defining:
1971            entry.func_cname = self.mangle(Naming.func_prefix, name)
1972        entry.utility_code = utility_code
1973        type.entry = entry
1974
1975        if u'inline' in modifiers:
1976            entry.is_inline_cmethod = True
1977
1978        if (self.parent_type.is_final_type or entry.is_inline_cmethod or
1979            self.directives.get('final')):
1980            entry.is_final_cmethod = True
1981            entry.final_func_cname = entry.func_cname
1982
1983        return entry
1984
1985    def add_cfunction(self, name, type, pos, cname, visibility, modifiers):
1986        # Add a cfunction entry without giving it a func_cname.
1987        prev_entry = self.lookup_here(name)
1988        entry = ClassScope.add_cfunction(self, name, type, pos, cname,
1989                                         visibility, modifiers)
1990        entry.is_cmethod = 1
1991        entry.prev_entry = prev_entry
1992        return entry
1993
1994    def declare_builtin_cfunction(self, name, type, cname, utility_code = None):
1995        # overridden methods of builtin types still have their Python
1996        # equivalent that must be accessible to support bound methods
1997        name = EncodedString(name)
1998        entry = self.declare_cfunction(name, type, None, cname, visibility='extern',
1999                                       utility_code = utility_code)
2000        var_entry = Entry(name, name, py_object_type)
2001        var_entry.is_variable = 1
2002        var_entry.is_builtin = 1
2003        var_entry.utility_code = utility_code
2004        entry.as_variable = var_entry
2005        return entry
2006
2007    def declare_property(self, name, doc, pos):
2008        entry = self.lookup_here(name)
2009        if entry is None:
2010            entry = self.declare(name, name, py_object_type, pos, 'private')
2011        entry.is_property = 1
2012        entry.doc = doc
2013        entry.scope = PropertyScope(name,
2014            outer_scope = self.global_scope(), parent_scope = self)
2015        entry.scope.parent_type = self.parent_type
2016        self.property_entries.append(entry)
2017        return entry
2018
2019    def declare_inherited_c_attributes(self, base_scope):
2020        # Declare entries for all the C attributes of an
2021        # inherited type, with cnames modified appropriately
2022        # to work with this type.
2023        def adapt(cname):
2024            return "%s.%s" % (Naming.obj_base_cname, base_entry.cname)
2025
2026        entries = base_scope.inherited_var_entries + base_scope.var_entries
2027        for base_entry in entries:
2028            entry = self.declare(
2029                base_entry.name, adapt(base_entry.cname),
2030                base_entry.type, None, 'private')
2031            entry.is_variable = 1
2032            self.inherited_var_entries.append(entry)
2033
2034        # If the class defined in a pxd, specific entries have not been added.
2035        # Ensure now that the parent (base) scope has specific entries
2036        # Iterate over a copy as get_all_specialized_function_types() will mutate
2037        for base_entry in base_scope.cfunc_entries[:]:
2038            if base_entry.type.is_fused:
2039                base_entry.type.get_all_specialized_function_types()
2040
2041        for base_entry in base_scope.cfunc_entries:
2042            cname = base_entry.cname
2043            var_entry = base_entry.as_variable
2044            is_builtin = var_entry and var_entry.is_builtin
2045            if not is_builtin:
2046                cname = adapt(cname)
2047            entry = self.add_cfunction(base_entry.name, base_entry.type,
2048                                       base_entry.pos, cname,
2049                                       base_entry.visibility, base_entry.func_modifiers)
2050            entry.is_inherited = 1
2051            if base_entry.is_final_cmethod:
2052                entry.is_final_cmethod = True
2053                entry.is_inline_cmethod = base_entry.is_inline_cmethod
2054                if (self.parent_scope == base_scope.parent_scope or
2055                        entry.is_inline_cmethod):
2056                    entry.final_func_cname = base_entry.final_func_cname
2057            if is_builtin:
2058                entry.is_builtin_cmethod = True
2059                entry.as_variable = var_entry
2060            if base_entry.utility_code:
2061                entry.utility_code = base_entry.utility_code
2062
2063
2064class CppClassScope(Scope):
2065    #  Namespace of a C++ class.
2066
2067    is_cpp_class_scope = 1
2068
2069    default_constructor = None
2070    type = None
2071
2072    def __init__(self, name, outer_scope, templates=None):
2073        Scope.__init__(self, name, outer_scope, None)
2074        self.directives = outer_scope.directives
2075        self.inherited_var_entries = []
2076        if templates is not None:
2077            for T in templates:
2078                template_entry = self.declare(
2079                    T, T, PyrexTypes.TemplatePlaceholderType(T), None, 'extern')
2080                template_entry.is_type = 1
2081
2082    def declare_var(self, name, type, pos,
2083                    cname = None, visibility = 'extern',
2084                    api = 0, in_pxd = 0, is_cdef = 0,
2085                    allow_pyobject = 0, defining = 0):
2086        # Add an entry for an attribute.
2087        if not cname:
2088            cname = name
2089        entry = self.lookup_here(name)
2090        if defining and entry is not None:
2091            if not entry.type.same_as(type):
2092                error(pos, "Function signature does not match previous declaration")
2093        else:
2094            entry = self.declare(name, cname, type, pos, visibility)
2095        entry.is_variable = 1
2096        if type.is_cfunction and self.type:
2097            entry.func_cname = "%s::%s" % (self.type.declaration_code(""), cname)
2098        if name != "this" and (defining or name != "<init>"):
2099            self.var_entries.append(entry)
2100        if type.is_pyobject and not allow_pyobject:
2101            error(pos,
2102                "C++ class member cannot be a Python object")
2103        return entry
2104
2105    def check_base_default_constructor(self, pos):
2106        # Look for default constructors in all base classes.
2107        if self.default_constructor is None:
2108            entry = self.lookup(self.name)
2109            if not entry.type.base_classes:
2110                self.default_constructor = True
2111                return
2112            for base_class in entry.type.base_classes:
2113                if base_class is PyrexTypes.error_type:
2114                    continue
2115                temp_entry = base_class.scope.lookup_here("<init>")
2116                found = False
2117                if temp_entry is None:
2118                    continue
2119                for alternative in temp_entry.all_alternatives():
2120                    type = alternative.type
2121                    if type.is_ptr:
2122                        type = type.base_type
2123                    if not type.args:
2124                        found = True
2125                        break
2126                if not found:
2127                    self.default_constructor = temp_entry.scope.name
2128                    error(pos, "no matching function for call to " \
2129                            "%s::%s()" % (temp_entry.scope.name, temp_entry.scope.name))
2130        elif not self.default_constructor:
2131            error(pos, "no matching function for call to %s::%s()" %
2132                  (self.default_constructor, self.default_constructor))
2133
2134    def declare_cfunction(self, name, type, pos,
2135                          cname = None, visibility = 'extern', api = 0, in_pxd = 0,
2136                          defining = 0, modifiers = (), utility_code = None):
2137        if name in (self.name.split('::')[-1], '__init__') and cname is None:
2138            self.check_base_default_constructor(pos)
2139            cname = self.type.cname
2140            name = '<init>'
2141            type.return_type = PyrexTypes.InvisibleVoidType()
2142        elif name == '__dealloc__' and cname is None:
2143            cname = "~%s" % self.type.cname
2144            name = '<del>'
2145            type.return_type = PyrexTypes.InvisibleVoidType()
2146        prev_entry = self.lookup_here(name)
2147        entry = self.declare_var(name, type, pos,
2148                                 defining=defining,
2149                                 cname=cname, visibility=visibility)
2150        if prev_entry and not defining:
2151            entry.overloaded_alternatives = prev_entry.all_alternatives()
2152        entry.utility_code = utility_code
2153        type.entry = entry
2154        return entry
2155
2156    def declare_inherited_cpp_attributes(self, base_scope):
2157        # Declare entries for all the C++ attributes of an
2158        # inherited type, with cnames modified appropriately
2159        # to work with this type.
2160        for base_entry in \
2161            base_scope.inherited_var_entries + base_scope.var_entries:
2162                #contructor is not inherited
2163                if base_entry.name == "<init>":
2164                    continue
2165                #print base_entry.name, self.entries
2166                if base_entry.name in self.entries:
2167                    base_entry.name    # FIXME: is there anything to do in this case?
2168                entry = self.declare(base_entry.name, base_entry.cname,
2169                    base_entry.type, None, 'extern')
2170                entry.is_variable = 1
2171                self.inherited_var_entries.append(entry)
2172        for base_entry in base_scope.cfunc_entries:
2173            entry = self.declare_cfunction(base_entry.name, base_entry.type,
2174                                           base_entry.pos, base_entry.cname,
2175                                           base_entry.visibility, 0,
2176                                           modifiers = base_entry.func_modifiers,
2177                                           utility_code = base_entry.utility_code)
2178            entry.is_inherited = 1
2179
2180    def specialize(self, values):
2181        scope = CppClassScope(self.name, self.outer_scope)
2182        for entry in self.entries.values():
2183            if entry.is_type:
2184                scope.declare_type(entry.name,
2185                                   entry.type.specialize(values),
2186                                   entry.pos,
2187                                   entry.cname,
2188                                   template=1)
2189            elif entry.type.is_cfunction:
2190                for e in entry.all_alternatives():
2191                    scope.declare_cfunction(e.name,
2192                                            e.type.specialize(values),
2193                                            e.pos,
2194                                            e.cname,
2195                                            utility_code = e.utility_code)
2196            else:
2197                scope.declare_var(entry.name,
2198                                  entry.type.specialize(values),
2199                                  entry.pos,
2200                                  entry.cname,
2201                                  entry.visibility)
2202
2203        return scope
2204
2205
2206class PropertyScope(Scope):
2207    #  Scope holding the __get__, __set__ and __del__ methods for
2208    #  a property of an extension type.
2209    #
2210    #  parent_type   PyExtensionType   The type to which the property belongs
2211
2212    is_property_scope = 1
2213
2214    def declare_pyfunction(self, name, pos, allow_redefine=False):
2215        # Add an entry for a method.
2216        signature = get_property_accessor_signature(name)
2217        if signature:
2218            entry = self.declare(name, name, py_object_type, pos, 'private')
2219            entry.is_special = 1
2220            entry.signature = signature
2221            return entry
2222        else:
2223            error(pos, "Only __get__, __set__ and __del__ methods allowed "
2224                "in a property declaration")
2225            return None
2226
2227
2228class CConstScope(Scope):
2229
2230    def __init__(self, const_base_type_scope):
2231        Scope.__init__(
2232            self,
2233            'const_' + const_base_type_scope.name,
2234            const_base_type_scope.outer_scope,
2235            const_base_type_scope.parent_scope)
2236        self.const_base_type_scope = const_base_type_scope
2237
2238    def lookup_here(self, name):
2239        entry = self.const_base_type_scope.lookup_here(name)
2240        if entry is not None:
2241            entry = copy.copy(entry)
2242            entry.type = PyrexTypes.c_const_type(entry.type)
2243            return entry
2244
2245class TemplateScope(Scope):
2246    def __init__(self, name, outer_scope):
2247        Scope.__init__(self, name, outer_scope, None)
2248        self.directives = outer_scope.directives
2249