This commit is contained in:
parent
8c33a95b49
commit
cfeea3d35c
|
@ -50,6 +50,7 @@ SymbolDatabase::SymbolDatabase(const Tokenizer *tokenizer, const Settings *setti
|
||||||
createSymbolDatabaseFindAllScopes();
|
createSymbolDatabaseFindAllScopes();
|
||||||
createSymbolDatabaseClassInfo();
|
createSymbolDatabaseClassInfo();
|
||||||
createSymbolDatabaseVariableInfo();
|
createSymbolDatabaseVariableInfo();
|
||||||
|
createSymbolDatabaseCopyAndMoveConstructors();
|
||||||
createSymbolDatabaseFunctionScopes();
|
createSymbolDatabaseFunctionScopes();
|
||||||
createSymbolDatabaseClassAndStructScopes();
|
createSymbolDatabaseClassAndStructScopes();
|
||||||
createSymbolDatabaseFunctionReturnTypes();
|
createSymbolDatabaseFunctionReturnTypes();
|
||||||
|
@ -421,29 +422,7 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
|
||||||
// destructor
|
// destructor
|
||||||
if (function.tokenDef->previous()->str() == "~")
|
if (function.tokenDef->previous()->str() == "~")
|
||||||
function.type = Function::eDestructor;
|
function.type = Function::eDestructor;
|
||||||
|
// constructor of any kind
|
||||||
// copy/move constructor?
|
|
||||||
else if (Token::Match(function.tokenDef, "%name% ( const| %name% &|&& &| %name%| )") ||
|
|
||||||
Token::Match(function.tokenDef, "%name% ( const| %name% <")) {
|
|
||||||
const Token* typeTok = function.tokenDef->tokAt(2);
|
|
||||||
if (typeTok->str() == "const")
|
|
||||||
typeTok = typeTok->next();
|
|
||||||
if (typeTok->strAt(1) == "<") { // TODO: Remove this branch (#4710)
|
|
||||||
if (Token::Match(typeTok->linkAt(1), "> & %name%| )"))
|
|
||||||
function.type = Function::eCopyConstructor;
|
|
||||||
else if (Token::Match(typeTok->linkAt(1), "> &&|& & %name%| )"))
|
|
||||||
function.type = Function::eMoveConstructor;
|
|
||||||
else
|
|
||||||
function.type = Function::eConstructor;
|
|
||||||
} else if (typeTok->strAt(1) == "&&" || typeTok->strAt(2) == "&")
|
|
||||||
function.type = Function::eMoveConstructor;
|
|
||||||
else
|
|
||||||
function.type = Function::eCopyConstructor;
|
|
||||||
|
|
||||||
if (typeTok->str() != function.tokenDef->str())
|
|
||||||
function.type = Function::eConstructor; // Overwrite, if types are not identical
|
|
||||||
}
|
|
||||||
// regular constructor
|
|
||||||
else
|
else
|
||||||
function.type = Function::eConstructor;
|
function.type = Function::eConstructor;
|
||||||
|
|
||||||
|
@ -504,9 +483,6 @@ void SymbolDatabase::createSymbolDatabaseFindAllScopes()
|
||||||
// count the number of constructors
|
// count the number of constructors
|
||||||
if (function.isConstructor())
|
if (function.isConstructor())
|
||||||
scope->numConstructors++;
|
scope->numConstructors++;
|
||||||
if (function.type == Function::eCopyConstructor ||
|
|
||||||
function.type == Function::eMoveConstructor)
|
|
||||||
scope->numCopyOrMoveConstructors++;
|
|
||||||
|
|
||||||
// assume implementation is inline (definition and implementation same)
|
// assume implementation is inline (definition and implementation same)
|
||||||
function.token = function.tokenDef;
|
function.token = function.tokenDef;
|
||||||
|
@ -917,6 +893,33 @@ void SymbolDatabase::createSymbolDatabaseVariableInfo()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SymbolDatabase::createSymbolDatabaseCopyAndMoveConstructors()
|
||||||
|
{
|
||||||
|
// fill in class and struct copy/move constructors
|
||||||
|
for (std::list<Scope>::iterator scope = scopeList.begin(); scope != scopeList.end(); ++scope) {
|
||||||
|
if (!scope->isClassOrStruct())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
std::list<Function>::iterator func;
|
||||||
|
for (func = scope->functionList.begin(); func != scope->functionList.end(); ++func) {
|
||||||
|
if (!func->isConstructor() || func->minArgCount() != 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const Variable* firstArg = func->getArgumentVar(0);
|
||||||
|
if (firstArg->type() == scope->definedType) {
|
||||||
|
if (firstArg->isRValueReference())
|
||||||
|
func->type = Function::eMoveConstructor;
|
||||||
|
else if (firstArg->isReference())
|
||||||
|
func->type = Function::eCopyConstructor;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (func->type == Function::eCopyConstructor ||
|
||||||
|
func->type == Function::eMoveConstructor)
|
||||||
|
scope->numCopyOrMoveConstructors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void SymbolDatabase::createSymbolDatabaseFunctionScopes()
|
void SymbolDatabase::createSymbolDatabaseFunctionScopes()
|
||||||
{
|
{
|
||||||
// fill in function scopes
|
// fill in function scopes
|
||||||
|
|
|
@ -1163,6 +1163,7 @@ private:
|
||||||
void createSymbolDatabaseFindAllScopes();
|
void createSymbolDatabaseFindAllScopes();
|
||||||
void createSymbolDatabaseClassInfo();
|
void createSymbolDatabaseClassInfo();
|
||||||
void createSymbolDatabaseVariableInfo();
|
void createSymbolDatabaseVariableInfo();
|
||||||
|
void createSymbolDatabaseCopyAndMoveConstructors();
|
||||||
void createSymbolDatabaseFunctionScopes();
|
void createSymbolDatabaseFunctionScopes();
|
||||||
void createSymbolDatabaseClassAndStructScopes();
|
void createSymbolDatabaseClassAndStructScopes();
|
||||||
void createSymbolDatabaseFunctionReturnTypes();
|
void createSymbolDatabaseFunctionReturnTypes();
|
||||||
|
|
|
@ -1270,6 +1270,12 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void testConstructors() {
|
void testConstructors() {
|
||||||
|
{
|
||||||
|
GET_SYMBOL_DB("class Foo { Foo(); };");
|
||||||
|
const Function* ctor = tokenizer.tokens()->tokAt(3)->function();
|
||||||
|
ASSERT(db && ctor && ctor->type == Function::eConstructor);
|
||||||
|
ASSERT(ctor && ctor->retDef == 0);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
GET_SYMBOL_DB("class Foo { Foo(Foo f); };");
|
GET_SYMBOL_DB("class Foo { Foo(Foo f); };");
|
||||||
const Function* ctor = tokenizer.tokens()->tokAt(3)->function();
|
const Function* ctor = tokenizer.tokens()->tokAt(3)->function();
|
||||||
|
@ -1282,18 +1288,54 @@ private:
|
||||||
ASSERT(db && ctor && ctor->type == Function::eConstructor && ctor->isExplicit());
|
ASSERT(db && ctor && ctor->type == Function::eConstructor && ctor->isExplicit());
|
||||||
ASSERT(ctor && ctor->retDef == 0);
|
ASSERT(ctor && ctor->retDef == 0);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
GET_SYMBOL_DB("class Foo { Foo(Bar& f); };");
|
||||||
|
const Function* ctor = tokenizer.tokens()->tokAt(3)->function();
|
||||||
|
ASSERT(db && ctor && ctor->type == Function::eConstructor);
|
||||||
|
ASSERT(ctor && ctor->retDef == 0);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
GET_SYMBOL_DB("class Foo { Foo(Foo& f); };");
|
GET_SYMBOL_DB("class Foo { Foo(Foo& f); };");
|
||||||
const Function* ctor = tokenizer.tokens()->tokAt(3)->function();
|
const Function* ctor = tokenizer.tokens()->tokAt(3)->function();
|
||||||
ASSERT(db && ctor && ctor->type == Function::eCopyConstructor);
|
ASSERT(db && ctor && ctor->type == Function::eCopyConstructor);
|
||||||
ASSERT(ctor && ctor->retDef == 0);
|
ASSERT(ctor && ctor->retDef == 0);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
GET_SYMBOL_DB("class Foo { Foo(const Foo &f); };");
|
||||||
|
const Function* ctor = tokenizer.tokens()->tokAt(3)->function();
|
||||||
|
ASSERT(db && ctor && ctor->type == Function::eCopyConstructor);
|
||||||
|
ASSERT(ctor && ctor->retDef == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
GET_SYMBOL_DB("template <T> class Foo { Foo(Foo<T>& f); };");
|
||||||
|
const Function* ctor = tokenizer.tokens()->tokAt(7)->function();
|
||||||
|
ASSERT(db && ctor && ctor->type == Function::eCopyConstructor);
|
||||||
|
ASSERT(ctor && ctor->retDef == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
GET_SYMBOL_DB("class Foo { Foo(Foo& f, int default = 0); };");
|
||||||
|
const Function* ctor = tokenizer.tokens()->tokAt(3)->function();
|
||||||
|
ASSERT(db && ctor && ctor->type == Function::eCopyConstructor);
|
||||||
|
ASSERT(ctor && ctor->retDef == 0);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
GET_SYMBOL_DB("class Foo { Foo(Foo& f, char noDefault); };");
|
||||||
|
const Function* ctor = tokenizer.tokens()->tokAt(3)->function();
|
||||||
|
ASSERT(db && ctor && ctor->type == Function::eConstructor);
|
||||||
|
ASSERT(ctor && ctor->retDef == 0);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
GET_SYMBOL_DB("class Foo { Foo(Foo&& f); };");
|
GET_SYMBOL_DB("class Foo { Foo(Foo&& f); };");
|
||||||
const Function* ctor = tokenizer.tokens()->tokAt(3)->function();
|
const Function* ctor = tokenizer.tokens()->tokAt(3)->function();
|
||||||
ASSERT(db && ctor && ctor->type == Function::eMoveConstructor);
|
ASSERT(db && ctor && ctor->type == Function::eMoveConstructor);
|
||||||
ASSERT(ctor && ctor->retDef == 0);
|
ASSERT(ctor && ctor->retDef == 0);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
GET_SYMBOL_DB("class Foo { Foo(Foo & & f, int default = 1, bool defaultToo = true); };");
|
||||||
|
const Function* ctor = tokenizer.tokens()->tokAt(3)->function();
|
||||||
|
ASSERT(db && ctor && ctor->type == Function::eMoveConstructor);
|
||||||
|
ASSERT(ctor && ctor->retDef == 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void functionDeclarationTemplate() {
|
void functionDeclarationTemplate() {
|
||||||
|
|
Loading…
Reference in New Issue