v.g.vassilev created this revision.
v.g.vassilev added reviewers: rsmith, sgraenitz, lhames, thakis.
Herald added a subscriber: mgorny.
v.g.vassilev requested review of this revision.

Repository:
  rC Clang

https://reviews.llvm.org/D112663

Files:
  clang/include/clang/Interpreter/Interpreter.h
  clang/lib/Interpreter/IncrementalExecutor.cpp
  clang/lib/Interpreter/IncrementalExecutor.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,109 @@
   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 *ND = cast<NamedDecl>(*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(ND);
+  auto Addr =
+      cantFail(Interp->getSymbolAddress(MangledName, /*IsMangled=*/true));
+  EXPECT_TRUE(Addr != 0);
+}
+
+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 *loc = 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*)" << loc << ")" << Name << "();";
+
+  auto R = Interp.ParseAndExecute(ss.str());
+  if (!R)
+    return nullptr;
+
+  return loc;
+}
+
+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, /*IsMangled=*/true));
+  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,12 @@
 }
 
 llvm::Expected<llvm::JITTargetAddress>
-Interpreter::getSymbolAddress(llvm::StringRef UnmangledName) const {
+Interpreter::getSymbolAddress(llvm::StringRef Name,
+                              bool IsMangled /*=false*/) 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, IsMangled);
 }
Index: clang/lib/Interpreter/IncrementalExecutor.h
===================================================================
--- clang/lib/Interpreter/IncrementalExecutor.h
+++ clang/lib/Interpreter/IncrementalExecutor.h
@@ -42,7 +42,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, bool IsMangled = false) const;
 };
 
 } // end namespace clang
Index: clang/lib/Interpreter/IncrementalExecutor.cpp
===================================================================
--- clang/lib/Interpreter/IncrementalExecutor.cpp
+++ clang/lib/Interpreter/IncrementalExecutor.cpp
@@ -61,8 +61,15 @@
 }
 
 llvm::Expected<llvm::JITTargetAddress>
-IncrementalExecutor::getSymbolAddress(llvm::StringRef UnmangledName) const {
-  auto Sym = Jit->lookup(UnmangledName);
+IncrementalExecutor::getSymbolAddress(llvm::StringRef Name,
+                                      bool IsMangled /*=false*/) const {
+  if (IsMangled) {
+    auto Sym = Jit->lookupLinkerMangled(Name);
+    if (!Sym)
+      return Sym.takeError();
+    return Sym->getAddress();
+  }
+  auto Sym = Jit->lookup(Name);
   if (!Sym)
     return Sym.takeError();
   return Sym->getAddress();
Index: clang/include/clang/Interpreter/Interpreter.h
===================================================================
--- clang/include/clang/Interpreter/Interpreter.h
+++ clang/include/clang/Interpreter/Interpreter.h
@@ -67,7 +67,7 @@
     return llvm::Error::success();
   }
   llvm::Expected<llvm::JITTargetAddress>
-  getSymbolAddress(llvm::StringRef UnmangledName) const;
+  getSymbolAddress(llvm::StringRef Name, bool IsMangled = false) const;
 };
 } // namespace clang
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D112663: ... Vassil Vassilev via Phabricator via cfe-commits

Reply via email to