diff --git a/clang/tools/ccc/ccclib/Arguments.py b/clang/tools/ccc/ccclib/Arguments.py index 57793cbae3d4..5b5dbfec61aa 100644 --- a/clang/tools/ccc/ccclib/Arguments.py +++ b/clang/tools/ccc/ccclib/Arguments.py @@ -17,6 +17,24 @@ class Option(object): return '<%s name=%r>' % (self.__class__.__name__, self.name) +# Dummy options + +class InputOption(Option): + def __init__(self): + super(InputOption, self).__init__('') + + def accept(self): + raise RuntimeError,"accept() should never be used on InputOption instance." + +class UnknownOption(Option): + def __init__(self): + super(UnknownOption, self).__init__('') + + def accept(self): + raise RuntimeError,"accept() should never be used on UnknownOption instance." + +# Normal options + class FlagOption(Option): """An option which takes no arguments.""" @@ -90,6 +108,7 @@ class JoinedAndSeparateOption(Option): class Arg(object): """Arg - Base class for actual driver arguments.""" def __init__(self, index, opt): + assert opt is not None self.index = index self.opt = opt @@ -115,9 +134,8 @@ class ValueArg(Arg): def setValue(self, args, value): abstract -class UnknownArg(ValueArg): - def __init__(self, index): - super(UnknownArg, self).__init__(index, None) +class PositionalArg(ValueArg): + """PositionalArg - A simple positional argument.""" def getValue(self, args): return args[self.index] @@ -129,6 +147,9 @@ class UnknownArg(ValueArg): return [args[self.index]] class JoinedValueArg(ValueArg): + """JoinedValueArg - A single value argument where the value is + joined (suffixed) to the option.""" + def getValue(self, args): return args[self.index][len(self.opt.name):] @@ -140,6 +161,9 @@ class JoinedValueArg(ValueArg): return [self.opt.name + self.getValue(args)] class SeparateValueArg(ValueArg): + """SeparateValueArg - A single value argument where the value + follows the option in the argument vector.""" + def getValue(self, args): return args[self.index+1] @@ -150,6 +174,11 @@ class SeparateValueArg(ValueArg): return [self.opt.name, self.getValue(args)] class MultipleValuesArg(Arg): + """MultipleValuesArg - An argument with multiple values which + follow the option in the argument vector.""" + + # FIXME: Should we unify this with SeparateValueArg? + def getValues(self, args): return args[self.index + 1:self.index + 1 + self.opt.numArgs] @@ -183,27 +212,15 @@ class JoinedAndSeparateValuesArg(Arg): return ([self.opt.name + self.getJoinedValue(args)] + [self.getSeparateValue(args)]) -class InputArg(ValueArg): - """InputArg - An input file (positional) argument.""" - - def __init__(self, index): - super(ValueArg, self).__init__(index, None) - - def getValue(self, args): - return args[self.index] - - def setValue(self, args, value): - args[self.index] = value - - def render(self, args): - return [self.getValue(args)] - class DerivedArg(ValueArg): """DerivedArg - A synthesized argument which does not correspend - to the actual input arguments array.""" + to an item in the argument vector.""" def __init__(self, value): - super(ValueArg, self).__init__(-1, None) + # FIXME: The UnknownOption() here is a total hack so we can + # rely on arg.opt not being nil. Ok for now since DerivedArg + # is dying. + super(DerivedArg, self).__init__(-1, UnknownOption()) self.value = value def getValue(self, args): @@ -216,7 +233,7 @@ class DerivedArg(ValueArg): return [self.value] class ArgList: - """ArgList - Collect an input argv along with a set of parsed Args + """ArgList - Collect an input argument vector along with a set of parsed Args and supporting information.""" def __init__(self, argv): @@ -248,7 +265,9 @@ class ArgList: class OptionParser: def __init__(self): self.options = [] - + self.inputOption = InputOption() + self.unknownOption = UnknownOption() + def addOption(self, opt): self.options.append(opt) @@ -274,15 +293,15 @@ class OptionParser: elif a[0] == '-' and a != '-': args.append(self.lookupOptForArg(i, a, it)) else: - args.append(InputArg(i)) + args.append(PositionalArg(i, self.inputOption)) return args - def lookupOptForArg(self, i, arg, it): - for op in self.options: - opt = op.accept(i, arg, it) - if opt is not None: - return opt - return UnknownArg(i) + def lookupOptForArg(self, i, string, it): + for o in self.options: + arg = o.accept(i, string, it) + if arg is not None: + return arg + return PositionalArg(i, self.unknownOption) def createOptionParser(): op = OptionParser() diff --git a/clang/tools/ccc/ccclib/Driver.py b/clang/tools/ccc/ccclib/Driver.py index c07631e8dbed..0133c34e08ff 100644 --- a/clang/tools/ccc/ccclib/Driver.py +++ b/clang/tools/ccc/ccclib/Driver.py @@ -101,7 +101,7 @@ class Driver(object): # Print in -### syntax. hasHashHashHash = None for arg in args: - if arg.opt and arg.opt.name == '-###': + if arg.opt.name == '-###': hasHashHashHash = arg if hasHashHashHash: @@ -137,13 +137,6 @@ class Driver(object): def printOptions(self, args): for i,arg in enumerate(args): - if isinstance(arg, Arguments.InputArg): - name = "" - elif isinstance(arg, Arguments.UnknownArg): - name = "" - else: - assert arg.opt - name = arg.opt.name if isinstance(arg, Arguments.MultipleValuesArg): values = list(args.getValues(arg)) elif isinstance(arg, Arguments.ValueArg): @@ -152,7 +145,7 @@ class Driver(object): values = [args.getJoinedValue(arg), args.getSeparateValue(arg)] else: values = [] - print 'Option %d - Name: "%s", Values: {%s}' % (i, name, + print 'Option %d - Name: "%s", Values: {%s}' % (i, arg.opt.name, ', '.join(['"%s"' % v for v in values])) @@ -200,34 +193,33 @@ class Driver(object): # presence of things like -dumpmachine and -print-search-dirs? # Probably not. for arg in args: - if arg.opt is not None: - if arg.opt.name == '-dumpmachine': - print 'FIXME: %s' % arg.opt.name - sys.exit(1) - elif arg.opt.name == '-dumpspecs': - print 'FIXME: %s' % arg.opt.name - sys.exit(1) - elif arg.opt.name == '-dumpversion': - print 'FIXME: %s' % arg.opt.name - sys.exit(1) - elif arg.opt.name == '-print-file-name=': - print 'FIXME: %s' % arg.opt.name - sys.exit(1) - elif arg.opt.name == '-print-multi-directory': - print 'FIXME: %s' % arg.opt.name - sys.exit(1) - elif arg.opt.name == '-print-multi-lib': - print 'FIXME: %s' % arg.opt.name - sys.exit(1) - elif arg.opt.name == '-print-prog-name=': - print 'FIXME: %s' % arg.opt.name - sys.exit(1) - elif arg.opt.name == '-print-libgcc-file-name': - print 'FIXME: %s' % arg.opt.name - sys.exit(1) - elif arg.opt.name == '-print-search-dirs': - print 'FIXME: %s' % arg.opt.name - sys.exit(1) + if arg.opt.name == '-dumpmachine': + print 'FIXME: %s' % arg.opt.name + sys.exit(1) + elif arg.opt.name == '-dumpspecs': + print 'FIXME: %s' % arg.opt.name + sys.exit(1) + elif arg.opt.name == '-dumpversion': + print 'FIXME: %s' % arg.opt.name + sys.exit(1) + elif arg.opt.name == '-print-file-name=': + print 'FIXME: %s' % arg.opt.name + sys.exit(1) + elif arg.opt.name == '-print-multi-directory': + print 'FIXME: %s' % arg.opt.name + sys.exit(1) + elif arg.opt.name == '-print-multi-lib': + print 'FIXME: %s' % arg.opt.name + sys.exit(1) + elif arg.opt.name == '-print-prog-name=': + print 'FIXME: %s' % arg.opt.name + sys.exit(1) + elif arg.opt.name == '-print-libgcc-file-name': + print 'FIXME: %s' % arg.opt.name + sys.exit(1) + elif arg.opt.name == '-print-search-dirs': + print 'FIXME: %s' % arg.opt.name + sys.exit(1) def buildNormalPipeline(self, args): hasCombine = None @@ -238,7 +230,7 @@ class Driver(object): inputTypeOpt = None inputs = [] for a in args: - if isinstance(a, Arguments.InputArg): + if a.opt.name == '': if inputType is None: base,ext = os.path.splitext(args.getValue(a)) if ext and ext in Types.kTypeSuffixMap: @@ -254,43 +246,40 @@ class Driver(object): self.claim(inputTypeOpt) klass = inputType inputs.append((klass, a)) - elif a.opt is not None: - # FIXME: We should warn about inconsistent and duplicate - # usage of these flags. - if a.opt.name == '-E': - hasDashE = a - elif a.opt.name == '-S': - hasDashS = a - elif a.opt.name == '-c': - hasDashC = a - elif a.opt.name == '-fsyntax-only': - hasSyntaxOnly = a - elif a.opt.name == '-combine': - hasCombine = a - elif a.opt.name == '-filelist': - # FIXME: This might not be good enough. We may - # need to introduce another type of InputArg for - # this case, so that other code which needs to - # know the inputs handles this properly. Best not - # to try and lipo this, for example. - # - # Treat as a linker input. - inputs.append((Types.ObjectType, a)) - elif a.opt.name == '-x': - self.claim(a) - inputTypeOpt = a - value = args.getValue(a) - if value in Types.kTypeSpecifierMap: - inputType = Types.kTypeSpecifierMap[value] - else: - # FIXME: How are we going to handle diagnostics. - self.warning("language %s not recognized" % value) + elif a.opt.name == '-E': + hasDashE = a + elif a.opt.name == '-S': + hasDashS = a + elif a.opt.name == '-c': + hasDashC = a + elif a.opt.name == '-fsyntax-only': + hasSyntaxOnly = a + elif a.opt.name == '-combine': + hasCombine = a + elif a.opt.name == '-filelist': + # Treat as a linker input. + # + # FIXME: This might not be good enough. We may + # need to introduce another type for this case, so + # that other code which needs to know the inputs + # handles this properly. Best not to try and lipo + # this, for example. + inputs.append((Types.ObjectType, a)) + elif a.opt.name == '-x': + self.claim(a) + inputTypeOpt = a + value = args.getValue(a) + if value in Types.kTypeSpecifierMap: + inputType = Types.kTypeSpecifierMap[value] + else: + # FIXME: How are we going to handle diagnostics. + self.warning("language %s not recognized" % value) - # FIXME: Its not clear why we shouldn't just - # revert to unknown. I think this is more likely a - # bug / unintended behavior in gcc. Not very - # important though. - inputType = ObjectType + # FIXME: Its not clear why we shouldn't just + # revert to unknown. I think this is more likely a + # bug / unintended behavior in gcc. Not very + # important though. + inputType = ObjectType # We claim things here so that options for which we silently allow # override only ever claim the used option. @@ -414,12 +403,8 @@ class Driver(object): hasOutput = None hasDashM = hasSaveTemps = None for arg in args: - if arg.opt is None: - continue - - if isinstance(arg, Arguments.ValueArg): - if arg.opt.name == '-arch': - archs.append(arg) + if arg.opt.name == '-arch': + archs.append(arg) elif arg.opt.name.startswith('-M'): hasDashM = arg elif arg.opt.name in ('-save-temps','--save-temps'): @@ -496,23 +481,20 @@ class Driver(object): hasSaveTemps = hasNoIntegratedCPP = hasPipe = None forward = [] for a in args: - if isinstance(a, Arguments.InputArg): + if a.opt.name == '': + pass + elif a.opt.name == '-save-temps': + hasSaveTemps = a + elif a.opt.name == '-no-integrated-cpp': + hasNoIntegratedCPP = a + elif a.opt.name == '-o': + finalOutput = a + elif a.opt.name == '-pipe': + hasPipe = a + elif a.opt.name in ('-E', '-S', '-c', + '-arch', '-fsyntax-only', '-combine', '-x', + '-###'): pass - elif a.opt is not None: - if a.opt.name == '-save-temps': - hasSaveTemps = a - elif a.opt.name == '-no-integrated-cpp': - hasNoIntegratedCPP = a - elif a.opt.name == '-o': - finalOutput = a - elif a.opt.name == '-pipe': - hasPipe = a - elif a.opt.name in ('-E', '-S', '-c', - '-arch', '-fsyntax-only', '-combine', '-x', - '-###'): - pass - else: - forward.append(a) else: forward.append(a) @@ -556,9 +538,7 @@ class Driver(object): archName = args.getValue(phase.arch) filteredArgs = [] for arg in forwardArgs: - if arg.opt is None: - filteredArgs.append(arg) - elif arg.opt.name == '-arch': + if arg.opt.name == '-arch': if arg is phase.arch: filteredArgs.append(arg) elif arg.opt.name == '-Xarch_':