[clang] [clang-repl] Lay the foundation of pretty printing for C. (PR #89811)
vgvassilev wrote: Our current theory is that somehow the build system does not mark this symbol as exported. Maybe we can confirm that by making the symbol resolution for that particular one via the JIT absolute symbol definition. This is rather a workaround and the real fix should be in the build system. ```diff diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index 7a9527891427..4131d5ff0d99 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -43,6 +43,9 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/Host.h" +#include "llvm/ExecutionEngine/Orc/LLJIT.h" + + #include using namespace clang; @@ -405,6 +408,83 @@ createJITTargetMachineBuilder(const std::string ) { return llvm::orc::JITTargetMachineBuilder(llvm::Triple(TT)); } +extern "C" void REPL_EXTERNAL_VISIBILITY __clang_Interpreter_SetValueNoAlloc( +void *This, void *OutVal, void *OpaqueType, ...) { + Value = *(Value *)OutVal; + Interpreter *I = static_cast(This); + VRef = Value(I, OpaqueType); + if (VRef.isVoid()) +return; + + va_list args; + va_start(args, /*last named param*/ OpaqueType); + + QualType QT = VRef.getType(); + if (VRef.getKind() == Value::K_PtrOrObj) { +VRef.setPtr(va_arg(args, void *)); + } else { +if (const auto *ET = QT->getAs()) + QT = ET->getDecl()->getIntegerType(); +switch (QT->castAs()->getKind()) { +default: + llvm_unreachable("unknown type kind!"); + break; + // Types shorter than int are resolved as int, else va_arg has UB. +case BuiltinType::Bool: + VRef.setBool(va_arg(args, int)); + break; +case BuiltinType::Char_S: + VRef.setChar_S(va_arg(args, int)); + break; +case BuiltinType::SChar: + VRef.setSChar(va_arg(args, int)); + break; +case BuiltinType::Char_U: + VRef.setChar_U(va_arg(args, unsigned)); + break; +case BuiltinType::UChar: + VRef.setUChar(va_arg(args, unsigned)); + break; +case BuiltinType::Short: + VRef.setShort(va_arg(args, int)); + break; +case BuiltinType::UShort: + VRef.setUShort(va_arg(args, unsigned)); + break; +case BuiltinType::Int: + VRef.setInt(va_arg(args, int)); + break; +case BuiltinType::UInt: + VRef.setUInt(va_arg(args, unsigned)); + break; +case BuiltinType::Long: + VRef.setLong(va_arg(args, long)); + break; +case BuiltinType::ULong: + VRef.setULong(va_arg(args, unsigned long)); + break; +case BuiltinType::LongLong: + VRef.setLongLong(va_arg(args, long long)); + break; +case BuiltinType::ULongLong: + VRef.setULongLong(va_arg(args, unsigned long long)); + break; + // Types shorter than double are resolved as double, else va_arg has UB. +case BuiltinType::Float: + VRef.setFloat(va_arg(args, double)); + break; +case BuiltinType::Double: + VRef.setDouble(va_arg(args, double)); + break; +case BuiltinType::LongDouble: + VRef.setLongDouble(va_arg(args, long double)); + break; + // See REPL_BUILTIN_TYPES. +} + } + va_end(args); +} + llvm::Error Interpreter::CreateExecutor() { if (IncrExecutor) return llvm::make_error("Operation failed. " @@ -431,6 +511,12 @@ llvm::Error Interpreter::CreateExecutor() { if (!Err) IncrExecutor = std::move(Executor); + auto = IncrExecutor->GetExecutionEngine(); + Err = J.getMainJITDylib().define( + llvm::orc::absoluteSymbols({{J.mangleAndIntern("__clang_Interpreter_SetValueNoAlloc"), + {llvm::orc::ExecutorAddr::fromPtr(&__clang_Interpreter_SetValueNoAlloc), + llvm::JITSymbolFlags::Exported}}})); + return Err; } @@ -860,83 +946,6 @@ __clang_Interpreter_SetValueWithAlloc(void *This, void *OutVal, return VRef.getPtr(); } -extern "C" void REPL_EXTERNAL_VISIBILITY __clang_Interpreter_SetValueNoAlloc( -void *This, void *OutVal, void *OpaqueType, ...) { - Value = *(Value *)OutVal; - Interpreter *I = static_cast(This); - VRef = Value(I, OpaqueType); - if (VRef.isVoid()) -return; - - va_list args; - va_start(args, /*last named param*/ OpaqueType); - - QualType QT = VRef.getType(); - if (VRef.getKind() == Value::K_PtrOrObj) { -VRef.setPtr(va_arg(args, void *)); - } else { -if (const auto *ET = QT->getAs()) - QT = ET->getDecl()->getIntegerType(); -switch (QT->castAs()->getKind()) { -default: - llvm_unreachable("unknown type kind!"); - break; - // Types shorter than int are resolved as int, else va_arg has UB. -case BuiltinType::Bool: - VRef.setBool(va_arg(args, int)); - break; -case BuiltinType::Char_S: - VRef.setChar_S(va_arg(args, int)); - break; -case BuiltinType::SChar: - VRef.setSChar(va_arg(args,
[clang] [clang-repl] Lay the foundation of pretty printing for C. (PR #89811)
vgvassilev wrote: > So actually even the `export_executable_symbols_for_plugins` doesn't fix our > bots. I've narrowed it down to `-DLLVM_ENABLE_PIC=ON/OFF`. Perhaps we're not > exporting symbols when `-DLLVM_ENABLE_PIC=OFF`. That’s quite strange. Is that somehow related to ld64? @lhames donyiu have any clue? https://github.com/llvm/llvm-project/pull/89811 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Lay the foundation of pretty printing for C. (PR #89811)
vgvassilev wrote: > > Would dropping this conditional make it work for your case? > > I don't have a mac handy to try it right now. If you commit it, our system > will test it automatically :) Or maybe @Thakis could give it a try? I am on my phone in the next couple of hours and I am not sure how to reproduce it. Maybe somebody who can should give it a shot? https://github.com/llvm/llvm-project/pull/89811 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Lay the foundation of pretty printing for C. (PR #89811)
vgvassilev wrote: Ah, that’s well spotted. The current test should not require plugins. Would dropping this conditional make it work for your case? https://github.com/llvm/llvm-project/pull/89811 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Teach clang-repl how to load PCHs. (PR #94166)
@@ -0,0 +1,14 @@ +// REQUIRES: host-supports-jit +// UNSUPPORTED: system-aix + +// RUN: rm -f %t.pch +// RUN: %clang_cc1 -fmax-type-align=16 -pic-level 2 -fdeprecated-macro -stack-protector 1 -fblocks -fskip-odr-check-in-gmf -fexceptions -fcxx-exceptions -fgnuc-version=0 -triple=%target_triple -DPCH -fincremental-extensions -emit-pch -x c++-header -o %t.pch %s +// RUN: clang-repl -Xcc -fgnuc-version=0 -Xcc -triple=%target_triple -Xcc -include-pch -Xcc %t.pch '#include "%s"' | FileCheck %s vgvassilev wrote: How we can get the “right” triple from clang? And yes, sometimes the build can be configured in an odd way (we have some bots) where the triple from clang is different from the triple of the JIT. Unfortunately, we did not find a way to suppress these cases with a good lit clause last time we dealt with them. https://github.com/llvm/llvm-project/pull/94166 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Lay the foundation of pretty printing for C. (PR #89811)
vgvassilev wrote: > You can debug it by cross-compiling a debug build, then running the unit > tests binary and connecting to qemu's built in gdbserver. The Arm toolchain > might have a copy of gdb in it already, but if not, gdb multiarch and lldb > would also work (which are both installable from apt). > > I'm going to try looking in a debugger myself today. Ok, this sounds good. I've never thought about that setup and perhaps is just fine to suppress that test. https://github.com/llvm/llvm-project/pull/89811 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Lay the foundation of pretty printing for C. (PR #89811)
vgvassilev wrote: Perhaps we can disable this platform if we have a way to express the setup in lit. https://github.com/llvm/llvm-project/pull/89811 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Lay the foundation of pretty printing for C. (PR #89811)
vgvassilev wrote: Could be. Is there a way for me to debug this? https://github.com/llvm/llvm-project/pull/89811 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Lay the foundation of pretty printing for C. (PR #89811)
vgvassilev wrote: > Not sure, nothing in cmake cmd: > > ``` > cmake -DLLVM_APPEND_VC_REV=OFF -GNinja -DCMAKE_BUILD_TYPE=Release > -DLLVM_CCACHE_BUILD=ON -DLLVM_USE_LINKER=lld -DLLVM_ENABLE_ASSERTIONS=ON > -DLLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF > -DCMAKE_C_COMPILER=/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm_build0/bin/clang > > -DCMAKE_CXX_COMPILER=/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm_build0/bin/clang++ > -DLLVM_ENABLE_PLUGINS=OFF '-DLLVM_ENABLE_PROJECTS='\''clang;lld;mlir'\''' > -DLLVM_USE_SANITIZER=HWAddress -DLLVM_ENABLE_LIBCXX=ON > '-DCMAKE_C_FLAGS=-nostdinc++ -isystem > /b/sanitizer-aarch64-linux-bootstrap-hwasan/build/libcxx_build_hwasan/include > -isystem > /b/sanitizer-aarch64-linux-bootstrap-hwasan/build/libcxx_build_hwasan/include/c++/v1 > -fsanitize=hwaddress -mllvm -hwasan-use-after-scope=1 > -Wl,--rpath=/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/libcxx_build_hwasan/lib > -L/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/libcxx_build_hwasan/lib > -w' '-DCMAKE_CXX_FLAGS=-nostdinc++ -isystem > /b/sanitizer-aarch64-linux-bootstrap-hwasan/build/libcxx_build_hwasan/include > -isystem > /b/sanitizer-aarch64-linux-bootstrap-hwasan/build/libcxx_build_hwasan/include/c++/v1 > -fsanitize=hwaddress -mllvm -hwasan-use-after-scope=1 > -Wl,--rpath=/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/libcxx_build_hwasan/lib > -L/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/libcxx_build_hwasan/lib > -w' > '-DCMAKE_EXE_LINKER_FLAGS=-Wl,--rpath=/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/libcxx_build_hwasan/lib > -L/b/sanitizer-aarch64-linux-bootstrap-hwasan/build/libcxx_build_hwasan/lib' > /b/sanitizer-aarch64-linux-bootstrap-hwasan/build/llvm-project/llvm > ``` @vitalybuka could it be a ccache glitch? https://github.com/llvm/llvm-project/pull/89811 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Lay the foundation of pretty printing for C. (PR #89811)
vgvassilev wrote: Very strange. I did not see a lot of platforms failing. If we decide to keep that commit, is there a way to disable this test for exactly that platform? https://github.com/llvm/llvm-project/pull/89811 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Lay the foundation of pretty printing for C. (PR #89811)
vgvassilev wrote: > It's broken here https://lab.llvm.org/buildbot/#/builders/236/builds/11633 It seems broken for a different reason. Somehow we did not export that `__clang_Interpreter_SetValueNoAlloc` symbol. Is that some `-fvisibility=hidden` build? https://github.com/llvm/llvm-project/pull/89811 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Lay the foundation of pretty printing for C. (PR #89811)
vgvassilev wrote: > So I am wondering if someone of the assumptions about types being larger than > one another do not hold on 32 bit. Or your change has exposed an existing > issue, it wouldn't be the first time. My feeling is the latter but how can we get a debug build and debug? https://github.com/llvm/llvm-project/pull/89811 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Lay the foundation of pretty printing for C. (PR #89811)
vgvassilev wrote: Is the bot configured to build for arm64 and run on arm32 somehow? But in either case the width of the `int` type should be the same, right? https://github.com/llvm/llvm-project/pull/89811 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Lay the foundation of pretty printing for C. (PR #89811)
https://github.com/vgvassilev closed https://github.com/llvm/llvm-project/pull/89811 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Lay the foundation of pretty printing for C. (PR #89811)
https://github.com/vgvassilev updated https://github.com/llvm/llvm-project/pull/89811 >From 0c1c53e7d12bf8398c1a18dca2fa472a1b7acb3f Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Tue, 23 Apr 2024 19:33:00 + Subject: [PATCH] [clang-repl] Lay the foundation of pretty printing for C. --- clang/lib/Interpreter/Interpreter.cpp | 165 ++ clang/lib/Parse/ParseStmt.cpp | 5 +- clang/test/Interpreter/pretty-print.c | 8 ++ 3 files changed, 100 insertions(+), 78 deletions(-) create mode 100644 clang/test/Interpreter/pretty-print.c diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index 683f87e8c8c79..7a95278914276 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -42,6 +42,9 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/Host.h" + +#include + using namespace clang; // FIXME: Figure out how to unify with namespace init_convenience from @@ -270,14 +273,10 @@ Interpreter::~Interpreter() { // can't find the precise resource directory in unittests so we have to hard // code them. const char *const Runtimes = R"( +#define __CLANG_REPL__ 1 #ifdef __cplusplus +#define EXTERN_C extern "C" void *__clang_Interpreter_SetValueWithAlloc(void*, void*, void*); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, void*); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, float); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, double); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, long double); -void __clang_Interpreter_SetValueNoAlloc(void*,void*,void*,unsigned long long); struct __clang_Interpreter_NewTag{} __ci_newtag; void* operator new(__SIZE_TYPE__, void* __p, __clang_Interpreter_NewTag) noexcept; template @@ -289,7 +288,11 @@ const char *const Runtimes = R"( void __clang_Interpreter_SetValueCopyArr(const T (*Src)[N], void* Placement, unsigned long Size) { __clang_Interpreter_SetValueCopyArr(Src[0], Placement, Size); } +#else +#define EXTERN_C extern #endif // __cplusplus + + EXTERN_C void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, ...); )"; llvm::Expected> @@ -588,15 +591,17 @@ std::unique_ptr Interpreter::FindRuntimeInterface() { if (!LookupInterface(ValuePrintingInfo[NoAlloc], MagicRuntimeInterface[NoAlloc])) return nullptr; - if (!LookupInterface(ValuePrintingInfo[WithAlloc], - MagicRuntimeInterface[WithAlloc])) -return nullptr; - if (!LookupInterface(ValuePrintingInfo[CopyArray], - MagicRuntimeInterface[CopyArray])) -return nullptr; - if (!LookupInterface(ValuePrintingInfo[NewTag], - MagicRuntimeInterface[NewTag])) -return nullptr; + if (Ctx.getLangOpts().CPlusPlus) { +if (!LookupInterface(ValuePrintingInfo[WithAlloc], + MagicRuntimeInterface[WithAlloc])) + return nullptr; +if (!LookupInterface(ValuePrintingInfo[CopyArray], + MagicRuntimeInterface[CopyArray])) + return nullptr; +if (!LookupInterface(ValuePrintingInfo[NewTag], + MagicRuntimeInterface[NewTag])) + return nullptr; + } return createInProcessRuntimeInterfaceBuilder(*this, Ctx, S); } @@ -855,69 +860,81 @@ __clang_Interpreter_SetValueWithAlloc(void *This, void *OutVal, return VRef.getPtr(); } -// Pointers, lvalue struct that can take as a reference. -REPL_EXTERNAL_VISIBILITY void -__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, -void *Val) { +extern "C" void REPL_EXTERNAL_VISIBILITY __clang_Interpreter_SetValueNoAlloc( +void *This, void *OutVal, void *OpaqueType, ...) { Value = *(Value *)OutVal; - VRef = Value(static_cast(This), OpaqueType); - VRef.setPtr(Val); -} + Interpreter *I = static_cast(This); + VRef = Value(I, OpaqueType); + if (VRef.isVoid()) +return; -REPL_EXTERNAL_VISIBILITY void -__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, -void *OpaqueType) { - Value = *(Value *)OutVal; - VRef = Value(static_cast(This), OpaqueType); -} + va_list args; + va_start(args, /*last named param*/ OpaqueType); -static void SetValueDataBasedOnQualType(Value , unsigned long long Data) { - QualType QT = V.getType(); - if (const auto *ET = QT->getAs()) -QT = ET->getDecl()->getIntegerType(); - - switch (QT->castAs()->getKind()) { - default: -llvm_unreachable("unknown type kind!"); -#define X(type, name) \ - case BuiltinType::name: \ -
[clang] [clang-repl] Lay the foundation of pretty printing for C. (PR #89811)
https://github.com/vgvassilev updated https://github.com/llvm/llvm-project/pull/89811 >From eb5d2ec5bb77626542671ac713714e723f66d62d Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Tue, 23 Apr 2024 19:33:00 + Subject: [PATCH] [clang-repl] Lay the foundation of pretty printing for C. --- clang/lib/Interpreter/Interpreter.cpp | 166 ++ clang/lib/Parse/ParseStmt.cpp | 5 +- clang/test/Interpreter/pretty-print.c | 8 ++ 3 files changed, 101 insertions(+), 78 deletions(-) create mode 100644 clang/test/Interpreter/pretty-print.c diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index 683f87e8c8c79..bd5a91dbf8ec9 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -42,6 +42,9 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/Host.h" + +#include + using namespace clang; // FIXME: Figure out how to unify with namespace init_convenience from @@ -270,14 +273,10 @@ Interpreter::~Interpreter() { // can't find the precise resource directory in unittests so we have to hard // code them. const char *const Runtimes = R"( +#define __CLANG_REPL__ 1 #ifdef __cplusplus +#define EXTERN_C extern "C" void *__clang_Interpreter_SetValueWithAlloc(void*, void*, void*); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, void*); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, float); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, double); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, long double); -void __clang_Interpreter_SetValueNoAlloc(void*,void*,void*,unsigned long long); struct __clang_Interpreter_NewTag{} __ci_newtag; void* operator new(__SIZE_TYPE__, void* __p, __clang_Interpreter_NewTag) noexcept; template @@ -289,7 +288,11 @@ const char *const Runtimes = R"( void __clang_Interpreter_SetValueCopyArr(const T (*Src)[N], void* Placement, unsigned long Size) { __clang_Interpreter_SetValueCopyArr(Src[0], Placement, Size); } +#else +#define EXTERN_C extern #endif // __cplusplus + + EXTERN_C void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, ...); )"; llvm::Expected> @@ -588,15 +591,17 @@ std::unique_ptr Interpreter::FindRuntimeInterface() { if (!LookupInterface(ValuePrintingInfo[NoAlloc], MagicRuntimeInterface[NoAlloc])) return nullptr; - if (!LookupInterface(ValuePrintingInfo[WithAlloc], - MagicRuntimeInterface[WithAlloc])) -return nullptr; - if (!LookupInterface(ValuePrintingInfo[CopyArray], - MagicRuntimeInterface[CopyArray])) -return nullptr; - if (!LookupInterface(ValuePrintingInfo[NewTag], - MagicRuntimeInterface[NewTag])) -return nullptr; + if (Ctx.getLangOpts().CPlusPlus) { +if (!LookupInterface(ValuePrintingInfo[WithAlloc], + MagicRuntimeInterface[WithAlloc])) + return nullptr; +if (!LookupInterface(ValuePrintingInfo[CopyArray], + MagicRuntimeInterface[CopyArray])) + return nullptr; +if (!LookupInterface(ValuePrintingInfo[NewTag], + MagicRuntimeInterface[NewTag])) + return nullptr; + } return createInProcessRuntimeInterfaceBuilder(*this, Ctx, S); } @@ -855,69 +860,82 @@ __clang_Interpreter_SetValueWithAlloc(void *This, void *OutVal, return VRef.getPtr(); } -// Pointers, lvalue struct that can take as a reference. -REPL_EXTERNAL_VISIBILITY void -__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, -void *Val) { +REPL_EXTERNAL_VISIBILITY +extern "C" void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, +void *OpaqueType, ...) { Value = *(Value *)OutVal; - VRef = Value(static_cast(This), OpaqueType); - VRef.setPtr(Val); -} + Interpreter *I = static_cast(This); + VRef = Value(I, OpaqueType); + if (VRef.isVoid()) +return; -REPL_EXTERNAL_VISIBILITY void -__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, -void *OpaqueType) { - Value = *(Value *)OutVal; - VRef = Value(static_cast(This), OpaqueType); -} + va_list args; + va_start(args, /*last named param*/ OpaqueType); -static void SetValueDataBasedOnQualType(Value , unsigned long long Data) { - QualType QT = V.getType(); - if (const auto *ET = QT->getAs()) -QT = ET->getDecl()->getIntegerType(); - - switch (QT->castAs()->getKind()) { - default: -llvm_unreachable("unknown type kind!"); -#define X(type, name) \ - case BuiltinType::name:
[clang] [clang-repl] Support wasm execution (PR #86402)
vgvassilev wrote: @AaronBallman do we have access to some existing bot to set it up as @argentite suggests? https://github.com/llvm/llvm-project/pull/86402 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Fix clang reject valid C++ code after d999ce0302f06d250f6d496b56a5a5f (PR #94471)
@@ -413,7 +413,9 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { if (!ND) continue; // Check if we need to clean up the IdResolver chain. -if (ND->getDeclName().getFETokenInfo()) +if (ND->getDeclName().getFETokenInfo() && +CI->getPreprocessor().isIncrementalProcessingEnabled() && vgvassilev wrote: Here the incremental processing is guaranteed. We do not need to check. https://github.com/llvm/llvm-project/pull/94471 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Fix clang reject valid C++ code after d999ce0302f06d250f6d496b56a5a5f (PR #94471)
vgvassilev wrote: > > Oh, we need to adjust > > https://github.com/root-project/root/blob/be5d34934de883270683030b3af2cd1195d17ea8/cmake/modules/RootMacros.cmake#L272 > > to skip in case of C++... > > The link points to an irrelevant project, I assume you mean here > https://github.com/llvm/llvm-project/blob/main/clang/lib/Interpreter/IncrementalParser.cpp#L416? > If we need to skip for C++, I think we should do it for ObjectiveC as well, > like > > ``` > if (ND->getDeclName().getFETokenInfo() && > !(!PP.isIncrementalProcessingEnabled() || getLangOpts().ObjC || > getLangOpts().CPlusPlus)) { >... > } > ``` Not sure how that happened. I meant https://github.com/llvm/llvm-project/blob/70550cd6aa9f2587e166d6ab9636192af3f3264d/clang/lib/Interpreter/IncrementalParser.cpp#L416-L417 https://github.com/llvm/llvm-project/pull/94471 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Fix clang reject valid C++ code after d999ce0302f06d250f6d496b56a5a5f (PR #94471)
vgvassilev wrote: Oh, we need to adjust https://github.com/root-project/root/blob/be5d34934de883270683030b3af2cd1195d17ea8/cmake/modules/RootMacros.cmake#L272 to skip in case of C++... https://github.com/llvm/llvm-project/pull/94471 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Fix clang reject valid C++ code after d999ce0302f06d250f6d496b56a5a5f (PR #94471)
https://github.com/vgvassilev approved this pull request. LGTM, can you include the produced errors and the steps to reproduce the failure in the commit log? Or refer to the github post describing it? https://github.com/llvm/llvm-project/pull/94471 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
vgvassilev wrote: > > Out of curiosity, in what context you use -fincremental-extensions? > > The code snippet I provided is extracted from our internal test. We have an > internal clang-tool (with the `incremental-extensions` on) to generate headers I am a bit overwhelmed right now, are you willing to open a PR with that change so we can merge it -- otherwise I could look later this week :( https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Support wasm execution (PR #86402)
vgvassilev wrote: > > > > @AaronBallman, to be fair, clang is testing the wasm features in terms > > > > of output. So this is wiring up a bunch of tested features that will > > > > allow execution. Clang generally does not test execution but output, so > > > > we are not creating a precedent here since that PR can be considered > > > > plumbing for downstream consumers. > > > > > > > > > If we don't have community test coverage, we'll regress that plumbing for > > > downstream consumers. In general, we shouldn't claim we support something > > > we don't test. However, if there is a downstream consumer that agrees to > > > be actively responsible for repairing breakages, we sometimes allow it > > > (e.g., > > > https://discourse.llvm.org/t/rfc-building-llvm-for-webassembly/79073) > > > > > > I am not sure if we have the same definition for "claim". FWIW I am not > > saying we should put any of this on the website or elsewhere. We have a > > downstream consumer which intergrates the emscripten version of wasm > > [here](https://github.com/emscripten-forge/recipes/tree/main/recipes/recipes_emscripten/llvm). > > @DerThorsten is my go-to person when it comes to emscripten and llvm. I > > believe they are quite sensitive about breakages. In any case we will > > develop tests in the CppInterOp project, too. > > For emscripten-forge recipes of xeus-cpp /clang you can break whatever you > want. I am sure there are no deployments / users yet > > > > @AaronBallman, to be fair, clang is testing the wasm features in terms > > > > of output. So this is wiring up a bunch of tested features that will > > > > allow execution. Clang generally does not test execution but output, so > > > > we are not creating a precedent here since that PR can be considered > > > > plumbing for downstream consumers. > > > > > > > > > If we don't have community test coverage, we'll regress that plumbing for > > > downstream consumers. In general, we shouldn't claim we support something > > > we don't test. However, if there is a downstream consumer that agrees to > > > be actively responsible for repairing breakages, we sometimes allow it > > > (e.g., > > > https://discourse.llvm.org/t/rfc-building-llvm-for-webassembly/79073) > > > > > > I am not sure if we have the same definition for "claim". FWIW I am not > > saying we should put any of this on the website or elsewhere. We have a > > downstream consumer which intergrates the emscripten version of wasm > > [here](https://github.com/emscripten-forge/recipes/tree/main/recipes/recipes_emscripten/llvm). > > @DerThorsten is my go-to person when it comes to emscripten and llvm. I > > believe they are quite sensitive about breakages. In any case we will > > develop tests in the CppInterOp project, too. > > For emscripten-forge recipes of xeus-cpp /clang you can break whatever you > want. I am sure there are no deployments / users yet I think Aaron's question was if we land this PR and it regresses over time, would our downstream clients be able to catch it in a timely manner. https://github.com/llvm/llvm-project/pull/86402 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
vgvassilev wrote: > Thanks for the prompt response. I think limiting it to C-only will fix the > issue (note that there is no `C` in `LangOpts`, you may want to use > `!getLangOpts().CPlusPlus` to exclude C++). Makes sense. If that works for you, we can check this in. I want to somehow record this breakage in the form of a test for our future selves when decide to revisit this workaround-looking code. Out of curiosity, in what context you use `-fincremental-extensions`? https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
vgvassilev wrote: I realize I do not entirely understand the role of the IdResolver chain in c++. Perhaps we are better of changing this line to: ```cpp if (!PP.isIncrementalProcessingEnabled() || getLangOpts().ObjC) IdResolver.RemoveDecl(D); ``` to ``` if (!PP.isIncrementalProcessingEnabled() || !getLangOpts().C) IdResolver.RemoveDecl(D); ``` This way will limit the scope to the actual intent without assuming the IdResolver changes are irrelevant for languages such as C++. Can you test if that works? https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
vgvassilev wrote: @hokein, ah, that's annoying. Can you provide the entire proprocessed file that does not work? I'd like to bisect and debug. https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Support wasm execution (PR #86402)
vgvassilev wrote: > > > > @AaronBallman, to be fair, clang is testing the wasm features in terms > > > > of output. So this is wiring up a bunch of tested features that will > > > > allow execution. Clang generally does not test execution but output, so > > > > we are not creating a precedent here since that PR can be considered > > > > plumbing for downstream consumers. > > > > > > > > > If we don't have community test coverage, we'll regress that plumbing for > > > downstream consumers. In general, we shouldn't claim we support something > > > we don't test. However, if there is a downstream consumer that agrees to > > > be actively responsible for repairing breakages, we sometimes allow it > > > (e.g., > > > https://discourse.llvm.org/t/rfc-building-llvm-for-webassembly/79073) > > > > > > I am not sure if we have the same definition for "claim". FWIW I am not > > saying we should put any of this on the website or elsewhere. We have a > > downstream consumer which intergrates the emscripten version of wasm > > [here](https://github.com/emscripten-forge/recipes/tree/main/recipes/recipes_emscripten/llvm). > > @DerThorsten is my go-to person when it comes to emscripten and llvm. I > > believe they are quite sensitive about breakages. In any case we will > > develop tests in the CppInterOp project, too. > > I wouldn't focus on "claim" too heavily. Ok. > We should not have code in-tree that's not tested except in exceptional > situations and it's not clear to me that this is (or isn't) such an > exceptional situation. Well, as of today I do not see how we can test execution of jit-based wasm in tree. I am not a wasm expert but IIUC, testing would require a browser and compiling llvm for emscripten and somehow running some remote execution service... My worry is that we are losing the forest for the trees because this work has stayed as a patch since maybe more than a year. It'd be a pity to wait more because that blocks downstream consumers in practice... https://github.com/llvm/llvm-project/pull/86402 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Support wasm execution (PR #86402)
vgvassilev wrote: > > @AaronBallman, to be fair, clang is testing the wasm features in terms of > > output. So this is wiring up a bunch of tested features that will allow > > execution. Clang generally does not test execution but output, so we are > > not creating a precedent here since that PR can be considered plumbing for > > downstream consumers. > > If we don't have community test coverage, we'll regress that plumbing for > downstream consumers. In general, we shouldn't claim we support something we > don't test. However, if there is a downstream consumer that agrees to be > actively responsible for repairing breakages, we sometimes allow it (e.g., > https://discourse.llvm.org/t/rfc-building-llvm-for-webassembly/79073) I am not sure if we have the same definition for "claim". FWIW I am not saying we should put any of this on the website or elsewhere. We have a downstream consumer which intergrates the emscripten version of wasm [here](https://github.com/emscripten-forge/recipes/tree/main/recipes/recipes_emscripten/llvm). @derthorsten is my go-to person when it comes to emscripten and llvm. I believe they are quite sensitive about breakages. In any case we will develop tests in the CppInterOp project, too. https://github.com/llvm/llvm-project/pull/86402 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Support wasm execution (PR #86402)
vgvassilev wrote: @AaronBallman, to be fair, clang is testing the wasm features in terms of output. So this is wiring up a bunch of tested features that will allow execution. Clang generally does not test execution but output, so we are not creating a precedent here since that PR can be considered plumbing for downstream consumers. https://github.com/llvm/llvm-project/pull/86402 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Support wasm execution (PR #86402)
vgvassilev wrote: That would make sense. I am not sure if we can set a post commit bot though. @argentite what do you think? https://github.com/llvm/llvm-project/pull/86402 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Support wasm execution (PR #86402)
vgvassilev wrote: Hi @AaronBallman, we need some leadership here. This pull request teaches clang-repl to work inside a browser. It enables webassembly [xeus-cpp](https://github.com/compiler-research/xeus-cpp) (through clang-repl) which connects to the JupyterLite infrastructure. This change (actually an older version of it) enables execution of C++ in a browser. Here is an example https://wasmdemo.argentite.me/ This way we can enable in JupyterLite system programming with C/C++ which can be transformative for education in system programming as it only requires a browser not a cloud service. Unfortunately, this PR cannot be tested in the current testing infrastructure in llvm because it needs a browser to provide a proper execution environment. If we move forward here that would unblock work on the other end of the infrastructure. https://github.com/llvm/llvm-project/pull/86402 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Support wasm execution (PR #86402)
https://github.com/vgvassilev updated https://github.com/llvm/llvm-project/pull/86402 >From e1e3b1ec07133fb67b4f98c6696e330fdedf2460 Mon Sep 17 00:00:00 2001 From: Anubhab Ghosh Date: Sat, 23 Mar 2024 15:13:57 + Subject: [PATCH] [clang-repl] Support wasm execution. This commit introduces support for running clang-repl and executing C++ code interactively inside a Javascript engine using WebAssembly when built with Emscripten. This is achieved by producing WASM "shared libraries" that can be loaded by the Emscripten runtime using dlopen() More discussion is available in https://reviews.llvm.org/D158140 --- clang/lib/Interpreter/CMakeLists.txt | 6 + clang/lib/Interpreter/IncrementalExecutor.cpp | 2 + clang/lib/Interpreter/IncrementalExecutor.h | 11 +- clang/lib/Interpreter/Interpreter.cpp | 13 ++ clang/lib/Interpreter/Wasm.cpp| 114 ++ clang/lib/Interpreter/Wasm.h | 37 ++ 6 files changed, 179 insertions(+), 4 deletions(-) create mode 100644 clang/lib/Interpreter/Wasm.cpp create mode 100644 clang/lib/Interpreter/Wasm.h diff --git a/clang/lib/Interpreter/CMakeLists.txt b/clang/lib/Interpreter/CMakeLists.txt index 9065f998f73c4..6a069659ebb8d 100644 --- a/clang/lib/Interpreter/CMakeLists.txt +++ b/clang/lib/Interpreter/CMakeLists.txt @@ -12,6 +12,10 @@ set(LLVM_LINK_COMPONENTS TargetParser ) +if (EMSCRIPTEN AND "lld" IN_LIST LLVM_ENABLE_PROJECTS) + set(WASM_SRC Wasm.cpp) +endif() + add_clang_library(clangInterpreter DeviceOffload.cpp CodeCompletion.cpp @@ -20,6 +24,8 @@ add_clang_library(clangInterpreter Interpreter.cpp InterpreterUtils.cpp Value.cpp + ${WASM_SRC} + PARTIAL_SOURCES_INTENDED DEPENDS intrinsics_gen diff --git a/clang/lib/Interpreter/IncrementalExecutor.cpp b/clang/lib/Interpreter/IncrementalExecutor.cpp index 6f036107c14a9..1824a5b4570a9 100644 --- a/clang/lib/Interpreter/IncrementalExecutor.cpp +++ b/clang/lib/Interpreter/IncrementalExecutor.cpp @@ -36,6 +36,8 @@ LLVM_ATTRIBUTE_USED void linkComponents() { } namespace clang { +IncrementalExecutor::IncrementalExecutor(llvm::orc::ThreadSafeContext ) +: TSCtx(TSC) {} llvm::Expected> IncrementalExecutor::createDefaultJITBuilder( diff --git a/clang/lib/Interpreter/IncrementalExecutor.h b/clang/lib/Interpreter/IncrementalExecutor.h index b4347209e14fe..7954cde36588b 100644 --- a/clang/lib/Interpreter/IncrementalExecutor.h +++ b/clang/lib/Interpreter/IncrementalExecutor.h @@ -43,16 +43,19 @@ class IncrementalExecutor { llvm::DenseMap ResourceTrackers; +protected: + IncrementalExecutor(llvm::orc::ThreadSafeContext ); + public: enum SymbolNameKind { IRName, LinkerName }; IncrementalExecutor(llvm::orc::ThreadSafeContext , llvm::orc::LLJITBuilder , llvm::Error ); - ~IncrementalExecutor(); + virtual ~IncrementalExecutor(); - llvm::Error addModule(PartialTranslationUnit ); - llvm::Error removeModule(PartialTranslationUnit ); - llvm::Error runCtors() const; + virtual llvm::Error addModule(PartialTranslationUnit ); + virtual llvm::Error removeModule(PartialTranslationUnit ); + virtual llvm::Error runCtors() const; llvm::Error cleanUp(); llvm::Expected getSymbolAddress(llvm::StringRef Name, SymbolNameKind NameKind) const; diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index 683f87e8c8c79..509f3e594568e 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -15,6 +15,9 @@ #include "IncrementalExecutor.h" #include "IncrementalParser.h" #include "InterpreterUtils.h" +#ifdef __EMSCRIPTEN__ +#include "Wasm.h" +#endif // __EMSCRIPTEN__ #include "clang/AST/ASTContext.h" #include "clang/AST/Mangle.h" @@ -183,6 +186,12 @@ IncrementalCompilerBuilder::CreateCpp() { std::vector Argv; Argv.reserve(5 + 1 + UserArgs.size()); Argv.push_back("-xc++"); +#ifdef __EMSCRIPTEN__ + Argv.push_back("-target"); + Argv.push_back("wasm32-unknown-emscripten"); + Argv.push_back("-pie"); + Argv.push_back("-shared"); +#endif Argv.insert(Argv.end(), UserArgs.begin(), UserArgs.end()); std::string TT = TargetTriple ? *TargetTriple : llvm::sys::getProcessTriple(); @@ -423,8 +432,12 @@ llvm::Error Interpreter::CreateExecutor() { } llvm::Error Err = llvm::Error::success(); +#ifdef __EMSCRIPTEN__ + auto Executor = std::make_unique(*TSCtx); +#else auto Executor = std::make_unique(*TSCtx, *JITBuilder, Err); +#endif if (!Err) IncrExecutor = std::move(Executor); diff --git a/clang/lib/Interpreter/Wasm.cpp b/clang/lib/Interpreter/Wasm.cpp new file mode 100644 index 0..1001410aa0f27 --- /dev/null +++ b/clang/lib/Interpreter/Wasm.cpp @@ -0,0 +1,114 @@ +//===- Wasm.cpp - Wasm Interpreter --*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See
[clang] [clang-tools-extra] [libcxx] Reland "[clang] Enable sized deallocation by default in C++14 onwards" (PR #90373)
vgvassilev wrote: It seems we have troubles with exporting the right symbols on windows. I am cc-ing @compnerd and @fsfod for more expertise. https://github.com/llvm/llvm-project/pull/90373 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Lay the foundation of pretty printing for C. (PR #89811)
https://github.com/vgvassilev updated https://github.com/llvm/llvm-project/pull/89811 >From 3094e6026925ebcba6da86dd16111f4f70f9a700 Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Tue, 23 Apr 2024 19:33:00 + Subject: [PATCH] [clang-repl] Lay the foundation of pretty printing for C. --- clang/lib/Interpreter/Interpreter.cpp | 166 ++ clang/lib/Parse/ParseStmt.cpp | 5 +- clang/test/Interpreter/pretty-print.c | 8 ++ 3 files changed, 101 insertions(+), 78 deletions(-) create mode 100644 clang/test/Interpreter/pretty-print.c diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index 683f87e8c8c79..bd5a91dbf8ec9 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -42,6 +42,9 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/Host.h" + +#include + using namespace clang; // FIXME: Figure out how to unify with namespace init_convenience from @@ -270,14 +273,10 @@ Interpreter::~Interpreter() { // can't find the precise resource directory in unittests so we have to hard // code them. const char *const Runtimes = R"( +#define __CLANG_REPL__ 1 #ifdef __cplusplus +#define EXTERN_C extern "C" void *__clang_Interpreter_SetValueWithAlloc(void*, void*, void*); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, void*); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, float); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, double); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, long double); -void __clang_Interpreter_SetValueNoAlloc(void*,void*,void*,unsigned long long); struct __clang_Interpreter_NewTag{} __ci_newtag; void* operator new(__SIZE_TYPE__, void* __p, __clang_Interpreter_NewTag) noexcept; template @@ -289,7 +288,11 @@ const char *const Runtimes = R"( void __clang_Interpreter_SetValueCopyArr(const T (*Src)[N], void* Placement, unsigned long Size) { __clang_Interpreter_SetValueCopyArr(Src[0], Placement, Size); } +#else +#define EXTERN_C extern #endif // __cplusplus + + EXTERN_C void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, ...); )"; llvm::Expected> @@ -588,15 +591,17 @@ std::unique_ptr Interpreter::FindRuntimeInterface() { if (!LookupInterface(ValuePrintingInfo[NoAlloc], MagicRuntimeInterface[NoAlloc])) return nullptr; - if (!LookupInterface(ValuePrintingInfo[WithAlloc], - MagicRuntimeInterface[WithAlloc])) -return nullptr; - if (!LookupInterface(ValuePrintingInfo[CopyArray], - MagicRuntimeInterface[CopyArray])) -return nullptr; - if (!LookupInterface(ValuePrintingInfo[NewTag], - MagicRuntimeInterface[NewTag])) -return nullptr; + if (Ctx.getLangOpts().CPlusPlus) { +if (!LookupInterface(ValuePrintingInfo[WithAlloc], + MagicRuntimeInterface[WithAlloc])) + return nullptr; +if (!LookupInterface(ValuePrintingInfo[CopyArray], + MagicRuntimeInterface[CopyArray])) + return nullptr; +if (!LookupInterface(ValuePrintingInfo[NewTag], + MagicRuntimeInterface[NewTag])) + return nullptr; + } return createInProcessRuntimeInterfaceBuilder(*this, Ctx, S); } @@ -855,69 +860,82 @@ __clang_Interpreter_SetValueWithAlloc(void *This, void *OutVal, return VRef.getPtr(); } -// Pointers, lvalue struct that can take as a reference. -REPL_EXTERNAL_VISIBILITY void -__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, -void *Val) { +REPL_EXTERNAL_VISIBILITY +extern "C" void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, +void *OpaqueType, ...) { Value = *(Value *)OutVal; - VRef = Value(static_cast(This), OpaqueType); - VRef.setPtr(Val); -} + Interpreter *I = static_cast(This); + VRef = Value(I, OpaqueType); + if (VRef.isVoid()) +return; -REPL_EXTERNAL_VISIBILITY void -__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, -void *OpaqueType) { - Value = *(Value *)OutVal; - VRef = Value(static_cast(This), OpaqueType); -} + va_list args; + va_start(args, /*last named param*/ OpaqueType); -static void SetValueDataBasedOnQualType(Value , unsigned long long Data) { - QualType QT = V.getType(); - if (const auto *ET = QT->getAs()) -QT = ET->getDecl()->getIntegerType(); - - switch (QT->castAs()->getKind()) { - default: -llvm_unreachable("unknown type kind!"); -#define X(type, name) \ - case BuiltinType::name:
[clang] [clang-repl] Extend the C support. (PR #89804)
vgvassilev wrote: @jasonmolenda, I struggled quite a bit in reproducing the test failures and everything but I have a fix. Thanks a lot for your time and I hope the fix works! https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] d999ce0 - Reland "[clang-repl] Extend the C support. (#89804)"
Author: Vassil Vassilev Date: 2024-06-04T13:55:03Z New Revision: d999ce0302f06d250f6d496b56a5a5f2dc331e61 URL: https://github.com/llvm/llvm-project/commit/d999ce0302f06d250f6d496b56a5a5f2dc331e61 DIFF: https://github.com/llvm/llvm-project/commit/d999ce0302f06d250f6d496b56a5a5f2dc331e61.diff LOG: Reland "[clang-repl] Extend the C support. (#89804)" Original commit message:" [clang-repl] Extend the C support. (#89804) The IdResolver chain is the main way for C to implement lookup rules. Every new partial translation unit caused clang to exit the top-most scope which in turn cleaned up the IdResolver chain. That was not an issue for C++ because its lookup is implemented on the level of declaration contexts. This patch keeps the IdResolver chain across partial translation units maintaining proper C-style lookup infrastructure. " It was reverted in dfdf1c5fe45a82b9c578306f3d7627fd251d63f8 because it broke the bots of lldb. This failure was subtle to debug but the current model does not work well with ObjectiveC support in lldb. This patch does cleans up the partial translation units in ObjectiveC. In future if we want to support ObjectiveC we need to understand what exactly lldb is doing when recovering from errors... Added: clang/test/Interpreter/execute.c Modified: clang/lib/Interpreter/IncrementalParser.cpp clang/lib/Sema/SemaDecl.cpp Removed: diff --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp index ef90fe9e6f545..5bc8385d874a1 100644 --- a/clang/lib/Interpreter/IncrementalParser.cpp +++ b/clang/lib/Interpreter/IncrementalParser.cpp @@ -387,8 +387,7 @@ std::unique_ptr IncrementalParser::GenModule() { void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { TranslationUnitDecl *MostRecentTU = PTU.TUPart; - TranslationUnitDecl *FirstTU = MostRecentTU->getFirstDecl(); - if (StoredDeclsMap *Map = FirstTU->getPrimaryContext()->getLookupPtr()) { + if (StoredDeclsMap *Map = MostRecentTU->getPrimaryContext()->getLookupPtr()) { for (auto &&[Key, List] : *Map) { DeclContextLookupResult R = List.getLookupResult(); std::vector NamedDeclsToRemove; @@ -407,6 +406,16 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { } } } + + // FIXME: We should de-allocate MostRecentTU + for (Decl *D : MostRecentTU->decls()) { +auto *ND = dyn_cast(D); +if (!ND) + continue; +// Check if we need to clean up the IdResolver chain. +if (ND->getDeclName().getFETokenInfo()) + getCI()->getSema().IdResolver.RemoveDecl(ND); + } } llvm::StringRef IncrementalParser::GetMangledName(GlobalDecl GD) const { diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 08483e6ebd67f..7ff05ae514ebe 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2284,9 +2284,13 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { if (LabelDecl *LD = dyn_cast(D)) CheckPoppedLabel(LD, *this, addDiag); -// Remove this name from our lexical scope, and warn on it if we haven't -// already. -IdResolver.RemoveDecl(D); +// Partial translation units that are created in incremental processing must +// not clean up the IdResolver because PTUs should take into account the +// declarations that came from previous PTUs. +if (!PP.isIncrementalProcessingEnabled() || getLangOpts().ObjC) + IdResolver.RemoveDecl(D); + +// Warn on it if we are shadowing a declaration. auto ShadowI = ShadowingDecls.find(D); if (ShadowI != ShadowingDecls.end()) { if (const auto *FD = dyn_cast(ShadowI->second)) { diff --git a/clang/test/Interpreter/execute.c b/clang/test/Interpreter/execute.c new file mode 100644 index 0..44a3a32c93011 --- /dev/null +++ b/clang/test/Interpreter/execute.c @@ -0,0 +1,21 @@ +// REQUIRES: host-supports-jit +// UNSUPPORTED: system-aix + +// RUN: cat %s | clang-repl -Xcc -xc -Xcc -Xclang -Xcc -verify | FileCheck %s +// RUN: cat %s | clang-repl -Xcc -xc -Xcc -O2 -Xcc -Xclang -Xcc -verify| FileCheck %s +int printf(const char *, ...); +int i = 42; err // expected-error{{use of undeclared identifier}} +int i = 42; +struct S { float f; struct S *m;} s = {1.0, 0}; +// FIXME: Making foo inline fails to emit the function. +int foo() { return 42; } +void run() {\ + printf("i = %d\n", i);\ + printf("S[f=%f, m=0x%llx]\n", s.f, (unsigned long long)s.m); \ + int r3 = foo(); \ +} +run(); +// CHECK: i = 42 +// CHECK-NEXT: S[f=1.00, m=0x0] + +%quit ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Teach clang-repl how to load PCHs. (PR #94166)
@@ -138,6 +138,8 @@ namespace { assert(!M && "Replacing existing Module?"); M.reset(new llvm::Module(ExpandModuleName(ModuleName, CodeGenOpts), C)); + IRGenFinished = false; vgvassilev wrote: It's a double negation: it is /not/ finished when we start a new module. https://github.com/llvm/llvm-project/pull/94166 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Teach clang-repl how to load PCHs. (PR #94166)
@@ -282,6 +288,8 @@ namespace { } void HandleTranslationUnit(ASTContext ) override { + IRGenFinished = true; vgvassilev wrote: Good point. I guess I was avoiding this early return which I have now removed. In fact this change fixed some of the failures we see in the tests. https://github.com/llvm/llvm-project/pull/94166 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Teach clang-repl how to load PCHs. (PR #94166)
https://github.com/vgvassilev updated https://github.com/llvm/llvm-project/pull/94166 >From 896f3090ca2eadf650459caee9a4106fc7dd381d Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Thu, 30 May 2024 05:05:41 + Subject: [PATCH 1/2] [clang-repl] Teach clang-repl how to load PCHs. --- clang/include/clang/CodeGen/ModuleBuilder.h | 6 ++ clang/lib/CodeGen/BackendConsumer.h | 5 - clang/lib/CodeGen/CodeGenAction.cpp | 6 +- clang/lib/CodeGen/ModuleBuilder.cpp | 8 clang/lib/Interpreter/IncrementalParser.cpp | 4 clang/test/Interpreter/execute-pch.cpp | 14 ++ 6 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 clang/test/Interpreter/execute-pch.cpp diff --git a/clang/include/clang/CodeGen/ModuleBuilder.h b/clang/include/clang/CodeGen/ModuleBuilder.h index edacd82bf899d..cb5919d1c8af5 100644 --- a/clang/include/clang/CodeGen/ModuleBuilder.h +++ b/clang/include/clang/CodeGen/ModuleBuilder.h @@ -48,6 +48,12 @@ namespace CodeGen { class CodeGenerator : public ASTConsumer { virtual void anchor(); +protected: + /// True if we've finished generating IR. This prevents us from generating + /// additional LLVM IR after emitting output in HandleTranslationUnit. This + /// can happen when Clang plugins trigger additional AST deserialization. + bool IRGenFinished = false; + public: /// Return an opaque reference to the CodeGenModule object, which can /// be used in various secondary APIs. It is valid as long as the diff --git a/clang/lib/CodeGen/BackendConsumer.h b/clang/lib/CodeGen/BackendConsumer.h index 0fe9929dca2b3..76ab5add603b7 100644 --- a/clang/lib/CodeGen/BackendConsumer.h +++ b/clang/lib/CodeGen/BackendConsumer.h @@ -41,11 +41,6 @@ class BackendConsumer : public ASTConsumer { llvm::Timer LLVMIRGeneration; unsigned LLVMIRGenerationRefCount; - /// True if we've finished generating IR. This prevents us from generating - /// additional LLVM IR after emitting output in HandleTranslationUnit. This - /// can happen when Clang plugins trigger additional AST deserialization. - bool IRGenFinished = false; - bool TimerIsEnabled = false; std::unique_ptr Gen; diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp index 6d3efdb5ffe34..6e2204d2dba0c 100644 --- a/clang/lib/CodeGen/CodeGenAction.cpp +++ b/clang/lib/CodeGen/CodeGenAction.cpp @@ -221,9 +221,7 @@ void BackendConsumer::HandleInlineFunctionDefinition(FunctionDecl *D) { } void BackendConsumer::HandleInterestingDecl(DeclGroupRef D) { - // Ignore interesting decls from the AST reader after IRGen is finished. - if (!IRGenFinished) -HandleTopLevelDecl(D); + HandleTopLevelDecl(D); } // Links each entry in LinkModules into our module. Returns true on error. @@ -285,8 +283,6 @@ void BackendConsumer::HandleTranslationUnit(ASTContext ) { if (LLVMIRGenerationRefCount == 0) LLVMIRGeneration.stopTimer(); } - -IRGenFinished = true; } // Silently ignore if we weren't initialized for some reason. diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp index df85295cfb2e2..768d2ffd2d8d9 100644 --- a/clang/lib/CodeGen/ModuleBuilder.cpp +++ b/clang/lib/CodeGen/ModuleBuilder.cpp @@ -138,6 +138,8 @@ namespace { assert(!M && "Replacing existing Module?"); M.reset(new llvm::Module(ExpandModuleName(ModuleName, CodeGenOpts), C)); + IRGenFinished = false; + std::unique_ptr OldBuilder = std::move(Builder); Initialize(*Ctx); @@ -179,6 +181,10 @@ namespace { } bool HandleTopLevelDecl(DeclGroupRef DG) override { + // Ignore interesting decls from the AST reader after IRGen is finished. + if (IRGenFinished) +return true; // We can't CodeGen more but pass to other consumers. + // FIXME: Why not return false and abort parsing? if (Diags.hasUnrecoverableErrorOccurred()) return true; @@ -282,6 +288,8 @@ namespace { } void HandleTranslationUnit(ASTContext ) override { + IRGenFinished = true; + // Release the Builder when there is no error. if (!Diags.hasUnrecoverableErrorOccurred() && Builder) Builder->Release(); diff --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp index ef90fe9e6f545..eddd4f356c5af 100644 --- a/clang/lib/Interpreter/IncrementalParser.cpp +++ b/clang/lib/Interpreter/IncrementalParser.cpp @@ -219,6 +219,10 @@ IncrementalParser::IncrementalParser(Interpreter , Consumer = >getASTConsumer(); P.reset( new Parser(CI->getPreprocessor(), CI->getSema(), /*SkipBodies=*/false)); + + if (ExternalASTSource *External = CI->getASTContext().getExternalSource()) +External->StartTranslationUnit(Consumer); + P->Initialize(); // An initial PTU is needed as CUDA includes some headers automatically diff --git a/clang/test/Interpreter/execute-pch.cpp
[clang] [clang-repl] Support wasm execution (PR #86402)
https://github.com/vgvassilev updated https://github.com/llvm/llvm-project/pull/86402 >From 6b94e0cd67e59a7fcde2a327d6565a3850dc5f50 Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Thu, 30 May 2024 05:08:17 + Subject: [PATCH 1/2] Revert "Revert "[clang-repl] Extend the C support. (#89804)"" This reverts commit dfdf1c5fe45a82b9c578306f3d7627fd251d63f8. --- clang/lib/Interpreter/IncrementalParser.cpp | 13 +++-- clang/lib/Sema/SemaDecl.cpp | 10 +++--- clang/test/Interpreter/execute.c| 21 + 3 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 clang/test/Interpreter/execute.c diff --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp index ef90fe9e6f545..5bc8385d874a1 100644 --- a/clang/lib/Interpreter/IncrementalParser.cpp +++ b/clang/lib/Interpreter/IncrementalParser.cpp @@ -387,8 +387,7 @@ std::unique_ptr IncrementalParser::GenModule() { void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { TranslationUnitDecl *MostRecentTU = PTU.TUPart; - TranslationUnitDecl *FirstTU = MostRecentTU->getFirstDecl(); - if (StoredDeclsMap *Map = FirstTU->getPrimaryContext()->getLookupPtr()) { + if (StoredDeclsMap *Map = MostRecentTU->getPrimaryContext()->getLookupPtr()) { for (auto &&[Key, List] : *Map) { DeclContextLookupResult R = List.getLookupResult(); std::vector NamedDeclsToRemove; @@ -407,6 +406,16 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { } } } + + // FIXME: We should de-allocate MostRecentTU + for (Decl *D : MostRecentTU->decls()) { +auto *ND = dyn_cast(D); +if (!ND) + continue; +// Check if we need to clean up the IdResolver chain. +if (ND->getDeclName().getFETokenInfo()) + getCI()->getSema().IdResolver.RemoveDecl(ND); + } } llvm::StringRef IncrementalParser::GetMangledName(GlobalDecl GD) const { diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index e29ddd81a3f88..521ae4467877d 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2282,9 +2282,13 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { if (LabelDecl *LD = dyn_cast(D)) CheckPoppedLabel(LD, *this, addDiag); -// Remove this name from our lexical scope, and warn on it if we haven't -// already. -IdResolver.RemoveDecl(D); +// Partial translation units that are created in incremental processing must +// not clean up the IdResolver because PTUs should take into account the +// declarations that came from previous PTUs. +if (!PP.isIncrementalProcessingEnabled()) + IdResolver.RemoveDecl(D); + +// Warn on it if we are shadowing a declaration. auto ShadowI = ShadowingDecls.find(D); if (ShadowI != ShadowingDecls.end()) { if (const auto *FD = dyn_cast(ShadowI->second)) { diff --git a/clang/test/Interpreter/execute.c b/clang/test/Interpreter/execute.c new file mode 100644 index 0..44a3a32c93011 --- /dev/null +++ b/clang/test/Interpreter/execute.c @@ -0,0 +1,21 @@ +// REQUIRES: host-supports-jit +// UNSUPPORTED: system-aix + +// RUN: cat %s | clang-repl -Xcc -xc -Xcc -Xclang -Xcc -verify | FileCheck %s +// RUN: cat %s | clang-repl -Xcc -xc -Xcc -O2 -Xcc -Xclang -Xcc -verify| FileCheck %s +int printf(const char *, ...); +int i = 42; err // expected-error{{use of undeclared identifier}} +int i = 42; +struct S { float f; struct S *m;} s = {1.0, 0}; +// FIXME: Making foo inline fails to emit the function. +int foo() { return 42; } +void run() {\ + printf("i = %d\n", i);\ + printf("S[f=%f, m=0x%llx]\n", s.f, (unsigned long long)s.m); \ + int r3 = foo(); \ +} +run(); +// CHECK: i = 42 +// CHECK-NEXT: S[f=1.00, m=0x0] + +%quit >From 3bf886259a85dc7670ff0cab2fd70f8386cd1752 Mon Sep 17 00:00:00 2001 From: Anubhab Ghosh Date: Sat, 23 Mar 2024 15:13:57 + Subject: [PATCH 2/2] [clang-repl] Support wasm execution. This commit introduces support for running clang-repl and executing C++ code interactively inside a Javascript engine using WebAssembly when built with Emscripten. This is achieved by producing WASM "shared libraries" that can be loaded by the Emscripten runtime using dlopen() More discussion is available in https://reviews.llvm.org/D158140 --- clang/lib/Interpreter/CMakeLists.txt | 6 + clang/lib/Interpreter/IncrementalExecutor.cpp | 2 + clang/lib/Interpreter/IncrementalExecutor.h | 11 +- clang/lib/Interpreter/Interpreter.cpp | 13 ++ clang/lib/Interpreter/Wasm.cpp| 114 ++ clang/lib/Interpreter/Wasm.h | 37 ++ 6 files changed, 179 insertions(+), 4 deletions(-) create mode 100644 clang/lib/Interpreter/Wasm.cpp create mode 100644
[clang] [clang-repl] Support wasm execution (PR #86402)
https://github.com/vgvassilev updated https://github.com/llvm/llvm-project/pull/86402 >From 4434ceeef152b95998ebd0a3b09a56d105490c4d Mon Sep 17 00:00:00 2001 From: Anubhab Ghosh Date: Sat, 23 Mar 2024 15:13:57 + Subject: [PATCH 1/3] [clang-repl] Support wasm execution. This commit introduces support for running clang-repl and executing C++ code interactively inside a Javascript engine using WebAssembly when built with Emscripten. This is achieved by producing WASM "shared libraries" that can be loaded by the Emscripten runtime using dlopen() More discussion is available in https://reviews.llvm.org/D158140 --- clang/lib/Interpreter/CMakeLists.txt | 1 + clang/lib/Interpreter/IncrementalExecutor.cpp | 2 + clang/lib/Interpreter/IncrementalExecutor.h | 11 +- clang/lib/Interpreter/Interpreter.cpp | 11 ++ clang/lib/Interpreter/WASM.cpp| 107 ++ clang/lib/Interpreter/WASM.h | 33 ++ 6 files changed, 161 insertions(+), 4 deletions(-) create mode 100644 clang/lib/Interpreter/WASM.cpp create mode 100644 clang/lib/Interpreter/WASM.h diff --git a/clang/lib/Interpreter/CMakeLists.txt b/clang/lib/Interpreter/CMakeLists.txt index 9065f998f73c4..a8a287edf5b04 100644 --- a/clang/lib/Interpreter/CMakeLists.txt +++ b/clang/lib/Interpreter/CMakeLists.txt @@ -20,6 +20,7 @@ add_clang_library(clangInterpreter Interpreter.cpp InterpreterUtils.cpp Value.cpp + WASM.cpp DEPENDS intrinsics_gen diff --git a/clang/lib/Interpreter/IncrementalExecutor.cpp b/clang/lib/Interpreter/IncrementalExecutor.cpp index 6f036107c14a9..1824a5b4570a9 100644 --- a/clang/lib/Interpreter/IncrementalExecutor.cpp +++ b/clang/lib/Interpreter/IncrementalExecutor.cpp @@ -36,6 +36,8 @@ LLVM_ATTRIBUTE_USED void linkComponents() { } namespace clang { +IncrementalExecutor::IncrementalExecutor(llvm::orc::ThreadSafeContext ) +: TSCtx(TSC) {} llvm::Expected> IncrementalExecutor::createDefaultJITBuilder( diff --git a/clang/lib/Interpreter/IncrementalExecutor.h b/clang/lib/Interpreter/IncrementalExecutor.h index b4347209e14fe..7954cde36588b 100644 --- a/clang/lib/Interpreter/IncrementalExecutor.h +++ b/clang/lib/Interpreter/IncrementalExecutor.h @@ -43,16 +43,19 @@ class IncrementalExecutor { llvm::DenseMap ResourceTrackers; +protected: + IncrementalExecutor(llvm::orc::ThreadSafeContext ); + public: enum SymbolNameKind { IRName, LinkerName }; IncrementalExecutor(llvm::orc::ThreadSafeContext , llvm::orc::LLJITBuilder , llvm::Error ); - ~IncrementalExecutor(); + virtual ~IncrementalExecutor(); - llvm::Error addModule(PartialTranslationUnit ); - llvm::Error removeModule(PartialTranslationUnit ); - llvm::Error runCtors() const; + virtual llvm::Error addModule(PartialTranslationUnit ); + virtual llvm::Error removeModule(PartialTranslationUnit ); + virtual llvm::Error runCtors() const; llvm::Error cleanUp(); llvm::Expected getSymbolAddress(llvm::StringRef Name, SymbolNameKind NameKind) const; diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index cf31456b6950a..7d572b20cd828 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -15,6 +15,7 @@ #include "IncrementalExecutor.h" #include "IncrementalParser.h" #include "InterpreterUtils.h" +#include "WASM.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Mangle.h" @@ -183,6 +184,12 @@ IncrementalCompilerBuilder::CreateCpp() { std::vector Argv; Argv.reserve(5 + 1 + UserArgs.size()); Argv.push_back("-xc++"); +#ifdef __EMSCRIPTEN__ + Argv.push_back("-target"); + Argv.push_back("wasm32-unknown-emscripten"); + Argv.push_back("-pie"); + Argv.push_back("-shared"); +#endif Argv.insert(Argv.end(), UserArgs.begin(), UserArgs.end()); std::string TT = TargetTriple ? *TargetTriple : llvm::sys::getProcessTriple(); @@ -400,7 +407,11 @@ llvm::Error Interpreter::CreateExecutor() { if (!JB) return JB.takeError(); llvm::Error Err = llvm::Error::success(); +#ifdef __EMSCRIPTEN__ + auto Executor = std::make_unique(*TSCtx, **JB, Err); +#else auto Executor = std::make_unique(*TSCtx, **JB, Err); +#endif if (!Err) IncrExecutor = std::move(Executor); diff --git a/clang/lib/Interpreter/WASM.cpp b/clang/lib/Interpreter/WASM.cpp new file mode 100644 index 0..d21d0ada1eafa --- /dev/null +++ b/clang/lib/Interpreter/WASM.cpp @@ -0,0 +1,107 @@ +//===- WASM.cpp - WASM Interpreter --*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// This file implements interpreter support for code execution in WebAssembly. +//
[clang] [clang-repl] Teach clang-repl how to load PCHs. (PR #94166)
@@ -0,0 +1,14 @@ +// REQUIRES: host-supports-jit +// UNSUPPORTED: system-aix + +// RUN: rm -f %t.pch +// RUN: %clang_cc1 -fmax-type-align=16 -pic-level 2 -fdeprecated-macro -stack-protector 1 -fblocks -fskip-odr-check-in-gmf -fexceptions -fcxx-exceptions -fgnuc-version=0 -triple=%target_triple -DPCH -fincremental-extensions -emit-pch -x c++-header -o %t.pch %s +// RUN: clang-repl -Xcc -fgnuc-version=0 -Xcc -triple=%target_triple -Xcc -include-pch -Xcc %t.pch '#include "%s"' | FileCheck %s vgvassilev wrote: @weliveindetail, it seems that clang-repl prefers the process triple: https://github.com/llvm/llvm-project/blob/c26a99384bce5719107d26f4617d6e3b1e9253ff/clang/lib/Interpreter/Interpreter.cpp#L188 What should we do here? Should we implement a lit version of `host-supports-jit` but `host-jit-triple`? Is there something smarter we could do? https://github.com/llvm/llvm-project/pull/94166 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Teach clang-repl how to load PCHs. (PR #94166)
https://github.com/vgvassilev created https://github.com/llvm/llvm-project/pull/94166 None >From 896f3090ca2eadf650459caee9a4106fc7dd381d Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Thu, 30 May 2024 05:05:41 + Subject: [PATCH] [clang-repl] Teach clang-repl how to load PCHs. --- clang/include/clang/CodeGen/ModuleBuilder.h | 6 ++ clang/lib/CodeGen/BackendConsumer.h | 5 - clang/lib/CodeGen/CodeGenAction.cpp | 6 +- clang/lib/CodeGen/ModuleBuilder.cpp | 8 clang/lib/Interpreter/IncrementalParser.cpp | 4 clang/test/Interpreter/execute-pch.cpp | 14 ++ 6 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 clang/test/Interpreter/execute-pch.cpp diff --git a/clang/include/clang/CodeGen/ModuleBuilder.h b/clang/include/clang/CodeGen/ModuleBuilder.h index edacd82bf899d..cb5919d1c8af5 100644 --- a/clang/include/clang/CodeGen/ModuleBuilder.h +++ b/clang/include/clang/CodeGen/ModuleBuilder.h @@ -48,6 +48,12 @@ namespace CodeGen { class CodeGenerator : public ASTConsumer { virtual void anchor(); +protected: + /// True if we've finished generating IR. This prevents us from generating + /// additional LLVM IR after emitting output in HandleTranslationUnit. This + /// can happen when Clang plugins trigger additional AST deserialization. + bool IRGenFinished = false; + public: /// Return an opaque reference to the CodeGenModule object, which can /// be used in various secondary APIs. It is valid as long as the diff --git a/clang/lib/CodeGen/BackendConsumer.h b/clang/lib/CodeGen/BackendConsumer.h index 0fe9929dca2b3..76ab5add603b7 100644 --- a/clang/lib/CodeGen/BackendConsumer.h +++ b/clang/lib/CodeGen/BackendConsumer.h @@ -41,11 +41,6 @@ class BackendConsumer : public ASTConsumer { llvm::Timer LLVMIRGeneration; unsigned LLVMIRGenerationRefCount; - /// True if we've finished generating IR. This prevents us from generating - /// additional LLVM IR after emitting output in HandleTranslationUnit. This - /// can happen when Clang plugins trigger additional AST deserialization. - bool IRGenFinished = false; - bool TimerIsEnabled = false; std::unique_ptr Gen; diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp index 6d3efdb5ffe34..6e2204d2dba0c 100644 --- a/clang/lib/CodeGen/CodeGenAction.cpp +++ b/clang/lib/CodeGen/CodeGenAction.cpp @@ -221,9 +221,7 @@ void BackendConsumer::HandleInlineFunctionDefinition(FunctionDecl *D) { } void BackendConsumer::HandleInterestingDecl(DeclGroupRef D) { - // Ignore interesting decls from the AST reader after IRGen is finished. - if (!IRGenFinished) -HandleTopLevelDecl(D); + HandleTopLevelDecl(D); } // Links each entry in LinkModules into our module. Returns true on error. @@ -285,8 +283,6 @@ void BackendConsumer::HandleTranslationUnit(ASTContext ) { if (LLVMIRGenerationRefCount == 0) LLVMIRGeneration.stopTimer(); } - -IRGenFinished = true; } // Silently ignore if we weren't initialized for some reason. diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp index df85295cfb2e2..768d2ffd2d8d9 100644 --- a/clang/lib/CodeGen/ModuleBuilder.cpp +++ b/clang/lib/CodeGen/ModuleBuilder.cpp @@ -138,6 +138,8 @@ namespace { assert(!M && "Replacing existing Module?"); M.reset(new llvm::Module(ExpandModuleName(ModuleName, CodeGenOpts), C)); + IRGenFinished = false; + std::unique_ptr OldBuilder = std::move(Builder); Initialize(*Ctx); @@ -179,6 +181,10 @@ namespace { } bool HandleTopLevelDecl(DeclGroupRef DG) override { + // Ignore interesting decls from the AST reader after IRGen is finished. + if (IRGenFinished) +return true; // We can't CodeGen more but pass to other consumers. + // FIXME: Why not return false and abort parsing? if (Diags.hasUnrecoverableErrorOccurred()) return true; @@ -282,6 +288,8 @@ namespace { } void HandleTranslationUnit(ASTContext ) override { + IRGenFinished = true; + // Release the Builder when there is no error. if (!Diags.hasUnrecoverableErrorOccurred() && Builder) Builder->Release(); diff --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp index ef90fe9e6f545..eddd4f356c5af 100644 --- a/clang/lib/Interpreter/IncrementalParser.cpp +++ b/clang/lib/Interpreter/IncrementalParser.cpp @@ -219,6 +219,10 @@ IncrementalParser::IncrementalParser(Interpreter , Consumer = >getASTConsumer(); P.reset( new Parser(CI->getPreprocessor(), CI->getSema(), /*SkipBodies=*/false)); + + if (ExternalASTSource *External = CI->getASTContext().getExternalSource()) +External->StartTranslationUnit(Consumer); + P->Initialize(); // An initial PTU is needed as CUDA includes some headers automatically diff --git
[clang] [clang-repl] Test explicit emission of dtors in runtime interface builder (NFC) (PR #89734)
Stefan =?utf-8?q?Gränitz?= , Stefan =?utf-8?q?Gränitz?= Message-ID: In-Reply-To: vgvassilev wrote: We generally have to put a switch for the late parsed templates. We have it in some other tests. https://github.com/llvm/llvm-project/pull/89734 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Introduce common fixture class in unittests (NFC) (PR #93816)
https://github.com/vgvassilev approved this pull request. LGTM! https://github.com/llvm/llvm-project/pull/93816 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Set up executor implicitly to account for init PTUs (PR #84758)
Stefan =?utf-8?q?Gränitz?= , Stefan =?utf-8?q?Gränitz?= , Stefan =?utf-8?q?Gränitz?= Message-ID: In-Reply-To: vgvassilev wrote: > > Looks like you already implemented it. Nice. > > Well, it's gonna be a bit more churn. Eventually, it will reduce coverage for > the incremental features in the frontend that are independent from the JIT. > To be honest, I don't mind because none of the targets seem relevant for me, > just wanted to point that out. We can test them in syntax-only mode. I am not too worried by that. https://github.com/llvm/llvm-project/pull/84758 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Set up executor implicitly to account for init PTUs (PR #84758)
Stefan =?utf-8?q?Gr=C3=A4nitz?= , Stefan =?utf-8?q?Gr=C3=A4nitz?= , Stefan =?utf-8?q?Gr=C3=A4nitz?= Message-ID: In-Reply-To: vgvassilev wrote: Looks like you already implemented it. Nice. https://github.com/llvm/llvm-project/pull/84758 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
vgvassilev wrote: @mysterymath, @jasonmolenda, ping -- I am still stuck in reproducing this issue. https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Set up executor implicitly to account for init PTUs (PR #84758)
Stefan =?utf-8?q?Gränitz?= , Stefan =?utf-8?q?Gränitz?= , Stefan =?utf-8?q?Gränitz?= Message-ID: In-Reply-To: vgvassilev wrote: Can we create some text fixture that will do that automatically for us and reduce this copy-paste? https://github.com/llvm/llvm-project/pull/84758 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Set up executor implicitly to account for init PTUs (PR #84758)
Stefan =?utf-8?q?Gränitz?= , Stefan =?utf-8?q?Gränitz?= , Stefan =?utf-8?q?Gränitz?= Message-ID: In-Reply-To: vgvassilev wrote: I am not sure how this patch changed these tests to start failing on Windows. Do you have any clue? https://github.com/llvm/llvm-project/pull/84758 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Set up executor implicitly to account for init PTUs (PR #84758)
Stefan =?utf-8?q?Gr=C3=A4nitz?= , Stefan =?utf-8?q?Gr=C3=A4nitz?= , Stefan =?utf-8?q?Gr=C3=A4nitz?= Message-ID: In-Reply-To: vgvassilev wrote: What do you mean? https://github.com/llvm/llvm-project/pull/84758 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Set up executor implicitly to account for init PTUs (PR #84758)
Stefan =?utf-8?q?Gränitz?= , Stefan =?utf-8?q?Gränitz?= , Stefan =?utf-8?q?Gränitz?= Message-ID: In-Reply-To: https://github.com/vgvassilev updated https://github.com/llvm/llvm-project/pull/84758 >From 917e4e0e07c5a312543732d6101742e709a6b429 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Gr=C3=A4nitz?= Date: Sun, 10 Mar 2024 18:17:48 +0100 Subject: [PATCH 1/4] [clang-repl] Set up executor implicitly to account for init PTUs --- clang/lib/Interpreter/Interpreter.cpp | 32 +++ clang/test/Interpreter/execute.cpp| 4 ++-- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index b20e6efcebfd1..7bd44f8e046c0 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -229,12 +229,30 @@ IncrementalCompilerBuilder::CreateCudaHost() { } Interpreter::Interpreter(std::unique_ptr CI, - llvm::Error ) { - llvm::ErrorAsOutParameter EAO(); + llvm::Error ) { + llvm::ErrorAsOutParameter EAO(); auto LLVMCtx = std::make_unique(); TSCtx = std::make_unique(std::move(LLVMCtx)); - IncrParser = std::make_unique(*this, std::move(CI), - *TSCtx->getContext(), Err); + IncrParser = std::make_unique( + *this, std::move(CI), *TSCtx->getContext(), ErrOut); + if (ErrOut) +return; + + // Not all frontends support code-generation, e.g. ast-dump actions don't + if (IncrParser->getCodeGen()) { +if (llvm::Error Err = CreateExecutor()) { + ErrOut = joinErrors(std::move(ErrOut), std::move(Err)); + return; +} + +// Process the PTUs that came from initialization. For example -include will +// give us a header that's processed at initialization of the preprocessor. +for (PartialTranslationUnit : IncrParser->getPTUs()) + if (llvm::Error Err = Execute(PTU)) { +ErrOut = joinErrors(std::move(ErrOut), std::move(Err)); +return; + } + } } Interpreter::~Interpreter() { @@ -395,10 +413,16 @@ llvm::Error Interpreter::CreateExecutor() { return llvm::make_error("Operation failed. " "Execution engine exists", std::error_code()); + if (!IncrParser->getCodeGen()) +return llvm::make_error("Operation failed. " + "No code generator available", + std::error_code()); + llvm::Expected> JB = CreateJITBuilder(*getCompilerInstance()); if (!JB) return JB.takeError(); + llvm::Error Err = llvm::Error::success(); auto Executor = std::make_unique(*TSCtx, **JB, Err); if (!Err) diff --git a/clang/test/Interpreter/execute.cpp b/clang/test/Interpreter/execute.cpp index 6e73ed3927e81..534a54ed94fba 100644 --- a/clang/test/Interpreter/execute.cpp +++ b/clang/test/Interpreter/execute.cpp @@ -7,6 +7,8 @@ // RUN: cat %s | clang-repl | FileCheck %s // RUN: cat %s | clang-repl -Xcc -O2 | FileCheck %s +// RUN: clang-repl -Xcc -include -Xcc %s | FileCheck %s +// RUN: clang-repl -Xcc -fsyntax-only -Xcc -include -Xcc %s extern "C" int printf(const char *, ...); int i = 42; auto r1 = printf("i = %d\n", i); @@ -19,5 +21,3 @@ auto r2 = printf("S[f=%f, m=0x%llx]\n", s.f, reinterpret_castFrom 3f61ec08491d871fb6bc9c1cc03f26c33dd1df48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Gr=C3=A4nitz?= Date: Mon, 11 Mar 2024 14:10:58 +0100 Subject: [PATCH 2/4] [tmp] Add crash note --- clang/test/Interpreter/inline-virtual.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/Interpreter/inline-virtual.cpp b/clang/test/Interpreter/inline-virtual.cpp index 79ab8ed337ffe..d862b3354f61f 100644 --- a/clang/test/Interpreter/inline-virtual.cpp +++ b/clang/test/Interpreter/inline-virtual.cpp @@ -14,7 +14,7 @@ struct A { int a; A(int a) : a(a) {} virtual ~A(); }; // PartialTranslationUnit. inline A::~A() { printf("~A(%d)\n", a); } -// Create one instance with new and delete it. +// Create one instance with new and delete it. We crash here now: A *a1 = new A(1); delete a1; // CHECK: ~A(1) >From 8b3c341480d3f3642a2c0b25456fb242523f4a1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Gr=C3=A4nitz?= Date: Mon, 22 Apr 2024 14:24:33 +0200 Subject: [PATCH 3/4] [wip] Fix unittests and highlight CreateJITBuilder() issue The test for CreateJITBuilder() now fails with: ``` [ RUN ] InterpreterExtensionsTest.CustomCrossJIT /home/ez/Develop/llvm-project/clang/unittests/Interpreter/InterpreterExtensionsTest.cpp:254: Failure Expected: (JIT) != (nullptr), actual: NULL vs (nullptr) ``` --- .../Interpreter/InterpreterExtensionsTest.cpp | 34 +-- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/clang/unittests/Interpreter/InterpreterExtensionsTest.cpp
[clang] [clang-repl] Set up executor implicitly to account for init PTUs (PR #84758)
Stefan =?utf-8?q?Gr=C3=A4nitz?= , Stefan =?utf-8?q?Gr=C3=A4nitz?= , Stefan =?utf-8?q?Gr=C3=A4nitz?= Message-ID: In-Reply-To: vgvassilev wrote: @weliveindetail, I was wondering what's the fate of this patch? https://github.com/llvm/llvm-project/pull/84758 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
vgvassilev wrote: > Just found out this keeps popping up from my notification, and I would like > give my 2 cents, maybe can provide some insights: > > Looking at the backtrace of the failing tests, I noticed we ran into > `clang::Parser::ParseTopLevelStmtDecl()` which makes me very confused. Do we > actually enable the incremental extension in lldb? I grep it in lldb codebase > and the only occurrence is here > > https://github.com/llvm/llvm-project/blob/b91b8fea8c58e9b414e291df677b12ca44197784/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp#L662 Hm, ok. I remember some discussions revolving around this but got the impression lldb turns that off. I think having it on is the right thing to do but that explains why my workaround did not work. > > The other thing I noticed is that the failure looks like have something to do > with the objc, can we also check the current language we're compiling when > skipping removing the name for the lexical scope? I am hoping to cover objc, too. That's why I am really interested in figuring out what is going on. Otherwise if we limit the feature to c/c++ maybe we will get away with the bot. I still want to see why it crashes though... https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
vgvassilev wrote: > fwiw if you have access to a mac, I don't think it's hard to build > lldb+clang? I have swig, cmake, and ninja installed on my mac via homebrew. > > ``` > lldb/scripts/macos-setup-codesign.sh > > mkdir build > cd build > cmake ../llvm -G Ninja -DLLDB_ENABLE_SWIFT_SUPPORT=0 > -DPython3_EXECUTABLE=/usr/bin/python3 -DCMAKE_BUILD_TYPE=Debug > -DLLVM_ENABLE_ASSERTIONS=1 -DLLVM_ENABLE_PROJECTS='llvm;lldb;clang' > '-DLLVM_ENABLE_RUNTIMES=libcxx;libcxxabi;libunwind' -DLLDB_ENABLE_PYTHON=1 > -DLLDB_ENABLE_LUA=0 > > ninja lldb > bin/lldb-dotest -p TestImportBuiltinFileID.py > ``` Does not seem to be reproducing it for me: ``` builds/llvm-project$ bin/lldb-dotest -p TestImportBuiltinFileID.py /Applications/Xcode.app/Contents/Developer/usr/bin/python3 /Users/vvassilev/workspace/sources/llvm-project/lldb/test/API/dotest.py --arch x86_64 --build-dir /Users/vvassilev/workspace/builds/llvm-project/lldb-test-build.noindex --executable /Users/vvassilev/workspace/builds/llvm-project/./bin/lldb --compiler /Users/vvassilev/workspace/builds/llvm-project/./bin/clang --dsymutil /Users/vvassilev/workspace/builds/llvm-project/./bin/dsymutil --lldb-libs-dir /Users/vvassilev/workspace/builds/llvm-project/./lib --llvm-tools-dir /Users/vvassilev/workspace/builds/llvm-project/./bin --libcxx-include-dir /Users/vvassilev/workspace/builds/llvm-project/include/c++/v1 --libcxx-library-dir /Users/vvassilev/workspace/builds/llvm-project/lib --lldb-obj-root /Users/vvassilev/workspace/builds/llvm-project/tools/lldb -p TestImportBuiltinFileID.py lldb version 19.0.0git (g...@github.com:llvm/llvm-project.git revision 253c28fa829cee0104c2fc59ed1a958980b5138c) clang revision 253c28fa829cee0104c2fc59ed1a958980b5138c llvm revision 253c28fa829cee0104c2fc59ed1a958980b5138c Skipping the following test categories: ['libstdcxx', 'dwo', 'llgs', 'fork'] PASS: LLDB (/Users/vvassilev/workspace/builds/llvm-project/bin/clang-x86_64) :: test_import_builtin_fileid_gmodules (TestImportBuiltinFileID.TestImportBuiltinFileID) -- Ran 1 test in 52.311s OK ``` https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
vgvassilev wrote: Ok, maybe I can you test this patch for a temporary fix until we figure out what's going wrong. ```diff diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 7f6921ea22be..d771a060f305 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2285,7 +2285,7 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { // Partial translation units that are created in incremental processing must // not clean up the IdResolver because PTUs should take into account the // declarations that came from previous PTUs. -if (!PP.isIncrementalProcessingEnabled()) +if (!PP.isIncrementalProcessingEnabled() && !getLangOpts().IncrementalExtensions) IdResolver.RemoveDecl(D); // Warn on it if we are shadowing a declaration. ``` https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
vgvassilev wrote: > I was able to verify that the revert fixed the tests at least. I am pretty sure that the failure ha to do with the incremental processing if-stmt in SemaDecl. I can provide a fix that does not trigger this for lldb but that would be a workaround. I suspect that change uncovers some inconsistency in either clang or lldb which I think we should fix. https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
vgvassilev wrote: > > @jasonmolenda, I am stuck. I could not find how the bot configures llvm and > > lldb. I built lldb and ran `make check-lldb` but did not fail in the same > > way. Can you provide a recipe to reproduce the failure? > > For some reason it only fails on our Mac LLDB builders, and not our Linux > ones. Our LLDB configuration is also quite tortured I'm afraid; it's > difficult to reproduce locally. I'm not sure whether this issue would be seen > on a clean Mac build; it seems like it might be some kind of pointer > Heisenbug or something. I can definitely test a candidate fix, but that's > about it. I tried on a mac machine. Can I get access to that bot then? https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
vgvassilev wrote: @jasonmolenda, I am stuck. I could not find how the bot configures llvm and lldb. I built lldb and ran `make check-lldb` but did not fail in the same way. Can you provide a recipe to reproduce the failure? https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
vgvassilev wrote: > I reverted in > > ``` > commit dfdf1c5fe45a82b9c578306f3d7627fd251d63f8 > Author: Jason Molenda > Date: Tue May 21 18:00:11 2024 -0700 > > Revert "[clang-repl] Extend the C support. (#89804)" > > This reverts commit 253c28fa829cee0104c2fc59ed1a958980b5138c. > ``` > > to unblock the CI bots until Vassil has a chance to look at it. Thank you! I suspect that this is due to the changes in SemaDecl.cpp (https://github.com/llvm/llvm-project/pull/89804/files#diff-edac6256ac508912a16d0165b2f8cf37123dc2f40a147dca49a34c33f1db13ddR2288) I am trying to build lldb but if you have a hint how to reproduce it outside lldb would be great! https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Lay the foundation of pretty printing for C. (PR #89811)
vgvassilev wrote: > LGTM, feel free to apply my suggestion if you like it. Applied it. Thanks for the review this unblock whole bunch of work for us.. https://github.com/llvm/llvm-project/pull/89811 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Lay the foundation of pretty printing for C. (PR #89811)
@@ -269,7 +267,10 @@ const char *const Runtimes = R"( void __clang_Interpreter_SetValueCopyArr(const T (*Src)[N], void* Placement, unsigned long Size) { __clang_Interpreter_SetValueCopyArr(Src[0], Placement, Size); } +extern "C" vgvassilev wrote: Done. https://github.com/llvm/llvm-project/pull/89811 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Lay the foundation of pretty printing for C. (PR #89811)
https://github.com/vgvassilev updated https://github.com/llvm/llvm-project/pull/89811 >From 0ff8aca868bfd78d4bcfd31f299e253e83c150a2 Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Tue, 23 Apr 2024 19:33:00 + Subject: [PATCH] [clang-repl] Lay the foundation of pretty printing for C. --- clang/lib/Interpreter/Interpreter.cpp | 170 ++ clang/lib/Parse/ParseStmt.cpp | 5 +- clang/test/Interpreter/pretty-print.c | 8 ++ 3 files changed, 103 insertions(+), 80 deletions(-) create mode 100644 clang/test/Interpreter/pretty-print.c diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index b20e6efcebfd1..4aa0491731484 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -42,6 +42,9 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/Host.h" + +#include + using namespace clang; // FIXME: Figure out how to unify with namespace init_convenience from @@ -250,14 +253,10 @@ Interpreter::~Interpreter() { // can't find the precise resource directory in unittests so we have to hard // code them. const char *const Runtimes = R"( +#define __CLANG_REPL__ 1 #ifdef __cplusplus +#define EXTERN_C extern "C" void *__clang_Interpreter_SetValueWithAlloc(void*, void*, void*); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, void*); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, float); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, double); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, long double); -void __clang_Interpreter_SetValueNoAlloc(void*,void*,void*,unsigned long long); struct __clang_Interpreter_NewTag{} __ci_newtag; void* operator new(__SIZE_TYPE__, void* __p, __clang_Interpreter_NewTag) noexcept; template @@ -269,7 +268,11 @@ const char *const Runtimes = R"( void __clang_Interpreter_SetValueCopyArr(const T (*Src)[N], void* Placement, unsigned long Size) { __clang_Interpreter_SetValueCopyArr(Src[0], Placement, Size); } +#else +#define EXTERN_C extern #endif // __cplusplus + + EXTERN_C void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, ...); )"; llvm::Expected> @@ -564,15 +567,17 @@ std::unique_ptr Interpreter::FindRuntimeInterface() { if (!LookupInterface(ValuePrintingInfo[NoAlloc], MagicRuntimeInterface[NoAlloc])) return nullptr; - if (!LookupInterface(ValuePrintingInfo[WithAlloc], - MagicRuntimeInterface[WithAlloc])) -return nullptr; - if (!LookupInterface(ValuePrintingInfo[CopyArray], - MagicRuntimeInterface[CopyArray])) -return nullptr; - if (!LookupInterface(ValuePrintingInfo[NewTag], - MagicRuntimeInterface[NewTag])) -return nullptr; + if (Ctx.getLangOpts().CPlusPlus) { +if (!LookupInterface(ValuePrintingInfo[WithAlloc], + MagicRuntimeInterface[WithAlloc])) + return nullptr; +if (!LookupInterface(ValuePrintingInfo[CopyArray], + MagicRuntimeInterface[CopyArray])) + return nullptr; +if (!LookupInterface(ValuePrintingInfo[NewTag], + MagicRuntimeInterface[NewTag])) + return nullptr; + } return createInProcessRuntimeInterfaceBuilder(*this, Ctx, S); } @@ -831,69 +836,82 @@ __clang_Interpreter_SetValueWithAlloc(void *This, void *OutVal, return VRef.getPtr(); } -// Pointers, lvalue struct that can take as a reference. -REPL_EXTERNAL_VISIBILITY void -__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, -void *Val) { - Value = *(Value *)OutVal; - VRef = Value(static_cast(This), OpaqueType); - VRef.setPtr(Val); -} - -REPL_EXTERNAL_VISIBILITY void -__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, -void *OpaqueType) { +REPL_EXTERNAL_VISIBILITY +extern "C" void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, +void *OpaqueType, ...) { Value = *(Value *)OutVal; - VRef = Value(static_cast(This), OpaqueType); -} - -static void SetValueDataBasedOnQualType(Value , unsigned long long Data) { - QualType QT = V.getType(); - if (const auto *ET = QT->getAs()) -QT = ET->getDecl()->getIntegerType(); - - switch (QT->castAs()->getKind()) { - default: -llvm_unreachable("unknown type kind!"); -#define X(type, name) \ - case BuiltinType::name: \ -V.set##name(Data); \ -break; -REPL_BUILTIN_TYPES -#undef X +
[clang] [clang-repl] Lay the foundation of pretty printing for C. (PR #89811)
vgvassilev wrote: > Generally looks good, but it seems that some parts of this PR are also > incorporated into another PR, so it's a bit hard to review. Rebased, should be only the commit in question now, as the other one landed. https://github.com/llvm/llvm-project/pull/89811 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Lay the foundation of pretty printing for C. (PR #89811)
@@ -42,6 +42,9 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/Host.h" + +#include vgvassilev wrote: Fixed. https://github.com/llvm/llvm-project/pull/89811 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Lay the foundation of pretty printing for C. (PR #89811)
https://github.com/vgvassilev updated https://github.com/llvm/llvm-project/pull/89811 >From 3e922935bc551dd5c3f76dae22a94318d0abd210 Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Tue, 23 Apr 2024 19:33:00 + Subject: [PATCH] [clang-repl] Lay the foundation of pretty printing for C. --- clang/lib/Interpreter/Interpreter.cpp | 168 ++ clang/lib/Parse/ParseStmt.cpp | 5 +- clang/test/Interpreter/pretty-print.c | 8 ++ 3 files changed, 101 insertions(+), 80 deletions(-) create mode 100644 clang/test/Interpreter/pretty-print.c diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index b20e6efcebfd1..3e94b963be714 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -42,6 +42,9 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/Host.h" + +#include + using namespace clang; // FIXME: Figure out how to unify with namespace init_convenience from @@ -250,14 +253,9 @@ Interpreter::~Interpreter() { // can't find the precise resource directory in unittests so we have to hard // code them. const char *const Runtimes = R"( +#define __CLANG_REPL__ 1 #ifdef __cplusplus void *__clang_Interpreter_SetValueWithAlloc(void*, void*, void*); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, void*); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, float); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, double); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, long double); -void __clang_Interpreter_SetValueNoAlloc(void*,void*,void*,unsigned long long); struct __clang_Interpreter_NewTag{} __ci_newtag; void* operator new(__SIZE_TYPE__, void* __p, __clang_Interpreter_NewTag) noexcept; template @@ -269,7 +267,10 @@ const char *const Runtimes = R"( void __clang_Interpreter_SetValueCopyArr(const T (*Src)[N], void* Placement, unsigned long Size) { __clang_Interpreter_SetValueCopyArr(Src[0], Placement, Size); } +extern "C" #endif // __cplusplus + + void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, ...); )"; llvm::Expected> @@ -564,15 +565,17 @@ std::unique_ptr Interpreter::FindRuntimeInterface() { if (!LookupInterface(ValuePrintingInfo[NoAlloc], MagicRuntimeInterface[NoAlloc])) return nullptr; - if (!LookupInterface(ValuePrintingInfo[WithAlloc], - MagicRuntimeInterface[WithAlloc])) -return nullptr; - if (!LookupInterface(ValuePrintingInfo[CopyArray], - MagicRuntimeInterface[CopyArray])) -return nullptr; - if (!LookupInterface(ValuePrintingInfo[NewTag], - MagicRuntimeInterface[NewTag])) -return nullptr; + if (Ctx.getLangOpts().CPlusPlus) { +if (!LookupInterface(ValuePrintingInfo[WithAlloc], + MagicRuntimeInterface[WithAlloc])) + return nullptr; +if (!LookupInterface(ValuePrintingInfo[CopyArray], + MagicRuntimeInterface[CopyArray])) + return nullptr; +if (!LookupInterface(ValuePrintingInfo[NewTag], + MagicRuntimeInterface[NewTag])) + return nullptr; + } return createInProcessRuntimeInterfaceBuilder(*this, Ctx, S); } @@ -831,69 +834,82 @@ __clang_Interpreter_SetValueWithAlloc(void *This, void *OutVal, return VRef.getPtr(); } -// Pointers, lvalue struct that can take as a reference. -REPL_EXTERNAL_VISIBILITY void -__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, -void *Val) { - Value = *(Value *)OutVal; - VRef = Value(static_cast(This), OpaqueType); - VRef.setPtr(Val); -} - -REPL_EXTERNAL_VISIBILITY void -__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, -void *OpaqueType) { +REPL_EXTERNAL_VISIBILITY +extern "C" void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, +void *OpaqueType, ...) { Value = *(Value *)OutVal; - VRef = Value(static_cast(This), OpaqueType); -} - -static void SetValueDataBasedOnQualType(Value , unsigned long long Data) { - QualType QT = V.getType(); - if (const auto *ET = QT->getAs()) -QT = ET->getDecl()->getIntegerType(); - - switch (QT->castAs()->getKind()) { - default: -llvm_unreachable("unknown type kind!"); -#define X(type, name) \ - case BuiltinType::name: \ -V.set##name(Data); \ -break; -REPL_BUILTIN_TYPES -#undef X + Interpreter *I = static_cast(This); + VRef = Value(I,
[clang] [clang-repl] Lay the foundation of pretty printing for C. (PR #89811)
https://github.com/vgvassilev updated https://github.com/llvm/llvm-project/pull/89811 >From 4a73cd3c3daca1cb1856a8e175dc9cb531ca Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Tue, 23 Apr 2024 19:33:00 + Subject: [PATCH] [clang-repl] Lay the foundation of pretty printing for C. --- clang/lib/Interpreter/Interpreter.cpp | 168 ++ clang/lib/Parse/ParseStmt.cpp | 5 +- clang/test/Interpreter/pretty-print.c | 8 ++ 3 files changed, 101 insertions(+), 80 deletions(-) create mode 100644 clang/test/Interpreter/pretty-print.c diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index b20e6efcebfd1..96abf4bc53ef4 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -42,6 +42,9 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/Host.h" + +#include + using namespace clang; // FIXME: Figure out how to unify with namespace init_convenience from @@ -250,14 +253,9 @@ Interpreter::~Interpreter() { // can't find the precise resource directory in unittests so we have to hard // code them. const char *const Runtimes = R"( +#define __CLANG_REPL__ 1 #ifdef __cplusplus void *__clang_Interpreter_SetValueWithAlloc(void*, void*, void*); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, void*); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, float); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, double); -void __clang_Interpreter_SetValueNoAlloc(void*, void*, void*, long double); -void __clang_Interpreter_SetValueNoAlloc(void*,void*,void*,unsigned long long); struct __clang_Interpreter_NewTag{} __ci_newtag; void* operator new(__SIZE_TYPE__, void* __p, __clang_Interpreter_NewTag) noexcept; template @@ -269,7 +267,10 @@ const char *const Runtimes = R"( void __clang_Interpreter_SetValueCopyArr(const T (*Src)[N], void* Placement, unsigned long Size) { __clang_Interpreter_SetValueCopyArr(Src[0], Placement, Size); } +extern "C" #endif // __cplusplus + + void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, ...); )"; llvm::Expected> @@ -564,15 +565,17 @@ std::unique_ptr Interpreter::FindRuntimeInterface() { if (!LookupInterface(ValuePrintingInfo[NoAlloc], MagicRuntimeInterface[NoAlloc])) return nullptr; - if (!LookupInterface(ValuePrintingInfo[WithAlloc], - MagicRuntimeInterface[WithAlloc])) -return nullptr; - if (!LookupInterface(ValuePrintingInfo[CopyArray], - MagicRuntimeInterface[CopyArray])) -return nullptr; - if (!LookupInterface(ValuePrintingInfo[NewTag], - MagicRuntimeInterface[NewTag])) -return nullptr; + if (Ctx.getLangOpts().CPlusPlus) { +if (!LookupInterface(ValuePrintingInfo[WithAlloc], + MagicRuntimeInterface[WithAlloc])) + return nullptr; +if (!LookupInterface(ValuePrintingInfo[CopyArray], + MagicRuntimeInterface[CopyArray])) + return nullptr; +if (!LookupInterface(ValuePrintingInfo[NewTag], + MagicRuntimeInterface[NewTag])) + return nullptr; + } return createInProcessRuntimeInterfaceBuilder(*this, Ctx, S); } @@ -831,69 +834,82 @@ __clang_Interpreter_SetValueWithAlloc(void *This, void *OutVal, return VRef.getPtr(); } -// Pointers, lvalue struct that can take as a reference. -REPL_EXTERNAL_VISIBILITY void -__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, -void *Val) { - Value = *(Value *)OutVal; - VRef = Value(static_cast(This), OpaqueType); - VRef.setPtr(Val); -} - -REPL_EXTERNAL_VISIBILITY void -__clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, -void *OpaqueType) { +REPL_EXTERNAL_VISIBILITY +extern "C" void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, +void *OpaqueType, ...) { Value = *(Value *)OutVal; - VRef = Value(static_cast(This), OpaqueType); -} - -static void SetValueDataBasedOnQualType(Value , unsigned long long Data) { - QualType QT = V.getType(); - if (const auto *ET = QT->getAs()) -QT = ET->getDecl()->getIntegerType(); - - switch (QT->castAs()->getKind()) { - default: -llvm_unreachable("unknown type kind!"); -#define X(type, name) \ - case BuiltinType::name: \ -V.set##name(Data); \ -break; -REPL_BUILTIN_TYPES -#undef X + Interpreter *I = static_cast(This); + VRef = Value(I,
[clang] [clang-repl] Extend the C support. (PR #89804)
https://github.com/vgvassilev closed https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
vgvassilev wrote: The failures on windows are due to "out of heap" error. Let's land this to test on the "real" bots. https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
@@ -407,6 +406,16 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { } } } + + // FIXME: We should de-allocate MostRecentTU + for (Decl *D : MostRecentTU->decls()) { +auto *ND = dyn_cast(D); +if (!ND) + continue; +// Check if we need to clean up the IdResolver chain. +if (ND->getDeclName().getFETokenInfo()) vgvassilev wrote: It always good to take rather than leave ;) I haven't got used to this syntax and I'd leave it :( https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
https://github.com/vgvassilev updated https://github.com/llvm/llvm-project/pull/89804 >From 0621608c575d9e4f7da5b08db143dbe88a45745a Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Tue, 23 Apr 2024 18:07:06 + Subject: [PATCH] [clang-repl] Extend the C support. The IdResolver chain is the main way for C to implement lookup rules. Every new partial translation unit caused clang to exit the top-most scope which in turn cleaned up the IdResolver chain. That was not an issue for C++ because its lookup is implemented on the level of declaration contexts. This patch keeps the IdResolver chain across partial translation units maintaining proper C-style lookup infrastructure. --- clang/lib/Interpreter/IncrementalParser.cpp | 13 +++-- clang/lib/Sema/SemaDecl.cpp | 10 +++--- clang/test/Interpreter/execute.c| 21 + 3 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 clang/test/Interpreter/execute.c diff --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp index ef90fe9e6f545..5bc8385d874a1 100644 --- a/clang/lib/Interpreter/IncrementalParser.cpp +++ b/clang/lib/Interpreter/IncrementalParser.cpp @@ -387,8 +387,7 @@ std::unique_ptr IncrementalParser::GenModule() { void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { TranslationUnitDecl *MostRecentTU = PTU.TUPart; - TranslationUnitDecl *FirstTU = MostRecentTU->getFirstDecl(); - if (StoredDeclsMap *Map = FirstTU->getPrimaryContext()->getLookupPtr()) { + if (StoredDeclsMap *Map = MostRecentTU->getPrimaryContext()->getLookupPtr()) { for (auto &&[Key, List] : *Map) { DeclContextLookupResult R = List.getLookupResult(); std::vector NamedDeclsToRemove; @@ -407,6 +406,16 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { } } } + + // FIXME: We should de-allocate MostRecentTU + for (Decl *D : MostRecentTU->decls()) { +auto *ND = dyn_cast(D); +if (!ND) + continue; +// Check if we need to clean up the IdResolver chain. +if (ND->getDeclName().getFETokenInfo()) + getCI()->getSema().IdResolver.RemoveDecl(ND); + } } llvm::StringRef IncrementalParser::GetMangledName(GlobalDecl GD) const { diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 6764a979168d6..7f6921ea22be1 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2282,9 +2282,13 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { if (LabelDecl *LD = dyn_cast(D)) CheckPoppedLabel(LD, *this, addDiag); -// Remove this name from our lexical scope, and warn on it if we haven't -// already. -IdResolver.RemoveDecl(D); +// Partial translation units that are created in incremental processing must +// not clean up the IdResolver because PTUs should take into account the +// declarations that came from previous PTUs. +if (!PP.isIncrementalProcessingEnabled()) + IdResolver.RemoveDecl(D); + +// Warn on it if we are shadowing a declaration. auto ShadowI = ShadowingDecls.find(D); if (ShadowI != ShadowingDecls.end()) { if (const auto *FD = dyn_cast(ShadowI->second)) { diff --git a/clang/test/Interpreter/execute.c b/clang/test/Interpreter/execute.c new file mode 100644 index 0..44a3a32c93011 --- /dev/null +++ b/clang/test/Interpreter/execute.c @@ -0,0 +1,21 @@ +// REQUIRES: host-supports-jit +// UNSUPPORTED: system-aix + +// RUN: cat %s | clang-repl -Xcc -xc -Xcc -Xclang -Xcc -verify | FileCheck %s +// RUN: cat %s | clang-repl -Xcc -xc -Xcc -O2 -Xcc -Xclang -Xcc -verify| FileCheck %s +int printf(const char *, ...); +int i = 42; err // expected-error{{use of undeclared identifier}} +int i = 42; +struct S { float f; struct S *m;} s = {1.0, 0}; +// FIXME: Making foo inline fails to emit the function. +int foo() { return 42; } +void run() {\ + printf("i = %d\n", i);\ + printf("S[f=%f, m=0x%llx]\n", s.f, (unsigned long long)s.m); \ + int r3 = foo(); \ +} +run(); +// CHECK: i = 42 +// CHECK-NEXT: S[f=1.00, m=0x0] + +%quit ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
vgvassilev wrote: The bots fail on windows due to `TEST 'Clang :: CoverageMapping/mcdc-system-headers.cpp' FAILED` which does not seem related to this PR. https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
https://github.com/vgvassilev updated https://github.com/llvm/llvm-project/pull/89804 >From 7acf367f2bd36409bcbb7443451ec83188ab589d Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Tue, 23 Apr 2024 18:07:06 + Subject: [PATCH] [clang-repl] Extend the C support. The IdResolver chain is the main way for C to implement lookup rules. Every new partial translation unit caused clang to exit the top-most scope which in turn cleaned up the IdResolver chain. That was not an issue for C++ because its lookup is implemented on the level of declaration contexts. This patch keeps the IdResolver chain across partial translation units maintaining proper C-style lookup infrastructure. --- clang/lib/Interpreter/IncrementalParser.cpp | 13 +++-- clang/lib/Sema/SemaDecl.cpp | 10 +++--- clang/test/Interpreter/execute.c| 21 + 3 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 clang/test/Interpreter/execute.c diff --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp index ef90fe9e6f545..5bc8385d874a1 100644 --- a/clang/lib/Interpreter/IncrementalParser.cpp +++ b/clang/lib/Interpreter/IncrementalParser.cpp @@ -387,8 +387,7 @@ std::unique_ptr IncrementalParser::GenModule() { void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { TranslationUnitDecl *MostRecentTU = PTU.TUPart; - TranslationUnitDecl *FirstTU = MostRecentTU->getFirstDecl(); - if (StoredDeclsMap *Map = FirstTU->getPrimaryContext()->getLookupPtr()) { + if (StoredDeclsMap *Map = MostRecentTU->getPrimaryContext()->getLookupPtr()) { for (auto &&[Key, List] : *Map) { DeclContextLookupResult R = List.getLookupResult(); std::vector NamedDeclsToRemove; @@ -407,6 +406,16 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { } } } + + // FIXME: We should de-allocate MostRecentTU + for (Decl *D : MostRecentTU->decls()) { +auto *ND = dyn_cast(D); +if (!ND) + continue; +// Check if we need to clean up the IdResolver chain. +if (ND->getDeclName().getFETokenInfo()) + getCI()->getSema().IdResolver.RemoveDecl(ND); + } } llvm::StringRef IncrementalParser::GetMangledName(GlobalDecl GD) const { diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 557fe10619c35..2dbf2ae64b436 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2282,9 +2282,13 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { if (LabelDecl *LD = dyn_cast(D)) CheckPoppedLabel(LD, *this, addDiag); -// Remove this name from our lexical scope, and warn on it if we haven't -// already. -IdResolver.RemoveDecl(D); +// Partial translation units that are created in incremental processing must +// not clean up the IdResolver because PTUs should take into account the +// declarations that came from previous PTUs. +if (!PP.isIncrementalProcessingEnabled()) + IdResolver.RemoveDecl(D); + +// Warn on it if we are shadowing a declaration. auto ShadowI = ShadowingDecls.find(D); if (ShadowI != ShadowingDecls.end()) { if (const auto *FD = dyn_cast(ShadowI->second)) { diff --git a/clang/test/Interpreter/execute.c b/clang/test/Interpreter/execute.c new file mode 100644 index 0..44a3a32c93011 --- /dev/null +++ b/clang/test/Interpreter/execute.c @@ -0,0 +1,21 @@ +// REQUIRES: host-supports-jit +// UNSUPPORTED: system-aix + +// RUN: cat %s | clang-repl -Xcc -xc -Xcc -Xclang -Xcc -verify | FileCheck %s +// RUN: cat %s | clang-repl -Xcc -xc -Xcc -O2 -Xcc -Xclang -Xcc -verify| FileCheck %s +int printf(const char *, ...); +int i = 42; err // expected-error{{use of undeclared identifier}} +int i = 42; +struct S { float f; struct S *m;} s = {1.0, 0}; +// FIXME: Making foo inline fails to emit the function. +int foo() { return 42; } +void run() {\ + printf("i = %d\n", i);\ + printf("S[f=%f, m=0x%llx]\n", s.f, (unsigned long long)s.m); \ + int r3 = foo(); \ +} +run(); +// CHECK: i = 42 +// CHECK-NEXT: S[f=1.00, m=0x0] + +%quit ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
@@ -2282,7 +2282,8 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { // Remove this name from our lexical scope, and warn on it if we haven't // already. -IdResolver.RemoveDecl(D); +if (!PP.isIncrementalProcessingEnabled()) + IdResolver.RemoveDecl(D); vgvassilev wrote: Added a comment. https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
https://github.com/vgvassilev updated https://github.com/llvm/llvm-project/pull/89804 >From 72d655c919ae29f83f1a39db2a63aa5468fb52cc Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Tue, 23 Apr 2024 18:07:06 + Subject: [PATCH] [clang-repl] Extend the C support. The IdResolver chain is the main way for C to implement lookup rules. Every new partial translation unit caused clang to exit the top-most scope which in turn cleaned up the IdResolver chain. That was not an issue for C++ because its lookup is implemented on the level of declaration contexts. This patch keeps the IdResolver chain across partial translation units maintaining proper C-style lookup infrastructure. --- clang/lib/Interpreter/IncrementalParser.cpp | 13 +++-- clang/lib/Sema/SemaDecl.cpp | 10 +++--- clang/test/Interpreter/execute.c| 21 + 3 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 clang/test/Interpreter/execute.c diff --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp index ef90fe9e6f545..5bc8385d874a1 100644 --- a/clang/lib/Interpreter/IncrementalParser.cpp +++ b/clang/lib/Interpreter/IncrementalParser.cpp @@ -387,8 +387,7 @@ std::unique_ptr IncrementalParser::GenModule() { void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { TranslationUnitDecl *MostRecentTU = PTU.TUPart; - TranslationUnitDecl *FirstTU = MostRecentTU->getFirstDecl(); - if (StoredDeclsMap *Map = FirstTU->getPrimaryContext()->getLookupPtr()) { + if (StoredDeclsMap *Map = MostRecentTU->getPrimaryContext()->getLookupPtr()) { for (auto &&[Key, List] : *Map) { DeclContextLookupResult R = List.getLookupResult(); std::vector NamedDeclsToRemove; @@ -407,6 +406,16 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { } } } + + // FIXME: We should de-allocate MostRecentTU + for (Decl *D : MostRecentTU->decls()) { +auto *ND = dyn_cast(D); +if (!ND) + continue; +// Check if we need to clean up the IdResolver chain. +if (ND->getDeclName().getFETokenInfo()) + getCI()->getSema().IdResolver.RemoveDecl(ND); + } } llvm::StringRef IncrementalParser::GetMangledName(GlobalDecl GD) const { diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index e0745fe9a4536..67d55f94bee3e 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2280,9 +2280,13 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { if (LabelDecl *LD = dyn_cast(D)) CheckPoppedLabel(LD, *this, addDiag); -// Remove this name from our lexical scope, and warn on it if we haven't -// already. -IdResolver.RemoveDecl(D); +// Partial translation units that are created in incremental processing must +// not clean up the IdResolver because PTUs should take into account the +// declarations that came from previous PTUs. +if (!PP.isIncrementalProcessingEnabled()) + IdResolver.RemoveDecl(D); + +// Warn on it if we are shadowing a declaration. auto ShadowI = ShadowingDecls.find(D); if (ShadowI != ShadowingDecls.end()) { if (const auto *FD = dyn_cast(ShadowI->second)) { diff --git a/clang/test/Interpreter/execute.c b/clang/test/Interpreter/execute.c new file mode 100644 index 0..44a3a32c93011 --- /dev/null +++ b/clang/test/Interpreter/execute.c @@ -0,0 +1,21 @@ +// REQUIRES: host-supports-jit +// UNSUPPORTED: system-aix + +// RUN: cat %s | clang-repl -Xcc -xc -Xcc -Xclang -Xcc -verify | FileCheck %s +// RUN: cat %s | clang-repl -Xcc -xc -Xcc -O2 -Xcc -Xclang -Xcc -verify| FileCheck %s +int printf(const char *, ...); +int i = 42; err // expected-error{{use of undeclared identifier}} +int i = 42; +struct S { float f; struct S *m;} s = {1.0, 0}; +// FIXME: Making foo inline fails to emit the function. +int foo() { return 42; } +void run() {\ + printf("i = %d\n", i);\ + printf("S[f=%f, m=0x%llx]\n", s.f, (unsigned long long)s.m); \ + int r3 = foo(); \ +} +run(); +// CHECK: i = 42 +// CHECK-NEXT: S[f=1.00, m=0x0] + +%quit ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
@@ -407,6 +406,16 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { } } } + + // FIXME: We should de-allocate MostRecentTU + for (Decl *D : MostRecentTU->decls()) { +if (!isa(D)) + continue; +// Check if we need to clean up the IdResolver chain. +NamedDecl *ND = cast(D); vgvassilev wrote: OTOH, that loop is easier to be spelled like: ``` for() { if (auto *ND = dyn_cast(D)) // do some work } ``` That violates the loop early exit policy :) https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
@@ -407,6 +406,16 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { } } } + + // FIXME: We should de-allocate MostRecentTU + for (Decl *D : MostRecentTU->decls()) { +if (!isa(D)) + continue; +// Check if we need to clean up the IdResolver chain. +NamedDecl *ND = cast(D); vgvassilev wrote: I don't. Let me make these changes so we can move forward here. https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
@@ -407,6 +406,16 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { } } } + + // FIXME: We should de-allocate MostRecentTU + for (Decl *D : MostRecentTU->decls()) { +if (!isa(D)) + continue; +// Check if we need to clean up the IdResolver chain. +NamedDecl *ND = cast(D); vgvassilev wrote: Hm. Ok I did not realize that code is smelly :) We are getting a bit theoretical here but for the sake of the argument: `isa<>` calls [CastInfo::isPossible](https://llvm.org/doxygen/structllvm_1_1CastIsPossible.html#a44e6fa462c45ccec1dcb2e52901e055d)(Val); `cast<>` calls [CastInfo::doCast](https://llvm.org/doxygen/structllvm_1_1CastInfo.html#a143f6f757917e1245aed3882209b466f)(Val); `dyn_cast<>` is both `isa + cast`. My point was that in the case of something that's not a `NamedDecl` we will avoid the check `isPossible` for that case. It's probably peanuts: https://godbolt.org/z/xeh7jh5ax Anyway, if you feel strongly about the other approach I can do it... https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
@@ -2282,7 +2282,8 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { // Remove this name from our lexical scope, and warn on it if we haven't // already. -IdResolver.RemoveDecl(D); +if (!PP.isIncrementalProcessingEnabled()) + IdResolver.RemoveDecl(D); vgvassilev wrote: No, this change makes sure that we preserve the state of the `IdResolver` across partial translation units (PTU). That is, when we see another incremental output, we still take into account the declarations that came from previous PTUs. Eg: ``` [repl] int i = 12; [repl] printf("%d\n", i); // without this patch we report we do not know what `i` is... ``` To your explicit question this patch produces: ``` bin/clang-repl -Xcc -xc clang-repl> { int i = 12; } clang-repl> printf("%d", i); // Fine? In file included from <<< inputs >>>:1: input_line_2:1:1: error: call to undeclared library function 'printf' with type 'int (const char *, ...)'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] 1 | printf("%d", i); // Fine? | ^ input_line_2:1:1: note: include the header or explicitly provide a declaration for 'printf' input_line_2:1:14: error: reference to local variable 'i' declared in enclosing context 1 | printf("%d", i); // Fine? | ^ input_line_1:1:7: note: 'i' declared here 1 | { int i = 12; } | ^ error: Parsing failed. clang-repl> %quit ``` https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
@@ -407,6 +406,16 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { } } } + + // FIXME: We should de-allocate MostRecentTU + for (Decl *D : MostRecentTU->decls()) { +if (!isa(D)) + continue; +// Check if we need to clean up the IdResolver chain. +NamedDecl *ND = cast(D); +if (ND->getDeclName().getFETokenInfo()) vgvassilev wrote: To clarify, you want an assert for the case where we try to remove the `ND` from the `IdResolved` but it was never registered? If so, `RemoveDecl` asserts (I was hurt couple of times there ;)) https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
@@ -407,6 +406,16 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { } } } + + // FIXME: We should de-allocate MostRecentTU + for (Decl *D : MostRecentTU->decls()) { +if (!isa(D)) + continue; +// Check if we need to clean up the IdResolver chain. +NamedDecl *ND = cast(D); vgvassilev wrote: The `isa` + `cast` saves a few instructions in the case where `D` is not a `NamedDecl`. I'd prefer to stay the way it is although we are not expecting a lot of declarations that are not `NamedDecl`s. https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
vgvassilev wrote: @AaronBallman, can you take a look at that patch, hopefully to move forward as seems the other reviewers are busy. https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
vgvassilev wrote: The pre-merge windows test failure in `Clang :: Driver/amdgpu-toolchain.c` seems unrelated to this PR. https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
https://github.com/vgvassilev updated https://github.com/llvm/llvm-project/pull/89804 >From 50fa9c91bee980a114ebab2b3301a1e378dd2b81 Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Tue, 23 Apr 2024 18:07:06 + Subject: [PATCH] [clang-repl] Extend the C support. The IdResolver chain is the main way for C to implement lookup rules. Every new partial translation unit caused clang to exit the top-most scope which in turn cleaned up the IdResolver chain. That was not an issue for C++ because its lookup is implemented on the level of declaration contexts. This patch keeps the IdResolver chain across partial translation units maintaining proper C-style lookup infrastructure. --- clang/lib/Interpreter/IncrementalParser.cpp | 13 +++-- clang/lib/Sema/SemaDecl.cpp | 3 ++- clang/test/Interpreter/execute.c| 21 + 3 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 clang/test/Interpreter/execute.c diff --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp index ef90fe9e6f5451..f1cb5fc870eb94 100644 --- a/clang/lib/Interpreter/IncrementalParser.cpp +++ b/clang/lib/Interpreter/IncrementalParser.cpp @@ -387,8 +387,7 @@ std::unique_ptr IncrementalParser::GenModule() { void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { TranslationUnitDecl *MostRecentTU = PTU.TUPart; - TranslationUnitDecl *FirstTU = MostRecentTU->getFirstDecl(); - if (StoredDeclsMap *Map = FirstTU->getPrimaryContext()->getLookupPtr()) { + if (StoredDeclsMap *Map = MostRecentTU->getPrimaryContext()->getLookupPtr()) { for (auto &&[Key, List] : *Map) { DeclContextLookupResult R = List.getLookupResult(); std::vector NamedDeclsToRemove; @@ -407,6 +406,16 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { } } } + + // FIXME: We should de-allocate MostRecentTU + for (Decl *D : MostRecentTU->decls()) { +if (!isa(D)) + continue; +// Check if we need to clean up the IdResolver chain. +NamedDecl *ND = cast(D); +if (ND->getDeclName().getFETokenInfo()) + getCI()->getSema().IdResolver.RemoveDecl(ND); + } } llvm::StringRef IncrementalParser::GetMangledName(GlobalDecl GD) const { diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index e0745fe9a45367..4f8c7e2b2e2941 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2282,7 +2282,8 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { // Remove this name from our lexical scope, and warn on it if we haven't // already. -IdResolver.RemoveDecl(D); +if (!PP.isIncrementalProcessingEnabled()) + IdResolver.RemoveDecl(D); auto ShadowI = ShadowingDecls.find(D); if (ShadowI != ShadowingDecls.end()) { if (const auto *FD = dyn_cast(ShadowI->second)) { diff --git a/clang/test/Interpreter/execute.c b/clang/test/Interpreter/execute.c new file mode 100644 index 00..44a3a32c930112 --- /dev/null +++ b/clang/test/Interpreter/execute.c @@ -0,0 +1,21 @@ +// REQUIRES: host-supports-jit +// UNSUPPORTED: system-aix + +// RUN: cat %s | clang-repl -Xcc -xc -Xcc -Xclang -Xcc -verify | FileCheck %s +// RUN: cat %s | clang-repl -Xcc -xc -Xcc -O2 -Xcc -Xclang -Xcc -verify| FileCheck %s +int printf(const char *, ...); +int i = 42; err // expected-error{{use of undeclared identifier}} +int i = 42; +struct S { float f; struct S *m;} s = {1.0, 0}; +// FIXME: Making foo inline fails to emit the function. +int foo() { return 42; } +void run() {\ + printf("i = %d\n", i);\ + printf("S[f=%f, m=0x%llx]\n", s.f, (unsigned long long)s.m); \ + int r3 = foo(); \ +} +run(); +// CHECK: i = 42 +// CHECK-NEXT: S[f=1.00, m=0x0] + +%quit ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
https://github.com/vgvassilev updated https://github.com/llvm/llvm-project/pull/89804 >From 8317ce33d07d0986e314de0b39aa977f784e0619 Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Tue, 23 Apr 2024 18:07:06 + Subject: [PATCH] [clang-repl] Extend the C support. The IdResolver chain is the main way for C to implement lookup rules. Every new partial translation unit caused clang to exit the top-most scope which in turn cleaned up the IdResolver chain. That was not an issue for C++ because its lookup is implemented on the level of declaration contexts. This patch keeps the IdResolver chain across partial translation units maintaining proper C-style lookup infrastructure. --- clang/lib/Interpreter/IncrementalParser.cpp | 13 +++-- clang/lib/Sema/SemaDecl.cpp | 3 ++- clang/test/Interpreter/execute.c| 21 + 3 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 clang/test/Interpreter/execute.c diff --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp index ef90fe9e6f5451..f1cb5fc870eb94 100644 --- a/clang/lib/Interpreter/IncrementalParser.cpp +++ b/clang/lib/Interpreter/IncrementalParser.cpp @@ -387,8 +387,7 @@ std::unique_ptr IncrementalParser::GenModule() { void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { TranslationUnitDecl *MostRecentTU = PTU.TUPart; - TranslationUnitDecl *FirstTU = MostRecentTU->getFirstDecl(); - if (StoredDeclsMap *Map = FirstTU->getPrimaryContext()->getLookupPtr()) { + if (StoredDeclsMap *Map = MostRecentTU->getPrimaryContext()->getLookupPtr()) { for (auto &&[Key, List] : *Map) { DeclContextLookupResult R = List.getLookupResult(); std::vector NamedDeclsToRemove; @@ -407,6 +406,16 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { } } } + + // FIXME: We should de-allocate MostRecentTU + for (Decl *D : MostRecentTU->decls()) { +if (!isa(D)) + continue; +// Check if we need to clean up the IdResolver chain. +NamedDecl *ND = cast(D); +if (ND->getDeclName().getFETokenInfo()) + getCI()->getSema().IdResolver.RemoveDecl(ND); + } } llvm::StringRef IncrementalParser::GetMangledName(GlobalDecl GD) const { diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 452e00fa32b102..2a0f73b42d3088 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2282,7 +2282,8 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { // Remove this name from our lexical scope, and warn on it if we haven't // already. -IdResolver.RemoveDecl(D); +if (!PP.isIncrementalProcessingEnabled()) + IdResolver.RemoveDecl(D); auto ShadowI = ShadowingDecls.find(D); if (ShadowI != ShadowingDecls.end()) { if (const auto *FD = dyn_cast(ShadowI->second)) { diff --git a/clang/test/Interpreter/execute.c b/clang/test/Interpreter/execute.c new file mode 100644 index 00..44a3a32c930112 --- /dev/null +++ b/clang/test/Interpreter/execute.c @@ -0,0 +1,21 @@ +// REQUIRES: host-supports-jit +// UNSUPPORTED: system-aix + +// RUN: cat %s | clang-repl -Xcc -xc -Xcc -Xclang -Xcc -verify | FileCheck %s +// RUN: cat %s | clang-repl -Xcc -xc -Xcc -O2 -Xcc -Xclang -Xcc -verify| FileCheck %s +int printf(const char *, ...); +int i = 42; err // expected-error{{use of undeclared identifier}} +int i = 42; +struct S { float f; struct S *m;} s = {1.0, 0}; +// FIXME: Making foo inline fails to emit the function. +int foo() { return 42; } +void run() {\ + printf("i = %d\n", i);\ + printf("S[f=%f, m=0x%llx]\n", s.f, (unsigned long long)s.m); \ + int r3 = foo(); \ +} +run(); +// CHECK: i = 42 +// CHECK-NEXT: S[f=1.00, m=0x0] + +%quit ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Fix the process return code if diagnostics occurred. (PR #89879)
https://github.com/vgvassilev closed https://github.com/llvm/llvm-project/pull/89879 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Fix the process return code if diagnostics occurred. (PR #89879)
vgvassilev wrote: The Unix pre-merge seems okay, however the windows pre-merge check is doing nothing for more than 12h. I will move forward. https://github.com/llvm/llvm-project/pull/89879 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Fix the process return code if diagnostics occurred. (PR #89879)
https://github.com/vgvassilev updated https://github.com/llvm/llvm-project/pull/89879 >From 49b47988e852003e2257b9f537c6c9738033fe9e Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Wed, 24 Apr 2024 06:30:55 + Subject: [PATCH] [clang-repl] Fix the process return code if diagnostics occurred. --- clang/test/Interpreter/fail.cpp | 21 ++--- clang/tools/clang-repl/ClangRepl.cpp | 17 +++-- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/clang/test/Interpreter/fail.cpp b/clang/test/Interpreter/fail.cpp index 4e301f37548f1f..633d92794325c2 100644 --- a/clang/test/Interpreter/fail.cpp +++ b/clang/test/Interpreter/fail.cpp @@ -1,12 +1,19 @@ -// FIXME: There're some inconsistencies between interactive and non-interactive -// modes. For example, when clang-repl runs in the interactive mode, issues an -// error, and then successfully recovers if we decide it's a success then for -// the non-interactive mode the exit code should be a failure. -// RUN: clang-repl "int x = 10;" "int y=7; err;" "int y = 10;" // REQUIRES: host-supports-jit // UNSUPPORTED: system-aix -// RUN: cat %s | not clang-repl | FileCheck %s -BOOM! +// clang-repl can be called from the prompt in non-interactive mode as a +// calculator in shell scripts, for example. In that case if there is an error +// we should set the exit code as failure. +// RUN: not clang-repl "int x = 10;" "int y=7; err;" "int y = 10;" + +// In interactive (REPL) mode, we can have errors but we should exit with +// success because errors in the input code are part of the interactive use. +// RUN: cat %s | clang-repl | FileCheck %s + +// However, interactive mode should fail when we specified -verify and there +// was a diagnostic mismatches. This will make the testsuite fail as intended. +// RUN: cat %s | not clang-repl -Xcc -Xclang -Xcc -verify | FileCheck %s + +BOOM! // expected-error {{intended to fail the -verify test}} extern "C" int printf(const char *, ...); int i = 42; auto r1 = printf("i = %d\n", i); diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp index aecf61b97fc719..9cfc70462893dd 100644 --- a/clang/tools/clang-repl/ClangRepl.cpp +++ b/clang/tools/clang-repl/ClangRepl.cpp @@ -215,13 +215,15 @@ int main(int argc, const char **argv) { } else Interp = ExitOnErr(clang::Interpreter::create(std::move(CI))); + bool HasError = false; + for (const std::string : OptInputs) { -if (auto Err = Interp->ParseAndExecute(input)) +if (auto Err = Interp->ParseAndExecute(input)) { llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: "); + HasError = true; +} } - bool HasError = false; - if (OptInputs.empty()) { llvm::LineEditor LE("clang-repl"); std::string Input; @@ -241,18 +243,13 @@ int main(int argc, const char **argv) { break; } if (Input == R"(%undo)") { -if (auto Err = Interp->Undo()) { +if (auto Err = Interp->Undo()) llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: "); - HasError = true; -} } else if (Input.rfind("%lib ", 0) == 0) { -if (auto Err = Interp->LoadDynamicLibrary(Input.data() + 5)) { +if (auto Err = Interp->LoadDynamicLibrary(Input.data() + 5)) llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: "); - HasError = true; -} } else if (auto Err = Interp->ParseAndExecute(Input)) { llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: "); -HasError = true; } Input = ""; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
@@ -0,0 +1,21 @@ +// REQUIRES: host-supports-jit +// UNSUPPORTED: system-aix + +// RUN: cat %s | clang-repl -Xcc -xc -Xcc -Xclang -Xcc -verify | FileCheck %s +// RUN: cat %s | clang-repl -Xcc -xc -Xcc -O2 -Xcc -Xclang -Xcc -verify| FileCheck %s +int printf(const char *, ...); +int i = 42; err // expected-error{{use of undeclared identifier}} +int i = 42; +struct S { float f; struct S *m;} s = {1.0, 0}; +// FIXME: Making foo inline fails to emit the function. vgvassilev wrote: Not a C expert, my guess was that it had to do with CodeGen deciding to defer the inline as being a weak symbol. Needs more debugging but that's probably something for a later stage. https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Extend the C support. (PR #89804)
@@ -407,6 +406,16 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { } } } + + // FIXME: We should de-allocate MostRecentTU + for (Decl *D : MostRecentTU->decls()) { +if (!isa(D)) + continue; +// Check if we need to clean up the IdResolver chain. +NamedDecl *ND = cast(D); +if (ND->getDeclName().getFETokenInfo()) vgvassilev wrote: If the `MostRecentTU` has a declaration which for some reason was removed from the IdResolver by exiting some lexical scope, for example? I suspect there are other language rules that may decide to make a declaration not visible to the C name lookup... https://github.com/llvm/llvm-project/pull/89804 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Fix the process return code if diagnostics occurred. (PR #89879)
@@ -241,18 +243,13 @@ int main(int argc, const char **argv) { break; } if (Input == R"(%undo)") { -if (auto Err = Interp->Undo()) { +if (auto Err = Interp->Undo()) llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: "); - HasError = true; -} } else if (Input.rfind("%lib ", 0) == 0) { -if (auto Err = Interp->LoadDynamicLibrary(Input.data() + 5)) { +if (auto Err = Interp->LoadDynamicLibrary(Input.data() + 5)) llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: "); - HasError = true; vgvassilev wrote: The idea is that when you use interactive mode and it recovers from errors properly to return success as exit code. However, for the when run it in non interactive mode people might use clang-repl as a calculator eg `clang-repl "printf(...)"` and can be put in scripts. There we want to get exit code 1 if it miscompiled something. https://github.com/llvm/llvm-project/pull/89879 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Fix the process return code if diagnostics occurred. (PR #89879)
https://github.com/vgvassilev updated https://github.com/llvm/llvm-project/pull/89879 >From d6b3d2a7b93399f8e895118e9f43378a2efa21f1 Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Wed, 24 Apr 2024 06:30:55 + Subject: [PATCH] [clang-repl] Fix the process return code if diagnostics occurred. --- clang/test/Interpreter/fail.cpp | 11 --- clang/tools/clang-repl/ClangRepl.cpp | 17 +++-- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/clang/test/Interpreter/fail.cpp b/clang/test/Interpreter/fail.cpp index 4e301f37548f1f..b9035aca3cb7b1 100644 --- a/clang/test/Interpreter/fail.cpp +++ b/clang/test/Interpreter/fail.cpp @@ -1,12 +1,9 @@ -// FIXME: There're some inconsistencies between interactive and non-interactive -// modes. For example, when clang-repl runs in the interactive mode, issues an -// error, and then successfully recovers if we decide it's a success then for -// the non-interactive mode the exit code should be a failure. -// RUN: clang-repl "int x = 10;" "int y=7; err;" "int y = 10;" // REQUIRES: host-supports-jit // UNSUPPORTED: system-aix -// RUN: cat %s | not clang-repl | FileCheck %s -BOOM! +// RUN: not clang-repl "int x = 10;" "int y=7; err;" "int y = 10;" +// RUN: cat %s | clang-repl | FileCheck %s +// RUN: cat %s | not clang-repl -Xcc -Xclang -Xcc -verify | FileCheck %s +BOOM! // expected-error {{intended to fail the -verify test}} extern "C" int printf(const char *, ...); int i = 42; auto r1 = printf("i = %d\n", i); diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp index aecf61b97fc719..9cfc70462893dd 100644 --- a/clang/tools/clang-repl/ClangRepl.cpp +++ b/clang/tools/clang-repl/ClangRepl.cpp @@ -215,13 +215,15 @@ int main(int argc, const char **argv) { } else Interp = ExitOnErr(clang::Interpreter::create(std::move(CI))); + bool HasError = false; + for (const std::string : OptInputs) { -if (auto Err = Interp->ParseAndExecute(input)) +if (auto Err = Interp->ParseAndExecute(input)) { llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: "); + HasError = true; +} } - bool HasError = false; - if (OptInputs.empty()) { llvm::LineEditor LE("clang-repl"); std::string Input; @@ -241,18 +243,13 @@ int main(int argc, const char **argv) { break; } if (Input == R"(%undo)") { -if (auto Err = Interp->Undo()) { +if (auto Err = Interp->Undo()) llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: "); - HasError = true; -} } else if (Input.rfind("%lib ", 0) == 0) { -if (auto Err = Interp->LoadDynamicLibrary(Input.data() + 5)) { +if (auto Err = Interp->LoadDynamicLibrary(Input.data() + 5)) llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: "); - HasError = true; -} } else if (auto Err = Interp->ParseAndExecute(Input)) { llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: "); -HasError = true; } Input = ""; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Fix the process return code if diagnostics occurred. (PR #89879)
https://github.com/vgvassilev created https://github.com/llvm/llvm-project/pull/89879 Should fix the failure seen in the pre-merge infrastructure of #89804. >From 066029973ac937f3a810bd4aefaed8c8f6e0af51 Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Wed, 24 Apr 2024 06:30:55 + Subject: [PATCH] [clang-repl] Fix the process return code if diagnostics occurred. --- clang/test/Interpreter/fail.cpp | 11 --- clang/tools/clang-repl/ClangRepl.cpp | 16 +++- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/clang/test/Interpreter/fail.cpp b/clang/test/Interpreter/fail.cpp index 4e301f37548f1f..b9035aca3cb7b1 100644 --- a/clang/test/Interpreter/fail.cpp +++ b/clang/test/Interpreter/fail.cpp @@ -1,12 +1,9 @@ -// FIXME: There're some inconsistencies between interactive and non-interactive -// modes. For example, when clang-repl runs in the interactive mode, issues an -// error, and then successfully recovers if we decide it's a success then for -// the non-interactive mode the exit code should be a failure. -// RUN: clang-repl "int x = 10;" "int y=7; err;" "int y = 10;" // REQUIRES: host-supports-jit // UNSUPPORTED: system-aix -// RUN: cat %s | not clang-repl | FileCheck %s -BOOM! +// RUN: not clang-repl "int x = 10;" "int y=7; err;" "int y = 10;" +// RUN: cat %s | clang-repl | FileCheck %s +// RUN: cat %s | not clang-repl -Xcc -Xclang -Xcc -verify | FileCheck %s +BOOM! // expected-error {{intended to fail the -verify test}} extern "C" int printf(const char *, ...); int i = 42; auto r1 = printf("i = %d\n", i); diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp index aecf61b97fc719..bdc740c33a8f72 100644 --- a/clang/tools/clang-repl/ClangRepl.cpp +++ b/clang/tools/clang-repl/ClangRepl.cpp @@ -215,12 +215,15 @@ int main(int argc, const char **argv) { } else Interp = ExitOnErr(clang::Interpreter::create(std::move(CI))); + bool HasError = false; + for (const std::string : OptInputs) { -if (auto Err = Interp->ParseAndExecute(input)) +if (auto Err = Interp->ParseAndExecute(input)) { llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: "); + HasError = true; +} } - bool HasError = false; if (OptInputs.empty()) { llvm::LineEditor LE("clang-repl"); @@ -241,18 +244,13 @@ int main(int argc, const char **argv) { break; } if (Input == R"(%undo)") { -if (auto Err = Interp->Undo()) { +if (auto Err = Interp->Undo()) llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: "); - HasError = true; -} } else if (Input.rfind("%lib ", 0) == 0) { -if (auto Err = Interp->LoadDynamicLibrary(Input.data() + 5)) { +if (auto Err = Interp->LoadDynamicLibrary(Input.data() + 5)) llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: "); - HasError = true; -} } else if (auto Err = Interp->ParseAndExecute(Input)) { llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: "); -HasError = true; } Input = ""; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Lay the foundation of pretty printing for C. (PR #89811)
https://github.com/vgvassilev created https://github.com/llvm/llvm-project/pull/89811 Depends on #89804. >From 8317ce33d07d0986e314de0b39aa977f784e0619 Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Tue, 23 Apr 2024 18:07:06 + Subject: [PATCH 1/2] [clang-repl] Extend the C support. The IdResolver chain is the main way for C to implement lookup rules. Every new partial translation unit caused clang to exit the top-most scope which in turn cleaned up the IdResolver chain. That was not an issue for C++ because its lookup is implemented on the level of declaration contexts. This patch keeps the IdResolver chain across partial translation units maintaining proper C-style lookup infrastructure. --- clang/lib/Interpreter/IncrementalParser.cpp | 13 +++-- clang/lib/Sema/SemaDecl.cpp | 3 ++- clang/test/Interpreter/execute.c| 21 + 3 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 clang/test/Interpreter/execute.c diff --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp index ef90fe9e6f5451..f1cb5fc870eb94 100644 --- a/clang/lib/Interpreter/IncrementalParser.cpp +++ b/clang/lib/Interpreter/IncrementalParser.cpp @@ -387,8 +387,7 @@ std::unique_ptr IncrementalParser::GenModule() { void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { TranslationUnitDecl *MostRecentTU = PTU.TUPart; - TranslationUnitDecl *FirstTU = MostRecentTU->getFirstDecl(); - if (StoredDeclsMap *Map = FirstTU->getPrimaryContext()->getLookupPtr()) { + if (StoredDeclsMap *Map = MostRecentTU->getPrimaryContext()->getLookupPtr()) { for (auto &&[Key, List] : *Map) { DeclContextLookupResult R = List.getLookupResult(); std::vector NamedDeclsToRemove; @@ -407,6 +406,16 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { } } } + + // FIXME: We should de-allocate MostRecentTU + for (Decl *D : MostRecentTU->decls()) { +if (!isa(D)) + continue; +// Check if we need to clean up the IdResolver chain. +NamedDecl *ND = cast(D); +if (ND->getDeclName().getFETokenInfo()) + getCI()->getSema().IdResolver.RemoveDecl(ND); + } } llvm::StringRef IncrementalParser::GetMangledName(GlobalDecl GD) const { diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 452e00fa32b102..2a0f73b42d3088 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2282,7 +2282,8 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { // Remove this name from our lexical scope, and warn on it if we haven't // already. -IdResolver.RemoveDecl(D); +if (!PP.isIncrementalProcessingEnabled()) + IdResolver.RemoveDecl(D); auto ShadowI = ShadowingDecls.find(D); if (ShadowI != ShadowingDecls.end()) { if (const auto *FD = dyn_cast(ShadowI->second)) { diff --git a/clang/test/Interpreter/execute.c b/clang/test/Interpreter/execute.c new file mode 100644 index 00..44a3a32c930112 --- /dev/null +++ b/clang/test/Interpreter/execute.c @@ -0,0 +1,21 @@ +// REQUIRES: host-supports-jit +// UNSUPPORTED: system-aix + +// RUN: cat %s | clang-repl -Xcc -xc -Xcc -Xclang -Xcc -verify | FileCheck %s +// RUN: cat %s | clang-repl -Xcc -xc -Xcc -O2 -Xcc -Xclang -Xcc -verify| FileCheck %s +int printf(const char *, ...); +int i = 42; err // expected-error{{use of undeclared identifier}} +int i = 42; +struct S { float f; struct S *m;} s = {1.0, 0}; +// FIXME: Making foo inline fails to emit the function. +int foo() { return 42; } +void run() {\ + printf("i = %d\n", i);\ + printf("S[f=%f, m=0x%llx]\n", s.f, (unsigned long long)s.m); \ + int r3 = foo(); \ +} +run(); +// CHECK: i = 42 +// CHECK-NEXT: S[f=1.00, m=0x0] + +%quit >From fa864fb5926a87596b8a6ccd998d5c2f123be1f7 Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Tue, 23 Apr 2024 19:33:00 + Subject: [PATCH 2/2] [clang-repl] Lay the foundation of pretty printing for C. --- clang/lib/Interpreter/Interpreter.cpp | 168 ++ clang/lib/Parse/ParseStmt.cpp | 5 +- clang/test/Interpreter/pretty-print.c | 8 ++ 3 files changed, 101 insertions(+), 80 deletions(-) create mode 100644 clang/test/Interpreter/pretty-print.c diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index b20e6efcebfd10..96abf4bc53ef4b 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -42,6 +42,9 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/Host.h" + +#include + using namespace clang; // FIXME: Figure out how to unify with namespace init_convenience from @@ -250,14 +253,9 @@ Interpreter::~Interpreter() { // can't find the
[clang] [clang-repl] Extend the C support. (PR #89804)
https://github.com/vgvassilev created https://github.com/llvm/llvm-project/pull/89804 The IdResolver chain is the main way for C to implement lookup rules. Every new partial translation unit caused clang to exit the top-most scope which in turn cleaned up the IdResolver chain. That was not an issue for C++ because its lookup is implemented on the level of declaration contexts. This patch keeps the IdResolver chain across partial translation units maintaining proper C-style lookup infrastructure. >From 8317ce33d07d0986e314de0b39aa977f784e0619 Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Tue, 23 Apr 2024 18:07:06 + Subject: [PATCH] [clang-repl] Extend the C support. The IdResolver chain is the main way for C to implement lookup rules. Every new partial translation unit caused clang to exit the top-most scope which in turn cleaned up the IdResolver chain. That was not an issue for C++ because its lookup is implemented on the level of declaration contexts. This patch keeps the IdResolver chain across partial translation units maintaining proper C-style lookup infrastructure. --- clang/lib/Interpreter/IncrementalParser.cpp | 13 +++-- clang/lib/Sema/SemaDecl.cpp | 3 ++- clang/test/Interpreter/execute.c| 21 + 3 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 clang/test/Interpreter/execute.c diff --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp index ef90fe9e6f5451..f1cb5fc870eb94 100644 --- a/clang/lib/Interpreter/IncrementalParser.cpp +++ b/clang/lib/Interpreter/IncrementalParser.cpp @@ -387,8 +387,7 @@ std::unique_ptr IncrementalParser::GenModule() { void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { TranslationUnitDecl *MostRecentTU = PTU.TUPart; - TranslationUnitDecl *FirstTU = MostRecentTU->getFirstDecl(); - if (StoredDeclsMap *Map = FirstTU->getPrimaryContext()->getLookupPtr()) { + if (StoredDeclsMap *Map = MostRecentTU->getPrimaryContext()->getLookupPtr()) { for (auto &&[Key, List] : *Map) { DeclContextLookupResult R = List.getLookupResult(); std::vector NamedDeclsToRemove; @@ -407,6 +406,16 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit ) { } } } + + // FIXME: We should de-allocate MostRecentTU + for (Decl *D : MostRecentTU->decls()) { +if (!isa(D)) + continue; +// Check if we need to clean up the IdResolver chain. +NamedDecl *ND = cast(D); +if (ND->getDeclName().getFETokenInfo()) + getCI()->getSema().IdResolver.RemoveDecl(ND); + } } llvm::StringRef IncrementalParser::GetMangledName(GlobalDecl GD) const { diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 452e00fa32b102..2a0f73b42d3088 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2282,7 +2282,8 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { // Remove this name from our lexical scope, and warn on it if we haven't // already. -IdResolver.RemoveDecl(D); +if (!PP.isIncrementalProcessingEnabled()) + IdResolver.RemoveDecl(D); auto ShadowI = ShadowingDecls.find(D); if (ShadowI != ShadowingDecls.end()) { if (const auto *FD = dyn_cast(ShadowI->second)) { diff --git a/clang/test/Interpreter/execute.c b/clang/test/Interpreter/execute.c new file mode 100644 index 00..44a3a32c930112 --- /dev/null +++ b/clang/test/Interpreter/execute.c @@ -0,0 +1,21 @@ +// REQUIRES: host-supports-jit +// UNSUPPORTED: system-aix + +// RUN: cat %s | clang-repl -Xcc -xc -Xcc -Xclang -Xcc -verify | FileCheck %s +// RUN: cat %s | clang-repl -Xcc -xc -Xcc -O2 -Xcc -Xclang -Xcc -verify| FileCheck %s +int printf(const char *, ...); +int i = 42; err // expected-error{{use of undeclared identifier}} +int i = 42; +struct S { float f; struct S *m;} s = {1.0, 0}; +// FIXME: Making foo inline fails to emit the function. +int foo() { return 42; } +void run() {\ + printf("i = %d\n", i);\ + printf("S[f=%f, m=0x%llx]\n", s.f, (unsigned long long)s.m); \ + int r3 = foo(); \ +} +run(); +// CHECK: i = 42 +// CHECK-NEXT: S[f=1.00, m=0x0] + +%quit ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Test explicit emission of dtors in runtime interface builder (NFC) (PR #89734)
Stefan =?utf-8?q?Gr=C3=A4nitz?= Message-ID: In-Reply-To: https://github.com/vgvassilev approved this pull request. LGTM! https://github.com/llvm/llvm-project/pull/89734 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Test explicit emission of dtors in runtime interface builder (NFC) (PR #89734)
@@ -0,0 +1,13 @@ +// UNSUPPORTED: system-aix + +// RUN: cat %s | clang-repl | FileCheck %s +int *x = new int(); +template struct GuardX { T * GuardX(T *) : x(x) {}; ~GuardX(); }; +template GuardX::~GuardX() { delete x; x = nullptr; } + +// clang would normally defer codegen for ~GuardX() +// Make sure that RuntimeInterfaceBuilder requests it explicitly +(GuardX(x)) + +// CHECK-NOT: Symbols not found +// CHECK-NOT: _ZN6GuardXIiED2Ev vgvassilev wrote: How about a printf in the dtor? https://github.com/llvm/llvm-project/pull/89734 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Set up executor implicitly to account for init PTUs (PR #84758)
Stefan =?utf-8?q?Gränitz?= , Stefan =?utf-8?q?Gränitz?= Message-ID: In-Reply-To: vgvassilev wrote: I am fine changing it in any way that creates an executor as part of the initialization phase when we have codegen. Maybe we can do it in the builder class and then pass it to the interpreter? https://github.com/llvm/llvm-project/pull/84758 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Set up executor implicitly to account for init PTUs (PR #84758)
Stefan =?utf-8?q?Gränitz?= Message-ID: In-Reply-To: vgvassilev wrote: For me it is high priority because without it I cannot land the pch support in clang repl. I believe that’s also somewhat important for your use case? https://github.com/llvm/llvm-project/pull/84758 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang-repl] Implement value printing of custom types (PR #84769)
https://github.com/vgvassilev updated https://github.com/llvm/llvm-project/pull/84769 >From a1639ef21a6085f12383e815ce2ed31976f78cfa Mon Sep 17 00:00:00 2001 From: Vassil Vassilev Date: Sun, 16 Jul 2023 21:18:26 + Subject: [PATCH 1/2] [clang-repl] Implement value printing of custom types. Differential revision: https://reviews.llvm.org/D146809 --- clang/include/clang/Interpreter/Interpreter.h | 6 + .../Interpreter/PartialTranslationUnit.h | 2 + clang/include/clang/Interpreter/Value.h | 7 +- clang/lib/Headers/CMakeLists.txt | 1 + .../__clang_interpreter_runtime_printvalue.h | 261 clang/lib/Interpreter/CMakeLists.txt | 1 + clang/lib/Interpreter/DeviceOffload.cpp | 4 +- clang/lib/Interpreter/DeviceOffload.h | 4 +- clang/lib/Interpreter/IncrementalExecutor.cpp | 8 +- clang/lib/Interpreter/IncrementalExecutor.h | 7 +- clang/lib/Interpreter/IncrementalParser.cpp | 5 +- clang/lib/Interpreter/IncrementalParser.h | 5 +- clang/lib/Interpreter/Interpreter.cpp | 28 +- clang/lib/Interpreter/InterpreterUtils.cpp| 399 - clang/lib/Interpreter/InterpreterUtils.h | 22 +- clang/lib/Interpreter/Value.cpp | 33 +- clang/lib/Interpreter/ValuePrinter.cpp| 564 ++ clang/test/Interpreter/pretty-print.cpp | 206 +++ clang/tools/clang-repl/CMakeLists.txt | 59 ++ clang/tools/clang-repl/ClangRepl.cpp | 21 +- .../Interpreter/CodeCompletionTest.cpp| 10 +- .../InterpreterExceptionTest.cpp | 5 +- .../IncrementalCompilerBuilderTest.cpp| 4 +- .../Interpreter/IncrementalProcessingTest.cpp | 5 +- .../Interpreter/InterpreterExtensionsTest.cpp | 9 +- .../unittests/Interpreter/InterpreterTest.cpp | 5 +- 26 files changed, 1627 insertions(+), 54 deletions(-) create mode 100644 clang/lib/Headers/__clang_interpreter_runtime_printvalue.h create mode 100644 clang/lib/Interpreter/ValuePrinter.cpp create mode 100644 clang/test/Interpreter/pretty-print.cpp diff --git a/clang/include/clang/Interpreter/Interpreter.h b/clang/include/clang/Interpreter/Interpreter.h index 970e0245417b51..43331b0fe92c96 100644 --- a/clang/include/clang/Interpreter/Interpreter.h +++ b/clang/include/clang/Interpreter/Interpreter.h @@ -38,6 +38,8 @@ class ThreadSafeContext; namespace clang { class CompilerInstance; + +namespace caas { class IncrementalExecutor; class IncrementalParser; @@ -150,6 +152,7 @@ class Interpreter { llvm::Expected getExecutionEngine(); llvm::Expected Parse(llvm::StringRef Code); + llvm::Error ExecuteModule(std::unique_ptr ); llvm::Error Execute(PartialTranslationUnit ); llvm::Error ParseAndExecute(llvm::StringRef Code, Value *V = nullptr); llvm::Expected CompileDtorCall(CXXRecordDecl *CXXRD); @@ -182,6 +185,8 @@ class Interpreter { Expr *SynthesizeExpr(Expr *E); + std::unique_ptr GenModule(); + private: size_t getEffectivePTUSize() const; void markUserCodeStart(); @@ -190,6 +195,7 @@ class Interpreter { llvm::SmallVector ValuePrintingInfo; }; +} // namespace caas } // namespace clang #endif // LLVM_CLANG_INTERPRETER_INTERPRETER_H diff --git a/clang/include/clang/Interpreter/PartialTranslationUnit.h b/clang/include/clang/Interpreter/PartialTranslationUnit.h index bf91d559452b8a..d28cd30010cb92 100644 --- a/clang/include/clang/Interpreter/PartialTranslationUnit.h +++ b/clang/include/clang/Interpreter/PartialTranslationUnit.h @@ -24,6 +24,7 @@ namespace clang { class TranslationUnitDecl; +namespace caas { /// The class keeps track of various objects created as part of processing /// incremental inputs. struct PartialTranslationUnit { @@ -32,6 +33,7 @@ struct PartialTranslationUnit { /// The llvm IR produced for the input. std::unique_ptr TheModule; }; +} // namespace caas } // namespace clang #endif // LLVM_CLANG_INTERPRETER_PARTIALTRANSLATIONUNIT_H diff --git a/clang/include/clang/Interpreter/Value.h b/clang/include/clang/Interpreter/Value.h index d70e8f8719026b..6b737c05846fff 100644 --- a/clang/include/clang/Interpreter/Value.h +++ b/clang/include/clang/Interpreter/Value.h @@ -49,9 +49,11 @@ class raw_ostream; namespace clang { class ASTContext; -class Interpreter; class QualType; +namespace caas { +class Interpreter; + #if defined(_WIN32) // REPL_EXTERNAL_VISIBILITY are symbols that we need to be able to locate // at runtime. On Windows, this requires them to be exported from any of the @@ -138,6 +140,7 @@ class REPL_EXTERNAL_VISIBILITY Value { void setOpaqueType(void *Ty) { OpaqueType = Ty; } void *getPtr() const; + void **getPtrAddress() const; void setPtr(void *Ptr) { Data.m_Ptr = Ptr; } #define X(type, name) \ @@ -204,6 +207,6 @@ template <> inline void *Value::as() const { return Data.m_Ptr; return (void *)as(); } - +} //