summaryrefslogtreecommitdiff
path: root/Tools/clang
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@digia.com>2013-09-13 12:51:20 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-19 20:50:05 +0200
commitd441d6f39bb846989d95bcf5caf387b42414718d (patch)
treee367e64a75991c554930278175d403c072de6bb8 /Tools/clang
parent0060b2994c07842f4c59de64b5e3e430525c4b90 (diff)
downloadqtwebkit-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.txt2
-rw-r--r--Tools/clang/ReportMemoryUsagePlugin/ReportMemoryUsage.cpp214
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");