diff --git a/lib/clangimport.cpp b/lib/clangimport.cpp index a3c10b725..ef1727829 100644 --- a/lib/clangimport.cpp +++ b/lib/clangimport.cpp @@ -720,15 +720,25 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList) return addtoken(tokenList, getSpelling()); if (nodeType == EnumDecl) { Token *enumtok = addtoken(tokenList, "enum"); + Token *nametok = nullptr; if (mExtTokens[mExtTokens.size() - 3].compare(0,4,"col:") == 0) - addtoken(tokenList, mExtTokens.back()); - createScope(tokenList, Scope::ScopeType::eEnum, children, enumtok); + nametok = addtoken(tokenList, mExtTokens.back()); + Scope *enumscope = createScope(tokenList, Scope::ScopeType::eEnum, children, enumtok); + if (nametok) + enumscope->className = nametok->str(); for (Token *tok = enumtok; tok; tok = tok->next()) { if (Token::simpleMatch(tok, "; }")) tok->deleteThis(); else if (tok->str() == ";") tok->str(","); } + + // Create enum type + mData->mSymbolDatabase->typeList.push_back(Type(enumtok, enumscope, enumtok->scope())); + enumscope->definedType = &mData->mSymbolDatabase->typeList.back(); + if (nametok) + const_cast(enumtok->scope())->definedTypesMap[nametok->str()] = enumscope->definedType; + return nullptr; } if (nodeType == ExprWithCleanups) @@ -859,7 +869,8 @@ Token *clangimport::AstNode::createTokens(TokenList *tokenList) if (children.empty()) return nullptr; Token *defToken = addtoken(tokenList, "namespace"); - Token *nameToken = (mExtTokens[mExtTokens.size() - 2].compare(0,4,"col:") == 0) ? + const std::string &s = mExtTokens[mExtTokens.size() - 2]; + Token *nameToken = (s.compare(0,4,"col:")==0 || s.compare(0,5,"line:")==0) ? addtoken(tokenList, mExtTokens.back()) : nullptr; Scope *scope = createScope(tokenList, Scope::ScopeType::eNamespace, children, defToken); if (nameToken) diff --git a/test/testclangimport.cpp b/test/testclangimport.cpp index d7048da47..477dc91ce 100644 --- a/test/testclangimport.cpp +++ b/test/testclangimport.cpp @@ -88,6 +88,7 @@ private: TEST_CASE(vardecl5); TEST_CASE(whileStmt); + TEST_CASE(symbolDatabaseEnum1); TEST_CASE(symbolDatabaseFunction1); TEST_CASE(symbolDatabaseFunction2); TEST_CASE(symbolDatabaseNodeType1); @@ -799,6 +800,38 @@ private: const SymbolDatabase *db = tokenizer.getSymbolDatabase(); \ ASSERT(db); + void symbolDatabaseEnum1() { + const char clang[] = "|-NamespaceDecl 0x29ad5f8 <1.cpp:1:1, line:3:1> line:1:11 ns\n" + "| `-EnumDecl 0x29ad660 col:6 referenced abc\n" + "| |-EnumConstantDecl 0x29ad720 col:11 a 'ns::abc'\n" + "| |-EnumConstantDecl 0x29ad768 col:13 b 'ns::abc'\n" + "| `-EnumConstantDecl 0x29ad7b0 col:15 referenced c 'ns::abc'\n" + "`-VarDecl 0x29ad898 col:9 x 'ns::abc':'ns::abc' cinit\n" + " `-DeclRefExpr 0x29ad998 'ns::abc' EnumConstant 0x29ad7b0 'c' 'ns::abc'\n"; + + ASSERT_EQUALS("namespace ns\n" + "{ enum abc { a , b , c } }\n" + "\n" + "\n" + "ns::abc x@1 = c ;", parse(clang)); + + GET_SYMBOL_DB(clang); + + // Enum scope and type + ASSERT_EQUALS(3, db->scopeList.size()); + const Scope &enumScope = db->scopeList.back(); + ASSERT_EQUALS(Scope::ScopeType::eEnum, enumScope.type); + ASSERT_EQUALS("abc", enumScope.className); + const Type *enumType = enumScope.definedType; + ASSERT_EQUALS("abc", enumType->name()); + + // Variable + const Token *vartok = Token::findsimplematch(tokenizer.tokens(), "x"); + ASSERT(vartok); + ASSERT(vartok->variable()); + //ASSERT(vartok->variable()->valueType()); + } + void symbolDatabaseFunction1() { const char clang[] = "|-FunctionDecl 0x3aea7a0 <1.cpp:2:1, col:22> col:6 used foo 'void (int, int)'\n" "| |-ParmVarDecl 0x3aea650 col:14 x 'int'\n"