diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 0b098370f..898ca801f 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -4303,7 +4303,10 @@ static const Token * parsedecl(const Token *type, ValueType * const valuetype, V valuetype->type = type->isLong() ? ValueType::Type::LONGDOUBLE : ValueType::Type::DOUBLE; else if (!valuetype->typeScope && (type->str() == "struct" || type->str() == "enum")) valuetype->type = ValueType::Type::NONSTD; - else if (type->isName() && valuetype->sign != ValueType::Sign::UNKNOWN_SIGN && valuetype->pointer == 0U) + else if (!valuetype->typeScope && type->type() && type->type()->classScope) { + valuetype->type = ValueType::Type::NONSTD; + valuetype->typeScope = type->type()->classScope; + } else if (type->isName() && valuetype->sign != ValueType::Sign::UNKNOWN_SIGN && valuetype->pointer == 0U) return nullptr; else if (type->str() == "*") valuetype->pointer++; @@ -4330,6 +4333,36 @@ static const Token * parsedecl(const Token *type, ValueType * const valuetype, V return (type && (valuetype->type != ValueType::Type::UNKNOWN_TYPE || valuetype->pointer > 0)) ? type : nullptr; } +static const Scope *getClassScope(const Token *tok) +{ + return tok && tok->valueType() && tok->valueType()->typeScope && tok->valueType()->typeScope->isClassOrStruct() ? + tok->valueType()->typeScope : + nullptr; +} + +static const Function *getOperatorFunction(const Token * const tok) +{ + const std::string functionName("operator" + tok->str()); + std::multimap::const_iterator it; + const Scope *classScope; + + classScope = getClassScope(tok->astOperand1()); + if (classScope) { + it = classScope->functionMap.find(functionName); + if (it != classScope->functionMap.end()) + return it->second; + } + + classScope = getClassScope(tok->astOperand2()); + if (classScope) { + it = classScope->functionMap.find(functionName); + if (it != classScope->functionMap.end()) + return it->second; + } + + return nullptr; +} + void SymbolDatabase::setValueTypeInTokenList(Token *tokens, bool cpp, char defaultSignedness, const Library* lib) { ValueType::Sign defsign; @@ -4365,9 +4398,18 @@ void SymbolDatabase::setValueTypeInTokenList(Token *tokens, bool cpp, char defau } ::setValueType(tok, ValueType(sign, type, 0U), cpp, defsign, lib); } - } else if (tok->isComparisonOp() || tok->tokType() == Token::eLogicalOp) + } else if (tok->isComparisonOp() || tok->tokType() == Token::eLogicalOp) { + if (cpp && tok->isComparisonOp() && (getClassScope(tok->astOperand1()) || getClassScope(tok->astOperand2()))) { + const Function *function = getOperatorFunction(tok); + if (function) { + ValueType vt; + parsedecl(function->retDef, &vt, defsign, lib); + ::setValueType(tok, vt, cpp, defsign, lib); + continue; + } + } ::setValueType(tok, ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::BOOL, 0U), cpp, defsign, lib); - else if (tok->tokType() == Token::eChar) + } else if (tok->tokType() == Token::eChar) ::setValueType(tok, ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::CHAR, 0U), cpp, defsign, lib); else if (tok->tokType() == Token::eString) { ValueType valuetype(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::CHAR, 1U, 1U); diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index fd55e6049..b7b096449 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -3360,6 +3360,9 @@ private: ASSERT_EQUALS("signed int", typeOf("struct AB { int a; int b; } ab; x = ab.a;", ".")); ASSERT_EQUALS("signed int", typeOf("struct AB { int a; int b; } *ab; x = ab[1].a;", ".")); + // Overloaded operators + ASSERT_EQUALS("Fred", typeOf("class Fred { Fred& operator<(int); }; void f() { Fred fred; x=fred<123; }", "<")); + // Static members ASSERT_EQUALS("signed int", typeOf("struct AB { static int a; }; x = AB::a;", "::"));