From 6a7258fbac414fba5f894e7ef89418acc8d5e614 Mon Sep 17 00:00:00 2001 From: Christopher Franzwa Date: Wed, 16 Jul 2025 00:36:49 -0400 Subject: [PATCH 1/3] Initial commit supporting Clang 19 --- build/llvm/LLVM-commit | 2 +- build/llvm/LLVM.lua | 9 +- src/CppParser/ASTNameMangler.cpp | 8 +- src/CppParser/Comments.cpp | 287 +++++++++++++------------------ src/CppParser/Link.cpp | 4 +- src/CppParser/ParseExpr.cpp | 2 +- src/CppParser/Parser.cpp | 137 ++++++++------- src/CppParser/Parser.h | 4 +- 8 files changed, 214 insertions(+), 239 deletions(-) diff --git a/build/llvm/LLVM-commit b/build/llvm/LLVM-commit index 1f1a216a1..f37d30ae5 100644 --- a/build/llvm/LLVM-commit +++ b/build/llvm/LLVM-commit @@ -1 +1 @@ -6eb36aed86ea276695697093eb8136554c29286b \ No newline at end of file +cd708029e0b2869e80abe31ddb175f7c35361f90 \ No newline at end of file diff --git a/build/llvm/LLVM.lua b/build/llvm/LLVM.lua index 77560cec3..c1e818f1e 100644 --- a/build/llvm/LLVM.lua +++ b/build/llvm/LLVM.lua @@ -260,6 +260,8 @@ function cmake(gen, conf, builddir, options) .. ' -DLLVM_INCLUDE_TESTS=false' .. ' -DLLVM_ENABLE_LIBEDIT=false' .. ' -DLLVM_ENABLE_LIBXML2=false' + .. ' -DLLVM_ENABLE_HIP=false' + .. ' -DLLVM_ENABLE_MLGO=false' .. ' -DLLVM_ENABLE_TERMINFO=false' .. ' -DLLVM_ENABLE_ZLIB=false' .. ' -DLLVM_ENABLE_ZSTD=false' @@ -323,7 +325,7 @@ function cmake(gen, conf, builddir, options) .. ' -DLLVM_TOOL_LLVM_MODEXTRACT_BUILD=false' .. ' -DLLVM_TOOL_LLVM_MT_BUILD=false' .. ' -DLLVM_TOOL_LLVM_NM_BUILD=false' - .. ' -DLLVM_TOOL_LLVM_OBJCOPY_BUILD=false' + .. ' -DLLVM_TOOL_LLVM_OBJCOPY_BUILD=true' .. ' -DLLVM_TOOL_LLVM_OBJDUMP_BUILD=false' .. ' -DLLVM_TOOL_LLVM_OPT_FUZZER_BUILD=false' .. ' -DLLVM_TOOL_LLVM_OPT_REPORT_BUILD=false' @@ -363,7 +365,8 @@ function cmake(gen, conf, builddir, options) .. ' -DLLVM_TOOL_VERIFY_USELISTORDER_BUILD=false' .. ' -DLLVM_TOOL_VFABI_DEMANGLE_FUZZER_BUILD=false' .. ' -DLLVM_TOOL_XCODE_TOOLCHAIN_BUILD=false' - .. ' -DLLVM_TOOL_YAML2OBJ_BUILD=false' + .. ' -DLLVM_TOOL_YAML2OBJ_BUILD=true' + .. ' -DLLVM_TOOL_LLVM_OBJCOPY_BUILD=true' .. ' -DLLVM_HAVE_LIBXAR=false' .. ' -DCLANG_BUILD_EXAMPLES=false ' .. ' -DCLANG_BUILD_TOOLS=false' @@ -373,6 +376,8 @@ function cmake(gen, conf, builddir, options) .. ' -DCLANG_INCLUDE_TESTS=false' .. ' -DCLANG_TOOL_AMDGPU_ARCH_BUILD=false' .. ' -DCLANG_TOOL_APINOTES_TEST_BUILD=false' + .. ' -DCLANG_ENABLE_HIP=false' + .. ' -DCLANG_ENABLE_API_NOTES=false' .. ' -DCLANG_TOOL_ARCMT_TEST_BUILD=false' .. ' -DCLANG_TOOL_CLANG_CHECK_BUILD=false' .. ' -DCLANG_TOOL_CLANG_DIFF_BUILD=false' diff --git a/src/CppParser/ASTNameMangler.cpp b/src/CppParser/ASTNameMangler.cpp index 454524f22..f114e9b85 100644 --- a/src/CppParser/ASTNameMangler.cpp +++ b/src/CppParser/ASTNameMangler.cpp @@ -99,14 +99,18 @@ std::string ASTNameMangler::GetMangledStructor(const NamedDecl* ND, unsigned Str return FrontendBuf; } -std::string ASTNameMangler::GetMangledThunk(const CXXMethodDecl* MD, const ThunkInfo& T, bool /*ElideOverrideInfo*/) const +std::string ASTNameMangler::GetMangledThunk(const CXXMethodDecl* MD, const ThunkInfo& T, bool ElideOverrideInfo) const { std::string FrontendBuf; llvm::raw_string_ostream FOS(FrontendBuf); // TODO: Enable `ElideOverrideInfo` param if clang is updated to 19 - MC->mangleThunk(MD, T, /*ElideOverrideInfo,*/ FOS); + #if LLVM_VERSION_MAJOR >= 19 + MC->mangleThunk(MD, T, ElideOverrideInfo, FOS); + #else + MC->mangleThunk(MD, T, FOS); + #endif return FrontendBuf; } diff --git a/src/CppParser/Comments.cpp b/src/CppParser/Comments.cpp index 799a0985e..65ba01dc2 100644 --- a/src/CppParser/Comments.cpp +++ b/src/CppParser/Comments.cpp @@ -49,41 +49,22 @@ RawComment* Parser::WalkRawComment(const clang::RawComment* RC) } static InlineCommandComment::RenderKind -ConvertRenderKind(clang::comments::InlineCommandComment::RenderKind Kind) +ConvertRenderKind(std::string Kind) { using namespace clang::comments; - switch (Kind) - { - case clang::comments::InlineCommandComment::RenderNormal: - return CppSharp::CppParser::AST::InlineCommandComment::RenderKind::RenderNormal; - case clang::comments::InlineCommandComment::RenderBold: - return CppSharp::CppParser::AST::InlineCommandComment::RenderKind::RenderBold; - case clang::comments::InlineCommandComment::RenderMonospaced: - return CppSharp::CppParser::AST::InlineCommandComment::RenderKind::RenderMonospaced; - case clang::comments::InlineCommandComment::RenderEmphasized: - return CppSharp::CppParser::AST::InlineCommandComment::RenderKind::RenderEmphasized; - case clang::comments::InlineCommandComment::RenderAnchor: - return CppSharp::CppParser::AST::InlineCommandComment::RenderKind::RenderAnchor; - } + if (Kind == "b") + return AST::InlineCommandComment::RenderKind::RenderBold; + else if (Kind == "c") + return AST::InlineCommandComment::RenderKind::RenderMonospaced; + else if (Kind == "a") + return AST::InlineCommandComment::RenderKind::RenderAnchor; + else if (Kind == "e") + return AST::InlineCommandComment::RenderKind::RenderEmphasized; + else + return AST::InlineCommandComment::RenderKind::RenderNormal; llvm_unreachable("Unknown render kind"); } -static ParamCommandComment::PassDirection -ConvertParamPassDirection(clang::comments::ParamCommandComment::PassDirection Dir) -{ - using namespace clang::comments; - switch (Dir) - { - case clang::comments::ParamCommandComment::In: - return CppSharp::CppParser::AST::ParamCommandComment::PassDirection::In; - case clang::comments::ParamCommandComment::Out: - return CppSharp::CppParser::AST::ParamCommandComment::PassDirection::Out; - case clang::comments::ParamCommandComment::InOut: - return CppSharp::CppParser::AST::ParamCommandComment::PassDirection::InOut; - } - llvm_unreachable("Unknown parameter pass direction"); -} - static void HandleInlineContent(const clang::comments::InlineContentComment* CK, InlineContentComment* IC) { @@ -102,158 +83,120 @@ static void HandleBlockCommand(const clang::comments::BlockCommandComment* CK, } } -static Comment* ConvertCommentBlock(clang::comments::Comment* C) +static Comment* ConvertCommentBlock(clang::comments::Comment* C, clang::CompilerInstance* CI) { using namespace clang; using clang::comments::Comment; // This needs to have an underscore else we get an ICE under VS2012. - CppSharp::CppParser::AST::Comment* _Comment = 0; - - switch (C->getCommentKind()) + CppSharp::CppParser::AST::Comment* _Comment = nullptr; + auto kind = C->getCommentKind(); + if (auto CK = dyn_cast(C)) { - case Comment::FullCommentKind: - { - auto CK = cast(C); - auto FC = new FullComment(); - _Comment = FC; - for (auto I = CK->child_begin(), E = CK->child_end(); I != E; ++I) - { - auto Content = ConvertCommentBlock(*I); - FC->Blocks.push_back(static_cast(Content)); - } - break; - } - case Comment::BlockCommandCommentKind: - { - auto CK = cast(C); - auto BC = new BlockCommandComment(); - _Comment = BC; - HandleBlockCommand(CK, BC); - BC->paragraphComment = static_cast(ConvertCommentBlock(CK->getParagraph())); - break; - } - case Comment::ParamCommandCommentKind: - { - auto CK = cast(C); - auto PC = new ParamCommandComment(); - _Comment = PC; - HandleBlockCommand(CK, PC); - PC->direction = ConvertParamPassDirection(CK->getDirection()); - if (CK->isParamIndexValid() && !CK->isVarArgParam()) - PC->paramIndex = CK->getParamIndex(); - PC->paragraphComment = static_cast(ConvertCommentBlock(CK->getParagraph())); - break; - } - case Comment::TParamCommandCommentKind: - { - auto CK = cast(C); - _Comment = new TParamCommandComment(); - auto TC = new TParamCommandComment(); - _Comment = TC; - HandleBlockCommand(CK, TC); - if (CK->isPositionValid()) - for (unsigned I = 0, E = CK->getDepth(); I != E; ++I) - TC->Position.push_back(CK->getIndex(I)); - TC->paragraphComment = static_cast(ConvertCommentBlock(CK->getParagraph())); - break; - } - case Comment::VerbatimBlockCommentKind: - { - auto CK = cast(C); - auto VB = new VerbatimBlockComment(); - _Comment = VB; - for (auto I = CK->child_begin(), E = CK->child_end(); I != E; ++I) - { - auto Line = ConvertCommentBlock(*I); - VB->Lines.push_back(static_cast(Line)); - } - break; - } - case Comment::VerbatimLineCommentKind: - { - auto CK = cast(C); - auto VL = new VerbatimLineComment(); - _Comment = VL; - VL->text = CK->getText().str(); - break; - } - case Comment::ParagraphCommentKind: - { - auto CK = cast(C); - auto PC = new ParagraphComment(); - _Comment = PC; - for (auto I = CK->child_begin(), E = CK->child_end(); I != E; ++I) - { - auto Content = ConvertCommentBlock(*I); - PC->Content.push_back(static_cast(Content)); - } - PC->isWhitespace = CK->isWhitespace(); - break; - } - case Comment::HTMLStartTagCommentKind: - { - auto CK = cast(C); - auto TC = new HTMLStartTagComment(); - _Comment = TC; - HandleInlineContent(CK, TC); - TC->tagName = CK->getTagName().str(); - for (unsigned I = 0, E = CK->getNumAttrs(); I != E; ++I) - { - auto A = CK->getAttr(I); - auto Attr = HTMLStartTagComment::Attribute(); - Attr.name = A.Name.str(); - Attr.value = A.Value.str(); - TC->Attributes.push_back(Attr); - } - break; - } - case Comment::HTMLEndTagCommentKind: - { - auto CK = cast(C); - auto TC = new HTMLEndTagComment(); - _Comment = TC; - HandleInlineContent(CK, TC); - TC->tagName = CK->getTagName().str(); - break; - } - case Comment::TextCommentKind: - { - auto CK = cast(C); - auto TC = new TextComment(); - _Comment = TC; - HandleInlineContent(CK, TC); - TC->text = CK->getText().str(); - break; - } - case Comment::InlineCommandCommentKind: + auto FC = new FullComment(); + _Comment = FC; + for (auto I = CK->child_begin(), E = CK->child_end(); I != E; ++I) + FC->Blocks.push_back(static_cast(ConvertCommentBlock(*I, CI))); + } + else if (auto CK = dyn_cast(C)) + { + auto BC = new BlockCommandComment(); + _Comment = BC; + HandleBlockCommand(CK, BC); + BC->paragraphComment = static_cast(ConvertCommentBlock(CK->getParagraph(), CI)); + } + else if (auto CK = dyn_cast(C)) + { + auto PC = new ParamCommandComment(); + _Comment = PC; + HandleBlockCommand(CK, PC); + if (CK->isParamIndexValid() && !CK->isVarArgParam()) + PC->paramIndex = CK->getParamIndex(); + PC->paragraphComment = static_cast(ConvertCommentBlock(CK->getParagraph(), CI)); + } + else if (auto CK = dyn_cast(C)) + { + auto TC = new TParamCommandComment(); + _Comment = TC; + HandleBlockCommand(CK, TC); + if (CK->isPositionValid()) + for (unsigned I = 0, E = CK->getDepth(); I != E; ++I) + TC->Position.push_back(CK->getIndex(I)); + TC->paragraphComment = static_cast(ConvertCommentBlock(CK->getParagraph(), CI)); + } + else if (auto CK = dyn_cast(C)) + { + auto VB = new VerbatimBlockComment(); + _Comment = VB; + for (auto I = CK->child_begin(), E = CK->child_end(); I != E; ++I) + VB->Lines.push_back(static_cast(ConvertCommentBlock(*I, CI))); + } + else if (auto CK = dyn_cast(C)) + { + auto VL = new VerbatimLineComment(); + _Comment = VL; + VL->text = CK->getText().str(); + } + else if (auto CK = dyn_cast(C)) + { + auto PC = new ParagraphComment(); + _Comment = PC; + for (auto I = CK->child_begin(), E = CK->child_end(); I != E; ++I) + PC->Content.push_back(static_cast(ConvertCommentBlock(*I, CI))); + PC->isWhitespace = CK->isWhitespace(); + } + else if (auto CK = dyn_cast(C)) + { + auto TC = new HTMLStartTagComment(); + _Comment = TC; + HandleInlineContent(CK, TC); + TC->tagName = CK->getTagName().str(); + for (unsigned I = 0, E = CK->getNumAttrs(); I != E; ++I) { - auto CK = cast(C); - auto IC = new InlineCommandComment(); - _Comment = IC; - HandleInlineContent(CK, IC); - IC->commandId = CK->getCommandID(); - IC->commentRenderKind = ConvertRenderKind(CK->getRenderKind()); - for (unsigned I = 0, E = CK->getNumArgs(); I != E; ++I) - { - auto Arg = InlineCommandComment::Argument(); - Arg.text = CK->getArgText(I).str(); - IC->Arguments.push_back(Arg); - } - break; + auto A = CK->getAttr(I); + auto Attr = HTMLStartTagComment::Attribute(); + Attr.name = A.Name.str(); + Attr.value = A.Value.str(); + TC->Attributes.push_back(Attr); } - case Comment::VerbatimBlockLineCommentKind: + } + else if (auto CK = dyn_cast(C)) + { + auto TC = new HTMLEndTagComment(); + _Comment = TC; + HandleInlineContent(CK, TC); + TC->tagName = CK->getTagName().str(); + } + else if (auto CK = dyn_cast(C)) + { + auto TC = new TextComment(); + _Comment = TC; + HandleInlineContent(CK, TC); + TC->text = CK->getText().str(); + } + else if (auto CK = dyn_cast(C)) + { + auto IC = new InlineCommandComment(); + _Comment = IC; + HandleInlineContent(CK, IC); + IC->commandId = CK->getCommandID(); + + IC->commentRenderKind = ConvertRenderKind(CK->getCommandName(CI->getASTContext().getCommentCommandTraits()).str()); + for (unsigned I = 0, E = CK->getNumArgs(); I != E; ++I) { - auto CK = cast(C); - auto VL = new VerbatimBlockLineComment(); - _Comment = VL; - VL->text = CK->getText().str(); - break; + auto Arg = InlineCommandComment::Argument(); + Arg.text = CK->getArgText(I).str(); + IC->Arguments.push_back(Arg); } - case Comment::NoCommentKind: return nullptr; - default: - llvm_unreachable("Unknown comment kind"); } + else if (auto CK = dyn_cast(C)) + { + auto VL = new VerbatimBlockLineComment(); + _Comment = VL; + VL->text = CK->getText().str(); + } + else + llvm_unreachable("Unknown comment kind"); assert(_Comment && "Invalid comment instance"); return _Comment; @@ -272,7 +215,7 @@ void Parser::HandleComments(const clang::Decl* D, Declaration* Decl) if (clang::comments::FullComment* FC = RC->parse(c->getASTContext(), &c->getPreprocessor(), D)) { - auto CB = static_cast(ConvertCommentBlock(FC)); + auto CB = static_cast(ConvertCommentBlock(FC, c.get())); RawComment->fullCommentBlock = CB; } } diff --git a/src/CppParser/Link.cpp b/src/CppParser/Link.cpp index 132018117..e8d6d7807 100644 --- a/src/CppParser/Link.cpp +++ b/src/CppParser/Link.cpp @@ -70,9 +70,9 @@ bool Parser::LinkWindows(const CppLinkerOptions* LinkerOptions, } const Triple& Triple = c->getTarget().getTriple(); - driver::Driver D("", Triple.str(), c->getDiagnostics()); + clang::driver::Driver D("", Triple.str(), c->getDiagnostics()); opt::InputArgList Args(0, 0); - driver::toolchains::MSVCToolChain TC(D, Triple, Args); + clang::driver::toolchains::MSVCToolChain TC(D, Triple, Args); std::vector LibraryPaths; LibraryPaths.push_back("-libpath:" + TC.getSubDirectoryPath( diff --git a/src/CppParser/ParseExpr.cpp b/src/CppParser/ParseExpr.cpp index 4e1bec7ae..166633063 100644 --- a/src/CppParser/ParseExpr.cpp +++ b/src/CppParser/ParseExpr.cpp @@ -2322,7 +2322,7 @@ AST::Expr* Parser::WalkExpression(const clang::Expr* Expr) _S->hasExplicitTemplateArgs = S->hasExplicitTemplateArgs(); _S->numTemplateArgs = S->getNumTemplateArgs(); _S->requiresADL = S->requiresADL(); - _S->isOverloaded = S->isOverloaded(); + _S->isOverloaded = S->getNumDecls() > 1; _Expr = _S; break; } diff --git a/src/CppParser/Parser.cpp b/src/CppParser/Parser.cpp index 22a500af2..90e5fa16c 100644 --- a/src/CppParser/Parser.cpp +++ b/src/CppParser/Parser.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -36,6 +37,7 @@ #include #include #include +#include "clang/AST/TemplateBase.h" #include #include #include @@ -1097,15 +1099,15 @@ static TagKind ConvertToTagKind(clang::TagTypeKind AS) { switch (AS) { - case clang::TagTypeKind::TTK_Struct: + case clang::TagTypeKind::Struct: return TagKind::Struct; - case clang::TagTypeKind::TTK_Interface: + case clang::TagTypeKind::Interface: return TagKind::Interface; - case clang::TagTypeKind::TTK_Union: + case clang::TagTypeKind::Union: return TagKind::Union; - case clang::TagTypeKind::TTK_Class: + case clang::TagTypeKind::Class: return TagKind::Class; - case clang::TagTypeKind::TTK_Enum: + case clang::TagTypeKind::Enum: return TagKind::Enum; } @@ -1394,17 +1396,9 @@ Parser::WalkClassTemplateSpecialization(const clang::ClassTemplateSpecialization CT->Specializations.push_back(TS); auto& TAL = CTS->getTemplateArgs(); - auto TSI = CTS->getTypeAsWritten(); - if (TSI) - { - auto TL = TSI->getTypeLoc(); - auto TSL = TL.getAs(); - TS->Arguments = WalkTemplateArgumentList(&TAL, &TSL); - } - else - { - TS->Arguments = WalkTemplateArgumentList(&TAL, (TemplateSpecializationTypeLoc*)0); - } + TemplateSpecializationTypeLoc TSL; + + TS->Arguments = WalkTemplateArgumentList(&TAL, nullptr); if (CTS->isCompleteDefinition()) { @@ -1448,13 +1442,8 @@ Parser::WalkClassTemplatePartialSpecialization(const clang::ClassTemplatePartial TS->specializationKind = WalkTemplateSpecializationKind(CTS->getSpecializationKind()); CT->Specializations.push_back(TS); - auto& TAL = CTS->getTemplateArgs(); - if (auto TSI = CTS->getTypeAsWritten()) - { - auto TL = TSI->getTypeLoc(); - auto TSL = TL.getAs(); - TS->Arguments = WalkTemplateArgumentList(&TAL, &TSL); - } + const TemplateArgumentList& TAL = CTS->getTemplateArgs(); + WalkTemplateArgumentList(&TAL, nullptr); if (CTS->isCompleteDefinition()) { @@ -1567,7 +1556,11 @@ TypeTemplateParameter* Parser::WalkTypeTemplateParameter(const clang::TemplateTy HandleDeclaration(TTPD, TP); if (TTPD->hasDefaultArgument()) - TP->defaultArgument = GetQualifiedType(TTPD->getDefaultArgument()); + { + auto TSI = TTPD->getDefaultArgument().getTypeSourceInfo(); + if (TSI) + TP->defaultArgument = GetQualifiedType(TSI->getType()); + } TP->depth = TTPD->getDepth(); TP->index = TTPD->getIndex(); TP->isParameterPack = TTPD->isParameterPack(); @@ -1591,7 +1584,7 @@ NonTypeTemplateParameter* Parser::WalkNonTypeTemplateParameter(const clang::NonT HandleDeclaration(NTTPD, NTP); if (NTTPD->hasDefaultArgument()) - NTP->defaultArgument = WalkExpressionObsolete(NTTPD->getDefaultArgument()); + NTP->defaultArgument = WalkExpressionObsolete(NTTPD->getDefaultArgument().getSourceExpression()); NTP->type = GetQualifiedType(NTTPD->getType()); NTP->depth = NTTPD->getDepth(); NTP->index = NTTPD->getIndex(); @@ -1641,6 +1634,39 @@ std::vector Parser::WalkTemplateArgumentList(const clang::Temp //-----------------------------------// +template +std::vector Parser::WalkTemplateArgumentList( + llvm::ArrayRef TAL, TypeLoc* TSTL) +{ + using namespace clang; + + const bool LocValid = TSTL && !TSTL->isNull() && TSTL->getTypePtr(); + + std::vector params; + const size_t typeLocNumArgs = LocValid ? TSTL->getNumArgs() : 0; + + for (size_t i = 0, e = TAL.size(); i < e; ++i) + { + const clang::TemplateArgument& TA = TAL[i]; + + TemplateArgumentLoc TArgLoc; + TemplateArgumentLoc* ArgLoc = nullptr; + + if (i < typeLocNumArgs && e == typeLocNumArgs) + { + TArgLoc = TSTL->getArgLoc(i); + ArgLoc = &TArgLoc; + } + + auto Arg = WalkTemplateArgument(TA, ArgLoc); + params.push_back(Arg); + } + + return params; +} + +//-----------------------------------// + std::vector Parser::WalkTemplateArgumentList(const clang::TemplateArgumentList* TAL, const clang::ASTTemplateArgumentListInfo* TALI) @@ -1893,7 +1919,7 @@ Parser::WalkVarTemplateSpecialization(const clang::VarTemplateSpecializationDecl VT->Specializations.push_back(TS); auto& TAL = VTS->getTemplateArgs(); - auto TSI = VTS->getTypeAsWritten(); + auto TSI = VTS->getTypeSourceInfo(); if (TSI) { auto TL = TSI->getTypeLoc(); @@ -1933,7 +1959,7 @@ Parser::WalkVarTemplatePartialSpecialization(const clang::VarTemplatePartialSpec VT->Specializations.push_back(TS); auto& TAL = VTS->getTemplateArgs(); - if (auto TSI = VTS->getTypeAsWritten()) + if (auto TSI = VTS->getTypeSourceInfo()) { auto TL = TSI->getTypeLoc(); auto TSL = TL.getAs(); @@ -2812,11 +2838,9 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL, bool if (TS->isSugared()) TST->desugared = GetQualifiedType(TS->getCanonicalTypeInternal(), TL); - TemplateArgumentList TArgs(TemplateArgumentList::OnStack, TS->template_arguments()); - if (!LocValid) { - TST->Arguments = WalkTemplateArgumentList(&TArgs, (TemplateSpecializationTypeLoc*)nullptr); + TST->Arguments = WalkTemplateArgumentList(TS->template_arguments(), (TemplateSpecializationTypeLoc*)nullptr); Ty = TST; break; } @@ -2840,21 +2864,21 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL, bool case TypeLoc::DependentTemplateSpecialization: { DependentTemplateSpecializationTypeLoc TSpecTL = TL->getAs(); - TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL); + TST->Arguments = WalkTemplateArgumentList(TS->template_arguments(), &TSpecTL); Ty = TST; break; } case TypeLoc::TemplateSpecialization: { TemplateSpecializationTypeLoc TSpecTL = TL->getAs(); - TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL); + TST->Arguments = WalkTemplateArgumentList(TS->template_arguments(), &TSpecTL); Ty = TST; break; } case TypeLoc::TemplateTypeParm: { TemplateTypeParmTypeLoc TTPTL = TL->getAs(); - TST->Arguments = WalkTemplateArgumentList(&TArgs, (TemplateSpecializationTypeLoc*)nullptr); + TST->Arguments = WalkTemplateArgumentList(TS->template_arguments(), (TemplateSpecializationTypeLoc*)nullptr); break; } default: @@ -2873,11 +2897,9 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL, bool if (TS->isSugared()) TST->desugared = GetQualifiedType(TS->getCanonicalTypeInternal(), TL); - TemplateArgumentList TArgs(TemplateArgumentList::OnStack, TS->template_arguments()); - if (!LocValid) { - TST->Arguments = WalkTemplateArgumentList(&TArgs, (DependentTemplateSpecializationTypeLoc*)nullptr); + TST->Arguments = WalkTemplateArgumentList(TS->template_arguments(), (DependentTemplateSpecializationTypeLoc*)nullptr); Ty = TST; break; } @@ -2901,18 +2923,18 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL, bool case TypeLoc::DependentTemplateSpecialization: { DependentTemplateSpecializationTypeLoc TSpecTL = TL->getAs(); - TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL); + TST->Arguments = WalkTemplateArgumentList(TS->template_arguments(), &TSpecTL); break; } case TypeLoc::TemplateSpecialization: { TemplateSpecializationTypeLoc TSpecTL = TL->getAs(); - TST->Arguments = WalkTemplateArgumentList(&TArgs, &TSpecTL); + TST->Arguments = WalkTemplateArgumentList(TS->template_arguments(), &TSpecTL); break; } case TypeLoc::TemplateTypeParm: { - TST->Arguments = WalkTemplateArgumentList(&TArgs, (DependentTemplateSpecializationTypeLoc*)nullptr); + TST->Arguments = WalkTemplateArgumentList(TS->template_arguments(), (DependentTemplateSpecializationTypeLoc*)nullptr); break; } default: @@ -3510,7 +3532,7 @@ void Parser::WalkFunction(const clang::FunctionDecl* FD, Function* F) F->isConstExpr = FD->isConstexpr(); F->isVariadic = FD->isVariadic(); F->isDependent = FD->isDependentContext(); - F->isPure = FD->isPure(); + F->isPure = FD->isPureVirtual(); F->isDeleted = FD->isDeleted(); F->isDefaulted = FD->isDefaulted(); SetBody(FD, F); @@ -4476,7 +4498,6 @@ Declaration* Parser::WalkDeclaration(const clang::Decl* D) break; } case Decl::BuiltinTemplate: - case Decl::ClassScopeFunctionSpecialization: case Decl::PragmaComment: case Decl::PragmaDetectMismatch: case Decl::Empty: @@ -4614,31 +4635,31 @@ void Parser::SetupLLVMCodegen() } bool Parser::SetupSourceFiles(const std::vector& SourceFiles, - std::vector& FileEntries) + std::vector& FileEntries) { - // Check that the file is reachable. - clang::ConstSearchDirIterator* Dir = 0; - llvm::ArrayRef> Includers; + clang::ConstSearchDirIterator* Dir = nullptr; + llvm::ArrayRef> EmptyIncluders; for (const auto& SourceFile : SourceFiles) { - auto FileEntry = c->getPreprocessor().getHeaderSearchInfo().LookupFile(SourceFile, - clang::SourceLocation(), /*isAngled*/ true, - nullptr, Dir, Includers, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); + auto FileEntry = c->getPreprocessor().getHeaderSearchInfo().LookupFile( + SourceFile, + clang::SourceLocation(), + /*isAngled*/ true, + nullptr, Dir, + EmptyIncluders, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); if (!FileEntry) return false; - FileEntries.push_back(&FileEntry.getPointer()->getFileEntry()); + FileEntries.push_back(FileEntry); } - // Create a virtual file that includes the header. This gets rid of some - // Clang warnings about parsing an header file as the main file. - std::string source; for (const auto& SourceFile : SourceFiles) { - source += "#include \"" + SourceFile + "\"" + "\n"; + source += "#include \"" + SourceFile + "\"\n"; } source += "\0"; @@ -4652,7 +4673,7 @@ bool Parser::SetupSourceFiles(const std::vector& SourceFiles, class SemaConsumer : public clang::SemaConsumer { public: - SemaConsumer(Parser& parser, std::vector& entries) + SemaConsumer(Parser& parser, std::vector& entries) : Parser(parser) , FileEntries(entries) { @@ -4662,7 +4683,7 @@ class SemaConsumer : public clang::SemaConsumer private: Parser& Parser; - std::vector& FileEntries; + std::vector& FileEntries; }; void SemaConsumer::HandleTranslationUnit(clang::ASTContext& Ctx) @@ -4675,7 +4696,7 @@ void SemaConsumer::HandleTranslationUnit(clang::ASTContext& Ctx) Parser.HandleDeclaration(TU, Unit); if (Unit->originalPtr == nullptr) - Unit->originalPtr = (void*)FileEntry; + Unit->originalPtr = (void*)&FileEntry->getFileEntry(); Parser.WalkAST(TU); } @@ -4695,7 +4716,7 @@ ParserResult* Parser::Parse(const std::vector& SourceFiles) Setup(); SetupLLVMCodegen(); - std::vector FileEntries; + std::vector FileEntries; if (!SetupSourceFiles(SourceFiles, FileEntries)) { res->kind = ParserResultKind::FileNotFound; @@ -4829,7 +4850,7 @@ ParserResultKind Parser::ParseSharedLib(const std::string& File, for (const auto& ImportedSymbol : COFFObjectFile->import_directories()) { llvm::StringRef Name; - if (!ImportedSymbol.getName(Name) && (Name.endswith(".dll") || Name.endswith(".DLL"))) + if (!ImportedSymbol.getName(Name) && (Name.ends_with(".dll") || Name.ends_with(".DLL"))) NativeLib->Dependencies.push_back(Name.str()); } diff --git a/src/CppParser/Parser.h b/src/CppParser/Parser.h index 08f6e6799..d8db6eccb 100644 --- a/src/CppParser/Parser.h +++ b/src/CppParser/Parser.h @@ -70,7 +70,7 @@ namespace CppSharp { namespace CppParser { void SetupLLVMCodegen(); bool SetupSourceFiles(const std::vector& SourceFiles, - std::vector& FileEntries); + std::vector& FileEntries); bool IsSupported(const clang::NamedDecl* ND); bool IsSupported(const clang::CXXMethodDecl* MD); @@ -114,6 +114,8 @@ namespace CppSharp { namespace CppParser { WalkVarTemplatePartialSpecialization(const clang::VarTemplatePartialSpecializationDecl* VTS); template std::vector WalkTemplateArgumentList(const clang::TemplateArgumentList* TAL, TypeLoc* TSTL); + template + std::vector WalkTemplateArgumentList(llvm::ArrayRef TAL,TypeLoc* TSTL); std::vector WalkTemplateArgumentList(const clang::TemplateArgumentList* TAL, const clang::ASTTemplateArgumentListInfo* TSTL); void WalkVTable(const clang::CXXRecordDecl* RD, AST::Class* C); AST::QualifiedType GetQualifiedType(clang::QualType qual, const clang::TypeLoc* TL = 0); From 2d59b825f15dc89b6278b9a05f82b1aef8afba09 Mon Sep 17 00:00:00 2001 From: Christopher Franzwa Date: Wed, 16 Jul 2025 14:55:32 -0400 Subject: [PATCH 2/3] Fixes link errors. Fixes for failing tests --- build/LLVM.lua | 7 ++++++- build/llvm/LLVM.lua | 3 --- src/CppParser/Comments.cpp | 14 +++++++------- src/CppParser/Parser.cpp | 24 +++++++++++++++++++----- 4 files changed, 32 insertions(+), 16 deletions(-) diff --git a/build/LLVM.lua b/build/LLVM.lua index d68f01933..420136d17 100644 --- a/build/LLVM.lua +++ b/build/LLVM.lua @@ -137,7 +137,8 @@ function SetupLLVMLibs() filter { "toolset:msc*" } links { "version" } - + links { "ntdll"} + filter {} if LLVMDirPerConfiguration then @@ -164,6 +165,7 @@ function SetupLLVMLibs() links { + "clangAPINotes", "clangFrontend", "clangDriver", "clangSerialization", @@ -185,8 +187,10 @@ function SetupLLVMLibs() "LLVMPasses", "LLVMObjCARCOpts", "LLVMLibDriver", + "LLVMFrontendOffloading", "LLVMFrontendHLSL", "LLVMFrontendOpenMP", + "LLVMHipStdPar", "LLVMOption", "LLVMCoverage", "LLVMCoroutines", @@ -201,6 +205,7 @@ function SetupLLVMLibs() "LLVMAArch64Disassembler", "LLVMAArch64Info", "LLVMAArch64Utils", + "LLVMFrontendDriver", "LLVMipo", "LLVMInstrumentation", "LLVMVectorize", diff --git a/build/llvm/LLVM.lua b/build/llvm/LLVM.lua index c1e818f1e..758a8fb02 100644 --- a/build/llvm/LLVM.lua +++ b/build/llvm/LLVM.lua @@ -260,7 +260,6 @@ function cmake(gen, conf, builddir, options) .. ' -DLLVM_INCLUDE_TESTS=false' .. ' -DLLVM_ENABLE_LIBEDIT=false' .. ' -DLLVM_ENABLE_LIBXML2=false' - .. ' -DLLVM_ENABLE_HIP=false' .. ' -DLLVM_ENABLE_MLGO=false' .. ' -DLLVM_ENABLE_TERMINFO=false' .. ' -DLLVM_ENABLE_ZLIB=false' @@ -376,8 +375,6 @@ function cmake(gen, conf, builddir, options) .. ' -DCLANG_INCLUDE_TESTS=false' .. ' -DCLANG_TOOL_AMDGPU_ARCH_BUILD=false' .. ' -DCLANG_TOOL_APINOTES_TEST_BUILD=false' - .. ' -DCLANG_ENABLE_HIP=false' - .. ' -DCLANG_ENABLE_API_NOTES=false' .. ' -DCLANG_TOOL_ARCMT_TEST_BUILD=false' .. ' -DCLANG_TOOL_CLANG_CHECK_BUILD=false' .. ' -DCLANG_TOOL_CLANG_DIFF_BUILD=false' diff --git a/src/CppParser/Comments.cpp b/src/CppParser/Comments.cpp index 65ba01dc2..28753903c 100644 --- a/src/CppParser/Comments.cpp +++ b/src/CppParser/Comments.cpp @@ -98,13 +98,6 @@ static Comment* ConvertCommentBlock(clang::comments::Comment* C, clang::Compiler for (auto I = CK->child_begin(), E = CK->child_end(); I != E; ++I) FC->Blocks.push_back(static_cast(ConvertCommentBlock(*I, CI))); } - else if (auto CK = dyn_cast(C)) - { - auto BC = new BlockCommandComment(); - _Comment = BC; - HandleBlockCommand(CK, BC); - BC->paragraphComment = static_cast(ConvertCommentBlock(CK->getParagraph(), CI)); - } else if (auto CK = dyn_cast(C)) { auto PC = new ParamCommandComment(); @@ -137,6 +130,13 @@ static Comment* ConvertCommentBlock(clang::comments::Comment* C, clang::Compiler _Comment = VL; VL->text = CK->getText().str(); } + else if (auto CK = dyn_cast(C)) + { + auto BC = new BlockCommandComment(); + _Comment = BC; + HandleBlockCommand(CK, BC); + BC->paragraphComment = static_cast(ConvertCommentBlock(CK->getParagraph(), CI)); + } else if (auto CK = dyn_cast(C)) { auto PC = new ParagraphComment(); diff --git a/src/CppParser/Parser.cpp b/src/CppParser/Parser.cpp index 90e5fa16c..326fb7544 100644 --- a/src/CppParser/Parser.cpp +++ b/src/CppParser/Parser.cpp @@ -1396,9 +1396,15 @@ Parser::WalkClassTemplateSpecialization(const clang::ClassTemplateSpecialization CT->Specializations.push_back(TS); auto& TAL = CTS->getTemplateArgs(); - TemplateSpecializationTypeLoc TSL; - - TS->Arguments = WalkTemplateArgumentList(&TAL, nullptr); + auto TSI = CTS->getTemplateArgsAsWritten(); + if (TSI) + { + TS->Arguments = WalkTemplateArgumentList(&TAL, TSI); + } + else + { + TS->Arguments = WalkTemplateArgumentList(&TAL, (TemplateSpecializationTypeLoc*)0); + } if (CTS->isCompleteDefinition()) { @@ -1442,8 +1448,16 @@ Parser::WalkClassTemplatePartialSpecialization(const clang::ClassTemplatePartial TS->specializationKind = WalkTemplateSpecializationKind(CTS->getSpecializationKind()); CT->Specializations.push_back(TS); - const TemplateArgumentList& TAL = CTS->getTemplateArgs(); - WalkTemplateArgumentList(&TAL, nullptr); + auto& TAL = CTS->getTemplateArgs(); + auto TSI = CTS->getTemplateArgsAsWritten(); + if (TSI) + { + TS->Arguments = WalkTemplateArgumentList(&TAL, TSI); + } + else + { + TS->Arguments = WalkTemplateArgumentList(&TAL, (TemplateSpecializationTypeLoc*)0); + } if (CTS->isCompleteDefinition()) { From c38b81730dbe64b1f5a44f7e62e889b26ee393ab Mon Sep 17 00:00:00 2001 From: Christopher Franzwa Date: Wed, 16 Jul 2025 20:59:55 -0400 Subject: [PATCH 3/3] Fixes failing macOS lib test --- src/CppParser/Parser.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/CppParser/Parser.cpp b/src/CppParser/Parser.cpp index 326fb7544..ca6b5184f 100644 --- a/src/CppParser/Parser.cpp +++ b/src/CppParser/Parser.cpp @@ -4892,12 +4892,18 @@ ParserResultKind Parser::ParseSharedLib(const std::string& File, // see https://bugs.llvm.org/show_bug.cgi?id=44433 for (const auto& Symbol : MachOObjectFile->symbols()) { - if (Symbol.getName().takeError() || Symbol.getFlags().takeError()) + auto NameOrErr = Symbol.getName(); + auto FlagsOrErr = Symbol.getFlags(); + + if (!NameOrErr || !FlagsOrErr) return ParserResultKind::Error; - if ((Symbol.getFlags().get() & llvm::object::BasicSymbolRef::Flags::SF_Exported) && - !(Symbol.getFlags().get() & llvm::object::BasicSymbolRef::Flags::SF_Undefined)) - NativeLib->Symbols.push_back(Symbol.getName().get().str()); + auto Flags = *FlagsOrErr; + if ((Flags & llvm::object::BasicSymbolRef::SF_Exported) && + !(Flags & llvm::object::BasicSymbolRef::SF_Undefined)) + { + NativeLib->Symbols.push_back(NameOrErr->str()); + } } return ParserResultKind::Success; }