diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-01-12 03:33:58 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-01-12 03:33:58 +0000 |
commit | 2ec55bcb666ef18d0caf629e58a9b64071028e3a (patch) | |
tree | 45f273781cf47e590d2db40ae73ba1cc1a52f121 | |
parent | ee8cc26f374a9dff0ba9e34fda1bdf3364c5beab (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.py | 70 | ||||
-rw-r--r-- | tools/ccc/ccclib/Driver.py | 19 | ||||
-rw-r--r-- | tools/ccc/ccclib/Tools.py | 14 |
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)) |