diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5f30dd81..f85d6225 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -549,6 +549,7 @@ jobs: - name: Run tests if: matrix.config.run_tests == 'Yes' + shell: bash id: run_tests run: | cmake --build build --target tests diff --git a/CMakeLists.txt b/CMakeLists.txt index 5cd489e8..9f947177 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -656,7 +656,8 @@ else() ${CMAKE_CURRENT_BINARY_DIR}/$ --cxx ${CMAKE_CXX_COMPILER} ${TEST_FAILURE_IS_OK} ${TEST_USE_LIBCPP} ${LLVM_PROF_DIR} COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/testSTDIN.sh ${CMAKE_CURRENT_BINARY_DIR}/$ COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/testInvalidOption.sh ${CMAKE_CURRENT_BINARY_DIR}/$ - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/$ ${CMAKE_CURRENT_SOURCE_DIR}/tests/runTest.py + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/shell/test-bash-completion.sh ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/tests/shell ${CMAKE_CURRENT_SOURCE_DIR}/scripts/bash-autocomplete.sh ${TEST_FAILURE_IS_OK} + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/$ ${CMAKE_CURRENT_SOURCE_DIR}/tests/runTest.py ${CMAKE_CURRENT_SOURCE_DIR}/tests/shell/test-bash-completion.sh WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests COMMENT "Running tests" VERBATIM ) @@ -667,7 +668,8 @@ if (NOT WIN32) COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/runTest.py --insights ${CMAKE_CURRENT_BINARY_DIR}/insights --cxx ${CMAKE_CXX_COMPILER} --update-tests ${TEST_FAILURE_IS_OK} COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/testSTDIN.sh ${CMAKE_CURRENT_BINARY_DIR}/insights COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/testInvalidOption.sh ${CMAKE_CURRENT_BINARY_DIR}/insights - DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/insights ${CMAKE_CURRENT_SOURCE_DIR}/tests/runTest.py + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/tests/shell/test-bash-completion.sh ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/tests/shell ${CMAKE_CURRENT_SOURCE_DIR}/scripts/bash-autocomplete.sh + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/insights ${CMAKE_CURRENT_SOURCE_DIR}/tests/runTest.py ${CMAKE_CURRENT_SOURCE_DIR}/tests/shell/test-bash-completion.sh WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tests COMMENT "Running tests" VERBATIM ) diff --git a/Insights.cpp b/Insights.cpp index 4f57e7c5..b6f9976d 100644 --- a/Insights.cpp +++ b/Insights.cpp @@ -55,16 +55,6 @@ static llvm::cl::OptionCategory gInsightEduCategory( "This transformations are only for education purposes. The resulting code most likely does not compile."sv); //----------------------------------------------------------------------------- -static llvm::cl::opt gStdinMode("stdin", - llvm::cl::desc("Read the input from ."sv), - llvm::cl::init(false), - llvm::cl::cat(gInsightCategory)); -//----------------------------------------------------------------------------- - -static llvm::cl::opt - gUseLibCpp("use-libc++", llvm::cl::desc("Use libc++."sv), llvm::cl::init(false), llvm::cl::cat(gInsightCategory)); -//----------------------------------------------------------------------------- - #define INSIGHTS_OPT(option, name, deflt, description, category) \ static llvm::cl::opt g##name(option, \ llvm::cl::desc(std::string_view{description}), \ @@ -397,7 +387,17 @@ extern struct __mptr* __vtbl_array[]; auto opExpected = CommonOptionsParser::create(argc, argv, gInsightCategory); if(auto err = opExpected.takeError()) { - llvm::errs() << toString(std::move(err)) << "\n"; + if(gAutoComplete) { +#define INSIGHTS_OPT(option, name, deflt, description, category) llvm::outs() << "--" << option << " "; + +#include "InsightsOptions.def" + + return 0; + } else { + + llvm::errs() << toString(std::move(err)) << "\n"; + } + return 1; } diff --git a/InsightsOptions.def b/InsightsOptions.def index b2a857af..1832d9d4 100644 --- a/InsightsOptions.def +++ b/InsightsOptions.def @@ -31,4 +31,9 @@ INSIGHTS_OPT("edu-show-coroutine-transformation", gInsightEduCategory) INSIGHTS_OPT("edu-show-cfront", UseShow2C, false, "Show transformation to C", gInsightEduCategory) INSIGHTS_OPT("edu-show-lifetime", ShowLifetime, false, "Show lifetime of objects", gInsightEduCategory) + +INSIGHTS_OPT("stdin", StdinMode, false, "Read the input from .", gInsightCategory) +INSIGHTS_OPT("use-libc++", UseLibCpp, false, "Use libc++ (LLVM) instead of libstdc++ (GNU).", gInsightCategory) +INSIGHTS_OPT("autocomplete", AutoComplete, false, "Generate list of options for autocomplete and exit.", gInsightCategory) + #undef INSIGHTS_OPT diff --git a/Readme.md b/Readme.md index bff3124c..9ff81339 100644 --- a/Readme.md +++ b/Readme.md @@ -263,6 +263,16 @@ At least for macOS, you can install C++ Insights via Homebrew thanks to [this fo brew install cppinsights ``` +## Bash autocomplete + +There is a bash autocomplete script. It autocompletes the C++ Insights options as well as the Clang options provided after `--`. +You can download it with the following commands: + +``` +cd +curl -o insights https://github.com/andreasfertig/cppinsights/tree/main/scripts/bash-autocomplete.sh +``` + ## Compatibility diff --git a/docs/CommandLineOptions.md b/docs/CommandLineOptions.md index 768fa87c..1975e7be 100644 --- a/docs/CommandLineOptions.md +++ b/docs/CommandLineOptions.md @@ -2,6 +2,7 @@ * [alt-syntax-for](@ref alt_syntax_for) * [alt-syntax-subscription](@ref alt_syntax_subscription) +* [autocomplete](@ref autocomplete) * [edu-show-cfront](@ref edu_show_cfront) * [edu-show-coroutine-transformation](@ref edu_show_coroutine_transformation) * [edu-show-initlist](@ref edu_show_initlist) @@ -10,3 +11,5 @@ * [edu-show-padding](@ref edu_show_padding) * [show-all-callexpr-template-parameters](@ref show_all_callexpr_template_parameters) * [show-all-implicit-casts](@ref show_all_implicit_casts) +* [stdin](@ref stdin) +* [use-libc++](@ref use_libc++) diff --git a/docs/cmdl-examples/autocomplete.cpp b/docs/cmdl-examples/autocomplete.cpp new file mode 100644 index 00000000..7482c809 --- /dev/null +++ b/docs/cmdl-examples/autocomplete.cpp @@ -0,0 +1 @@ +// Just prints out all the C++ Insights options. diff --git a/docs/cmdl-examples/edu-show-cfront.cpp b/docs/cmdl-examples/edu-show-cfront.cpp index 43346e8a..27ae9da8 100644 --- a/docs/cmdl-examples/edu-show-cfront.cpp +++ b/docs/cmdl-examples/edu-show-cfront.cpp @@ -1,5 +1,3 @@ -// cmdlineinsights:-edu-show-cfront - #include class A diff --git a/docs/cmdl-examples/edu-show-coroutine-transformation.cpp b/docs/cmdl-examples/edu-show-coroutine-transformation.cpp index 86767b8e..cdc7a003 100644 --- a/docs/cmdl-examples/edu-show-coroutine-transformation.cpp +++ b/docs/cmdl-examples/edu-show-coroutine-transformation.cpp @@ -1,18 +1,8 @@ -#if __has_include() #include -#elif __has_include() -#include - -namespace std { -using namespace std::experimental; -} -#else -#error "No coroutine header" -#endif - #include #include #include +#include struct generator { @@ -35,7 +25,7 @@ struct generator generator(generator const&) = delete; generator(generator&& rhs) - : p{std::exchange(rhs.p, nullptr)} + : handle{std::exchange(rhs.handle, nullptr)} { } diff --git a/docs/cmdl-examples/stdin.cpp b/docs/cmdl-examples/stdin.cpp new file mode 100644 index 00000000..e17f4f2f --- /dev/null +++ b/docs/cmdl-examples/stdin.cpp @@ -0,0 +1,4 @@ +int main() +{ + // Nothing going on here. +} diff --git a/docs/cmdl-examples/use-libc++.cpp b/docs/cmdl-examples/use-libc++.cpp new file mode 100644 index 00000000..809bac40 --- /dev/null +++ b/docs/cmdl-examples/use-libc++.cpp @@ -0,0 +1,9 @@ +#include + +int main() +{ + const std::string s{"Hello"}; + + for(const auto& e : s) { + } +} diff --git a/docs/examples/auto-uniform-initialization-and-the-equal-sign.md b/docs/examples/auto-uniform-initialization-and-the-equal-sign.md index afae08de..3362ec2a 100644 --- a/docs/examples/auto-uniform-initialization-and-the-equal-sign.md +++ b/docs/examples/auto-uniform-initialization-and-the-equal-sign.md @@ -29,7 +29,6 @@ int main() return 0; } - ``` [Live view](https://cppinsights.io/lnk?code=I2luY2x1ZGUgPGluaXRpYWxpemVyX2xpc3Q+CgppbnQgbWFpbigpCnsKICAgIGF1dG8gaSA9IDM7ICAgICAgIC8vIGludAogICAgYXV0byBhID0gezQyfTsgICAgLy8gaW5pdGlhbGl6ZXIgbGlzdAogICAgYXV0byBiezQyfTsgICAgICAgLy8gaW50CiAgICBhdXRvIGMgPSB7MSwgMn07ICAvLyBpbml0aWFsaXplciBsaXN0Cn0=&insightsOptions=cpp2a&rev=1.0) diff --git a/docs/examples/auto.md b/docs/examples/auto.md index a54859b7..f809a259 100644 --- a/docs/examples/auto.md +++ b/docs/examples/auto.md @@ -77,41 +77,35 @@ class CTest }; - int Test() { return 1; } - int Best() { return 1; } - inline constexpr int CEBest() { return 1; } - char West() { return 'c'; } - inline constexpr char CEWest() { return 'c'; } [[maybe_unused]] inline constexpr char MUCEWest() - { - return 'c'; - } - +{ + return 'c'; +} int main() { @@ -137,7 +131,6 @@ int main() return 0; } - ``` [Live view](https://cppinsights.io/lnk?code=Y2xhc3MgQ1Rlc3QKewogICAgYXV0byBUZXN0KCkgeyByZXR1cm4gMjI7IH0KfTsKCmF1dG8gVGVzdCgpCnsKICAgIHJldHVybiAxOwp9CgphdXRvIEJlc3QoKSAtPiBpbnQKewogICAgcmV0dXJuIDE7Cn0KCmNvbnN0ZXhwciBhdXRvIENFQmVzdCgpIC0+IGludAp7CiAgICByZXR1cm4gMTsKfQoKZGVjbHR5cGUoYXV0bykgV2VzdCgpCnsKICAgIHJldHVybiAnYyc7Cn0KCmNvbnN0ZXhwciBkZWNsdHlwZShhdXRvKSBDRVdlc3QoKQp7CiAgICByZXR1cm4gJ2MnOwp9CgpbW21heWJlX3VudXNlZF1dIGlubGluZSBjb25zdGV4cHIgZGVjbHR5cGUoYXV0bykgTVVDRVdlc3QoKQp7CiAgICByZXR1cm4gJ2MnOwp9CgppbnQgbWFpbigpCnsKICAgIGludCAgICAgICAgICAgIHggPSAyOwogICAgY29uc3QgY2hhciogICAgcDsKICAgIGNvbnN0ZXhwciBhdXRvIGNlaSAgICAgICA9IDA7CiAgICBhdXRvIGNvbnN0ZXhwciBjZWkyICAgICAgPSAwOwogICAgYXV0byAgICAgICAgICAgICAgICAgaSAgID0gMDsKICAgIGRlY2x0eXBlKGF1dG8pICAgICAgIHhYICA9IChpKTsKICAgIGF1dG8gICAgICAgICAgICAgICAgIGlpICA9ICZpOwogICAgYXV0byYgICAgICAgICAgICAgICAgaXIgID0gaTsKICAgIGF1dG8qICAgICAgICAgICAgICAgIGlwICA9ICZpOwogICAgY29uc3QgYXV0byogICAgICAgICAgY2lwID0gJmk7CiAgICBhdXRvKiAgICAgICAgICAgICAgICBwcCAgPSBwOwogICAgY29uc3QgYXV0byogICAgICAgICAgY3AgID0gcDsKICAgIHZvbGF0aWxlIGNvbnN0IGF1dG8qIHZjcCA9IHA7CiAgICBhdXRvICAgICAgICAgICAgICAgICBmICAgPSAxLjBmOwogICAgYXV0byAgICAgICAgICAgICAgICAgYyAgID0gJ2MnOwogICAgYXV0byAgICAgICAgICAgICAgICAgdSAgID0gMHU7CiAgICBkZWNsdHlwZSh1KSAgICAgICAgICB1dSAgPSB1OwoKICAgIFtbbWF5YmVfdW51c2VkXV0gYXV0byAgICAgICAgbXUgID0gMHU7CiAgICBbW21heWJlX3VudXNlZF1dIGRlY2x0eXBlKHUpIG11dSA9IHU7Cn0=&insightsOptions=cpp2a&rev=1.0) diff --git a/docs/examples/braced-array-initialization.md b/docs/examples/braced-array-initialization.md index 20d4f781..fdd574d8 100644 --- a/docs/examples/braced-array-initialization.md +++ b/docs/examples/braced-array-initialization.md @@ -21,7 +21,6 @@ int main() return 0; } - ``` [Live view](https://cppinsights.io/lnk?code=aW50IG1haW4oKQp7CiAgICAvLyBUaGUgY29tcGlsZXIgYXV0b21hdGljYWxseSBmaWxscyB0aGUgcmVtYWluaW5nCiAgICAvLyBmaWVsZHMgd2l0aCAwIHRoYW5rcyB0byBicmFjZWQgaW5pdGlhbGl6YXRpb24uCiAgICBpbnQgYXJyWzVdezIsIDMsIDR9Owp9&insightsOptions=cpp2a&rev=1.0) diff --git a/docs/examples/braced-return-value-and-decltype-auto.md b/docs/examples/braced-return-value-and-decltype-auto.md index 768d89cf..ac7c68d7 100644 --- a/docs/examples/braced-return-value-and-decltype-auto.md +++ b/docs/examples/braced-return-value-and-decltype-auto.md @@ -21,7 +21,6 @@ int & Bar() return (x); } - ``` [Live view](https://cppinsights.io/lnk?code=ZGVjbHR5cGUoYXV0bykgQmFyKCkKewogICAgaW50IHggPSAyMjsKICAgIC8vIGRvIHNvbWUgZmFuY3kgY2FsY3VsYXRpb24gd2l0aCB4CiAgICByZXR1cm4gKHgpOwp9&insightsOptions=cpp2a&rev=1.0) diff --git a/docs/examples/braced-uniform-initialization.md b/docs/examples/braced-uniform-initialization.md index ce078c46..87e30a58 100644 --- a/docs/examples/braced-uniform-initialization.md +++ b/docs/examples/braced-uniform-initialization.md @@ -48,7 +48,6 @@ struct A }; - struct B { int i; @@ -57,7 +56,6 @@ struct B }; - int main() { A a = A(); @@ -67,7 +65,6 @@ int main() return 0; } - ``` [Live view](https://cppinsights.io/lnk?code=c3RydWN0IEEKewogICAgLy8gdXNlciBwcm92aWRlZCBjb25zdHJ1Y3RvciBfbWlzc2luZ18gaW5pdGlhbGl6YXRpb24gb2YgYGpgCiAgICBBKCkKICAgIDogaXszfQogICAgewogICAgfQoKICAgIGludCBpOwogICAgaW50IGo7Cn07CgpzdHJ1Y3QgQgp7CiAgICAvLyB1c2VzIHRoZSBkZWZhdWx0IGNvbnN0cnVjdG9yCiAgICBpbnQgaTsKICAgIGludCBqOwp9OwoKaW50IG1haW4oKQp7CiAgICBBIGE7CiAgICBBIGEye307ICAvLyBvbmx5IGkgZ2V0cyBpbml0aWFsaXplZC4KCiAgICBCIGI7CiAgICBCIGIye307ICAvLyBib3RoIGkgYW5kIGogZ2V0IGluaXRpYWxpemVkLgp9&insightsOptions=cpp2a&rev=1.0) diff --git a/docs/examples/generic-lambda.md b/docs/examples/generic-lambda.md index b55f620b..e32be842 100644 --- a/docs/examples/generic-lambda.md +++ b/docs/examples/generic-lambda.md @@ -61,7 +61,6 @@ int main() return 0; } - ``` [Live view](https://cppinsights.io/lnk?code=aW50IG1haW4oKQp7CiAgICAvLyBHZW5lcmljIGxhbWJkYXMgaGF2ZSBhIG1ldGhvZCB0ZW1wbGF0ZSBjYWxsIG9wZXJhdG9yLgogICAgYXV0byB4ID0gW10oYXV0byB4KSB7IHJldHVybiB4ICogeDsgfTsKCiAgICB4KDIpOyAgICAvLyBpbnQKICAgIHgoMy4wKTsgIC8vIGRvdWJsZQp9&insightsOptions=cpp2a&rev=1.0) diff --git a/docs/examples/implicit-conversions.md b/docs/examples/implicit-conversions.md index d9530b36..e0dae9a3 100644 --- a/docs/examples/implicit-conversions.md +++ b/docs/examples/implicit-conversions.md @@ -38,6 +38,7 @@ int main() Here is the transformed code: ```{.cpp} #include + template class X { @@ -106,7 +107,6 @@ class X #endif - int main() { X arr[2] = {X{}, X{}}; @@ -122,7 +122,6 @@ int main() return 0; } - ``` [Live view](https://cppinsights.io/lnk?code=I2luY2x1ZGUgPGNzdGRpbz4KdGVtcGxhdGU8dHlwZW5hbWUgVT4KY2xhc3MgWAp7CnB1YmxpYzoKICAgIFgoKSAgICAgICAgICAgPSBkZWZhdWx0OwogICAgWChjb25zdCBYJiB4KSA9IGRlZmF1bHQ7CgogICAgdGVtcGxhdGU8dHlwZW5hbWUgVD4KICAgIFgoVCYmIHgpCiAgICA6IG1Ye30KICAgIHsKICAgIH0KCnByaXZhdGU6CiAgICBVIG1YOwp9OwoKaW50IG1haW4oKQp7CiAgICBYPGludD4gYXJyWzJde307CgogICAgLy8gV2UgdXNlIFg8Y29uc3QgaW50PiBpbnN0ZWFkIG9mIFg8aW50PiBoZXJlLiBUaGlzIHJlc3VsdHMKICAgIC8vIGluIGEgY29uc3RydWN0b3IgY2FsbCB0byBjcmVhdGUgYSBYPGNvbnN0IGludD4gb2JqZWN0IGFzCiAgICAvLyB5b3UgY2FuIHNlZSBpbiB0aGUgdHJhbnNmb3JtYXRpb24uCiAgICBmb3IoY29uc3QgWDxjb25zdCBpbnQ+JiB4IDogYXJyKSB7CiAgICB9Cn0=&insightsOptions=cpp2a&rev=1.0) diff --git a/docs/examples/lambda-with-static-invoke.md b/docs/examples/lambda-with-static-invoke.md index 04bc9089..fc43138a 100644 --- a/docs/examples/lambda-with-static-invoke.md +++ b/docs/examples/lambda-with-static-invoke.md @@ -44,7 +44,6 @@ int main() return 0; } - ``` [Live view](https://cppinsights.io/lnk?code=aW50IG1haW4oKQp7CiAgICBpbnQgKCpmcCkoaW50LCBjaGFyKSA9IFtdKGludCBhLCBjaGFyIGIpIHsgcmV0dXJuIGEgKyBiOyB9Owp9&insightsOptions=cpp2a&rev=1.0) diff --git a/docs/examples/range-based-for-loop.md b/docs/examples/range-based-for-loop.md index 3309a038..f699c77d 100644 --- a/docs/examples/range-based-for-loop.md +++ b/docs/examples/range-based-for-loop.md @@ -37,7 +37,6 @@ int main() return 0; } - ``` [Live view](https://cppinsights.io/lnk?code=I2luY2x1ZGUgPGNzdGRpbz4KCmludCBtYWluKCkKewogICAgY29uc3QgY2hhciBhcnJbXXsyLCA0LCA2LCA4LCAxMH07CgogICAgZm9yKGNvbnN0IGNoYXImIGMgOiBhcnIpIHsKICAgICAgICBwcmludGYoImM9JWNcbiIsIGMpOwogICAgfQp9&insightsOptions=cpp2a&rev=1.0) diff --git a/docs/examples/recursive-template.md b/docs/examples/recursive-template.md index dad58710..3d9f1a79 100644 --- a/docs/examples/recursive-template.md +++ b/docs/examples/recursive-template.md @@ -74,7 +74,6 @@ struct A<5> #endif - template<> struct A<1> { @@ -82,14 +81,12 @@ struct A<1> }; - int main() { printf("c=%c\n", A<5>::value); return 0; } - ``` [Live view](https://cppinsights.io/lnk?code=I2luY2x1ZGUgPGNzdGRpbz4KI2luY2x1ZGUgPHZlY3Rvcj4KCnRlbXBsYXRlPGludCBuPgpzdHJ1Y3QgQQp7CiAgICBzdGF0aWMgY29uc3QgYXV0byB2YWx1ZSA9IEE8biAtIDE+Ojp2YWx1ZSArIG47Cn07Cgp0ZW1wbGF0ZTw+CnN0cnVjdCBBPDE+CnsKICAgIHN0YXRpYyBjb25zdCBhdXRvIHZhbHVlID0gMTsKfTsKCmludCBtYWluKCkKewogICAgcHJpbnRmKCJjPSVjXG4iLCBBPDU+Ojp2YWx1ZSk7Cn0=&insightsOptions=cpp2a&rev=1.0) diff --git a/docs/examples/structured-bindings.md b/docs/examples/structured-bindings.md index b57b7ad9..3a774170 100644 --- a/docs/examples/structured-bindings.md +++ b/docs/examples/structured-bindings.md @@ -30,22 +30,16 @@ struct Point }; - Point pt = {1, 2}; -// Here we get an additional object injected to which ax and ay refer. Point __pt9 = Point(pt); int & ax = __pt9.x; int & ay = __pt9.y; - -// In case of an reference the injected object is just a reference to -// the original one. Point & __pt13 = pt; int & a2x = __pt13.x; int & a2y = __pt13.y; - ``` [Live view](https://cppinsights.io/lnk?code=c3RydWN0IFBvaW50CnsKICAgIGludCB4OwogICAgaW50IHk7Cn07CgpQb2ludCBwdHsxLCAyfTsKLy8gSGVyZSB3ZSBnZXQgYW4gYWRkaXRpb25hbCBvYmplY3QgaW5qZWN0ZWQgdG8gd2hpY2ggYXggYW5kIGF5IHJlZmVyLgphdXRvIFtheCwgYXldID0gcHQ7CgovLyBJbiBjYXNlIG9mIGFuIHJlZmVyZW5jZSB0aGUgaW5qZWN0ZWQgb2JqZWN0IGlzIGp1c3QgYSByZWZlcmVuY2UgdG8KLy8gdGhlIG9yaWdpbmFsIG9uZS4KYXV0byYgW2EyeCwgYTJ5XSA9IHB0Ow==&insightsOptions=cpp2a&rev=1.0) diff --git a/docs/opt-alt-syntax-for.md b/docs/opt-alt-syntax-for.md index 50689eea..bfe40b9f 100644 --- a/docs/opt-alt-syntax-for.md +++ b/docs/opt-alt-syntax-for.md @@ -35,5 +35,4 @@ int main() return 0; } - ``` diff --git a/docs/opt-alt-syntax-subscription.md b/docs/opt-alt-syntax-subscription.md index 30cec680..b6055c69 100644 --- a/docs/opt-alt-syntax-subscription.md +++ b/docs/opt-alt-syntax-subscription.md @@ -24,5 +24,4 @@ int main() return 0; } - ``` diff --git a/docs/opt-autocomplete.md b/docs/opt-autocomplete.md new file mode 100644 index 00000000..8226d175 --- /dev/null +++ b/docs/opt-autocomplete.md @@ -0,0 +1,16 @@ +# autocomplete {#autocomplete} +Generate list of options for autocomplete and exit. + +__Default:__ Off + +__Examples:__ + +```.cpp +// Just prints out all the C++ Insights options. +``` + +transforms into this: + +```.cpp + +``` diff --git a/docs/opt-edu-show-cfront.md b/docs/opt-edu-show-cfront.md index 5dba1e89..2695116f 100644 --- a/docs/opt-edu-show-cfront.md +++ b/docs/opt-edu-show-cfront.md @@ -6,10 +6,39 @@ __Default:__ Off __Examples:__ ```.cpp +#include + +class A +{ +public: + int a; + virtual void v() { puts("A->v"); } +}; + +class B +{ +public: + int b; + virtual void w() { puts("B->w"); } +}; + +class C : public A, public B +{ +public: + int c; + void w() { puts("C->w"); } +}; + +class D : public A, public B +{ +public: + int d; +}; + class Apple { public: - Apple(){}; + Apple() {} Apple(int x) : mX{x} @@ -27,7 +56,7 @@ private: int mX{}; }; -int main() +void MemberFunctions() { Apple a{}; @@ -41,6 +70,33 @@ int main() b = a; } + +void Inheritance() +{ + C c; + + c.w(); + c.v(); + + B* b = &c; + b->w(); + + C* cb = (C*)(b); + cb->v(); + + // + D d; + B* bd = &d; + D* db = (D*)bd; + db->w(); +} + +int main() +{ + MemberFunctions(); + + Inheritance(); +} ``` transforms into this: @@ -52,6 +108,99 @@ transforms into this: *************************************************************************************/ void __cxa_start(void); void __cxa_atexit(void); +typedef int (*__vptp)(); + +struct __mptr +{ + short d; + short i; + __vptp f; +}; + +extern struct __mptr* __vtbl_array[]; + + +#include + +typedef struct A +{ + __mptr * __vptrA; + int a; +} A; + +inline void vA(A * __this) +{ + puts("A->v"); +} + +inline A * Constructor_A(A * __this) +{ + __this->__vptrA = __vtbl_array[0]; + return __this; +} + + +typedef struct B +{ + __mptr * __vptrB; + int b; +} B; + +inline void wB(B * __this) +{ + puts("B->w"); +} + +inline B * Constructor_B(B * __this) +{ + __this->__vptrB = __vtbl_array[1]; + return __this; +} + + +typedef struct C +{ + __mptr * __vptrA; + int a; + __mptr * __vptrB; + int b; + int c; +} C; + +inline void wC(C * __this) +{ + puts("C->w"); +} + +inline C * Constructor_C(C * __this) +{ + Constructor_A((A *)__this); + Constructor_B((B *)__this); + __this->__vptrA = __vtbl_array[2]; + __this->__vptrB = __vtbl_array[3]; + return __this; +} + + +typedef struct D +{ + __mptr * __vptrA; + int a; + __mptr * __vptrB; + int b; + int d; +} D; + +inline D * Constructor_D(D * __this) +{ + Constructor_A((A *)__this); + Constructor_B((B *)__this); + __this->__vptrA = __vtbl_array[4]; + __this->__vptrB = __vtbl_array[5]; + return __this; +} + + typedef struct Apple { int mX; @@ -97,24 +246,46 @@ inline Apple * operatorEqual(Apple * __this, const Apple * __rhs) } - -int __main(void) +void MemberFunctions(void) { Apple a; - ; + Constructor_Apple((Apple *)&a); Set(&a, 4); Apple * paaa = nullptr; Set(paaa, 5); Apple b; - ; + Constructor_Apple((Apple *)&b, 6); Apple c; - ; + CopyConstructor_Apple((Apple *)&c, &b); operatorEqual(&b, &a); - return 0; Destructor_Apple(&c); Destructor_Apple(&b); Destructor_Apple(&a); - ; +} + +void Inheritance(void) +{ + C c; + Constructor_C((C *)&c); + (*((void (*)(C *))((&c)->__vptrA[0]).f))((((C *)(char *)(&c)) + ((&c)->__vptrA[0]).d)); + (*((void (*)(A *))((&c)->__vptrA[0]).f))((((A *)(char *)(&c)) + ((&c)->__vptrA[0]).d)); + B * b = (B *)((char*)&c+16); + (*((void (*)(B *))((b)->__vptrB[0]).f))((((B *)(char *)(b)) + ((b)->__vptrB[0]).d)); + C * cb = (C *)((char*)(b)-16); + (*((void (*)(A *))((cb)->__vptrA[0]).f))((((A *)(char *)(cb)) + ((cb)->__vptrA[0]).d)); + D d; + Constructor_D((D *)&d); + B * bd = (B *)((char*)&d+16); + D * db = (D *)((char*)bd-16); + (*((void (*)(B *))((db)->__vptrB[0]).f))((((B *)(char *)(db)) + ((db)->__vptrB[0]).d)); + /* d // lifetime ends here */ + /* c // lifetime ends here */ +} + +int __main(void) +{ + MemberFunctions()Inheritance(); + return 0; } int main(void) @@ -124,9 +295,17 @@ int main(void) __cxa_atexit(); return ret; /* ret // lifetime ends here */ - ; } +__mptr __vtbl_A[1] = {0, 0, (__vptp)vA}; +__mptr __vtbl_B[1] = {0, 0, (__vptp)wB}; +__mptr __vtbl_CA[2] = {{0, 0, (__vptp)vA}, {0, 0, (__vptp)wC}}; +__mptr __vtbl_CB[1] = {-16, 0, (__vptp)wC}; +__mptr __vtbl_DA[1] = {0, 0, (__vptp)vA}; +__mptr __vtbl_DB[1] = {0, 0, (__vptp)wB}; + +__mptr * __vtbl_array[6] = {__vtbl_A, __vtbl_B, __vtbl_CA, __vtbl_CB, __vtbl_DA, __vtbl_DB}; + void __cxa_start(void) { } diff --git a/docs/opt-edu-show-coroutine-transformation.md b/docs/opt-edu-show-coroutine-transformation.md index ed5223a8..19483175 100644 --- a/docs/opt-edu-show-coroutine-transformation.md +++ b/docs/opt-edu-show-coroutine-transformation.md @@ -6,21 +6,11 @@ __Default:__ Off __Examples:__ ```.cpp -#if __has_include() #include -#elif __has_include() -#include - -namespace std { -using namespace std::experimental; -} -#else -#error "No coroutine header" -#endif - #include #include #include +#include struct generator { @@ -43,7 +33,7 @@ struct generator generator(generator const&) = delete; generator(generator&& rhs) - : p{std::exchange(rhs.p, nullptr)} + : handle{std::exchange(rhs.handle, nullptr)} { } @@ -104,21 +94,11 @@ transforms into this: * NOTE: The coroutine transformation you've enabled is a hand coded transformation! * * Most of it is _not_ present in the AST. What you see is an approximation. * *************************************************************************************/ -#if __has_include() #include -#elif __has_include() -#include - -namespace std { -using namespace std::experimental; -} -#else -#error "No coroutine header" -#endif - #include #include #include +#include struct generator { @@ -165,14 +145,14 @@ struct generator inline ~generator() noexcept { - if(/* INSIGHTS-TODO: CodeGenerator.cpp:4287 stmt: RecoveryExpr */) { + if(/* INSIGHTS-TODO: CodeGenerator.cpp:4519 stmt: RecoveryExpr */) { } } inline void run() { - if(/* INSIGHTS-TODO: CodeGenerator.cpp:4287 stmt: RecoveryExpr */) { + if(/* INSIGHTS-TODO: CodeGenerator.cpp:4519 stmt: RecoveryExpr */) { } } @@ -192,14 +172,12 @@ struct generator }; - generator fun() { printf("Hello,"); printf("C++ Insights.\n"); } - int main() { generator s = fun(); @@ -210,5 +188,4 @@ int main() return 0; } - ``` diff --git a/docs/opt-edu-show-initlist.md b/docs/opt-edu-show-initlist.md index 0f21826f..6467a4d0 100644 --- a/docs/opt-edu-show-initlist.md +++ b/docs/opt-edu-show-initlist.md @@ -19,5 +19,4 @@ transforms into this: const int __list3_21[2]{40, 2}; std::vector > vec = std::vector >{std::initializer_list{__list3_21, 2}}; - ``` diff --git a/docs/opt-edu-show-lifetime.md b/docs/opt-edu-show-lifetime.md index a5dc1d90..2180dc19 100644 --- a/docs/opt-edu-show-lifetime.md +++ b/docs/opt-edu-show-lifetime.md @@ -6,29 +6,30 @@ __Default:__ Off __Examples:__ ```.cpp -struct Data { +struct Data +{ int mData[5]{}; -const int* begin() const { return mData; } -const int* end() const { return mData + 1;} + const int* begin() const { return mData; } + const int* end() const { return mData + 1; } }; +struct Keeper +{ + Data data{2, 3, 4}; - -struct Keeper { - Data data{2, 3, 4}; - - auto& items() const { return data; } + auto& items() const { return data; } }; Keeper get() { - return {}; + return {}; } int main() { - for(auto& item : get().items()) { } + for(auto& item : get().items()) { + } } ``` @@ -55,9 +56,6 @@ struct Data }; - - - struct Keeper { Data data{{2, 3, 4, 0, 0}}; @@ -69,19 +67,17 @@ struct Keeper }; - Keeper get() { return {{{2, 3, 4, 0, 0}}}; } - int main() { { - Keeper __temporary23_24 = get(); - const Data & __range1 = static_cast(__temporary23_24).items(); - /* __temporary23_24 // lifetime ends here */ + Keeper __temporary23_26 = get(); + const Data & __range1 = static_cast(__temporary23_26).items(); + /* __temporary23_26 // lifetime ends here */ const int * __begin1 = __range1.begin(); const int * __end1 = __range1.end(); for(; __begin1 != __end1; ++__begin1) { @@ -94,5 +90,4 @@ int main() return 0; } - ``` diff --git a/docs/opt-edu-show-noexcept.md b/docs/opt-edu-show-noexcept.md index 193ab734..01dfca64 100644 --- a/docs/opt-edu-show-noexcept.md +++ b/docs/opt-edu-show-noexcept.md @@ -21,6 +21,7 @@ transforms into this: ```.cpp #include // for noexcept transformation + void Fun() noexcept(true) { try @@ -31,11 +32,9 @@ void Fun() noexcept(true) } } - void Fun2() noexcept(false) { int i = 3; } - ``` diff --git a/docs/opt-edu-show-padding.md b/docs/opt-edu-show-padding.md index d762bbbb..b9b82900 100644 --- a/docs/opt-edu-show-padding.md +++ b/docs/opt-edu-show-padding.md @@ -27,5 +27,4 @@ struct Data /* size: 12, align: 4 */ }; - ``` diff --git a/docs/opt-show-all-callexpr-template-parameters.md b/docs/opt-show-all-callexpr-template-parameters.md index 8d5beb34..b383041d 100644 --- a/docs/opt-show-all-callexpr-template-parameters.md +++ b/docs/opt-show-all-callexpr-template-parameters.md @@ -24,5 +24,4 @@ std::pair Fun() return std::make_pair(5, 7.5); } - ``` diff --git a/docs/opt-show-all-implicit-casts.md b/docs/opt-show-all-implicit-casts.md index df43944e..0dba36ab 100644 --- a/docs/opt-show-all-implicit-casts.md +++ b/docs/opt-show-all-implicit-casts.md @@ -21,5 +21,4 @@ int main() return 0; } - ``` diff --git a/docs/opt-stdin.md b/docs/opt-stdin.md new file mode 100644 index 00000000..78f9326f --- /dev/null +++ b/docs/opt-stdin.md @@ -0,0 +1,19 @@ +# stdin {#stdin} +Read the input from . + +__Default:__ Off + +__Examples:__ + +```.cpp +int main() +{ + // Nothing going on here. +} +``` + +transforms into this: + +```.cpp + +``` diff --git a/docs/opt-use-libc++.md b/docs/opt-use-libc++.md new file mode 100644 index 00000000..4842867c --- /dev/null +++ b/docs/opt-use-libc++.md @@ -0,0 +1,40 @@ +# use-libc++ {#use_libc++} +Use libc++ (LLVM) instead of libstdc++ (GNU). + +__Default:__ Off + +__Examples:__ + +```.cpp +#include + +int main() +{ + const std::string s{"Hello"}; + + for(const auto& e : s) { + } +} +``` + +transforms into this: + +```.cpp +#include + +int main() +{ + const std::basic_string, std::allocator > s = std::basic_string, std::allocator >{"Hello"}; + { + const std::basic_string, std::allocator > & __range1 = s; + std::__wrap_iter __begin1 = __range1.begin(); + std::__wrap_iter __end1 = __range1.end(); + for(; std::operator!=(__begin1, __end1); __begin1.operator++()) { + const char & e = __begin1.operator*(); + } + + } + return 0; +} + +``` diff --git a/scripts/bash-autocomplete.sh b/scripts/bash-autocomplete.sh new file mode 100644 index 00000000..52e1c791 --- /dev/null +++ b/scripts/bash-autocomplete.sh @@ -0,0 +1,77 @@ +# +# C++ Insights, copyright (C) by Andreas Fertig +# Distributed under an MIT license. See LICENSE for details +# +#------------------------------------------------------------------------------ + +if [ $(which insights) ]; then + +_insights_clang_options() +{ + # Note: This implementation is derived from: https://github.com/llvm/llvm-project/blob/fe42d34274cac79794637bf2f69f85537dde8b74/clang/utils/bash-autocomplete.sh + # It is reduced to what's needed for completing Clangs options for C++ Insights. + local cur cword arg options + + COMPREPLY=() + cword=$COMP_CWORD + cur="${COMP_WORDS[$cword]}" + + for i in `seq 1 $cword`; do + arg="$arg${COMP_WORDS[$i-1]}" + + # Handle = which gets a special treatment from bash + [[ $i != $cword && "${COMP_WORDS[$(($i))]}" != '=' ]] && arg="$arg," + done + + options=$( insights -- --autocomplete="$arg" 2>/dev/null | awk '{print $1}' | tr '\n' ' ' ) + + if [[ "$options" == "" || "$options" == " " ]]; then + [[ "$cur" == '=' || "$cur" == -*= ]] && cur="" + COMPREPLY=( $( compgen -f "$cur" | sort ) ) + else + [[ "${options: -1}" == '=' ]] && compopt -o nospace 2>/dev/null + [[ "$cur" == '=' ]] && cur="" + COMPREPLY=( $( compgen -W "$options" -- "$cur" ) ) + fi +} + +_insights() +{ + local cur words cword + + cur="${COMP_WORDS[COMP_CWORD]}" + words=("${COMP_WORDS[@]}") + cword=$COMP_CWORD + + for (( i=0; i<${#words[@]}; i++ )); do + if [[ ${words[i]} == "--" ]]; then + local clang_args=("${words[@]:i+1}") + COMP_LINE="${clang_args[*]}" + COMP_POINT=$(( ${#COMP_LINE} )) + COMP_WORDS=("${clang_args[@]}") + COMP_CWORD=$(( ${#clang_args[@]} )) + + _insights_clang_options "${COMP_WORDS[1]}" "$2" "$3" + + return 0 + fi + done + + COMP_WORDS=$words + COMP_CWORD=$cword + + VALUES=$(insights --autocomplete) + COMPREPLY=( $( compgen -W '-h --help --help-list --version -p --extra-arg --extra-arg-before $VALUES' -- "$cur" ) ) + + # Expanding files if nothing was provided + if [[ -z "$COMPREPLY" || "$cur" == "" ]]; then + COMPREPLY=( $( compgen -f "$cur" | sort ) ) + fi + + return 0 +} +complete -o bashdefault -o default -F _insights insights + +fi + +# ex: ts=4 sw=4 et filetype=sh diff --git a/tests/shell/a.cpp b/tests/shell/a.cpp new file mode 100644 index 00000000..e69de29b diff --git a/tests/shell/another.cpp b/tests/shell/another.cpp new file mode 100644 index 00000000..e69de29b diff --git a/tests/shell/b.cpp b/tests/shell/b.cpp new file mode 100644 index 00000000..e69de29b diff --git a/tests/shell/test-bash-completion.sh b/tests/shell/test-bash-completion.sh new file mode 100755 index 00000000..2ff938b4 --- /dev/null +++ b/tests/shell/test-bash-completion.sh @@ -0,0 +1,55 @@ +#! /bin/bash +# +# C++ Insights, copyright (C) by Andreas Fertig +# Distributed under an MIT license. See LICENSE for details +# +#------------------------------------------------------------------------------ + +PATH=$PATH:$1 +failureIsOkay=$4 + +cd $2 + +source $3 + +ret=0 + +do_test() +{ +COMP_WORDS=(insights $1) # array of words in command line +COMP_CWORD=1 # index of the word containing cursor position + +ins="$(complete -p insights 2>/dev/null|sed 's/.*-F \([^ ]*\) .*/\1/')" + +$ins a a + +expect=$2 +res=${COMPREPLY[@]} + +if [ "$res" == "$expect" ]; then + echo "[PASSED] $1" +else + echo "[FAILED] $1" + echo "${COMPREPLY[@]}" + ret=1 +fi +} + +echo "Running bash autocomplete tests..." + +do_test "-- -std" "-std= -stdlib -stdlib++-isystem -stdlib=" +do_test "-- -std = c++1" "c++11 c++14 c++17 c++1y c++1z" +do_test "--use" "--use-libc++" +do_test "--use-libc++ -- -Weff" "-Weffc++" +do_test "-- ---" "a.cpp another.cpp b.cpp test-bash-completion.sh" +do_test "-- -fmodule-name=a." "a.cpp another.cpp b.cpp test-bash-completion.sh" +do_test "" "a.cpp another.cpp b.cpp test-bash-completion.sh" +do_test "a" "a.cpp another.cpp" +do_test "a." "a.cpp" + +if [ "$failureIsOkay" == "--failure-is-ok" ]; then + echo "Accepting failed tests" + exit 0 +fi + +exit $ret