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 }