ccc: Support arguments which behave like linker inputs.

- Support comma joined options which magically turn into multiple
   value arguments (e.g., -Wl,)

 - Split out separate Arg::render routine for when an argument is
   being rendered as an input (as opposed to in its original form).

 - Add option flag for options which should be rendered without the
   option when they are used as an input (e.g., -Xlinker or -o).

 - Support -weak-l..., -weak_framework, and -weak_library.

llvm-svn: 62075
This commit is contained in:
Daniel Dunbar 2009-01-12 03:33:58 +00:00
parent b2c42c648d
commit 02cd7e4070
3 changed files with 80 additions and 23 deletions

View File

@ -1,7 +1,10 @@
class Option(object): class Option(object):
"""Root option class.""" """Root option class."""
def __init__(self, name):
def __init__(self, name, isLinkerInput=False, noOptAsInput=False):
self.name = name self.name = name
self.isLinkerInput = isLinkerInput
self.noOptAsInput = noOptAsInput
def accept(self, index, arg, it): def accept(self, index, arg, it):
"""accept(index, arg, iterator) -> Arg or None """accept(index, arg, iterator) -> Arg or None
@ -49,6 +52,15 @@ class JoinedOption(Option):
if arg.startswith(self.name): if arg.startswith(self.name):
return JoinedValueArg(index, self) return JoinedValueArg(index, self)
class CommaJoinedOption(Option):
"""An option which literally prefixs its argument, but which
conceptually may have an arbitrary number of arguments which are
separated by commas."""
def accept(self, index, arg, it):
if arg.startswith(self.name):
return CommaJoinedValuesArg(index, self)
class SeparateOption(Option): class SeparateOption(Option):
"""An option which is followed by its value.""" """An option which is followed by its value."""
@ -111,7 +123,7 @@ class Arg(object):
assert opt is not None assert opt is not None
self.index = index self.index = index
self.opt = opt self.opt = opt
def __repr__(self): def __repr__(self):
return '<%s index=%r opt=%r>' % (self.__class__.__name__, return '<%s index=%r opt=%r>' % (self.__class__.__name__,
self.index, self.index,
@ -125,6 +137,9 @@ class Arg(object):
assert self.opt assert self.opt
return [self.opt.name] return [self.opt.name]
def renderAsInput(self, args):
return self.render(args)
class ValueArg(Arg): class ValueArg(Arg):
"""ValueArg - An instance of an option which has an argument.""" """ValueArg - An instance of an option which has an argument."""
@ -150,6 +165,11 @@ class JoinedValueArg(ValueArg):
def render(self, args): def render(self, args):
return [self.opt.name + self.getValue(args)] return [self.opt.name + self.getValue(args)]
def renderAsInput(self, args):
if self.opt.noOptAsInput:
return [self.getValue(args)]
return self.render(args)
class SeparateValueArg(ValueArg): class SeparateValueArg(ValueArg):
"""SeparateValueArg - A single value argument where the value """SeparateValueArg - A single value argument where the value
follows the option in the argument vector.""" follows the option in the argument vector."""
@ -160,6 +180,11 @@ class SeparateValueArg(ValueArg):
def render(self, args): def render(self, args):
return [self.opt.name, self.getValue(args)] return [self.opt.name, self.getValue(args)]
def renderAsInput(self, args):
if self.opt.noOptAsInput:
return [self.getValue(args)]
return self.render(args)
class MultipleValuesArg(Arg): class MultipleValuesArg(Arg):
"""MultipleValuesArg - An argument with multiple values which """MultipleValuesArg - An argument with multiple values which
follow the option in the argument vector.""" follow the option in the argument vector."""
@ -173,6 +198,23 @@ class MultipleValuesArg(Arg):
def render(self, args): def render(self, args):
return [self.opt.name] + self.getValues(args) return [self.opt.name] + self.getValues(args)
class CommaJoinedValuesArg(Arg):
"""CommaJoinedValuesArg - An argument with multiple values joined
by commas and joined (suffixed) to the option.
The key point of this arg is that it renders its values into
separate arguments, which allows it to be used as a generic
mechanism for passing arguments through to tools."""
def getValues(self, args):
return args.getInputString(self.index)[len(self.opt.name):].split(',')
def render(self, args):
return [self.opt.name + ','.join(self.getValues(args))]
def renderAsInput(self, args):
return self.getValues(args)
# FIXME: Man, this is lame. It is only used by -Xarch. Maybe easier to # FIXME: Man, this is lame. It is only used by -Xarch. Maybe easier to
# just special case? # just special case?
class JoinedAndSeparateValuesArg(Arg): class JoinedAndSeparateValuesArg(Arg):
@ -299,6 +341,9 @@ class ArgList:
def render(self, arg): def render(self, arg):
return arg.render(self) return arg.render(self)
def renderAsInput(self, arg):
return arg.renderAsInput(self)
def getValue(self, arg): def getValue(self, arg):
return arg.getValue(self) return arg.getValue(self)
@ -367,7 +412,7 @@ class OptionParser:
self.addOption(FlagOption('-v')) self.addOption(FlagOption('-v'))
# Input/output stuff # Input/output stuff
self.oOption = self.addOption(JoinedOrSeparateOption('-o')) self.oOption = self.addOption(JoinedOrSeparateOption('-o', noOptAsInput=True))
self.xOption = self.addOption(JoinedOrSeparateOption('-x')) self.xOption = self.addOption(JoinedOrSeparateOption('-x'))
self.ObjCOption = self.addOption(FlagOption('-ObjC')) self.ObjCOption = self.addOption(FlagOption('-ObjC'))
@ -385,14 +430,14 @@ class OptionParser:
# Blanket pass-through options. # Blanket pass-through options.
self.addOption(JoinedOption('-Wa,')) self.addOption(CommaJoinedOption('-Wa,'))
self.addOption(SeparateOption('-Xassembler')) self.addOption(SeparateOption('-Xassembler'))
self.addOption(JoinedOption('-Wp,')) self.addOption(CommaJoinedOption('-Wp,'))
self.addOption(SeparateOption('-Xpreprocessor')) self.addOption(SeparateOption('-Xpreprocessor'))
self.addOption(JoinedOption('-Wl,')) self.addOption(CommaJoinedOption('-Wl,', isLinkerInput=True))
self.addOption(SeparateOption('-Xlinker')) self.addOption(SeparateOption('-Xlinker', isLinkerInput=True, noOptAsInput=True))
#### ####
# Bring on the random garbage. # Bring on the random garbage.
@ -456,6 +501,9 @@ class OptionParser:
self.addOption(FlagOption('-traditional')) self.addOption(FlagOption('-traditional'))
self.addOption(FlagOption('--traditional')) self.addOption(FlagOption('--traditional'))
self.addOption(FlagOption('-no_dead_strip_inits_and_terms')) self.addOption(FlagOption('-no_dead_strip_inits_and_terms'))
self.addOption(JoinedOption('-weak-l', isLinkerInput=True))
self.addOption(SeparateOption('-weak_framework', isLinkerInput=True))
self.addOption(SeparateOption('-weak_library', isLinkerInput=True))
self.whyloadOption = self.addOption(FlagOption('-whyload')) self.whyloadOption = self.addOption(FlagOption('-whyload'))
self.whatsloadedOption = self.addOption(FlagOption('-whatsloaded')) self.whatsloadedOption = self.addOption(FlagOption('-whatsloaded'))
self.sectalignOption = self.addOption(MultiArgOption('-sectalign', numArgs=3)) self.sectalignOption = self.addOption(MultiArgOption('-sectalign', numArgs=3))
@ -496,10 +544,8 @@ class OptionParser:
self.Zunexported_symbols_listOption = self.addOption(JoinedOrSeparateOption('-Zunexported_symbols_list')) self.Zunexported_symbols_listOption = self.addOption(JoinedOrSeparateOption('-Zunexported_symbols_list'))
self.Zweak_reference_mismatchesOption = self.addOption(JoinedOrSeparateOption('-Zweak_reference_mismatches')) self.Zweak_reference_mismatchesOption = self.addOption(JoinedOrSeparateOption('-Zweak_reference_mismatches'))
# I dunno why these don't end up working when joined. Maybe self.addOption(SeparateOption('-filelist', isLinkerInput=True))
# because of translation? self.addOption(SeparateOption('-framework', isLinkerInput=True))
self.filelistOption = self.addOption(SeparateOption('-filelist'))
self.addOption(SeparateOption('-framework'))
# FIXME: Alias. # FIXME: Alias.
self.addOption(SeparateOption('-install_name')) self.addOption(SeparateOption('-install_name'))
self.Zinstall_nameOption = self.addOption(JoinedOrSeparateOption('-Zinstall_name')) self.Zinstall_nameOption = self.addOption(JoinedOrSeparateOption('-Zinstall_name'))
@ -532,7 +578,7 @@ class OptionParser:
self.addOption(JoinedOrSeparateOption('-U')) self.addOption(JoinedOrSeparateOption('-U'))
self.ZOption = self.addOption(JoinedOrSeparateOption('-Z')) self.ZOption = self.addOption(JoinedOrSeparateOption('-Z'))
self.addOption(JoinedOrSeparateOption('-l')) self.addOption(JoinedOrSeparateOption('-l', isLinkerInput=True))
self.uOption = self.addOption(JoinedOrSeparateOption('-u')) self.uOption = self.addOption(JoinedOrSeparateOption('-u'))
self.tOption = self.addOption(JoinedOrSeparateOption('-t')) self.tOption = self.addOption(JoinedOrSeparateOption('-t'))
self.yOption = self.addOption(JoinedOption('-y')) self.yOption = self.addOption(JoinedOption('-y'))

View File

@ -299,9 +299,8 @@ class Driver(object):
self.claim(inputTypeOpt) self.claim(inputTypeOpt)
klass = inputType klass = inputType
inputs.append((klass, a)) inputs.append((klass, a))
elif a.opt is self.parser.filelistOption: elif a.opt.isLinkerInput:
# Treat as a linker input. Investigate how gcc is # Treat as a linker input.
# handling this.
# #
# FIXME: This might not be good enough. We may # FIXME: This might not be good enough. We may
# need to introduce another type for this case, so # need to introduce another type for this case, so
@ -528,15 +527,21 @@ class Driver(object):
args.getLastArg(self.parser.saveTempsOption2)) args.getLastArg(self.parser.saveTempsOption2))
hasNoIntegratedCPP = args.getLastArg(self.parser.noIntegratedCPPOption) hasNoIntegratedCPP = args.getLastArg(self.parser.noIntegratedCPPOption)
hasPipe = args.getLastArg(self.parser.pipeOption) 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 = [] forward = []
for a in args: for a in args:
if a.opt is self.parser.inputOption: if a.opt is self.parser.inputOption:
pass pass
# FIXME: Needs to be part of option. # FIXME: Needs to be part of option.
elif a.opt.name in ('-E', '-S', '-c', elif (a.opt.name in ('-E', '-S', '-c',
'-arch', '-fsyntax-only', '-combine', '-x', '-arch', '-fsyntax-only', '-combine', '-x',
'-###'): '-###') or
a.opt.isLinkerInput):
pass pass
else: else:
@ -648,10 +653,10 @@ class Driver(object):
# #
# FIXME: gcc has some special case in here so that it doesn't # FIXME: gcc has some special case in here so that it doesn't
# create output files if they would conflict with an input. # create output files if they would conflict with an input.
inputName = args.getValue(baseInput)
if phase.type is Types.ImageType: if phase.type is Types.ImageType:
namedOutput = "a.out" namedOutput = "a.out"
else: else:
inputName = args.getValue(baseInput)
base,_ = os.path.splitext(inputName) base,_ = os.path.splitext(inputName)
assert phase.type.tempSuffix is not None assert phase.type.tempSuffix is not None
namedOutput = base + '.' + phase.type.tempSuffix namedOutput = base + '.' + phase.type.tempSuffix

View File

@ -52,7 +52,13 @@ class GCC_Common_Tool(Tool):
if isinstance(input.source, Jobs.PipedJob): if isinstance(input.source, Jobs.PipedJob):
cmd_args.append('-') cmd_args.append('-')
else: else:
cmd_args.append(arglist.getValue(input.source)) assert isinstance(input.source, Arguments.Arg)
# If this is a linker input then assume we can forward
# just by rendering.
if input.source.opt.isLinkerInput:
cmd_args.extend(arglist.render(input.source))
else:
cmd_args.extend(arglist.renderAsInput(input.source))
jobs.addJob(Jobs.Command('gcc', cmd_args)) jobs.addJob(Jobs.Command('gcc', cmd_args))
@ -113,7 +119,7 @@ class DarwinAssembleTool(Tool):
if isinstance(input.source, Jobs.PipedJob): if isinstance(input.source, Jobs.PipedJob):
cmd_args.append('-') cmd_args.append('-')
else: else:
cmd_args.append(arglist.getValue(input.source)) cmd_args.extend(arglist.renderAsInput(input.source))
jobs.addJob(Jobs.Command('as', cmd_args)) jobs.addJob(Jobs.Command('as', cmd_args))
class GCC_AssembleTool(GCC_Common_Tool): class GCC_AssembleTool(GCC_Common_Tool):
@ -471,7 +477,7 @@ class Darwin10_X86_LinkTool(Tool):
"-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.."]) "-L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.."])
for input in inputs: for input in inputs:
cmd_args.append(arglist.getValue(input.source)) cmd_args.extend(arglist.renderAsInput(input.source))
if (arglist.getLastArg(arglist.parser.f_profileArcsOption) or if (arglist.getLastArg(arglist.parser.f_profileArcsOption) or
arglist.getLastArg(arglist.parser.f_profileGenerateOption) or arglist.getLastArg(arglist.parser.f_profileGenerateOption) or
@ -548,5 +554,5 @@ class LipoTool(Tool):
cmd_args = ['-create'] cmd_args = ['-create']
cmd_args.extend(arglist.render(output)) cmd_args.extend(arglist.render(output))
for input in inputs: for input in inputs:
cmd_args.append(arglist.getValue(input.source)) cmd_args.extend(arglist.renderAsInput(input.source))
jobs.addJob(Jobs.Command('lipo', cmd_args)) jobs.addJob(Jobs.Command('lipo', cmd_args))