Clang import: Fixed data for inline static functions

This commit is contained in:
Daniel Marjamäki 2020-11-03 17:52:38 +01:00
parent 98946143f6
commit 8956ecb5fc
5 changed files with 57 additions and 36 deletions

View File

@ -1083,11 +1083,17 @@ void clangimport::AstNode::createTokensFunctionDecl(TokenList *tokenList)
{
const bool prev = (std::find(mExtTokens.begin(), mExtTokens.end(), "prev") != mExtTokens.end());
const bool hasBody = mFile == 0 && !children.empty() && children.back()->nodeType == CompoundStmt;
const bool isStatic = (std::find(mExtTokens.begin(), mExtTokens.end(), "static") != mExtTokens.end());
const bool isInline = (std::find(mExtTokens.begin(), mExtTokens.end(), "inline") != mExtTokens.end());
const Token *startToken = nullptr;
SymbolDatabase *symbolDatabase = mData->mSymbolDatabase;
if (nodeType != CXXConstructorDecl && nodeType != CXXDestructorDecl) {
if (isStatic)
addtoken(tokenList, "static");
if (isInline)
addtoken(tokenList, "inline");
const Token * const before = tokenList->back();
addTypeTokens(tokenList, '\'' + getType() + '\'');
startToken = before ? before->next() : tokenList->front();

View File

@ -2102,40 +2102,7 @@ Function::Function(const Tokenizer *mTokenizer,
isExplicit(tokenDef->previous()->str() == "explicit");
}
const Token *tok1 = tok;
// look for end of previous statement
while (tok1->previous() && !Token::Match(tok1->previous(), ";|}|{|public:|protected:|private:")) {
tok1 = tok1->previous();
// extern function
if (tok1->str() == "extern") {
isExtern(true);
}
// virtual function
else if (tok1->str() == "virtual") {
hasVirtualSpecifier(true);
}
// static function
else if (tok1->str() == "static") {
isStatic(true);
if (scope->type == Scope::eNamespace || scope->type == Scope::eGlobal)
isStaticLocal(true);
}
// friend function
else if (tok1->str() == "friend") {
isFriend(true);
}
// Function template
else if (tok1->link() && tok1->str() == ">" && Token::simpleMatch(tok1->link()->previous(), "template <")) {
templateDef = tok1->link()->previous();
break;
}
}
const Token *tok1 = setFlags(tok, scope);
// find the return type
if (!isConstructor() && !isDestructor() && !isLambda()) {
@ -2234,6 +2201,45 @@ Function::Function(const Token *tokenDef)
if (tokenDef->str() == "operator=")
type = Function::eOperatorEqual;
}
setFlags(tokenDef, tokenDef->scope());
}
const Token *Function::setFlags(const Token *tok1, const Scope *scope)
{
// look for end of previous statement
while (tok1->previous() && !Token::Match(tok1->previous(), ";|}|{|public:|protected:|private:")) {
tok1 = tok1->previous();
// extern function
if (tok1->str() == "extern") {
isExtern(true);
}
// virtual function
else if (tok1->str() == "virtual") {
hasVirtualSpecifier(true);
}
// static function
else if (tok1->str() == "static") {
isStatic(true);
if (scope->type == Scope::eNamespace || scope->type == Scope::eGlobal)
isStaticLocal(true);
}
// friend function
else if (tok1->str() == "friend") {
isFriend(true);
}
// Function template
else if (tok1->link() && tok1->str() == ">" && Token::simpleMatch(tok1->link()->previous(), "template <")) {
templateDef = tok1->link()->previous();
break;
}
}
return tok1;
}
std::string Function::fullName() const

View File

@ -978,6 +978,7 @@ private:
void hasTrailingReturnType(bool state) {
return setFlag(fHasTrailingReturnType, state);
}
const Token *setFlags(const Token *tok1, const Scope *scope);
};
class CPPCHECKLIB Scope {

View File

@ -85,8 +85,7 @@ def test_symbol_database_1():
check_symbol_database('int main(){return 0;}')
def test_symbol_database_2():
code = 'struct Foo { void f(); }; void Foo::f() {}'
check_symbol_database(code)
check_symbol_database('struct Foo { void f(); }; void Foo::f() {}')
def test_symbol_database_3():
check_symbol_database('struct Fred { int a; }; int b; void f(int c, int d) { int e; }')
@ -97,6 +96,9 @@ def test_symbol_database_4():
def test_symbol_database_5():
check_symbol_database('void f(int);')
def test_symbol_database_6():
check_symbol_database('inline static int foo(int x) { return x; }')
def test_symbol_database_operator():
check_symbol_database('struct Fred { void operator=(int x); };')

View File

@ -74,6 +74,7 @@ private:
TEST_CASE(funcdecl2);
TEST_CASE(funcdecl3);
TEST_CASE(funcdecl4);
TEST_CASE(funcdecl5);
TEST_CASE(functionTemplateDecl1);
TEST_CASE(functionTemplateDecl2);
TEST_CASE(initListExpr);
@ -684,6 +685,11 @@ private:
ASSERT_EQUALS("unsigned long fwrite ( const void * , unsigned long , unsigned long , FILE * ) ;", parse(clang));
}
void funcdecl5() {
const char clang[] = "`-FunctionDecl 0x59d670 <1.c:1:1, col:28> col:20 foo 'void (void)' static inline";
ASSERT_EQUALS("static inline void foo ( ) ;", parse(clang));
}
void functionTemplateDecl1() {
const char clang[] = "`-FunctionTemplateDecl 0x3242860 <a.cpp:1:1, col:46> col:21 foo";
ASSERT_EQUALS("", parse(clang));