Added test for MultipleInterpreters, and some changes.

This commit is contained in:
Elisavet Sakellari 2016-01-11 15:17:58 +01:00 committed by sftnight
parent 8f51dd1617
commit 4ac0a10a3e
4 changed files with 80 additions and 32 deletions

View File

@ -9,8 +9,6 @@
#ifndef CLING_ASTIMPORTSOURCE_H #ifndef CLING_ASTIMPORTSOURCE_H
#define CLING_ASTIMPORTSOURCE_H #define CLING_ASTIMPORTSOURCE_H
#include "cling/Interpreter/Interpreter.h"
#include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/CompilerInstance.h"
#include "clang/Sema/Sema.h" #include "clang/Sema/Sema.h"
#include "clang/AST/ASTContext.h" #include "clang/AST/ASTContext.h"
@ -28,6 +26,10 @@ namespace clang {
class Sema; class Sema;
} }
namespace cling {
class Interpreter;
}
namespace cling { namespace cling {
namespace utils { namespace utils {
@ -56,20 +58,7 @@ namespace cling {
public: public:
ASTImportSource(cling::Interpreter *parent_interpreter, ASTImportSource(cling::Interpreter *parent_interpreter,
cling::Interpreter *child_interpreter) : cling::Interpreter *child_interpreter);
m_parent_Interp(parent_interpreter), m_child_Interp(child_interpreter) {
clang::DeclContext *parentTUDeclContext =
clang::TranslationUnitDecl::castToDeclContext(
m_parent_Interp->getCI()->getASTContext().getTranslationUnitDecl());
clang::DeclContext *childTUDeclContext =
clang::TranslationUnitDecl::castToDeclContext(
m_child_Interp->getCI()->getASTContext().getTranslationUnitDecl());
// Also keep in the map of Decl Contexts the Translation Unit Decl Context
m_DeclContexts_map[childTUDeclContext] = parentTUDeclContext;
}
~ASTImportSource() { }; ~ASTImportSource() { };

View File

@ -25,6 +25,7 @@
#include "cling/Interpreter/Transaction.h" #include "cling/Interpreter/Transaction.h"
#include "cling/Interpreter/Value.h" #include "cling/Interpreter/Value.h"
#include "cling/Utils/AST.h" #include "cling/Utils/AST.h"
#include "cling/Utils/ASTImportSource.h"
#include "cling/Interpreter/AutoloadCallback.h" #include "cling/Interpreter/AutoloadCallback.h"
#include "clang/AST/ASTContext.h" #include "clang/AST/ASTContext.h"
@ -233,8 +234,25 @@ namespace cling {
Interpreter::Interpreter(Interpreter &parentInterpreter, int argc, const char* const *argv, Interpreter::Interpreter(Interpreter &parentInterpreter, int argc, const char* const *argv,
const char* llvmdir /*= 0*/, bool noRuntime) : const char* llvmdir /*= 0*/, bool noRuntime) :
Interpreter(argc, argv, llvmdir, noRuntime, /* isChildInterp */ true) { Interpreter(argc, argv, llvmdir, noRuntime, /* isChildInterp */ true) {
// Do the "setup" of the connection between this interpreter and
// its parent interpreter.
// The "bridge" between the interpreters.
utils::ASTImportSource *myExternalSource =
new utils::ASTImportSource(&parentInterpreter, this);
llvm::IntrusiveRefCntPtr <ExternalASTSource>
astContextExternalSource(myExternalSource);
this->getCI()->getASTContext().ExternalSource.resetWithoutRelease();
this->getCI()->getASTContext().setExternalSource(astContextExternalSource);
// Inform the Translation Unit Decl of I2 that it has to
// search somewhere else to find the declarations.
this->getCI()->getASTContext().getTranslationUnitDecl()->setHasExternalVisibleStorage();
// Give my IncrementalExecutor a pointer to the Incremental executor // Give my IncrementalExecutor a pointer to the Incremental executor
// of the parent Interpreter. // of the parent Interpreter.
m_Executor->setExternalIncrementalExecutor(parentInterpreter.m_Executor.get()); m_Executor->setExternalIncrementalExecutor(parentInterpreter.m_Executor.get());
} }

View File

@ -1,10 +1,27 @@
#include "cling/Utils/ASTImportSource.h" #include "cling/Utils/ASTImportSource.h"
#include "cling/Interpreter/Interpreter.h"
using namespace clang; using namespace clang;
namespace cling { namespace cling {
namespace utils { namespace utils {
ASTImportSource::ASTImportSource(cling::Interpreter *parent_interpreter,
cling::Interpreter *child_interpreter) :
m_parent_Interp(parent_interpreter), m_child_Interp(child_interpreter) {
clang::DeclContext *parentTUDeclContext =
clang::TranslationUnitDecl::castToDeclContext(
m_parent_Interp->getCI()->getASTContext().getTranslationUnitDecl());
clang::DeclContext *childTUDeclContext =
clang::TranslationUnitDecl::castToDeclContext(
m_child_Interp->getCI()->getASTContext().getTranslationUnitDecl());
// Also keep in the map of Decl Contexts the Translation Unit Decl Context
m_DeclContexts_map[childTUDeclContext] = parentTUDeclContext;
}
void ASTImportSource::ImportDecl(Decl *declToImport, void ASTImportSource::ImportDecl(Decl *declToImport,
ASTImporter &importer, ASTImporter &importer,
DeclarationName &childDeclName, DeclarationName &childDeclName,
@ -17,13 +34,6 @@ namespace cling {
// once clang supports the import of function templates. // once clang supports the import of function templates.
if (!(declToImport->isFunctionOrFunctionTemplate() && declToImport->isTemplateDecl())) { if (!(declToImport->isFunctionOrFunctionTemplate() && declToImport->isTemplateDecl())) {
if (Decl *importedDecl = importer.Import(declToImport)) { if (Decl *importedDecl = importer.Import(declToImport)) {
if (NamedDecl *importedNamedDecl = llvm::dyn_cast<NamedDecl>(importedDecl)) {
std::vector < NamedDecl * > declVector{importedNamedDecl};
llvm::ArrayRef < NamedDecl * > FoundDecls(declVector);
SetExternalVisibleDeclsForName(childCurrentDeclContext,
importedNamedDecl->getDeclName(),
FoundDecls);
}
// Put the name of the Decl imported with the // Put the name of the Decl imported with the
// DeclarationName coming from the parent, in my map. // DeclarationName coming from the parent, in my map.
m_DeclName_map[childDeclName.getAsString()] = parentDeclName; m_DeclName_map[childDeclName.getAsString()] = parentDeclName;
@ -41,16 +51,13 @@ namespace cling {
importedDeclContext->setHasExternalVisibleStorage(true); importedDeclContext->setHasExternalVisibleStorage(true);
if (NamedDecl *importedNamedDecl = llvm::dyn_cast<NamedDecl>(importedDeclContext)) {
std::vector < NamedDecl * > declVector{importedNamedDecl};
llvm::ArrayRef < NamedDecl * > FoundDecls(declVector);
SetExternalVisibleDeclsForName(childCurrentDeclContext,
importedNamedDecl->getDeclName(),
FoundDecls);
}
// Put the name of the DeclContext imported with the // Put the name of the DeclContext imported with the
// DeclarationName coming from the parent, in my map. // DeclarationName coming from the parent, in my map.
m_DeclName_map[childDeclName.getAsString()] = parentDeclName; // (Except for the case when it is a function declaration,
// because we may want to search again for functions
// with the same name (function overloading). )
if (!importedDeclContext->isFunctionOrMethod())
m_DeclName_map[childDeclName.getAsString()] = parentDeclName;
// And also put the declaration context I found from the parent Interpreter // And also put the declaration context I found from the parent Interpreter
// in the map of the child Interpreter to have it for the future. // in the map of the child Interpreter to have it for the future.

View File

@ -0,0 +1,34 @@
//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------
// RUN: cat %s | %cling 2>&1 | FileCheck %s
// Test to check the functionality of the multiple interpreters.
// Create a "child" interpreter and use gCling as its "parent".
#include "cling/Interpreter/Interpreter.h"
#include <iostream>
const char * const argV = "cling";
cling::Interpreter *ChildInterp = new cling::Interpreter(*gCling, 1, &argV);
//declare something in the parent interpreter
gCling->declare("void foo(){ std::cout << \"foo(void)\" << std::endl; }");
//then execute it from the child interpreter
ChildInterp->execute("foo()");
//CHECK:foo(void)
//check if function overloading works
gCling->declare("void foo(int i){ std::cout << \"foo(int)\" << std::endl; }");
ChildInterp->execute("foo(1)");
//CHECK:foo(int)
.q