Clang import: Improved handling of structs

This commit is contained in:
Daniel Marjamäki 2020-11-01 09:12:58 +01:00
parent 226e996e46
commit 5aab1f9692
2 changed files with 19 additions and 11 deletions

View File

@ -276,6 +276,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;
bool isDefinition() const;
std::string getTemplateParameters() const; std::string getTemplateParameters() const;
const Scope *getNestedInScope(TokenList *tokenList); const Scope *getNestedInScope(TokenList *tokenList);
void setValueType(Token *tok); void setValueType(Token *tok);
@ -356,6 +357,11 @@ std::string clangimport::AstNode::getType(int index) const
return unquote(type); return unquote(type);
} }
bool clangimport::AstNode::isDefinition() const
{
return std::find(mExtTokens.begin(), mExtTokens.end(), "definition") != mExtTokens.end();
}
std::string clangimport::AstNode::getTemplateParameters() const std::string clangimport::AstNode::getTemplateParameters() const
{ {
if (children.empty() || children[0]->nodeType != TemplateArgument) if (children.empty() || children[0]->nodeType != TemplateArgument)
@ -495,8 +501,8 @@ Scope *clangimport::AstNode::createScope(TokenList *tokenList, Scope::ScopeType
scope->type = scopeType; scope->type = scopeType;
scope->classDef = def; scope->classDef = def;
scope->check = nestedIn->check; scope->check = nestedIn->check;
scope->bodyStart = addtoken(tokenList, "{");
if (!children2.empty()) { if (!children2.empty()) {
Token *bodyStart = children2[0]->addtoken(tokenList, "{");
tokenList->back()->scope(scope); tokenList->back()->scope(scope);
for (AstNodePtr astNode: children2) { for (AstNodePtr astNode: children2) {
astNode->createTokens(tokenList); astNode->createTokens(tokenList);
@ -505,12 +511,9 @@ Scope *clangimport::AstNode::createScope(TokenList *tokenList, Scope::ScopeType
else if (!Token::Match(tokenList->back(), "[;{}]")) else if (!Token::Match(tokenList->back(), "[;{}]"))
astNode->addtoken(tokenList, ";"); astNode->addtoken(tokenList, ";");
} }
Token *bodyEnd = children2.back()->addtoken(tokenList, "}");
bodyStart->link(bodyEnd);
bodyEnd->link(bodyStart);
scope->bodyStart = bodyStart;
scope->bodyEnd = bodyEnd;
} }
scope->bodyEnd = addtoken(tokenList, "}");
Token::createMutualLinks(const_cast<Token*>(scope->bodyStart), const_cast<Token*>(scope->bodyEnd));
return scope; return scope;
} }
@ -954,8 +957,10 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList)
const std::string &recordName = getSpelling(); const std::string &recordName = getSpelling();
if (!recordName.empty()) if (!recordName.empty())
addtoken(tokenList, getSpelling()); addtoken(tokenList, getSpelling());
if (children.empty()) if (!isDefinition()) {
addtoken(tokenList, ";"); addtoken(tokenList, ";");
return nullptr;
}
Scope *recordScope = createScope(tokenList, Scope::ScopeType::eStruct, children, classDef); Scope *recordScope = createScope(tokenList, Scope::ScopeType::eStruct, children, classDef);
mData->mSymbolDatabase->typeList.push_back(Type(classDef, recordScope, classDef->scope())); mData->mSymbolDatabase->typeList.push_back(Type(classDef, recordScope, classDef->scope()));
@ -1181,6 +1186,10 @@ void clangimport::AstNode::createTokensForCXXRecord(TokenList *tokenList)
className = mExtTokens[mExtTokens.size() - 2]; className = mExtTokens[mExtTokens.size() - 2];
className += getTemplateParameters(); className += getTemplateParameters();
/*Token *nameToken =*/ addtoken(tokenList, className); /*Token *nameToken =*/ addtoken(tokenList, className);
if (!isDefinition()) {
addtoken(tokenList, ";");
return;
}
std::vector<AstNodePtr> children2; std::vector<AstNodePtr> children2;
for (AstNodePtr child: children) { for (AstNodePtr child: children) {
if (child->nodeType == CXXConstructorDecl || if (child->nodeType == CXXConstructorDecl ||
@ -1189,10 +1198,6 @@ void clangimport::AstNode::createTokensForCXXRecord(TokenList *tokenList)
child->nodeType == FieldDecl) child->nodeType == FieldDecl)
children2.push_back(child); children2.push_back(child);
} }
if (children2.empty()) {
addtoken(tokenList, ";");
return;
}
Scope *scope = createScope(tokenList, isStruct ? Scope::ScopeType::eStruct : Scope::ScopeType::eClass, children2, classToken); Scope *scope = createScope(tokenList, isStruct ? Scope::ScopeType::eStruct : Scope::ScopeType::eClass, children2, classToken);
scope->className = className; scope->className = className;
mData->mSymbolDatabase->typeList.push_back(Type(classToken, scope, classToken->scope())); mData->mSymbolDatabase->typeList.push_back(Type(classToken, scope, classToken->scope()));

View File

@ -94,6 +94,9 @@ def test_symbol_database_3():
def test_symbol_database_4(): def test_symbol_database_4():
check_symbol_database('void f(const int x) {}') check_symbol_database('void f(const int x) {}')
def test_symbol_database_struct_1():
check_symbol_database('struct S {};')
def test_ast_calculations(): def test_ast_calculations():
check_ast('int x = 5; int y = (x + 4) * 2;') check_ast('int x = 5; int y = (x + 4) * 2;')
check_ast('long long dostuff(int x) { return x ? 3 : 5; }') check_ast('long long dostuff(int x) { return x ? 3 : 5; }')