...
 
Commits (2)
......@@ -100,7 +100,7 @@ DataAccessorPtr getCacheAccessor(size_t bufferSize, const std::wstring& locatio
DataAccessorPtr getCacheAccessor(const void* rawBuffer, size_t bufferSize, const std::wstring& location=L"");
DataAccessorPtr getCacheAccessor(const NumVariant& var, const std::wstring& location=L"");
template<typename T>
template<typename T, typename std::enable_if< !std::is_integral<T>::value >::type* = nullptr >
DataAccessorPtr getCacheAccessor(const T& structType, const std::wstring& location=L"")
{
return getCacheAccessor(&structType, sizeof(structType), location);
......
......@@ -70,6 +70,7 @@ TypedVarPtr loadBoolVar( bool var );
TypedVarPtr loadFloatVar( float var );
TypedVarPtr loadDoubleVar( double var );
TypedVarPtr loadWCharVar( wchar_t var );
TypedVarPtr loadNullPtr();
class TypedVar : public NumConvertable, private boost::noncopyable {
......@@ -175,6 +176,7 @@ public:
TypedValue( double var ) : m_value( loadDoubleVar(var) ) {}
TypedValue( wchar_t var ) : m_value( loadWCharVar(var) ) {}
TypedValue( bool var ) : m_value( loadBoolVar(var) ) {}
TypedValue( nullptr_t ) : m_value(loadNullPtr() ) {}
template<typename T>
TypedValue(T* var) : m_value(loadULongLongVar((unsigned long long)var)) {}
......
......@@ -779,6 +779,9 @@ TypedValue ExprEval::getIdentifierValue()
if (fullName == "false")
return TypedValue(false);
if (fullName == "nullptr")
return TypedValue(nullptr);
TypedValue result;
std::wstring wname = strToWStr(fullName);
if (m_scope->find(wname, result))
......@@ -801,6 +804,12 @@ TypeInfoPtr applyComplexModifierRecursive(const parser::ComplexMatcher& matcher,
{
TypeInfoPtr typeInfo = typeInfo_;
if (matcher.isReference())
{
if (typeInfo->isVoid() )
throw ExprException(L"error syntax");
}
if (matcher.isPointer())
{
for ( auto p : matcher.getPointerMatcher().getPointerMatchers() )
......@@ -1266,6 +1275,12 @@ std::string TypeEval::getBaseTypeName(const parser::BaseTypeMatcher& baseTypeMa
TypeInfoPtr TypeEval::getBaseType()
{
if (m_tokens->front().is(clang::tok::kw_void))
{
m_tokens->pop_front();
return loadType(L"Void");
}
std::unique_ptr<BaseTypeBuilder> baseTypeBuilder(new EmptyBaseTypeBuilder);
while (true)
......@@ -1637,7 +1652,8 @@ static const std::map< std::string, std::function<kdlib::TypeInfoPtr(void)> >
{ "size_t", []() { return kdlib::ptrSize() == 4 ? kdlib::loadType(L"UInt4B") : kdlib::loadType(L"UInt8B"); } },
{ "intptr_t", []() { return kdlib::ptrSize() == 4 ? kdlib::loadType(L"Int4B") : kdlib::loadType(L"Int8B"); } },
{ "uintptr_t", []() { return kdlib::ptrSize() == 4 ? kdlib::loadType(L"UInt4B") : kdlib::loadType(L"UInt8B"); } },
{ "bool", []() { return kdlib::loadType(L"Bool"); } }
{ "bool", []() { return kdlib::loadType(L"Bool"); } },
{ "void", []() { return kdlib::loadType(L"Void"); } }
};
bool isStandardIntType(const clang::Token& token)
......
......@@ -179,6 +179,16 @@ public:
return arrayMatcher;
}
bool isReference() const
{
return refMatcher.getMatchResult().isMatched();
}
const RefMatcher& getRefMatcher() const
{
assert(isReference());
return refMatcher;
}
private:
......
......@@ -621,6 +621,14 @@ TypedVarPtr loadBoolVar(bool var)
///////////////////////////////////////////////////////////////////////////////
TypedVarPtr loadNullPtr()
{
DataAccessorPtr accessor = getCacheAccessor(8);
return loadType(L"Void*")->getVar(accessor);
}
///////////////////////////////////////////////////////////////////////////////
TypedVarPtr loadFloatVar( float var )
{
DataAccessorPtr accessor = getCacheAccessor( sizeof(float) );
......
......@@ -58,7 +58,7 @@ public:
throw TypeException(m_name, L"method has no offset");
if (m_constMember)
throw TypeException(m_name, L"constatnt has no offset");
throw TypeException(m_name, L"constant has no offset");
return m_offset;
}
......
......@@ -310,6 +310,12 @@ TEST(ExprEval, PointerArithm)
EXPECT_THROW(evalExpr("-(long*)10"), DbgException);
}
TEST(ExprEval, NullPtr)
{
EXPECT_EQ(0, evalExpr("(void*)0"));
EXPECT_EQ(0, evalExpr("(int**)nullptr"));
}
class ExprEvalTarget : public ProcessFixture
{
public:
......@@ -381,11 +387,6 @@ TEST_F(ExprEvalTarget, CastUdt)
EXPECT_THROW(evalExpr("(structTest)g_classChild", m_targetModule->getScope()), DbgException);
}
//
//TEST_F(ExprEvalTarget, CastUdt)
//{
// EXPECT_THROW(evalExpr("(int)g_classChild", m_targetModule->getScope()), DbgException);
TEST_F(ExprEvalTarget, EnumVal)
{
EXPECT_EQ(enumType::THREE, evalExpr("enumType::THREE", m_targetModule->getScope()));
......@@ -436,4 +437,5 @@ TEST_F(ExprEvalTarget, Eval1)
EXPECT_EQ(g_testArray[1].m_field1, evalExpr("g_testArray[1].m_field1", m_targetModule->getScope()));
EXPECT_EQ(g_structTest1.m_field4->m_field1 + 200, evalExpr("g_structTest1.m_field4->m_field1 + 200", m_targetModule->getScope()));
EXPECT_EQ( (g_testArray + 1)->m_field1 % 4, evalExpr("(g_testArray + 1)->m_field1 % 4", m_targetModule->getScope()));
}
\ No newline at end of file
}
......@@ -442,3 +442,15 @@ TEST(TypeEvalTest, TemplateUnusedType)
EXPECT_NO_THROW(evalType("TestStruct<int,TestStruct<int,int>>", typeProvider));
}
TEST(TypeEvalTest, Void)
{
EXPECT_EQ(L"Void", evalType("void")->getName());
EXPECT_EQ(L"Void*", evalType("void *")->getName());
EXPECT_EQ(L"Void*[1]", evalType("void *[1]")->getName());
EXPECT_THROW(evalType("void&"), TypeException);
EXPECT_THROW(evalType("void&&"), TypeException);
EXPECT_THROW(evalType("void[5]"), TypeException);
}