v.g.vassilev updated this revision to Diff 382939.
v.g.vassilev marked 2 inline comments as done.
v.g.vassilev added a comment.
Address comments
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D112663/new/
https://reviews.llvm.org/D112663
Files:
clang/include/clang/CodeGen/ModuleBuilder.h
clang/include/clang/Interpreter/Interpreter.h
clang/lib/CodeGen/ModuleBuilder.cpp
clang/lib/Interpreter/IncrementalExecutor.cpp
clang/lib/Interpreter/IncrementalExecutor.h
clang/lib/Interpreter/IncrementalParser.cpp
clang/lib/Interpreter/IncrementalParser.h
clang/lib/Interpreter/Interpreter.cpp
clang/unittests/Interpreter/CMakeLists.txt
clang/unittests/Interpreter/IncrementalProcessingTest.cpp
clang/unittests/Interpreter/InterpreterTest.cpp
Index: clang/unittests/Interpreter/InterpreterTest.cpp
===================================================================
--- clang/unittests/Interpreter/InterpreterTest.cpp
+++ clang/unittests/Interpreter/InterpreterTest.cpp
@@ -14,8 +14,13 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclGroup.h"
+#include "clang/AST/Mangle.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/Sema.h"
+
+#include "llvm/Support/TargetSelect.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@@ -123,4 +128,110 @@
EXPECT_EQ("Parsing failed.", llvm::toString(std::move(Err)));
}
+static std::string MangleName(NamedDecl *ND) {
+ ASTContext &C = ND->getASTContext();
+ std::unique_ptr<MangleContext> MangleC(C.createMangleContext());
+ std::string mangledName;
+ llvm::raw_string_ostream RawStr(mangledName);
+ MangleC->mangleName(ND, RawStr);
+ return RawStr.str();
+}
+
+struct LLVMInitRAII {
+ LLVMInitRAII() {
+ llvm::InitializeNativeTarget();
+ llvm::InitializeNativeTargetAsmPrinter();
+ }
+ ~LLVMInitRAII() { llvm::llvm_shutdown(); }
+} LLVMInit;
+
+TEST(IncrementalProcessing, FindMangledNameSymbol) {
+
+ std::unique_ptr<Interpreter> Interp = createInterpreter();
+
+ auto &PTU(cantFail(Interp->Parse("int f(const char*) {return 0;}")));
+ EXPECT_EQ(1U, DeclsSize(PTU.TUPart));
+ auto R1DeclRange = PTU.TUPart->decls();
+
+ NamedDecl *FD = cast<FunctionDecl>(*R1DeclRange.begin());
+ // Lower the PTU
+ if (llvm::Error Err = Interp->Execute(PTU)) {
+ // We cannot execute on the platform.
+ consumeError(std::move(Err));
+ return;
+ }
+
+ std::string MangledName = MangleName(FD);
+ auto Addr = cantFail(Interp->getSymbolAddress(MangledName));
+ EXPECT_TRUE(Addr != 0);
+ GlobalDecl GD(FD);
+ EXPECT_TRUE(Addr == cantFail(Interp->getSymbolAddress(GD)));
+}
+
+static void *AllocateObject(TypeDecl *TD, Interpreter &Interp) {
+ std::string Name = TD->getQualifiedNameAsString();
+ const clang::Type *RDTy = TD->getTypeForDecl();
+ clang::ASTContext &C = Interp.getCompilerInstance()->getASTContext();
+ size_t Size = C.getTypeSize(RDTy);
+ void *Addr = malloc(Size);
+
+ // Tell the interpreter to call the default ctor with this memory. Synthesize:
+ // new (loc) ClassName;
+ static unsigned Counter = 0;
+ std::stringstream SS;
+ SS << "auto _v" << Counter++ << " = "
+ << "new ((void*)" << Addr << ")" << Name << "();";
+
+ auto R = Interp.ParseAndExecute(SS.str());
+ if (!R)
+ return nullptr;
+
+ return Addr;
+}
+
+static NamedDecl *LookupSingleName(Interpreter &Interp, const char *Name) {
+ Sema &SemaRef = Interp.getCompilerInstance()->getSema();
+ ASTContext &C = SemaRef.getASTContext();
+ DeclarationName DeclName = &C.Idents.get(Name);
+ LookupResult R(SemaRef, DeclName, SourceLocation(), Sema::LookupOrdinaryName);
+ SemaRef.LookupName(R, SemaRef.TUScope);
+ assert(!R.empty());
+ return R.getFoundDecl();
+}
+
+TEST(IncrementalProcessing, InstantiateTemplate) {
+ std::unique_ptr<Interpreter> Interp = createInterpreter();
+
+ llvm::cantFail(Interp->Parse("void* operator new(__SIZE_TYPE__, void* __p);"
+ "extern \"C\" int printf(const char*,...);"
+ "class A {};"
+ "struct B {"
+ " template<typename T>"
+ " int callme(T) { return 42; }"
+ "};"));
+ auto &PTU = llvm::cantFail(Interp->Parse("auto _t = &B::callme<A*>;"));
+ auto PTUDeclRange = PTU.TUPart->decls();
+ EXPECT_TRUE(std::distance(PTUDeclRange.begin(), PTUDeclRange.end()));
+
+ // Lower the PTU
+ if (llvm::Error Err = Interp->Execute(PTU)) {
+ // We cannot execute on the platform.
+ consumeError(std::move(Err));
+ return;
+ }
+
+ TypeDecl *TD = cast<TypeDecl>(LookupSingleName(*Interp, "A"));
+ void *NewA = AllocateObject(TD, *Interp);
+
+ // Find back the template specialization
+ VarDecl *VD = static_cast<VarDecl *>(*PTUDeclRange.begin());
+ UnaryOperator *UO = llvm::cast<UnaryOperator>(VD->getInit());
+ NamedDecl *TmpltSpec = llvm::cast<DeclRefExpr>(UO->getSubExpr())->getDecl();
+
+ std::string MangledName = MangleName(TmpltSpec);
+ typedef int (*TemplateSpecFn)(void *);
+ auto fn = (TemplateSpecFn)cantFail(Interp->getSymbolAddress(MangledName));
+ EXPECT_TRUE(42 == fn(NewA));
+}
+
} // end anonymous namespace
Index: clang/unittests/Interpreter/IncrementalProcessingTest.cpp
===================================================================
--- clang/unittests/Interpreter/IncrementalProcessingTest.cpp
+++ clang/unittests/Interpreter/IncrementalProcessingTest.cpp
@@ -15,7 +15,9 @@
#include "clang/Interpreter/Interpreter.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/Parser.h"
+#include "clang/Sema/Lookup.h"
#include "clang/Sema/Sema.h"
+#include "clang/Sema/TemplateDeduction.h"
#include "llvm/ADT/Triple.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
Index: clang/unittests/Interpreter/CMakeLists.txt
===================================================================
--- clang/unittests/Interpreter/CMakeLists.txt
+++ clang/unittests/Interpreter/CMakeLists.txt
@@ -1,4 +1,5 @@
set(LLVM_LINK_COMPONENTS
+ ${LLVM_TARGETS_TO_BUILD}
Core
)
@@ -11,6 +12,7 @@
clangBasic
clangInterpreter
clangFrontend
+ clangSema
)
# Exceptions on Windows are not yet supported.
Index: clang/lib/Interpreter/Interpreter.cpp
===================================================================
--- clang/lib/Interpreter/Interpreter.cpp
+++ clang/lib/Interpreter/Interpreter.cpp
@@ -223,11 +223,31 @@
}
llvm::Expected<llvm::JITTargetAddress>
-Interpreter::getSymbolAddress(llvm::StringRef UnmangledName) const {
+Interpreter::getSymbolAddress(GlobalDecl GD) const {
+ if (!IncrExecutor)
+ return llvm::make_error<llvm::StringError>("Operation failed. "
+ "No execution engine",
+ std::error_code());
+ llvm::StringRef MangledName = IncrParser->GetMangledName(GD);
+ return getSymbolAddress(MangledName);
+}
+
+llvm::Expected<llvm::JITTargetAddress>
+Interpreter::getSymbolAddress(llvm::StringRef IRName) const {
+ if (!IncrExecutor)
+ return llvm::make_error<llvm::StringError>("Operation failed. "
+ "No execution engine",
+ std::error_code());
+
+ return IncrExecutor->getSymbolAddress(IRName, IncrementalExecutor::IRName);
+}
+
+llvm::Expected<llvm::JITTargetAddress>
+Interpreter::getSymbolAddressFromLinkerName(llvm::StringRef Name) const {
if (!IncrExecutor)
return llvm::make_error<llvm::StringError>("Operation failed. "
"No execution engine",
std::error_code());
- return IncrExecutor->getSymbolAddress(UnmangledName);
+ return IncrExecutor->getSymbolAddress(Name, IncrementalExecutor::LinkerName);
}
Index: clang/lib/Interpreter/IncrementalParser.h
===================================================================
--- clang/lib/Interpreter/IncrementalParser.h
+++ clang/lib/Interpreter/IncrementalParser.h
@@ -15,6 +15,8 @@
#include "clang/Interpreter/PartialTranslationUnit.h"
+#include "clang/AST/GlobalDecl.h"
+
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Error.h"
@@ -69,6 +71,10 @@
/// \c TranslationUnitDecl and \c llvm::Module corresponding to the input.
llvm::Expected<PartialTranslationUnit &> Parse(llvm::StringRef Input);
+ /// Uses the CodeGenModule mangled name cache and avoids recomputing.
+ ///\returns the mangled name of a \c GD.
+ llvm::StringRef GetMangledName(GlobalDecl GD) const;
+
private:
llvm::Expected<PartialTranslationUnit &> ParseOrWrapTopLevelDecl();
};
Index: clang/lib/Interpreter/IncrementalParser.cpp
===================================================================
--- clang/lib/Interpreter/IncrementalParser.cpp
+++ clang/lib/Interpreter/IncrementalParser.cpp
@@ -291,4 +291,11 @@
return PTU;
}
+
+llvm::StringRef IncrementalParser::GetMangledName(GlobalDecl GD) const {
+ CodeGenerator *CG = getCodeGen(Act.get());
+ assert(CG);
+ return CG->GetMangledName(GD);
+}
+
} // end namespace clang
Index: clang/lib/Interpreter/IncrementalExecutor.h
===================================================================
--- clang/lib/Interpreter/IncrementalExecutor.h
+++ clang/lib/Interpreter/IncrementalExecutor.h
@@ -35,6 +35,8 @@
llvm::orc::ThreadSafeContext &TSCtx;
public:
+ enum SymbolNameKind { IRName, LinkerName };
+
IncrementalExecutor(llvm::orc::ThreadSafeContext &TSC, llvm::Error &Err,
const llvm::Triple &Triple);
~IncrementalExecutor();
@@ -42,7 +44,7 @@
llvm::Error addModule(std::unique_ptr<llvm::Module> M);
llvm::Error runCtors() const;
llvm::Expected<llvm::JITTargetAddress>
- getSymbolAddress(llvm::StringRef UnmangledName) const;
+ getSymbolAddress(llvm::StringRef Name, SymbolNameKind NameKind) const;
};
} // end namespace clang
Index: clang/lib/Interpreter/IncrementalExecutor.cpp
===================================================================
--- clang/lib/Interpreter/IncrementalExecutor.cpp
+++ clang/lib/Interpreter/IncrementalExecutor.cpp
@@ -61,8 +61,11 @@
}
llvm::Expected<llvm::JITTargetAddress>
-IncrementalExecutor::getSymbolAddress(llvm::StringRef UnmangledName) const {
- auto Sym = Jit->lookup(UnmangledName);
+IncrementalExecutor::getSymbolAddress(llvm::StringRef Name,
+ SymbolNameKind NameKind) const {
+ auto Sym = (NameKind == LinkerName) ? Jit->lookupLinkerMangled(Name)
+ : Jit->lookup(Name);
+
if (!Sym)
return Sym.takeError();
return Sym->getAddress();
Index: clang/lib/CodeGen/ModuleBuilder.cpp
===================================================================
--- clang/lib/CodeGen/ModuleBuilder.cpp
+++ clang/lib/CodeGen/ModuleBuilder.cpp
@@ -122,6 +122,10 @@
return D;
}
+ llvm::StringRef GetMangledName(GlobalDecl GD) {
+ return Builder->getMangledName(GD);
+ }
+
llvm::Constant *GetAddrOfGlobal(GlobalDecl global, bool isForDefinition) {
return Builder->GetAddrOfGlobal(global, ForDefinition_t(isForDefinition));
}
@@ -325,6 +329,10 @@
return static_cast<CodeGeneratorImpl*>(this)->GetDeclForMangledName(name);
}
+llvm::StringRef CodeGenerator::GetMangledName(GlobalDecl GD) {
+ return static_cast<CodeGeneratorImpl *>(this)->GetMangledName(GD);
+}
+
llvm::Constant *CodeGenerator::GetAddrOfGlobal(GlobalDecl global,
bool isForDefinition) {
return static_cast<CodeGeneratorImpl*>(this)
Index: clang/include/clang/Interpreter/Interpreter.h
===================================================================
--- clang/include/clang/Interpreter/Interpreter.h
+++ clang/include/clang/Interpreter/Interpreter.h
@@ -16,6 +16,8 @@
#include "clang/Interpreter/PartialTranslationUnit.h"
+#include "clang/AST/GlobalDecl.h"
+
#include "llvm/ExecutionEngine/JITSymbol.h"
#include "llvm/Support/Error.h"
@@ -66,8 +68,20 @@
return Execute(*PTU);
return llvm::Error::success();
}
+
+ ///\returns the \c JITTargetAddress of a \c GlobalDecl. This interface uses
+ /// the CodeGenModule's internal mangling cache to avoid recomputing the
+ /// mangled name.
+ llvm::Expected<llvm::JITTargetAddress> getSymbolAddress(GlobalDecl GD) const;
+
+ ///\returns the \c JITTargetAddress of a given name as written in the IR.
+ llvm::Expected<llvm::JITTargetAddress>
+ getSymbolAddress(llvm::StringRef IRName) const;
+
+ ///\returns the \c JITTargetAddress of a given name as written in the object
+ /// file.
llvm::Expected<llvm::JITTargetAddress>
- getSymbolAddress(llvm::StringRef UnmangledName) const;
+ getSymbolAddressFromLinkerName(llvm::StringRef LinkerName) const;
};
} // namespace clang
Index: clang/include/clang/CodeGen/ModuleBuilder.h
===================================================================
--- clang/include/clang/CodeGen/ModuleBuilder.h
+++ clang/include/clang/CodeGen/ModuleBuilder.h
@@ -74,6 +74,10 @@
/// This may return null if there was no matching declaration.
const Decl *GetDeclForMangledName(llvm::StringRef MangledName);
+ /// Given a global declaration, return a mangled name for this declaration
+ /// which has been added to this code generator via a Handle method.
+ llvm::StringRef GetMangledName(GlobalDecl GD);
+
/// Return the LLVM address of the given global entity.
///
/// \param isForDefinition If true, the caller intends to define the
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits