From d026b4918a696e6c8a5ef2c15985c8b9d98da2b2 Mon Sep 17 00:00:00 2001 From: Axel Naumann Date: Tue, 22 Jun 2021 15:04:10 +0200 Subject: [PATCH] [cling] Also fwd decl underlying type of using decls: Before, only the using decl itself was forward declared, causing undeclared identifiers in forward declaration code, as witnessed in https://github.com/root-project/root/issues/8499 Given the similarity of using and typedef, merge both into a single function, making sure both have the same featureset, and through that fixing this issue as a side-effect. --- .../lib/Interpreter/ForwardDeclPrinter.cpp | 57 +++++++++++-------- .../lib/Interpreter/ForwardDeclPrinter.h | 3 + 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp b/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp index 889eb585aea70..810cb4aa9572b 100644 --- a/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp +++ b/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp @@ -298,7 +298,7 @@ namespace cling { } } - void ForwardDeclPrinter::VisitTypedefDecl(TypedefDecl *D) { + void ForwardDeclPrinter::printTypedefOrAliasDecl(TypedefNameDecl *D) { QualType q = D->getTypeSourceInfo()->getType(); Visit(q); if (m_SkipFlag) { @@ -308,34 +308,45 @@ namespace cling { std::string closeBraces = PrintEnclosingDeclContexts(Out(), D->getDeclContext()); - if (!m_Policy.SuppressSpecifiers) - Out() << "typedef "; - if (D->isModulePrivate()) - Out() << "__module_private__ "; + auto printUnderying = [&]() { + QualType qNoRestrict = q; + if (qNoRestrict.isRestrictQualified()) + qNoRestrict.removeLocalRestrict(); + qNoRestrict.print(Out(), m_Policy); + }; + auto printDeclName = [&]() { + if (D->isModulePrivate()) + Out() << "__module_private__ "; - if (q.isRestrictQualified()){ - q.removeLocalRestrict(); - q.print(Out(), m_Policy, ""); - Out() << " __restrict " << D->getName(); //TODO: Find some policy that does this automatically - } - else { - q.print(Out(), m_Policy, D->getName()); + if (q.isRestrictQualified()) { + Out() << " __restrict "; // TODO: Find some policy that does this automatically + } + Out() << D->getName(); + prettyPrintAttributes(D); + }; + + if (llvm::isa(D)) { + Out() << "typedef "; + printUnderying(); + Out() << " "; + printDeclName(); + } else if (llvm::isa(D)) { + Out() << "using "; + printDeclName(); + Out() << " = "; + printUnderying(); + } else { + skipDecl(D, "Neither a typedef nor a type alias!"); } - prettyPrintAttributes(D); Out() << ';' << closeBraces << '\n'; + } + + void ForwardDeclPrinter::VisitTypedefDecl(TypedefDecl *D) { + printTypedefOrAliasDecl(D); } void ForwardDeclPrinter::VisitTypeAliasDecl(TypeAliasDecl *D) { - /*FIXME: Ugly Hack*/ -// if(!D->getLexicalDeclContext()->isNamespace() -// && !D->getLexicalDeclContext()->isFileContext()) -// return; - std::string closeBraces = PrintEnclosingDeclContexts(Out(), - D->getDeclContext()); - Out() << "using " << *D; - prettyPrintAttributes(D); - Out() << " = " << D->getTypeSourceInfo()->getType().getAsString(m_Policy) - << ';' << closeBraces << '\n'; + printTypedefOrAliasDecl(D); } void ForwardDeclPrinter::VisitEnumDecl(EnumDecl *D) { diff --git a/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.h b/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.h index 8311be287d813..a4b0c68c932ff 100644 --- a/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.h +++ b/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.h @@ -79,6 +79,7 @@ namespace clang { class TranslationUnitDecl; class TypeAliasDecl; class TypedefDecl; + class TypedefNameDecl; class VarDecl; class UsingDirectiveDecl; } @@ -109,6 +110,8 @@ namespace cling { std::set m_BuiltinNames; IgnoreFilesFunc_t m_IgnoreFile; // Call back to ignore some top level files. + void printTypedefOrAliasDecl(clang::TypedefNameDecl* D); + public: ForwardDeclPrinter(llvm::raw_ostream& OutS, llvm::raw_ostream& LogS,