/// Warns on methods overridden in DerivedDecl with respect to BaseDecl. /// FIXME: this warns on all overrides outside of the sliced path in case of /// multiple inheritance. void SlicingCheck::DiagnoseSlicedOverriddenMethods( const Expr &Call, const CXXRecordDecl &DerivedDecl, const CXXRecordDecl &BaseDecl) { if (DerivedDecl.getCanonicalDecl() == BaseDecl.getCanonicalDecl()) return; for (const auto &Method : DerivedDecl.methods()) { // Virtual destructors are OK. We're ignoring constructors since they are // tagged as overrides. if (isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method)) continue; if (Method->size_overridden_methods() > 0) { diag(Call.getExprLoc(), "slicing object from type %0 to %1 discards override %2") << &DerivedDecl << &BaseDecl << Method; } } // Recursively process bases. for (const auto &Base : DerivedDecl.bases()) { if (const auto *BaseRecordType = Base.getType()->getAs<RecordType>()) { if (const auto *BaseRecord = cast_or_null<CXXRecordDecl>( BaseRecordType->getDecl()->getDefinition())) DiagnoseSlicedOverriddenMethods(Call, *BaseRecord, BaseDecl); } } }
void ReturnSynthesizer::Transform() { if (!getTransaction()->getCompilationOpts().ResultEvaluation) return; FunctionDecl* FD = getTransaction()->getWrapperFD(); int foundAtPos = -1; Expr* lastExpr = utils::Analyze::GetOrCreateLastExpr(FD, &foundAtPos, /*omitDS*/false, m_Sema); if (lastExpr) { QualType RetTy = lastExpr->getType(); if (!RetTy->isVoidType() && RetTy.isTriviallyCopyableType(*m_Context)) { // Change the void function's return type // We can't PushDeclContext, because we don't have scope. Sema::ContextRAII pushedDC(*m_Sema, FD); FunctionProtoType::ExtProtoInfo EPI; QualType FnTy = m_Context->getFunctionType(RetTy, llvm::ArrayRef<QualType>(), EPI); FD->setType(FnTy); CompoundStmt* CS = cast<CompoundStmt>(FD->getBody()); assert(CS && "Missing body?"); // Change it to a return stmt (Avoid dealloc/alloc of all el.) *(CS->body_begin() + foundAtPos) = m_Sema->ActOnReturnStmt(lastExpr->getExprLoc(), lastExpr).take(); } } else if (foundAtPos >= 0) { // check for non-void return statement CompoundStmt* CS = cast<CompoundStmt>(FD->getBody()); Stmt* CSS = *(CS->body_begin() + foundAtPos); if (ReturnStmt* RS = dyn_cast<ReturnStmt>(CSS)) { if (Expr* RetV = RS->getRetValue()) { QualType RetTy = RetV->getType(); // Any return statement will have been "healed" by Sema // to correspond to the original void return type of the // wrapper, using a ImplicitCastExpr 'void' <ToVoid>. // Remove that. if (RetTy->isVoidType()) { ImplicitCastExpr* VoidCast = dyn_cast<ImplicitCastExpr>(RetV); if (VoidCast) { RS->setRetValue(VoidCast->getSubExpr()); RetTy = VoidCast->getSubExpr()->getType(); } } if (!RetTy->isVoidType() && RetTy.isTriviallyCopyableType(*m_Context)) { Sema::ContextRAII pushedDC(*m_Sema, FD); FunctionProtoType::ExtProtoInfo EPI; QualType FnTy = m_Context->getFunctionType(RetTy, llvm::ArrayRef<QualType>(), EPI); FD->setType(FnTy); } // not returning void } // have return value } // is a return statement } // have a statement }
// // Replace Enqueue Function Call // void HostProgramTuning::ProcessFuncCall(std::string fname, CallExpr* E) { if (dividend_prof_mode && E) { unsigned i = 0; if (fname == "clFinish") { clFinishPresent = true; } else if (fname == "clEnqueueNDRangeKernel" && pr) { //The 6th argument passed to clEnqueueNDRangeKernel is the //local work group size //I am going to rename it Expr *LArg = E->getArg(5); if (LArg) { SourceLocation SL = LArg->getExprLoc(); std::string TypeS; llvm::raw_string_ostream s(TypeS); LArg->printPretty(s, 0, Context.getPrintingPolicy()); if (pr->getIdentifier() != s.str()) { std::cerr << "[WARNING]: The local work group size identifer (" << s.str() << ") does not match with the one given in the pragma (" << pr->getIdentifier() << ")" << std::endl; } std::string rs = lwsName(pr->getIdentifier(), pr->getKernelId()); Rewrite.ReplaceText(SL, s.str().length(), rs.c_str()); delete pr; pr = NULL; } } while(FuncName2ReplaceWithDividendWarp[i] != NULL) { if (fname == FuncName2ReplaceWithDividendWarp[i]) { ReplaceWithDividendCLWrap(E, fname, addDividendWrap(fname)); break; } i++; } } }