--- /dev/null
+#!/usr/bin/env python
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+#
+# A reduced version of the 'ccc' script that is designed to handle off
+# actual compilation to gcc, but run the code passed to gcc through the
+# static analyzer.
+#
+##===----------------------------------------------------------------------===##
+
+import sys
+import subprocess
+import os
+
+def error(message):
+ print >> sys.stderr, 'ccc: ' + message
+ sys.exit(1)
+
+def run(args):
+ print >> sys.stderr, ' '.join(args)
+ print >> sys.stderr, '\n'
+ code = subprocess.call(args)
+ if code > 255:
+ code = 1
+ if code:
+ sys.exit(code)
+
+def preprocess(args):
+ command = 'clang -E'.split()
+ run(command + args)
+
+def compile(args):
+ print >> sys.stderr, '\n'
+ command = 'gcc'.split()
+ run(command + args)
+
+def remove_pch_extension(path):
+ i = path.rfind('.gch')
+ if i < 0:
+ return path
+ return path[:i]
+
+def analyze(args,language,output,files):
+ if language.find("c++") > 0:
+ return
+
+ print >> sys.stderr, ' '.join(['\n[LOCATION]:', os.getcwd(), '\n' ])
+
+ print_args = []
+
+ i = 0
+ while i < len(args):
+ print_args.append(''.join([ '\'', args[i], '\'' ]))
+ i += 1
+
+ if language.find("header") > 0:
+ target = remove_pch_extension(output)
+ command = 'cp'.split()
+ args = command + files + target.split()
+ else:
+ command = 'clang --grsimple'.split()
+ args = command + args
+
+ print >> sys.stderr, ' '.join(command+print_args)
+ print >> sys.stderr, '\n'
+ subprocess.call(args)
+
+def link(args):
+ command = 'gcc'.split()
+ run(command + args)
+
+def extension(path):
+ return path.split(".")[-1]
+
+def changeextension(path, newext):
+ i = path.rfind('.')
+ if i < 0:
+ return path
+ j = path.rfind('/', 0, i)
+ print path
+ if j < 0:
+ return path[:i] + "." + newext
+ return path[j+1:i] + "." + newext
+
+def inferlanguage(extension):
+ if extension == "c":
+ return "c"
+ elif extension in ["cpp", "cc"]:
+ return "c++"
+ elif extension == "i":
+ return "c-cpp-output"
+ elif extension == "m":
+ return "objective-c"
+ elif extension == "mi":
+ return "objective-c-cpp-output"
+ else:
+ return "unknown"
+
+def main(args):
+ old_args = args
+ action = 'link'
+ output = ''
+ compile_opts = [ ]
+ link_opts = [ ]
+ files = []
+ save_temps = 0
+ language = ''
+
+ i = 0
+ while i < len(args):
+ arg = args[i]
+
+ # Modes ccc supports
+ if arg == '-E':
+ action = 'preprocess'
+ if arg == '-c':
+ action = 'compile'
+ if arg.startswith('-print-prog-name'):
+ action = 'print-prog-name'
+ if arg == '-save-temps':
+ save_temps = 1
+
+ # Options with no arguments that should pass through
+ if arg in ['-v']:
+ compile_opts.append(arg)
+ link_opts.append(arg)
+
+ # Options with one argument that should be ignored
+ if arg in ['--param', '-arch', '-u']:
+ i += 1
+
+ # Prefix matches for the compile mode
+ if arg[:2] in ['-D', '-I', '-U', '-F']:
+ if not arg[2:]:
+ arg += args[i+1]
+ i += 1
+ compile_opts.append(arg)
+ if arg[:5] in ['-std=']:
+ compile_opts.append(arg)
+
+ # Options with one argument that should pass through
+ if arg in ['-include']:
+ compile_opts.append(arg)
+ compile_opts.append(args[i+1])
+ i += 1
+
+ # Prefix matches for the link mode
+ if arg[:2] in ['-l', '-L', '-O', '-F']:
+ if arg == '-O': arg = '-O1'
+ if arg == '-Os': arg = '-O2'
+ link_opts.append(arg)
+
+ # Options with one argument that should pass through
+ if arg in ['-framework']:
+ link_opts.append(arg)
+ link_opts.append(args[i+1])
+ i += 1
+
+ # Input files
+ if arg == '-filelist':
+ f = open(args[i+1])
+ for line in f:
+ files.append(line.strip())
+ f.close()
+ i += 1
+ if arg == '-x':
+ language = args[i+1]
+ i += 1
+ if arg[0] != '-':
+ files.append(arg)
+
+ # Output file
+ if arg == '-o':
+ output = args[i+1]
+ i += 1
+
+ i += 1
+
+ if action == 'print-prog-name':
+ # assume we can handle everything
+ print sys.argv[0]
+ return
+
+ if not files:
+ error('no input files')
+
+ if action == 'preprocess' or save_temps:
+ compile(args)
+
+ if action == 'compile' or save_temps:
+ for i, file in enumerate(files):
+ if not language:
+ language = inferlanguage(extension(file))
+ if save_temps and action != "compile":
+ # Need a temporary output file
+ coutput = changeextension(file, "o");
+ files[i] = coutput
+ elif not output:
+ coutput = changeextension(file, "o")
+ else:
+ coutput = output
+ analyze_args = [ file ]
+ if language != 'unknown':
+ analyze_args = analyze_args + [ '-x', language ]
+ analyze_args = analyze_args + compile_opts
+ analyze(analyze_args,language,output,files)
+ compile(args)
+
+
+ if action == 'link':
+ link(args)
+# analyze(link_opts)
+
+if __name__ == '__main__':
+ main(sys.argv[1:])