From: Axel Naumann Date: Tue, 23 Sep 2014 14:33:01 +0000 (+0200) Subject: Write declcontext for each visit; delay template <...>. X-Git-Tag: v6-02-00-rc1~20 X-Git-Url: https://root.cern.ch/gitweb?p=root.git;a=commitdiff_plain;h=a13d5cb80bb9786af6c6e42a8248950f3ab8ce3c Write declcontext for each visit; delay template <...>. Writing the template parameters might cause visitation of other decls which need to be in their respective namespaces. Thus we need to buffer / delay the whole template decl, including its enclosing namespaces. As we forward e.g. from ClassTemplateInstanceDecl() to RedeclarableTemplateDecl() we need to selectively write the enclosing namespaces, no just for any Visit(Decl*). Make sure that a template pattern is not again writing its enclosing scopes - it is just called from its VisitRedeclarableTemplateDecl(). --- diff --git a/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp b/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp index 449d51f..d7c768f 100644 --- a/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp +++ b/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.cpp @@ -122,15 +122,11 @@ namespace cling { // shouldSkip() called skipDecl() m_Visited[getCanonicalOrNamespace(D)] = false; } else { - StreamRAII Stream(*this); - std::string closeBraces = PrintEnclosingDeclContexts(D->getDeclContext()); clang::DeclVisitor::Visit(D); if (m_SkipFlag) { // D was not good, flag it. skipDecl(D, "Dependency skipped"); m_Visited[getCanonicalOrNamespace(D)] = false; - } else { - Out() << closeBraces; } } } @@ -226,6 +222,8 @@ namespace cling { return; } + std::string closeBraces = PrintEnclosingDeclContexts(Out(), + D->getDeclContext()); if (!m_Policy.SuppressSpecifiers) Out() << "typedef "; if (D->isModulePrivate()) @@ -240,7 +238,7 @@ namespace cling { q.print(Out(), m_Policy, D->getName()); } prettyPrintAttributes(D); - Out() << ";\n"; + Out() << ';' << closeBraces << '\n'; } void ForwardDeclPrinter::VisitTypeAliasDecl(TypeAliasDecl *D) { @@ -248,13 +246,17 @@ namespace cling { // 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) - << ";\n"; + << ';' << closeBraces << '\n'; } void ForwardDeclPrinter::VisitEnumDecl(EnumDecl *D) { + std::string closeBraces = PrintEnclosingDeclContexts(Out(), + D->getDeclContext()); if (!m_Policy.SuppressSpecifiers && D->isModulePrivate()) Out() << "__module_private__ "; Out() << "enum "; @@ -268,16 +270,24 @@ namespace cling { Out() << *D; // if (D->isFixed()) - Out() << " : " << D->getIntegerType().stream(m_Policy) << ";\n"; + Out() << " : " << D->getIntegerType().stream(m_Policy) + << ';' << closeBraces << '\n'; } void ForwardDeclPrinter::VisitRecordDecl(RecordDecl *D) { + std::string closeBraces; + bool isTemplatePattern = false; + if (CXXRecordDecl* CXXRD = dyn_cast(D)) + isTemplatePattern = CXXRD->getDescribedClassTemplate(); + if (!isTemplatePattern) + closeBraces = PrintEnclosingDeclContexts(Out(), D->getDeclContext()); if (!m_Policy.SuppressSpecifiers && D->isModulePrivate()) Out() << "__module_private__ "; Out() << D->getKindName(); prettyPrintAttributes(D); if (D->getIdentifier()) - Out() << ' ' << *D << ";\n"; + Out() << ' ' << *D << ';' << closeBraces << '\n'; + // if (D->isCompleteDefinition()) { // Out << " {\n"; @@ -300,6 +310,8 @@ namespace cling { StreamRAII stream(*this); + std::string closeBraces = PrintEnclosingDeclContexts(Out(), + D->getDeclContext()); if (!m_Policy.SuppressSpecifiers) { switch (D->getStorageClass()) { case SC_None: break; @@ -516,16 +528,17 @@ namespace cling { } } else Out() << ' '; - // D->getBody()->printPretty(Out, 0, SubPolicy, Indentation); - } + Out() << ';' << closeBraces << '\n'; } void ForwardDeclPrinter::VisitFriendDecl(FriendDecl *D) { } void ForwardDeclPrinter::VisitFieldDecl(FieldDecl *D) { + std::string closeBraces = PrintEnclosingDeclContexts(Out(), + D->getDeclContext()); if (!m_Policy.SuppressSpecifiers && D->isMutable()) Out() << "mutable "; if (!m_Policy.SuppressSpecifiers && D->isModulePrivate()) @@ -547,7 +560,7 @@ namespace cling { Init->printPretty(Out(), 0, m_Policy, m_Indentation); } prettyPrintAttributes(D); - Out() << ";\n"; + Out() << ';' << closeBraces << '\n'; } void ForwardDeclPrinter::VisitLabelDecl(LabelDecl *D) { @@ -566,6 +579,8 @@ namespace cling { return; } + std::string closeBraces = PrintEnclosingDeclContexts(Out(), + D->getDeclContext()); if (D->isDefinedOutsideFunctionOrMethod() && D->getStorageClass() != SC_Extern && D->getStorageClass() != SC_Static) Out() << "extern "; @@ -651,7 +666,7 @@ namespace cling { } } - Out() << ";\n"; + Out() << ';' << closeBraces << '\n'; } void ForwardDeclPrinter::VisitParmVarDecl(ParmVarDecl *D) { @@ -659,9 +674,11 @@ namespace cling { } void ForwardDeclPrinter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) { + std::string closeBraces = PrintEnclosingDeclContexts(Out(), + D->getDeclContext()); Out() << "__asm ("; D->getAsmString()->printPretty(Out(), 0, m_Policy, m_Indentation); - Out() << ");\n"; + Out() << ");" << closeBraces << '\n'; } void ForwardDeclPrinter::VisitImportDecl(ImportDecl *D) { @@ -670,11 +687,13 @@ namespace cling { } void ForwardDeclPrinter::VisitStaticAssertDecl(StaticAssertDecl *D) { + std::string closeBraces = PrintEnclosingDeclContexts(Out(), + D->getDeclContext()); Out() << "static_assert("; D->getAssertExpr()->printPretty(Out(), 0, m_Policy, m_Indentation); Out() << ", "; D->getMessage()->printPretty(Out(), 0, m_Policy, m_Indentation); - Out() << ");\n"; + Out() << ");" << closeBraces << '\n'; } //---------------------------------------------------------------------------- @@ -693,7 +712,7 @@ namespace cling { if (!haveAnyDecl) { // make sure at least one redecl of this namespace is fwd declared. if (D == D->getCanonicalDecl()) { - PrintNamespaceOpen(D); + PrintNamespaceOpen(Out(), D); Out() << "}\n"; } } @@ -706,10 +725,12 @@ namespace cling { return; } + std::string closeBraces = PrintEnclosingDeclContexts(Out(), + D->getDeclContext()); Out() << "using namespace "; if (D->getQualifier()) D->getQualifier()->print(Out(), m_Policy); - Out() << *D->getNominatedNamespaceAsWritten() << ";\n"; + Out() << *D->getNominatedNamespaceAsWritten() << ';' << closeBraces << '\n'; } void ForwardDeclPrinter::VisitUsingDecl(UsingDecl *D) { @@ -721,8 +742,10 @@ namespace cling { skipDecl(D, "shadow decl failed"); return; } + std::string closeBraces = PrintEnclosingDeclContexts(Out(), + D->getDeclContext()); D->print(Out(),m_Policy); - Out() << ";\n"; + Out() << ';' << closeBraces << '\n'; } void ForwardDeclPrinter::VisitUsingShadowDecl(UsingShadowDecl *D) { Visit(D->getTargetDecl()); @@ -734,17 +757,21 @@ namespace cling { } void ForwardDeclPrinter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { + std::string closeBraces = PrintEnclosingDeclContexts(Out(), + D->getDeclContext()); Out() << "namespace " << *D << " = "; if (D->getQualifier()) D->getQualifier()->print(Out(), m_Policy); - Out() << *D->getAliasedNamespace() << ";\n"; + Out() << *D->getAliasedNamespace() << ';' << closeBraces << '\n'; } void ForwardDeclPrinter::VisitEmptyDecl(EmptyDecl *D) { // prettyPrintAttributes(D); } - void ForwardDeclPrinter::VisitTagDecl(CXXRecordDecl *D) { + void ForwardDeclPrinter::VisitTagDecl(TagDecl *D) { + std::string closeBraces = PrintEnclosingDeclContexts(Out(), + D->getDeclContext()); if (!m_Policy.SuppressSpecifiers && D->isModulePrivate()) Out() << "__module_private__ "; Out() << D->getKindName(); @@ -752,7 +779,7 @@ namespace cling { // if (D->isCompleteDefinition()) prettyPrintAttributes(D); if (D->getIdentifier()) - Out() << ' ' << *D << ";\n"; + Out() << ' ' << *D << ';' << closeBraces << '\n'; } void ForwardDeclPrinter::VisitLinkageSpecDecl(LinkageSpecDecl *D) { @@ -762,13 +789,12 @@ namespace cling { } } - void ForwardDeclPrinter::PrintTemplateParameters(TemplateParameterList *Params, - const TemplateArgumentList *Args) { + void ForwardDeclPrinter::PrintTemplateParameters(llvm::raw_ostream& Stream, + TemplateParameterList *Params, + const TemplateArgumentList *Args) { assert(Params); assert(!Args || Params->size() == Args->size()); - std::string Output; - llvm::raw_string_ostream Stream(Output); Stream << "template <"; for (unsigned i = 0, e = Params->size(); i != e; ++i) { @@ -841,8 +867,6 @@ namespace cling { } Stream << "> "; - Stream.flush(); - Out() << Output; } void ForwardDeclPrinter::VisitRedeclarableTemplateDecl(const RedeclarableTemplateDecl *D) { @@ -855,9 +879,14 @@ namespace cling { D = RD; } - StreamRAII Stream(*this); + std::string Output; + llvm::raw_string_ostream Stream(Output); + + std::string closeBraces; + if (!isa(D)) + closeBraces = PrintEnclosingDeclContexts(Stream, D->getDeclContext()); - PrintTemplateParameters(D->getTemplateParameters()); + PrintTemplateParameters(Stream, D->getTemplateParameters()); if (m_SkipFlag) { skipDecl(0, "Template parameters failed"); return; @@ -865,14 +894,18 @@ namespace cling { if (const TemplateTemplateParmDecl *TTP = dyn_cast(D)) { - Out() << "class "; + Stream << "class "; if (TTP->isParameterPack()) Out() << "..."; - Out() << D->getName(); + Stream << D->getName(); } else { + StreamRAII SubStream(*this); Visit(D->getTemplatedDecl()); + Stream << SubStream.take(true); } + Stream.flush(); + Out() << Output << closeBraces << '\n'; } void ForwardDeclPrinter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { @@ -881,7 +914,8 @@ namespace cling { TemplateParameterList *Params = D->getTemplateParameters(); for (FunctionTemplateDecl::spec_iterator I = D->spec_begin(), E = D->spec_end(); I != E; ++I) { - PrintTemplateParameters(Params, (*I)->getTemplateSpecializationArgs()); + PrintTemplateParameters(Out(), + Params, (*I)->getTemplateSpecializationArgs()); if (m_SkipFlag) { skipDecl(D, "Template parameters failed"); return; @@ -907,7 +941,7 @@ namespace cling { TemplateParameterList *Params = D->getTemplateParameters(); for (ClassTemplateDecl::spec_iterator I = D->spec_begin(), E = D->spec_end(); I != E; ++I) { - PrintTemplateParameters(Params, &(*I)->getTemplateArgs()); + PrintTemplateParameters(Out(), Params, &(*I)->getTemplateArgs()); if (m_SkipFlag) { skipDecl(D, "template parameters failed"); return; @@ -1150,7 +1184,7 @@ namespace cling { bool ForwardDeclPrinter::shouldSkipImpl(VarDecl *D) { if (D->getType().isConstant(m_Ctx)) { Log() << D->getName() <<" Var : Const\n"; - m_Visited[D->getCanonicalDecl()] = false; + m_Visited[D->getCanonicalDecl()] = false; return true; } return false; @@ -1201,37 +1235,40 @@ namespace cling { for (auto&& i: m_Visited) if (!i.second) ++bad; - + Log() << bad << " decls skipped out of " << m_Visited.size() << "\n"; } - void ForwardDeclPrinter::PrintNamespaceOpen(NamespaceDecl* ND) { + void ForwardDeclPrinter::PrintNamespaceOpen(llvm::raw_ostream& Stream, + const NamespaceDecl* ND) { if (ND->isInline()) - Out() << "inline "; - Out() << "namespace " << *ND << '{'; + Stream << "inline "; + Stream << "namespace " << *ND << '{'; } - void ForwardDeclPrinter::PrintLinkageOpen(LinkageSpecDecl* LSD) { + void ForwardDeclPrinter::PrintLinkageOpen(llvm::raw_ostream& Stream, + const LinkageSpecDecl* LSD) { assert((LSD->getLanguage() == LinkageSpecDecl::lang_cxx || LSD->getLanguage() == LinkageSpecDecl::lang_c) && "Unknown linkage spec!"); - Out() << "extern \"C"; + Stream << "extern \"C"; if (LSD->getLanguage() == LinkageSpecDecl::lang_cxx) { - Out() << "++"; + Stream << "++"; } - Out() << "\" {"; + Stream << "\" {"; } - std::string ForwardDeclPrinter::PrintEnclosingDeclContexts(DeclContext* DC) { + std::string ForwardDeclPrinter::PrintEnclosingDeclContexts(llvm::raw_ostream& Stream, + const DeclContext* DC) { // Return closing "} } } }"... size_t numClose = 0; for(; DC && !DC->isTranslationUnit(); DC = DC->getParent()) { - if (NamespaceDecl* ND = dyn_cast(DC)) { - PrintNamespaceOpen(ND); + if (const NamespaceDecl* ND = dyn_cast(DC)) { + PrintNamespaceOpen(Stream, ND); ++numClose; - } else if (LinkageSpecDecl* LSD = dyn_cast(DC)) { - PrintLinkageOpen(LSD); + } else if (const LinkageSpecDecl* LSD = dyn_cast(DC)) { + PrintLinkageOpen(Stream, LSD); ++numClose; } else { Log() << "Skipping unhandled " << DC->getDeclKindName() << '\n'; diff --git a/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.h b/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.h index 8d16b7a..b917234 100644 --- a/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.h +++ b/interpreter/cling/lib/Interpreter/ForwardDeclPrinter.h @@ -134,7 +134,7 @@ namespace cling { void VisitUsingDecl(clang::UsingDecl* D); void VisitUsingShadowDecl(clang::UsingShadowDecl* D); void VisitNamespaceAliasDecl(clang::NamespaceAliasDecl *D); - void VisitTagDecl(clang::CXXRecordDecl *D); + void VisitTagDecl(clang::TagDecl *D); void VisitLinkageSpecDecl(clang::LinkageSpecDecl *D); void VisitRedeclarableTemplateDecl(const clang::RedeclarableTemplateDecl *D); void VisitFunctionTemplateDecl(clang::FunctionTemplateDecl *D); @@ -151,8 +151,9 @@ namespace cling { void printDeclType(clang::QualType T, llvm::StringRef DeclName, bool Pack = false); - void PrintTemplateParameters(clang::TemplateParameterList *Params, - const clang::TemplateArgumentList *Args = 0); + void PrintTemplateParameters(llvm::raw_ostream& Stream, + clang::TemplateParameterList *Params, + const clang::TemplateArgumentList *Args = 0); void prettyPrintAttributes(clang::Decl *D, std::string extra = ""); bool isOperator(clang::FunctionDecl* D); @@ -243,9 +244,12 @@ namespace cling { const clang::Decl* getCanonicalOrNamespace(const clang::NamespaceDecl* D) const { return D; } - std::string PrintEnclosingDeclContexts(clang::DeclContext* DC); - void PrintNamespaceOpen(clang::NamespaceDecl* ND); - void PrintLinkageOpen(clang::LinkageSpecDecl* LSD); + std::string PrintEnclosingDeclContexts(llvm::raw_ostream& Stream, + const clang::DeclContext* DC); + void PrintNamespaceOpen(llvm::raw_ostream& Stream, + const clang::NamespaceDecl* ND); + void PrintLinkageOpen(llvm::raw_ostream& Stream, + const clang::LinkageSpecDecl* LSD); class StreamRAII { ForwardDeclPrinter& m_pr;