Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: xcpp support reexecution #80

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion include/xeus-clang-repl/xparser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ std::vector<std::string> split_line(const std::string &input,

std::vector<std::string> get_lines(const std::string &input);

std::vector<std::string> split_from_includes(const std::string &input);
struct SplitBlock {
bool is_include;
std::string code;
};

std::vector<SplitBlock> split_from_includes(const std::string &input);

bool short_has_arg(const std::string &opt, const std::string &short_opts);

Expand Down
77 changes: 77 additions & 0 deletions patches/llvm/clang17-2-fix-toplevel-code.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index cd0878d70825..7b1d9e8be6c5 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -4440,7 +4440,8 @@ class TopLevelStmtDecl : public Decl {
virtual void anchor();

public:
- static TopLevelStmtDecl *Create(ASTContext &C, Stmt *Statement);
+ static TopLevelStmtDecl *Create(ASTContext &C, DeclContext *DC,
+ Stmt *Statement);
static TopLevelStmtDecl *CreateDeserialized(ASTContext &C, unsigned ID);

SourceRange getSourceRange() const override LLVM_READONLY;
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 527ea6042daa..5c0f4f5b6b4c 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -5513,13 +5513,13 @@ FileScopeAsmDecl *FileScopeAsmDecl::CreateDeserialized(ASTContext &C,

void TopLevelStmtDecl::anchor() {}

-TopLevelStmtDecl *TopLevelStmtDecl::Create(ASTContext &C, Stmt *Statement) {
+TopLevelStmtDecl *TopLevelStmtDecl::Create(ASTContext &C, DeclContext *DC,
+ Stmt *Statement) {
assert(Statement);
assert(C.getLangOpts().IncrementalExtensions &&
"Must be used only in incremental mode");

SourceLocation BeginLoc = Statement->getBeginLoc();
- DeclContext *DC = C.getTranslationUnitDecl();

return new (C, DC) TopLevelStmtDecl(DC, BeginLoc, Statement);
}
diff --git a/clang/lib/Interpreter/IncrementalParser.cpp b/clang/lib/Interpreter/IncrementalParser.cpp
index 370bcbfee8b0..366610abecb0 100644
--- a/clang/lib/Interpreter/IncrementalParser.cpp
+++ b/clang/lib/Interpreter/IncrementalParser.cpp
@@ -373,8 +373,22 @@ std::unique_ptr<llvm::Module> IncrementalParser::GenModule() {

void IncrementalParser::CleanUpPTU(PartialTranslationUnit &PTU) {
TranslationUnitDecl *MostRecentTU = PTU.TUPart;
+ if (!MostRecentTU) {
+ return;
+ }
+
TranslationUnitDecl *FirstTU = MostRecentTU->getFirstDecl();
- if (StoredDeclsMap *Map = FirstTU->getPrimaryContext()->getLookupPtr()) {
+ if (!FirstTU) {
+ return;
+ }
+
+ SmallVector<DeclContext *> contexts;
+ FirstTU->collectAllContexts(contexts);
+ if (contexts.empty()) {
+ return;
+ }
+
+ if (StoredDeclsMap *Map = contexts.back()->getLookupPtr()) {
for (auto I = Map->begin(); I != Map->end(); ++I) {
StoredDeclsList &List = I->second;
DeclContextLookupResult R = List.getLookupResult();
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index be6a136ef37b..f78fada57f62 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -20287,8 +20287,8 @@ Decl *Sema::ActOnFileScopeAsmDecl(Expr *expr,
}

Decl *Sema::ActOnTopLevelStmtDecl(Stmt *Statement) {
- auto *New = TopLevelStmtDecl::Create(Context, Statement);
- Context.getTranslationUnitDecl()->addDecl(New);
+ auto *New = TopLevelStmtDecl::Create(Context, CurContext, Statement);
+ CurContext->addDecl(New);
return New;
}

28 changes: 26 additions & 2 deletions src/xinterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,26 @@ interpreter::interpreter(int argc, const char *const *argv)

interpreter::~interpreter() { restore_output(); }

nl::json interpreter::execute_request_impl(int /*execution_counter*/,

std::string namespace_name(int namespace_number) {
const std::string NAMESPACE_PREFIX = "__xns";
return NAMESPACE_PREFIX + std::to_string(namespace_number);
}

std::string namespace_full_name(int namespace_number) {
std::string result;
for (int i = 1; i < namespace_number; ++i) {
result += namespace_name(i) + "::";
}
result += namespace_name(namespace_number);
return result;
}

std::string encapsulate_code(const std::string &code, int namespace_number) {
return "\nnamespace " + namespace_full_name(namespace_number) + " {" + code + "}";
}

nl::json interpreter::execute_request_impl(int execution_counter,
const std::string &code, bool silent,
bool /*store_history*/,
nl::json /*user_expressions*/,
Expand Down Expand Up @@ -110,7 +129,12 @@ nl::json interpreter::execute_request_impl(int /*execution_counter*/,
try {
Cpp::BeginStdStreamCapture(Cpp::kStdErr);
Cpp::BeginStdStreamCapture(Cpp::kStdOut);
compilation_result = Cpp::Process(block.c_str());
if (block.is_include) {
compilation_result = Cpp::Process(block.code.c_str());
} else {
std::string encapsulated = encapsulate_code(block.code, execution_counter);
compilation_result = Cpp::Process(encapsulated.c_str());
}
out = Cpp::EndStdStreamCapture();
err = Cpp::EndStdStreamCapture();
std::cout << out;
Expand Down
19 changes: 10 additions & 9 deletions src/xparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ std::vector<std::string> get_lines(const std::string &input) {
return lines;
}

std::vector<std::string> split_from_includes(const std::string &input) {
std::vector<SplitBlock> split_from_includes(const std::string &input) {
// this function split the input into part where we have only #include.

// split input into lines
Expand All @@ -63,15 +63,15 @@ std::vector<std::string> split_from_includes(const std::string &input) {
// part of the result
std::regex incl_re("\\#include.*");
std::regex magic_re("^\\%\\w+");
std::vector<std::string> result;
result.push_back("");
std::vector<SplitBlock> result;
result.push_back({false, ""});
std::size_t current = 0; // 0 include, 1 other
std::size_t rindex = 0; // current index of result vector
for (std::size_t i = 0; i < lines.size(); ++i) {
if (!lines[i].empty()) {
if (std::regex_search(lines[i], magic_re)) {
result.push_back(lines[i] + "\n");
result.push_back("");
result.push_back({false, lines[i] + "\n"});
result.push_back({false, ""});
rindex += 2;
} else {
if (std::regex_match(lines[i], incl_re)) {
Expand All @@ -80,7 +80,7 @@ std::vector<std::string> split_from_includes(const std::string &input) {
// other things
if (current != 0) {
current = 0;
result.push_back("");
result.push_back({false, ""});
rindex++;
}
} else {
Expand All @@ -89,15 +89,16 @@ std::vector<std::string> split_from_includes(const std::string &input) {
// the include parts
if (current != 1) {
current = 1;
result.push_back("");
result.push_back({false, ""});
rindex++;
}
}
// if we have multiple lines, we add a semicolon at the end of the lines
// that not contain #include keyword (except for the last line)
result[rindex] += lines[i];
result[rindex].is_include = (current == 0);
result[rindex].code += lines[i];
if (i != lines.size() - 1) {
result[rindex] += "\n";
result[rindex].code += "\n";
}
}
}
Expand Down
Loading