ValueType: Improved type handling of containers when [] operator is used
This commit is contained in:
parent
7e15e39f39
commit
0daa3bba30
|
@ -4963,6 +4963,14 @@ void SymbolDatabase::setValueType(Token *tok, const ValueType &valuetype)
|
|||
}
|
||||
}
|
||||
|
||||
if (vt1 && vt1->containerTypeToken && parent->str() == "[") {
|
||||
ValueType vtParent;
|
||||
if (parsedecl(vt1->containerTypeToken, &vtParent, defaultSignedness, _settings)) {
|
||||
setValueType(parent, vtParent);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!vt1)
|
||||
return;
|
||||
if (parent->astOperand2() && !vt2)
|
||||
|
@ -5090,8 +5098,15 @@ static const Token * parsedecl(const Token *type, ValueType * const valuetype, V
|
|||
valuetype->type = ValueType::Type::CONTAINER;
|
||||
valuetype->container = container;
|
||||
while (Token::Match(type, "%name%|::|<")) {
|
||||
if (type->str() == "<" && type->link())
|
||||
if (type->str() == "<" && type->link()) {
|
||||
if (container->type_templateArgNo >= 0) {
|
||||
const Token *templateType = type->next();
|
||||
for (int j = 0; templateType && j < container->type_templateArgNo; j++)
|
||||
templateType = templateType->nextTemplateArgument();
|
||||
valuetype->containerTypeToken = templateType;
|
||||
}
|
||||
type = type->link();
|
||||
}
|
||||
type = type->next();
|
||||
}
|
||||
continue;
|
||||
|
|
|
@ -1059,13 +1059,14 @@ public:
|
|||
unsigned int constness; // bit 0=data, bit 1=*, bit 2=**
|
||||
const Scope *typeScope;
|
||||
const Library::Container *container;
|
||||
const Token *containerTypeToken;
|
||||
std::string originalTypeName;
|
||||
|
||||
ValueType() : sign(UNKNOWN_SIGN), type(UNKNOWN_TYPE), pointer(0U), constness(0U), typeScope(nullptr), container(nullptr) {}
|
||||
ValueType(const ValueType &vt) : sign(vt.sign), type(vt.type), pointer(vt.pointer), constness(vt.constness), typeScope(vt.typeScope), container(vt.container), originalTypeName(vt.originalTypeName) {}
|
||||
ValueType(enum Sign s, enum Type t, unsigned int p) : sign(s), type(t), pointer(p), constness(0U), typeScope(nullptr), container(nullptr) {}
|
||||
ValueType(enum Sign s, enum Type t, unsigned int p, unsigned int c) : sign(s), type(t), pointer(p), constness(c), typeScope(nullptr), container(nullptr) {}
|
||||
ValueType(enum Sign s, enum Type t, unsigned int p, unsigned int c, const std::string &otn) : sign(s), type(t), pointer(p), constness(c), typeScope(nullptr), container(nullptr), originalTypeName(otn) {}
|
||||
ValueType() : sign(UNKNOWN_SIGN), type(UNKNOWN_TYPE), pointer(0U), constness(0U), typeScope(nullptr), container(nullptr), containerTypeToken(nullptr) {}
|
||||
ValueType(const ValueType &vt) : sign(vt.sign), type(vt.type), pointer(vt.pointer), constness(vt.constness), typeScope(vt.typeScope), container(vt.container), containerTypeToken(vt.containerTypeToken), originalTypeName(vt.originalTypeName) {}
|
||||
ValueType(enum Sign s, enum Type t, unsigned int p) : sign(s), type(t), pointer(p), constness(0U), typeScope(nullptr), container(nullptr), containerTypeToken(nullptr) {}
|
||||
ValueType(enum Sign s, enum Type t, unsigned int p, unsigned int c) : sign(s), type(t), pointer(p), constness(c), typeScope(nullptr), container(nullptr), containerTypeToken(nullptr) {}
|
||||
ValueType(enum Sign s, enum Type t, unsigned int p, unsigned int c, const std::string &otn) : sign(s), type(t), pointer(p), constness(c), typeScope(nullptr), container(nullptr), containerTypeToken(nullptr), originalTypeName(otn) {}
|
||||
|
||||
static ValueType parseDecl(const Token *type, const Settings *settings);
|
||||
|
||||
|
|
|
@ -2851,8 +2851,8 @@ private:
|
|||
"void foo() {\n"
|
||||
" printf(\"%d %u %f\", v[0], v[0], v[0]);\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'int'.\n"
|
||||
"[test.cpp:3]: (warning) %f in format string (no. 3) requires 'double' but the argument type is 'int'.\n", errout.str());
|
||||
ASSERT_EQUALS("[test.cpp:3]: (warning) %u in format string (no. 2) requires 'unsigned int' but the argument type is 'signed int'.\n"
|
||||
"[test.cpp:3]: (warning) %f in format string (no. 3) requires 'double' but the argument type is 'signed int'.\n", errout.str());
|
||||
|
||||
// #4999 (crash)
|
||||
check("int bar(int a);\n"
|
||||
|
|
|
@ -4734,6 +4734,16 @@ private:
|
|||
ASSERT_EQUALS("container(C) *", typeOf("C*c=new C;","new","test.cpp",&sC));
|
||||
ASSERT_EQUALS("container(C) *", typeOf("x=(C*)c;","(","test.cpp",&sC));
|
||||
}
|
||||
{
|
||||
// Container (vector)
|
||||
Settings set;
|
||||
Library::Container vector;
|
||||
vector.startPattern = "Vector";
|
||||
vector.type_templateArgNo = 0;
|
||||
vector.arrayLike_indexOp = true;
|
||||
set.library.containers["Vector"] = vector;
|
||||
ASSERT_EQUALS("signed int", typeOf("Vector<int> v; v[0]=3;", "[", "test.cpp", &set));
|
||||
}
|
||||
|
||||
// new
|
||||
ASSERT_EQUALS("C *", typeOf("class C {}; x = new C();", "new"));
|
||||
|
|
Loading…
Reference in New Issue