slicc: enable overloading in functions not in classes
authorBrad Beckmann <Brad.Beckmann@amd.com>
Mon, 20 Jul 2015 14:15:18 +0000 (09:15 -0500)
committerBrad Beckmann <Brad.Beckmann@amd.com>
Mon, 20 Jul 2015 14:15:18 +0000 (09:15 -0500)
For many years the slicc symbol table has supported overloaded functions in
external classes.  This patch extends that support to functions that are not
part of classes (a.k.a. no parent).  For example, this support allows slicc
to understand that mapAddressToRange is overloaded and the NodeID is an
optional parameter.

src/mem/protocol/RubySlicc_ComponentMapping.sm
src/mem/slicc/ast/EnumDeclAST.py
src/mem/slicc/ast/FuncCallExprAST.py
src/mem/slicc/ast/FuncDeclAST.py
src/mem/slicc/ast/InPortDeclAST.py
src/mem/slicc/ast/StateDeclAST.py
src/mem/slicc/symbols/Func.py
src/mem/slicc/symbols/Transition.py

index 37b2c3ef4ef83efc35e9dc886a212c34bf58d136..afb758b6812549ea692c8397ae17423eeefac7ac 100644 (file)
@@ -30,6 +30,8 @@
 // Mapping functions
 
 int machineCount(MachineType machType);
+MachineID mapAddressToRange(Address addr, MachineType type,
+                            int low, int high);
 MachineID mapAddressToRange(Address addr, MachineType type,
                             int low, int high, NodeID n);
 NetDest broadcast(MachineType type);
index acddcb91f4aa75a7470174b77687362e58ef9b77..d97c134831d6f1515f666bbb3e23e4e7f6ab3690 100644 (file)
@@ -65,7 +65,8 @@ class EnumDeclAST(DeclAST):
         func_id = "%s_to_string" % t.c_ident
 
         pairs = { "external" : "yes" }
-        func = Func(self.symtab, func_id, self.location,
+        func = Func(self.symtab, func_id + "_" + t.c_ident,
+                    func_id, self.location,
                     self.symtab.find("std::string", Type), [ t ], [], "",
                     pairs)
         self.symtab.newSymbol(func)
index 8aebad336f6464a5d6c33d81892b5f0dc671f808..9336a22977ee232178652ec4e0cbe46afd50a2c2 100644 (file)
@@ -80,12 +80,18 @@ class FuncCallExprAST(ExprAST):
             code("APPEND_TRANSITION_COMMENT($0)", self.exprs[0].inline())
             return self.symtab.find("void", Type)
 
+        func_name_args = self.proc_name
+
+        for expr in self.exprs:
+            actual_type,param_code = expr.inline(True)
+            func_name_args += "_" + str(actual_type.ident)
+
         # Look up the function in the symbol table
-        func = self.symtab.find(self.proc_name, Func)
+        func = self.symtab.find(func_name_args, Func)
 
         # Check the types and get the code for the parameters
         if func is None:
-            self.error("Unrecognized function name: '%s'", self.proc_name)
+            self.error("Unrecognized function name: '%s'", func_name_args)
 
         if len(self.exprs) != len(func.param_types):
             self.error("Wrong number of arguments passed to function : '%s'" +\
@@ -193,7 +199,7 @@ if (!(${{cvec[0]}})) {
                     params += str(param_code);
 
             fix = code.nofix()
-            code('(${{func.c_ident}}($params))')
+            code('(${{func.c_name}}($params))')
             code.fix(fix)
 
         return func.return_type
index 052d9f05e7465bed3664a0704ba3416571d3021a..47ae7076ef3ce74f8b6463854d152f7a1dcb6bad 100644 (file)
@@ -74,9 +74,20 @@ class FuncDeclAST(DeclAST):
 
         self.symtab.popFrame()
 
+        func_name_args = self.ident
+
+        if parent is None:
+            for arg in self.formals:
+                from slicc.ast import FormalParamAST
+                if isinstance(arg, FormalParamAST):
+                    arg_name = arg.type_ast.ident
+                else:
+                    arg_name = arg
+                func_name_args += "_" + str(arg_name)
+
         machine = self.state_machine
-        func = Func(self.symtab, self.ident, self.location, return_type,
-                    types, params, str(body), self.pairs)
+        func = Func(self.symtab, func_name_args, self.ident, self.location,
+                    return_type, types, params, str(body), self.pairs)
 
         if parent is not None:
             if not parent.addFunc(func):
index c5a1435eb1da2317b6018aa5677112c5068cc1e8..da7357580d870a702f7bfd7932af54d8f904d3cc 100644 (file)
@@ -85,14 +85,17 @@ class InPortDeclAST(DeclAST):
 
         # Add the trigger method - FIXME, this is a bit dirty
         pairs = { "external" : "yes" }
-        func = Func(self.symtab, "trigger", self.location, void_type,
-                    param_types, [], "", pairs)
+        trigger_func_name = "trigger"
+        for param in param_types:
+            trigger_func_name += "_" + param.ident
+        func = Func(self.symtab, trigger_func_name, "trigger", self.location,
+                    void_type, param_types, [], "", pairs)
         symtab.newSymbol(func)
 
         # Add the stallPort method - this hacks reschedules the controller
         # for stalled messages that don't trigger events
-        func = Func(self.symtab, "stallPort", self.location, void_type, [],
-                    [], "", pairs)
+        func = Func(self.symtab, "stallPort", "stallPort", self.location,
+                    void_type, [], [], "", pairs)
         symtab.newSymbol(func)
 
         param_types = []
index 2bca54d092b187dff6840f18802a16419260c56d..f0a0b97d37f08a5fa4ea36f29acc5f1d3f82f7ca 100644 (file)
@@ -64,7 +64,8 @@ class StateDeclAST(DeclAST):
         func_id = "%s_to_string" % t.c_ident
 
         pairs = { "external" : "yes" }
-        func = Func(self.symtab, func_id, self.location,
+        func = Func(self.symtab, func_id + "_" +
+                    t.ident, func_id, self.location,
                     self.symtab.find("std::string", Type), [ t ], [], "",
                     pairs)
         self.symtab.newSymbol(func)
@@ -73,7 +74,8 @@ class StateDeclAST(DeclAST):
         func_id = "%s_to_permission" % t.c_ident
 
         pairs = { "external" : "yes" }
-        func = Func(self.symtab, func_id, self.location,
+        func = Func(self.symtab, func_id + "_" +
+                    t.ident, func_id, self.location,
                     self.symtab.find("AccessPermission", Type), [ t ], [], "",
                     pairs)
         self.symtab.newSymbol(func)
index a52b6bbcc1ce62fe8e5be236514acf35242178e6..d50d0309fdaa11412509818fe592832235624c9d 100644 (file)
@@ -29,7 +29,7 @@ from slicc.symbols.Symbol import Symbol
 from slicc.symbols.Type import Type
 
 class Func(Symbol):
-    def __init__(self, table, ident, location, return_type, param_types,
+    def __init__(self, table, ident, name, location, return_type, param_types,
                  param_strings, body, pairs):
         super(Func, self).__init__(table, ident, location, pairs)
         self.return_type = return_type
@@ -38,6 +38,7 @@ class Func(Symbol):
         self.body = body
         self.isInternalMachineFunc = False
         self.c_ident = ident
+        self.c_name = name
         self.class_name = ""
 
     def __repr__(self):
@@ -55,7 +56,7 @@ class Func(Symbol):
         elif "return_by_pointer" in self and self.return_type != void_type:
             return_type += "*"
 
-        return "%s %s(%s);" % (return_type, self.c_ident,
+        return "%s %s(%s);" % (return_type, self.c_name,
                                ", ".join(self.param_strings))
 
     def writeCodeFiles(self, path, includes):
@@ -80,7 +81,7 @@ class Func(Symbol):
 
         code('''
 $return_type
-${{self.class_name}}::${{self.c_ident}}($params)
+${{self.class_name}}::${{self.c_name}}($params)
 {
 ${{self.body}}
 }
index 9ecd6c54bd51d7b9f5e09c40fd4906d825a8ba39..856d3f4b000d250cc0290d388ede4e22ea9e9951 100644 (file)
@@ -40,7 +40,7 @@ class Transition(Symbol):
             # check to make sure there is a getNextState function declared
             found = False
             for func in machine.functions:
-                if func.c_ident == 'getNextState':
+                if func.c_ident == 'getNextState_Address':
                     found = True
                     break
             if found == False: