This commit is contained in:
parent
354ea60b87
commit
d9a8909d2a
|
@ -4365,9 +4365,14 @@ void Function::addArguments(const SymbolDatabase *symbolDatabase, const Scope *s
|
||||||
if (Token::Match(typeTok, ",|)")) { // #8333
|
if (Token::Match(typeTok, ",|)")) { // #8333
|
||||||
symbolDatabase->mTokenizer.syntaxError(typeTok);
|
symbolDatabase->mTokenizer.syntaxError(typeTok);
|
||||||
}
|
}
|
||||||
|
if (Token::Match(typeTok, "%type% <") && Token::Match(typeTok->linkAt(1), "> :: %type%"))
|
||||||
|
typeTok = typeTok->linkAt(1)->tokAt(2);
|
||||||
// skip over qualification
|
// skip over qualification
|
||||||
while (Token::Match(typeTok, "%type% ::"))
|
while (Token::Match(typeTok, "%type% ::")) {
|
||||||
typeTok = typeTok->tokAt(2);
|
typeTok = typeTok->tokAt(2);
|
||||||
|
if (Token::Match(typeTok, "%type% <") && Token::Match(typeTok->linkAt(1), "> :: %type%"))
|
||||||
|
typeTok = typeTok->linkAt(1)->tokAt(2);
|
||||||
|
}
|
||||||
|
|
||||||
// check for argument with no name or missing varid
|
// check for argument with no name or missing varid
|
||||||
if (!endTok) {
|
if (!endTok) {
|
||||||
|
|
|
@ -4640,6 +4640,10 @@ void Tokenizer::setVarIdPass1()
|
||||||
} catch (const Token * errTok) {
|
} catch (const Token * errTok) {
|
||||||
syntaxError(errTok);
|
syntaxError(errTok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tok->str() == "(" && isFunctionHead(tok, "{") && scopeStack.top().isExecutable)
|
||||||
|
inlineFunction = true;
|
||||||
|
|
||||||
if (decl) {
|
if (decl) {
|
||||||
if (isCPP()) {
|
if (isCPP()) {
|
||||||
if (Token *declTypeTok = Token::findsimplematch(tok, "decltype (", tok2)) {
|
if (Token *declTypeTok = Token::findsimplematch(tok, "decltype (", tok2)) {
|
||||||
|
@ -4650,9 +4654,6 @@ void Tokenizer::setVarIdPass1()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tok->str() == "(" && isFunctionHead(tok,"{") && scopeStack.top().isExecutable)
|
|
||||||
inlineFunction = true;
|
|
||||||
|
|
||||||
const Token* prev2 = tok2->previous();
|
const Token* prev2 = tok2->previous();
|
||||||
if (Token::Match(prev2, "%type% [;[=,)]") && tok2->previous()->str() != "const")
|
if (Token::Match(prev2, "%type% [;[=,)]") && tok2->previous()->str() != "const")
|
||||||
;
|
;
|
||||||
|
|
|
@ -248,6 +248,7 @@ private:
|
||||||
TEST_CASE(functionArgs18); // #10376
|
TEST_CASE(functionArgs18); // #10376
|
||||||
TEST_CASE(functionArgs19); // #10376
|
TEST_CASE(functionArgs19); // #10376
|
||||||
TEST_CASE(functionArgs20);
|
TEST_CASE(functionArgs20);
|
||||||
|
TEST_CASE(functionArgs21);
|
||||||
|
|
||||||
TEST_CASE(functionImplicitlyVirtual);
|
TEST_CASE(functionImplicitlyVirtual);
|
||||||
TEST_CASE(functionGetOverridden);
|
TEST_CASE(functionGetOverridden);
|
||||||
|
@ -2765,6 +2766,28 @@ private:
|
||||||
TODO_ASSERT(arg->hasDefault());
|
TODO_ASSERT(arg->hasDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void functionArgs21() {
|
||||||
|
const char code[] = "void f(std::vector<int>::size_type) {}\n" // #11408
|
||||||
|
"template<typename T>\n"
|
||||||
|
"struct S { using t = int; };\n"
|
||||||
|
"template<typename T>\n"
|
||||||
|
"S<T> operator+(const S<T>&lhs, typename S<T>::t) { return lhs; }";
|
||||||
|
GET_SYMBOL_DB(code);
|
||||||
|
ASSERT(db != nullptr);
|
||||||
|
auto it = db->functionScopes.begin();
|
||||||
|
const Function *func = (*it)->function;
|
||||||
|
ASSERT_EQUALS("f", func->name());
|
||||||
|
ASSERT_EQUALS(1, func->argCount());
|
||||||
|
const Variable* arg = func->getArgumentVar(0);
|
||||||
|
ASSERT_EQUALS("", arg->name());
|
||||||
|
++it;
|
||||||
|
func = (*it)->function;
|
||||||
|
ASSERT_EQUALS("operator+", func->name());
|
||||||
|
ASSERT_EQUALS(2, func->argCount());
|
||||||
|
arg = func->getArgumentVar(1);
|
||||||
|
ASSERT_EQUALS("", arg->name());
|
||||||
|
}
|
||||||
|
|
||||||
void functionImplicitlyVirtual() {
|
void functionImplicitlyVirtual() {
|
||||||
GET_SYMBOL_DB("class base { virtual void f(); };\n"
|
GET_SYMBOL_DB("class base { virtual void f(); };\n"
|
||||||
"class derived : base { void f(); };\n"
|
"class derived : base { void f(); };\n"
|
||||||
|
|
|
@ -100,6 +100,7 @@ private:
|
||||||
TEST_CASE(varid66);
|
TEST_CASE(varid66);
|
||||||
TEST_CASE(varid67); // #11711 - NOT function pointer
|
TEST_CASE(varid67); // #11711 - NOT function pointer
|
||||||
TEST_CASE(varid68); // #11740 - switch (str_chars(&strOut)[0])
|
TEST_CASE(varid68); // #11740 - switch (str_chars(&strOut)[0])
|
||||||
|
TEST_CASE(varid69);
|
||||||
TEST_CASE(varid_for_1);
|
TEST_CASE(varid_for_1);
|
||||||
TEST_CASE(varid_for_2);
|
TEST_CASE(varid_for_2);
|
||||||
TEST_CASE(varid_cpp_keywords_in_c_code);
|
TEST_CASE(varid_cpp_keywords_in_c_code);
|
||||||
|
@ -1241,6 +1242,16 @@ private:
|
||||||
ASSERT_EQUALS(expected1, tokenize(code1, "test.cpp"));
|
ASSERT_EQUALS(expected1, tokenize(code1, "test.cpp"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void varid69() {
|
||||||
|
const char code1[] = "void f() {\n"
|
||||||
|
" auto g = [](int&, int& r, int i) {};\n"
|
||||||
|
"}";
|
||||||
|
const char expected1[] = "1: void f ( ) {\n"
|
||||||
|
"2: auto g@1 ; g@1 = [ ] ( int & , int & r@2 , int i@3 ) { } ;\n"
|
||||||
|
"3: }\n";
|
||||||
|
ASSERT_EQUALS(expected1, tokenize(code1, "test.cpp"));
|
||||||
|
}
|
||||||
|
|
||||||
void varid_for_1() {
|
void varid_for_1() {
|
||||||
const char code[] = "void foo(int a, int b) {\n"
|
const char code[] = "void foo(int a, int b) {\n"
|
||||||
" for (int a=1,b=2;;) {}\n"
|
" for (int a=1,b=2;;) {}\n"
|
||||||
|
|
Loading…
Reference in New Issue