Clang import; ClassTemplateDecl

This commit is contained in:
Daniel Marjamäki 2020-01-08 21:31:06 +01:00
parent eb3270959e
commit 3387ee3512
2 changed files with 116 additions and 28 deletions

View File

@ -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<AstNodePtr> &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<AstNodePtr> 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<Scope *>(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<AstNodePtr> 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();

View File

@ -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 <a.cpp:1:1, col:59> col:25 C\n"
" |-TemplateTypeParmDecl 0x29d15f8 <col:10, col:16> col:16 referenced class depth 0 index 0 T\n"
" `-CXXRecordDecl 0x29d16b0 <col:19, col:59> 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:19, col:25> col:25 implicit class C\n"
" |-AccessSpecDecl 0x29d1a48 <col:29, col:35> col:29 public\n"
" `-CXXMethodDecl 0x29d1b20 <col:37, col:57> col:39 foo 'T ()'\n"
" `-CompoundStmt 0x29d1c18 <col:45, col:57>\n"
" `-ReturnStmt 0x29d1c00 <col:47, col:54>\n"
" `-IntegerLiteral 0x29d1be0 <col:54> 'int' 0";
ASSERT_EQUALS("", parse(clang));
}
void classTemplateDecl2() {
const char clang[] = "|-ClassTemplateDecl 0x244e748 <a.cpp:1:1, col:59> col:25 C\n"
"| |-TemplateTypeParmDecl 0x244e5f8 <col:10, col:16> col:16 referenced class depth 0 index 0 T\n"
"| |-CXXRecordDecl 0x244e6b0 <col:19, col:59> 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:19, col:25> col:25 implicit class C\n"
"| | |-AccessSpecDecl 0x244ea48 <col:29, col:35> col:29 public\n"
"| | `-CXXMethodDecl 0x244eb20 <col:37, col:57> col:39 foo 'T ()'\n"
"| | `-CompoundStmt 0x244ec18 <col:45, col:57>\n"
"| | `-ReturnStmt 0x244ec00 <col:47, col:54>\n"
"| | `-IntegerLiteral 0x244ebe0 <col:54> 'int' 0\n"
"| `-ClassTemplateSpecializationDecl 0x244ed78 <col:1, col:59> 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:19, col:25> col:25 implicit class C\n"
"| |-AccessSpecDecl 0x244f088 <col:29, col:35> col:29 public\n"
"| |-CXXMethodDecl 0x244f160 <col:37, col:57> col:39 used foo 'int ()'\n"
"| | `-CompoundStmt 0x247cb40 <col:45, col:57>\n"
"| | `-ReturnStmt 0x247cb28 <col:47, col:54>\n"
"| | `-IntegerLiteral 0x244ebe0 <col:54> 'int' 0\n"
"| |-CXXConstructorDecl 0x247c540 <col:25> col:25 implicit used constexpr C 'void () noexcept' inline default trivial\n"
"| | `-CompoundStmt 0x247ca00 <col:25>\n"
"| |-CXXConstructorDecl 0x247c658 <col:25> col:25 implicit constexpr C 'void (const C<int> &)' inline default trivial noexcept-unevaluated 0x247c658\n"
"| | `-ParmVarDecl 0x247c790 <col:25> col:25 'const C<int> &'\n"
"| `-CXXConstructorDecl 0x247c828 <col:25> col:25 implicit constexpr C 'void (C<int> &&)' inline default trivial noexcept-unevaluated 0x247c828\n"
"| `-ParmVarDecl 0x247c960 <col:25> col:25 'C<int> &&'\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 <col:12, col:34>\n"