Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package cvise for openSUSE:Factory checked in at 2022-12-16 17:51:37 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/cvise (Old) and /work/SRC/openSUSE:Factory/.cvise.new.1835 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "cvise" Fri Dec 16 17:51:37 2022 rev:64 rq:1043346 version:2.6.0+git.20221216.1423ed5 Changes: -------- --- /work/SRC/openSUSE:Factory/cvise/cvise.changes 2022-12-14 14:11:31.831657513 +0100 +++ /work/SRC/openSUSE:Factory/.cvise.new.1835/cvise.changes 2022-12-16 17:51:44.292046225 +0100 @@ -1,0 +2,18 @@ +Fri Dec 16 14:46:32 UTC 2022 - mli...@suse.cz + +- Update to version 2.6.0+git.20221216.1423ed5: + * Split remove-base-class transformation into remove-base-class and merge-base-class and supporting templated base classes + * Update reason comment. + * Improve LLVM version detection. + * Add support for skipIf get_llvm_version. + +------------------------------------------------------------------- +Thu Dec 15 17:37:53 UTC 2022 - mli...@suse.cz + +- Update to version 2.6.0+git.20221215.2f76b4f: + * Added getDescribedTemplateParams for backwards compatibility + * The move-function-body transformation learned to move class methods, templated functions and methods within templated classes + * testing: quit if we cannot create bug report + * Fixed crash in reduce-class-template-param + +------------------------------------------------------------------- Old: ---- cvise-2.6.0+git.20221214.96f841e.tar.xz New: ---- cvise-2.6.0+git.20221216.1423ed5.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ cvise.spec ++++++ --- /var/tmp/diff_new_pack.a0wCJ1/_old 2022-12-16 17:51:44.840049241 +0100 +++ /var/tmp/diff_new_pack.a0wCJ1/_new 2022-12-16 17:51:44.844049263 +0100 @@ -17,7 +17,7 @@ Name: cvise -Version: 2.6.0+git.20221214.96f841e +Version: 2.6.0+git.20221216.1423ed5 Release: 0 Summary: Super-parallel Python port of the C-Reduce License: BSD-3-Clause ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.a0wCJ1/_old 2022-12-16 17:51:44.908049615 +0100 +++ /var/tmp/diff_new_pack.a0wCJ1/_new 2022-12-16 17:51:44.912049637 +0100 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/marxin/cvise</param> - <param name="changesrevision">96f841e316adad54bdce10cc2b045eaf4619e142</param></service></servicedata> + <param name="changesrevision">1423ed528af9bcef03169c09c3a5077cf65867b4</param></service></servicedata> (No newline at EOF) ++++++ cvise-2.6.0+git.20221214.96f841e.tar.xz -> cvise-2.6.0+git.20221216.1423ed5.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/CMakeLists.txt new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/CMakeLists.txt --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/CMakeLists.txt 2022-12-14 08:57:16.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/CMakeLists.txt 2022-12-16 15:46:11.000000000 +0100 @@ -118,6 +118,30 @@ "/tests/reduce-array-dim/non-type-temp-arg.output" "/tests/reduce-pointer-level/scalar-init-expr.cpp" "/tests/reduce-pointer-level/scalar-init-expr.output" + "/tests/merge-base-class/test1.cc" + "/tests/merge-base-class/test1.output" + "/tests/merge-base-class/test2.cc" + "/tests/merge-base-class/test2.output" + "/tests/merge-base-class/test3.cc" + "/tests/merge-base-class/test3.output" + "/tests/remove-base-class/test1.cc" + "/tests/remove-base-class/test1.output" + "/tests/remove-base-class/test2.cc" + "/tests/remove-base-class/test2.output" + "/tests/remove-base-class/test3.cc" + "/tests/remove-base-class/test3.output" + "/tests/remove-base-class/test4.cc" + "/tests/remove-base-class/test4.output" + "/tests/move-function-body/test1.cc" + "/tests/move-function-body/test1.output" + "/tests/move-function-body/test2.cc" + "/tests/move-function-body/test2.output" + "/tests/move-function-body/test3.cc" + "/tests/move-function-body/test3.output" + "/tests/move-function-body/test4.cc" + "/tests/move-function-body/test4.output" + "/tests/move-function-body/test5.cc" + "/tests/move-function-body/test5.output" "/tests/remove-namespace/macro.cpp" "/tests/remove-namespace/macro.output" "/tests/remove-namespace/macro.output2" @@ -519,6 +543,7 @@ RemoveArray.h RemoveBaseClass.cpp RemoveBaseClass.h + MergeBaseClass.cpp RemoveCtorInitializer.cpp RemoveCtorInitializer.h RemoveEnumMemberValue.cpp diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/MergeBaseClass.cpp new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/MergeBaseClass.cpp --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/MergeBaseClass.cpp 1970-01-01 01:00:00.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/MergeBaseClass.cpp 2022-12-16 15:46:11.000000000 +0100 @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// Copyright (c) 2012, 2013, 2014, 2015, 2016, 2017, 2018 The University of Utah +// All rights reserved. +// +// This file is distributed under the University of Illinois Open Source +// License. See the file COPYING for details. +// +//===----------------------------------------------------------------------===// + +#if HAVE_CONFIG_H +# include <config.h> +#endif + +#include "RemoveBaseClass.h" + +#include "TransformationManager.h" + +static const char* DescriptionMsg = +"This pass merges a base class into a derived class if \n\ + * it has less than or equal to 5 declarations. \n\ +All its declarations will be moved into one of its subclasses, \ +and all references to this base class will be replaced with \ +the corresponding subclass. \n"; + +static RegisterTransformation<RemoveBaseClass, RemoveBaseClass::EMode> + Trans("merge-base-class", DescriptionMsg, RemoveBaseClass::EMode::Merge); + + +// Implementation is in RemoveBaseClass.cp + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/MoveFunctionBody.cpp new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/MoveFunctionBody.cpp --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/MoveFunctionBody.cpp 2022-12-14 08:57:16.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/MoveFunctionBody.cpp 2022-12-16 15:46:11.000000000 +0100 @@ -24,58 +24,41 @@ static const char *DescriptionMsg = "Move function body towards its declaration. \ -Note that this pass would generate incompilable code. \n"; +Note that this pass would generate uncompilable code. \n"; static RegisterTransformation<MoveFunctionBody> Trans("move-function-body", DescriptionMsg); -void MoveFunctionBody::Initialize(ASTContext &context) -{ - Transformation::Initialize(context); -} - -bool MoveFunctionBody::HandleTopLevelDecl(DeclGroupRef D) -{ - for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) { - FunctionDecl *FD = dyn_cast<FunctionDecl>(*I); - if (!FD || isInIncludedFile(FD)) { - PrevFunctionDecl = NULL; - continue; - } +class MoveFunctionBody::CollectionVisitor : public RecursiveASTVisitor<CollectionVisitor> { + MoveFunctionBody* ConsumerInstance; - FunctionDecl *CanonicalFD = FD->getCanonicalDecl(); - if (FD->isThisDeclarationADefinition()) { - FunctionDecl *FDDecl = AllValidFunctionDecls[CanonicalFD]; - if (!FDDecl) { - PrevFunctionDecl = NULL; - continue; - } +public: + explicit CollectionVisitor(MoveFunctionBody* Instance) : ConsumerInstance(Instance) + { } + + bool VisitFunctionDecl(FunctionDecl* FuncDef) { + if (!FuncDef->isThisDeclarationADefinition()) + return true; + + auto* FuncDecl = FuncDef->getFirstDecl(); + if (FuncDef == FuncDecl) + return true; + if (ConsumerInstance->isInIncludedFile(FuncDef) || ConsumerInstance->isInIncludedFile(FuncDecl)) + return true; - // Declaration and Definition are next to each other - if (PrevFunctionDecl) { - FunctionDecl *CanonicalPrevFD = PrevFunctionDecl->getCanonicalDecl(); - if (CanonicalFD == CanonicalPrevFD) { - PrevFunctionDecl = NULL; - continue; - } - } + ConsumerInstance->FunctionCandidates.push_back(FuncDef); - FuncDeclToFuncDef[FDDecl] = FD; - } + return true; + } - PrevFunctionDecl = FD; - // We only need the first FunctionDecl - if (AllValidFunctionDecls[CanonicalFD]) - continue; +private: +}; - AllValidFunctionDecls[CanonicalFD] = FD; - } - return true; -} - void MoveFunctionBody::HandleTranslationUnit(ASTContext &Ctx) { - doAnalysis(); + CollectionVisitor(this).TraverseDecl(Ctx.getTranslationUnitDecl()); + + ValidInstanceNum = FunctionCandidates.size(); if (QueryInstanceOnly) return; @@ -85,6 +68,9 @@ return; } + TheFunctionDef = FunctionCandidates[TransformationCounter-1]; + TheFunctionDecl = TheFunctionDef->getFirstDecl(); + Ctx.getDiagnostics().setSuppressAllDiagnostics(false); TransAssert(TheFunctionDecl && "NULL TheFunctionDecl!"); @@ -101,28 +87,70 @@ TransError = TransInternalError; } -void MoveFunctionBody::doAnalysis(void) -{ - for (FuncDeclToFuncDeclMap::iterator I = FuncDeclToFuncDef.begin(), - E = FuncDeclToFuncDef.end(); I != E; ++I) { - ValidInstanceNum++; - - if (ValidInstanceNum == TransformationCounter) { - TheFunctionDecl = (*I).first; - TheFunctionDef = (*I).second; - } - } +// Decl::getDescribedTemplateParams was introduced in LLVM 11. +// Copied here for backwards compatibility. +static const TemplateParameterList* getDescribedTemplateParams(Decl* D) { + if (auto* TD = D->getDescribedTemplate()) + return TD->getTemplateParameters(); + if (auto* CTPSD = dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) + return CTPSD->getTemplateParameters(); + if (auto* VTPSD = dyn_cast<VarTemplatePartialSpecializationDecl>(D)) + return VTPSD->getTemplateParameters(); + return nullptr; } void MoveFunctionBody::doRewriting(void) { - std::string FuncDefStr; - RewriteHelper->getFunctionDefStrAndRemove(TheFunctionDef, FuncDefStr); - RewriteHelper->addStringAfterFuncDecl(TheFunctionDecl, FuncDefStr); + SourceRange DefRange = RewriteHelper->getDeclFullSourceRange(TheFunctionDef); + + // Remove namespace and class qualifiers + if (auto QL = TheFunctionDef->getQualifierLoc()) { + TheRewriter.RemoveText(QL.getSourceRange()); + } + + if (auto* MD = dyn_cast<CXXMethodDecl>(TheFunctionDecl)) { + // Update the template parameters name of the class if they are empty + // This is very likely since unused parameter names gets removed during reduction + if (TheFunctionDef->getNumTemplateParameterLists() == 1) { + TemplateParameterList* TPL = TheFunctionDef->getTemplateParameterList(0); + + if (const TemplateParameterList* ClassTPL = getDescribedTemplateParams(MD->getParent())) { + assert(TPL->size() == ClassTPL->size()); + for (unsigned i2 = 0; i2 < ClassTPL->size(); ++i2) { + auto* Param = TPL->getParam(i2); + auto* ClassParam = ClassTPL->getParam(i2); + + if (ClassParam->getName().empty()) { + std::string ParamStr = TheRewriter.getRewrittenText(Param->getSourceRange()); + TheRewriter.ReplaceText(ClassParam->getSourceRange().getEnd(), ParamStr); + } + } + } + + TheRewriter.RemoveText(TPL->getSourceRange()); + } + + // Removing template lists for classes + for (unsigned i = 0; i < TheFunctionDef->getNumTemplateParameterLists(); ++i) { + TemplateParameterList* TPL = TheFunctionDef->getTemplateParameterList(i); + TheRewriter.RemoveText(TPL->getSourceRange()); + } + } + + std::string FuncDefStr = TheRewriter.getRewrittenText(DefRange); + + TheRewriter.RemoveText(DefRange); + + // Inside a class we need to remove the declaration + if (isa<CXXMethodDecl>(TheFunctionDecl)) { + auto DeclRange = RewriteHelper->getDeclFullSourceRange(TheFunctionDecl); + TheRewriter.ReplaceText(DeclRange, FuncDefStr); + } else { + RewriteHelper->addStringAfterFuncDecl(TheFunctionDecl, FuncDefStr); + } } MoveFunctionBody::~MoveFunctionBody(void) { // Nothing to do } - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/MoveFunctionBody.h new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/MoveFunctionBody.h --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/MoveFunctionBody.h 2022-12-14 08:57:16.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/MoveFunctionBody.h 2022-12-16 15:46:11.000000000 +0100 @@ -22,14 +22,13 @@ } class MoveFunctionBody : public Transformation { + class CollectionVisitor; + public: MoveFunctionBody(const char *TransName, const char *Desc) - : Transformation(TransName, Desc), - TheFunctionDecl(NULL), - TheFunctionDef(NULL), - PrevFunctionDecl(NULL) + : Transformation(TransName, Desc) { } ~MoveFunctionBody(void); @@ -39,31 +38,14 @@ typedef llvm::DenseMap<clang::FunctionDecl *, clang::FunctionDecl *> FuncDeclToFuncDeclMap; - virtual void Initialize(clang::ASTContext &context); - - virtual bool HandleTopLevelDecl(clang::DeclGroupRef D); - virtual void HandleTranslationUnit(clang::ASTContext &Ctx); - void doAnalysis(void); - void doRewriting(void); - FuncDeclToFuncDeclMap AllValidFunctionDecls; - - FuncDeclToFuncDeclMap FuncDeclToFuncDef; - - clang::FunctionDecl *TheFunctionDecl; - - clang::FunctionDecl *TheFunctionDef; - - clang::FunctionDecl *PrevFunctionDecl; - - // Unimplemented - MoveFunctionBody(void); + std::vector<clang::FunctionDecl*> FunctionCandidates; - MoveFunctionBody(const MoveFunctionBody &); + clang::FunctionDecl *TheFunctionDecl = nullptr; - void operator=(const MoveFunctionBody &); + clang::FunctionDecl *TheFunctionDef = nullptr; }; #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/ReduceClassTemplateParameter.cpp new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/ReduceClassTemplateParameter.cpp --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/ReduceClassTemplateParameter.cpp 2022-12-14 08:57:16.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/ReduceClassTemplateParameter.cpp 2022-12-16 15:46:11.000000000 +0100 @@ -206,10 +206,8 @@ "<>"); } else if ((ConsumerInstance->TheParameterIndex + 1) == NumArgs) { - SourceLocation EndLoc = Loc.getRAngleLoc(); - EndLoc = EndLoc.getLocWithOffset(-1); ConsumerInstance->RewriteHelper->removeTextFromLeftAt( - Range, ',', EndLoc); + Range, ',', Range.getEnd()); } else { ConsumerInstance->RewriteHelper->removeTextUntil(Range, ','); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/RemoveBaseClass.cpp new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/RemoveBaseClass.cpp --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/RemoveBaseClass.cpp 2022-12-14 08:57:16.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/RemoveBaseClass.cpp 2022-12-16 15:46:11.000000000 +0100 @@ -24,19 +24,14 @@ using namespace clang_delta_common_visitor; static const char *DescriptionMsg = -"This pass removes a base class from its class hierarchy if \n\ - * it has less than or equal to 5 declarations, and \n\ - * it is not a templated class. \n\ -All its declarations will be moved into one of its subclasses, \ -and all references to this base class will be replaced with \ -the corresponding subclass. \n"; +"This pass removes a base class from a derived class. \n"; // Note that this pass doesn't do much analysis, so -// it will produce quite a few incompilable code, especially +// it will produce quite a few uncompilable code, especially // when multi-inheritance is involved. -static RegisterTransformation<RemoveBaseClass> - Trans("remove-base-class", DescriptionMsg); +static RegisterTransformation<RemoveBaseClass, RemoveBaseClass::EMode> + Trans("remove-base-class", DescriptionMsg, RemoveBaseClass::EMode::Remove); class RemoveBaseClassBaseVisitor : public RecursiveASTVisitor<RemoveBaseClassBaseVisitor> { @@ -60,20 +55,6 @@ return true; } -class RemoveBaseClassRewriteVisitor : public - CommonRenameClassRewriteVisitor<RemoveBaseClassRewriteVisitor> -{ -public: - RemoveBaseClassRewriteVisitor(Transformation *Instance, - Rewriter *RT, - RewriteUtils *Helper, - const CXXRecordDecl *CXXRD, - const std::string &Name) - : CommonRenameClassRewriteVisitor<RemoveBaseClassRewriteVisitor> - (Instance, RT, Helper, CXXRD, Name) - { } -}; - void RemoveBaseClass::Initialize(ASTContext &context) { Transformation::Initialize(context); @@ -102,13 +83,6 @@ TransAssert(TheDerivedClass && "TheDerivedClass is NULL!"); Ctx.getDiagnostics().setSuppressAllDiagnostics(false); - RewriteVisitor = - new RemoveBaseClassRewriteVisitor(this, &TheRewriter, RewriteHelper, - TheBaseClass->getCanonicalDecl(), - TheDerivedClass->getNameAsString()); - - TransAssert(RewriteVisitor && "NULL RewriteVisitor!"); - RewriteVisitor->TraverseDecl(Ctx.getTranslationUnitDecl()); doRewrite(); if (Ctx.getDiagnostics().hasErrorOccurred() || @@ -134,59 +108,39 @@ void RemoveBaseClass::handleOneCXXRecordDecl(const CXXRecordDecl *CXXRD) { - if (isSpecialRecordDecl(CXXRD) || CXXRD->getDescribedClassTemplate() || - !CXXRD->hasDefinition()) + if (isSpecialRecordDecl(CXXRD) || !CXXRD->isThisDeclarationADefinition()) return; - const CXXRecordDecl *CanonicalRD = CXXRD->getCanonicalDecl(); - if (VisitedCXXRecordDecls.count(CanonicalRD)) - return; - VisitedCXXRecordDecls.insert(CanonicalRD); - if (CanonicalRD->getNumBases()) { - const CXXRecordDecl *Base = NULL; - for (CXXRecordDeclSet::iterator I = AllBaseClasses.begin(), - E = AllBaseClasses.end(); I != E; ++I) { - if (const ClassTemplateSpecializationDecl * CTSD = - dyn_cast<ClassTemplateSpecializationDecl> - (CanonicalRD->getDefinition())) { - if (!CTSD->isExplicitSpecialization()) - continue; - } + for (const CXXBaseSpecifier& BS : CXXRD->bases()) { + auto* Base = BS.getType()->getAsCXXRecordDecl(); - if (isInIncludedFile(*I)) - continue; - if (isDirectlyDerivedFrom(CanonicalRD, *I)) { - Base = (*I); - ValidInstanceNum++; - if (ValidInstanceNum == TransformationCounter) { - TransAssert(Base->hasDefinition() && - "Base class does not have any definition!"); - TheBaseClass = Base->getDefinition(); - TransAssert(CanonicalRD->hasDefinition() && - "Derived class does not have any definition!"); - TheDerivedClass = CanonicalRD->getDefinition(); - } - } + if (Base == nullptr) + continue; + if (Mode == EMode::Merge && getNumExplicitDecls(Base) > MaxNumDecls) + continue; + if (isInIncludedFile(Base)) + continue; + + ValidInstanceNum++; + if (ValidInstanceNum == TransformationCounter) { + TransAssert(Base->hasDefinition() && "Base class does not have any definition!"); + TheBaseClass = Base->getDefinition(); + TheDerivedClass = CXXRD; } - return; } - - if (getNumExplicitDecls(CanonicalRD) > MaxNumDecls) - return; - - if (!AllBaseClasses.count(CanonicalRD)) - AllBaseClasses.insert(CanonicalRD); } void RemoveBaseClass::doRewrite(void) { - copyBaseClassDecls(); + if (Mode == EMode::Merge) + copyBaseClassDecls(); removeBaseSpecifier(); - RewriteHelper->removeClassDecls(TheBaseClass); + if (Mode == EMode::Merge) + RewriteHelper->removeClassDecls(TheBaseClass); // ISSUE: I didn't handle Base initializer in a Ctor's initlist. // * keeping it untouched is wrong, because delegating constructors - // are only valie in c++11 + // are only valid in c++11 // * naively removing the base initializer doesn't work in some cases, // e.g., // class A { @@ -207,13 +161,37 @@ { if (!getNumExplicitDecls(TheBaseClass)) return; - SourceLocation StartLoc = TheBaseClass->getBraceRange().getBegin(); - SourceLocation EndLoc = TheBaseClass->getBraceRange().getEnd(); - TransAssert(EndLoc.isValid() && "Invalid RBraceLoc!"); - EndLoc = EndLoc.getLocWithOffset(-1); - std::string DeclsStr = - TheRewriter.getRewrittenText(SourceRange(StartLoc, EndLoc)); + std::string DeclsStr; + auto* CTSD = dyn_cast<ClassTemplateSpecializationDecl>(TheBaseClass); + if (CTSD && CTSD->getSpecializationKind() == TSK_ImplicitInstantiation) { + // For template bases, we use the printing feature of clang to generate + // the class with all resolved template parameters + + // Rename internally the constructors to the derived class + for (CXXConstructorDecl* CD : CTSD->ctors()) { + CD->setDeclName(TheDerivedClass->getDeclName()); + } + + llvm::raw_string_ostream Strm(DeclsStr); + CTSD->print(Strm); + + DeclsStr.erase(0, DeclsStr.find('{') + 1); + DeclsStr.erase(DeclsStr.rfind('}'), 1); + } else { + // Rename constructors + for (CXXConstructorDecl* CD : TheBaseClass->ctors()) { + TheRewriter.ReplaceText(CD->getNameInfo().getSourceRange(), TheDerivedClass->getDeclName().getAsString()); + } + + SourceLocation StartLoc = TheBaseClass->getBraceRange().getBegin(); + SourceLocation EndLoc = TheBaseClass->getBraceRange().getEnd(); + TransAssert(EndLoc.isValid() && "Invalid RBraceLoc!"); + StartLoc = StartLoc.getLocWithOffset(1); + EndLoc = EndLoc.getLocWithOffset(-1); + + DeclsStr = TheRewriter.getRewrittenText(SourceRange(StartLoc, EndLoc)) + "\n"; + } TransAssert(!DeclsStr.empty() && "Empty DeclsStr!"); SourceLocation InsertLoc = TheDerivedClass->getBraceRange().getEnd(); @@ -290,16 +268,16 @@ void RemoveBaseClass::removeBaseInitializer(void) { - for (CXXRecordDecl::ctor_iterator I = TheDerivedClass->ctor_begin(), - E = TheDerivedClass->ctor_end(); I != E; ++I) { - if ((*I)->isThisDeclarationADefinition() && !(*I)->isDefaulted()) - rewriteOneCtor(*I); + for (Decl* D : TheDerivedClass->decls()) { + if (auto* FTD = dyn_cast<FunctionTemplateDecl>(D)) + D =FTD->getTemplatedDecl(); + if (auto* Ctor = dyn_cast<CXXConstructorDecl>(D)) + if (Ctor->isThisDeclarationADefinition() && !Ctor->isDefaulted()) + rewriteOneCtor(Ctor); } } RemoveBaseClass::~RemoveBaseClass(void) { delete CollectionVisitor; - delete RewriteVisitor; } - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/RemoveBaseClass.h new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/RemoveBaseClass.h --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/RemoveBaseClass.h 2022-12-14 08:57:16.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/RemoveBaseClass.h 2022-12-16 15:46:11.000000000 +0100 @@ -22,21 +22,17 @@ } class RemoveBaseClassBaseVisitor; -class RemoveBaseClassRewriteVisitor; class RemoveBaseClass : public Transformation { friend class RemoveBaseClassBaseVisitor; public: - RemoveBaseClass(const char *TransName, const char *Desc) + enum class EMode { Remove, Merge }; + + RemoveBaseClass(const char *TransName, const char *Desc, EMode Mode) : Transformation(TransName, Desc), - CollectionVisitor(NULL), - RewriteVisitor(NULL), - TheBaseClass(NULL), - TheDerivedClass(NULL), - MaxNumDecls(5) + Mode(Mode) { } - ~RemoveBaseClass(void); private: @@ -63,19 +59,15 @@ bool isTheBaseClass(const clang::CXXBaseSpecifier &Specifier); - CXXRecordDeclSet VisitedCXXRecordDecls; - - CXXRecordDeclSet AllBaseClasses; - - RemoveBaseClassBaseVisitor *CollectionVisitor; + RemoveBaseClassBaseVisitor *CollectionVisitor = nullptr; - RemoveBaseClassRewriteVisitor *RewriteVisitor; + const clang::CXXRecordDecl *TheBaseClass = nullptr; - const clang::CXXRecordDecl *TheBaseClass; + const clang::CXXRecordDecl *TheDerivedClass = nullptr; - const clang::CXXRecordDecl *TheDerivedClass; + const unsigned MaxNumDecls = 5; - const unsigned MaxNumDecls; + EMode Mode; // Unimplemented RemoveBaseClass(void); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/RewriteUtils.cpp new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/RewriteUtils.cpp --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/RewriteUtils.cpp 2022-12-14 08:57:16.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/RewriteUtils.cpp 2022-12-16 15:46:11.000000000 +0100 @@ -173,6 +173,45 @@ return EndLoc.getLocWithOffset(Offset); } +clang::SourceRange RewriteUtils::getDeclFullSourceRange(const clang::Decl* D) +{ + SourceRange Range = D->getSourceRange(); + + // Ensure that template parameters are included in the def range + if (auto* FD = dyn_cast<FunctionDecl>(D)) { + if (FD->getNumTemplateParameterLists()) { + TemplateParameterList* TPL = FD->getTemplateParameterList(0); + Range.setBegin(TPL->getSourceRange().getBegin()); + } else if (auto* T = FD->getDescribedTemplate()) { + TemplateParameterList* TPL = T->getTemplateParameters(); + Range.setBegin(TPL->getSourceRange().getBegin()); + } + } else if (auto* TD = dyn_cast<TagDecl>(D)) { + if (TD->getNumTemplateParameterLists()) { + TemplateParameterList* TPL = TD->getTemplateParameterList(0); + Range.setBegin(TPL->getSourceRange().getBegin()); + } else if (auto* T = TD->getDescribedTemplate()) { + TemplateParameterList* TPL = T->getTemplateParameters(); + Range.setBegin(TPL->getSourceRange().getBegin()); + } + } + + + // Include the semicolon into the declaration. + // See DeclPrinter::VisitDeclContext in clang source code for all cases. + bool HasSemicolon = true; + if (auto* FD = dyn_cast<FunctionDecl>(D)) { + HasSemicolon = !FD->doesThisDeclarationHaveABody(); + } else if (auto* FTD = dyn_cast<FunctionTemplateDecl>(D)) { + HasSemicolon = !FTD->getTemplatedDecl()->isThisDeclarationADefinition(); + } + + if (HasSemicolon) + Range.setEnd(getEndLocationAfter(Range, ';')); + + return Range; +} + SourceLocation RewriteUtils::getLocationAfter(SourceLocation Loc, char Symbol) { @@ -1862,22 +1901,17 @@ bool RewriteUtils::removeClassDecls(const CXXRecordDecl *CXXRD) { - for (CXXRecordDecl::redecl_iterator I = CXXRD->redecls_begin(), - E = CXXRD->redecls_end(); I != E; ++I) { - SourceRange Range = (*I)->getSourceRange(); - SourceLocation LocEnd; - if ((*I)->isThisDeclarationADefinition()) { - LocEnd = (*I)->getBraceRange().getEnd(); - if (LocEnd.isValid()) - LocEnd = getLocationUntil(LocEnd, ';'); - else - LocEnd = getEndLocationUntil(Range, ';'); - } - else { - LocEnd = getEndLocationUntil(Range, ';'); - } - TheRewriter->RemoveText(SourceRange(Range.getBegin(), LocEnd)); + if (auto* CTSD = dyn_cast<ClassTemplateSpecializationDecl>(CXXRD)) { + if (CTSD->getSpecializationKind() == TSK_ImplicitInstantiation) + CXXRD = CTSD->getSpecializedTemplate()->getTemplatedDecl(); + } + + for (const TagDecl* Redecl : CXXRD->redecls()) { + SourceRange Range = getDeclFullSourceRange(Redecl); + if (Range.isValid()) + TheRewriter->RemoveText(Range); } + return true; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/RewriteUtils.h new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/RewriteUtils.h --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/RewriteUtils.h 2022-12-14 08:57:16.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/RewriteUtils.h 2022-12-16 15:46:11.000000000 +0100 @@ -282,6 +282,8 @@ clang::SourceLocation getLocationAfterSkiping(clang::SourceLocation StartLoc, char Symbol); + clang::SourceRange getDeclFullSourceRange(const clang::Decl* D); + private: static RewriteUtils *Instance; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/TransformationManager.h new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/TransformationManager.h --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/TransformationManager.h 2022-12-14 08:57:16.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/TransformationManager.h 2022-12-16 15:46:11.000000000 +0100 @@ -184,12 +184,12 @@ }; -template<typename TransformationClass> +template<typename TransformationClass, typename... Args> class RegisterTransformation { public: - RegisterTransformation(const char *TransName, const char *Desc) { - Transformation *TransImpl = new TransformationClass(TransName, Desc); + RegisterTransformation(const char *TransName, const char *Desc, Args... args) { + Transformation *TransImpl = new TransformationClass(TransName, Desc, args...); assert(TransImpl && "Fail to create TransformationClass"); TransformationManager::registerTransformation(TransName, TransImpl); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/merge-base-class/test1.cc new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/merge-base-class/test1.cc --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/merge-base-class/test1.cc 1970-01-01 01:00:00.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/merge-base-class/test1.cc 2022-12-16 15:46:11.000000000 +0100 @@ -0,0 +1,14 @@ + +struct c1 { + int x; + int y; + + // hello + c1(int x); +}; + +struct c2 : public c1 { + c2() : c1(5) { + } + +}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/merge-base-class/test1.output new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/merge-base-class/test1.output --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/merge-base-class/test1.output 1970-01-01 01:00:00.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/merge-base-class/test1.output 2022-12-16 15:46:11.000000000 +0100 @@ -0,0 +1,13 @@ + + + +struct c2 { + c2() { + } + + + int x; + int y; + + // hello + c2(int x); }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/merge-base-class/test2.cc new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/merge-base-class/test2.cc --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/merge-base-class/test2.cc 1970-01-01 01:00:00.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/merge-base-class/test2.cc 2022-12-16 15:46:11.000000000 +0100 @@ -0,0 +1,14 @@ + +template <class T> +struct c1 { + c1(T x); + + // hello + T y; +}; + +struct c2 : public c1<int> { + c2() : c1<int>(5) { + } + +}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/merge-base-class/test2.output new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/merge-base-class/test2.output --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/merge-base-class/test2.output 1970-01-01 01:00:00.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/merge-base-class/test2.output 2022-12-16 15:46:11.000000000 +0100 @@ -0,0 +1,11 @@ + + + +struct c2 { + c2() { + } + + + c2(int x); + int y; +}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/merge-base-class/test3.cc new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/merge-base-class/test3.cc --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/merge-base-class/test3.cc 1970-01-01 01:00:00.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/merge-base-class/test3.cc 2022-12-16 15:46:11.000000000 +0100 @@ -0,0 +1,18 @@ + +template <class T> +struct c1 { +}; + +template <> +struct c1<int> { + c1(int x); + + // hello + int y; +}; + +struct c2 : public c1<int> { + c2() : c1<int>(5) { + } + +}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/merge-base-class/test3.output new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/merge-base-class/test3.output --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/merge-base-class/test3.output 1970-01-01 01:00:00.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/merge-base-class/test3.output 2022-12-16 15:46:11.000000000 +0100 @@ -0,0 +1,16 @@ + +template <class T> +struct c1 { +}; + + + +struct c2 { + c2() { + } + + + c2(int x); + + // hello + int y; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/move-function-body/test1.cc new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/move-function-body/test1.cc --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/move-function-body/test1.cc 1970-01-01 01:00:00.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/move-function-body/test1.cc 2022-12-16 15:46:11.000000000 +0100 @@ -0,0 +1,8 @@ + +int test(int hello); + +// ... + +int test(int x) { + return 42; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/move-function-body/test1.output new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/move-function-body/test1.output --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/move-function-body/test1.output 1970-01-01 01:00:00.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/move-function-body/test1.output 2022-12-16 15:46:11.000000000 +0100 @@ -0,0 +1,9 @@ + +int test(int hello); +int test(int x) { + return 42; +} + +// ... + + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/move-function-body/test2.cc new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/move-function-body/test2.cc --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/move-function-body/test2.cc 1970-01-01 01:00:00.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/move-function-body/test2.cc 2022-12-16 15:46:11.000000000 +0100 @@ -0,0 +1,10 @@ + +template <class T> +T test(T); + +// ... + +template <class T> +T test(T x) { + return x; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/move-function-body/test2.output new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/move-function-body/test2.output --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/move-function-body/test2.output 1970-01-01 01:00:00.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/move-function-body/test2.output 2022-12-16 15:46:11.000000000 +0100 @@ -0,0 +1,11 @@ + +template <class T> +T test(T); +template <class T> +T test(T x) { + return x; +} + +// ... + + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/move-function-body/test3.cc new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/move-function-body/test3.cc --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/move-function-body/test3.cc 1970-01-01 01:00:00.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/move-function-body/test3.cc 2022-12-16 15:46:11.000000000 +0100 @@ -0,0 +1,12 @@ + +namespace ns { + struct C { + int test(int hello); + }; +} + +// ... + +int ns::C::test(int x) { + return 42; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/move-function-body/test3.output new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/move-function-body/test3.output --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/move-function-body/test3.output 1970-01-01 01:00:00.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/move-function-body/test3.output 2022-12-16 15:46:11.000000000 +0100 @@ -0,0 +1,12 @@ + +namespace ns { + struct C { + int test(int x) { + return 42; +} + }; +} + +// ... + + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/move-function-body/test4.cc new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/move-function-body/test4.cc --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/move-function-body/test4.cc 1970-01-01 01:00:00.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/move-function-body/test4.cc 2022-12-16 15:46:11.000000000 +0100 @@ -0,0 +1,14 @@ + +namespace ns { + struct C { + template <class T> + T test(T hello); + }; +} + +// ... + +template <class T> +T ns::C::test(T x) { + return 42; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/move-function-body/test4.output new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/move-function-body/test4.output --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/move-function-body/test4.output 1970-01-01 01:00:00.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/move-function-body/test4.output 2022-12-16 15:46:11.000000000 +0100 @@ -0,0 +1,13 @@ + +namespace ns { + struct C { + template <class T> +T test(T x) { + return 42; +} + }; +} + +// ... + + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/move-function-body/test5.cc new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/move-function-body/test5.cc --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/move-function-body/test5.cc 1970-01-01 01:00:00.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/move-function-body/test5.cc 2022-12-16 15:46:11.000000000 +0100 @@ -0,0 +1,14 @@ + +template <class> +struct C { + template <class T> + T test(T hello); +}; + +// ... + +template <class T1> +template <class T2> +T2 C<T1>::test(T2 x) { + return T1(); +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/move-function-body/test5.output new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/move-function-body/test5.output --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/move-function-body/test5.output 1970-01-01 01:00:00.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/move-function-body/test5.output 2022-12-16 15:46:11.000000000 +0100 @@ -0,0 +1,13 @@ + +template <class T1> +struct C { + +template <class T2> +T2 test(T2 x) { + return T1(); +} +}; + +// ... + + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/remove-base-class/test1.cc new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/remove-base-class/test1.cc --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/remove-base-class/test1.cc 1970-01-01 01:00:00.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/remove-base-class/test1.cc 2022-12-16 15:46:11.000000000 +0100 @@ -0,0 +1,14 @@ + +struct c1 { + int x; + int y; + + // hello + c1(int x); +}; + +struct c2 : public c1 { + c2() : c1(5) { + } + +}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/remove-base-class/test1.output new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/remove-base-class/test1.output --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/remove-base-class/test1.output 1970-01-01 01:00:00.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/remove-base-class/test1.output 2022-12-16 15:46:11.000000000 +0100 @@ -0,0 +1,14 @@ + +struct c1 { + int x; + int y; + + // hello + c1(int x); +}; + +struct c2 { + c2() { + } + +}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/remove-base-class/test2.cc new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/remove-base-class/test2.cc --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/remove-base-class/test2.cc 1970-01-01 01:00:00.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/remove-base-class/test2.cc 2022-12-16 15:46:11.000000000 +0100 @@ -0,0 +1,14 @@ + +template <class T> +struct c1 { + c1(T x); + + // hello + T y; +}; + +struct c2 : public c1<int> { + c2() : c1<int>(5) { + } + +}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/remove-base-class/test2.output new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/remove-base-class/test2.output --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/remove-base-class/test2.output 1970-01-01 01:00:00.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/remove-base-class/test2.output 2022-12-16 15:46:11.000000000 +0100 @@ -0,0 +1,14 @@ + +template <class T> +struct c1 { + c1(T x); + + // hello + T y; +}; + +struct c2 { + c2() { + } + +}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/remove-base-class/test3.cc new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/remove-base-class/test3.cc --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/remove-base-class/test3.cc 1970-01-01 01:00:00.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/remove-base-class/test3.cc 2022-12-16 15:46:11.000000000 +0100 @@ -0,0 +1,18 @@ + +template <class T> +struct c1 { +}; + +template <> +struct c1<int> { + c1(int x); + + // hello + int y; +}; + +struct c2 : public c1<int> { + c2() : c1<int>(5) { + } + +}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/remove-base-class/test3.output new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/remove-base-class/test3.output --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/remove-base-class/test3.output 1970-01-01 01:00:00.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/remove-base-class/test3.output 2022-12-16 15:46:11.000000000 +0100 @@ -0,0 +1,18 @@ + +template <class T> +struct c1 { +}; + +template <> +struct c1<int> { + c1(int x); + + // hello + int y; +}; + +struct c2 { + c2() { + } + +}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/remove-base-class/test4.cc new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/remove-base-class/test4.cc --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/remove-base-class/test4.cc 1970-01-01 01:00:00.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/remove-base-class/test4.cc 2022-12-16 15:46:11.000000000 +0100 @@ -0,0 +1,9 @@ +template <class T> +struct c { + c(T) {} +}; + +struct i : c<double>, c<int> { + template <class T> + i() : c<double>(1.0), c<int>(10) {} +}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/remove-base-class/test4.output new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/remove-base-class/test4.output --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/remove-base-class/test4.output 1970-01-01 01:00:00.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/remove-base-class/test4.output 2022-12-16 15:46:11.000000000 +0100 @@ -0,0 +1,9 @@ +template <class T> +struct c { + c(T) {} +}; + +struct i : c<int> { + template <class T> + i() : c<int>(10) {} +}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/test_clang_delta.py new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/test_clang_delta.py --- old/cvise-2.6.0+git.20221214.96f841e/clang_delta/tests/test_clang_delta.py 2022-12-14 08:57:16.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/clang_delta/tests/test_clang_delta.py 2022-12-16 15:46:11.000000000 +0100 @@ -1,8 +1,25 @@ import os +import re import subprocess import unittest +def get_llvm_version(): + current = os.path.dirname(__file__) + binary = os.path.join(current, '../clang_delta') + output = subprocess.check_output(f'ldd {binary}', shell=True, universal_newlines=True) + for line in output.splitlines(): + part = line.strip().split()[0] + if part.startswith('libLLVM'): + m = re.match(r'libLLVM-(?P<version>[0-9]+)\.so', part) + if m: + return int(m.group('version')) + else: + return int(part.split('.')[-1]) + + raise AssertionError() + + class TestClangDelta(unittest.TestCase): @classmethod @@ -357,7 +374,7 @@ def test_rename_class_bool(self): self.check_clang_delta('rename-class/bool.cc', '--transformation=rename-class --counter=1') - @unittest.skip(reason='Fails with LLVM 16') + @unittest.skipIf(get_llvm_version() >= 16, 'Fails with LLVM >= 16') def test_rename_class_class_template(self): self.check_clang_delta('rename-class/class_template.cc', '--transformation=rename-class --counter=1') @@ -614,3 +631,40 @@ def test_rename_operator_test2(self): self.check_clang_delta('rename-operator/test2.cc', '--transformation=rename-operator --counter=1') + + def test_merge_base_class_test1(self): + self.check_clang_delta('merge-base-class/test1.cc', '--transformation=merge-base-class --counter=1') + + @unittest.skipIf(get_llvm_version() <= 9, 'Fails with LLVM <= 9') + def test_merge_base_class_test2(self): + self.check_clang_delta('merge-base-class/test2.cc', '--transformation=merge-base-class --counter=1') + + def test_merge_base_class_test3(self): + self.check_clang_delta('merge-base-class/test3.cc', '--transformation=merge-base-class --counter=1') + + def test_remove_base_class_test1(self): + self.check_clang_delta('remove-base-class/test1.cc', '--transformation=remove-base-class --counter=1') + + def test_remove_base_class_test2(self): + self.check_clang_delta('remove-base-class/test2.cc', '--transformation=remove-base-class --counter=1') + + def test_remove_base_class_test3(self): + self.check_clang_delta('remove-base-class/test3.cc', '--transformation=remove-base-class --counter=1') + + def test_remove_base_class_test4(self): + self.check_clang_delta('remove-base-class/test4.cc', '--transformation=remove-base-class --counter=1') + + def test_move_function_body_test1(self): + self.check_clang_delta('move-function-body/test1.cc', '--transformation=move-function-body --counter=1') + + def test_move_function_body_test2(self): + self.check_clang_delta('move-function-body/test2.cc', '--transformation=move-function-body --counter=1') + + def test_move_function_body_test3(self): + self.check_clang_delta('move-function-body/test3.cc', '--transformation=move-function-body --counter=1') + + def test_move_function_body_test4(self): + self.check_clang_delta('move-function-body/test4.cc', '--transformation=move-function-body --counter=1') + + def test_move_function_body_test5(self): + self.check_clang_delta('move-function-body/test5.cc', '--transformation=move-function-body --counter=1') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/cvise/pass_groups/all.json new/cvise-2.6.0+git.20221216.1423ed5/cvise/pass_groups/all.json --- old/cvise-2.6.0+git.20221214.96f841e/cvise/pass_groups/all.json 2022-12-14 08:57:16.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/cvise/pass_groups/all.json 2022-12-16 15:46:11.000000000 +0100 @@ -85,6 +85,7 @@ {"pass": "clang", "arg": "reduce-class-template-param", "c": true }, {"pass": "clang", "arg": "remove-trivial-base-template", "c": true }, {"pass": "clang", "arg": "class-template-to-class", "c": true }, + {"pass": "clang", "arg": "merge-base-class", "c": true }, {"pass": "clang", "arg": "remove-base-class", "c": true }, {"pass": "clang", "arg": "replace-derived-class", "c": true }, {"pass": "clang", "arg": "remove-unresolved-base", "c": true }, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/cvise-2.6.0+git.20221214.96f841e/cvise/utils/testing.py new/cvise-2.6.0+git.20221216.1423ed5/cvise/utils/testing.py --- old/cvise-2.6.0+git.20221214.96f841e/cvise/utils/testing.py 2022-12-14 08:57:16.000000000 +0100 +++ new/cvise-2.6.0+git.20221216.1423ed5/cvise/utils/testing.py 2022-12-16 15:46:11.000000000 +0100 @@ -253,13 +253,15 @@ return extra_dir def report_pass_bug(self, test_env, problem): + """Create pass report bug and return True if the directory is created.""" + if not self.die_on_pass_bug: logging.warning(f'{self.current_pass} has encountered a non fatal bug: {problem}') crash_dir = self.get_extra_dir('cvise_bug_', self.MAX_CRASH_DIRS) if crash_dir is None: - return + return False os.mkdir(crash_dir) test_env.dump(crash_dir) @@ -276,6 +278,8 @@ if self.die_on_pass_bug: raise PassBugError(self.current_pass, problem, test_env.state, crash_dir) + else: + return True @staticmethod def diff_files(orig_file, changed_file): @@ -382,7 +386,8 @@ # Report bug if transform did not change the file if filecmp.cmp(self.current_test_case, test_env.test_case_path): if not self.silent_pass_bug: - self.report_pass_bug(test_env, 'pass failed to modify the variant') + if not self.report_pass_bug(test_env, 'pass failed to modify the variant'): + quit_loop = True else: quit_loop = True new_futures.add(future)