Skip to content

Commit

Permalink
Ast visitor function for using declarations. (#645)
Browse files Browse the repository at this point in the history
Co-authored-by: Bendegúz Filyó <[email protected]>
Co-authored-by: Máté Cserép <[email protected]>
  • Loading branch information
3 people authored Nov 13, 2023
1 parent 09958e1 commit e23b1dc
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 4 deletions.
2 changes: 2 additions & 0 deletions plugins/cpp/model/include/model/cppastnode.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ struct CppAstNode
LocalTypeLoc,
TypedefTypeLoc,
InheritanceTypeLoc,
UsingLoc,
Other = 1000
};

Expand Down Expand Up @@ -133,6 +134,7 @@ inline std::string astTypeToString(CppAstNode::AstType type_)
case CppAstNode::AstType::LocalTypeLoc: return "LocalTypeLoc";
case CppAstNode::AstType::TypedefTypeLoc: return "TypedefTypeLoc";
case CppAstNode::AstType::InheritanceTypeLoc: return "InheritanceTypeLoc";
case CppAstNode::AstType::UsingLoc: return "UsingLoc";
case CppAstNode::AstType::Other: return "Other";
}

Expand Down
56 changes: 55 additions & 1 deletion plugins/cpp/parser/src/clangastvisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,60 @@ class ClangASTVisitor : public clang::RecursiveASTVisitor<ClangASTVisitor>
return true;
}


bool VisitUsingDecl(clang::UsingDecl* ud_)
{
//--- CppAstNode ---//

for (const clang::UsingShadowDecl* nd : ud_->shadows()) {
model::CppAstNodePtr astNode = std::make_shared<model::CppAstNode>();

astNode->astValue = getSourceText(
_clangSrcMgr,
ud_->getBeginLoc(),
ud_->getLocation(),
true);
astNode->location = getFileLoc(ud_->getBeginLoc(), ud_->getEndLoc());
astNode->entityHash = util::fnvHash(getUSR(nd->getTargetDecl()));

astNode->symbolType = model::CppAstNode::SymbolType::Other;
astNode->astType = model::CppAstNode::AstType::UsingLoc;

astNode->id = model::createIdentifier(*astNode);

if (insertToCache(nd, astNode))
_astNodes.push_back(astNode);
}

return true;
}

bool VisitUsingDirectiveDecl(clang::UsingDirectiveDecl* udd_)
{
//--- CppAstNode ---//

model::CppAstNodePtr astNode = std::make_shared<model::CppAstNode>();

const clang::NamespaceDecl* nd = udd_->getNominatedNamespace();

astNode->astValue = getSourceText(
_clangSrcMgr,
udd_->getBeginLoc(),
udd_->getLocation(),
true);
astNode->location = getFileLoc(udd_->getBeginLoc(), udd_->getEndLoc());
astNode->entityHash = util::fnvHash(getUSR(nd));
astNode->symbolType = model::CppAstNode::SymbolType::Namespace;
astNode->astType = model::CppAstNode::AstType::Usage;

astNode->id = model::createIdentifier(*astNode);

if (insertToCache(udd_, astNode))
_astNodes.push_back(astNode);

return true;
}

bool VisitCXXConstructExpr(clang::CXXConstructExpr* ce_)
{
model::CppAstNodePtr astNode = std::make_shared<model::CppAstNode>();
Expand Down Expand Up @@ -1298,7 +1352,7 @@ class ClangASTVisitor : public clang::RecursiveASTVisitor<ClangASTVisitor>

clang::SourceLocation realStart = start_;
clang::SourceLocation realEnd = end_;

if (_clangSrcMgr.isMacroBodyExpansion(start_))
realStart = _clangSrcMgr.getExpansionLoc(start_);
if (_clangSrcMgr.isMacroArgExpansion(start_))
Expand Down
1 change: 1 addition & 0 deletions plugins/cpp/test/sources/parser/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ add_library(CppTestProject STATIC
cxxrecord.cpp
enum.cpp
function.cpp
using.cpp
variable.cpp
namespace.cpp)
33 changes: 33 additions & 0 deletions plugins/cpp/test/sources/parser/using.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
namespace Nested
{
namespace MyNamespace
{
class C
{
};

void g(C) { }

void g(double) { }

constexpr C VAR1{};

template<class T>
constexpr T VAR2 = T{};
}
}

using namespace Nested;
void g() {}
using MyNamespace::g;

void using_fun()
{
using MyNamespace::C;
using MyNamespace::VAR1;
using MyNamespace::VAR2;

g();
g(VAR1);
g(VAR2<double>);
}
73 changes: 70 additions & 3 deletions plugins/cpp/test/src/cppparsertest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ TEST_F(CppParserTest, FilesAreInDatabase)
file = _db->query_value<model::File>(QFile::filename == "namespace.cpp");
EXPECT_EQ(file.type, "CPP");
EXPECT_EQ(file.parseStatus, model::File::PSFullyParsed);

file = _db->query_value<model::File>(QFile::filename == "using.cpp");
EXPECT_EQ(file.type, "CPP");
EXPECT_EQ(file.parseStatus, model::File::PSFullyParsed);
});
}

Expand Down Expand Up @@ -546,7 +550,7 @@ TEST_F(CppParserTest, Fields)
{
_transaction([&, this] {
model::CppVariable fieldFunction = _db->query_value<model::CppVariable>(
QCppFunction::name == "fieldFunction");
QCppVariable::name == "fieldFunction");
RCppAstNode astNodes = _db->query<model::CppAstNode>(
QCppAstNode::entityHash == fieldFunction.entityHash);

Expand Down Expand Up @@ -686,11 +690,11 @@ TEST_F(CppParserTest, Namespace)
model::CppNamespace myNamespace1 = _db->query_value<model::CppNamespace>(
QCppNamespace::name == "MyNamespace1");
model::CppAstNode astNode = _db->query_value<model::CppAstNode>(
QCppAstNode::entityHash == myNamespace1.entityHash);
QCppAstNode::entityHash == myNamespace1.entityHash &&
QCppAstNode::astType == model::CppAstNode::AstType::Definition);

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

model::CppNamespace myNamespace2 = _db->query_value<model::CppNamespace>(
QCppNamespace::name == "MyNamespace2");
Expand All @@ -702,3 +706,66 @@ TEST_F(CppParserTest, Namespace)
EXPECT_EQ(astNode.astType, model::CppAstNode::AstType::Definition);
});
}

TEST_F(CppParserTest, Using)
{
_transaction([&, this] {
model::CppNamespace nested = _db->query_value<model::CppNamespace>(
QCppNamespace::name == "Nested");

model::CppAstNode astNode = _db->query_value<model::CppAstNode>(
QCppAstNode::entityHash == nested.entityHash &&
QCppAstNode::astType == model::CppAstNode::AstType::Usage);

EXPECT_EQ(astNode.symbolType, model::CppAstNode::SymbolType::Namespace);
EXPECT_EQ(astNode.location.range.start.line, 20);


model::CppRecord cClass = _db->query_value<model::CppRecord>(
QCppRecord::qualifiedName == "Nested::MyNamespace::C");

astNode = _db->query_value<model::CppAstNode>(
QCppAstNode::entityHash == cClass.entityHash &&
QCppAstNode::astType == model::CppAstNode::AstType::UsingLoc);

EXPECT_EQ(astNode.symbolType, model::CppAstNode::SymbolType::Other);
EXPECT_EQ(astNode.location.range.start.line, 26);


model::CppVariable var1 = _db->query_value<model::CppVariable>(
QCppVariable::name == "VAR1");

astNode = _db->query_value<model::CppAstNode>(
QCppAstNode::entityHash == var1.entityHash &&
QCppAstNode::astType == model::CppAstNode::AstType::UsingLoc);

EXPECT_EQ(astNode.symbolType, model::CppAstNode::SymbolType::Other);
EXPECT_EQ(astNode.location.range.start.line, 27);

astNode = _db->query_value<model::CppAstNode>(
QCppAstNode::entityHash == var1.entityHash &&
QCppAstNode::astType == model::CppAstNode::AstType::Read);

EXPECT_EQ(astNode.symbolType, model::CppAstNode::SymbolType::Variable);
EXPECT_EQ(astNode.location.range.start.line, 31);

RCppFunction functions_with_g = _db->query<model::CppFunction>(
QCppFunction::qualifiedName == "Nested::MyNamespace::g");

for (const model::CppFunction& func : functions_with_g) {
astNode = _db->query_value<model::CppAstNode>(
QCppAstNode::entityHash == func.entityHash &&
QCppAstNode::astType == model::CppAstNode::AstType::UsingLoc);

EXPECT_EQ(astNode.symbolType, model::CppAstNode::SymbolType::Other);
EXPECT_EQ(astNode.location.range.start.line, 22);


astNode = _db->query_value<model::CppAstNode>(
QCppAstNode::entityHash == func.entityHash &&
QCppAstNode::astType == model::CppAstNode::AstType::Usage);

EXPECT_EQ(astNode.symbolType, model::CppAstNode::SymbolType::Function);
}
});
}

0 comments on commit e23b1dc

Please sign in to comment.