diff --git a/clang-tools-extra/focxt/CMakeLists.txt b/clang-tools-extra/focxt/CMakeLists.txt index 35c8a51764925..92385533f68e2 100755 --- a/clang-tools-extra/focxt/CMakeLists.txt +++ b/clang-tools-extra/focxt/CMakeLists.txt @@ -1,5 +1,5 @@ set(LLVM_LINK_COMPONENTS support) -set(CMAKE_BUILD_TYPE Debug) +# set(CMAKE_BUILD_TYPE Debug) include(FetchContent) diff --git a/clang-tools-extra/focxt/Focxt.cpp b/clang-tools-extra/focxt/Focxt.cpp index bbcc7802cd425..485a9af7890e3 100755 --- a/clang-tools-extra/focxt/Focxt.cpp +++ b/clang-tools-extra/focxt/Focxt.cpp @@ -79,14 +79,14 @@ void get_all_files(std::string path, std::vector *file_paths) { // && // 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 - ) { + // 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 && + directorty_entry.find("/vendor") == std::string::npos) { get_all_files(entry.path(), file_paths); } } @@ -131,6 +131,7 @@ int main(int argc, const char **argv) { // freopen(output_path.c_str(), "w", stdout); // classes_and_functions.cout(); // freopen("/dev/tty", "w", stdout); + classes_and_functions.cout_nums(); GetFileContext get_file_context(RealProjectPath, RealBuildPath, file_paths, FocxtCategory, classes_and_functions); get_file_context.get_all_file_contexts(); @@ -175,63 +176,63 @@ int main(int argc, const char **argv) { 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(); - // } + else { + std::string json_path = RealProjectPath; + std::string class_function_name; + if (RealClassName == "") { + class_function_name = 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; diff --git a/clang-tools-extra/focxt/GetAllContext.cpp b/clang-tools-extra/focxt/GetAllContext.cpp index 79895fe2e7357..3d72d3f93b409 100755 --- a/clang-tools-extra/focxt/GetAllContext.cpp +++ b/clang-tools-extra/focxt/GetAllContext.cpp @@ -841,10 +841,13 @@ json FileContext::get_j(bool test_flag) { json j; json file_j = get_file_j(); j[file_path] = json::object(); + std::cout << file_path << std::endl; for (auto function : functions) { // if (function.function_name == "main") { // std::cout << std::endl; // } + // std::cout << function.class_name << "\t" << function.function_name + // << std::endl; std::string class_function; if (function.class_name != "class") { class_function = function.class_name + "::" + function.function_name; @@ -924,6 +927,7 @@ void FileContexts::push_back(FileContext file_context) { } json FileContexts::get_j(bool test_flag) { + std::cout << "generate json" << std::endl; json j; for (auto file_context : file_contexts) { j.merge_patch(file_context.get_j(test_flag)); @@ -1178,6 +1182,7 @@ 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::cout << file_path << std::endl; std::vector args{"file_context", "-p", compilation_database_path.c_str(), file_path.c_str()}; diff --git a/clang-tools-extra/focxt/GetAllDefinition.cpp b/clang-tools-extra/focxt/GetAllDefinition.cpp index c0d79b35ed267..9c5be13342122 100755 --- a/clang-tools-extra/focxt/GetAllDefinition.cpp +++ b/clang-tools-extra/focxt/GetAllDefinition.cpp @@ -423,6 +423,11 @@ void ClassesAndFunctions::cout() { // } } +void ClassesAndFunctions::cout_nums() { + std::cout << "there are " << classes.size() << " classes" << std::endl; + std::cout << "there are " << functions.size() << " functions" << std::endl; +} + std::vector ClassesAndFunctions::get_application_classes(std::string type) { std::vector application_classes; @@ -532,6 +537,7 @@ void update_applications(std::vector &applications) { } void ClassesAndFunctions::update_all_applications() { + std::cout << "update all applications" << std::endl; for (auto &a_class : classes) { update_applications(a_class.applications); for (auto &constructor : a_class.constructors) { @@ -4586,7 +4592,7 @@ class FindClassesAndFunctionsAction : public clang::ASTFrontendAction { void GetClassesAndFunctions::get_definitions() { gad_project_path = project_path; for (auto file_path : *file_paths) { - // std::cout << file_path << std::endl; + std::cout << file_path << std::endl; std::vector args{"context_path", "-p", compilation_database_path.c_str(), file_path.c_str()}; diff --git a/clang-tools-extra/focxt/GetAllDefinition.h b/clang-tools-extra/focxt/GetAllDefinition.h index b834d5e2a2ce0..27575bb6273a3 100755 --- a/clang-tools-extra/focxt/GetAllDefinition.h +++ b/clang-tools-extra/focxt/GetAllDefinition.h @@ -302,6 +302,7 @@ class ClassesAndFunctions { void push_back_destructor(std::string class_name, Destructor destructor); void push_back_method(std::string class_name, Method method); void cout(); + void cout_nums(); void update_all_applications(); std::vector get_applications(std::string class_name, std::string signature); diff --git a/clang-tools-extra/focxt/README.md b/clang-tools-extra/focxt/README.md index 3f97f7ce45d89..91a74a1f18e71 100755 --- a/clang-tools-extra/focxt/README.md +++ b/clang-tools-extra/focxt/README.md @@ -1,16 +1,16 @@ -##### Focxt +# Focxt -该工具用于分析c++源代码每个函数的上下文信息。 +该工具用于分析 c++源代码每个函数的上下文信息。 -##### 前提 +## 前提 -使用该工具首先需要被分析项目具有类似compile_commands.json的编译数据库。 +使用该工具首先需要被分析项目具有类似 compile_commands.json 的编译数据库。 -如果被分析项目本身使用CMake管理构建,可以通过在配置CMake时添加-DCMAKE_EXPORT_COMPILE_COMMANDS=ON来生成。 +如果被分析项目本身使用 CMake 管理构建,可以通过在配置 CMake 时添加-DCMAKE_EXPORT_COMPILE_COMMANDS=ON 来生成。 -如果项目本身不使用CMake管理构建,可以考虑使用Bear来生成。 +如果项目本身不使用 CMake 管理构建,可以考虑使用 Bear 来生成。 -##### 使用 +## 使用 ```shell /usr/local/bin/focxt --help @@ -42,55 +42,49 @@ focxt options: --class= - Specify the class to analyze --file= - Specify the file to analyze --function= - Specify the function to analyze - --may-test - Specify get may test - --must-test= - Specify must test second parameters --project= - Specify the projrct path ``` -##### 用法 +## 用法 -###### 分析整个项目 +### 分析整个项目 ``` -./focxt --project path/to/project --build path/to/build/directory {--may-test} +./focxt --project path/to/project --build path/to/build/directory ``` -​ 其中--may-test是一个开关,搜索可能的测试函数,由于TEST(TestSuiteName, TestName) { }会被展开为class TestSuiteName_TestName_Test,所以会搜索项目中TestName包含函数名的TEST宏和宏展开后的类。 - -###### 分析整个文件 +### 分析整个文件 ``` -./focxt --project path/to/project --build path/to/build/directory --file path/to/source_file {--may-test} +./focxt --project path/to/project --build path/to/build/directory --file path/to/source_file ``` -###### 分析某个函数或方法 +### 分析某个函数或方法 ``` -./focxt --project path/to/project --build path/to/build/directory --file path/to/source_file --class class_name --function function_name {--may-test {--must-test TEST_second_parameter} {--must-test TEST_second_parameter} ..} +./focxt --project path/to/project --build path/to/build/directory --file path/to/source_file --class class_name --function function_name ``` -​ 其中--must-test需要输入的是TEST宏的第二个参数,开启--may-test后,才能够通过--must-test手动指定测试函数。 - -最终结果以*_cxt.json存储在path/to/project目录中。 - -##### 构建 - -###### 安装依赖,包括: +分析类的方法时需要传入 class_name 和 function_name;分析函数时不用传入 class_name,只用传入 function_name 就可以。 -```C/C++编译工具,如gcc或clang -CMake -Ninja``` +## 构建 -###### 克隆并进入该项目 +1. 安装依赖,包括: -```git clone https://github.com/cppbear/llvm-project.git && cd llvm-project``` + 1. C/C++编译工具,如`gcc`或`clang` + 2. `CMake` + 3. `Ninja` -###### 配置CMake +2. 配置 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 + ``` -###### 构建并安装 +3. 构建并安装 -```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 + ```