aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Interpreter/Interpreter.cpp
AgeCommit message (Collapse)AuthorFilesLines
2023-11-23[ClangRepl] Type Directed Code Completion (#67349)Fred Fu1-0/+4
Differential Revision: https://reviews.llvm.org/D159128
2023-08-28Reland "[clang-repl] support code completion at a REPL."Fred Fu1-4/+3
Original commit message: " This patch enabled code completion for ClangREPL. The feature was built upon three existing Clang components: a list completer for LineEditor, a CompletionConsumer from SemaCodeCompletion, and the ASTUnit::codeComplete method. The first component serves as the main entry point of handling interactive inputs. Because a completion point for a compiler instance has to be unchanged once it is set, an incremental compiler instance is created for each code completion. Such a compiler instance carries over AST context source from the main interpreter compiler in order to obtain declarations or bindings from previous input in the same REPL session. The most important API codeComplete in Interpreter/CodeCompletion is a thin wrapper that calls with ASTUnit::codeComplete with necessary arguments, such as a code completion point and a ReplCompletionConsumer, which communicates completion results from SemaCodeCompletion back to the list completer for the REPL. In addition, PCC_TopLevelOrExpression and CCC_TopLevelOrExpression` top levels were added so that SemaCodeCompletion can treat top level statements like expression statements at the REPL. For example, clang-repl> int foo = 42; clang-repl> f<tab> From a parser's persective, the cursor is at a top level. If we used code completion without any changes, PCC_Namespace would be supplied to Sema::CodeCompleteOrdinaryName, and thus the completion results would not include foo. Currently, the way we use PCC_TopLevelOrExpression and CCC_TopLevelOrExpression is no different from the way we use PCC_Statement and CCC_Statement respectively. Differential revision: https://reviews.llvm.org/D154382 " The new patch also fixes clangd and several memory issues that the bots reported and upload the missing files.
2023-08-28Revert "Reland "[clang-repl] support code completion at a REPL.""Vassil Vassilev1-3/+4
This reverts commit 5ab25a42ba70c4b50214b0e78eaaccd30696fa09 due to forgotten files.
2023-08-28Reland "[clang-repl] support code completion at a REPL."Fred Fu1-4/+3
Original commit message: " This patch enabled code completion for ClangREPL. The feature was built upon three existing Clang components: a list completer for LineEditor, a CompletionConsumer from SemaCodeCompletion, and the ASTUnit::codeComplete method. The first component serves as the main entry point of handling interactive inputs. Because a completion point for a compiler instance has to be unchanged once it is set, an incremental compiler instance is created for each code completion. Such a compiler instance carries over AST context source from the main interpreter compiler in order to obtain declarations or bindings from previous input in the same REPL session. The most important API codeComplete in Interpreter/CodeCompletion is a thin wrapper that calls with ASTUnit::codeComplete with necessary arguments, such as a code completion point and a ReplCompletionConsumer, which communicates completion results from SemaCodeCompletion back to the list completer for the REPL. In addition, PCC_TopLevelOrExpression and CCC_TopLevelOrExpression` top levels were added so that SemaCodeCompletion can treat top level statements like expression statements at the REPL. For example, clang-repl> int foo = 42; clang-repl> f<tab> From a parser's persective, the cursor is at a top level. If we used code completion without any changes, PCC_Namespace would be supplied to Sema::CodeCompleteOrdinaryName, and thus the completion results would not include foo. Currently, the way we use PCC_TopLevelOrExpression and CCC_TopLevelOrExpression is no different from the way we use PCC_Statement and CCC_Statement respectively. Differential revision: https://reviews.llvm.org/D154382 " The new patch also fixes clangd and several memory issues that the bots reported.
2023-08-23Revert "[clang-repl] support code completion at a REPL."Vassil Vassilev1-3/+4
This reverts commit eb0e6c3134ef6deafe0a4958e9e1a1214b3c2f14 due to failures in clangd such as https://lab.llvm.org/buildbot/#/builders/57/builds/29377
2023-08-23[clang-repl] support code completion at a REPL.Fred Fu1-4/+3
This patch enabled code completion for ClangREPL. The feature was built upon three existing Clang components: a list completer for LineEditor, a CompletionConsumer from SemaCodeCompletion, and the ASTUnit::codeComplete method. The first component serves as the main entry point of handling interactive inputs. Because a completion point for a compiler instance has to be unchanged once it is set, an incremental compiler instance is created for each code completion. Such a compiler instance carries over AST context source from the main interpreter compiler in order to obtain declarations or bindings from previous input in the same REPL session. The most important API codeComplete in Interpreter/CodeCompletion is a thin wrapper that calls with ASTUnit::codeComplete with necessary arguments, such as a code completion point and a ReplCompletionConsumer, which communicates completion results from SemaCodeCompletion back to the list completer for the REPL. In addition, PCC_TopLevelOrExpression and CCC_TopLevelOrExpression` top levels were added so that SemaCodeCompletion can treat top level statements like expression statements at the REPL. For example, clang-repl> int foo = 42; clang-repl> f<tab> From a parser's persective, the cursor is at a top level. If we used code completion without any changes, PCC_Namespace would be supplied to Sema::CodeCompleteOrdinaryName, and thus the completion results would not include foo. Currently, the way we use PCC_TopLevelOrExpression and CCC_TopLevelOrExpression is no different from the way we use PCC_Statement and CCC_Statement respectively. Differential revision: https://reviews.llvm.org/D154382
2023-05-31[NFC][CLANG] Fix nullptr dereference issue in SetValueDataBasedOnQualType()Manna, Soumi1-1/+1
This patch uses castAs instead of getAs which will assert if the type doesn't match in SetValueDataBasedOnQualType(clang::Value &, unsigned long long). Reviewed By: erichkeane Differential Revision: https://reviews.llvm.org/D151770
2023-05-27[clang-repl][CUDA] Re-land: Initial interactive CUDA support for clang-replAnubhab Ghosh1-1/+86
CUDA support can be enabled in clang-repl with --cuda flag. Device code linking is not yet supported. inline must be used with all __device__ functions. Differential Revision: https://reviews.llvm.org/D146389
2023-05-23Reland "Reland [clang-repl] Introduce Value to capture expression results"Jun Zhang1-4/+420
This reverts commit 094ab4781262b6cb49d57b0ecdf84b047c879295. Reland with changing `ParseAndExecute` to `Parse` in `Interpreter::create`. This avoid creating JIT instance everytime even if we don't really need them. This should fixes failures like https://lab.llvm.org/buildbot/#/builders/38/builds/11955 The original reverted patch also causes GN bot fails on M1. (https://lab.llvm.org/buildbot/#/builders/38/builds/11955) However, we can't reproduce it so let's reland it and see what happens. See discussions here: https://reviews.llvm.org/rGd71a4e02277a64a9dece591cdf2b34f15c3b19a0
2023-05-20Revert "[clang-repl][CUDA] Initial interactive CUDA support for clang-repl"Anubhab Ghosh1-86/+2
This reverts commit 80e7eed6a610ab3c7289e6f9b7ec006bc7d7ae31.
2023-05-20[clang-repl][CUDA] Initial interactive CUDA support for clang-replAnubhab Ghosh1-2/+86
CUDA support can be enabled in clang-repl with --cuda flag. Device code linking is not yet supported. inline must be used with all __device__ functions. Differential Revision: https://reviews.llvm.org/D146389
2023-05-19Revert "Reland [clang-repl] Introduce Value to capture expression results"Jun Zhang1-419/+4
This reverts commit d71a4e02277a64a9dece591cdf2b34f15c3b19a0. See http://45.33.8.238/macm1/61024/step_7.txt
2023-05-19Fix MSVC "not all control paths return a value" warning. NFC.Simon Pilgrim1-0/+1
2023-05-19Reland [clang-repl] Introduce Value to capture expression resultsJun Zhang1-4/+418
This reverts commit 7158fd381a0bc0222195d6a07ebb42ea57957bda. * Fixes endianness issue on big endian machines like PowerPC-bl * Disable tests on platforms that having trouble to support JIT Signed-off-by: Jun Zhang <jun@junz.org>
2023-05-16Revert "[clang-repl] Introduce Value to capture expression results"Jun Zhang1-400/+4
This reverts commit a423b7f1d7ca8b263af85944f57a69aa08fc942c. See https://lab.llvm.org/buildbot/#/changes/95083
2023-05-16[clang-repl] Introduce Value to capture expression resultsJun Zhang1-4/+400
This is the second part of the below RFC: https://discourse.llvm.org/t/rfc-handle-execution-results-in-clang-repl/68493 This patch implements a Value class that can be used to carry expression results in clang-repl. In other words, when we see a top expression without semi, it will be captured and stored to a Value object. You can explicitly specify where you want to store the object, like: ``` Value V; llvm::cantFail(Interp->ParseAndExecute("int x = 42;")); llvm::cantFail(Interp->ParseAndExecute("x", &V)); ``` `V` now stores some useful infomation about `x`, you can get its real value (42), it's `clang::QualType` or anything interesting. However, if you don't specify the optional argument, it will be captured to a local variable, and automatically called `Value::dump`, which is not implemented yet in this patch. Signed-off-by: Jun Zhang <jun@junz.org>
2023-04-16[clang-repl] JITTargetAddress --> ExecutorAddr, NFCJun Zhang1-3/+3
Most of Orc and JITLink are movinng away from JITTargetAddress and use ExecutorAddr instead. Signed-off-by: Jun Zhang <jun@junz.org> Differential Revision: https://reviews.llvm.org/D148434
2023-03-29[clang-repl] Use std::move when converting Error to ExpectedAnubhab Ghosh1-1/+1
2023-03-29[clang-repl] Add a command to load dynamic librariesAnubhab Ghosh1-9/+36
This commit adds the %lib <file> command to load a dynamic library to be used by the currently running interpreted code. For example `%lib libSDL2.so`. Differential Revision: https://reviews.llvm.org/D141824
2023-02-10[NFC][TargetParser] Replace uses of llvm/Support/Host.hArchibald Elliott1-1/+1
The forwarding header is left in place because of its use in `polly/lib/External/isl/interface/extract_interface.cc`, but I have added a GCC warning about the fact it is deprecated, because it is used in `isl` from where it is included by Polly.
2023-01-09Move from llvm::makeArrayRef to ArrayRef deduction guides - clang/ partserge-sans-paille1-3/+2
This is a follow-up to https://reviews.llvm.org/D140896, split into several parts as it touches a lot of files. Differential Revision: https://reviews.llvm.org/D141139
2022-12-03[clang-repl] Support statements on global scope in incremental mode.Vassil Vassilev1-7/+5
This patch teaches clang to parse statements on the global scope to allow: ``` ./bin/clang-repl clang-repl> int i = 12; clang-repl> ++i; clang-repl> extern "C" int printf(const char*,...); clang-repl> printf("%d\n", i); 13 clang-repl> %quit ``` Generally, disambiguating between statements and declarations is a non-trivial task for a C++ parser. The challenge is to allow both standard C++ to be translated as if this patch does not exist and in the cases where the user typed a statement to be executed as if it were in a function body. Clang's Parser does pretty well in disambiguating between declarations and expressions. We have added DisambiguatingWithExpression flag which allows us to preserve the existing and optimized behavior where needed and implement the extra rules for disambiguating. Only few cases require additional attention: * Constructors/destructors -- Parser::isConstructorDeclarator was used in to disambiguate between ctor-looking declarations and statements on the global scope(eg. `Ns::f()`). * The template keyword -- the template keyword can appear in both declarations and statements. This patch considers the template keyword to be a declaration starter which breaks a few cases in incremental mode which will be tackled later. * The inline (and similar) keyword -- looking at the first token in many cases allows us to classify what is a declaration. * Other language keywords and specifiers -- ObjC/ObjC++/OpenCL/OpenMP rely on pragmas or special tokens which will be handled in subsequent patches. The patch conceptually models a "top-level" statement into a TopLevelStmtDecl. The TopLevelStmtDecl is lowered into a void function with no arguments. We attach this function to the global initializer list to execute the statement blocks in the correct order. Differential revision: https://reviews.llvm.org/D127284
2022-07-29 [clang-repl] Support destructors of global objects.Sunho Kim1-1/+8
Supports destructors of global objects by properly calling jitdylib deinitialize which calls the global dtors of ir modules. This supersedes https://reviews.llvm.org/D127945. There was an issue when calling deinitialize on windows but it got fixed by https://reviews.llvm.org/D128037. Reviewed By: v.g.vassilev Differential Revision: https://reviews.llvm.org/D128589
2022-06-30[Interpreter] Pass target features to JITJonas Hahnfeld1-3/+3
This is required to support RISC-V where the '+d' target feature indicates the presence of the D instruction set extension, which changes to the Hard-float 'd' ABI. Differential Revision: https://reviews.llvm.org/D128853
2022-06-26Revert "[clang-repl] Support destructors of global objects."Sunho Kim1-8/+1
This reverts commit 9de8b05bfe0de2915d2443d06159396c5f9d389f.
2022-06-26[clang-repl] Implement code undo.Jun Zhang1-1/+20
In interactive C++ it is convenient to roll back to a previous state of the compiler. For example: clang-repl> int x = 42; clang-repl> %undo clang-repl> float x = 24 // not an error To support this, the patch extends the functionality used to recover from errors and adds functionality to recover the low-level execution infrastructure. The current implementation is based on watermarks. It exploits the fact that at each incremental input the underlying compiler infrastructure is in a valid state. We can only go N incremental inputs back to a previous valid state. We do not need and do not do any further dependency tracking. This patch was co-developed with V. Vassilev, relies on the past work of Purva Chaudhari in clang-repl and is inspired by the past work on the same feature in the Cling interpreter. Co-authored-by: Purva-Chaudhari <purva.chaudhari02@gmail.com> Co-authored-by: Vassil Vassilev <v.g.vassilev@gmail.com> Signed-off-by: Jun Zhang <jun@junz.org>
2022-06-26[clang-repl] Support destructors of global objects.Sunho Kim1-1/+8
Supports destructors of global objects by properly calling jitdylib deinitialize which calls the global dtors of ir modules. This supersedes https://reviews.llvm.org/D127945. There was an issue when calling deinitialize on windows but it got fixed by https://reviews.llvm.org/D128037. Reviewed By: v.g.vassilev Differential Revision: https://reviews.llvm.org/D128589
2022-06-18[clang-repl] Remove memory leak of ASTContext/TargetMachine.Sunho Kim1-0/+3
Removes memory leak of ASTContext and TargetMachine. When DisableFree is turned on, it intentionally leaks these instances as they can be trivially deallocated. This patch turns this off and delete Parser instance early so that they will not reference dangling pargma headers. Asan shouldn't detect these as leaks normally, since burypointer is called for them. But, every invocation of incremental parser createa an additional leak of TargetMachine. If there are many invocations within a single test case, we easily reach number of leaks exceeding kGraveYardMaxSize (which is 12) and leaks start to get reported by asan buildbots. Reviewed By: v.g.vassilev Differential Revision: https://reviews.llvm.org/D127991
2022-03-11[clang-repl] Add an accessor to our underlying execution engineVassil Vassilev1-0/+6
This patch will allow better incremental adoption of these changes in downstream cling and other users which want to experiment by customizing the execution engine.
2021-11-10[clang-repl] Allow Interpreter::getSymbolAddress to take a mangled name.Vassil Vassilev1-2/+22
2021-10-26Reinstate "[clang-repl] Re-implement clang-interpreter as a test case."Vassil Vassilev1-2/+11
Original commit message: " Original commit message: " Original commit message: " Original commit message:" The current infrastructure in lib/Interpreter has a tool, clang-repl, very similar to clang-interpreter which also allows incremental compilation. This patch moves clang-interpreter as a test case and drops it as conditionally built example as we already have clang-repl in place. " This patch also ignores ppc due to missing weak symbol for __gxx_personality_v0 which may be a feature request for the jit infrastructure. Also, adds a missing build system dependency to the orc jit. " Additionally, this patch defines a custom exception type and thus avoids the requirement to include header <exception>, making it easier to deploy across systems without standard location of the c++ headers. " This patch also works around PR49692 and finds a way to use llvm::consumeError in rtti mode. " This patch also checks if stl is built with rtti. Differential revision: https://reviews.llvm.org/D107049
2021-10-21Reland [clang] Pass -clear-ast-before-backend in Clang::ConstructJob()Arthur Eubanks1-0/+4
This clears the memory used for the Clang AST before we run LLVM passes. https://llvm-compile-time-tracker.com/compare.php?from=d0a5f61c4f6fccec87fd5207e3fcd9502dd59854&to=b7437fee79e04464dd968e1a29185495f3590481&stat=max-rss shows significant memory savings with no slowdown (in fact -O0 slightly speeds up). For more background, see https://lists.llvm.org/pipermail/cfe-dev/2021-September/068930.html. Turn this off for the interpreter since it does codegen multiple times. Relanding with fix for -print-stats: D111973 Relanding with fix for plugins: D112190 If you'd like to use this even with plugins, consider using the features introduced in D112096. This can be turned off with -Xclang -no-clear-ast-before-backend. Differential Revision: https://reviews.llvm.org/D111270
2021-10-19Revert "Reland [clang] Pass -clear-ast-before-backend in Clang::ConstructJob()"Zequan Wu1-4/+0
This reverts commit 1fb24fe85a19ae71b00875ff6c96ef1831dcf7e3. This causes clang crash on chromium. See repro at https://bugs.chromium.org/p/chromium/issues/detail?id=1261551#c1.
2021-10-18Reland [clang] Pass -clear-ast-before-backend in Clang::ConstructJob()Arthur Eubanks1-0/+4
This clears the memory used for the Clang AST before we run LLVM passes. https://llvm-compile-time-tracker.com/compare.php?from=d0a5f61c4f6fccec87fd5207e3fcd9502dd59854&to=b7437fee79e04464dd968e1a29185495f3590481&stat=max-rss shows significant memory savings with no slowdown (in fact -O0 slightly speeds up). For more background, see https://lists.llvm.org/pipermail/cfe-dev/2021-September/068930.html. Turn this off for the interpreter since it does codegen multiple times. Relanding with fix for -print-stats: D111973 Differential Revision: https://reviews.llvm.org/D111270
2021-10-16Revert "[clang] Pass -clear-ast-before-backend in Clang::ConstructJob()"Arthur Eubanks1-4/+0
This reverts commit 47eb99aa44ab1d20327d67a49d6c47163de76387. This causes crashes with -print-stats: PR52193.
2021-10-15[clang] Pass -clear-ast-before-backend in Clang::ConstructJob()Arthur Eubanks1-0/+4
This clears the memory used for the Clang AST before we run LLVM passes. https://llvm-compile-time-tracker.com/compare.php?from=d0a5f61c4f6fccec87fd5207e3fcd9502dd59854&to=b7437fee79e04464dd968e1a29185495f3590481&stat=max-rss shows significant memory savings with no slowdown (in fact -O0 slightly speeds up). For more background, see https://lists.llvm.org/pipermail/cfe-dev/2021-September/068930.html. Turn this off for the interpreter since it does codegen multiple times. Differential Revision: https://reviews.llvm.org/D111270
2021-10-14[NFC][Interpreter] Remove unused CompilerInvocationArthur Eubanks1-1/+0
2021-10-08Revert "Reland "[clang-repl] Re-implement clang-interpreter as a test case.""Leonard Chan1-11/+2
This reverts commit 1dba6b37bdc70210f75a480eff3715ebe1f1d8be. Reverting because the ClangReplInterpreterExceptionTests test fails on our builders with this patch.
2021-10-08Reland "[clang-repl] Re-implement clang-interpreter as a test case."Vassil Vassilev1-2/+11
Original commit message: " Original commit message: " Original commit message:" The current infrastructure in lib/Interpreter has a tool, clang-repl, very similar to clang-interpreter which also allows incremental compilation. This patch moves clang-interpreter as a test case and drops it as conditionally built example as we already have clang-repl in place. Differential revision: https://reviews.llvm.org/D107049 " This patch also ignores ppc due to missing weak symbol for __gxx_personality_v0 which may be a feature request for the jit infrastructure. Also, adds a missing build system dependency to the orc jit. " Additionally, this patch defines a custom exception type and thus avoids the requirement to include header <exception>, making it easier to deploy across systems without standard location of the c++ headers. " This patch also works around PR49692 and finds a way to use llvm::consumeError in rtti mode. Differential revision: https://reviews.llvm.org/D107049
2021-10-07Workaround build error for mingw-g++Luke Drummond1-5/+6
mingw-g++ does not correctly support the full `std::errc` namespace as worded in the standard[1]. As such, we cannot reliably use all names therein. This patch changes the use of `std::errc::state_not_recoverable`, to use portable error codes from the `llvm::errc` equivalent. [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71444 Reviewed by v.g.vassilev Differential Revision: https://reviews.llvm.org/D111315
2021-09-03Revert "Reland "[clang-repl] Re-implement clang-interpreter as a test case.""Vassil Vassilev1-11/+2
This reverts commit 6fe2beba7d2a41964af658c8c59dd172683ef739 which fails on clang-hexagon-elf
2021-09-03Reland "[clang-repl] Re-implement clang-interpreter as a test case."Vassil Vassilev1-2/+11
Original commit message: " Original commit message:" The current infrastructure in lib/Interpreter has a tool, clang-repl, very similar to clang-interpreter which also allows incremental compilation. This patch moves clang-interpreter as a test case and drops it as conditionally built example as we already have clang-repl in place. Differential revision: https://reviews.llvm.org/D107049 " This patch also ignores ppc due to missing weak symbol for __gxx_personality_v0 which may be a feature request for the jit infrastructure. Also, adds a missing build system dependency to the orc jit. " Additionally, this patch defines a custom exception type and thus avoids the requirement to include header <exception>, making it easier to deploy across systems without standard location of the c++ headers. Differential revision: https://reviews.llvm.org/D107049
2021-09-02[clang] NFC: Extract DiagnosticOptions parsingJan Svoboda1-7/+2
The way we parse `DiagnosticOptions` is a bit involved. `DiagnosticOptions` are parsed as part of the cc1-parsing function `CompilerInvocation::CreateFromArgs` which takes `DiagnosticsEngine` as an argument to be able to report errors in command-line arguments. But to create `DiagnosticsEngine`, `DiagnosticOptions` are needed. This is solved by exposing the `ParseDiagnosticArgs` to clients and making its `DiagnosticsEngine` argument optional, essentially breaking the dependency cycle. The `ParseDiagnosticArgs` function takes `llvm::opt::ArgList &`, which each client needs to create from the command-line (typically represented as `std::vector<const char *>`). Creating this data structure in this context is somewhat particular. This code pattern is copy-pasted in some places across the upstream code base and also in downstream repos. To make things a bit more uniform, this patch extracts the code into a new reusable function: `CreateAndPopulateDiagOpts`. Reviewed By: dexonsmith Differential Revision: https://reviews.llvm.org/D108918
2021-09-01Revert "Reland "[clang-repl] Re-implement clang-interpreter as a test case.""Nico Weber1-11/+2
This reverts commit f0514a4d26100239088f08d618f2ba100f59958e. Test fails on macOS: https://reviews.llvm.org/D107049#2976603
2021-09-01Reland "[clang-repl] Re-implement clang-interpreter as a test case."Vassil Vassilev1-2/+11
Original commit message:" The current infrastructure in lib/Interpreter has a tool, clang-repl, very similar to clang-interpreter which also allows incremental compilation. This patch moves clang-interpreter as a test case and drops it as conditionally built example as we already have clang-repl in place. Differential revision: https://reviews.llvm.org/D107049 " This patch also ignores ppc due to missing weak symbol for __gxx_personality_v0 which may be a feature request for the jit infrastructure. Also, adds a missing build system dependency to the orc jit.
2021-09-01Revert "[clang-repl] Re-implement clang-interpreter as a test case."Vassil Vassilev1-11/+2
This reverts commit 319ce98011742141dad8dd95a2f9de9c0449be5c because it fails on various platforms.
2021-09-01[clang-repl] Re-implement clang-interpreter as a test case.Vassil Vassilev1-2/+11
The current infrastructure in lib/Interpreter has a tool, clang-repl, very similar to clang-interpreter which also allows incremental compilation. This patch moves clang-interpreter as a test case and drops it as conditionally built example as we already have clang-repl in place. Differential revision: https://reviews.llvm.org/D107049
2021-07-12Reland "[clang-repl] Implement partial translation units and error recovery."Vassil Vassilev1-2/+3
Original commit message: [clang-repl] Implement partial translation units and error recovery. https://reviews.llvm.org/D96033 contained a discussion regarding efficient modeling of error recovery. @rjmccall has outlined the key ideas: Conceptually, we can split the translation unit into a sequence of partial translation units (PTUs). Every declaration will be associated with a unique PTU that owns it. The first key insight here is that the owning PTU isn't always the "active" (most recent) PTU, and it isn't always the PTU that the declaration "comes from". A new declaration (that isn't a redeclaration or specialization of anything) does belong to the active PTU. A template specialization, however, belongs to the most recent PTU of all the declarations in its signature - mostly that means that it can be pulled into a more recent PTU by its template arguments. The second key insight is that processing a PTU might extend an earlier PTU. Rolling back the later PTU shouldn't throw that extension away. For example, if the second PTU defines a template, and the third PTU requires that template to be instantiated at float, that template specialization is still part of the second PTU. Similarly, if the fifth PTU uses an inline function belonging to the fourth, that definition still belongs to the fourth. When we go to emit code in a new PTU, we map each declaration we have to emit back to its owning PTU and emit it in a new module for just the extensions to that PTU. We keep track of all the modules we've emitted for a PTU so that we can unload them all if we decide to roll it back. Most declarations/definitions will only refer to entities from the same or earlier PTUs. However, it is possible (primarily by defining a previously-declared entity, but also through templates or ADL) for an entity that belongs to one PTU to refer to something from a later PTU. We will have to keep track of this and prevent unwinding to later PTU when we recognize it. Fortunately, this should be very rare; and crucially, we don't have to do the bookkeeping for this if we've only got one PTU, e.g. in normal compilation. Otherwise, PTUs after the first just need to record enough metadata to be able to revert any changes they've made to declarations belonging to earlier PTUs, e.g. to redeclaration chains or template specialization lists. It should even eventually be possible for PTUs to provide their own slab allocators which can be thrown away as part of rolling back the PTU. We can maintain a notion of the active allocator and allocate things like Stmt/Expr nodes in it, temporarily changing it to the appropriate PTU whenever we go to do something like instantiate a function template. More care will be required when allocating declarations and types, though. We would want the PTU to be efficiently recoverable from a Decl; I'm not sure how best to do that. An easy option that would cover most declarations would be to make multiple TranslationUnitDecls and parent the declarations appropriately, but I don't think that's good enough for things like member function templates, since an instantiation of that would still be parented by its original class. Maybe we can work this into the DC chain somehow, like how lexical DCs are. We add a different kind of translation unit `TU_Incremental` which is a complete translation unit that we might nonetheless incrementally extend later. Because it is complete (and we might want to generate code for it), we do perform template instantiation, but because it might be extended later, we don't warn if it declares or uses undefined internal-linkage symbols. This patch teaches clang-repl how to recover from errors by disconnecting the most recent PTU and update the primary PTU lookup tables. For instance: ```./clang-repl clang-repl> int i = 12; error; In file included from <<< inputs >>>:1: input_line_0:1:13: error: C++ requires a type specifier for all declarations int i = 12; error; ^ error: Parsing failed. clang-repl> int i = 13; extern "C" int printf(const char*,...); clang-repl> auto r1 = printf("i=%d\n", i); i=13 clang-repl> quit ``` Differential revision: https://reviews.llvm.org/D104918
2021-07-11Revert "[clang-repl] Implement partial translation units and error recovery."Vassil Vassilev1-3/+2
This reverts commit 6775fc6ffa3ca1c36b20c25fa4e7f48f81213cf2. It also reverts "[lldb] Fix compilation by adjusting to the new ASTContext signature." This reverts commit 03a3f86071c10a1f6cbbf7375aa6fe9d94168972. We see some failures on the lldb infrastructure, these changes might play a role in it. Let's revert it now and see if the bots will become green. Ref: https://reviews.llvm.org/D104918
2021-07-11[clang-repl] Implement partial translation units and error recovery.Vassil Vassilev1-2/+3
https://reviews.llvm.org/D96033 contained a discussion regarding efficient modeling of error recovery. @rjmccall has outlined the key ideas: Conceptually, we can split the translation unit into a sequence of partial translation units (PTUs). Every declaration will be associated with a unique PTU that owns it. The first key insight here is that the owning PTU isn't always the "active" (most recent) PTU, and it isn't always the PTU that the declaration "comes from". A new declaration (that isn't a redeclaration or specialization of anything) does belong to the active PTU. A template specialization, however, belongs to the most recent PTU of all the declarations in its signature - mostly that means that it can be pulled into a more recent PTU by its template arguments. The second key insight is that processing a PTU might extend an earlier PTU. Rolling back the later PTU shouldn't throw that extension away. For example, if the second PTU defines a template, and the third PTU requires that template to be instantiated at float, that template specialization is still part of the second PTU. Similarly, if the fifth PTU uses an inline function belonging to the fourth, that definition still belongs to the fourth. When we go to emit code in a new PTU, we map each declaration we have to emit back to its owning PTU and emit it in a new module for just the extensions to that PTU. We keep track of all the modules we've emitted for a PTU so that we can unload them all if we decide to roll it back. Most declarations/definitions will only refer to entities from the same or earlier PTUs. However, it is possible (primarily by defining a previously-declared entity, but also through templates or ADL) for an entity that belongs to one PTU to refer to something from a later PTU. We will have to keep track of this and prevent unwinding to later PTU when we recognize it. Fortunately, this should be very rare; and crucially, we don't have to do the bookkeeping for this if we've only got one PTU, e.g. in normal compilation. Otherwise, PTUs after the first just need to record enough metadata to be able to revert any changes they've made to declarations belonging to earlier PTUs, e.g. to redeclaration chains or template specialization lists. It should even eventually be possible for PTUs to provide their own slab allocators which can be thrown away as part of rolling back the PTU. We can maintain a notion of the active allocator and allocate things like Stmt/Expr nodes in it, temporarily changing it to the appropriate PTU whenever we go to do something like instantiate a function template. More care will be required when allocating declarations and types, though. We would want the PTU to be efficiently recoverable from a Decl; I'm not sure how best to do that. An easy option that would cover most declarations would be to make multiple TranslationUnitDecls and parent the declarations appropriately, but I don't think that's good enough for things like member function templates, since an instantiation of that would still be parented by its original class. Maybe we can work this into the DC chain somehow, like how lexical DCs are. We add a different kind of translation unit `TU_Incremental` which is a complete translation unit that we might nonetheless incrementally extend later. Because it is complete (and we might want to generate code for it), we do perform template instantiation, but because it might be extended later, we don't warn if it declares or uses undefined internal-linkage symbols. This patch teaches clang-repl how to recover from errors by disconnecting the most recent PTU and update the primary PTU lookup tables. For instance: ```./clang-repl clang-repl> int i = 12; error; In file included from <<< inputs >>>:1: input_line_0:1:13: error: C++ requires a type specifier for all declarations int i = 12; error; ^ error: Parsing failed. clang-repl> int i = 13; extern "C" int printf(const char*,...); clang-repl> auto r1 = printf("i=%d\n", i); i=13 clang-repl> quit ``` Differential revision: https://reviews.llvm.org/D104918