From 1b3565dd77a076128c87ac00a639b2fc456d2d68 Mon Sep 17 00:00:00 2001 From: Petr Silhavik Date: Mon, 18 Mar 2013 19:19:12 +0100 Subject: [PATCH] Add warning when event struct is defined but not used Events are stored to list when they are traversed and removed from the list whenever they are used in machine. --- src/visualizer.cpp | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/visualizer.cpp b/src/visualizer.cpp index 5c932cb..3b6e9e3 100644 --- a/src/visualizer.cpp +++ b/src/visualizer.cpp @@ -278,12 +278,27 @@ public: class Visitor : public RecursiveASTVisitor { + struct eventModel { + string name; + SourceLocation loc; + eventModel(string ev, SourceLocation sourceLoc) : name(ev), loc(sourceLoc){} + }; + struct testEventModel { + string eventName; + testEventModel(string name) : eventName(name){} + bool operator() (const eventModel& model) { + if (eventName.compare(model.name) == 0) + return true; + return false; + } + }; ASTContext *ASTCtx; Model::Model &model; DiagnosticsEngine &Diags; unsigned diag_unhandled_reaction_type, diag_unhandled_reaction_decl, diag_found_state, diag_found_statemachine, diag_no_history, diag_missing_reaction, diag_warning; std::vector reactMethodInReactions; // Indicates whether i-th react method is referenced from typedef reactions. + std::list listOfDefinedEvents; public: bool shouldVisitTemplateInstantiations() const { return true; } @@ -365,6 +380,7 @@ public: const Type *DstStateType = TST->getArg(1).getAsType().getTypePtr(); CXXRecordDecl *Event = EventType->getAsCXXRecordDecl(); CXXRecordDecl *DstState = DstStateType->getAsCXXRecordDecl(); + listOfDefinedEvents.remove_if(testEventModel(Event->getNameAsString())); Model::Transition *T = new Model::Transition(SrcState->getName(), DstState->getName(), Event->getName()); model.transitions.push_back(T); @@ -373,9 +389,11 @@ public: if (!HandleCustomReaction(SrcState, EventType)) { Diag(SrcState->getLocation(), diag_missing_reaction) << EventType->getAsCXXRecordDecl()->getName(); } + listOfDefinedEvents.remove_if(testEventModel(EventType->getAsCXXRecordDecl()->getNameAsString())); } else if (name == "boost::statechart::deferral") { const Type *EventType = TST->getArg(0).getAsType().getTypePtr(); CXXRecordDecl *Event = EventType->getAsCXXRecordDecl(); + listOfDefinedEvents.remove_if(testEventModel(Event->getNameAsString())); Model::State *s = model.findState(SrcState->getName()); assert(s); @@ -516,11 +534,14 @@ public: else if (RecordDecl->isDerivedFrom("boost::statechart::state_machine", &Base)) handleStateMachine(RecordDecl, Base); else if (RecordDecl->isDerivedFrom("boost::statechart::event")) - { - //sc.events.push_back(RecordDecl->getNameAsString()); - } + listOfDefinedEvents.push_back(eventModel(RecordDecl->getNameAsString(), RecordDecl->getLocation())); return true; } + void printUnusedEventDefinitions() { + for(list::iterator it = listOfDefinedEvents.begin(); it!=listOfDefinedEvents.end(); it++) + Diag((*it).loc, diag_warning) + << (*it).name << "event defined but not used in any state"; + } }; @@ -536,6 +557,7 @@ public: virtual void HandleTranslationUnit(clang::ASTContext &Context) { visitor.TraverseDecl(Context.getTranslationUnitDecl()); + visitor.printUnusedEventDefinitions(); model.write_as_dot_file(destFileName); } }; -- 2.39.2