ccc: Embrace destiny as a clang compiler driver.

This redoes the default mode that ccc runs in w.r.t. using clang. Now
ccc defaults to always using clang for any task clang can
handle. However, the following options exist to tweak this behavior:

 -ccc-no-clang: Don't use clang at all for compilation (still used for
  static analysis).
 
 -ccc-no-clang-cxx: Don't use clang for C++ and Objective-C++ inputs.

 -ccc-no-clang-cpp: Don't use clang as a preprocessor.

 -ccc-clang-archs <archs>: If present, only use clang for the given
  comma separated list of architectures. This only works on Darwin for
  now.

Note that all -ccc options must be first on the command line.

llvm-svn: 63346
This commit is contained in:
Daniel Dunbar 2009-01-29 23:54:06 +00:00
parent 38b9c05f1c
commit 711e882c1b
11 changed files with 94 additions and 53 deletions

View File

@ -28,9 +28,10 @@ class Driver(object):
self.cccHostBits = self.cccHostMachine = None
self.cccHostSystem = self.cccHostRelease = None
self.cccCXX = False
self.cccClang = False
self.cccEcho = False
self.cccFallback = False
self.cccNoClang = self.cccNoClangCXX = self.cccNoClangPreprocessor = False
self.cccClangArchs = None
# Certain options suppress the 'no input files' warning.
self.suppressMissingInputWarning = False
@ -115,12 +116,10 @@ class Driver(object):
# FIXME: How to handle override of host? ccc specific options?
# Abuse -b?
if self.getenvBool('CCC_CLANG'):
self.cccClang = True
if self.getenvBool('CCC_ECHO'):
self.cccEcho = True
if self.getenvBool('CCC_FALLBACK'):
self.cccFallback = True
arg = os.getenv('CCC_ADD_ARGS')
if arg:
args = filter(None, map(str.strip, arg.split(',')))
argv = args + argv
while argv and argv[0].startswith('-ccc-'):
fullOpt,argv = argv[0],argv[1:]
@ -132,12 +131,20 @@ class Driver(object):
cccPrintPhases = True
elif opt == 'cxx':
self.cccCXX = True
elif opt == 'clang':
self.cccClang = True
elif opt == 'echo':
self.cccEcho = True
elif opt == 'fallback':
self.cccFallback = True
elif opt == 'no-clang':
self.cccNoClang = True
elif opt == 'no-clang-cxx':
self.cccNoClangCXX = True
elif opt == 'no-clang-cpp':
self.cccNoClangPreprocessor = True
elif opt == 'clang-archs':
self.cccClangArchs,argv = argv[0].split(','),argv[1:]
elif opt == 'host-bits':
self.cccHostBits,argv = argv[0],argv[1:]
elif opt == 'host-machine':

View File

@ -54,6 +54,28 @@ class ToolChain(object):
else:
return args
def shouldUseClangCompiler(self, action):
# If user requested no clang, or this isn't a "compile" phase,
# or this isn't a C family option, then don't use clang.
if (self.driver.cccNoClang or
not isinstance(action.phase, (Phases.PreprocessPhase,
Phases.CompilePhase,
Phases.SyntaxOnlyPhase,
Phases.EmitLLVMPhase,
Phases.PrecompilePhase)) or
action.inputs[0].type not in Types.cTypesSet):
return False
if self.driver.cccNoClangPreprocessor:
if isinstance(action.phase, Phases.PreprocessPhase):
return False
if self.driver.cccNoClangCXX:
if action.inputs[0].type in Types.cxxTypesSet:
return False
return True
class Darwin_X86_ToolChain(ToolChain):
def __init__(self, driver, darwinVersion, gccVersion, archName):
super(Darwin_X86_ToolChain, self).__init__(driver)
@ -106,20 +128,23 @@ class Darwin_X86_ToolChain(ToolChain):
major,minor,minorminor = self.darwinVersion
return '%d.%d.%d' % (10, major-4, minor)
def shouldUseClangCompiler(self, action):
if not super(Darwin_X86_ToolChain, self).shouldUseClangCompiler(action):
return False
# Only use clang if user didn't override archs, or this is one
# of the ones they provided.
if (not self.driver.cccClangArchs or
self.archName in self.driver.cccClangArchs):
return True
return False
def selectTool(self, action):
assert isinstance(action, Phases.JobAction)
if self.driver.cccClang and self.archName == 'i386':
if (action.inputs[0].type in (Types.CType, Types.CTypeNoPP,
Types.ObjCType, Types.ObjCTypeNoPP) and
(isinstance(action.phase, Phases.CompilePhase) or
isinstance(action.phase, Phases.SyntaxOnlyPhase) or
isinstance(action.phase, Phases.EmitLLVMPhase))):
return self.clangTool
elif (action.inputs[0].type in (Types.CHeaderType, Types.CHeaderNoPPType,
Types.ObjCHeaderType, Types.ObjCHeaderNoPPType) and
isinstance(action.phase, Phases.PrecompilePhase)):
return self.clangTool
if self.shouldUseClangCompiler(action):
return self.clangTool
return self.toolMap[action.phase.__class__]
@ -220,17 +245,7 @@ class Generic_GCC_ToolChain(ToolChain):
def selectTool(self, action):
assert isinstance(action, Phases.JobAction)
if self.driver.cccClang:
if (action.inputs[0].type in (Types.CType, Types.CTypeNoPP,
Types.ObjCType, Types.ObjCTypeNoPP) and
(isinstance(action.phase, Phases.PreprocessPhase) or
isinstance(action.phase, Phases.CompilePhase) or
isinstance(action.phase, Phases.SyntaxOnlyPhase) or
isinstance(action.phase, Phases.EmitLLVMPhase))):
return self.clangTool
elif (action.inputs[0].type in (Types.CHeaderType, Types.CHeaderNoPPType,
Types.ObjCHeaderType, Types.ObjCHeaderNoPPType) and
isinstance(action.phase, Phases.PrecompilePhase)):
return self.clangTool
if self.shouldUseClangCompiler(action):
return self.clangTool
return self.toolMap[action.phase.__class__]

View File

@ -190,6 +190,9 @@ class Clang_CompileTool(Tool):
cmd_args.append('-emit-llvm-bc')
elif outputType is Types.AsmTypeNoPP:
cmd_args.append('-S')
elif (inputs[0].type.preprocess and
outputType is inputs[0].type.preprocess):
cmd_args.append('-E')
elif outputType is Types.PCHType:
# No special option needed, driven by -x. However, we
# patch the output name to try and not conflict with gcc.

View File

@ -146,6 +146,22 @@ kTypeSpecifierMap = {
'treelang' : TreelangType,
}
# Set of C family types.
cTypesSet = set([CType, CTypeNoPP,
ObjCType, ObjCTypeNoPP,
CXXType, CXXTypeNoPP,
ObjCXXType, ObjCXXTypeNoPP,
CHeaderType, CHeaderNoPPType,
ObjCHeaderType, ObjCHeaderNoPPType,
CXXHeaderType, CXXHeaderNoPPType,
ObjCXXHeaderType, ObjCXXHeaderNoPPType])
# Set of C++ family types.
cxxTypesSet = set([CXXType, CXXTypeNoPP,
ObjCXXType, ObjCXXTypeNoPP,
CXXHeaderType, CXXHeaderNoPPType,
ObjCXXHeaderType, ObjCXXHeaderNoPPType])
# Check that the type specifier map at least matches what the types
# believe to be true.
assert not [name for name,type in kTypeSpecifierMap.items()

View File

@ -1,4 +1,4 @@
// RUN: xcc -### -fsyntax-only -Xarch_i386 -Wall -Xarch_ppc -Wunused -arch i386 -arch ppc %s &> %t &&
// RUN: xcc -ccc-no-clang -### -fsyntax-only -Xarch_i386 -Wall -Xarch_ppc -Wunused -arch i386 -arch ppc %s &> %t &&
// RUN: grep '"-Xarch"' %t | count 0 &&
// RUN: grep '"-Wall"' %t | count 1 &&
// RUN: grep 'i686-apple' %t | grep -v '"-m64"' | count 1 &&

View File

@ -1,13 +1,13 @@
// RUN: xcc -### -S --all-warnings %s &> %t &&
// RUN: xcc -ccc-no-clang -### -S --all-warnings %s &> %t &&
// RUN: grep -- '"-Wall"' %t &&
// RUN: xcc -### -S --ansi %s &> %t &&
// RUN: xcc -ccc-no-clang -### -S --ansi %s &> %t &&
// RUN: grep -- '"-ansi"' %t &&
// RUN: xcc -### -S --assert foo --assert=foo %s &> %t &&
// RUN: xcc -ccc-no-clang -### -S --assert foo --assert=foo %s &> %t &&
// RUN: grep -- '"-A" "foo" "-A" "foo"' %t &&
// RUN: xcc -### -S --classpath foo --classpath=foo %s &> %t &&
// RUN: xcc -ccc-no-clang -### -S --classpath foo --classpath=foo %s &> %t &&
// RUN: grep -- '"-fclasspath=foo" "-fclasspath=foo"' %t &&
// RUN: true

View File

@ -1,11 +1,11 @@
// Check that object files compiled with -mdynamic-no-pic can be
// linked.
//
// RUN: xcc -ccc-clang -m32 -mdynamic-no-pic %s -c -o %t.o &&
// RUN: xcc -ccc-clang -m32 %t.o -o %t &&
// RUN: xcc -m32 -mdynamic-no-pic %s -c -o %t.o &&
// RUN: xcc -m32 %t.o -o %t &&
// RUN: %t | grep "Hello, World" &&
// RUN: xcc -ccc-clang -m64 -mdynamic-no-pic %s -c -o %t.o &&
// RUN: xcc -ccc-clang -m64 %t.o -o %t &&
// RUN: xcc -m64 -mdynamic-no-pic %s -c -o %t.o &&
// RUN: xcc -m64 %t.o -o %t &&
// RUN: %t | grep "Hello, World" &&
// RUN: true

View File

@ -1,14 +1,14 @@
// 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: xcc -ccc-no-clang -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" ".*" "-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 &&
// RUN: xcc -ccc-host-bits 32 -ccc-host-machine i386 -ccc-host-system darwin -ccc-host-release 10.5.0 -### -v -E -dM -arch i386 -xobjective-c -c %s &> %t.opts &&
// RUN: xcc -ccc-no-clang -ccc-host-bits 32 -ccc-host-machine i386 -ccc-host-system darwin -ccc-host-release 10.5.0 -### -v -E -dM -arch i386 -xobjective-c -c %s &> %t.opts &&
// RUN: grep ' "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/cc1obj" "-E" "-quiet" "-v" "-D__DYNAMIC__" ".*" "-fPIC" "-mmacosx-version-min=10.6.5" "-mtune=core2" "-dM"' %t.opts &&
// RUN: xcc -ccc-host-bits 32 -ccc-host-machine i386 -ccc-host-system darwin -ccc-host-release 10.5.0 -### -m32 -S -x cpp-output %s &> %t.opts &&
// RUN: xcc -ccc-no-clang -ccc-host-bits 32 -ccc-host-machine i386 -ccc-host-system darwin -ccc-host-release 10.5.0 -### -m32 -S -x cpp-output %s &> %t.opts &&
// RUN: grep ' "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/cc1" "-fpreprocessed" ".*darwin-x86-cc1.m" "-fPIC" "-quiet" "-dumpbase" "darwin-x86-cc1.m" "-mmacosx-version-min=10.6.5" "-m32" "-mtune=core2" "-auxbase" "darwin-x86-cc1" "-o" ".*"' %t.opts &&
// RUN: xcc -ccc-host-bits 32 -ccc-host-machine i386 -ccc-host-system darwin -ccc-host-release 10.5.0 -### -x objective-c-header %s -o /tmp/x.gch &> %t.opts &&
// RUN: xcc -ccc-no-clang -ccc-host-bits 32 -ccc-host-machine i386 -ccc-host-system darwin -ccc-host-release 10.5.0 -### -x objective-c-header %s -o /tmp/x.gch &> %t.opts &&
// RUN: grep ' "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/cc1obj" "-quiet" "-D__DYNAMIC__" ".*darwin-x86-cc1.m" "-fPIC" "-quiet" "-dumpbase" "darwin-x86-cc1.m" "-mmacosx-version-min=10.6.5" "-mtune=core2" "-auxbase" ".*" "-o" "/dev/null" "--output-pch=" "/tmp/x.gch"' %t.opts &&
// RUN: true

View File

@ -1,8 +1,8 @@
// RUN: xcc -ccc-no-clang %s -o %t &&
// RUN: %t | grep "Hello, World" &&
// RUN: xcc -ccc-no-clang %s -o %t -pipe &&
// RUN: %t | grep "Hello, World" &&
// RUN: xcc %s -o %t &&
// RUN: %t | grep "Hello, World" &&
// RUN: xcc %s -o %t -pipe &&
// RUN: %t | grep "Hello, World" &&
// RUN: xcc -ccc-clang %s -o %t &&
// RUN: %t | grep "Hello, World"
int main() {

View File

@ -1,6 +1,6 @@
// RUN: xcc %s -o %t &&
// RUN: xcc -ccc-no-clang %s -o %t &&
// RUN: %t | grep "Hello, World" &&
// RUN: xcc -ccc-clang %s -o %t &&
// RUN: xcc %s -o %t &&
// RUN: %t | grep "Hello, World"
int main() {

View File

@ -1,7 +1,7 @@
// RUN: xcc -arch ppc -arch i386 -arch x86_64 %s -o %t &&
// RUN: xcc -ccc-no-clang -arch ppc -arch i386 -arch x86_64 %s -o %t &&
// RUN: %t | grep "Hello, World" &&
// RUN: xcc -pipe -arch ppc -arch i386 -arch x86_64 %s -o %t &&
// RUN: xcc -ccc-no-clang -pipe -arch ppc -arch i386 -arch x86_64 %s -o %t &&
// RUN: %t | grep "Hello, World" &&
// Check that multiple archs are handled properly.