Update gcmole to a more recent clang/llvm.
authorsvenpanne@chromium.org <svenpanne@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 7 Aug 2014 12:56:53 +0000 (12:56 +0000)
committersvenpanne@chromium.org <svenpanne@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 7 Aug 2014 12:56:53 +0000 (12:56 +0000)
* Changes for 2.9:
     * Use CXX in Makefile instead of hardwired g++, we need a more
       modern GCC than 4.6 later, anyway.

* Changes for 3.0:
     * Use llvm namespace.
     * Diagnostic => DiagnosticsEngine.

* Changes for 3.1:
     * The BlockDeclRefExpr AST node is gone.
     * The structure of the CXXNewExpr AST node has changed.
     * Path changed from Release to Release+Asserts.
     * Use clang++ instead of -cc1, otherwise we lose the system include
       paths.

* Changes for 3.2:
     none needed

* Changes for 3.3:
     * Use lookup_iterator::begin/end instead of first/second.

* Changes for 3.4:
     * createItaniumMangleContext => ItaniumMangleContext::create.

* Changes for 3.5:
     * clang uses <type_traits> now, so -std=c++0x is needed.
     * Type-trait-related AST changes.
     * getCustomDiagID signature changed.
     * We must link the C++ library statically now.

R=mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/445983002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22972 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

.gitignore
tools/gcmole/Makefile
tools/gcmole/bootstrap.sh
tools/gcmole/gcmole.cc
tools/gcmole/gcmole.lua

index 707582c..d0d4b43 100644 (file)
@@ -64,6 +64,7 @@ shell_g
 /testing/gmock
 /testing/gtest
 /third_party/icu
+/third_party/llvm
 /tools/jsfunfuzz
 /tools/jsfunfuzz.zip
 /tools/oom_dump/oom_dump
index 764245c..ee43c00 100644 (file)
@@ -31,13 +31,12 @@ LLVM_INCLUDE:=$(LLVM_SRC_ROOT)/include
 CLANG_INCLUDE:=$(LLVM_SRC_ROOT)/tools/clang/include
 
 libgcmole.so: gcmole.cc
-       g++ -I$(LLVM_INCLUDE) -I$(CLANG_INCLUDE) -I. -D_DEBUG -D_GNU_SOURCE \
-       -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -O3                  \
-       -fomit-frame-pointer -fno-exceptions -fno-rtti -fPIC                \
-       -Woverloaded-virtual -Wcast-qual -fno-strict-aliasing               \
-       -pedantic -Wno-long-long -Wall                                      \
-       -W -Wno-unused-parameter -Wwrite-strings                            \
-       -shared -o libgcmole.so gcmole.cc
+       $(CXX) -I$(LLVM_INCLUDE) -I$(CLANG_INCLUDE) -I. -D_DEBUG              \
+       -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS         \
+       -D__STDC_LIMIT_MACROS -O3 -fomit-frame-pointer -fno-exceptions        \
+       -fno-rtti -fPIC -Woverloaded-virtual -Wcast-qual -fno-strict-aliasing \
+       -pedantic -Wno-long-long -Wall -W -Wno-unused-parameter               \
+       -Wwrite-strings -std=c++0x -shared -o libgcmole.so gcmole.cc
 
 clean:
-       rm -f libgcmole.so
+       $(RM) libgcmole.so
index baa0b1f..ac6593c 100755 (executable)
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-# This script will build libgcmole.so.
+# This script will build libgcmole.so. Building a recent clang needs a
+# recent GCC, so if you explicitly want to use GCC 4.8, use:
+#
+#    CC=gcc-4.8 CPP=cpp-4.8 CXX=g++-4.8 CXXFLAGS=-static-libstdc++ CXXCPP=cpp-4.8 ./bootstrap.sh
 
-CLANG_RELEASE=2.9
+CLANG_RELEASE=3.5
 
 THIS_DIR="$(dirname "${0}")"
 LLVM_DIR="${THIS_DIR}/../../third_party/llvm"
@@ -110,7 +113,7 @@ if [ "${OS}" = "Darwin" ]; then
   # See http://crbug.com/256342
   STRIP_FLAGS=-x
 fi
-strip ${STRIP_FLAGS} Release/bin/clang
+strip ${STRIP_FLAGS} Release+Asserts/bin/clang
 cd -
 
 # Build libgcmole.so
@@ -122,5 +125,5 @@ set +x
 echo
 echo You can now run gcmole using this command:
 echo
-echo CLANG_BIN=\"third_party/llvm/Release/bin\" lua tools/gcmole/gcmole.lua
+echo CLANG_BIN=\"third_party/llvm/Release+Asserts/bin\" lua tools/gcmole/gcmole.lua
 echo
index bdff189..9f1f781 100644 (file)
@@ -51,8 +51,8 @@ typedef std::set<MangledName> CalleesSet;
 static bool GetMangledName(clang::MangleContext* ctx,
                            const clang::NamedDecl* decl,
                            MangledName* result) {
-  if (!isa<clang::CXXConstructorDecl>(decl) &&
-      !isa<clang::CXXDestructorDecl>(decl)) {
+  if (!llvm::isa<clang::CXXConstructorDecl>(decl) &&
+      !llvm::isa<clang::CXXDestructorDecl>(decl)) {
     llvm::SmallVector<char, 512> output;
     llvm::raw_svector_ostream out(output);
     ctx->mangleName(decl, out);
@@ -74,7 +74,7 @@ static std::string STATE_TAG("enum v8::internal::StateTag");
 
 static bool IsExternalVMState(const clang::ValueDecl* var) {
   const clang::EnumConstantDecl* enum_constant =
-      dyn_cast<clang::EnumConstantDecl>(var);
+      llvm::dyn_cast<clang::EnumConstantDecl>(var);
   if (enum_constant != NULL && enum_constant->getNameAsString() == EXTERNAL) {
     clang::QualType type = enum_constant->getType();
     return (type.getAsString() == STATE_TAG);
@@ -109,11 +109,10 @@ struct Resolver {
     clang::DeclContext::lookup_result result =
         decl_ctx_->lookup(ResolveName(n));
 
-    clang::DeclContext::lookup_iterator end = result.second;
-    for (clang::DeclContext::lookup_iterator i = result.first;
-         i != end;
+    clang::DeclContext::lookup_iterator end = result.end();
+    for (clang::DeclContext::lookup_iterator i = result.begin(); i != end;
          i++) {
-      if (isa<T>(*i)) return cast<T>(*i);
+      if (llvm::isa<T>(*i)) return llvm::cast<T>(*i);
     }
 
     return NULL;
@@ -208,13 +207,13 @@ class FunctionDeclarationFinder
     : public clang::ASTConsumer,
       public clang::RecursiveASTVisitor<FunctionDeclarationFinder> {
  public:
-  explicit FunctionDeclarationFinder(clang::Diagnostic& d,
+  explicit FunctionDeclarationFinder(clang::DiagnosticsEngine& d,
                                      clang::SourceManager& sm,
                                      const std::vector<std::string>& args)
-      : d_(d), sm_(sm) { }
+      : d_(d), sm_(sm) {}
 
   virtual void HandleTranslationUnit(clang::ASTContext &ctx) {
-    mangle_context_ = clang::createItaniumMangleContext(ctx, d_);
+    mangle_context_ = clang::ItaniumMangleContext::create(ctx, d_);
     callees_printer_ = new CalleesPrinter(mangle_context_);
 
     TraverseDecl(ctx.getTranslationUnitDecl());
@@ -228,7 +227,7 @@ class FunctionDeclarationFinder
   }
 
  private:
-  clang::Diagnostic& d_;
+  clang::DiagnosticsEngine& d_;
   clang::SourceManager& sm_;
   clang::MangleContext* mangle_context_;
 
@@ -508,10 +507,8 @@ class FunctionAnalyzer {
   FunctionAnalyzer(clang::MangleContext* ctx,
                    clang::DeclarationName handle_decl_name,
                    clang::CXXRecordDecl* object_decl,
-                   clang::CXXRecordDecl* smi_decl,
-                   clang::Diagnostic& d,
-                   clang::SourceManager& sm,
-                   bool dead_vars_analysis)
+                   clang::CXXRecordDecl* smi_decl, clang::DiagnosticsEngine& d,
+                   clang::SourceManager& sm, bool dead_vars_analysis)
       : ctx_(ctx),
         handle_decl_name_(handle_decl_name),
         object_decl_(object_decl),
@@ -519,8 +516,7 @@ class FunctionAnalyzer {
         d_(d),
         sm_(sm),
         block_(NULL),
-        dead_vars_analysis_(dead_vars_analysis) {
-  }
+        dead_vars_analysis_(dead_vars_analysis) {}
 
 
   // --------------------------------------------------------------------------
@@ -528,19 +524,18 @@ class FunctionAnalyzer {
   // --------------------------------------------------------------------------
 
   ExprEffect VisitExpr(clang::Expr* expr, const Environment& env) {
-#define VISIT(type) do {                                                \
-      clang::type* concrete_expr = dyn_cast_or_null<clang::type>(expr); \
-      if (concrete_expr != NULL) {                                      \
-        return Visit##type (concrete_expr, env);                        \
-      }                                                                 \
-    } while(0);
+#define VISIT(type)                                                         \
+  do {                                                                      \
+    clang::type* concrete_expr = llvm::dyn_cast_or_null<clang::type>(expr); \
+    if (concrete_expr != NULL) {                                            \
+      return Visit##type(concrete_expr, env);                               \
+    }                                                                       \
+  } while (0);
 
     VISIT(AbstractConditionalOperator);
     VISIT(AddrLabelExpr);
     VISIT(ArraySubscriptExpr);
     VISIT(BinaryOperator);
-    VISIT(BinaryTypeTraitExpr);
-    VISIT(BlockDeclRefExpr);
     VISIT(BlockExpr);
     VISIT(CallExpr);
     VISIT(CastExpr);
@@ -587,8 +582,8 @@ class FunctionAnalyzer {
     VISIT(StmtExpr);
     VISIT(StringLiteral);
     VISIT(SubstNonTypeTemplateParmPackExpr);
+    VISIT(TypeTraitExpr);
     VISIT(UnaryOperator);
-    VISIT(UnaryTypeTraitExpr);
     VISIT(VAArgExpr);
 #undef VISIT
 
@@ -604,7 +599,6 @@ class FunctionAnalyzer {
   }
 
   IGNORE_EXPR(AddrLabelExpr);
-  IGNORE_EXPR(BinaryTypeTraitExpr);
   IGNORE_EXPR(BlockExpr);
   IGNORE_EXPR(CharacterLiteral);
   IGNORE_EXPR(ChooseExpr);
@@ -633,7 +627,7 @@ class FunctionAnalyzer {
   IGNORE_EXPR(StmtExpr);
   IGNORE_EXPR(StringLiteral);
   IGNORE_EXPR(SubstNonTypeTemplateParmPackExpr);
-  IGNORE_EXPR(UnaryTypeTraitExpr);
+  IGNORE_EXPR(TypeTraitExpr);
   IGNORE_EXPR(VAArgExpr);
   IGNORE_EXPR(GNUNullExpr);
   IGNORE_EXPR(OverloadExpr);
@@ -654,12 +648,9 @@ class FunctionAnalyzer {
   }
 
   bool IsRawPointerVar(clang::Expr* expr, std::string* var_name) {
-    if (isa<clang::BlockDeclRefExpr>(expr)) {
-      *var_name = cast<clang::BlockDeclRefExpr>(expr)->getDecl()->
-          getNameAsString();
-      return true;
-    } else if (isa<clang::DeclRefExpr>(expr)) {
-      *var_name = cast<clang::DeclRefExpr>(expr)->getDecl()->getNameAsString();
+    if (llvm::isa<clang::DeclRefExpr>(expr)) {
+      *var_name =
+          llvm::cast<clang::DeclRefExpr>(expr)->getDecl()->getNameAsString();
       return true;
     }
     return false;
@@ -707,12 +698,7 @@ class FunctionAnalyzer {
     return VisitExpr(expr->getArgument(), env);
   }
 
-  DECL_VISIT_EXPR(CXXNewExpr) {
-    return Par(expr,
-               expr->getNumConstructorArgs(),
-               expr->getConstructorArgs(),
-               env);
-  }
+  DECL_VISIT_EXPR(CXXNewExpr) { return VisitExpr(expr->getInitializer(), env); }
 
   DECL_VISIT_EXPR(ExprWithCleanups) {
     return VisitExpr(expr->getSubExpr(), env);
@@ -766,10 +752,6 @@ class FunctionAnalyzer {
     return Use(expr, expr->getDecl(), env);
   }
 
-  DECL_VISIT_EXPR(BlockDeclRefExpr) {
-    return Use(expr, expr->getDecl(), env);
-  }
-
   ExprEffect Par(clang::Expr* parent,
                  int n,
                  clang::Expr** exprs,
@@ -844,7 +826,7 @@ class FunctionAnalyzer {
     CallProps props;
 
     clang::CXXMemberCallExpr* memcall =
-        dyn_cast_or_null<clang::CXXMemberCallExpr>(call);
+        llvm::dyn_cast_or_null<clang::CXXMemberCallExpr>(call);
     if (memcall != NULL) {
       clang::Expr* receiver = memcall->getImplicitObjectArgument();
       props.SetEffect(0, VisitExpr(receiver, env));
@@ -870,14 +852,15 @@ class FunctionAnalyzer {
   // --------------------------------------------------------------------------
 
   Environment VisitStmt(clang::Stmt* stmt, const Environment& env) {
-#define VISIT(type) do {                                                \
-      clang::type* concrete_stmt = dyn_cast_or_null<clang::type>(stmt); \
-      if (concrete_stmt != NULL) {                                      \
-        return Visit##type (concrete_stmt, env);                        \
-      }                                                                 \
-    } while(0);
-
-    if (clang::Expr* expr = dyn_cast_or_null<clang::Expr>(stmt)) {
+#define VISIT(type)                                                         \
+  do {                                                                      \
+    clang::type* concrete_stmt = llvm::dyn_cast_or_null<clang::type>(stmt); \
+    if (concrete_stmt != NULL) {                                            \
+      return Visit##type(concrete_stmt, env);                               \
+    }                                                                       \
+  } while (0);
+
+    if (clang::Expr* expr = llvm::dyn_cast_or_null<clang::Expr>(stmt)) {
       return env.ApplyEffect(VisitExpr(expr, env));
     }
 
@@ -1078,11 +1061,12 @@ class FunctionAnalyzer {
   const clang::TagType* ToTagType(const clang::Type* t) {
     if (t == NULL) {
       return NULL;
-    } else if (isa<clang::TagType>(t)) {
-      return cast<clang::TagType>(t);
-    } else if (isa<clang::SubstTemplateTypeParmType>(t)) {
-      return ToTagType(cast<clang::SubstTemplateTypeParmType>(t)->
-                           getReplacementType().getTypePtr());
+    } else if (llvm::isa<clang::TagType>(t)) {
+      return llvm::cast<clang::TagType>(t);
+    } else if (llvm::isa<clang::SubstTemplateTypeParmType>(t)) {
+      return ToTagType(llvm::cast<clang::SubstTemplateTypeParmType>(t)
+                           ->getReplacementType()
+                           .getTypePtr());
     } else {
       return NULL;
     }
@@ -1095,7 +1079,7 @@ class FunctionAnalyzer {
 
   bool IsRawPointerType(clang::QualType qtype) {
     const clang::PointerType* type =
-        dyn_cast_or_null<clang::PointerType>(qtype.getTypePtrOrNull());
+        llvm::dyn_cast_or_null<clang::PointerType>(qtype.getTypePtrOrNull());
     if (type == NULL) return false;
 
     const clang::TagType* pointee =
@@ -1103,7 +1087,7 @@ class FunctionAnalyzer {
     if (pointee == NULL) return false;
 
     clang::CXXRecordDecl* record =
-        dyn_cast_or_null<clang::CXXRecordDecl>(pointee->getDecl());
+        llvm::dyn_cast_or_null<clang::CXXRecordDecl>(pointee->getDecl());
     if (record == NULL) return false;
 
     if (!InV8Namespace(record)) return false;
@@ -1117,7 +1101,7 @@ class FunctionAnalyzer {
   }
 
   Environment VisitDecl(clang::Decl* decl, const Environment& env) {
-    if (clang::VarDecl* var = dyn_cast<clang::VarDecl>(decl)) {
+    if (clang::VarDecl* var = llvm::dyn_cast<clang::VarDecl>(decl)) {
       Environment out = var->hasInit() ? VisitStmt(var->getInit(), env) : env;
 
       if (IsRawPointerType(var->getType())) {
@@ -1177,7 +1161,8 @@ class FunctionAnalyzer {
  private:
   void ReportUnsafe(const clang::Expr* expr, const std::string& msg) {
     d_.Report(clang::FullSourceLoc(expr->getExprLoc(), sm_),
-              d_.getCustomDiagID(clang::Diagnostic::Warning, msg));
+              d_.getCustomDiagID(clang::DiagnosticsEngine::Warning, "%0"))
+        << msg;
   }
 
 
@@ -1186,7 +1171,7 @@ class FunctionAnalyzer {
   clang::CXXRecordDecl* object_decl_;
   clang::CXXRecordDecl* smi_decl_;
 
-  clang::Diagnostic& d_;
+  clang::DiagnosticsEngine& d_;
   clang::SourceManager& sm_;
 
   Block* block_;
@@ -1197,8 +1182,7 @@ class FunctionAnalyzer {
 class ProblemsFinder : public clang::ASTConsumer,
                        public clang::RecursiveASTVisitor<ProblemsFinder> {
  public:
-  ProblemsFinder(clang::Diagnostic& d,
-                 clang::SourceManager& sm,
+  ProblemsFinder(clang::DiagnosticsEngine& d, clang::SourceManager& sm,
                  const std::vector<std::string>& args)
       : d_(d), sm_(sm), dead_vars_analysis_(false) {
     for (unsigned i = 0; i < args.size(); ++i) {
@@ -1224,14 +1208,9 @@ class ProblemsFinder : public clang::ASTConsumer,
     if (smi_decl != NULL) smi_decl = smi_decl->getDefinition();
 
     if (object_decl != NULL && smi_decl != NULL) {
-      function_analyzer_ =
-          new FunctionAnalyzer(clang::createItaniumMangleContext(ctx, d_),
-                               r.ResolveName("Handle"),
-                               object_decl,
-                               smi_decl,
-                               d_,
-                               sm_,
-                               dead_vars_analysis_);
+      function_analyzer_ = new FunctionAnalyzer(
+          clang::ItaniumMangleContext::create(ctx, d_), r.ResolveName("Handle"),
+          object_decl, smi_decl, d_, sm_, dead_vars_analysis_);
       TraverseDecl(ctx.getTranslationUnitDecl());
     } else {
       if (object_decl == NULL) {
@@ -1249,7 +1228,7 @@ class ProblemsFinder : public clang::ASTConsumer,
   }
 
  private:
-  clang::Diagnostic& d_;
+  clang::DiagnosticsEngine& d_;
   clang::SourceManager& sm_;
   bool dead_vars_analysis_;
 
index 706f4de..833d4c1 100644 (file)
@@ -93,14 +93,16 @@ end
 local function MakeClangCommandLine(plugin, plugin_args, triple, arch_define)
    if plugin_args then
      for i = 1, #plugin_args do
-        plugin_args[i] = "-plugin-arg-" .. plugin .. " " .. plugin_args[i]
+        plugin_args[i] = "-Xclang -plugin-arg-" .. plugin
+           .. " -Xclang " .. plugin_args[i]
      end
      plugin_args = " " .. table.concat(plugin_args, " ")
    end
-   return CLANG_BIN .. "/clang -cc1 -load " .. CLANG_PLUGINS .. "/libgcmole.so"
-      .. " -plugin "  .. plugin
+   return CLANG_BIN .. "/clang++ -c "
+      .. " -Xclang -load -Xclang " .. CLANG_PLUGINS .. "/libgcmole.so"
+      .. " -Xclang -plugin -Xclang "  .. plugin
       .. (plugin_args or "")
-      .. " -triple " .. triple
+      .. " -Xclang -triple -Xclang " .. triple
       .. " -D" .. arch_define
       .. " -DENABLE_DEBUGGER_SUPPORT"
       .. " -DV8_I18N_SUPPORT"