From 00eed767196017e2bc334f8c5d97a47c100c1de5 Mon Sep 17 00:00:00 2001 From: Krystian Stasiowski Date: Fri, 14 Feb 2025 12:41:14 -0500 Subject: [PATCH] correctly handle files included through symlinks --- src/lib/AST/ASTVisitor.cpp | 45 ++++++--------- src/lib/AST/ASTVisitor.hpp | 24 +------- .../golden-tests/filters/file/excluded.hpp | 4 ++ .../filters/file/include-symlink.adoc | 39 +++++++++++++ .../filters/file/include-symlink.cpp | 1 + .../filters/file/include-symlink.html | 55 +++++++++++++++++++ .../filters/file/include-symlink.xml | 14 +++++ .../filters/file/include-symlink.yml | 3 + .../golden-tests/filters/file/included.hpp | 1 + 9 files changed, 135 insertions(+), 51 deletions(-) create mode 100644 test-files/golden-tests/filters/file/excluded.hpp create mode 100644 test-files/golden-tests/filters/file/include-symlink.adoc create mode 100644 test-files/golden-tests/filters/file/include-symlink.cpp create mode 100644 test-files/golden-tests/filters/file/include-symlink.html create mode 100644 test-files/golden-tests/filters/file/include-symlink.xml create mode 100644 test-files/golden-tests/filters/file/include-symlink.yml create mode 120000 test-files/golden-tests/filters/file/included.hpp diff --git a/src/lib/AST/ASTVisitor.cpp b/src/lib/AST/ASTVisitor.cpp index 2014ac685..106e35bd0 100644 --- a/src/lib/AST/ASTVisitor.cpp +++ b/src/lib/AST/ASTVisitor.cpp @@ -3120,25 +3120,18 @@ ASTVisitor:: findFileInfo(clang::SourceLocation const loc) { MRDOCS_CHECK_OR(!loc.isInvalid(), nullptr); - - // KRYSTIAN FIXME: we really should not be calling getPresumedLoc this often, - // it's quite expensive - auto const presumed = source_.getPresumedLoc(loc, false); - MRDOCS_CHECK_OR(!presumed.isInvalid(), nullptr); - - FileEntry const* entry = source_.getFileEntryForID( presumed.getFileID()); - MRDOCS_CHECK_OR(entry, nullptr); + // Find the presumed location, ignoring #line directives + PresumedLoc presumed = source_.getPresumedLoc(loc, false); + FileID id = presumed.getFileID(); + if(id.isInvalid()) + return nullptr; // Find in the cache - if (auto const it = files_.find(entry); it != files_.end()) - { + if(auto const it = files_.find(id); it != files_.end()) return std::addressof(it->second); - } - // Build FileInfo - auto const FI = buildFileInfo(entry); - MRDOCS_CHECK_OR(FI, nullptr); - auto [it, inserted] = files_.try_emplace(entry, std::move(*FI)); + auto [it, inserted] = files_.try_emplace( + id, buildFileInfo(presumed.getFilename())); return std::addressof(it->second); } @@ -3154,25 +3147,19 @@ findFileInfo(Decl const* D) return findFileInfo(Loc); } -std::optional -ASTVisitor:: -buildFileInfo(FileEntry const* entry) -{ - std::string_view const file_path = entry->tryGetRealPathName(); - MRDOCS_CHECK_OR(!file_path.empty(), std::nullopt); - return buildFileInfo(file_path); -} - ASTVisitor::FileInfo ASTVisitor:: -buildFileInfo(std::string_view const file_path) +buildFileInfo(std::string_view path) { FileInfo file_info; - file_info.full_path = file_path; - if (!files::isPosixStyle(file_info.full_path)) - { + file_info.full_path = path; + + if (! files::isAbsolute(file_info.full_path)) + file_info.full_path = files::makeAbsolute( + file_info.full_path, config_->sourceRoot); + + if (! files::isPosixStyle(file_info.full_path)) file_info.full_path = files::makePosixStyle(file_info.full_path); - } // Attempts to get a relative path for the prefix auto tryGetRelativePosixPath = [&file_info](std::string_view const prefix) diff --git a/src/lib/AST/ASTVisitor.hpp b/src/lib/AST/ASTVisitor.hpp index 07aabc9f4..359b70d93 100644 --- a/src/lib/AST/ASTVisitor.hpp +++ b/src/lib/AST/ASTVisitor.hpp @@ -138,7 +138,7 @@ class ASTVisitor if a file should be extracted or to add the SourceInfo to an Info object. */ - std::unordered_map files_; + llvm::DenseMap files_; /* Determine how a Decl matched the filters */ @@ -1112,26 +1112,6 @@ class ASTVisitor FileInfo* findFileInfo(Decl const* D); - /* Build a FileInfo for a FileEntry - - This function will build a FileInfo object for a - given Clang FileEntry object. - - The function will extract the full path and short - path of the file, and store the information in the - FileInfo object. - - This function is used as an auxiliary function to - `findFileInfo` when the FileInfo object does not - exist in the cache. - - @param file The Clang FileEntry object to build the FileInfo for. - @return the FileInfo object. - - */ - std::optional - buildFileInfo(FileEntry const* entry); - /* Build a FileInfo for a string path This function will build a FileInfo object for a @@ -1153,7 +1133,7 @@ class ASTVisitor @return the FileInfo object. */ FileInfo - buildFileInfo(std::string_view file_path); + buildFileInfo(std::string_view path); /* Result of an upsert operation diff --git a/test-files/golden-tests/filters/file/excluded.hpp b/test-files/golden-tests/filters/file/excluded.hpp new file mode 100644 index 000000000..ae0baa306 --- /dev/null +++ b/test-files/golden-tests/filters/file/excluded.hpp @@ -0,0 +1,4 @@ +/** A brief. +*/ + +void f(); diff --git a/test-files/golden-tests/filters/file/include-symlink.adoc b/test-files/golden-tests/filters/file/include-symlink.adoc new file mode 100644 index 000000000..81a97ecc7 --- /dev/null +++ b/test-files/golden-tests/filters/file/include-symlink.adoc @@ -0,0 +1,39 @@ += Reference +:mrdocs: + +[#index] +== Global namespace + + +=== Functions + +[cols=2] +|=== +| Name +| Description + +| <> +| A brief. + +|=== + +[#f] +== f + + +A brief. + +=== Synopsis + + +Declared in `<included.hpp>` + +[source,cpp,subs="verbatim,replacements,macros,-callouts"] +---- +void +f(); +---- + + + +[.small]#Created with https://www.mrdocs.com[MrDocs]# diff --git a/test-files/golden-tests/filters/file/include-symlink.cpp b/test-files/golden-tests/filters/file/include-symlink.cpp new file mode 100644 index 000000000..080c83935 --- /dev/null +++ b/test-files/golden-tests/filters/file/include-symlink.cpp @@ -0,0 +1 @@ +#include "included.hpp" diff --git a/test-files/golden-tests/filters/file/include-symlink.html b/test-files/golden-tests/filters/file/include-symlink.html new file mode 100644 index 000000000..757ff259f --- /dev/null +++ b/test-files/golden-tests/filters/file/include-symlink.html @@ -0,0 +1,55 @@ + + +Reference + + +
+

Reference

+
+
+

Global namespace

+
+

Functions

+ + + + + + + + + + + + +
NameDescription
f A brief. +
+
+
+
+

f

+
+A brief. + + +
+
+
+

Synopsis

+
+Declared in <included.hpp>
+
+
+void
+f();
+
+
+
+
+ +
+
+

Created with MrDocs

+
+ + \ No newline at end of file diff --git a/test-files/golden-tests/filters/file/include-symlink.xml b/test-files/golden-tests/filters/file/include-symlink.xml new file mode 100644 index 000000000..4e00cd859 --- /dev/null +++ b/test-files/golden-tests/filters/file/include-symlink.xml @@ -0,0 +1,14 @@ + + + + + + + + A brief. + + + + + diff --git a/test-files/golden-tests/filters/file/include-symlink.yml b/test-files/golden-tests/filters/file/include-symlink.yml new file mode 100644 index 000000000..1369aaae6 --- /dev/null +++ b/test-files/golden-tests/filters/file/include-symlink.yml @@ -0,0 +1,3 @@ +# Exclude excluded.hpp +exclude: + - 'excluded.hpp' diff --git a/test-files/golden-tests/filters/file/included.hpp b/test-files/golden-tests/filters/file/included.hpp new file mode 120000 index 000000000..95f280f3e --- /dev/null +++ b/test-files/golden-tests/filters/file/included.hpp @@ -0,0 +1 @@ +excluded.hpp \ No newline at end of file