Clang import: Fixed data for inline static functions
This commit is contained in:
parent
98946143f6
commit
8956ecb5fc
|
@ -1083,11 +1083,17 @@ void clangimport::AstNode::createTokensFunctionDecl(TokenList *tokenList)
|
||||||
{
|
{
|
||||||
const bool prev = (std::find(mExtTokens.begin(), mExtTokens.end(), "prev") != mExtTokens.end());
|
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 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;
|
const Token *startToken = nullptr;
|
||||||
|
|
||||||
SymbolDatabase *symbolDatabase = mData->mSymbolDatabase;
|
SymbolDatabase *symbolDatabase = mData->mSymbolDatabase;
|
||||||
if (nodeType != CXXConstructorDecl && nodeType != CXXDestructorDecl) {
|
if (nodeType != CXXConstructorDecl && nodeType != CXXDestructorDecl) {
|
||||||
|
if (isStatic)
|
||||||
|
addtoken(tokenList, "static");
|
||||||
|
if (isInline)
|
||||||
|
addtoken(tokenList, "inline");
|
||||||
const Token * const before = tokenList->back();
|
const Token * const before = tokenList->back();
|
||||||
addTypeTokens(tokenList, '\'' + getType() + '\'');
|
addTypeTokens(tokenList, '\'' + getType() + '\'');
|
||||||
startToken = before ? before->next() : tokenList->front();
|
startToken = before ? before->next() : tokenList->front();
|
||||||
|
|
|
@ -2102,40 +2102,7 @@ Function::Function(const Tokenizer *mTokenizer,
|
||||||
isExplicit(tokenDef->previous()->str() == "explicit");
|
isExplicit(tokenDef->previous()->str() == "explicit");
|
||||||
}
|
}
|
||||||
|
|
||||||
const Token *tok1 = tok;
|
const Token *tok1 = setFlags(tok, 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// find the return type
|
// find the return type
|
||||||
if (!isConstructor() && !isDestructor() && !isLambda()) {
|
if (!isConstructor() && !isDestructor() && !isLambda()) {
|
||||||
|
@ -2234,6 +2201,45 @@ Function::Function(const Token *tokenDef)
|
||||||
if (tokenDef->str() == "operator=")
|
if (tokenDef->str() == "operator=")
|
||||||
type = Function::eOperatorEqual;
|
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
|
std::string Function::fullName() const
|
||||||
|
|
|
@ -978,6 +978,7 @@ private:
|
||||||
void hasTrailingReturnType(bool state) {
|
void hasTrailingReturnType(bool state) {
|
||||||
return setFlag(fHasTrailingReturnType, state);
|
return setFlag(fHasTrailingReturnType, state);
|
||||||
}
|
}
|
||||||
|
const Token *setFlags(const Token *tok1, const Scope *scope);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CPPCHECKLIB Scope {
|
class CPPCHECKLIB Scope {
|
||||||
|
|
|
@ -85,8 +85,7 @@ def test_symbol_database_1():
|
||||||
check_symbol_database('int main(){return 0;}')
|
check_symbol_database('int main(){return 0;}')
|
||||||
|
|
||||||
def test_symbol_database_2():
|
def test_symbol_database_2():
|
||||||
code = 'struct Foo { void f(); }; void Foo::f() {}'
|
check_symbol_database('struct Foo { void f(); }; void Foo::f() {}')
|
||||||
check_symbol_database(code)
|
|
||||||
|
|
||||||
def test_symbol_database_3():
|
def test_symbol_database_3():
|
||||||
check_symbol_database('struct Fred { int a; }; int b; void f(int c, int d) { int e; }')
|
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():
|
def test_symbol_database_5():
|
||||||
check_symbol_database('void f(int);')
|
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():
|
def test_symbol_database_operator():
|
||||||
check_symbol_database('struct Fred { void operator=(int x); };')
|
check_symbol_database('struct Fred { void operator=(int x); };')
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,7 @@ private:
|
||||||
TEST_CASE(funcdecl2);
|
TEST_CASE(funcdecl2);
|
||||||
TEST_CASE(funcdecl3);
|
TEST_CASE(funcdecl3);
|
||||||
TEST_CASE(funcdecl4);
|
TEST_CASE(funcdecl4);
|
||||||
|
TEST_CASE(funcdecl5);
|
||||||
TEST_CASE(functionTemplateDecl1);
|
TEST_CASE(functionTemplateDecl1);
|
||||||
TEST_CASE(functionTemplateDecl2);
|
TEST_CASE(functionTemplateDecl2);
|
||||||
TEST_CASE(initListExpr);
|
TEST_CASE(initListExpr);
|
||||||
|
@ -684,6 +685,11 @@ private:
|
||||||
ASSERT_EQUALS("unsigned long fwrite ( const void * , unsigned long , unsigned long , FILE * ) ;", parse(clang));
|
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() {
|
void functionTemplateDecl1() {
|
||||||
const char clang[] = "`-FunctionTemplateDecl 0x3242860 <a.cpp:1:1, col:46> col:21 foo";
|
const char clang[] = "`-FunctionTemplateDecl 0x3242860 <a.cpp:1:1, col:46> col:21 foo";
|
||||||
ASSERT_EQUALS("", parse(clang));
|
ASSERT_EQUALS("", parse(clang));
|
||||||
|
|
Loading…
Reference in New Issue