def ParseCurrentFile(): global parseLock global parseFile global parseContent global parseNeeded global parseLastFile global parseTus global parseScopeNames global parsingCurrentState with parseLock: if not parseNeeded: return fileToParse = parseFile contentToParse = parseContent parseNeeded = False parsingCurrentState = "Parsing %s" % fileToParse command = None try: if g_api is not None: command = g_api.get_file_args(fileToParse) except Exception as e: with parseLock: parsingCurrentState = str(e) return parsingStatePrefix = "" unsaved_files = [(fileToParse, contentToParse)] if command == None: if fileToParse.endswith(".h") or fileToParse.endswith(".hpp"): unsaved_files.append(("temporary_source.cpp", "#include \"%s\"\n#include <stdint.h>\nint main() { return 0; }\n" % fileToParse)) command = ["g++", "temporary_source.cpp"] parsingStatePrefix = "[HEADER] " elif fileToParse.endswith(".cpp") or fileToParse.endswith(".cc") or fileToParse.endswith(".c") or fileToParse.endswith(".cxx"): command = ["g++", fileToParse] parsingStatePrefix = "[SOURCE] " else: with parseLock: parsingCurrentState = "Can't find command line arguments" return index = Index.create() tu = index.parse(None, command + ["-I%s" % g_builtin_header_path], unsaved_files=unsaved_files, options = TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD) with parseLock: parseTus[fileToParse] = tu parsingCurrentState = "%sPartially parsed %s" % (parsingStatePrefix, fileToParse) scopeNames = [] scopeDepths = [] # create a new tu so that we don't walk it from two different threads index = Index.create() tu = index.parse(None, command + ["-I%s" % g_builtin_header_path], unsaved_files=unsaved_files, options = TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD) PopulateScopeNames(GetCursorForFile(tu, os.path.abspath(fileToParse)), scopeNames, scopeDepths) with parseLock: parseScopeNames[fileToParse] = scopeNames parsingCurrentState = "%sFully parsed %s" % (parsingStatePrefix, fileToParse)
def skip_if_no_clang(): """ Decorate your test with this to skip it if clang isn't present. """ try: Index.create() return skipIf(False, '') except LibclangError as error: return skip(str(error))
def clang_available(cls): """ Checks if Clang is available and ready to use. :return: True if Clang is available, a description of the error else. """ try: Index.create() return True except LibclangError as error: # pragma: no cover return str(error)
def clang_available(cls): """ Checks if Clang is available and ready to use. :return: True if Clang is available, a description of the error else. """ if get_distribution('libclang-py3').version != '3.4.0': return ClangBear.name + ' requires clang 3.4.0' try: # pragma nt: no cover Index.create() return True except LibclangError as error: # pragma: no cover return str(error)
def parseKernel(self, path: Path, name: str) -> Kernel: # Invoke Clang parser on kernel source translation_unit = Index.create().parse(path) # Collect root-level nodes nodes = translation_unit.cursor.get_children() # Search for kernel function node = safeFind( nodes, lambda n: n.kind == CursorKind.FUNCTION_DECL and n.spelling == name) if not node: raise ParseError(f'failed to locate kernel function {name}', parseLocation(node)) # Collect parameter types params = [] for n in node.get_children(): if n.kind == CursorKind.PARM_DECL: type = n.type.get_pointee() or n.type type = re.sub(r'\s*const\s*', '', type.spelling) param = (n.spelling, type) params.append(param) return Kernel(name, path, translation_unit.cursor, params)
def main(args): """ divides the monolithic mock file into different mock class files. """ decl_filename = args["decl"] impl_filename = args["impl"] idx = Index.create() impl_translation_unit = TranslationUnit.from_source( impl_filename, options=TranslationUnit.PARSE_SKIP_FUNCTION_BODIES) impl_includes = get_directives(impl_translation_unit) decl_translation_unit = idx.parse(decl_filename, ["-x", "c++"]) defns = class_definitions(decl_translation_unit.cursor) decl_includes = get_directives(decl_translation_unit) impl_cursors = class_implementations(impl_translation_unit.cursor) contents = read_file_contents(impl_filename) classname_to_impl = extract_implementations(impl_cursors, contents) classnames = [cursor.spelling for cursor in defns] for defn in defns: # writing {class}.h and {classname}.cc class_name, class_defn, deps = extract_definition(defn, classnames) includes = "" for name in deps: includes += '#include "{}.h"\n'.format(to_filename(name)) class_defn = decl_includes + includes + class_defn class_impl = "" if class_name not in classname_to_impl: print("Warning: empty class {}".format(class_name)) else: impl_include = impl_includes.replace(decl_filename, "{}.h".format(to_filename(class_name))) # we need to enclose methods with namespaces namespace_prefix, namespace_suffix = get_enclosing_namespace(defn) class_impl = impl_include + namespace_prefix + \ classname_to_impl[class_name] + namespace_suffix write_file_contents(class_name, class_defn, class_impl)
def run(c_src_filename): global conditionals, orig_file, mod_file global orig_lines, mod_lines index = Index.create() if not os.path.exists(c_src_filename): print('Problem opening file: ' + c_src_filename) return None orig_file = open(c_src_filename, 'r') mod_file = open(c_src_filename + '.instr', 'w+') orig_lines = orig_file.readlines() # Make the modified file the same as original file mod_lines = orig_lines tu = index.parse(c_src_filename) if not tu: print('Unable to load input') return None # Get list of all if, while and for statements get_ifs_and_whiles(tu.cursor) # Add instrumentation for all branching statements add_instrumentation() # Include stdio, just in case mod_lines = ['#include <stdio.h>\n'] + mod_lines # Finally write it to the instrumented replacement file mod_file.writelines(mod_lines) print([c.location.line for c in conditionals])
def __init__(self, lang, header, api_headers, check_all, args, verbose): index = Index.create() self.is_cpp = True if lang == 'c++' else False self.clang_args = ['-x', lang] self.translation_unit = index.parse(header, args + self.clang_args, options=1) if verbose: for diag in self.translation_unit.diagnostics: if diag.severity == 2: msg = '\033[93mWARNING : ' elif diag.severity == 3: msg = '\033[91mERROR : ' elif diag.severity == 4: msg = '\033[91mFATAL : ' msg += '{} at {} line {}, column {}\033[00m' print( msg.format(diag.spelling, diag.location.file, diag.location.line, diag.location.column)) self.api_headers = api_headers self.check_all = check_all self.enum_constant_decls = [] self.function_decls = [] self.var_decls = [] self.macro_defs = [] self.record_decls = [] self.namespaces = []
def _run_checker(checker, argv): global clang_library_file if argv.execution_mode == 'full': files = core.get_files(argv.location[0]) else: files = core.get_files(argv.location[0], checker.get_pattern_hint()) if not files: cnf = 'Could not find any problem related to ' cnf += checker.get_problem_type().lower() sys.stderr.write(cnf + '\n') else: print(__current_wip(checker, files)) visitor = Visitor(checker) if clang_library_file == '': clang_libraries = glob.glob('/usr/lib64/libclang.so*') + glob.glob('/usr/lib64/llvm/libclang.so') + glob.glob('/usr/lib*/*/libclang-[0-9]*.so.*') reverse_list = list(reversed(sorted(clang_libraries))) if reverse_list: clang_library_file = reverse_list[0] Config.set_library_file(clang_library_file) index = Index.create() for c_file in files: args = ["-ferror-limit=9999"] + _include_paths() root = index.parse(c_file, args=args, options=TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD) ReportBlocker.blocked_lines = [] visitor.visit(root.cursor, c_file)
def getBuiltinHeaderPath(library_path): index = Index.create() knownPaths = [ library_path + "/../lib/clang", # default value library_path + "/../clang", # gentoo library_path + "/clang", # opensuse library_path + "/", # Google "/usr/lib64/clang", # x86_64 (openSUSE, Fedora) "/usr/lib/clang" ] for path in knownPaths: try: files = os.listdir(path) if len(files) >= 1: files = sorted(files) subDir = files[-1] else: subDir = '.' path = path + "/" + subDir + "/include/" arg = "-I" + path if canFindBuiltinHeaders(index, [arg]): return path except Exception: pass return None
def main(): from clang.cindex import Index from pprint import pprint from optparse import OptionParser, OptionGroup global opts parser = OptionParser("usage: %prog [options] {filename} [clang-args*]") parser.add_option("", "--show-ids", dest="showIDs", help="Don't compute cursor IDs (very slow)", default=False) parser.add_option("", "--max-depth", dest="maxDepth", help="Limit cursor expansion to depth N", metavar="N", type=int, default=None) parser.disable_interspersed_args() (opts, args) = parser.parse_args() if len(args) == 0: parser.error('invalid number arguments') index = Index.create() tu = index.parse(None, args) if not tu: parser.error("unable to load input") pprint(('diags', map(get_diag_info, tu.diagnostics))) pprint(('nodes', get_info(tu.cursor)))
def main(): import sys from clang.cindex import Index, Config from io import open # TODO: Don't hard code the clang library path Config.set_library_path("/usr/lib/llvm-3.3/lib") if len(sys.argv) == 1 or len(sys.argv) > 3: usage() sys.exit(1) cppFile = str() overwrite = False if "-o" in sys.argv: overwrite = True cppFile = sys.argv[len(sys.argv) - 1] index = Index.create() transUnit = index.parse(cppFile) docBlocks = get_doc_comments(transUnit.cursor, cppFile) source = source_with_doc_blocks(cppFile, docBlocks) if overwrite: with open(cppFile, "w") as file: file.write(unicode(source)) else: sys.stdout.write(unicode(source))
def parse(root_path, filenames: List[str], clang_args: List[str], macros={}): index = [] for filename in filenames: print('Parsing ' + filename) group = '' with open(filename, 'r', encoding='utf-8') as strm: text = strm.read() m = re.search(r'@addtogroup\s+([a-zA-Z0-9_-]+)', text) if m: group = m.group(1) clangIndex = Index.create() tu = clangIndex.parse(None, [filename.replace('\\', '/')] + clang_args) if not tu: print('Unable to load input') exit(1) if len(tu.diagnostics): print('------------DIAGNOSTICS---------------') for diag in tu.diagnostics: print(diag) print('------------/DIAGNOSTICS---------------') count = len(index) parse_index(root_path, index, tu.cursor, tu.cursor.displayname, group, '', macros) print(' Found {} entities'.format(len(index) - count)) return index
def parse_files(list_of_files: List[str]) -> Tuple[Any, List[Any]]: """ Use Clang to parse the provided list of files. """ idx = Index.create() t_units = [] # type: List[Any] # To avoid parsing the files all the time, store the parsed ASTs # of each compilation unit in a cache. if not os.path.exists(".cache"): os.mkdir(".cache") for i, filename in enumerate(list_of_files): cache_filename = '.cache/' + os.path.basename(filename) + "_cache" # Have I parsed this file before? if os.path.exists(cache_filename): # Yes, load from cache try: t_units.append( TranslationUnit.from_ast_file(cache_filename, idx)) logging.info("[-] Loading cached AST for %s", filename) except TranslationUnitLoadError: # pragma: nocover logging.info("[-] %3d%% Parsing %s", (100 * (i + 1) / len(list_of_files)), filename) # pragma: nocover t_units.append(idx.parse(filename)) # pragma: nocover t_units[-1].save(cache_filename) # pragma: nocover else: # No, parse it now. logging.info("[-] %3d%% Parsing %s", (100 * (i + 1) / len(list_of_files)), filename) # ...to adapt to: .... filename, args=['-I ...', '-D ...'] t_units.append(idx.parse(filename)) t_units[-1].save(cache_filename) return idx, t_units
def test_get_children(): index = Index.create() tu = index.parse("t.c", unsaved_files=[("t.c", kInput)]) # Skip until past start_decl. it = tu.cursor.get_children() while it.next().spelling != "start_decl": pass tu_nodes = list(it) assert len(tu_nodes) == 3 assert tu_nodes[0].kind == CursorKind.STRUCT_DECL assert tu_nodes[0].spelling == "s0" assert tu_nodes[0].is_definition() == True assert tu_nodes[0].location.file.name == "t.c" assert tu_nodes[0].location.line == 4 assert tu_nodes[0].location.column == 8 s0_nodes = list(tu_nodes[0].get_children()) assert len(s0_nodes) == 2 assert s0_nodes[0].kind == CursorKind.FIELD_DECL assert s0_nodes[0].spelling == "a" assert s0_nodes[1].kind == CursorKind.FIELD_DECL assert s0_nodes[1].spelling == "b" assert tu_nodes[1].kind == CursorKind.STRUCT_DECL assert tu_nodes[1].spelling == "s1" assert tu_nodes[1].is_definition() == False assert tu_nodes[2].kind == CursorKind.FUNCTION_DECL assert tu_nodes[2].spelling == "f0" assert tu_nodes[2].is_definition() == True
def parse(self, filename): """ . reads 1 file . if there is a compilation error, print a warning . get root cursor and recurse . for each STRUCT_DECL, register a new struct type . for each UNION_DECL, register a new union type . for each TYPEDEF_DECL, register a new alias/typdef to the underlying type - underlying type is cursor.type.get_declaration() for Record . for each VAR_DECL, register a Variable . for each TYPEREF ?? """ index = Index.create() self.tu = index.parse(filename, self.flags, options=self.tu_options) if not self.tu: log.warning("unable to load input") return if len(self.tu.diagnostics) > 0: for x in self.tu.diagnostics: log.warning(x.spelling) if x.severity > 2: log.warning("Source code has some error. Please fix.") log.warning(x.spelling) # code.interact(local=locals()) break root = self.tu.cursor for node in root.get_children(): self.startElement(node) return
def parse(filename, clang_args=None): index = Index.create() tu = index.parse(filename, args=clang_args, options=TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD | TranslationUnit.PARSE_SKIP_FUNCTION_BODIES) errors = _clang_diagnostics(tu.diagnostics) top_level_comments, comments = _comment_extract(tu) # Empty comment with just children result = docstring.Docstring() for comment in top_level_comments: text = comment.spelling meta = _get_meta(comment) ds = docstring.TextDocstring(text=text, meta=meta) result.add_child(ds) for cursor in tu.cursor.get_children(): if cursor.hash in comments: result.add_children(_recursive_parse(comments, cursor, 0)) return result, errors
def main(): from clang.cindex import Index from pprint import pprint from optparse import OptionParser, OptionGroup global opts parser = OptionParser("usage: %prog [options] {filename} [clang-args*]") parser.add_option("", "--show-ids", dest="showIDs", help="Compute cursor IDs (very slow)", action="store_true", default=False) parser.add_option("", "--max-depth", dest="maxDepth", help="Limit cursor expansion to depth N", metavar="N", type=int, default=None) parser.disable_interspersed_args() (opts, args) = parser.parse_args() if len(args) == 0: parser.error('invalid number arguments') index = Index.create() tu = index.parse(None, args) if not tu: parser.error("unable to load input") pprint(('diags', map(get_diag_info, tu.diagnostics))) pprint(('nodes', get_info(tu.cursor)))
def get_tu(source, lang='c', all_warnings=False): """Obtain a translation unit from source and language. By default, the translation unit is created from source file "t.<ext>" where <ext> is the default file extension for the specified language. By default it is C, so "t.c" is the default file name. Supported languages are {c, cpp, objc}. all_warnings is a convenience argument to enable all compiler warnings. """ name = 't.c' if lang == 'cpp': name = 't.cpp' elif lang == 'objc': name = 't.m' elif lang != 'c': raise Exception('Unknown language: %s' % lang) args = [] if all_warnings: args = ['-Wall', '-Wextra'] index = Index.create() tu = index.parse(name, args=args, unsaved_files=[(name, source)]) assert tu is not None return tu
def main(): if len(sys.argv) < 2: sys.stderr.write('missing arguments (see -h for help)\n') sys.exit(1) if '-h' in sys.argv: sys.stderr.write('%s\n\n' % __doc__.strip()) sys.stderr.write('usage example: %s /usr/include/stdio.h | dot -Txlib\n' % sys.argv[0]) sys.exit(1) logging.basicConfig(level=logging.INFO) index = Index.create() tu = index.parse(None, sys.argv[1:]) rc = 0 if tu: emit_graph(sys.stdout, tu) log_map = { 0: logger.debug, 1: logger.info, 2: logger.warning, 3: logger.error, 4: logger.fatal } rc = 0 for d in tu.diagnostics: rc = max(d.severity, rc) log = log_map[d.severity] log('in file %s, line %d:%s' % (d.location.file.name, d.location.line, d.spelling)) else: rc = 1 sys.exit(rc)
def test_file(): index = Index.create() tu = index.parse('t.c', unsaved_files=[('t.c', "")]) file = File.from_name(tu, "t.c") assert str(file) == "t.c" assert file.name == "t.c" assert repr(file) == "<File: t.c>"
def get_lines_to_insert(files_funcs, call_name): lines = [] for f in files_funcs: filename, func_name = f index = Index.create() try: tu = index.parse(filename) if not tu: parser.error('unable to load input: ' + filename) func_node = get_func_node(tu.cursor, func_name) if func_node: call_line = get_function_call(func_node, call_name) if call_line: lines.append((filename, func_name, call_line)) else: print( 'Problem with file: %s caller function: %s callee function: %s' % (filename, func_name, call_name)) except Exception: print( 'Problem with file: %s caller function: %s callee function: %s' % (filename, func_name, call_name)) continue return lines
def get_tu(cpp_basename): cpp_file_path = os.path.join(kInputsDir, cpp_basename) print 'clang++ -c ' + ' '.join(extra_args) + \ ' ' + ' '.join(include_args) + ' ' + cpp_file_path index = Index.create() tu = index.parse(cpp_file_path, args=extra_args+include_args) return tu
def test_file(self): index = Index.create() tu = index.parse('t.c', unsaved_files = [('t.c', "")]) file = File.from_name(tu, "t.c") self.assertEqual(str(file), "t.c") self.assertEqual(file.name, "t.c") self.assertEqual(repr(file), "<File: t.c>")
def __init__(self, srcdir, files=None, filespattern="*.h", clangargs=('-x', 'c++'), pythonify_types=True): """ Default class constructor. :param `srcdir`: C/C++/ObjC source files directory path. :type `srcdir`: str :param `files`: C/C++/ObjC source files paths. :type `files`: str :param `clangargs`: Agruments passed to clang. :type `clangargs`: Sequence[str] :param `filespattern`: Unix shell like pattern for soure files :type `filespattern`: str :param `pythonify_types`: If set to True replace clang types with their python alternatives. :type `pythonify_types`: bool """ self.srcdir = srcdir self.clangargs = clangargs self.pythonify_types = pythonify_types if files is not None: self.fileslist = list(files) else: self.fileslist = glob_recursive(srcdir, filespattern) self._index = Index.create() self._pool = {} self._searchindex = {}
def test_parse_arguments(): path = os.path.join(kInputsDir, 'parse_arguments.c') index = Index.create() tu = TranslationUnit.from_source(path, ['-DDECL_ONE=hello', '-DDECL_TWO=hi'], index=index) spellings = [c.spelling for c in tu.cursor.get_children()] assert spellings[-2] == 'hello' assert spellings[-1] == 'hi'
def __init__(self): self.index = Index.create() self.ast = Object() self.mapping = { } super(Parser, self).__init__()
def __init__(self, lang, header, api_headers, check_all, args, verbose): index = Index.create() self.is_cpp = True if lang == 'c++' else False self.clang_args = ['-x', lang] self.translation_unit = index.parse(header, args + self.clang_args, options=1) if verbose: for diag in self.translation_unit.diagnostics: if diag.severity == 2: msg = '\033[93mWARNING : ' elif diag.severity == 3: msg = '\033[91mERROR : ' elif diag.severity == 4: msg = '\033[91mFATAL : ' msg += '{} at {} line {}, column {}\033[00m' print (msg.format(diag.spelling, diag.location.file, diag.location.line, diag.location.column)) self.api_headers = api_headers self.check_all = check_all self.enum_constant_decls = [] self.function_decls = [] self.var_decls = [] self.macro_defs = [] self.record_decls = [] self.namespaces = []
def test_unsaved_files_2(): import io index = Index.create() tu = TranslationUnit.from_source('fake.c', unsaved_files = [ ('fake.c', io.StringIO('int x;'))], index=index) spellings = [c.spelling for c in tu.cursor.get_children()] assert spellings[-1] == 'x'
def run(c_src_filename): global conditionals, orig_file, mod_file global orig_lines, mod_lines index = Index.create() if not os.path.exists(c_src_filename): print 'Problem opening file: ' + c_src_filename return None orig_file = open(c_src_filename, 'r') mod_file = open(c_src_filename+'.instr', 'w+') orig_lines = orig_file.readlines() # Make the modified file the same as original file mod_lines = orig_lines tu = index.parse(c_src_filename) if not tu: print 'Unable to load input' return None # Get list of all if, while and for statements get_ifs_and_whiles(tu.cursor) # Add instrumentation for all branching statements add_instrumentation() # Include stdio, just in case mod_lines = ['#include <stdio.h>\n'] + mod_lines # Finally write it to the instrumented replacement file mod_file.writelines(mod_lines) print [c.location.line for c in conditionals]
def getClangObject(self): """ need import clang.cindex and Index just return the cursor object, which points to the target function """ index = Index.create() if self.options: tu = index.parse(self.filename, args = self.options) else: tu = index.parse(self.filename) tmpCnt = 0 for obj in tu.cursor.get_children(): if obj.spelling == self.function: if tmpCnt != int(self.count): tmpCnt = tmpCnt + 1 continue #here we succeeded in finding self.obj = obj del index del tu return True # in this case: we find it is error(just return when reaching here) del index del tu return False
def main(): from clang.cindex import Index from pprint import pprint from optparse import OptionParser, OptionGroup # TODO: global opts parser = OptionParser("usage: %prog [options] {filename} [clang-args*]") parser.disable_interspersed_args() (opts, args) = parser.parse_args() if len(args) > 0: args.append('-c') args.append('-ObjC') args.append('-m64') args.append('-fobjc-arc') tu = Index.create().parse(None, args) if tu: create_go_source(tu.cursor) else: parser.error("unable to load input") else: parser.error('invalid number arguments')
def test_file(): index = Index.create() tu = index.parse('t.c', unsaved_files = [('t.c', "")]) file = File.from_name(tu, "t.c") assert str(file) == "t.c" assert file.name == "t.c" assert repr(file) == "<File: t.c>"
def test_code_complete(): index = Index.create() files = [ ( "fake.c", """ /// Aaa. int test1; /// Bbb. void test2(void); void f() { } """, ) ] tu = TranslationUnit.from_source( "fake.c", ["-std=c99"], unsaved_files=files, options=TranslationUnit.PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION, index=index, ) cr = tu.codeComplete("fake.c", 9, 1, unsaved_files=files, include_brief_comments=True) expected = [ "{'int', ResultType} | {'test1', TypedText} || Priority: 50 || Availability: Available || Brief comment: Aaa.", "{'void', ResultType} | {'test2', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 50 || Availability: Available || Brief comment: Bbb.", "{'return', TypedText} || Priority: 40 || Availability: Available || Brief comment: None", ] check_completion_results(cr, expected)
def test_location(): index = Index.create() tu = index.parse('t.c', unsaved_files = [('t.c',baseInput)]) for n in tu.cursor.get_children(): if n.spelling == 'one': assert_location(n.location,line=1,column=5,offset=4) if n.spelling == 'two': assert_location(n.location,line=2,column=5,offset=13) # adding a linebreak at top should keep columns same tu = index.parse('t.c', unsaved_files = [('t.c',"\n"+baseInput)]) for n in tu.cursor.get_children(): if n.spelling == 'one': assert_location(n.location,line=2,column=5,offset=5) if n.spelling == 'two': assert_location(n.location,line=3,column=5,offset=14) # adding a space should affect column on first line only tu = index.parse('t.c', unsaved_files = [('t.c'," "+baseInput)]) for n in tu.cursor.get_children(): if n.spelling == 'one': assert_location(n.location,line=1,column=6,offset=5) if n.spelling == 'two': assert_location(n.location,line=2,column=5,offset=14)
def test_a_struct(): index = Index.create() tu = index.parse('t.c', unsaved_files=[('t.c', kInput)]) for n in tu.cursor.get_children(): if n.spelling == 'teststruct': fields = list(n.get_children()) assert all(x.kind == CursorKind.FIELD_DECL for x in fields) assert fields[0].spelling == 'a' assert not fields[0].type.is_const_qualified() assert fields[0].type.kind == TypeKind.INT assert fields[0].type.get_canonical().kind == TypeKind.INT assert fields[1].spelling == 'b' assert not fields[1].type.is_const_qualified() assert fields[1].type.kind == TypeKind.TYPEDEF assert fields[1].type.get_canonical().kind == TypeKind.INT assert fields[1].type.get_declaration().spelling == 'I' assert fields[2].spelling == 'c' assert not fields[2].type.is_const_qualified() assert fields[2].type.kind == TypeKind.LONG assert fields[2].type.get_canonical().kind == TypeKind.LONG assert fields[3].spelling == 'd' assert not fields[3].type.is_const_qualified() assert fields[3].type.kind == TypeKind.ULONG assert fields[3].type.get_canonical().kind == TypeKind.ULONG assert fields[4].spelling == 'e' assert not fields[4].type.is_const_qualified() assert fields[4].type.kind == TypeKind.LONG assert fields[4].type.get_canonical().kind == TypeKind.LONG assert fields[5].spelling == 'f' assert fields[5].type.is_const_qualified() assert fields[5].type.kind == TypeKind.INT assert fields[5].type.get_canonical().kind == TypeKind.INT assert fields[6].spelling == 'g' assert not fields[6].type.is_const_qualified() assert fields[6].type.kind == TypeKind.POINTER assert fields[6].type.get_pointee().kind == TypeKind.INT assert fields[7].spelling == 'h' assert not fields[7].type.is_const_qualified() assert fields[7].type.kind == TypeKind.POINTER assert fields[7].type.get_pointee().kind == TypeKind.POINTER assert fields[7].type.get_pointee().get_pointee( ).kind == TypeKind.POINTER assert fields[7].type.get_pointee().get_pointee().get_pointee( ).kind == TypeKind.INT break else: assert False, "Didn't find teststruct??"
def __init__(self, compiler_args): self.index = Index.create() self.compiler_args = compiler_args self.ignore = frozenset() self.file_extensions = tuple() self.forbidden = frozenset() self.allowed = {} self.system_includes = self._load_system_includes()
def __parse(self, args): tmp_file = b"~.hpp" return Index.create(excludeDecls = True).parse( path = tmp_file , args = args , unsaved_files = [(tmp_file, bytes(self.includes, self.encode))] , options = TranslationUnit.PARSE_SKIP_FUNCTION_BODIES | TranslationUnit.PARSE_INCOMPLETE )
def __init__(self): if env.has_key('TM_PROJECT_DIRECTORY'): self.project_dir = env['TM_PROJECT_DIRECTORY'] else: self.project_dir = "." self.index = Index.create() self.type_kinds = set([CursorKind.STRUCT_DECL, CursorKind.CLASS_DECL, CursorKind.CLASS_TEMPLATE,CursorKind.TYPEDEF_DECL])
def test_reparse_arguments(): path = os.path.join(kInputsDir, 'parse_arguments.c') index = Index.create() tu = TranslationUnit.from_source(path, ['-DDECL_ONE=hello', '-DDECL_TWO=hi'], index=index) tu.reparse() spellings = [c.spelling for c in tu.cursor.get_children()] assert spellings[-2] == 'hello' assert spellings[-1] == 'hi'
def test_fail_from_ast_file(): path = os.path.join(kInputsDir, 'non-existent.ast') try: index = Index.create() tu = TranslationUnit.from_ast_file(path, index=index) except TranslationUnitLoadError: tu = None assert tu == None
def initClangComplete(clang_complete_flags, clang_compilation_database, library_path): global index debug = int(vim.eval("g:clang_debug")) == 1 quiet = int(vim.eval("g:clang_quiet")) == 1 if library_path: if os.path.isdir(library_path): Config.set_library_path(library_path) else: Config.set_library_file(library_path) Config.set_compatibility_check(False) try: index = Index.create() except Exception as e: if quiet: return 0 if library_path: suggestion = "Are you sure '%s' contains libclang?" % library_path else: suggestion = "Consider setting g:clang_library_path." if debug: exception_msg = str(e) else: exception_msg = '' print('''Loading libclang failed, completion won't be available. %s %s ''' % (suggestion, exception_msg)) return 0 global builtinHeaderPath builtinHeaderPath = None if not canFindBuiltinHeaders(index): builtinHeaderPath = getBuiltinHeaderPath(library_path) if not builtinHeaderPath: print("WARNING: libclang can not find the builtin includes.") print(" This will cause slow code completion.") print(" Please report the problem.") global translationUnits translationUnits = dict() global complete_flags complete_flags = int(clang_complete_flags) global compilation_database if clang_compilation_database != '': compilation_database = CompilationDatabase.fromDirectory( clang_compilation_database) else: compilation_database = None global libclangLock libclangLock = threading.Lock() return 1
def initClangComplete(clang_complete_flags, clang_compilation_database, library_path): global index debug = int(vim.eval("g:clang_debug")) == 1 quiet = int(vim.eval("g:clang_quiet")) == 1 if library_path: if os.path.isdir(library_path): Config.set_library_path(library_path) else: Config.set_library_file(library_path) Config.set_compatibility_check(False) try: index = Index.create() except Exception as e: if quiet: return 0 if library_path: suggestion = "Are you sure '%s' contains libclang?" % library_path else: suggestion = "Consider setting g:clang_library_path." if debug: exception_msg = str(e) else: exception_msg = '' print('''Loading libclang failed, completion won't be available. %s %s ''' % (suggestion, exception_msg)) return 0 global builtinHeaderPath builtinHeaderPath = None if not canFindBuiltinHeaders(index): builtinHeaderPath = getBuiltinHeaderPath(library_path) if not builtinHeaderPath: print("WARNING: libclang can not find the builtin includes.") print(" This will cause slow code completion.") print(" Please report the problem.") global translationUnits translationUnits = dict() global complete_flags complete_flags = int(clang_complete_flags) global compilation_database if clang_compilation_database != '': compilation_database = CompilationDatabase.fromDirectory(clang_compilation_database) else: compilation_database = None global libclangLock libclangLock = threading.Lock() return 1
def test_a_struct(): index = Index.create() tu = index.parse('t.c', unsaved_files = [('t.c',kInput)]) for n in tu.cursor.get_children(): if n.spelling == 'teststruct': fields = list(n.get_children()) assert all(x.kind == CursorKind.FIELD_DECL for x in fields) assert fields[0].spelling == 'a' assert not fields[0].type.is_const_qualified() assert fields[0].type.kind == TypeKind.INT assert fields[0].type.get_canonical().kind == TypeKind.INT assert fields[1].spelling == 'b' assert not fields[1].type.is_const_qualified() assert fields[1].type.kind == TypeKind.TYPEDEF assert fields[1].type.get_canonical().kind == TypeKind.INT assert fields[1].type.get_declaration().spelling == 'I' assert fields[2].spelling == 'c' assert not fields[2].type.is_const_qualified() assert fields[2].type.kind == TypeKind.LONG assert fields[2].type.get_canonical().kind == TypeKind.LONG assert fields[3].spelling == 'd' assert not fields[3].type.is_const_qualified() assert fields[3].type.kind == TypeKind.ULONG assert fields[3].type.get_canonical().kind == TypeKind.ULONG assert fields[4].spelling == 'e' assert not fields[4].type.is_const_qualified() assert fields[4].type.kind == TypeKind.LONG assert fields[4].type.get_canonical().kind == TypeKind.LONG assert fields[5].spelling == 'f' assert fields[5].type.is_const_qualified() assert fields[5].type.kind == TypeKind.INT assert fields[5].type.get_canonical().kind == TypeKind.INT assert fields[6].spelling == 'g' assert not fields[6].type.is_const_qualified() assert fields[6].type.kind == TypeKind.POINTER assert fields[6].type.get_pointee().kind == TypeKind.INT assert fields[7].spelling == 'h' assert not fields[7].type.is_const_qualified() assert fields[7].type.kind == TypeKind.POINTER assert fields[7].type.get_pointee().kind == TypeKind.POINTER assert fields[7].type.get_pointee().get_pointee().kind == TypeKind.POINTER assert fields[7].type.get_pointee().get_pointee().get_pointee().kind == TypeKind.INT break else: assert False, "Didn't find teststruct??"
def build(): cpp_file_path = os.path.join(kInputsDir, 'main.cpp') index = Index.create() tu = index.parse(cpp_file_path) G = pygraphviz.AGraph(directed=True) for this, parent in ir.each_inheritance_relation(tu.cursor): edge = (this, parent) G.add_edge(edge) return G
def __init__(self, source): opt = TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD self.filename = Path(source) self.index = Index.create() self.translation = self.index.parse(source, options=opt) self.printed_functions = set() self.define_map = {}
def parser(file_path, min_tokens): '''解析''' index = Index.create() tu = index.parse(file_path) AST_root_node = tu.cursor visit_root(AST_root_node, min_tokens)
def test_from_clang_fixit(self): joined_file = 'struct { int f0; }\nx = { f0 :1 };\n' file = joined_file.splitlines(True) fixed_file = ['struct { int f0; }\n', 'x = { .f0 = 1 };\n'] tu = Index.create().parse('t.c', unsaved_files=[('t.c', joined_file)]) fixit = tu.diagnostics[0].fixits[0] clang_fixed_file = Diff.from_clang_fixit(fixit, file).modified self.assertEqual(fixed_file, clang_fixed_file)
def __init__(self, filename, args=[]): self.filename = filename index = Index.create() tu = index.parse(filename, args) self.tu = tu self.enum_map = {} for v in self.kinds('ENUM_DECL'): e = TAIEnum(v) self.enum_map[e.typename] = e
def main(): # This script should be run using filters and only those nodes who match the # filter types will be processed. # # Example: # ./libclang.py CXX_METHOD FUNCTION_DECL filters = [getattr(CursorKind, arg) for arg in sys.argv] file_ext = vim.eval("expand('%:p:e')") ext = file_ext if file_ext else vim.eval('&filetype') workdir = vim.eval("expand('%:p:h')") try: args = vim.eval('g:doge_clang_args') except vim.error: args = [] lines = vim.eval("getline(line(1), line('$'))") current_line = int(vim.eval("line('.')")) # Normalize the expression by transforming everything into 1 line. opener_pos = int(vim.eval("search('\m[{;]', 'n')")) normalized_expr = vim.eval( "join(map(getline(line('.'), {}), 'doge#helpers#trim(v:val)'), ' ')". format(opener_pos)) del lines[current_line - 1:opener_pos] lines.insert(current_line - 1, normalized_expr) # Save the lines to a temp file and parse that file. fd, filename = tempfile.mkstemp(dir=workdir, prefix='vim-doge-', suffix='.{}'.format(ext)) try: with os.fdopen(fd, 'w') as tmp: tmp.write('\n'.join(lines)) index = Index.create() tu = index.parse(filename, args=args) if tu: node = find_node(tu.cursor, current_line) if node and node.kind in filters: if node.kind == CursorKind.FIELD_DECL: print_field_decl(node) elif node.kind == CursorKind.STRUCT_DECL: print_struct_decl(node) elif node.kind in [ CursorKind.CONSTRUCTOR, CursorKind.CXX_METHOD, CursorKind.FUNCTION_DECL, CursorKind.FUNCTION_TEMPLATE, CursorKind.CLASS_TEMPLATE ]: print_func_decl(node) except Exception as e: print(e) finally: os.remove(filename)
def tokenize_code(code, mod_brace=True): from clang.cindex import Index index = Index.create() tu = index.parse('tmp.cpp', args=['-std=c++11'], unsaved_files=[('tmp.cpp', code)]) tokens = [ token.spelling for token in tu.get_tokens(extent=tu.cursor.extent) ] tokens = fix_char_string_tok(tokens, mod_brace) return tokens
def __init__(self, max_contexts_num, max_path_len, max_subtokens_num, max_ast_depth, out_path): self.validate = False self.save_buffer_size = 1000 self.out_path = out_path self.max_subtokens_num = max_subtokens_num self.max_contexts_num = max_contexts_num self.max_path_len = max_path_len self.max_ast_depth = max_ast_depth self.index = Index.create() self.samples = set() self.header_only_functions = set()
def __init__(self, filepath): self.filepath = filepath self.index = Index.create() # NOTE: for avoid search extra include files # NOTE: Maybe, system-header-prefix is not needed? # NOTE: If you want to see the help of clang index parser, add '--help' options to below list # args = ['-nobuiltininc', '-nostdinc++', '--system-header-prefix=".*"'] args = ['-nobuiltininc'] self.tu = self.index.parse("", [filepath, *args]) if not self.tu: parser.error("unable to load input")
def __init__(self): # from ctypes.util import find_library # print(find_library("clang")) # if (os.path.exists("/usr/lib/llvm-3.9/lib/libclang-3.9.1.so")): # Config.set_library_file("/usr/lib/llvm-3.9/lib/libclang-3.9.1.so") # if (os.path.exists("/usr/lib/x86_64-linux-gnu/libclang-3.9.so")): # Config.set_library_file("/usr/lib/x86_64-linux-gnu/libclang-3.9.so") Config.library_file = "/usr/lib/x86_64-linux-gnu/libclang-3.9.so" # Config.set_library_file(find_library('clang')) self.index = Index.create()
def run(self): """ This bear is meant for debugging purposes relating to clang. It just prints out the whole AST for a file to the DEBUG channel. """ for filename, file in sorted(self.file_dict.items()): root = Index.create().parse( filename, options=TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD ).cursor self.print_node(root, filename)
def extract(self): protos = dict() for dirpath, dirnames, filenames in os.walk(self.srcdir): for fname in filenames: fpath = dirpath + "/" + fname fext = fname.split(".")[-1] if fext == "c" or fext == "h": index = Index.create() tu = index.parse(fpath) self.__clang_find_protos(tu.cursor, protos) return protos
def run( self, filename, file, clang_cli_options: typed_list(str) = None, ): """ Check code for syntactical or semantical problems using Clang. This bear supports automatic fixes. :param clang_cli_options: Any options that will be passed through to Clang. """ index = Index.create() diagnostics = index.parse(filename, args=clang_cli_options, unsaved_files=[(filename, ''.join(file)) ]).diagnostics for diag in diagnostics: severity = { 0: RESULT_SEVERITY.INFO, 1: RESULT_SEVERITY.INFO, 2: RESULT_SEVERITY.NORMAL, 3: RESULT_SEVERITY.MAJOR, 4: RESULT_SEVERITY.MAJOR }.get(diag.severity) affected_code = tuple( sourcerange_from_clang_range(clang_range) for clang_range in diag.ranges) diffs = None fixits = list(diag.fixits) if len(fixits) > 0: # FIXME: coala doesn't support choice of diffs, for now # append first one only, often there's only one anyway diffs = {filename: diff_from_clang_fixit(fixits[0], file)} # No affected code yet? Let's derive it from the fix! if len(affected_code) == 0: affected_code = diffs[filename].affected_code(filename) # Still no affected code? Position is the best we can get... if len(affected_code) == 0 and diag.location.file is not None: affected_code = (SourceRange.from_values( diag.location.file.name, diag.location.line, diag.location.column), ) yield Result(self, diag.spelling, severity=severity, affected_code=affected_code, diffs=diffs)