#
# Author: Olivier Dion <odion@efficios.com>
#
-# Auto-generate lttng-ust tracepoints for HIP.
+# Auto-generate lttng-ust wrappers for HIP.
#
# Require: python-clang (libclang)
import clang.cindex
def list_function_declarations(root):
+ """Return all function declarations under ROOT."""
return [
child
for child in root.get_children()
]
def get_system_include_paths():
-
+ """Get default system include paths from Clang."""
clang_args = ["clang", "-v", "-c", "-xc", "-o", "/dev/null", "/dev/null"]
paths = []
return paths
def parse_header(header_file, includes, defines):
-
+ """
+ Parse HEADER_FILE with Clang with INCLUDES (-I) and DEFINES (-D).
+ Return a cursor to root.
+ """
+
+ # For some reason, python-clang does not use all system include paths.
+ # Thus, compiler dependant headers, like stddef.h can not be found without
+ # this.
args = get_system_include_paths()
if includes:
return tu.cursor
def list_functions(root):
+ """Return the list of function declarations with `hip' prefix from ROOT."""
return [
fn
for fn in list_function_declarations(root)
]
def exact_definition(arg):
-
+ """Given a cursor ARG that is a function argument, return its exact definition."""
ct = arg.type.get_canonical()
if ct.kind == clang.cindex.TypeKind.POINTER:
pt = ct.get_pointee()
return f"{arg.type.spelling} {arg.spelling}"
def cast(arg):
+ """
+ Cast argument ARG to something that LTTng-UST can consume. Typically,
+ this is used to cast any pointer to void * because pointers are not
+ dereferenced anyway. Furthermore, array are also cast void *.
+ """
canon = arg.type.get_canonical()
if canon.kind == clang.cindex.TypeKind.POINTER:
return "void *"
return re.sub(r'\[[0-9]*\]', '*', canon.spelling)
-forbiden_list = set()
-
-extra_works = {
-}
-
def main():
+ # Extra works to do for functions.
+ #
+ # Format:
+ # key = str: function name ; e.g. hipMalloc
+ # value = str: C code ; e.g. printf("hello\n");
+ extra_works = {
+ }
+
parser = argparse.ArgumentParser(prog="gen-hip-wrappers")
parser.add_argument("api",
args = parser.parse_args()
+ # The set of function to not instrument.
+ forbiden_list = set()
+
if args.ignores:
with open(args.ignores, "r") as f:
for ignore in f.read().splitlines():
}
""")
+ # Void function are special because they do not return anything ..
void_fn_tpl = Template("""
static void lttng_${fn_name}(${fn_arguments})
{
}
""")
+ # Because C++ does not support designated initializer.
epilogue_tpl = Template("""
static void lttng_hip_install_wrappers(void)
{