Bug 918651 - part 7 - place includes intelligently in generated IPDL files; r=bent

This is where the magic starts to happen.  We move includes from the base
protocol header (${NAME}.h) to the parent and child headers (${NAME}Parent.h
and ${NAME}Child.h) to follow good include hygiene.

For the base protocol header, we examine the set of types used by struct and
union definitions to determine which headers we need to include.

For parent and child headers, we forward declare what we can and include
appropriate headers otherwise.  For forward-declared types, we include the
appropriate headers in the parent and child source files.
This commit is contained in:
Nathan Froyd 2013-10-01 12:55:42 -04:00
Родитель 91725bfec2
Коммит f478d39678
2 изменённых файлов: 79 добавлений и 7 удалений

Просмотреть файл

@ -1419,7 +1419,37 @@ class _GenerateProtocolCode(ipdl.ast.Visitor):
hf.addthing(Whitespace.NL)
for inc in builtinHeaderIncludes:
self.visitCxxInclude(inc)
self.visitBuiltinCxxInclude(inc)
# Compute the set of includes we need for declared structure/union
# classes for this protocol.
typesToIncludes = {}
for using in tu.using:
typestr = str(using.type.spec)
assert typestr not in typesToIncludes
typesToIncludes[typestr] = using.header
aggregateTypeIncludes = set()
for su in tu.structsAndUnions:
typedeps = _ComputeTypeDeps(su.decl.type, True)
if isinstance(su, ipdl.ast.StructDecl):
for f in su.fields:
f.ipdltype.accept(typedeps)
elif isinstance(su, ipdl.ast.UnionDecl):
for c in su.components:
c.ipdltype.accept(typedeps)
for typename in [t.fromtype.name for t in typedeps.usingTypedefs]:
if typename in typesToIncludes:
aggregateTypeIncludes.add(typesToIncludes[typename])
if len(aggregateTypeIncludes) != 0:
hf.addthing(Whitespace.NL)
hf.addthings([ Whitespace("// Headers for typedefs"), Whitespace.NL ])
for headername in sorted(iter(aggregateTypeIncludes)):
hf.addthing(CppDirective('include', '"' + headername + '"'))
ipdl.ast.Visitor.visitTranslationUnit(self, tu)
if tu.filetype == 'header':
self.cppIncludeHeaders.append(_ipdlhHeaderName(tu))
@ -1446,7 +1476,7 @@ class _GenerateProtocolCode(ipdl.ast.Visitor):
cf.addthings(self.structUnionDefns)
def visitCxxInclude(self, inc):
def visitBuiltinCxxInclude(self, inc):
self.hdrfile.addthing(CppDirective('include', '"'+ inc.file +'"'))
def visitInclude(self, inc):
@ -2456,6 +2486,10 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
self.includedActorTypedefs = [ ]
self.includedActorUsings = [ ]
self.protocolCxxIncludes = [ ]
self.actorForwardDecls = [ ]
self.usingDecls = [ ]
self.externalIncludes = set()
self.nonForwardDeclaredHeaders = set()
def lower(self, tu, clsname, cxxHeaderFile, cxxFile):
self.clsname = clsname
@ -2497,6 +2531,11 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
for inc in tu.includes:
inc.accept(self)
for inc in tu.cxxIncludes:
inc.accept(self)
for using in tu.using:
using.accept(self)
# this generates the actor's full impl in self.cls
tu.protocol.accept(self)
@ -2510,6 +2549,10 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
if stmt.decl.ret and stmt.decl.ret.name == 'Result':
stmt.decl.ret.name = clsdecl.name +'::'+ stmt.decl.ret.name
def setToIncludes(s):
return [ CppDirective('include', '"%s"' % i)
for i in sorted(iter(s)) ]
def makeNamespace(p, file):
if 0 == len(p.namespaces):
return file
@ -2518,6 +2561,16 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
file.addthing(outerns)
return ns
if len(self.nonForwardDeclaredHeaders) != 0:
self.hdrfile.addthings(
[ Whitespace('// Headers for things that cannot be forward declared'),
Whitespace.NL ]
+ setToIncludes(self.nonForwardDeclaredHeaders)
+ [ Whitespace.NL ]
)
self.hdrfile.addthings(self.actorForwardDecls)
self.hdrfile.addthings(self.usingDecls)
hdrns = makeNamespace(self.protocol, self.hdrfile)
hdrns.addstmts([
Whitespace.NL,
@ -2545,8 +2598,8 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
Whitespace.NL,
CppDirective(
'include',
'"'+ _protocolHeaderName(self.protocol, self.side) +'.h"')
])
'"'+ _protocolHeaderName(self.protocol, self.side) +'.h"') ]
+ setToIncludes(self.externalIncludes))
if self.protocol.decl.type.isToplevel():
cf.addthings([
@ -2574,13 +2627,32 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
Whitespace.NL
])
def visitUsingStmt(self, using):
if using.header is None:
return
if using.canBeForwardDeclared():
spec = using.type.spec
self.usingDecls.extend([
_makeForwardDeclForQClass(spec.baseid, spec.quals,
cls=using.isClass(),
struct=using.isStruct()),
Whitespace.NL
])
self.externalIncludes.add(using.header)
else:
self.nonForwardDeclaredHeaders.add(using.header)
def visitCxxInclude(self, inc):
self.nonForwardDeclaredHeaders.add(inc.file)
def visitInclude(self, inc):
ip = inc.tu.protocol
if not ip:
return
self.hdrfile.addthings([
self.actorForwardDecls.extend([
_makeForwardDeclForActor(ip.decl.type, self.side),
Whitespace.NL
])
@ -2648,8 +2720,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
friends.discard(ptype)
for friend in friends:
self.hdrfile.addthings([
Whitespace.NL,
self.actorForwardDecls.extend([
_makeForwardDeclForActor(friend, self.prettyside),
Whitespace.NL
])

Просмотреть файл

@ -43,6 +43,7 @@
#include "BasicLayers.h"
#include "libdisplay/GonkDisplay.h"
#include "pixelflinger/format.h"
#include "mozilla/BasicEvents.h"
#include "HwcComposer2D.h"