ccc: Clean up (user level) error handling.

- ccc now checks for existence of input files (more annoying to test,
   but matches gcc).
 - Fix some test cases.

llvm-svn: 62378
This commit is contained in:
Daniel Dunbar 2009-01-16 23:12:12 +00:00
parent 8c573f7e49
commit b3a633fc0c
6 changed files with 81 additions and 46 deletions

View File

@ -1,3 +1,16 @@
###
class InvalidArgumentsError(ValueError):
"""InvalidArgumentsError - The driver arguments are invalid or
inconsistent."""
class MissingArgumentError(ValueError):
"""MissingArgumentError - An option required an argument but none
was given."""
###
class Option(object):
"""Option - Root option class."""

View File

@ -19,14 +19,10 @@ import Util
####
class MissingArgumentError(ValueError):
"""MissingArgumentError - An option required an argument but none
was given."""
###
class Driver(object):
def __init__(self):
def __init__(self, driverName, driverDir):
self.driverName = driverName
self.driverDir = driverDir
self.hostInfo = None
self.parser = Arguments.OptionParser()
self.cccHostBits = self.cccHostMachine = None
@ -104,7 +100,8 @@ class Driver(object):
self.cccFallback = True
while argv and argv[0].startswith('-ccc-'):
opt,argv = argv[0][5:],argv[1:]
fullOpt,argv = argv[0],argv[1:]
opt = fullOpt[5:]
if opt == 'print-options':
cccPrintOptions = True
@ -127,7 +124,7 @@ class Driver(object):
elif opt == 'host-release':
self.cccHostRelease,argv = argv[0],argv[1:]
else:
raise ValueError,"Invalid ccc option: %r" % opt
raise Arguments.InvalidArgumentsError("invalid option: %r" % fullOpt)
self.hostInfo = HostInfo.getHostInfo(self)
self.toolChain = self.hostInfo.getToolChain()
@ -209,7 +206,7 @@ class Driver(object):
pass
def warning(self, message):
print >>sys.stderr,'%s: %s' % (sys.argv[0], message)
print >>sys.stderr,'%s: %s' % (self.driverName, message)
def printOptions(self, args):
for i,arg in enumerate(args):
@ -325,8 +322,9 @@ class Driver(object):
inputs = []
for a in args:
if a.opt is self.parser.inputOption:
inputValue = args.getValue(a)
if inputType is None:
base,ext = os.path.splitext(args.getValue(a))
base,ext = os.path.splitext(inputValue)
if ext and ext in Types.kTypeSuffixMap:
klass = Types.kTypeSuffixMap[ext]
else:
@ -339,6 +337,14 @@ class Driver(object):
assert inputTypeOpt is not None
self.claim(inputTypeOpt)
klass = inputType
# Check that the file exists. It isn't clear this is
# worth doing, since the tool presumably does this
# anyway, and this just adds an extra stat to the
# equation, but this is gcc compatible.
if not os.path.exists(inputValue):
self.warning("%s: No such file or directory" % inputValue)
else:
inputs.append((klass, a))
elif a.opt.isLinkerInput:
# Treat as a linker input.
@ -348,13 +354,8 @@ class Driver(object):
# that other code which needs to know the inputs
# handles this properly. Best not to try and lipo
# this, for example.
#
# FIXME: Actually, this is just flat out broken, the
# tools expect inputs to be accessible by .getValue
# but that of course only yields the argument.
inputs.append((Types.ObjectType, a))
elif a.opt is self.parser.xOption:
self.claim(a)
inputTypeOpt = a
value = args.getValue(a)
if value in Types.kTypeSpecifierMap:
@ -396,7 +397,11 @@ class Driver(object):
# FIXME: Support -combine.
if hasCombine:
raise NotImplementedError,"-combine is not yet supported."
raise NotImplementedError,"-combine is not yet supported"
if (not inputs and
not args.getLastArg(self.parser.hashHashHashOption)):
raise Arguments.InvalidArgumentsError("no input files")
actions = []
linkerInputs = []
@ -511,9 +516,9 @@ class Driver(object):
# these cause downstream.
if len(archs) > 1:
if hasDashM:
raise ValueError,"Cannot use -M options with multiple arch flags."
raise Arguments.InvalidArgumentsError("Cannot use -M options with multiple arch flags.")
elif hasSaveTemps:
raise ValueError,"Cannot use -save-temps with multiple arch flags."
raise Arguments.InvalidArgumentsError("Cannot use -save-temps with multiple arch flags.")
# Execute once per arch.
finalActions = []
@ -531,7 +536,7 @@ class Driver(object):
# developers.
if (len(archs) > 1 and
p.type not in (Types.NothingType,Types.ObjectType,Types.ImageType)):
raise ValueError,'Cannot use %s output with multiple arch flags.' % p.type.name
raise Arguments.InvalidArgumentsError('Cannot use %s output with multiple arch flags.' % p.type.name)
inputs = []
for arch in archs:
@ -701,8 +706,7 @@ class Driver(object):
# It is an error to provide a -o option if we are making multiple
# output files.
if finalOutput and len([a for a in phases if a.type is not Types.NothingType]) > 1:
# FIXME: Custom exception.
raise ValueError,"Cannot specify -o when generating multiple files."
raise Arguments.InvalidArgumentsError("cannot specify -o when generating multiple files")
for phase in phases:
createJobs(self.toolChain, phase,

View File

@ -375,12 +375,12 @@ class Darwin_X86_CompileTool(Tool):
usePP = False
isCXX = True
else:
raise RuntimeError,"Unexpected input type for Darwin compile tool."
raise ValueError,"Unexpected input type for Darwin compile tool."
cmd_args = []
if (arglist.getLastArg(arglist.parser.traditionalOption) or
arglist.getLastArg(arglist.parser.f_traditionalOption)):
raise ValueError,"-traditional is not supported without -E"
raise Arguments.InvalidArgumentsError("-traditional is not supported without -E")
if usePP:
# Derived from cpp_options.
@ -390,7 +390,7 @@ class Darwin_X86_CompileTool(Tool):
if (arglist.getLastArg(arglist.parser.COption) or
arglist.getLastArg(arglist.parser.CCOption)):
if not arglist.getLastArg(arglist.parser.EOption):
raise ValueError,"-C or -CC is not supported without -E"
raise Arguments.InvalidArgumentsError("-C or -CC is not supported without -E")
if not arglist.getLastArg(arglist.parser.QOption):
cmd_args.append('-quiet')
arglist.addAllArgs(cmd_args, arglist.parser.nostdincOption)
@ -491,7 +491,7 @@ class Darwin_X86_CompileTool(Tool):
if (arglist.getLastArg(arglist.parser.pgOption) and
arglist.getLastArg(arglist.parser.f_omitFramePointerOption)):
raise ValueError,"-pg and -fomit-frame-pointer are incompatible"
raise Arguments.InvalidArgumentsError("-pg and -fomit-frame-pointer are incompatible")
self.addCC1Args(cmd_args, arch, arglist)
@ -596,7 +596,7 @@ class Darwin_X86_LinkTool(Tool):
try:
return tuple(map(int, components))
except:
raise ValueError,"invalid version number %r" % version
raise Arguments.InvalidArgumentsError("invalid version number %r" % version)
else:
major,minor,minorminor = self.toolChain.darwinVersion
return (10, major-4, minor)

View File

@ -1,4 +1,4 @@
// RUN: xcc -ccc-host-bits 32 -ccc-host-machine i386 -ccc-host-system darwin -ccc-host-release 10.5.0 -### -x objective-c -arch i386 -fmessage-length=0 -Wno-trigraphs -fpascal-strings -fasm-blocks -Os -mdynamic-no-pic -DUSER_DEFINE_0 -fvisibility=hidden -mmacosx-version-min=10.5 -gdwarf-2 -IINCLUDE_PATH_0 -Wall -Wextra -Wno-missing-field-initializers -Wno-unused-parameter -Wno-four-char-constants -Wno-unknown-pragmas -Wno-format-y2k -Wpointer-arith -Wreturn-type -Wwrite-strings -Wswitch -Wcast-align -Wchar-subscripts -Winline -Wnested-externs -Wint-to-pointer-cast -Wpointer-to-int-cast -Wshorten-64-to-32 -FFRAMEWORK_0 -IINCLUDE_PATH_1 -FFRAMEWORK_1 -include USER_INCLUDE_0 -c %s -o %t.out &> %t.opts &&
// RUN: grep ' "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/cc1obj" "-quiet" "-IINCLUDE_PATH_0" "-FFRAMEWORK_0" "-IINCLUDE_PATH_1" "-FFRAMEWORK_1" "-D__DYNAMIC__" "-DUSER_DEFINE_0" "-include" "USER_INCLUDE_0" "darwin-x86-cc1.m" "-quiet" "-dumpbase" "darwin-x86-cc1.m" "-mpascal-strings" "-mdynamic-no-pic" "-mmacosx-version-min=10.5" "-mtune=core2" "-auxbase-strip" "Output/darwin-x86-cc1.m.out.tmp.out" "-gdwarf-2" "-Os" "-Wno-trigraphs" "-Wall" "-Wextra" "-Wno-missing-field-initializers" "-Wno-unused-parameter" "-Wno-four-char-constants" "-Wno-unknown-pragmas" "-Wno-format-y2k" "-Wpointer-arith" "-Wreturn-type" "-Wwrite-strings" "-Wswitch" "-Wcast-align" "-Wchar-subscripts" "-Winline" "-Wnested-externs" "-Wint-to-pointer-cast" "-Wpointer-to-int-cast" "-Wshorten-64-to-32" "-fmessage-length=0" "-fasm-blocks" "-fvisibility=hidden" "-o"' %t.opts &&
// RUN: grep ' "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/as" "-arch" "i386" "-force_cpusubtype_ALL" "-o" "Output/darwin-x86-cc1.m.out.tmp.out" ' %t.opts
// RUN: grep ' "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/cc1obj" "-quiet" "-IINCLUDE_PATH_0" "-FFRAMEWORK_0" "-IINCLUDE_PATH_1" "-FFRAMEWORK_1" "-D__DYNAMIC__" "-DUSER_DEFINE_0" "-include" "USER_INCLUDE_0" ".*" "-quiet" "-dumpbase" "darwin-x86-cc1.m" "-mpascal-strings" "-mdynamic-no-pic" "-mmacosx-version-min=10.5" "-mtune=core2" "-auxbase-strip" ".*" "-gdwarf-2" "-Os" "-Wno-trigraphs" "-Wall" "-Wextra" "-Wno-missing-field-initializers" "-Wno-unused-parameter" "-Wno-four-char-constants" "-Wno-unknown-pragmas" "-Wno-format-y2k" "-Wpointer-arith" "-Wreturn-type" "-Wwrite-strings" "-Wswitch" "-Wcast-align" "-Wchar-subscripts" "-Winline" "-Wnested-externs" "-Wint-to-pointer-cast" "-Wpointer-to-int-cast" "-Wshorten-64-to-32" "-fmessage-length=0" "-fasm-blocks" "-fvisibility=hidden" "-o"' %t.opts &&
// RUN: grep ' "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/as" "-arch" "i386" "-force_cpusubtype_ALL" "-o"' %t.opts

View File

@ -1,41 +1,46 @@
// One C file.
// RUN: xcc -ccc-host-system unknown -ccc-print-phases a.c > %t &&
// RUN: grep '0: input, "a.c", c' %t &&
// RUN: touch %t.c &&
// RUN: xcc -ccc-host-system unknown -ccc-print-phases %t.c > %t &&
// RUN: grep '0: input, "%t.c", c' %t &&
// RUN: grep '1: preprocessor, {0}, cpp-output' %t &&
// RUN: grep '2: compiler, {1}, assembler' %t &&
// RUN: grep '3: assembler, {2}, object' %t &&
// RUN: grep '4: linker, {3}, image' %t &&
// PCH.
// RUN: xcc -ccc-host-system unknown -ccc-print-phases -x c-header a.h > %t &&
// RUN: grep '0: input, "a.h", c-header' %t &&
// RUN: touch %t.h &&
// RUN: xcc -ccc-host-system unknown -ccc-print-phases -x c-header %t.h > %t &&
// RUN: grep '0: input, "%t.h", c-header' %t &&
// RUN: grep '1: preprocessor, {0}, c-header-cpp-output' %t &&
// RUN: grep '2: precompiler, {1}, precompiled-header' %t &&
// Assembler w/ and w/o preprocessor.
// RUN: xcc -ccc-host-system unknown -ccc-print-phases -x assembler a.s > %t &&
// RUN: grep '0: input, "a.s", assembler' %t &&
// RUN: touch %t.s &&
// RUN: xcc -ccc-host-system unknown -ccc-print-phases -x assembler %t.s > %t &&
// RUN: grep '0: input, "%t.s", assembler' %t &&
// RUN: grep '1: assembler, {0}, object' %t &&
// RUN: grep '2: linker, {1}, image' %t &&
// RUN: xcc -ccc-host-system unknown -ccc-print-phases -x assembler-with-cpp a.s > %t &&
// RUN: grep '0: input, "a.s", assembler-with-cpp' %t &&
// RUN: xcc -ccc-host-system unknown -ccc-print-phases -x assembler-with-cpp %t.s > %t &&
// RUN: grep '0: input, "%t.s", assembler-with-cpp' %t &&
// RUN: grep '1: preprocessor, {0}, assembler' %t &&
// RUN: grep '2: assembler, {1}, object' %t &&
// RUN: grep '3: linker, {2}, image' %t &&
// Check the various ways of early termination.
// RUN: xcc -ccc-host-system unknown -ccc-print-phases -E a.c > %t &&
// RUN: xcc -ccc-host-system unknown -ccc-print-phases -E %s > %t &&
// RUN: not grep ': compiler, ' %t &&
// RUN: xcc -ccc-host-system unknown -ccc-print-phases -fsyntax-only a.c > %t &&
// RUN: xcc -ccc-host-system unknown -ccc-print-phases -fsyntax-only %s > %t &&
// RUN: grep ': compiler, {1}, nothing' %t &&
// RUN: not grep ': assembler, ' %t &&
// RUN: xcc -ccc-host-system unknown -ccc-print-phases -S a.c > %t &&
// RUN: xcc -ccc-host-system unknown -ccc-print-phases -S %s > %t &&
// RUN: not grep ': assembler, ' %t &&
// RUN: xcc -ccc-host-system unknown -ccc-print-phases -c a.c > %t &&
// RUN: xcc -ccc-host-system unknown -ccc-print-phases -c %s > %t &&
// RUN: not grep ': linker, ' %t &&
// Multiple output files.
// RUN: xcc -ccc-host-system unknown -ccc-print-phases -c a.c b.c > %t &&
// RUN: touch %t.1.c &&
// RUN: touch %t.2.c &&
// RUN: xcc -ccc-host-system unknown -ccc-print-phases -c %t.1.c %t.2.c > %t &&
// RUN: grep ': assembler,' %t | count 2 &&
// FIXME: Only for darwin.

View File

@ -1,12 +1,25 @@
#!/usr/bin/python
import os
import sys
from ccclib import Arguments
from ccclib import Driver
def main():
d = Driver.Driver()
# FIXME: We should pass program name here as well.
progDir = os.path.dirname(sys.argv[0])
progName = os.path.basename(sys.argv[0])
d = Driver.Driver(progDir, progName)
try:
d.run(sys.argv[1:])
except Arguments.InvalidArgumentsError,e:
print >>sys.stderr, "%s: %s" % (progName, e.args[0])
sys.exit(1)
except Arguments.MissingArgumentError,e:
print >>sys.stderr, "%s: %s" % (progName, e.args[0])
sys.exit(1)
except NotImplementedError,e:
print >>sys.stderr, "%s: not implemented: %s" % (progName, e.args[0])
if __name__=='__main__':
main()