diff options
Diffstat (limited to 'src/mem/slicc/ast')
-rw-r--r-- | src/mem/slicc/ast/FormalParamAST.py | 3 | ||||
-rw-r--r-- | src/mem/slicc/ast/MethodCallExprAST.py | 46 | ||||
-rw-r--r-- | src/mem/slicc/ast/StaticCastAST.py | 54 | ||||
-rw-r--r-- | src/mem/slicc/ast/__init__.py | 1 |
4 files changed, 100 insertions, 4 deletions
diff --git a/src/mem/slicc/ast/FormalParamAST.py b/src/mem/slicc/ast/FormalParamAST.py index b821dc197..c64731196 100644 --- a/src/mem/slicc/ast/FormalParamAST.py +++ b/src/mem/slicc/ast/FormalParamAST.py @@ -29,11 +29,12 @@ from slicc.ast.AST import AST from slicc.symbols import Var class FormalParamAST(AST): - def __init__(self, slicc, type_ast, ident, default = None): + def __init__(self, slicc, type_ast, ident, default = None, pointer = False): super(FormalParamAST, self).__init__(slicc) self.type_ast = type_ast self.ident = ident self.default = default + self.pointer = pointer def __repr__(self): return "[FormalParamAST: %s]" % self.ident diff --git a/src/mem/slicc/ast/MethodCallExprAST.py b/src/mem/slicc/ast/MethodCallExprAST.py index 3f9b250c1..150f391bc 100644 --- a/src/mem/slicc/ast/MethodCallExprAST.py +++ b/src/mem/slicc/ast/MethodCallExprAST.py @@ -68,7 +68,8 @@ class MethodCallExprAST(ExprAST): for actual_type, expected_type in \ zip(paramTypes, obj_type.methods[methodId].param_types): - if actual_type != expected_type: + if actual_type != expected_type and \ + str(actual_type["interface"]) != str(expected_type): self.error("Type mismatch: expected: %s actual: %s", expected_type, actual_type) @@ -97,9 +98,48 @@ class MemberMethodCallExprAST(MethodCallExprAST): methodId = obj_type.methodId(self.proc_name, paramTypes) prefix = "" + implements_interface = False if methodId not in obj_type.methods: - self.error("Invalid method call: Type '%s' does not have a method '%s'", - obj_type, methodId) + # + # The initial method check has failed, but before generating an + # error we must check whether any of the paramTypes implement + # an interface. If so, we must check if the method ids using + # the inherited types exist. + # + # This code is a temporary fix and only checks for the methodId + # where all paramTypes are converted to their inherited type. The + # right way to do this is to replace slicc's simple string + # comparison for determining the correct overloaded method, with a + # more robust param by param check. + # + implemented_paramTypes = [] + for paramType in paramTypes: + implemented_paramType = paramType + if paramType.isInterface: + implements_interface = True + implemented_paramType.abstract_ident = paramType["interface"] + else: + implemented_paramType.abstract_ident = paramType.c_ident + + implemented_paramTypes.append(implemented_paramType) + + if implements_interface: + implementedMethodId = obj_type.methodIdAbstract(self.proc_name, + implemented_paramTypes) + else: + implementedMethodId = "" + + if implementedMethodId not in obj_type.methods: + self.error("Invalid method call: " \ + "Type '%s' does not have a method '%s' nor '%s'", + obj_type, methodId, implementedMethodId) + else: + # + # Replace the methodId with the implementedMethodId found in + # the method list. + # + methodId = implementedMethodId + return_type = obj_type.methods[methodId].return_type if return_type.isInterface: prefix = "static_cast<%s &>" % return_type.c_ident diff --git a/src/mem/slicc/ast/StaticCastAST.py b/src/mem/slicc/ast/StaticCastAST.py new file mode 100644 index 000000000..3a48f398e --- /dev/null +++ b/src/mem/slicc/ast/StaticCastAST.py @@ -0,0 +1,54 @@ +# Copyright (c) 2009 Advanced Micro Devices, Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from slicc.ast.ExprAST import ExprAST + +class StaticCastAST(ExprAST): + def __init__(self, slicc, type_ast, expr_ast): + super(StaticCastAST, self).__init__(slicc) + + self.type_ast = type_ast + self.expr_ast = expr_ast + + def __repr__(self): + return "[StaticCastAST: %r]" % self.expr_ast + + def generate(self, code): + actual_type, ecode = self.expr_ast.inline(True) + code('static_cast<${{self.type_ast.type.c_ident}} &>($ecode)') + + if not "interface" in self.type_ast.type: + self.expr_ast.error("static cast only premitted for those types " \ + "that implement inherit an interface") + + # The interface type should match + if str(actual_type) != str(self.type_ast.type["interface"]): + self.expr_ast.error("static cast miss-match, type is '%s'," \ + "but inherited type is '%s'", + actual_type, self.type_ast.type["interface"]) + + return self.type_ast.type + diff --git a/src/mem/slicc/ast/__init__.py b/src/mem/slicc/ast/__init__.py index de50cbd49..cc5f02b84 100644 --- a/src/mem/slicc/ast/__init__.py +++ b/src/mem/slicc/ast/__init__.py @@ -59,6 +59,7 @@ from slicc.ast.PeekStatementAST import * from slicc.ast.ReturnStatementAST import * from slicc.ast.StatementAST import * from slicc.ast.StatementListAST import * +from slicc.ast.StaticCastAST import * from slicc.ast.TransitionDeclAST import * from slicc.ast.TypeAST import * from slicc.ast.TypeDeclAST import * |