self.function.entry = entry
self.function.type = entry.type
func_type = self.function_type()
- # Check function type
- if not func_type.is_cfunction:
- if not func_type.is_error:
- error(self.pos, "Calling non-function type '%s'" %
- func_type)
- self.type = PyrexTypes.error_type
- self.result_code = "<error>"
- return
# Check no. of args
max_nargs = len(func_type.args)
expected_nargs = max_nargs - func_type.optional_arg_count
def c_call_code(self):
func_type = self.function_type()
- if self.args is None or not func_type.is_cfunction:
+ if self.type is PyrexTypes.error_type or not func_type.is_cfunction:
return "<error>"
formal_args = func_type.args
arg_list_code = []
self.type = py_object_type
self.gil_check(env)
self.is_temp = 1
- elif self.is_cpp_operation:
- self.analyse_cpp_operation
+ elif self.is_cpp_operation():
+ self.analyse_cpp_operation(env)
else:
self.analyse_c_operation(env)
if self == other_type:
return 1
elif self.template_type == other_type.template_type:
+ if self.templates == other_type.templates:
+ return 1
for t1, t2 in zip(self.templates, other_type.templates):
if not t1.same_as_resolved_type(t2):
return 0
func_type = func.type
if func_type.is_ptr:
func_type = func_type.base_type
+ # Check function type
+ if not func_type.is_cfunction:
+ if not func_type.is_error:
+ error(pos, "Calling non-function type '%s'" % func_type)
+ return None
# Check no. of args
max_nargs = len(func_type.args)
min_nargs = max_nargs - func_type.optional_arg_count
if actual_nargs < min_nargs \
or (not func_type.has_varargs and actual_nargs > max_nargs):
+ if max_nargs == min_nargs and not func_type.has_varargs:
+ expectation = max_nargs
+ elif actual_nargs < min_nargs:
+ expectation = "at least %s" % min_nargs
+ else:
+ expectation = "at most %s" % max_nargs
+ error_str = "Call with wrong number of arguments (expected %s, got %s)" \
+ % (expectation, actual_nargs)
continue
score = [0,0,0]
- for i in range(len(args)):
+ for i in range(min(len(args), len(func_type.args))):
src_type = args[i].type
dst_type = func_type.args[i].type
if dst_type.assignable_from(src_type):
# This will raise the right error.
return func
else:
- error(pos, "Call with wrong number of arguments (expected %s, got %s)"
- % (expected_str, actual_nargs))
+ error(pos, error_str)
return None
# Create new entry, and add to dictionary if
# name is not None. Reports a warning if already
# declared.
+ if type.is_buffer and not isinstance(self, LocalScope):
+ error(pos, ERR_BUF_LOCALONLY)
if not self.in_cinclude and cname and re.match("^_[_A-Z]+$", cname):
# See http://www.gnu.org/software/libc/manual/html_node/Reserved-Names.html#Reserved-Names
warning(pos, "'%s' is a reserved name in C." % cname, -1)
entries = self.entries
- overloaded = False
if name and name in entries:
if visibility == 'extern':
warning(pos, "'%s' redeclared " % name, 0)
elif visibility != 'ignore':
- overloaded = True
- #error(pos, "'%s' redeclared " % name)
+ error(pos, "'%s' redeclared " % name)
entry = Entry(name, cname, type, pos = pos)
entry.in_cinclude = self.in_cinclude
if name:
entry.qualified_name = self.qualify_name(name)
- if overloaded:
- entries[name].overloaded_alternatives.append(entry)
- #print entries[name].overloaded_alternatives
- else:
- entries[name] = entry
+ entries[name] = entry
entry.scope = self
entry.visibility = visibility
return entry
cname = self.mangle(Naming.func_prefix, name)
entry = self.lookup_here(name)
if entry:
- entry.overloaded_alternatives.append(self.add_cfunction(name, type, pos, cname, visibility, modifiers))
if visibility != 'private' and visibility != entry.visibility:
warning(pos, "Function '%s' previously declared as '%s'" % (name, entry.visibility), 1)
if not entry.type.same_as(type):
if visibility == 'extern' and entry.visibility == 'extern':
warning(pos, "Function signature does not match previous declaration", 1)
#entry.type = type
+ entry.overloaded_alternatives.append(
+ self.add_cfunction(name, type, pos, cname, visibility, modifiers))
else:
error(pos, "Function signature does not match previous declaration")
else:
#
return entry
+ def check_for_illegal_incomplete_ctypedef(self, typedef_flag, pos):
+ if typedef_flag and not self.in_cinclude:
+ error(pos, "Forward-referenced type must use 'cdef', not 'ctypedef'")
+
def declare_cpp_class(self, name, scope,
pos, cname = None, base_classes = [],
visibility = 'extern', templates = None):
"C++ class member cannot be a Python object")
return entry
+ def declare_cfunction(self, name, type, pos,
+ cname = None, visibility = 'extern', defining = 0,
+ api = 0, in_pxd = 0, modifiers = ()):
+ entry = self.declare_var(name, type, pos, cname, visibility)
+
def declare_inherited_cpp_attributes(self, base_scope):
# Declare entries for all the C++ attributes of an
# inherited type, with cnames modified appropriately
self.inherited_var_entries.append(entry)
for base_entry in base_scope.cfunc_entries:
entry = self.declare_cfunction(base_entry.name, base_entry.type,
- base_entry.pos, adapt(base_entry.cname),
+ base_entry.pos, base_entry.cname,
base_entry.visibility, base_entry.func_modifiers)
entry.is_inherited = 1
return NULL;
}
""")
+
+#------------------------------------------------------------------------------------
+
+ERR_BUF_LOCALONLY = 'Buffer types only allowed as function local variables'