From f9f829c48e380604b13906514131b7b5aa620f21 Mon Sep 17 00:00:00 2001
From: manasij7479 <manasij7479@gmail.com>
Date: Tue, 10 Jun 2014 18:30:14 +0530
Subject: [PATCH] autoloading visitor

---
 include/cling/Interpreter/Interpreter.h |   3 +
 lib/Interpreter/AutoloadingVisitor.cpp  |  82 +++++++++++++
 lib/Interpreter/AutoloadingVisitor.h    |  33 +++++
 lib/Interpreter/Interpreter.cpp         |  19 +++
 tools/CMakeLists.txt                    |   1 -
 tools/Makefile                          |   2 +-
 tools/fwd/CMakeLists.txt                |  20 ---
 tools/fwd/Makefile                      |  25 ----
 tools/fwd/main.cpp                      | 155 ------------------------
 9 files changed, 138 insertions(+), 202 deletions(-)
 create mode 100644 lib/Interpreter/AutoloadingVisitor.cpp
 create mode 100644 lib/Interpreter/AutoloadingVisitor.h
 delete mode 100644 tools/fwd/CMakeLists.txt
 delete mode 100644 tools/fwd/Makefile
 delete mode 100644 tools/fwd/main.cpp

diff --git a/include/cling/Interpreter/Interpreter.h b/include/cling/Interpreter/Interpreter.h
index 78c13afe..03edf12e 100644
--- a/include/cling/Interpreter/Interpreter.h
+++ b/include/cling/Interpreter/Interpreter.h
@@ -614,6 +614,9 @@ namespace cling {
     ///
     void AddAtExitFunc(void (*Func) (void*), void* Arg);
 
+
+    void GenerateAutoloadingMap(llvm::StringRef inFile,llvm::StringRef outFile);
+
     friend class runtime::internal::LifetimeHandler;
     // FIXME: workaround until JIT supports exceptions
     static jmp_buf*& getNullDerefJump() { return m_JumpBuf; }
diff --git a/lib/Interpreter/AutoloadingVisitor.cpp b/lib/Interpreter/AutoloadingVisitor.cpp
new file mode 100644
index 00000000..c9e9de00
--- /dev/null
+++ b/lib/Interpreter/AutoloadingVisitor.cpp
@@ -0,0 +1,82 @@
+#include "AutoloadingVisitor.h"
+namespace cling {
+  bool AutoloadingVisitor::VisitCXXRecordDecl(clang::CXXRecordDecl* Declaration) {
+    if(Declaration->getName().startswith("_")
+          || Declaration->getName().size() == 0
+          /*|| //TODO: Find a way to avoid templates here*/)
+      return true;
+
+    std::vector<NamespacePrinterRAII> scope;
+    clang::DeclContext* c=Declaration->getEnclosingNamespaceContext();
+    while(c->isNamespace()) {
+      clang::NamespaceDecl* n = llvm::cast<clang::NamespaceDecl>(c);
+      scope.emplace_back(n->getNameAsString());
+      c=c->getParent();
+    }
+
+    llvm::outs() << "\n" << Declaration->getKindName()
+             << " __attribute__((annotate(\""
+             << m_InFile << "\"))) "
+             << Declaration->getName() << ";\n";
+    return true;
+  }
+  bool AutoloadingVisitor::VisitFunctionDecl(clang::FunctionDecl* Declaration) {
+
+    if(Declaration->getName().startswith("_")
+        || Declaration->getName().size() == 0
+        || Declaration->isCXXClassMember()
+        || !Declaration->hasBody())
+      return true;
+
+    std::vector<NamespacePrinterRAII> scope;
+    clang::DeclContext* c = Declaration->getEnclosingNamespaceContext();
+    while(c->isNamespace()) {
+      clang::NamespaceDecl* n = llvm::cast<clang::NamespaceDecl>(c);
+      scope.emplace_back(n->getNameAsString());
+      c=c->getParent();
+    }
+
+    llvm::outs() << "\n" << Declaration->getReturnType().getAsString()
+             << " " << Declaration->getName() << " () "
+             << "__attribute__((annotate(\""
+             << m_InFile << "\")));\n";
+
+    //TODO: arg list, not sure if necessary
+
+    return true;
+  }
+
+  bool AutoloadingVisitor::VisitClassTemplateDecl
+        (clang::ClassTemplateDecl* Declaration) {
+   if(Declaration->getName().startswith("_")
+      || Declaration->getName().size() == 0)
+     return true;
+
+    std::vector<NamespacePrinterRAII> scope;
+    clang::DeclContext* c=
+      Declaration->getTemplatedDecl()->getEnclosingNamespaceContext();
+    while(c->isNamespace()) {
+      clang::NamespaceDecl* n = llvm::cast<clang::NamespaceDecl>(c);
+      scope.emplace_back(n->getNameAsString());
+      c=c->getParent();
+    }
+
+    llvm::outs()<<"template <";
+    clang::TemplateParameterList* tl=Declaration->getTemplateParameters();
+    for(auto it=tl->begin();it!=tl->end();++it) {
+      if(llvm::isa<clang::NonTypeTemplateParmDecl>(*it)) {
+        clang::NonTypeTemplateParmDecl* td=llvm::cast<clang::NonTypeTemplateParmDecl>(*it);
+        llvm::outs() << td->getType().getAsString();
+      }
+      else llvm::outs() << "typename";
+      llvm::outs()<<" " << (*it)->getName();
+      if((it+1) != tl->end())
+        llvm::outs() << ", ";
+    }
+    llvm::outs()<<"> class __attribute__((annotate(\""
+            << m_InFile << "\"))) "
+            << Declaration->getName() << ";\n";
+
+    return true;
+  }
+} // end namespace cling
diff --git a/lib/Interpreter/AutoloadingVisitor.h b/lib/Interpreter/AutoloadingVisitor.h
new file mode 100644
index 00000000..07192679
--- /dev/null
+++ b/lib/Interpreter/AutoloadingVisitor.h
@@ -0,0 +1,33 @@
+#ifndef CLING_AUTOLOADING_VISITOR_H
+#define CLING_AUTOLOADING_VISITOR_H
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
+
+namespace cling {
+  class NamespacePrinterRAII {
+  public:
+    NamespacePrinterRAII(std::string name) {
+      llvm::outs()<< "namespace " <<name<<" {\n";
+    }
+    ~NamespacePrinterRAII() {
+      llvm::outs()<<"\n}\n";
+    }
+  };
+
+  class AutoloadingVisitor
+    :public clang::RecursiveASTVisitor<AutoloadingVisitor> {
+  public:
+    AutoloadingVisitor(llvm::StringRef InFile,llvm::StringRef OutFile)
+        :m_InFile(InFile),m_OutFile(OutFile){}
+    bool VisitCXXRecordDecl(clang::CXXRecordDecl* Declaration);
+    bool VisitFunctionDecl(clang::FunctionDecl* Declaration);
+    bool VisitClassTemplateDecl(clang::ClassTemplateDecl* Declaration);
+
+  private:
+    llvm::StringRef m_InFile;
+    llvm::StringRef m_OutFile;
+  };
+}//end namespace cling
+
+#endif
diff --git a/lib/Interpreter/Interpreter.cpp b/lib/Interpreter/Interpreter.cpp
index 4af98c2c..c60db3c1 100644
--- a/lib/Interpreter/Interpreter.cpp
+++ b/lib/Interpreter/Interpreter.cpp
@@ -13,6 +13,7 @@
 #include "DynamicLookup.h"
 #include "IncrementalExecutor.h"
 #include "IncrementalParser.h"
+#include "AutoloadingVisitor.h"
 
 #include "cling/Interpreter/CIFactory.h"
 #include "cling/Interpreter/ClangInternalState.h"
@@ -1186,4 +1187,22 @@ namespace cling {
   void Interpreter::AddAtExitFunc(void (*Func) (void*), void* Arg) {
     m_Executor->AddAtExitFunc(Func, Arg, getLastTransaction());
   }
+
+  void Interpreter::GenerateAutoloadingMap(llvm::StringRef inFile,
+                                           llvm::StringRef outFile) {
+    cling::Transaction* T;
+    this->declare(std::string("#include \"") + std::string(inFile) + "\"", &T);
+    for(auto dcit=T->decls_begin(); dcit!=T->decls_end(); ++dcit) {
+      Transaction::DelayCallInfo& dci = *dcit;
+
+      for(auto dit = dci.m_DGR.begin(); dit != dci.m_DGR.end(); ++dit) {
+        clang::Decl* decl = *dit;
+        auto visitor = new AutoloadingVisitor(inFile,outFile);
+        visitor->TraverseDecl(decl);
+        delete visitor;
+      }
+
+    }
+    return;
+  }
 } // namespace cling
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index a1b1c057..961db625 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -9,6 +9,5 @@
 
 if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../lib/UserInterface/textinput)
   add_subdirectory(driver)
-  add_subdirectory(fwd)
 endif()
 
diff --git a/tools/Makefile b/tools/Makefile
index e816d2a1..f5afba7e 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -9,6 +9,6 @@
 ##===----------------------------------------------------------------------===##
 
 LEVEL := ../../..
-DIRS := driver fwd
+DIRS := driver
 
 include $(LEVEL)/Makefile.common
diff --git a/tools/fwd/CMakeLists.txt b/tools/fwd/CMakeLists.txt
deleted file mode 100644
index bf6fb7d1..00000000
--- a/tools/fwd/CMakeLists.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-set(LLVM_LINK_COMPONENTS
-  Support
-  Option
-  )
-
-add_clang_executable(fwd
-  main.cpp
-  )
-
-target_link_libraries(fwd
-  clangAST
-  clangASTMatchers
-  clangBasic
-  clangFrontend
-  clangTooling
-  clangDriver
-  )
-
-install(TARGETS fwd
-  RUNTIME DESTINATION bin)
\ No newline at end of file
diff --git a/tools/fwd/Makefile b/tools/fwd/Makefile
deleted file mode 100644
index 233436ce..00000000
--- a/tools/fwd/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-##===-------- tools/toolTemplate/Makefile ------------------*- Makefile -*-===##
-#
-#                     The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-CLANG_LEVEL := ../../../clang
-
-TOOLNAME = fwd
-NO_INSTALL = 1
-
-# No plugins, optimize startup time.
-TOOL_NO_EXPORTS = 1
-
-include $(CLANG_LEVEL)/../../Makefile.config
-LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
-USEDLIBS = clangTooling.a clangFrontend.a clangSerialization.a clangDriver.a \
-					 clangRewriteFrontend.a clangRewriteCore.a \
-					 clangParse.a clangSema.a clangAnalysis.a \
-					 clangAST.a clangASTMatchers.a clangEdit.a clangLex.a clangBasic.a
-
-include $(CLANG_LEVEL)/Makefile
diff --git a/tools/fwd/main.cpp b/tools/fwd/main.cpp
deleted file mode 100644
index c9eb17a0..00000000
--- a/tools/fwd/main.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-#include "clang/Frontend/FrontendActions.h"
-#include "clang/Tooling/CommonOptionsParser.h"
-#include "clang/Tooling/Tooling.h"
-#include "llvm/Support/CommandLine.h"
-
-#include "clang/AST/RecursiveASTVisitor.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclTemplate.h"
-
-
-using namespace clang::tooling;
-using namespace llvm;
-
-// Apply a custom category to all command-line options so that they are the
-// only ones displayed.
-static cl::OptionCategory FwdCategory("fwd options");
-
-// CommonOptionsParser declares HelpMessage with a description of the common
-// command-line options related to the compilation database and input files.
-// It's nice to have this help message in all tools.
-static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
-
-// A help message for this specific tool can be added afterwards.
-static cl::extrahelp MoreHelp("\nMore help text...");
-
-class NamespacePrinterRAII {
-public:
-  NamespacePrinterRAII(std::string name) {
-    llvm::outs()<< "namespace " <<name<<" {\n";
-  }
-  ~NamespacePrinterRAII() {
-    llvm::outs()<<"\n}\n";
-  }
-};
-
-class FindNamedClassVisitor
-  :public clang::RecursiveASTVisitor<FindNamedClassVisitor> {
-public:
-  FindNamedClassVisitor(llvm::StringRef InFile):m_File(InFile){}
-  bool VisitCXXRecordDecl(clang::CXXRecordDecl* Declaration) {
-
-      if(Declaration->getName().startswith("_")
-              || Declaration->getName().size()==0
-              /*|| //TODO: Find a way to avoid templates here*/)
-          return true;
-
-      std::vector<NamespacePrinterRAII> scope;
-      clang::DeclContext* c=Declaration->getEnclosingNamespaceContext();
-      while(c->isNamespace()) {
-        clang::NamespaceDecl* n=llvm::cast<clang::NamespaceDecl>(c);
-        scope.emplace_back(n->getNameAsString());
-        c=c->getParent();
-      }
-
-    llvm::outs() << "\n" << Declaration->getKindName()
-                 << " __attribute__((annotate(\""
-                 << m_File << "\"))) "
-                 << Declaration->getName() << ";\n";
-    return true;
-  }
-  bool VisitFunctionDecl(clang::FunctionDecl* Declaration) {
-
-      if(Declaration->getName().startswith("_")
-            || Declaration->getName().size()==0
-            || Declaration->isCXXClassMember()
-            || !Declaration->hasBody())
-        return true;
-
-      std::vector<NamespacePrinterRAII> scope;
-      clang::DeclContext* c=Declaration->getEnclosingNamespaceContext();
-      while(c->isNamespace()) {
-        clang::NamespaceDecl* n=llvm::cast<clang::NamespaceDecl>(c);
-        scope.emplace_back(n->getNameAsString());
-        c=c->getParent();
-      }
-
-    llvm::outs() << "\n" << Declaration->getReturnType().getAsString()
-                 << " " << Declaration->getName() << " () "
-                 << "__attribute__((annotate(\""
-                 << m_File << "\")));\n";
-
-    //TODO: arg list, not sure if necessary
-
-    return true;
-  }
-
-  bool VisitClassTemplateDecl(clang::ClassTemplateDecl* Declaration) {
-
-   if(Declaration->getName().startswith("_")
-          || Declaration->getName().size()==0)
-     return true;
-
-    std::vector<NamespacePrinterRAII> scope;
-    clang::DeclContext* c=Declaration->getTemplatedDecl()->getEnclosingNamespaceContext();
-    while(c->isNamespace()) {
-      clang::NamespaceDecl* n=llvm::cast<clang::NamespaceDecl>(c);
-      scope.emplace_back(n->getNameAsString());
-      c=c->getParent();
-    }
-
-    llvm::outs()<<"template <";
-    clang::TemplateParameterList* tl=Declaration->getTemplateParameters();
-    for(auto it=tl->begin();it!=tl->end();++it) {
-      if(llvm::isa<clang::NonTypeTemplateParmDecl>(*it)) {
-        clang::NonTypeTemplateParmDecl* td=llvm::cast<clang::NonTypeTemplateParmDecl>(*it);
-        llvm::outs()<<td->getType().getAsString();
-      }
-      else llvm::outs()<<"typename";
-      llvm::outs()<<" "<<(*it)->getName();
-      if((it+1)!=tl->end())
-        llvm::outs()<<", ";
-    }
-    llvm::outs()<<"> class __attribute__((annotate(\""
-                << m_File << "\"))) "
-                << Declaration->getName() << ";\n";
-
-    return true;
-  }
-
-private:
-  llvm::StringRef m_File;
-};
-
-class FindNamedClassConsumer : public clang::ASTConsumer {
-public:
-  FindNamedClassConsumer(llvm::StringRef InFile):Visitor(InFile){}
-  virtual void HandleTranslationUnit(clang::ASTContext &Context) {
-    // Traversing the translation unit decl via a RecursiveASTVisitor
-    // will visit all nodes in the AST.
-    Visitor.TraverseDecl(Context.getTranslationUnitDecl());
-  }
-private:
-  // A RecursiveASTVisitor implementation.
-  FindNamedClassVisitor Visitor;
-};
-
-
-class FindNamedClassAction : public clang::ASTFrontendAction {
-public:
-  virtual clang::ASTConsumer *CreateASTConsumer(
-    clang::CompilerInstance &Compiler, llvm::StringRef InFile) {
-    return new FindNamedClassConsumer(InFile);
-  }
-};
-
-
-int main(int argc, const char **argv) {
-  CommonOptionsParser OptionsParser(argc, argv, FwdCategory);
-  ClangTool Tool(OptionsParser.getCompilations(),
-                 OptionsParser.getSourcePathList());
-
-  return Tool.run(newFrontendActionFactory<FindNamedClassAction>());
-}