Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jobs:
use-libcxx: {{#if (and (ieq compiler 'clang') (ge major 19)) }}true{{else}}false{{/if}}
libcxx-runtimes: libcxx{{#if (ne compiler 'msvc')}};libcxxabi{{/if}}
llvm-runtimes: {{#if (ine use-libcxx 'true') }}{{{ libcxx-runtimes }}}{{/if}}
llvm-hash: 3f797a8342c3dbe4a260b26f948d8776ff490431
llvm-hash: dc4cef81d47c7bc4a3c4d58fbacf8a6359683fae
llvm-build-preset-prefix: {{#if optimized-debug}}optimizeddebug{{else}}{{{lowercase build-type}}}{{/if}}
llvm-build-preset-os: {{#if (ieq os 'windows') }}win{{else}}unix{{/if}}
llvm-sanitizer: {{#if (eq compiler 'gcc')}}{{else if ubsan}}-UBSan{{else if asan}}-ASan{{else if msan}}-MSan{{/if}}
Expand Down
2 changes: 1 addition & 1 deletion bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class InstallOptions:
llvm_build_dir: str = "<llvm-src-dir>/build/<llvm-build-type:lower><\"-\":if(cc)><cc:basename><\"-\":if(sanitizer)><sanitizer:lower>"
llvm_install_dir: str = "<llvm-src-dir>/install/<llvm-build-type:lower><\"-\":if(cc)><cc:basename><\"-\":if(sanitizer)><sanitizer:lower>"
llvm_repo: str = "https://github.com/llvm/llvm-project.git"
llvm_commit: str = "a1b6e7ff393533a5c4f3bdfd4efe5da106e2de2b"
llvm_commit: str = "dc4cef81d47c7bc4a3c4d58fbacf8a6359683fae"

# Libxml2
libxml2_src_dir: str = "<third-party-src-dir>/libxml2"
Expand Down
4 changes: 2 additions & 2 deletions docs/modules/ROOT/pages/install.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ cd ..
=== LLVM

MrDocs uses LLVM to parse C++ code and extract documentation from it.
It depends on a recent version of LLVM: https://github.com/llvm/llvm-project/tree/a1b6e7ff393533a5c4f3bdfd4efe5da106e2de2b[a1b6e7f]
It depends on a recent version of LLVM: https://github.com/llvm/llvm-project/tree/dc4cef81d47c7bc4a3c4d58fbacf8a6359683fae[dc4cef8]

**Download**:

Expand All @@ -272,7 +272,7 @@ mkdir -p llvm-project <.>
cd llvm-project
git init <.>
git remote add origin https://github.com/llvm/llvm-project.git <.>
git fetch --depth 1 origin a1b6e7ff393533a5c4f3bdfd4efe5da106e2de2b <.>
git fetch --depth 1 origin dc4cef81d47c7bc4a3c4d58fbacf8a6359683fae <.>
git checkout FETCH_HEAD <.>
----

Expand Down
31 changes: 31 additions & 0 deletions src/lib/AST/ClangHelpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
#include <lib/AST/ClangHelpers.hpp>
#include <mrdocs/Support/Assert.hpp>
#include <mrdocs/Support/Report.hpp>
#include <clang/Driver/Driver.h>
#include <clang/Index/USRGeneration.h>
#include <clang/Sema/Template.h>
#include <llvm/Option/ArgList.h>
#include <ranges>

namespace mrdocs {
Expand Down Expand Up @@ -453,4 +455,33 @@ isDocumented(clang::Decl const* D)
return getDocumentation(D) != nullptr;
}

bool
isClangCL(clang::tooling::CompileCommand const& cc)
{
auto const& cmdline = cc.CommandLine;

// ------------------------------------------------------
// Convert to InputArgList
// ------------------------------------------------------
// InputArgList is the input format for llvm functions
auto cmdLineCStrsView = std::views::transform(cmdline, &std::string::c_str);
std::vector const
cmdLineCStrs(cmdLineCStrsView.begin(), cmdLineCStrsView.end());
llvm::opt::InputArgList const
args(cmdLineCStrs.data(), cmdLineCStrs.data() + cmdLineCStrs.size());

// ------------------------------------------------------
// Get driver mode
// ------------------------------------------------------
// The driver mode distinguishes between clang/gcc and msvc
// command line option formats. The value is deduced from
// the `-drive-mode` option or from `progName`.
// Common values are "gcc", "g++", "cpp", "cl" and "flang".
std::string const& progName = cmdline.front();
clang::StringRef const driver_mode = clang::driver::
getDriverMode(progName, cmdLineCStrs);

return clang::driver::IsClangCL(driver_mode);
}

} // mrdocs
8 changes: 8 additions & 0 deletions src/lib/AST/ClangHelpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <clang/AST/DeclOpenMP.h>
#include <clang/AST/Expr.h>
#include <clang/Sema/Sema.h>
#include <clang/Tooling/CompilationDatabase.h>
#include <type_traits>

namespace mrdocs {
Expand Down Expand Up @@ -1082,6 +1083,13 @@ namespace detail {
report::trace("{}", MRDOCS_SYMBOL_TRACE_UNIQUE_NAME)
#endif

/** Determine whether the driver mode is ClangCL.

@param cc The compilation command to insepct.
*/
bool
isClangCL(clang::tooling::CompileCommand const& cc);

} // mrdocs

#endif
72 changes: 41 additions & 31 deletions src/lib/AST/TerminalTypeVisitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -555,17 +555,6 @@ class TerminalTypeVisitor
return true;
}

bool
VisitDependentTemplateSpecializationType(
clang::DependentTemplateSpecializationType const* T)
{
MRDOCS_SYMBOL_TRACE(T, Visitor_.context_);
const clang::DependentTemplateStorage &S = T->getDependentTemplateName();
getDerived().buildTerminal(S.getQualifier(), S.getName().getIdentifier(),
T->template_arguments(), Quals_, IsPack_);
return true;
}

// Visit a template specialization such as `A<T>`
bool
VisitTemplateSpecializationType(
Expand All @@ -589,31 +578,44 @@ class TerminalTypeVisitor

// The list of template parameters and a reference to
// the templated scoped declaration
clang::NamedDecl* D = TN.getAsTemplateDecl();
MRDOCS_SYMBOL_TRACE(TN, Visitor_.context_);

if (!T->isTypeAlias())
clang::NamedDecl* D = nullptr;
if (auto* CT = dyn_cast<clang::TagType>(T->getCanonicalTypeInternal());
!T->isTypeAlias() && CT)
{
if (auto* CT = dyn_cast<clang::TagType>(T->getCanonicalTypeInternal()))
{
MRDOCS_SYMBOL_TRACE(CT, Visitor_.context_);
D = CT->getOriginalDecl()->getDefinitionOrSelf();
MRDOCS_SYMBOL_TRACE(D, Visitor_.context_);
}
MRDOCS_SYMBOL_TRACE(CT, Visitor_.context_);
D = CT->getDecl()->getDefinitionOrSelf();
MRDOCS_SYMBOL_TRACE(D, Visitor_.context_);
}
else
{
D = TN.getAsTemplateDecl(/*IgnoreDeduced=*/true);
}
if (D)
{
getDerived().buildTerminal(
TN.getQualifier(),
D,
T->template_arguments(),
Quals_,
IsPack_);
}
else if (auto const* S = TN.getAsDependentTemplateName())
{
getDerived().buildTerminal(
S->getQualifier(),
S->getName().getIdentifier(),
T->template_arguments(),
Quals_,
IsPack_);
}

getDerived().buildTerminal(
TN.getQualifier(), D,
T->template_arguments(),
Quals_, IsPack_);
return true;
}

bool
VisitRecordType(
clang::RecordType const* T)
{
clang::RecordDecl* RD = T->getOriginalDecl()->getDefinitionOrSelf();
clang::RecordDecl* RD = T->getDecl()->getDefinitionOrSelf();
// if this is an instantiation of a class template,
// create a SpecializationType & extract the template arguments
Optional<llvm::ArrayRef<clang::TemplateArgument>> TArgs = std::nullopt;
Expand All @@ -630,17 +632,25 @@ class TerminalTypeVisitor
VisitInjectedClassNameType(
clang::InjectedClassNameType const* T)
{
getDerived().buildTerminal(T->getQualifier(), T->getOriginalDecl()->getDefinitionOrSelf(),
std::nullopt, Quals_, IsPack_);
getDerived().buildTerminal(
T->getQualifier(),
T->getDecl()->getDefinitionOrSelf(),
std::nullopt,
Quals_,
IsPack_);
return true;
}

bool
VisitEnumType(
clang::EnumType const* T)
{
getDerived().buildTerminal(T->getQualifier(), T->getOriginalDecl()->getDefinitionOrSelf(),
std::nullopt, Quals_, IsPack_);
getDerived().buildTerminal(
T->getQualifier(),
T->getDecl()->getDefinitionOrSelf(),
std::nullopt,
Quals_,
IsPack_);
return true;
}

Expand Down
15 changes: 10 additions & 5 deletions src/lib/CorpusImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -746,10 +746,9 @@ lookupCacheSet(
//------------------------------------------------

mrdocs::Expected<std::unique_ptr<Corpus>>
CorpusImpl::
build(
CorpusImpl::build(
std::shared_ptr<ConfigImpl const> const& config,
clang::tooling::CompilationDatabase const& compilations)
MrDocsCompilationDatabase const& compilations)
{
using clock_type = std::chrono::steady_clock;
auto start_time = clock_type::now();
Expand All @@ -769,6 +768,10 @@ build(
// SymbolSet in the execution context.
InfoExecutionContext context(*config);

// Identify if we should use "msvc/clang-cl" or "clang/gcc" format
// for options.
bool const is_clang_cl = compilations.isClangCL();

// ------------------------------------------
// "Process file" task
// ------------------------------------------
Expand Down Expand Up @@ -829,8 +832,10 @@ build(
FSConcrete->addVirtualFile(shimPath, shimContent);
Tool.appendArgumentsAdjuster(
clang::tooling::combineAdjusters(
clang::tooling::getInsertArgumentAdjuster("-include"),
clang::tooling::getInsertArgumentAdjuster(shimPath.data())));
clang::tooling::getInsertArgumentAdjuster(
is_clang_cl ? "/FI" : "-include"),
clang::tooling::getInsertArgumentAdjuster(
shimPath.data())));
}

// Run the action
Expand Down
8 changes: 4 additions & 4 deletions src/lib/CorpusImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <lib/AST/ParseRef.hpp>
#include <lib/ConfigImpl.hpp>
#include <lib/Metadata/SymbolSet.hpp>
#include <lib/MrDocsCompilationDatabase.hpp>
#include <lib/Support/Debug.hpp>
#include <mrdocs/ADT/UnorderedStringMap.hpp>
#include <mrdocs/Corpus.hpp>
Expand Down Expand Up @@ -161,15 +162,14 @@ class CorpusImpl final : public Corpus
not need to call this function directly.

@param config A shared pointer to the configuration.
@param compilations A compilations database for the input files.
@param compilations A MrDocs compilations database for the input files.
*/
// MRDOCS_DECL
[[nodiscard]]
static
mrdocs::Expected<std::unique_ptr<Corpus>>
static mrdocs::Expected<std::unique_ptr<Corpus>>
build(
std::shared_ptr<ConfigImpl const> const& config,
clang::tooling::CompilationDatabase const& compilations);
MrDocsCompilationDatabase const& compilations);

void
qualifiedName(Symbol const& I,
Expand Down
Loading
Loading