From 3387ee3512de2308aa203839d77ef7cbb74bd5f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 8 Jan 2020 21:31:06 +0100 Subject: [PATCH] Clang import; ClassTemplateDecl --- lib/clangastdump.cpp | 81 +++++++++++++++++++++++++-------------- test/testclangastdump.cpp | 63 ++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+), 28 deletions(-) diff --git a/lib/clangastdump.cpp b/lib/clangastdump.cpp index 5722deff4..36d259587 100644 --- a/lib/clangastdump.cpp +++ b/lib/clangastdump.cpp @@ -30,6 +30,8 @@ static const std::string ArraySubscriptExpr = "ArraySubscriptExpr"; static const std::string BinaryOperator = "BinaryOperator"; static const std::string BreakStmt = "BreakStmt"; static const std::string CallExpr = "CallExpr"; +static const std::string ClassTemplateDecl = "ClassTemplateDecl"; +static const std::string ClassTemplateSpecializationDecl = "ClassTemplateSpecializationDecl"; static const std::string CompoundStmt = "CompoundStmt"; static const std::string ContinueStmt = "ContinueStmt"; static const std::string CXXMethodDecl = "CXXMethodDecl"; @@ -163,9 +165,11 @@ namespace clangastdump { Scope *createScope(TokenList *tokenList, Scope::ScopeType scopeType, AstNodePtr astNode); Scope *createScope(TokenList *tokenList, Scope::ScopeType scopeType, const std::vector &children); void createTokensFunctionDecl(TokenList *tokenList); + void createTokensForCXXRecord(TokenList *tokenList); Token *createTokensVarDecl(TokenList *tokenList); std::string getSpelling() const; std::string getType() const; + std::string getTemplateParameters() const; const Scope *getNestedInScope(TokenList *tokenList); int mFile = 0; @@ -205,6 +209,23 @@ std::string clangastdump::AstNode::getType() const return ""; } +std::string clangastdump::AstNode::getTemplateParameters() const +{ + if (children.empty() || children[0]->nodeType != TemplateArgument) + return ""; + std::string templateParameters; + for (AstNodePtr child: children) { + if (child->nodeType == TemplateArgument) { + if (templateParameters.empty()) + templateParameters = "<"; + else + templateParameters += ","; + templateParameters += unquote(child->mExtTokens.back()); + } + } + return templateParameters + ">"; +} + void clangastdump::AstNode::dumpAst(int num, int indent) const { (void)num; @@ -340,6 +361,17 @@ Token *clangastdump::AstNode::createTokens(TokenList *tokenList) par1->link(addtoken(tokenList, ")")); return par1; } + if (nodeType == ClassTemplateDecl) { + for (AstNodePtr child: children) { + if (child->nodeType == ClassTemplateSpecializationDecl) + child->createTokens(tokenList); + } + return nullptr; + } + if (nodeType == ClassTemplateSpecializationDecl) { + createTokensForCXXRecord(tokenList); + return nullptr; + } if (nodeType == CompoundStmt) { for (AstNodePtr child: children) { child->createTokens(tokenList); @@ -354,20 +386,7 @@ Token *clangastdump::AstNode::createTokens(TokenList *tokenList) return nullptr; } if (nodeType == CXXRecordDecl) { - Token *classToken = addtoken(tokenList, "class"); - Token *nameToken = addtoken(tokenList, mExtTokens[mExtTokens.size() - 2]); - std::vector children2; - for (auto child: children) { - if (child->nodeType == CXXMethodDecl) - children2.push_back(child); - else if (child->nodeType == FieldDecl) - children2.push_back(child); - } - Scope *scope = createScope(tokenList, Scope::ScopeType::eClass, children2); - scope->classDef = classToken; - scope->className = nameToken->str(); - mData->mSymbolDatabase->typeList.push_back(Type(classToken, scope, classToken->scope())); - scope->definedType = &mData->mSymbolDatabase->typeList.back(); + createTokensForCXXRecord(tokenList); return nullptr; } if (nodeType == DeclStmt) @@ -515,20 +534,7 @@ void clangastdump::AstNode::createTokensFunctionDecl(TokenList *tokenList) (mExtTokens.size() - 2); const int retTypeIndex = nameIndex + 1; addTypeTokens(tokenList, mExtTokens[retTypeIndex]); - Token *nameToken = addtoken(tokenList, mExtTokens[nameIndex]); - if (!children.empty() && children[0]->nodeType == TemplateArgument) { - std::string templateParameters; - for (AstNodePtr child: children) { - if (child->nodeType == TemplateArgument) { - if (templateParameters.empty()) - templateParameters = "<"; - else - templateParameters += ","; - templateParameters += unquote(child->mExtTokens.back()); - } - } - nameToken->str(nameToken->str() + templateParameters + ">"); - } + Token *nameToken = addtoken(tokenList, mExtTokens[nameIndex] + getTemplateParameters()); Scope *nestedIn = const_cast(nameToken->scope()); symbolDatabase->scopeList.push_back(Scope(nullptr, nullptr, nestedIn)); Scope &scope = symbolDatabase->scopeList.back(); @@ -570,6 +576,25 @@ void clangastdump::AstNode::createTokensFunctionDecl(TokenList *tokenList) } } +void clangastdump::AstNode::createTokensForCXXRecord(TokenList *tokenList) +{ + Token *classToken = addtoken(tokenList, "class"); + const std::string className = mExtTokens[mExtTokens.size() - 2] + getTemplateParameters(); + /*Token *nameToken =*/ addtoken(tokenList, className); + std::vector children2; + for (auto child: children) { + if (child->nodeType == CXXMethodDecl) + children2.push_back(child); + else if (child->nodeType == FieldDecl) + children2.push_back(child); + } + Scope *scope = createScope(tokenList, Scope::ScopeType::eClass, children2); + scope->classDef = classToken; + scope->className = className; + mData->mSymbolDatabase->typeList.push_back(Type(classToken, scope, classToken->scope())); + scope->definedType = &mData->mSymbolDatabase->typeList.back(); +} + Token * clangastdump::AstNode::createTokensVarDecl(TokenList *tokenList) { const std::string addr = mExtTokens.front(); diff --git a/test/testclangastdump.cpp b/test/testclangastdump.cpp index f9f67e8b3..8e6028816 100644 --- a/test/testclangastdump.cpp +++ b/test/testclangastdump.cpp @@ -31,6 +31,8 @@ private: void run() OVERRIDE { TEST_CASE(breakStmt); TEST_CASE(class1); + TEST_CASE(classTemplateDecl1); + TEST_CASE(classTemplateDecl2); TEST_CASE(continueStmt); TEST_CASE(forStmt); TEST_CASE(funcdecl1); @@ -87,6 +89,67 @@ private: ASSERT_EQUALS("class C { void foo ( ) { } }", parse(clang)); } + void classTemplateDecl1() { + const char clang[] = "`-ClassTemplateDecl 0x29d1748 col:25 C\n" + " |-TemplateTypeParmDecl 0x29d15f8 col:16 referenced class depth 0 index 0 T\n" + " `-CXXRecordDecl 0x29d16b0 col:25 class C definition\n" + " |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init\n" + " | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr\n" + " | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param\n" + " | |-MoveConstructor exists simple trivial needs_implicit\n" + " | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param\n" + " | |-MoveAssignment exists simple trivial needs_implicit\n" + " | `-Destructor simple irrelevant trivial needs_implicit\n" + " |-CXXRecordDecl 0x29d19b0 col:25 implicit class C\n" + " |-AccessSpecDecl 0x29d1a48 col:29 public\n" + " `-CXXMethodDecl 0x29d1b20 col:39 foo 'T ()'\n" + " `-CompoundStmt 0x29d1c18 \n" + " `-ReturnStmt 0x29d1c00 \n" + " `-IntegerLiteral 0x29d1be0 'int' 0"; + ASSERT_EQUALS("", parse(clang)); + } + + void classTemplateDecl2() { + const char clang[] = "|-ClassTemplateDecl 0x244e748 col:25 C\n" + "| |-TemplateTypeParmDecl 0x244e5f8 col:16 referenced class depth 0 index 0 T\n" + "| |-CXXRecordDecl 0x244e6b0 col:25 class C definition\n" + "| | |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init\n" + "| | | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr\n" + "| | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param\n" + "| | | |-MoveConstructor exists simple trivial needs_implicit\n" + "| | | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param\n" + "| | | |-MoveAssignment exists simple trivial needs_implicit\n" + "| | | `-Destructor simple irrelevant trivial needs_implicit\n" + "| | |-CXXRecordDecl 0x244e9b0 col:25 implicit class C\n" + "| | |-AccessSpecDecl 0x244ea48 col:29 public\n" + "| | `-CXXMethodDecl 0x244eb20 col:39 foo 'T ()'\n" + "| | `-CompoundStmt 0x244ec18 \n" + "| | `-ReturnStmt 0x244ec00 \n" + "| | `-IntegerLiteral 0x244ebe0 'int' 0\n" + "| `-ClassTemplateSpecializationDecl 0x244ed78 col:25 class C definition\n" + "| |-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init\n" + "| | |-DefaultConstructor exists trivial constexpr defaulted_is_constexpr\n" + "| | |-CopyConstructor simple trivial has_const_param implicit_has_const_param\n" + "| | |-MoveConstructor exists simple trivial\n" + "| | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param\n" + "| | |-MoveAssignment exists simple trivial needs_implicit\n" + "| | `-Destructor simple irrelevant trivial needs_implicit\n" + "| |-TemplateArgument type 'int'\n" + "| |-CXXRecordDecl 0x244eff0 prev 0x244ed78 col:25 implicit class C\n" + "| |-AccessSpecDecl 0x244f088 col:29 public\n" + "| |-CXXMethodDecl 0x244f160 col:39 used foo 'int ()'\n" + "| | `-CompoundStmt 0x247cb40 \n" + "| | `-ReturnStmt 0x247cb28 \n" + "| | `-IntegerLiteral 0x244ebe0 'int' 0\n" + "| |-CXXConstructorDecl 0x247c540 col:25 implicit used constexpr C 'void () noexcept' inline default trivial\n" + "| | `-CompoundStmt 0x247ca00 \n" + "| |-CXXConstructorDecl 0x247c658 col:25 implicit constexpr C 'void (const C &)' inline default trivial noexcept-unevaluated 0x247c658\n" + "| | `-ParmVarDecl 0x247c790 col:25 'const C &'\n" + "| `-CXXConstructorDecl 0x247c828 col:25 implicit constexpr C 'void (C &&)' inline default trivial noexcept-unevaluated 0x247c828\n" + "| `-ParmVarDecl 0x247c960 col:25 'C &&'\n"; + ASSERT_EQUALS("class C { int foo ( ) { return 0 ; } }", parse(clang)); + } + void continueStmt() { const char clang[] = "`-FunctionDecl 0x2c31b18 <1.c:1:1, col:34> col:6 foo 'void ()'\n" " `-CompoundStmt 0x2c31c40 \n"