diff --git a/src/lib_parser/data/parser/cxx/ASTVisitor.cpp b/src/lib_parser/data/parser/cxx/ASTVisitor.cpp index 2439bdc8..8c2d5249 100644 --- a/src/lib_parser/data/parser/cxx/ASTVisitor.cpp +++ b/src/lib_parser/data/parser/cxx/ASTVisitor.cpp @@ -148,6 +148,14 @@ bool ASTVisitor::TraverseTypedefDecl(clang::TypedefDecl *d) return base::TraverseTypedefDecl(d); } +bool ASTVisitor::TraverseTypeAliasDecl(clang::TypeAliasDecl *d) +{ + ScopedSwitcher> switcher( + m_contextNameGenerator, std::make_shared(d, m_declNameCache) + ); + return base::TraverseTypeAliasDecl(d); +} + bool ASTVisitor::TraverseFieldDecl(clang::FieldDecl *d) { ScopedSwitcher> switcher( @@ -878,12 +886,17 @@ bool ASTVisitor::VisitDecl(clang::Decl *d) // Do nothing. The function will be recorded when it appears as a // FunctionDecl. } else if (llvm::isa(d)) { - // Do nothing. The class will be recorded when it appears as a - // RecordDecl. - } else if (llvm::isa(d)) { + // Do nothing. The class will be recorded when it appears as a + // RecordDecl. + } else if (llvm::isa(d)) { + // Do nothing. The type alias will be recorded when it appears as a + // TypeAliasDecl. + } else if (llvm::isa(d)) { RecordDeclRef(nd, loc, RT_Declaration, SYMBOL_FIELD); - } else if (llvm::isa(d)) { - RecordDeclRef(nd, loc, RT_Declaration, SYMBOL_TYPEDEF); + } else if (llvm::isa(d)) { + RecordDeclRef(nd, loc, RT_Declaration, SYMBOL_TYPEDEF); + } else if (llvm::isa(d)) { + RecordDeclRef(nd, loc, RT_Declaration, SYMBOL_TYPEDEF); } else if (llvm::isa(d)) { RecordDeclRef(nd, loc, RT_Declaration, SYMBOL_NAMESPACE); } else if (llvm::isa(d)) { @@ -1169,12 +1182,21 @@ void ASTVisitor::RecordDeclRef( switch (symbolType) { case SYMBOL_TYPEDEF: - if (clang::TypedefDecl* typedefDecl = clang::dyn_cast(d)) { + clang::AccessSpecifier accessSpecifier = clang::AccessSpecifier::AS_none; + if (clang::TypeAliasDecl* typeAliasDecl = clang::dyn_cast(d)) + { + accessSpecifier = typeAliasDecl->getAccess(); + } + else if (clang::TypedefDecl* typedefDecl = clang::dyn_cast(d)) + { + accessSpecifier = typedefDecl->getAccess(); + } + m_client->onTypedefParsed( parseLocation, declNameHierarchy, - convertAccessType(typedefDecl->getAccess()), + convertAccessType(accessSpecifier), declIsImplicit); } break; diff --git a/src/lib_parser/data/parser/cxx/ASTVisitor.h b/src/lib_parser/data/parser/cxx/ASTVisitor.h index 5fe85454..b870523c 100644 --- a/src/lib_parser/data/parser/cxx/ASTVisitor.h +++ b/src/lib_parser/data/parser/cxx/ASTVisitor.h @@ -139,6 +139,7 @@ private: bool TraverseLambdaExpr(clang::LambdaExpr* e); bool TraverseFunctionDecl(clang::FunctionDecl* d); bool TraverseTypedefDecl(clang::TypedefDecl *d); + bool TraverseTypeAliasDecl(clang::TypeAliasDecl *d); bool TraverseFieldDecl(clang::FieldDecl *d); bool TraverseVarDecl(clang::VarDecl *d); bool TraverseClassTemplateDecl(clang::ClassTemplateDecl* d); diff --git a/src/lib_parser/data/parser/cxx/name_resolver/CxxDeclNameResolver.cpp b/src/lib_parser/data/parser/cxx/name_resolver/CxxDeclNameResolver.cpp index 5863d6b1..af484043 100644 --- a/src/lib_parser/data/parser/cxx/name_resolver/CxxDeclNameResolver.cpp +++ b/src/lib_parser/data/parser/cxx/name_resolver/CxxDeclNameResolver.cpp @@ -88,6 +88,14 @@ std::shared_ptr CxxDeclNameResolver::getDeclName() { const clang::NamedDecl* declaration = clang::dyn_cast(m_declaration); std::string declNameString = declaration->getNameAsString(); + if (const clang::TypeAliasDecl* typeAliasDecl = clang::dyn_cast_or_null(declaration)) + { + clang::TypeAliasTemplateDecl* templatedDeclaration = typeAliasDecl->getDescribedAliasTemplate(); + if (templatedDeclaration) + { + return getDeclName(templatedDeclaration); + } + } if (const clang::CXXRecordDecl* recordDecl = clang::dyn_cast_or_null(declaration)) { clang::ClassTemplateDecl* templateClassDeclaration = recordDecl->getDescribedClassTemplate(); diff --git a/src/test/CxxParserTestSuite.h b/src/test/CxxParserTestSuite.h index c0b9b858..40e49231 100644 --- a/src/test/CxxParserTestSuite.h +++ b/src/test/CxxParserTestSuite.h @@ -266,6 +266,19 @@ public: TS_ASSERT_EQUALS(client->typedefs[0], "anonymous namespace (input.cc)::uint <3:23 3:26>"); } + void test_cxx_parser_finds_type_alias_in_class() + { + std::shared_ptr client = parseCode( + "class Foo\n" + "{\n" + " using Bar = Foo;\n" + "};\n" + ); + + TS_ASSERT_EQUALS(client->typedefs.size(), 1); + TS_ASSERT_EQUALS(client->typedefs[0], "private Foo::Bar <3:8 3:10>"); + } + void test_cxx_parser_finds_macro_define() { std::shared_ptr client = parseCode( @@ -378,6 +391,17 @@ public: TS_ASSERT_EQUALS(client->macros[0], "MAX <1:9 <1:9 1:11> 2:17>"); } + //void __test_cxx_parser_finds_type_template_parameter_type_of_template_type_alias() + //{ + // std::shared_ptr client = parseCode( + // "template\n" + // "using MyType = int;\n" + // ); + + // TS_ASSERT_EQUALS(client->templateParameterTypes.size(), 1); + // TS_ASSERT_EQUALS(client->templateParameterTypes[0], "MyType::T <1:17 1:17>"); + //} + void test_cxx_parser_finds_type_template_parameter_type_of_template_class() { std::shared_ptr client = parseCode(