# If this node can be interpreted as a reference to a
# cimported module, return its scope, else None.
return None
+
+ def analyse_as_type(self, env):
+ # If this node can be interpreted as a reference to a
+ # type, return that type, else None.
+ return None
def analyse_as_extension_type(self, env):
# If this node can be interpreted as a reference to an
if entry and entry.as_module:
return entry.as_module
return None
+
+ def analyse_as_type(self, env):
+ entry = self.entry
+ if not entry:
+ entry = env.lookup(self.name)
+ if entry and entry.is_type:
+ return entry.type
+ else:
+ return None
def analyse_as_extension_type(self, env):
# Try to interpret this as a reference to an extension type.
def analyse_target_declaration(self, env):
pass
+
+ def analyse_as_type(self, env):
+ base_type = self.base.analyse_as_type(env)
+ if base_type and not base_type.is_pyobject:
+ return PyrexTypes.CArrayType(base_type, int(self.index.compile_time_value(env)))
+ return None
def analyse_types(self, env):
self.analyse_base_and_index_types(env, getting = 1)
self.mutate_into_name_node(env, ubcm_entry, None)
return 1
return 0
+
+ def analyse_as_type(self, env):
+ module_scope = self.obj.analyse_as_module(env)
+ if module_scope:
+ entry = module_scope.lookup_here(self.attribute)
+ if entry and entry.is_type:
+ return entry.type
+ return None
def analyse_as_extension_type(self, env):
# Try to interpret this as a reference to an extension type
class SizeofNode(ExprNode):
# Abstract base class for sizeof(x) expression nodes.
+
+ type = PyrexTypes.c_int_type
def check_const(self):
pass
def analyse_types(self, env):
# we may have incorrectly interpreted a dotted name as a type rather than an attribute
# this could be better handled by more uniformly treating types as runtime-available objects
- if self.base_type.module_path:
+ if self.base_type.module_path and 0:
path = self.base_type.module_path
obj = env.lookup(path[0])
if obj.as_module is None:
base_type = self.base_type.analyse(env)
_, arg_type = self.declarator.analyse(base_type, env)
self.arg_type = arg_type
+ self.check_type()
+
+ def check_type(self):
+ arg_type = self.arg_type
if arg_type.is_pyobject and not arg_type.is_extension_type:
error(self.pos, "Cannot take sizeof Python object")
elif arg_type.is_void:
error(self.pos, "Cannot take sizeof void")
elif not arg_type.is_complete():
error(self.pos, "Cannot take sizeof incomplete type '%s'" % arg_type)
- self.type = PyrexTypes.c_int_type
def calculate_result_code(self):
if self.arg_type.is_extension_type:
subexprs = ['operand']
def analyse_types(self, env):
- self.operand.analyse_types(env)
- self.type = PyrexTypes.c_int_type
+ # We may actually be looking at a type rather than a variable...
+ # If we are, traditional analysis would fail...
+ operand_as_type = self.operand.analyse_as_type(env)
+ if operand_as_type:
+ self.arg_type = operand_as_type
+ self.__class__ = SizeofTypeNode
+ self.check_type()
+ else:
+ self.operand.analyse_types(env)
def calculate_result_code(self):
return "(sizeof(%s))" % self.operand.result()
pos = s.position()
s.next()
s.expect('(')
- if looking_at_type(s) or looking_at_dotted_name(s):
+ # Here we decide if we are looking at an expression or type
+ # If it is actually a type, but parsable as an expression,
+ # we treat it as an expression here.
+ if looking_at_type(s):
base_type = p_c_base_type(s)
declarator = p_c_declarator(s, empty = 1)
node = ExprNodes.SizeofTypeNode(pos,
elif kind == 'cimport':
for (name_pos, name, as_name, kind) in imported_names:
local_name = as_name or name
- s.add_type_name(local_name)
+ if local_name == "*" and False:
+ print s.__dict__.keys()
+ module = s.context.find_module(dotted_name)
+ for type in module.type_entries:
+ s.add_type_name(type.name)
+ else:
+ s.add_type_name(local_name)
return Nodes.FromCImportStatNode(pos,
module_name = dotted_name,
imported_names = imported_names)
s.next()
else:
name = 'int'
- elif s.looking_at_type_name():
+ elif looking_at_dotted_name(s):
+ #print "p_c_simple_base_type: looking_at_type_name at", s.position()
+ name = s.systring
+ s.next()
+ while s.sy == '.':
+ module_path.append(name)
+ s.next()
+ name = p_ident(s)
+ elif s.looking_at_type_name(): # looking_at_type(s):
name = s.systring
s.next()
if nonempty and s.sy != 'IDENT':
elif s.sy not in ('*', '**', '['):
s.put_back('IDENT', name)
name = None
- elif looking_at_dotted_name(s):
- #print "p_c_simple_base_type: looking_at_type_name at", s.position()
- name = s.systring
- s.next()
- while s.sy == '.':
- module_path.append(name)
- s.next()
- name = p_ident(s)
else:
#print "p_c_simple_base_type: not looking at type at", s.position()
name = None
return result
+def looking_at_possible_type(s):
+ return s.sy == 'IDENT' and not s.systring in calling_convention_words
+# return looking_at_base_type(s) or s.looking_at_type_name()
+
def looking_at_type(s):
- return looking_at_base_type(s) or s.looking_at_type_name()
+ if s.systring in base_type_start_words:
+ return True
+ elif s.sy == 'IDENT':
+ is_type = False
+ name = s.systring
+ dotted_path = []
+ s.next()
+ while s.sy == '.':
+ s.next()
+ dotted_path.append(s.systring)
+ s.expect('IDENT')
+ saved = s.sy, s.systring
+ if s.sy == '*' or s.sy == '**':
+ s.next()
+ is_type = s.sy == ')'
+ s.put_back(*saved)
+ elif s.sy == '(':
+ s.next()
+ is_type = s.sy == '*'
+ s.put_back(*saved)
+ elif s.sy == '[':
+ s.next()
+ is_type = s.sy == ']'
+ s.put_back(*saved)
+ elif s.sy == 'IDENT':
+ is_type = True
+ dotted_path.reverse()
+ for p in dotted_path:
+ s.put_back('IDENT', p)
+ s.put_back('.', '.')
+ s.put_back('IDENT', name)
+ return is_type
+ else:
+ return False
def looking_at_base_type(s):
#print "looking_at_base_type?", s.sy, s.systring, s.position()
return result
else:
return 0
-
+
basic_c_type_names = ("void", "char", "int", "float", "double", "Py_ssize_t", "bint")
sign_and_longness_words = ("short", "long", "signed", "unsigned")
pos = s.position()
if s.sy == '(':
s.next()
- if s.sy == ')' or looking_at_type(s):
+ if s.sy == ')' or looking_at_possible_type(s):
base = Nodes.CNameDeclaratorNode(pos, name = EncodedString(u""), cname = None)
result = p_c_func_declarator(s, pos, ctx, base, cmethod_flag)
else: