================ @@ -13,246 +13,40 @@ #include "IncrementalParser.h" #include "clang/AST/DeclContextInternals.h" -#include "clang/CodeGen/BackendUtil.h" -#include "clang/CodeGen/CodeGenAction.h" -#include "clang/CodeGen/ModuleBuilder.h" #include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/FrontendAction.h" -#include "clang/FrontendTool/Utils.h" -#include "clang/Interpreter/Interpreter.h" +#include "clang/Interpreter/PartialTranslationUnit.h" #include "clang/Parse/Parser.h" #include "clang/Sema/Sema.h" -#include "llvm/Option/ArgList.h" #include "llvm/Support/CrashRecoveryContext.h" #include "llvm/Support/Error.h" -#include "llvm/Support/Timer.h" #include <sstream> namespace clang { -class IncrementalASTConsumer final : public ASTConsumer { - Interpreter &Interp; - std::unique_ptr<ASTConsumer> Consumer; +// IncrementalParser::IncrementalParser() {} -public: - IncrementalASTConsumer(Interpreter &InterpRef, std::unique_ptr<ASTConsumer> C) - : Interp(InterpRef), Consumer(std::move(C)) {} - - bool HandleTopLevelDecl(DeclGroupRef DGR) override final { - if (DGR.isNull()) - return true; - if (!Consumer) - return true; - - for (Decl *D : DGR) - if (auto *TSD = llvm::dyn_cast<TopLevelStmtDecl>(D); - TSD && TSD->isSemiMissing()) - TSD->setStmt(Interp.SynthesizeExpr(cast<Expr>(TSD->getStmt()))); - - return Consumer->HandleTopLevelDecl(DGR); - } - void HandleTranslationUnit(ASTContext &Ctx) override final { - Consumer->HandleTranslationUnit(Ctx); - } - void HandleInlineFunctionDefinition(FunctionDecl *D) override final { - Consumer->HandleInlineFunctionDefinition(D); - } - void HandleInterestingDecl(DeclGroupRef D) override final { - Consumer->HandleInterestingDecl(D); - } - void HandleTagDeclDefinition(TagDecl *D) override final { - Consumer->HandleTagDeclDefinition(D); - } - void HandleTagDeclRequiredDefinition(const TagDecl *D) override final { - Consumer->HandleTagDeclRequiredDefinition(D); - } - void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) override final { - Consumer->HandleCXXImplicitFunctionInstantiation(D); - } - void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override final { - Consumer->HandleTopLevelDeclInObjCContainer(D); - } - void HandleImplicitImportDecl(ImportDecl *D) override final { - Consumer->HandleImplicitImportDecl(D); - } - void CompleteTentativeDefinition(VarDecl *D) override final { - Consumer->CompleteTentativeDefinition(D); - } - void CompleteExternalDeclaration(DeclaratorDecl *D) override final { - Consumer->CompleteExternalDeclaration(D); - } - void AssignInheritanceModel(CXXRecordDecl *RD) override final { - Consumer->AssignInheritanceModel(RD); - } - void HandleCXXStaticMemberVarInstantiation(VarDecl *D) override final { - Consumer->HandleCXXStaticMemberVarInstantiation(D); - } - void HandleVTable(CXXRecordDecl *RD) override final { - Consumer->HandleVTable(RD); - } - ASTMutationListener *GetASTMutationListener() override final { - return Consumer->GetASTMutationListener(); - } - ASTDeserializationListener *GetASTDeserializationListener() override final { - return Consumer->GetASTDeserializationListener(); - } - void PrintStats() override final { Consumer->PrintStats(); } - bool shouldSkipFunctionBody(Decl *D) override final { - return Consumer->shouldSkipFunctionBody(D); - } - static bool classof(const clang::ASTConsumer *) { return true; } -}; - -/// A custom action enabling the incremental processing functionality. -/// -/// The usual \p FrontendAction expects one call to ExecuteAction and once it -/// sees a call to \p EndSourceFile it deletes some of the important objects -/// such as \p Preprocessor and \p Sema assuming no further input will come. -/// -/// \p IncrementalAction ensures it keep its underlying action's objects alive -/// as long as the \p IncrementalParser needs them. -/// -class IncrementalAction : public WrapperFrontendAction { -private: - bool IsTerminating = false; - -public: - IncrementalAction(CompilerInstance &CI, llvm::LLVMContext &LLVMCtx, - llvm::Error &Err) - : WrapperFrontendAction([&]() { - llvm::ErrorAsOutParameter EAO(&Err); - std::unique_ptr<FrontendAction> Act; - switch (CI.getFrontendOpts().ProgramAction) { - default: - Err = llvm::createStringError( - std::errc::state_not_recoverable, - "Driver initialization failed. " - "Incremental mode for action %d is not supported", - CI.getFrontendOpts().ProgramAction); - return Act; - case frontend::ASTDump: - [[fallthrough]]; - case frontend::ASTPrint: - [[fallthrough]]; - case frontend::ParseSyntaxOnly: - Act = CreateFrontendAction(CI); - break; - case frontend::PluginAction: - [[fallthrough]]; - case frontend::EmitAssembly: - [[fallthrough]]; - case frontend::EmitBC: - [[fallthrough]]; - case frontend::EmitObj: - [[fallthrough]]; - case frontend::PrintPreprocessedInput: - [[fallthrough]]; - case frontend::EmitLLVMOnly: - Act.reset(new EmitLLVMOnlyAction(&LLVMCtx)); - break; - } - return Act; - }()) {} - FrontendAction *getWrapped() const { return WrappedAction.get(); } - TranslationUnitKind getTranslationUnitKind() override { - return TU_Incremental; - } - - void ExecuteAction() override { - CompilerInstance &CI = getCompilerInstance(); - assert(CI.hasPreprocessor() && "No PP!"); - - // Use a code completion consumer? - CodeCompleteConsumer *CompletionConsumer = nullptr; - if (CI.hasCodeCompletionConsumer()) - CompletionConsumer = &CI.getCodeCompletionConsumer(); - - Preprocessor &PP = CI.getPreprocessor(); - PP.EnterMainSourceFile(); - - if (!CI.hasSema()) - CI.createSema(getTranslationUnitKind(), CompletionConsumer); - } - - // Do not terminate after processing the input. This allows us to keep various - // clang objects alive and to incrementally grow the current TU. - void EndSourceFile() override { - // The WrappedAction can be nullptr if we issued an error in the ctor. - if (IsTerminating && getWrapped()) - WrapperFrontendAction::EndSourceFile(); - } - - void FinalizeAction() { - assert(!IsTerminating && "Already finalized!"); - IsTerminating = true; - EndSourceFile(); - } -}; - -CodeGenerator *IncrementalParser::getCodeGen() const { - FrontendAction *WrappedAct = Act->getWrapped(); - if (!WrappedAct->hasIRSupport()) - return nullptr; - return static_cast<CodeGenAction *>(WrappedAct)->getCodeGenerator(); -} - -IncrementalParser::IncrementalParser() {} - -IncrementalParser::IncrementalParser(Interpreter &Interp, - std::unique_ptr<CompilerInstance> Instance, - llvm::LLVMContext &LLVMCtx, +IncrementalParser::IncrementalParser(CompilerInstance &Instance, llvm::Error &Err) - : CI(std::move(Instance)) { + : S(Instance.getSema()) { ---------------- AaronBallman wrote:
For `clang-repl` alone, there is no failed assertion. For `clang-repl --cuda` we create two `IncrementalParser` objects. The first one does not assert and its call stack is: ``` > > clang-repl.exe!clang::IncrementalParser::IncrementalParser(clang::CompilerInstance > & Instance, llvm::Error & Err) Line 31 C++ clang-repl.exe!std::make_unique<clang::IncrementalParser,clang::CompilerInstance &,llvm::Error &,0>(clang::CompilerInstance & <_Args_0>, llvm::Error & <_Args_1>) Line 3597 C++ clang-repl.exe!clang::Interpreter::Interpreter(std::unique_ptr<clang::CompilerInstance,std::default_delete<clang::CompilerInstance>> Instance, llvm::Error & ErrOut, std::unique_ptr<llvm::orc::LLJITBuilder,std::default_delete<llvm::orc::LLJITBuilder>> JITBuilder, std::unique_ptr<clang::ASTConsumer,std::default_delete<clang::ASTConsumer>> Consumer) Line 390 C++ clang-repl.exe!clang::Interpreter::create(std::unique_ptr<clang::CompilerInstance,std::default_delete<clang::CompilerInstance>> CI) Line 461 C++ clang-repl.exe!clang::Interpreter::createWithCUDA(std::unique_ptr<clang::CompilerInstance,std::default_delete<clang::CompilerInstance>> CI, std::unique_ptr<clang::CompilerInstance,std::default_delete<clang::CompilerInstance>> DCI) Line 489 C++ clang-repl.exe!main(int argc, const char * * argv) Line 206 C++ ``` and the second one is: ``` clang-repl.exe!clang::IncrementalParser::IncrementalParser(clang::CompilerInstance & Instance, llvm::Error & Err) Line 31 C++ > > clang-repl.exe!clang::IncrementalCUDADeviceParser::IncrementalCUDADeviceParser(std::unique_ptr<clang::CompilerInstance,std::default_delete<clang::CompilerInstance>> > DeviceInstance, clang::CompilerInstance & HostInstance, > llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS, llvm::Error & > Err, const > std::list<clang::PartialTranslationUnit,std::allocator<clang::PartialTranslationUnit>> > & PTUs) Line 34 C++ clang-repl.exe!std::make_unique<clang::IncrementalCUDADeviceParser,std::unique_ptr<clang::CompilerInstance,std::default_delete<clang::CompilerInstance>>,clang::CompilerInstance &,llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> &,llvm::Error &,std::list<clang::PartialTranslationUnit,std::allocator<clang::PartialTranslationUnit>> &,0>(std::unique_ptr<clang::CompilerInstance,std::default_delete<clang::CompilerInstance>> && <_Args_0>, clang::CompilerInstance & <_Args_1>, llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> & <_Args_2>, llvm::Error & <_Args_3>, std::list<clang::PartialTranslationUnit,std::allocator<clang::PartialTranslationUnit>> & <_Args_4>) Line 3597 C++ clang-repl.exe!clang::Interpreter::createWithCUDA(std::unique_ptr<clang::CompilerInstance,std::default_delete<clang::CompilerInstance>> CI, std::unique_ptr<clang::CompilerInstance,std::default_delete<clang::CompilerInstance>> DCI) Line 494 C++ clang-repl.exe!main(int argc, const char * * argv) Line 206 C++ ``` and this one fails because the `DeviceInstance` passed to `IncrementalCUDADeviceParser::IncrementalCUDADeviceParser()` is mostly empty, including an empty `Sema` pointer. https://github.com/llvm/llvm-project/pull/107737 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits