diff --git a/bindings/pyroot/pythonizations/test/numbadeclare.py b/bindings/pyroot/pythonizations/test/numbadeclare.py index 08dde20d26d82..6fa1eb0cce2bb 100644 --- a/bindings/pyroot/pythonizations/test/numbadeclare.py +++ b/bindings/pyroot/pythonizations/test/numbadeclare.py @@ -95,7 +95,7 @@ def test_cling(self): @ROOT.Numba.Declare(["float"], "float") def fn12(x): return 2.0 * x - ROOT.gInterpreter.ProcessLine("y12 = Numba::fn12(42.0);") + ROOT.gInterpreter.ProcessLine("auto y12 = Numba::fn12(42.0);") self.assertEqual(fn12(42.0), ROOT.y12) # Test RDataFrame integration diff --git a/core/metacling/src/TClingCallbacks.cxx b/core/metacling/src/TClingCallbacks.cxx index edbd33107192a..399551f7ddec0 100644 --- a/core/metacling/src/TClingCallbacks.cxx +++ b/core/metacling/src/TClingCallbacks.cxx @@ -395,18 +395,6 @@ bool TClingCallbacks::LookupObject(LookupResult &R, Scope *S) { if (tryFindROOTSpecialInternal(R, S)) return true; - // For backward-compatibility with CINT we must support stmts like: - // x = 4; y = new MyClass(); - // I.e we should "inject" a C++11 auto keyword in front of "x" and "y" - // This has to have higher precedence than the dynamic scopes. It is claimed - // that if one assigns to a name and the lookup of that name fails if *must* - // auto keyword must be injected and the stmt evaluation must not be delayed - // until runtime. - // For now supported only at the prompt. - if (tryInjectImplicitAutoKeyword(R, S)) { - return true; - } - if (fIsAutoLoadingRecursively) return false; @@ -926,87 +914,6 @@ bool TClingCallbacks::shouldResolveAtRuntime(LookupResult& R, Scope* S) { return false; } -bool TClingCallbacks::tryInjectImplicitAutoKeyword(LookupResult &R, Scope *S) { - if (!fROOTSpecialNamespace) { - // init error or rootcling - return false; - } - - // Should be disabled with the dynamic scopes. - if (m_IsRuntime) - return false; - - if (R.isForRedeclaration()) - return false; - - if (R.getLookupKind() != Sema::LookupOrdinaryName) - return false; - - if (!isa(R.getSema().CurContext)) - return false; - - { - // ROOT-8538: only top-most (function-level) scope is supported. - DeclContext* ScopeDC = S->getEntity(); - if (!ScopeDC || !llvm::isa(ScopeDC)) - return false; - - // Make sure that the failed lookup comes the prompt. Currently, we - // support only the prompt. - Scope* FnScope = S->getFnParent(); - if (!FnScope) - return false; - auto FD = dyn_cast_or_null(FnScope->getEntity()); - if (!FD || !utils::Analyze::IsWrapper(FD)) - return false; - } - - Sema& SemaRef = R.getSema(); - ASTContext& C = SemaRef.getASTContext(); - DeclContext* DC = SemaRef.CurContext; - assert(DC && "Must not be null."); - - - Preprocessor& PP = R.getSema().getPreprocessor(); - //Preprocessor::CleanupAndRestoreCacheRAII cleanupRAII(PP); - //PP.EnableBacktrackAtThisPos(); - if (PP.LookAhead(0).isNot(tok::equal)) { - //PP.Backtrack(); - return false; - } - //PP.CommitBacktrackedTokens(); - //cleanupRAII.pop(); - DeclarationName Name = R.getLookupName(); - IdentifierInfo* II = Name.getAsIdentifierInfo(); - SourceLocation Loc = R.getNameLoc(); - VarDecl* Result = VarDecl::Create(C, DC, Loc, Loc, II, - C.getAutoType(QualType(), - clang::AutoTypeKeyword::Auto, - /*IsDependent*/false), - /*TypeSourceInfo*/nullptr, SC_None); - - if (!Result) { - ROOT::TMetaUtils::Error("TClingCallbacks::tryInjectImplicitAutoKeyword", - "Cannot create VarDecl"); - return false; - } - - // Annotate the decl to give a hint in cling. - // FIXME: We should move this in cling, when we implement turning it on - // and off. - Result->addAttr(AnnotateAttr::CreateImplicit(C, "__Auto", nullptr, 0)); - - R.addDecl(Result); - - // Raise a warning when trying to use implicit auto injection feature. - SemaRef.getDiagnostics().setSeverity(diag::warn_deprecated_message, diag::Severity::Warning, SourceLocation()); - SemaRef.Diag(Loc, diag::warn_deprecated_message) - << "declaration without the 'auto' keyword" << DC << Loc << FixItHint::CreateInsertion(Loc, "auto "); - - // Say that we can handle the situation. Clang should try to recover - return true; -} - void TClingCallbacks::Initialize() { // Replay existing decls from the AST. if (fFirstRun) { diff --git a/core/metacling/src/TClingCallbacks.h b/core/metacling/src/TClingCallbacks.h index 5ac4ae2889b07..f7bcd632fa18a 100644 --- a/core/metacling/src/TClingCallbacks.h +++ b/core/metacling/src/TClingCallbacks.h @@ -128,6 +128,5 @@ class TClingCallbacks : public cling::InterpreterCallbacks { bool tryFindROOTSpecialInternal(clang::LookupResult &R, clang::Scope *S); bool tryResolveAtRuntimeInternal(clang::LookupResult &R, clang::Scope *S); bool shouldResolveAtRuntime(clang::LookupResult &R, clang::Scope *S); - bool tryInjectImplicitAutoKeyword(clang::LookupResult &R, clang::Scope *S); bool findInGlobalModuleIndex(clang::DeclarationName Name, bool loadFirstMatchOnly = true); }; diff --git a/core/metacling/test/TClingTests.cxx b/core/metacling/test/TClingTests.cxx index 674ec865c761e..f53abeceb81a2 100644 --- a/core/metacling/test/TClingTests.cxx +++ b/core/metacling/test/TClingTests.cxx @@ -88,24 +88,6 @@ TEST_F(TClingTests, GetEnumWithSameVariableName) EXPECT_TRUE(en != nullptr); } -TEST_F(TClingTests, SuccessfulAutoInjection) -{ - gInterpreter->ProcessLine("int SuccessfulAutoInjectionTest(int j) { return 0; }"); - gInterpreter->ProcessLine("success = SuccessfulAutoInjectionTest(3)"); - - auto success = gInterpreter->GetDataMember(nullptr, "success"); - EXPECT_TRUE(success != nullptr); -} - -TEST_F(TClingTests, FailedAutoInjection) -{ - gInterpreter->ProcessLine("int FailedAutoInjectionTest(int j) { return 0; }"); - gInterpreter->ProcessLine("failed = FailedAutoInjectionTest(3, 6)"); - - auto failed = gInterpreter->GetDataMember(nullptr, "failed"); - EXPECT_TRUE(failed == nullptr); -} - // Check if we can get the source code of function definitions. TEST_F(TClingTests, MakeInterpreterValue) { @@ -239,19 +221,6 @@ TEST_F(TClingTests, GetSharedLibDeps) } #endif -// Check that a warning message is generated when using auto-injection. -TEST_F(TClingTests, WarningAutoInjection) -{ - ROOT::TestSupport::CheckDiagsRAII diags; - diags.requiredDiag(kWarning, "cling", "declaration without the 'auto' keyword is deprecated", - /*matchFullMessage=*/false); - - gInterpreter->ProcessLine("/* no auto */ t = new int;"); - - auto t = gInterpreter->GetDataMember(nullptr, "t"); - EXPECT_TRUE(t != nullptr); -} - // Check the interface which interacts with the cling::LookupHelper. TEST_F(TClingTests, ClingLookupHelper) { // Exception spec evaluation. diff --git a/interpreter/cling/lib/Interpreter/AutoSynthesizer.cpp b/interpreter/cling/lib/Interpreter/AutoSynthesizer.cpp deleted file mode 100644 index e14eccab82e4a..0000000000000 --- a/interpreter/cling/lib/Interpreter/AutoSynthesizer.cpp +++ /dev/null @@ -1,125 +0,0 @@ -//------------------------------------------------------------------------------ -// CLING - the C++ LLVM-based InterpreterG :) -// author: Vassil Vassilev -// -// This file is dual-licensed: you can choose to license it under the University -// of Illinois Open Source License or the GNU Lesser General Public License. See -// LICENSE.TXT for details. -//------------------------------------------------------------------------------ - -#include "AutoSynthesizer.h" - -#include "clang/AST/ASTContext.h" -#include "clang/AST/RecursiveASTVisitor.h" -#include "clang/Sema/Sema.h" - -using namespace clang; - -namespace cling { - class AutoFixer : public RecursiveASTVisitor { - private: - Sema* m_Sema; - DeclRefExpr* m_FoundDRE; - llvm::DenseSet m_HandledDecls; - private: - public: - AutoFixer(Sema* S) : m_Sema(S), m_FoundDRE(nullptr) {} - - CompoundStmt* Fix(CompoundStmt* CS) { - if (!CS->size()) - return nullptr; - typedef llvm::SmallVector Statements; - Statements Stmts; - Stmts.append(CS->body_begin(), CS->body_end()); - for (Statements::iterator I = Stmts.begin(); I != Stmts.end(); ++I) { - if (!TraverseStmt(*I) && !m_HandledDecls.count(m_FoundDRE->getDecl())) { - Sema::DeclGroupPtrTy VDPtrTy - = m_Sema->ConvertDeclToDeclGroup(m_FoundDRE->getDecl()); - StmtResult DS = m_Sema->ActOnDeclStmt(VDPtrTy, - m_FoundDRE->getBeginLoc(), - m_FoundDRE->getEndLoc()); - assert(!DS.isInvalid() && "Invalid DeclStmt."); - I = Stmts.insert(I, DS.get()); - m_HandledDecls.insert(m_FoundDRE->getDecl()); - } - } - if (CS->size() != Stmts.size()) { - FPOptionsOverride FPFeatures; - if (CS->hasStoredFPFeatures()) { - FPFeatures = CS->getStoredFPFeatures(); - } - return CompoundStmt::Create(m_Sema->getASTContext(), Stmts, FPFeatures, - CS->getLBracLoc(), CS->getRBracLoc()); - } - return nullptr; - } - - CXXTryStmt* Fix(CXXTryStmt* TS) { - ASTContext &Context = m_Sema->getASTContext(); - CompoundStmt *TryBlock = TS->getTryBlock(); - if (CompoundStmt *NewTryBlock = Fix(TryBlock)) - TryBlock = NewTryBlock; - - llvm::SmallVector Handlers(TS->getNumHandlers()); - for (unsigned int h = 0; h < TS->getNumHandlers(); ++h) { - CXXCatchStmt *Handler = TS->getHandler(h); - Stmt *HandlerBlock = Handler->getHandlerBlock(); - if (CompoundStmt *HandlerCS = dyn_cast_or_null(HandlerBlock)) { - if (CompoundStmt *NewHandlerCS = Fix(HandlerCS)) - HandlerBlock = NewHandlerCS; - } else if (CXXTryStmt *HandlerTS = dyn_cast_or_null(HandlerBlock)) { - if (CXXTryStmt *NewHandlerTS = Fix(HandlerTS)) - HandlerBlock = NewHandlerTS; - } - Handlers[h] = new (Context) - CXXCatchStmt(Handler->getCatchLoc(), Handler->getExceptionDecl(), - HandlerBlock); - } - - return CXXTryStmt::Create(Context, TS->getTryLoc(), TryBlock, Handlers); - } - - bool VisitDeclRefExpr(DeclRefExpr* DRE) { - const Decl* D = DRE->getDecl(); - if (const AnnotateAttr* A = D->getAttr()) - if (A->getAnnotation().equals("__Auto")) { - m_FoundDRE = DRE; - return false; // we abort on the first found candidate. - } - return true; // returning false will abort the in-depth traversal. - } - }; -} // end namespace cling - -namespace cling { - AutoSynthesizer::AutoSynthesizer(clang::Sema* S) - : ASTTransformer(S) { - // TODO: We would like to keep that local without keeping track of all - // decls that were handled in the AutoFixer. This can be done by removing - // the __Auto attribute, but for now I am still hesitant to do it. Having - // the __Auto attribute is very useful for debugging because it localize the - // the problem if exists. - m_AutoFixer.reset(new AutoFixer(S)); - } - - // pin the vtable here. - AutoSynthesizer::~AutoSynthesizer() - { } - - ASTTransformer::Result AutoSynthesizer::Transform(Decl* D) { - if (FunctionDecl* FD = dyn_cast(D)) { - // getBody() might return nullptr even though hasBody() is true for - // late template parsed functions. We simply don't do auto auto on - // those. - Stmt *Body = FD->getBody(); - if (CompoundStmt* CS = dyn_cast_or_null(Body)) - Body = m_AutoFixer->Fix(CS); - else if (CXXTryStmt *TS = dyn_cast_or_null(Body)) - Body = m_AutoFixer->Fix(TS); - - if (Body != nullptr) - FD->setBody(Body); - } - return Result(D, true); - } -} // end namespace cling diff --git a/interpreter/cling/lib/Interpreter/AutoSynthesizer.h b/interpreter/cling/lib/Interpreter/AutoSynthesizer.h deleted file mode 100644 index ad717e5c8b867..0000000000000 --- a/interpreter/cling/lib/Interpreter/AutoSynthesizer.h +++ /dev/null @@ -1,43 +0,0 @@ -//--------------------------------------------------------------------*- C++ -*- -// CLING - the C++ LLVM-based InterpreterG :) -// author: Vassil Vassilev -// -// This file is dual-licensed: you can choose to license it under the University -// of Illinois Open Source License or the GNU Lesser General Public License. See -// LICENSE.TXT for details. -//------------------------------------------------------------------------------ - -#ifndef CLING_AUTO_SYNTHESIZER_H -#define CLING_AUTO_SYNTHESIZER_H - -#include "ASTTransformer.h" - -#include - -namespace clang { - class Decl; - class Sema; -} - -namespace cling { - class AutoFixer; - - class AutoSynthesizer : public ASTTransformer { - private: - std::unique_ptr m_AutoFixer; - - public: - ///\ brief Constructs the auto synthesizer. - /// - ///\param[in] S - The semantic analysis object. - /// - AutoSynthesizer(clang::Sema* S); - - virtual ~AutoSynthesizer(); - - Result Transform(clang::Decl*) override; - }; - -} // namespace cling - -#endif // CLING_AUTO_SYNTHESIZER_H diff --git a/interpreter/cling/lib/Interpreter/CMakeLists.txt b/interpreter/cling/lib/Interpreter/CMakeLists.txt index e397da97f6bda..6170b2aea0301 100644 --- a/interpreter/cling/lib/Interpreter/CMakeLists.txt +++ b/interpreter/cling/lib/Interpreter/CMakeLists.txt @@ -58,7 +58,6 @@ endif() add_cling_library(clingInterpreter OBJECT - AutoSynthesizer.cpp AutoloadCallback.cpp ASTTransformer.cpp BackendPasses.cpp diff --git a/interpreter/cling/lib/Interpreter/IncrementalParser.cpp b/interpreter/cling/lib/Interpreter/IncrementalParser.cpp index 58e2b56736df8..d26b972d42562 100644 --- a/interpreter/cling/lib/Interpreter/IncrementalParser.cpp +++ b/interpreter/cling/lib/Interpreter/IncrementalParser.cpp @@ -10,7 +10,6 @@ #include "IncrementalParser.h" #include "ASTTransformer.h" -#include "AutoSynthesizer.h" #include "CheckEmptyTransactionTransformer.h" #include "ClingPragmas.h" #include "DeclCollector.h" @@ -1023,7 +1022,6 @@ namespace cling { // Register the AST Transformers typedef std::unique_ptr ASTTPtr_t; std::vector ASTTransformers; - ASTTransformers.emplace_back(new AutoSynthesizer(TheSema)); ASTTransformers.emplace_back(new EvaluateTSynthesizer(TheSema)); if (hasCodeGenerator() && !m_Interpreter->getOptions().NoRuntime) { // Don't protect against crashes if we cannot run anything. diff --git a/interpreter/llvm-project/clang/lib/Sema/SemaExpr.cpp b/interpreter/llvm-project/clang/lib/Sema/SemaExpr.cpp index 99f41d8134591..4cce0abc23150 100644 --- a/interpreter/llvm-project/clang/lib/Sema/SemaExpr.cpp +++ b/interpreter/llvm-project/clang/lib/Sema/SemaExpr.cpp @@ -15654,46 +15654,6 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, switch (Opc) { case BO_Assign: - // ROOT hack: we want to support constructs like n = new TNamed() and if n - // wasn't declared we should declare it. - if (DeclRefExpr* DRE = dyn_cast(LHSExpr)) { - if (VarDecl* VD = dyn_cast(DRE->getDecl())) { - if (const AutoType* aTy = dyn_cast(VD->getType().getTypePtr())) { - if (const AnnotateAttr* A = VD->getAttr()) { - // If the deduction didn't take place and it is our special - // annotation - if (!aTy->isDeduced() && A->getAnnotation().equals("__Auto")) { - QualType ResTy; - ASTContext& C = getASTContext(); - TypeSourceInfo* TrivialTSI - = C.getTrivialTypeSourceInfo(VD->getType()); - TemplateDeductionInfo Info(RHSExpr->getExprLoc()); - TemplateDeductionResult Result = - DeduceAutoType(TrivialTSI->getTypeLoc(), RHSExpr, ResTy, Info); - if (Result != TDK_Success && Result != TDK_AlreadyDiagnosed) { - Diag(VD->getLocation(), diag::err_auto_var_requires_init) - << VD->getDeclName() << VD->getType(); - VD->setInvalidDecl(); - - return ExprError(); - } - if (!ResTy.isNull()) { - VD->setTypeSourceInfo(C.getTrivialTypeSourceInfo(ResTy)); - VD->setType(ResTy); - } - VD->setInit(DefaultLvalueConversion(RHSExpr).get()); - PushOnScopeChains(VD, getCurScope(), /*Add to ctx*/true); - - // Here we need to return 'something' to make the parser happy. - // A reference to the decl is semantically closest to what we want. - return BuildDeclRefExpr(VD, VD->getType(), VK_LValue, - SourceLocation()); - } - } - } - } - } - ResultTy = CheckAssignmentOperands(LHS.get(), RHS, OpLoc, QualType(), Opc); if (getLangOpts().CPlusPlus && LHS.get()->getObjectKind() != OK_ObjCProperty) {