From 87ebb72f02acc4374d587108a22e04ec0e7897d3 Mon Sep 17 00:00:00 2001 From: AbeZbm <1287589303@qq.com> Date: Mon, 22 Jul 2024 17:50:02 +0800 Subject: [PATCH] get context with template slowly --- clang-tools-extra/focxt/CMakeLists.txt | 5 +- clang-tools-extra/focxt/CoutContext.cpp | 507 -- clang-tools-extra/focxt/CoutContext.h | 80 - clang-tools-extra/focxt/Focxt.cpp | 421 +- clang-tools-extra/focxt/GetAllContext.cpp | 1433 ++--- clang-tools-extra/focxt/GetAllContext.h | 137 +- clang-tools-extra/focxt/GetAllDefinition.cpp | 5074 ++++++++++++++++++ clang-tools-extra/focxt/GetAllDefinition.h | 347 ++ clang-tools-extra/focxt/GetAllPath.cpp | 211 - clang-tools-extra/focxt/GetAllPath.h | 58 - clang-tools-extra/focxt/GetSignature.cpp | 125 +- clang-tools-extra/focxt/GetSignature.h | 4 +- clang-tools-extra/focxt/README.md | 14 +- 13 files changed, 6497 insertions(+), 1919 deletions(-) mode change 100644 => 100755 clang-tools-extra/focxt/CMakeLists.txt delete mode 100644 clang-tools-extra/focxt/CoutContext.cpp delete mode 100644 clang-tools-extra/focxt/CoutContext.h mode change 100644 => 100755 clang-tools-extra/focxt/Focxt.cpp mode change 100644 => 100755 clang-tools-extra/focxt/GetAllContext.cpp mode change 100644 => 100755 clang-tools-extra/focxt/GetAllContext.h create mode 100755 clang-tools-extra/focxt/GetAllDefinition.cpp create mode 100755 clang-tools-extra/focxt/GetAllDefinition.h delete mode 100644 clang-tools-extra/focxt/GetAllPath.cpp delete mode 100644 clang-tools-extra/focxt/GetAllPath.h mode change 100644 => 100755 clang-tools-extra/focxt/GetSignature.cpp mode change 100644 => 100755 clang-tools-extra/focxt/GetSignature.h mode change 100644 => 100755 clang-tools-extra/focxt/README.md diff --git a/clang-tools-extra/focxt/CMakeLists.txt b/clang-tools-extra/focxt/CMakeLists.txt old mode 100644 new mode 100755 index 0e9c7cd05645d..35c8a51764925 --- a/clang-tools-extra/focxt/CMakeLists.txt +++ b/clang-tools-extra/focxt/CMakeLists.txt @@ -1,4 +1,5 @@ set(LLVM_LINK_COMPONENTS support) +set(CMAKE_BUILD_TYPE Debug) include(FetchContent) @@ -7,10 +8,10 @@ FetchContent_MakeAvailable(json) add_clang_executable(focxt Focxt.cpp -GetAllPath.cpp +GetAllDefinition.cpp GetSignature.cpp GetAllContext.cpp -CoutContext.cpp +# CoutContext.cpp ) target_link_libraries(focxt diff --git a/clang-tools-extra/focxt/CoutContext.cpp b/clang-tools-extra/focxt/CoutContext.cpp deleted file mode 100644 index 9cd6cd851d606..0000000000000 --- a/clang-tools-extra/focxt/CoutContext.cpp +++ /dev/null @@ -1,507 +0,0 @@ -#include "CoutContext.h" - -// bool SignatureApplication::has(std::string file_path, std::string class_name, -// std::string signature) { -// for (auto file : files) { -// if (file.file_path == file_path) { -// for (auto a_class : file.classes) { -// if (a_class.class_name == class_name) { -// for (auto method : a_class.signatures) { -// if (method == signature) { -// return 1; -// } -// } -// return 0; -// } -// } -// return 0; -// } -// } -// return 0; -// } - -void SignatureApplication::append(std::string file_path, std::string class_name, - std::string signature) { - bool b = 0; - for (auto &file : files) { - if (file.file_path == file_path) { - for (auto &a_class : file.classes) { - if (a_class.class_name == class_name) { - a_class.signatures.insert(signature); - b = 1; - } - } - if (b == 0) { - SignatureClass new_signature_class; - new_signature_class.class_name = class_name; - new_signature_class.signatures.insert(signature); - file.classes.push_back(new_signature_class); - b = 1; - } - } - } - if (b == 0) { - SignatureFiles new_signature_file; - new_signature_file.file_path = file_path; - SignatureClass new_signature_class; - new_signature_class.class_name = class_name; - new_signature_class.signatures.insert(signature); - new_signature_file.classes.push_back(new_signature_class); - files.push_back(new_signature_file); - } -} - -json SignatureContext::get_j() { - // std::string file_path; - // std::string signature; - // std::string class_name; - // std::string function_name; - // std::vector includes; - // std::vector defines; - // std::vector global_vars; - // std::vector classes; - // std::vector functions; - json j = json::object(); - j[file_path] = json::object(); - j[file_path][class_name + "::" + function_name] = json::object(); - j[file_path][class_name + "::" + function_name][signature] = json::object(); - j[file_path][class_name + "::" + function_name][signature]["includes"] = - json::array(); - j[file_path][class_name + "::" + function_name][signature]["includes"] = - includes; - j[file_path][class_name + "::" + function_name][signature]["defines"] = - json::object(); - for (auto define : defines) { - j[file_path][class_name + "::" + function_name][signature]["defines"] - [define.define_name] = define.define_body; - } - for (auto var : global_vars) { - if (j[file_path][class_name + "::" + function_name][signature].find( - var.its_namespace) == - j[file_path][class_name + "::" + function_name][signature].end()) { - j[file_path][class_name + "::" + function_name][signature] - [var.its_namespace] = json::object(); - } - if (j[file_path][class_name + "::" + function_name][signature] - [var.its_namespace] - .find("global_vars") == - j[file_path][class_name + "::" + function_name][signature] - [var.its_namespace] - .end()) { - j[file_path][class_name + "::" + function_name][signature] - [var.its_namespace]["global_vars"] = json::array(); - } - j[file_path][class_name + "::" + function_name][signature] - [var.its_namespace]["global_vars"] - .push_back(var.global_var); - } - if (function_name != "TestBody") { - j[file_path][class_name + "::" + function_name][signature] - ["function_body"] = json::object(); - j[file_path][class_name + "::" + function_name][signature] - ["function_body"] = function_body; - } - for (int i = 0; i < classes.size(); i++) { - if (j[file_path][class_name + "::" + function_name][signature].find( - classes[i].its_namespace) == - j[file_path][class_name + "::" + function_name][signature].end()) { - j[file_path][class_name + "::" + function_name][signature] - [classes[i].its_namespace] = json::object(); - } - if (j[file_path][class_name + "::" + function_name][signature] - [classes[i].its_namespace] - .find("class") == j[file_path][class_name + "::" + function_name] - [signature][classes[i].its_namespace] - .end()) { - j[file_path][class_name + "::" + function_name][signature] - [classes[i].its_namespace]["class"] = json::object(); - } - j[file_path][class_name + "::" + function_name][signature] - [classes[i].its_namespace]["class"][classes[i].class_name] = - json::object(); - j[file_path][class_name + "::" + function_name][signature] - [classes[i].its_namespace]["class"][classes[i].class_name]["base_class"] = - classes[i].base_class; - j[file_path][class_name + "::" + function_name][signature] - [classes[i].its_namespace]["class"][classes[i].class_name]["constructor"] = - json::object(); - for (int k = 0; k < classes[i].constructors.size(); k++) { - j[file_path][class_name + "::" + function_name][signature] - [classes[i].its_namespace]["class"][classes[i].class_name]["constructor"] - [classes[i].constructors[k].signature] = json::object(); - j[file_path][class_name + "::" + function_name][signature] - [classes[i].its_namespace]["class"][classes[i].class_name]["constructor"] - [classes[i].constructors[k].signature]["function_body"] = - classes[i].constructors[k].function_body; - j[file_path][class_name + "::" + function_name][signature] - [classes[i].its_namespace]["class"][classes[i].class_name]["constructor"] - [classes[i].constructors[k].signature]["parameters"] = json::array(); - j[file_path][class_name + "::" + function_name][signature] - [classes[i].its_namespace]["class"][classes[i].class_name]["constructor"] - [classes[i].constructors[k].signature]["parameters"] = - classes[i].constructors[k].parameters; - } - j[file_path][class_name + "::" + function_name][signature] - [classes[i].its_namespace]["class"][classes[i].class_name]["destructor"] = - json::object(); - j[file_path][class_name + "::" + function_name][signature] - [classes[i].its_namespace]["class"][classes[i].class_name]["destructor"] - ["signature"] = classes[i].destructor.signature; - j[file_path][class_name + "::" + function_name][signature] - [classes[i].its_namespace]["class"][classes[i].class_name]["destructor"] - ["function_body"] = classes[i].destructor.function_body; - j[file_path][class_name + "::" + function_name][signature] - [classes[i].its_namespace]["class"][classes[i].class_name]["fields"] = - json::array(); - j[file_path][class_name + "::" + function_name][signature] - [classes[i].its_namespace]["class"][classes[i].class_name]["fields"] = - classes[i].fields; - j[file_path][class_name + "::" + function_name][signature] - [classes[i].its_namespace]["class"][classes[i].class_name]["methods"] = - json::object(); - for (int k = 0; k < classes[i].methods.size(); k++) { - j[file_path][class_name + "::" + function_name][signature] - [classes[i].its_namespace]["class"][classes[i].class_name]["methods"] - [classes[i].methods[k].signature] = json::object(); - j[file_path][class_name + "::" + function_name][signature] - [classes[i].its_namespace]["class"][classes[i].class_name]["methods"] - [classes[i].methods[k].signature]["function_body"] = - classes[i].methods[k].function_body; - j[file_path][class_name + "::" + function_name][signature] - [classes[i].its_namespace]["class"][classes[i].class_name]["methods"] - [classes[i].methods[k].signature]["parameters"] = json::array(); - j[file_path][class_name + "::" + function_name][signature] - [classes[i].its_namespace]["class"][classes[i].class_name]["methods"] - [classes[i].methods[k].signature]["parameters"] = - classes[i].methods[k].parameters; - j[file_path][class_name + "::" + function_name][signature] - [classes[i].its_namespace]["class"][classes[i].class_name]["methods"] - [classes[i].methods[k].signature]["return_type"] = - classes[i].methods[k].return_type; - } - } - for (int i = 0; i < functions.size(); i++) { - if (j[file_path][class_name + "::" + function_name][signature].find( - functions[i].its_namespace) == - j[file_path][class_name + "::" + function_name][signature].end()) { - j[file_path][class_name + "::" + function_name][signature] - [functions[i].its_namespace] = json::object(); - } - if (j[file_path][class_name + "::" + function_name][signature] - [functions[i].its_namespace] - .find("function") == - j[file_path][class_name + "::" + function_name][signature] - [functions[i].its_namespace] - .end()) { - j[file_path][class_name + "::" + function_name][signature] - [functions[i].its_namespace]["function"] = json::object(); - } - j[file_path][class_name + "::" + function_name][signature] - [functions[i].its_namespace]["function"][functions[i].signature] = - json::object(); - j[file_path][class_name + "::" + function_name][signature] - [functions[i].its_namespace]["function"][functions[i].signature] - ["function_body"] = functions[i].function_body; - j[file_path][class_name + "::" + function_name][signature] - [functions[i].its_namespace]["function"][functions[i].signature] - ["parameters"] = json::array(); - j[file_path][class_name + "::" + function_name][signature] - [functions[i].its_namespace]["function"][functions[i].signature] - ["parameters"] = functions[i].parameters; - j[file_path][class_name + "::" + function_name][signature] - [functions[i].its_namespace]["function"][functions[i].signature] - ["return_type"] = functions[i].return_type; - } - - return j; -} - -void get_all_applications(std::vector *applications, - std::vector &file_contexts, - std::string file_path, std::string class_name, - std::string signature) { - for (auto file_context : file_contexts) { - if (file_context.file_path == file_path) { - if (class_name == "class") { - for (auto function : file_context.functions) { - if (function.signature == signature) { - Application application; - application.class_name = class_name; - application.file_path = file_path; - application.signature = signature; - applications->push_back(application); - if (function.applications.size() > 0) { - for (auto application : function.applications) { - bool b = 1; - for (auto has_application : *applications) { - if (has_application == application) { - b = 0; - break; - } - } - if (b) { - get_all_applications( - applications, file_contexts, application.file_path, - application.class_name, application.signature); - } - } - } - } - } - } else { - for (auto a_class : file_context.classes) { - if (class_name == a_class.class_name) { - for (auto constructor : a_class.constructors) { - if (signature == constructor.signature) { - Application application; - application.class_name = class_name; - application.file_path = file_path; - application.signature = signature; - applications->push_back(application); - if (constructor.applications.size() > 0) { - for (auto application : constructor.applications) { - bool b = 1; - for (auto has_application : *applications) { - if (has_application == application) { - b = 0; - break; - } - } - if (b) { - get_all_applications( - applications, file_contexts, application.file_path, - application.class_name, application.signature); - } - } - } - } - } - auto destructor = a_class.destructor; - if (signature == destructor.signature) { - Application application; - application.class_name = class_name; - application.file_path = file_path; - application.signature = signature; - applications->push_back(application); - if (destructor.applications.size() > 0) { - for (auto application : destructor.applications) { - bool b = 1; - for (auto has_application : *applications) { - if (has_application == application) { - b = 0; - break; - } - } - if (b) { - get_all_applications( - applications, file_contexts, application.file_path, - application.class_name, application.signature); - } - } - } - } - for (auto method : a_class.methods) { - if (signature == method.signature) { - Application application; - application.class_name = class_name; - application.file_path = file_path; - application.signature = signature; - applications->push_back(application); - if (method.applications.size() > 0) { - for (auto application : method.applications) { - bool b = 1; - for (auto has_application : *applications) { - if (has_application == application) { - b = 0; - break; - } - } - if (b) { - get_all_applications( - applications, file_contexts, application.file_path, - application.class_name, application.signature); - } - } - } - } - } - break; - } - } - } - break; - } - } -} - -SignatureContext get_signature_context(std::vector &file_contexts, - std::string file_path, - std::string class_name, - std::string signature) { - for (auto file_context : file_contexts) { - if (file_context.file_path == file_path) { - std::vector *applications = new std::vector; - get_all_applications(applications, file_contexts, file_path, class_name, - signature); - SignatureApplication signature_application; - for (auto application : *applications) { - signature_application.append(application.file_path, - application.class_name, - application.signature); - } - // class SignatureContext { - // std::string file_path; - // std::string signature; - // std::string class_name; - // std::string function_name; - // std::vector includes; - // std::vector defines; - // std::vector global_vars; - // std::vector classes; - // std::vector functions; - // }; - SignatureContext signature_context; - signature_context.file_path = file_path; - signature_context.signature = signature; - signature_context.class_name = class_name; - for (auto file_context : file_contexts) { - if (file_context.file_path == file_path) { - signature_context.includes = file_context.includes; - signature_context.defines = file_context.defines; - signature_context.global_vars = file_context.global_vars; - if (class_name == "class") { - for (auto function : file_context.functions) { - if (function.signature == signature) { - signature_context.function_name = function.function_name; - signature_context.function_body = function.function_body; - break; - } - } - } else { - bool b = 0; - for (auto a_class : file_context.classes) { - if (a_class.class_name == class_name) { - for (auto method : a_class.constructors) { - if (method.signature == signature) { - signature_context.function_name = class_name; - signature_context.function_body = method.function_body; - b = 1; - break; - } - } - if (b == 0 && a_class.destructor.signature == signature) { - signature_context.function_name = "~" + class_name; - signature_context.function_body = - a_class.destructor.function_body; - } - for (auto method : a_class.methods) { - if (b == 1) { - break; - } - if (method.signature == signature) { - signature_context.function_name = method.method_name; - signature_context.function_body = method.function_body; - b = 1; - break; - } - } - break; - } - } - } - break; - } - } - for (auto file : signature_application.files) { - FileContext file_context; - for (int i = 0; i < file_contexts.size(); i++) { - if (file_contexts[i].file_path == file.file_path) { - file_context = file_contexts[i]; - break; - } - } - for (auto a_class : file.classes) { - if (a_class.class_name == "class") { - for (auto signature : a_class.signatures) { - signature_context.functions.push_back( - file_context.get_function(signature)); - } - } else { - int i = 0; - for (i; i < signature_context.classes.size(); i++) { - if (signature_context.classes[i].class_name == - a_class.class_name) { - break; - } - } - if (i == signature_context.classes.size()) { - signature_context.classes.push_back( - file_context.get_simple_class(a_class.class_name)); - } - for (auto signature : a_class.signatures) { - if (file_context.class_has_constructor(a_class.class_name, - signature)) { - for (int j = 0; - j < signature_context.classes[i].constructors.size(); - j++) { - if (signature_context.classes[i].constructors[j].signature == - signature) { - signature_context.classes[i].constructors[j] = - file_context.class_get_constructor(a_class.class_name, - signature); - } - } - } else if (file_context.class_has_destructor(a_class.class_name, - signature)) { - signature_context.classes[i].destructor = - file_context.class_get_destructor(a_class.class_name, - signature); - } else if (file_context.class_has_method(a_class.class_name, - signature)) { - for (int j = 0; j < signature_context.classes[i].methods.size(); - j++) { - if (signature_context.classes[i].methods[j].signature == - signature) { - signature_context.classes[i].methods[j] = - file_context.class_get_method(a_class.class_name, - signature); - } - } - } - } - } - } - } - delete applications; - return signature_context; - } - } -} - -std::vector get_may_tests(std::vector &file_contexts, - std::string class_name, - std::string function_name) { - std::vector ret; - for (auto file_context : file_contexts) { - std::vector file_may_test_macros = - file_context.get_may_test_macros(class_name, function_name); - for (auto test_macro : file_may_test_macros) { - ret.push_back(test_macro); - } - } - return ret; -} - -std::vector get_must_test(std::vector &file_contexts, - std::string second_parameter) { - std::vector ret; - for (auto file_context : file_contexts) { - std::vector file_must_test_macro = - file_context.get_must_test_macros(second_parameter); - if (file_must_test_macro.size() != 0) { - ret.push_back(file_must_test_macro[0]); - return ret; - } - } - return ret; -} \ No newline at end of file diff --git a/clang-tools-extra/focxt/CoutContext.h b/clang-tools-extra/focxt/CoutContext.h deleted file mode 100644 index 4319b0ad6831e..0000000000000 --- a/clang-tools-extra/focxt/CoutContext.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once -#include "GetAllContext.h" -#include "clang/AST/ASTConsumer.h" -#include "clang/AST/RecursiveASTVisitor.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" -#include "clang/ASTMatchers/ASTMatchers.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/FrontendAction.h" -#include "clang/Frontend/FrontendActions.h" -#include "clang/Lex/Lexer.h" -#include "clang/Tooling/CommonOptionsParser.h" -#include "clang/Tooling/Tooling.h" -#include "llvm/Support/CommandLine.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace fs = std::filesystem; -using json = nlohmann::json; -using namespace clang; -using namespace clang::ast_matchers; -using namespace clang::tooling; -using namespace llvm; - -struct SignatureClass { - std::string class_name; - std::set signatures; -}; - -struct SignatureFiles { - std::string file_path; - std::vector classes; -}; - -class SignatureApplication { -public: - std::vector files; - // bool has(std::string file_path, std::string class_name, - // std::string signature); - void append(std::string file_path, std::string class_name, - std::string signature); -}; - -class SignatureContext { -public: - std::string file_path; - std::string signature; - std::string class_name; - std::string function_name; - std::string function_body; - std::vector includes; - std::vector defines; - std::vector global_vars; - std::vector classes; - std::vector functions; - json get_j(); -}; - -void get_all_applications(std::vector *applications, - std::vector &file_contexts, - std::string file_path, std::string class_name, - std::string signature); - -SignatureContext get_signature_context(std::vector &file_contexts, - std::string file_path, - std::string class_name, - std::string signature); - -std::vector get_may_tests(std::vector &file_contexts, - std::string class_name, - std::string function_name); - -std::vector get_must_test(std::vector &file_contexts, - std::string second_parameter); \ No newline at end of file diff --git a/clang-tools-extra/focxt/Focxt.cpp b/clang-tools-extra/focxt/Focxt.cpp old mode 100644 new mode 100755 index 7696a6e70ccdf..bbcc7802cd425 --- a/clang-tools-extra/focxt/Focxt.cpp +++ b/clang-tools-extra/focxt/Focxt.cpp @@ -1,6 +1,5 @@ -#include "CoutContext.h" +// #include "CoutContext.h" #include "GetAllContext.h" -#include "GetAllPath.h" #include "nlohmann/json.hpp" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" @@ -9,6 +8,7 @@ #include "clang/Tooling/CommonOptionsParser.h" #include "clang/Tooling/Tooling.h" #include "llvm/Support/CommandLine.h" +#include #include #include #include @@ -56,9 +56,7 @@ cl::list TestList("must-test", cl::value_desc("string"), cl::cat(FocxtCategory)); -static std::vector file_paths; - -void get_all_files(std::string path) { +void get_all_files(std::string path, std::vector *file_paths) { for (auto entry : fs::directory_iterator(path)) { if (fs::is_regular_file(entry)) { std::string file_path = entry.path().string(); @@ -68,20 +66,28 @@ void get_all_files(std::string path) { if (extension == ".c" || extension == ".h" || extension == ".cpp" || extension == ".cxx" || extension == ".cc" || extension == ".C" || extension == ".hpp" || extension == ".hxx" || extension == ".hh") { - file_paths.push_back(entry.path().string()); + file_paths->push_back(entry.path().string()); } } } else if (fs::is_directory(entry)) { std::string directorty_entry = entry.path().string(); // std::cout << directorty_entry << std::endl; if (directorty_entry.find("/build") == std::string::npos && - directorty_entry.find("/llm_tests") == std::string::npos + directorty_entry.find("/llm_tests") == std::string::npos && + directorty_entry.find("/llm_coverage") == std::string::npos && + directorty_entry.find("/leetcode") == std::string::npos // && - // directorty_entry.find("test") == std::string::npos && - // directorty_entry.find("doc") == std::string::npos && - // directorty_entry.find("example") == std::string::npos + // directorty_entry.find("/test") == std::string::npos && + // directorty_entry.find("/doc") == std::string::npos && + // directorty_entry.find("/example") == std::string::npos && + // directorty_entry.find("/go") == std::string::npos && + // directorty_entry.find("/java") == std::string::npos && + // directorty_entry.find("/js") == std::string::npos && + // directorty_entry.find("/python") == std::string::npos && + // directorty_entry.find("/research") == std::string::npos && + // directorty_entry.find("/scripts") == std::string::npos ) { - get_all_files(entry.path()); + get_all_files(entry.path(), file_paths); } } } @@ -111,267 +117,26 @@ int main(int argc, const char **argv) { RealFunctionName = FunctionName; RealTestFlag = TestFlag; RealTestList = TestList; - get_all_files(RealProjectPath); - AllContextPaths *all_context_paths = new AllContextPaths; - for (auto file_path : file_paths) { - std::vector args{"context_path", "-p", RealBuildPath.c_str(), - file_path.c_str()}; - int argc = args.size(); - const char **argv = args.data(); - auto ExpectedParser = - CommonOptionsParser::create(argc, argv, FocxtCategory); - if (!ExpectedParser) { - errs() << ExpectedParser.takeError(); - return 1; - } - CommonOptionsParser &OptionParser = ExpectedParser.get(); - ClangTool Tool(OptionParser.getCompilations(), - OptionParser.getSourcePathList()); - get_all_paths(Tool, all_context_paths, RealProjectPath); - } - // all_context_paths->cout(); - std::vector file_contexts; - for (auto file_path : file_paths) { - std::vector args{"file_context", "-p", RealBuildPath.c_str(), - file_path.c_str()}; - int argc = args.size(); - const char **argv = args.data(); - auto ExpectedParser = - CommonOptionsParser::create(argc, argv, FocxtCategory); - if (!ExpectedParser) { - errs() << ExpectedParser.takeError(); - return 1; - } - CommonOptionsParser &OptionParser = ExpectedParser.get(); - ClangTool Tool(OptionParser.getCompilations(), - OptionParser.getSourcePathList()); - OneFileContext one_file_context(Tool, all_context_paths, RealProjectPath, - RealBuildPath, file_path); - file_contexts.push_back(one_file_context.get_file_context()); - } - json j; + std::vector *file_paths = new std::vector; + get_all_files(RealProjectPath, file_paths); + // for (auto file_path : *file_paths) { + // std::cout << file_path << std::endl; + // } + GetClassesAndFunctions get_classes_and_functions( + RealProjectPath, RealBuildPath, file_paths, FocxtCategory); + get_classes_and_functions.get_definitions(); + ClassesAndFunctions classes_and_functions = + get_classes_and_functions.get_classes_and_functions(); + // std::string output_path = RealProjectPath + "/output.txt"; + // freopen(output_path.c_str(), "w", stdout); + // classes_and_functions.cout(); + // freopen("/dev/tty", "w", stdout); + GetFileContext get_file_context(RealProjectPath, RealBuildPath, file_paths, + FocxtCategory, classes_and_functions); + get_file_context.get_all_file_contexts(); + FileContexts file_contexts = get_file_context.get_file_contexts(); + json j = file_contexts.get_j(TestFlag); // int i = 0; - for (auto file_context : file_contexts) { - // file_context.cout(); - // i++; - for (auto a_class : file_context.classes) { - for (auto constructor : a_class.constructors) { - if (constructor.function_body != "") { - json temp_j = json::object(); - SignatureContext constructor_signature_context = - get_signature_context(file_contexts, file_context.file_path, - a_class.class_name, constructor.signature); - json constructor_signatre_j = constructor_signature_context.get_j(); - temp_j[file_context.file_path] = json::object(); - temp_j[file_context.file_path] - [a_class.class_name + "::" + a_class.class_name] = - json::object(); - temp_j[file_context.file_path] - [a_class.class_name + "::" + a_class.class_name]["focal"] = - json::object(); - temp_j[file_context.file_path] - [a_class.class_name + "::" + a_class.class_name]["focal"] = - constructor_signatre_j[file_context.file_path] - [a_class.class_name + - "::" + a_class.class_name]; - if (RealTestFlag) { - std::vector may_tests = get_may_tests( - file_contexts, a_class.class_name, a_class.class_name); - temp_j[file_context.file_path] - [a_class.class_name + "::" + a_class.class_name]["may_test"] = - json::object(); - for (auto may_test : may_tests) { - std::pair> - may_test_class_signature = - all_context_paths->getTest(may_test.second_parameter); - SignatureContext may_test_signature_context = - get_signature_context(file_contexts, - may_test_class_signature.first, - may_test_class_signature.second.first, - may_test_class_signature.second.second); - json may_test_signature_j = may_test_signature_context.get_j(); - temp_j[file_context.file_path] - [a_class.class_name + "::" + a_class.class_name]["may_test"] - [may_test.second_parameter] = json::object(); - for (auto [key, value] : may_test_signature_j.items()) { - for (auto [key1, value1] : value.items()) { - temp_j[file_context.file_path] - [a_class.class_name + "::" + a_class.class_name] - ["may_test"][may_test.second_parameter] = value1; - } - } - temp_j[file_context.file_path] - [a_class.class_name + "::" + a_class.class_name]["may_test"] - [may_test.second_parameter]["test_macro"] = json::object(); - temp_j[file_context.file_path] - [a_class.class_name + "::" + a_class.class_name]["may_test"] - [may_test.second_parameter]["test_macro"] = - may_test.test_mecro; - } - } - j.merge_patch(temp_j); - } - } - if (a_class.destructor.function_body != "") { - std::string function_name = "~" + a_class.class_name; - json temp_j = json::object(); - SignatureContext destructor_signature_context = get_signature_context( - file_contexts, file_context.file_path, a_class.class_name, - a_class.destructor.signature); - json destructor_signatre_j = destructor_signature_context.get_j(); - temp_j[file_context.file_path] = json::object(); - temp_j[file_context.file_path] - [a_class.class_name + "::" + function_name] = json::object(); - temp_j[file_context.file_path] - [a_class.class_name + "::" + function_name]["focal"] = - json::object(); - temp_j[file_context.file_path][a_class.class_name + - "::" + function_name]["focal"] = - destructor_signatre_j[file_context.file_path] - [a_class.class_name + "::" + function_name]; - if (RealTestFlag) { - std::vector may_tests = - get_may_tests(file_contexts, a_class.class_name, function_name); - temp_j[file_context.file_path] - [a_class.class_name + "::" + function_name]["may_test"] = - json::object(); - for (auto may_test : may_tests) { - std::pair> - may_test_class_signature = - all_context_paths->getTest(may_test.second_parameter); - SignatureContext may_test_signature_context = get_signature_context( - file_contexts, may_test_class_signature.first, - may_test_class_signature.second.first, - may_test_class_signature.second.second); - json may_test_signature_j = may_test_signature_context.get_j(); - temp_j[file_context.file_path] - [a_class.class_name + "::" + function_name]["may_test"] - [may_test.second_parameter] = json::object(); - for (auto [key, value] : may_test_signature_j.items()) { - for (auto [key1, value1] : value.items()) { - temp_j[file_context.file_path] - [a_class.class_name + "::" + function_name]["may_test"] - [may_test.second_parameter] = value1; - } - } - temp_j[file_context.file_path] - [a_class.class_name + "::" + function_name]["may_test"] - [may_test.second_parameter]["test_macro"] = json::object(); - temp_j[file_context.file_path] - [a_class.class_name + "::" + function_name]["may_test"] - [may_test.second_parameter]["test_macro"] = - may_test.test_mecro; - } - } - j.merge_patch(temp_j); - } - for (auto method : a_class.methods) { - if (method.function_body != "") { - json temp_j = json::object(); - SignatureContext method_signature_context = - get_signature_context(file_contexts, file_context.file_path, - a_class.class_name, method.signature); - json method_signatre_j = method_signature_context.get_j(); - temp_j[file_context.file_path] = json::object(); - temp_j[file_context.file_path] - [a_class.class_name + "::" + method.method_name] = - json::object(); - temp_j[file_context.file_path] - [a_class.class_name + "::" + method.method_name]["focal"] = - json::object(); - temp_j[file_context.file_path][a_class.class_name + - "::" + method.method_name]["focal"] = - method_signatre_j[file_context.file_path] - [a_class.class_name + "::" + method.method_name]; - if (RealTestFlag) { - std::vector may_tests = get_may_tests( - file_contexts, a_class.class_name, method.method_name); - temp_j[file_context.file_path] - [a_class.class_name + "::" + method.method_name]["may_test"] = - json::object(); - for (auto may_test : may_tests) { - std::pair> - may_test_class_signature = - all_context_paths->getTest(may_test.second_parameter); - SignatureContext may_test_signature_context = - get_signature_context(file_contexts, - may_test_class_signature.first, - may_test_class_signature.second.first, - may_test_class_signature.second.second); - json may_test_signature_j = may_test_signature_context.get_j(); - temp_j[file_context.file_path] - [a_class.class_name + "::" + method.method_name]["may_test"] - [may_test.second_parameter] = json::object(); - for (auto [key, value] : may_test_signature_j.items()) { - for (auto [key1, value1] : value.items()) { - temp_j[file_context.file_path] - [a_class.class_name + "::" + method.method_name] - ["may_test"][may_test.second_parameter] = value1; - } - } - temp_j[file_context.file_path] - [a_class.class_name + "::" + method.method_name]["may_test"] - [may_test.second_parameter]["test_macro"] = json::object(); - temp_j[file_context.file_path] - [a_class.class_name + "::" + method.method_name]["may_test"] - [may_test.second_parameter]["test_macro"] = - may_test.test_mecro; - } - } - j.merge_patch(temp_j); - } - } - } - for (auto function : file_context.functions) { - if (function.function_body != "") { - json temp_j = json::object(); - SignatureContext function_signature_context = get_signature_context( - file_contexts, file_context.file_path, "class", function.signature); - json function_signatre_j = function_signature_context.get_j(); - temp_j[file_context.file_path] = json::object(); - temp_j[file_context.file_path]["class::" + function.function_name] = - json::object(); - temp_j[file_context.file_path]["class::" + function.function_name] - ["focal"] = json::object(); - temp_j[file_context.file_path]["class::" + function.function_name] - ["focal"] = - function_signatre_j[file_context.file_path] - ["class::" + function.function_name]; - if (RealTestFlag) { - std::vector may_tests = - get_may_tests(file_contexts, "class", function.function_name); - temp_j[file_context.file_path]["class::" + function.function_name] - ["may_test"] = json::object(); - for (auto may_test : may_tests) { - std::pair> - may_test_class_signature = - all_context_paths->getTest(may_test.second_parameter); - SignatureContext may_test_signature_context = get_signature_context( - file_contexts, may_test_class_signature.first, - may_test_class_signature.second.first, - may_test_class_signature.second.second); - json may_test_signature_j = may_test_signature_context.get_j(); - temp_j[file_context.file_path]["class::" + function.function_name] - ["may_test"][may_test.second_parameter] = json::object(); - for (auto [key, value] : may_test_signature_j.items()) { - for (auto [key1, value1] : value.items()) { - temp_j[file_context.file_path] - ["class::" + function.function_name]["may_test"] - [may_test.second_parameter] = value1; - } - } - temp_j[file_context.file_path]["class::" + function.function_name] - ["may_test"][may_test.second_parameter]["test_macro"] = - json::object(); - temp_j[file_context.file_path]["class::" + function.function_name] - ["may_test"][may_test.second_parameter]["test_macro"] = - may_test.test_mecro; - } - } - j.merge_patch(temp_j); - } - } - } // std::string json_path = RealProjectPath; // json_path = json_path + "/" + "allcontext" + ".json"; // std::ofstream outFile; @@ -409,61 +174,65 @@ int main(int argc, const char **argv) { outFile.open(json_path); outFile << cout_j.dump(4); outFile.close(); - } else { - std::string json_path = RealProjectPath; - std::string class_function_name; - if (RealClassName == "") { - class_function_name = "class::" + RealFunctionName; - json_path = json_path + "/" + "project_cxt" + ".json"; - } else { - class_function_name = RealClassName + "::" + RealFunctionName; - json_path = json_path + "/" + "project_cxt" + ".json "; - } - json cout_j = json::object(); - if (RealTestFlag) { - cout_j[RealFilePath] = json::object(); - cout_j[RealFilePath][class_function_name] = json::object(); - cout_j[RealFilePath][class_function_name]["may_test"] = json::object(); - cout_j[RealFilePath][class_function_name]["may_test"] = - j[RealFilePath][class_function_name]["may_test"]; - for (auto a_test : RealTestList) { - std::vector must_test = get_must_test(file_contexts, a_test); - if (must_test.size() != 0) { - std::pair> - must_test_class_signature = - all_context_paths->getTest(must_test[0].second_parameter); - cout_j[RealFilePath][class_function_name]["must_test"] = - json::object(); - SignatureContext must_test_signature_context = get_signature_context( - file_contexts, must_test_class_signature.first, - must_test_class_signature.second.first, - must_test_class_signature.second.second); - json must_test_signature_j = must_test_signature_context.get_j(); - for (auto [key, value] : must_test_signature_j.items()) { - for (auto [key1, value1] : value.items()) { - cout_j[RealFilePath][class_function_name]["must_test"] - [must_test[0].second_parameter] = json::object(); - cout_j[RealFilePath][class_function_name]["must_test"] - [must_test[0].second_parameter] = value1; - } - } - cout_j[RealFilePath][class_function_name]["must_test"] - [must_test[0].second_parameter]["test_macro"] = json::object(); - cout_j[RealFilePath][class_function_name]["must_test"] - [must_test[0].second_parameter]["test_macro"] = - must_test[0].test_mecro; - } - } - } - // cout_j["type"] = "function"; - cout_j[RealFilePath][class_function_name]["focal"] = json::object(); - cout_j[RealFilePath][class_function_name]["focal"] = - j[RealFilePath][class_function_name]["focal"]; - std::ofstream outFile; - outFile.open(json_path); - outFile << cout_j.dump(4); - outFile.close(); } - delete all_context_paths; + // else { + // std::string json_path = RealProjectPath; + // std::string class_function_name; + // if (RealClassName == "") { + // class_function_name = "class::" + RealFunctionName; + // json_path = json_path + "/" + "project_cxt" + ".json"; + // } else { + // class_function_name = RealClassName + "::" + RealFunctionName; + // json_path = json_path + "/" + "project_cxt" + ".json "; + // } + // json cout_j = json::object(); + // if (RealTestFlag) { + // cout_j[RealFilePath] = json::object(); + // cout_j[RealFilePath][class_function_name] = json::object(); + // cout_j[RealFilePath][class_function_name]["may_test"] = json::object(); + // cout_j[RealFilePath][class_function_name]["may_test"] = + // j[RealFilePath][class_function_name]["may_test"]; + // for (auto a_test : RealTestList) { + // std::vector must_test = get_must_test(file_contexts, + // a_test); if (must_test.size() != 0) { + // std::pair> + // must_test_class_signature = + // all_context_paths->getTest(must_test[0].second_parameter); + // cout_j[RealFilePath][class_function_name]["must_test"] = + // json::object(); + // SignatureContext must_test_signature_context = + // get_signature_context( + // file_contexts, must_test_class_signature.first, + // must_test_class_signature.second.first, + // must_test_class_signature.second.second); + // json must_test_signature_j = must_test_signature_context.get_j(); + // for (auto [key, value] : must_test_signature_j.items()) { + // for (auto [key1, value1] : value.items()) { + // cout_j[RealFilePath][class_function_name]["must_test"] + // [must_test[0].second_parameter] = json::object(); + // cout_j[RealFilePath][class_function_name]["must_test"] + // [must_test[0].second_parameter] = value1; + // } + // } + // cout_j[RealFilePath][class_function_name]["must_test"] + // [must_test[0].second_parameter]["test_macro"] = + // json::object(); + // cout_j[RealFilePath][class_function_name]["must_test"] + // [must_test[0].second_parameter]["test_macro"] = + // must_test[0].test_mecro; + // } + // } + // } + // // cout_j["type"] = "function"; + // cout_j[RealFilePath][class_function_name]["focal"] = json::object(); + // cout_j[RealFilePath][class_function_name]["focal"] = + // j[RealFilePath][class_function_name]["focal"]; + // std::ofstream outFile; + // outFile.open(json_path); + // outFile << cout_j.dump(4); + // outFile.close(); + // } + + delete file_paths; return 0; } \ No newline at end of file diff --git a/clang-tools-extra/focxt/GetAllContext.cpp b/clang-tools-extra/focxt/GetAllContext.cpp old mode 100644 new mode 100755 index c1fdd15da93c7..79895fe2e7357 --- a/clang-tools-extra/focxt/GetAllContext.cpp +++ b/clang-tools-extra/focxt/GetAllContext.cpp @@ -21,30 +21,22 @@ #include #include -AllContextPaths *gac_all_context_paths; +ClassesAndFunctions gac_classes_and_functions; std::string gac_project_path; -std::string gac_compilation_database_path; std::string gac_file_path; std::vector gac_defines; -std::vector gac_classes; -std::vector gac_functions; +std::vector gac_in_file_functions; +std::vector gac_alias; +std::vector gac_applications; +// std::vector gac_classes; +// std::vector gac_functions; -void OneFileContext::set_global_vars() { - ::gac_all_context_paths = all_context_paths; - ::gac_project_path = project_path; - ::gac_compilation_database_path = compilation_database_path; +void FileContext::set_global_vars() { + // ::gac_all_context_paths = all_context_paths; ::gac_file_path = file_path; } -void applications_cout(std::vector &applications) { - std::cout << "applications:" << std::endl; - for (auto application : applications) { - std::cout << application.file_path << " " << application.class_name << " " - << application.signature << std::endl; - } -} - -void OneFileContext::get_includes() { +void FileContext::get_includes() { std::ifstream file(file_path); if (!file.is_open()) { std::cerr << "Unable to open the focal file!" << "\n"; @@ -57,14 +49,14 @@ void OneFileContext::get_includes() { if (start != std::string::npos && end != std::string::npos && start < end) { std::string header = line.substr(start, end - start); - file_context.includes.push_back(header); + includes.push_back(header); } } } file.close(); } -void OneFileContext::get_test_macros() { +void FileContext::get_test_macros() { std::ifstream file(file_path); if (!file.is_open()) { std::cerr << "Unable to open the focal file!" << "\n"; @@ -99,9 +91,11 @@ void OneFileContext::get_test_macros() { line.find(")") != std::string::npos) { key = line.substr(line.find_first_of(',') + 1, line.find_first_of(')') - line.find_first_of(',') - 1); - key = key.substr(key.find_first_not_of(' '), - key.find_last_of(' ') - key.find_first_not_of(' ')); - is_inside_test_function = true; + if (key != "") { + key = key.substr(key.find_first_not_of(' '), + key.find_last_of(' ') - key.find_first_not_of(' ')); + is_inside_test_function = true; + } } if (is_inside_test_function) { if (n == 0 && line.find('{') == std::string::npos) { @@ -118,7 +112,7 @@ void OneFileContext::get_test_macros() { } if (n == 0) { TestMacro a_test_macro = {key, a_macro}; - file_context.test_macros.push_back(a_test_macro); + test_macros.push_back(a_test_macro); is_inside_test_function = false; a_macro = ""; key = ""; @@ -177,15 +171,16 @@ class DefineGeterFrontendAction : public ASTFrontendAction { } }; -void OneFileContext::get_defines() { +void FileContext::get_defines() { ::gac_defines.clear(); Tool.run(newFrontendActionFactory().get()); - file_context.defines = ::gac_defines; + defines = ::gac_defines; } class GlobalVarMatchFinder : public MatchFinder::MatchCallback { private: std::vector global_vars; + std::vector applications; std::string focal_path; public: @@ -213,6 +208,8 @@ class GlobalVarMatchFinder : public MatchFinder::MatchCallback { } else { global_var.its_namespace = namespaceDecl->getNameAsString() + "::" + global_var.its_namespace; + global_var.its_namespace = namespaceDecl->getNameAsString() + + "::" + global_var.its_namespace; } } decl_context = decl_context->getParent(); @@ -237,81 +234,108 @@ class GlobalVarMatchFinder : public MatchFinder::MatchCallback { } global_var.global_var = std::string(srcText_str); QualType qualType = varDecl->getType(); - if (qualType->isReferenceType()) { - qualType = qualType.getNonReferenceType(); - } - qualType = qualType.getUnqualifiedType(); - qualType = qualType.getCanonicalType(); + // if (qualType->isReferenceType()) { + // qualType = qualType.getNonReferenceType(); + // } + // qualType = qualType.getUnqualifiedType(); + // qualType = qualType.getNonReferenceType(); + // qualType = qualType.getCanonicalType(); // const clang::Type *typePtr = qualType.getTypePtr(); // while (const TypedefType *typedefType = // dyn_cast(typePtr)) { // const TypedefNameDecl *typedefDecl = typedefType->getDecl(); // qualType = typedefDecl->getUnderlyingType(); // } - std::string class_name = qualType.getAsString(); - if (gac_all_context_paths->hasClass(class_name)) { - std::vector> need_constructors = - gac_all_context_paths->getClassConstructor(class_name); - for (int i = 0; i < need_constructors.size(); i++) { - std::string function_name = class_name; - std::string signature = need_constructors[i].first; - std::string file_path = need_constructors[i].second; + std::vector types = + gac_classes_and_functions.get_application_classes( + qualType.getAsString()); + for (auto type : types) { + if (gac_classes_and_functions.has_class(type)) { Application application; - application.file_path = file_path; - application.class_name = class_name; - application.signature = signature; - global_var.applications.push_back(application); - } - std::pair need_destructor = - gac_all_context_paths->getClassDestructor(class_name); - if (need_destructor.first != "class") { - std::string function_name = "~" + class_name; - std::string signature = need_destructor.first; - std::string file_path = need_destructor.second; - Application application; - application.file_path = file_path; - application.class_name = class_name; - application.signature = signature; - global_var.applications.push_back(application); + application.class_name = type; + application.signature = ""; + applications.push_back(application); + std::vector need_constructors = + gac_classes_and_functions.get_constructors(type); + for (int i = 0; i < need_constructors.size(); i++) { + Application application; + application.class_name = type; + application.signature = need_constructors[i]; + applications.push_back(application); + } + std::string need_destructor = + gac_classes_and_functions.get_destructor(type); + if (need_destructor != "class") { + Application application; + application.class_name = type; + application.signature = need_destructor; + applications.push_back(application); + } } } + // Application application; + // application.class_name = class_name; + // application.signature = ""; + // applications.push_back(application); + // if (gac_classes_and_functions.has_class(class_name)) { + // std::vector need_constructors = + // gac_classes_and_functions.get_constructors(class_name); + // for (int i = 0; i < need_constructors.size(); i++) { + // Application application; + // application.class_name = class_name; + // application.signature = need_constructors[i]; + // applications.push_back(application); + // } + // std::string need_destructor = + // gac_classes_and_functions.get_destructor(class_name); + // if (need_destructor != "class") { + // Application application; + // application.class_name = class_name; + // application.signature = need_destructor; + // applications.push_back(application); + // } + // } if (varDecl->hasInit()) { const Expr *Expr = varDecl->getInit(); if (Expr) { if (const CallExpr *Call = dyn_cast(Expr)) { const FunctionDecl *Callee = Call->getDirectCallee(); if (Callee) { + Callee = Callee->getCanonicalDecl(); + if (Callee->getPrimaryTemplate()) { + Callee = Callee->getPrimaryTemplate()->getTemplatedDecl(); + } + // Callee->dump(); + if (Callee->getTemplateInstantiationPattern()) { + Callee = Callee->getTemplateInstantiationPattern(); + // InstantiatedCallee->dump(); + } if (Callee->isCXXClassMember()) { const CXXRecordDecl *ParentClass = - dyn_cast(Callee->getParent()); + dyn_cast(Callee->getParent()) + ->getCanonicalDecl(); std::string class_name = ParentClass->getNameAsString(); std::string function_name = Callee->getNameAsString(); std::string signature = get_signature(Callee); // std::cout << class_name << std::endl; // std::cout << signature << std::endl; - if (gac_all_context_paths->hasClassMethodPath(class_name, - signature)) { - std::string file_path = - gac_all_context_paths->getClassMethodPath(class_name, - signature); + if (gac_classes_and_functions.has_function(class_name, + signature)) { Application application; - application.file_path = file_path; application.class_name = class_name; application.signature = signature; - global_var.applications.push_back(application); + applications.push_back(application); } } else { std::string function_name = Callee->getNameAsString(); std::string signature = get_signature(Callee); // std::cout << signature << std::endl; - if (gac_all_context_paths->hasFunctionPath(signature)) { - std::string file_path = - gac_all_context_paths->getFunctionPath(signature); + if (gac_classes_and_functions.has_function("class", + signature)) { Application application; - application.file_path = file_path; application.class_name = "class"; application.signature = signature; - global_var.applications.push_back(application); + applications.push_back(application); } } } @@ -334,127 +358,23 @@ class GlobalVarMatchFinder : public MatchFinder::MatchCallback { } const std::vector get_vars() { return global_vars; }; + const std::vector get_applications() { return applications; } }; DeclarationMatcher globalvarMatcher = varDecl(hasGlobalStorage()).bind("globalvars"); -void OneFileContext::get_global_vars() { +void FileContext::get_global_vars() { GlobalVarMatchFinder Printer(file_path); MatchFinder Finder; Finder.addMatcher(globalvarMatcher, &Printer); Tool.run(newFrontendActionFactory(&Finder).get()); - file_context.global_vars = Printer.get_vars(); -} - -class StmtVarFunctionVisitor - : public RecursiveASTVisitor { -private: - ASTContext *Context; - std::vector applications; - -public: - StmtVarFunctionVisitor(ASTContext *Context) : Context(Context) {} - bool VisitCallExpr(CallExpr *Call); - bool VisitVarDecl(VarDecl *Var); - std::vector get_applications(); -}; - -bool StmtVarFunctionVisitor::VisitCallExpr(CallExpr *Call) { - const FunctionDecl *Callee = Call->getDirectCallee(); - if (Callee) { - if (Callee->isCXXClassMember()) { - // std::string file_path; - // std::string class_name; - // std::string function_name; - // std::string signature; - const CXXRecordDecl *ParentClass = - dyn_cast(Callee->getParent()); - std::string class_name = ParentClass->getNameAsString(); - std::string function_name = Callee->getNameAsString(); - std::string signature = get_signature(Callee); - // std::cout << "Class " << class_name << " Method " << function_name - // << " Call" << std::endl; - // std::cout << class_name << std::endl; - // std::cout << signature << std::endl; - if (gac_all_context_paths->hasClassMethodPath(class_name, signature)) { - std::string file_path = - gac_all_context_paths->getClassMethodPath(class_name, signature); - Application application; - application.file_path = file_path; - application.class_name = class_name; - application.signature = signature; - applications.push_back(application); - } - } else { - // std::string file_path; - // std::string class_name; - // std::string function_name; - // std::string signature; - std::string function_name = Callee->getNameAsString(); - // std::cout << "Function Call " << function_name << std::endl; - std::string signature = get_signature(Callee); - // std::cout << signature << std::endl; - if (gac_all_context_paths->hasFunctionPath(signature)) { - std::string file_path = - gac_all_context_paths->getFunctionPath(signature); - Application application; - application.file_path = file_path; - application.class_name = "class"; - application.signature = signature; - applications.push_back(application); - } - } + global_vars = Printer.get_vars(); + std::vector global_vars_applications = + Printer.get_applications(); + for (auto application : global_vars_applications) { + applications.push_back(application); } - return true; -} - -bool StmtVarFunctionVisitor::VisitVarDecl(VarDecl *Var) { - if (Var) { - QualType qualType = Var->getType(); - if (qualType->isReferenceType()) { - qualType = qualType.getNonReferenceType(); - } - qualType = qualType.getUnqualifiedType(); - qualType = qualType.getCanonicalType(); - // const clang::Type *typePtr = qualType.getTypePtr(); - // while (const TypedefType *typedefType = dyn_cast(typePtr)) { - // const TypedefNameDecl *typedefDecl = typedefType->getDecl(); - // qualType = typedefDecl->getUnderlyingType(); - // } - std::string class_name = qualType.getAsString(); - if (gac_all_context_paths->hasClass(class_name)) { - std::vector> need_constructors = - gac_all_context_paths->getClassConstructor(class_name); - for (int i = 0; i < need_constructors.size(); i++) { - std::string function_name = class_name; - std::string signature = need_constructors[i].first; - std::string file_path = need_constructors[i].second; - Application application; - application.file_path = file_path; - application.class_name = class_name; - application.signature = signature; - applications.push_back(application); - } - std::pair need_destructor = - gac_all_context_paths->getClassDestructor(class_name); - if (need_destructor.first != "class") { - std::string function_name = "~" + class_name; - std::string signature = need_destructor.first; - std::string file_path = need_destructor.second; - Application application; - application.file_path = file_path; - application.class_name = class_name; - application.signature = signature; - applications.push_back(application); - } - } - } - return true; -} - -std::vector StmtVarFunctionVisitor::get_applications() { - return applications; } class MethodFunctionVisitor @@ -462,6 +382,94 @@ class MethodFunctionVisitor public: explicit MethodFunctionVisitor(ASTContext *Context) : Context(Context) {} + bool VisitTypeAliasDecl(TypeAliasDecl *TypeAlias) { + clang::SourceLocation loc = TypeAlias->getLocation(); + clang::SourceManager &SM = Context->getSourceManager(); + clang::PresumedLoc presumedLoc = SM.getPresumedLoc(loc); + std::string file_path = presumedLoc.getFilename(); + if (file_path.find(gac_project_path) != std::string::npos) { + DeclContext *ParentContext = TypeAlias->getDeclContext(); + if (!isa(ParentContext)) { + InFileAlias alias; + alias.alias_name = TypeAlias->getNameAsString(); + alias.base_name = TypeAlias->getUnderlyingType().getAsString(); + const DeclContext *context = TypeAlias->getDeclContext(); + bool b = 0; + while (context) { + if (const NamespaceDecl *namespaceDecl = + dyn_cast(context)) { + b = 1; + if (alias.its_namespace == "") { + alias.its_namespace = namespaceDecl->getNameAsString(); + } else { + alias.its_namespace = + namespaceDecl->getNameAsString() + "::" + alias.its_namespace; + } + } + context = context->getParent(); + } + if (b == 0) { + alias.its_namespace = ""; + } + // std::cout << alias.alias_name << " " << alias.base_name << std::endl; + gac_alias.push_back(alias); + // QualType qualType = TypeAlias->getUnderlyingType(); + // qualType = qualType.getUnqualifiedType(); + // qualType = qualType.getNonReferenceType(); + // qualType = qualType.getCanonicalType(); + std::vector types = + gac_classes_and_functions.get_application_classes(alias.base_name); + for (auto type : types) { + if (gac_classes_and_functions.has_class(type)) { + Application application; + application.class_name = type; + application.signature = ""; + gac_applications.push_back(application); + std::vector need_constructors = + gac_classes_and_functions.get_constructors(type); + for (int i = 0; i < need_constructors.size(); i++) { + Application application; + application.class_name = type; + application.signature = need_constructors[i]; + gac_applications.push_back(application); + } + std::string need_destructor = + gac_classes_and_functions.get_destructor(type); + if (need_destructor != "class") { + Application application; + application.class_name = type; + application.signature = need_destructor; + gac_applications.push_back(application); + } + } + } + // Application application; + // application.class_name = class_name; + // application.signature = ""; + // gac_applications.push_back(application); + // if (gac_classes_and_functions.has_class(class_name)) { + // std::vector need_constructors = + // gac_classes_and_functions.get_constructors(class_name); + // for (int i = 0; i < need_constructors.size(); i++) { + // Application application; + // application.class_name = class_name; + // application.signature = need_constructors[i]; + // gac_applications.push_back(application); + // } + // std::string need_destructor = + // gac_classes_and_functions.get_destructor(class_name); + // if (need_destructor != "class") { + // Application application; + // application.class_name = class_name; + // application.signature = need_destructor; + // gac_applications.push_back(application); + // } + // } + } + } + return true; + } + bool VisitFunctionDecl(FunctionDecl *Func) { if (Func->isThisDeclarationADefinition()) { clang::SourceLocation loc = Func->getLocation(); @@ -469,11 +477,21 @@ class MethodFunctionVisitor clang::PresumedLoc presumedLoc = SM.getPresumedLoc(loc); std::string file_path = presumedLoc.getFilename(); if (file_path == gac_file_path) { - if (!isa(Func)) { - std::string function_name = Func->getNameAsString(); - std::string signature = get_signature(Func); - if (gac_all_context_paths->hasFunctionPath(signature)) { - Function function; + auto CanonicalFunc = Func->getCanonicalDecl(); + if (CanonicalFunc->getPrimaryTemplate()) { + CanonicalFunc = + CanonicalFunc->getPrimaryTemplate()->getTemplatedDecl(); + } + // Callee->dump(); + if (CanonicalFunc->getTemplateInstantiationPattern()) { + CanonicalFunc = CanonicalFunc->getTemplateInstantiationPattern(); + // InstantiatedCallee->dump(); + } + if (!isa(CanonicalFunc)) { + std::string function_name = CanonicalFunc->getNameAsString(); + std::string signature = get_signature(CanonicalFunc); + if (gac_classes_and_functions.has_function("class", signature)) { + InFileFunction in_file_function; // std::string function_name; // std::string signature; // std::string function_body; @@ -483,274 +501,44 @@ class MethodFunctionVisitor // std::string its_namespace; // std::cout << "Function Declaration " << function_name << // std::endl; - function.function_name = function_name; - function.signature = signature; - const SourceManager &sourceManager = Context->getSourceManager(); - SourceRange srcRange_r = Func->getReturnTypeSourceRange(); - srcRange_r.setEnd(Lexer::getLocForEndOfToken( - srcRange_r.getEnd(), 0, sourceManager, Context->getLangOpts())); - bool Invalid = false; - StringRef srcText_r = Lexer::getSourceText( - CharSourceRange::getTokenRange(srcRange_r), sourceManager, - Context->getLangOpts(), &Invalid); - function.return_type = std::string(srcText_r); - for (const ParmVarDecl *param : Func->parameters()) { - SourceRange srcRange_p = param->getSourceRange(); - srcRange_p.setEnd(Lexer::getLocForEndOfToken( - srcRange_p.getEnd(), 0, sourceManager, - Context->getLangOpts())); - StringRef srcText_p = Lexer::getSourceText( - CharSourceRange::getTokenRange(srcRange_p), sourceManager, - Context->getLangOpts(), &Invalid); - std::string srcText_str = std::string(srcText_p); - if (srcText_str[srcText_str.length() - 1] == ')' || - srcText_str[srcText_str.length() - 1] == ',' || - srcText_str[srcText_str.length() - 1] == ';') { - srcText_str.erase(srcText_str.length() - 1); - } - function.parameters.push_back(srcText_str); - } - SourceRange srcRange = Func->getSourceRange(); - srcRange.setEnd(Lexer::getLocForEndOfToken( - srcRange.getEnd(), 0, sourceManager, Context->getLangOpts())); - StringRef srcText = Lexer::getSourceText( - CharSourceRange::getTokenRange(srcRange), sourceManager, - Context->getLangOpts(), &Invalid); - function.function_body = srcText; - const DeclContext *context = Func->getDeclContext(); - bool b = 0; - while (context) { - if (const NamespaceDecl *namespaceDecl = - dyn_cast(context)) { - b = 1; - if (function.its_namespace == "") { - function.its_namespace = namespaceDecl->getNameAsString(); - } else { - function.its_namespace = namespaceDecl->getNameAsString() + - "::" + function.its_namespace; - } - } - context = context->getParent(); - } - if (b == 0) { - function.its_namespace = ""; - } - StmtVarFunctionVisitor function_stmt_visitor(Context); - function_stmt_visitor.TraverseStmt(Func->getBody()); - function.applications = function_stmt_visitor.get_applications(); - gac_functions.push_back(function); + in_file_function.class_name = "class"; + in_file_function.function_name = function_name; + in_file_function.signature = signature; + gac_in_file_functions.push_back(in_file_function); } } else { const CXXRecordDecl *ParentClass = - dyn_cast(Func->getParent()); + dyn_cast(CanonicalFunc->getParent()) + ->getCanonicalDecl(); std::string class_name = ParentClass->getNameAsString(); - if (gac_all_context_paths->hasClass(class_name)) { - // std::cout << "Class Declaration " << class_name << std::endl; - bool b = 0; - for (int i = 0; i < gac_classes.size(); i++) { - if (class_name == gac_classes[i].class_name) { - b = 1; - break; - } - } - if (b == 0) { - // std::string class_name; - // std::string base_class; - // std::vector constructors; - // Destructor destructor; - // std::vector fields; - // std::vector methods; - // std::string its_namespace; - Class a_class; - a_class.class_name = class_name; - if (ParentClass->getNumBases() > 0) { - a_class.base_class = - ParentClass->bases_begin()->getType().getAsString(); - } - const DeclContext *context = ParentClass->getDeclContext(); - bool b = 0; - while (context) { - if (const NamespaceDecl *namespaceDecl = - dyn_cast(context)) { - b = 1; - if (a_class.its_namespace == "") { - a_class.its_namespace = namespaceDecl->getNameAsString(); - } else { - a_class.its_namespace = namespaceDecl->getNameAsString() + - "::" + a_class.its_namespace; - } - } - context = context->getParent(); - } - if (b == 0) { - a_class.its_namespace = ""; - } - int i = 0; - for (const auto *decl : ParentClass->decls()) { - if (const CXXRecordDecl *Record = - dyn_cast(decl)) { - if (i == 0) { - continue; - } - const SourceManager &sourceManager = - Context->getSourceManager(); - SourceRange srcRange = Record->getSourceRange(); - srcRange.setEnd(Lexer::getLocForEndOfToken( - srcRange.getEnd(), 0, sourceManager, - Context->getLangOpts())); - bool Invalid = false; - StringRef srcText = Lexer::getSourceText( - CharSourceRange::getTokenRange(srcRange), sourceManager, - Context->getLangOpts(), &Invalid); - // std::cout << std::string(srcText) << std::endl; - std::string srcText_str = std::string(srcText); - if (srcText_str[srcText_str.length() - 1] == ';') { - srcText_str.erase(srcText_str.length() - 1); - } - if (Record->isClass()) { - if (srcText.find('{') != std::string::npos) { - srcText_str.erase(srcText_str.find_first_of('{')); - } - a_class.fields.push_back(srcText_str); - } else { - a_class.fields.push_back(srcText_str); - } - } else if (const FieldDecl *Field = dyn_cast(decl)) { - const SourceManager &sourceManager = - Context->getSourceManager(); - SourceRange srcRange = Field->getSourceRange(); - srcRange.setEnd(Lexer::getLocForEndOfToken( - srcRange.getEnd(), 0, sourceManager, - Context->getLangOpts())); - bool Invalid = false; - StringRef srcText = Lexer::getSourceText( - CharSourceRange::getTokenRange(srcRange), sourceManager, - Context->getLangOpts(), &Invalid); - // std::cout << std::string(srcText) << std::endl; - std::string srcText_str = std::string(srcText); - if (srcText_str[srcText_str.length() - 1] == ';') { - srcText_str.erase(srcText_str.length() - 1); - } - a_class.fields.push_back(srcText_str); - } else if (const EnumDecl *Enum = dyn_cast(decl)) { - const SourceManager &sourceManager = - Context->getSourceManager(); - SourceRange srcRange = Enum->getSourceRange(); - srcRange.setEnd(Lexer::getLocForEndOfToken( - srcRange.getEnd(), 0, sourceManager, - Context->getLangOpts())); - bool Invalid = false; - StringRef srcText = Lexer::getSourceText( - CharSourceRange::getTokenRange(srcRange), sourceManager, - Context->getLangOpts(), &Invalid); - // std::cout << std::string(srcText) << std::endl; - std::string srcText_str = std::string(srcText); - if (srcText_str[srcText_str.length() - 1] == ';') { - srcText_str.erase(srcText_str.length() - 1); - } - a_class.fields.push_back(srcText_str); - } - i++; - } - i = 1; - while (i < a_class.fields.size()) { - if (a_class.fields[i].substr( - 0, a_class.fields[i].find_last_of('}') + 1) == - a_class.fields[i - 1].substr( - 0, a_class.fields[i - 1].find_last_of('}') + 1)) { - a_class.fields.erase(a_class.fields.begin() + i - 1); - } else { - i++; - } - } - i = 0; - while (i < a_class.fields.size()) { - if (a_class.fields[i] == "union" || - a_class.fields[i] == "struct" || - a_class.fields[i] == "class" || - a_class.fields[i] == "enum") { - a_class.fields.erase(a_class.fields.begin() + i); - } else { - i++; - } - } - gac_classes.push_back(a_class); - } - int i = 0; - while (i < gac_classes.size()) { - if (class_name == gac_classes[i].class_name) { - break; - } - i++; - } - std::string signature = get_signature(Func); - if (gac_all_context_paths->hasClassMethodPath(class_name, - signature)) { - if (isa(Func)) { + if (gac_classes_and_functions.has_class(class_name)) { + // std::cout << "Class Declaration " << class_name << + // std::endl; + std::string signature = get_signature(CanonicalFunc); + if (gac_classes_and_functions.has_function(class_name, signature)) { + if (isa(CanonicalFunc)) { // std::cout << "Constructor Declaration " << class_name // << std::endl; // std::string signature; // std::string function_body; // std::vector parameters; // std::vector applications; - Constructor constructor; - const SourceManager &sourceManager = - Context->getSourceManager(); - bool Invalid = false; - constructor.signature = signature; - for (const ParmVarDecl *param : Func->parameters()) { - SourceRange srcRange_p = param->getSourceRange(); - srcRange_p.setEnd(Lexer::getLocForEndOfToken( - srcRange_p.getEnd(), 0, sourceManager, - Context->getLangOpts())); - StringRef srcText_p = Lexer::getSourceText( - CharSourceRange::getTokenRange(srcRange_p), sourceManager, - Context->getLangOpts(), &Invalid); - std::string srcText_str = std::string(srcText_p); - if (srcText_str[srcText_str.length() - 1] == ')' || - srcText_str[srcText_str.length() - 1] == ',' || - srcText_str[srcText_str.length() - 1] == ';') { - srcText_str.erase(srcText_str.length() - 1); - } - constructor.parameters.push_back(srcText_str); - } - SourceRange srcRange = Func->getSourceRange(); - srcRange.setEnd(Lexer::getLocForEndOfToken( - srcRange.getEnd(), 0, sourceManager, - Context->getLangOpts())); - StringRef srcText = Lexer::getSourceText( - CharSourceRange::getTokenRange(srcRange), sourceManager, - Context->getLangOpts(), &Invalid); - constructor.function_body = srcText; - StmtVarFunctionVisitor function_stmt_visitor(Context); - function_stmt_visitor.TraverseStmt(Func->getBody()); - constructor.applications = - function_stmt_visitor.get_applications(); - gac_classes[i].constructors.push_back(constructor); - } else if (isa(Func)) { + InFileFunction in_file_function; + in_file_function.class_name = class_name; + in_file_function.function_name = class_name; + in_file_function.signature = signature; + gac_in_file_functions.push_back(in_file_function); + } else if (isa(CanonicalFunc)) { // std::string signature; // std::string function_body; // std::vector applications; // std::cout << "Destructor Declaration " << class_name // << std::endl; - Destructor destructor; - const SourceManager &sourceManager = - Context->getSourceManager(); - SourceRange srcRange = Func->getSourceRange(); - srcRange.setEnd(Lexer::getLocForEndOfToken( - srcRange.getEnd(), 0, sourceManager, - Context->getLangOpts())); - bool Invalid = false; - StringRef srcText = Lexer::getSourceText( - CharSourceRange::getTokenRange(srcRange), sourceManager, - Context->getLangOpts(), &Invalid); - destructor.signature = signature; - destructor.function_body = srcText; - StmtVarFunctionVisitor function_stmt_visitor(Context); - function_stmt_visitor.TraverseStmt(Func->getBody()); - destructor.applications = - function_stmt_visitor.get_applications(); - gac_classes[i].destructor = destructor; + InFileFunction in_file_function; + in_file_function.class_name = class_name; + in_file_function.function_name = "~" + class_name; + in_file_function.signature = signature; + gac_in_file_functions.push_back(in_file_function); } else { // std::string method_name; // std::string signature; @@ -762,47 +550,11 @@ class MethodFunctionVisitor std::string function_name = Func->getNameAsString(); // std::cout << "Method Declaration " << function_name // << std::endl; - method.method_name = function_name; - method.signature = signature; - const SourceManager &sourceManager = - Context->getSourceManager(); - SourceRange srcRange_r = Func->getReturnTypeSourceRange(); - srcRange_r.setEnd(Lexer::getLocForEndOfToken( - srcRange_r.getEnd(), 0, sourceManager, - Context->getLangOpts())); - bool Invalid = false; - StringRef srcText_r = Lexer::getSourceText( - CharSourceRange::getTokenRange(srcRange_r), sourceManager, - Context->getLangOpts(), &Invalid); - method.return_type = std::string(srcText_r); - for (const ParmVarDecl *param : Func->parameters()) { - SourceRange srcRange_p = param->getSourceRange(); - srcRange_p.setEnd(Lexer::getLocForEndOfToken( - srcRange_p.getEnd(), 0, sourceManager, - Context->getLangOpts())); - StringRef srcText_p = Lexer::getSourceText( - CharSourceRange::getTokenRange(srcRange_p), sourceManager, - Context->getLangOpts(), &Invalid); - std::string srcText_str = std::string(srcText_p); - if (srcText_str[srcText_str.length() - 1] == ')' || - srcText_str[srcText_str.length() - 1] == ',' || - srcText_str[srcText_str.length() - 1] == ';') { - srcText_str.erase(srcText_str.length() - 1); - } - method.parameters.push_back(srcText_str); - } - SourceRange srcRange = Func->getSourceRange(); - srcRange.setEnd(Lexer::getLocForEndOfToken( - srcRange.getEnd(), 0, sourceManager, - Context->getLangOpts())); - StringRef srcText = Lexer::getSourceText( - CharSourceRange::getTokenRange(srcRange), sourceManager, - Context->getLangOpts(), &Invalid); - method.function_body = srcText; - StmtVarFunctionVisitor function_stmt_visitor(Context); - function_stmt_visitor.TraverseStmt(Func->getBody()); - method.applications = function_stmt_visitor.get_applications(); - gac_classes[i].methods.push_back(method); + InFileFunction in_file_function; + in_file_function.class_name = class_name; + in_file_function.function_name = function_name; + in_file_function.signature = signature; + gac_in_file_functions.push_back(in_file_function); } } } @@ -836,191 +588,614 @@ class MethodFunctionAction : public clang::ASTFrontendAction { } }; -void OneFileContext::get_context() { - ::gac_classes.clear(); - ::gac_functions.clear(); +void FileContext::get_context() { + ::gac_in_file_functions.clear(); + ::gac_alias.clear(); + ::gac_applications.clear(); Tool.run(newFrontendActionFactory().get()); - file_context.classes = ::gac_classes; - file_context.functions = ::gac_functions; + functions = gac_in_file_functions; + alias = gac_alias; + for (auto application : gac_applications) { + applications.push_back(application); + } } -FileContext OneFileContext::get_file_context() { return file_context; } +// Class FileContext::get_simple_class(std::string class_name) { +// for (auto a_class : classes) { +// if (a_class.class_name == class_name) { +// Class ret; +// ret.class_name = a_class.class_name; +// ret.base_class = a_class.base_class; +// ret.fields = a_class.fields; +// ret.its_namespace = a_class.its_namespace; +// for (auto constructor : a_class.constructors) { +// Constructor new_constructor; +// new_constructor.signature = constructor.signature; +// ret.constructors.push_back(new_constructor); +// } +// Destructor new_destructor; +// new_destructor.signature = a_class.destructor.signature; +// ret.destructor = new_destructor; +// for (auto method : a_class.methods) { +// Method new_method; +// new_method.signature = method.signature; +// ret.methods.push_back(new_method); +// } +// return ret; +// } +// } +// } -Class FileContext::get_simple_class(std::string class_name) { - for (auto a_class : classes) { - if (a_class.class_name == class_name) { - Class ret; - ret.class_name = a_class.class_name; - ret.base_class = a_class.base_class; - ret.fields = a_class.fields; - ret.its_namespace = a_class.its_namespace; - for (auto constructor : a_class.constructors) { - Constructor new_constructor; - new_constructor.signature = constructor.signature; - ret.constructors.push_back(new_constructor); - } - Destructor new_destructor; - new_destructor.signature = a_class.destructor.signature; - ret.destructor = new_destructor; - for (auto method : a_class.methods) { - Method new_method; - new_method.signature = method.signature; - ret.methods.push_back(new_method); - } - return ret; - } - } -} +// bool FileContext::class_has_constructor(std::string class_name, +// std::string signature) { +// for (auto a_class : classes) { +// if (a_class.class_name == class_name) { +// for (auto constructor : a_class.constructors) { +// if (constructor.signature == signature) { +// return 1; +// } +// } +// return 0; +// } +// } +// return 0; +// } -bool FileContext::class_has_constructor(std::string class_name, - std::string signature) { - for (auto a_class : classes) { - if (a_class.class_name == class_name) { - for (auto constructor : a_class.constructors) { - if (constructor.signature == signature) { - return 1; - } +// Constructor FileContext::class_get_constructor(std::string class_name, +// std::string signature) { +// for (auto a_class : classes) { +// if (a_class.class_name == class_name) { +// for (auto constructor : a_class.constructors) { +// if (constructor.signature == signature) { +// return constructor; +// } +// } +// } +// } +// } + +// bool FileContext::class_has_destructor(std::string class_name, +// std::string signature) { +// for (auto a_class : classes) { +// if (a_class.class_name == class_name) { +// if (a_class.destructor.signature == signature) { +// return 1; +// } +// return 0; +// } +// } +// return 0; +// } +// Destructor FileContext::class_get_destructor(std::string class_name, +// std::string signature) { +// for (auto a_class : classes) { +// if (a_class.class_name == class_name) { +// return a_class.destructor; +// } +// } +// } + +// bool FileContext::class_has_method(std::string class_name, +// std::string signature) { +// for (auto a_class : classes) { +// if (a_class.class_name == class_name) { +// for (auto method : a_class.methods) { +// if (method.signature == signature) { +// return 1; +// } +// } +// return 0; +// } +// } +// return 0; +// } +// Method FileContext::class_get_method(std::string class_name, +// std::string signature) { +// for (auto a_class : classes) { +// if (a_class.class_name == class_name) { +// for (auto method : a_class.methods) { +// if (method.signature == signature) { +// return method; +// } +// } +// } +// } +// } + +// Function FileContext::get_function(std::string signature) { +// for (auto function : functions) { +// if (function.signature == signature) { +// return function; +// } +// } +// } + +// std::vector +// FileContext::get_may_test_macros(std::string class_name, +// std::string function_name) { +// std::vector ret; +// for (auto a_test_macro : test_macros) { +// if (class_name == "class") { +// if (a_test_macro.second_parameter.find(function_name) != +// std::string::npos) { +// ret.push_back(a_test_macro); +// } +// } else { +// if (a_test_macro.second_parameter.find(class_name) != std::string::npos +// && +// a_test_macro.second_parameter.find(function_name) != +// std::string::npos) { +// ret.push_back(a_test_macro); +// } +// } +// } +// return ret; +// } + +// std::vector +// FileContext::get_must_test_macros(std::string second_parameter) { +// std::vector ret; +// for (auto a_test_macro : test_macros) { +// if (a_test_macro.second_parameter == second_parameter) { +// ret.push_back(a_test_macro); +// return ret; +// } +// } +// return ret; +// } + +// void FileContext::cout() { +// std::cout << file_path << std::endl; +// // std::vector includes; +// // std::vector defines; +// // std::vector global_vars; +// // std::vector classes; +// // std::vector functions; +// std::cout << "includes:" << std::endl; +// for (auto include : includes) { +// std::cout << include << std::endl; +// } +// std::cout << "defines:" << std::endl; +// for (auto define : defines) { +// std::cout << define.define_name << " " << define.define_body << +// std::endl; +// } +// std::cout << "global_vars:" << std::endl; +// for (auto global_var : global_vars) { +// std::cout << global_var.global_var << " " << global_var.its_namespace +// << std::endl; +// applications_cout(global_var.applications); +// } +// std::cout << "classes:" << std::endl; +// for (auto one_class : classes) { +// std::cout << one_class.class_name << std::endl; +// } +// std::cout << "functions:" << std::endl; +// for (auto function : functions) { +// std::cout << function.function_name << std::endl; +// applications_cout(function.applications); +// } +// } + +void FileContext::delete_repeated_applications() { + for (auto it = applications.begin(); it != applications.end();) { + bool b = 0; + for (auto it2 = applications.begin(); it2 != applications.end(); ++it2) { + if (it2 != it && it2->class_name == it->class_name && + it2->signature == it->signature) { + b = 1; + break; } - return 0; + } + if (b == 1) { + it = applications.erase(it); + } else { + ++it; } } - return 0; } -Constructor FileContext::class_get_constructor(std::string class_name, - std::string signature) { - for (auto a_class : classes) { - if (a_class.class_name == class_name) { - for (auto constructor : a_class.constructors) { - if (constructor.signature == signature) { - return constructor; - } - } - } - } +void FileContext::get_one_file_context() { + set_global_vars(); + get_includes(); + get_defines(); + get_global_vars(); + get_test_macros(); + get_context(); + delete_repeated_applications(); } -bool FileContext::class_has_destructor(std::string class_name, - std::string signature) { - for (auto a_class : classes) { - if (a_class.class_name == class_name) { - if (a_class.destructor.signature == signature) { - return 1; - } - return 0; +json FileContext::get_file_j() { + json j; + j["includes"] = json::array(); + j["includes"] = includes; + j["defines"] = json::object(); + for (auto define : defines) { + j["defines"][define.define_name] = define.define_body; + } + for (auto global_var : global_vars) { + if (j.find(global_var.its_namespace) == j.end()) { + j[global_var.its_namespace] = json::object(); + } + if (j[global_var.its_namespace].find("global_vars") == + j[global_var.its_namespace].end()) { + j[global_var.its_namespace]["global_vars"] = json::array(); } + j[global_var.its_namespace]["global_vars"].push_back(global_var.global_var); } - return 0; -} -Destructor FileContext::class_get_destructor(std::string class_name, - std::string signature) { - for (auto a_class : classes) { - if (a_class.class_name == class_name) { - return a_class.destructor; + for (auto alias : alias) { + if (j.find(alias.its_namespace) == j.end()) { + j[alias.its_namespace] = json::object(); } + if (j[alias.its_namespace].find("alias") == j[alias.its_namespace].end()) { + j[alias.its_namespace]["alias"] = json::array(); + } + std::string alias_string = + "using " + alias.alias_name + " = " + alias.base_name; + j[alias.its_namespace]["alias"].push_back(alias_string); } + return j; } -bool FileContext::class_has_method(std::string class_name, - std::string signature) { - for (auto a_class : classes) { - if (a_class.class_name == class_name) { - for (auto method : a_class.methods) { - if (method.signature == signature) { - return 1; +json FileContext::get_j(bool test_flag) { + json j; + json file_j = get_file_j(); + j[file_path] = json::object(); + for (auto function : functions) { + // if (function.function_name == "main") { + // std::cout << std::endl; + // } + std::string class_function; + if (function.class_name != "class") { + class_function = function.class_name + "::" + function.function_name; + } else { + class_function = function.function_name; + } + if (j[file_path].find(class_function) == j[file_path].end()) { + j[file_path][class_function] = json::object(); + j[file_path][class_function]["focal"] = json::object(); + } + j[file_path][class_function]["focal"][function.signature] = json::object(); + j[file_path][class_function]["focal"][function.signature].merge_patch( + file_j); + j[file_path][class_function]["focal"][function.signature]["function_body"] = + json::object(); + j[file_path][class_function]["focal"][function.signature]["function_body"] = + gac_classes_and_functions.get_function_body(function.class_name, + function.signature); + std::vector need_applications = applications; + Application function_application; + function_application.class_name = function.class_name; + function_application.signature = function.signature; + bool b = 0; + for (auto application : need_applications) { + if (application == function_application) { + b = 1; + break; + } + } + if (b == 0) { + need_applications.push_back(function_application); + } + std::vector need_function_applications = + gac_classes_and_functions.get_applications(function.class_name, + function.signature); + for (auto need_function_application : need_function_applications) { + bool b = 0; + for (auto application : need_applications) { + if (application == need_function_application) { + b = 1; + break; } } - return 0; + if (b == 0) { + need_applications.push_back(need_function_application); + } } - } - return 0; -} -Method FileContext::class_get_method(std::string class_name, - std::string signature) { - for (auto a_class : classes) { - if (a_class.class_name == class_name) { - for (auto method : a_class.methods) { - if (method.signature == signature) { - return method; + gac_classes_and_functions.get_all_applications(&need_applications); + std::vector used_classes; + for (auto application : need_applications) { + if (application.class_name != "class") { + bool b = 0; + for (auto used_class : used_classes) { + if (used_class == application.class_name) { + b = 1; + break; + } + } + if (b == 0) { + used_classes.push_back(application.class_name); + j[file_path][class_function]["focal"][function.signature].merge_patch( + gac_classes_and_functions.get_simple_class( + application.class_name)); } } + if (application.signature != "") { + j[file_path][class_function]["focal"][function.signature].merge_patch( + gac_classes_and_functions.get_j(application)); + } } } + return j; } -Function FileContext::get_function(std::string signature) { - for (auto function : functions) { - if (function.signature == signature) { - return function; - } - } +void FileContexts::push_back(FileContext file_context) { + file_contexts.push_back(file_context); } -std::vector -FileContext::get_may_test_macros(std::string class_name, - std::string function_name) { - std::vector ret; - for (auto a_test_macro : test_macros) { - if (class_name == "class") { - if (a_test_macro.second_parameter.find(function_name) != - std::string::npos) { - ret.push_back(a_test_macro); - } - } else { - if (a_test_macro.second_parameter.find(class_name) != std::string::npos && - a_test_macro.second_parameter.find(function_name) != - std::string::npos) { - ret.push_back(a_test_macro); - } - } +json FileContexts::get_j(bool test_flag) { + json j; + for (auto file_context : file_contexts) { + j.merge_patch(file_context.get_j(test_flag)); } - return ret; + return j; + // for (auto file_context : file_contexts) { + // // file_context.cout(); + // // i++; + // for (auto a_class : file_context.classes) { + // for (auto constructor : a_class.constructors) { + // if (constructor.function_body != "") { + // json temp_j = json::object(); + // SignatureContext constructor_signature_context = + // get_signature_context(file_contexts, file_context.file_path, + // a_class.class_name, + // constructor.signature); + // json constructor_signatre_j = + // constructor_signature_context.get_j(); + // temp_j[file_context.file_path] = json::object(); + // temp_j[file_context.file_path] + // [a_class.class_name + "::" + a_class.class_name] = + // json::object(); + // temp_j[file_context.file_path] + // [a_class.class_name + "::" + a_class.class_name]["focal"] = + // json::object(); + // temp_j[file_context.file_path] + // [a_class.class_name + "::" + a_class.class_name]["focal"] = + // constructor_signatre_j[file_context.file_path] + // [a_class.class_name + + // "::" + a_class.class_name]; + // if (RealTestFlag) { + // std::vector may_tests = get_may_tests( + // file_contexts, a_class.class_name, a_class.class_name); + // temp_j[file_context.file_path] + // [a_class.class_name + "::" + + // a_class.class_name]["may_test"] = + // json::object(); + // for (auto may_test : may_tests) { + // std::pair> + // may_test_class_signature = + // all_context_paths->getTest(may_test.second_parameter); + // SignatureContext may_test_signature_context = + // get_signature_context(file_contexts, + // may_test_class_signature.first, + // may_test_class_signature.second.first, + // may_test_class_signature.second.second); + // json may_test_signature_j = may_test_signature_context.get_j(); + // temp_j[file_context.file_path] + // [a_class.class_name + "::" + + // a_class.class_name]["may_test"] + // [may_test.second_parameter] = json::object(); + // for (auto [key, value] : may_test_signature_j.items()) { + // for (auto [key1, value1] : value.items()) { + // temp_j[file_context.file_path] + // [a_class.class_name + "::" + a_class.class_name] + // ["may_test"][may_test.second_parameter] = value1; + // } + // } + // temp_j[file_context.file_path] + // [a_class.class_name + "::" + + // a_class.class_name]["may_test"] + // [may_test.second_parameter]["test_macro"] = + // json::object(); + // temp_j[file_context.file_path] + // [a_class.class_name + "::" + + // a_class.class_name]["may_test"] + // [may_test.second_parameter]["test_macro"] = + // may_test.test_mecro; + // } + // } + // j.merge_patch(temp_j); + // } + // } + // if (a_class.destructor.function_body != "") { + // std::string function_name = "~" + a_class.class_name; + // json temp_j = json::object(); + // SignatureContext destructor_signature_context = + // get_signature_context( + // file_contexts, file_context.file_path, a_class.class_name, + // a_class.destructor.signature); + // json destructor_signatre_j = destructor_signature_context.get_j(); + // temp_j[file_context.file_path] = json::object(); + // temp_j[file_context.file_path] + // [a_class.class_name + "::" + function_name] = json::object(); + // temp_j[file_context.file_path] + // [a_class.class_name + "::" + function_name]["focal"] = + // json::object(); + // temp_j[file_context.file_path][a_class.class_name + + // "::" + function_name]["focal"] = + // destructor_signatre_j[file_context.file_path] + // [a_class.class_name + "::" + function_name]; + // if (RealTestFlag) { + // std::vector may_tests = + // get_may_tests(file_contexts, a_class.class_name, + // function_name); + // temp_j[file_context.file_path] + // [a_class.class_name + "::" + function_name]["may_test"] = + // json::object(); + // for (auto may_test : may_tests) { + // std::pair> + // may_test_class_signature = + // all_context_paths->getTest(may_test.second_parameter); + // SignatureContext may_test_signature_context = + // get_signature_context( + // file_contexts, may_test_class_signature.first, + // may_test_class_signature.second.first, + // may_test_class_signature.second.second); + // json may_test_signature_j = may_test_signature_context.get_j(); + // temp_j[file_context.file_path] + // [a_class.class_name + "::" + function_name]["may_test"] + // [may_test.second_parameter] = json::object(); + // for (auto [key, value] : may_test_signature_j.items()) { + // for (auto [key1, value1] : value.items()) { + // temp_j[file_context.file_path] + // [a_class.class_name + "::" + function_name]["may_test"] + // [may_test.second_parameter] = value1; + // } + // } + // temp_j[file_context.file_path] + // [a_class.class_name + "::" + function_name]["may_test"] + // [may_test.second_parameter]["test_macro"] = json::object(); + // temp_j[file_context.file_path] + // [a_class.class_name + "::" + function_name]["may_test"] + // [may_test.second_parameter]["test_macro"] = + // may_test.test_mecro; + // } + // } + // j.merge_patch(temp_j); + // } + // for (auto method : a_class.methods) { + // if (method.function_body != "") { + // json temp_j = json::object(); + // SignatureContext method_signature_context = + // get_signature_context(file_contexts, file_context.file_path, + // a_class.class_name, method.signature); + // json method_signatre_j = method_signature_context.get_j(); + // temp_j[file_context.file_path] = json::object(); + // temp_j[file_context.file_path] + // [a_class.class_name + "::" + method.method_name] = + // json::object(); + // temp_j[file_context.file_path] + // [a_class.class_name + "::" + method.method_name]["focal"] = + // json::object(); + // temp_j[file_context.file_path][a_class.class_name + + // "::" + method.method_name]["focal"] + // = + // method_signatre_j[file_context.file_path] + // [a_class.class_name + "::" + + // method.method_name]; + // if (RealTestFlag) { + // std::vector may_tests = get_may_tests( + // file_contexts, a_class.class_name, method.method_name); + // temp_j[file_context.file_path] + // [a_class.class_name + "::" + + // method.method_name]["may_test"] = + // json::object(); + // for (auto may_test : may_tests) { + // std::pair> + // may_test_class_signature = + // all_context_paths->getTest(may_test.second_parameter); + // SignatureContext may_test_signature_context = + // get_signature_context(file_contexts, + // may_test_class_signature.first, + // may_test_class_signature.second.first, + // may_test_class_signature.second.second); + // json may_test_signature_j = may_test_signature_context.get_j(); + // temp_j[file_context.file_path] + // [a_class.class_name + "::" + + // method.method_name]["may_test"] + // [may_test.second_parameter] = json::object(); + // for (auto [key, value] : may_test_signature_j.items()) { + // for (auto [key1, value1] : value.items()) { + // temp_j[file_context.file_path] + // [a_class.class_name + "::" + method.method_name] + // ["may_test"][may_test.second_parameter] = value1; + // } + // } + // temp_j[file_context.file_path] + // [a_class.class_name + "::" + + // method.method_name]["may_test"] + // [may_test.second_parameter]["test_macro"] = + // json::object(); + // temp_j[file_context.file_path] + // [a_class.class_name + "::" + + // method.method_name]["may_test"] + // [may_test.second_parameter]["test_macro"] = + // may_test.test_mecro; + // } + // } + // j.merge_patch(temp_j); + // } + // } + // } + // for (auto function : file_context.functions) { + // if (function.function_body != "") { + // json temp_j = json::object(); + // SignatureContext function_signature_context = get_signature_context( + // file_contexts, file_context.file_path, "class", + // function.signature); + // json function_signatre_j = function_signature_context.get_j(); + // temp_j[file_context.file_path] = json::object(); + // temp_j[file_context.file_path]["class::" + function.function_name] = + // json::object(); + // temp_j[file_context.file_path]["class::" + function.function_name] + // ["focal"] = json::object(); + // temp_j[file_context.file_path]["class::" + function.function_name] + // ["focal"] = + // function_signatre_j[file_context.file_path] + // ["class::" + function.function_name]; + // if (RealTestFlag) { + // std::vector may_tests = + // get_may_tests(file_contexts, "class", function.function_name); + // temp_j[file_context.file_path]["class::" + function.function_name] + // ["may_test"] = json::object(); + // for (auto may_test : may_tests) { + // std::pair> + // may_test_class_signature = + // all_context_paths->getTest(may_test.second_parameter); + // SignatureContext may_test_signature_context = + // get_signature_context( + // file_contexts, may_test_class_signature.first, + // may_test_class_signature.second.first, + // may_test_class_signature.second.second); + // json may_test_signature_j = may_test_signature_context.get_j(); + // temp_j[file_context.file_path]["class::" + + // function.function_name] + // ["may_test"][may_test.second_parameter] = json::object(); + // for (auto [key, value] : may_test_signature_j.items()) { + // for (auto [key1, value1] : value.items()) { + // temp_j[file_context.file_path] + // ["class::" + function.function_name]["may_test"] + // [may_test.second_parameter] = value1; + // } + // } + // temp_j[file_context.file_path]["class::" + + // function.function_name] + // ["may_test"][may_test.second_parameter]["test_macro"] = + // json::object(); + // temp_j[file_context.file_path]["class::" + + // function.function_name] + // ["may_test"][may_test.second_parameter]["test_macro"] = + // may_test.test_mecro; + // } + // } + // j.merge_patch(temp_j); + // } + // } + // } } -std::vector -FileContext::get_must_test_macros(std::string second_parameter) { - std::vector ret; - for (auto a_test_macro : test_macros) { - if (a_test_macro.second_parameter == second_parameter) { - ret.push_back(a_test_macro); - return ret; +void GetFileContext::get_all_file_contexts() { + ::gac_project_path = project_path; + ::gac_classes_and_functions = classes_and_functions; + for (auto file_path : *file_paths) { + std::vector args{"file_context", "-p", + compilation_database_path.c_str(), + file_path.c_str()}; + int argc = args.size(); + const char **argv = args.data(); + auto ExpectedParser = + CommonOptionsParser::create(argc, argv, FocxtCategory); + if (!ExpectedParser) { + errs() << ExpectedParser.takeError(); + exit(1); } - } - return ret; -} - -void FileContext::cout() { - std::cout << file_path << std::endl; - // std::vector includes; - // std::vector defines; - // std::vector global_vars; - // std::vector classes; - // std::vector functions; - std::cout << "includes:" << std::endl; - for (auto include : includes) { - std::cout << include << std::endl; - } - std::cout << "defines:" << std::endl; - for (auto define : defines) { - std::cout << define.define_name << " " << define.define_body << std::endl; - } - std::cout << "global_vars:" << std::endl; - for (auto global_var : global_vars) { - std::cout << global_var.global_var << " " << global_var.its_namespace - << std::endl; - applications_cout(global_var.applications); - } - std::cout << "classes:" << std::endl; - for (auto one_class : classes) { - std::cout << one_class.class_name << std::endl; - } - std::cout << "functions:" << std::endl; - for (auto function : functions) { - std::cout << function.function_name << std::endl; - applications_cout(function.applications); + CommonOptionsParser &OptionParser = ExpectedParser.get(); + ClangTool Tool(OptionParser.getCompilations(), + OptionParser.getSourcePathList()); + FileContext file_context(Tool, file_path); + file_context.get_one_file_context(); + file_contexts.push_back(file_context); } } -void get_all_applications(std::set all_applications, - std::string a_file_path, std::string class_name, - std::string signature); \ No newline at end of file +FileContexts GetFileContext::get_file_contexts() { return file_contexts; } diff --git a/clang-tools-extra/focxt/GetAllContext.h b/clang-tools-extra/focxt/GetAllContext.h old mode 100644 new mode 100755 index db69e56f7eced..7a8d2303883d1 --- a/clang-tools-extra/focxt/GetAllContext.h +++ b/clang-tools-extra/focxt/GetAllContext.h @@ -1,5 +1,4 @@ #pragma once -#include "GetAllPath.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/ASTMatchers/ASTMatchFinder.h" @@ -11,6 +10,7 @@ #include "clang/Tooling/CommonOptionsParser.h" #include "clang/Tooling/Tooling.h" #include "llvm/Support/CommandLine.h" +#include #include #include #include @@ -28,85 +28,55 @@ using namespace clang::ast_matchers; using namespace clang::tooling; using namespace llvm; -struct Application { - std::string file_path; - std::string class_name; - std::string signature; - bool operator==(const Application &other) const { - return file_path == other.file_path && class_name == other.class_name && - signature == other.signature; - } -}; - struct GlobalVar { std::string global_var; std::string its_namespace; - std::vector applications; }; -struct Constructor { - std::string signature; - std::string function_body; - std::vector parameters; - std::vector applications; -}; - -struct Destructor { - std::string signature; - std::string function_body; - std::vector applications; +struct ADefine { + std::string define_name; + std::string define_body; }; -struct Method { - std::string method_name; - std::string signature; - std::string function_body; - std::vector parameters; - std::string return_type; - std::vector applications; +struct TestMacro { + std::string second_parameter; + std::string test_mecro; }; -struct Class { +struct InFileFunction { std::string class_name; - std::string base_class; - std::vector constructors; - Destructor destructor; - std::vector fields; - std::vector methods; - std::string its_namespace; -}; - -struct Function { std::string function_name; std::string signature; - std::string function_body; - std::vector parameters; - std::string return_type; - std::vector applications; - std::string its_namespace; -}; - -struct ADefine { - std::string define_name; - std::string define_body; }; -struct TestMacro { - std::string second_parameter; - std::string test_mecro; +struct InFileAlias { + std::string alias_name; + std::string base_name; + std::string its_namespace; }; class FileContext { -public: + ClangTool &Tool; std::string file_path; std::vector includes; std::vector defines; std::vector global_vars; - std::vector classes; - std::vector functions; + std::vector functions; std::vector test_macros; + std::vector alias; + std::vector applications; + + void set_global_vars(); + void get_includes(); + void get_defines(); + void get_global_vars(); + void get_test_macros(); + void get_context(); + +public: FileContext() = default; - FileContext(std::string file_path) : file_path(file_path) {} + FileContext(ClangTool &Tool, std::string file_path) + : Tool(Tool), file_path(file_path) {} Class get_simple_class(std::string class_name); bool class_has_constructor(std::string class_name, std::string signature); Constructor class_get_constructor(std::string class_name, @@ -121,36 +91,39 @@ class FileContext { std::string function_name); std::vector get_must_test_macros(std::string second_parameter); void cout(); + + void delete_repeated_applications(); + void get_one_file_context(); + json get_file_j(); + json get_j(bool test_flag); }; -class OneFileContext { - ClangTool &Tool; - AllContextPaths *all_context_paths; +class FileContexts { + std::vector file_contexts; + +public: + void push_back(FileContext file_context); + json get_j(bool test_flag); +}; + +class GetFileContext { + FileContexts file_contexts; std::string project_path; std::string compilation_database_path; - std::string file_path; - FileContext file_context; + std::vector *file_paths; + cl::OptionCategory FocxtCategory; + ClassesAndFunctions classes_and_functions; public: - OneFileContext(ClangTool &Tool, AllContextPaths *all_context_paths, - std::string project_path, - std::string compilation_database_path, std::string file_path) - : Tool(Tool), all_context_paths(all_context_paths), - project_path(project_path), + GetFileContext(std::string project_path, + std::string compilation_database_path, + std::vector *file_paths, + cl::OptionCategory FocxtCategory, + ClassesAndFunctions classes_and_functions) + : project_path(project_path), compilation_database_path(compilation_database_path), - file_path(file_path), file_context(file_path) { - set_global_vars(); - get_includes(); - get_defines(); - get_global_vars(); - get_test_macros(); - get_context(); - } - void set_global_vars(); - void get_includes(); - void get_defines(); - void get_global_vars(); - void get_test_macros(); - void get_context(); - FileContext get_file_context(); + file_paths(file_paths), FocxtCategory(FocxtCategory), + classes_and_functions(classes_and_functions) {} + void get_all_file_contexts(); + FileContexts get_file_contexts(); }; \ No newline at end of file diff --git a/clang-tools-extra/focxt/GetAllDefinition.cpp b/clang-tools-extra/focxt/GetAllDefinition.cpp new file mode 100755 index 0000000000000..c0d79b35ed267 --- /dev/null +++ b/clang-tools-extra/focxt/GetAllDefinition.cpp @@ -0,0 +1,5074 @@ +#include +#include + +std::string gad_project_path; +ClassesAndFunctions gad_classes_and_functions; + +bool ClassesAndFunctions::has_class(std::string class_name) { + for (auto a_class : classes) { + if (a_class.class_name == class_name) { + return 1; + } + } + return 0; +} + +void ClassesAndFunctions::push_back_class(Class a_class) { + classes.push_back(a_class); +} + +std::string ClassesAndFunctions::get_function_body(std::string class_name, + std::string signature) { + if (class_name != "class") { + for (auto a_class : classes) { + if (a_class.class_name == class_name) { + for (auto constructor : a_class.constructors) { + if (constructor.signature == signature) { + return constructor.function_body; + } + } + if (a_class.destructor.signature == signature) { + return a_class.destructor.function_body; + } + for (auto method : a_class.methods) { + if (method.signature == signature) { + return method.function_body; + } + } + } + } + } else { + for (auto function : functions) { + if (function.signature == signature) { + return function.function_body; + } + } + } +} + +void ClassesAndFunctions::push_back_specialization_parameter( + std::string class_name, std::string signature, + std::vector specialization_parameter) { + if (signature == "") { + for (auto &a_class : classes) { + if (a_class.class_name == class_name) { + bool b = 0; + for (auto exist_specialization_parameter : + a_class.specialization_parameters) { + if (exist_specialization_parameter == specialization_parameter) { + b = 1; + break; + } + } + if (b == 0) { + a_class.specialization_parameters.push_back(specialization_parameter); + // for (auto specialization_type : specialization_parameter) { + // Application application; + // application.class_name = specialization_type; + // application.signature = ""; + // a_class.applications.push_back(application); + // // if (this->has_class(specialization_type)) { + // // std::vector constructors = + // // this->get_constructors(specialization_type); + // // std::vector> + // applications; + // // for (auto constructor : constructors) { + // // applications.push_back(std::pair( + // // specialization_type, constructor)); + // // } + // // std::string destructor = this->get_destructor(class_name); + // // if (destructor != "class") { + // // applications.push_back(std::pair( + // // specialization_type, destructor)); + // // } + // // this->push_back_applications(class_name, "", applications); + // // } + // } + } + } + } + } else { + if (class_name == "class") { + for (auto &function : functions) { + if (function.signature == signature) { + bool b = 0; + for (auto exist_specialization_parameter : + function.specialization_parameters) { + if (exist_specialization_parameter == specialization_parameter) { + b = 1; + break; + } + } + if (b == 0) { + function.specialization_parameters.push_back( + specialization_parameter); + // for (auto specialization_type : specialization_parameter) { + // Application application; + // application.class_name = specialization_type; + // application.signature = ""; + // function.applications.push_back(application); + // // if (this->has_class(specialization_type)) { + // // std::vector constructors = + // // this->get_constructors(specialization_type); + // // std::vector> + // // applications; for (auto constructor : constructors) { + // // applications.push_back(std::pair( + // // specialization_type, constructor)); + // // } + // // std::string destructor = this->get_destructor(class_name); + // // if (destructor != "class") { + // // applications.push_back(std::pair( + // // specialization_type, destructor)); + // // } + // // this->push_back_applications("class", signature, + // // applications); + // // } + // } + } + } + } + } else { + for (auto &a_class : classes) { + if (a_class.class_name == class_name) { + for (auto &method : a_class.methods) { + if (method.signature == signature) { + bool b = 0; + for (auto exist_specialization_parameter : + method.specialization_parameters) { + if (exist_specialization_parameter == + specialization_parameter) { + b = 1; + break; + } + } + if (b == 0) { + method.specialization_parameters.push_back( + specialization_parameter); + // for (auto specialization_type : specialization_parameter) { + // Application application; + // application.class_name = specialization_type; + // application.signature = ""; + // method.applications.push_back(application); + // // if (this->has_class(specialization_type)) { + // // std::vector constructors = + // // this->get_constructors(specialization_type); + // // std::vector> + // // applications; + // // for (auto constructor : constructors) { + // // applications.push_back( + // // std::pair( + // // specialization_type, constructor)); + // // } + // // std::string destructor = + // // this->get_destructor(class_name); if (destructor != + // // "class") { + // // applications.push_back( + // // std::pair( + // // specialization_type, destructor)); + // // } + // // this->push_back_applications(class_name, signature, + // // applications); + // // } + // } + } + } + } + } + } + } + } +} + +void ClassesAndFunctions::push_back_applications( + std::string class_name, std::string signature, + std::vector> applications) { + if (signature == "") { + for (auto &a_class : classes) { + if (a_class.class_name == class_name) { + for (auto application : applications) { + Application a_application; + a_application.class_name = application.first; + a_application.signature = application.second; + a_class.applications.push_back(a_application); + } + } + } + } else { + if (class_name == "class") { + for (auto &function : functions) { + if (function.signature == signature) { + for (auto application : applications) { + Application a_application; + a_application.class_name = application.first; + a_application.signature = application.second; + function.applications.push_back(a_application); + } + } + } + } else { + for (auto &a_class : classes) { + if (a_class.class_name == class_name) { + for (auto &method : a_class.methods) { + if (method.signature == signature) { + for (auto application : applications) { + Application a_application; + a_application.class_name = application.first; + a_application.signature = application.second; + method.applications.push_back(a_application); + } + } + } + } + } + } + } +} + +std::vector +ClassesAndFunctions::get_constructors(std::string class_name) { + std::vector constructors; + for (auto a_class : classes) { + if (a_class.class_name == class_name) { + for (auto constructor : a_class.constructors) { + constructors.push_back(constructor.signature); + } + break; + } + } + return constructors; +} + +std::string ClassesAndFunctions::get_destructor(std::string class_name) { + for (auto a_class : classes) { + if (a_class.class_name == class_name && + a_class.destructor.signature != "") { + return a_class.destructor.signature; + } + break; + } + return "class"; +} + +bool ClassesAndFunctions::has_function(std::string class_name, + std::string signature) { + if (class_name == "class") { + for (auto function : functions) { + if (function.signature == signature) { + return 1; + } + } + return 0; + } else { + for (auto a_class : classes) { + if (a_class.class_name == class_name) { + for (auto constructor : a_class.constructors) { + if (constructor.signature == signature) { + return 1; + } + } + if (a_class.destructor.signature == signature) { + return 1; + } + for (auto method : a_class.methods) { + if (method.signature == signature) { + return 1; + } + } + return 0; + } + } + } + return 0; +} + +void ClassesAndFunctions::push_back_function(Function function) { + functions.push_back(function); +} + +void ClassesAndFunctions::push_back_constructor(std::string class_name, + Constructor constructor) { + for (auto &a_class : classes) { + if (a_class.class_name == class_name) { + a_class.constructors.push_back(constructor); + } + } +} + +void ClassesAndFunctions::push_back_destructor(std::string class_name, + Destructor destructor) { + for (auto &a_class : classes) { + if (a_class.class_name == class_name) { + a_class.destructor = destructor; + } + } +} + +void ClassesAndFunctions::push_back_method(std::string class_name, + Method method) { + for (auto &a_class : classes) { + if (a_class.class_name == class_name) { + a_class.methods.push_back(method); + } + } +} + +void ClassesAndFunctions::cout() { + std::cout << "classes:" << std::endl; + for (auto a_class : classes) { + a_class.cout(); + } + std::cout << "functions:" << std::endl; + for (auto function : functions) { + function.cout(); + } + // std::cout << "class:" << std::endl; + // for (auto a_class : classes) { + // std::cout << a_class.class_name + // << "\t" + // // << a_class.base_class << "\t" + // << a_class.is_template << std::endl + // << "template_parameters:"; + // for (auto template_parameter : a_class.template_parameters) { + // std::cout << template_parameter << "\t"; + // } + // std::cout << std::endl << "specialization_parameters:"; + // for (auto specialization_parameter : a_class.specialization_parameters) { + // std::cout << "<"; + // for (auto specialization_type : specialization_parameter) { + // std::cout << specialization_type << ","; + // } + // std::cout << ">\t"; + // } + // std::cout << std::endl << "fields:"; + // for (auto field : a_class.fields) { + // std::cout << field << "\t"; + // } + // std::cout << std::endl << "alias:"; + // for (auto alias : a_class.aliases) { + // std::cout << "<" << alias.alias_name << "," << alias.base_name << + // ">\t"; + // } + // std::cout << std::endl + // << "namespace:" << a_class.its_namespace << std::endl + // << "constructors:"; + // for (auto constructor : a_class.constructors) { + // std::cout << constructor.signature << "\t"; + // for (auto application : constructor.applications) { + // application.cout(); + // } + // std::cout << std::endl; + // } + // std::cout << std::endl + // << "destructor:" << a_class.destructor.signature << "\t"; + // for (auto application : a_class.destructor.applications) { + // application.cout(); + // } + // std::cout << std::endl; + // std::cout << std::endl << "methods:"; + // for (auto method : a_class.methods) { + // std::cout << method.signature << "\t" << method.is_template << + // std::endl + // << "template_parameters:"; + // for (auto template_parameter : method.template_parameters) { + // std::cout << template_parameter << "\t"; + // } + // std::cout << std::endl << "specialization_parameters:"; + // for (auto specialization_parameter : method.specialization_parameters) + // { + // std::cout << "<"; + // for (auto specialization_type : specialization_parameter) { + // std::cout << specialization_type << ","; + // } + // std::cout << ">\t"; + // } + // for (auto application : method.applications) { + // application.cout(); + // } + // std::cout << std::endl; + // } + // std::cout << std::endl << "applications:"; + // for (auto application : a_class.applications) { + // application.cout(); + // } + // std::cout << std::endl << std::endl; + // } + // std::cout << "functions:" << std::endl; + // for (auto function : functions) { + // std::cout << function.function_name << "\t" << function.signature << "\t" + // << function.is_template << std::endl + // << "template_parameters:"; + // for (auto template_parameter : function.template_parameters) { + // std::cout << template_parameter << "\t"; + // } + // std::cout << std::endl << "specialization_parameters:"; + // for (auto specialization_parameter : function.specialization_parameters) + // { + // std::cout << "<"; + // for (auto specialization_type : specialization_parameter) { + // std::cout << specialization_type << ","; + // } + // std::cout << ">\t"; + // } + // std::cout << std::endl + // << "namespace:" << function.its_namespace << std::endl + // << "applications:"; + // for (auto application : function.applications) { + // application.cout(); + // } + // std::cout << std::endl << std::endl; + // } +} + +std::vector +ClassesAndFunctions::get_application_classes(std::string type) { + std::vector application_classes; + for (auto a_class : classes) { + if (a_class.class_name != "" && + type.find(a_class.class_name) != std::string::npos) { + application_classes.push_back(a_class.class_name); + } + } + return application_classes; +} + +MyRecordType ClassesAndFunctions::get_class_type(std::string class_name) { + for (auto a_class : classes) { + if (a_class.class_name == class_name) { + return a_class.record_type; + } + } +} + +void update_applications(std::vector &applications) { + std::vector need_application_types; + for (auto it = applications.begin(); it != applications.end();) { + if (it->signature == "" && + !gad_classes_and_functions.has_class(it->class_name)) { + std::vector need_application_type = + gad_classes_and_functions.get_application_classes(it->class_name); + for (auto need_application : need_application_type) { + need_application_types.push_back(need_application); + } + it = applications.erase(it); + continue; + } + // else if (!gad_classes_and_functions.has_function(it->class_name, + // it->signature)) { + // it = applications.erase(it); + // continue; + // } + else { + ++it; + continue; + } + } + for (auto need_application_type : need_application_types) { + Application application; + application.class_name = need_application_type; + application.signature = ""; + applications.push_back(application); + } + int i = 0; + while (i < applications.size()) { + auto a_application = applications[i]; + if (a_application.signature == "" + // && gad_classes_and_functions.get_class_type( + // it->class_name) != + // MyRecordType::EnumType + ) { + std::string class_name = a_application.class_name; + // it = applications.erase(it); + std::vector need_applications; + need_applications = + gad_classes_and_functions.get_constructors(class_name); + std::string need_destructor = + gad_classes_and_functions.get_destructor(class_name); + if (need_destructor != "class") { + need_applications.push_back(need_destructor); + } + for (auto need_application : need_applications) { + Application application; + application.class_name = class_name; + application.signature = need_application; + applications.push_back(application); + } + } + i++; + } + for (auto it = applications.begin(); it != applications.end();) { + // if (it->signature == "" && + // !gad_classes_and_functions.has_class(it->class_name)) { + // it = applications.erase(it); + // continue; + // } + if (it->signature != "" && !gad_classes_and_functions.has_function( + it->class_name, it->signature)) { + it = applications.erase(it); + continue; + } else { + ++it; + continue; + } + } + for (auto it = applications.begin(); it != applications.end();) { + bool b = 0; + for (auto it2 = applications.begin(); it2 != applications.end(); ++it2) { + if (it2 != it && it2->class_name == it->class_name && + it2->signature == it->signature) { + b = 1; + break; + } + } + if (b == 1) { + it = applications.erase(it); + } else { + ++it; + } + } +} + +void ClassesAndFunctions::update_all_applications() { + for (auto &a_class : classes) { + update_applications(a_class.applications); + for (auto &constructor : a_class.constructors) { + update_applications(constructor.applications); + } + update_applications(a_class.destructor.applications); + for (auto &method : a_class.methods) { + update_applications(method.applications); + } + } + for (auto &function : functions) { + // if (function.function_name == "BrotliEncoderCompress") { + // std::cout << std::endl; + // } + update_applications(function.applications); + } +} + +bool StmtVarFunctionVisitor::VisitCallExpr(CallExpr *Call) { + FunctionDecl *Callee = Call->getDirectCallee(); + if (Callee) { + Callee = Callee->getCanonicalDecl(); + if (Callee->getPrimaryTemplate()) { + Callee = Callee->getPrimaryTemplate()->getTemplatedDecl(); + } + // Callee->dump(); + if (Callee->getTemplateInstantiationPattern()) { + Callee = Callee->getTemplateInstantiationPattern(); + // InstantiatedCallee->dump(); + } + // std::cout << std::endl; + if (Callee->isCXXClassMember()) { + // std::string file_path; + // std::string class_name; + // std::string function_name; + // std::string signature; + const CXXRecordDecl *ParentClass = + dyn_cast(Callee->getParent())->getCanonicalDecl(); + std::string class_name = ParentClass->getNameAsString(); + std::string function_name = Callee->getNameAsString(); + std::string signature = get_signature(Callee); + // std::cout << "Class " << class_name << " Method " << function_name + // << " Call" << std::endl; + // std::cout << class_name << std::endl; + // std::cout << signature << std::endl; + // if (gad_classes_and_functions.has_function(class_name, signature)) { + Application application; + application.class_name = class_name; + application.signature = signature; + applications.push_back(application); + // } + } else { + // std::string file_path; + // std::string class_name; + // std::string function_name; + // std::string signature; + std::string function_name = Callee->getNameAsString(); + // std::cout << "Function Call " << function_name << std::endl; + std::string signature = get_signature(Callee); + // std::cout << signature << std::endl; + // if (gad_classes_and_functions.has_function("class", signature)) { + Application application; + application.class_name = "class"; + application.signature = signature; + applications.push_back(application); + // } + } + } + return true; +} + +bool StmtVarFunctionVisitor::VisitVarDecl(VarDecl *Var) { + if (Var) { + QualType qualType = Var->getType(); + // // if (qualType->isReferenceType()) { + // // qualType = qualType.getNonReferenceType(); + // // } + // qualType = qualType.getUnqualifiedType(); + // qualType = qualType.getNonReferenceType(); + // // qualType = qualType.getCanonicalType(); + // // const clang::Type *typePtr = qualType.getTypePtr(); + // // while (const TypedefType *typedefType = + // dyn_cast(typePtr)) { + // // const TypedefNameDecl *typedefDecl = typedefType->getDecl(); + // // qualType = typedefDecl->getUnderlyingType(); + // // } + // std::string class_name = get_application_type(qualType); + // std::vector types = + // gad_classes_and_functions.get_application_classes( + // qualType.getAsString()); + // if (class_name.find(" ") != std::string::npos) { + // class_name = class_name.substr(class_name.find_last_of(" ") + 1); + // } + // for (auto type : types) { + Application application; + application.class_name = qualType.getAsString(); + application.signature = ""; + applications.push_back(application); + // } + // Application application; + // application.class_name = class_name; + // application.signature = ""; + // applications.push_back(application); + // if (gad_classes_and_functions.has_class(class_name)) { + // std::vector need_constructors = + // gad_classes_and_functions.get_constructors(class_name); + // for (int i = 0; i < need_constructors.size(); i++) { + // std::string function_name = class_name; + // std::string signature = need_constructors[i]; + // Application application; + // application.class_name = class_name; + // application.signature = signature; + // applications.push_back(application); + // } + // std::string need_destructor = + // gad_classes_and_functions.get_destructor(class_name); + // if (need_destructor != "class") { + // std::string function_name = "~" + class_name; + // std::string signature = need_destructor; + // Application application; + // application.class_name = class_name; + // application.signature = signature; + // applications.push_back(application); + // } + // } + } + return true; +} + +std::vector StmtVarFunctionVisitor::get_applications() { + return applications; +} + +class FindClassesAndFunctionsVisitor + : public RecursiveASTVisitor { +public: + explicit FindClassesAndFunctionsVisitor(ASTContext *Context) + : Context(Context) {} + + // bool VisitTypeDecl(TypeDecl *Declaration) { + // clang::SourceLocation loc = Declaration->getLocation(); + // clang::SourceManager &SM = Context->getSourceManager(); + // clang::PresumedLoc presumedLoc = SM.getPresumedLoc(loc); + // std::string file_path = presumedLoc.getFilename(); + // if (file_path.find(gad_project_path) != std::string::npos) { + // Declaration->dump(); + // } + // return true; + // } + + bool VisitClassTemplateDecl(ClassTemplateDecl *Declaration) { + if (Declaration->isThisDeclarationADefinition()) { + clang::SourceLocation loc = Declaration->getLocation(); + clang::SourceManager &SM = Context->getSourceManager(); + clang::PresumedLoc presumedLoc = SM.getPresumedLoc(loc); + std::string file_path = presumedLoc.getFilename(); + if (file_path.find(gad_project_path) != std::string::npos) { + // std::cout << Declaration->getNameAsString() << std::endl; + // Declaration->dump(); + // std::cout << std::endl; + auto CanonicalDeclaration = Declaration->getCanonicalDecl(); + // auto canonical_declaration = Declaration->getCanonicalDecl(); + // canonical_declaration->dump(); + // Declaration->dump(); + std::string class_name = CanonicalDeclaration->getNameAsString(); + if (!gad_classes_and_functions.has_class(class_name)) { + // if (class_name == "C1") { + // Declaration->dump(); + // } + CXXRecordDecl *RecordDecl = Declaration->getTemplatedDecl(); + Class a_class; + a_class.class_name = class_name; + a_class.is_template = 1; + auto template_parameters = Declaration->getTemplateParameters(); + for (auto template_parameter : template_parameters->asArray()) { + // a_class.template_parameters.push_back( + // template_parameter->getNameAsString()); + const SourceManager &sourceManager = Context->getSourceManager(); + SourceRange srcRange_tp = template_parameter->getSourceRange(); + srcRange_tp.setEnd(Lexer::getLocForEndOfToken( + srcRange_tp.getEnd(), 0, sourceManager, + Context->getLangOpts())); + bool Invalid = false; + StringRef srcText_tp = Lexer::getSourceText( + CharSourceRange::getTokenRange(srcRange_tp), sourceManager, + Context->getLangOpts(), &Invalid); + std::string srcText_tp_str = std::string(srcText_tp); + if (srcText_tp_str.size() > 0) { + srcText_tp_str.erase(srcText_tp_str.length() - 1); + } + a_class.template_parameters.push_back(srcText_tp_str); + // std::cout << std::string(srcText_tp) << std::endl; + } + if (RecordDecl->isClass()) { + a_class.record_type = MyRecordType::ClassType; + } else if (RecordDecl->isStruct()) { + a_class.record_type = MyRecordType::StructType; + } else if (RecordDecl->isUnion()) { + a_class.record_type = MyRecordType::UnionType; + } + // if (RecordDecl->getNumBases() > 0) { + // a_class.base_class = + // RecordDecl->bases_begin()->getType().getAsString(); + // } + for (auto its_base_class : RecordDecl->bases()) { + a_class.base_class.push_back( + its_base_class.getType().getAsString()); + QualType qualType = its_base_class.getType(); + // if (qualType->isReferenceType()) { + // qualType = qualType.getNonReferenceType(); + // } + // qualType = qualType.getUnqualifiedType(); + // qualType = qualType.getNonReferenceType(); + // qualType = qualType.getCanonicalType(); + Application application; + application.class_name = qualType.getAsString(); + application.signature = ""; + a_class.applications.push_back(application); + } + const DeclContext *context = Declaration->getDeclContext(); + bool b = 0; + while (context) { + if (const NamespaceDecl *namespaceDecl = + dyn_cast(context)) { + b = 1; + if (a_class.its_namespace == "") { + a_class.its_namespace = namespaceDecl->getNameAsString(); + } else { + a_class.its_namespace = namespaceDecl->getNameAsString() + + "::" + a_class.its_namespace; + } + } + context = context->getParent(); + } + if (b == 0) { + a_class.its_namespace = ""; + } + for (const auto *decl : RecordDecl->decls()) { + // if (decl->getCanonicalDecl() == CanonicalDeclaration) { + // continue; + // } + // if (const CXXRecordDecl *Record = dyn_cast(decl)) + // { + // if (i == 0) { + // continue; + // } + // const SourceManager &sourceManager = + // Context->getSourceManager(); SourceRange srcRange = + // Record->getSourceRange(); + // srcRange.setEnd(Lexer::getLocForEndOfToken( + // srcRange.getEnd(), 0, sourceManager, + // Context->getLangOpts())); + // bool Invalid = false; + // StringRef srcText = Lexer::getSourceText( + // CharSourceRange::getTokenRange(srcRange), sourceManager, + // Context->getLangOpts(), &Invalid); + // // std::cout << std::string(srcText) << std::endl; + // std::string srcText_str = std::string(srcText); + // if (srcText_str[srcText_str.length() - 1] == ';') { + // srcText_str.erase(srcText_str.length() - 1); + // } + // // if (Record->isClass()) { + // // if (srcText.find('{') != std::string::npos) { + // // srcText_str.erase(srcText_str.find_first_of('{')); + // // } + // // a_class.fields.push_back(srcText_str); + // // } else { + // // a_class.fields.push_back(srcText_str); + // // } + // a_class.fields.push_back(srcText_str); + // } + if (const FieldDecl *Field = dyn_cast(decl)) { + std::string field_type = Field->getType().getAsString(); + // // if (field_type.find(" ") != std::string::npos) { + // // field_type = + // // field_type.substr(field_type.find_last_of(" ") + 1); + // // } + // // QualType qualType = Field->getType(); + // // // if (qualType->isReferenceType()) { + // // // qualType = qualType.getNonReferenceType(); + // // // } + // // qualType = qualType.getUnqualifiedType(); + // // qualType = qualType.getNonReferenceType(); + // std::vector types = + // gad_classes_and_functions.get_application_classes(field_type); + // for (auto type : types) { + Application application; + application.class_name = field_type; + application.signature = ""; + a_class.applications.push_back(application); + // } + // qualType = qualType.getCanonicalType(); + // Application application; + // application.class_name = get_application_type(qualType); + // application.signature = ""; + // a_class.applications.push_back(application); + const SourceManager &sourceManager = Context->getSourceManager(); + SourceRange srcRange = Field->getSourceRange(); + srcRange.setEnd(Lexer::getLocForEndOfToken( + srcRange.getEnd(), 0, sourceManager, Context->getLangOpts())); + bool Invalid = false; + StringRef srcText = Lexer::getSourceText( + CharSourceRange::getTokenRange(srcRange), sourceManager, + Context->getLangOpts(), &Invalid); + // std::cout << std::string(srcText) << std::endl; + std::string srcText_str = std::string(srcText); + if (srcText_str[srcText_str.length() - 1] == ';') { + srcText_str.erase(srcText_str.length() - 1); + } + if (srcText_str.find("{") != std::string::npos) { + srcText_str.erase(srcText_str.find_first_of("{"), + srcText_str.find_last_of("}") + 1 - + srcText_str.find_first_of("{")); + } + if (srcText_str.find("class") != std::string::npos) { + srcText_str.erase(srcText_str.find_first_of("class"), 6); + } + if (srcText_str.find("struct") != std::string::npos) { + srcText_str.erase(srcText_str.find_first_of("struct"), 7); + } + if (srcText_str.find("enum") != std::string::npos) { + srcText_str.erase(srcText_str.find_first_of("enum"), 5); + } + if (srcText_str.find("union") != std::string::npos) { + srcText_str.erase(srcText_str.find_first_of("union"), 6); + } + a_class.fields.push_back(srcText_str); + } + // else if (const EnumDecl *Enum = dyn_cast(decl)) { + // const SourceManager &sourceManager = + // Context->getSourceManager(); SourceRange srcRange = + // Enum->getSourceRange(); + // srcRange.setEnd(Lexer::getLocForEndOfToken( + // srcRange.getEnd(), 0, sourceManager, + // Context->getLangOpts())); + // bool Invalid = false; + // StringRef srcText = Lexer::getSourceText( + // CharSourceRange::getTokenRange(srcRange), sourceManager, + // Context->getLangOpts(), &Invalid); + // // std::cout << std::string(srcText) << std::endl; + // std::string srcText_str = std::string(srcText); + // if (srcText_str[srcText_str.length() - 1] == ';') { + // srcText_str.erase(srcText_str.length() - 1); + // } + // a_class.fields.push_back(srcText_str); + // } + else if (const TypeAliasDecl *TypeAlias = + dyn_cast(decl)) { + Alias alias; + alias.alias_name = TypeAlias->getNameAsString(); + alias.base_name = TypeAlias->getUnderlyingType().getAsString(); + // QualType qualType = TypeAlias->getUnderlyingType(); + // if (qualType->isReferenceType()) { + // qualType = qualType.getNonReferenceType(); + // } + // qualType = qualType.getUnqualifiedType(); + // qualType = qualType.getNonReferenceType(); + // qualType = qualType.getCanonicalType(); + a_class.aliases.push_back(alias); + // std::vector types = + // gad_classes_and_functions.get_application_classes( + // alias.base_name); + // for (auto type : types) { + Application application; + application.class_name = alias.base_name; + application.signature = ""; + a_class.applications.push_back(application); + // } + // Application application; + // application.class_name = get_application_type(qualType); + // application.signature = ""; + // a_class.applications.push_back(application); + // if (gad_classes_and_functions.has_class(alias.base_name)) { + // std::vector constructors = + // gad_classes_and_functions.get_constructors(alias.base_name); + // std::vector> + // applications; for (auto constructor : constructors) { + // applications.push_back(std::pair( + // alias.base_name, constructor)); + // } + // std::string destructor = + // gad_classes_and_functions.get_destructor(alias.base_name); + // if (destructor != "class") { + // applications.push_back(std::pair( + // alias.base_name, destructor)); + // } + // for (auto application : applications) { + // Application a_application; + // a_application.class_name = application.first; + // a_application.signature = application.second; + // a_class.applications.push_back(a_application); + // } + // } + } + } + // i = 1; + // while (i < a_class.fields.size()) { + // if (a_class.fields[i] == a_class.fields[i - 1] || + // (a_class.fields[i].substr( + // 0, a_class.fields[i].find_last_of('}') + 1) != "" && + // a_class.fields[i - 1].substr( + // 0, a_class.fields[i - 1].find_last_of('}') + 1) != "" && + // a_class.fields[i].substr( + // 0, a_class.fields[i].find_last_of('}') + 1) == + // a_class.fields[i - 1].substr( + // 0, a_class.fields[i - 1].find_last_of('}') + 1)) || + // a_class.fields[i].find(a_class.fields[i - 1]) != + // std::string::npos) { + // a_class.fields.erase(a_class.fields.begin() + i - 1); + // } else { + // i++; + // } + // } + // i = 0; + // while (i < a_class.fields.size()) { + // if (a_class.fields[i] == "union" || a_class.fields[i] == "struct" + // || + // a_class.fields[i] == "class" || a_class.fields[i] == "enum") + // { + // a_class.fields.erase(a_class.fields.begin() + i); + // } else { + // i++; + // } + // } + // std::cout << a_class.class_name << "\t" << a_class.base_class + // << std::endl; + // for (auto template_parameter : a_class.template_parameters) { + // std::cout << template_parameter << "\t"; + // } + // std::cout << std::endl; + gad_classes_and_functions.push_back_class(a_class); + } + for (auto specialization : Declaration->specializations()) { + std::vector specialization_parameter; + std::vector> applications; + for (unsigned i = 0; i < specialization->getTemplateArgs().size(); + ++i) { + const TemplateArgument &Arg = + specialization->getTemplateArgs().get(i); + if (Arg.getKind() == TemplateArgument::Type) { + // std::cout << "Specialization Argument: " + // << Arg.getAsType().getAsString() << "\n"; + std::string type_name = Arg.getAsType().getAsString(); + // if (type_name.find(" ") != std::string::npos) { + // type_name = type_name.substr(type_name.find_last_of(" ") + + // 1); + // } + specialization_parameter.push_back(type_name); + // QualType qualType = Arg.getAsType(); + // if (qualType->isReferenceType()) { + // qualType = qualType.getNonReferenceType(); + // } + // qualType = qualType.getUnqualifiedType(); + // qualType = qualType.getNonReferenceType(); + // qualType = qualType.getCanonicalType(); + // std::vector types = + // gad_classes_and_functions.get_application_classes(type_name); + // for (auto type : types) { + std::pair application; + application.first = type_name; + application.second = ""; + applications.push_back(application); + // } + // std::pair application; + // application.first = get_application_type(qualType); + // application.second = ""; + // applications.push_back(application); + } + } + gad_classes_and_functions.push_back_specialization_parameter( + class_name, "", specialization_parameter); + gad_classes_and_functions.push_back_applications(class_name, "", + applications); + } + // gad_classes_and_functions.cout(); + } + } + return true; + } + + bool VisitRecordDecl(RecordDecl *Declaration) { + if (Declaration->isThisDeclarationADefinition()) { + // Declaration->dump(); + clang::SourceLocation loc = Declaration->getLocation(); + clang::SourceManager &SM = Context->getSourceManager(); + clang::PresumedLoc presumedLoc = SM.getPresumedLoc(loc); + std::string file_path = presumedLoc.getFilename(); + if (file_path.find(gad_project_path) != std::string::npos) { + if (auto CXXDeclaration = dyn_cast(Declaration)) { + // std::cout << Declaration->getNameAsString() << std::endl; + // Declaration->dump(); + // std::cout << std::endl; + auto CanonicalDeclaration = CXXDeclaration->getCanonicalDecl(); + // auto canonical_declaration = Declaration->getCanonicalDecl(); + // canonical_declaration->dump(); + // Declaration->dump(); + std::string class_name = CanonicalDeclaration->getNameAsString(); + if (!gad_classes_and_functions.has_class(class_name)) { + Class a_class; + a_class.class_name = class_name; + a_class.is_template = 0; + if (CXXDeclaration->isClass()) { + a_class.record_type = MyRecordType::ClassType; + } else if (CXXDeclaration->isStruct()) { + a_class.record_type = MyRecordType::StructType; + } else if (CXXDeclaration->isUnion()) { + a_class.record_type = MyRecordType::UnionType; + } + // if (RecordDecl->getNumBases() > 0) { + // a_class.base_class = + // RecordDecl->bases_begin()->getType().getAsString(); + // } + for (auto its_base_class : CXXDeclaration->bases()) { + a_class.base_class.push_back( + its_base_class.getType().getAsString()); + QualType qualType = its_base_class.getType(); + // if (qualType->isReferenceType()) { + // qualType = qualType.getNonReferenceType(); + // } + // qualType = qualType.getUnqualifiedType(); + // qualType = qualType.getNonReferenceType(); + // qualType = qualType.getCanonicalType(); + // std::vector types = + // gad_classes_and_functions.get_application_classes( + // qualType.getAsString()); + // for (auto type : types) { + Application application; + application.class_name = qualType.getAsString(); + application.signature = ""; + a_class.applications.push_back(application); + // } + // Application application; + // application.class_name = get_application_type(qualType); + // application.signature = ""; + // a_class.applications.push_back(application); + } + const DeclContext *context = CXXDeclaration->getDeclContext(); + bool b = 0; + while (context) { + if (const NamespaceDecl *namespaceDecl = + dyn_cast(context)) { + b = 1; + if (a_class.its_namespace == "") { + a_class.its_namespace = namespaceDecl->getNameAsString(); + } else { + a_class.its_namespace = namespaceDecl->getNameAsString() + + "::" + a_class.its_namespace; + } + } + context = context->getParent(); + } + if (b == 0) { + a_class.its_namespace = ""; + } + for (const auto *decl : CXXDeclaration->decls()) { + // if (decl->getCanonicalDecl() == CanonicalDeclaration) { + // continue; + // } + // if (const CXXRecordDecl *Record = + // dyn_cast(decl)) + // { + // if (i == 0) { + // continue; + // } + // const SourceManager &sourceManager = + // Context->getSourceManager(); SourceRange srcRange = + // Record->getSourceRange(); + // srcRange.setEnd(Lexer::getLocForEndOfToken( + // srcRange.getEnd(), 0, sourceManager, + // Context->getLangOpts())); + // bool Invalid = false; + // StringRef srcText = Lexer::getSourceText( + // CharSourceRange::getTokenRange(srcRange), sourceManager, + // Context->getLangOpts(), &Invalid); + // // std::cout << std::string(srcText) << std::endl; + // std::string srcText_str = std::string(srcText); + // if (srcText_str[srcText_str.length() - 1] == ';') { + // srcText_str.erase(srcText_str.length() - 1); + // } + // // if (Record->isClass()) { + // // if (srcText.find('{') != std::string::npos) { + // // srcText_str.erase(srcText_str.find_first_of('{')); + // // } + // // a_class.fields.push_back(srcText_str); + // // } else { + // // a_class.fields.push_back(srcText_str); + // // } + // a_class.fields.push_back(srcText_str); + // } + if (const FieldDecl *Field = dyn_cast(decl)) { + std::string field_type = Field->getType().getAsString(); + // if (field_type.find(" ") != std::string::npos) { + // field_type = + // field_type.substr(field_type.find_last_of(" ") + 1); + // } + // QualType qualType = Field->getType(); + // if (qualType->isReferenceType()) { + // qualType = qualType.getNonReferenceType(); + // } + // qualType = qualType.getUnqualifiedType(); + // qualType = qualType.getNonReferenceType(); + // qualType = qualType.getCanonicalType(); + // std::vector types = + // gad_classes_and_functions.get_application_classes( + // field_type); + // for (auto type : types) { + Application application; + application.class_name = field_type; + application.signature = ""; + a_class.applications.push_back(application); + // } + // Application application; + // application.class_name = get_application_type(qualType); + // application.signature = ""; + // a_class.applications.push_back(application); + const SourceManager &sourceManager = + Context->getSourceManager(); + SourceRange srcRange = Field->getSourceRange(); + srcRange.setEnd(Lexer::getLocForEndOfToken( + srcRange.getEnd(), 0, sourceManager, + Context->getLangOpts())); + bool Invalid = false; + StringRef srcText = Lexer::getSourceText( + CharSourceRange::getTokenRange(srcRange), sourceManager, + Context->getLangOpts(), &Invalid); + // std::cout << std::string(srcText) << std::endl; + std::string srcText_str = std::string(srcText); + if (srcText_str[srcText_str.length() - 1] == ';') { + srcText_str.erase(srcText_str.length() - 1); + } + if (srcText_str.find("{") != std::string::npos) { + srcText_str.erase(srcText_str.find_first_of("{"), + srcText_str.find_last_of("}") + 1 - + srcText_str.find_first_of("{")); + } + if (srcText_str.find("class") != std::string::npos) { + srcText_str.erase(srcText_str.find_first_of("class"), 6); + } + if (srcText_str.find("struct") != std::string::npos) { + srcText_str.erase(srcText_str.find_first_of("struct"), 7); + } + if (srcText_str.find("enum") != std::string::npos) { + srcText_str.erase(srcText_str.find_first_of("enum"), 5); + } + if (srcText_str.find("union") != std::string::npos) { + srcText_str.erase(srcText_str.find_first_of("union"), 6); + } + a_class.fields.push_back(srcText_str); + } + // else if (const EnumDecl *Enum = dyn_cast(decl)) { + // const SourceManager &sourceManager = + // Context->getSourceManager(); SourceRange srcRange = + // Enum->getSourceRange(); + // srcRange.setEnd(Lexer::getLocForEndOfToken( + // srcRange.getEnd(), 0, sourceManager, + // Context->getLangOpts())); + // bool Invalid = false; + // StringRef srcText = Lexer::getSourceText( + // CharSourceRange::getTokenRange(srcRange), sourceManager, + // Context->getLangOpts(), &Invalid); + // // std::cout << std::string(srcText) << std::endl; + // std::string srcText_str = std::string(srcText); + // if (srcText_str[srcText_str.length() - 1] == ';') { + // srcText_str.erase(srcText_str.length() - 1); + // } + // a_class.fields.push_back(srcText_str); + // } + else if (const TypeAliasDecl *TypeAlias = + dyn_cast(decl)) { + Alias alias; + alias.alias_name = TypeAlias->getNameAsString(); + alias.base_name = TypeAlias->getUnderlyingType().getAsString(); + // QualType qualType = TypeAlias->getUnderlyingType(); + // if (qualType->isReferenceType()) { + // qualType = qualType.getNonReferenceType(); + // } + // qualType = qualType.getUnqualifiedType(); + // qualType = qualType.getNonReferenceType(); + // qualType = qualType.getCanonicalType(); + a_class.aliases.push_back(alias); + // std::vector types = + // gad_classes_and_functions.get_application_classes( + // alias.base_name); + // for (auto type : types) { + Application application; + application.class_name = alias.base_name; + application.signature = ""; + a_class.applications.push_back(application); + // } + // Application application; + // application.class_name = get_application_type(qualType); + // application.signature = ""; + // a_class.applications.push_back(application); + // if (gad_classes_and_functions.has_class(alias.base_name)) { + // std::vector constructors = + // gad_classes_and_functions.get_constructors(alias.base_name); + // std::vector> + // applications; for (auto constructor : constructors) { + // applications.push_back(std::pair( + // alias.base_name, constructor)); + // } + // std::string destructor = + // gad_classes_and_functions.get_destructor(alias.base_name); + // if (destructor != "class") { + // applications.push_back(std::pair( + // alias.base_name, destructor)); + // } + // for (auto application : applications) { + // Application a_application; + // a_application.class_name = application.first; + // a_application.signature = application.second; + // a_class.applications.push_back(a_application); + // } + // } + } + } + // i = 1; + // while (i < a_class.fields.size()) { + // if (a_class.fields[i] == a_class.fields[i - 1] || + // (a_class.fields[i].substr( + // 0, a_class.fields[i].find_last_of('}') + 1) != "" && + // a_class.fields[i - 1].substr( + // 0, a_class.fields[i - 1].find_last_of('}') + 1) != "" + // && + // a_class.fields[i].substr( + // 0, a_class.fields[i].find_last_of('}') + 1) == + // a_class.fields[i - 1].substr( + // 0, a_class.fields[i - 1].find_last_of('}') + 1)) + // || + // a_class.fields[i].find(a_class.fields[i - 1]) != + // std::string::npos) { + // a_class.fields.erase(a_class.fields.begin() + i - 1); + // } else { + // i++; + // } + // } + // i = 0; + // while (i < a_class.fields.size()) { + // if (a_class.fields[i] == "union" || a_class.fields[i] == + // "struct" + // || + // a_class.fields[i] == "class" || a_class.fields[i] == + // "enum") + // { + // a_class.fields.erase(a_class.fields.begin() + i); + // } else { + // i++; + // } + // } + // std::cout << a_class.class_name << "\t" << a_class.base_class + // << std::endl; + // for (auto template_parameter : a_class.template_parameters) { + // std::cout << template_parameter << "\t"; + // } + // std::cout << std::endl; + gad_classes_and_functions.push_back_class(a_class); + } + } + // gad_classes_and_functions.cout(); + else { // std::cout << Declaration->getNameAsString() << std::endl; + // Declaration->dump(); + // std::cout << std::endl; + auto CanonicalDeclaration = Declaration->getCanonicalDecl(); + std::string class_name = CanonicalDeclaration->getNameAsString(); + for (auto *D : CanonicalDeclaration->getDeclContext()->decls()) { + if (auto *TD = dyn_cast(D)) { + if (auto *TRD = TD->getUnderlyingType()->getAsRecordDecl()) { + if (TRD->getCanonicalDecl() == CanonicalDeclaration) { + class_name = TD->getNameAsString(); + break; + } + } + } + } + // auto canonical_declaration = Declaration->getCanonicalDecl(); + // CanonicalDeclaration->dump(); + // Declaration->dump(); + if (!gad_classes_and_functions.has_class(class_name)) { + Class a_class; + a_class.class_name = class_name; + if (Declaration->isClass()) { + a_class.record_type = MyRecordType::ClassType; + } else if (Declaration->isStruct()) { + a_class.record_type = MyRecordType::StructType; + } else if (Declaration->isUnion()) { + a_class.record_type = MyRecordType::UnionType; + } + // if (RecordDecl->getNumBases() > 0) { + // a_class.base_class = + // RecordDecl->bases_begin()->getType().getAsString(); + // } + const DeclContext *context = Declaration->getDeclContext(); + bool b = 0; + while (context) { + if (const NamespaceDecl *namespaceDecl = + dyn_cast(context)) { + b = 1; + if (a_class.its_namespace == "") { + a_class.its_namespace = namespaceDecl->getNameAsString(); + } else { + a_class.its_namespace = namespaceDecl->getNameAsString() + + "::" + a_class.its_namespace; + } + } + context = context->getParent(); + } + if (b == 0) { + a_class.its_namespace = ""; + } + for (const auto *decl : Declaration->decls()) { + // if (decl->getCanonicalDecl() == CanonicalDeclaration) { + // continue; + // } + // if (const CXXRecordDecl *Record = + // dyn_cast(decl)) + // { + // if (i == 0) { + // continue; + // } + // const SourceManager &sourceManager = + // Context->getSourceManager(); SourceRange srcRange = + // Record->getSourceRange(); + // srcRange.setEnd(Lexer::getLocForEndOfToken( + // srcRange.getEnd(), 0, sourceManager, + // Context->getLangOpts())); + // bool Invalid = false; + // StringRef srcText = Lexer::getSourceText( + // CharSourceRange::getTokenRange(srcRange), sourceManager, + // Context->getLangOpts(), &Invalid); + // // std::cout << std::string(srcText) << std::endl; + // std::string srcText_str = std::string(srcText); + // if (srcText_str[srcText_str.length() - 1] == ';') { + // srcText_str.erase(srcText_str.length() - 1); + // } + // // if (Record->isClass()) { + // // if (srcText.find('{') != std::string::npos) { + // // srcText_str.erase(srcText_str.find_first_of('{')); + // // } + // // a_class.fields.push_back(srcText_str); + // // } else { + // // a_class.fields.push_back(srcText_str); + // // } + // a_class.fields.push_back(srcText_str); + // } + if (const FieldDecl *Field = dyn_cast(decl)) { + std::string field_type = Field->getType().getAsString(); + // if (field_type.find(" ") != std::string::npos) { + // field_type = + // field_type.substr(field_type.find_last_of(" ") + 1); + // } + // QualType qualType = Field->getType(); + // if (qualType->isReferenceType()) { + // qualType = qualType.getNonReferenceType(); + // } + // qualType = qualType.getUnqualifiedType(); + // qualType = qualType.getNonReferenceType(); + // qualType = qualType.getCanonicalType(); + // std::vector types = + // gad_classes_and_functions.get_application_classes( + // field_type); + // for (auto type : types) { + Application application; + application.class_name = field_type; + application.signature = ""; + a_class.applications.push_back(application); + // } + // Application application; + // application.class_name = get_application_type(qualType); + // application.signature = ""; + // a_class.applications.push_back(application); + const SourceManager &sourceManager = + Context->getSourceManager(); + SourceRange srcRange = Field->getSourceRange(); + srcRange.setEnd(Lexer::getLocForEndOfToken( + srcRange.getEnd(), 0, sourceManager, + Context->getLangOpts())); + bool Invalid = false; + StringRef srcText = Lexer::getSourceText( + CharSourceRange::getTokenRange(srcRange), sourceManager, + Context->getLangOpts(), &Invalid); + // std::cout << std::string(srcText) << std::endl; + std::string srcText_str = std::string(srcText); + if (srcText_str[srcText_str.length() - 1] == ';') { + srcText_str.erase(srcText_str.length() - 1); + } + if (srcText_str.find("{") != std::string::npos) { + srcText_str.erase(srcText_str.find_first_of("{"), + srcText_str.find_last_of("}") + 1 - + srcText_str.find_first_of("{")); + } + if (srcText_str.find("class") != std::string::npos) { + srcText_str.erase(srcText_str.find_first_of("class"), 6); + } + if (srcText_str.find("struct") != std::string::npos) { + srcText_str.erase(srcText_str.find_first_of("struct"), 7); + } + if (srcText_str.find("enum") != std::string::npos) { + srcText_str.erase(srcText_str.find_first_of("enum"), 5); + } + if (srcText_str.find("union") != std::string::npos) { + srcText_str.erase(srcText_str.find_first_of("union"), 6); + } + a_class.fields.push_back(srcText_str); + } + // else if (const EnumDecl *Enum = dyn_cast(decl)) { + // const SourceManager &sourceManager = + // Context->getSourceManager(); SourceRange srcRange = + // Enum->getSourceRange(); + // srcRange.setEnd(Lexer::getLocForEndOfToken( + // srcRange.getEnd(), 0, sourceManager, + // Context->getLangOpts())); + // bool Invalid = false; + // StringRef srcText = Lexer::getSourceText( + // CharSourceRange::getTokenRange(srcRange), sourceManager, + // Context->getLangOpts(), &Invalid); + // // std::cout << std::string(srcText) << std::endl; + // std::string srcText_str = std::string(srcText); + // if (srcText_str[srcText_str.length() - 1] == ';') { + // srcText_str.erase(srcText_str.length() - 1); + // } + // a_class.fields.push_back(srcText_str); + // } + else if (const TypeAliasDecl *TypeAlias = + dyn_cast(decl)) { + Alias alias; + alias.alias_name = TypeAlias->getNameAsString(); + alias.base_name = TypeAlias->getUnderlyingType().getAsString(); + // QualType qualType = TypeAlias->getUnderlyingType(); + // if (qualType->isReferenceType()) { + // qualType = qualType.getNonReferenceType(); + // } + // qualType = qualType.getUnqualifiedType(); + // qualType = qualType.getNonReferenceType(); + // qualType = qualType.getCanonicalType(); + a_class.aliases.push_back(alias); + // std::vector types = + // gad_classes_and_functions.get_application_classes( + // alias.base_name); + // for (auto type : types) { + Application application; + application.class_name = alias.base_name; + application.signature = ""; + a_class.applications.push_back(application); + // } + // Application application; + // application.class_name = get_application_type(qualType); + // application.signature = ""; + // a_class.applications.push_back(application); + // if (gad_classes_and_functions.has_class(alias.base_name)) { + // std::vector constructors = + // gad_classes_and_functions.get_constructors(alias.base_name); + // std::vector> + // applications; for (auto constructor : constructors) { + // applications.push_back(std::pair( + // alias.base_name, constructor)); + // } + // std::string destructor = + // gad_classes_and_functions.get_destructor(alias.base_name); + // if (destructor != "class") { + // applications.push_back(std::pair( + // alias.base_name, destructor)); + // } + // for (auto application : applications) { + // Application a_application; + // a_application.class_name = application.first; + // a_application.signature = application.second; + // a_class.applications.push_back(a_application); + // } + // } + } + } + // i = 1; + // while (i < a_class.fields.size()) { + // if (a_class.fields[i] == a_class.fields[i - 1] || + // (a_class.fields[i].substr( + // 0, a_class.fields[i].find_last_of('}') + 1) != "" && + // a_class.fields[i - 1].substr( + // 0, a_class.fields[i - 1].find_last_of('}') + 1) != "" + // && + // a_class.fields[i].substr( + // 0, a_class.fields[i].find_last_of('}') + 1) == + // a_class.fields[i - 1].substr( + // 0, a_class.fields[i - 1].find_last_of('}') + 1)) + // || + // a_class.fields[i].find(a_class.fields[i - 1]) != + // std::string::npos) { + // a_class.fields.erase(a_class.fields.begin() + i - 1); + // } else { + // i++; + // } + // } + // i = 0; + // while (i < a_class.fields.size()) { + // if (a_class.fields[i] == "union" || a_class.fields[i] == + // "struct" + // || + // a_class.fields[i] == "class" || a_class.fields[i] == + // "enum") + // { + // a_class.fields.erase(a_class.fields.begin() + i); + // } else { + // i++; + // } + // } + // std::cout << a_class.class_name << "\t" << a_class.base_class + // << std::endl; + // for (auto template_parameter : a_class.template_parameters) { + // std::cout << template_parameter << "\t"; + // } + // std::cout << std::endl; + gad_classes_and_functions.push_back_class(a_class); + } + } + } + } + return true; + } + + // bool VisitCXXRecordDecl(CXXRecordDecl *Declaration) { + // if (Declaration->isThisDeclarationADefinition()) { + // clang::SourceLocation loc = Declaration->getLocation(); + // clang::SourceManager &SM = Context->getSourceManager(); + // clang::PresumedLoc presumedLoc = SM.getPresumedLoc(loc); + // std::string file_path = presumedLoc.getFilename(); + // if (file_path.find(gad_project_path) != std::string::npos) { + // // std::cout << Declaration->getNameAsString() << std::endl; + // // Declaration->dump(); + // // std::cout << std::endl; + // auto canonical_declaration = Declaration->getCanonicalDecl(); + // canonical_declaration->dump(); + // Declaration->dump(); + // std::string class_name = Declaration->getNameAsString(); + // if (!gad_classes_and_functions.has_class(class_name)) { + // Class a_class; + // a_class.class_name = class_name; + // a_class.is_template = 0; + // // if (Declaration->getNumBases() > 0) { + // // a_class.base_class = + // // Declaration->bases_begin()->getType().getAsString(); + // // } + // for (auto its_base_class : Declaration->bases()) { + // a_class.base_class.push_back( + // its_base_class.getType().getAsString()); + // } + // const DeclContext *context = Declaration->getDeclContext(); + // bool b = 0; + // while (context) { + // if (const NamespaceDecl *namespaceDecl = + // dyn_cast(context)) { + // b = 1; + // if (a_class.its_namespace == "") { + // a_class.its_namespace = namespaceDecl->getNameAsString(); + // } else { + // a_class.its_namespace = namespaceDecl->getNameAsString() + + // "::" + a_class.its_namespace; + // } + // } + // context = context->getParent(); + // } + // if (b == 0) { + // a_class.its_namespace = ""; + // } + // int i = 0; + // for (const auto *decl : Declaration->decls()) { + // if (i == 0) { + // continue; + // } + // // if (const CXXRecordDecl *Record = + // dyn_cast(decl)) + // // { + // // if (i == 0) { + // // continue; + // // } + // // const SourceManager &sourceManager = + // // Context->getSourceManager(); SourceRange srcRange = + // // Record->getSourceRange(); + // // srcRange.setEnd(Lexer::getLocForEndOfToken( + // // srcRange.getEnd(), 0, sourceManager, + // // Context->getLangOpts())); + // // bool Invalid = false; + // // StringRef srcText = Lexer::getSourceText( + // // CharSourceRange::getTokenRange(srcRange), sourceManager, + // // Context->getLangOpts(), &Invalid); + // // // std::cout << std::string(srcText) << std::endl; + // // std::string srcText_str = std::string(srcText); + // // if (srcText_str[srcText_str.length() - 1] == ';') { + // // srcText_str.erase(srcText_str.length() - 1); + // // } + // // // if (Record->isClass()) { + // // // if (srcText.find('{') != std::string::npos) { + // // // srcText_str.erase(srcText_str.find_first_of('{')); + // // // } + // // // a_class.fields.push_back(srcText_str); + // // // } else { + // // // a_class.fields.push_back(srcText_str); + // // // } + // // a_class.fields.push_back(srcText_str); + // // } + // if (const FieldDecl *Field = dyn_cast(decl)) { + // std::string field_type = Field->getType().getAsString(); + // if (field_type.find(" ") != std::string::npos) { + // field_type = + // field_type.substr(field_type.find_last_of(" ") + 1); + // } + // Application application; + // application.class_name = field_type; + // application.signature = ""; + // a_class.applications.push_back(application); + // const SourceManager &sourceManager = + // Context->getSourceManager(); SourceRange srcRange = + // Field->getSourceRange(); + // srcRange.setEnd(Lexer::getLocForEndOfToken( + // srcRange.getEnd(), 0, sourceManager, + // Context->getLangOpts())); + // bool Invalid = false; + // StringRef srcText = Lexer::getSourceText( + // CharSourceRange::getTokenRange(srcRange), sourceManager, + // Context->getLangOpts(), &Invalid); + // // std::cout << std::string(srcText) << std::endl; + // std::string srcText_str = std::string(srcText); + // if (srcText_str[srcText_str.length() - 1] == ';') { + // srcText_str.erase(srcText_str.length() - 1); + // } + // a_class.fields.push_back(srcText_str); + // } + // // else if (const EnumDecl *Enum = dyn_cast(decl)) { + // // const SourceManager &sourceManager = + // // Context->getSourceManager(); SourceRange srcRange = + // // Enum->getSourceRange(); + // // srcRange.setEnd(Lexer::getLocForEndOfToken( + // // srcRange.getEnd(), 0, sourceManager, + // // Context->getLangOpts())); + // // bool Invalid = false; + // // StringRef srcText = Lexer::getSourceText( + // // CharSourceRange::getTokenRange(srcRange), sourceManager, + // // Context->getLangOpts(), &Invalid); + // // // std::cout << std::string(srcText) << std::endl; + // // std::string srcText_str = std::string(srcText); + // // if (srcText_str[srcText_str.length() - 1] == ';') { + // // srcText_str.erase(srcText_str.length() - 1); + // // } + // // a_class.fields.push_back(srcText_str); + // // } + // else if (const TypeAliasDecl *TypeAlias = + // dyn_cast(decl)) { + // Alias alias; + // alias.alias_name = TypeAlias->getNameAsString(); + // alias.base_name = TypeAlias->getUnderlyingType().getAsString(); + // a_class.aliases.push_back(alias); + // Application application; + // application.class_name = alias.base_name; + // application.signature = ""; + // a_class.applications.push_back(application); + // // if (gad_classes_and_functions.has_class(alias.base_name)) { + // // std::vector constructors = + // // gad_classes_and_functions.get_constructors(alias.base_name); + // // std::vector> + // // applications; for (auto constructor : constructors) { + // // applications.push_back(std::pair( + // // alias.base_name, constructor)); + // // } + // // std::string destructor = + // // gad_classes_and_functions.get_destructor(alias.base_name); + // // if (destructor != "class") { + // // applications.push_back(std::pair( + // // alias.base_name, destructor)); + // // } + // // for (auto application : applications) { + // // Application a_application; + // // a_application.class_name = application.first; + // // a_application.signature = application.second; + // // a_class.applications.push_back(a_application); + // // } + // // } + // } + // i++; + // } + // // i = 1; + // // while (i < a_class.fields.size()) { + // // if (a_class.fields[i] == a_class.fields[i - 1] || + // // (a_class.fields[i].substr( + // // 0, a_class.fields[i].find_last_of('}') + 1) != "" && + // // a_class.fields[i - 1].substr( + // // 0, a_class.fields[i - 1].find_last_of('}') + 1) != "" + // && + // // a_class.fields[i].substr( + // // 0, a_class.fields[i].find_last_of('}') + 1) == + // // a_class.fields[i - 1].substr( + // // 0, a_class.fields[i - 1].find_last_of('}') + 1)) + // || + // // a_class.fields[i].find(a_class.fields[i - 1]) != + // // std::string::npos) { + // // a_class.fields.erase(a_class.fields.begin() + i - 1); + // // } else { + // // i++; + // // } + // // } + // // i = 0; + // // while (i < a_class.fields.size()) { + // // if (a_class.fields[i] == "union" || a_class.fields[i] == + // "struct" + // // || + // // a_class.fields[i] == "class" || a_class.fields[i] == + // "enum") + // // { + // // a_class.fields.erase(a_class.fields.begin() + i); + // // } else { + // // i++; + // // } + // // } + // // std::cout << a_class.class_name << "\t" << a_class.base_class + // // << std::endl; + // // for (auto template_parameter : a_class.template_parameters) { + // // std::cout << template_parameter << "\t"; + // // } + // // std::cout << std::endl; + // gad_classes_and_functions.push_back_class(a_class); + // } + // // gad_classes_and_functions.cout(); + // } + // } + // return true; + // } + + bool VisitFunctionTemplateDecl(FunctionTemplateDecl *Declaration) { + if (Declaration->isThisDeclarationADefinition()) { + clang::SourceLocation loc = Declaration->getLocation(); + clang::SourceManager &SM = Context->getSourceManager(); + clang::PresumedLoc presumedLoc = SM.getPresumedLoc(loc); + std::string file_path = presumedLoc.getFilename(); + if (file_path.find(gad_project_path) != std::string::npos) { + // std::cout << get_signature(Declaration->getAsFunction()) << + // std::endl; Declaration->dump(); std::cout << std::endl; + auto CanonicalDeclaration = Declaration->getCanonicalDecl(); + // auto canonical_declaration = Declaration->getCanonicalDecl(); + // canonical_declaration->dump(); + // Declaration->dump(); + FunctionDecl *Func = Declaration->getTemplatedDecl(); + FunctionDecl *CanonicalFunc = Func->getCanonicalDecl(); + if (!isa(Func)) { + std::string function_name = CanonicalDeclaration->getNameAsString(); + std::string signature = get_signature(CanonicalFunc); + if (!gad_classes_and_functions.has_function("class", signature)) { + Function function; + // std::vector applications; + function.function_name = function_name; + function.signature = signature; + function.is_template = 1; + auto template_parameters = Declaration->getTemplateParameters(); + for (auto template_parameter : template_parameters->asArray()) { + // function.template_parameters.push_back( + // template_parameter->getNameAsString()); + const SourceManager &sourceManager = Context->getSourceManager(); + SourceRange srcRange_tp = template_parameter->getSourceRange(); + srcRange_tp.setEnd(Lexer::getLocForEndOfToken( + srcRange_tp.getEnd(), 0, sourceManager, + Context->getLangOpts())); + bool Invalid = false; + StringRef srcText_tp = Lexer::getSourceText( + CharSourceRange::getTokenRange(srcRange_tp), sourceManager, + Context->getLangOpts(), &Invalid); + std::string srcText_tp_str = std::string(srcText_tp); + if (srcText_tp_str.size() > 0) { + srcText_tp_str.erase(srcText_tp_str.length() - 1); + } + function.template_parameters.push_back(srcText_tp_str); + } + const SourceManager &sourceManager = Context->getSourceManager(); + SourceRange srcRange_r = Func->getReturnTypeSourceRange(); + srcRange_r.setEnd(Lexer::getLocForEndOfToken( + srcRange_r.getEnd(), 0, sourceManager, Context->getLangOpts())); + bool Invalid = false; + StringRef srcText_r = Lexer::getSourceText( + CharSourceRange::getTokenRange(srcRange_r), sourceManager, + Context->getLangOpts(), &Invalid); + function.return_type = std::string(srcText_r); + std::string return_type = Func->getReturnType().getAsString(); + // if (return_type.find(" ") != std::string::npos) { + // return_type = + // return_type.substr(return_type.find_last_of(" ") + 1); + // } + // QualType qualType = Func->getReturnType(); + // std::cout << qualType.getAsString() << std::endl; + // if (qualType->isReferenceType()) { + // qualType = qualType.getNonReferenceType(); + // } + // qualType = qualType.getUnqualifiedType(); + // std::cout << qualType.getAsString() << std::endl; + // qualType = qualType.getNonReferenceType(); + // std::cout << qualType.getAsString() << std::endl; + // qualType = qualType.getLocalUnqualifiedType(); + // std::cout << qualType.getAsString() << std::endl; + // qualType = qualType.getCanonicalType(); + // std::cout << qualType.getAsString() << std::endl; + // qualType = qualType.getCanonicalType(); + // std::vector types = + // gad_classes_and_functions.get_application_classes(return_type); + // for (auto type : types) { + Application application; + application.class_name = return_type; + application.signature = ""; + function.applications.push_back(application); + // } + // Application application; + // application.class_name = get_application_type(qualType); + // application.signature = ""; + // function.applications.push_back(application); + for (const ParmVarDecl *param : Func->parameters()) { + std::string param_type = param->getType().getAsString(); + // if (param_type.find(" ") != std::string::npos) { + // param_type = + // param_type.substr(param_type.find_last_of(" ") + 1); + // } + // QualType qualType = param->getType(); + // std::cout << qualType.getAsString() << std::endl; + // if (qualType->isReferenceType()) { + // qualType = qualType.getNonReferenceType(); + // } + // qualType = qualType.getUnqualifiedType(); + // std::cout << qualType.getAsString() << std::endl; + // qualType = qualType.getNonReferenceType(); + // std::cout << qualType.getAsString() << std::endl; + // qualType = qualType.getLocalUnqualifiedType(); + // std::cout << qualType.getAsString() << std::endl; + // qualType = qualType.getCanonicalType(); + // std::cout << qualType.getAsString() << std::endl; + // qualType = qualType.getCanonicalType(); + // std::vector types = + // gad_classes_and_functions.get_application_classes(param_type); + // for (auto type : types) { + Application application; + application.class_name = param_type; + application.signature = ""; + function.applications.push_back(application); + // } + // Application application; + // application.class_name = get_application_type(qualType); + // application.signature = ""; + // function.applications.push_back(application); + SourceRange srcRange_p = param->getSourceRange(); + srcRange_p.setEnd(Lexer::getLocForEndOfToken( + srcRange_p.getEnd(), 0, sourceManager, + Context->getLangOpts())); + StringRef srcText_p = Lexer::getSourceText( + CharSourceRange::getTokenRange(srcRange_p), sourceManager, + Context->getLangOpts(), &Invalid); + std::string srcText_str = std::string(srcText_p); + if (srcText_str[srcText_str.length() - 1] == ')' || + srcText_str[srcText_str.length() - 1] == ',' || + srcText_str[srcText_str.length() - 1] == ';') { + srcText_str.erase(srcText_str.length() - 1); + } + function.parameters.push_back(srcText_str); + } + SourceRange srcRange = Declaration->getSourceRange(); + srcRange.setEnd(Lexer::getLocForEndOfToken( + srcRange.getEnd(), 0, sourceManager, Context->getLangOpts())); + StringRef srcText = Lexer::getSourceText( + CharSourceRange::getTokenRange(srcRange), sourceManager, + Context->getLangOpts(), &Invalid); + function.function_body = srcText; + const DeclContext *context = Func->getDeclContext(); + bool b = 0; + while (context) { + if (const NamespaceDecl *namespaceDecl = + dyn_cast(context)) { + b = 1; + if (function.its_namespace == "") { + function.its_namespace = namespaceDecl->getNameAsString(); + } else { + function.its_namespace = namespaceDecl->getNameAsString() + + "::" + function.its_namespace; + } + } + context = context->getParent(); + } + if (b == 0) { + function.its_namespace = ""; + } + StmtVarFunctionVisitor function_stmt_visitor(Context); + function_stmt_visitor.TraverseStmt(Func->getBody()); + std::vector stmt_applications = + function_stmt_visitor.get_applications(); + for (auto application : stmt_applications) { + function.applications.push_back(application); + } + gad_classes_and_functions.push_back_function(function); + } + for (FunctionDecl *Spec : Declaration->specializations()) { + const TemplateArgumentList *TAL = + Spec->getTemplateSpecializationArgs(); + std::vector> applications; + if (TAL) { + std::vector specialization_parameter; + for (const TemplateArgument &Arg : TAL->asArray()) { + if (Arg.getKind() == TemplateArgument::Type) { + // std::cout << "Template Argument Type: " + // << Arg.getAsType().getAsString() << "\n"; + std::string type_name = Arg.getAsType().getAsString(); + // if (type_name.find(" ") != std::string::npos) { + // type_name = + // type_name.substr(type_name.find_last_of(" ") + 1); + // } + specialization_parameter.push_back(type_name); + // QualType qualType = Arg.getAsType(); + // if (qualType->isReferenceType()) { + // qualType = qualType.getNonReferenceType(); + // } + // qualType = qualType.getUnqualifiedType(); + // qualType = qualType.getNonReferenceType(); + // qualType = qualType.getCanonicalType(); + // std::vector types = + // gad_classes_and_functions.get_application_classes( + // type_name); + // for (auto type : types) { + std::pair application; + application.first = type_name; + application.second = ""; + applications.push_back(application); + // } + // std::pair application; + // application.first = get_application_type(qualType); + // application.second = ""; + // applications.push_back(application); + } + } + gad_classes_and_functions.push_back_specialization_parameter( + "class", signature, specialization_parameter); + gad_classes_and_functions.push_back_applications( + "class", signature, applications); + } + } + } else { + const CXXRecordDecl *CanonicalParentClass = + dyn_cast(Func->getParent())->getCanonicalDecl(); + std::string class_name = CanonicalParentClass->getNameAsString(); + if (gad_classes_and_functions.has_class(class_name)) { + // std::cout << "Class Declaration " << class_name << + // std::endl; + std::string signature = get_signature(CanonicalFunc); + if (!gad_classes_and_functions.has_function(class_name, + signature)) { + if (isa(Func)) { + // std::string signature; + // std::string function_body; + // std::vector parameters; + // std::vector applications; + Constructor constructor; + const SourceManager &sourceManager = + Context->getSourceManager(); + bool Invalid = false; + constructor.signature = signature; + for (const ParmVarDecl *param : Func->parameters()) { + std::string param_type = param->getType().getAsString(); + // if (param_type.find(" ") != std::string::npos) { + // param_type = + // param_type.substr(param_type.find_last_of(" ") + 1); + // } + // QualType qualType = param->getType(); + // if (qualType->isReferenceType()) { + // qualType = qualType.getNonReferenceType(); + // } + // qualType = qualType.getUnqualifiedType(); + // qualType = qualType.getNonReferenceType(); + // qualType = qualType.getCanonicalType(); + // std::vector types = + // gad_classes_and_functions.get_application_classes( + // param_type); + // for (auto type : types) { + Application application; + application.class_name = param_type; + application.signature = ""; + constructor.applications.push_back(application); + // } + // Application application; + // application.class_name = get_application_type(qualType); + // application.signature = ""; + // constructor.applications.push_back(application); + SourceRange srcRange_p = param->getSourceRange(); + srcRange_p.setEnd(Lexer::getLocForEndOfToken( + srcRange_p.getEnd(), 0, sourceManager, + Context->getLangOpts())); + StringRef srcText_p = Lexer::getSourceText( + CharSourceRange::getTokenRange(srcRange_p), sourceManager, + Context->getLangOpts(), &Invalid); + std::string srcText_str = std::string(srcText_p); + if (srcText_str[srcText_str.length() - 1] == ')' || + srcText_str[srcText_str.length() - 1] == ',' || + srcText_str[srcText_str.length() - 1] == ';') { + srcText_str.erase(srcText_str.length() - 1); + } + constructor.parameters.push_back(srcText_str); + } + SourceRange srcRange = Declaration->getSourceRange(); + srcRange.setEnd(Lexer::getLocForEndOfToken( + srcRange.getEnd(), 0, sourceManager, + Context->getLangOpts())); + StringRef srcText = Lexer::getSourceText( + CharSourceRange::getTokenRange(srcRange), sourceManager, + Context->getLangOpts(), &Invalid); + constructor.function_body = srcText; + StmtVarFunctionVisitor function_stmt_visitor(Context); + function_stmt_visitor.TraverseStmt(Func->getBody()); + std::vector stmt_applications = + function_stmt_visitor.get_applications(); + for (auto application : stmt_applications) { + constructor.applications.push_back(application); + } + gad_classes_and_functions.push_back_constructor(class_name, + constructor); + } else if (isa(Func)) { + // std::string signature; + // std::string function_body; + // std::vector applications; + // std::cout << "Destructor Declaration " << + // class_name + // << std::endl; + Destructor destructor; + const SourceManager &sourceManager = + Context->getSourceManager(); + SourceRange srcRange = Declaration->getSourceRange(); + srcRange.setEnd(Lexer::getLocForEndOfToken( + srcRange.getEnd(), 0, sourceManager, + Context->getLangOpts())); + bool Invalid = false; + StringRef srcText = Lexer::getSourceText( + CharSourceRange::getTokenRange(srcRange), sourceManager, + Context->getLangOpts(), &Invalid); + destructor.signature = signature; + destructor.function_body = srcText; + StmtVarFunctionVisitor function_stmt_visitor(Context); + function_stmt_visitor.TraverseStmt(Func->getBody()); + std::vector stmt_applications = + function_stmt_visitor.get_applications(); + for (auto application : stmt_applications) { + destructor.applications.push_back(application); + } + gad_classes_and_functions.push_back_destructor(class_name, + destructor); + } else { + Method method; + std::string function_name = Func->getNameAsString(); + // std::cout << "Method Declaration " << + // function_name + // << std::endl; + method.method_name = function_name; + method.signature = signature; + method.is_template = 1; + auto template_parameters = Declaration->getTemplateParameters(); + for (auto template_parameter : template_parameters->asArray()) { + // method.template_parameters.push_back( + // template_parameter->getNameAsString()); + const SourceManager &sourceManager = + Context->getSourceManager(); + SourceRange srcRange_tp = + template_parameter->getSourceRange(); + srcRange_tp.setEnd(Lexer::getLocForEndOfToken( + srcRange_tp.getEnd(), 0, sourceManager, + Context->getLangOpts())); + bool Invalid = false; + StringRef srcText_tp = Lexer::getSourceText( + CharSourceRange::getTokenRange(srcRange_tp), + sourceManager, Context->getLangOpts(), &Invalid); + std::string srcText_tp_str = std::string(srcText_tp); + if (srcText_tp_str.size() > 0) { + srcText_tp_str.erase(srcText_tp_str.length() - 1); + } + method.template_parameters.push_back(srcText_tp_str); + } + const SourceManager &sourceManager = + Context->getSourceManager(); + SourceRange srcRange_r = Func->getReturnTypeSourceRange(); + srcRange_r.setEnd(Lexer::getLocForEndOfToken( + srcRange_r.getEnd(), 0, sourceManager, + Context->getLangOpts())); + bool Invalid = false; + StringRef srcText_r = Lexer::getSourceText( + CharSourceRange::getTokenRange(srcRange_r), sourceManager, + Context->getLangOpts(), &Invalid); + method.return_type = std::string(srcText_r); + std::string return_type = Func->getReturnType().getAsString(); + // if (return_type.find(" ") != std::string::npos) { + // return_type = + // return_type.substr(return_type.find_last_of(" ") + 1); + // } + // QualType qualType = Func->getReturnType(); + // if (qualType->isReferenceType()) { + // qualType = qualType.getNonReferenceType(); + // } + // qualType = qualType.getUnqualifiedType(); + // qualType = qualType.getNonReferenceType(); + // qualType = qualType.getCanonicalType(); + // std::vector types = + // gad_classes_and_functions.get_application_classes( + // return_type); + // for (auto type : types) { + Application application; + application.class_name = return_type; + application.signature = ""; + method.applications.push_back(application); + // } + // Application application; + // application.class_name = get_application_type(qualType); + // application.signature = ""; + // method.applications.push_back(application); + for (const ParmVarDecl *param : Func->parameters()) { + std::string param_type = param->getType().getAsString(); + // if (param_type.find(" ") != std::string::npos) { + // param_type = + // param_type.substr(param_type.find_last_of(" ") + 1); + // } + // QualType qualType = param->getType(); + // if (qualType->isReferenceType()) { + // qualType = qualType.getNonReferenceType(); + // } + // qualType = qualType.getUnqualifiedType(); + // qualType = qualType.getNonReferenceType(); + // qualType = qualType.getCanonicalType(); + // std::vector types = + // gad_classes_and_functions.get_application_classes( + // param_type); + // for (auto type : types) { + Application application; + application.class_name = param_type; + application.signature = ""; + method.applications.push_back(application); + // } + // Application application; + // application.class_name = get_application_type(qualType); + // application.signature = ""; + // method.applications.push_back(application); + SourceRange srcRange_p = param->getSourceRange(); + srcRange_p.setEnd(Lexer::getLocForEndOfToken( + srcRange_p.getEnd(), 0, sourceManager, + Context->getLangOpts())); + StringRef srcText_p = Lexer::getSourceText( + CharSourceRange::getTokenRange(srcRange_p), sourceManager, + Context->getLangOpts(), &Invalid); + std::string srcText_str = std::string(srcText_p); + if (srcText_str[srcText_str.length() - 1] == ')' || + srcText_str[srcText_str.length() - 1] == ',' || + srcText_str[srcText_str.length() - 1] == ';') { + srcText_str.erase(srcText_str.length() - 1); + } + method.parameters.push_back(srcText_str); + } + SourceRange srcRange = Declaration->getSourceRange(); + srcRange.setEnd(Lexer::getLocForEndOfToken( + srcRange.getEnd(), 0, sourceManager, + Context->getLangOpts())); + StringRef srcText = Lexer::getSourceText( + CharSourceRange::getTokenRange(srcRange), sourceManager, + Context->getLangOpts(), &Invalid); + method.function_body = srcText; + StmtVarFunctionVisitor function_stmt_visitor(Context); + function_stmt_visitor.TraverseStmt(Func->getBody()); + std::vector stmt_applications = + function_stmt_visitor.get_applications(); + for (auto application : stmt_applications) { + method.applications.push_back(application); + } + gad_classes_and_functions.push_back_method(class_name, method); + } + } + if (isa(Func)) { + // Declaration->dump(); + for (FunctionDecl *Spec : Declaration->specializations()) { + const TemplateArgumentList *TAL = + Spec->getTemplateSpecializationArgs(); + if (TAL) { + std::vector specialization_parameter; + std::vector> applications; + for (const TemplateArgument &Arg : TAL->asArray()) { + if (Arg.getKind() == TemplateArgument::Type) { + // std::cout << "Template Argument Type: " + // << Arg.getAsType().getAsString() << "\n"; + std::string type_name = Arg.getAsType().getAsString(); + // if (type_name.find(" ") != std::string::npos) { + // type_name = + // type_name.substr(type_name.find_last_of(" ") + + // 1); + // } + specialization_parameter.push_back(type_name); + // QualType qualType = Arg.getAsType(); + // if (qualType->isReferenceType()) { + // qualType = qualType.getNonReferenceType(); + // } + // qualType = qualType.getUnqualifiedType(); + // qualType = qualType.getNonReferenceType(); + // qualType = qualType.getCanonicalType(); + // std::vector types = + // gad_classes_and_functions.get_application_classes( + // type_name); + // for (auto type : types) { + std::pair application; + application.first = type_name; + application.second = ""; + applications.push_back(application); + // } + // std::pair application; + // application.first = get_application_type(qualType); + // application.second = ""; + // applications.push_back(application); + } + } + gad_classes_and_functions.push_back_specialization_parameter( + class_name, signature, specialization_parameter); + gad_classes_and_functions.push_back_applications( + class_name, signature, applications); + } + } + } + } + } + // gad_classes_and_functions.cout(); + } + } + return true; + } + + bool VisitFunctionDecl(FunctionDecl *Declaration) { + if (Declaration->isThisDeclarationADefinition()) { + clang::SourceLocation loc = Declaration->getLocation(); + clang::SourceManager &SM = Context->getSourceManager(); + clang::PresumedLoc presumedLoc = SM.getPresumedLoc(loc); + std::string file_path = presumedLoc.getFilename(); + if (file_path.find(gad_project_path) != std::string::npos) { + // std::cout << get_signature(Declaration->getAsFunction()) << + // std::endl; Declaration->dump(); std::cout << std::endl; + auto CanonicalDeclaration = Declaration->getCanonicalDecl(); + // auto canonical_declaration = Declaration->getCanonicalDecl(); + // canonical_declaration->dump(); + // Declaration->dump(); + if (!isa(CanonicalDeclaration)) { + std::string function_name = CanonicalDeclaration->getNameAsString(); + // if (function_name == "BrotliEncoderCompress") { + // std::cout << std::endl; + // } + std::string signature = get_signature(CanonicalDeclaration); + if (!gad_classes_and_functions.has_function("class", signature)) { + Function function; + // std::vector applications; + function.function_name = function_name; + function.signature = signature; + function.is_template = 0; + const SourceManager &sourceManager = Context->getSourceManager(); + SourceRange srcRange_r = Declaration->getReturnTypeSourceRange(); + srcRange_r.setEnd(Lexer::getLocForEndOfToken( + srcRange_r.getEnd(), 0, sourceManager, Context->getLangOpts())); + bool Invalid = false; + StringRef srcText_r = Lexer::getSourceText( + CharSourceRange::getTokenRange(srcRange_r), sourceManager, + Context->getLangOpts(), &Invalid); + function.return_type = std::string(srcText_r); + std::string return_type = + Declaration->getReturnType().getAsString(); + // if (return_type.find(" ") != std::string::npos) { + // return_type = + // return_type.substr(return_type.find_last_of(" ") + 1); + // } + // QualType qualType = FunctionDeclaration->getReturnType(); + // if (qualType->isReferenceType()) { + // qualType = qualType.getNonReferenceType(); + // } + // qualType = qualType.getUnqualifiedType(); + // qualType = qualType.getNonReferenceType(); + // qualType = qualType.getCanonicalType(); std::set + // types; + // std::vector types = + // gad_classes_and_functions.get_application_classes(return_type); + // for (auto type : types) { + Application application; + application.class_name = return_type; + application.signature = ""; + function.applications.push_back(application); + // } + // Application application; + // application.class_name = get_application_type(qualType); + // application.signature = ""; + // function.applications.push_back(application); + for (const ParmVarDecl *param : Declaration->parameters()) { + std::string param_type = param->getType().getAsString(); + // if (param_type.find(" ") != std::string::npos) { + // param_type = + // param_type.substr(param_type.find_last_of(" ") + 1); + // } + // QualType qualType = param->getType(); + // if (qualType->isReferenceType()) { + // qualType = qualType.getNonReferenceType(); + // } + // qualType = qualType.getUnqualifiedType(); + // qualType = qualType.getNonReferenceType(); + // qualType = qualType.getCanonicalType(); + // std::vector types = + // gad_classes_and_functions.get_application_classes(param_type); + // for (auto type : types) { + Application application; + application.class_name = param_type; + application.signature = ""; + function.applications.push_back(application); + // } + // Application application; + // application.class_name = get_application_type(qualType); + // application.signature = ""; + // function.applications.push_back(application); + SourceRange srcRange_p = param->getSourceRange(); + srcRange_p.setEnd(Lexer::getLocForEndOfToken( + srcRange_p.getEnd(), 0, sourceManager, + Context->getLangOpts())); + StringRef srcText_p = Lexer::getSourceText( + CharSourceRange::getTokenRange(srcRange_p), sourceManager, + Context->getLangOpts(), &Invalid); + std::string srcText_str = std::string(srcText_p); + if (srcText_str[srcText_str.length() - 1] == ')' || + srcText_str[srcText_str.length() - 1] == ',' || + srcText_str[srcText_str.length() - 1] == ';') { + srcText_str.erase(srcText_str.length() - 1); + } + function.parameters.push_back(srcText_str); + } + SourceRange srcRange = Declaration->getSourceRange(); + srcRange.setEnd(Lexer::getLocForEndOfToken( + srcRange.getEnd(), 0, sourceManager, Context->getLangOpts())); + StringRef srcText = Lexer::getSourceText( + CharSourceRange::getTokenRange(srcRange), sourceManager, + Context->getLangOpts(), &Invalid); + function.function_body = srcText; + const DeclContext *context = Declaration->getDeclContext(); + bool b = 0; + while (context) { + if (const NamespaceDecl *namespaceDecl = + dyn_cast(context)) { + b = 1; + if (function.its_namespace == "") { + function.its_namespace = namespaceDecl->getNameAsString(); + } else { + function.its_namespace = namespaceDecl->getNameAsString() + + "::" + function.its_namespace; + } + } + context = context->getParent(); + } + if (b == 0) { + function.its_namespace = ""; + } + StmtVarFunctionVisitor function_stmt_visitor(Context); + function_stmt_visitor.TraverseStmt(Declaration->getBody()); + std::vector stmt_applications = + function_stmt_visitor.get_applications(); + for (auto application : stmt_applications) { + function.applications.push_back(application); + } + gad_classes_and_functions.push_back_function(function); + } + } else { + const CXXRecordDecl *CanonicalParentClass = + dyn_cast(CanonicalDeclaration->getParent()) + ->getCanonicalDecl(); + std::string class_name = CanonicalParentClass->getNameAsString(); + if (gad_classes_and_functions.has_class(class_name)) { + // std::cout << "Class Declaration " << class_name << + // std::endl; + std::string signature = get_signature(CanonicalDeclaration); + if (!gad_classes_and_functions.has_function(class_name, + signature)) { + if (isa(CanonicalDeclaration)) { + // std::string signature; + // std::string function_body; + // std::vector parameters; + // std::vector applications; + Constructor constructor; + const SourceManager &sourceManager = + Context->getSourceManager(); + bool Invalid = false; + constructor.signature = signature; + for (const ParmVarDecl *param : Declaration->parameters()) { + std::string param_type = param->getType().getAsString(); + // if (param_type.find(" ") != std::string::npos) { + // param_type = + // param_type.substr(param_type.find_last_of(" ") + 1); + // } + // QualType qualType = param->getType(); + // std::cout << qualType.getAsString() << std::endl; + // if (qualType->isReferenceType()) { + // qualType = qualType.getNonReferenceType(); + // } + // qualType = qualType.getUnqualifiedType(); + // std::cout << qualType.getAsString() << std::endl; + // qualType = qualType.getNonReferenceType(); + // std::cout << qualType.getAsString() << std::endl; + // qualType = qualType.getLocalUnqualifiedType(); + // std::cout << qualType.getAsString() << std::endl; + // qualType = qualType.getCanonicalType(); + // std::cout << qualType.getAsString() << std::endl; + // qualType = qualType.getCanonicalType(); + // std::vector types = + // gad_classes_and_functions.get_application_classes( + // param_type); + // for (auto type : types) { + Application application; + application.class_name = param_type; + application.signature = ""; + constructor.applications.push_back(application); + // } + // Application application; + // application.class_name = get_application_type(qualType); + // application.signature = ""; + // constructor.applications.push_back(application); + SourceRange srcRange_p = param->getSourceRange(); + srcRange_p.setEnd(Lexer::getLocForEndOfToken( + srcRange_p.getEnd(), 0, sourceManager, + Context->getLangOpts())); + StringRef srcText_p = Lexer::getSourceText( + CharSourceRange::getTokenRange(srcRange_p), sourceManager, + Context->getLangOpts(), &Invalid); + std::string srcText_str = std::string(srcText_p); + if (srcText_str[srcText_str.length() - 1] == ')' || + srcText_str[srcText_str.length() - 1] == ',' || + srcText_str[srcText_str.length() - 1] == ';') { + srcText_str.erase(srcText_str.length() - 1); + } + constructor.parameters.push_back(srcText_str); + } + SourceRange srcRange = Declaration->getSourceRange(); + srcRange.setEnd(Lexer::getLocForEndOfToken( + srcRange.getEnd(), 0, sourceManager, + Context->getLangOpts())); + StringRef srcText = Lexer::getSourceText( + CharSourceRange::getTokenRange(srcRange), sourceManager, + Context->getLangOpts(), &Invalid); + constructor.function_body = srcText; + StmtVarFunctionVisitor function_stmt_visitor(Context); + function_stmt_visitor.TraverseStmt(Declaration->getBody()); + std::vector stmt_applications = + function_stmt_visitor.get_applications(); + for (auto application : stmt_applications) { + constructor.applications.push_back(application); + } + gad_classes_and_functions.push_back_constructor(class_name, + constructor); + } else if (isa(CanonicalDeclaration)) { + // std::string signature; + // std::string function_body; + // std::vector applications; + // std::cout << "Destructor Declaration " << + // class_name + // << std::endl; + Destructor destructor; + const SourceManager &sourceManager = + Context->getSourceManager(); + SourceRange srcRange = Declaration->getSourceRange(); + srcRange.setEnd(Lexer::getLocForEndOfToken( + srcRange.getEnd(), 0, sourceManager, + Context->getLangOpts())); + bool Invalid = false; + StringRef srcText = Lexer::getSourceText( + CharSourceRange::getTokenRange(srcRange), sourceManager, + Context->getLangOpts(), &Invalid); + destructor.signature = signature; + destructor.function_body = srcText; + StmtVarFunctionVisitor function_stmt_visitor(Context); + function_stmt_visitor.TraverseStmt(Declaration->getBody()); + std::vector stmt_applications = + function_stmt_visitor.get_applications(); + for (auto application : stmt_applications) { + destructor.applications.push_back(application); + } + gad_classes_and_functions.push_back_destructor(class_name, + destructor); + } else { + Method method; + std::string function_name = Declaration->getNameAsString(); + // std::cout << "Method Declaration " << + // function_name + // << std::endl; + method.method_name = function_name; + method.signature = signature; + method.is_template = 0; + const SourceManager &sourceManager = + Context->getSourceManager(); + SourceRange srcRange_r = + Declaration->getReturnTypeSourceRange(); + srcRange_r.setEnd(Lexer::getLocForEndOfToken( + srcRange_r.getEnd(), 0, sourceManager, + Context->getLangOpts())); + bool Invalid = false; + StringRef srcText_r = Lexer::getSourceText( + CharSourceRange::getTokenRange(srcRange_r), sourceManager, + Context->getLangOpts(), &Invalid); + method.return_type = std::string(srcText_r); + std::string return_type = + Declaration->getReturnType().getAsString(); + // if (return_type.find(" ") != std::string::npos) { + // return_type = + // return_type.substr(return_type.find_last_of(" ") + 1); + // } + // QualType qualType = FunctionDeclaration->getReturnType(); + // if (qualType->isReferenceType()) { + // qualType = qualType.getNonReferenceType(); + // } + // qualType = qualType.getUnqualifiedType(); + // qualType = qualType.getNonReferenceType(); + // qualType = qualType.getCanonicalType(); + // std::vector types = + // gad_classes_and_functions.get_application_classes( + // return_type); + // for (auto type : types) { + Application application; + application.class_name = return_type; + application.signature = ""; + method.applications.push_back(application); + // } + // Application application; + // application.class_name = get_application_type(qualType); + // application.signature = ""; + // method.applications.push_back(application); + for (const ParmVarDecl *param : Declaration->parameters()) { + std::string param_type = param->getType().getAsString(); + // if (param_type.find(" ") != std::string::npos) { + // param_type = + // param_type.substr(param_type.find_last_of(" ") + 1); + // } + // QualType qualType = param->getType(); + // if (qualType->isReferenceType()) { + // qualType = qualType.getNonReferenceType(); + // } + // qualType = qualType.getUnqualifiedType(); + // qualType = qualType.getNonReferenceType(); + // qualType = qualType.getCanonicalType(); + // std::vector types = + // gad_classes_and_functions.get_application_classes( + // param_type); + // for (auto type : types) { + Application application; + application.class_name = param_type; + application.signature = ""; + method.applications.push_back(application); + // } + // Application application; + // application.class_name = get_application_type(qualType); + // application.signature = ""; + // method.applications.push_back(application); + SourceRange srcRange_p = param->getSourceRange(); + srcRange_p.setEnd(Lexer::getLocForEndOfToken( + srcRange_p.getEnd(), 0, sourceManager, + Context->getLangOpts())); + StringRef srcText_p = Lexer::getSourceText( + CharSourceRange::getTokenRange(srcRange_p), sourceManager, + Context->getLangOpts(), &Invalid); + std::string srcText_str = std::string(srcText_p); + if (srcText_str[srcText_str.length() - 1] == ')' || + srcText_str[srcText_str.length() - 1] == ',' || + srcText_str[srcText_str.length() - 1] == ';') { + srcText_str.erase(srcText_str.length() - 1); + } + method.parameters.push_back(srcText_str); + } + SourceRange srcRange = Declaration->getSourceRange(); + srcRange.setEnd(Lexer::getLocForEndOfToken( + srcRange.getEnd(), 0, sourceManager, + Context->getLangOpts())); + StringRef srcText = Lexer::getSourceText( + CharSourceRange::getTokenRange(srcRange), sourceManager, + Context->getLangOpts(), &Invalid); + method.function_body = srcText; + StmtVarFunctionVisitor function_stmt_visitor(Context); + function_stmt_visitor.TraverseStmt(Declaration->getBody()); + std::vector stmt_applications = + function_stmt_visitor.get_applications(); + for (auto application : stmt_applications) { + method.applications.push_back(application); + } + gad_classes_and_functions.push_back_method(class_name, method); + } + } + } + } + // gad_classes_and_functions.cout(); + } + } + return true; + } + + bool VisitEnumDecl(EnumDecl *Declaration) { + if (Declaration->isThisDeclarationADefinition()) { + clang::SourceLocation loc = Declaration->getLocation(); + clang::SourceManager &SM = Context->getSourceManager(); + clang::PresumedLoc presumedLoc = SM.getPresumedLoc(loc); + std::string file_path = presumedLoc.getFilename(); + if (file_path.find(gad_project_path) != std::string::npos) { + auto CanonicalDeclaration = Declaration->getCanonicalDecl(); + // Declaration->dump(); + std::string enum_name = CanonicalDeclaration->getNameAsString(); + for (auto *D : CanonicalDeclaration->getDeclContext()->decls()) { + if (auto *TD = dyn_cast(D)) { + if (auto *TRD = TD->getUnderlyingType()->getAsTagDecl()) { + if (auto *ETRD = dyn_cast(TRD)) { + if (ETRD->getCanonicalDecl() == CanonicalDeclaration) { + enum_name = TD->getNameAsString(); + break; + } + } + } + } + } + if (!gad_classes_and_functions.has_class(enum_name)) { + Class a_class; + a_class.class_name = enum_name; + a_class.record_type = MyRecordType::EnumType; + for (auto it = Declaration->enumerator_begin(); + it != Declaration->enumerator_end(); ++it) { + EnumConstantDecl *ECD = *it; + a_class.fields.push_back(ECD->getNameAsString()); + // std::cout << "Enumerator: " << ECD->getNameAsString() << + // std::endl; + llvm::APSInt value = ECD->getInitVal(); + a_class.enum_int_constants.push_back(value.getExtValue()); + // std::cout << "Value: " << value.getSExtValue() << std::endl; + } + gad_classes_and_functions.push_back_class(a_class); + } + } + } + return true; + } + +private: + ASTContext *Context; +}; + +class FindClassesAndFunctionsConsumer : public clang::ASTConsumer { +public: + explicit FindClassesAndFunctionsConsumer(ASTContext *Context) + : Visitor(Context) {} + + virtual void HandleTranslationUnit(clang::ASTContext &Context) { + Visitor.TraverseDecl(Context.getTranslationUnitDecl()); + } + +private: + FindClassesAndFunctionsVisitor Visitor; +}; + +class FindClassesAndFunctionsAction : public clang::ASTFrontendAction { +public: + virtual std::unique_ptr + CreateASTConsumer(clang::CompilerInstance &Compiler, llvm::StringRef InFile) { + return std::make_unique( + &Compiler.getASTContext()); + } +}; + +// class FirstHandler : public MatchFinder::MatchCallback { +// public: +// virtual void run(const MatchFinder::MatchResult &Result) { +// if (const ClassTemplateDecl *Declaration = +// Result.Nodes.getNodeAs("classTemplateDecl")) { +// if (Declaration->isThisDeclarationADefinition()) { +// clang::SourceLocation loc = Declaration->getLocation(); +// clang::SourceManager &SM = Result.Context->getSourceManager(); +// clang::PresumedLoc presumedLoc = SM.getPresumedLoc(loc); +// std::string file_path = presumedLoc.getFilename(); +// if (file_path.find(gad_project_path) != std::string::npos) { +// // std::cout << Declaration->getNameAsString() << std::endl; +// // Declaration->dump(); +// // std::cout << std::endl; +// auto CanonicalDeclaration = Declaration->getCanonicalDecl(); +// // auto canonical_declaration = Declaration->getCanonicalDecl(); +// // canonical_declaration->dump(); +// // Declaration->dump(); +// std::string class_name = CanonicalDeclaration->getNameAsString(); +// if (!gad_classes_and_functions.has_class(class_name)) { +// // if (class_name == "C1") { +// // Declaration->dump(); +// // } +// CXXRecordDecl *RecordDecl = Declaration->getTemplatedDecl(); +// Class a_class; +// a_class.class_name = class_name; +// a_class.is_template = 1; +// auto template_parameters = Declaration->getTemplateParameters(); +// for (auto template_parameter : template_parameters->asArray()) { +// // a_class.template_parameters.push_back( +// // template_parameter->getNameAsString()); +// const SourceManager &sourceManager = +// Result.Context->getSourceManager(); +// SourceRange srcRange_tp = template_parameter->getSourceRange(); +// srcRange_tp.setEnd(Lexer::getLocForEndOfToken( +// srcRange_tp.getEnd(), 0, sourceManager, +// Result.Context->getLangOpts())); +// bool Invalid = false; +// StringRef srcText_tp = Lexer::getSourceText( +// CharSourceRange::getTokenRange(srcRange_tp), sourceManager, +// Result.Context->getLangOpts(), &Invalid); +// std::string srcText_tp_str = std::string(srcText_tp); +// srcText_tp_str.erase(srcText_tp_str.length() - 1); +// a_class.template_parameters.push_back(srcText_tp_str); +// // std::cout << std::string(srcText_tp) << std::endl; +// } +// if (RecordDecl->isClass()) { +// a_class.record_type = MyRecordType::ClassType; +// } else if (RecordDecl->isStruct()) { +// a_class.record_type = MyRecordType::StructType; +// } else if (RecordDecl->isUnion()) { +// a_class.record_type = MyRecordType::UnionType; +// } +// // if (RecordDecl->getNumBases() > 0) { +// // a_class.base_class = +// // RecordDecl->bases_begin()->getType().getAsString(); +// // } +// for (auto its_base_class : RecordDecl->bases()) { +// a_class.base_class.push_back( +// its_base_class.getType().getAsString()); +// QualType qualType = its_base_class.getType(); +// // if (qualType->isReferenceType()) { +// // qualType = qualType.getNonReferenceType(); +// // } +// // qualType = qualType.getUnqualifiedType(); +// // qualType = qualType.getNonReferenceType(); +// // qualType = qualType.getCanonicalType(); +// Application application; +// application.class_name = qualType.getAsString(); +// application.signature = ""; +// a_class.applications.push_back(application); +// } +// const DeclContext *context = Declaration->getDeclContext(); +// bool b = 0; +// while (context) { +// if (const NamespaceDecl *namespaceDecl = +// dyn_cast(context)) { +// b = 1; +// if (a_class.its_namespace == "") { +// a_class.its_namespace = namespaceDecl->getNameAsString(); +// } else { +// a_class.its_namespace = namespaceDecl->getNameAsString() + +// "::" + a_class.its_namespace; +// } +// } +// context = context->getParent(); +// } +// if (b == 0) { +// a_class.its_namespace = ""; +// } +// for (const auto *decl : RecordDecl->decls()) { +// // if (decl->getCanonicalDecl() == CanonicalDeclaration) { +// // continue; +// // } +// // if (const CXXRecordDecl *Record = +// // dyn_cast(decl)) +// // { +// // if (i == 0) { +// // continue; +// // } +// // const SourceManager &sourceManager = +// // Context->getSourceManager(); SourceRange srcRange = +// // Record->getSourceRange(); +// // srcRange.setEnd(Lexer::getLocForEndOfToken( +// // srcRange.getEnd(), 0, sourceManager, +// // Context->getLangOpts())); +// // bool Invalid = false; +// // StringRef srcText = Lexer::getSourceText( +// // CharSourceRange::getTokenRange(srcRange), +// sourceManager, +// // Context->getLangOpts(), &Invalid); +// // // std::cout << std::string(srcText) << std::endl; +// // std::string srcText_str = std::string(srcText); +// // if (srcText_str[srcText_str.length() - 1] == ';') { +// // srcText_str.erase(srcText_str.length() - 1); +// // } +// // // if (Record->isClass()) { +// // // if (srcText.find('{') != std::string::npos) { +// // // srcText_str.erase(srcText_str.find_first_of('{')); +// // // } +// // // a_class.fields.push_back(srcText_str); +// // // } else { +// // // a_class.fields.push_back(srcText_str); +// // // } +// // a_class.fields.push_back(srcText_str); +// // } +// if (const FieldDecl *Field = dyn_cast(decl)) { +// std::string field_type = Field->getType().getAsString(); +// // // if (field_type.find(" ") != std::string::npos) { +// // // field_type = +// // // field_type.substr(field_type.find_last_of(" ") + +// 1); +// // // } +// // // QualType qualType = Field->getType(); +// // // // if (qualType->isReferenceType()) { +// // // // qualType = qualType.getNonReferenceType(); +// // // // } +// // // qualType = qualType.getUnqualifiedType(); +// // // qualType = qualType.getNonReferenceType(); +// // std::vector types = +// // +// gad_classes_and_functions.get_application_classes(field_type); +// // for (auto type : types) { +// Application application; +// application.class_name = field_type; +// application.signature = ""; +// a_class.applications.push_back(application); +// // } +// // qualType = qualType.getCanonicalType(); +// // Application application; +// // application.class_name = get_application_type(qualType); +// // application.signature = ""; +// // a_class.applications.push_back(application); +// const SourceManager &sourceManager = +// Result.Context->getSourceManager(); +// SourceRange srcRange = Field->getSourceRange(); +// srcRange.setEnd(Lexer::getLocForEndOfToken( +// srcRange.getEnd(), 0, sourceManager, +// Result.Context->getLangOpts())); +// bool Invalid = false; +// StringRef srcText = Lexer::getSourceText( +// CharSourceRange::getTokenRange(srcRange), sourceManager, +// Result.Context->getLangOpts(), &Invalid); +// // std::cout << std::string(srcText) << std::endl; +// std::string srcText_str = std::string(srcText); +// if (srcText_str[srcText_str.length() - 1] == ';') { +// srcText_str.erase(srcText_str.length() - 1); +// } +// if (srcText_str.find("{") != std::string::npos) { +// srcText_str.erase(srcText_str.find_first_of("{"), +// srcText_str.find_last_of("}") + 1 - +// srcText_str.find_first_of("{")); +// } +// if (srcText_str.find("class") != std::string::npos) { +// srcText_str.erase(srcText_str.find_first_of("class"), 6); +// } +// if (srcText_str.find("struct") != std::string::npos) { +// srcText_str.erase(srcText_str.find_first_of("struct"), 7); +// } +// if (srcText_str.find("enum") != std::string::npos) { +// srcText_str.erase(srcText_str.find_first_of("enum"), 5); +// } +// if (srcText_str.find("union") != std::string::npos) { +// srcText_str.erase(srcText_str.find_first_of("union"), 6); +// } +// a_class.fields.push_back(srcText_str); +// } +// // else if (const EnumDecl *Enum = dyn_cast(decl)) { +// // const SourceManager &sourceManager = +// // Context->getSourceManager(); SourceRange srcRange = +// // Enum->getSourceRange(); +// // srcRange.setEnd(Lexer::getLocForEndOfToken( +// // srcRange.getEnd(), 0, sourceManager, +// // Context->getLangOpts())); +// // bool Invalid = false; +// // StringRef srcText = Lexer::getSourceText( +// // CharSourceRange::getTokenRange(srcRange), +// sourceManager, +// // Context->getLangOpts(), &Invalid); +// // // std::cout << std::string(srcText) << std::endl; +// // std::string srcText_str = std::string(srcText); +// // if (srcText_str[srcText_str.length() - 1] == ';') { +// // srcText_str.erase(srcText_str.length() - 1); +// // } +// // a_class.fields.push_back(srcText_str); +// // } +// else if (const TypeAliasDecl *TypeAlias = +// dyn_cast(decl)) { +// Alias alias; +// alias.alias_name = TypeAlias->getNameAsString(); +// alias.base_name = +// TypeAlias->getUnderlyingType().getAsString(); +// // QualType qualType = TypeAlias->getUnderlyingType(); +// // if (qualType->isReferenceType()) { +// // qualType = qualType.getNonReferenceType(); +// // } +// // qualType = qualType.getUnqualifiedType(); +// // qualType = qualType.getNonReferenceType(); +// // qualType = qualType.getCanonicalType(); +// a_class.aliases.push_back(alias); +// // std::vector types = +// // gad_classes_and_functions.get_application_classes( +// // alias.base_name); +// // for (auto type : types) { +// Application application; +// application.class_name = alias.base_name; +// application.signature = ""; +// a_class.applications.push_back(application); +// // } +// // Application application; +// // application.class_name = get_application_type(qualType); +// // application.signature = ""; +// // a_class.applications.push_back(application); +// // if (gad_classes_and_functions.has_class(alias.base_name)) +// { +// // std::vector constructors = +// // +// gad_classes_and_functions.get_constructors(alias.base_name); +// // std::vector> +// // applications; for (auto constructor : constructors) { +// // applications.push_back(std::pair( +// // alias.base_name, constructor)); +// // } +// // std::string destructor = +// // gad_classes_and_functions.get_destructor(alias.base_name); +// // if (destructor != "class") { +// // applications.push_back(std::pair( +// // alias.base_name, destructor)); +// // } +// // for (auto application : applications) { +// // Application a_application; +// // a_application.class_name = application.first; +// // a_application.signature = application.second; +// // a_class.applications.push_back(a_application); +// // } +// // } +// } +// } +// // i = 1; +// // while (i < a_class.fields.size()) { +// // if (a_class.fields[i] == a_class.fields[i - 1] || +// // (a_class.fields[i].substr( +// // 0, a_class.fields[i].find_last_of('}') + 1) != "" +// && +// // a_class.fields[i - 1].substr( +// // 0, a_class.fields[i - 1].find_last_of('}') + 1) != +// "" +// // && +// // a_class.fields[i].substr( +// // 0, a_class.fields[i].find_last_of('}') + 1) == +// // a_class.fields[i - 1].substr( +// // 0, a_class.fields[i - 1].find_last_of('}') + +// 1)) +// // || +// // a_class.fields[i].find(a_class.fields[i - 1]) != +// // std::string::npos) { +// // a_class.fields.erase(a_class.fields.begin() + i - 1); +// // } else { +// // i++; +// // } +// // } +// // i = 0; +// // while (i < a_class.fields.size()) { +// // if (a_class.fields[i] == "union" || a_class.fields[i] == +// // "struct" +// // || +// // a_class.fields[i] == "class" || a_class.fields[i] == +// // "enum") +// // { +// // a_class.fields.erase(a_class.fields.begin() + i); +// // } else { +// // i++; +// // } +// // } +// // std::cout << a_class.class_name << "\t" << +// a_class.base_class +// // << std::endl; +// // for (auto template_parameter : a_class.template_parameters) +// { +// // std::cout << template_parameter << "\t"; +// // } +// // std::cout << std::endl; +// gad_classes_and_functions.push_back_class(a_class); +// } +// for (auto specialization : Declaration->specializations()) { +// std::vector specialization_parameter; +// std::vector> applications; +// for (unsigned i = 0; i < +// specialization->getTemplateArgs().size(); +// ++i) { +// const TemplateArgument &Arg = +// specialization->getTemplateArgs().get(i); +// if (Arg.getKind() == TemplateArgument::Type) { +// // std::cout << "Specialization Argument: " +// // << Arg.getAsType().getAsString() << "\n"; +// std::string type_name = Arg.getAsType().getAsString(); +// // if (type_name.find(" ") != std::string::npos) { +// // type_name = type_name.substr(type_name.find_last_of(" ") +// + +// // 1); +// // } +// specialization_parameter.push_back(type_name); +// // QualType qualType = Arg.getAsType(); +// // if (qualType->isReferenceType()) { +// // qualType = qualType.getNonReferenceType(); +// // } +// // qualType = qualType.getUnqualifiedType(); +// // qualType = qualType.getNonReferenceType(); +// // qualType = qualType.getCanonicalType(); +// // std::vector types = +// // +// gad_classes_and_functions.get_application_classes(type_name); +// // for (auto type : types) { +// std::pair application; +// application.first = type_name; +// application.second = ""; +// applications.push_back(application); +// // } +// // std::pair application; +// // application.first = get_application_type(qualType); +// // application.second = ""; +// // applications.push_back(application); +// } +// } +// gad_classes_and_functions.push_back_specialization_parameter( +// class_name, "", specialization_parameter); +// gad_classes_and_functions.push_back_applications(class_name, "", +// applications); +// } +// // gad_classes_and_functions.cout(); +// } +// } +// } else if (const FunctionTemplateDecl *Declaration = +// Result.Nodes.getNodeAs( +// "functionTemplateDecl")) { +// if (Declaration->isThisDeclarationADefinition()) { +// clang::SourceLocation loc = Declaration->getLocation(); +// clang::SourceManager &SM = Result.Context->getSourceManager(); +// clang::PresumedLoc presumedLoc = SM.getPresumedLoc(loc); +// std::string file_path = presumedLoc.getFilename(); +// if (file_path.find(gad_project_path) != std::string::npos) { +// // std::cout << get_signature(Declaration->getAsFunction()) << +// // std::endl; Declaration->dump(); std::cout << std::endl; +// auto CanonicalDeclaration = Declaration->getCanonicalDecl(); +// // auto canonical_declaration = Declaration->getCanonicalDecl(); +// // canonical_declaration->dump(); +// // Declaration->dump(); +// FunctionDecl *Func = Declaration->getTemplatedDecl(); +// FunctionDecl *CanonicalFunc = Func->getCanonicalDecl(); +// if (!isa(Func)) { +// std::string function_name = +// CanonicalDeclaration->getNameAsString(); std::string signature = +// get_signature(CanonicalFunc); if +// (!gad_classes_and_functions.has_function("class", signature)) { +// Function function; +// // std::vector applications; +// function.function_name = function_name; +// function.signature = signature; +// function.is_template = 1; +// auto template_parameters = +// Declaration->getTemplateParameters(); for (auto +// template_parameter : template_parameters->asArray()) { +// // function.template_parameters.push_back( +// // template_parameter->getNameAsString()); +// const SourceManager &sourceManager = +// Result.Context->getSourceManager(); +// SourceRange srcRange_tp = +// template_parameter->getSourceRange(); +// srcRange_tp.setEnd(Lexer::getLocForEndOfToken( +// srcRange_tp.getEnd(), 0, sourceManager, +// Result.Context->getLangOpts())); +// bool Invalid = false; +// StringRef srcText_tp = Lexer::getSourceText( +// CharSourceRange::getTokenRange(srcRange_tp), +// sourceManager, Result.Context->getLangOpts(), &Invalid); +// std::string srcText_tp_str = std::string(srcText_tp); +// srcText_tp_str.erase(srcText_tp_str.length() - 1); +// function.template_parameters.push_back(srcText_tp_str); +// } +// const SourceManager &sourceManager = +// Result.Context->getSourceManager(); +// SourceRange srcRange_r = Func->getReturnTypeSourceRange(); +// srcRange_r.setEnd(Lexer::getLocForEndOfToken( +// srcRange_r.getEnd(), 0, sourceManager, +// Result.Context->getLangOpts())); +// bool Invalid = false; +// StringRef srcText_r = Lexer::getSourceText( +// CharSourceRange::getTokenRange(srcRange_r), sourceManager, +// Result.Context->getLangOpts(), &Invalid); +// function.return_type = std::string(srcText_r); +// std::string return_type = Func->getReturnType().getAsString(); +// // if (return_type.find(" ") != std::string::npos) { +// // return_type = +// // return_type.substr(return_type.find_last_of(" ") + 1); +// // } +// // QualType qualType = Func->getReturnType(); +// // std::cout << qualType.getAsString() << std::endl; +// // if (qualType->isReferenceType()) { +// // qualType = qualType.getNonReferenceType(); +// // } +// // qualType = qualType.getUnqualifiedType(); +// // std::cout << qualType.getAsString() << std::endl; +// // qualType = qualType.getNonReferenceType(); +// // std::cout << qualType.getAsString() << std::endl; +// // qualType = qualType.getLocalUnqualifiedType(); +// // std::cout << qualType.getAsString() << std::endl; +// // qualType = qualType.getCanonicalType(); +// // std::cout << qualType.getAsString() << std::endl; +// // qualType = qualType.getCanonicalType(); +// // std::vector types = +// // +// gad_classes_and_functions.get_application_classes(return_type); +// // for (auto type : types) { +// Application application; +// application.class_name = return_type; +// application.signature = ""; +// function.applications.push_back(application); +// // } +// // Application application; +// // application.class_name = get_application_type(qualType); +// // application.signature = ""; +// // function.applications.push_back(application); +// for (const ParmVarDecl *param : Func->parameters()) { +// std::string param_type = param->getType().getAsString(); +// // if (param_type.find(" ") != std::string::npos) { +// // param_type = +// // param_type.substr(param_type.find_last_of(" ") + 1); +// // } +// // QualType qualType = param->getType(); +// // std::cout << qualType.getAsString() << std::endl; +// // if (qualType->isReferenceType()) { +// // qualType = qualType.getNonReferenceType(); +// // } +// // qualType = qualType.getUnqualifiedType(); +// // std::cout << qualType.getAsString() << std::endl; +// // qualType = qualType.getNonReferenceType(); +// // std::cout << qualType.getAsString() << std::endl; +// // qualType = qualType.getLocalUnqualifiedType(); +// // std::cout << qualType.getAsString() << std::endl; +// // qualType = qualType.getCanonicalType(); +// // std::cout << qualType.getAsString() << std::endl; +// // qualType = qualType.getCanonicalType(); +// // std::vector types = +// // +// gad_classes_and_functions.get_application_classes(param_type); +// // for (auto type : types) { +// Application application; +// application.class_name = param_type; +// application.signature = ""; +// function.applications.push_back(application); +// // } +// // Application application; +// // application.class_name = get_application_type(qualType); +// // application.signature = ""; +// // function.applications.push_back(application); +// SourceRange srcRange_p = param->getSourceRange(); +// srcRange_p.setEnd(Lexer::getLocForEndOfToken( +// srcRange_p.getEnd(), 0, sourceManager, +// Result.Context->getLangOpts())); +// StringRef srcText_p = Lexer::getSourceText( +// CharSourceRange::getTokenRange(srcRange_p), +// sourceManager, Result.Context->getLangOpts(), &Invalid); +// std::string srcText_str = std::string(srcText_p); +// if (srcText_str[srcText_str.length() - 1] == ')' || +// srcText_str[srcText_str.length() - 1] == ',' || +// srcText_str[srcText_str.length() - 1] == ';') { +// srcText_str.erase(srcText_str.length() - 1); +// } +// function.parameters.push_back(srcText_str); +// } +// SourceRange srcRange = Declaration->getSourceRange(); +// srcRange.setEnd(Lexer::getLocForEndOfToken( +// srcRange.getEnd(), 0, sourceManager, +// Result.Context->getLangOpts())); +// StringRef srcText = Lexer::getSourceText( +// CharSourceRange::getTokenRange(srcRange), sourceManager, +// Result.Context->getLangOpts(), &Invalid); +// function.function_body = srcText; +// const DeclContext *context = Func->getDeclContext(); +// bool b = 0; +// while (context) { +// if (const NamespaceDecl *namespaceDecl = +// dyn_cast(context)) { +// b = 1; +// if (function.its_namespace == "") { +// function.its_namespace = +// namespaceDecl->getNameAsString(); +// } else { +// function.its_namespace = namespaceDecl->getNameAsString() +// + +// "::" + function.its_namespace; +// } +// } +// context = context->getParent(); +// } +// if (b == 0) { +// function.its_namespace = ""; +// } +// StmtVarFunctionVisitor function_stmt_visitor(Result.Context); +// function_stmt_visitor.TraverseStmt(Func->getBody()); +// std::vector stmt_applications = +// function_stmt_visitor.get_applications(); +// for (auto application : stmt_applications) { +// function.applications.push_back(application); +// } +// gad_classes_and_functions.push_back_function(function); +// } +// for (FunctionDecl *Spec : Declaration->specializations()) { +// const TemplateArgumentList *TAL = +// Spec->getTemplateSpecializationArgs(); +// std::vector> applications; +// if (TAL) { +// std::vector specialization_parameter; +// for (const TemplateArgument &Arg : TAL->asArray()) { +// if (Arg.getKind() == TemplateArgument::Type) { +// // std::cout << "Template Argument Type: " +// // << Arg.getAsType().getAsString() << "\n"; +// std::string type_name = Arg.getAsType().getAsString(); +// // if (type_name.find(" ") != std::string::npos) { +// // type_name = +// // type_name.substr(type_name.find_last_of(" ") + +// 1); +// // } +// specialization_parameter.push_back(type_name); +// // QualType qualType = Arg.getAsType(); +// // if (qualType->isReferenceType()) { +// // qualType = qualType.getNonReferenceType(); +// // } +// // qualType = qualType.getUnqualifiedType(); +// // qualType = qualType.getNonReferenceType(); +// // qualType = qualType.getCanonicalType(); +// // std::vector types = +// // gad_classes_and_functions.get_application_classes( +// // type_name); +// // for (auto type : types) { +// std::pair application; +// application.first = type_name; +// application.second = ""; +// applications.push_back(application); +// // } +// // std::pair application; +// // application.first = get_application_type(qualType); +// // application.second = ""; +// // applications.push_back(application); +// } +// } +// gad_classes_and_functions.push_back_specialization_parameter( +// "class", signature, specialization_parameter); +// gad_classes_and_functions.push_back_applications( +// "class", signature, applications); +// } +// } +// } else { +// const CXXRecordDecl *CanonicalParentClass = +// dyn_cast(Func->getParent())->getCanonicalDecl(); +// std::string class_name = CanonicalParentClass->getNameAsString(); +// if (gad_classes_and_functions.has_class(class_name)) { +// // std::cout << "Class Declaration " << class_name << +// // std::endl; +// std::string signature = get_signature(CanonicalFunc); +// if (!gad_classes_and_functions.has_function(class_name, +// signature)) { +// if (isa(Func)) { +// // std::string signature; +// // std::string function_body; +// // std::vector parameters; +// // std::vector applications; +// Constructor constructor; +// const SourceManager &sourceManager = +// Result.Context->getSourceManager(); +// bool Invalid = false; +// constructor.signature = signature; +// for (const ParmVarDecl *param : Func->parameters()) { +// std::string param_type = param->getType().getAsString(); +// // if (param_type.find(" ") != std::string::npos) { +// // param_type = +// // param_type.substr(param_type.find_last_of(" ") + +// // 1); +// // } +// // QualType qualType = param->getType(); +// // if (qualType->isReferenceType()) { +// // qualType = qualType.getNonReferenceType(); +// // } +// // qualType = qualType.getUnqualifiedType(); +// // qualType = qualType.getNonReferenceType(); +// // qualType = qualType.getCanonicalType(); +// // std::vector types = +// // gad_classes_and_functions.get_application_classes( +// // param_type); +// // for (auto type : types) { +// Application application; +// application.class_name = param_type; +// application.signature = ""; +// constructor.applications.push_back(application); +// // } +// // Application application; +// // application.class_name = +// get_application_type(qualType); +// // application.signature = ""; +// // constructor.applications.push_back(application); +// SourceRange srcRange_p = param->getSourceRange(); +// srcRange_p.setEnd(Lexer::getLocForEndOfToken( +// srcRange_p.getEnd(), 0, sourceManager, +// Result.Context->getLangOpts())); +// StringRef srcText_p = Lexer::getSourceText( +// CharSourceRange::getTokenRange(srcRange_p), +// sourceManager, Result.Context->getLangOpts(), +// &Invalid); +// std::string srcText_str = std::string(srcText_p); +// if (srcText_str[srcText_str.length() - 1] == ')' || +// srcText_str[srcText_str.length() - 1] == ',' || +// srcText_str[srcText_str.length() - 1] == ';') { +// srcText_str.erase(srcText_str.length() - 1); +// } +// constructor.parameters.push_back(srcText_str); +// } +// SourceRange srcRange = Declaration->getSourceRange(); +// srcRange.setEnd(Lexer::getLocForEndOfToken( +// srcRange.getEnd(), 0, sourceManager, +// Result.Context->getLangOpts())); +// StringRef srcText = Lexer::getSourceText( +// CharSourceRange::getTokenRange(srcRange), +// sourceManager, Result.Context->getLangOpts(), +// &Invalid); +// constructor.function_body = srcText; +// StmtVarFunctionVisitor +// function_stmt_visitor(Result.Context); +// function_stmt_visitor.TraverseStmt(Func->getBody()); +// std::vector stmt_applications = +// function_stmt_visitor.get_applications(); +// for (auto application : stmt_applications) { +// constructor.applications.push_back(application); +// } +// gad_classes_and_functions.push_back_constructor(class_name, +// constructor); +// } else if (isa(Func)) { +// // std::string signature; +// // std::string function_body; +// // std::vector applications; +// // std::cout << "Destructor Declaration " << +// // class_name +// // << std::endl; +// Destructor destructor; +// const SourceManager &sourceManager = +// Result.Context->getSourceManager(); +// SourceRange srcRange = Declaration->getSourceRange(); +// srcRange.setEnd(Lexer::getLocForEndOfToken( +// srcRange.getEnd(), 0, sourceManager, +// Result.Context->getLangOpts())); +// bool Invalid = false; +// StringRef srcText = Lexer::getSourceText( +// CharSourceRange::getTokenRange(srcRange), +// sourceManager, Result.Context->getLangOpts(), +// &Invalid); +// destructor.signature = signature; +// destructor.function_body = srcText; +// StmtVarFunctionVisitor +// function_stmt_visitor(Result.Context); +// function_stmt_visitor.TraverseStmt(Func->getBody()); +// std::vector stmt_applications = +// function_stmt_visitor.get_applications(); +// for (auto application : stmt_applications) { +// destructor.applications.push_back(application); +// } +// gad_classes_and_functions.push_back_destructor(class_name, +// destructor); +// } else { +// Method method; +// std::string function_name = Func->getNameAsString(); +// // std::cout << "Method Declaration " << +// // function_name +// // << std::endl; +// method.method_name = function_name; +// method.signature = signature; +// method.is_template = 1; +// auto template_parameters = +// Declaration->getTemplateParameters(); +// for (auto template_parameter : +// template_parameters->asArray()) { +// // method.template_parameters.push_back( +// // template_parameter->getNameAsString()); +// const SourceManager &sourceManager = +// Result.Context->getSourceManager(); +// SourceRange srcRange_tp = +// template_parameter->getSourceRange(); +// srcRange_tp.setEnd(Lexer::getLocForEndOfToken( +// srcRange_tp.getEnd(), 0, sourceManager, +// Result.Context->getLangOpts())); +// bool Invalid = false; +// StringRef srcText_tp = Lexer::getSourceText( +// CharSourceRange::getTokenRange(srcRange_tp), +// sourceManager, Result.Context->getLangOpts(), +// &Invalid); +// std::string srcText_tp_str = std::string(srcText_tp); +// srcText_tp_str.erase(srcText_tp_str.length() - 1); +// method.template_parameters.push_back(srcText_tp_str); +// } +// const SourceManager &sourceManager = +// Result.Context->getSourceManager(); +// SourceRange srcRange_r = Func->getReturnTypeSourceRange(); +// srcRange_r.setEnd(Lexer::getLocForEndOfToken( +// srcRange_r.getEnd(), 0, sourceManager, +// Result.Context->getLangOpts())); +// bool Invalid = false; +// StringRef srcText_r = Lexer::getSourceText( +// CharSourceRange::getTokenRange(srcRange_r), +// sourceManager, Result.Context->getLangOpts(), +// &Invalid); +// method.return_type = std::string(srcText_r); +// std::string return_type = +// Func->getReturnType().getAsString(); +// // if (return_type.find(" ") != std::string::npos) { +// // return_type = +// // return_type.substr(return_type.find_last_of(" ") + +// // 1); +// // } +// // QualType qualType = Func->getReturnType(); +// // if (qualType->isReferenceType()) { +// // qualType = qualType.getNonReferenceType(); +// // } +// // qualType = qualType.getUnqualifiedType(); +// // qualType = qualType.getNonReferenceType(); +// // qualType = qualType.getCanonicalType(); +// // std::vector types = +// // gad_classes_and_functions.get_application_classes( +// // return_type); +// // for (auto type : types) { +// Application application; +// application.class_name = return_type; +// application.signature = ""; +// method.applications.push_back(application); +// // } +// // Application application; +// // application.class_name = get_application_type(qualType); +// // application.signature = ""; +// // method.applications.push_back(application); +// for (const ParmVarDecl *param : Func->parameters()) { +// std::string param_type = param->getType().getAsString(); +// // if (param_type.find(" ") != std::string::npos) { +// // param_type = +// // param_type.substr(param_type.find_last_of(" ") + +// // 1); +// // } +// // QualType qualType = param->getType(); +// // if (qualType->isReferenceType()) { +// // qualType = qualType.getNonReferenceType(); +// // } +// // qualType = qualType.getUnqualifiedType(); +// // qualType = qualType.getNonReferenceType(); +// // qualType = qualType.getCanonicalType(); +// // std::vector types = +// // gad_classes_and_functions.get_application_classes( +// // param_type); +// // for (auto type : types) { +// Application application; +// application.class_name = param_type; +// application.signature = ""; +// method.applications.push_back(application); +// // } +// // Application application; +// // application.class_name = +// get_application_type(qualType); +// // application.signature = ""; +// // method.applications.push_back(application); +// SourceRange srcRange_p = param->getSourceRange(); +// srcRange_p.setEnd(Lexer::getLocForEndOfToken( +// srcRange_p.getEnd(), 0, sourceManager, +// Result.Context->getLangOpts())); +// StringRef srcText_p = Lexer::getSourceText( +// CharSourceRange::getTokenRange(srcRange_p), +// sourceManager, Result.Context->getLangOpts(), +// &Invalid); +// std::string srcText_str = std::string(srcText_p); +// if (srcText_str[srcText_str.length() - 1] == ')' || +// srcText_str[srcText_str.length() - 1] == ',' || +// srcText_str[srcText_str.length() - 1] == ';') { +// srcText_str.erase(srcText_str.length() - 1); +// } +// method.parameters.push_back(srcText_str); +// } +// SourceRange srcRange = Declaration->getSourceRange(); +// srcRange.setEnd(Lexer::getLocForEndOfToken( +// srcRange.getEnd(), 0, sourceManager, +// Result.Context->getLangOpts())); +// StringRef srcText = Lexer::getSourceText( +// CharSourceRange::getTokenRange(srcRange), +// sourceManager, Result.Context->getLangOpts(), +// &Invalid); +// method.function_body = srcText; +// StmtVarFunctionVisitor +// function_stmt_visitor(Result.Context); +// function_stmt_visitor.TraverseStmt(Func->getBody()); +// std::vector stmt_applications = +// function_stmt_visitor.get_applications(); +// for (auto application : stmt_applications) { +// method.applications.push_back(application); +// } +// gad_classes_and_functions.push_back_method(class_name, +// method); +// } +// } +// if (isa(Func)) { +// // Declaration->dump(); +// for (FunctionDecl *Spec : Declaration->specializations()) { +// const TemplateArgumentList *TAL = +// Spec->getTemplateSpecializationArgs(); +// if (TAL) { +// std::vector specialization_parameter; +// std::vector> +// applications; +// for (const TemplateArgument &Arg : TAL->asArray()) { +// if (Arg.getKind() == TemplateArgument::Type) { +// // std::cout << "Template Argument Type: " +// // << Arg.getAsType().getAsString() << +// "\n"; std::string type_name = +// Arg.getAsType().getAsString(); +// // if (type_name.find(" ") != std::string::npos) { +// // type_name = +// // type_name.substr(type_name.find_last_of(" ") +// + +// // 1); +// // } +// specialization_parameter.push_back(type_name); +// // QualType qualType = Arg.getAsType(); +// // if (qualType->isReferenceType()) { +// // qualType = qualType.getNonReferenceType(); +// // } +// // qualType = qualType.getUnqualifiedType(); +// // qualType = qualType.getNonReferenceType(); +// // qualType = qualType.getCanonicalType(); +// // std::vector types = +// // gad_classes_and_functions.get_application_classes( +// // type_name); +// // for (auto type : types) { +// std::pair application; +// application.first = type_name; +// application.second = ""; +// applications.push_back(application); +// // } +// // std::pair application; +// // application.first = +// get_application_type(qualType); +// // application.second = ""; +// // applications.push_back(application); +// } +// } +// gad_classes_and_functions +// .push_back_specialization_parameter( +// class_name, signature, specialization_parameter); +// gad_classes_and_functions.push_back_applications( +// class_name, signature, applications); +// } +// } +// } +// } +// } +// // gad_classes_and_functions.cout(); +// } +// } +// } else if (const EnumDecl *Declaration = +// Result.Nodes.getNodeAs("enumDecl")) { +// if (Declaration->isThisDeclarationADefinition()) { +// clang::SourceLocation loc = Declaration->getLocation(); +// clang::SourceManager &SM = Result.Context->getSourceManager(); +// clang::PresumedLoc presumedLoc = SM.getPresumedLoc(loc); +// std::string file_path = presumedLoc.getFilename(); +// if (file_path.find(gad_project_path) != std::string::npos) { +// auto CanonicalDeclaration = Declaration->getCanonicalDecl(); +// // Declaration->dump(); +// std::string enum_name = CanonicalDeclaration->getNameAsString(); +// for (auto *D : CanonicalDeclaration->getDeclContext()->decls()) { +// if (auto *TD = dyn_cast(D)) { +// if (auto *TRD = TD->getUnderlyingType()->getAsTagDecl()) { +// if (auto *ETRD = dyn_cast(TRD)) { +// if (ETRD->getCanonicalDecl() == CanonicalDeclaration) { +// enum_name = TD->getNameAsString(); +// break; +// } +// } +// } +// } +// } +// if (!gad_classes_and_functions.has_class(enum_name)) { +// Class a_class; +// a_class.class_name = enum_name; +// a_class.record_type = MyRecordType::EnumType; +// for (auto it = Declaration->enumerator_begin(); +// it != Declaration->enumerator_end(); ++it) { +// EnumConstantDecl *ECD = *it; +// a_class.fields.push_back(ECD->getNameAsString()); +// // std::cout << "Enumerator: " << ECD->getNameAsString() << +// // std::endl; +// llvm::APSInt value = ECD->getInitVal(); +// a_class.enum_int_constants.push_back(value.getExtValue()); +// // std::cout << "Value: " << value.getSExtValue() << std::endl; +// } +// gad_classes_and_functions.push_back_class(a_class); +// } +// } +// } +// } +// } +// }; + +// class SecondHandler : public MatchFinder::MatchCallback { +// public: +// virtual void run(const MatchFinder::MatchResult &Result) { +// if (const RecordDecl *Declaration = +// Result.Nodes.getNodeAs("recordDecl")) { +// if (Declaration->isThisDeclarationADefinition()) { +// // Declaration->dump(); +// clang::SourceLocation loc = Declaration->getLocation(); +// clang::SourceManager &SM = Result.Context->getSourceManager(); +// clang::PresumedLoc presumedLoc = SM.getPresumedLoc(loc); +// std::string file_path = presumedLoc.getFilename(); +// if (file_path.find(gad_project_path) != std::string::npos) { +// if (auto CXXDeclaration = dyn_cast(Declaration)) { +// // std::cout << Declaration->getNameAsString() << std::endl; +// // Declaration->dump(); +// // std::cout << std::endl; +// auto CanonicalDeclaration = CXXDeclaration->getCanonicalDecl(); +// // auto canonical_declaration = Declaration->getCanonicalDecl(); +// // canonical_declaration->dump(); +// // Declaration->dump(); +// std::string class_name = CanonicalDeclaration->getNameAsString(); +// if (!gad_classes_and_functions.has_class(class_name)) { +// Class a_class; +// a_class.class_name = class_name; +// a_class.is_template = 0; +// if (CXXDeclaration->isClass()) { +// a_class.record_type = MyRecordType::ClassType; +// } else if (CXXDeclaration->isStruct()) { +// a_class.record_type = MyRecordType::StructType; +// } else if (CXXDeclaration->isUnion()) { +// a_class.record_type = MyRecordType::UnionType; +// } +// // if (RecordDecl->getNumBases() > 0) { +// // a_class.base_class = +// // RecordDecl->bases_begin()->getType().getAsString(); +// // } +// for (auto its_base_class : CXXDeclaration->bases()) { +// a_class.base_class.push_back( +// its_base_class.getType().getAsString()); +// QualType qualType = its_base_class.getType(); +// // if (qualType->isReferenceType()) { +// // qualType = qualType.getNonReferenceType(); +// // } +// // qualType = qualType.getUnqualifiedType(); +// // qualType = qualType.getNonReferenceType(); +// // qualType = qualType.getCanonicalType(); +// // std::vector types = +// // gad_classes_and_functions.get_application_classes( +// // qualType.getAsString()); +// // for (auto type : types) { +// Application application; +// application.class_name = qualType.getAsString(); +// application.signature = ""; +// a_class.applications.push_back(application); +// // } +// // Application application; +// // application.class_name = get_application_type(qualType); +// // application.signature = ""; +// // a_class.applications.push_back(application); +// } +// const DeclContext *context = CXXDeclaration->getDeclContext(); +// bool b = 0; +// while (context) { +// if (const NamespaceDecl *namespaceDecl = +// dyn_cast(context)) { +// b = 1; +// if (a_class.its_namespace == "") { +// a_class.its_namespace = namespaceDecl->getNameAsString(); +// } else { +// a_class.its_namespace = namespaceDecl->getNameAsString() +// + +// "::" + a_class.its_namespace; +// } +// } +// context = context->getParent(); +// } +// if (b == 0) { +// a_class.its_namespace = ""; +// } +// for (const auto *decl : CXXDeclaration->decls()) { +// // if (decl->getCanonicalDecl() == CanonicalDeclaration) { +// // continue; +// // } +// // if (const CXXRecordDecl *Record = +// // dyn_cast(decl)) +// // { +// // if (i == 0) { +// // continue; +// // } +// // const SourceManager &sourceManager = +// // Context->getSourceManager(); SourceRange srcRange = +// // Record->getSourceRange(); +// // srcRange.setEnd(Lexer::getLocForEndOfToken( +// // srcRange.getEnd(), 0, sourceManager, +// // Context->getLangOpts())); +// // bool Invalid = false; +// // StringRef srcText = Lexer::getSourceText( +// // CharSourceRange::getTokenRange(srcRange), +// // sourceManager, Context->getLangOpts(), &Invalid); +// // // std::cout << std::string(srcText) << std::endl; +// // std::string srcText_str = std::string(srcText); +// // if (srcText_str[srcText_str.length() - 1] == ';') { +// // srcText_str.erase(srcText_str.length() - 1); +// // } +// // // if (Record->isClass()) { +// // // if (srcText.find('{') != std::string::npos) { +// // // srcText_str.erase(srcText_str.find_first_of('{')); +// // // } +// // // a_class.fields.push_back(srcText_str); +// // // } else { +// // // a_class.fields.push_back(srcText_str); +// // // } +// // a_class.fields.push_back(srcText_str); +// // } +// if (const FieldDecl *Field = dyn_cast(decl)) { +// std::string field_type = Field->getType().getAsString(); +// // if (field_type.find(" ") != std::string::npos) { +// // field_type = +// // field_type.substr(field_type.find_last_of(" ") + +// 1); +// // } +// // QualType qualType = Field->getType(); +// // if (qualType->isReferenceType()) { +// // qualType = qualType.getNonReferenceType(); +// // } +// // qualType = qualType.getUnqualifiedType(); +// // qualType = qualType.getNonReferenceType(); +// // qualType = qualType.getCanonicalType(); +// // std::vector types = +// // gad_classes_and_functions.get_application_classes( +// // field_type); +// // for (auto type : types) { +// Application application; +// application.class_name = field_type; +// application.signature = ""; +// a_class.applications.push_back(application); +// // } +// // Application application; +// // application.class_name = get_application_type(qualType); +// // application.signature = ""; +// // a_class.applications.push_back(application); +// const SourceManager &sourceManager = +// Result.Context->getSourceManager(); +// SourceRange srcRange = Field->getSourceRange(); +// srcRange.setEnd(Lexer::getLocForEndOfToken( +// srcRange.getEnd(), 0, sourceManager, +// Result.Context->getLangOpts())); +// bool Invalid = false; +// StringRef srcText = Lexer::getSourceText( +// CharSourceRange::getTokenRange(srcRange), +// sourceManager, Result.Context->getLangOpts(), +// &Invalid); +// // std::cout << std::string(srcText) << std::endl; +// std::string srcText_str = std::string(srcText); +// if (srcText_str[srcText_str.length() - 1] == ';') { +// srcText_str.erase(srcText_str.length() - 1); +// } +// if (srcText_str.find("{") != std::string::npos) { +// srcText_str.erase(srcText_str.find_first_of("{"), +// srcText_str.find_last_of("}") + 1 - +// srcText_str.find_first_of("{")); +// } +// if (srcText_str.find("class") != std::string::npos) { +// srcText_str.erase(srcText_str.find_first_of("class"), 6); +// } +// if (srcText_str.find("struct") != std::string::npos) { +// srcText_str.erase(srcText_str.find_first_of("struct"), +// 7); +// } +// if (srcText_str.find("enum") != std::string::npos) { +// srcText_str.erase(srcText_str.find_first_of("enum"), 5); +// } +// if (srcText_str.find("union") != std::string::npos) { +// srcText_str.erase(srcText_str.find_first_of("union"), 6); +// } +// a_class.fields.push_back(srcText_str); +// } +// // else if (const EnumDecl *Enum = dyn_cast(decl)) +// { +// // const SourceManager &sourceManager = +// // Context->getSourceManager(); SourceRange srcRange = +// // Enum->getSourceRange(); +// // srcRange.setEnd(Lexer::getLocForEndOfToken( +// // srcRange.getEnd(), 0, sourceManager, +// // Context->getLangOpts())); +// // bool Invalid = false; +// // StringRef srcText = Lexer::getSourceText( +// // CharSourceRange::getTokenRange(srcRange), +// // sourceManager, Context->getLangOpts(), &Invalid); +// // // std::cout << std::string(srcText) << std::endl; +// // std::string srcText_str = std::string(srcText); +// // if (srcText_str[srcText_str.length() - 1] == ';') { +// // srcText_str.erase(srcText_str.length() - 1); +// // } +// // a_class.fields.push_back(srcText_str); +// // } +// else if (const TypeAliasDecl *TypeAlias = +// dyn_cast(decl)) { +// Alias alias; +// alias.alias_name = TypeAlias->getNameAsString(); +// alias.base_name = +// TypeAlias->getUnderlyingType().getAsString(); +// // QualType qualType = TypeAlias->getUnderlyingType(); +// // if (qualType->isReferenceType()) { +// // qualType = qualType.getNonReferenceType(); +// // } +// // qualType = qualType.getUnqualifiedType(); +// // qualType = qualType.getNonReferenceType(); +// // qualType = qualType.getCanonicalType(); +// a_class.aliases.push_back(alias); +// // std::vector types = +// // gad_classes_and_functions.get_application_classes( +// // alias.base_name); +// // for (auto type : types) { +// Application application; +// application.class_name = alias.base_name; +// application.signature = ""; +// a_class.applications.push_back(application); +// // } +// // Application application; +// // application.class_name = get_application_type(qualType); +// // application.signature = ""; +// // a_class.applications.push_back(application); +// // if +// (gad_classes_and_functions.has_class(alias.base_name)) { +// // std::vector constructors = +// // +// gad_classes_and_functions.get_constructors(alias.base_name); +// // std::vector> +// // applications; for (auto constructor : constructors) { +// // applications.push_back(std::pair( +// // alias.base_name, constructor)); +// // } +// // std::string destructor = +// // +// gad_classes_and_functions.get_destructor(alias.base_name); +// // if (destructor != "class") { +// // applications.push_back(std::pair( +// // alias.base_name, destructor)); +// // } +// // for (auto application : applications) { +// // Application a_application; +// // a_application.class_name = application.first; +// // a_application.signature = application.second; +// // a_class.applications.push_back(a_application); +// // } +// // } +// } +// } +// // i = 1; +// // while (i < a_class.fields.size()) { +// // if (a_class.fields[i] == a_class.fields[i - 1] || +// // (a_class.fields[i].substr( +// // 0, a_class.fields[i].find_last_of('}') + 1) != "" +// && +// // a_class.fields[i - 1].substr( +// // 0, a_class.fields[i - 1].find_last_of('}') + 1) +// != +// // "" +// // && +// // a_class.fields[i].substr( +// // 0, a_class.fields[i].find_last_of('}') + 1) == +// // a_class.fields[i - 1].substr( +// // 0, a_class.fields[i - 1].find_last_of('}') + +// 1)) +// // || +// // a_class.fields[i].find(a_class.fields[i - 1]) != +// // std::string::npos) { +// // a_class.fields.erase(a_class.fields.begin() + i - 1); +// // } else { +// // i++; +// // } +// // } +// // i = 0; +// // while (i < a_class.fields.size()) { +// // if (a_class.fields[i] == "union" || a_class.fields[i] == +// // "struct" +// // || +// // a_class.fields[i] == "class" || a_class.fields[i] == +// // "enum") +// // { +// // a_class.fields.erase(a_class.fields.begin() + i); +// // } else { +// // i++; +// // } +// // } +// // std::cout << a_class.class_name << "\t" << +// a_class.base_class +// // << std::endl; +// // for (auto template_parameter : +// a_class.template_parameters) { +// // std::cout << template_parameter << "\t"; +// // } +// // std::cout << std::endl; +// gad_classes_and_functions.push_back_class(a_class); +// } +// } +// // gad_classes_and_functions.cout(); +// else { // std::cout << Declaration->getNameAsString() << std::endl; +// // Declaration->dump(); +// // std::cout << std::endl; +// auto CanonicalDeclaration = Declaration->getCanonicalDecl(); +// std::string class_name = CanonicalDeclaration->getNameAsString(); +// for (auto *D : CanonicalDeclaration->getDeclContext()->decls()) { +// if (auto *TD = dyn_cast(D)) { +// if (auto *TRD = TD->getUnderlyingType()->getAsRecordDecl()) { +// if (TRD->getCanonicalDecl() == CanonicalDeclaration) { +// class_name = TD->getNameAsString(); +// break; +// } +// } +// } +// } +// // auto canonical_declaration = Declaration->getCanonicalDecl(); +// // CanonicalDeclaration->dump(); +// // Declaration->dump(); +// if (!gad_classes_and_functions.has_class(class_name)) { +// Class a_class; +// a_class.class_name = class_name; +// if (Declaration->isClass()) { +// a_class.record_type = MyRecordType::ClassType; +// } else if (Declaration->isStruct()) { +// a_class.record_type = MyRecordType::StructType; +// } else if (Declaration->isUnion()) { +// a_class.record_type = MyRecordType::UnionType; +// } +// // if (RecordDecl->getNumBases() > 0) { +// // a_class.base_class = +// // RecordDecl->bases_begin()->getType().getAsString(); +// // } +// const DeclContext *context = Declaration->getDeclContext(); +// bool b = 0; +// while (context) { +// if (const NamespaceDecl *namespaceDecl = +// dyn_cast(context)) { +// b = 1; +// if (a_class.its_namespace == "") { +// a_class.its_namespace = namespaceDecl->getNameAsString(); +// } else { +// a_class.its_namespace = namespaceDecl->getNameAsString() +// + +// "::" + a_class.its_namespace; +// } +// } +// context = context->getParent(); +// } +// if (b == 0) { +// a_class.its_namespace = ""; +// } +// for (const auto *decl : Declaration->decls()) { +// // if (decl->getCanonicalDecl() == CanonicalDeclaration) { +// // continue; +// // } +// // if (const CXXRecordDecl *Record = +// // dyn_cast(decl)) +// // { +// // if (i == 0) { +// // continue; +// // } +// // const SourceManager &sourceManager = +// // Context->getSourceManager(); SourceRange srcRange = +// // Record->getSourceRange(); +// // srcRange.setEnd(Lexer::getLocForEndOfToken( +// // srcRange.getEnd(), 0, sourceManager, +// // Context->getLangOpts())); +// // bool Invalid = false; +// // StringRef srcText = Lexer::getSourceText( +// // CharSourceRange::getTokenRange(srcRange), +// // sourceManager, Context->getLangOpts(), &Invalid); +// // // std::cout << std::string(srcText) << std::endl; +// // std::string srcText_str = std::string(srcText); +// // if (srcText_str[srcText_str.length() - 1] == ';') { +// // srcText_str.erase(srcText_str.length() - 1); +// // } +// // // if (Record->isClass()) { +// // // if (srcText.find('{') != std::string::npos) { +// // // srcText_str.erase(srcText_str.find_first_of('{')); +// // // } +// // // a_class.fields.push_back(srcText_str); +// // // } else { +// // // a_class.fields.push_back(srcText_str); +// // // } +// // a_class.fields.push_back(srcText_str); +// // } +// if (const FieldDecl *Field = dyn_cast(decl)) { +// std::string field_type = Field->getType().getAsString(); +// // if (field_type.find(" ") != std::string::npos) { +// // field_type = +// // field_type.substr(field_type.find_last_of(" ") + +// 1); +// // } +// // QualType qualType = Field->getType(); +// // if (qualType->isReferenceType()) { +// // qualType = qualType.getNonReferenceType(); +// // } +// // qualType = qualType.getUnqualifiedType(); +// // qualType = qualType.getNonReferenceType(); +// // qualType = qualType.getCanonicalType(); +// // std::vector types = +// // gad_classes_and_functions.get_application_classes( +// // field_type); +// // for (auto type : types) { +// Application application; +// application.class_name = field_type; +// application.signature = ""; +// a_class.applications.push_back(application); +// // } +// // Application application; +// // application.class_name = get_application_type(qualType); +// // application.signature = ""; +// // a_class.applications.push_back(application); +// const SourceManager &sourceManager = +// Result.Context->getSourceManager(); +// SourceRange srcRange = Field->getSourceRange(); +// srcRange.setEnd(Lexer::getLocForEndOfToken( +// srcRange.getEnd(), 0, sourceManager, +// Result.Context->getLangOpts())); +// bool Invalid = false; +// StringRef srcText = Lexer::getSourceText( +// CharSourceRange::getTokenRange(srcRange), +// sourceManager, Result.Context->getLangOpts(), +// &Invalid); +// // std::cout << std::string(srcText) << std::endl; +// std::string srcText_str = std::string(srcText); +// if (srcText_str[srcText_str.length() - 1] == ';') { +// srcText_str.erase(srcText_str.length() - 1); +// } +// if (srcText_str.find("{") != std::string::npos) { +// srcText_str.erase(srcText_str.find_first_of("{"), +// srcText_str.find_last_of("}") + 1 - +// srcText_str.find_first_of("{")); +// } +// if (srcText_str.find("class") != std::string::npos) { +// srcText_str.erase(srcText_str.find_first_of("class"), 6); +// } +// if (srcText_str.find("struct") != std::string::npos) { +// srcText_str.erase(srcText_str.find_first_of("struct"), +// 7); +// } +// if (srcText_str.find("enum") != std::string::npos) { +// srcText_str.erase(srcText_str.find_first_of("enum"), 5); +// } +// if (srcText_str.find("union") != std::string::npos) { +// srcText_str.erase(srcText_str.find_first_of("union"), 6); +// } +// a_class.fields.push_back(srcText_str); +// } +// // else if (const EnumDecl *Enum = dyn_cast(decl)) +// { +// // const SourceManager &sourceManager = +// // Context->getSourceManager(); SourceRange srcRange = +// // Enum->getSourceRange(); +// // srcRange.setEnd(Lexer::getLocForEndOfToken( +// // srcRange.getEnd(), 0, sourceManager, +// // Context->getLangOpts())); +// // bool Invalid = false; +// // StringRef srcText = Lexer::getSourceText( +// // CharSourceRange::getTokenRange(srcRange), +// // sourceManager, Context->getLangOpts(), &Invalid); +// // // std::cout << std::string(srcText) << std::endl; +// // std::string srcText_str = std::string(srcText); +// // if (srcText_str[srcText_str.length() - 1] == ';') { +// // srcText_str.erase(srcText_str.length() - 1); +// // } +// // a_class.fields.push_back(srcText_str); +// // } +// else if (const TypeAliasDecl *TypeAlias = +// dyn_cast(decl)) { +// Alias alias; +// alias.alias_name = TypeAlias->getNameAsString(); +// alias.base_name = +// TypeAlias->getUnderlyingType().getAsString(); +// // QualType qualType = TypeAlias->getUnderlyingType(); +// // if (qualType->isReferenceType()) { +// // qualType = qualType.getNonReferenceType(); +// // } +// // qualType = qualType.getUnqualifiedType(); +// // qualType = qualType.getNonReferenceType(); +// // qualType = qualType.getCanonicalType(); +// a_class.aliases.push_back(alias); +// // std::vector types = +// // gad_classes_and_functions.get_application_classes( +// // alias.base_name); +// // for (auto type : types) { +// Application application; +// application.class_name = alias.base_name; +// application.signature = ""; +// a_class.applications.push_back(application); +// // } +// // Application application; +// // application.class_name = get_application_type(qualType); +// // application.signature = ""; +// // a_class.applications.push_back(application); +// // if +// (gad_classes_and_functions.has_class(alias.base_name)) { +// // std::vector constructors = +// // +// gad_classes_and_functions.get_constructors(alias.base_name); +// // std::vector> +// // applications; for (auto constructor : constructors) { +// // applications.push_back(std::pair( +// // alias.base_name, constructor)); +// // } +// // std::string destructor = +// // +// gad_classes_and_functions.get_destructor(alias.base_name); +// // if (destructor != "class") { +// // applications.push_back(std::pair( +// // alias.base_name, destructor)); +// // } +// // for (auto application : applications) { +// // Application a_application; +// // a_application.class_name = application.first; +// // a_application.signature = application.second; +// // a_class.applications.push_back(a_application); +// // } +// // } +// } +// } +// // i = 1; +// // while (i < a_class.fields.size()) { +// // if (a_class.fields[i] == a_class.fields[i - 1] || +// // (a_class.fields[i].substr( +// // 0, a_class.fields[i].find_last_of('}') + 1) != "" +// && +// // a_class.fields[i - 1].substr( +// // 0, a_class.fields[i - 1].find_last_of('}') + 1) +// != +// // "" +// // && +// // a_class.fields[i].substr( +// // 0, a_class.fields[i].find_last_of('}') + 1) == +// // a_class.fields[i - 1].substr( +// // 0, a_class.fields[i - 1].find_last_of('}') + +// 1)) +// // || +// // a_class.fields[i].find(a_class.fields[i - 1]) != +// // std::string::npos) { +// // a_class.fields.erase(a_class.fields.begin() + i - 1); +// // } else { +// // i++; +// // } +// // } +// // i = 0; +// // while (i < a_class.fields.size()) { +// // if (a_class.fields[i] == "union" || a_class.fields[i] == +// // "struct" +// // || +// // a_class.fields[i] == "class" || a_class.fields[i] == +// // "enum") +// // { +// // a_class.fields.erase(a_class.fields.begin() + i); +// // } else { +// // i++; +// // } +// // } +// // std::cout << a_class.class_name << "\t" << +// a_class.base_class +// // << std::endl; +// // for (auto template_parameter : +// a_class.template_parameters) { +// // std::cout << template_parameter << "\t"; +// // } +// // std::cout << std::endl; +// gad_classes_and_functions.push_back_class(a_class); +// } +// } +// } +// } +// } else if (const FunctionDecl *Declaration = +// Result.Nodes.getNodeAs("functionDecl")) { +// if (Declaration->isThisDeclarationADefinition()) { +// clang::SourceLocation loc = Declaration->getLocation(); +// clang::SourceManager &SM = Result.Context->getSourceManager(); +// clang::PresumedLoc presumedLoc = SM.getPresumedLoc(loc); +// std::string file_path = presumedLoc.getFilename(); +// if (file_path.find(gad_project_path) != std::string::npos) { +// // std::cout << get_signature(Declaration->getAsFunction()) << +// // std::endl; Declaration->dump(); std::cout << std::endl; +// auto CanonicalDeclaration = Declaration->getCanonicalDecl(); +// // auto canonical_declaration = Declaration->getCanonicalDecl(); +// // canonical_declaration->dump(); +// // Declaration->dump(); +// if (!isa(CanonicalDeclaration)) { +// std::string function_name = +// CanonicalDeclaration->getNameAsString(); +// // if (function_name == "BrotliEncoderCompress") { +// // std::cout << std::endl; +// // } +// std::string signature = get_signature(CanonicalDeclaration); +// if (!gad_classes_and_functions.has_function("class", signature)) +// { +// Function function; +// // std::vector applications; +// function.function_name = function_name; +// function.signature = signature; +// function.is_template = 0; +// const SourceManager &sourceManager = +// Result.Context->getSourceManager(); +// SourceRange srcRange_r = +// Declaration->getReturnTypeSourceRange(); +// srcRange_r.setEnd(Lexer::getLocForEndOfToken( +// srcRange_r.getEnd(), 0, sourceManager, +// Result.Context->getLangOpts())); +// bool Invalid = false; +// StringRef srcText_r = Lexer::getSourceText( +// CharSourceRange::getTokenRange(srcRange_r), sourceManager, +// Result.Context->getLangOpts(), &Invalid); +// function.return_type = std::string(srcText_r); +// std::string return_type = +// Declaration->getReturnType().getAsString(); +// // if (return_type.find(" ") != std::string::npos) { +// // return_type = +// // return_type.substr(return_type.find_last_of(" ") + 1); +// // } +// // QualType qualType = FunctionDeclaration->getReturnType(); +// // if (qualType->isReferenceType()) { +// // qualType = qualType.getNonReferenceType(); +// // } +// // qualType = qualType.getUnqualifiedType(); +// // qualType = qualType.getNonReferenceType(); +// // qualType = qualType.getCanonicalType(); +// std::set +// // types; +// // std::vector types = +// // +// gad_classes_and_functions.get_application_classes(return_type); +// // for (auto type : types) { +// Application application; +// application.class_name = return_type; +// application.signature = ""; +// function.applications.push_back(application); +// // } +// // Application application; +// // application.class_name = get_application_type(qualType); +// // application.signature = ""; +// // function.applications.push_back(application); +// for (const ParmVarDecl *param : Declaration->parameters()) { +// std::string param_type = param->getType().getAsString(); +// // if (param_type.find(" ") != std::string::npos) { +// // param_type = +// // param_type.substr(param_type.find_last_of(" ") + 1); +// // } +// // QualType qualType = param->getType(); +// // if (qualType->isReferenceType()) { +// // qualType = qualType.getNonReferenceType(); +// // } +// // qualType = qualType.getUnqualifiedType(); +// // qualType = qualType.getNonReferenceType(); +// // qualType = qualType.getCanonicalType(); +// // std::vector types = +// // +// gad_classes_and_functions.get_application_classes(param_type); +// // for (auto type : types) { +// Application application; +// application.class_name = param_type; +// application.signature = ""; +// function.applications.push_back(application); +// // } +// // Application application; +// // application.class_name = get_application_type(qualType); +// // application.signature = ""; +// // function.applications.push_back(application); +// SourceRange srcRange_p = param->getSourceRange(); +// srcRange_p.setEnd(Lexer::getLocForEndOfToken( +// srcRange_p.getEnd(), 0, sourceManager, +// Result.Context->getLangOpts())); +// StringRef srcText_p = Lexer::getSourceText( +// CharSourceRange::getTokenRange(srcRange_p), +// sourceManager, Result.Context->getLangOpts(), &Invalid); +// std::string srcText_str = std::string(srcText_p); +// if (srcText_str[srcText_str.length() - 1] == ')' || +// srcText_str[srcText_str.length() - 1] == ',' || +// srcText_str[srcText_str.length() - 1] == ';') { +// srcText_str.erase(srcText_str.length() - 1); +// } +// function.parameters.push_back(srcText_str); +// } +// SourceRange srcRange = Declaration->getSourceRange(); +// srcRange.setEnd(Lexer::getLocForEndOfToken( +// srcRange.getEnd(), 0, sourceManager, +// Result.Context->getLangOpts())); +// StringRef srcText = Lexer::getSourceText( +// CharSourceRange::getTokenRange(srcRange), sourceManager, +// Result.Context->getLangOpts(), &Invalid); +// function.function_body = srcText; +// const DeclContext *context = Declaration->getDeclContext(); +// bool b = 0; +// while (context) { +// if (const NamespaceDecl *namespaceDecl = +// dyn_cast(context)) { +// b = 1; +// if (function.its_namespace == "") { +// function.its_namespace = +// namespaceDecl->getNameAsString(); +// } else { +// function.its_namespace = namespaceDecl->getNameAsString() +// + +// "::" + function.its_namespace; +// } +// } +// context = context->getParent(); +// } +// if (b == 0) { +// function.its_namespace = ""; +// } +// StmtVarFunctionVisitor function_stmt_visitor(Result.Context); +// function_stmt_visitor.TraverseStmt(Declaration->getBody()); +// std::vector stmt_applications = +// function_stmt_visitor.get_applications(); +// for (auto application : stmt_applications) { +// function.applications.push_back(application); +// } +// gad_classes_and_functions.push_back_function(function); +// } +// } else { +// const CXXRecordDecl *CanonicalParentClass = +// dyn_cast(CanonicalDeclaration->getParent()) +// ->getCanonicalDecl(); +// std::string class_name = CanonicalParentClass->getNameAsString(); +// if (gad_classes_and_functions.has_class(class_name)) { +// // std::cout << "Class Declaration " << class_name << +// // std::endl; +// std::string signature = get_signature(CanonicalDeclaration); +// if (!gad_classes_and_functions.has_function(class_name, +// signature)) { +// if (isa(CanonicalDeclaration)) { +// // std::string signature; +// // std::string function_body; +// // std::vector parameters; +// // std::vector applications; +// Constructor constructor; +// const SourceManager &sourceManager = +// Result.Context->getSourceManager(); +// bool Invalid = false; +// constructor.signature = signature; +// for (const ParmVarDecl *param : Declaration->parameters()) +// { +// std::string param_type = param->getType().getAsString(); +// // if (param_type.find(" ") != std::string::npos) { +// // param_type = +// // param_type.substr(param_type.find_last_of(" ") + +// // 1); +// // } +// // QualType qualType = param->getType(); +// // std::cout << qualType.getAsString() << std::endl; +// // if (qualType->isReferenceType()) { +// // qualType = qualType.getNonReferenceType(); +// // } +// // qualType = qualType.getUnqualifiedType(); +// // std::cout << qualType.getAsString() << std::endl; +// // qualType = qualType.getNonReferenceType(); +// // std::cout << qualType.getAsString() << std::endl; +// // qualType = qualType.getLocalUnqualifiedType(); +// // std::cout << qualType.getAsString() << std::endl; +// // qualType = qualType.getCanonicalType(); +// // std::cout << qualType.getAsString() << std::endl; +// // qualType = qualType.getCanonicalType(); +// // std::vector types = +// // gad_classes_and_functions.get_application_classes( +// // param_type); +// // for (auto type : types) { +// Application application; +// application.class_name = param_type; +// application.signature = ""; +// constructor.applications.push_back(application); +// // } +// // Application application; +// // application.class_name = +// get_application_type(qualType); +// // application.signature = ""; +// // constructor.applications.push_back(application); +// SourceRange srcRange_p = param->getSourceRange(); +// srcRange_p.setEnd(Lexer::getLocForEndOfToken( +// srcRange_p.getEnd(), 0, sourceManager, +// Result.Context->getLangOpts())); +// StringRef srcText_p = Lexer::getSourceText( +// CharSourceRange::getTokenRange(srcRange_p), +// sourceManager, Result.Context->getLangOpts(), +// &Invalid); +// std::string srcText_str = std::string(srcText_p); +// if (srcText_str[srcText_str.length() - 1] == ')' || +// srcText_str[srcText_str.length() - 1] == ',' || +// srcText_str[srcText_str.length() - 1] == ';') { +// srcText_str.erase(srcText_str.length() - 1); +// } +// constructor.parameters.push_back(srcText_str); +// } +// SourceRange srcRange = Declaration->getSourceRange(); +// srcRange.setEnd(Lexer::getLocForEndOfToken( +// srcRange.getEnd(), 0, sourceManager, +// Result.Context->getLangOpts())); +// StringRef srcText = Lexer::getSourceText( +// CharSourceRange::getTokenRange(srcRange), +// sourceManager, Result.Context->getLangOpts(), +// &Invalid); +// constructor.function_body = srcText; +// StmtVarFunctionVisitor +// function_stmt_visitor(Result.Context); +// function_stmt_visitor.TraverseStmt(Declaration->getBody()); +// std::vector stmt_applications = +// function_stmt_visitor.get_applications(); +// for (auto application : stmt_applications) { +// constructor.applications.push_back(application); +// } +// gad_classes_and_functions.push_back_constructor(class_name, +// constructor); +// } else if (isa(CanonicalDeclaration)) { +// // std::string signature; +// // std::string function_body; +// // std::vector applications; +// // std::cout << "Destructor Declaration " << +// // class_name +// // << std::endl; +// Destructor destructor; +// const SourceManager &sourceManager = +// Result.Context->getSourceManager(); +// SourceRange srcRange = Declaration->getSourceRange(); +// srcRange.setEnd(Lexer::getLocForEndOfToken( +// srcRange.getEnd(), 0, sourceManager, +// Result.Context->getLangOpts())); +// bool Invalid = false; +// StringRef srcText = Lexer::getSourceText( +// CharSourceRange::getTokenRange(srcRange), +// sourceManager, Result.Context->getLangOpts(), +// &Invalid); +// destructor.signature = signature; +// destructor.function_body = srcText; +// StmtVarFunctionVisitor +// function_stmt_visitor(Result.Context); +// function_stmt_visitor.TraverseStmt(Declaration->getBody()); +// std::vector stmt_applications = +// function_stmt_visitor.get_applications(); +// for (auto application : stmt_applications) { +// destructor.applications.push_back(application); +// } +// gad_classes_and_functions.push_back_destructor(class_name, +// destructor); +// } else { +// Method method; +// std::string function_name = Declaration->getNameAsString(); +// // std::cout << "Method Declaration " << +// // function_name +// // << std::endl; +// method.method_name = function_name; +// method.signature = signature; +// method.is_template = 0; +// const SourceManager &sourceManager = +// Result.Context->getSourceManager(); +// SourceRange srcRange_r = +// Declaration->getReturnTypeSourceRange(); +// srcRange_r.setEnd(Lexer::getLocForEndOfToken( +// srcRange_r.getEnd(), 0, sourceManager, +// Result.Context->getLangOpts())); +// bool Invalid = false; +// StringRef srcText_r = Lexer::getSourceText( +// CharSourceRange::getTokenRange(srcRange_r), +// sourceManager, Result.Context->getLangOpts(), +// &Invalid); +// method.return_type = std::string(srcText_r); +// std::string return_type = +// Declaration->getReturnType().getAsString(); +// // if (return_type.find(" ") != std::string::npos) { +// // return_type = +// // return_type.substr(return_type.find_last_of(" ") + +// // 1); +// // } +// // QualType qualType = +// FunctionDeclaration->getReturnType(); +// // if (qualType->isReferenceType()) { +// // qualType = qualType.getNonReferenceType(); +// // } +// // qualType = qualType.getUnqualifiedType(); +// // qualType = qualType.getNonReferenceType(); +// // qualType = qualType.getCanonicalType(); +// // std::vector types = +// // gad_classes_and_functions.get_application_classes( +// // return_type); +// // for (auto type : types) { +// Application application; +// application.class_name = return_type; +// application.signature = ""; +// method.applications.push_back(application); +// // } +// // Application application; +// // application.class_name = get_application_type(qualType); +// // application.signature = ""; +// // method.applications.push_back(application); +// for (const ParmVarDecl *param : Declaration->parameters()) +// { +// std::string param_type = param->getType().getAsString(); +// // if (param_type.find(" ") != std::string::npos) { +// // param_type = +// // param_type.substr(param_type.find_last_of(" ") + +// // 1); +// // } +// // QualType qualType = param->getType(); +// // if (qualType->isReferenceType()) { +// // qualType = qualType.getNonReferenceType(); +// // } +// // qualType = qualType.getUnqualifiedType(); +// // qualType = qualType.getNonReferenceType(); +// // qualType = qualType.getCanonicalType(); +// // std::vector types = +// // gad_classes_and_functions.get_application_classes( +// // param_type); +// // for (auto type : types) { +// Application application; +// application.class_name = param_type; +// application.signature = ""; +// method.applications.push_back(application); +// // } +// // Application application; +// // application.class_name = +// get_application_type(qualType); +// // application.signature = ""; +// // method.applications.push_back(application); +// SourceRange srcRange_p = param->getSourceRange(); +// srcRange_p.setEnd(Lexer::getLocForEndOfToken( +// srcRange_p.getEnd(), 0, sourceManager, +// Result.Context->getLangOpts())); +// StringRef srcText_p = Lexer::getSourceText( +// CharSourceRange::getTokenRange(srcRange_p), +// sourceManager, Result.Context->getLangOpts(), +// &Invalid); +// std::string srcText_str = std::string(srcText_p); +// if (srcText_str[srcText_str.length() - 1] == ')' || +// srcText_str[srcText_str.length() - 1] == ',' || +// srcText_str[srcText_str.length() - 1] == ';') { +// srcText_str.erase(srcText_str.length() - 1); +// } +// method.parameters.push_back(srcText_str); +// } +// SourceRange srcRange = Declaration->getSourceRange(); +// srcRange.setEnd(Lexer::getLocForEndOfToken( +// srcRange.getEnd(), 0, sourceManager, +// Result.Context->getLangOpts())); +// StringRef srcText = Lexer::getSourceText( +// CharSourceRange::getTokenRange(srcRange), +// sourceManager, Result.Context->getLangOpts(), +// &Invalid); +// method.function_body = srcText; +// StmtVarFunctionVisitor +// function_stmt_visitor(Result.Context); +// function_stmt_visitor.TraverseStmt(Declaration->getBody()); +// std::vector stmt_applications = +// function_stmt_visitor.get_applications(); +// for (auto application : stmt_applications) { +// method.applications.push_back(application); +// } +// gad_classes_and_functions.push_back_method(class_name, +// method); +// } +// } +// } +// } +// // gad_classes_and_functions.cout(); +// } +// } +// } +// } +// }; + +void GetClassesAndFunctions::get_definitions() { + gad_project_path = project_path; + for (auto file_path : *file_paths) { + // std::cout << file_path << std::endl; + std::vector args{"context_path", "-p", + compilation_database_path.c_str(), + file_path.c_str()}; + int argc = args.size(); + const char **argv = args.data(); + auto ExpectedParser = + CommonOptionsParser::create(argc, argv, FocxtCategory); + if (!ExpectedParser) { + errs() << ExpectedParser.takeError(); + exit(1); + } + CommonOptionsParser &OptionParser = ExpectedParser.get(); + ClangTool Tool(OptionParser.getCompilations(), + OptionParser.getSourcePathList()); + Tool.run(newFrontendActionFactory().get()); + // FirstHandler first_handler; + // MatchFinder first_finder; + // first_finder.addMatcher(classTemplateDecl().bind("classTemplateDecl"), + // &first_handler); + // first_finder.addMatcher(functionTemplateDecl().bind("functionTemplateDecl"), + // &first_handler); + // first_finder.addMatcher(enumDecl().bind("enumDecl"), &first_handler); + // Tool.run(newFrontendActionFactory(&first_finder).get()); + // SecondHandler second_handler; + // MatchFinder second_finder; + // second_finder.addMatcher(recordDecl().bind("recordDecl"), + // &second_handler); + // second_finder.addMatcher(functionDecl().bind("functionDecl"), + // &second_handler); + // Tool.run(newFrontendActionFactory(&second_finder).get()); + } + // gad_classes_and_functions.cout(); + gad_classes_and_functions.update_all_applications(); + classes_and_functions = gad_classes_and_functions; +} + +ClassesAndFunctions GetClassesAndFunctions::get_classes_and_functions() { + return classes_and_functions; +} + +std::vector +ClassesAndFunctions::get_applications(std::string class_name, + std::string signature) { + if (class_name != "class") { + for (auto a_class : classes) { + if (a_class.class_name == class_name) { + if (signature == "") { + return a_class.applications; + } else { + for (auto constructor : a_class.constructors) { + if (constructor.signature == signature) { + return constructor.applications; + } + } + if (a_class.destructor.signature == signature) { + return a_class.destructor.applications; + } + for (auto method : a_class.methods) { + if (method.signature == signature) { + return method.applications; + } + } + } + } + } + } else { + for (auto function : functions) { + if (function.signature == signature) { + return function.applications; + } + } + } +} + +void ClassesAndFunctions::get_all_applications( + std::vector *applications) { + for (auto &application : *applications) { + application.is_direct = 1; + } + int i = 0; + while (i < applications->size()) { + auto application = (*applications)[i]; + std::vector need_applications = + get_applications(application.class_name, application.signature); + for (auto &need_application : need_applications) { + bool b = 0; + for (auto exist_application : *applications) { + if (exist_application == need_application) { + b = 1; + break; + } + } + if (b == 0) { + need_application.is_direct = 0; + applications->push_back(need_application); + } + } + i++; + } +} + +json ClassesAndFunctions::get_simple_class(std::string class_name) { + json j; + for (auto a_class : classes) { + if (a_class.class_name == class_name) { + if (a_class.record_type != MyRecordType::EnumType) { + std::string record_type; + switch (a_class.record_type) { + case MyRecordType::ClassType: + record_type = "class"; + break; + case MyRecordType::StructType: + record_type = "struct"; + break; + case MyRecordType::UnionType: + record_type = "union"; + break; + default: + break; + } + j[a_class.its_namespace] = json::object(); + j[a_class.its_namespace][record_type] = json::object(); + j[a_class.its_namespace][record_type][a_class.class_name] = + json::object(); + if (record_type == "class" || record_type == "struct") { + j[a_class.its_namespace][record_type][a_class.class_name]["base"] = + json::array(); + j[a_class.its_namespace][record_type][a_class.class_name]["base"] = + a_class.base_class; + } + j[a_class.its_namespace][record_type][a_class.class_name] + ["is_template"] = json::object(); + if (a_class.is_template == 1) { + j[a_class.its_namespace][record_type][a_class.class_name] + ["is_template"] = true; + j[a_class.its_namespace][record_type][a_class.class_name] + ["template_parameters"] = json::object(); + // j[a_class.its_namespace][record_type][a_class.class_name] + // ["template_parameters"] = a_class.template_parameters; + std::string template_parameters_str = "template <"; + int i = 0; + for (auto template_parameter : a_class.template_parameters) { + if (i != 0) { + template_parameters_str += ", "; + } + template_parameters_str += template_parameter; + i++; + } + template_parameters_str += ">"; + j[a_class.its_namespace][record_type][a_class.class_name] + ["template_parameters"] = template_parameters_str; + j[a_class.its_namespace][record_type][a_class.class_name] + ["specialization_parameters"] = json::array(); + for (auto specialization_parameter : + a_class.specialization_parameters) { + std::string specialization_parameter_string = "<"; + int i = 0; + for (auto specialization_parameter_type : + specialization_parameter) { + if (i == 0) { + specialization_parameter_string = + specialization_parameter_string + + specialization_parameter_type; + } else { + specialization_parameter_string = + specialization_parameter_string + "," + + specialization_parameter_type; + } + i++; + } + specialization_parameter_string = + specialization_parameter_string + ">"; + j[a_class.its_namespace][record_type][a_class.class_name] + ["specialization_parameters"] + .push_back(specialization_parameter_string); + } + } else { + j[a_class.its_namespace][record_type][a_class.class_name] + ["is_template"] = false; + } + j[a_class.its_namespace][record_type][a_class.class_name]["alias"] = + json::array(); + for (auto alias : a_class.aliases) { + std::string alias_string = + "using " + alias.alias_name + " = " + alias.base_name; + j[a_class.its_namespace][record_type][a_class.class_name]["alias"] + .push_back(alias_string); + } + j[a_class.its_namespace][record_type][a_class.class_name] + ["constructor"] = json::object(); + for (auto constructor : a_class.constructors) { + j[a_class.its_namespace][record_type][a_class.class_name] + ["constructor"][constructor.signature] = json::object(); + j[a_class.its_namespace][record_type][a_class.class_name] + ["constructor"][constructor.signature]["function_body"] = + json::object(); + j[a_class.its_namespace][record_type][a_class.class_name] + ["constructor"][constructor.signature]["parameters"] = json::array(); + } + j[a_class.its_namespace][record_type][a_class.class_name] + ["destructor"] = json::object(); + j[a_class.its_namespace][record_type][a_class.class_name]["destructor"] + ["function_body"] = json::object(); + j[a_class.its_namespace][record_type][a_class.class_name]["destructor"] + ["signature"] = json::object(); + j[a_class.its_namespace][record_type][a_class.class_name]["destructor"] + ["signature"] = a_class.destructor.signature; + j[a_class.its_namespace][record_type][a_class.class_name]["fields"] = + json::array(); + j[a_class.its_namespace][record_type][a_class.class_name]["fields"] = + a_class.fields; + j[a_class.its_namespace][record_type][a_class.class_name]["methods"] = + json::object(); + for (auto method : a_class.methods) { + j[a_class.its_namespace][record_type][a_class.class_name]["methods"] + [method.signature] = json::object(); + j[a_class.its_namespace][record_type][a_class.class_name]["methods"] + [method.signature]["function_body"] = json::object(); + j[a_class.its_namespace][record_type][a_class.class_name]["methods"] + [method.signature]["parameters"] = json::array(); + j[a_class.its_namespace][record_type][a_class.class_name]["methods"] + [method.signature]["return_type"] = json::object(); + j[a_class.its_namespace][record_type][a_class.class_name]["methods"] + [method.signature]["is_template"] = json::object(); + } + } else { + j[a_class.its_namespace] = json::object(); + j[a_class.its_namespace]["enum"] = json::object(); + j[a_class.its_namespace]["enum"][a_class.class_name] = json::object(); + j[a_class.its_namespace]["enum"][a_class.class_name]["enum_constants"] = + json::array(); + j[a_class.its_namespace]["enum"][a_class.class_name]["enum_constants"] = + a_class.fields; + j[a_class.its_namespace]["enum"][a_class.class_name] + ["enum_int_constants"] = json::array(); + j[a_class.its_namespace]["enum"][a_class.class_name] + ["enum_int_constants"] = a_class.enum_int_constants; + } + return j; + } + } +} + +json ClassesAndFunctions::get_j(Application application) { + json j; + if (application.class_name != "class") { + for (auto a_class : classes) { + if (a_class.class_name == application.class_name) { + std::string record_type; + switch (a_class.record_type) { + case MyRecordType::ClassType: + record_type = "class"; + break; + case MyRecordType::StructType: + record_type = "struct"; + break; + case MyRecordType::UnionType: + record_type = "union"; + break; + default: + break; + } + bool b = 0; + if (b == 0) { + for (auto constructor : a_class.constructors) { + if (constructor.signature == application.signature) { + b = 1; + j[a_class.its_namespace] = json::object(); + j[a_class.its_namespace][record_type] = json::object(); + j[a_class.its_namespace][record_type][a_class.class_name] = + json::object(); + j[a_class.its_namespace][record_type][a_class.class_name] + ["constructor"] = json::object(); + j[a_class.its_namespace][record_type][a_class.class_name] + ["constructor"][constructor.signature] = json::object(); + j[a_class.its_namespace][record_type][a_class.class_name] + ["constructor"][constructor.signature]["function_body"] = + json::object(); + if (application.is_direct == 1) { + j[a_class.its_namespace][record_type][a_class.class_name] + ["constructor"][constructor.signature]["function_body"] = + constructor.function_body; + } + j[a_class.its_namespace][record_type][a_class.class_name] + ["constructor"][constructor.signature]["parameters"] = + json::array(); + j[a_class.its_namespace][record_type][a_class.class_name] + ["constructor"][constructor.signature]["parameters"] = + constructor.parameters; + break; + } + } + } else { + break; + } + if (b == 0) { + if (a_class.destructor.signature == application.signature) { + b = 1; + j[a_class.its_namespace] = json::object(); + j[a_class.its_namespace][record_type] = json::object(); + j[a_class.its_namespace][record_type][a_class.class_name] = + json::object(); + j[a_class.its_namespace][record_type][a_class.class_name] + ["destructor"] = json::object(); + j[a_class.its_namespace][record_type][a_class.class_name] + ["destructor"]["function_body"] = json::object(); + if (application.is_direct == 1) { + j[a_class.its_namespace][record_type][a_class.class_name] + ["destructor"]["function_body"] = + a_class.destructor.function_body; + } + j[a_class.its_namespace][record_type][a_class.class_name] + ["destructor"]["signature"] = json::object(); + j[a_class.its_namespace][record_type][a_class.class_name] + ["destructor"]["signature"] = a_class.destructor.signature; + } + } else { + break; + } + if (b == 0) { + for (auto method : a_class.methods) { + if (method.signature == application.signature) { + j[a_class.its_namespace] = json::object(); + j[a_class.its_namespace][record_type] = json::object(); + j[a_class.its_namespace][record_type][a_class.class_name] = + json::object(); + j[a_class.its_namespace][record_type][a_class.class_name] + ["methods"] = json::object(); + j[a_class.its_namespace][record_type][a_class.class_name] + ["methods"][method.signature] = json::object(); + j[a_class.its_namespace][record_type][a_class.class_name] + ["methods"][method.signature]["function_body"] = json::object(); + if (application.is_direct == 1) { + j[a_class.its_namespace][record_type][a_class.class_name] + ["methods"][method.signature]["function_body"] = + method.function_body; + } + j[a_class.its_namespace][record_type][a_class.class_name] + ["methods"][method.signature]["parameters"] = json::array(); + j[a_class.its_namespace][record_type][a_class.class_name] + ["methods"][method.signature]["parameters"] = method.parameters; + j[a_class.its_namespace][record_type][a_class.class_name] + ["methods"][method.signature]["is_template"] = json::object(); + if (method.is_template == 1) { + j[a_class.its_namespace][record_type][a_class.class_name] + ["methods"][method.signature]["is_template"] = true; + j[a_class.its_namespace][record_type][a_class.class_name] + ["methods"][method.signature]["template_parameters"] = + json::object(); + // j[a_class.its_namespace][record_type][a_class.class_name] + // ["methods"][method.signature]["template_parameters"] = + // method.template_parameters; + std::string template_parameters_str = "template <"; + int i = 0; + for (auto template_parameter : method.template_parameters) { + if (i != 0) { + template_parameters_str += ", "; + } + template_parameters_str += template_parameter; + i++; + } + template_parameters_str += ">"; + j[a_class.its_namespace][record_type][a_class.class_name] + ["methods"][method.signature]["template_parameters"] = + template_parameters_str; + j[a_class.its_namespace][record_type][a_class.class_name] + ["methods"][method.signature]["specialization_parameters"] = + json::array(); + for (auto specialization_parameter : + method.specialization_parameters) { + std::string specialization_parameter_string = "<"; + int i = 0; + for (auto specialization_parameter_type : + specialization_parameter) { + if (i == 0) { + specialization_parameter_string = + specialization_parameter_string + + specialization_parameter_type; + } else { + specialization_parameter_string = + specialization_parameter_string + "," + + specialization_parameter_type; + } + i++; + } + specialization_parameter_string = + specialization_parameter_string + ">"; + j[a_class.its_namespace][record_type][a_class.class_name] + ["methods"][method.signature]["specialization_parameters"] + .push_back(specialization_parameter_string); + } + } else { + j[a_class.its_namespace][record_type][a_class.class_name] + ["methods"][method.signature]["is_template"] = false; + } + j[a_class.its_namespace][record_type][a_class.class_name] + ["methods"][method.signature]["return_type"] = json::object(); + j[a_class.its_namespace][record_type][a_class.class_name] + ["methods"][method.signature]["return_type"] = + method.return_type; + break; + } + } + } else { + break; + } + } + } + } else { + for (auto function : functions) { + if (function.signature == application.signature) { + j[function.its_namespace] = json::object(); + j[function.its_namespace]["function"] = json::object(); + j[function.its_namespace]["function"][function.signature] = + json::object(); + j[function.its_namespace]["function"][function.signature] + ["function_body"] = json::object(); + if (application.is_direct == 1) { + j[function.its_namespace]["function"][function.signature] + ["function_body"] = function.function_body; + } + j[function.its_namespace]["function"][function.signature] + ["parameters"] = json::array(); + j[function.its_namespace]["function"][function.signature] + ["parameters"] = function.parameters; + j[function.its_namespace]["function"][function.signature] + ["is_template"] = json::object(); + if (function.is_template == 1) { + j[function.its_namespace]["function"][function.signature] + ["is_template"] = true; + j[function.its_namespace]["function"][function.signature] + ["template_parameters"] = json::object(); + // j[function.its_namespace]["function"][function.signature] + // ["template_parameters"] = function.template_parameters; + std::string template_parameters_str = "template <"; + int i = 0; + for (auto template_parameter : function.template_parameters) { + if (i != 0) { + template_parameters_str += ", "; + } + template_parameters_str += template_parameter; + i++; + } + template_parameters_str += ">"; + j[function.its_namespace]["function"][function.signature] + ["template_parameters"] = template_parameters_str; + j[function.its_namespace]["function"][function.signature] + ["specialization_parameters"] = json::array(); + for (auto specialization_parameter : + function.specialization_parameters) { + std::string specialization_parameter_string = "<"; + int i = 0; + for (auto specialization_parameter_type : + specialization_parameter) { + if (i == 0) { + specialization_parameter_string = + specialization_parameter_string + + specialization_parameter_type; + } else { + specialization_parameter_string = + specialization_parameter_string + "," + + specialization_parameter_type; + } + i++; + } + specialization_parameter_string = + specialization_parameter_string + ">"; + j[function.its_namespace]["function"][function.signature] + ["specialization_parameters"] + .push_back(specialization_parameter_string); + } + } else { + j[function.its_namespace]["function"][function.signature] + ["is_template"] = false; + } + j[function.its_namespace]["function"][function.signature] + ["return_type"] = json::object(); + j[function.its_namespace]["function"][function.signature] + ["return_type"] = function.return_type; + break; + } + } + } + return j; +} \ No newline at end of file diff --git a/clang-tools-extra/focxt/GetAllDefinition.h b/clang-tools-extra/focxt/GetAllDefinition.h new file mode 100755 index 0000000000000..b834d5e2a2ce0 --- /dev/null +++ b/clang-tools-extra/focxt/GetAllDefinition.h @@ -0,0 +1,347 @@ +#pragma once +#include "nlohmann/json.hpp" +#include "clang/AST/ASTConsumer.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FrontendAction.h" +#include "clang/Frontend/FrontendActions.h" +#include "clang/Lex/Lexer.h" +#include "clang/Tooling/CommonOptionsParser.h" +#include "clang/Tooling/Tooling.h" +#include "llvm/Support/CommandLine.h" +#include +#include +#include +#include +#include +#include +#include +#include + +namespace fs = std::filesystem; +using json = nlohmann::json; +using namespace clang; +using namespace clang::tooling; +using namespace llvm; + +enum MyRecordType { ClassType, StructType, UnionType, EnumType }; + +struct Application { + std::string class_name; + std::string signature; + bool is_direct; + bool operator==(const Application &other) const { + return class_name == other.class_name && signature == other.signature; + } + void cout() { + std::cout << "application_class:\t" << class_name + << "\tapplication_signature:\t" << signature << std::endl; + } +}; + +struct Function { + std::string function_name; + std::string signature; + bool is_template; + std::vector template_parameters; + std::vector> specialization_parameters; + std::string function_body; + std::vector parameters; + std::string return_type; + std::vector applications; + std::string its_namespace; + void cout() { + std::cout << "function_name:\t" << function_name << "\tsignature:\t" + << signature << "\tis_template:\t" << is_template + << "\tnamespace:\t" << its_namespace << std::endl; + if (is_template) { + std::cout << "template_parameters:\t"; + for (auto template_parameter : template_parameters) { + std::cout << template_parameter << "\t"; + } + std::cout << std::endl; + std::cout << "specialization_parameters:\t"; + for (auto specialization_parameter : specialization_parameters) { + std::cout << "<\t"; + for (auto specialization_paramete : specialization_parameter) { + std::cout << specialization_paramete << "\t"; + } + std::cout << ">\t"; + } + std::cout << std::endl; + } + std::cout << "function_body:\t" << function_body << std::endl; + std::cout << "parameters:\t"; + for (auto parameter : parameters) { + std::cout << parameter << "\t"; + } + std::cout << std::endl; + std::cout << "return_type:\t" << return_type << std::endl; + std::cout << "applications:\t"; + for (auto application : applications) { + application.cout(); + } + std::cout << std::endl << std::endl; + } +}; + +struct Constructor { + std::string signature; + std::string function_body; + std::vector parameters; + std::vector applications; + void cout() { + std::cout << "signature:\t" << signature << std::endl; + std::cout << "function_body:\t" << function_body << std::endl; + std::cout << "parameters:\t"; + for (auto parameter : parameters) { + std::cout << parameter << "\t"; + } + std::cout << std::endl; + std::cout << "applications:\t"; + for (auto application : applications) { + application.cout(); + } + std::cout << std::endl; + } +}; + +struct Destructor { + std::string signature; + std::string function_body; + std::vector applications; + void cout() { + std::cout << "signature:\t" << signature << std::endl; + std::cout << "function_body:\t" << function_body << std::endl; + std::cout << "applications:\t"; + for (auto application : applications) { + application.cout(); + } + std::cout << std::endl; + } +}; + +struct Method { + std::string method_name; + std::string signature; + bool is_template; + std::vector template_parameters; + std::vector> specialization_parameters; + std::string function_body; + std::vector parameters; + std::string return_type; + std::vector applications; + void cout() { + std::cout << "method_name:\t" << method_name << "\tsignature:\t" + << signature << "\tis_template:\t" << is_template << std::endl; + if (is_template) { + std::cout << "template_parameters:\t"; + for (auto template_parameter : template_parameters) { + std::cout << template_parameter << "\t"; + } + std::cout << std::endl; + std::cout << "specialization_parameters:\t"; + for (auto specialization_parameter : specialization_parameters) { + std::cout << "<\t"; + for (auto specialization_paramete : specialization_parameter) { + std::cout << specialization_paramete << "\t"; + } + std::cout << ">\t"; + } + std::cout << std::endl; + } + std::cout << "function_body:\t" << function_body << std::endl; + std::cout << "parameters:\t"; + for (auto parameter : parameters) { + std::cout << parameter << "\t"; + } + std::cout << std::endl; + std::cout << "return_type:\t" << return_type << std::endl; + std::cout << "applications:\t"; + for (auto application : applications) { + application.cout(); + } + std::cout << std::endl; + } +}; + +struct Alias { + std::string alias_name; + std::string base_name; + void cout() { + std::cout << "using " << alias_name << " = " << base_name << std::endl; + } +}; + +struct Class { + MyRecordType record_type; + std::string class_name; + std::vector base_class; + bool is_template; + std::vector template_parameters; + std::vector> specialization_parameters; + std::vector fields; + std::vector enum_int_constants; + std::string its_namespace; + std::vector aliases; + std::vector constructors; + Destructor destructor; + std::vector methods; + std::vector applications; + void cout() { + if (record_type == MyRecordType::EnumType) { + std::cout << "type:\tenum" << "\tclass_name:\t" << class_name + << std::endl; + std::cout << "fields:\t"; + for (auto field : fields) { + std::cout << field << "\t"; + } + std::cout << std::endl; + std::cout << "enum_int_constants:\t"; + for (auto enum_int_constant : enum_int_constants) { + std::cout << enum_int_constant << "\t"; + } + std::cout << std::endl; + std::cout << "applications:\t"; + for (auto application : applications) { + application.cout(); + } + std::cout << std::endl << std::endl; + } else { + std::string record_type_string; + switch (record_type) { + case MyRecordType::ClassType: + record_type_string = "class"; + break; + case MyRecordType::StructType: + record_type_string = "struct"; + break; + case MyRecordType::UnionType: + record_type_string = "union"; + break; + default: + break; + } + std::cout << "type:\t" << record_type_string << "\tclass_name:\t" + << class_name << "\tnamespace:\t" << its_namespace << std::endl; + std::cout << "base_class:\t"; + for (auto base : base_class) { + std::cout << base << "\t"; + } + std::cout << std::endl; + std::cout << "is_template:\t" << is_template << std::endl; + if (is_template) { + std::cout << "template_parameters:\t"; + for (auto template_parameter : template_parameters) { + std::cout << template_parameter << "\t"; + } + std::cout << std::endl; + std::cout << "specialization_parameters:\t"; + for (auto specialization_parameter : specialization_parameters) { + std::cout << "<\t"; + for (auto specialization_paramete : specialization_parameter) { + std::cout << specialization_paramete << "\t"; + } + std::cout << ">\t"; + } + std::cout << std::endl; + } + std::cout << "fields:\t"; + for (auto field : fields) { + std::cout << field << "\t"; + } + std::cout << std::endl; + std::cout << "alias:\t"; + for (auto alias : aliases) { + alias.cout(); + } + std::cout << std::endl; + std::cout << "constructors:\t"; + for (auto constructor : constructors) { + constructor.cout(); + } + std::cout << std::endl; + std::cout << "destructor:\t"; + destructor.cout(); + std::cout << std::endl; + std::cout << "methods:\t"; + for (auto method : methods) { + method.cout(); + } + std::cout << std::endl; + std::cout << "applications:\t"; + for (auto application : applications) { + application.cout(); + } + std::cout << std::endl << std::endl; + } + } +}; + +void update_applications(std::vector &applications); + +class ClassesAndFunctions { + std::vector classes; + std::vector functions; + +public: + bool has_class(std::string class_name); + MyRecordType get_class_type(std::string class_name); + void push_back_class(Class a_class); + void push_back_specialization_parameter( + std::string clas_name, std::string signature, + std::vector specialization_parameter); + void push_back_applications( + std::string class_name, std::string signature, + std::vector> applications); + std::vector get_constructors(std::string class_name); + std::string get_destructor(std::string class_name); + bool has_function(std::string class_name, std::string signature); + void push_back_function(Function function); + void push_back_constructor(std::string class_name, Constructor constructor); + void push_back_destructor(std::string class_name, Destructor destructor); + void push_back_method(std::string class_name, Method method); + void cout(); + void update_all_applications(); + std::vector get_applications(std::string class_name, + std::string signature); + json get_simple_class(std::string class_name); + void get_all_applications(std::vector *applications); + json get_j(Application application); + std::string get_function_body(std::string class_name, std::string signature); + std::vector get_application_classes(std::string type); +}; + +class StmtVarFunctionVisitor + : public RecursiveASTVisitor { +private: + ASTContext *Context; + std::vector applications; + +public: + StmtVarFunctionVisitor(ASTContext *Context) : Context(Context) {} + bool VisitCallExpr(CallExpr *Call); + bool VisitVarDecl(VarDecl *Var); + std::vector get_applications(); +}; + +class GetClassesAndFunctions { + ClassesAndFunctions classes_and_functions; + // AllContextPaths *all_context_paths; + std::string project_path; + std::string compilation_database_path; + std::vector *file_paths; + cl::OptionCategory FocxtCategory; + +public: + GetClassesAndFunctions(std::string project_path, + std::string compilation_database_path, + std::vector *file_paths, + cl::OptionCategory FocxtCategory) + : project_path(project_path), + compilation_database_path(compilation_database_path), + file_paths(file_paths), FocxtCategory(FocxtCategory) {} + + void get_definitions(); + ClassesAndFunctions get_classes_and_functions(); +}; \ No newline at end of file diff --git a/clang-tools-extra/focxt/GetAllPath.cpp b/clang-tools-extra/focxt/GetAllPath.cpp deleted file mode 100644 index c73ada2436a6c..0000000000000 --- a/clang-tools-extra/focxt/GetAllPath.cpp +++ /dev/null @@ -1,211 +0,0 @@ -#include "GetAllPath.h" -#include "GetSignature.h" - -void AllContextPaths::append(ClassMethodandPath class_method_path) { - class_method_paths.push_back(class_method_path); -} - -void AllContextPaths::append(FunctionandPath function_path) { - function_paths.push_back(function_path); -} - -std::string AllContextPaths::getClassMethodPath(std::string class_name, - std::string signature) { - for (auto class_method_path : class_method_paths) { - if (class_method_path.class_name == class_name && - class_method_path.signature == signature) { - return class_method_path.path; - } - } -} -std::string AllContextPaths::getFunctionPath(std::string signature) { - for (auto function_path : function_paths) { - if (function_path.signature == signature) { - return function_path.path; - } - } -} - -bool AllContextPaths::hasClassMethodPath(std::string class_name, - std::string signature) { - for (auto class_method_path : class_method_paths) { - if (class_method_path.class_name == class_name && - class_method_path.signature == signature) { - return 1; - } - } - return 0; -} -bool AllContextPaths::hasFunctionPath(std::string signature) { - for (auto function_path : function_paths) { - if (function_path.signature == signature) { - return 1; - } - } - return 0; -} - -void AllContextPaths::cout() { - for (auto class_method_path : class_method_paths) { - std::cout << "Class:" << class_method_path.class_name << "\t" - << "Method:" << class_method_path.signature << "\t" - << "Path:" << class_method_path.path << std::endl; - } - for (auto function_path : function_paths) { - std::cout << "Function:" << function_path.signature << "\t" - << "Path:" << function_path.path << std::endl; - } -} - -std::pair> -AllContextPaths::getTest(std::string second_parameter) { - for (auto class_method_path : class_method_paths) { - if (class_method_path.class_name.find("Test") != std::string::npos && - class_method_path.class_name.find(second_parameter) != - std::string::npos && - class_method_path.signature.find("TestBody") != std::string::npos) { - std::pair class_function_name( - class_method_path.class_name, class_method_path.signature); - return std::pair>( - class_method_path.path, class_function_name); - } - } -} - -bool AllContextPaths::hasClass(std::string class_name) { - for (auto class_method_path : class_method_paths) { - if (class_method_path.class_name == class_name) { - return 1; - } - } - return 0; -} -std::vector> -AllContextPaths::getClassConstructor(std::string class_name) { - std::vector> ret; - for (auto class_method_path : class_method_paths) { - if (class_method_path.class_name == class_name) { - auto method_name = class_method_path.signature; - size_t end = method_name.find_first_of('('); - method_name = method_name.substr(0, end); - size_t begin = method_name.find_last_of(':'); - method_name = method_name.substr(begin + 1); - if (method_name == class_name) { - ret.push_back(std::pair( - class_method_path.signature, class_method_path.path)); - } - } - } - return ret; -} - -std::pair -AllContextPaths::getClassDestructor(std::string class_name) { - for (auto class_method_path : class_method_paths) { - if (class_method_path.class_name == class_name) { - auto method_name = class_method_path.signature; - size_t end = method_name.find_first_of('('); - method_name = method_name.substr(0, end); - size_t begin = method_name.find_last_of(':'); - method_name = method_name.substr(begin + 1); - if (method_name == "~" + class_name) { - return std::pair(class_method_path.signature, - class_method_path.path); - } - } - } - return std::pair("class", "class"); -} - -AllContextPaths *gap_context_paths; -std::string gap_project_path; - -class FunctionMethodFinder : public RecursiveASTVisitor { -public: - explicit FunctionMethodFinder(ASTContext *Context) : Context(Context) {} - - bool VisitFunctionDecl(FunctionDecl *Function) { - if (Function->isThisDeclarationADefinition()) { - clang::SourceLocation loc = Function->getLocation(); - clang::SourceManager &SM = Context->getSourceManager(); - clang::PresumedLoc presumedLoc = SM.getPresumedLoc(loc); - std::string file_path = presumedLoc.getFilename(); - if (file_path.find(gap_project_path) != std::string::npos) { - if (!isa(Function)) { - std::string signature = get_signature(Function); - if (!gap_context_paths->hasFunctionPath(signature)) { - FunctionandPath function_path; - function_path.signature = signature; - function_path.path = file_path; - gap_context_paths->append(function_path); - } - } else { - const CXXRecordDecl *ParentClass = - dyn_cast(Function->getParent()); - if (isa(Function)) { - std::string class_name = ParentClass->getNameAsString(); - std::string signature = get_signature(Function); - if (!gap_context_paths->hasClassMethodPath(class_name, signature)) { - ClassMethodandPath class_method_path; - class_method_path.class_name = class_name; - class_method_path.signature = signature; - class_method_path.path = file_path; - gap_context_paths->append(class_method_path); - } - } else if (isa(Function)) { - std::string class_name = ParentClass->getNameAsString(); - std::string signature = get_signature(Function); - if (!gap_context_paths->hasClassMethodPath(class_name, signature)) { - ClassMethodandPath class_method_path; - class_method_path.class_name = class_name; - class_method_path.signature = signature; - class_method_path.path = file_path; - gap_context_paths->append(class_method_path); - } - } else { - std::string class_name = ParentClass->getNameAsString(); - std::string signature = get_signature(Function); - if (!gap_context_paths->hasClassMethodPath(class_name, signature)) { - ClassMethodandPath class_method_path; - class_method_path.class_name = class_name; - class_method_path.signature = signature; - class_method_path.path = file_path; - gap_context_paths->append(class_method_path); - } - } - } - } - } - return true; - } - -private: - ASTContext *Context; -}; - -class FunctionMethodConsumer : public clang::ASTConsumer { -public: - explicit FunctionMethodConsumer(ASTContext *Context) : Visitor(Context) {} - - virtual void HandleTranslationUnit(clang::ASTContext &Context) { - Visitor.TraverseDecl(Context.getTranslationUnitDecl()); - } - -private: - FunctionMethodFinder Visitor; -}; - -class FunctionMethodAction : public clang::ASTFrontendAction { -public: - virtual std::unique_ptr - CreateASTConsumer(clang::CompilerInstance &Compiler, llvm::StringRef InFile) { - return std::make_unique(&Compiler.getASTContext()); - } -}; - -void get_all_paths(ClangTool &Tool, AllContextPaths *all_context_paths, - std::string project_path) { - gap_context_paths = all_context_paths; - gap_project_path = project_path; - Tool.run(newFrontendActionFactory().get()); -} \ No newline at end of file diff --git a/clang-tools-extra/focxt/GetAllPath.h b/clang-tools-extra/focxt/GetAllPath.h deleted file mode 100644 index 1297b632a5e1f..0000000000000 --- a/clang-tools-extra/focxt/GetAllPath.h +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once -#include "clang/AST/ASTConsumer.h" -#include "clang/AST/RecursiveASTVisitor.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/FrontendAction.h" -#include "clang/Frontend/FrontendActions.h" -#include "clang/Lex/Lexer.h" -#include "clang/Tooling/CommonOptionsParser.h" -#include "clang/Tooling/Tooling.h" -#include "llvm/Support/CommandLine.h" -#include -#include -#include -#include -#include -#include -#include -#include - -namespace fs = std::filesystem; -using namespace clang; -using namespace clang::tooling; -using namespace llvm; - -struct ClassMethodandPath { - std::string class_name; - std::string signature; - std::string path; -}; - -struct FunctionandPath { - std::string signature; - std::string path; -}; - -class AllContextPaths { - std::vector class_method_paths; - std::vector function_paths; - -public: - void append(ClassMethodandPath class_method_path); - void append(FunctionandPath function_path); - std::string getClassMethodPath(std::string class_name, std::string signature); - std::string getFunctionPath(std::string signature); - bool hasClassMethodPath(std::string class_name, std::string signature); - bool hasFunctionPath(std::string signature); - void cout(); - std::pair> - getTest(std::string second_parameter); - bool hasClass(std::string class_name); - std::vector> - getClassConstructor(std::string class_name); - std::pair - getClassDestructor(std::string class_name); -}; - -void get_all_paths(ClangTool &Tool, AllContextPaths *all_context_paths, - std::string project_path); \ No newline at end of file diff --git a/clang-tools-extra/focxt/GetSignature.cpp b/clang-tools-extra/focxt/GetSignature.cpp old mode 100644 new mode 100755 index b8e8245a9bb98..1676f2657e1ed --- a/clang-tools-extra/focxt/GetSignature.cpp +++ b/clang-tools-extra/focxt/GetSignature.cpp @@ -1,13 +1,55 @@ #include "GetSignature.h" +// std::string get_application_type(QualType qualtype) { +// auto tp = qualtype.getTypePtrOrNull(); +// if (tp->getAsTagDecl()) { +// auto tag_decl = tp->getAsTagDecl()->getCanonicalDecl(); +// if (dyn_cast(tag_decl)) { +// auto record_decl = +// dyn_cast(tag_decl)->getCanonicalDecl(); if +// (record_decl->getDescribedClassTemplate()) { +// auto template_decl = +// record_decl->getDescribedClassTemplate()->getCanonicalDecl(); +// std::string return_string = template_decl->getNameAsString(); +// if (return_string.find(" ") != std::string::npos) { +// return_string.erase(0, return_string.find_last_of(" ") + 1); +// } +// return return_string; +// } +// // return record_decl->getNameAsString(); +// std::string return_string = record_decl->getNameAsString(); +// if (return_string.find(" ") != std::string::npos) { +// return_string.erase(0, return_string.find_last_of(" ") + 1); +// } +// return return_string; +// } +// // return tag_decl->getNameAsString(); +// std::string return_string = tag_decl->getNameAsString(); +// if (return_string.find(" ") != std::string::npos) { +// return_string.erase(0, return_string.find_last_of(" ") + 1); +// } +// return return_string; +// } +// // return qualtype.getAsString(); +// std::string return_string = qualtype.getAsString(); +// if (return_string.find(" ") != std::string::npos) { +// return_string.erase(0, return_string.find_last_of(" ") + 1); +// } +// return return_string; +// } + std::string get_signature(const FunctionDecl *function) { - function = function->getCanonicalDecl(); + // if (function->getPrimaryTemplate()) { + // function = function->getPrimaryTemplate()->getTemplatedDecl(); + // } + auto functiondecl = function->getCanonicalDecl(); + // function->dump(); std::string signature; - if (!isa(function)) { - signature = function->getReturnType().getAsString() + " "; - signature = signature + function->getNameAsString() + "("; + if (!isa(functiondecl)) { + signature = functiondecl->getReturnType().getAsString() + " "; + signature = signature + functiondecl->getNameAsString() + "("; int i = 0; - for (const ParmVarDecl *param : function->parameters()) { + for (const ParmVarDecl *param : functiondecl->parameters()) { if (i > 0) { signature = signature + ", "; } @@ -17,12 +59,18 @@ std::string get_signature(const FunctionDecl *function) { signature = signature + ")"; } else { const CXXRecordDecl *ParentClass = - dyn_cast(function->getParent()); - if (isa(function)) { + dyn_cast(functiondecl->getParent())->getCanonicalDecl(); + // ParentClass->dump(); + // if (isa(ParentClass)) { + // dyn_cast(ParentClass) + // ->getTemplatedDecl() + // ->dump(); + // } + if (isa(functiondecl)) { signature = signature + ParentClass->getNameAsString() + - "::" + function->getNameAsString() + "("; + "::" + functiondecl->getNameAsString() + "("; int i = 0; - for (const ParmVarDecl *param : function->parameters()) { + for (const ParmVarDecl *param : functiondecl->parameters()) { if (i > 0) { signature = signature + ", "; } @@ -30,11 +78,11 @@ std::string get_signature(const FunctionDecl *function) { i++; } signature = signature + ")"; - } else if (isa(function)) { + } else if (isa(functiondecl)) { signature = signature + ParentClass->getNameAsString() + - "::" + function->getNameAsString() + "("; + "::" + functiondecl->getNameAsString() + "("; int i = 0; - for (const ParmVarDecl *param : function->parameters()) { + for (const ParmVarDecl *param : functiondecl->parameters()) { if (i > 0) { signature = signature + ", "; } @@ -43,11 +91,11 @@ std::string get_signature(const FunctionDecl *function) { } signature = signature + ")"; } else { - signature = function->getReturnType().getAsString() + " "; + signature = functiondecl->getReturnType().getAsString() + " "; signature = signature + ParentClass->getNameAsString() + - "::" + function->getNameAsString() + "("; + "::" + functiondecl->getNameAsString() + "("; int i = 0; - for (const ParmVarDecl *param : function->parameters()) { + for (const ParmVarDecl *param : functiondecl->parameters()) { if (i > 0) { signature = signature + ", "; } @@ -59,4 +107,49 @@ std::string get_signature(const FunctionDecl *function) { } // std::cout << signature << std::endl; return signature; -} \ No newline at end of file +} + +// void get_application_types(QualType qualtype, std::set &types) { +// qualtype = qualtype.getUnqualifiedType(); +// std::cout << qualtype.getAsString() << std::endl; +// auto type = qualtype.getTypePtrOrNull(); +// if (!type) { +// return; +// } +// // Directly dealing with built-in and referencing the record types +// if (type->isBuiltinType()) { +// types.insert(qualtype.getAsString()); +// return; +// } else if (const auto *recordType = type->getAs()) { +// types.insert(recordType->getDecl()->getNameAsString()); +// return; +// } else if (const auto *enumType = type->getAs()) { +// types.insert(enumType->getDecl()->getNameAsString()); +// return; +// } +// // Dealing with pointers and references (unwrapping them) +// if (type->isPointerType() || type->isReferenceType()) { +// get_application_types(qualtype->getPointeeType(), types); +// } else if (auto arrayType = dyn_cast(type)) { +// get_application_types(arrayType->getElementType(), types); +// // get_application_types(arrayType->getElementType(), types); +// } + +// // Specifying the template types +// if (const auto *templateSpecializationType = +// dyn_cast(type)) { +// types.insert(templateSpecializationType->getTemplateName() +// .getAsTemplateDecl() +// ->getNameAsString()); +// for (const auto &arg : templateSpecializationType->template_arguments()) +// { +// if (arg.getKind() == TemplateArgument::Type) { +// get_application_types(arg.getAsType(), types); +// } +// } +// } + +// // if (qualtype.isConstQualified()) { +// // get_application_types(qualtype.getLocalUnqualifiedType(), types); +// // } +// } \ No newline at end of file diff --git a/clang-tools-extra/focxt/GetSignature.h b/clang-tools-extra/focxt/GetSignature.h old mode 100644 new mode 100755 index e14fda42cc388..2dadfee09c2fe --- a/clang-tools-extra/focxt/GetSignature.h +++ b/clang-tools-extra/focxt/GetSignature.h @@ -23,4 +23,6 @@ using namespace clang::ast_matchers; using namespace clang::tooling; using namespace llvm; -std::string get_signature(const FunctionDecl *function); \ No newline at end of file +// std::string get_application_type(QualType qualtype); +std::string get_signature(const FunctionDecl *function); +// void get_application_types(QualType qualtype, std::set &types); \ No newline at end of file diff --git a/clang-tools-extra/focxt/README.md b/clang-tools-extra/focxt/README.md old mode 100644 new mode 100755 index 988fe6c7bd426..3f97f7ce45d89 --- a/clang-tools-extra/focxt/README.md +++ b/clang-tools-extra/focxt/README.md @@ -77,20 +77,20 @@ focxt options: ###### 安装依赖,包括: -C/C++编译工具,如gcc或clang +```C/C++编译工具,如gcc或clang CMake -Ninja +Ninja``` ###### 克隆并进入该项目 -git clone https://github.com/cppbear/llvm-project.git && cd llvm-project +```git clone https://github.com/cppbear/llvm-project.git && cd llvm-project``` ###### 配置CMake -cmake -S llvm -B build -G Ninja -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD=host -DLLVM_ENABLE_DUMP=ON +```cmake -S llvm -B build -G Ninja -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD=host -DLLVM_ENABLE_DUMP=ON``` ###### 构建并安装 -cmake --build build --target focxt -cmake --install build --component focxt -cmake --install build --component clang-resource-headers +```cmake --build build --target focxt``` +```cmake --install build --component focxt``` +```cmake --install build --component clang-resource-headers```