Commit bd0e7533 authored by ussrhero's avatar ussrhero
Browse files

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"" );
......
......@@ -17,6 +17,7 @@
#include "strconvert.h"
#include "clang.h"
#include "fnmatch.h"
using namespace clang;
using namespace clang::tooling;
......@@ -211,8 +212,8 @@ TypeInfoClangStruct::TypeInfoClangStruct(const std::wstring & name, ClangASTSess
m_astSession(session),
m_decl(decl)
{
if ( decl->isInvalidDecl() )
throw TypeException(L"Invalid declaration");
// if ( decl->isInvalidDecl() )
/// throw TypeException(L"Invalid declaration");
}
///////////////////////////////////////////////////////////////////////////////
......@@ -389,17 +390,20 @@ void TypeInfoClangEnum::getFields()
///////////////////////////////////////////////////////////////////////////////
class StructDefVisitor : public RecursiveASTVisitor<StructDefVisitor>
class DeclNamedVisitor : public RecursiveASTVisitor<DeclNamedVisitor>
{
public:
StructDefVisitor(ClangASTSessionPtr& astSession, const std::string& typeName) :
DeclNamedVisitor(ClangASTSessionPtr& astSession, const std::string& typeName) :
m_session(astSession),
m_typeName(typeName)
{}
bool VisitCXXRecordDecl(CXXRecordDecl *Declaration)
{
if ( Declaration->isInvalidDecl() )
return true;
std::string& name = Declaration->getQualifiedNameAsString();
if ( name != m_typeName)
......@@ -415,6 +419,9 @@ public:
bool VisitTypedefDecl(TypedefDecl *Declaration)
{
if ( Declaration->isInvalidDecl() )
return true;
std::string& name = Declaration->getQualifiedNameAsString();
if ( name != m_typeName)
......@@ -429,15 +436,24 @@ public:
bool VisitFunctionDecl(FunctionDecl *Declaration)
{
if ( Declaration->isInvalidDecl() )
return true;
if ( Declaration->getTemplatedKind() == FunctionDecl::TemplatedKind:: TK_FunctionTemplate )
return true;
if ( CXXRecordDecl *parentClassDecl = llvm::dyn_cast<CXXRecordDecl>(Declaration->getDeclContext()))
{
if ( parentClassDecl->getDescribedClassTemplate() )
return true;
}
std::string& name = Declaration->getQualifiedNameAsString();
if ( name != m_typeName)
return true;
if ( Declaration->isInvalidDecl() )
throw TypeException(L"Invalid declaration");
const FunctionProtoType* protoType = Declaration->getFunctionType()->getAs<FunctionProtoType>();
const FunctionProtoType* protoType = Declaration->getFunctionType()->getAs<FunctionProtoType>();
m_typeInfo = TypeInfoPtr( new TypeInfoClangFunc(m_session, protoType ) );
......@@ -446,6 +462,9 @@ public:
bool VisitEnumDecl (EnumDecl *Declaration)
{
if ( Declaration->isInvalidDecl() )
return true;
std::string& name = Declaration->getQualifiedNameAsString();
if ( name != m_typeName)
......@@ -471,18 +490,271 @@ private:
///////////////////////////////////////////////////////////////////////////////
TypeInfoPtr ClangASTSession::getTypeInfo(const std::wstring& name)
//class DeclNextVisitor : public RecursiveASTVisitor<DeclNextVisitor>
//{
//public:
//
// DeclNextVisitor(ClangASTSessionPtr& astSession, const std::string& mask, size_t pos) :
// m_session(astSession),
// m_mask(mask),
// m_currentPos(0),
// m_startPos(pos)
// {}
//
// bool VisitCXXRecordDecl(CXXRecordDecl *Declaration)
// {
// try {
//
// if (m_startPos > m_currentPos++ )
// return true;
//
// if ( Declaration->isInvalidDecl() )
// return true;
//
// CXXRecordDecl * definition = Declaration->getDefinition();
//
// if ( definition && definition->isInvalidDecl() )
// return true;
//
// std::string name = Declaration->getNameAsString();
//
// if (m_mask.length() > 0 && !fnmatch(m_mask, name) )
// return true;
//
// TypeInfoPtr typeInfo;
//
// if ( definition )
// typeInfo = TypeInfoPtr( new TypeInfoClangStruct( strToWStr(name), m_session, definition ) );
// else
// typeInfo = TypeInfoPtr( new TypeInfoClangStructNoDef( strToWStr(name), m_session, Declaration ) );
//
// m_typeInfo = typeInfo;
//
// return false;
//
// } catch(TypeException& )
// {}
//
// return true;
// }
//
// bool VisitFunctionDecl(FunctionDecl *Declaration)
// {
// try {
//
// if (m_startPos > m_currentPos++ )
// return true;
//
// if ( Declaration->isInvalidDecl() )
// return true;
//
// if ( Declaration->getTemplatedKind() == FunctionDecl::TemplatedKind:: TK_FunctionTemplate )
// return true;
//
// if ( CXXRecordDecl *parentClassDecl = llvm::dyn_cast<CXXRecordDecl>(Declaration->getDeclContext()))
// {
// if ( parentClassDecl->getDescribedClassTemplate() )
// return true;
// }
//
// std::string name = Declaration->getNameAsString();
//
// if (m_mask.length() > 0 && !fnmatch(m_mask, name) )
// return true;
//
// const FunctionProtoType* protoType = Declaration->getFunctionType()->getAs<FunctionProtoType>();
//
// TypeInfoPtr typeInfo = TypeInfoPtr( new TypeInfoClangFunc(m_session, protoType ) );
//
// m_typeInfo = typeInfo;
//
// return false;
//
// } catch(TypeException& )
// {}
//
// return true;
// }
//
// bool VisitEnumDecl (EnumDecl *Declaration)
// {
// try {
//
// if (m_startPos > m_currentPos++ )
// return true;
//
// if ( Declaration->isInvalidDecl() )
// return true;
//
// std::string name = Declaration->getNameAsString();
//
// if (m_mask.length() > 0 && !fnmatch(m_mask, name) )
// return true;
//
// TypeInfoPtr typeInfo = TypeInfoPtr( new TypeInfoClangEnum(m_session, Declaration) );
//
// m_typeInfo = typeInfo;
//
// return false;
//
// } catch(TypeException& )
// {}
//
// return true;
// }
//
// TypeInfoPtr getTypeInfo() {
// return m_typeInfo;
// }
//
// size_t currentPos() {
// return m_currentPos;
// }
//
//private:
//
// std::string m_mask;
//
// ClangASTSessionPtr m_session;
//
// TypeInfoPtr m_typeInfo;
//
// size_t m_currentPos;
// size_t m_startPos;
//};
///////////////////////////////////////////////////////////////////////////////
class DeclNextVisitor : public RecursiveASTVisitor<DeclNextVisitor>
{
StructDefVisitor visitor( shared_from_this(), wstrToStr(name) );
visitor.TraverseDecl( m_astUnit->getASTContext().getTranslationUnitDecl() );
TypeInfoPtr ptr = visitor.getTypeInfo();
public:
if (!ptr)
throw TypeException(L"Failed to get type from AST");
DeclNextVisitor(ClangASTSessionPtr& astSession, std::map<std::string, TypeInfoPtr>* typeMap) :
m_session(astSession),
m_typeMap(typeMap)
{}
bool VisitCXXRecordDecl(CXXRecordDecl *Declaration)
{
try {
CXXRecordDecl * definition = Declaration->getDefinition();
if ( definition && definition->isInvalidDecl() )
return true;
std::string name = Declaration->getQualifiedNameAsString();
TypeInfoPtr typeInfo;
if ( definition )
typeInfo = TypeInfoPtr( new TypeInfoClangStruct( strToWStr(name), m_session, definition ) );
else
typeInfo = TypeInfoPtr( new TypeInfoClangStructNoDef( strToWStr(name), m_session, Declaration ) );
(*m_typeMap)[name] = typeInfo;
} catch(TypeException& )
{}
return true;
}
bool VisitTypedefDecl(TypedefDecl *Declaration)
{
try {
if ( Declaration->isInvalidDecl() )
return true;
std::string& name = Declaration->getQualifiedNameAsString();
QualType decl = Declaration->getUnderlyingType().getCanonicalType();
(*m_typeMap)[name] = getTypeForClangType(m_session, decl);
} catch(TypeException& )
{}
return true;
}
bool VisitFunctionDecl(FunctionDecl *Declaration)
{
try {
if ( Declaration->isInvalidDecl() )
return true;
if ( Declaration->getTemplatedKind() == FunctionDecl::TemplatedKind:: TK_FunctionTemplate )
return true;
if ( CXXRecordDecl *parentClassDecl = llvm::dyn_cast<CXXRecordDecl>(Declaration->getDeclContext()))
{
if ( parentClassDecl->getDescribedClassTemplate() )
return true;
}
std::string name = Declaration->getQualifiedNameAsString();
const FunctionProtoType* protoType = Declaration->getFunctionType()->getAs<FunctionProtoType>();
TypeInfoPtr typeInfo = TypeInfoPtr( new TypeInfoClangFunc(m_session, protoType ) );
(*m_typeMap)[name] = typeInfo;
} catch(TypeException& )
{}
return true;
}
bool VisitEnumDecl (EnumDecl *Declaration)
{
try {
if ( Declaration->isInvalidDecl() )
return true;
std::string name = Declaration->getQualifiedNameAsString();
TypeInfoPtr typeInfo = TypeInfoPtr( new TypeInfoClangEnum(m_session, Declaration) );
(*m_typeMap)[name] = typeInfo;
} catch(TypeException& )
{}
return true;
}
private:
ClangASTSessionPtr m_session;
std::map<std::string, TypeInfoPtr> *m_typeMap;
};
return ptr;
}
///////////////////////////////////////////////////////////////////////////////
//TypeInfoPtr ClangASTSession::getTypeInfo(const std::wstring& name)
//{
// DeclNamedVisitor visitor( shared_from_this(), wstrToStr(name) );
// visitor.TraverseDecl( m_astUnit->getASTContext().getTranslationUnitDecl() );
//
// TypeInfoPtr ptr = visitor.getTypeInfo();
//
// if (!ptr)
// throw TypeException(L"Failed to get type from AST");
//
// return ptr;
//}
///////////////////////////////////////////////////////////////////////////////
......@@ -533,13 +805,55 @@ TypeInfoProviderClang::TypeInfoProviderClang( const std::wstring& sourceCode, co
std::unique_ptr<ASTUnit> ast = buildASTFromCodeWithArgs(wstrToStr(sourceCode), args );
m_astSession = ClangASTSession::getASTSession(ast);
DeclNextVisitor visitor(m_astSession, &m_typeCache);
visitor.TraverseDecl( m_astSession->getASTContext().getTranslationUnitDecl() );
}
///////////////////////////////////////////////////////////////////////////////
TypeInfoPtr TypeInfoProviderClang::getTypeByName(const std::wstring& name)
{
return m_astSession->getTypeInfo(name);
auto foundType = m_typeCache.find( wstrToStr(name) );
if ( foundType == m_typeCache.end() )
throw TypeException(name, L"Failed to get type");
return foundType->second;
}
///////////////////////////////////////////////////////////////////////////////
TypeInfoEnumeratorPtr TypeInfoProviderClang::getTypeEnumerator(const std::wstring& mask)
{
return TypeInfoEnumeratorPtr( new TypeInfoProviderClangEnum(mask, shared_from_this()) );
}
///////////////////////////////////////////////////////////////////////////////
TypeInfoProviderClangEnum::TypeInfoProviderClangEnum(const std::wstring& mask, boost::shared_ptr<TypeInfoProviderClang>& clangProvider )
{
m_index = 0;
std::string ansimask = wstrToStr(mask);
std::for_each( clangProvider->m_typeCache.begin(), clangProvider->m_typeCache.end(),
[&]( const std::pair<std::string, TypeInfoPtr> &it ) {
if (ansimask.empty() || fnmatch(ansimask, it.first) )
m_typeList.push_back(it.second);
}
);
}
///////////////////////////////////////////////////////////////////////////////
TypeInfoPtr TypeInfoProviderClangEnum::Next()
{
if ( m_index < m_typeList.size() )
return m_typeList[m_index++];
return TypeInfoPtr();
}
///////////////////////////////////////////////////////////////////////////////
......@@ -551,6 +865,5 @@ TypeInfoProviderPtr getTypeInfoProviderFromSource( const std::wstring& source,
///////////////////////////////////////////////////////////////////////////////
}
......@@ -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" />