Commit bd0e7533 authored by ussrhero's avatar ussrhero

Merge branch 'enumTypeProvider' into dev-1.0

parents 20e20461 3dce4c04
......@@ -173,6 +173,7 @@ public:
virtual unsigned long getBaseType() = 0;
virtual BITOFFSET getBitPosition() = 0;
virtual SymbolPtr getChildByIndex(unsigned long index ) = 0;
virtual SymbolPtr getChildByIndex(unsigned long symTag, unsigned long index ) = 0;
virtual SymbolPtr getChildByName(const std::wstring &name ) = 0;
virtual size_t getChildCount() = 0;
virtual size_t getChildCount(unsigned long symTag ) = 0;
......
......@@ -150,6 +150,9 @@ protected:
///////////////////////////////////////////////////////////////////////////////
class TypeInfoEnumerator;
typedef boost::shared_ptr<TypeInfoEnumerator> TypeInfoEnumeratorPtr;
class TypeInfoProvider;
typedef boost::shared_ptr<TypeInfoProvider> TypeInfoProviderPtr;
......@@ -158,7 +161,12 @@ class TypeInfoProvider
public:
virtual TypeInfoPtr getTypeByName(const std::wstring& name) = 0;
virtual TypeInfoEnumeratorPtr getTypeEnumerator(const std::wstring& mask = L"") = 0;
};
class TypeInfoEnumerator {
public:
virtual TypeInfoPtr Next() = 0;
};
TypeInfoProviderPtr getTypeInfoProviderFromSource( const std::wstring& source, const std::wstring& opts = L"" );
......
This diff is collapsed.
......@@ -15,6 +15,7 @@ namespace kdlib {
class ClangASTSession;
typedef boost::shared_ptr<ClangASTSession> ClangASTSessionPtr;
class TypeInfoProviderClang;
class ClangASTSession : public boost::enable_shared_from_this<ClangASTSession>
......@@ -25,7 +26,7 @@ public:
return ClangASTSessionPtr( new ClangASTSession(astUnit) );
}
TypeInfoPtr getTypeInfo(const std::wstring& name);
//TypeInfoPtr getTypeInfo(const std::wstring& name);
clang::ASTContext& getASTContext() {
return m_astUnit->getASTContext();
......@@ -304,8 +305,29 @@ protected:
};
class TypeInfoProviderClang : public TypeInfoProvider
class TypeInfoProviderClangEnum : public TypeInfoEnumerator {
public:
virtual TypeInfoPtr Next();
TypeInfoProviderClangEnum(const std::wstring& mask, boost::shared_ptr<TypeInfoProviderClang>& clangProvider );
private:
size_t m_index;
std::vector<TypeInfoPtr> m_typeList;
};
class TypeInfoProviderClang : public TypeInfoProvider, public boost::enable_shared_from_this<TypeInfoProviderClang>
{
friend TypeInfoProviderClangEnum;
public:
TypeInfoProviderClang( const std::wstring& sourceCode, const std::wstring& compileOptions);
......@@ -314,12 +336,16 @@ private:
virtual TypeInfoPtr getTypeByName(const std::wstring& name);
virtual TypeInfoEnumeratorPtr getTypeEnumerator(const std::wstring& mask);
private:
ClangASTSessionPtr m_astSession;
std::map< std::string, TypeInfoPtr> m_typeCache;
};
}
\ No newline at end of file
}
......@@ -322,7 +322,12 @@ public:
NOT_IMPLEMENTED();
}
virtual SymbolPtr getChildByIndex(ULONG _index)
virtual SymbolPtr getChildByIndex(ULONG index)
{
return getChildByIndex(SymTagNull, index);
}
virtual SymbolPtr getChildByIndex(unsigned long symTag, unsigned long index )
{
throw SymbolException(L"symbol not found");
}
......
......@@ -88,6 +88,11 @@ class ExportSymbolBase : public Symbol
NOT_IMPLEMENTED();
}
virtual SymbolPtr getChildByIndex(unsigned long symTag, unsigned long index )
{
NOT_IMPLEMENTED();
}
virtual SymbolPtr getChildByName(const std::wstring &_name )
{
NOT_IMPLEMENTED();
......
#include "stdafx.h"
#include <boost/regex.hpp>
/////////////////////////////////////////////////////////////////////////////////
namespace kdlib {
const boost::regex r1("\\?");
const boost::regex r2("\\*");
const boost::regex r3("\\.");
bool fnmatch( const std::string& pattern, const std::string& str)
{
std::string mask = pattern;
mask = boost::regex_replace(mask, r1, ".");
mask = boost::regex_replace(mask, r2, ".*");
mask = boost::regex_replace(mask, r3, "\\.");
boost::smatch matchResult;
boost::regex regEx(mask);
return boost::regex_match(str, matchResult, regEx);
}
const boost::wregex wr1(L"\\?");
const boost::wregex wr2(L"\\*");
const boost::wregex wr3(L"\\.");
bool fnmatch( const std::wstring& pattern, const std::wstring& str)
{
std::wstring mask = pattern;
mask = boost::regex_replace(mask, wr1, L".");
mask = boost::regex_replace(mask, wr2, L".*");
mask = boost::regex_replace(mask, wr3, L"\\.");
boost::wsmatch matchResult;
boost::wregex regEx(mask);
return boost::regex_match(str, matchResult, regEx);
}
}
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <string>
namespace kdlib {
///////////////////////////////////////////////////////////////////////////////
bool fnmatch( const std::string& pattern, const std::string& str);
bool fnmatch( const std::wstring& pattern, const std::wstring& str);
///////////////////////////////////////////////////////////////////////////////
}
......@@ -44,6 +44,7 @@
<ClCompile Include="dia\diawrapper.cpp" />
<ClCompile Include="dia\symexport.cpp" />
<ClCompile Include="disasm.cpp" />
<ClCompile Include="fnmatch.cpp" />
<ClCompile Include="memaccess.cpp" />
<ClCompile Include="module.cpp" />
<ClCompile Include="net\metadata.cpp" />
......@@ -110,6 +111,7 @@
<ClInclude Include="dataaccessorimpl.h" />
<ClInclude Include="dia\diacallback.h" />
<ClInclude Include="dia\diawrapper.h" />
<ClInclude Include="fnmatch.h" />
<ClInclude Include="moduleimp.h" />
<ClInclude Include="net\metadata.h" />
<ClInclude Include="net\net.h" />
......
......@@ -139,6 +139,9 @@
<ClCompile Include="win\tagged.cpp">
<Filter>win</Filter>
</ClCompile>
<ClCompile Include="fnmatch.cpp">
<Filter>common</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h" />
......@@ -281,6 +284,9 @@
<ClInclude Include="..\include\kdlib\tagged.h">
<Filter>kdlib/include</Filter>
</ClInclude>
<ClInclude Include="fnmatch.h">
<Filter>common</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="kdlib/include">
......
......@@ -10,33 +10,7 @@
#include "net/nettype.h"
#include "net/metadata.h"
#include <boost/regex.hpp>
///////////////////////////////////////////////////////////////////////////////
namespace {
///////////////////////////////////////////////////////////////////////////////
const boost::wregex r1(L"\\?");
const boost::wregex r2(L"\\*");
const boost::wregex r3(L"\\.");
bool fnmatch( const std::wstring& pattern, const std::wstring& str)
{
std::wstring mask = pattern;
mask = boost::regex_replace(mask, r1, L".");
mask = boost::regex_replace(mask, r2, L".*");
mask = boost::regex_replace(mask, r3, L"\\.");
boost::wsmatch matchResult;
boost::wregex regEx(mask);
return boost::regex_match(str, matchResult, regEx);
}
///////////////////////////////////////////////////////////////////////////////
}
#include "fnmatch.h"
namespace kdlib {
......
......@@ -14,6 +14,7 @@
#include "typeinfoimp.h"
#include "typedvarimp.h"
#include "processmon.h"
#include "fnmatch.h"
namespace {
......@@ -1866,4 +1867,58 @@ TypeInfoPtr TypeInfoSymbolProvider::getTypeByName(const std::wstring& name)
///////////////////////////////////////////////////////////////////////////////
TypeInfoEnumeratorPtr TypeInfoSymbolProvider::getTypeEnumerator(const std::wstring& mask)
{
return TypeInfoEnumeratorPtr( new TypeInfoSymbolEnum(m_symbolSession, mask) );
}
///////////////////////////////////////////////////////////////////////////////
inline
bool isTypeTag(SymTags tag)
{
switch(tag)
{
case SymTagUDT:
case SymTagEnum:
case SymTagTypedef:
return true;
}
return false;
}
TypeInfoSymbolEnum::TypeInfoSymbolEnum(SymbolSessionPtr& symSession, const std::wstring& mask)
{
m_index = 0;
SymbolPtr symScope = symSession->getSymbolScope();
size_t symCount = symScope->getChildCount();
for ( size_t index = 0; index < symCount; index++)
{
SymbolPtr sym = symScope->getChildByIndex(index);
if (!isTypeTag(sym->getSymTag()) )
continue;
std::wstring symName = sym->getName();
if ( mask.empty() || fnmatch(mask, symName ) )
{
m_typeList.push_back( loadType(sym) );
}
}
}
///////////////////////////////////////////////////////////////////////////////
TypeInfoPtr TypeInfoSymbolEnum::Next()
{
if ( m_index < m_typeList.size() )
return m_typeList[m_index++];
return TypeInfoPtr();
}
///////////////////////////////////////////////////////////////////////////////
} // kdlib namespace end
......@@ -998,6 +998,22 @@ protected:
///////////////////////////////////////////////////////////////////////////////
class TypeInfoSymbolEnum : public TypeInfoEnumerator {
public:
TypeInfoSymbolEnum(SymbolSessionPtr& symSession, const std::wstring& mask);
virtual TypeInfoPtr Next();
private:
std::vector<TypeInfoPtr> m_typeList;
size_t m_index;
};
///////////////////////////////////////////////////////////////////////////////
class TypeInfoSymbolProvider : public TypeInfoProvider
{
public:
......@@ -1008,6 +1024,8 @@ private:
virtual TypeInfoPtr getTypeByName(const std::wstring& name);
virtual TypeInfoEnumeratorPtr getTypeEnumerator(const std::wstring& mask = L"");
private:
SymbolSessionPtr m_symbolSession;
......
......@@ -367,3 +367,66 @@ TEST_F(ClangTest, Typedef)
ASSERT_EQ(L"_Test", typeProvider->getTypeByName(L"TEST")->getName() );
}
TEST_F(ClangTest, TypeProviderEnum)
{
const std::wstring src = L"#include \"../../../kdlib/include/test/testvars.h\"";
TypeInfoProviderPtr typeProvider;
ASSERT_NO_THROW( typeProvider = getTypeInfoProviderFromSource(src) );
TypeInfoEnumeratorPtr typeEnum;
size_t count;
ASSERT_NO_THROW( typeEnum = typeProvider->getTypeEnumerator() );
for ( count = 0; 0 != typeEnum->Next(); ++count);
EXPECT_LT(1000, count);
ASSERT_NO_THROW( typeEnum = typeProvider->getTypeEnumerator(L"struct*") );
for ( count = 0; 0 != typeEnum->Next(); ++count);
EXPECT_EQ(13, count);
}
static const wchar_t template_func_src1[] = L"\
\
template<typename T1, typename T2> \
T1 func(T2 v) { \
return v * 10; \
} \
";
static const wchar_t template_func_src2[] = L"\
\
template<typename T1, typename T2> \
T1 func(T2 v) { \
return v * 10; \
} \
\
template<> \
int func<int,int>(int v); \
";
static const wchar_t template_func_src3[] = L"\
\
template<typename T> \
class Generic { \
\
int intMethod() { \
return 0; \
} \
\
T tMethod() { \
return 0; \
} \
}; \
";
TEST_F(ClangTest, TemplateFunc)
{
EXPECT_THROW(compileType(template_func_src1, L"func"), TypeException );
EXPECT_NO_THROW( compileType(template_func_src2, L"func") );
EXPECT_THROW( compileType(template_func_src3, L"Generic::intMethod"), TypeException );
EXPECT_THROW( compileType(template_func_src3, L"Generic::tMethod"), TypeException );
}
......@@ -592,3 +592,22 @@ TEST_F(TypeInfoTest, GetScopeName)
}
TEST_F(TypeInfoTest, PdbProviderEnum)
{
TypeInfoProviderPtr typeProvider;
ASSERT_NO_THROW( typeProvider = getTypeInfoProviderFromPdb( m_targetModule->getSymFile() ) );
TypeInfoEnumeratorPtr typeEnum;
size_t count;
ASSERT_NO_THROW( typeEnum = typeProvider->getTypeEnumerator() );
for ( count = 0; 0 != typeEnum->Next(); ++count);
EXPECT_LT(1000, count);
ASSERT_NO_THROW( typeEnum = typeProvider->getTypeEnumerator(L"struct*") );
for ( count = 0; 0 != typeEnum->Next(); ++count);
EXPECT_EQ(12, count);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment