Clang import: Better handling of const methods

This commit is contained in:
Daniel Marjamäki 2020-11-09 14:50:23 +01:00
parent a5258a3fb0
commit 8b52ed590e
4 changed files with 42 additions and 15 deletions

View File

@ -306,6 +306,7 @@ namespace clangimport {
Token *createTokensVarDecl(TokenList *tokenList); Token *createTokensVarDecl(TokenList *tokenList);
std::string getSpelling() const; std::string getSpelling() const;
std::string getType(int index = 0) const; std::string getType(int index = 0) const;
std::string getFullType(int index = 0) const;
bool isDefinition() const; bool isDefinition() const;
std::string getTemplateParameters() const; std::string getTemplateParameters() const;
const Scope *getNestedInScope(TokenList *tokenList); const Scope *getNestedInScope(TokenList *tokenList);
@ -357,18 +358,7 @@ std::string clangimport::AstNode::getSpelling() const
std::string clangimport::AstNode::getType(int index) const std::string clangimport::AstNode::getType(int index) const
{ {
int typeIndex = 1; std::string type = getFullType(index);
while (typeIndex < mExtTokens.size() && mExtTokens[typeIndex][0] != '\'')
typeIndex++;
if (typeIndex >= mExtTokens.size())
return "";
std::string type = mExtTokens[typeIndex];
if (type.find("\':\'") != std::string::npos) {
if (index == 0)
type.erase(type.find("\':\'") + 1);
else
type.erase(0, type.find("\':\'") + 2);
}
if (type.find(" (") != std::string::npos) { if (type.find(" (") != std::string::npos) {
std::string::size_type pos = type.find(" ("); std::string::size_type pos = type.find(" (");
type[pos] = '\''; type[pos] = '\'';
@ -387,6 +377,23 @@ std::string clangimport::AstNode::getType(int index) const
return unquote(type); return unquote(type);
} }
std::string clangimport::AstNode::getFullType(int index) const
{
int typeIndex = 1;
while (typeIndex < mExtTokens.size() && mExtTokens[typeIndex][0] != '\'')
typeIndex++;
if (typeIndex >= mExtTokens.size())
return "";
std::string type = mExtTokens[typeIndex];
if (type.find("\':\'") != std::string::npos) {
if (index == 0)
type.erase(type.find("\':\'") + 1);
else
type.erase(0, type.find("\':\'") + 2);
}
return type;
}
bool clangimport::AstNode::isDefinition() const bool clangimport::AstNode::isDefinition() const
{ {
return contains(mExtTokens, "definition"); return contains(mExtTokens, "definition");
@ -1188,7 +1195,7 @@ void clangimport::AstNode::createTokensFunctionDecl(TokenList *tokenList)
mData->ref(addr, nameToken); mData->ref(addr, nameToken);
} }
if (!nameToken->function()) { if (!nameToken->function()) {
nestedIn->functionList.push_back(Function(nameToken)); nestedIn->functionList.push_back(Function(nameToken, unquote(getFullType())));
mData->funcDecl(mExtTokens.front(), nameToken, &nestedIn->functionList.back()); mData->funcDecl(mExtTokens.front(), nameToken, &nestedIn->functionList.back());
if (nodeType == CXXConstructorDecl) if (nodeType == CXXConstructorDecl)
nestedIn->functionList.back().type = Function::Type::eConstructor; nestedIn->functionList.back().type = Function::Type::eConstructor;
@ -1254,6 +1261,9 @@ void clangimport::AstNode::createTokensFunctionDecl(TokenList *tokenList)
par1->link(par2); par1->link(par2);
par2->link(par1); par2->link(par1);
if (function->isConst())
addtoken(tokenList, "const");
// Function body // Function body
if (hasBody) { if (hasBody) {
symbolDatabase->functionScopes.push_back(scope); symbolDatabase->functionScopes.push_back(scope);

View File

@ -2177,7 +2177,7 @@ Function::Function(const Tokenizer *mTokenizer,
} }
} }
Function::Function(const Token *tokenDef) Function::Function(const Token *tokenDef, const std::string &clangType)
: tokenDef(tokenDef), : tokenDef(tokenDef),
argDef(nullptr), argDef(nullptr),
token(nullptr), token(nullptr),
@ -2205,6 +2205,9 @@ Function::Function(const Token *tokenDef)
} }
setFlags(tokenDef, tokenDef->scope()); setFlags(tokenDef, tokenDef->scope());
if (endsWith(clangType, " const", 6))
isConst(true);
} }
const Token *Function::setFlags(const Token *tok1, const Scope *scope) const Token *Function::setFlags(const Token *tok1, const Scope *scope)

View File

@ -739,7 +739,7 @@ public:
enum Type { eConstructor, eCopyConstructor, eMoveConstructor, eOperatorEqual, eDestructor, eFunction, eLambda }; enum Type { eConstructor, eCopyConstructor, eMoveConstructor, eOperatorEqual, eDestructor, eFunction, eLambda };
Function(const Tokenizer *mTokenizer, const Token *tok, const Scope *scope, const Token *tokDef, const Token *tokArgDef); Function(const Tokenizer *mTokenizer, const Token *tok, const Scope *scope, const Token *tokDef, const Token *tokArgDef);
explicit Function(const Token *tokenDef); Function(const Token *tokenDef, const std::string &clangType);
const std::string &name() const { const std::string &name() const {
return tokenDef->str(); return tokenDef->str();

View File

@ -106,6 +106,7 @@ private:
TEST_CASE(symbolDatabaseFunction1); TEST_CASE(symbolDatabaseFunction1);
TEST_CASE(symbolDatabaseFunction2); TEST_CASE(symbolDatabaseFunction2);
TEST_CASE(symbolDatabaseFunction3); TEST_CASE(symbolDatabaseFunction3);
TEST_CASE(symbolDatabaseFunctionConst);
TEST_CASE(symbolDatabaseNodeType1); TEST_CASE(symbolDatabaseNodeType1);
TEST_CASE(valueFlow1); TEST_CASE(valueFlow1);
@ -1044,6 +1045,19 @@ private:
ASSERT_EQUALS(true, func->getArgumentVar(1)->isReference()); ASSERT_EQUALS(true, func->getArgumentVar(1)->isReference());
} }
void symbolDatabaseFunctionConst() {
const char clang[] = "`-CXXRecordDecl 0x7e2d98 <1.cpp:2:1, line:5:1> line:2:7 class foo definition\n"
" `-CXXMethodDecl 0x7e3000 <line:4:3, col:12> col:8 f 'void () const'";
GET_SYMBOL_DB(clang);
// There is a function f that is const
ASSERT_EQUALS(2, db->scopeList.size());
ASSERT_EQUALS(1, db->scopeList.back().functionList.size());
const Function &func = db->scopeList.back().functionList.back();
ASSERT(func.isConst());
}
void symbolDatabaseNodeType1() { void symbolDatabaseNodeType1() {
const char clang[] = "`-FunctionDecl 0x32438c0 <line:5:1, line:7:1> line:5:6 foo 'a::b (a::b)'\n" const char clang[] = "`-FunctionDecl 0x32438c0 <line:5:1, line:7:1> line:5:6 foo 'a::b (a::b)'\n"
" |-ParmVarDecl 0x32437b0 <col:10, col:15> col:15 used i 'a::b':'long'\n" " |-ParmVarDecl 0x32437b0 <col:10, col:15> col:15 used i 'a::b':'long'\n"