aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-01-12 03:33:58 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-01-12 03:33:58 +0000
commit2ec55bcb666ef18d0caf629e58a9b64071028e3a (patch)
tree45f273781cf47e590d2db40ae73ba1cc1a52f121
parentee8cc26f374a9dff0ba9e34fda1bdf3364c5beab (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62075 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--tools/ccc/ccclib/Arguments.py70
-rw-r--r--tools/ccc/ccclib/Driver.py19
-rw-r--r--tools/ccc/ccclib/Tools.py14
3 files changed, 80 insertions, 23 deletions
diff --git a/tools/ccc/ccclib/Arguments.py b/tools/ccc/ccclib/Arguments.py
index 564114f405..0e8d05350d 100644
--- a/tools/ccc/ccclib/Arguments.py
+++ b/tools/ccc/ccclib/Arguments.py
@@ -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'))
diff --git a/tools/ccc/ccclib/Driver.py b/tools/ccc/ccclib/Driver.py
index b781479df6..afc7cf5854 100644
--- a/tools/ccc/ccclib/Driver.py
+++ b/tools/ccc/ccclib/Driver.py
@@ -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
diff --git a/tools/ccc/ccclib/Tools.py b/tools/ccc/ccclib/Tools.py
index 17a9ce822a..100344131f 100644
--- a/tools/ccc/ccclib/Tools.py
+++ b/tools/ccc/ccclib/Tools.py
@@ -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))