Bug 564086, part d: Emit common code for PFoo into PFoo.h and PFoo.cpp. r=bsmedberg

This commit is contained in:
Chris Jones 2011-06-03 13:33:55 -05:00
parent 2bfe0087e1
commit 79ac480fe7
3 changed files with 83 additions and 42 deletions

View File

@ -97,6 +97,7 @@ $(foreach IPDLDIR,$(IPDLDIRS),$(eval $(ADD_IPDLDIR)))
CPPSRCS = \
$(PROTOCOLS:%.ipdl=%Parent.cpp) \
$(PROTOCOLS:%.ipdl=%Child.cpp) \
$(PROTOCOLS:%.ipdl=%.cpp) \
$(NULL)
GARBAGE += $(CPPSRCS)

View File

@ -110,6 +110,12 @@ class Visitor:
meth.decl.accept(self)
self.visitBlock(meth)
def visitFunctionDecl(self, fun):
self.visitMethodDecl(fun)
def visitFunctionDefn(self, fd):
self.visitMethodDefn(fd)
def visitConstructorDecl(self, ctor):
self.visitMethodDecl(ctor)
@ -509,6 +515,20 @@ class MethodDefn(Block):
Block.__init__(self)
self.decl = decl
class FunctionDecl(MethodDecl):
def __init__(self, name, params=[ ], ret=Type('void'),
static=0, warn_unused=0,
inline=0, force_inline=0,
T=None):
MethodDecl.__init__(self, name, params=params, ret=ret,
static=static, warn_unused=warn_unused,
inline=inline, force_inline=force_inline,
T=T)
class FunctionDefn(MethodDefn):
def __init__(self, decl):
MethodDefn.__init__(self, decl)
class ConstructorDecl(MethodDecl):
def __init__(self, name, params=[ ], explicit=0, force_inline=0):
MethodDecl.__init__(self, name, params=params, ret=None,

View File

@ -55,8 +55,8 @@ lowered form of |tu|'''
pname = tu.protocol.name
pheader = File(pname +'.h')
_GenerateProtocolHeader().lower(tu, pheader)
pheader, pcpp = File(pname +'.h'), File(pname +'.cpp')
_GenerateProtocolCode().lower(tu, pheader, pcpp)
parentheader, parentcpp = File(pname +'Parent.h'), File(pname +'Parent.cpp')
_GenerateProtocolParentCode().lower(
@ -66,7 +66,7 @@ lowered form of |tu|'''
_GenerateProtocolChildCode().lower(
tu, pname+'Child', childheader, childcpp)
return [ pheader, parentheader, childheader ], [ parentcpp, childcpp ]
return [ pheader, parentheader, childheader ], [ pcpp, parentcpp, childcpp ]
##-----------------------------------------------------------------------------
@ -76,6 +76,14 @@ lowered form of |tu|'''
_NULL_ACTOR_ID = ExprLiteral.ZERO
_FREED_ACTOR_ID = ExprLiteral.ONE
_DISCLAIMER = Whitespace('''//
// Automatically generated by ipdlc.
// Edit at your own risk
//
''')
class _struct: pass
def _protocolHeaderName(p, side=''):
@ -1311,46 +1319,59 @@ with some new IPDL/C++ nodes that are tuned for C++ codegen."""
##-----------------------------------------------------------------------------
class _GenerateProtocolHeader(ipdl.ast.Visitor):
'''Creates a header containing code common to both the parent and
child actors.'''
class _GenerateProtocolCode(ipdl.ast.Visitor):
'''Creates code common to both the parent and child actors.'''
def __init__(self):
self.protocol = None # protocol we're generating a class for
self.file = None # File stuff is stuck in
self.hdrfile = None # what will become Protocol.h
self.cppfile = None # what will become Protocol.cpp
self.structUnionDefns = []
self.funcDefns = []
def lower(self, tu, outcxxfile):
def lower(self, tu, cxxHeaderFile, cxxFile):
self.protocol = tu.protocol
self.file = outcxxfile
self.hdrfile = cxxHeaderFile
self.cppfile = cxxFile
tu.accept(self)
def visitTranslationUnit(self, tu):
f = self.file
hf = self.hdrfile
f.addthing(Whitespace('''//
// Automatically generated by the IPDL compiler.
// Edit at your own risk
//
'''))
f.addthings(_includeGuardStart(f))
f.addthing(Whitespace.NL)
hf.addthing(_DISCLAIMER)
hf.addthings(_includeGuardStart(hf))
hf.addthing(Whitespace.NL)
ipdl.ast.Visitor.visitTranslationUnit(self, tu)
f.addthings(self.structUnionDefns)
hf.addthing(Whitespace.NL)
hf.addthings(_includeGuardEnd(hf))
f.addthing(Whitespace.NL)
f.addthings(_includeGuardEnd(f))
cf = self.cppfile
cf.addthings([
_DISCLAIMER,
Whitespace.NL,
CppDirective(
'include',
'"'+ _protocolHeaderName(self.protocol, '') +'.h"'),
Whitespace.NL
])
# construct the namespace into which we'll stick all our defns
ns = Namespace(self.protocol.name)
cf.addthing(_putInNamespaces(ns, self.protocol.namespaces))
ns.addstmts(([ Whitespace.NL]
+ self.funcDefns
+[ Whitespace.NL ]))
cf.addthings(self.structUnionDefns)
def visitCxxInclude(self, inc):
self.file.addthing(CppDirective('include', '"'+ inc.file +'"'))
self.hdrfile.addthing(CppDirective('include', '"'+ inc.file +'"'))
def processStructOrUnionClass(self, su, which, forwarddecls, cls):
clsdecl, methoddefns = _splitClassDeclDefn(cls, inlinedefns=1)
clsdecl, methoddefns = _splitClassDeclDefn(cls)
self.file.addthings(
self.hdrfile.addthings(
[ Whitespace.NL ]
+ forwarddecls
+ [ Whitespace("""
@ -1379,7 +1400,7 @@ child actors.'''
*_generateCxxUnion(ud))
def visitProtocol(self, p):
self.file.addthing(Whitespace("""
self.hdrfile.addthing(Whitespace("""
//-----------------------------------------------------------------------------
// Code common to %sChild and %sParent
//
@ -1387,7 +1408,7 @@ child actors.'''
# construct the namespace into which we'll stick all our decls
ns = Namespace(self.protocol.name)
self.file.addthing(_putInNamespaces(ns, p.namespaces))
self.hdrfile.addthing(_putInNamespaces(ns, p.namespaces))
ns.addstmt(Whitespace.NL)
# state information
@ -1421,7 +1442,9 @@ child actors.'''
msgenum.addId(self.protocol.name +'End')
ns.addstmts([ StmtDecl(Decl(msgenum, '')), Whitespace.NL ])
ns.addstmts([ self.genTransitionFunc(), Whitespace.NL ])
tfDecl, tfDefn = _splitFuncDeclDefn(self.genTransitionFunc())
ns.addstmts([ tfDecl, Whitespace.NL ])
self.funcDefns.append(tfDefn)
typedefs = self.protocol.decl.cxxtypedefs
for md in p.messageDecls:
@ -1466,13 +1489,12 @@ child actors.'''
msgexpr = ExprSelect(triggervar, '.', 'mMsg')
actionexpr = ExprSelect(triggervar, '.', 'mAction')
transitionfunc = MethodDefn(MethodDecl(
transitionfunc = FunctionDefn(FunctionDecl(
'Transition',
params=[ Decl(Type('State'), fromvar.name),
Decl(Type('mozilla::ipc::Trigger'), triggervar.name),
Decl(Type('State', ptr=1), nextvar.name) ],
ret=Type.BOOL,
inline=1))
ret=Type.BOOL))
fromswitch = StmtSwitch(fromvar)
@ -2255,15 +2277,9 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
hf = self.hdrfile
cf = self.cppfile
disclaimer = Whitespace('''//
// Automatically generated by ipdlc.
// Edit at your own risk
//
''')
# make the C++ header
hf.addthings(
[ disclaimer ]
[ _DISCLAIMER ]
+ _includeGuardStart(hf)
+[
Whitespace.NL,
@ -2318,7 +2334,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
# make the .cpp file
cf.addthings([
disclaimer,
_DISCLAIMER,
Whitespace.NL,
CppDirective(
'include',
@ -4684,7 +4700,7 @@ class _GenerateProtocolChildCode(_GenerateProtocolActorCode):
## Utility passes
##
def _splitClassDeclDefn(cls, inlinedefns=0):
def _splitClassDeclDefn(cls):
"""Destructively split |cls| methods into declarations and
definitions (if |not methodDecl.force_inline|). Return classDecl,
methodDefns."""
@ -4692,25 +4708,29 @@ methodDefns."""
for i, stmt in enumerate(cls.stmts):
if isinstance(stmt, MethodDefn) and not stmt.decl.force_inline:
decl, defn = _splitMethodDefn(stmt, cls.name, inlinedefns)
decl, defn = _splitMethodDefn(stmt, cls.name)
cls.stmts[i] = StmtDecl(decl)
defns.addstmts([ defn, Whitespace.NL ])
return cls, defns
def _splitMethodDefn(md, clsname, inlinedefn):
def _splitMethodDefn(md, clsname):
saveddecl = deepcopy(md.decl)
md.decl.name = (clsname +'::'+ md.decl.name)
md.decl.virtual = 0
md.decl.static = 0
md.decl.warn_unused = 0
md.decl.inline = inlinedefn
for param in md.decl.params:
if isinstance(param, Param):
param.default = None
return saveddecl, md
def _splitFuncDeclDefn(fun):
assert not fun.decl.inline
return StmtDecl(fun.decl), fun
# XXX this is tantalizingly similar to _splitClassDeclDefn, but just
# different enough that I don't see the need to define
# _GenerateSkeleton in terms of that