From 1aba5fcea80c379d46bee3c3b192aa81715e9ef3 Mon Sep 17 00:00:00 2001 From: Axel Naumann Date: Fri, 5 Mar 2021 17:48:14 +0100 Subject: [PATCH 1/5] [cling] A CastExpr cannot be a DeclRefExpr. --- interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp b/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp index 736d6f61666c0..64e9df55c6073 100644 --- a/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp +++ b/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp @@ -1199,7 +1199,7 @@ namespace cling { Expr* TAExpr = TA.getAsExpr(); if (CastExpr* CastExpr = dyn_cast(TAExpr)) TAExpr = CastExpr->getSubExpr(); - if (DeclRefExpr* DRE = dyn_cast(TAExpr)) { + else if (DeclRefExpr* DRE = dyn_cast(TAExpr)) { Visit(DRE->getFoundDecl()); if (m_SkipFlag) { return; From ab4fd91c4cb8214634ff0210920b894d4c79dce0 Mon Sep 17 00:00:00 2001 From: Axel Naumann Date: Fri, 5 Mar 2021 17:49:57 +0100 Subject: [PATCH 2/5] [cling] skipDecl if template arg cannot be fwd declared: Fixes CMS dictionary build issue with forward declaring a template argument of enum constant type - something we do not forward declare. --- .../cling/lib/Interpreter/ForwardDeclPrinter.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp b/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp index 64e9df55c6073..a7312dd702bfa 100644 --- a/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp +++ b/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp @@ -1205,11 +1205,22 @@ namespace cling { return; } } + else { + std::string buf; + { + llvm::raw_string_ostream osbuf(buf); + TAExpr->printPretty(osbuf, nullptr, m_Policy); + } + Log() << "Visit(Type*): cannot forward declare template argument expression: " + << buf; + skipDecl(nullptr, nullptr); + } } break; default: Log() << "Visit(Type*): Unexpected TemplateSpecializationType " << TA.getKind() << '\n'; + skipDecl(nullptr, nullptr); break; } } From bb927bdb3689d537fd6ca1c76579e4b547a959f5 Mon Sep 17 00:00:00 2001 From: Axel Naumann Date: Fri, 5 Mar 2021 17:51:02 +0100 Subject: [PATCH 3/5] [cling] ForwardDeclPrinter: also log skipped types. --- .../lib/Interpreter/ForwardDeclPrinter.cpp | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp b/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp index a7312dd702bfa..ef55c3a7219c4 100644 --- a/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp +++ b/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp @@ -114,6 +114,7 @@ namespace cling { QT = utils::TypeName::GetFullyQualifiedType(QT, m_Ctx); Visit(QT.getTypePtr()); } + void ForwardDeclPrinter::Visit(clang::Decl *D) { auto Insert = m_Visited.insert(std::pair( getCanonicalOrNamespace(D), true)); @@ -971,6 +972,10 @@ namespace cling { dyn_cast(Param)) { Visit(TTPD); // FIXME: print the default argument, if present. + if (m_SkipFlag) { + skipDecl(TTPD, "template template param decl failed"); + return; + } } } @@ -1080,6 +1085,10 @@ namespace cling { for (const TemplateArgument& TA: iargs.asArray()) { VisitTemplateArgument(TA); } + if (m_SkipFlag) { + skipDecl(D, "template arguments failed"); + return; + } // Out() << "template <> "; // VisitCXXRecordDecl(D->getCanonicalDecl()); @@ -1098,6 +1107,10 @@ namespace cling { Visit(D->getSpecializedTemplate()); //Above code doesn't work properly //Must find better and more general way to print specializations + if (m_SkipFlag) { + skipDecl(D, "template specialization failed"); + return; + } } @@ -1107,6 +1120,10 @@ namespace cling { #define VISIT_DECL(WHAT, HOW) \ case clang::Type::WHAT: \ Visit(static_cast(typ)->HOW().getTypePtr()); \ + if (m_SkipFlag) { \ + skipDecl(nullptr, #WHAT " type failed"); \ + return; \ + } \ break VISIT_DECL(ConstantArray, getElementType); VISIT_DECL(DependentSizedArray, getElementType); @@ -1136,6 +1153,10 @@ namespace cling { const MemberPointerType* MPT = static_cast(typ); Visit(MPT->getPointeeType().getTypePtr()); + if (m_SkipFlag) { + skipDecl(nullptr, "pointee type failed"); + return; + } Visit(MPT->getClass()); } break; @@ -1152,8 +1173,16 @@ namespace cling { = static_cast(typ); for (const TemplateArgument& TA: *TST) { VisitTemplateArgument(TA); + if (m_SkipFlag) { + skipDecl(nullptr, "template argument failed"); + return; + } } VisitTemplateName(TST->getTemplateName()); + if (m_SkipFlag) { + skipDecl(nullptr, "template specialization type failed"); + return; + } } break; From 0309a6f28cbc079415eff7a6c98e9057b6184030 Mon Sep 17 00:00:00 2001 From: Axel Naumann Date: Fri, 5 Mar 2021 18:07:04 +0100 Subject: [PATCH 4/5] [dictgen,clingutils] Expose fwdDecl errors for --debug. --- core/clingutils/res/TClingUtils.h | 2 +- core/clingutils/src/TClingUtils.cxx | 14 ++++++++++++-- core/dictgen/src/rootcling_impl.cxx | 8 +++++++- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/core/clingutils/res/TClingUtils.h b/core/clingutils/res/TClingUtils.h index 45382a9993d7c..593252673bf1d 100644 --- a/core/clingutils/res/TClingUtils.h +++ b/core/clingutils/res/TClingUtils.h @@ -855,7 +855,7 @@ namespace AST2SourceTools { //______________________________________________________________________________ const std::string Decls2FwdDecls(const std::vector &decls, bool (*ignoreFiles)(const clang::PresumedLoc&) , - const cling::Interpreter& interp); + const cling::Interpreter& interp, std::string *logs); //______________________________________________________________________________ int PrepareArgsForFwdDecl(std::string& templateArgs, diff --git a/core/clingutils/src/TClingUtils.cxx b/core/clingutils/src/TClingUtils.cxx index 1566114415e81..2065189647334 100644 --- a/core/clingutils/src/TClingUtils.cxx +++ b/core/clingutils/src/TClingUtils.cxx @@ -5105,7 +5105,10 @@ bool ROOT::TMetaUtils::IsHeaderName(const std::string &filename) //////////////////////////////////////////////////////////////////////////////// -const std::string ROOT::TMetaUtils::AST2SourceTools::Decls2FwdDecls(const std::vector &decls, cling::Interpreter::IgnoreFilesFunc_t ignoreFiles, const cling::Interpreter &interp) +const std::string ROOT::TMetaUtils::AST2SourceTools::Decls2FwdDecls(const std::vector &decls, + cling::Interpreter::IgnoreFilesFunc_t ignoreFiles, + const cling::Interpreter &interp, + std::string *logs) { clang::Sema &sema = interp.getSema(); cling::Transaction theTransaction(sema); @@ -5117,8 +5120,15 @@ const std::string ROOT::TMetaUtils::AST2SourceTools::Decls2FwdDecls(const std::v } std::string newFwdDecl; llvm::raw_string_ostream llvmOstr(newFwdDecl); - interp.forwardDeclare(theTransaction, sema.getPreprocessor(), sema.getASTContext(), llvmOstr, true, nullptr, ignoreFiles); + + std::string locallogs; + llvm::raw_string_ostream llvmLogStr(locallogs); + interp.forwardDeclare(theTransaction, sema.getPreprocessor(), sema.getASTContext(), llvmOstr, true, + logs ? &llvmLogStr : nullptr, ignoreFiles); llvmOstr.flush(); + llvmLogStr.flush(); + if (logs) + logs->swap(locallogs); return newFwdDecl; } diff --git a/core/dictgen/src/rootcling_impl.cxx b/core/dictgen/src/rootcling_impl.cxx index 87c340fe820d8..ae1404185cd39 100644 --- a/core/dictgen/src/rootcling_impl.cxx +++ b/core/dictgen/src/rootcling_impl.cxx @@ -3308,10 +3308,16 @@ static std::string GenerateFwdDeclString(const RScanner &scan, // for (auto* VAR: scan.fSelectedVariables) // selectedDecls.push_back(VAR); + std::string fwdDeclLogs; + // The "R\"DICTFWDDCLS(\n" ")DICTFWDDCLS\"" pieces have been moved to // TModuleGenerator to be able to make the diagnostics more telling in presence // of an issue ROOT-6752. - fwdDeclString += Decls2FwdDecls(selectedDecls,IsLinkdefFile,interp); + fwdDeclString += Decls2FwdDecls(selectedDecls,IsLinkdefFile,interp, genreflex::verbose ? &fwdDeclLogs : nullptr); + + if (genreflex::verbose && !fwdDeclLogs.empty()) + std::cout << "Logs from forward decl printer: \n" + << fwdDeclLogs; // Functions // for (auto const& fcnDeclPtr : scan.fSelectedFunctions){ From 4e6f5c28055aa8815e089ad0411f5392b5ff4944 Mon Sep 17 00:00:00 2001 From: Axel Naumann Date: Fri, 5 Mar 2021 21:57:03 +0100 Subject: [PATCH 5/5] [cling] Put `else` back to handle CastExpr of DeclRefExpr --- interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp b/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp index ef55c3a7219c4..889eb585aea70 100644 --- a/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp +++ b/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp @@ -1228,7 +1228,7 @@ namespace cling { Expr* TAExpr = TA.getAsExpr(); if (CastExpr* CastExpr = dyn_cast(TAExpr)) TAExpr = CastExpr->getSubExpr(); - else if (DeclRefExpr* DRE = dyn_cast(TAExpr)) { + if (DeclRefExpr* DRE = dyn_cast(TAExpr)) { Visit(DRE->getFoundDecl()); if (m_SkipFlag) { return;