From e4d8b904565e9c598c4ede172944e47d95cc31dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Str=C3=B6mberg?= <5454791+bjornstromberg@users.noreply.github.com> Date: Sat, 9 May 2020 11:43:25 +0200 Subject: [PATCH 01/10] - added preprocessor directives to: - support for clang/llvm >= 10 which uses smartptr's instead of rawpointers. - support for clang/llvm < 10 which uses raw pointers. - bump required C++ version from 11 to 14, since Clang-10 requires C++14 to build, and clang-9 builds fine with it. --- src/CMakeLists.txt | 2 +- src/main.cpp | 16 ++++++++++++++-- src/mocng.cpp | 37 +++++++++++++++++++++++++------------ 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f68f84c..8888e40 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -27,7 +27,7 @@ message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") Find_Package(Clang REQUIRED CONFIG HINTS "${LLVM_INSTALL_PREFIX}/lib/cmake/clang") message(STATUS "Found Clang in ${CLANG_INSTALL_PREFIX}") -set (CMAKE_CXX_STANDARD 11) +set (CMAKE_CXX_STANDARD 14) SET(common_srcs mocng.cpp generator.cpp propertyparser.cpp mocppcallbacks.cpp mocastconsumer.cpp qbjs.cpp clangversionabstraction.cpp workaroundtests.cpp) diff --git a/src/main.cpp b/src/main.cpp index ed8132c..4e8f8d0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -448,7 +448,13 @@ int main(int argc, const char **argv) if (PreprocessorOnly) { Argv.push_back("-P"); - clang::tooling::ToolInvocation Inv(Argv, new clang::PrintPreprocessedAction, &FM); + clang::tooling::ToolInvocation Inv(Argv, + #if CLANG_VERSION_MAJOR >= 10 + std::make_unique(), + #else + new clang::PrintPreprocessedAction, + #endif + &FM); return !Inv.run(); } @@ -462,7 +468,13 @@ int main(int argc, const char **argv) Argv.push_back("QtCore/qobject.h"); } - clang::tooling::ToolInvocation Inv(Argv, new MocAction, &FM); + clang::tooling::ToolInvocation Inv(Argv, + #if CLANG_VERSION_MAJOR >= 10 + std::make_unique(), + #else + new MocAction, + #endif + &FM); const EmbeddedFile *f = EmbeddedFiles; while (f->filename) { diff --git a/src/mocng.cpp b/src/mocng.cpp index b6ef0d9..242384a 100644 --- a/src/mocng.cpp +++ b/src/mocng.cpp @@ -156,20 +156,33 @@ static void parsePluginMetaData(ClassDef &Def, clang::Expr *Content, clang::Sema else { llvm::StringRef Filename = Literal.GetString(); const clang::DirectoryLookup *CurDir; - const clang::FileEntry *File = PP.LookupFile( - Val->getSourceRange().getBegin(), - Filename, false, nullptr, -#if CLANG_VERSION_MAJOR!=3 || CLANG_VERSION_MINOR>5 - nullptr, -#endif - CurDir, nullptr, nullptr, nullptr -#if CLANG_VERSION_MAJOR >= 5 - , nullptr +#if CLANG_VERSION_MAJOR < 10 + const clang::FileEntry *File = +#else + const clang::Optional fileRef + { #endif -#if CLANG_VERSION_MAJOR >= 9 - , nullptr + PP.LookupFile( + Val->getSourceRange().getBegin(), + Filename, false, nullptr, + #if CLANG_VERSION_MAJOR!=3 || CLANG_VERSION_MINOR>5 + nullptr, + #endif + CurDir, nullptr, nullptr, nullptr + #if CLANG_VERSION_MAJOR >= 5 + , nullptr + #endif + #if CLANG_VERSION_MAJOR >= 9 + , nullptr + #endif + ) +#if CLANG_VERSION_MAJOR >= 10 + }; + + const clang::FileEntry *File = fileRef ? &fileRef->getFileEntry() : nullptr; +#else + ; #endif - ); if (!File) { PP.getDiagnostics().Report(GetFromLiteral(StrToks.front(), Val, PP), clang::diag::err_pp_file_not_found) From 63d51006f4cfc605ec5016c47db15392cd535d24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Str=C3=B6mberg?= <5454791+bjornstromberg@users.noreply.github.com> Date: Sat, 9 May 2020 13:00:10 +0200 Subject: [PATCH 02/10] fix [-Winconsistent-missing-override] on hasCodeCompletionSupport --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 4e8f8d0..bd31c68 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -273,7 +273,7 @@ class MocAction : public clang::ASTFrontendAction { public: // CHECK - virtual bool hasCodeCompletionSupport() const { return true; } + virtual bool hasCodeCompletionSupport() const override { return true; } }; static void showVersion(bool /*Long*/) { From 8683506652873b38bc331a669b2412abb444893c Mon Sep 17 00:00:00 2001 From: Andreas Hollandt Date: Tue, 28 Jul 2020 16:12:34 +0200 Subject: [PATCH 03/10] allow using clang -fplugin option --- README.md | 2 +- src/plugin.cpp | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 982707c..b1add90 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Then run cmake and make (adapt your paths) * As a binary: replace the moc provided by Qt by the one which is in src/moc * As a clang plugin: Tell your build system not to run moc, and add this to the CXXFLAGS - -Xclang -load -Xclang /path/to/src/libmocng_plugin.so -Xclang -add-plugin -Xclang moc + `-fplugin=/path/to/src/libmocng_plugin.so` ## Differences with upstream moc diff --git a/src/plugin.cpp b/src/plugin.cpp index 0044c6f..fef9b52 100644 --- a/src/plugin.cpp +++ b/src/plugin.cpp @@ -34,7 +34,7 @@ static bool IsQtInternal(const clang::CXXMethodDecl *MD) { return (Name.startswith("qt_") || Name == "metaObject"); } -class MocPluginASTConsumer : public MocASTConsumer { +class MocPluginASTConsumer final : public MocASTConsumer { bool done = false; bool HandleTopLevelDecl(clang::DeclGroupRef D) override { @@ -186,7 +186,7 @@ class MocPluginASTConsumer : public MocASTConsumer { MocPluginASTConsumer(clang::CompilerInstance& ci) : MocASTConsumer(ci) {} }; -class MocPluginAction : public clang::PluginASTAction { +class MocPluginAction final : public clang::PluginASTAction { protected: #if CLANG_VERSION_MAJOR == 3 && CLANG_VERSION_MINOR <= 5 clang::ASTConsumer * @@ -199,6 +199,10 @@ class MocPluginAction : public clang::PluginASTAction { bool ParseArgs(const clang::CompilerInstance& CI, const std::vector< std::string >& arg) override { return true; } + + ActionType getActionType() override { + return AddAfterMainAction; + } }; From b0f709d9e386180da40c3d70d2e8eb2d7d4f450c Mon Sep 17 00:00:00 2001 From: Andreas Hollandt Date: Tue, 28 Jul 2020 16:13:28 +0200 Subject: [PATCH 04/10] fix missing pragma once --- src/mocppcallbacks.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mocppcallbacks.h b/src/mocppcallbacks.h index 245c870..1dd52f7 100644 --- a/src/mocppcallbacks.h +++ b/src/mocppcallbacks.h @@ -16,7 +16,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - +#pragma once #include #include #include From b5d837c2d4b94538ae5afab1926287d7af4b8675 Mon Sep 17 00:00:00 2001 From: Andreas Hollandt Date: Tue, 28 Jul 2020 16:14:54 +0200 Subject: [PATCH 05/10] fix the static assert test for new clang --- src/mocng.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/mocng.cpp b/src/mocng.cpp index 242384a..52b6b4d 100644 --- a/src/mocng.cpp +++ b/src/mocng.cpp @@ -353,8 +353,9 @@ static void parseClassInfo(BaseDef &Def, clang::Expr *SubExp, clang::Preprocesso static bool IsAnnotationStaticAssert(clang::Decl *Decl, llvm::StringRef *Key, clang::Expr **SubExp) { if (clang::StaticAssertDecl *S = llvm::dyn_cast(Decl)) { - if (auto *E = llvm::dyn_cast(S->getAssertExpr())) - if (clang::ParenExpr *PE = llvm::dyn_cast(E->getArgumentExpr())) + if (auto *Cast = llvm::dyn_cast(S->getAssertExpr())) + if (auto *E = llvm::dyn_cast(Cast->getSubExpr())) + if (clang::ParenExpr *PE = llvm::dyn_cast(E->getArgumentExpr())) { *Key = S->getMessage()->getString(); *SubExp = PE->getSubExpr(); From e8e7af67cc5dd84ced5fb786cdaa934e20705f4f Mon Sep 17 00:00:00 2001 From: Andreas Hollandt Date: Tue, 28 Jul 2020 16:15:50 +0200 Subject: [PATCH 06/10] get rid of qobjectdefs-injected.h --- src/mocastconsumer.cpp | 2 +- src/mocppcallbacks.cpp | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mocastconsumer.cpp b/src/mocastconsumer.cpp index 0a43235..6d1b012 100644 --- a/src/mocastconsumer.cpp +++ b/src/mocastconsumer.cpp @@ -35,7 +35,7 @@ void MocASTConsumer::Initialize(clang::ASTContext& Ctx) { // We will enable this when we require Qt >= 5.6.1 and libclang >= 3.8 // Then we will be able to get rid of qobjectdefs-injected -#if 0 +#if 1 std::string qtPredefinesBuffer; llvm::raw_string_ostream qtPredefines(qtPredefinesBuffer); clang::MacroBuilder builder(qtPredefines); diff --git a/src/mocppcallbacks.cpp b/src/mocppcallbacks.cpp index 7783dc2..48a2e64 100644 --- a/src/mocppcallbacks.cpp +++ b/src/mocppcallbacks.cpp @@ -21,10 +21,12 @@ #include "clangversionabstraction.h" void MocPPCallbacks::InjectQObjectDefs(clang::SourceLocation Loc) { - #include "qobjectdefs-injected.h" +#if 0 +#include "qobjectdefs-injected.h" auto Buf = maybe_unique(llvm::MemoryBuffer::getMemBuffer(Injected, "qobjectdefs-injected.moc")); Loc = PP.getSourceManager().getFileLoc(Loc); PP.EnterSourceFile( CreateFileIDForMemBuffer(PP, Buf, Loc), nullptr, Loc); +#endif } void MocPPCallbacks::EnterMainFile(llvm::StringRef Name) From 100018bf278d9702b473ea0203148600e33ed823 Mon Sep 17 00:00:00 2001 From: Andreas Hollandt Date: Tue, 28 Jul 2020 16:16:16 +0200 Subject: [PATCH 07/10] mark classes final --- src/main.cpp | 2 +- src/mocastconsumer.h | 4 ++-- src/mocppcallbacks.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index bd31c68..b3987bb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -121,7 +121,7 @@ struct MocDiagConsumer : clang::DiagnosticConsumer { -struct MocNGASTConsumer : public MocASTConsumer { +struct MocNGASTConsumer final : public MocASTConsumer { std::string InFile; MocNGASTConsumer(clang::CompilerInstance& ci, llvm::StringRef InFile) : MocASTConsumer(ci), InFile(InFile) { } diff --git a/src/mocastconsumer.h b/src/mocastconsumer.h index 41d7386..b18959b 100644 --- a/src/mocastconsumer.h +++ b/src/mocastconsumer.h @@ -41,8 +41,8 @@ class MocASTConsumer : public clang::ASTConsumer MocASTConsumer(clang::CompilerInstance &ci) :ci(ci) { } - void Initialize(clang::ASTContext& Ctx) override; - void HandleTagDeclDefinition(clang::TagDecl* D) override; + void Initialize(clang::ASTContext &Ctx) final; + void HandleTagDeclDefinition(clang::TagDecl* D) final; bool HandleTopLevelDecl(clang::DeclGroupRef D) override; virtual bool shouldParseDecl(clang::Decl *D) { return true; } diff --git a/src/mocppcallbacks.h b/src/mocppcallbacks.h index 1dd52f7..72bacbc 100644 --- a/src/mocppcallbacks.h +++ b/src/mocppcallbacks.h @@ -21,7 +21,7 @@ #include #include -class MocPPCallbacks : public clang::PPCallbacks { +class MocPPCallbacks final : public clang::PPCallbacks { clang::Preprocessor &PP; bool IncludeNotFoundSupressed = false; From fb10c8dc2b10f0be044083dd53606e2644031b6f Mon Sep 17 00:00:00 2001 From: Andreas Hollandt Date: Tue, 28 Jul 2020 16:18:58 +0200 Subject: [PATCH 08/10] use range-for --- src/mocng.cpp | 8 ++++---- src/plugin.cpp | 18 +++++++++--------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/mocng.cpp b/src/mocng.cpp index 52b6b4d..3c4b84c 100644 --- a/src/mocng.cpp +++ b/src/mocng.cpp @@ -371,10 +371,10 @@ ClassDef MocNg::parseClass(clang::CXXRecordDecl* RD, clang::Sema& Sema) ClassDef Def; Def.Record = RD; - for (auto it = RD->decls_begin(); it != RD->decls_end(); ++it) { + for (auto decl : RD->decls()) { llvm::StringRef key; clang::Expr *SubExp; - if (IsAnnotationStaticAssert(*it, &key, &SubExp)) { + if (IsAnnotationStaticAssert(decl, &key, &SubExp)) { if (key == "qt_property") { clang::StringLiteral *Val = llvm::dyn_cast(SubExp); if (Val) { @@ -385,7 +385,7 @@ ClassDef MocNg::parseClass(clang::CXXRecordDecl* RD, clang::Sema& Sema) Def.Properties.push_back(Parser.parseProperty()); Def.addExtra(Parser.Extra); } else { - PP.getDiagnostics().Report((*it)->getLocation(), + PP.getDiagnostics().Report(decl->getLocation(), PP.getDiagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error, "Invalid Q_PROPERTY annotation")); } @@ -437,7 +437,7 @@ ClassDef MocNg::parseClass(clang::CXXRecordDecl* RD, clang::Sema& Sema) parsePluginMetaData(Def, SubExp, Sema); HasPlugin = true; } - } else if (clang::CXXMethodDecl *M = llvm::dyn_cast(*it)) { + } else if (clang::CXXMethodDecl *M = llvm::dyn_cast(decl)) { for (auto attr_it = M->specific_attr_begin(); attr_it != M->specific_attr_end(); ++attr_it) { diff --git a/src/plugin.cpp b/src/plugin.cpp index fef9b52..3696e4d 100644 --- a/src/plugin.cpp +++ b/src/plugin.cpp @@ -125,33 +125,33 @@ class MocPluginASTConsumer final : public MocASTConsumer { Key = nullptr; if (!Key) { - for (auto it = RD->method_begin(); it != RD->method_end(); ++it ) { + for (auto Method : RD->methods()) { - if (Key && !it->isVirtual()) + if (Key && !Method->isVirtual()) continue; - if (it->isPure() || it->isImplicit() || it->hasInlineBody() - || it->isInlineSpecified() || !it->isUserProvided() ) + if (Method->isPure() || Method->isImplicit() || Method->hasInlineBody() + || Method->isInlineSpecified() || !Method->isUserProvided() ) continue; const clang::FunctionDecl *Def; - if (it->hasBody(Def) && Def->isInlineSpecified()) + if (Method->hasBody(Def) && Def->isInlineSpecified()) continue; - if (IsQtInternal(*it)) + if (IsQtInternal(Method)) continue; /* if (Key->isFunctionTemplateSpecialization()) continue; */ - if (std::any_of(it->specific_attr_begin(), - it->specific_attr_end(), + if (std::any_of(Method->specific_attr_begin(), + Method->specific_attr_end(), [](clang::AnnotateAttr *A) { return A->getAnnotation() == "qt_signal"; })) continue; - Key = *it; + Key = Method; if (Key->isVirtual()) break; } From c33da40328160aaa283f9588a30c4c17a626c708 Mon Sep 17 00:00:00 2001 From: Andreas Hollandt Date: Tue, 28 Jul 2020 16:21:36 +0200 Subject: [PATCH 09/10] use unity builds --- CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 61568f9..e946149 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,3 +1,5 @@ -cmake_minimum_required(VERSION 3.1) -add_subdirectory(src) +cmake_minimum_required(VERSION 3.16) +set(CMAKE_UNITY_BUILD TRUE) +set(CMAKE_UNITY_BUILD_BATCH_SIZE 8) +add_subdirectory(src) From 580534d7dddd5d163945117f3e7e4e6d91d36063 Mon Sep 17 00:00:00 2001 From: Andreas Hollandt Date: Tue, 28 Jul 2020 16:22:07 +0200 Subject: [PATCH 10/10] use -Og for Debug and create split debug info for Release --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index e946149..4ed1ce1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ cmake_minimum_required(VERSION 3.16) set(CMAKE_UNITY_BUILD TRUE) set(CMAKE_UNITY_BUILD_BATCH_SIZE 8) +add_compile_options($<$:-Og> -gsplit-dwarf) add_subdirectory(src)