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):
"""Root option class."""
def __init__(self, name):
def __init__(self, name, isLinkerInput=False, noOptAsInput=False):
self.name = name
self.isLinkerInput = isLinkerInput
self.noOptAsInput = noOptAsInput
def accept(self, index, arg, it):
"""accept(index, arg, iterator) -> Arg or None
@ -49,6 +52,15 @@ class JoinedOption(Option):
if arg.startswith(self.name):
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):
"""An option which is followed by its value."""
@ -111,7 +123,7 @@ class Arg(object):
assert opt is not None
self.index = index
self.opt = opt
def __repr__(self):
return '<%s index=%r opt=%r>' % (self.__class__.__name__,
self.index,
@ -125,6 +137,9 @@ class Arg(object):
assert self.opt
return [self.opt.name]
def renderAsInput(self, args):
return self.render(args)
class ValueArg(Arg):
"""ValueArg - An instance of an option which has an argument."""
@ -150,6 +165,11 @@ class JoinedValueArg(ValueArg):
def render(self, 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):
"""SeparateValueArg - A single value argument where the value
follows the option in the argument vector."""
@ -160,6 +180,11 @@ class SeparateValueArg(ValueArg):
def render(self, 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):
"""MultipleValuesArg - An argument with multiple values which
follow the option in the argument vector."""
@ -173,6 +198,23 @@ class MultipleValuesArg(Arg):
def render(self, 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
# just special case?
class JoinedAndSeparateValuesArg(Arg):
@ -299,6 +341,9 @@ class ArgList:
def render(self, arg):
return arg.render(self)
def renderAsInput(self, arg):
return arg.renderAsInput(self)
def getValue(self, arg):
return arg.getValue(self)
@ -367,7 +412,7 @@ class OptionParser:
self.addOption(FlagOption('-v'))
# Input/output stuff
self.oOption = self.addOption(JoinedOrSeparateOption('-o'))
self.oOption = self.addOption(JoinedOrSeparateOption('-o', noOptAsInput=True))
self.xOption = self.addOption(JoinedOrSeparateOption('-x'))
self.ObjCOption = self.addOption(FlagOption('-ObjC'))
@ -385,14 +430,14 @@ class OptionParser:
# Blanket pass-through options.
self.addOption(JoinedOption('-Wa,'))
self.addOption(CommaJoinedOption('-Wa,'))
self.addOption(SeparateOption('-Xassembler'))
self.addOption(JoinedOption('-Wp,'))
self.addOption(CommaJoinedOption('-Wp,'))
self.addOption(SeparateOption('-Xpreprocessor'))
self.addOption(JoinedOption('-Wl,'))
self.addOption(SeparateOption('-Xlinker'))
self.addOption(CommaJoinedOption('-Wl,', isLinkerInput=True))
self.addOption(SeparateOption('-Xlinker', isLinkerInput=True, noOptAsInput=True))
####
# Bring on the random garbage.
@ -456,6 +501,9 @@ class OptionParser:
self.addOption(FlagOption('-traditional'))
self.addOption(FlagOption('--traditional'))
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.whatsloadedOption = self.addOption(FlagOption('-whatsloaded'))
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.Zweak_reference_mismatchesOption = self.addOption(JoinedOrSeparateOption('-Zweak_reference_mismatches'))
# I dunno why these don't end up working when joined. Maybe
# because of translation?
self.filelistOption = self.addOption(SeparateOption('-filelist'))
self.addOption(SeparateOption('-framework'))
self.addOption(SeparateOption('-filelist', isLinkerInput=True))
self.addOption(SeparateOption('-framework', isLinkerInput=True))
# FIXME: Alias.
self.addOption(SeparateOption('-install_name'))
self.Zinstall_nameOption = self.addOption(JoinedOrSeparateOption('-Zinstall_name'))
@ -532,7 +578,7 @@ class OptionParser:
self.addOption(JoinedOrSeparateOption('-U'))
self.ZOption = self.addOption(JoinedOrSeparateOption('-Z'))
self.addOption(JoinedOrSeparateOption('-l'))
self.addOption(JoinedOrSeparateOption('-l', isLinkerInput=True))
self.uOption = self.addOption(JoinedOrSeparateOption('-u'))
self.tOption = self.addOption(JoinedOrSeparateOption('-t'))
self.yOption = self.addOption(JoinedOption('-y'))

View File

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

View File

@ -52,7 +52,13 @@ class GCC_Common_Tool(Tool):
if isinstance(input.source, Jobs.PipedJob):
cmd_args.append('-')
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))
@ -113,7 +119,7 @@ class DarwinAssembleTool(Tool):
if isinstance(input.source, Jobs.PipedJob):
cmd_args.append('-')
else:
cmd_args.append(arglist.getValue(input.source))
cmd_args.extend(arglist.renderAsInput(input.source))
jobs.addJob(Jobs.Command('as', cmd_args))
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/../../.."])
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
arglist.getLastArg(arglist.parser.f_profileGenerateOption) or
@ -548,5 +554,5 @@ class LipoTool(Tool):
cmd_args = ['-create']
cmd_args.extend(arglist.render(output))
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))