Skip to content

Commit e23b1dc

Browse files
schaumbfilbeofITKmcserep
authored
Ast visitor function for using declarations. (#645)
Co-authored-by: Bendegúz Filyó <[email protected]> Co-authored-by: Máté Cserép <[email protected]>
1 parent 09958e1 commit e23b1dc

File tree

5 files changed

+161
-4
lines changed

5 files changed

+161
-4
lines changed

plugins/cpp/model/include/model/cppastnode.h

+2
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ struct CppAstNode
5858
LocalTypeLoc,
5959
TypedefTypeLoc,
6060
InheritanceTypeLoc,
61+
UsingLoc,
6162
Other = 1000
6263
};
6364

@@ -133,6 +134,7 @@ inline std::string astTypeToString(CppAstNode::AstType type_)
133134
case CppAstNode::AstType::LocalTypeLoc: return "LocalTypeLoc";
134135
case CppAstNode::AstType::TypedefTypeLoc: return "TypedefTypeLoc";
135136
case CppAstNode::AstType::InheritanceTypeLoc: return "InheritanceTypeLoc";
137+
case CppAstNode::AstType::UsingLoc: return "UsingLoc";
136138
case CppAstNode::AstType::Other: return "Other";
137139
}
138140

plugins/cpp/parser/src/clangastvisitor.h

+55-1
Original file line numberDiff line numberDiff line change
@@ -998,6 +998,60 @@ class ClangASTVisitor : public clang::RecursiveASTVisitor<ClangASTVisitor>
998998
return true;
999999
}
10001000

1001+
1002+
bool VisitUsingDecl(clang::UsingDecl* ud_)
1003+
{
1004+
//--- CppAstNode ---//
1005+
1006+
for (const clang::UsingShadowDecl* nd : ud_->shadows()) {
1007+
model::CppAstNodePtr astNode = std::make_shared<model::CppAstNode>();
1008+
1009+
astNode->astValue = getSourceText(
1010+
_clangSrcMgr,
1011+
ud_->getBeginLoc(),
1012+
ud_->getLocation(),
1013+
true);
1014+
astNode->location = getFileLoc(ud_->getBeginLoc(), ud_->getEndLoc());
1015+
astNode->entityHash = util::fnvHash(getUSR(nd->getTargetDecl()));
1016+
1017+
astNode->symbolType = model::CppAstNode::SymbolType::Other;
1018+
astNode->astType = model::CppAstNode::AstType::UsingLoc;
1019+
1020+
astNode->id = model::createIdentifier(*astNode);
1021+
1022+
if (insertToCache(nd, astNode))
1023+
_astNodes.push_back(astNode);
1024+
}
1025+
1026+
return true;
1027+
}
1028+
1029+
bool VisitUsingDirectiveDecl(clang::UsingDirectiveDecl* udd_)
1030+
{
1031+
//--- CppAstNode ---//
1032+
1033+
model::CppAstNodePtr astNode = std::make_shared<model::CppAstNode>();
1034+
1035+
const clang::NamespaceDecl* nd = udd_->getNominatedNamespace();
1036+
1037+
astNode->astValue = getSourceText(
1038+
_clangSrcMgr,
1039+
udd_->getBeginLoc(),
1040+
udd_->getLocation(),
1041+
true);
1042+
astNode->location = getFileLoc(udd_->getBeginLoc(), udd_->getEndLoc());
1043+
astNode->entityHash = util::fnvHash(getUSR(nd));
1044+
astNode->symbolType = model::CppAstNode::SymbolType::Namespace;
1045+
astNode->astType = model::CppAstNode::AstType::Usage;
1046+
1047+
astNode->id = model::createIdentifier(*astNode);
1048+
1049+
if (insertToCache(udd_, astNode))
1050+
_astNodes.push_back(astNode);
1051+
1052+
return true;
1053+
}
1054+
10011055
bool VisitCXXConstructExpr(clang::CXXConstructExpr* ce_)
10021056
{
10031057
model::CppAstNodePtr astNode = std::make_shared<model::CppAstNode>();
@@ -1298,7 +1352,7 @@ class ClangASTVisitor : public clang::RecursiveASTVisitor<ClangASTVisitor>
12981352

12991353
clang::SourceLocation realStart = start_;
13001354
clang::SourceLocation realEnd = end_;
1301-
1355+
13021356
if (_clangSrcMgr.isMacroBodyExpansion(start_))
13031357
realStart = _clangSrcMgr.getExpansionLoc(start_);
13041358
if (_clangSrcMgr.isMacroArgExpansion(start_))

plugins/cpp/test/sources/parser/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ add_library(CppTestProject STATIC
99
cxxrecord.cpp
1010
enum.cpp
1111
function.cpp
12+
using.cpp
1213
variable.cpp
1314
namespace.cpp)
+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
namespace Nested
2+
{
3+
namespace MyNamespace
4+
{
5+
class C
6+
{
7+
};
8+
9+
void g(C) { }
10+
11+
void g(double) { }
12+
13+
constexpr C VAR1{};
14+
15+
template<class T>
16+
constexpr T VAR2 = T{};
17+
}
18+
}
19+
20+
using namespace Nested;
21+
void g() {}
22+
using MyNamespace::g;
23+
24+
void using_fun()
25+
{
26+
using MyNamespace::C;
27+
using MyNamespace::VAR1;
28+
using MyNamespace::VAR2;
29+
30+
g();
31+
g(VAR1);
32+
g(VAR2<double>);
33+
}

plugins/cpp/test/src/cppparsertest.cpp

+70-3
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ TEST_F(CppParserTest, FilesAreInDatabase)
8383
file = _db->query_value<model::File>(QFile::filename == "namespace.cpp");
8484
EXPECT_EQ(file.type, "CPP");
8585
EXPECT_EQ(file.parseStatus, model::File::PSFullyParsed);
86+
87+
file = _db->query_value<model::File>(QFile::filename == "using.cpp");
88+
EXPECT_EQ(file.type, "CPP");
89+
EXPECT_EQ(file.parseStatus, model::File::PSFullyParsed);
8690
});
8791
}
8892

@@ -546,7 +550,7 @@ TEST_F(CppParserTest, Fields)
546550
{
547551
_transaction([&, this] {
548552
model::CppVariable fieldFunction = _db->query_value<model::CppVariable>(
549-
QCppFunction::name == "fieldFunction");
553+
QCppVariable::name == "fieldFunction");
550554
RCppAstNode astNodes = _db->query<model::CppAstNode>(
551555
QCppAstNode::entityHash == fieldFunction.entityHash);
552556

@@ -686,11 +690,11 @@ TEST_F(CppParserTest, Namespace)
686690
model::CppNamespace myNamespace1 = _db->query_value<model::CppNamespace>(
687691
QCppNamespace::name == "MyNamespace1");
688692
model::CppAstNode astNode = _db->query_value<model::CppAstNode>(
689-
QCppAstNode::entityHash == myNamespace1.entityHash);
693+
QCppAstNode::entityHash == myNamespace1.entityHash &&
694+
QCppAstNode::astType == model::CppAstNode::AstType::Definition);
690695

691696
EXPECT_EQ(astNode.symbolType, model::CppAstNode::SymbolType::Namespace);
692697
EXPECT_EQ(astNode.location.range.start.line, 1);
693-
EXPECT_EQ(astNode.astType, model::CppAstNode::AstType::Definition);
694698

695699
model::CppNamespace myNamespace2 = _db->query_value<model::CppNamespace>(
696700
QCppNamespace::name == "MyNamespace2");
@@ -702,3 +706,66 @@ TEST_F(CppParserTest, Namespace)
702706
EXPECT_EQ(astNode.astType, model::CppAstNode::AstType::Definition);
703707
});
704708
}
709+
710+
TEST_F(CppParserTest, Using)
711+
{
712+
_transaction([&, this] {
713+
model::CppNamespace nested = _db->query_value<model::CppNamespace>(
714+
QCppNamespace::name == "Nested");
715+
716+
model::CppAstNode astNode = _db->query_value<model::CppAstNode>(
717+
QCppAstNode::entityHash == nested.entityHash &&
718+
QCppAstNode::astType == model::CppAstNode::AstType::Usage);
719+
720+
EXPECT_EQ(astNode.symbolType, model::CppAstNode::SymbolType::Namespace);
721+
EXPECT_EQ(astNode.location.range.start.line, 20);
722+
723+
724+
model::CppRecord cClass = _db->query_value<model::CppRecord>(
725+
QCppRecord::qualifiedName == "Nested::MyNamespace::C");
726+
727+
astNode = _db->query_value<model::CppAstNode>(
728+
QCppAstNode::entityHash == cClass.entityHash &&
729+
QCppAstNode::astType == model::CppAstNode::AstType::UsingLoc);
730+
731+
EXPECT_EQ(astNode.symbolType, model::CppAstNode::SymbolType::Other);
732+
EXPECT_EQ(astNode.location.range.start.line, 26);
733+
734+
735+
model::CppVariable var1 = _db->query_value<model::CppVariable>(
736+
QCppVariable::name == "VAR1");
737+
738+
astNode = _db->query_value<model::CppAstNode>(
739+
QCppAstNode::entityHash == var1.entityHash &&
740+
QCppAstNode::astType == model::CppAstNode::AstType::UsingLoc);
741+
742+
EXPECT_EQ(astNode.symbolType, model::CppAstNode::SymbolType::Other);
743+
EXPECT_EQ(astNode.location.range.start.line, 27);
744+
745+
astNode = _db->query_value<model::CppAstNode>(
746+
QCppAstNode::entityHash == var1.entityHash &&
747+
QCppAstNode::astType == model::CppAstNode::AstType::Read);
748+
749+
EXPECT_EQ(astNode.symbolType, model::CppAstNode::SymbolType::Variable);
750+
EXPECT_EQ(astNode.location.range.start.line, 31);
751+
752+
RCppFunction functions_with_g = _db->query<model::CppFunction>(
753+
QCppFunction::qualifiedName == "Nested::MyNamespace::g");
754+
755+
for (const model::CppFunction& func : functions_with_g) {
756+
astNode = _db->query_value<model::CppAstNode>(
757+
QCppAstNode::entityHash == func.entityHash &&
758+
QCppAstNode::astType == model::CppAstNode::AstType::UsingLoc);
759+
760+
EXPECT_EQ(astNode.symbolType, model::CppAstNode::SymbolType::Other);
761+
EXPECT_EQ(astNode.location.range.start.line, 22);
762+
763+
764+
astNode = _db->query_value<model::CppAstNode>(
765+
QCppAstNode::entityHash == func.entityHash &&
766+
QCppAstNode::astType == model::CppAstNode::AstType::Usage);
767+
768+
EXPECT_EQ(astNode.symbolType, model::CppAstNode::SymbolType::Function);
769+
}
770+
});
771+
}

0 commit comments

Comments
 (0)