Added test for MultipleInterpreters, and some changes.
This commit is contained in:
parent
8f51dd1617
commit
4ac0a10a3e
@ -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() { };
|
||||||
|
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
34
test/Utils/MultipleInterpreters.C
Normal file
34
test/Utils/MultipleInterpreters.C
Normal 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
|
Loading…
Reference in New Issue
Block a user