diff options
| author | Allan Sandfeld Jensen <allan.jensen@digia.com> | 2013-09-13 12:51:20 +0200 |
|---|---|---|
| committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-19 20:50:05 +0200 |
| commit | d441d6f39bb846989d95bcf5caf387b42414718d (patch) | |
| tree | e367e64a75991c554930278175d403c072de6bb8 /Tools/clang | |
| parent | 0060b2994c07842f4c59de64b5e3e430525c4b90 (diff) | |
| download | qtwebkit-d441d6f39bb846989d95bcf5caf387b42414718d.tar.gz | |
Import Qt5x2 branch of QtWebkit for Qt 5.2
Importing a new snapshot of webkit.
Change-Id: I2d01ad12cdc8af8cb015387641120a9d7ea5f10c
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
Diffstat (limited to 'Tools/clang')
| -rw-r--r-- | Tools/clang/ReportMemoryUsagePlugin/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | Tools/clang/ReportMemoryUsagePlugin/ReportMemoryUsage.cpp | 214 |
2 files changed, 113 insertions, 103 deletions
diff --git a/Tools/clang/ReportMemoryUsagePlugin/CMakeLists.txt b/Tools/clang/ReportMemoryUsagePlugin/CMakeLists.txt index 53225f790..1cc4783d0 100644 --- a/Tools/clang/ReportMemoryUsagePlugin/CMakeLists.txt +++ b/Tools/clang/ReportMemoryUsagePlugin/CMakeLists.txt @@ -1,6 +1,6 @@ set(MODULE TRUE) -set( LLVM_LINK_COMPONENTS support mc) +set(LLVM_LINK_COMPONENTS support mc) add_clang_library(ReportMemoryUsage ReportMemoryUsage.cpp) diff --git a/Tools/clang/ReportMemoryUsagePlugin/ReportMemoryUsage.cpp b/Tools/clang/ReportMemoryUsagePlugin/ReportMemoryUsage.cpp index f5d45f545..f30994765 100644 --- a/Tools/clang/ReportMemoryUsagePlugin/ReportMemoryUsage.cpp +++ b/Tools/clang/ReportMemoryUsagePlugin/ReportMemoryUsage.cpp @@ -39,31 +39,16 @@ using namespace clang; namespace { -typedef std::vector<std::string> Strings; +using namespace std; +typedef vector<string> Strings; Strings instrumentationMethods; -const std::string instrimentingMethodName("reportMemoryUsage"); +const char instrumentingMethodName[] = "reportMemoryUsage"; class AddMemberCallVisitor : public RecursiveASTVisitor<AddMemberCallVisitor> { public: - bool VisitCallExpr(CallExpr* callExpr) - { - CXXMemberCallExpr* methodCallExpr = dyn_cast<CXXMemberCallExpr>(callExpr); - bool instrumented = false; - if (methodCallExpr) { - std::string methodName = methodCallExpr->getMethodDecl()->getNameAsString(); - Strings::iterator i = find(instrumentationMethods.begin(), instrumentationMethods.end(), methodName); - instrumented = i != instrumentationMethods.end(); - } - if (instrumented || !methodCallExpr) { - for (CallExpr::arg_iterator i = callExpr->arg_begin(); i != callExpr->arg_end(); ++i) { - if (MemberExpr* memberExpr = dyn_cast<MemberExpr>(*i)) - m_instrumentedMembers.push_back(memberExpr->getMemberNameInfo().getAsString()); - } - } - return true; - } + bool VisitCallExpr(CallExpr*); const Strings& instrumentedMembers() const { return m_instrumentedMembers; } private: @@ -76,75 +61,13 @@ public: : m_instance(instance) , m_context(context) { } - bool VisitCXXMethodDecl(clang::CXXMethodDecl* decl) - { - if (decl->doesThisDeclarationHaveABody() && decl->getNameAsString() == instrimentingMethodName) { - FullSourceLoc fullLocation = m_context->getFullLoc(decl->getLocStart()); - if (fullLocation.isValid()) { - AddMemberCallVisitor visitor; - visitor.TraverseStmt(decl->getBody()); - CheckMembersCoverage(decl->getParent(), visitor.instrumentedMembers(), decl->getLocStart()); - } - } - return true; - } + bool VisitCXXMethodDecl(clang::CXXMethodDecl*); private: - void emitWarning(SourceLocation loc, const char* rawError) - { - FullSourceLoc full(loc, m_instance.getSourceManager()); - std::string err("[webkit-style] "); - err += rawError; - DiagnosticsEngine& diagnostic = m_instance.getDiagnostics(); - DiagnosticsEngine::Level level = diagnostic.getWarningsAsErrors() ? DiagnosticsEngine::Error : DiagnosticsEngine::Warning; - unsigned id = diagnostic.getCustomDiagID(level, err); - DiagnosticBuilder builder = diagnostic.Report(full, id); - } - - CXXMethodDecl* findInstrumentationMethod(CXXRecordDecl* record) - { - for (CXXRecordDecl::method_iterator m = record->method_begin(); m != record->method_end(); ++m) { - if (m->getNameInfo().getAsString() == instrimentingMethodName) - return *m; - } - return 0; - } - - bool needsToBeInstrumented(const Type* type) - { - if (type->isBuiltinType()) - return false; - if (type->isEnumeralType()) - return false; - if (type->isClassType()) { - const RecordType* recordType = dyn_cast<RecordType>(type); - if (recordType) { - CXXRecordDecl* decl = dyn_cast<CXXRecordDecl>(recordType->getDecl()); - if (decl->getNameAsString() == "String") - return true; - if (!decl || !findInstrumentationMethod(decl)) - return false; - } - } - if (type->isArrayType()) { - const ArrayType* arrayType = dyn_cast<const ArrayType>(type); - return needsToBeInstrumented(arrayType->getElementType().getTypePtr()); - } - return true; - } - - void CheckMembersCoverage(const CXXRecordDecl* instrumentedClass, const Strings& instrumentedMembers, SourceLocation location) - { - for (CXXRecordDecl::field_iterator i = instrumentedClass->field_begin(); i != instrumentedClass->field_end(); ++i) { - std::string fieldName = i->getNameAsString(); - if (find(instrumentedMembers.begin(), instrumentedMembers.end(), fieldName) == instrumentedMembers.end()) { - if (!needsToBeInstrumented(i->getType().getTypePtr())) - continue; - emitWarning(i->getSourceRange().getBegin(), "class member needs to be instrumented in reportMemoryUsage function"); - emitWarning(location, "located here"); - } - } - } + void emitWarning(SourceLocation, const char* rawError); + CXXMethodDecl* findInstrumentationMethod(CXXRecordDecl*); + bool needsToBeInstrumented(const Type*); + void checkMembersCoverage(const CXXRecordDecl* instrumentedClass, const Strings& instrumentedMembers, SourceLocation); CompilerInstance& m_instance; ASTContext* m_context; @@ -156,18 +79,9 @@ public: : m_visitor(instance, context) { instrumentationMethods.push_back("addMember"); - instrumentationMethods.push_back("addInstrumentedMember"); - instrumentationMethods.push_back("addVector"); - instrumentationMethods.push_back("addVectorPtr"); - instrumentationMethods.push_back("addInstrumentedVector"); - instrumentationMethods.push_back("addInstrumentedVectorPtr"); - instrumentationMethods.push_back("addHashSet"); - instrumentationMethods.push_back("addInstrumentedHashSet"); - instrumentationMethods.push_back("addHashMap"); - instrumentationMethods.push_back("addInstrumentedHashMap"); - instrumentationMethods.push_back("addListHashSet"); instrumentationMethods.push_back("addRawBuffer"); - instrumentationMethods.push_back("addString"); + instrumentationMethods.push_back("addWeakPointer"); + instrumentationMethods.push_back("ignoreMember"); } virtual void HandleTranslationUnit(clang::ASTContext& context) @@ -186,7 +100,7 @@ protected: return new ReportMemoryUsageConsumer(CI, &CI.getASTContext()); } - bool ParseArgs(const CompilerInstance& CI, const std::vector<std::string>& args) + bool ParseArgs(const CompilerInstance& CI, const vector<string>& args) { if (args.size() && args[0] == "help") llvm::errs() << m_helpText; @@ -200,22 +114,118 @@ const char* ReportMemoryUsageAction::m_helpText = "This plugin is checking native memory instrumentation code.\n" "The class is instrumented if it has reportMemoryUsage member function.\n" "Sample:\n" - "class InstrumentedClass {\n" + "class InstrumentedClass : public BaseInstrumentedClass {\n" "public:\n" " void reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const\n" " {\n" - " MemoryClassInfo<InstrumentedClass> info(memoryObjectInfo, this, MemoryInstrumentation::DOM);\n" - " info.addMember(m_notInstrumentedPtr);\n" - " info.addInstrumentedMember(m_instrumentedObject);\n" + " MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM);\n" + " BaseInstrumentedClass::reportMemoryUsage(memoryObjectInfo);\n" + " info.addMember(m_notInstrumentedObject);\n" + " info.addMember(m_instrumentedObject);\n" + " info.addRawBuffer(m_pointer, m_length);\n" + " info.ignoreMember(m_pointerToInternalField);\n" " }\n" "\n" "private:\n" " NotInstrumentedClass* m_notInstrumentedPtr;\n" " InstrumentedClass m_instrumentedObject;\n" + " long m_length;\n" + " double* m_pointer;\n" + " Data* m_pointerToInternalField;\n" "}\n"; +bool AddMemberCallVisitor::VisitCallExpr(CallExpr* callExpr) +{ + CXXMemberCallExpr* methodCallExpr = dyn_cast<CXXMemberCallExpr>(callExpr); + bool instrumented = false; + if (methodCallExpr) { + string methodName = methodCallExpr->getMethodDecl()->getNameAsString(); + Strings::iterator i = find(instrumentationMethods.begin(), instrumentationMethods.end(), methodName); + instrumented = i != instrumentationMethods.end(); + } + if (instrumented || !methodCallExpr) { + for (CallExpr::arg_iterator i = callExpr->arg_begin(); i != callExpr->arg_end(); ++i) { + Expr* expr = *i; + while (ImplicitCastExpr::classof(expr)) + expr = static_cast<ImplicitCastExpr*>(expr)->getSubExpr(); + if (MemberExpr* memberExpr = dyn_cast<MemberExpr>(expr)) + m_instrumentedMembers.push_back(memberExpr->getMemberNameInfo().getAsString()); + } + } + return true; +} + +bool ReportMemoryUsageVisitor::VisitCXXMethodDecl(clang::CXXMethodDecl* decl) +{ + if (decl->doesThisDeclarationHaveABody() && decl->getNameAsString() == instrumentingMethodName) { + FullSourceLoc fullLocation = m_context->getFullLoc(decl->getLocStart()); + if (fullLocation.isValid()) { + AddMemberCallVisitor visitor; + visitor.TraverseStmt(decl->getBody()); + checkMembersCoverage(decl->getParent(), visitor.instrumentedMembers(), decl->getLocStart()); + } + } + return true; +} + +void ReportMemoryUsageVisitor::emitWarning(SourceLocation loc, const char* rawError) +{ + FullSourceLoc full(loc, m_instance.getSourceManager()); + string err("[webkit-style] "); + err += rawError; + DiagnosticsEngine& diagnostic = m_instance.getDiagnostics(); + DiagnosticsEngine::Level level = diagnostic.getWarningsAsErrors() ? DiagnosticsEngine::Error : DiagnosticsEngine::Warning; + unsigned id = diagnostic.getCustomDiagID(level, err); + DiagnosticBuilder builder = diagnostic.Report(full, id); } +CXXMethodDecl* ReportMemoryUsageVisitor::findInstrumentationMethod(CXXRecordDecl* record) +{ + for (CXXRecordDecl::method_iterator m = record->method_begin(); m != record->method_end(); ++m) { + if (m->getNameInfo().getAsString() == instrumentingMethodName) + return *m; + } + return 0; +} + +bool ReportMemoryUsageVisitor::needsToBeInstrumented(const Type* type) +{ + if (type->isBuiltinType()) + return false; + if (type->isEnumeralType()) + return false; + if (type->isClassType()) { + const RecordType* recordType = dyn_cast<RecordType>(type); + if (recordType) { + CXXRecordDecl* decl = dyn_cast<CXXRecordDecl>(recordType->getDecl()); + if (decl->getNameAsString() == "String") + return true; + if (!decl || !findInstrumentationMethod(decl)) + return false; + } + } + if (type->isArrayType()) { + const ArrayType* arrayType = dyn_cast<const ArrayType>(type); + return needsToBeInstrumented(arrayType->getElementType().getTypePtr()); + } + return true; +} + +void ReportMemoryUsageVisitor::checkMembersCoverage(const CXXRecordDecl* instrumentedClass, const Strings& instrumentedMembers, SourceLocation location) +{ + for (CXXRecordDecl::field_iterator i = instrumentedClass->field_begin(); i != instrumentedClass->field_end(); ++i) { + string fieldName = i->getNameAsString(); + if (find(instrumentedMembers.begin(), instrumentedMembers.end(), fieldName) == instrumentedMembers.end()) { + if (!needsToBeInstrumented(i->getType().getTypePtr())) + continue; + emitWarning(i->getSourceRange().getBegin(), "class member needs to be instrumented in reportMemoryUsage function"); + emitWarning(location, "located here"); + } + } +} + +} // namespace + static FrontendPluginRegistry::Add<ReportMemoryUsageAction> X("report-memory-usage", "Checks reportMemoryUsage function consistency"); |
