File indexing completed on 2024-04-28 04:34:21

0001 /***************************************************************************
0002  *   Copyright 2009 Sandro Andrade <sandroandrade@kde.org>                 *
0003  *                                                                         *
0004  *   This program is free software; you can redistribute it and/or modify  *
0005  *   it under the terms of the GNU Library General Public License as       *
0006  *   published by the Free Software Foundation; either version 2 of the    *
0007  *   License, or (at your option) any later version.                       *
0008  *                                                                         *
0009  *   This program is distributed in the hope that it will be useful,       *
0010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0012  *   GNU General Public License for more details.                          *
0013  *                                                                         *
0014  *   You should have received a copy of the GNU Library General Public     *
0015  *   License along with this program; if not, write to the                 *
0016  *   Free Software Foundation, Inc.,                                       *
0017  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
0018  ***************************************************************************/
0019 
0020 #include "controlflowgraphusescollector.h"
0021 
0022 #include <language/duchain/use.h>
0023 #include <language/duchain/duchain.h>
0024 #include <language/duchain/declaration.h>
0025 #include <language/duchain/duchainlock.h>
0026 
0027 using namespace KDevelop;
0028 
0029 ControlFlowGraphUsesCollector::ControlFlowGraphUsesCollector(IndexedDeclaration declaration)
0030  : UsesCollector(declaration), m_declaration(declaration)
0031 {
0032 }
0033 
0034 ControlFlowGraphUsesCollector::~ControlFlowGraphUsesCollector()
0035 {
0036 }
0037 
0038 void ControlFlowGraphUsesCollector::processUses(ReferencedTopDUContext topContext)
0039 {
0040     if (topContext.data())
0041     {
0042         DUChainReadLocker lock(DUChain::lock());
0043         CodeRepresentation::Ptr code = createCodeRepresentation(topContext.data()->url());
0044         processContext(topContext.data(), code);
0045     }
0046 }
0047 
0048 void ControlFlowGraphUsesCollector::processContext(DUContext *context, CodeRepresentation::Ptr code)
0049 {
0050     foreach (const IndexedDeclaration &ideclaration, declarations())
0051     {
0052         Declaration *declaration = ideclaration.data();
0053         if (!declaration)
0054             continue;
0055         
0056         int declarationIndex = context->topContext()->indexForUsedDeclaration(declaration, false);
0057         if (declarationIndex == std::numeric_limits<int>::max())
0058             continue;
0059         
0060         int usesCount = context->usesCount();
0061         for (int useIndex = 0; useIndex < usesCount; ++useIndex)
0062         {
0063             if (context->uses()[useIndex].m_declarationIndex == declarationIndex)
0064             {
0065                 // Navigate to uppermost executable context
0066                 DUContext *uppermostExecutableContext = context;
0067                 while (uppermostExecutableContext->parentContext() && uppermostExecutableContext->parentContext()->type() == DUContext::Other)
0068                     uppermostExecutableContext = uppermostExecutableContext->parentContext();
0069 
0070                 // Get the definition
0071                 Declaration* definition = 0;
0072                 if (!uppermostExecutableContext || !uppermostExecutableContext->owner())
0073                     continue;
0074                 else
0075                     definition = uppermostExecutableContext->owner();
0076 
0077                 if (!definition) continue;
0078 
0079                 emit processFunctionCall(definition, m_declaration.data(), context->uses()[useIndex]);
0080             }
0081         }
0082     }
0083     foreach (DUContext *child, context->childContexts())
0084         processContext(child, code);
0085 }