144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// Copyright 2011 the V8 project authors. All rights reserved. 244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// Redistribution and use in source and binary forms, with or without 344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// modification, are permitted provided that the following conditions are 444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// met: 544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// 644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// * Redistributions of source code must retain the above copyright 744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// notice, this list of conditions and the following disclaimer. 844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// * Redistributions in binary form must reproduce the above 944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// copyright notice, this list of conditions and the following 1044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// disclaimer in the documentation and/or other materials provided 1144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// with the distribution. 1244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// * Neither the name of Google Inc. nor the names of its 1344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// contributors may be used to endorse or promote products derived 1444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// from this software without specific prior written permission. 1544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// 1644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 2844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org// This is clang plugin used by gcmole tool. See README for more details. 2944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 3044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org#include "clang/AST/AST.h" 3144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org#include "clang/AST/ASTConsumer.h" 3244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org#include "clang/AST/Mangle.h" 3344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org#include "clang/AST/RecursiveASTVisitor.h" 3444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org#include "clang/AST/StmtVisitor.h" 3544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org#include "clang/Frontend/FrontendPluginRegistry.h" 3644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org#include "clang/Frontend/CompilerInstance.h" 3744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org#include "llvm/Support/raw_ostream.h" 3844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 3944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org#include <bitset> 4044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org#include <fstream> 4144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org#include <iostream> 4244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org#include <map> 4344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org#include <set> 4444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org#include <stack> 4544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 4644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgnamespace { 4744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 4844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgtypedef std::string MangledName; 4944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgtypedef std::set<MangledName> CalleesSet; 5044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 5144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgstatic bool GetMangledName(clang::MangleContext* ctx, 5244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org const clang::NamedDecl* decl, 5344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org MangledName* result) { 5444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org if (!isa<clang::CXXConstructorDecl>(decl) && 5544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org !isa<clang::CXXDestructorDecl>(decl)) { 5644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org llvm::SmallVector<char, 512> output; 5744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org llvm::raw_svector_ostream out(output); 5844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org ctx->mangleName(decl, out); 5944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org *result = out.str().str(); 6044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org return true; 6144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 6244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 6344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org return false; 6444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org} 6544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 6644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 6744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgstatic bool InV8Namespace(const clang::NamedDecl* decl) { 6844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org return decl->getQualifiedNameAsString().compare(0, 4, "v8::") == 0; 6944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org} 7044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 7144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 72f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgstatic std::string EXTERNAL("EXTERNAL"); 73f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgstatic std::string STATE_TAG("enum v8::internal::StateTag"); 74f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 75f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.orgstatic bool IsExternalVMState(const clang::ValueDecl* var) { 76f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org const clang::EnumConstantDecl* enum_constant = 77f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org dyn_cast<clang::EnumConstantDecl>(var); 78f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org if (enum_constant != NULL && enum_constant->getNameAsString() == EXTERNAL) { 79f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org clang::QualType type = enum_constant->getType(); 80f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org return (type.getAsString() == STATE_TAG); 81f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 82f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 83f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org return false; 84f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org} 85f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 86f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgstruct Resolver { 887304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org explicit Resolver(clang::ASTContext& ctx) 897304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org : ctx_(ctx), decl_ctx_(ctx.getTranslationUnitDecl()) { 907304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 917304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 927304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Resolver(clang::ASTContext& ctx, clang::DeclContext* decl_ctx) 937304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org : ctx_(ctx), decl_ctx_(decl_ctx) { 947304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 957304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 967304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::DeclarationName ResolveName(const char* n) { 977304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::IdentifierInfo* ident = &ctx_.Idents.get(n); 987304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return ctx_.DeclarationNames.getIdentifier(ident); 997304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 1007304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1017304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Resolver ResolveNamespace(const char* n) { 1027304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return Resolver(ctx_, Resolve<clang::NamespaceDecl>(n)); 1037304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 1047304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org template<typename T> 1067304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org T* Resolve(const char* n) { 1077304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (decl_ctx_ == NULL) return NULL; 1087304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1097304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::DeclContext::lookup_result result = 1107304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org decl_ctx_->lookup(ResolveName(n)); 1117304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1127304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::DeclContext::lookup_iterator end = result.second; 1137304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org for (clang::DeclContext::lookup_iterator i = result.first; 1147304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org i != end; 1157304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org i++) { 1167304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (isa<T>(*i)) return cast<T>(*i); 1177304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 1187304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1197304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return NULL; 1207304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 1217304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1227304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org private: 1237304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::ASTContext& ctx_; 1247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::DeclContext* decl_ctx_; 1257304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org}; 1267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 12844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgclass CalleesPrinter : public clang::RecursiveASTVisitor<CalleesPrinter> { 12944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org public: 13044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org explicit CalleesPrinter(clang::MangleContext* ctx) : ctx_(ctx) { 13144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 13244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 13344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org virtual bool VisitCallExpr(clang::CallExpr* expr) { 13444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org const clang::FunctionDecl* callee = expr->getDirectCallee(); 13544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org if (callee != NULL) AnalyzeFunction(callee); 13644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org return true; 13744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 13844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 139f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org virtual bool VisitDeclRefExpr(clang::DeclRefExpr* expr) { 140f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // If function mentions EXTERNAL VMState add artificial garbage collection 141f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org // mark. 142f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org if (IsExternalVMState(expr->getDecl())) AddCallee("CollectGarbage"); 143f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org return true; 144f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 145f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 14644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org void AnalyzeFunction(const clang::FunctionDecl* f) { 14744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org MangledName name; 14844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org if (InV8Namespace(f) && GetMangledName(ctx_, f, &name)) { 14944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org AddCallee(name); 15044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 15144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org const clang::FunctionDecl* body = NULL; 15244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org if (f->hasBody(body) && !Analyzed(name)) { 15344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org EnterScope(name); 15444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org TraverseStmt(body->getBody()); 15544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org LeaveScope(); 15644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 15744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 15844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 15944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 16044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org typedef std::map<MangledName, CalleesSet* > Callgraph; 16144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 16244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org bool Analyzed(const MangledName& name) { 16344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org return callgraph_[name] != NULL; 16444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 16544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 16644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org void EnterScope(const MangledName& name) { 16744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org CalleesSet* callees = callgraph_[name]; 16844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 16944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org if (callees == NULL) { 17044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org callgraph_[name] = callees = new CalleesSet(); 17144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 17244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 17344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org scopes_.push(callees); 17444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 17544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 17644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org void LeaveScope() { 17744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org scopes_.pop(); 17844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 17944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 18044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org void AddCallee(const MangledName& name) { 18144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org if (!scopes_.empty()) scopes_.top()->insert(name); 18244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 18344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 18444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org void PrintCallGraph() { 18544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org for (Callgraph::const_iterator i = callgraph_.begin(), e = callgraph_.end(); 18644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org i != e; 18744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org ++i) { 18844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org std::cout << i->first << "\n"; 18944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 19044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org CalleesSet* callees = i->second; 19144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org for (CalleesSet::const_iterator j = callees->begin(), e = callees->end(); 19244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org j != e; 19344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org ++j) { 19444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org std::cout << "\t" << *j << "\n"; 19544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 19644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 19744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 19844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 19944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org private: 20044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org clang::MangleContext* ctx_; 20144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 20244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org std::stack<CalleesSet* > scopes_; 20344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org Callgraph callgraph_; 20444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org}; 20544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 2067304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 20744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgclass FunctionDeclarationFinder 20844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org : public clang::ASTConsumer, 20944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org public clang::RecursiveASTVisitor<FunctionDeclarationFinder> { 21044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org public: 21144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org explicit FunctionDeclarationFinder(clang::Diagnostic& d, 2127304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::SourceManager& sm, 2137304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org const std::vector<std::string>& args) 21444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org : d_(d), sm_(sm) { } 21544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 21644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org virtual void HandleTranslationUnit(clang::ASTContext &ctx) { 21744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org mangle_context_ = clang::createItaniumMangleContext(ctx, d_); 21844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org callees_printer_ = new CalleesPrinter(mangle_context_); 21944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 22044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org TraverseDecl(ctx.getTranslationUnitDecl()); 22144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 22244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org callees_printer_->PrintCallGraph(); 22344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 22444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 22544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org virtual bool VisitFunctionDecl(clang::FunctionDecl* decl) { 22644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org callees_printer_->AnalyzeFunction(decl); 22744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org return true; 22844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 22944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 23044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org private: 23144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org clang::Diagnostic& d_; 23244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org clang::SourceManager& sm_; 23344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org clang::MangleContext* mangle_context_; 23444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 23544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org CalleesPrinter* callees_printer_; 23644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org}; 23744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 23844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 23944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgstatic bool loaded = false; 24044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgstatic CalleesSet gc_suspects; 24144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 24244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 24344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgstatic void LoadGCSuspects() { 24444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org if (loaded) return; 24544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 24644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org std::ifstream fin("gcsuspects"); 24744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org std::string s; 24844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 24944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org while (fin >> s) gc_suspects.insert(s); 25044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 25144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org loaded = true; 25244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org} 25344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 25444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 25544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgstatic bool KnownToCauseGC(clang::MangleContext* ctx, 25644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org const clang::FunctionDecl* decl) { 25744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org LoadGCSuspects(); 25844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 25944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org if (!InV8Namespace(decl)) return false; 26044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 26144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org MangledName name; 26244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org if (GetMangledName(ctx, decl, &name)) { 26344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org return gc_suspects.find(name) != gc_suspects.end(); 26444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 26544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 26644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org return false; 26744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org} 26844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 26944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 2707304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgstatic const int kNoEffect = 0; 2717304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgstatic const int kCausesGC = 1; 2727304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgstatic const int kRawDef = 2; 2737304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgstatic const int kRawUse = 4; 2747304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgstatic const int kAllEffects = kCausesGC | kRawDef | kRawUse; 27544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 2767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgclass Environment; 2777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 2787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgclass ExprEffect { 2797304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org public: 2807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org bool hasGC() { return (effect_ & kCausesGC) != 0; } 2817304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org void setGC() { effect_ |= kCausesGC; } 2827304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 2837304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org bool hasRawDef() { return (effect_ & kRawDef) != 0; } 2847304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org void setRawDef() { effect_ |= kRawDef; } 2857304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 2867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org bool hasRawUse() { return (effect_ & kRawUse) != 0; } 2877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org void setRawUse() { effect_ |= kRawUse; } 2887304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 2897304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org static ExprEffect None() { return ExprEffect(kNoEffect, NULL); } 2907304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org static ExprEffect NoneWithEnv(Environment* env) { 2917304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return ExprEffect(kNoEffect, env); 2927304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 2937304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org static ExprEffect RawUse() { return ExprEffect(kRawUse, NULL); } 2947304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 2957304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org static ExprEffect Merge(ExprEffect a, ExprEffect b); 2967304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org static ExprEffect MergeSeq(ExprEffect a, ExprEffect b); 2977304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ExprEffect Define(const std::string& name); 2987304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 2997304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment* env() { 3007304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return reinterpret_cast<Environment*>(effect_ & ~kAllEffects); 3017304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 3027304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 303f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org static ExprEffect GC() { 304f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org return ExprEffect(kCausesGC, NULL); 305f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 306f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 3077304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org private: 3087304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ExprEffect(int effect, Environment* env) 3097304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org : effect_((effect & kAllEffects) | 3107304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org reinterpret_cast<intptr_t>(env)) { } 3117304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 3127304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org intptr_t effect_; 3137304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org}; 3147304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 3157304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 3167304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgconst std::string BAD_EXPR_MSG("Possible problem with evaluation order."); 3177304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgconst std::string DEAD_VAR_MSG("Possibly dead variable."); 3187304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 3197304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 3207304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgclass Environment { 3217304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org public: 3227304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment() { } 3237304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 3247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org static Environment Unreachable() { 3257304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment env; 3267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org env.live_.set(); 3277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return env; 3287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 3297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 3307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org static Environment Merge(const Environment& l, 3317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org const Environment& r) { 3327304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return Environment(l, r); 3337304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 3347304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 3357304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment ApplyEffect(ExprEffect effect) const { 3367304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment out = effect.hasGC() ? Environment() : Environment(*this); 3377304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (effect.env() != NULL) out.live_ |= effect.env()->live_; 3387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return out; 3397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 3407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 3417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org typedef std::map<std::string, int> SymbolTable; 3427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 3437304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org bool IsAlive(const std::string& name) const { 3447304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org SymbolTable::iterator code = symbol_table_.find(name); 3457304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (code == symbol_table_.end()) return false; 3467304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return live_[code->second]; 3477304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 3487304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 3497304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org bool Equal(const Environment& env) { 3507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return live_ == env.live_; 3517304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 3527304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 3537304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment Define(const std::string& name) const { 3547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return Environment(*this, SymbolToCode(name)); 3557304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 3567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 3577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org void MDefine(const std::string& name) { 3587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org live_.set(SymbolToCode(name)); 3597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 3607304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 3617304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org static int SymbolToCode(const std::string& name) { 3627304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org SymbolTable::iterator code = symbol_table_.find(name); 3637304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 3647304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (code == symbol_table_.end()) { 3657304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org int new_code = symbol_table_.size(); 3667304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org symbol_table_.insert(std::make_pair(name, new_code)); 3677304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return new_code; 36844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 3697304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 3707304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return code->second; 3717304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 3727304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 3737304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org static void ClearSymbolTable() { 3747304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org std::vector<Environment*>::iterator end = envs_.end(); 3757304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org for (std::vector<Environment*>::iterator i = envs_.begin(); 3767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org i != end; 3777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ++i) { 3787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org delete *i; 3797304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 3807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org envs_.clear(); 3817304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org symbol_table_.clear(); 3827304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 3837304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 3847304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org void Print() const { 3857304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org bool comma = false; 3867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org std::cout << "{"; 3877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org SymbolTable::iterator end = symbol_table_.end(); 3887304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org for (SymbolTable::iterator i = symbol_table_.begin(); 3897304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org i != end; 3907304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ++i) { 3917304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (live_[i->second]) { 3927304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (comma) std::cout << ", "; 3937304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org std::cout << i->first; 3947304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org comma = true; 39544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 39644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 3977304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org std::cout << "}"; 39844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 39944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 4007304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org static Environment* Allocate(const Environment& env) { 4017304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment* allocated_env = new Environment(env); 4027304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org envs_.push_back(allocated_env); 4037304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return allocated_env; 4047304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 4057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 4067304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org private: 4077304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment(const Environment& l, const Environment& r) 4087304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org : live_(l.live_ & r.live_) { 4097304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 4107304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 4117304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment(const Environment& l, int code) 4127304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org : live_(l.live_) { 4137304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org live_.set(code); 4147304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 4157304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 4167304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org static SymbolTable symbol_table_; 4177304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org static std::vector<Environment* > envs_; 4187304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 4197304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org static const int kMaxNumberOfLocals = 256; 4207304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org std::bitset<kMaxNumberOfLocals> live_; 4217304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 4227304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org friend class ExprEffect; 4237304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org friend class CallProps; 4247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org}; 4257304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 4267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 4277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgclass CallProps { 4287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org public: 4297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org CallProps() : env_(NULL) { } 4307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 4317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org void SetEffect(int arg, ExprEffect in) { 4327304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (in.hasGC()) gc_.set(arg); 4337304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (in.hasRawDef()) raw_def_.set(arg); 4347304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (in.hasRawUse()) raw_use_.set(arg); 4357304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (in.env() != NULL) { 4367304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (env_ == NULL) env_ = in.env(); 4377304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org env_->live_ |= in.env()->live_; 4387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 4397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 4407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 4417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ExprEffect ComputeCumulativeEffect(bool result_is_raw) { 4427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ExprEffect out = ExprEffect::NoneWithEnv(env_); 4437304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (gc_.any()) out.setGC(); 4447304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (raw_use_.any()) out.setRawUse(); 4457304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (result_is_raw) out.setRawDef(); 4467304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return out; 4477304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 4487304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 4497304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org bool IsSafe() { 4507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (!gc_.any()) return true; 4517304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org std::bitset<kMaxNumberOfArguments> raw = (raw_def_ | raw_use_); 4527304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (!raw.any()) return true; 4537304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return gc_.count() == 1 && !((raw ^ gc_).any()); 4547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 4557304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 4567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org private: 4577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org static const int kMaxNumberOfArguments = 64; 4587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org std::bitset<kMaxNumberOfArguments> raw_def_; 4597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org std::bitset<kMaxNumberOfArguments> raw_use_; 4607304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org std::bitset<kMaxNumberOfArguments> gc_; 4617304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment* env_; 4627304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org}; 4637304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 4647304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 4657304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgEnvironment::SymbolTable Environment::symbol_table_; 4667304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgstd::vector<Environment* > Environment::envs_; 4677304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 4687304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 4697304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgExprEffect ExprEffect::Merge(ExprEffect a, ExprEffect b) { 4707304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment* a_env = a.env(); 4717304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment* b_env = b.env(); 4727304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment* out = NULL; 4737304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (a_env != NULL && b_env != NULL) { 4747304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org out = Environment::Allocate(*a_env); 4757304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org out->live_ &= b_env->live_; 4767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 4777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return ExprEffect(a.effect_ | b.effect_, out); 4787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org} 4797304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 4807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 4817304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgExprEffect ExprEffect::MergeSeq(ExprEffect a, ExprEffect b) { 4827304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment* a_env = b.hasGC() ? NULL : a.env(); 4837304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment* b_env = b.env(); 4847304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment* out = (b_env == NULL) ? a_env : b_env; 4857304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (a_env != NULL && b_env != NULL) { 4867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org out = Environment::Allocate(*b_env); 4877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org out->live_ |= a_env->live_; 4887304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 4897304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return ExprEffect(a.effect_ | b.effect_, out); 49044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org} 49144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 49244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 4937304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgExprEffect ExprEffect::Define(const std::string& name) { 4947304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment* e = env(); 4957304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (e == NULL) { 4967304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org e = Environment::Allocate(Environment()); 4977304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 4987304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org e->MDefine(name); 4997304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return ExprEffect(effect_, e); 5007304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org} 5017304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 5027304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 5037304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgstatic std::string THIS ("this"); 5047304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 5057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 5067304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgclass FunctionAnalyzer { 50744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org public: 5087304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org FunctionAnalyzer(clang::MangleContext* ctx, 5097304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::DeclarationName handle_decl_name, 5107304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::CXXRecordDecl* object_decl, 5117304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::CXXRecordDecl* smi_decl, 5127304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::Diagnostic& d, 5137304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::SourceManager& sm, 5147304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org bool dead_vars_analysis) 5157304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org : ctx_(ctx), 5167304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org handle_decl_name_(handle_decl_name), 5177304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org object_decl_(object_decl), 5187304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org smi_decl_(smi_decl), 5197304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org d_(d), 5207304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org sm_(sm), 5217304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org block_(NULL), 5227304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org dead_vars_analysis_(dead_vars_analysis) { 52344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 52444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 5257304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 5267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -------------------------------------------------------------------------- 5277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Expressions 5287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -------------------------------------------------------------------------- 5297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 5307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ExprEffect VisitExpr(clang::Expr* expr, const Environment& env) { 5317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org#define VISIT(type) do { \ 5327304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::type* concrete_expr = dyn_cast_or_null<clang::type>(expr); \ 5337304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (concrete_expr != NULL) { \ 5347304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return Visit##type (concrete_expr, env); \ 5357304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } \ 5367304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } while(0); 5377304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 5387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(AbstractConditionalOperator); 5397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(AddrLabelExpr); 5407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(ArraySubscriptExpr); 5417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(BinaryOperator); 5427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(BinaryTypeTraitExpr); 5437304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(BlockDeclRefExpr); 5447304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(BlockExpr); 5457304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(CallExpr); 5467304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(CastExpr); 5477304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(CharacterLiteral); 5487304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(ChooseExpr); 5497304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(CompoundLiteralExpr); 5507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(CXXBindTemporaryExpr); 5517304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(CXXBoolLiteralExpr); 5527304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(CXXConstructExpr); 5537304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(CXXDefaultArgExpr); 5547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(CXXDeleteExpr); 5557304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(CXXDependentScopeMemberExpr); 5567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(CXXNewExpr); 5577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(CXXNoexceptExpr); 5587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(CXXNullPtrLiteralExpr); 5597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(CXXPseudoDestructorExpr); 5607304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(CXXScalarValueInitExpr); 5617304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(CXXThisExpr); 5627304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(CXXThrowExpr); 5637304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(CXXTypeidExpr); 5647304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(CXXUnresolvedConstructExpr); 5657304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(CXXUuidofExpr); 5667304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(DeclRefExpr); 5677304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(DependentScopeDeclRefExpr); 5687304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(DesignatedInitExpr); 5697304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(ExprWithCleanups); 5707304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(ExtVectorElementExpr); 5717304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(FloatingLiteral); 5727304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(GNUNullExpr); 5737304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(ImaginaryLiteral); 5747304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(ImplicitValueInitExpr); 5757304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(InitListExpr); 5767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(IntegerLiteral); 5777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(MemberExpr); 5787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(OffsetOfExpr); 5797304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(OpaqueValueExpr); 5807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(OverloadExpr); 5817304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(PackExpansionExpr); 5827304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(ParenExpr); 5837304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(ParenListExpr); 5847304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(PredefinedExpr); 5857304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(ShuffleVectorExpr); 5867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(SizeOfPackExpr); 5877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(StmtExpr); 5887304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(StringLiteral); 5897304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(SubstNonTypeTemplateParmPackExpr); 5907304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(UnaryOperator); 5917304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(UnaryTypeTraitExpr); 5927304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(VAArgExpr); 5937304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org#undef VISIT 5947304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 5957304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return ExprEffect::None(); 59644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 59744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 5987304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org#define DECL_VISIT_EXPR(type) \ 5997304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ExprEffect Visit##type (clang::type* expr, const Environment& env) 60044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 6017304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org#define IGNORE_EXPR(type) \ 6027304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ExprEffect Visit##type (clang::type* expr, const Environment& env) { \ 6037304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return ExprEffect::None(); \ 6047304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 60544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 6067304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(AddrLabelExpr); 6077304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(BinaryTypeTraitExpr); 6087304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(BlockExpr); 6097304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(CharacterLiteral); 6107304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(ChooseExpr); 6117304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(CompoundLiteralExpr); 6127304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(CXXBoolLiteralExpr); 6137304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(CXXDependentScopeMemberExpr); 6147304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(CXXNullPtrLiteralExpr); 6157304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(CXXPseudoDestructorExpr); 6167304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(CXXScalarValueInitExpr); 6177304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(CXXNoexceptExpr); 6187304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(CXXTypeidExpr); 6197304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(CXXUnresolvedConstructExpr); 6207304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(CXXUuidofExpr); 6217304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(DependentScopeDeclRefExpr); 6227304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(DesignatedInitExpr); 6237304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(ExtVectorElementExpr); 6247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(FloatingLiteral); 6257304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(ImaginaryLiteral); 6267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(IntegerLiteral); 6277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(OffsetOfExpr); 6287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(ImplicitValueInitExpr); 6297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(PackExpansionExpr); 6307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(PredefinedExpr); 6317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(ShuffleVectorExpr); 6327304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(SizeOfPackExpr); 6337304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(StmtExpr); 6347304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(StringLiteral); 6357304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(SubstNonTypeTemplateParmPackExpr); 6367304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(UnaryTypeTraitExpr); 6377304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(VAArgExpr); 6387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(GNUNullExpr); 6397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_EXPR(OverloadExpr); 6407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 6417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_EXPR(CXXThisExpr) { 6427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return Use(expr, expr->getType(), THIS, env); 6437304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 6447304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 6457304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_EXPR(AbstractConditionalOperator) { 6467304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment after_cond = env.ApplyEffect(VisitExpr(expr->getCond(), env)); 6477304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return ExprEffect::Merge(VisitExpr(expr->getTrueExpr(), after_cond), 6487304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VisitExpr(expr->getFalseExpr(), after_cond)); 6497304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 6507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 6517304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_EXPR(ArraySubscriptExpr) { 6527304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::Expr* exprs[2] = {expr->getBase(), expr->getIdx()}; 6537304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return Par(expr, 2, exprs, env); 6547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 6557304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 6567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org bool IsRawPointerVar(clang::Expr* expr, std::string* var_name) { 6577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (isa<clang::BlockDeclRefExpr>(expr)) { 6587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org *var_name = cast<clang::BlockDeclRefExpr>(expr)->getDecl()-> 6597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org getNameAsString(); 6607304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return true; 6617304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } else if (isa<clang::DeclRefExpr>(expr)) { 6627304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org *var_name = cast<clang::DeclRefExpr>(expr)->getDecl()->getNameAsString(); 6637304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return true; 66444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 66544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org return false; 66644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 66744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 6687304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_EXPR(BinaryOperator) { 6697304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::Expr* lhs = expr->getLHS(); 6707304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::Expr* rhs = expr->getRHS(); 6717304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::Expr* exprs[2] = {lhs, rhs}; 6727304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 6737304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org switch (expr->getOpcode()) { 6747304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org case clang::BO_Comma: 6757304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return Seq(expr, 2, exprs, env); 6767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 6777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org case clang::BO_LAnd: 6787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org case clang::BO_LOr: 6797304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return ExprEffect::Merge(VisitExpr(lhs, env), VisitExpr(rhs, env)); 6807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 6817304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org case clang::BO_Assign: { 6827304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org std::string var_name; 6837304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (IsRawPointerVar(lhs, &var_name)) { 6847304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return VisitExpr(rhs, env).Define(var_name); 6857304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 6867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return Par(expr, 2, exprs, env); 6877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 6887304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 6897304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org default: 6907304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return Par(expr, 2, exprs, env); 6917304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 69244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 69344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 6947304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_EXPR(CXXBindTemporaryExpr) { 6957304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return VisitExpr(expr->getSubExpr(), env); 69644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 69744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 6987304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_EXPR(CXXConstructExpr) { 6997304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return VisitArguments<>(expr, env); 7007304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 7017304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 7027304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_EXPR(CXXDefaultArgExpr) { 7037304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return VisitExpr(expr->getExpr(), env); 7047304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 7057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 7067304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_EXPR(CXXDeleteExpr) { 7077304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return VisitExpr(expr->getArgument(), env); 7087304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 7097304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 7107304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_EXPR(CXXNewExpr) { 7117304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return Par(expr, 7127304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org expr->getNumConstructorArgs(), 7137304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org expr->getConstructorArgs(), 7147304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org env); 7157304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 7167304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 7177304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_EXPR(ExprWithCleanups) { 7187304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return VisitExpr(expr->getSubExpr(), env); 7197304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 7207304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 7217304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_EXPR(CXXThrowExpr) { 7227304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return VisitExpr(expr->getSubExpr(), env); 7237304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 7247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 7257304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_EXPR(InitListExpr) { 7267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return Seq(expr, expr->getNumInits(), expr->getInits(), env); 7277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 7287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 7297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_EXPR(MemberExpr) { 7307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return VisitExpr(expr->getBase(), env); 7317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 7327304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 7337304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_EXPR(OpaqueValueExpr) { 7347304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return VisitExpr(expr->getSourceExpr(), env); 7357304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 7367304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 7377304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_EXPR(ParenExpr) { 7387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return VisitExpr(expr->getSubExpr(), env); 7397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 7407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 7417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_EXPR(ParenListExpr) { 7427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return Par(expr, expr->getNumExprs(), expr->getExprs(), env); 7437304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 7447304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 7457304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_EXPR(UnaryOperator) { 7467304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // TODO We are treating all expressions that look like &raw_pointer_var 7477304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // as definitions of raw_pointer_var. This should be changed to 7487304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // recognize less generic pattern: 7497304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // 7507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // if (maybe_object->ToObject(&obj)) return maybe_object; 7517304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // 7527304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (expr->getOpcode() == clang::UO_AddrOf) { 7537304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org std::string var_name; 7547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (IsRawPointerVar(expr->getSubExpr(), &var_name)) { 7557304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return ExprEffect::None().Define(var_name); 7567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 7577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 7587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return VisitExpr(expr->getSubExpr(), env); 7597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 7607304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 7617304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_EXPR(CastExpr) { 7627304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return VisitExpr(expr->getSubExpr(), env); 7637304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 7647304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 7657304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_EXPR(DeclRefExpr) { 7667304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return Use(expr, expr->getDecl(), env); 7677304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 7687304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 7697304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_EXPR(BlockDeclRefExpr) { 7707304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return Use(expr, expr->getDecl(), env); 7717304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 7727304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 7737304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ExprEffect Par(clang::Expr* parent, 7747304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org int n, 7757304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::Expr** exprs, 7767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org const Environment& env) { 7777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org CallProps props; 7787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 7797304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org for (int i = 0; i < n; ++i) { 7807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org props.SetEffect(i, VisitExpr(exprs[i], env)); 7817304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 7827304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 7837304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (!props.IsSafe()) ReportUnsafe(parent, BAD_EXPR_MSG); 7847304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 7857304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return props.ComputeCumulativeEffect(IsRawPointerType(parent->getType())); 7867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 7877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 7887304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ExprEffect Seq(clang::Stmt* parent, 7897304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org int n, 7907304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::Expr** exprs, 7917304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org const Environment& env) { 7927304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ExprEffect out = ExprEffect::None(); 7937304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment out_env = env; 7947304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org for (int i = 0; i < n; ++i) { 7957304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org out = ExprEffect::MergeSeq(out, VisitExpr(exprs[i], out_env)); 7967304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org out_env = out_env.ApplyEffect(out); 7977304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 7987304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return out; 7997304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 8007304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 8017304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ExprEffect Use(const clang::Expr* parent, 8027304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org const clang::QualType& var_type, 8037304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org const std::string& var_name, 8047304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org const Environment& env) { 8057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (IsRawPointerType(var_type)) { 8067304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (!env.IsAlive(var_name) && dead_vars_analysis_) { 8077304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ReportUnsafe(parent, DEAD_VAR_MSG); 80844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 8097304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return ExprEffect::RawUse(); 81044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 8117304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return ExprEffect::None(); 8127304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 8137304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 8147304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ExprEffect Use(const clang::Expr* parent, 8157304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org const clang::ValueDecl* var, 8167304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org const Environment& env) { 817f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org if (IsExternalVMState(var)) { 818f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org return ExprEffect::GC(); 819f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org } 8207304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return Use(parent, var->getType(), var->getNameAsString(), env); 8217304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 8227304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 82344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 8247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org template<typename ExprType> 8257304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ExprEffect VisitArguments(ExprType* call, const Environment& env) { 8267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org CallProps props; 8277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VisitArguments<>(call, &props, env); 8287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (!props.IsSafe()) ReportUnsafe(call, BAD_EXPR_MSG); 8297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return props.ComputeCumulativeEffect(IsRawPointerType(call->getType())); 8307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 8317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 8327304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org template<typename ExprType> 8337304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org void VisitArguments(ExprType* call, 8347304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org CallProps* props, 8357304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org const Environment& env) { 83644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org for (unsigned arg = 0; arg < call->getNumArgs(); arg++) { 8377304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org props->SetEffect(arg + 1, VisitExpr(call->getArg(arg), env)); 83844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 83944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 84044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 8417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 8427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ExprEffect VisitCallExpr(clang::CallExpr* call, 8437304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org const Environment& env) { 8447304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org CallProps props; 84544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 84644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org clang::CXXMemberCallExpr* memcall = 84744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org dyn_cast_or_null<clang::CXXMemberCallExpr>(call); 8487304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (memcall != NULL) { 8497304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::Expr* receiver = memcall->getImplicitObjectArgument(); 8507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org props.SetEffect(0, VisitExpr(receiver, env)); 85144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 85244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 8537304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VisitArguments<>(call, &props, env); 8547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 8557304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (!props.IsSafe()) ReportUnsafe(call, BAD_EXPR_MSG); 8567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 8577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ExprEffect out = 8587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org props.ComputeCumulativeEffect(IsRawPointerType(call->getType())); 8597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 8607304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::FunctionDecl* callee = call->getDirectCallee(); 8617304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if ((callee != NULL) && KnownToCauseGC(ctx_, callee)) { 8627304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org out.setGC(); 8637304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 8647304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 8657304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return out; 8667304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 8677304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 8687304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -------------------------------------------------------------------------- 8697304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // Statements 8707304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // -------------------------------------------------------------------------- 8717304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 8727304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment VisitStmt(clang::Stmt* stmt, const Environment& env) { 8737304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org#define VISIT(type) do { \ 8747304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::type* concrete_stmt = dyn_cast_or_null<clang::type>(stmt); \ 8757304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (concrete_stmt != NULL) { \ 8767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return Visit##type (concrete_stmt, env); \ 8777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } \ 8787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } while(0); 8797304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 8807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (clang::Expr* expr = dyn_cast_or_null<clang::Expr>(stmt)) { 8817304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return env.ApplyEffect(VisitExpr(expr, env)); 8827304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 8837304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 8847304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(AsmStmt); 8857304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(BreakStmt); 8867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(CompoundStmt); 8877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(ContinueStmt); 8887304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(CXXCatchStmt); 8897304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(CXXTryStmt); 8907304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(DeclStmt); 8917304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(DoStmt); 8927304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(ForStmt); 8937304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(GotoStmt); 8947304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(IfStmt); 8957304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(IndirectGotoStmt); 8967304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(LabelStmt); 8977304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(NullStmt); 8987304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(ReturnStmt); 8997304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(CaseStmt); 9007304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(DefaultStmt); 9017304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(SwitchStmt); 9027304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VISIT(WhileStmt); 9037304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org#undef VISIT 9047304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 9057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return env; 9067304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 9077304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 9087304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org#define DECL_VISIT_STMT(type) \ 9097304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment Visit##type (clang::type* stmt, const Environment& env) 9107304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 9117304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org#define IGNORE_STMT(type) \ 9127304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment Visit##type (clang::type* stmt, const Environment& env) { \ 9137304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return env; \ 9147304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 9157304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 9167304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_STMT(IndirectGotoStmt); 9177304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_STMT(NullStmt); 9187304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_STMT(AsmStmt); 9197304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 9207304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // We are ignoring control flow for simplicity. 9217304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_STMT(GotoStmt); 9227304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_STMT(LabelStmt); 9237304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 9247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // We are ignoring try/catch because V8 does not use them. 9257304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_STMT(CXXCatchStmt); 9267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org IGNORE_STMT(CXXTryStmt); 9277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 9287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org class Block { 9297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org public: 9307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Block(const Environment& in, 9317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org FunctionAnalyzer* owner) 9327304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org : in_(in), 9337304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org out_(Environment::Unreachable()), 9347304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org changed_(false), 9357304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org owner_(owner) { 9367304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org parent_ = owner_->EnterBlock(this); 9377304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 9387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 9397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ~Block() { 9407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org owner_->LeaveBlock(parent_); 9417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 9427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 9437304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org void MergeIn(const Environment& env) { 9447304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment old_in = in_; 9457304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org in_ = Environment::Merge(in_, env); 9467304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org changed_ = !old_in.Equal(in_); 9477304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 9487304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 9497304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org bool changed() { 9507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (changed_) { 9517304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org changed_ = false; 9527304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return true; 9537304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 9547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return false; 9557304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 9567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 9577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org const Environment& in() { 9587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return in_; 9597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 9607304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 9617304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org const Environment& out() { 9627304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return out_; 9637304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 9647304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 9657304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org void MergeOut(const Environment& env) { 9667304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org out_ = Environment::Merge(out_, env); 9677304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 9687304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 9697304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org void Seq(clang::Stmt* a, clang::Stmt* b, clang::Stmt* c) { 9707304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment a_out = owner_->VisitStmt(a, in()); 9717304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment b_out = owner_->VisitStmt(b, a_out); 9727304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment c_out = owner_->VisitStmt(c, b_out); 9737304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org MergeOut(c_out); 9747304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 9757304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 9767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org void Seq(clang::Stmt* a, clang::Stmt* b) { 9777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment a_out = owner_->VisitStmt(a, in()); 9787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment b_out = owner_->VisitStmt(b, a_out); 9797304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org MergeOut(b_out); 9807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 9817304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 9827304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org void Loop(clang::Stmt* a, clang::Stmt* b, clang::Stmt* c) { 9837304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Seq(a, b, c); 9847304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org MergeIn(out()); 9857304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 9867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 9877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org void Loop(clang::Stmt* a, clang::Stmt* b) { 9887304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Seq(a, b); 9897304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org MergeIn(out()); 99044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 9917304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 9927304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 9937304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org private: 9947304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment in_; 9957304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment out_; 9967304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org bool changed_; 9977304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org FunctionAnalyzer* owner_; 9987304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Block* parent_; 9997304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org }; 10007304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 10017304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 10027304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_STMT(BreakStmt) { 10037304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org block_->MergeOut(env); 10047304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return Environment::Unreachable(); 10057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 10067304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 10077304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_STMT(ContinueStmt) { 10087304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org block_->MergeIn(env); 10097304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return Environment::Unreachable(); 10107304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 10117304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 10127304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_STMT(CompoundStmt) { 10137304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment out = env; 10147304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::CompoundStmt::body_iterator end = stmt->body_end(); 10157304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org for (clang::CompoundStmt::body_iterator s = stmt->body_begin(); 10167304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org s != end; 10177304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ++s) { 10187304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org out = VisitStmt(*s, out); 10197304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 10207304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return out; 10217304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 10227304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 10237304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_STMT(WhileStmt) { 10247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Block block (env, this); 10257304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org do { 10267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org block.Loop(stmt->getCond(), stmt->getBody()); 10277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } while (block.changed()); 10287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return block.out(); 10297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 10307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 10317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_STMT(DoStmt) { 10327304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Block block (env, this); 10337304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org do { 10347304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org block.Loop(stmt->getBody(), stmt->getCond()); 10357304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } while (block.changed()); 10367304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return block.out(); 10377304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 10387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 10397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_STMT(ForStmt) { 10407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Block block (VisitStmt(stmt->getInit(), env), this); 10417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org do { 10427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org block.Loop(stmt->getCond(), 10437304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org stmt->getBody(), 10447304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org stmt->getInc()); 10457304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } while (block.changed()); 10467304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return block.out(); 10477304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 10487304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 10497304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_STMT(IfStmt) { 10507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment cond_out = VisitStmt(stmt->getCond(), env); 10517304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment then_out = VisitStmt(stmt->getThen(), cond_out); 10527304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment else_out = VisitStmt(stmt->getElse(), cond_out); 10537304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return Environment::Merge(then_out, else_out); 10547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 10557304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 10567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_STMT(SwitchStmt) { 10577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Block block (env, this); 10587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org block.Seq(stmt->getCond(), stmt->getBody()); 10597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return block.out(); 10607304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 10617304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 10627304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_STMT(CaseStmt) { 10637304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment in = Environment::Merge(env, block_->in()); 10647304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment after_lhs = VisitStmt(stmt->getLHS(), in); 10657304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return VisitStmt(stmt->getSubStmt(), after_lhs); 10667304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 10677304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 10687304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_STMT(DefaultStmt) { 10697304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment in = Environment::Merge(env, block_->in()); 10707304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return VisitStmt(stmt->getSubStmt(), in); 10717304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 10727304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 10737304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_STMT(ReturnStmt) { 10747304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VisitExpr(stmt->getRetValue(), env); 10757304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return Environment::Unreachable(); 107644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 107744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 107844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org const clang::TagType* ToTagType(const clang::Type* t) { 107944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org if (t == NULL) { 108044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org return NULL; 108144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } else if (isa<clang::TagType>(t)) { 108244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org return cast<clang::TagType>(t); 108344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } else if (isa<clang::SubstTemplateTypeParmType>(t)) { 108444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org return ToTagType(cast<clang::SubstTemplateTypeParmType>(t)-> 108544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org getReplacementType().getTypePtr()); 108644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } else { 108744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org return NULL; 108844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 108944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 109044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 10917304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org bool IsDerivedFrom(clang::CXXRecordDecl* record, 10927304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::CXXRecordDecl* base) { 10937304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return (record == base) || record->isDerivedFrom(base); 10947304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 109544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 10967304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org bool IsRawPointerType(clang::QualType qtype) { 109744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org const clang::PointerType* type = 10987304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org dyn_cast_or_null<clang::PointerType>(qtype.getTypePtrOrNull()); 109944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org if (type == NULL) return false; 110044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 110144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org const clang::TagType* pointee = 110244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org ToTagType(type->getPointeeType().getTypePtr()); 110344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org if (pointee == NULL) return false; 110444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 110544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org clang::CXXRecordDecl* record = 110644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org dyn_cast_or_null<clang::CXXRecordDecl>(pointee->getDecl()); 110744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org if (record == NULL) return false; 110844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 11097304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (!InV8Namespace(record)) return false; 111044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 11117304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (!record->hasDefinition()) return false; 111244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 11137304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org record = record->getDefinition(); 111444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 11157304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return IsDerivedFrom(record, object_decl_) && 11167304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org !IsDerivedFrom(record, smi_decl_); 111744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 111844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 11197304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment VisitDecl(clang::Decl* decl, const Environment& env) { 11207304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (clang::VarDecl* var = dyn_cast<clang::VarDecl>(decl)) { 11217304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment out = var->hasInit() ? VisitStmt(var->getInit(), env) : env; 11227304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 11237304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (IsRawPointerType(var->getType())) { 11247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org out = out.Define(var->getNameAsString()); 11257304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 112644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 11277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return out; 11287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 11297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org // TODO: handle other declarations? 11307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return env; 113144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 113244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 11337304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DECL_VISIT_STMT(DeclStmt) { 11347304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment out = env; 11357304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::DeclStmt::decl_iterator end = stmt->decl_end(); 11367304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org for (clang::DeclStmt::decl_iterator decl = stmt->decl_begin(); 11377304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org decl != end; 11387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ++decl) { 11397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org out = VisitDecl(*decl, out); 11407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 11417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return out; 114244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 114344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 114444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 11457304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org void DefineParameters(const clang::FunctionDecl* f, 11467304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment* env) { 11477304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org env->MDefine(THIS); 11487304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::FunctionDecl::param_const_iterator end = f->param_end(); 11497304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org for (clang::FunctionDecl::param_const_iterator p = f->param_begin(); 11507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org p != end; 11517304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ++p) { 11527304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org env->MDefine((*p)->getNameAsString()); 11537304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 11547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 115544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 115644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 11577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org void AnalyzeFunction(const clang::FunctionDecl* f) { 11587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org const clang::FunctionDecl* body = NULL; 11597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (f->hasBody(body)) { 11607304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment env; 11617304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org DefineParameters(body, &env); 11627304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org VisitStmt(body->getBody(), env); 11637304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Environment::ClearSymbolTable(); 11647304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 11657304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 116644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 11677304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Block* EnterBlock(Block* block) { 11687304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Block* parent = block_; 11697304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org block_ = block; 11707304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return parent; 11717304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 117244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 11737304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org void LeaveBlock(Block* block) { 11747304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org block_ = block; 11757304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 117644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 11777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org private: 11787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org void ReportUnsafe(const clang::Expr* expr, const std::string& msg) { 11797304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org d_.Report(clang::FullSourceLoc(expr->getExprLoc(), sm_), 11807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org d_.getCustomDiagID(clang::Diagnostic::Warning, msg)); 11817304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 118244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 118344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 11847304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::MangleContext* ctx_; 11857304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::DeclarationName handle_decl_name_; 11867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::CXXRecordDecl* object_decl_; 11877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::CXXRecordDecl* smi_decl_; 118844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 11897304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::Diagnostic& d_; 11907304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::SourceManager& sm_; 119144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 11927304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Block* block_; 11937304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org bool dead_vars_analysis_; 11947304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org}; 119544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 119644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 11977304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgclass ProblemsFinder : public clang::ASTConsumer, 11987304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org public clang::RecursiveASTVisitor<ProblemsFinder> { 11997304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org public: 12007304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org ProblemsFinder(clang::Diagnostic& d, 12017304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::SourceManager& sm, 12027304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org const std::vector<std::string>& args) 12037304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org : d_(d), sm_(sm), dead_vars_analysis_(false) { 12047304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org for (unsigned i = 0; i < args.size(); ++i) { 12057304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (args[i] == "--dead-vars") { 12067304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org dead_vars_analysis_ = true; 12077304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 120844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 12097304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 121044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 121144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org virtual void HandleTranslationUnit(clang::ASTContext &ctx) { 121244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org Resolver r(ctx); 121344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 12147304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::CXXRecordDecl* object_decl = 121544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org r.ResolveNamespace("v8").ResolveNamespace("internal"). 121644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org Resolve<clang::CXXRecordDecl>("Object"); 121744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 12187304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org clang::CXXRecordDecl* smi_decl = 12197304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org r.ResolveNamespace("v8").ResolveNamespace("internal"). 12207304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Resolve<clang::CXXRecordDecl>("Smi"); 12217304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 12227304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (object_decl != NULL) object_decl = object_decl->getDefinition(); 12237304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 12247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (smi_decl != NULL) smi_decl = smi_decl->getDefinition(); 12257304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 12267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (object_decl != NULL && smi_decl != NULL) { 12277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org function_analyzer_ = 12287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org new FunctionAnalyzer(clang::createItaniumMangleContext(ctx, d_), 12297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org r.ResolveName("Handle"), 12307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org object_decl, 12317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org smi_decl, 12327304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org d_, 12337304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org sm_, 12347304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org dead_vars_analysis_); 123544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org TraverseDecl(ctx.getTranslationUnitDecl()); 123644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } else { 12377304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (object_decl == NULL) { 12387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org llvm::errs() << "Failed to resolve v8::internal::Object\n"; 12397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 12407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org if (smi_decl == NULL) { 12417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org llvm::errs() << "Failed to resolve v8::internal::Smi\n"; 12427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 124344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 124444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 124544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 12467304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org virtual bool VisitFunctionDecl(clang::FunctionDecl* decl) { 12477304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org function_analyzer_->AnalyzeFunction(decl); 124844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org return true; 124944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 125044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 125144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org private: 125244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org clang::Diagnostic& d_; 125344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org clang::SourceManager& sm_; 12547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org bool dead_vars_analysis_; 125544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 12567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org FunctionAnalyzer* function_analyzer_; 125744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org}; 125844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 125944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 126044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgtemplate<typename ConsumerType> 126144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgclass Action : public clang::PluginASTAction { 126244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org protected: 126344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org clang::ASTConsumer *CreateASTConsumer(clang::CompilerInstance &CI, 126444bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org llvm::StringRef InFile) { 12657304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return new ConsumerType(CI.getDiagnostics(), CI.getSourceManager(), args_); 126644bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 126744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 126844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org bool ParseArgs(const clang::CompilerInstance &CI, 126944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org const std::vector<std::string>& args) { 12707304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org args_ = args; 127144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org return true; 127244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org } 127344bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 12747304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org void PrintHelp(llvm::raw_ostream& ros) { 12757304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org } 12767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org private: 12777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org std::vector<std::string> args_; 127844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org}; 127944bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 128044bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 128144bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org} 128244bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 12837304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgstatic clang::FrontendPluginRegistry::Add<Action<ProblemsFinder> > 12847304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgFindProblems("find-problems", "Find GC-unsafe places."); 128544bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org 12867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgstatic clang::FrontendPluginRegistry::Add< 12877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org Action<FunctionDeclarationFinder> > 128844bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.orgDumpCallees("dump-callees", "Dump callees for each function."); 1289