diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-03-25 22:35:32 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-03-25 22:35:32 +0000 |
commit | b0982880c09a07147b5a9ad275393fedff13aad0 (patch) | |
tree | 971e146bcdd0e0216c57b4e56eb6976c89114f33 | |
parent | 8e7dafec4b70303dfaff95151cd06bfc5532720c (diff) |
Added hacked version of ccc script used to invoke the static analyzer. This
will gradually get pruned down, as it doesn't need to be as functional as
'ccc'.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@48806 91177308-0d34-0410-b5e6-96231b3b80d8
-rwxr-xr-x | utils/ccc-analyzer | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/utils/ccc-analyzer b/utils/ccc-analyzer new file mode 100755 index 0000000000..1b925165f4 --- /dev/null +++ b/utils/ccc-analyzer @@ -0,0 +1,220 @@ +#!/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:]) |