44#include " AstNode.hpp"
55#include " CommentExtractor.hpp"
66#include " ProcessorImpl.hpp"
7- #include " clang/AST/ASTConsumer.h"
8- #include < clang/AST/Comment.h>
9- #include < clang/AST/CommentVisitor.h>
10- #include < clang/AST/Expr.h>
11- #include < clang/AST/ExprCXX.h>
12- #include < clang/AST/RecursiveASTVisitor.h>
137#include < clang/AST/Type.h>
148#include < clang/AST/TypeVisitor.h>
15- #include < iostream>
16- #include < iterator>
179#include < list>
1810#include < vector>
1911
@@ -1041,7 +1033,7 @@ class AstAttribute : public AstNode {
10411033 }
10421034 switch (m_syntax)
10431035 {
1044- case Attr::Syntax::AS_C2x :
1036+ case Attr::Syntax::AS_C23 :
10451037 case Attr::Syntax::AS_CXX11:
10461038 dumper->InsertPunctuation (' [' );
10471039 dumper->InsertPunctuation (' [' );
@@ -1072,7 +1064,7 @@ class AstAttribute : public AstNode {
10721064 }
10731065 switch (m_syntax)
10741066 {
1075- case Attr::Syntax::AS_C2x :
1067+ case Attr::Syntax::AS_C23 :
10761068 case Attr::Syntax::AS_CXX11:
10771069 dumper->InsertPunctuation (' [' );
10781070 dumper->InsertPunctuation (' [' );
@@ -1318,10 +1310,62 @@ static std::string GetNavigationId(clang::FunctionDecl const* func)
13181310 return navigationId;
13191311}
13201312
1313+ static std::string GetNavigationId (clang::CXXRecordDecl const * record)
1314+ {
1315+ return record->getQualifiedNameAsString ();
1316+ }
1317+
1318+ /* *
1319+ * Get the navigation ID for a qualified type declaration.
1320+ *
1321+ * The navigation ID uniquely
1322+ * identifies a declaration in the ApiView. For qualified type
1323+ * declarations, we want to include
1324+ * the full type name, including the namespace.
1325+ *
1326+ * @param type The type to get the navigation ID
1327+ * for.
1328+ * @return The navigation ID for the type.
1329+ *
1330+ */
1331+ static std::string GetNavigationId (clang::QualType const & type)
1332+ {
1333+ std::string navigationId;
1334+ clang::PrintingPolicy pp{LangOptions{}};
1335+ pp.adjustForCPlusPlus ();
1336+ pp.FullyQualifiedName = true ;
1337+ pp.TerseOutput = true ;
1338+ llvm::raw_string_ostream os (navigationId);
1339+
1340+ type.print (os, pp);
1341+ return navigationId;
1342+ }
1343+
1344+ /* *
1345+ * Get the navigation ID for a friend declaration.
1346+ *
1347+ * The navigation ID uniquely identifies a
1348+ * declaration in the ApiView. For friend declarations, we
1349+ * want to include the navigation ID of
1350+ * the parent node, followed by "_friend_", followed by the
1351+ * navigation ID of the friend
1352+ * declaration.
1353+ *
1354+ * @param friendDecl The friend declaration to get the navigation ID for.
1355+ * @param
1356+ * parentNodeNavigationId The navigation ID of the parent node.
1357+ * @return The navigation ID for the
1358+ * friend declaration.
1359+ *
1360+ */
13211361static std::string GetNavigationId (
13221362 clang::FriendDecl const * friendDecl,
13231363 std::string const & parentNodeNavigationId)
13241364{
1365+ if (parentNodeNavigationId.empty ())
1366+ {
1367+ llvm::errs () << " Parent node navigation ID is empty\n " ;
1368+ }
13251369 std::string navigationId = parentNodeNavigationId + " _friend_" ;
13261370 auto dc = friendDecl->getFriendDecl ();
13271371 if (dc)
@@ -1334,10 +1378,11 @@ static std::string GetNavigationId(
13341378 else if (isa<CXXRecordDecl>(dc))
13351379 {
13361380 auto rd = cast<CXXRecordDecl>(dc);
1337- navigationId += rd-> getQualifiedNameAsString ( );
1381+ navigationId += GetNavigationId (rd );
13381382 }
13391383 else
13401384 {
1385+ llvm::errs () << " Unknown friend declaration type.\n " ;
13411386 dc->dump (llvm::outs ());
13421387 }
13431388 }
@@ -1346,11 +1391,13 @@ static std::string GetNavigationId(
13461391 auto friendType = friendDecl->getFriendType ();
13471392 if (friendType)
13481393 {
1394+ navigationId += GetNavigationId (friendType->getType ());
13491395 navigationId
13501396 += QualType::getAsString (friendDecl->getFriendType ()->getType ().split (), LangOptions{});
13511397 }
13521398 else
13531399 {
1400+ llvm::errs () << " Unknown friend declaration.\n " ;
13541401 friendDecl->dump (llvm::outs ());
13551402 }
13561403 }
@@ -2040,7 +2087,7 @@ class AstMethod : public AstFunction {
20402087 AzureClassesDatabase* const database,
20412088 std::shared_ptr<TypeHierarchy::TypeHierarchyNode> parentNode)
20422089 : AstFunction(method, database, parentNode), m_isVirtual(method->isVirtual ()),
2043- m_isPure(method->isPure ()), m_isConst(method->isConst ())
2090+ m_isPure(method->isPureVirtual ()), m_isConst(method->isConst ())
20442091 {
20452092 // We assume that this is an implicit override if there are overriden methods. If we later
20462093 // find an override attribute, we know it's not an implicit override.
@@ -2377,23 +2424,23 @@ class AstClassLike : public AstNamedNode {
23772424 switch (m_tagUsed)
23782425 {
23792426 // / The "struct" keyword.
2380- case TTK_Struct :
2427+ case TagDecl::TagKind::Struct :
23812428 dumper->InsertKeyword (" struct" );
23822429 break ;
23832430 // / The "__interface" keyword.
2384- case TTK_Interface :
2431+ case TagDecl::TagKind::Interface :
23852432 dumper->InsertKeyword (" __interface" );
23862433 break ;
23872434 // / The "union" keyword.
2388- case TTK_Union :
2435+ case TagDecl::TagKind::Union :
23892436 dumper->InsertKeyword (" union" );
23902437 break ;
23912438 // / The "class" keyword.
2392- case TTK_Class :
2439+ case TagDecl::TagKind::Class :
23932440 dumper->InsertKeyword (" class" );
23942441 break ;
23952442 // / The "enum" keyword.
2396- case TTK_Enum :
2443+ case TagDecl::TagKind::Enum :
23972444 dumper->InsertKeyword (" enum" );
23982445 break ;
23992446 default :
@@ -2828,6 +2875,26 @@ class AstUsingDirective : public AstNode {
28282875 : AstNode(), m_namedNamespace{
28292876 usingDirective->getNominatedNamespaceAsWritten ()->getQualifiedNameAsString ()}
28302877 {
2878+
2879+ // Determine the location for the error message.
2880+ auto location = usingDirective->getLocation ();
2881+ auto const & sourceManager = usingDirective->getASTContext ().getSourceManager ();
2882+ auto const & presumedLocation = sourceManager.getPresumedLoc (location);
2883+ std::string typeLocation{presumedLocation.getFilename ()};
2884+
2885+ // Remove the root directory from the location if the location is within the root directory.
2886+ if (typeLocation.find (azureClassesDatabase->GetProcessor ()->RootDirectory ()) == 0 )
2887+ {
2888+ typeLocation.erase (0 , azureClassesDatabase->GetProcessor ()->RootDirectory ().size () + 1 );
2889+ }
2890+
2891+ typeLocation += " :" + std::to_string (presumedLocation.getLine ());
2892+ typeLocation += " :" + std::to_string (presumedLocation.getColumn ());
2893+
2894+ llvm::errs () << raw_ostream::Colors::RED
2895+ << " Found `using namespace` directive in public headers for `m_namedNamespace`, "
2896+ " at location " << typeLocation << raw_ostream::Colors::RESET << " \n " ;
2897+
28312898 azureClassesDatabase->CreateApiViewMessage (
28322899 ApiViewMessages::UsingDirectiveFound, m_namedNamespace);
28332900 }
@@ -2978,19 +3045,19 @@ AstClassLike::AstClassLike(
29783045 TypeHierarchy::TypeHierarchyClass classType;
29793046 switch (m_tagUsed)
29803047 {
2981- case TagDecl::TagKind::TTK_Class :
3048+ case TagDecl::TagKind::Class :
29823049 classType = TypeHierarchy::TypeHierarchyClass::Class;
29833050 break ;
2984- case TagDecl::TagKind::TTK_Enum :
3051+ case TagDecl::TagKind::Enum :
29853052 classType = TypeHierarchy::TypeHierarchyClass::Enum;
29863053 break ;
2987- case TagDecl::TagKind::TTK_Interface :
3054+ case TagDecl::TagKind::Interface :
29883055 classType = TypeHierarchy::TypeHierarchyClass::Interface;
29893056 break ;
2990- case TagDecl::TagKind::TTK_Struct :
3057+ case TagDecl::TagKind::Struct :
29913058 classType = TypeHierarchy::TypeHierarchyClass::Struct;
29923059 break ;
2993- case TagDecl::TagKind::TTK_Union :
3060+ case TagDecl::TagKind::Union :
29943061 classType = TypeHierarchy::TypeHierarchyClass::Unknown;
29953062 break ;
29963063 default :
0 commit comments