root-project / cling

The cling C++ interpreter
Other
3.51k stars 269 forks source link

`cling -x c` errors when not using terminating semicolons #419

Open deliciouslytyped opened 3 years ago

deliciouslytyped commented 3 years ago

CLING

Setup

cling 0.7 on NixOS

Additional info

https://root-forum.cern.ch/t/objective-c-support/19065/6 looks kind of related?

deliciouslytyped commented 3 years ago

Looks semicolon related instead:

$ ./cling -x c

***************** CLING *****************
* Type C code and press enter to run it *
*            Type .q to exit            *
*****************************************
[cling]$ sizeof(int)
input_line_2:2:2: error: ValueExtractionSynthesizer could not find: 'cling::runtime::internal::setValueNoAlloc'.
 sizeof(int)
 ^
[cling]$ sizeof(int);
[cling]$ int x = sizeof(int);
[cling]$ x;
[cling]$ printf("%d\n", x)
input_line_6:2:2: warning: implicitly declaring library function 'printf' with type 'int (const char *, ...)' [-Wimplicit-function-declaration]
 printf("%d\n", x)
 ^
input_line_6:2:2: note: include the header <stdio.h> or explicitly provide a declaration for 'printf'
input_line_6:2:2: error: ValueExtractionSynthesizer could not find: 'cling::runtime::internal::setValueNoAlloc'.
 printf("%d\n", x)
 ^
[cling]$ printf("%d\n", x);
4
deliciouslytyped commented 3 years ago

This thread: https://root-forum.cern.ch/t/cling-cint-parse-issue/18312 says something about c++ automatic semicolons.

SimeonEhrig commented 3 years ago

I never tried cling -x c but I believe, it does not work and the ValueExtractionSynthesizer is a good example for it. In Cling, the JIT and the execution runtime of the user code are "mixed". This means, if you type in code, the JIT will analyze the source code and modify it depending of the kind of the code. Sometimes it adds some extra C++ code to enable some special functions of Cling, like the printing the value of a statement, if you skip the semicolon. Therefore, pure C should not work.

rubdos commented 3 years ago

So, looks like this may be a dupe of #364. That said, there's more discussion here, so I'll drop what I wrote on the xeus-cling PR here too:

So, seems like I cannot afford to spend a lot more time on this. I've been digging a bit in cling, and I'll dump my findings here. It looks like the ValueExtractionSynthesizer needs some extra help in the lookup and calling of the setValueNoAlloc helper function. Most probably, there needs to be a new variant of that overloaded method that's callable from C (which then forwards it to the existing methods, although that's probably even not necessary). Something like this:

diff --git a/lib/Interpreter/ValueExtractionSynthesizer.cpp b/lib/Interpreter/ValueExtractionSynthesizer.cpp
index fc568572..596b6afb 100644
--- a/lib/Interpreter/ValueExtractionSynthesizer.cpp
+++ b/lib/Interpreter/ValueExtractionSynthesizer.cpp
@@ -22,6 +22,16 @@
 #include "clang/Sema/Sema.h"
 #include "clang/Sema/SemaDiagnostic.h"

+// Implements the CValueExtractionPrinter interface.
+extern "C" {
+    CLING_LIB_EXPORT
+    void cling_SetValueNoAlloc(void * /*cling::Value* V*/) {
+    }
+    CLING_LIB_EXPORT
+    void cling_SetValueWithAlloc(void * /*cling::Value* V*/) {
+    }
+}
+
 using namespace clang;

 namespace cling {
@@ -430,6 +440,9 @@ namespace {
         return VSError(m_Sema, E, "cling::runtime::gCling");
       if (!(NSD = utils::Lookup::Namespace(m_Sema, "internal", NSD)))
         return VSError(m_Sema, E, "cling::runtime::internal namespace");
+    } else if (m_Sema->getLangOpts().C) {
+      if (!(NSD = utils::Lookup::Namespace(m_Sema, "cling")))
+        return VSError(m_Sema, E, "cling namespace");
     }
     LookupResult R(*m_Sema, &m_Context->Idents.get("setValueNoAlloc"),
                    SourceLocation(), Sema::LookupOrdinaryName,

The above is inspired on the code from the ValuePrinter (lib/Interpreter/ValuePrinter.cpp), and more inspiration can probably be drawn from there. After that's all done, it can be easily tested via the unit testing system, because it should fail on the C driver test after the behaviour is corrected (test/Driver/C.c).


A work around (which I was still not able to implement, weirdly) is to find out why this part of the runtime code is hit from xeus-cling, but not from cling itself when ran from the CLI. The unit tests in this PR fail, although there's no left-out semicolons. If it can be found why this happens, a patch can be made here to just disallow the value catching.


I still want to offer my help and time; if someone wants to try and tackle this, feel free to mention me all around. If this PR needs a rebase or something, I'll be glad to help. If someone has a hint on how to patch the ValueExtractionSynthesizer correctly, I might give it another shot. It's quite a huge project to dive into though :)