From: Daniel Dunbar Date: Tue, 13 Jan 2009 18:51:26 +0000 (+0000) Subject: ccc: Allow internal tool chain specific argument translation. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=11672ec82f406fabfb349efea0c8c0cc2de6b1d9;p=clang ccc: Allow internal tool chain specific argument translation. - Pulled -Xarch processing into this. - Get rid of manual creation of forwarding arg array. - Use Darwin/CC1 instead of generic GCC cc1 on X86. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62172 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/tools/ccc/ccclib/Arguments.py b/tools/ccc/ccclib/Arguments.py index 127af2460c..a8a808bd4d 100644 --- a/tools/ccc/ccclib/Arguments.py +++ b/tools/ccc/ccclib/Arguments.py @@ -34,6 +34,18 @@ class Option(object): return '<%s name=%r>' % (self.__class__.__name__, self.name) + def forwardToGCC(self): + # FIXME: Get rid of this hack. + if self.name == '': + return False + + if self.isLinkerInput: + return False + + return self.name not in ('-E', '-S', '-c', + '-arch', '-fsyntax-only', '-combine', '-x', + '-###') + class OptionGroup(Option): """OptionGroup - A fake option class used to group options so that the driver can efficiently refer to an entire set of options.""" @@ -268,16 +280,15 @@ class InputIndex: def __repr__(self): return 'InputIndex(%d, %d)' % (self.sourceId, self.pos) -class ArgList: - """ArgList - Collect an input argument vector along with a set of parsed Args - and supporting information.""" +class ArgList(object): + """ArgList - Collect an input argument vector along with a set of + parsed Args and supporting information.""" def __init__(self, parser, argv): self.parser = parser self.argv = list(argv) self.syntheticArgv = [] self.lastArgs = {} - self.lastGroupArgs = {} self.args = [] def getArgs(self, option): @@ -418,6 +429,15 @@ class ArgList: def getJoinedValue(self, arg): return arg.getJoinedValue(self) +class DerivedArgList(ArgList): + def __init__(self, args): + super(DerivedArgList, self).__init__(args.parser, args.argv) + self.parser = args.parser + self.argv = args.argv + self.syntheticArgv = args.syntheticArgv + self.lastArgs = {} + self.args = [] + ### class OptionParser: diff --git a/tools/ccc/ccclib/Driver.py b/tools/ccc/ccclib/Driver.py index 75f48da886..310607c1da 100644 --- a/tools/ccc/ccclib/Driver.py +++ b/tools/ccc/ccclib/Driver.py @@ -538,25 +538,6 @@ class Driver(object): hasTraditionalCPP = args.getLastArg(self.parser.traditionalCPPOption) hasPipe = args.getLastArg(self.parser.pipeOption) - # FIXME: forward will die, this isn't really how things are - # done, instead everything comes from the arglist. For this we - # need a DerivedArgList for handling -Xarch, and some way to - # still figure out what to forward to the generic gcc tool. - forward = [] - for a in args: - if a.opt is self.parser.inputOption: - pass - - # FIXME: Needs to be part of option. - elif (a.opt.name in ('-E', '-S', '-c', - '-arch', '-fsyntax-only', '-combine', '-x', - '-###') or - a.opt.isLinkerInput): - pass - - else: - forward.append(a) - # We claim things here so that options for which we silently allow # override only ever claim the used option. if hasPipe: @@ -587,32 +568,20 @@ class Driver(object): def isOriginalInput(self): return self.source is self.baseInput - def createJobs(tc, phase, forwardArgs, - canAcceptPipe=False, atTopLevel=False, arch=None): + def createJobs(tc, phase, + canAcceptPipe=False, atTopLevel=False, arch=None, + tcArgs=None): if isinstance(phase, Phases.InputAction): return InputInfo(phase.filename, phase.type, phase.filename) elif isinstance(phase, Phases.BindArchAction): archName = args.getValue(phase.arch) tc = self.hostInfo.getToolChainForArch(archName) - filteredArgs = [] - for arg in forwardArgs: - if arg.opt is self.parser.archOption: - if arg is phase.arch: - filteredArgs.append(arg) - elif arg.opt is self.parser.XarchOption: - # FIXME: gcc-dd has another conditional for passing - # through, when the arch conditional array has an empty - # string. Why? - if args.getJoinedValue(arg) == archName: - # FIXME: This is wrong, we don't want a - # unknown arg we want an actual parsed - # version of this arg. - filteredArgs.append(args.makeUnknownArg(args.getSeparateValue(arg))) - else: - filteredArgs.append(arg) - - return createJobs(tc, phase.inputs[0], filteredArgs, - canAcceptPipe, atTopLevel, phase.arch) + return createJobs(tc, phase.inputs[0], + canAcceptPipe, atTopLevel, phase.arch, + tcArgs=None) + + if tcArgs is None: + tcArgs = tc.translateArgs(args, arch) assert isinstance(phase, Phases.JobAction) tool = tc.selectTool(phase) @@ -633,7 +602,7 @@ class Driver(object): # Only try to use pipes when exactly one input. canAcceptPipe = len(inputList) == 1 and tool.acceptsPipedInput() - inputs = [createJobs(tc, p, forwardArgs, canAcceptPipe, False, arch) + inputs = [createJobs(tc, p, canAcceptPipe, False, arch, tcArgs) for p in inputList] # Determine if we should output to a pipe. @@ -693,7 +662,7 @@ class Driver(object): self.parser.oOption) tool.constructJob(phase, arch, jobList, inputs, output, phase.type, - forwardArgs, args) + tcArgs) return InputInfo(output, phase.type, baseInput) @@ -704,7 +673,7 @@ class Driver(object): raise ValueError,"Cannot specify -o when generating multiple files." for phase in phases: - createJobs(self.toolChain, phase, forward, + createJobs(self.toolChain, phase, canAcceptPipe=True, atTopLevel=True) return jobs diff --git a/tools/ccc/ccclib/ToolChain.py b/tools/ccc/ccclib/ToolChain.py index 698b1bfecc..07ac926af1 100644 --- a/tools/ccc/ccclib/ToolChain.py +++ b/tools/ccc/ccclib/ToolChain.py @@ -1,3 +1,4 @@ +import Arguments import Phases import Tools @@ -14,6 +15,32 @@ class ToolChain(object): some particular action.""" abstract + def translateArgs(self, args, arch): + """translateArgs - Callback to allow argument translation for + an entire toolchain.""" + + # FIXME: Would be nice to move arch handling out of generic + # code. + if arch: + archName = args.getValue(arch) + al = Arguments.DerivedArgList(args) + for arg in args.args: + if arg.opt is args.parser.archOption: + if arg is arch: + al.append(arg) + elif arg.opt is args.parser.XarchOption: + if args.getJoinedValue(arg) == archName: + # FIXME: Fix this. + arg = args.parser.lookupOptForArg(Arguments.InputIndex(0, arg.index.pos + 1), + args.getSeparateValue(arg), + iter([])) + al.append(arg) + else: + al.append(arg) + return al + else: + return args + class Darwin_X86_ToolChain(ToolChain): def __init__(self, driver, darwinVersion, gccVersion): super(Darwin_X86_ToolChain, self).__init__(driver) @@ -24,7 +51,7 @@ class Darwin_X86_ToolChain(ToolChain): self.toolMap = { Phases.PreprocessPhase : Tools.GCC_PreprocessTool(), - Phases.CompilePhase : Tools.GCC_CompileTool(), + Phases.CompilePhase : Tools.Darwin_X86_CompileTool(self), Phases.PrecompilePhase : Tools.GCC_PrecompileTool(), Phases.AssemblePhase : Tools.Darwin_AssembleTool(self), Phases.LinkPhase : Tools.Darwin_X86_LinkTool(self), diff --git a/tools/ccc/ccclib/Tools.py b/tools/ccc/ccclib/Tools.py index 989b472b72..1713a144ab 100644 --- a/tools/ccc/ccclib/Tools.py +++ b/tools/ccc/ccclib/Tools.py @@ -25,9 +25,14 @@ class Tool(object): class GCC_Common_Tool(Tool): def constructJob(self, phase, arch, jobs, inputs, - output, outputType, args, arglist, + output, outputType, arglist, extraArgs): - cmd_args = sum(map(arglist.render, args),[]) + extraArgs + cmd_args = [] + for arg in arglist.args: + if arg.opt.forwardToGCC(): + cmd_args.extend(arglist.render(arg)) + + cmd_args.extend(extraArgs) if arch: cmd_args.extend(arglist.render(arch)) if isinstance(output, Jobs.PipedJob): @@ -70,9 +75,9 @@ class GCC_PreprocessTool(GCC_Common_Tool): Tool.eFlagsPipedOutput)) def constructJob(self, phase, arch, jobs, inputs, - output, outputType, args, arglist): + output, outputType, arglist): return super(GCC_PreprocessTool, self).constructJob(phase, arch, jobs, inputs, - output, outputType, args, arglist, + output, outputType, arglist, ['-E']) class GCC_CompileTool(GCC_Common_Tool): @@ -83,9 +88,9 @@ class GCC_CompileTool(GCC_Common_Tool): Tool.eFlagsIntegratedCPP)) def constructJob(self, phase, arch, jobs, inputs, - output, outputType, args, arglist): + output, outputType, arglist): return super(GCC_CompileTool, self).constructJob(phase, arch, jobs, inputs, - output, outputType, args, arglist, + output, outputType, arglist, ['-S']) class GCC_PrecompileTool(GCC_Common_Tool): @@ -95,9 +100,9 @@ class GCC_PrecompileTool(GCC_Common_Tool): Tool.eFlagsIntegratedCPP)) def constructJob(self, phase, arch, jobs, inputs, - output, outputType, args, arglist): + output, outputType, arglist): return super(GCC_PrecompileTool, self).constructJob(phase, arch, jobs, inputs, - output, outputType, args, arglist, + output, outputType, arglist, []) class Darwin_AssembleTool(Tool): @@ -107,7 +112,7 @@ class Darwin_AssembleTool(Tool): self.toolChain = toolChain def constructJob(self, phase, arch, jobs, inputs, - output, outputType, args, arglist): + output, outputType, arglist): assert len(inputs) == 1 assert outputType is Types.ObjectType @@ -152,9 +157,9 @@ class GCC_AssembleTool(GCC_Common_Tool): super(GCC_AssembleTool, self).__init__('gcc (as)') def constructJob(self, phase, arch, jobs, inputs, - output, outputType, args, arglist): + output, outputType, arglist): return super(GCC_AssembleTool, self).constructJob(phase, arch, jobs, inputs, - output, outputType, args, arglist, + output, outputType, arglist, ['-c']) class GCC_LinkTool(GCC_Common_Tool): @@ -162,9 +167,9 @@ class GCC_LinkTool(GCC_Common_Tool): super(GCC_LinkTool, self).__init__('gcc (ld)') def constructJob(self, phase, arch, jobs, inputs, - output, outputType, args, arglist): + output, outputType, arglist): return super(GCC_LinkTool, self).constructJob(phase, arch, jobs, inputs, - output, outputType, args, arglist, + output, outputType, arglist, []) class Darwin_X86_CompileTool(Tool): @@ -217,7 +222,7 @@ class Darwin_X86_CompileTool(Tool): # FIXME: Remove mcpu=G4 # FIXME: Remove mcpu=G5 - if (arglist.getLastArg(arglist.parser.gOption) and + if (arglist.getLastArg(arglist.parser.gGroup) and not arglist.getLastArg(arglist.parser.f_noEliminateUnusedDebugSymbolsOption)): cmd_args.append('-feliminate-unused-debug-symbols') @@ -231,7 +236,7 @@ class Darwin_X86_CompileTool(Tool): return os.path.splitext(self.getBaseInputName(inputs, arglist))[0] def constructJob(self, phase, arch, jobs, inputs, - output, outputType, args, arglist): + output, outputType, arglist): inputType = inputs[0].type assert not [i for i in inputs if i.type != inputType] @@ -705,7 +710,7 @@ class Darwin_X86_LinkTool(Tool): arglist.addLastArg(cmd_args, arglist.parser.MachOption) def constructJob(self, phase, arch, jobs, inputs, - output, outputType, args, arglist): + output, outputType, arglist): assert outputType is Types.ImageType # The logic here is derived from gcc's behavior; most of which @@ -896,7 +901,7 @@ class LipoTool(Tool): super(LipoTool, self).__init__('lipo') def constructJob(self, phase, arch, jobs, inputs, - output, outputType, args, arglist): + output, outputType, arglist): assert outputType is Types.ImageType cmd_args = ['-create'] diff --git a/tools/ccc/test/ccc/Xarch.c b/tools/ccc/test/ccc/Xarch.c index 06dae74d47..9c0ebde2db 100644 --- a/tools/ccc/test/ccc/Xarch.c +++ b/tools/ccc/test/ccc/Xarch.c @@ -1,8 +1,8 @@ // RUN: xcc -### -fsyntax-only -Xarch_i386 -Wall -Xarch_ppc -Wunused -arch i386 -arch ppc %s &> %t && // RUN: grep '"-Xarch"' %t | count 0 && // RUN: grep '"-Wall"' %t | count 1 && -// RUN: grep '"-arch" "i386"' %t | count 1 && -// RUN: grep '"-Wall"' %t | grep '"-arch" "i386"' | count 1 && +// RUN: grep 'i686-apple' %t | grep '"-m32"' | count 1 && +// RUN: grep '"-Wall"' %t | grep 'i686-apple' | grep '"-m32"' | count 1 && // RUN: grep '"-Wunused"' %t | count 1 && // RUN: grep '"-arch" "ppc"' %t | count 1 && // RUN: grep '"-Wunused"' %t | grep '"-arch" "ppc"' | count 1