Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
2 changes: 2 additions & 0 deletions clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
bool isInSameModule(const Module *M1, const Module *M2) const;

TranslationUnitDecl *getTranslationUnitDecl() const {
assert(TUDecl->getMostRecentDecl() == TUDecl &&
"The active TU is not current one!");
return TUDecl->getMostRecentDecl();
}
void addTranslationUnitDecl() {
Expand Down
39 changes: 25 additions & 14 deletions clang/include/clang/Interpreter/Interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,31 +175,42 @@ class Interpreter {
llvm::Expected<llvm::orc::ExecutorAddr>
getSymbolAddressFromLinkerName(llvm::StringRef LinkerName) const;

const llvm::SmallVectorImpl<Expr *> &getValuePrintingInfo() const {
return ValuePrintingInfo;
}

Expr *SynthesizeExpr(Expr *E);
std::unique_ptr<llvm::Module> GenModule(IncrementalAction *Action = nullptr);
PartialTranslationUnit &RegisterPTU(TranslationUnitDecl *TU,
std::unique_ptr<llvm::Module> M = {},
IncrementalAction *Action = nullptr);

private:
size_t getEffectivePTUSize() const;
void markUserCodeStart();
llvm::Expected<Expr *> ExtractValueFromExpr(Expr *E);
llvm::Expected<llvm::orc::ExecutorAddr> CompileDtorCall(CXXRecordDecl *CXXRD);

CodeGenerator *getCodeGen(IncrementalAction *Action = nullptr) const;
std::unique_ptr<llvm::Module> GenModule(IncrementalAction *Action = nullptr);
PartialTranslationUnit &RegisterPTU(TranslationUnitDecl *TU,
std::unique_ptr<llvm::Module> M = {},
IncrementalAction *Action = nullptr);

// A cache for the compiled destructors used to for de-allocation of managed
// clang::Values.
llvm::DenseMap<CXXRecordDecl *, llvm::orc::ExecutorAddr> Dtors;
mutable llvm::DenseMap<CXXRecordDecl *, llvm::orc::ExecutorAddr> Dtors;

llvm::SmallVector<Expr *, 4> ValuePrintingInfo;
std::array<Expr *, 4> ValuePrintingInfo;

std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder;

/// @}
/// @name Value and pretty printing support
/// @{

std::string ValueDataToString(const Value &V) const;
std::string ValueTypeToString(const Value &V) const;

llvm::Expected<Expr *> convertExprToValue(Expr *E);

// When we deallocate clang::Value we need to run the destructor of the type.
// This function forces emission of the needed dtor.
llvm::Expected<llvm::orc::ExecutorAddr>
CompileDtorCall(CXXRecordDecl *CXXRD) const;

/// @}
/// @name Code generation
/// @{
CodeGenerator *getCodeGen(IncrementalAction *Action = nullptr) const;
};
} // namespace clang

Expand Down
7 changes: 2 additions & 5 deletions clang/include/clang/Interpreter/Value.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ class REPL_EXTERNAL_VISIBILITY Value {
};

Value() = default;
Value(Interpreter *In, void *Ty);
Value(const Interpreter *In, void *Ty);
Value(const Value &RHS);
Value(Value &&RHS) noexcept;
Value &operator=(const Value &RHS);
Expand All @@ -124,9 +124,7 @@ class REPL_EXTERNAL_VISIBILITY Value {
void dump() const;
void clear();

ASTContext &getASTContext();
const ASTContext &getASTContext() const;
Interpreter &getInterpreter();
const Interpreter &getInterpreter() const;
QualType getType() const;

Expand Down Expand Up @@ -193,7 +191,7 @@ class REPL_EXTERNAL_VISIBILITY Value {
}
};

Interpreter *Interp = nullptr;
const Interpreter *Interp = nullptr;
void *OpaqueType = nullptr;
Storage Data;
Kind ValueKind = K_Unspecified;
Expand All @@ -205,6 +203,5 @@ template <> inline void *Value::as() const {
return Data.m_Ptr;
return (void *)as<uintptr_t>();
}

} // namespace clang
#endif
1 change: 1 addition & 0 deletions clang/lib/Interpreter/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ add_clang_library(clangInterpreter
InterpreterUtils.cpp
RemoteJITUtils.cpp
Value.cpp
InterpreterValuePrinter.cpp
${WASM_SRC}
PARTIAL_SOURCES_INTENDED

Expand Down
43 changes: 26 additions & 17 deletions clang/lib/Interpreter/Interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ class InProcessPrintingASTConsumer final : public MultiplexConsumer {
if (auto *TLSD = llvm::dyn_cast<TopLevelStmtDecl>(D))
if (TLSD && TLSD->isSemiMissing()) {
auto ExprOrErr =
Interp.ExtractValueFromExpr(cast<Expr>(TLSD->getStmt()));
Interp.convertExprToValue(cast<Expr>(TLSD->getStmt()));
if (llvm::Error E = ExprOrErr.takeError()) {
llvm::logAllUnhandledErrors(std::move(E), llvm::errs(),
"Value printing failed: ");
Expand Down Expand Up @@ -440,11 +440,10 @@ const char *const Runtimes = R"(
#define __CLANG_REPL__ 1
#ifdef __cplusplus
#define EXTERN_C extern "C"
void *__clang_Interpreter_SetValueWithAlloc(void*, void*, void*);
struct __clang_Interpreter_NewTag{} __ci_newtag;
void* operator new(__SIZE_TYPE__, void* __p, __clang_Interpreter_NewTag) noexcept;
template <class T, class = T (*)() /*disable for arrays*/>
void __clang_Interpreter_SetValueCopyArr(T* Src, void* Placement, unsigned long Size) {
void __clang_Interpreter_SetValueCopyArr(const T* Src, void* Placement, unsigned long Size) {
for (auto Idx = 0; Idx < Size; ++Idx)
new ((void*)(((T*)Placement) + Idx), __ci_newtag) T(Src[Idx]);
}
Expand All @@ -454,8 +453,12 @@ const char *const Runtimes = R"(
}
#else
#define EXTERN_C extern
EXTERN_C void *memcpy(void *restrict dst, const void *restrict src, __SIZE_TYPE__ n);
EXTERN_C inline void __clang_Interpreter_SetValueCopyArr(const void* Src, void* Placement, unsigned long Size) {
memcpy(Placement, Src, Size);
}
#endif // __cplusplus

EXTERN_C void *__clang_Interpreter_SetValueWithAlloc(void*, void*, void*);
EXTERN_C void __clang_Interpreter_SetValueNoAlloc(void *This, void *OutVal, void *OpaqueType, ...);
)";

Expand All @@ -470,12 +473,12 @@ Interpreter::create(std::unique_ptr<CompilerInstance> CI,

// Add runtime code and set a marker to hide it from user code. Undo will not
// go through that.
auto PTU = Interp->Parse(Runtimes);
if (!PTU)
return PTU.takeError();
Err = Interp->ParseAndExecute(Runtimes);
if (Err)
return std::move(Err);

Interp->markUserCodeStart();

Interp->ValuePrintingInfo.resize(4);
return std::move(Interp);
}

Expand Down Expand Up @@ -524,12 +527,11 @@ Interpreter::createWithCUDA(std::unique_ptr<CompilerInstance> CI,
return std::move(Interp);
}

CompilerInstance *Interpreter::getCompilerInstance() { return CI.get(); }
const CompilerInstance *Interpreter::getCompilerInstance() const {
return CI.get();
return const_cast<Interpreter *>(this)->getCompilerInstance();
}

CompilerInstance *Interpreter::getCompilerInstance() { return CI.get(); }

llvm::Expected<llvm::orc::LLJIT &> Interpreter::getExecutionEngine() {
if (!IncrExecutor) {
if (auto Err = CreateExecutor())
Expand Down Expand Up @@ -610,7 +612,14 @@ Interpreter::Parse(llvm::StringRef Code) {
if (!TuOrErr)
return TuOrErr.takeError();

return RegisterPTU(*TuOrErr);
PTUs.emplace_back(PartialTranslationUnit());
PartialTranslationUnit &LastPTU = PTUs.back();
LastPTU.TUPart = *TuOrErr;

if (std::unique_ptr<llvm::Module> M = GenModule())
LastPTU.TheModule = std::move(M);

return LastPTU;
}

static llvm::Expected<llvm::orc::JITTargetMachineBuilder>
Expand Down Expand Up @@ -806,13 +815,13 @@ Interpreter::GenModule(IncrementalAction *Action) {
// of the module which does not map well to CodeGen's design. To work this
// around we created an empty module to make CodeGen happy. We should make
// sure it always stays empty.
assert(((!CachedInCodeGenModule ||
!getCompilerInstance()->getPreprocessorOpts().Includes.empty()) ||
(CachedInCodeGenModule->empty() &&
assert((!CachedInCodeGenModule ||
!getCompilerInstance()->getPreprocessorOpts().Includes.empty()) ||
((CachedInCodeGenModule->empty() &&
CachedInCodeGenModule->global_empty() &&
CachedInCodeGenModule->alias_empty() &&
CachedInCodeGenModule->ifunc_empty())) &&
"CodeGen wrote to a readonly module");
"CodeGen wrote to a readonly module");
std::unique_ptr<llvm::Module> M(CG->ReleaseModule());
CG->StartModule("incr_module_" + std::to_string(ID++), M->getContext());
return M;
Expand All @@ -828,4 +837,4 @@ CodeGenerator *Interpreter::getCodeGen(IncrementalAction *Action) const {
return nullptr;
return static_cast<CodeGenAction *>(WrappedAct)->getCodeGenerator();
}
} // namespace clang
} // end namespace clang
8 changes: 5 additions & 3 deletions clang/lib/Interpreter/InterpreterUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//

#include "InterpreterUtils.h"
#include "clang/AST/QualTypeNames.h"

namespace clang {

Expand Down Expand Up @@ -81,7 +82,7 @@ NamedDecl *LookupNamed(Sema &S, llvm::StringRef Name,
else {
const DeclContext *PrimaryWithin = nullptr;
if (const auto *TD = dyn_cast<TagDecl>(Within))
PrimaryWithin = llvm::dyn_cast_or_null<DeclContext>(TD->getDefinition());
PrimaryWithin = dyn_cast_if_present<DeclContext>(TD->getDefinition());
else
PrimaryWithin = Within->getPrimaryContext();

Expand All @@ -97,15 +98,16 @@ NamedDecl *LookupNamed(Sema &S, llvm::StringRef Name,
R.resolveKind();

if (R.isSingleResult())
return llvm::dyn_cast<NamedDecl>(R.getFoundDecl());
return dyn_cast<NamedDecl>(R.getFoundDecl());

return nullptr;
}

std::string GetFullTypeName(ASTContext &Ctx, QualType QT) {
QualType FQT = TypeName::getFullyQualifiedType(QT, Ctx);
PrintingPolicy Policy(Ctx.getPrintingPolicy());
Policy.SuppressScope = false;
Policy.AnonymousTagLocations = false;
return QT.getAsString(Policy);
return FQT.getAsString(Policy);
}
} // namespace clang
2 changes: 1 addition & 1 deletion clang/lib/Interpreter/InterpreterUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ NamespaceDecl *LookupNamespace(Sema &S, llvm::StringRef Name,
const DeclContext *Within = nullptr);

NamedDecl *LookupNamed(Sema &S, llvm::StringRef Name,
const DeclContext *Within);
const DeclContext *Within = nullptr);

std::string GetFullTypeName(ASTContext &Ctx, QualType QT);
} // namespace clang
Expand Down
Loading
Loading