def dispatch_ctu(opts, continuation=run_analyzer): """ Execute only one phase of 2 phases of CTU if needed. """ ctu_config = opts['ctu'] # Recover namedtuple from json when coming from analyze_cc if not hasattr(ctu_config, 'collect'): ctu_config = CtuConfig(collect=ctu_config[0], analyze=ctu_config[1], dir=ctu_config[2], func_map_cmd=ctu_config[3]) opts['ctu'] = ctu_config if ctu_config.collect or ctu_config.analyze: assert ctu_config.collect != ctu_config.analyze if ctu_config.collect: return ctu_collect_phase(opts) if ctu_config.analyze: cwd = opts['directory'] cmd = [opts['clang'], '--analyze'] + opts['direct_args'] \ + opts['flags'] + [opts['file']] triarch = get_triple_arch(cmd, cwd) ctu_options = ['ctu-dir=' + os.path.join(ctu_config.dir), 'reanalyze-ctu-visited=true'] analyzer_options = prefix_with('-analyzer-config', ctu_options) direct_options = prefix_with('-Xanalyzer', analyzer_options) opts['direct_args'].extend(direct_options) return continuation(opts)
def ctu_collect_phase(opts): """ Preprocess source by generating all data needed by CTU analysis. """ def generate_ast(triple_arch): """ Generates ASTs for the current compilation command. """ args = opts['direct_args'] + opts['flags'] ast_joined_path = os.path.join(opts['ctu'].dir, triple_arch, 'ast', os.path.realpath(opts['file'])[1:] + '.ast') ast_path = os.path.abspath(ast_joined_path) ast_dir = os.path.dirname(ast_path) if not os.path.isdir(ast_dir): try: os.makedirs(ast_dir) except OSError: # In case an other process already created it. pass ast_command = [opts['clang'], '-emit-ast'] ast_command.extend(args) ast_command.append('-w') ast_command.append(opts['file']) ast_command.append('-o') ast_command.append(ast_path) logging.debug("Generating AST using '%s'", ast_command) run_command(ast_command, cwd=opts['directory']) def map_extdefs(triple_arch): """ Generate external definition map file for the current source. """ args = opts['direct_args'] + opts['flags'] extdefmap_command = [opts['ctu'].extdef_map_cmd] extdefmap_command.append(opts['file']) extdefmap_command.append('--') extdefmap_command.extend(args) logging.debug("Generating external definition map using '%s'", extdefmap_command) extdef_src_list = run_command(extdefmap_command, cwd=opts['directory']) extdef_ast_list = extdef_map_list_src_to_ast(extdef_src_list) extern_defs_map_folder = os.path.join(opts['ctu'].dir, triple_arch, CTU_TEMP_DEFMAP_FOLDER) if not os.path.isdir(extern_defs_map_folder): try: os.makedirs(extern_defs_map_folder) except OSError: # In case an other process already created it. pass if extdef_ast_list: with tempfile.NamedTemporaryFile(mode='w', dir=extern_defs_map_folder, delete=False) as out_file: out_file.write("\n".join(extdef_ast_list) + "\n") cwd = opts['directory'] cmd = [opts['clang'], '--analyze'] + opts['direct_args'] + opts['flags'] \ + [opts['file']] triple_arch = get_triple_arch(cmd, cwd) generate_ast(triple_arch) map_extdefs(triple_arch)
def dispatch_ctu(opts, continuation=run_analyzer): """ Execute only one phase of 2 phases of CTU if needed. """ ctu_config = opts['ctu'] if ctu_config.collect or ctu_config.analyze: assert ctu_config.collect != ctu_config.analyze if ctu_config.collect: return ctu_collect_phase(opts) if ctu_config.analyze: cwd = opts['directory'] cmd = [opts['clang'], '--analyze'] + opts['direct_args'] \ + opts['flags'] + [opts['file']] triarch = get_triple_arch(cmd, cwd) ctu_options = ['ctu-dir=' + os.path.join(ctu_config.dir, triarch), 'experimental-enable-naive-ctu-analysis=true'] analyzer_options = prefix_with('-analyzer-config', ctu_options) direct_options = prefix_with('-Xanalyzer', analyzer_options) opts['direct_args'].extend(direct_options) return continuation(opts)
def test_arch_is_not_empty(self): arch = sut.get_triple_arch(['clang', '-E', '-'], '.') self.assertTrue(len(arch) > 0)