================
@@ -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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits