[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
@@ -0,0 +1,29 @@ +/// Invalid output path (%t is a file, not a directory). +// RUN: rm -rf %t && touch %t +// RUN: not clang-doc %s -output=%t/subdir 2>&1 | FileCheck %s +// CHECK: clang-doc error: +// CHECK: {{(Not a directory|no such file or directory)}} + +/// Invalid format option. +// RUN: not clang-doc %s --output=%t.dir -format=badformat 2>&1 | FileCheck %s --check-prefix=BAD-FORMAT +// BAD-FORMAT: clang-doc: for the --format option: Cannot find option named 'badformat'! + +/// Missing HTML asset directory (warning only). +// RUN: clang-doc %s -format=html -asset=%t/nonexistent-assets 2>&1 | FileCheck %s --check-prefix=ASSET-WARN +// ASSET-WARN: Asset path supply is not a directory +// ASSET-WARN: falling back to default + +/// Mapping failure (with --ignore-map-errors=false). +// RUN: not clang-doc %t/nonexistent.cpp -ignore-map-errors=false 2>&1 | FileCheck %s --check-prefix=MAP-FAIL +// MAP-FAIL: clang-doc error: Failed to run action + +/// Mapping failure (with --ignore-map-errors=true). +// RUN: clang-doc %t/nonexistent.cpp 2>&1 | FileCheck %s --check-prefix=MAP-WARN +// MAP-WARN: Error mapping decls in files. Clang-doc will ignore these files and continue + +///Invalid executor type +// RUN: not clang-doc --executor=invalid %s 2>&1 | FileCheck %s --check-prefix=EXECUTOR-FAIL +// EXECUTOR-FAIL: clang-doc error: +// EXECUTOR-FAIL: Executor "invalid" is not registered snarang181 wrote: I ran `clang-doc --extra-arg=-nonexistentflag %s` and I get a diagnostic error saying `error: unknown argument: '-nonexistentflag'` but this does not seem to be blocking, and the test does return. Hence, the `ExitOnErr` handler does not get invoked. https://github.com/llvm/llvm-project/pull/141699 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/141699 >From f0b3184f2d4342eb0aacf3a77671556ac2e57650 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Tue, 27 May 2025 21:32:41 -0400 Subject: [PATCH 01/14] [clang-doc] Refactor error handling to use ExitOnError This patch replaces manual error checks and exit() calls in clang-doc with llvm::ExitOnError for consistency and maintainability. No functional changes to outputs or APIs. --- .../clang-doc/tool/ClangDocMain.cpp | 32 ++- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp index 41fbe87a713d9..54c5d41e3a6cd 100644 --- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -43,6 +43,7 @@ using namespace clang::ast_matchers; using namespace clang::tooling; using namespace clang; +static llvm::ExitOnError ExitOnErr; static llvm::cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); static llvm::cl::OptionCategory ClangDocCategory("clang-doc options"); @@ -249,6 +250,8 @@ int main(int argc, const char **argv) { llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); std::error_code OK; + ExitOnErr.setBanner("clang-doc error: "); + const char *Overview = R"(Generates documentation from source code and comments. @@ -272,11 +275,7 @@ Example usage for a project using a compile commands database: // Fail early if an invalid format was provided. std::string Format = getFormatString(); llvm::outs() << "Emiting docs in " << Format << " format.\n"; - auto G = doc::findGeneratorByName(Format); - if (!G) { -llvm::errs() << toString(G.takeError()) << "\n"; -return 1; - } + auto G = ExitOnErr(doc::findGeneratorByName(Format)); ArgumentsAdjuster ArgAdjuster; if (!DoxygenOnly) @@ -297,10 +296,7 @@ Example usage for a project using a compile commands database: {UserStylesheets.begin(), UserStylesheets.end()}}; if (Format == "html") { -if (auto Err = getHtmlAssetFiles(argv[0], CDCtx)) { - llvm::errs() << toString(std::move(Err)) << "\n"; - return 1; -} +ExitOnErr(getHtmlAssetFiles(argv[0], CDCtx)); } if (Format == "mustache") { @@ -320,7 +316,7 @@ Example usage for a project using a compile commands database: "these files and continue:\n" << toString(std::move(Err)) << "\n"; else { - llvm::errs() << toString(std::move(Err)) << "\n"; + ExitOnErr(std::move(Err)); return 1; } } @@ -391,22 +387,14 @@ Example usage for a project using a compile commands database: sortUsrToInfo(USRToInfo); // Ensure the root output directory exists. - if (std::error_code Err = llvm::sys::fs::create_directories(OutDirectory); - Err != std::error_code()) { -llvm::errs() << "Failed to create directory '" << OutDirectory << "'\n"; -return 1; - } + ExitOnErr( + llvm::errorCodeToError(llvm::sys::fs::create_directories(OutDirectory))); // Run the generator. llvm::outs() << "Generating docs...\n"; - if (auto Err = - G->get()->generateDocs(OutDirectory, std::move(USRToInfo), CDCtx)) { -llvm::errs() << toString(std::move(Err)) << "\n"; -return 1; - } - + ExitOnErr(G->generateDocs(OutDirectory, std::move(USRToInfo), CDCtx)); llvm::outs() << "Generating assets for docs...\n"; - Err = G->get()->createResources(CDCtx); + Err = G->createResources(CDCtx); if (Err) { llvm::outs() << "warning: " << toString(std::move(Err)) << "\n"; } >From daab868b8bc145286af02867b24175b6cb9edd0e Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Wed, 28 May 2025 18:47:17 -0400 Subject: [PATCH 02/14] Addressing PR feedback --- clang-tools-extra/clang-doc/tool/ClangDocMain.cpp| 12 +--- .../test/clang-doc/invalid-file-error.test | 4 2 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 clang-tools-extra/test/clang-doc/invalid-file-error.test diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp index 54c5d41e3a6cd..932a9654b563a 100644 --- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -43,7 +43,6 @@ using namespace clang::ast_matchers; using namespace clang::tooling; using namespace clang; -static llvm::ExitOnError ExitOnErr; static llvm::cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); static llvm::cl::OptionCategory ClangDocCategory("clang-doc options"); @@ -119,6 +118,8 @@ static llvm::cl::opt FormatEnum( "Documentation in mustache HTML format")), llvm::cl::init(OutputFormatTy::yaml), llvm::cl::cat(ClangDocCategory)); +static llvm::ExitOnError ExitOnErr; + static std::string getFormatString() { switch (FormatEn
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/141699 >From f0b3184f2d4342eb0aacf3a77671556ac2e57650 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Tue, 27 May 2025 21:32:41 -0400 Subject: [PATCH 01/17] [clang-doc] Refactor error handling to use ExitOnError This patch replaces manual error checks and exit() calls in clang-doc with llvm::ExitOnError for consistency and maintainability. No functional changes to outputs or APIs. --- .../clang-doc/tool/ClangDocMain.cpp | 32 ++- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp index 41fbe87a713d9..54c5d41e3a6cd 100644 --- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -43,6 +43,7 @@ using namespace clang::ast_matchers; using namespace clang::tooling; using namespace clang; +static llvm::ExitOnError ExitOnErr; static llvm::cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); static llvm::cl::OptionCategory ClangDocCategory("clang-doc options"); @@ -249,6 +250,8 @@ int main(int argc, const char **argv) { llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); std::error_code OK; + ExitOnErr.setBanner("clang-doc error: "); + const char *Overview = R"(Generates documentation from source code and comments. @@ -272,11 +275,7 @@ Example usage for a project using a compile commands database: // Fail early if an invalid format was provided. std::string Format = getFormatString(); llvm::outs() << "Emiting docs in " << Format << " format.\n"; - auto G = doc::findGeneratorByName(Format); - if (!G) { -llvm::errs() << toString(G.takeError()) << "\n"; -return 1; - } + auto G = ExitOnErr(doc::findGeneratorByName(Format)); ArgumentsAdjuster ArgAdjuster; if (!DoxygenOnly) @@ -297,10 +296,7 @@ Example usage for a project using a compile commands database: {UserStylesheets.begin(), UserStylesheets.end()}}; if (Format == "html") { -if (auto Err = getHtmlAssetFiles(argv[0], CDCtx)) { - llvm::errs() << toString(std::move(Err)) << "\n"; - return 1; -} +ExitOnErr(getHtmlAssetFiles(argv[0], CDCtx)); } if (Format == "mustache") { @@ -320,7 +316,7 @@ Example usage for a project using a compile commands database: "these files and continue:\n" << toString(std::move(Err)) << "\n"; else { - llvm::errs() << toString(std::move(Err)) << "\n"; + ExitOnErr(std::move(Err)); return 1; } } @@ -391,22 +387,14 @@ Example usage for a project using a compile commands database: sortUsrToInfo(USRToInfo); // Ensure the root output directory exists. - if (std::error_code Err = llvm::sys::fs::create_directories(OutDirectory); - Err != std::error_code()) { -llvm::errs() << "Failed to create directory '" << OutDirectory << "'\n"; -return 1; - } + ExitOnErr( + llvm::errorCodeToError(llvm::sys::fs::create_directories(OutDirectory))); // Run the generator. llvm::outs() << "Generating docs...\n"; - if (auto Err = - G->get()->generateDocs(OutDirectory, std::move(USRToInfo), CDCtx)) { -llvm::errs() << toString(std::move(Err)) << "\n"; -return 1; - } - + ExitOnErr(G->generateDocs(OutDirectory, std::move(USRToInfo), CDCtx)); llvm::outs() << "Generating assets for docs...\n"; - Err = G->get()->createResources(CDCtx); + Err = G->createResources(CDCtx); if (Err) { llvm::outs() << "warning: " << toString(std::move(Err)) << "\n"; } >From daab868b8bc145286af02867b24175b6cb9edd0e Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Wed, 28 May 2025 18:47:17 -0400 Subject: [PATCH 02/17] Addressing PR feedback --- clang-tools-extra/clang-doc/tool/ClangDocMain.cpp| 12 +--- .../test/clang-doc/invalid-file-error.test | 4 2 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 clang-tools-extra/test/clang-doc/invalid-file-error.test diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp index 54c5d41e3a6cd..932a9654b563a 100644 --- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -43,7 +43,6 @@ using namespace clang::ast_matchers; using namespace clang::tooling; using namespace clang; -static llvm::ExitOnError ExitOnErr; static llvm::cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); static llvm::cl::OptionCategory ClangDocCategory("clang-doc options"); @@ -119,6 +118,8 @@ static llvm::cl::opt FormatEnum( "Documentation in mustache HTML format")), llvm::cl::init(OutputFormatTy::yaml), llvm::cl::cat(ClangDocCategory)); +static llvm::ExitOnError ExitOnErr; + static std::string getFormatString() { switch (FormatEn
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
snarang181 wrote: Thanks again @ilovepi for the handholding, appreciate it. BTW -- do you know what's going on with the Linux CI? https://github.com/llvm/llvm-project/pull/141699 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
snarang181 wrote: @ilovepi, requesting your review here. https://github.com/llvm/llvm-project/pull/141699 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
snarang181 wrote: I made the requested changes, can the CI workflows be triggered? I do not have access. https://github.com/llvm/llvm-project/pull/141699 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
https://github.com/snarang181 edited https://github.com/llvm/llvm-project/pull/141699 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/141699 >From b2dc4f8a50d86ecdc5fd27fedd7efde5c6882df5 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Tue, 27 May 2025 21:32:41 -0400 Subject: [PATCH 1/2] [clang-doc] Refactor error handling to use ExitOnError This patch replaces manual error checks and exit() calls in clang-doc with llvm::ExitOnError for consistency and maintainability. No functional changes to outputs or APIs. --- .../clang-doc/tool/ClangDocMain.cpp | 32 ++- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp index 8e8f7053a8f87..e7efa4b15d80f 100644 --- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -49,6 +49,7 @@ using namespace clang::ast_matchers; using namespace clang::tooling; using namespace clang; +static llvm::ExitOnError ExitOnErr; static llvm::cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); static llvm::cl::OptionCategory ClangDocCategory("clang-doc options"); @@ -236,6 +237,8 @@ int main(int argc, const char **argv) { llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); std::error_code OK; + ExitOnErr.setBanner("clang-doc error: "); + const char *Overview = R"(Generates documentation from source code and comments. @@ -259,11 +262,7 @@ Example usage for a project using a compile commands database: // Fail early if an invalid format was provided. std::string Format = getFormatString(); llvm::outs() << "Emiting docs in " << Format << " format.\n"; - auto G = doc::findGeneratorByName(Format); - if (!G) { -llvm::errs() << toString(G.takeError()) << "\n"; -return 1; - } + auto G = ExitOnErr(doc::findGeneratorByName(Format)); ArgumentsAdjuster ArgAdjuster; if (!DoxygenOnly) @@ -284,10 +283,7 @@ Example usage for a project using a compile commands database: {UserStylesheets.begin(), UserStylesheets.end()}}; if (Format == "html") { -if (auto Err = getHtmlAssetFiles(argv[0], CDCtx)) { - llvm::errs() << toString(std::move(Err)) << "\n"; - return 1; -} +ExitOnErr(getHtmlAssetFiles(argv[0], CDCtx)); } // Mapping phase @@ -300,7 +296,7 @@ Example usage for a project using a compile commands database: "these files and continue:\n" << toString(std::move(Err)) << "\n"; else { - llvm::errs() << toString(std::move(Err)) << "\n"; + ExitOnErr(std::move(Err)); return 1; } } @@ -371,22 +367,14 @@ Example usage for a project using a compile commands database: sortUsrToInfo(USRToInfo); // Ensure the root output directory exists. - if (std::error_code Err = llvm::sys::fs::create_directories(OutDirectory); - Err != std::error_code()) { -llvm::errs() << "Failed to create directory '" << OutDirectory << "'\n"; -return 1; - } + ExitOnErr( + llvm::errorCodeToError(llvm::sys::fs::create_directories(OutDirectory))); // Run the generator. llvm::outs() << "Generating docs...\n"; - if (auto Err = - G->get()->generateDocs(OutDirectory, std::move(USRToInfo), CDCtx)) { -llvm::errs() << toString(std::move(Err)) << "\n"; -return 1; - } - + ExitOnErr(G->generateDocs(OutDirectory, std::move(USRToInfo), CDCtx)); llvm::outs() << "Generating assets for docs...\n"; - Err = G->get()->createResources(CDCtx); + Err = G->createResources(CDCtx); if (Err) { llvm::outs() << "warning: " << toString(std::move(Err)) << "\n"; } >From 51238bcaf1a6450eb2b7dfbc259a1d7c4bba0a17 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Wed, 28 May 2025 18:47:17 -0400 Subject: [PATCH 2/2] Addressing PR feedback --- clang-tools-extra/clang-doc/tool/ClangDocMain.cpp| 12 +--- .../test/clang-doc/invalid-file-error.test | 4 2 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 clang-tools-extra/test/clang-doc/invalid-file-error.test diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp index e7efa4b15d80f..78ad1521397e6 100644 --- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -49,7 +49,6 @@ using namespace clang::ast_matchers; using namespace clang::tooling; using namespace clang; -static llvm::ExitOnError ExitOnErr; static llvm::cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); static llvm::cl::OptionCategory ClangDocCategory("clang-doc options"); @@ -128,6 +127,8 @@ static llvm::cl::opt llvm::cl::init(OutputFormatTy::yaml), llvm::cl::cat(ClangDocCategory)); +static llvm::ExitOnError ExitOnErr; + static std::string getFormatString() { switch (FormatEnum) { case OutputFormatTy::yaml: @@ -367,8 +368,13 @@ Example usage for a
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
@@ -373,20 +370,16 @@ Example usage for a project using a compile commands database: // Ensure the root output directory exists. if (std::error_code Err = llvm::sys::fs::create_directories(OutDirectory); Err != std::error_code()) { -llvm::errs() << "Failed to create directory '" << OutDirectory << "'\n"; -return 1; +ExitOnErr(llvm::createStringError( +llvm::inconvertibleErrorCode(), "Failed to create directory '%s': %s", snarang181 wrote: The string error looks verbose and explanatory to me. However, would you prefer me looking into the error APIs or revert this change altogether? https://github.com/llvm/llvm-project/pull/141699 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
@@ -0,0 +1,4 @@ +// RUN: not clang-doc %S/Inputs/basic-project/src/Circle.cpp -output=/root/docs 2>&1 | FileCheck %s snarang181 wrote: Sorry, I might be misunderstanding but won't `llvm::sys::fs::create_directories()` create a valid directory path? Giving the `/root/` output directory fails because it is a read-only file system. If I take the `%t` approach, the clang-doc error will not be fired. https://github.com/llvm/llvm-project/pull/141699 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
https://github.com/snarang181 edited https://github.com/llvm/llvm-project/pull/141699 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
snarang181 wrote: @ilovepi, wrapped the creation of the `Executor` in the error handler, created a helper like you suggested, and added a test case for the creation of the `Executor` failing. https://github.com/llvm/llvm-project/pull/141699 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/141699 >From 1cddd0889b2aa322e1d1fce1225d6da0f5e8cc20 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Tue, 27 May 2025 21:32:41 -0400 Subject: [PATCH 01/12] [clang-doc] Refactor error handling to use ExitOnError This patch replaces manual error checks and exit() calls in clang-doc with llvm::ExitOnError for consistency and maintainability. No functional changes to outputs or APIs. --- .../clang-doc/tool/ClangDocMain.cpp | 32 ++- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp index 41fbe87a713d9..54c5d41e3a6cd 100644 --- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -43,6 +43,7 @@ using namespace clang::ast_matchers; using namespace clang::tooling; using namespace clang; +static llvm::ExitOnError ExitOnErr; static llvm::cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); static llvm::cl::OptionCategory ClangDocCategory("clang-doc options"); @@ -249,6 +250,8 @@ int main(int argc, const char **argv) { llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); std::error_code OK; + ExitOnErr.setBanner("clang-doc error: "); + const char *Overview = R"(Generates documentation from source code and comments. @@ -272,11 +275,7 @@ Example usage for a project using a compile commands database: // Fail early if an invalid format was provided. std::string Format = getFormatString(); llvm::outs() << "Emiting docs in " << Format << " format.\n"; - auto G = doc::findGeneratorByName(Format); - if (!G) { -llvm::errs() << toString(G.takeError()) << "\n"; -return 1; - } + auto G = ExitOnErr(doc::findGeneratorByName(Format)); ArgumentsAdjuster ArgAdjuster; if (!DoxygenOnly) @@ -297,10 +296,7 @@ Example usage for a project using a compile commands database: {UserStylesheets.begin(), UserStylesheets.end()}}; if (Format == "html") { -if (auto Err = getHtmlAssetFiles(argv[0], CDCtx)) { - llvm::errs() << toString(std::move(Err)) << "\n"; - return 1; -} +ExitOnErr(getHtmlAssetFiles(argv[0], CDCtx)); } if (Format == "mustache") { @@ -320,7 +316,7 @@ Example usage for a project using a compile commands database: "these files and continue:\n" << toString(std::move(Err)) << "\n"; else { - llvm::errs() << toString(std::move(Err)) << "\n"; + ExitOnErr(std::move(Err)); return 1; } } @@ -391,22 +387,14 @@ Example usage for a project using a compile commands database: sortUsrToInfo(USRToInfo); // Ensure the root output directory exists. - if (std::error_code Err = llvm::sys::fs::create_directories(OutDirectory); - Err != std::error_code()) { -llvm::errs() << "Failed to create directory '" << OutDirectory << "'\n"; -return 1; - } + ExitOnErr( + llvm::errorCodeToError(llvm::sys::fs::create_directories(OutDirectory))); // Run the generator. llvm::outs() << "Generating docs...\n"; - if (auto Err = - G->get()->generateDocs(OutDirectory, std::move(USRToInfo), CDCtx)) { -llvm::errs() << toString(std::move(Err)) << "\n"; -return 1; - } - + ExitOnErr(G->generateDocs(OutDirectory, std::move(USRToInfo), CDCtx)); llvm::outs() << "Generating assets for docs...\n"; - Err = G->get()->createResources(CDCtx); + Err = G->createResources(CDCtx); if (Err) { llvm::outs() << "warning: " << toString(std::move(Err)) << "\n"; } >From 261c3959de40a879aa0e8166b284c494fc1db437 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Wed, 28 May 2025 18:47:17 -0400 Subject: [PATCH 02/12] Addressing PR feedback --- clang-tools-extra/clang-doc/tool/ClangDocMain.cpp| 12 +--- .../test/clang-doc/invalid-file-error.test | 4 2 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 clang-tools-extra/test/clang-doc/invalid-file-error.test diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp index 54c5d41e3a6cd..932a9654b563a 100644 --- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -43,7 +43,6 @@ using namespace clang::ast_matchers; using namespace clang::tooling; using namespace clang; -static llvm::ExitOnError ExitOnErr; static llvm::cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); static llvm::cl::OptionCategory ClangDocCategory("clang-doc options"); @@ -119,6 +118,8 @@ static llvm::cl::opt FormatEnum( "Documentation in mustache HTML format")), llvm::cl::init(OutputFormatTy::yaml), llvm::cl::cat(ClangDocCategory)); +static llvm::ExitOnError ExitOnErr; + static std::string getFormatString() { switch (FormatEn
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/141699 >From f0b3184f2d4342eb0aacf3a77671556ac2e57650 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Tue, 27 May 2025 21:32:41 -0400 Subject: [PATCH 01/15] [clang-doc] Refactor error handling to use ExitOnError This patch replaces manual error checks and exit() calls in clang-doc with llvm::ExitOnError for consistency and maintainability. No functional changes to outputs or APIs. --- .../clang-doc/tool/ClangDocMain.cpp | 32 ++- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp index 41fbe87a713d9..54c5d41e3a6cd 100644 --- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -43,6 +43,7 @@ using namespace clang::ast_matchers; using namespace clang::tooling; using namespace clang; +static llvm::ExitOnError ExitOnErr; static llvm::cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); static llvm::cl::OptionCategory ClangDocCategory("clang-doc options"); @@ -249,6 +250,8 @@ int main(int argc, const char **argv) { llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); std::error_code OK; + ExitOnErr.setBanner("clang-doc error: "); + const char *Overview = R"(Generates documentation from source code and comments. @@ -272,11 +275,7 @@ Example usage for a project using a compile commands database: // Fail early if an invalid format was provided. std::string Format = getFormatString(); llvm::outs() << "Emiting docs in " << Format << " format.\n"; - auto G = doc::findGeneratorByName(Format); - if (!G) { -llvm::errs() << toString(G.takeError()) << "\n"; -return 1; - } + auto G = ExitOnErr(doc::findGeneratorByName(Format)); ArgumentsAdjuster ArgAdjuster; if (!DoxygenOnly) @@ -297,10 +296,7 @@ Example usage for a project using a compile commands database: {UserStylesheets.begin(), UserStylesheets.end()}}; if (Format == "html") { -if (auto Err = getHtmlAssetFiles(argv[0], CDCtx)) { - llvm::errs() << toString(std::move(Err)) << "\n"; - return 1; -} +ExitOnErr(getHtmlAssetFiles(argv[0], CDCtx)); } if (Format == "mustache") { @@ -320,7 +316,7 @@ Example usage for a project using a compile commands database: "these files and continue:\n" << toString(std::move(Err)) << "\n"; else { - llvm::errs() << toString(std::move(Err)) << "\n"; + ExitOnErr(std::move(Err)); return 1; } } @@ -391,22 +387,14 @@ Example usage for a project using a compile commands database: sortUsrToInfo(USRToInfo); // Ensure the root output directory exists. - if (std::error_code Err = llvm::sys::fs::create_directories(OutDirectory); - Err != std::error_code()) { -llvm::errs() << "Failed to create directory '" << OutDirectory << "'\n"; -return 1; - } + ExitOnErr( + llvm::errorCodeToError(llvm::sys::fs::create_directories(OutDirectory))); // Run the generator. llvm::outs() << "Generating docs...\n"; - if (auto Err = - G->get()->generateDocs(OutDirectory, std::move(USRToInfo), CDCtx)) { -llvm::errs() << toString(std::move(Err)) << "\n"; -return 1; - } - + ExitOnErr(G->generateDocs(OutDirectory, std::move(USRToInfo), CDCtx)); llvm::outs() << "Generating assets for docs...\n"; - Err = G->get()->createResources(CDCtx); + Err = G->createResources(CDCtx); if (Err) { llvm::outs() << "warning: " << toString(std::move(Err)) << "\n"; } >From daab868b8bc145286af02867b24175b6cb9edd0e Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Wed, 28 May 2025 18:47:17 -0400 Subject: [PATCH 02/15] Addressing PR feedback --- clang-tools-extra/clang-doc/tool/ClangDocMain.cpp| 12 +--- .../test/clang-doc/invalid-file-error.test | 4 2 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 clang-tools-extra/test/clang-doc/invalid-file-error.test diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp index 54c5d41e3a6cd..932a9654b563a 100644 --- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -43,7 +43,6 @@ using namespace clang::ast_matchers; using namespace clang::tooling; using namespace clang; -static llvm::ExitOnError ExitOnErr; static llvm::cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); static llvm::cl::OptionCategory ClangDocCategory("clang-doc options"); @@ -119,6 +118,8 @@ static llvm::cl::opt FormatEnum( "Documentation in mustache HTML format")), llvm::cl::init(OutputFormatTy::yaml), llvm::cl::cat(ClangDocCategory)); +static llvm::ExitOnError ExitOnErr; + static std::string getFormatString() { switch (FormatEn
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/141699 >From f0b3184f2d4342eb0aacf3a77671556ac2e57650 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Tue, 27 May 2025 21:32:41 -0400 Subject: [PATCH 01/16] [clang-doc] Refactor error handling to use ExitOnError This patch replaces manual error checks and exit() calls in clang-doc with llvm::ExitOnError for consistency and maintainability. No functional changes to outputs or APIs. --- .../clang-doc/tool/ClangDocMain.cpp | 32 ++- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp index 41fbe87a713d9..54c5d41e3a6cd 100644 --- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -43,6 +43,7 @@ using namespace clang::ast_matchers; using namespace clang::tooling; using namespace clang; +static llvm::ExitOnError ExitOnErr; static llvm::cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); static llvm::cl::OptionCategory ClangDocCategory("clang-doc options"); @@ -249,6 +250,8 @@ int main(int argc, const char **argv) { llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); std::error_code OK; + ExitOnErr.setBanner("clang-doc error: "); + const char *Overview = R"(Generates documentation from source code and comments. @@ -272,11 +275,7 @@ Example usage for a project using a compile commands database: // Fail early if an invalid format was provided. std::string Format = getFormatString(); llvm::outs() << "Emiting docs in " << Format << " format.\n"; - auto G = doc::findGeneratorByName(Format); - if (!G) { -llvm::errs() << toString(G.takeError()) << "\n"; -return 1; - } + auto G = ExitOnErr(doc::findGeneratorByName(Format)); ArgumentsAdjuster ArgAdjuster; if (!DoxygenOnly) @@ -297,10 +296,7 @@ Example usage for a project using a compile commands database: {UserStylesheets.begin(), UserStylesheets.end()}}; if (Format == "html") { -if (auto Err = getHtmlAssetFiles(argv[0], CDCtx)) { - llvm::errs() << toString(std::move(Err)) << "\n"; - return 1; -} +ExitOnErr(getHtmlAssetFiles(argv[0], CDCtx)); } if (Format == "mustache") { @@ -320,7 +316,7 @@ Example usage for a project using a compile commands database: "these files and continue:\n" << toString(std::move(Err)) << "\n"; else { - llvm::errs() << toString(std::move(Err)) << "\n"; + ExitOnErr(std::move(Err)); return 1; } } @@ -391,22 +387,14 @@ Example usage for a project using a compile commands database: sortUsrToInfo(USRToInfo); // Ensure the root output directory exists. - if (std::error_code Err = llvm::sys::fs::create_directories(OutDirectory); - Err != std::error_code()) { -llvm::errs() << "Failed to create directory '" << OutDirectory << "'\n"; -return 1; - } + ExitOnErr( + llvm::errorCodeToError(llvm::sys::fs::create_directories(OutDirectory))); // Run the generator. llvm::outs() << "Generating docs...\n"; - if (auto Err = - G->get()->generateDocs(OutDirectory, std::move(USRToInfo), CDCtx)) { -llvm::errs() << toString(std::move(Err)) << "\n"; -return 1; - } - + ExitOnErr(G->generateDocs(OutDirectory, std::move(USRToInfo), CDCtx)); llvm::outs() << "Generating assets for docs...\n"; - Err = G->get()->createResources(CDCtx); + Err = G->createResources(CDCtx); if (Err) { llvm::outs() << "warning: " << toString(std::move(Err)) << "\n"; } >From daab868b8bc145286af02867b24175b6cb9edd0e Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Wed, 28 May 2025 18:47:17 -0400 Subject: [PATCH 02/16] Addressing PR feedback --- clang-tools-extra/clang-doc/tool/ClangDocMain.cpp| 12 +--- .../test/clang-doc/invalid-file-error.test | 4 2 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 clang-tools-extra/test/clang-doc/invalid-file-error.test diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp index 54c5d41e3a6cd..932a9654b563a 100644 --- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -43,7 +43,6 @@ using namespace clang::ast_matchers; using namespace clang::tooling; using namespace clang; -static llvm::ExitOnError ExitOnErr; static llvm::cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); static llvm::cl::OptionCategory ClangDocCategory("clang-doc options"); @@ -119,6 +118,8 @@ static llvm::cl::opt FormatEnum( "Documentation in mustache HTML format")), llvm::cl::init(OutputFormatTy::yaml), llvm::cl::cat(ClangDocCategory)); +static llvm::ExitOnError ExitOnErr; + static std::string getFormatString() { switch (FormatEn
[clang-tools-extra] Refactor clang doc comment structure (PR #142273)
https://github.com/snarang181 edited https://github.com/llvm/llvm-project/pull/142273 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Refactor clang doc comment structure (PR #142273)
https://github.com/snarang181 converted_to_draft https://github.com/llvm/llvm-project/pull/142273 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Refactor clang doc comment structure (PR #142273)
https://github.com/snarang181 ready_for_review https://github.com/llvm/llvm-project/pull/142273 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Refactor clang doc comment structure (PR #142273)
https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/142273 >From 725dd21adcd2f776b2e6adc648e3038812059bf3 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Sat, 31 May 2025 10:05:52 -0400 Subject: [PATCH 1/6] [clang-doc] Refactor CommentInfo.Kind to use CommentKind enum This patch replaces the raw SmallString<16> `Kind` field in `CommentInfo` with a strongly typed enum `CommentKind`. This improves type safety, allows compiler-checked switch handling, and removes the reliance on string comparisons across the clang-doc codebase. --- clang-tools-extra/clang-doc/BitcodeReader.cpp | 9 ++- clang-tools-extra/clang-doc/BitcodeWriter.cpp | 3 +- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 74 ++- .../clang-doc/HTMLMustacheGenerator.cpp | 12 +-- clang-tools-extra/clang-doc/MDGenerator.cpp | 59 ++- .../clang-doc/Representation.cpp | 60 +++ clang-tools-extra/clang-doc/Representation.h | 33 +++-- clang-tools-extra/clang-doc/Serialize.cpp | 2 +- clang-tools-extra/clang-doc/YAMLGenerator.cpp | 20 - 9 files changed, 201 insertions(+), 71 deletions(-) diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp index f8e338eb7c6ed..2e5d402106547 100644 --- a/clang-tools-extra/clang-doc/BitcodeReader.cpp +++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp @@ -315,8 +315,13 @@ static llvm::Error parseRecord(const Record &R, unsigned ID, static llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, CommentInfo *I) { switch (ID) { - case COMMENT_KIND: -return decodeRecord(R, I->Kind, Blob); + case COMMENT_KIND: { +llvm::SmallString<16> KindStr; +if (llvm::Error Err = decodeRecord(R, KindStr, Blob)) + return Err; +I->Kind = stringToCommentKind(KindStr); +return llvm::Error::success(); + } case COMMENT_TEXT: return decodeRecord(R, I->Text, Blob); case COMMENT_NAME: diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.cpp b/clang-tools-extra/clang-doc/BitcodeWriter.cpp index f0a445e606bff..efd60fdc2ec76 100644 --- a/clang-tools-extra/clang-doc/BitcodeWriter.cpp +++ b/clang-tools-extra/clang-doc/BitcodeWriter.cpp @@ -484,8 +484,9 @@ void ClangDocBitcodeWriter::emitBlock(const MemberTypeInfo &T) { void ClangDocBitcodeWriter::emitBlock(const CommentInfo &I) { StreamSubBlockGuard Block(Stream, BI_COMMENT_BLOCK_ID); + // Handle Kind (enum) separately, since it is not a string. + emitRecord(commentKindToString(I.Kind), COMMENT_KIND); for (const auto &L : std::vector>{ - {I.Kind, COMMENT_KIND}, {I.Text, COMMENT_TEXT}, {I.Name, COMMENT_NAME}, {I.Direction, COMMENT_DIRECTION}, diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index 93b9279462a89..eb7bfb842589b 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -635,47 +635,53 @@ genHTML(const Index &Index, StringRef InfoPath, bool IsOutermostList) { } static std::unique_ptr genHTML(const CommentInfo &I) { - if (I.Kind == "FullComment") { -auto FullComment = std::make_unique(HTMLTag::TAG_DIV); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child); - if (Node) -FullComment->Children.emplace_back(std::move(Node)); + switch (I.Kind) { +case CommentKind::CK_FullComment: { + auto FullComment = std::make_unique(HTMLTag::TAG_DIV); + for (const auto &Child : I.Children) { +std::unique_ptr Node = genHTML(*Child); +if (Node) + FullComment->Children.emplace_back(std::move(Node)); + } + return std::move(FullComment); } -return std::move(FullComment); - } - if (I.Kind == "ParagraphComment") { -auto ParagraphComment = std::make_unique(HTMLTag::TAG_P); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child); - if (Node) -ParagraphComment->Children.emplace_back(std::move(Node)); +case CommentKind::CK_ParagraphComment: { + auto ParagraphComment = std::make_unique(HTMLTag::TAG_P); + for (const auto &Child : I.Children) { +std::unique_ptr Node = genHTML(*Child); +if (Node) + ParagraphComment->Children.emplace_back(std::move(Node)); + } + if (ParagraphComment->Children.empty()) +return nullptr; + return std::move(ParagraphComment); } -if (ParagraphComment->Children.empty()) - return nullptr; -return std::move(ParagraphComment); - } - if (I.Kind == "BlockCommandComment") { -auto BlockComment = std::make_unique(HTMLTag::TAG_DIV); -BlockComment->Children.emplace_back( -std::make_unique(HTMLTag::TAG_DIV, I.Name)); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child
[clang-tools-extra] Refactor clang doc comment structure (PR #142273)
https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/142273 >From cd99fbe06a384db3775d1fc8c923275df07d4db3 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Sat, 31 May 2025 10:05:52 -0400 Subject: [PATCH 1/7] [clang-doc] Refactor CommentInfo.Kind to use CommentKind enum This patch replaces the raw SmallString<16> `Kind` field in `CommentInfo` with a strongly typed enum `CommentKind`. This improves type safety, allows compiler-checked switch handling, and removes the reliance on string comparisons across the clang-doc codebase. --- clang-tools-extra/clang-doc/BitcodeReader.cpp | 9 ++- clang-tools-extra/clang-doc/BitcodeWriter.cpp | 3 +- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 74 ++- .../clang-doc/HTMLMustacheGenerator.cpp | 12 +-- clang-tools-extra/clang-doc/MDGenerator.cpp | 59 ++- .../clang-doc/Representation.cpp | 60 +++ clang-tools-extra/clang-doc/Representation.h | 33 +++-- clang-tools-extra/clang-doc/Serialize.cpp | 2 +- clang-tools-extra/clang-doc/YAMLGenerator.cpp | 20 - 9 files changed, 201 insertions(+), 71 deletions(-) diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp index f8e338eb7c6ed..2e5d402106547 100644 --- a/clang-tools-extra/clang-doc/BitcodeReader.cpp +++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp @@ -315,8 +315,13 @@ static llvm::Error parseRecord(const Record &R, unsigned ID, static llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, CommentInfo *I) { switch (ID) { - case COMMENT_KIND: -return decodeRecord(R, I->Kind, Blob); + case COMMENT_KIND: { +llvm::SmallString<16> KindStr; +if (llvm::Error Err = decodeRecord(R, KindStr, Blob)) + return Err; +I->Kind = stringToCommentKind(KindStr); +return llvm::Error::success(); + } case COMMENT_TEXT: return decodeRecord(R, I->Text, Blob); case COMMENT_NAME: diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.cpp b/clang-tools-extra/clang-doc/BitcodeWriter.cpp index f0a445e606bff..efd60fdc2ec76 100644 --- a/clang-tools-extra/clang-doc/BitcodeWriter.cpp +++ b/clang-tools-extra/clang-doc/BitcodeWriter.cpp @@ -484,8 +484,9 @@ void ClangDocBitcodeWriter::emitBlock(const MemberTypeInfo &T) { void ClangDocBitcodeWriter::emitBlock(const CommentInfo &I) { StreamSubBlockGuard Block(Stream, BI_COMMENT_BLOCK_ID); + // Handle Kind (enum) separately, since it is not a string. + emitRecord(commentKindToString(I.Kind), COMMENT_KIND); for (const auto &L : std::vector>{ - {I.Kind, COMMENT_KIND}, {I.Text, COMMENT_TEXT}, {I.Name, COMMENT_NAME}, {I.Direction, COMMENT_DIRECTION}, diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index 93b9279462a89..eb7bfb842589b 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -635,47 +635,53 @@ genHTML(const Index &Index, StringRef InfoPath, bool IsOutermostList) { } static std::unique_ptr genHTML(const CommentInfo &I) { - if (I.Kind == "FullComment") { -auto FullComment = std::make_unique(HTMLTag::TAG_DIV); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child); - if (Node) -FullComment->Children.emplace_back(std::move(Node)); + switch (I.Kind) { +case CommentKind::CK_FullComment: { + auto FullComment = std::make_unique(HTMLTag::TAG_DIV); + for (const auto &Child : I.Children) { +std::unique_ptr Node = genHTML(*Child); +if (Node) + FullComment->Children.emplace_back(std::move(Node)); + } + return std::move(FullComment); } -return std::move(FullComment); - } - if (I.Kind == "ParagraphComment") { -auto ParagraphComment = std::make_unique(HTMLTag::TAG_P); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child); - if (Node) -ParagraphComment->Children.emplace_back(std::move(Node)); +case CommentKind::CK_ParagraphComment: { + auto ParagraphComment = std::make_unique(HTMLTag::TAG_P); + for (const auto &Child : I.Children) { +std::unique_ptr Node = genHTML(*Child); +if (Node) + ParagraphComment->Children.emplace_back(std::move(Node)); + } + if (ParagraphComment->Children.empty()) +return nullptr; + return std::move(ParagraphComment); } -if (ParagraphComment->Children.empty()) - return nullptr; -return std::move(ParagraphComment); - } - if (I.Kind == "BlockCommandComment") { -auto BlockComment = std::make_unique(HTMLTag::TAG_DIV); -BlockComment->Children.emplace_back( -std::make_unique(HTMLTag::TAG_DIV, I.Name)); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child
[clang-tools-extra] Refactor clang doc comment structure (PR #142273)
https://github.com/snarang181 created https://github.com/llvm/llvm-project/pull/142273 None >From 725dd21adcd2f776b2e6adc648e3038812059bf3 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Sat, 31 May 2025 10:05:52 -0400 Subject: [PATCH 1/2] [clang-doc] Refactor CommentInfo.Kind to use CommentKind enum This patch replaces the raw SmallString<16> `Kind` field in `CommentInfo` with a strongly typed enum `CommentKind`. This improves type safety, allows compiler-checked switch handling, and removes the reliance on string comparisons across the clang-doc codebase. --- clang-tools-extra/clang-doc/BitcodeReader.cpp | 9 ++- clang-tools-extra/clang-doc/BitcodeWriter.cpp | 3 +- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 74 ++- .../clang-doc/HTMLMustacheGenerator.cpp | 12 +-- clang-tools-extra/clang-doc/MDGenerator.cpp | 59 ++- .../clang-doc/Representation.cpp | 60 +++ clang-tools-extra/clang-doc/Representation.h | 33 +++-- clang-tools-extra/clang-doc/Serialize.cpp | 2 +- clang-tools-extra/clang-doc/YAMLGenerator.cpp | 20 - 9 files changed, 201 insertions(+), 71 deletions(-) diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp index f8e338eb7c6ed..2e5d402106547 100644 --- a/clang-tools-extra/clang-doc/BitcodeReader.cpp +++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp @@ -315,8 +315,13 @@ static llvm::Error parseRecord(const Record &R, unsigned ID, static llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, CommentInfo *I) { switch (ID) { - case COMMENT_KIND: -return decodeRecord(R, I->Kind, Blob); + case COMMENT_KIND: { +llvm::SmallString<16> KindStr; +if (llvm::Error Err = decodeRecord(R, KindStr, Blob)) + return Err; +I->Kind = stringToCommentKind(KindStr); +return llvm::Error::success(); + } case COMMENT_TEXT: return decodeRecord(R, I->Text, Blob); case COMMENT_NAME: diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.cpp b/clang-tools-extra/clang-doc/BitcodeWriter.cpp index f0a445e606bff..efd60fdc2ec76 100644 --- a/clang-tools-extra/clang-doc/BitcodeWriter.cpp +++ b/clang-tools-extra/clang-doc/BitcodeWriter.cpp @@ -484,8 +484,9 @@ void ClangDocBitcodeWriter::emitBlock(const MemberTypeInfo &T) { void ClangDocBitcodeWriter::emitBlock(const CommentInfo &I) { StreamSubBlockGuard Block(Stream, BI_COMMENT_BLOCK_ID); + // Handle Kind (enum) separately, since it is not a string. + emitRecord(commentKindToString(I.Kind), COMMENT_KIND); for (const auto &L : std::vector>{ - {I.Kind, COMMENT_KIND}, {I.Text, COMMENT_TEXT}, {I.Name, COMMENT_NAME}, {I.Direction, COMMENT_DIRECTION}, diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index 93b9279462a89..eb7bfb842589b 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -635,47 +635,53 @@ genHTML(const Index &Index, StringRef InfoPath, bool IsOutermostList) { } static std::unique_ptr genHTML(const CommentInfo &I) { - if (I.Kind == "FullComment") { -auto FullComment = std::make_unique(HTMLTag::TAG_DIV); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child); - if (Node) -FullComment->Children.emplace_back(std::move(Node)); + switch (I.Kind) { +case CommentKind::CK_FullComment: { + auto FullComment = std::make_unique(HTMLTag::TAG_DIV); + for (const auto &Child : I.Children) { +std::unique_ptr Node = genHTML(*Child); +if (Node) + FullComment->Children.emplace_back(std::move(Node)); + } + return std::move(FullComment); } -return std::move(FullComment); - } - if (I.Kind == "ParagraphComment") { -auto ParagraphComment = std::make_unique(HTMLTag::TAG_P); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child); - if (Node) -ParagraphComment->Children.emplace_back(std::move(Node)); +case CommentKind::CK_ParagraphComment: { + auto ParagraphComment = std::make_unique(HTMLTag::TAG_P); + for (const auto &Child : I.Children) { +std::unique_ptr Node = genHTML(*Child); +if (Node) + ParagraphComment->Children.emplace_back(std::move(Node)); + } + if (ParagraphComment->Children.empty()) +return nullptr; + return std::move(ParagraphComment); } -if (ParagraphComment->Children.empty()) - return nullptr; -return std::move(ParagraphComment); - } - if (I.Kind == "BlockCommandComment") { -auto BlockComment = std::make_unique(HTMLTag::TAG_DIV); -BlockComment->Children.emplace_back( -std::make_unique(HTMLTag::TAG_DIV, I.Name)); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(
[clang-tools-extra] Refactor clang doc comment structure (PR #142273)
https://github.com/snarang181 edited https://github.com/llvm/llvm-project/pull/142273 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
snarang181 wrote: @ilovepi, thanks for the patience and taking out the time to give detailed reviews. I will work on addresing your comments. One word on the tests: I was trying to test some of the other fail conditions but seems like a lot of the error conditions are caught by the parsing early on and do not actually invoke our error handler (like the current existing test case). Would adding those cases be OK regardless? Even though this patch does not directly address those issues. In that vein, it might be better to add `clang-doc` tests as part of a different PR, and I will be happy to work on that follow up too. Let me know what you think. https://github.com/llvm/llvm-project/pull/141699 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
@@ -284,10 +284,7 @@ Example usage for a project using a compile commands database: {UserStylesheets.begin(), UserStylesheets.end()}}; if (Format == "html") { -if (auto Err = getHtmlAssetFiles(argv[0], CDCtx)) { - llvm::errs() << toString(std::move(Err)) << "\n"; - return 1; -} +ExitOnErr(getHtmlAssetFiles(argv[0], CDCtx)); } snarang181 wrote: I am not familiar with this, will have to look into it. https://github.com/llvm/llvm-project/pull/141699 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/141699 >From b2dc4f8a50d86ecdc5fd27fedd7efde5c6882df5 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Tue, 27 May 2025 21:32:41 -0400 Subject: [PATCH 1/7] [clang-doc] Refactor error handling to use ExitOnError This patch replaces manual error checks and exit() calls in clang-doc with llvm::ExitOnError for consistency and maintainability. No functional changes to outputs or APIs. --- .../clang-doc/tool/ClangDocMain.cpp | 32 ++- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp index 8e8f7053a8f87..e7efa4b15d80f 100644 --- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -49,6 +49,7 @@ using namespace clang::ast_matchers; using namespace clang::tooling; using namespace clang; +static llvm::ExitOnError ExitOnErr; static llvm::cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); static llvm::cl::OptionCategory ClangDocCategory("clang-doc options"); @@ -236,6 +237,8 @@ int main(int argc, const char **argv) { llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); std::error_code OK; + ExitOnErr.setBanner("clang-doc error: "); + const char *Overview = R"(Generates documentation from source code and comments. @@ -259,11 +262,7 @@ Example usage for a project using a compile commands database: // Fail early if an invalid format was provided. std::string Format = getFormatString(); llvm::outs() << "Emiting docs in " << Format << " format.\n"; - auto G = doc::findGeneratorByName(Format); - if (!G) { -llvm::errs() << toString(G.takeError()) << "\n"; -return 1; - } + auto G = ExitOnErr(doc::findGeneratorByName(Format)); ArgumentsAdjuster ArgAdjuster; if (!DoxygenOnly) @@ -284,10 +283,7 @@ Example usage for a project using a compile commands database: {UserStylesheets.begin(), UserStylesheets.end()}}; if (Format == "html") { -if (auto Err = getHtmlAssetFiles(argv[0], CDCtx)) { - llvm::errs() << toString(std::move(Err)) << "\n"; - return 1; -} +ExitOnErr(getHtmlAssetFiles(argv[0], CDCtx)); } // Mapping phase @@ -300,7 +296,7 @@ Example usage for a project using a compile commands database: "these files and continue:\n" << toString(std::move(Err)) << "\n"; else { - llvm::errs() << toString(std::move(Err)) << "\n"; + ExitOnErr(std::move(Err)); return 1; } } @@ -371,22 +367,14 @@ Example usage for a project using a compile commands database: sortUsrToInfo(USRToInfo); // Ensure the root output directory exists. - if (std::error_code Err = llvm::sys::fs::create_directories(OutDirectory); - Err != std::error_code()) { -llvm::errs() << "Failed to create directory '" << OutDirectory << "'\n"; -return 1; - } + ExitOnErr( + llvm::errorCodeToError(llvm::sys::fs::create_directories(OutDirectory))); // Run the generator. llvm::outs() << "Generating docs...\n"; - if (auto Err = - G->get()->generateDocs(OutDirectory, std::move(USRToInfo), CDCtx)) { -llvm::errs() << toString(std::move(Err)) << "\n"; -return 1; - } - + ExitOnErr(G->generateDocs(OutDirectory, std::move(USRToInfo), CDCtx)); llvm::outs() << "Generating assets for docs...\n"; - Err = G->get()->createResources(CDCtx); + Err = G->createResources(CDCtx); if (Err) { llvm::outs() << "warning: " << toString(std::move(Err)) << "\n"; } >From 51238bcaf1a6450eb2b7dfbc259a1d7c4bba0a17 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Wed, 28 May 2025 18:47:17 -0400 Subject: [PATCH 2/7] Addressing PR feedback --- clang-tools-extra/clang-doc/tool/ClangDocMain.cpp| 12 +--- .../test/clang-doc/invalid-file-error.test | 4 2 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 clang-tools-extra/test/clang-doc/invalid-file-error.test diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp index e7efa4b15d80f..78ad1521397e6 100644 --- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -49,7 +49,6 @@ using namespace clang::ast_matchers; using namespace clang::tooling; using namespace clang; -static llvm::ExitOnError ExitOnErr; static llvm::cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); static llvm::cl::OptionCategory ClangDocCategory("clang-doc options"); @@ -128,6 +127,8 @@ static llvm::cl::opt llvm::cl::init(OutputFormatTy::yaml), llvm::cl::cat(ClangDocCategory)); +static llvm::ExitOnError ExitOnErr; + static std::string getFormatString() { switch (FormatEnum) { case OutputFormatTy::yaml: @@ -367,8 +368,13 @@ Example usage for a
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
@@ -300,7 +297,7 @@ Example usage for a project using a compile commands database: "these files and continue:\n" << toString(std::move(Err)) << "\n"; else { - llvm::errs() << toString(std::move(Err)) << "\n"; snarang181 wrote: Sounds like a good refactoring practice, but do we have enough usecases? I suppose if it's just two calls, I doubt if the code size increase + extra function call is worth it? https://github.com/llvm/llvm-project/pull/141699 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
snarang181 wrote: Also, from the CI test run, I see the Linux build failing. This seems unrelated, right? Does it warrant a rerun? ``` /home/gha/actions-runner/_work/llvm-project/llvm-project/libc/test/src/math/smoke/HypotTest.h:31: FAILURE Failed to match aNaN against LIBC_NAMESPACE::testing::getMatcher< LIBC_NAMESPACE::testing::TestCond::EQ>(func(sNaN, neg_inf)). Expected floating point value: (+Infinity) Actual floating point value: (NaN) [ FAILED ] LlvmLibcHypotf16Test.SpecialNumbers Ran 1 tests. PASS: 0 FAIL: 1/home/gha/actions-runner/_work/llvm-project/llvm-project/libc/test/src/math/smoke/HypotTest.h:31: FAILURE Failed to match aNaN against LIBC_NAMESPACE::testing::getMatcher< LIBC_NAMESPACE::testing::TestCond::EQ>(func(sNaN, neg_inf)). Expected floating point value: (+Infinity) Actual floating point value: (NaN) [ FAILED ] LlvmLibcHypotf16Test.SpecialNumbers Ran 1 tests. PASS: 0 FAIL: 1 ``` https://github.com/llvm/llvm-project/pull/141699 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
@@ -0,0 +1,12 @@ +// Test: Invalid output path (%t is a file, not a directory) snarang181 wrote: Thanks for the pointer. https://github.com/llvm/llvm-project/pull/141699 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
@@ -0,0 +1,12 @@ +// Test: Invalid output path (%t is a file, not a directory) +// RUN: rm -rf %t && echo "not a dir" > %t +// RUN: not clang-doc %s -output=%t/subdir 2>&1 | FileCheck --check-prefix=BAD-OUTPUT %s + +// BAD-OUTPUT: clang-doc error: +// BAD-OUTPUT: {{(Not a directory|no such file or directory)}} + +// +// Test: Invalid format option +// RUN: not clang-doc %s -format=badformat 2>&1 | FileCheck --check-prefix=BAD-FORMAT %s snarang181 wrote: Thanks for letting me know. https://github.com/llvm/llvm-project/pull/141699 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
@@ -371,22 +368,15 @@ Example usage for a project using a compile commands database: sortUsrToInfo(USRToInfo); // Ensure the root output directory exists. - if (std::error_code Err = llvm::sys::fs::create_directories(OutDirectory); - Err != std::error_code()) { -llvm::errs() << "Failed to create directory '" << OutDirectory << "'\n"; -return 1; + if (std::error_code Err = llvm::sys::fs::create_directories(OutDirectory)) { +ExitOnErr(llvm::createFileError(OutDirectory, Err)); } // Run the generator. llvm::outs() << "Generating docs...\n"; - if (auto Err = - G->get()->generateDocs(OutDirectory, std::move(USRToInfo), CDCtx)) { -llvm::errs() << toString(std::move(Err)) << "\n"; -return 1; - } - + ExitOnErr(G->generateDocs(OutDirectory, std::move(USRToInfo), CDCtx)); llvm::outs() << "Generating assets for docs...\n"; - Err = G->get()->createResources(CDCtx); + Err = G->createResources(CDCtx); snarang181 wrote: I will try this out. https://github.com/llvm/llvm-project/pull/141699 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
https://github.com/snarang181 edited https://github.com/llvm/llvm-project/pull/141699 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
@@ -0,0 +1,12 @@ +// Test: Invalid output path (%t is a file, not a directory) +// RUN: rm -rf %t && echo "not a dir" > %t +// RUN: not clang-doc %s -output=%t/subdir 2>&1 | FileCheck --check-prefix=BAD-OUTPUT %s + +// BAD-OUTPUT: clang-doc error: +// BAD-OUTPUT: {{(Not a directory|no such file or directory)}} snarang181 wrote: Makes sense. https://github.com/llvm/llvm-project/pull/141699 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
@@ -373,20 +370,16 @@ Example usage for a project using a compile commands database: // Ensure the root output directory exists. if (std::error_code Err = llvm::sys::fs::create_directories(OutDirectory); Err != std::error_code()) { -llvm::errs() << "Failed to create directory '" << OutDirectory << "'\n"; -return 1; +ExitOnErr(llvm::createStringError( +llvm::inconvertibleErrorCode(), "Failed to create directory '%s': %s", snarang181 wrote: You're right, the `createFileError() API` seems like a good fit. https://github.com/llvm/llvm-project/pull/141699 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/141699 >From b2dc4f8a50d86ecdc5fd27fedd7efde5c6882df5 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Tue, 27 May 2025 21:32:41 -0400 Subject: [PATCH 1/6] [clang-doc] Refactor error handling to use ExitOnError This patch replaces manual error checks and exit() calls in clang-doc with llvm::ExitOnError for consistency and maintainability. No functional changes to outputs or APIs. --- .../clang-doc/tool/ClangDocMain.cpp | 32 ++- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp index 8e8f7053a8f87..e7efa4b15d80f 100644 --- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -49,6 +49,7 @@ using namespace clang::ast_matchers; using namespace clang::tooling; using namespace clang; +static llvm::ExitOnError ExitOnErr; static llvm::cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); static llvm::cl::OptionCategory ClangDocCategory("clang-doc options"); @@ -236,6 +237,8 @@ int main(int argc, const char **argv) { llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); std::error_code OK; + ExitOnErr.setBanner("clang-doc error: "); + const char *Overview = R"(Generates documentation from source code and comments. @@ -259,11 +262,7 @@ Example usage for a project using a compile commands database: // Fail early if an invalid format was provided. std::string Format = getFormatString(); llvm::outs() << "Emiting docs in " << Format << " format.\n"; - auto G = doc::findGeneratorByName(Format); - if (!G) { -llvm::errs() << toString(G.takeError()) << "\n"; -return 1; - } + auto G = ExitOnErr(doc::findGeneratorByName(Format)); ArgumentsAdjuster ArgAdjuster; if (!DoxygenOnly) @@ -284,10 +283,7 @@ Example usage for a project using a compile commands database: {UserStylesheets.begin(), UserStylesheets.end()}}; if (Format == "html") { -if (auto Err = getHtmlAssetFiles(argv[0], CDCtx)) { - llvm::errs() << toString(std::move(Err)) << "\n"; - return 1; -} +ExitOnErr(getHtmlAssetFiles(argv[0], CDCtx)); } // Mapping phase @@ -300,7 +296,7 @@ Example usage for a project using a compile commands database: "these files and continue:\n" << toString(std::move(Err)) << "\n"; else { - llvm::errs() << toString(std::move(Err)) << "\n"; + ExitOnErr(std::move(Err)); return 1; } } @@ -371,22 +367,14 @@ Example usage for a project using a compile commands database: sortUsrToInfo(USRToInfo); // Ensure the root output directory exists. - if (std::error_code Err = llvm::sys::fs::create_directories(OutDirectory); - Err != std::error_code()) { -llvm::errs() << "Failed to create directory '" << OutDirectory << "'\n"; -return 1; - } + ExitOnErr( + llvm::errorCodeToError(llvm::sys::fs::create_directories(OutDirectory))); // Run the generator. llvm::outs() << "Generating docs...\n"; - if (auto Err = - G->get()->generateDocs(OutDirectory, std::move(USRToInfo), CDCtx)) { -llvm::errs() << toString(std::move(Err)) << "\n"; -return 1; - } - + ExitOnErr(G->generateDocs(OutDirectory, std::move(USRToInfo), CDCtx)); llvm::outs() << "Generating assets for docs...\n"; - Err = G->get()->createResources(CDCtx); + Err = G->createResources(CDCtx); if (Err) { llvm::outs() << "warning: " << toString(std::move(Err)) << "\n"; } >From 51238bcaf1a6450eb2b7dfbc259a1d7c4bba0a17 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Wed, 28 May 2025 18:47:17 -0400 Subject: [PATCH 2/6] Addressing PR feedback --- clang-tools-extra/clang-doc/tool/ClangDocMain.cpp| 12 +--- .../test/clang-doc/invalid-file-error.test | 4 2 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 clang-tools-extra/test/clang-doc/invalid-file-error.test diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp index e7efa4b15d80f..78ad1521397e6 100644 --- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -49,7 +49,6 @@ using namespace clang::ast_matchers; using namespace clang::tooling; using namespace clang; -static llvm::ExitOnError ExitOnErr; static llvm::cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); static llvm::cl::OptionCategory ClangDocCategory("clang-doc options"); @@ -128,6 +127,8 @@ static llvm::cl::opt llvm::cl::init(OutputFormatTy::yaml), llvm::cl::cat(ClangDocCategory)); +static llvm::ExitOnError ExitOnErr; + static std::string getFormatString() { switch (FormatEnum) { case OutputFormatTy::yaml: @@ -367,8 +368,13 @@ Example usage for a
[clang-tools-extra] [clang-doc] Refactor error handling to use ExitOnError (PR #141699)
snarang181 wrote: @ilovepi -- In the updated version, I have used the `createFileError()` API and checked that the output is reliable. Also, I have renamed the lit test file; in the tests, I create a temporary file using `%t` and then obviously, it cannot create a directory there. Hopefully that is a reliable way of testing and we are not hardcoding any paths like `/root` or `/dev` which are not portable, also not changing permissions, which you were concerned about. The second test I have added in the test file is of a bad format option; however, the `ExitOnErr` handler never gets invoked because I believe this is parsed earlier and reported as an error already. https://github.com/llvm/llvm-project/pull/141699 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Refactor clang doc comment structure (PR #142273)
https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/142273 >From 725dd21adcd2f776b2e6adc648e3038812059bf3 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Sat, 31 May 2025 10:05:52 -0400 Subject: [PATCH 1/4] [clang-doc] Refactor CommentInfo.Kind to use CommentKind enum This patch replaces the raw SmallString<16> `Kind` field in `CommentInfo` with a strongly typed enum `CommentKind`. This improves type safety, allows compiler-checked switch handling, and removes the reliance on string comparisons across the clang-doc codebase. --- clang-tools-extra/clang-doc/BitcodeReader.cpp | 9 ++- clang-tools-extra/clang-doc/BitcodeWriter.cpp | 3 +- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 74 ++- .../clang-doc/HTMLMustacheGenerator.cpp | 12 +-- clang-tools-extra/clang-doc/MDGenerator.cpp | 59 ++- .../clang-doc/Representation.cpp | 60 +++ clang-tools-extra/clang-doc/Representation.h | 33 +++-- clang-tools-extra/clang-doc/Serialize.cpp | 2 +- clang-tools-extra/clang-doc/YAMLGenerator.cpp | 20 - 9 files changed, 201 insertions(+), 71 deletions(-) diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp index f8e338eb7c6ed..2e5d402106547 100644 --- a/clang-tools-extra/clang-doc/BitcodeReader.cpp +++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp @@ -315,8 +315,13 @@ static llvm::Error parseRecord(const Record &R, unsigned ID, static llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, CommentInfo *I) { switch (ID) { - case COMMENT_KIND: -return decodeRecord(R, I->Kind, Blob); + case COMMENT_KIND: { +llvm::SmallString<16> KindStr; +if (llvm::Error Err = decodeRecord(R, KindStr, Blob)) + return Err; +I->Kind = stringToCommentKind(KindStr); +return llvm::Error::success(); + } case COMMENT_TEXT: return decodeRecord(R, I->Text, Blob); case COMMENT_NAME: diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.cpp b/clang-tools-extra/clang-doc/BitcodeWriter.cpp index f0a445e606bff..efd60fdc2ec76 100644 --- a/clang-tools-extra/clang-doc/BitcodeWriter.cpp +++ b/clang-tools-extra/clang-doc/BitcodeWriter.cpp @@ -484,8 +484,9 @@ void ClangDocBitcodeWriter::emitBlock(const MemberTypeInfo &T) { void ClangDocBitcodeWriter::emitBlock(const CommentInfo &I) { StreamSubBlockGuard Block(Stream, BI_COMMENT_BLOCK_ID); + // Handle Kind (enum) separately, since it is not a string. + emitRecord(commentKindToString(I.Kind), COMMENT_KIND); for (const auto &L : std::vector>{ - {I.Kind, COMMENT_KIND}, {I.Text, COMMENT_TEXT}, {I.Name, COMMENT_NAME}, {I.Direction, COMMENT_DIRECTION}, diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index 93b9279462a89..eb7bfb842589b 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -635,47 +635,53 @@ genHTML(const Index &Index, StringRef InfoPath, bool IsOutermostList) { } static std::unique_ptr genHTML(const CommentInfo &I) { - if (I.Kind == "FullComment") { -auto FullComment = std::make_unique(HTMLTag::TAG_DIV); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child); - if (Node) -FullComment->Children.emplace_back(std::move(Node)); + switch (I.Kind) { +case CommentKind::CK_FullComment: { + auto FullComment = std::make_unique(HTMLTag::TAG_DIV); + for (const auto &Child : I.Children) { +std::unique_ptr Node = genHTML(*Child); +if (Node) + FullComment->Children.emplace_back(std::move(Node)); + } + return std::move(FullComment); } -return std::move(FullComment); - } - if (I.Kind == "ParagraphComment") { -auto ParagraphComment = std::make_unique(HTMLTag::TAG_P); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child); - if (Node) -ParagraphComment->Children.emplace_back(std::move(Node)); +case CommentKind::CK_ParagraphComment: { + auto ParagraphComment = std::make_unique(HTMLTag::TAG_P); + for (const auto &Child : I.Children) { +std::unique_ptr Node = genHTML(*Child); +if (Node) + ParagraphComment->Children.emplace_back(std::move(Node)); + } + if (ParagraphComment->Children.empty()) +return nullptr; + return std::move(ParagraphComment); } -if (ParagraphComment->Children.empty()) - return nullptr; -return std::move(ParagraphComment); - } - if (I.Kind == "BlockCommandComment") { -auto BlockComment = std::make_unique(HTMLTag::TAG_DIV); -BlockComment->Children.emplace_back( -std::make_unique(HTMLTag::TAG_DIV, I.Name)); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child
[clang-tools-extra] Refactor clang doc comment structure (PR #142273)
https://github.com/snarang181 ready_for_review https://github.com/llvm/llvm-project/pull/142273 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Refactor clang doc comment structure (PR #142273)
snarang181 wrote: @ilovepi, would be great to get your review here. https://github.com/llvm/llvm-project/pull/142273 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Refactor clang doc comment structure (PR #142273)
https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/142273 >From 725dd21adcd2f776b2e6adc648e3038812059bf3 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Sat, 31 May 2025 10:05:52 -0400 Subject: [PATCH 1/5] [clang-doc] Refactor CommentInfo.Kind to use CommentKind enum This patch replaces the raw SmallString<16> `Kind` field in `CommentInfo` with a strongly typed enum `CommentKind`. This improves type safety, allows compiler-checked switch handling, and removes the reliance on string comparisons across the clang-doc codebase. --- clang-tools-extra/clang-doc/BitcodeReader.cpp | 9 ++- clang-tools-extra/clang-doc/BitcodeWriter.cpp | 3 +- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 74 ++- .../clang-doc/HTMLMustacheGenerator.cpp | 12 +-- clang-tools-extra/clang-doc/MDGenerator.cpp | 59 ++- .../clang-doc/Representation.cpp | 60 +++ clang-tools-extra/clang-doc/Representation.h | 33 +++-- clang-tools-extra/clang-doc/Serialize.cpp | 2 +- clang-tools-extra/clang-doc/YAMLGenerator.cpp | 20 - 9 files changed, 201 insertions(+), 71 deletions(-) diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp index f8e338eb7c6ed..2e5d402106547 100644 --- a/clang-tools-extra/clang-doc/BitcodeReader.cpp +++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp @@ -315,8 +315,13 @@ static llvm::Error parseRecord(const Record &R, unsigned ID, static llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, CommentInfo *I) { switch (ID) { - case COMMENT_KIND: -return decodeRecord(R, I->Kind, Blob); + case COMMENT_KIND: { +llvm::SmallString<16> KindStr; +if (llvm::Error Err = decodeRecord(R, KindStr, Blob)) + return Err; +I->Kind = stringToCommentKind(KindStr); +return llvm::Error::success(); + } case COMMENT_TEXT: return decodeRecord(R, I->Text, Blob); case COMMENT_NAME: diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.cpp b/clang-tools-extra/clang-doc/BitcodeWriter.cpp index f0a445e606bff..efd60fdc2ec76 100644 --- a/clang-tools-extra/clang-doc/BitcodeWriter.cpp +++ b/clang-tools-extra/clang-doc/BitcodeWriter.cpp @@ -484,8 +484,9 @@ void ClangDocBitcodeWriter::emitBlock(const MemberTypeInfo &T) { void ClangDocBitcodeWriter::emitBlock(const CommentInfo &I) { StreamSubBlockGuard Block(Stream, BI_COMMENT_BLOCK_ID); + // Handle Kind (enum) separately, since it is not a string. + emitRecord(commentKindToString(I.Kind), COMMENT_KIND); for (const auto &L : std::vector>{ - {I.Kind, COMMENT_KIND}, {I.Text, COMMENT_TEXT}, {I.Name, COMMENT_NAME}, {I.Direction, COMMENT_DIRECTION}, diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index 93b9279462a89..eb7bfb842589b 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -635,47 +635,53 @@ genHTML(const Index &Index, StringRef InfoPath, bool IsOutermostList) { } static std::unique_ptr genHTML(const CommentInfo &I) { - if (I.Kind == "FullComment") { -auto FullComment = std::make_unique(HTMLTag::TAG_DIV); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child); - if (Node) -FullComment->Children.emplace_back(std::move(Node)); + switch (I.Kind) { +case CommentKind::CK_FullComment: { + auto FullComment = std::make_unique(HTMLTag::TAG_DIV); + for (const auto &Child : I.Children) { +std::unique_ptr Node = genHTML(*Child); +if (Node) + FullComment->Children.emplace_back(std::move(Node)); + } + return std::move(FullComment); } -return std::move(FullComment); - } - if (I.Kind == "ParagraphComment") { -auto ParagraphComment = std::make_unique(HTMLTag::TAG_P); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child); - if (Node) -ParagraphComment->Children.emplace_back(std::move(Node)); +case CommentKind::CK_ParagraphComment: { + auto ParagraphComment = std::make_unique(HTMLTag::TAG_P); + for (const auto &Child : I.Children) { +std::unique_ptr Node = genHTML(*Child); +if (Node) + ParagraphComment->Children.emplace_back(std::move(Node)); + } + if (ParagraphComment->Children.empty()) +return nullptr; + return std::move(ParagraphComment); } -if (ParagraphComment->Children.empty()) - return nullptr; -return std::move(ParagraphComment); - } - if (I.Kind == "BlockCommandComment") { -auto BlockComment = std::make_unique(HTMLTag::TAG_DIV); -BlockComment->Children.emplace_back( -std::make_unique(HTMLTag::TAG_DIV, I.Name)); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child
[clang-tools-extra] Refactor clang doc comment structure (PR #142273)
https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/142273 >From cd99fbe06a384db3775d1fc8c923275df07d4db3 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Sat, 31 May 2025 10:05:52 -0400 Subject: [PATCH 1/8] [clang-doc] Refactor CommentInfo.Kind to use CommentKind enum This patch replaces the raw SmallString<16> `Kind` field in `CommentInfo` with a strongly typed enum `CommentKind`. This improves type safety, allows compiler-checked switch handling, and removes the reliance on string comparisons across the clang-doc codebase. --- clang-tools-extra/clang-doc/BitcodeReader.cpp | 9 ++- clang-tools-extra/clang-doc/BitcodeWriter.cpp | 3 +- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 74 ++- .../clang-doc/HTMLMustacheGenerator.cpp | 12 +-- clang-tools-extra/clang-doc/MDGenerator.cpp | 59 ++- .../clang-doc/Representation.cpp | 60 +++ clang-tools-extra/clang-doc/Representation.h | 33 +++-- clang-tools-extra/clang-doc/Serialize.cpp | 2 +- clang-tools-extra/clang-doc/YAMLGenerator.cpp | 20 - 9 files changed, 201 insertions(+), 71 deletions(-) diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp index f8e338eb7c6ed..2e5d402106547 100644 --- a/clang-tools-extra/clang-doc/BitcodeReader.cpp +++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp @@ -315,8 +315,13 @@ static llvm::Error parseRecord(const Record &R, unsigned ID, static llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, CommentInfo *I) { switch (ID) { - case COMMENT_KIND: -return decodeRecord(R, I->Kind, Blob); + case COMMENT_KIND: { +llvm::SmallString<16> KindStr; +if (llvm::Error Err = decodeRecord(R, KindStr, Blob)) + return Err; +I->Kind = stringToCommentKind(KindStr); +return llvm::Error::success(); + } case COMMENT_TEXT: return decodeRecord(R, I->Text, Blob); case COMMENT_NAME: diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.cpp b/clang-tools-extra/clang-doc/BitcodeWriter.cpp index f0a445e606bff..efd60fdc2ec76 100644 --- a/clang-tools-extra/clang-doc/BitcodeWriter.cpp +++ b/clang-tools-extra/clang-doc/BitcodeWriter.cpp @@ -484,8 +484,9 @@ void ClangDocBitcodeWriter::emitBlock(const MemberTypeInfo &T) { void ClangDocBitcodeWriter::emitBlock(const CommentInfo &I) { StreamSubBlockGuard Block(Stream, BI_COMMENT_BLOCK_ID); + // Handle Kind (enum) separately, since it is not a string. + emitRecord(commentKindToString(I.Kind), COMMENT_KIND); for (const auto &L : std::vector>{ - {I.Kind, COMMENT_KIND}, {I.Text, COMMENT_TEXT}, {I.Name, COMMENT_NAME}, {I.Direction, COMMENT_DIRECTION}, diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index 93b9279462a89..eb7bfb842589b 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -635,47 +635,53 @@ genHTML(const Index &Index, StringRef InfoPath, bool IsOutermostList) { } static std::unique_ptr genHTML(const CommentInfo &I) { - if (I.Kind == "FullComment") { -auto FullComment = std::make_unique(HTMLTag::TAG_DIV); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child); - if (Node) -FullComment->Children.emplace_back(std::move(Node)); + switch (I.Kind) { +case CommentKind::CK_FullComment: { + auto FullComment = std::make_unique(HTMLTag::TAG_DIV); + for (const auto &Child : I.Children) { +std::unique_ptr Node = genHTML(*Child); +if (Node) + FullComment->Children.emplace_back(std::move(Node)); + } + return std::move(FullComment); } -return std::move(FullComment); - } - if (I.Kind == "ParagraphComment") { -auto ParagraphComment = std::make_unique(HTMLTag::TAG_P); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child); - if (Node) -ParagraphComment->Children.emplace_back(std::move(Node)); +case CommentKind::CK_ParagraphComment: { + auto ParagraphComment = std::make_unique(HTMLTag::TAG_P); + for (const auto &Child : I.Children) { +std::unique_ptr Node = genHTML(*Child); +if (Node) + ParagraphComment->Children.emplace_back(std::move(Node)); + } + if (ParagraphComment->Children.empty()) +return nullptr; + return std::move(ParagraphComment); } -if (ParagraphComment->Children.empty()) - return nullptr; -return std::move(ParagraphComment); - } - if (I.Kind == "BlockCommandComment") { -auto BlockComment = std::make_unique(HTMLTag::TAG_DIV); -BlockComment->Children.emplace_back( -std::make_unique(HTMLTag::TAG_DIV, I.Name)); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child
[clang-tools-extra] Refactor clang doc comment structure (PR #142273)
@@ -26,6 +26,66 @@ namespace clang { namespace doc { +CommentKind stringToCommentKind(llvm::StringRef KindStr) { + if (KindStr == "FullComment") +return CommentKind::CK_FullComment; snarang181 wrote: Updated the function to do a `StringMap` lookup. https://github.com/llvm/llvm-project/pull/142273 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clang-doc] [test] Generalize error message patterns (PR #142373)
https://github.com/snarang181 commented: Looks fine. But I see your point regarding portability, I'll think how we can modify this. https://github.com/llvm/llvm-project/pull/142373 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Refactor clang doc comment structure (PR #142273)
https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/142273 >From 51adbab1511e92c44925d20661ed86d2ab28dca0 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Sat, 31 May 2025 10:05:52 -0400 Subject: [PATCH 1/9] [clang-doc] Refactor CommentInfo.Kind to use CommentKind enum This patch replaces the raw SmallString<16> `Kind` field in `CommentInfo` with a strongly typed enum `CommentKind`. This improves type safety, allows compiler-checked switch handling, and removes the reliance on string comparisons across the clang-doc codebase. --- clang-tools-extra/clang-doc/BitcodeReader.cpp | 9 ++- clang-tools-extra/clang-doc/BitcodeWriter.cpp | 3 +- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 74 ++- .../clang-doc/HTMLMustacheGenerator.cpp | 12 +-- clang-tools-extra/clang-doc/MDGenerator.cpp | 59 ++- .../clang-doc/Representation.cpp | 60 +++ clang-tools-extra/clang-doc/Representation.h | 33 +++-- clang-tools-extra/clang-doc/Serialize.cpp | 2 +- clang-tools-extra/clang-doc/YAMLGenerator.cpp | 20 - 9 files changed, 201 insertions(+), 71 deletions(-) diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp index 546dd0254ec01..d15ca02c864f6 100644 --- a/clang-tools-extra/clang-doc/BitcodeReader.cpp +++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp @@ -316,8 +316,13 @@ static llvm::Error parseRecord(const Record &R, unsigned ID, static llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, CommentInfo *I) { switch (ID) { - case COMMENT_KIND: -return decodeRecord(R, I->Kind, Blob); + case COMMENT_KIND: { +llvm::SmallString<16> KindStr; +if (llvm::Error Err = decodeRecord(R, KindStr, Blob)) + return Err; +I->Kind = stringToCommentKind(KindStr); +return llvm::Error::success(); + } case COMMENT_TEXT: return decodeRecord(R, I->Text, Blob); case COMMENT_NAME: diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.cpp b/clang-tools-extra/clang-doc/BitcodeWriter.cpp index f0a445e606bff..efd60fdc2ec76 100644 --- a/clang-tools-extra/clang-doc/BitcodeWriter.cpp +++ b/clang-tools-extra/clang-doc/BitcodeWriter.cpp @@ -484,8 +484,9 @@ void ClangDocBitcodeWriter::emitBlock(const MemberTypeInfo &T) { void ClangDocBitcodeWriter::emitBlock(const CommentInfo &I) { StreamSubBlockGuard Block(Stream, BI_COMMENT_BLOCK_ID); + // Handle Kind (enum) separately, since it is not a string. + emitRecord(commentKindToString(I.Kind), COMMENT_KIND); for (const auto &L : std::vector>{ - {I.Kind, COMMENT_KIND}, {I.Text, COMMENT_TEXT}, {I.Name, COMMENT_NAME}, {I.Direction, COMMENT_DIRECTION}, diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index 93b9279462a89..eb7bfb842589b 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -635,47 +635,53 @@ genHTML(const Index &Index, StringRef InfoPath, bool IsOutermostList) { } static std::unique_ptr genHTML(const CommentInfo &I) { - if (I.Kind == "FullComment") { -auto FullComment = std::make_unique(HTMLTag::TAG_DIV); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child); - if (Node) -FullComment->Children.emplace_back(std::move(Node)); + switch (I.Kind) { +case CommentKind::CK_FullComment: { + auto FullComment = std::make_unique(HTMLTag::TAG_DIV); + for (const auto &Child : I.Children) { +std::unique_ptr Node = genHTML(*Child); +if (Node) + FullComment->Children.emplace_back(std::move(Node)); + } + return std::move(FullComment); } -return std::move(FullComment); - } - if (I.Kind == "ParagraphComment") { -auto ParagraphComment = std::make_unique(HTMLTag::TAG_P); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child); - if (Node) -ParagraphComment->Children.emplace_back(std::move(Node)); +case CommentKind::CK_ParagraphComment: { + auto ParagraphComment = std::make_unique(HTMLTag::TAG_P); + for (const auto &Child : I.Children) { +std::unique_ptr Node = genHTML(*Child); +if (Node) + ParagraphComment->Children.emplace_back(std::move(Node)); + } + if (ParagraphComment->Children.empty()) +return nullptr; + return std::move(ParagraphComment); } -if (ParagraphComment->Children.empty()) - return nullptr; -return std::move(ParagraphComment); - } - if (I.Kind == "BlockCommandComment") { -auto BlockComment = std::make_unique(HTMLTag::TAG_DIV); -BlockComment->Children.emplace_back( -std::make_unique(HTMLTag::TAG_DIV, I.Name)); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child
[clang-tools-extra] Refactor clang doc comment structure (PR #142273)
snarang181 wrote: Left a reply to this [comment](https://github.com/llvm/llvm-project/pull/142273/files#r2125020120) @ilovepi. Addressed some other comments. https://github.com/llvm/llvm-project/pull/142273 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Refactor clang doc comment structure (PR #142273)
https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/142273 >From 51adbab1511e92c44925d20661ed86d2ab28dca0 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Sat, 31 May 2025 10:05:52 -0400 Subject: [PATCH 01/10] [clang-doc] Refactor CommentInfo.Kind to use CommentKind enum This patch replaces the raw SmallString<16> `Kind` field in `CommentInfo` with a strongly typed enum `CommentKind`. This improves type safety, allows compiler-checked switch handling, and removes the reliance on string comparisons across the clang-doc codebase. --- clang-tools-extra/clang-doc/BitcodeReader.cpp | 9 ++- clang-tools-extra/clang-doc/BitcodeWriter.cpp | 3 +- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 74 ++- .../clang-doc/HTMLMustacheGenerator.cpp | 12 +-- clang-tools-extra/clang-doc/MDGenerator.cpp | 59 ++- .../clang-doc/Representation.cpp | 60 +++ clang-tools-extra/clang-doc/Representation.h | 33 +++-- clang-tools-extra/clang-doc/Serialize.cpp | 2 +- clang-tools-extra/clang-doc/YAMLGenerator.cpp | 20 - 9 files changed, 201 insertions(+), 71 deletions(-) diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp index 546dd0254ec01..d15ca02c864f6 100644 --- a/clang-tools-extra/clang-doc/BitcodeReader.cpp +++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp @@ -316,8 +316,13 @@ static llvm::Error parseRecord(const Record &R, unsigned ID, static llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, CommentInfo *I) { switch (ID) { - case COMMENT_KIND: -return decodeRecord(R, I->Kind, Blob); + case COMMENT_KIND: { +llvm::SmallString<16> KindStr; +if (llvm::Error Err = decodeRecord(R, KindStr, Blob)) + return Err; +I->Kind = stringToCommentKind(KindStr); +return llvm::Error::success(); + } case COMMENT_TEXT: return decodeRecord(R, I->Text, Blob); case COMMENT_NAME: diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.cpp b/clang-tools-extra/clang-doc/BitcodeWriter.cpp index f0a445e606bff..efd60fdc2ec76 100644 --- a/clang-tools-extra/clang-doc/BitcodeWriter.cpp +++ b/clang-tools-extra/clang-doc/BitcodeWriter.cpp @@ -484,8 +484,9 @@ void ClangDocBitcodeWriter::emitBlock(const MemberTypeInfo &T) { void ClangDocBitcodeWriter::emitBlock(const CommentInfo &I) { StreamSubBlockGuard Block(Stream, BI_COMMENT_BLOCK_ID); + // Handle Kind (enum) separately, since it is not a string. + emitRecord(commentKindToString(I.Kind), COMMENT_KIND); for (const auto &L : std::vector>{ - {I.Kind, COMMENT_KIND}, {I.Text, COMMENT_TEXT}, {I.Name, COMMENT_NAME}, {I.Direction, COMMENT_DIRECTION}, diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index 93b9279462a89..eb7bfb842589b 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -635,47 +635,53 @@ genHTML(const Index &Index, StringRef InfoPath, bool IsOutermostList) { } static std::unique_ptr genHTML(const CommentInfo &I) { - if (I.Kind == "FullComment") { -auto FullComment = std::make_unique(HTMLTag::TAG_DIV); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child); - if (Node) -FullComment->Children.emplace_back(std::move(Node)); + switch (I.Kind) { +case CommentKind::CK_FullComment: { + auto FullComment = std::make_unique(HTMLTag::TAG_DIV); + for (const auto &Child : I.Children) { +std::unique_ptr Node = genHTML(*Child); +if (Node) + FullComment->Children.emplace_back(std::move(Node)); + } + return std::move(FullComment); } -return std::move(FullComment); - } - if (I.Kind == "ParagraphComment") { -auto ParagraphComment = std::make_unique(HTMLTag::TAG_P); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child); - if (Node) -ParagraphComment->Children.emplace_back(std::move(Node)); +case CommentKind::CK_ParagraphComment: { + auto ParagraphComment = std::make_unique(HTMLTag::TAG_P); + for (const auto &Child : I.Children) { +std::unique_ptr Node = genHTML(*Child); +if (Node) + ParagraphComment->Children.emplace_back(std::move(Node)); + } + if (ParagraphComment->Children.empty()) +return nullptr; + return std::move(ParagraphComment); } -if (ParagraphComment->Children.empty()) - return nullptr; -return std::move(ParagraphComment); - } - if (I.Kind == "BlockCommandComment") { -auto BlockComment = std::make_unique(HTMLTag::TAG_DIV); -BlockComment->Children.emplace_back( -std::make_unique(HTMLTag::TAG_DIV, I.Name)); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Chi
[clang-tools-extra] [clang-doc] [test] Generalize error message patterns (PR #142373)
snarang181 wrote: @ilovepi, for this check, should we just be looking for "clang doc error: " and remove the directory substring matching entirely? https://github.com/llvm/llvm-project/pull/142373 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Refactor clang doc comment structure (PR #142273)
https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/142273 >From 6610faa1775c290fa44b0c498ac19ef26ad599ac Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Sat, 31 May 2025 10:05:52 -0400 Subject: [PATCH 01/13] [clang-doc] Refactor CommentInfo.Kind to use CommentKind enum This patch replaces the raw SmallString<16> `Kind` field in `CommentInfo` with a strongly typed enum `CommentKind`. This improves type safety, allows compiler-checked switch handling, and removes the reliance on string comparisons across the clang-doc codebase. --- clang-tools-extra/clang-doc/BitcodeReader.cpp | 9 ++- clang-tools-extra/clang-doc/BitcodeWriter.cpp | 3 +- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 74 ++- .../clang-doc/HTMLMustacheGenerator.cpp | 12 +-- clang-tools-extra/clang-doc/MDGenerator.cpp | 59 ++- .../clang-doc/Representation.cpp | 60 +++ clang-tools-extra/clang-doc/Representation.h | 33 +++-- clang-tools-extra/clang-doc/Serialize.cpp | 2 +- clang-tools-extra/clang-doc/YAMLGenerator.cpp | 20 - 9 files changed, 201 insertions(+), 71 deletions(-) diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp index 546dd0254ec01..d15ca02c864f6 100644 --- a/clang-tools-extra/clang-doc/BitcodeReader.cpp +++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp @@ -316,8 +316,13 @@ static llvm::Error parseRecord(const Record &R, unsigned ID, static llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, CommentInfo *I) { switch (ID) { - case COMMENT_KIND: -return decodeRecord(R, I->Kind, Blob); + case COMMENT_KIND: { +llvm::SmallString<16> KindStr; +if (llvm::Error Err = decodeRecord(R, KindStr, Blob)) + return Err; +I->Kind = stringToCommentKind(KindStr); +return llvm::Error::success(); + } case COMMENT_TEXT: return decodeRecord(R, I->Text, Blob); case COMMENT_NAME: diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.cpp b/clang-tools-extra/clang-doc/BitcodeWriter.cpp index f0a445e606bff..efd60fdc2ec76 100644 --- a/clang-tools-extra/clang-doc/BitcodeWriter.cpp +++ b/clang-tools-extra/clang-doc/BitcodeWriter.cpp @@ -484,8 +484,9 @@ void ClangDocBitcodeWriter::emitBlock(const MemberTypeInfo &T) { void ClangDocBitcodeWriter::emitBlock(const CommentInfo &I) { StreamSubBlockGuard Block(Stream, BI_COMMENT_BLOCK_ID); + // Handle Kind (enum) separately, since it is not a string. + emitRecord(commentKindToString(I.Kind), COMMENT_KIND); for (const auto &L : std::vector>{ - {I.Kind, COMMENT_KIND}, {I.Text, COMMENT_TEXT}, {I.Name, COMMENT_NAME}, {I.Direction, COMMENT_DIRECTION}, diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index 93b9279462a89..eb7bfb842589b 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -635,47 +635,53 @@ genHTML(const Index &Index, StringRef InfoPath, bool IsOutermostList) { } static std::unique_ptr genHTML(const CommentInfo &I) { - if (I.Kind == "FullComment") { -auto FullComment = std::make_unique(HTMLTag::TAG_DIV); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child); - if (Node) -FullComment->Children.emplace_back(std::move(Node)); + switch (I.Kind) { +case CommentKind::CK_FullComment: { + auto FullComment = std::make_unique(HTMLTag::TAG_DIV); + for (const auto &Child : I.Children) { +std::unique_ptr Node = genHTML(*Child); +if (Node) + FullComment->Children.emplace_back(std::move(Node)); + } + return std::move(FullComment); } -return std::move(FullComment); - } - if (I.Kind == "ParagraphComment") { -auto ParagraphComment = std::make_unique(HTMLTag::TAG_P); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child); - if (Node) -ParagraphComment->Children.emplace_back(std::move(Node)); +case CommentKind::CK_ParagraphComment: { + auto ParagraphComment = std::make_unique(HTMLTag::TAG_P); + for (const auto &Child : I.Children) { +std::unique_ptr Node = genHTML(*Child); +if (Node) + ParagraphComment->Children.emplace_back(std::move(Node)); + } + if (ParagraphComment->Children.empty()) +return nullptr; + return std::move(ParagraphComment); } -if (ParagraphComment->Children.empty()) - return nullptr; -return std::move(ParagraphComment); - } - if (I.Kind == "BlockCommandComment") { -auto BlockComment = std::make_unique(HTMLTag::TAG_DIV); -BlockComment->Children.emplace_back( -std::make_unique(HTMLTag::TAG_DIV, I.Name)); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Chi
[clang-tools-extra] Refactor clang doc comment structure (PR #142273)
snarang181 wrote: > LGTM once the last few nits are addressed. @ilovepi, for the last few nits, - Removed the `default` case in the switch, and manually returning `nullptr` for all the unhandled cases. - Removed the braces in the `case` of the `switch` and shifted the variable decl. inside outside the switch to get around the compiler errors. https://github.com/llvm/llvm-project/pull/142273 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Refactor clang doc comment structure (PR #142273)
snarang181 wrote: > LGTM. Thanks for the patch Awesome, feel free to merge when you see fit. I don't think I can do so myself. https://github.com/llvm/llvm-project/pull/142273 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Refactor clang doc comment structure (PR #142273)
snarang181 wrote: @ilovepi, this failure is probably related to the merged PR, right? https://github.com/llvm/llvm-project/pull/142273 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Replace loop with llvm:any_of (PR #143275)
https://github.com/snarang181 created https://github.com/llvm/llvm-project/pull/143275 None >From dc4e3c9afbef406ae1acbd572dfe9edd9d5efea3 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Sat, 7 Jun 2025 12:21:17 -0400 Subject: [PATCH] Replace loop with llvm:any_of --- clang/include/clang/AST/DeclContextInternals.h | 12 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/clang/include/clang/AST/DeclContextInternals.h b/clang/include/clang/AST/DeclContextInternals.h index b17b7627ac90c..a1071f62d5fae 100644 --- a/clang/include/clang/AST/DeclContextInternals.h +++ b/clang/include/clang/AST/DeclContextInternals.h @@ -176,14 +176,10 @@ class StoredDeclsList { DeclListNode::Decls *Tail = erase_if([Decls](NamedDecl *ND) { if (ND->isFromASTFile()) return true; - // FIXME: Can we get rid of this loop completely? - for (NamedDecl *D : Decls) -// Only replace the local declaration if the external declaration has -// higher visibilities. -if (D->getModuleOwnershipKind() <= ND->getModuleOwnershipKind() && -D->declarationReplaces(ND, /*IsKnownNewer=*/false)) - return true; - return false; + return llvm::any_of(Decls, [ND](NamedDecl *D) { +return D->getModuleOwnershipKind() <= ND->getModuleOwnershipKind() && + D->declarationReplaces(ND, /*IsKnownNewer=*/false); + }); }); // Don't have any pending external decls any more. ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Refactor replaceExternalDecls to use llvm::any_of (PR #143275)
https://github.com/snarang181 edited https://github.com/llvm/llvm-project/pull/143275 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Refactor replaceExternalDecls to use llvm::any_of (PR #143275)
https://github.com/snarang181 edited https://github.com/llvm/llvm-project/pull/143275 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][NFC] Refactor replaceExternalDecls to use llvm::any_of (PR #143275)
https://github.com/snarang181 edited https://github.com/llvm/llvm-project/pull/143275 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][NFC] Refactor replaceExternalDecls to use llvm::any_of (PR #143275)
https://github.com/snarang181 ready_for_review https://github.com/llvm/llvm-project/pull/143275 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][NFC] Refactor replaceExternalDecls to use llvm::any_of (PR #143275)
snarang181 wrote: @ChuanqiXu9, requesting your review here. https://github.com/llvm/llvm-project/pull/143275 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Refactor clang doc comment structure (PR #142273)
https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/142273 >From 5bc81ef0cd42194bfe4f8aef9bc98a17ada2d297 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Sat, 31 May 2025 10:05:52 -0400 Subject: [PATCH 01/11] [clang-doc] Refactor CommentInfo.Kind to use CommentKind enum This patch replaces the raw SmallString<16> `Kind` field in `CommentInfo` with a strongly typed enum `CommentKind`. This improves type safety, allows compiler-checked switch handling, and removes the reliance on string comparisons across the clang-doc codebase. --- clang-tools-extra/clang-doc/BitcodeReader.cpp | 9 ++- clang-tools-extra/clang-doc/BitcodeWriter.cpp | 3 +- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 74 ++- .../clang-doc/HTMLMustacheGenerator.cpp | 12 +-- clang-tools-extra/clang-doc/MDGenerator.cpp | 59 ++- .../clang-doc/Representation.cpp | 60 +++ clang-tools-extra/clang-doc/Representation.h | 33 +++-- clang-tools-extra/clang-doc/Serialize.cpp | 2 +- clang-tools-extra/clang-doc/YAMLGenerator.cpp | 20 - 9 files changed, 201 insertions(+), 71 deletions(-) diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp index 546dd0254ec01..d15ca02c864f6 100644 --- a/clang-tools-extra/clang-doc/BitcodeReader.cpp +++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp @@ -316,8 +316,13 @@ static llvm::Error parseRecord(const Record &R, unsigned ID, static llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, CommentInfo *I) { switch (ID) { - case COMMENT_KIND: -return decodeRecord(R, I->Kind, Blob); + case COMMENT_KIND: { +llvm::SmallString<16> KindStr; +if (llvm::Error Err = decodeRecord(R, KindStr, Blob)) + return Err; +I->Kind = stringToCommentKind(KindStr); +return llvm::Error::success(); + } case COMMENT_TEXT: return decodeRecord(R, I->Text, Blob); case COMMENT_NAME: diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.cpp b/clang-tools-extra/clang-doc/BitcodeWriter.cpp index f0a445e606bff..efd60fdc2ec76 100644 --- a/clang-tools-extra/clang-doc/BitcodeWriter.cpp +++ b/clang-tools-extra/clang-doc/BitcodeWriter.cpp @@ -484,8 +484,9 @@ void ClangDocBitcodeWriter::emitBlock(const MemberTypeInfo &T) { void ClangDocBitcodeWriter::emitBlock(const CommentInfo &I) { StreamSubBlockGuard Block(Stream, BI_COMMENT_BLOCK_ID); + // Handle Kind (enum) separately, since it is not a string. + emitRecord(commentKindToString(I.Kind), COMMENT_KIND); for (const auto &L : std::vector>{ - {I.Kind, COMMENT_KIND}, {I.Text, COMMENT_TEXT}, {I.Name, COMMENT_NAME}, {I.Direction, COMMENT_DIRECTION}, diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index 93b9279462a89..eb7bfb842589b 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -635,47 +635,53 @@ genHTML(const Index &Index, StringRef InfoPath, bool IsOutermostList) { } static std::unique_ptr genHTML(const CommentInfo &I) { - if (I.Kind == "FullComment") { -auto FullComment = std::make_unique(HTMLTag::TAG_DIV); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child); - if (Node) -FullComment->Children.emplace_back(std::move(Node)); + switch (I.Kind) { +case CommentKind::CK_FullComment: { + auto FullComment = std::make_unique(HTMLTag::TAG_DIV); + for (const auto &Child : I.Children) { +std::unique_ptr Node = genHTML(*Child); +if (Node) + FullComment->Children.emplace_back(std::move(Node)); + } + return std::move(FullComment); } -return std::move(FullComment); - } - if (I.Kind == "ParagraphComment") { -auto ParagraphComment = std::make_unique(HTMLTag::TAG_P); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child); - if (Node) -ParagraphComment->Children.emplace_back(std::move(Node)); +case CommentKind::CK_ParagraphComment: { + auto ParagraphComment = std::make_unique(HTMLTag::TAG_P); + for (const auto &Child : I.Children) { +std::unique_ptr Node = genHTML(*Child); +if (Node) + ParagraphComment->Children.emplace_back(std::move(Node)); + } + if (ParagraphComment->Children.empty()) +return nullptr; + return std::move(ParagraphComment); } -if (ParagraphComment->Children.empty()) - return nullptr; -return std::move(ParagraphComment); - } - if (I.Kind == "BlockCommandComment") { -auto BlockComment = std::make_unique(HTMLTag::TAG_DIV); -BlockComment->Children.emplace_back( -std::make_unique(HTMLTag::TAG_DIV, I.Name)); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Chi
[clang-tools-extra] Refactor clang doc comment structure (PR #142273)
https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/142273 >From f75d81cacf455477fe9bc6cb498fb2f76bebcfe2 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Sat, 31 May 2025 10:05:52 -0400 Subject: [PATCH 01/12] [clang-doc] Refactor CommentInfo.Kind to use CommentKind enum This patch replaces the raw SmallString<16> `Kind` field in `CommentInfo` with a strongly typed enum `CommentKind`. This improves type safety, allows compiler-checked switch handling, and removes the reliance on string comparisons across the clang-doc codebase. --- clang-tools-extra/clang-doc/BitcodeReader.cpp | 9 ++- clang-tools-extra/clang-doc/BitcodeWriter.cpp | 3 +- clang-tools-extra/clang-doc/HTMLGenerator.cpp | 74 ++- .../clang-doc/HTMLMustacheGenerator.cpp | 12 +-- clang-tools-extra/clang-doc/MDGenerator.cpp | 59 ++- .../clang-doc/Representation.cpp | 60 +++ clang-tools-extra/clang-doc/Representation.h | 33 +++-- clang-tools-extra/clang-doc/Serialize.cpp | 2 +- clang-tools-extra/clang-doc/YAMLGenerator.cpp | 20 - 9 files changed, 201 insertions(+), 71 deletions(-) diff --git a/clang-tools-extra/clang-doc/BitcodeReader.cpp b/clang-tools-extra/clang-doc/BitcodeReader.cpp index 546dd0254ec01..d15ca02c864f6 100644 --- a/clang-tools-extra/clang-doc/BitcodeReader.cpp +++ b/clang-tools-extra/clang-doc/BitcodeReader.cpp @@ -316,8 +316,13 @@ static llvm::Error parseRecord(const Record &R, unsigned ID, static llvm::Error parseRecord(const Record &R, unsigned ID, llvm::StringRef Blob, CommentInfo *I) { switch (ID) { - case COMMENT_KIND: -return decodeRecord(R, I->Kind, Blob); + case COMMENT_KIND: { +llvm::SmallString<16> KindStr; +if (llvm::Error Err = decodeRecord(R, KindStr, Blob)) + return Err; +I->Kind = stringToCommentKind(KindStr); +return llvm::Error::success(); + } case COMMENT_TEXT: return decodeRecord(R, I->Text, Blob); case COMMENT_NAME: diff --git a/clang-tools-extra/clang-doc/BitcodeWriter.cpp b/clang-tools-extra/clang-doc/BitcodeWriter.cpp index f0a445e606bff..efd60fdc2ec76 100644 --- a/clang-tools-extra/clang-doc/BitcodeWriter.cpp +++ b/clang-tools-extra/clang-doc/BitcodeWriter.cpp @@ -484,8 +484,9 @@ void ClangDocBitcodeWriter::emitBlock(const MemberTypeInfo &T) { void ClangDocBitcodeWriter::emitBlock(const CommentInfo &I) { StreamSubBlockGuard Block(Stream, BI_COMMENT_BLOCK_ID); + // Handle Kind (enum) separately, since it is not a string. + emitRecord(commentKindToString(I.Kind), COMMENT_KIND); for (const auto &L : std::vector>{ - {I.Kind, COMMENT_KIND}, {I.Text, COMMENT_TEXT}, {I.Name, COMMENT_NAME}, {I.Direction, COMMENT_DIRECTION}, diff --git a/clang-tools-extra/clang-doc/HTMLGenerator.cpp b/clang-tools-extra/clang-doc/HTMLGenerator.cpp index 93b9279462a89..eb7bfb842589b 100644 --- a/clang-tools-extra/clang-doc/HTMLGenerator.cpp +++ b/clang-tools-extra/clang-doc/HTMLGenerator.cpp @@ -635,47 +635,53 @@ genHTML(const Index &Index, StringRef InfoPath, bool IsOutermostList) { } static std::unique_ptr genHTML(const CommentInfo &I) { - if (I.Kind == "FullComment") { -auto FullComment = std::make_unique(HTMLTag::TAG_DIV); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child); - if (Node) -FullComment->Children.emplace_back(std::move(Node)); + switch (I.Kind) { +case CommentKind::CK_FullComment: { + auto FullComment = std::make_unique(HTMLTag::TAG_DIV); + for (const auto &Child : I.Children) { +std::unique_ptr Node = genHTML(*Child); +if (Node) + FullComment->Children.emplace_back(std::move(Node)); + } + return std::move(FullComment); } -return std::move(FullComment); - } - if (I.Kind == "ParagraphComment") { -auto ParagraphComment = std::make_unique(HTMLTag::TAG_P); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Child); - if (Node) -ParagraphComment->Children.emplace_back(std::move(Node)); +case CommentKind::CK_ParagraphComment: { + auto ParagraphComment = std::make_unique(HTMLTag::TAG_P); + for (const auto &Child : I.Children) { +std::unique_ptr Node = genHTML(*Child); +if (Node) + ParagraphComment->Children.emplace_back(std::move(Node)); + } + if (ParagraphComment->Children.empty()) +return nullptr; + return std::move(ParagraphComment); } -if (ParagraphComment->Children.empty()) - return nullptr; -return std::move(ParagraphComment); - } - if (I.Kind == "BlockCommandComment") { -auto BlockComment = std::make_unique(HTMLTag::TAG_DIV); -BlockComment->Children.emplace_back( -std::make_unique(HTMLTag::TAG_DIV, I.Name)); -for (const auto &Child : I.Children) { - std::unique_ptr Node = genHTML(*Chi
[clang-tools-extra] Refactor clang doc comment structure (PR #142273)
https://github.com/snarang181 edited https://github.com/llvm/llvm-project/pull/142273 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Refactor clang doc comment structure (PR #142273)
snarang181 wrote: > Oh, lets updated the PR description with a more complete description of the > change. It can also be marked as `Fixes #NNN` since this basically implements > everything outlined in the issues, unless I'm forgetting something. Done. https://github.com/llvm/llvm-project/pull/142273 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] Refactor clang doc comment structure (PR #142273)
snarang181 wrote: Sounds good, @ilovepi. I also raised an issue to get commit access and you might have gotten a notification. It'd be great if you can take a look at that too :) https://github.com/llvm/llvm-project/pull/142273 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][NFC] Refactor replaceExternalDecls to use llvm::any_of (PR #143275)
https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/143275 >From c18c91f7f8f4332696dd309a5164c568f32c137b Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Sat, 7 Jun 2025 12:21:17 -0400 Subject: [PATCH 1/2] Replace loop with llvm:any_of --- clang/include/clang/AST/DeclContextInternals.h | 12 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/clang/include/clang/AST/DeclContextInternals.h b/clang/include/clang/AST/DeclContextInternals.h index b17b7627ac90c..a1071f62d5fae 100644 --- a/clang/include/clang/AST/DeclContextInternals.h +++ b/clang/include/clang/AST/DeclContextInternals.h @@ -176,14 +176,10 @@ class StoredDeclsList { DeclListNode::Decls *Tail = erase_if([Decls](NamedDecl *ND) { if (ND->isFromASTFile()) return true; - // FIXME: Can we get rid of this loop completely? - for (NamedDecl *D : Decls) -// Only replace the local declaration if the external declaration has -// higher visibilities. -if (D->getModuleOwnershipKind() <= ND->getModuleOwnershipKind() && -D->declarationReplaces(ND, /*IsKnownNewer=*/false)) - return true; - return false; + return llvm::any_of(Decls, [ND](NamedDecl *D) { +return D->getModuleOwnershipKind() <= ND->getModuleOwnershipKind() && + D->declarationReplaces(ND, /*IsKnownNewer=*/false); + }); }); // Don't have any pending external decls any more. >From 844654597a9f21ff4027ed40c6f6b386fb2dd370 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Sun, 8 Jun 2025 22:07:43 -0400 Subject: [PATCH 2/2] Retain comments --- clang/include/clang/AST/DeclContextInternals.h | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/include/clang/AST/DeclContextInternals.h b/clang/include/clang/AST/DeclContextInternals.h index a1071f62d5fae..a23352865453a 100644 --- a/clang/include/clang/AST/DeclContextInternals.h +++ b/clang/include/clang/AST/DeclContextInternals.h @@ -176,6 +176,7 @@ class StoredDeclsList { DeclListNode::Decls *Tail = erase_if([Decls](NamedDecl *ND) { if (ND->isFromASTFile()) return true; + // FIXME: Can we get rid of this loop completely? return llvm::any_of(Decls, [ND](NamedDecl *D) { return D->getModuleOwnershipKind() <= ND->getModuleOwnershipKind() && D->declarationReplaces(ND, /*IsKnownNewer=*/false); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][NFC] Refactor replaceExternalDecls to use llvm::any_of (PR #143275)
snarang181 wrote: > IIUC the `FIXME` comment means that the time complexity of this part of code > is not good enough and we can make it faster. OK. In any case, the usage of `llvm_any_of` seemed better than using an explicit `for-loop`. https://github.com/llvm/llvm-project/pull/143275 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][NFC] Refactor replaceExternalDecls to use llvm::any_of (PR #143275)
@@ -176,14 +176,10 @@ class StoredDeclsList { DeclListNode::Decls *Tail = erase_if([Decls](NamedDecl *ND) { if (ND->isFromASTFile()) return true; - // FIXME: Can we get rid of this loop completely? - for (NamedDecl *D : Decls) -// Only replace the local declaration if the external declaration has -// higher visibilities. -if (D->getModuleOwnershipKind() <= ND->getModuleOwnershipKind() && -D->declarationReplaces(ND, /*IsKnownNewer=*/false)) - return true; - return false; + return llvm::any_of(Decls, [ND](NamedDecl *D) { snarang181 wrote: I added the comment back. Is that what you meant? https://github.com/llvm/llvm-project/pull/143275 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][NFC] Refactor replaceExternalDecls to use llvm::any_of (PR #143275)
https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/143275 >From c18c91f7f8f4332696dd309a5164c568f32c137b Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Sat, 7 Jun 2025 12:21:17 -0400 Subject: [PATCH 1/2] Replace loop with llvm:any_of --- clang/include/clang/AST/DeclContextInternals.h | 12 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/clang/include/clang/AST/DeclContextInternals.h b/clang/include/clang/AST/DeclContextInternals.h index b17b7627ac90c..a1071f62d5fae 100644 --- a/clang/include/clang/AST/DeclContextInternals.h +++ b/clang/include/clang/AST/DeclContextInternals.h @@ -176,14 +176,10 @@ class StoredDeclsList { DeclListNode::Decls *Tail = erase_if([Decls](NamedDecl *ND) { if (ND->isFromASTFile()) return true; - // FIXME: Can we get rid of this loop completely? - for (NamedDecl *D : Decls) -// Only replace the local declaration if the external declaration has -// higher visibilities. -if (D->getModuleOwnershipKind() <= ND->getModuleOwnershipKind() && -D->declarationReplaces(ND, /*IsKnownNewer=*/false)) - return true; - return false; + return llvm::any_of(Decls, [ND](NamedDecl *D) { +return D->getModuleOwnershipKind() <= ND->getModuleOwnershipKind() && + D->declarationReplaces(ND, /*IsKnownNewer=*/false); + }); }); // Don't have any pending external decls any more. >From 84b94745cddff8acf0539ab28f0b3e258b1c3dcb Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Sun, 8 Jun 2025 22:07:43 -0400 Subject: [PATCH 2/2] Retain comments --- clang/include/clang/AST/DeclContextInternals.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/include/clang/AST/DeclContextInternals.h b/clang/include/clang/AST/DeclContextInternals.h index a1071f62d5fae..9bde6a459a2c9 100644 --- a/clang/include/clang/AST/DeclContextInternals.h +++ b/clang/include/clang/AST/DeclContextInternals.h @@ -177,6 +177,8 @@ class StoredDeclsList { if (ND->isFromASTFile()) return true; return llvm::any_of(Decls, [ND](NamedDecl *D) { +// Only replace the local declaration if the external declaration has +// a higher module ownership kind, or if the local declaration is return D->getModuleOwnershipKind() <= ND->getModuleOwnershipKind() && D->declarationReplaces(ND, /*IsKnownNewer=*/false); }); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][NFC] Refactor replaceExternalDecls to use llvm::any_of (PR #143275)
@@ -177,13 +177,10 @@ class StoredDeclsList { if (ND->isFromASTFile()) return true; // FIXME: Can we get rid of this loop completely? - for (NamedDecl *D : Decls) -// Only replace the local declaration if the external declaration has -// higher visibilities. snarang181 wrote: Retain all now, I think. https://github.com/llvm/llvm-project/pull/143275 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][NFC] Refactor replaceExternalDecls to use llvm::any_of (PR #143275)
@@ -177,13 +177,10 @@ class StoredDeclsList { if (ND->isFromASTFile()) return true; // FIXME: Can we get rid of this loop completely? - for (NamedDecl *D : Decls) -// Only replace the local declaration if the external declaration has -// higher visibilities. snarang181 wrote: OK. Should we keep the FIXME? https://github.com/llvm/llvm-project/pull/143275 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][NFC] Refactor replaceExternalDecls to use llvm::any_of (PR #143275)
https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/143275 >From c18c91f7f8f4332696dd309a5164c568f32c137b Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Sat, 7 Jun 2025 12:21:17 -0400 Subject: [PATCH 1/2] Replace loop with llvm:any_of --- clang/include/clang/AST/DeclContextInternals.h | 12 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/clang/include/clang/AST/DeclContextInternals.h b/clang/include/clang/AST/DeclContextInternals.h index b17b7627ac90c..a1071f62d5fae 100644 --- a/clang/include/clang/AST/DeclContextInternals.h +++ b/clang/include/clang/AST/DeclContextInternals.h @@ -176,14 +176,10 @@ class StoredDeclsList { DeclListNode::Decls *Tail = erase_if([Decls](NamedDecl *ND) { if (ND->isFromASTFile()) return true; - // FIXME: Can we get rid of this loop completely? - for (NamedDecl *D : Decls) -// Only replace the local declaration if the external declaration has -// higher visibilities. -if (D->getModuleOwnershipKind() <= ND->getModuleOwnershipKind() && -D->declarationReplaces(ND, /*IsKnownNewer=*/false)) - return true; - return false; + return llvm::any_of(Decls, [ND](NamedDecl *D) { +return D->getModuleOwnershipKind() <= ND->getModuleOwnershipKind() && + D->declarationReplaces(ND, /*IsKnownNewer=*/false); + }); }); // Don't have any pending external decls any more. >From 9bee4e3c96ba12ce132ccea7415bdf8a235815db Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Sun, 8 Jun 2025 22:07:43 -0400 Subject: [PATCH 2/2] Retain comments --- clang/include/clang/AST/DeclContextInternals.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/include/clang/AST/DeclContextInternals.h b/clang/include/clang/AST/DeclContextInternals.h index a1071f62d5fae..698e835e0b5ac 100644 --- a/clang/include/clang/AST/DeclContextInternals.h +++ b/clang/include/clang/AST/DeclContextInternals.h @@ -177,6 +177,8 @@ class StoredDeclsList { if (ND->isFromASTFile()) return true; return llvm::any_of(Decls, [ND](NamedDecl *D) { +// Only replace the local declaration if the external declaration has +// higher visiblities return D->getModuleOwnershipKind() <= ND->getModuleOwnershipKind() && D->declarationReplaces(ND, /*IsKnownNewer=*/false); }); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][NFC] Refactor replaceExternalDecls to use llvm::any_of (PR #143275)
https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/143275 >From c18c91f7f8f4332696dd309a5164c568f32c137b Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Sat, 7 Jun 2025 12:21:17 -0400 Subject: [PATCH 1/2] Replace loop with llvm:any_of --- clang/include/clang/AST/DeclContextInternals.h | 12 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/clang/include/clang/AST/DeclContextInternals.h b/clang/include/clang/AST/DeclContextInternals.h index b17b7627ac90c..a1071f62d5fae 100644 --- a/clang/include/clang/AST/DeclContextInternals.h +++ b/clang/include/clang/AST/DeclContextInternals.h @@ -176,14 +176,10 @@ class StoredDeclsList { DeclListNode::Decls *Tail = erase_if([Decls](NamedDecl *ND) { if (ND->isFromASTFile()) return true; - // FIXME: Can we get rid of this loop completely? - for (NamedDecl *D : Decls) -// Only replace the local declaration if the external declaration has -// higher visibilities. -if (D->getModuleOwnershipKind() <= ND->getModuleOwnershipKind() && -D->declarationReplaces(ND, /*IsKnownNewer=*/false)) - return true; - return false; + return llvm::any_of(Decls, [ND](NamedDecl *D) { +return D->getModuleOwnershipKind() <= ND->getModuleOwnershipKind() && + D->declarationReplaces(ND, /*IsKnownNewer=*/false); + }); }); // Don't have any pending external decls any more. >From ff09e5c962daec3fa66329b6822af9424bfb1123 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Sun, 8 Jun 2025 22:07:43 -0400 Subject: [PATCH 2/2] Retain comments --- clang/include/clang/AST/DeclContextInternals.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/include/clang/AST/DeclContextInternals.h b/clang/include/clang/AST/DeclContextInternals.h index a1071f62d5fae..b13334119fa25 100644 --- a/clang/include/clang/AST/DeclContextInternals.h +++ b/clang/include/clang/AST/DeclContextInternals.h @@ -177,6 +177,8 @@ class StoredDeclsList { if (ND->isFromASTFile()) return true; return llvm::any_of(Decls, [ND](NamedDecl *D) { +// Only replace the local declaration if the external declaration has +// higher visiblities. return D->getModuleOwnershipKind() <= ND->getModuleOwnershipKind() && D->declarationReplaces(ND, /*IsKnownNewer=*/false); }); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][NFC] Refactor replaceExternalDecls to use llvm::any_of (PR #143275)
https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/143275 >From c18c91f7f8f4332696dd309a5164c568f32c137b Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Sat, 7 Jun 2025 12:21:17 -0400 Subject: [PATCH 1/2] Replace loop with llvm:any_of --- clang/include/clang/AST/DeclContextInternals.h | 12 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/clang/include/clang/AST/DeclContextInternals.h b/clang/include/clang/AST/DeclContextInternals.h index b17b7627ac90c..a1071f62d5fae 100644 --- a/clang/include/clang/AST/DeclContextInternals.h +++ b/clang/include/clang/AST/DeclContextInternals.h @@ -176,14 +176,10 @@ class StoredDeclsList { DeclListNode::Decls *Tail = erase_if([Decls](NamedDecl *ND) { if (ND->isFromASTFile()) return true; - // FIXME: Can we get rid of this loop completely? - for (NamedDecl *D : Decls) -// Only replace the local declaration if the external declaration has -// higher visibilities. -if (D->getModuleOwnershipKind() <= ND->getModuleOwnershipKind() && -D->declarationReplaces(ND, /*IsKnownNewer=*/false)) - return true; - return false; + return llvm::any_of(Decls, [ND](NamedDecl *D) { +return D->getModuleOwnershipKind() <= ND->getModuleOwnershipKind() && + D->declarationReplaces(ND, /*IsKnownNewer=*/false); + }); }); // Don't have any pending external decls any more. >From f8498219698ab33b512d82ac3fc9df5ab69f3b57 Mon Sep 17 00:00:00 2001 From: Samarth Narang Date: Sun, 8 Jun 2025 22:07:43 -0400 Subject: [PATCH 2/2] Retain comments --- clang/include/clang/AST/DeclContextInternals.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/clang/include/clang/AST/DeclContextInternals.h b/clang/include/clang/AST/DeclContextInternals.h index a1071f62d5fae..a0f37886cc014 100644 --- a/clang/include/clang/AST/DeclContextInternals.h +++ b/clang/include/clang/AST/DeclContextInternals.h @@ -176,7 +176,10 @@ class StoredDeclsList { DeclListNode::Decls *Tail = erase_if([Decls](NamedDecl *ND) { if (ND->isFromASTFile()) return true; + // FIXME: Can we get rid of this loop completely? return llvm::any_of(Decls, [ND](NamedDecl *D) { +// Only replace the local declaration if the external declaration has +// higher visiblities. return D->getModuleOwnershipKind() <= ND->getModuleOwnershipKind() && D->declarationReplaces(ND, /*IsKnownNewer=*/false); }); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits