Skip to content

Commit 87a66f2

Browse files
K-ballomizvekov
authored andcommitted
Fix support for clang cl-mode driver
1 parent ba0dcfd commit 87a66f2

22 files changed

+610
-214
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ jobs:
6969
use-libcxx: {{#if (and (ieq compiler 'clang') (ge major 19)) }}true{{else}}false{{/if}}
7070
libcxx-runtimes: libcxx{{#if (ne compiler 'msvc')}};libcxxabi{{/if}}
7171
llvm-runtimes: {{#if (ine use-libcxx 'true') }}{{{ libcxx-runtimes }}}{{/if}}
72-
llvm-hash: 3f797a8342c3dbe4a260b26f948d8776ff490431
72+
llvm-hash: dc4cef81d47c7bc4a3c4d58fbacf8a6359683fae
7373
llvm-build-preset-prefix: {{#if optimized-debug}}optimizeddebug{{else}}{{{lowercase build-type}}}{{/if}}
7474
llvm-build-preset-os: {{#if (ieq os 'windows') }}win{{else}}unix{{/if}}
7575
llvm-sanitizer: {{#if (eq compiler 'gcc')}}{{else if ubsan}}-UBSan{{else if asan}}-ASan{{else if msan}}-MSan{{/if}}

bootstrap.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ class InstallOptions:
104104
llvm_build_dir: str = "<llvm-src-dir>/build/<llvm-build-type:lower><\"-\":if(cc)><cc:basename><\"-\":if(sanitizer)><sanitizer:lower>"
105105
llvm_install_dir: str = "<llvm-src-dir>/install/<llvm-build-type:lower><\"-\":if(cc)><cc:basename><\"-\":if(sanitizer)><sanitizer:lower>"
106106
llvm_repo: str = "https://github.com/llvm/llvm-project.git"
107-
llvm_commit: str = "a1b6e7ff393533a5c4f3bdfd4efe5da106e2de2b"
107+
llvm_commit: str = "dc4cef81d47c7bc4a3c4d58fbacf8a6359683fae"
108108

109109
# Libxml2
110110
libxml2_src_dir: str = "<third-party-src-dir>/libxml2"

docs/modules/ROOT/pages/install.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ cd ..
259259
=== LLVM
260260
261261
MrDocs uses LLVM to parse C++ code and extract documentation from it.
262-
It depends on a recent version of LLVM: https://github.com/llvm/llvm-project/tree/a1b6e7ff393533a5c4f3bdfd4efe5da106e2de2b[a1b6e7f]
262+
It depends on a recent version of LLVM: https://github.com/llvm/llvm-project/tree/dc4cef81d47c7bc4a3c4d58fbacf8a6359683fae[dc4cef8]
263263
264264
**Download**:
265265
@@ -272,7 +272,7 @@ mkdir -p llvm-project <.>
272272
cd llvm-project
273273
git init <.>
274274
git remote add origin https://github.com/llvm/llvm-project.git <.>
275-
git fetch --depth 1 origin a1b6e7ff393533a5c4f3bdfd4efe5da106e2de2b <.>
275+
git fetch --depth 1 origin dc4cef81d47c7bc4a3c4d58fbacf8a6359683fae <.>
276276
git checkout FETCH_HEAD <.>
277277
----
278278

src/lib/AST/ClangHelpers.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,10 @@
1313
#include <lib/AST/ClangHelpers.hpp>
1414
#include <mrdocs/Support/Assert.hpp>
1515
#include <mrdocs/Support/Report.hpp>
16+
#include <clang/Driver/Driver.h>
1617
#include <clang/Index/USRGeneration.h>
1718
#include <clang/Sema/Template.h>
19+
#include <llvm/Option/ArgList.h>
1820
#include <ranges>
1921

2022
namespace mrdocs {
@@ -453,4 +455,33 @@ isDocumented(clang::Decl const* D)
453455
return getDocumentation(D) != nullptr;
454456
}
455457

458+
bool
459+
isClangCL(clang::tooling::CompileCommand const& cc)
460+
{
461+
auto const& cmdline = cc.CommandLine;
462+
463+
// ------------------------------------------------------
464+
// Convert to InputArgList
465+
// ------------------------------------------------------
466+
// InputArgList is the input format for llvm functions
467+
auto cmdLineCStrsView = std::views::transform(cmdline, &std::string::c_str);
468+
std::vector const
469+
cmdLineCStrs(cmdLineCStrsView.begin(), cmdLineCStrsView.end());
470+
llvm::opt::InputArgList const
471+
args(cmdLineCStrs.data(), cmdLineCStrs.data() + cmdLineCStrs.size());
472+
473+
// ------------------------------------------------------
474+
// Get driver mode
475+
// ------------------------------------------------------
476+
// The driver mode distinguishes between clang/gcc and msvc
477+
// command line option formats. The value is deduced from
478+
// the `-drive-mode` option or from `progName`.
479+
// Common values are "gcc", "g++", "cpp", "cl" and "flang".
480+
std::string const& progName = cmdline.front();
481+
clang::StringRef const driver_mode = clang::driver::
482+
getDriverMode(progName, cmdLineCStrs);
483+
484+
return clang::driver::IsClangCL(driver_mode);
485+
}
486+
456487
} // mrdocs

src/lib/AST/ClangHelpers.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <clang/AST/DeclOpenMP.h>
2727
#include <clang/AST/Expr.h>
2828
#include <clang/Sema/Sema.h>
29+
#include <clang/Tooling/CompilationDatabase.h>
2930
#include <type_traits>
3031

3132
namespace mrdocs {
@@ -1082,6 +1083,13 @@ namespace detail {
10821083
report::trace("{}", MRDOCS_SYMBOL_TRACE_UNIQUE_NAME)
10831084
#endif
10841085

1086+
/** Determine whether the driver mode is ClangCL.
1087+
1088+
@param cc The compilation command to insepct.
1089+
*/
1090+
bool
1091+
isClangCL(clang::tooling::CompileCommand const& cc);
1092+
10851093
} // mrdocs
10861094

10871095
#endif

src/lib/AST/TerminalTypeVisitor.hpp

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -555,17 +555,6 @@ class TerminalTypeVisitor
555555
return true;
556556
}
557557

558-
bool
559-
VisitDependentTemplateSpecializationType(
560-
clang::DependentTemplateSpecializationType const* T)
561-
{
562-
MRDOCS_SYMBOL_TRACE(T, Visitor_.context_);
563-
const clang::DependentTemplateStorage &S = T->getDependentTemplateName();
564-
getDerived().buildTerminal(S.getQualifier(), S.getName().getIdentifier(),
565-
T->template_arguments(), Quals_, IsPack_);
566-
return true;
567-
}
568-
569558
// Visit a template specialization such as `A<T>`
570559
bool
571560
VisitTemplateSpecializationType(
@@ -589,31 +578,44 @@ class TerminalTypeVisitor
589578

590579
// The list of template parameters and a reference to
591580
// the templated scoped declaration
592-
clang::NamedDecl* D = TN.getAsTemplateDecl();
593-
MRDOCS_SYMBOL_TRACE(TN, Visitor_.context_);
594-
595-
if (!T->isTypeAlias())
581+
clang::NamedDecl* D = nullptr;
582+
if (auto* CT = dyn_cast<clang::TagType>(T->getCanonicalTypeInternal());
583+
!T->isTypeAlias() && CT)
596584
{
597-
if (auto* CT = dyn_cast<clang::TagType>(T->getCanonicalTypeInternal()))
598-
{
599-
MRDOCS_SYMBOL_TRACE(CT, Visitor_.context_);
600-
D = CT->getOriginalDecl()->getDefinitionOrSelf();
601-
MRDOCS_SYMBOL_TRACE(D, Visitor_.context_);
602-
}
585+
MRDOCS_SYMBOL_TRACE(CT, Visitor_.context_);
586+
D = CT->getDecl()->getDefinitionOrSelf();
587+
MRDOCS_SYMBOL_TRACE(D, Visitor_.context_);
588+
}
589+
else
590+
{
591+
D = TN.getAsTemplateDecl(/*IgnoreDeduced=*/true);
592+
}
593+
if (D)
594+
{
595+
getDerived().buildTerminal(
596+
TN.getQualifier(),
597+
D,
598+
T->template_arguments(),
599+
Quals_,
600+
IsPack_);
601+
}
602+
else if (auto const* S = TN.getAsDependentTemplateName())
603+
{
604+
getDerived().buildTerminal(
605+
S->getQualifier(),
606+
S->getName().getIdentifier(),
607+
T->template_arguments(),
608+
Quals_,
609+
IsPack_);
603610
}
604-
605-
getDerived().buildTerminal(
606-
TN.getQualifier(), D,
607-
T->template_arguments(),
608-
Quals_, IsPack_);
609611
return true;
610612
}
611613

612614
bool
613615
VisitRecordType(
614616
clang::RecordType const* T)
615617
{
616-
clang::RecordDecl* RD = T->getOriginalDecl()->getDefinitionOrSelf();
618+
clang::RecordDecl* RD = T->getDecl()->getDefinitionOrSelf();
617619
// if this is an instantiation of a class template,
618620
// create a SpecializationType & extract the template arguments
619621
Optional<llvm::ArrayRef<clang::TemplateArgument>> TArgs = std::nullopt;
@@ -630,7 +632,7 @@ class TerminalTypeVisitor
630632
VisitInjectedClassNameType(
631633
clang::InjectedClassNameType const* T)
632634
{
633-
getDerived().buildTerminal(T->getQualifier(), T->getOriginalDecl()->getDefinitionOrSelf(),
635+
getDerived().buildTerminal(T->getQualifier(), T->getDecl()->getDefinitionOrSelf(),
634636
std::nullopt, Quals_, IsPack_);
635637
return true;
636638
}
@@ -639,7 +641,7 @@ class TerminalTypeVisitor
639641
VisitEnumType(
640642
clang::EnumType const* T)
641643
{
642-
getDerived().buildTerminal(T->getQualifier(), T->getOriginalDecl()->getDefinitionOrSelf(),
644+
getDerived().buildTerminal(T->getQualifier(), T->getDecl()->getDefinitionOrSelf(),
643645
std::nullopt, Quals_, IsPack_);
644646
return true;
645647
}

src/lib/CorpusImpl.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -746,10 +746,9 @@ lookupCacheSet(
746746
//------------------------------------------------
747747

748748
mrdocs::Expected<std::unique_ptr<Corpus>>
749-
CorpusImpl::
750-
build(
749+
CorpusImpl::build(
751750
std::shared_ptr<ConfigImpl const> const& config,
752-
clang::tooling::CompilationDatabase const& compilations)
751+
MrDocsCompilationDatabase const& compilations)
753752
{
754753
using clock_type = std::chrono::steady_clock;
755754
auto start_time = clock_type::now();
@@ -769,6 +768,10 @@ build(
769768
// SymbolSet in the execution context.
770769
InfoExecutionContext context(*config);
771770

771+
// Identify if we should use "msvc/clang-cl" or "clang/gcc" format
772+
// for options.
773+
bool const is_clang_cl = compilations.isClangCL();
774+
772775
// ------------------------------------------
773776
// "Process file" task
774777
// ------------------------------------------
@@ -829,8 +832,10 @@ build(
829832
FSConcrete->addVirtualFile(shimPath, shimContent);
830833
Tool.appendArgumentsAdjuster(
831834
clang::tooling::combineAdjusters(
832-
clang::tooling::getInsertArgumentAdjuster("-include"),
833-
clang::tooling::getInsertArgumentAdjuster(shimPath.data())));
835+
clang::tooling::getInsertArgumentAdjuster(
836+
is_clang_cl ? "/FI" : "-include"),
837+
clang::tooling::getInsertArgumentAdjuster(
838+
shimPath.data())));
834839
}
835840

836841
// Run the action

src/lib/CorpusImpl.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <lib/AST/ParseRef.hpp>
1717
#include <lib/ConfigImpl.hpp>
1818
#include <lib/Metadata/SymbolSet.hpp>
19+
#include <lib/MrDocsCompilationDatabase.hpp>
1920
#include <lib/Support/Debug.hpp>
2021
#include <mrdocs/ADT/UnorderedStringMap.hpp>
2122
#include <mrdocs/Corpus.hpp>
@@ -161,15 +162,14 @@ class CorpusImpl final : public Corpus
161162
not need to call this function directly.
162163
163164
@param config A shared pointer to the configuration.
164-
@param compilations A compilations database for the input files.
165+
@param compilations A MrDocs compilations database for the input files.
165166
*/
166167
// MRDOCS_DECL
167168
[[nodiscard]]
168-
static
169-
mrdocs::Expected<std::unique_ptr<Corpus>>
169+
static mrdocs::Expected<std::unique_ptr<Corpus>>
170170
build(
171171
std::shared_ptr<ConfigImpl const> const& config,
172-
clang::tooling::CompilationDatabase const& compilations);
172+
MrDocsCompilationDatabase const& compilations);
173173

174174
void
175175
qualifiedName(Symbol const& I,

0 commit comments

Comments
 (0)