Commit 977dfab3 authored by ussrhero's avatar ussrhero

Expreval

parent 4d702f44
......@@ -115,6 +115,8 @@ public:
virtual void getFileVersion(unsigned long& majorVersion, unsigned long& minorVerion, unsigned long& revision, unsigned long& build) = 0;
virtual void getFixedFileInfo( FixedFileInfo &fixedFileInfo ) = 0;
virtual ScopePtr getScope() = 0;
};
///////////////////////////////////////////////////////////////////////////////
......
#pragma once
#include <vector>
#include <map>
#include <boost/utility.hpp>
#include <boost/shared_ptr.hpp>
......@@ -8,6 +9,7 @@
#include "kdlib/typeinfo.h"
#include "kdlib/variant.h"
#include "kdlib/dataaccessor.h"
#include "kdlib/exceptions.h"
namespace kdlib {
......@@ -18,12 +20,11 @@ typedef std::vector<TypedVarPtr> TypedVarList;
class TypedValue;
typedef std::vector<TypedValue> TypedValueList;
class TypedVarScope;
typedef boost::shared_ptr<TypedVarScope> TypedVarScopePtr;
class StackFrame;
typedef boost::shared_ptr<StackFrame> StackFramePtr;
class Scope;
typedef boost::shared_ptr<Scope> ScopePtr;
///////////////////////////////////////////////////////////////////////////////
......@@ -88,6 +89,11 @@ class TypedVar : public NumConvertable, private boost::noncopyable {
public:
template <typename T>
explicit operator T() {
return static_cast<T>(getValue());
}
template <typename T>
explicit operator T() const {
return static_cast<T>(getValue());
......@@ -138,22 +144,13 @@ protected:
{}
};
///////////////////////////////////////////////////////////////////////////////
class TypedValue
class TypedValue : public NumConvertable
{
public:
operator NumVariant() {
return getValue();
}
operator NumVariant() const {
return getValue();
}
TypedValue();
TypedValue(const TypedVarPtr& var) : m_value(var){}
......@@ -178,19 +175,31 @@ public:
TypedValue( bool var ) : m_value( loadBoolVar(var) ) {}
template<typename T>
explicit operator T() {
if ( sizeof(T) < getSize() )
throw TypeException( L"cannot cast TypedValue");
TypedValue(T* var) : m_value(loadULongLongVar((unsigned long long)var)) {}
template<typename T, typename std::enable_if < !std::is_arithmetic<T>::value && std::is_trivially_copyable<T>::value, T >::type* = nullptr>
explicit operator T () const
{
auto name = typeid(T).name();
DataAccessorPtr dataRange = getCacheAccessor(sizeof(T) );
if ( sizeof(T) > getSize() )
throw TypeException( L"cannot cast TypedValue");
DataAccessorPtr dataRange = getCacheAccessor( m_value->getSize() );
m_value->writeBytes(dataRange);
std::vector<unsigned char> buf(sizeof(T));
dataRange->readBytes(buf, sizeof(T));
std::vector<unsigned char> buf(m_value->getSize());
dataRange->readBytes(buf, m_value->getSize());
return *reinterpret_cast<T*>(&buf.front());
}
template<typename T, typename std::enable_if < std::is_arithmetic<T>::value, T >::type* = nullptr>
explicit operator T() const
{
return static_cast<T>(getValue());
}
public:
std::wstring str() {
......@@ -310,9 +319,96 @@ private:
};
template<typename T>
TypedValue makeArrayValue (const std::vector<T>& data);
template <typename T>
TypedValue makeValue(const std::wstring &typeName, const T& copyVar) {
return loadTypedVar(typeName, getCacheAccessor(copyVar));
}
template <typename T>
TypedValue makeValue(const TypeInfoPtr &typeInfo, const T& copyVar) {
return loadTypedVar(typeInfo, getCacheAccessor(copyVar));
}
inline
TypedValue makePointer(const TypeInfoPtr &typeInfo, const MEMOFFSET_64& addr)
{
return TypedValue(addr).castTo(typeInfo->ptrTo());
}
inline
TypedValue makePointer(const std::wstring &typeName, const MEMOFFSET_64& addr)
{
return TypedValue(addr).castTo(loadType(typeName)->ptrTo());
}
///////////////////////////////////////////////////////////////////////////////
class Scope
{
public:
virtual TypedValue get(const std::wstring& varName) const = 0;
virtual bool find(const std::wstring& varName, TypedValue& value) const = 0;
public:
TypedValue operator[] (const std::wstring& varName) {
return get(varName);
}
};
class ScopeList : public Scope
{
public:
ScopeList()
{}
explicit ScopeList(const std::list < std::pair<std::wstring, TypedValue> >& varList)
{
m_scope.insert(varList.begin(), varList.end());
}
virtual TypedValue get(const std::wstring& varName) const override
{
auto var = m_scope.find(varName);
if (var == m_scope.end())
throw DbgException("scope doesn't contain varibale");
return var->second;
}
virtual bool find(const std::wstring& varName, TypedValue& value) const override
{
auto var = m_scope.find(varName);
if (var == m_scope.end())
return false;
value = var->second;
return true;
}
private:
std::map<std::wstring, TypedValue> m_scope;
};
inline ScopePtr makeScope(const std::list < std::pair<std::wstring, TypedValue> >& varList)
{
return ScopePtr(new ScopeList(varList));
}
///////////////////////////////////////////////////////////////////////////////
TypedValue callRaw(MEMOFFSET_64 addr, CallingConventionType callingConvention, const TypedValueList& arglst);
TypedValue evalExpr(const std::wstring& expr, const std::list< std::pair<std::wstring, TypedValue> >& scope = {});
TypedValue evalExpr(const std::wstring& expr, const ScopePtr& scope = ScopePtr(new ScopeList()),
const TypeInfoProviderPtr& typeInfoProvider = getDefaultTypeInfoProvider());
TypedValue evalExpr(const std::string& expr, const ScopePtr& scope = ScopePtr(new ScopeList()),
const TypeInfoProviderPtr& typeInfoProvider = getDefaultTypeInfoProvider());
///////////////////////////////////////////////////////////////////////////////
......
......@@ -169,7 +169,9 @@ public:
};
TypeInfoProviderPtr getTypeInfoProviderFromSource( const std::wstring& source, const std::wstring& opts = L"" );
TypeInfoProviderPtr getTypeInfoProviderFromSource(const std::string& source, const std::string& opts = "");
TypeInfoProviderPtr getTypeInfoProviderFromPdb( const std::wstring& pdbFile, MEMOFFSET_64 loadBase = 0 );
TypeInfoProviderPtr getDefaultTypeInfoProvider();
///////////////////////////////////////////////////////////////////////////////
......@@ -190,4 +192,9 @@ TypeInfoPtr makeBoolConst(bool val);
///////////////////////////////////////////////////////////////////////////////
TypeInfoPtr evalType(const std::wstring& expr, const TypeInfoProviderPtr typeInfoProvider = getDefaultTypeInfoProvider());
TypeInfoPtr evalType(const std::string& expr, const TypeInfoProviderPtr typeInfoProvider = getDefaultTypeInfoProvider());
///////////////////////////////////////////////////////////////////////////////
}; // kdlib namespace end
......@@ -139,11 +139,11 @@ public:
return *this;
}
NumVariant(bool val)
{
m_numType = ucharT;
m_ucharVal = val;
}
//NumVariant(bool val)
//{
// m_numType = ucharT;
// m_ucharVal = val;
//}
NumVariant(char val)
{
......@@ -218,6 +218,13 @@ public:
m_doubleVal = val;
}
template<typename T>
NumVariant(const T* val)
{
m_numType = ulonglongT;
m_ulonglongVal = (unsigned long long)val;
}
char asChar() const {
return cast( charT ).m_charVal;
}
......@@ -266,6 +273,10 @@ public:
return cast( doubleT ).m_doubleVal;
}
bool asBool() const {
return cast(ucharT).m_ucharVal != 0;
}
std::wstring asStr() const {
std::wstringstream sstr;
......@@ -592,6 +603,7 @@ public:
throw NumVariantError();
}
explicit operator char() const {
return asChar();
}
......@@ -607,7 +619,7 @@ public:
explicit operator unsigned short() const {
return asUShort();
}
explicit operator unsigned long() const {
return asULong();
}
......@@ -620,7 +632,7 @@ public:
return asULongLong();
}
explicit operator long long() const {
explicit operator long long() const {
return asLongLong();
}
......@@ -632,10 +644,19 @@ public:
return asDouble();
}
explicit operator bool() const {
explicit operator int() const {
return asInt();
}
explicit operator unsigned int() const{
return asUInt();
}
explicit operator bool () const {
return asChar() != 0;
}
private:
enum NumType { charT, ucharT, shortT, ushortT, longT, ulongT, longlongT, ulonglongT, intT, uintT, floatT, doubleT, maxT };
......@@ -799,6 +820,7 @@ private:
}
};
inline bool operator==(const NumVariant& v1, const NumVariant& v2)
{
return NumVariant::all_op<bool, equal_op>(v1, v2);
......@@ -934,74 +956,9 @@ inline NumVariant operator-(const NumVariant& v1)
return NumVariant(0).cast(v1.m_numType) - v1;
}
/*
template<>
inline
NumVariant::operator char() const {
return asChar();
}
template<>
inline
NumVariant::operator unsigned char() const {
return asUChar();
}
template<>
inline
NumVariant::operator short() const {
return asShort();
}
template<>
inline
NumVariant::operator unsigned short() const {
return asUShort();
}
template<>
inline
NumVariant::operator unsigned long() const {
return asULong();
}
template<>
inline
NumVariant::operator long() const {
return asLong();
}
template<>
inline
NumVariant::operator unsigned long long() const {
return asULongLong();
}
template<>
inline
NumVariant::operator long long() const{
return asLongLong();
}
template<>
inline
NumVariant::operator float() const{
return asFloat();
}
template<>
inline
NumVariant::operator double() const{
return asDouble();
}
template<>
inline
NumVariant::operator bool() const {
return asChar() != 0;
}
*/
class NumConvertable
{
......
#pragma once
#include <string>
#include <list>
#pragma pack( push, 4 )
......@@ -438,5 +439,25 @@ extern TemplateStruct<TemplateStruct<int>[4]> g_template4;
////////////////////////////////////////////////////////////////////////////////
extern std::list<int> g_stdIntList;
template<typename T>
struct TestStructTemplate
{
T field;
};
extern TestStructTemplate<int> g_testStructTemplate;
template<typename T>
class TestClassTemplate
{
T field;
};
extern TestClassTemplate<int> g_testClassTemplate;
////////////////////////////////////////////////////////////////////////////////
#pragma pack ( pop )
......@@ -614,7 +614,7 @@ public:
try {
CXXRecordDecl * definition = Declaration->getDefinition();
if (definition)
{
if (definition->isInvalidDecl())
......@@ -629,6 +629,8 @@ public:
LangOptions lo;
PrintingPolicy pp(lo);
pp.SuppressTagKeyword = true;
pp.MSVCFormatting = true;
std::string name = (*specIt)->getTypeForDecl()->getCanonicalTypeInternal().getAsString(pp);
auto rr = llvm::dyn_cast<CXXRecordDecl>(*specIt);
......@@ -649,8 +651,10 @@ public:
(*m_typeMap)[name] = TypeInfoPtr(new TypeInfoClangStructNoDef(strToWStr(name), m_session, Declaration));
}
} catch(TypeException& )
{}
}
catch (TypeException&)
{
}
return true;
}
......@@ -750,15 +754,14 @@ TypeInfoPtr compileType( const std::wstring& sourceCode, const std::wstring& typ
///////////////////////////////////////////////////////////////////////////////
TypeInfoProviderClang::TypeInfoProviderClang( const std::wstring& sourceCode, const std::wstring& compileOptions)
TypeInfoProviderClang::TypeInfoProviderClang( const std::string& sourceCode, const std::string& compileOptions)
{
std::vector< std::string > args;
typedef boost::tokenizer< boost::escaped_list_separator<char> > Tokenizer;
boost::escaped_list_separator<char> Separator( '\\', ' ', '\"' );
std::string optionsStr = wstrToStr(compileOptions);
Tokenizer tok( optionsStr, Separator );
Tokenizer tok(compileOptions, Separator );
std::copy(tok.begin(), tok.end(), std::inserter(args, args.end() ) );
......@@ -773,13 +776,16 @@ TypeInfoProviderClang::TypeInfoProviderClang( const std::wstring& sourceCode, co
if ( it == args.end() )
{
if ( getCPUMode() == CPU_AMD64 )
args.push_back("--target=x86_64-pc-windows-msvc");
else if ( getCPUMode() == CPU_I386 )
args.push_back("--target=i686-pc-windows-msvc");
if (targetExecutionStatus() != DebugStatusNoDebuggee )
{
if (getCPUMode() == CPU_AMD64)
args.push_back("--target=x86_64-pc-windows-msvc");
else if (getCPUMode() == CPU_I386)
args.push_back("--target=i686-pc-windows-msvc");
}
}
std::unique_ptr<ASTUnit> ast = buildASTFromCodeWithArgs(wstrToStr(sourceCode), args );
std::unique_ptr<ASTUnit> ast = buildASTFromCodeWithArgs(sourceCode, args );
m_astSession = ClangASTSession::getASTSession(ast);
......@@ -837,9 +843,17 @@ TypeInfoPtr TypeInfoProviderClangEnum::Next()
TypeInfoProviderPtr getTypeInfoProviderFromSource( const std::wstring& source, const std::wstring& opts )
{
return TypeInfoProviderPtr( new TypeInfoProviderClang(source, opts) );
return TypeInfoProviderPtr( new TypeInfoProviderClang(wstrToStr(source), wstrToStr(opts) ) );
}
///////////////////////////////////////////////////////////////////////////////
TypeInfoProviderPtr getTypeInfoProviderFromSource(const std::string& source, const std::string& opts)
{
return TypeInfoProviderPtr(new TypeInfoProviderClang(source, opts));
}
///////////////////////////////////////////////////////////////////////////////
}
......
......@@ -342,7 +342,7 @@ class TypeInfoProviderClang : public TypeInfoProvider, public boost::enable_shar
public:
TypeInfoProviderClang( const std::wstring& sourceCode, const std::wstring& compileOptions);
TypeInfoProviderClang( const std::string& sourceCode, const std::string& compileOptions);
private:
......
This diff is collapsed.
This diff is collapsed.
#pragma once
#include "parser.h"
namespace kdlib {
namespace parser {
class OperandMatcher : public Matcher
{
public:
auto match(const TokenRange& matchRange)
{
return matchResult = numericMatcher.match(matchRange);
}
const auto& getNumeric() const
{
return numericMatcher;
}
private:
NumericMatcher numericMatcher;
};
class UnaryRvalueOperation : public Matcher
{
public:
auto match(const TokenRange& matchRange)
{
return matchResult = any_of(
Is<clang::tok::minus>(),
Is<clang::tok::plus>(),
Is<clang::tok::exclaim>(),
Is<clang::tok::tilde>()
).match(matchRange);
}
};
class ConstExpressionMatcher : public Matcher
{
public:
auto match(const TokenRange& matchRange)
{
auto matcher = all_of(opt(leftOps), operandMatcher);
matchResult = matcher.match(matchRange);
return matchResult;
}
const auto& getOperand() const {
return operandMatcher;
}
const auto& getLeftOps() const
{
return leftOps;
}
private:
OperandMatcher operandMatcher;
ListMatcher<UnaryRvalueOperation> leftOps;
};
}
}
#pragma once
#include <list>
#include <vector>
#include "clang/Lex/Token.h"
namespace kdlib {
std::string tokenToStr(const clang::Token& token);
using TokenIterator = std::list<clang::Token>::const_iterator;
using TokenRange = std::pair<TokenIterator, TokenIterator>;
namespace parser {
using Token = clang::Token;
using TokenKind = clang::tok::TokenKind;
class MatchResult
{
public:
MatchResult() : matched(false)
{}
MatchResult(const TokenRange& m) :
matchedRange(m)
{
matched = matchedRange.first != matchedRange.second;
}
~MatchResult()
{}
const TokenRange& getMatchedRange() const
{
assert(matched);
return matchedRange;
}
TokenIterator begin() const
{
assert(matched);
return matchedRange.first;
}
TokenIterator end() const
{
assert(matched);
return matchedRange.second;
}
bool isMatched() const
{
return matched;
}
private:
bool matched;
TokenRange matchedRange;
};
class Matcher
{
public:
const MatchResult& getMatchResult() const
{
return matchResult;
}
protected:
MatchResult matchResult;
};
template<TokenKind tokenKind>
class Is : public Matcher
{
public:
auto match(const TokenRange& matchRange)
{
auto& beg = matchRange.first;
auto& end = matchRange.second;
if (beg != end && (*beg).is(tokenKind))
{
return matchResult = MatchResult(std::make_pair(beg, std::next(beg, 1)));
}
return matchResult = MatchResult();
}
};
class BaseOpt
{};
template<typename T>
class Opt : public BaseOpt
{
public:
Opt(T& m) : matcher(m)
{}
auto match(const TokenRange& matchRange)
{
return matcher.match(matchRange);
}
private:
T& matcher;
};