private BIR.BIR ProduceBIR(Configuration config) { BIR.BIR bir = null; using (var section = CreateSection("Producing BIR")) { // Assemble the producers var producers = new List <IBIRProducer>(); producers.Add(new Clang(Context)); // Run the producers foreach (var producer in producers) { if ((bir = producer.Produce(config)) != null) { break; } } if (bir == null) { return(null); } // Let the producers visit the final BIR foreach (var producer in producers) { producer.Visit(config, bir); } section.Done(); } return(bir); }
/// <summary> /// Transform the Clang AST to BIR /// </summary> private BIR.BIR TransformClangASTtoBIR(Configuration config, CXIndex index, TranslationUnit tu) { BIR.BIR bir = null; using (var section = CreateSection("Transforming Clang AST to BIR")) { using (var parser = new ClangParser(Context, index, tu)) { bir = parser.ProduceBIR(config); } if (bir != null) { section.Done(); } } return(bir); }
private bool ConsumeBIR(Configuration config, BIR.BIR bir) { bool success = true; using (var section = CreateSection("Consuming BIR")) { // Assemble the consumers var consumers = new List <IBIRConsumer>(); consumers.Add(new BifrostPlugin(Context)); // Let the producers visit the final BIR foreach (var consumer in consumers) { success &= consumer.Consume(config, bir); } section.Done(); } return(success); }
/// <inheritDoc /> public bool Consume(Configuration config, BIR.BIR bir) { using (var section = CreateSection("Generating Bifrost C++ plugin")) { var pluginH = GetPluginH(); var pluginCpp = GetPluginCpp(); // Create the macros var macros = CreateMacros(config, bir); // Expand the includes pluginH = ExpandIncludes(pluginH); // Expand selected macros pluginH = ExpandMacros(pluginH, macros); pluginCpp = ExpandMacros(pluginCpp, macros); // Write plugin to disk and format it WriteOutputs(config, pluginH, pluginCpp, macros); section.Done(); } return(true); }
/// <inheritDoc /> public void Visit(Configuration config, BIR.BIR bir) { }
/// <summary> /// Create the necessary macros /// </summary> private Dictionary <string, string> CreateMacros(Configuration config, BIR.BIR bir) { var pluginName = IO.MakeValidIdentifier(config.Plugin.Name); var pluginNamespace = IO.MakeValidIdentifier(string.IsNullOrEmpty(config.Plugin.Namespace) ? pluginName.ToLower() : config.Plugin.Namespace); var pluginCppFile = $"{pluginName}.cpp"; var pluginHFile = $"{pluginName}.h"; var pluginIdentifier = new List <string>(); var pluginStringToIdentifier = new List <string>(); var pluginIdentifierToFunctionName = new List <string>(); var pluginIdentifierToModule = new List <string>(); var includes = new HashSet <string>(); var module = new List <string>(); var moduleToString = new List <string>(); var hookModuleToModule = new Dictionary <string, string>(); var dslDefines = new List <(string, string)>(); foreach (var hook in bir.Hooks) { // Identifiers pluginIdentifier.Add($"{hook.Identifier}"); pluginStringToIdentifier.Add($"{{\"{hook.Identifier}\", Plugin::Identifier::{hook.Identifier}}}"); switch (hook.HookType) { case BIR.BIR.HookTypeEnum.CFunction: pluginIdentifierToFunctionName.Add($"\"{hook.CFunctionName}\""); break; case BIR.BIR.HookTypeEnum.MethodFunction: pluginIdentifierToFunctionName.Add($"\"\""); break; case BIR.BIR.HookTypeEnum.VTable: pluginIdentifierToFunctionName.Add($"\"\""); break; } // Includes foreach (var include in hook.Inputs) { includes.Add($"#include <{include}>"); } // Modules var moduleIdentifier = ""; if (hookModuleToModule.ContainsKey(hook.Module)) { moduleIdentifier = hookModuleToModule[hook.Module]; } else { moduleIdentifier = IO.MakeValidIdentifier(hook.Module); hookModuleToModule.Add(hook.Module, moduleIdentifier); module.Add(moduleIdentifier); moduleToString.Add(hook.Module); } pluginIdentifierToModule.Add($"Module::{moduleIdentifier}"); // DSL var postfix = $"{pluginNamespace}__{hook.Identifier}"; dslDefines.Add((null, $"\n// {hook.Identifier}")); dslDefines.Add(($"_bf_func_decl_ret_{postfix}", hook.ReturnType)); dslDefines.Add(($"_bf_func_decl_args_{postfix}", string.Join(", ", hook.Parameters.Select(p => p.Type + " " + p.Name)))); dslDefines.Add(($"_bf_func_{postfix}", $"(({hook.ReturnType} (*)(" + string.Join(", ", hook.Parameters.Select(p => p.Type)) + $"))::{pluginNamespace}::Plugin::Get().GetHook<::{pluginNamespace}::Plugin::Identifier::{hook.Identifier}>()->GetOriginal())")); dslDefines.Add(($"_bf_args_{postfix}", string.Join(", ", hook.Parameters.Select(p => p.Name)))); for (int i = 0; i < hook.Parameters.Count; ++i) { dslDefines.Add(($"_bf_arg_{i + 1}_{postfix}", hook.Parameters[i].Name)); } } var dslDef = string.Join("\n", dslDefines.Select(s => s.Item1 == null ? s.Item2 : $"#define {s.Item1} {s.Item2}")); return(new Dictionary <string, string>() { ["BIFROST_PLUGIN_H_FILE"] = pluginHFile, ["BIFROST_PLUGIN_CPP_FILE"] = pluginCppFile, ["BIFROST_PLUGIN_NAME"] = pluginName, ["BIFROST_PLUGIN_BASE"] = $"::{pluginNamespace}::Plugin", ["BIFROST_PLUGIN_INCLUDE"] = $"#include \"{pluginHFile}\"", ["BIFROST_NAMESPACE"] = pluginNamespace, ["BIFROST_PLUGIN_IDENTIFIER"] = string.Join(",", pluginIdentifier) + ",", ["BIFROST_PLUGIN_IDENTIFIER_TO_STRING"] = "\"" + string.Join("\",\"", pluginIdentifier) + "\",", ["BIFROST_PLUGIN_STRING_TO_IDENTIFIER"] = string.Join(",", pluginStringToIdentifier), ["BIFROST_PLUGIN_IDENTIFIER_TO_FUNCTION_NAME"] = string.Join(",", pluginIdentifierToFunctionName) + ",", ["BIFROST_PLUGIN_MODULE"] = string.Join(",", module) + ",", ["BIFROST_PLUGIN_MODULE_TO_STRING"] = "L\"" + string.Join("\",L\"", moduleToString) + "\",", ["BIFROST_PLUGIN_IDENTIFIER_TO_MODULE"] = string.Join(",", pluginIdentifierToModule) + ",", ["BIFROST_PLUGIN_DSL_DEF"] = dslDef, ["BIFROST_PLUGIN_INCLUDES"] = string.Join("\n", includes) }); }