aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-03-25 22:35:32 +0000
committerTed Kremenek <kremenek@apple.com>2008-03-25 22:35:32 +0000
commitb0982880c09a07147b5a9ad275393fedff13aad0 (patch)
tree971e146bcdd0e0216c57b4e56eb6976c89114f33
parent8e7dafec4b70303dfaff95151cd06bfc5532720c (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-xutils/ccc-analyzer220
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:])