From 5aab1f969203dee551bd7abaa01064eb2d52c0dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 1 Nov 2020 09:12:58 +0100 Subject: [PATCH] Clang import: Improved handling of structs --- lib/clangimport.cpp | 27 ++++++++++++++++----------- test/cli/test-clang-import.py | 3 +++ 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/lib/clangimport.cpp b/lib/clangimport.cpp index 2337fcd4a..0909252b7 100644 --- a/lib/clangimport.cpp +++ b/lib/clangimport.cpp @@ -276,6 +276,7 @@ namespace clangimport { Token *createTokensVarDecl(TokenList *tokenList); std::string getSpelling() const; std::string getType(int index = 0) const; + bool isDefinition() const; std::string getTemplateParameters() const; const Scope *getNestedInScope(TokenList *tokenList); void setValueType(Token *tok); @@ -356,6 +357,11 @@ std::string clangimport::AstNode::getType(int index) const return unquote(type); } +bool clangimport::AstNode::isDefinition() const +{ + return std::find(mExtTokens.begin(), mExtTokens.end(), "definition") != mExtTokens.end(); +} + std::string clangimport::AstNode::getTemplateParameters() const { if (children.empty() || children[0]->nodeType != TemplateArgument) @@ -495,8 +501,8 @@ Scope *clangimport::AstNode::createScope(TokenList *tokenList, Scope::ScopeType scope->type = scopeType; scope->classDef = def; scope->check = nestedIn->check; + scope->bodyStart = addtoken(tokenList, "{"); if (!children2.empty()) { - Token *bodyStart = children2[0]->addtoken(tokenList, "{"); tokenList->back()->scope(scope); for (AstNodePtr astNode: children2) { astNode->createTokens(tokenList); @@ -505,12 +511,9 @@ Scope *clangimport::AstNode::createScope(TokenList *tokenList, Scope::ScopeType else if (!Token::Match(tokenList->back(), "[;{}]")) 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(scope->bodyStart), const_cast(scope->bodyEnd)); return scope; } @@ -954,8 +957,10 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList) const std::string &recordName = getSpelling(); if (!recordName.empty()) addtoken(tokenList, getSpelling()); - if (children.empty()) + if (!isDefinition()) { addtoken(tokenList, ";"); + return nullptr; + } Scope *recordScope = createScope(tokenList, Scope::ScopeType::eStruct, children, classDef); 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 += getTemplateParameters(); /*Token *nameToken =*/ addtoken(tokenList, className); + if (!isDefinition()) { + addtoken(tokenList, ";"); + return; + } std::vector children2; for (AstNodePtr child: children) { if (child->nodeType == CXXConstructorDecl || @@ -1189,10 +1198,6 @@ void clangimport::AstNode::createTokensForCXXRecord(TokenList *tokenList) child->nodeType == FieldDecl) children2.push_back(child); } - if (children2.empty()) { - addtoken(tokenList, ";"); - return; - } Scope *scope = createScope(tokenList, isStruct ? Scope::ScopeType::eStruct : Scope::ScopeType::eClass, children2, classToken); scope->className = className; mData->mSymbolDatabase->typeList.push_back(Type(classToken, scope, classToken->scope())); diff --git a/test/cli/test-clang-import.py b/test/cli/test-clang-import.py index 0fafaab00..b54a0f1c9 100644 --- a/test/cli/test-clang-import.py +++ b/test/cli/test-clang-import.py @@ -94,6 +94,9 @@ def test_symbol_database_3(): def test_symbol_database_4(): check_symbol_database('void f(const int x) {}') +def test_symbol_database_struct_1(): + check_symbol_database('struct S {};') + def test_ast_calculations(): check_ast('int x = 5; int y = (x + 4) * 2;') check_ast('long long dostuff(int x) { return x ? 3 : 5; }')