Edited test for Multiple Interps, and added some fixes

This commit is contained in:
Elisavet Sakellari 2016-01-12 17:17:08 +01:00 committed by sftnight
parent 4ac0a10a3e
commit 01a4526fc6
6 changed files with 67 additions and 54 deletions

View File

@ -1,10 +1,9 @@
#include "cling/Utils/ASTImportSource.h"
#include "ASTImportSource.h"
#include "cling/Interpreter/Interpreter.h"
using namespace clang;
namespace cling {
namespace utils {
ASTImportSource::ASTImportSource(cling::Interpreter *parent_interpreter,
cling::Interpreter *child_interpreter) :
@ -34,9 +33,16 @@ namespace cling {
// once clang supports the import of function templates.
if (!(declToImport->isFunctionOrFunctionTemplate() && declToImport->isTemplateDecl())) {
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
// DeclarationName coming from the parent, in my map.
m_DeclName_map[childDeclName.getAsString()] = parentDeclName;
m_DeclName_map[childDeclName] = parentDeclName;
}
}
}
@ -51,13 +57,16 @@ namespace cling {
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
// DeclarationName coming from the parent, in my map.
// (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;
m_DeclName_map[childDeclName] = parentDeclName;
// 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.
@ -113,20 +122,21 @@ namespace cling {
assert(childCurrentDeclContext->hasExternalVisibleStorage() &&
"DeclContext has no visible decls in storage");
// Check if we have already imported this Decl (Context).
if (m_DeclName_map.find(childDeclName.getAsString()) != m_DeclName_map.end())
return true;
// Clang will call FindExternalVisibleDeclsByName with an
// IdentifierInfo valid for the child interpreter. Get the
// IdentifierInfo's StringRef representation.
// Get the identifier info from the parent interpreter
// for this Name.
llvm::StringRef name(childDeclName.getAsString());
IdentifierTable &parentIdentifierTable =
m_parent_Interp->getCI()->getASTContext().Idents;
IdentifierInfo &parentIdentifierInfo = parentIdentifierTable.get(name);
DeclarationName parentDeclName(&parentIdentifierInfo);
//Check if we have already found this declaration Name before
DeclarationName parentDeclName;
std::map <clang::DeclarationName, clang::DeclarationName>::iterator II;
if ((II = m_DeclName_map.find(childDeclName)) != m_DeclName_map.end()) {
parentDeclName = II->second;
} else {
// Get the identifier info from the parent interpreter
// for this Name.
llvm::StringRef name(childDeclName.getAsString());
IdentifierTable &parentIdentifierTable =
m_parent_Interp->getCI()->getASTContext().Idents;
IdentifierInfo &parentIdentifierInfo = parentIdentifierTable.get(name);
DeclarationName parentDeclNameTemp(&parentIdentifierInfo);
parentDeclName = parentDeclNameTemp;
}
// Search in the map of the stored Decl Contexts for this
// Decl Context.
@ -156,5 +166,4 @@ namespace cling {
}
return false;
}
} // end namespace utils
} // end namespace cling

View File

@ -31,7 +31,6 @@ namespace cling {
}
namespace cling {
namespace utils {
class ASTImportSource : public clang::ExternalASTSource {
@ -54,7 +53,7 @@ namespace cling {
/// Value: The DeclarationName of this Decl(Context) is the one
/// that comes from the first Interpreter.
///
std::map <std::string, clang::DeclarationName> m_DeclName_map;
std::map <clang::DeclarationName, clang::DeclarationName > m_DeclName_map;
public:
ASTImportSource(cling::Interpreter *parent_interpreter,
@ -88,6 +87,5 @@ namespace cling {
clang::DeclarationName &parentDeclName,
const clang::DeclContext *childCurrentDeclContext);
};
} // end namespace utils
} // end namespace cling
#endif //CLING_ASTIMPORTSOURCE_H

View File

@ -20,6 +20,7 @@ set( LLVM_LINK_COMPONENTS
add_cling_library(clingInterpreter
AutoSynthesizer.cpp
AutoloadCallback.cpp
ASTImportSource.cpp
BackendPasses.cpp
CheckEmptyTransactionTransformer.cpp
CIFactory.cpp

View File

@ -16,6 +16,7 @@
#include "IncrementalExecutor.h"
#include "IncrementalParser.h"
#include "MultiplexInterpreterCallbacks.h"
#include "ASTImportSource.h"
#include "cling/Interpreter/CIFactory.h"
#include "cling/Interpreter/ClangInternalState.h"
@ -25,7 +26,6 @@
#include "cling/Interpreter/Transaction.h"
#include "cling/Interpreter/Value.h"
#include "cling/Utils/AST.h"
#include "cling/Utils/ASTImportSource.h"
#include "cling/Interpreter/AutoloadCallback.h"
#include "clang/AST/ASTContext.h"
@ -222,37 +222,41 @@ namespace cling {
m_IncrParser->commitTransaction(I);
// Disable suggestions for ROOT
bool showSuggestions = !llvm::StringRef(ClingStringify(CLING_VERSION)).startswith("ROOT");
std::unique_ptr<InterpreterCallbacks>
AutoLoadCB(new AutoloadCallback(this, showSuggestions));
setCallbacks(std::move(AutoLoadCB));
// We need InterpreterCallbacks only if it is a parent Interpreter.
if (!isChildInterp) {
std::unique_ptr<InterpreterCallbacks>
AutoLoadCB(new AutoloadCallback(this, showSuggestions));
setCallbacks(std::move(AutoLoadCB));
}
}
///\brief Constructor for the child Interpreter.
/// Passing the parent Interpreter as an argument.
///
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) :
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);
ASTImportSource *myExternalSource =
new ASTImportSource(&parentInterpreter, this);
llvm::IntrusiveRefCntPtr <ExternalASTSource>
astContextExternalSource(myExternalSource);
this->getCI()->getASTContext().ExternalSource.resetWithoutRelease();
this->getCI()->getASTContext().setExternalSource(astContextExternalSource);
getCI()->getASTContext().ExternalSource.resetWithoutRelease();
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();
// Inform the Translation Unit Decl of I2 that it has to search somewhere
// else to find the declarations.
getCI()->getASTContext().getTranslationUnitDecl()->setHasExternalVisibleStorage();
// Give my IncrementalExecutor a pointer to the Incremental executor
// of the parent Interpreter.
// Give my IncrementalExecutor a pointer to the Incremental executor of the
// parent Interpreter.
m_Executor->setExternalIncrementalExecutor(parentInterpreter.m_Executor.get());
}

View File

@ -8,7 +8,6 @@
add_cling_library(clingUtils
AST.cpp
ASTImportSource.cpp
LINK_LIBS
clangCodeGen

View File

@ -12,23 +12,25 @@
// Create a "child" interpreter and use gCling as its "parent".
#include "cling/Interpreter/Interpreter.h"
#include <iostream>
#include <cstdio>
const char * const argV = "cling";
cling::Interpreter ChildInterp(*gCling, 1, &argV);
cling::Interpreter *ChildInterp = new cling::Interpreter(*gCling, 1, &argV);
//Declare something in the parent interpreter
.rawInput 1
void foo(){ printf("foo(void)\n"); }
void foo(int i){ printf("foo(int) = %d\n", i); }
.rawInput 0
// OR
//gCling->declare("void foo(){ llvm::outs() << \"foo(void)\\n\"; }");
//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()");
//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)
//Check if function overloading works
ChildInterp.execute("foo(1)");
//CHECK:foo(int) = 1
.q