diff --git a/lib/Interpreter/ForwardDeclPrinter.cpp b/lib/Interpreter/ForwardDeclPrinter.cpp index 285d17c2..da9222a2 100644 --- a/lib/Interpreter/ForwardDeclPrinter.cpp +++ b/lib/Interpreter/ForwardDeclPrinter.cpp @@ -13,41 +13,40 @@ #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" - namespace cling { using namespace clang; - static QualType GetBaseType(QualType T) { - // FIXME: This should be on the Type class! - QualType BaseType = T; - while (!BaseType->isSpecifierType()) { - if (isa(BaseType)) - break; - else if (const PointerType* PTy = BaseType->getAs()) - BaseType = PTy->getPointeeType(); - else if (const BlockPointerType *BPy = BaseType->getAs()) - BaseType = BPy->getPointeeType(); - else if (const ArrayType* ATy = dyn_cast(BaseType)) - BaseType = ATy->getElementType(); - else if (const FunctionType* FTy = BaseType->getAs()) - BaseType = FTy->getReturnType(); - else if (const VectorType *VTy = BaseType->getAs()) - BaseType = VTy->getElementType(); - else if (const ReferenceType *RTy = BaseType->getAs()) - BaseType = RTy->getPointeeType(); - else - llvm_unreachable("Unknown declarator!"); - } - return BaseType; - } - static QualType getDeclType(Decl* D) { - if (TypedefNameDecl* TDD = dyn_cast(D)) - return TDD->getUnderlyingType(); - if (ValueDecl* VD = dyn_cast(D)) - return VD->getType(); - return QualType(); - } +// static QualType GetBaseType(QualType T) { +// // FIXME: This should be on the Type class! +// QualType BaseType = T; +// while (!BaseType->isSpecifierType()) { +// if (isa(BaseType)) +// break; +// else if (const PointerType* PTy = BaseType->getAs()) +// BaseType = PTy->getPointeeType(); +// else if (const BlockPointerType *BPy = BaseType->getAs()) +// BaseType = BPy->getPointeeType(); +// else if (const ArrayType* ATy = dyn_cast(BaseType)) +// BaseType = ATy->getElementType(); +// else if (const FunctionType* FTy = BaseType->getAs()) +// BaseType = FTy->getReturnType(); +// else if (const VectorType *VTy = BaseType->getAs()) +// BaseType = VTy->getElementType(); +// else if (const ReferenceType *RTy = BaseType->getAs()) +// BaseType = RTy->getPointeeType(); +// else +// llvm_unreachable("Unknown declarator!"); +// } +// return BaseType; +// } +// static QualType getDeclType(Decl* D) { +// if (TypedefNameDecl* TDD = dyn_cast(D)) +// return TDD->getUnderlyingType(); +// if (ValueDecl* VD = dyn_cast(D)) +// return VD->getType(); +// return QualType(); +// } ForwardDeclPrinter::ForwardDeclPrinter(llvm::raw_ostream& Out, SourceManager& SM, @@ -62,9 +61,11 @@ namespace cling { m_Policy.Bool = true; // Avoid printing _Bool instead of bool // Suppress some unfixable warnings. + // TODO: Find proper fix for these issues m_Out << "#pragma clang diagnostic ignored \"-Wkeyword-compat\"" << "\n"; m_Out << "#pragma clang diagnostic ignored \"-Wignored-attributes\"" <<"\n"; - + m_Out << "#pragma clang diagnostic ignored \"-Wreturn-type-c-linkage\"" <<"\n"; + std::vector macrodefs; if (printMacros) { for (auto mit = T.macros_begin(); mit != T.macros_end(); ++mit) { @@ -160,14 +161,18 @@ namespace cling { m_Out << "\"))) "; } - void ForwardDeclPrinter::ProcessDeclGroup(SmallVectorImpl& Decls) { - Indent(); - Decl::printGroup(Decls.data(), Decls.size(), m_Out, m_Policy, - m_Indentation); - m_Out << ";\n"; - Decls.clear(); - - } +// void ForwardDeclPrinter::ProcessDeclGroup(SmallVectorImpl& Decls) { +//// Indent(); +//// Decl::printGroup(Decls.data(), Decls.size(), m_Out, m_Policy, +//// m_Indentation); +//// m_Out << ";\n"; +//// Decls.clear(); +// for (auto decl : Decls ) { +// Visit(decl); +// printSemiColon(); +// } +// Decls.clear(); +// } void ForwardDeclPrinter::Print(AccessSpecifier AS) { switch(AS) { @@ -182,135 +187,117 @@ namespace cling { // Common C declarations //---------------------------------------------------------------------------- - void ForwardDeclPrinter::VisitDeclContext(DeclContext *DC, bool shouldIndent){ - if (m_Policy.TerseOutput) - return; - if (shouldIndent) - m_Indentation += m_Policy.Indentation; +// void ForwardDeclPrinter::VisitDeclContext(DeclContext *DC, bool shouldIndent){ +// if (m_Policy.TerseOutput) +// return; +// if (shouldIndent) +// m_Indentation += m_Policy.Indentation; - SmallVector Decls; - for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end(); - D != DEnd; ++D) { +// SmallVector Decls; +// for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end(); +// D != DEnd; ++D) { - // Don't print ObjCIvarDecls, as they are printed when visiting the - // containing ObjCInterfaceDecl. - if (isa(*D)) - continue; +// // Don't print ObjCIvarDecls, as they are printed when visiting the +// // containing ObjCInterfaceDecl. +// if (isa(*D)) +// continue; - // Skip over implicit declarations in pretty-printing mode. - if (D->isImplicit()) - continue; +// // Skip over implicit declarations in pretty-printing mode. +// if (D->isImplicit()) +// continue; - // The next bits of code handles stuff like "struct {int x;} a,b"; we're - // forced to merge the declarations because there's no other way to - // refer to the struct in question. This limited merging is safe without - // a bunch of other checks because it only merges declarations directly - // referring to the tag, not typedefs. - // - // Check whether the current declaration should be grouped with a previous - // unnamed struct. - QualType CurDeclType = getDeclType(*D); - if (!Decls.empty() && !CurDeclType.isNull()) { - QualType BaseType = GetBaseType(CurDeclType); - if (!BaseType.isNull() && isa(BaseType)) - BaseType = cast(BaseType)->getNamedType(); - if (!BaseType.isNull() && isa(BaseType) && - cast(BaseType)->getDecl() == Decls[0]) { - Decls.push_back(*D); - continue; - } - } +// // The next bits of code handles stuff like "struct {int x;} a,b"; we're +// // forced to merge the declarations because there's no other way to +// // refer to the struct in question. This limited merging is safe without +// // a bunch of other checks because it only merges declarations directly +// // referring to the tag, not typedefs. +// // +// // Check whether the current declaration should be grouped with a previous +// // unnamed struct. +// QualType CurDeclType = getDeclType(*D); +// if (!Decls.empty() && !CurDeclType.isNull()) { +// QualType BaseType = GetBaseType(CurDeclType); +// if (!BaseType.isNull() && isa(BaseType)) +// BaseType = cast(BaseType)->getNamedType(); +// if (!BaseType.isNull() && isa(BaseType) && +// cast(BaseType)->getDecl() == Decls[0]) { +// Decls.push_back(*D); +// continue; +// } +// } - // If we have a merged group waiting to be handled, handle it now. - if (!Decls.empty()) - ProcessDeclGroup(Decls); +// // If we have a merged group waiting to be handled, handle it now. +// if (!Decls.empty()) +// ProcessDeclGroup(Decls); - // If the current declaration is an unnamed tag type, save it - // so we can merge it with the subsequent declaration(s) using it. - if (isa(*D) && !cast(*D)->getIdentifier()) { - Decls.push_back(*D); - continue; - } +// // If the current declaration is an unnamed tag type, save it +// // so we can merge it with the subsequent declaration(s) using it. +// if (isa(*D) && !cast(*D)->getIdentifier()) { +// Decls.push_back(*D); +// continue; +// } - if (isa(*D)) { - m_Indentation -= m_Policy.Indentation; - Indent(); - Print(D->getAccess()); - m_Out << ":\n"; - m_Indentation += m_Policy.Indentation; - continue; - } +// if (isa(*D)) { +// m_Indentation -= m_Policy.Indentation; +// Indent(); +// Print(D->getAccess()); +// m_Out << ":\n"; +// m_Indentation += m_Policy.Indentation; +// continue; +// } - Indent(); - Visit(*D); +// Indent(); +// Visit(*D); - const char *Terminator = 0; - if (isa(*D)) - Terminator = 0; - else if (isa(*D) && - cast(*D)->isThisDeclarationADefinition()) - Terminator = 0; - else if (isa(*D) && cast(*D)->getBody()) - Terminator = 0; - else if (isa(*D) || isa(*D) || - isa(*D) || - isa(*D) || - isa(*D) || - isa(*D) || - isa(*D)) - Terminator = 0; - else if (isa(*D)) { - DeclContext::decl_iterator Next = D; - ++Next; - if (Next != DEnd) - Terminator = ","; - } else - Terminator = ";"; +// const char *Terminator = 0; +// if (isa(*D)) +// Terminator = 0; +// else if (isa(*D) && +// cast(*D)->isThisDeclarationADefinition()) +// Terminator = 0; +// else if (isa(*D) && cast(*D)->getBody()) +// Terminator = 0; +// else if (isa(*D) || isa(*D) || +// isa(*D) || +// isa(*D) || +// isa(*D) || +// isa(*D) || +// isa(*D)) +// Terminator = 0; +// else if (isa(*D)) { +// DeclContext::decl_iterator Next = D; +// ++Next; +// if (Next != DEnd) +// Terminator = ","; +// } else +// Terminator = ";"; - if (Terminator) - m_Out << Terminator; - m_Out << "\n"; - } +// if (Terminator) +// m_Out << Terminator; +// m_Out << "\n"; +// } - if (!Decls.empty()) - ProcessDeclGroup(Decls); +// if (!Decls.empty()) +// ProcessDeclGroup(Decls); - if (shouldIndent) - m_Indentation -= m_Policy.Indentation; - } +// if (shouldIndent) +// m_Indentation -= m_Policy.Indentation; +// } void ForwardDeclPrinter::VisitTranslationUnitDecl(TranslationUnitDecl *D) { - VisitDeclContext(D, false); +// VisitDeclContext(D, false); + for (auto it = D->decls_begin(); it != D->decls_end(); ++it) { + Visit(*it); + printSemiColon(); + } } void ForwardDeclPrinter::VisitTypedefDecl(TypedefDecl *D) { -// if (const ElaboratedType* ET = -// dyn_cast(D->getTypeSourceInfo()->getType().getTypePtr())) { -// if (const EnumType* Enum = -// dyn_cast(ET->getNamedType())) { - -// std::string str = "_enum_" + std::to_string(m_UniqueCounter++); - -// VisitEnumDecl(Enum->getDecl(),str); -// printSemiColon(); -// m_Out << "typedef " << str << ' ' << D->getName(); -// return; -// } -// } - - llvm::StringRef str = D->getTypeSourceInfo()->getType().getAsString(); - if (str.startswith("enum")) { - std::pair pair = str.split(' '); - m_IncompatibleTypes.insert(pair.second); + if (shouldSkip(D)) { m_SkipFlag = true; return; } - if (isIncompatibleType(D->getTypeSourceInfo()->getType())) { - m_SkipFlag = true; - return; - } - if (!m_Policy.SuppressSpecifiers) { m_Out << "typedef "; @@ -386,7 +373,7 @@ namespace cling { } void ForwardDeclPrinter::VisitFunctionDecl(FunctionDecl *D) { - if (shouldSkipFunction(D)) { + if (shouldSkip(D)) { m_SkipFlag = true; return; } @@ -635,6 +622,7 @@ namespace cling { // Out << "friend "; // VisitRedeclarableTemplateDecl(CTD); // } + m_SkipFlag = true; } void ForwardDeclPrinter::VisitFieldDecl(FieldDecl *D) { @@ -781,7 +769,7 @@ namespace cling { printSemiColon(); } Indent() << "}\n"; - m_SkipFlag = true; + m_SkipFlag = true; //Don't print a semi after a namespace } void ForwardDeclPrinter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { @@ -791,6 +779,13 @@ namespace cling { m_Out << *D->getNominatedNamespaceAsWritten(); } + void ForwardDeclPrinter::VisitUsingDecl(UsingDecl *D) { + m_SkipFlag = true; + } + void ForwardDeclPrinter::VisitUsingShadowDecl(UsingShadowDecl *D) { + m_SkipFlag = true; + } + void ForwardDeclPrinter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { m_Out << "namespace " << *D << " = "; if (D->getQualifier()) @@ -804,7 +799,7 @@ namespace cling { } void ForwardDeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) { - if (D->getNameAsString().size() == 0) { + if (shouldSkip(D)) { m_SkipFlag = true; return; } @@ -846,8 +841,8 @@ namespace cling { // VisitDeclContext(D); // Indent() << "}"; // } - m_Out << ";\n"; - m_SkipFlag = true; +// m_Out << ";\n"; +// m_SkipFlag = true; } void ForwardDeclPrinter::VisitLinkageSpecDecl(LinkageSpecDecl *D) { @@ -956,7 +951,7 @@ namespace cling { } void ForwardDeclPrinter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { - if (shouldSkipFunction(D->getAsFunction())) { + if (shouldSkip(D->getAsFunction())) { m_SkipFlag = true; return; } @@ -974,7 +969,7 @@ namespace cling { } void ForwardDeclPrinter::VisitClassTemplateDecl(ClassTemplateDecl *D) { - if (D->getName().size() == 0 ) { + if (shouldSkip(D->getTemplatedDecl()) ) { m_SkipFlag = true; return; } @@ -994,7 +989,7 @@ namespace cling { void ForwardDeclPrinter:: VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl* D) { - //D->dump(); + m_SkipFlag = true; } void ForwardDeclPrinter::printSemiColon(bool flag) { @@ -1029,12 +1024,13 @@ namespace cling { } bool ForwardDeclPrinter::isOperator(FunctionDecl *D) { + //TODO: Find a better check for this return D->getNameAsString().find("operator") == 0; } - bool ForwardDeclPrinter::shouldSkipFunction(FunctionDecl *D) { + bool ForwardDeclPrinter::shouldSkip(FunctionDecl *D) { bool param = false; - //will be true if any of the params turn out to have nested types + //will be true if any of the params turn out to have incompatible types for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) { if (isIncompatibleType(D->getParamDecl(i)->getType())) @@ -1051,4 +1047,24 @@ namespace cling { return true; return false; } + bool ForwardDeclPrinter::shouldSkip(CXXRecordDecl *D) { + return D->getNameAsString().size() == 0; + } + bool ForwardDeclPrinter::shouldSkip(TypedefDecl *D) { + if (const ElaboratedType* ET = + dyn_cast(D->getTypeSourceInfo()->getType().getTypePtr())) { + if (isa(ET->getNamedType())) { + m_IncompatibleTypes.insert(D->getName()); +// m_SkipFlag = true; + return true; + } + } + + if (isIncompatibleType(D->getTypeSourceInfo()->getType())) { +// m_SkipFlag = true; + return true; + } + return false; + + } }//end namespace cling diff --git a/lib/Interpreter/ForwardDeclPrinter.h b/lib/Interpreter/ForwardDeclPrinter.h index 080a6c7f..b086df8b 100644 --- a/lib/Interpreter/ForwardDeclPrinter.h +++ b/lib/Interpreter/ForwardDeclPrinter.h @@ -71,7 +71,7 @@ namespace cling { const clang::PrintingPolicy& P, unsigned Indentation = 0); - void VisitDeclContext(clang::DeclContext *DC, bool shouldIndent = true); +// void VisitDeclContext(clang::DeclContext *DC, bool shouldIndent = true); void VisitTranslationUnitDecl(clang::TranslationUnitDecl *D); void VisitTypedefDecl(clang::TypedefDecl *D); @@ -91,6 +91,8 @@ namespace cling { void VisitStaticAssertDecl(clang::StaticAssertDecl *D); void VisitNamespaceDecl(clang::NamespaceDecl *D); void VisitUsingDirectiveDecl(clang::UsingDirectiveDecl *D); + void VisitUsingDecl(clang::UsingDecl* D); + void VisitUsingShadowDecl(clang::UsingShadowDecl* D); void VisitNamespaceAliasDecl(clang::NamespaceAliasDecl *D); void VisitCXXRecordDecl(clang::CXXRecordDecl *D); void VisitLinkageSpecDecl(clang::LinkageSpecDecl *D); @@ -109,12 +111,22 @@ namespace cling { bool isIncompatibleType(clang::QualType q); bool isOperator(clang::FunctionDecl* D); - bool shouldSkipFunction(clang::FunctionDecl* D); + + template + bool shouldSkip(DeclT* D){return false;} + + bool shouldSkip(clang::FunctionDecl* D); + bool shouldSkip(clang::CXXRecordDecl* D); + bool shouldSkip(clang::TypedefDecl* D); + bool shouldSkip(clang::ClassTemplateSpecializationDecl* D){return true;} + bool shouldSkip(clang::UsingDecl* D){return true;} + bool shouldSkip(clang::UsingShadowDecl* D){return true;} + private: llvm::raw_ostream& Indent() { return Indent(m_Indentation); } llvm::raw_ostream& Indent(unsigned Indentation); - void ProcessDeclGroup(llvm::SmallVectorImpl& Decls); +// void ProcessDeclGroup(llvm::SmallVectorImpl& Decls); void Print(clang::AccessSpecifier AS); };