diff --git a/.github/workflows/llvm-win.yml b/.github/workflows/llvm-win.yml index 455c4f4dcf..43b9891fba 100644 --- a/.github/workflows/llvm-win.yml +++ b/.github/workflows/llvm-win.yml @@ -9,8 +9,8 @@ jobs: fail-fast: false matrix: config: - - { os: windows-2022, platform: x86, vs: 2022 } - - { os: windows-2022, platform: x64, vs: 2022 } + - { os: windows-2022, platform: x86, vs: "Program Files/Microsoft Visual Studio/2022" } + - { os: windows-2022, platform: x64, vs: "Program Files/Microsoft Visual Studio/2022" } runs-on: ${{ matrix.config.os }} @@ -35,7 +35,7 @@ jobs: - name: Environment shell: cmd run: | - call "C:\Program Files\Microsoft Visual Studio\%VS_VERSION%\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" %PLATFORM% + call "C:\%VS_VERSION%\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" %PLATFORM% :: Loop over all environment variables and make them global using set-env. :: See: https://stackoverflow.com/a/39184941 setlocal diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6756de7613..d26b7adcb0 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -9,15 +9,16 @@ jobs: fail-fast: false matrix: config: - - { os: ubuntu-20.04, platform: x64, cxx: g++-10, cc: gcc-10 } + - { os: ubuntu-22.04, platform: x64, cxx: g++-11, cc: gcc-11 } - { os: macos-11, platform: x64, cxx: clang++, cc: clang } - - { os: windows-2019, platform: x64, vs: msvc } + - { os: windows-2022, platform: x64, vs: "Program Files/Microsoft Visual Studio/2022" } runs-on: ${{ matrix.config.os }} env: CC: ${{ matrix.config.cc }} CXX: ${{ matrix.config.cxx }} + VS_VERSION: ${{ matrix.config.vs }} PLATFORM: ${{ matrix.config.platform }} DOTNET_NOLOGO: true DOTNET_CLI_TELEMETRY_OPTOUT: true @@ -38,7 +39,7 @@ jobs: - name: Environment if: matrix.config.vs shell: bash - run: echo "/c/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/MSBuild/Current/Bin" >> $GITHUB_PATH + run: echo "/c/$VS_VERSION/Enterprise/MSBuild/Current/Bin" >> $GITHUB_PATH - name: Setup shell: bash diff --git a/Directory.Build.props b/Directory.Build.props index 3fe84b36b1..e6c25f85f5 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -52,7 +52,6 @@ - \ No newline at end of file diff --git a/build/LLVM.lua b/build/LLVM.lua index d2781b7451..86fa1be6b3 100644 --- a/build/LLVM.lua +++ b/build/LLVM.lua @@ -42,6 +42,7 @@ function SetupLLVMIncludes() includedirs { path.join(LLVMRootDirDebug, "include"), + path.join(LLVMRootDirDebug, "llvm/include"), path.join(LLVMRootDirDebug, "lld/include"), path.join(LLVMRootDirDebug, "clang/include"), path.join(LLVMRootDirDebug, "clang/lib"), @@ -53,6 +54,7 @@ function SetupLLVMIncludes() includedirs { path.join(LLVMRootDirRelease, "include"), + path.join(LLVMRootDirRelease, "llvm/include"), path.join(LLVMRootDirRelease, "lld/include"), path.join(LLVMRootDirRelease, "clang/include"), path.join(LLVMRootDirRelease, "clang/lib"), @@ -64,6 +66,7 @@ function SetupLLVMIncludes() includedirs { path.join(LLVMRootDir, "include"), + path.join(LLVMRootDir, "llvm/include"), path.join(LLVMRootDir, "lld/include"), path.join(LLVMRootDir, "clang/include"), path.join(LLVMRootDir, "clang/lib"), @@ -144,18 +147,22 @@ function SetupLLVMLibs() "clangCodeGen", "clangParse", "clangSema", + "clangSupport", "clangAnalysis", "clangEdit", "clangAST", "clangLex", "clangBasic", "clangIndex", + "clangASTMatchers", + "LLVMWindowsDriver", "LLVMWindowsManifest", "LLVMDebugInfoPDB", "LLVMLTO", "LLVMPasses", "LLVMObjCARCOpts", "LLVMLibDriver", + "LLVMFrontendHLSL", "LLVMFrontendOpenMP", "LLVMOption", "LLVMCoverage", @@ -170,6 +177,7 @@ function SetupLLVMLibs() "LLVMVectorize", "LLVMLinker", "LLVMIRReader", + "LLVMIRPrinter", "LLVMAsmParser", "LLVMMCDisassembler", "LLVMCFGuard", @@ -178,7 +186,9 @@ function SetupLLVMLibs() "LLVMAsmPrinter", "LLVMDebugInfoDWARF", "LLVMCodeGen", + "LLVMCodeGenTypes", "LLVMTarget", + "LLVMTargetParser", "LLVMScalarOpts", "LLVMInstCombine", "LLVMAggressiveInstCombine", @@ -202,7 +212,8 @@ function SetupLLVMLibs() "lldCommon", "lldCOFF", "lldELF", - "lldMachO" + "lldMachO", + "lldMinGW" } filter(c) diff --git a/build/build.sh b/build/build.sh index 6f7a086fee..5cd81557a2 100755 --- a/build/build.sh +++ b/build/build.sh @@ -2,7 +2,7 @@ set -e builddir=$(cd "$(dirname "$0")"; pwd) platform=x64 -vs=vs2019 +vs=vs2022 configuration=Release build_only=false ci=false @@ -104,18 +104,26 @@ download_premake() { premake_dir="$builddir/premake" premake_filename=premake5 + premake_archive_ext=tar.gz if [ $oshost = "windows" ]; then premake_filename=$premake_filename.exe + premake_archive_ext=zip fi premake_path=$premake_dir/$premake_filename if ! [ -f "$premake_path" ]; then echo "Downloading and unpacking Premake..." - premake_url=https://github.com/InteropAlliance/premake-core/releases/download/latest/premake-$oshost-$platform.zip + premake_version=5.0.0-beta2 + premake_archive=premake-$premake_version-$oshost.$premake_archive_ext + premake_url=https://github.com/premake/premake-core/releases/download/v$premake_version/$premake_archive curl -L -O $premake_url - unzip premake-$oshost-$platform.zip $premake_filename -d "$premake_dir" + if [ $oshost = "windows" ]; then + unzip $premake_archive $premake_filename -d "$premake_dir" + else + tar -xf $premake_archive -C "$premake_dir" ./$premake_filename + fi chmod +x "$premake_path" - rm premake-$oshost-$platform.zip + rm $premake_archive fi } diff --git a/build/llvm/LLVM-commit b/build/llvm/LLVM-commit index 8a0cb18633..1f1a216a13 100644 --- a/build/llvm/LLVM-commit +++ b/build/llvm/LLVM-commit @@ -1 +1 @@ -791523bae6153b13bb41ba05c9fc89e502cc4a1a \ No newline at end of file +6eb36aed86ea276695697093eb8136554c29286b \ No newline at end of file diff --git a/build/llvm/LLVM.lua b/build/llvm/LLVM.lua index 30a3943314..f375b39e92 100644 --- a/build/llvm/LLVM.lua +++ b/build/llvm/LLVM.lua @@ -251,6 +251,7 @@ function cmake(gen, conf, builddir, options) .. ' -DLLVM_ENABLE_LIBXML2=false' .. ' -DLLVM_ENABLE_TERMINFO=false' .. ' -DLLVM_ENABLE_ZLIB=false' + .. ' -DLLVM_ENABLE_ZSTD=false' .. ' -DLLVM_INCLUDE_DOCS=false' .. ' -DLLVM_INCLUDE_EXAMPLES=false' .. ' -DLLVM_TARGETS_TO_BUILD="X86"' @@ -370,6 +371,8 @@ function cmake(gen, conf, builddir, options) .. ' -DCLANG_TOOL_CLANG_FUZZER_BUILD=false' .. ' -DCLANG_TOOL_CLANG_IMPORT_TEST_BUILD=false' .. ' -DCLANG_TOOL_CLANG_NVLINK_WRAPPER_BUILD=false' + .. ' -DCLANG_TOOL_CLANG_LINKER_WRAPPER_BUILD=false' + .. ' -DCLANG_TOOL_CLANG_OFFLOAD_PACKAGER_BUILD=false' .. ' -DCLANG_TOOL_CLANG_OFFLOAD_BUNDLER_BUILD=false' .. ' -DCLANG_TOOL_CLANG_OFFLOAD_WRAPPER_BUILD=false' .. ' -DCLANG_TOOL_CLANG_REFACTOR_BUILD=false' @@ -456,7 +459,7 @@ function package_llvm(conf, llvm_base, llvm_build) if os.isdir(out) then os.rmdir(out) end os.mkdir(out) - os.copydir(llvm_base .. "/llvm/include", out .. "/include") + os.copydir(llvm_base .. "/llvm/include", out .. "/llvm/include") os.copydir(llvm_base .. "/lld/include", out .. "/lld/include") os.copydir(llvm_build .. "/include", out .. "/build/include") @@ -483,12 +486,10 @@ function package_llvm(conf, llvm_base, llvm_build) local out_lib_dir = out .. "/build/lib" if os.ishost("windows") then os.rmfiles(out_lib_dir, "clang*ARC*.lib") - os.rmfiles(out_lib_dir, "clang*Matchers*.lib") os.rmfiles(out_lib_dir, "clang*Rewrite*.lib") os.rmfiles(out_lib_dir, "clang*StaticAnalyzer*.lib") else os.rmfiles(out_lib_dir, "libclang*ARC*.a") - os.rmfiles(out_lib_dir, "libclang*Matchers*.a") os.rmfiles(out_lib_dir, "libclang*Rewrite*.a") os.rmfiles(out_lib_dir, "libclang*StaticAnalyzer*.a") end diff --git a/src/Core/Toolchains/MSVCToolchain.cs b/src/Core/Toolchains/MSVCToolchain.cs index 605825c31f..91964cd486 100644 --- a/src/Core/Toolchains/MSVCToolchain.cs +++ b/src/Core/Toolchains/MSVCToolchain.cs @@ -16,6 +16,7 @@ public enum VisualStudioVersion VS2015 = 14, VS2017 = 15, VS2019 = 16, + VS2022 = 17, Latest, } @@ -67,9 +68,12 @@ public static Version GetCLVersion(VisualStudioVersion vsVersion) clVersion = new Version { Major = 19, Minor = 10 }; break; case VisualStudioVersion.VS2019: - case VisualStudioVersion.Latest: clVersion = new Version { Major = 19, Minor = 20 }; break; + case VisualStudioVersion.VS2022: + case VisualStudioVersion.Latest: + clVersion = new Version { Major = 19, Minor = 30 }; + break; default: throw new Exception("Unknown Visual Studio version"); } diff --git a/src/CppParser/CppParser.cpp b/src/CppParser/CppParser.cpp index 0066458166..d6c1f7b36a 100644 --- a/src/CppParser/CppParser.cpp +++ b/src/CppParser/CppParser.cpp @@ -7,7 +7,7 @@ #include "CppParser.h" #include "Parser.h" -#include +#include #include namespace CppSharp { namespace CppParser { diff --git a/src/CppParser/Link.cpp b/src/CppParser/Link.cpp index 3514256d14..46d066218f 100644 --- a/src/CppParser/Link.cpp +++ b/src/CppParser/Link.cpp @@ -11,6 +11,11 @@ #include #include +LLD_HAS_DRIVER(coff) +LLD_HAS_DRIVER(elf) +LLD_HAS_DRIVER(mingw) +LLD_HAS_DRIVER(macho) + using namespace CppSharp::CppParser; bool Parser::Link(const std::string& File, const CppLinkerOptions* LinkerOptions) @@ -69,7 +74,7 @@ bool Parser::LinkWindows(const CppLinkerOptions* LinkerOptions, std::vector LibraryPaths; LibraryPaths.push_back("-libpath:" + TC.getSubDirectoryPath( - clang::driver::toolchains::MSVCToolChain::SubDirectoryType::Lib)); + llvm::SubDirectoryType::Lib)); std::string CRTPath; if (TC.getUniversalCRTLibraryPath(Args, CRTPath)) LibraryPaths.push_back("-libpath:" + CRTPath); @@ -100,7 +105,7 @@ bool Parser::LinkWindows(const CppLinkerOptions* LinkerOptions, std::string Out("-out:" + std::string(Output)); args.push_back(Out.data()); - return lld::coff::link(args, false, outs(), errs()); + return lld::coff::link(args, outs(), errs(), /*exitEarly=*/false, /*disableOutput=*/false); #else return false; #endif @@ -141,7 +146,7 @@ bool Parser::LinkELF(const CppLinkerOptions* LinkerOptions, std::string Out(Output); args.push_back(Out.data()); - return lld::elf::link(args, false, outs(), errs()); + return lld::elf::link(args, outs(), errs(), /*exitEarly=*/false, /*disableOutput=*/false); #else return false; #endif @@ -182,7 +187,7 @@ bool Parser::LinkMachO(const CppLinkerOptions* LinkerOptions, std::string Out(Output); args.push_back(Out.data()); - return lld::macho::link(args, false, outs(), errs()); + return lld::macho::link(args, outs(), errs(), /*exitEarly=*/false, /*disableOutput=*/false); #else return false; #endif diff --git a/src/CppParser/ParseExpr.cpp b/src/CppParser/ParseExpr.cpp index 4587d73fdd..27639a3d48 100644 --- a/src/CppParser/ParseExpr.cpp +++ b/src/CppParser/ParseExpr.cpp @@ -223,7 +223,7 @@ AST::Expr* Parser::WalkExpression(const clang::Expr* Expr) _S->length = S->getLength(); _S->charByteWidth = S->getCharByteWidth(); _S->kind = (StringLiteral::StringKind) S->getKind(); - _S->isAscii = S->isAscii(); + _S->isAscii = S->isOrdinary(); _S->isWide = S->isWide(); _S->isUTF8 = S->isUTF8(); _S->isUTF16 = S->isUTF16(); @@ -400,7 +400,7 @@ AST::Expr* Parser::WalkExpression(const clang::Expr* Expr) _S->calleeDecl = static_cast(WalkDeclaration(S->getCalleeDecl())); _S->directCallee = static_cast(WalkDeclaration(S->getDirectCallee())); _S->numArgs = S->getNumArgs(); - _S->numCommas = S->getNumCommas(); + _S->numCommas = 0; // Removed from Clang _S->builtinCallee = S->getBuiltinCallee(); _S->isCallToStdMove = S->isCallToStdMove(); for (auto _E : S->arguments()) @@ -1172,7 +1172,7 @@ AST::Expr* Parser::WalkExpression(const clang::Expr* Expr) _S->calleeDecl = static_cast(WalkDeclaration(S->getCalleeDecl())); _S->directCallee = static_cast(WalkDeclaration(S->getDirectCallee())); _S->numArgs = S->getNumArgs(); - _S->numCommas = S->getNumCommas(); + _S->numCommas = 0; // Removed from Clang _S->builtinCallee = S->getBuiltinCallee(); _S->isCallToStdMove = S->isCallToStdMove(); for (auto _E : S->arguments()) @@ -1207,7 +1207,7 @@ AST::Expr* Parser::WalkExpression(const clang::Expr* Expr) _S->calleeDecl = static_cast(WalkDeclaration(S->getCalleeDecl())); _S->directCallee = static_cast(WalkDeclaration(S->getDirectCallee())); _S->numArgs = S->getNumArgs(); - _S->numCommas = S->getNumCommas(); + _S->numCommas = 0; // Removed from Clang _S->builtinCallee = S->getBuiltinCallee(); _S->isCallToStdMove = S->isCallToStdMove(); for (auto _E : S->arguments()) @@ -1241,7 +1241,7 @@ AST::Expr* Parser::WalkExpression(const clang::Expr* Expr) _S->calleeDecl = static_cast(WalkDeclaration(S->getCalleeDecl())); _S->directCallee = static_cast(WalkDeclaration(S->getDirectCallee())); _S->numArgs = S->getNumArgs(); - _S->numCommas = S->getNumCommas(); + _S->numCommas = 0; // Removed from Clang _S->builtinCallee = S->getBuiltinCallee(); _S->isCallToStdMove = S->isCallToStdMove(); for (auto _E : S->arguments()) @@ -1391,7 +1391,7 @@ AST::Expr* Parser::WalkExpression(const clang::Expr* Expr) _S->calleeDecl = static_cast(WalkDeclaration(S->getCalleeDecl())); _S->directCallee = static_cast(WalkDeclaration(S->getDirectCallee())); _S->numArgs = S->getNumArgs(); - _S->numCommas = S->getNumCommas(); + _S->numCommas = 0; // Removed from Clang _S->builtinCallee = S->getBuiltinCallee(); _S->isCallToStdMove = S->isCallToStdMove(); for (auto _E : S->arguments()) @@ -1850,7 +1850,7 @@ AST::Expr* Parser::WalkExpression(const clang::Expr* Expr) _S->operatorDelete = static_cast(WalkDeclaration(S->getOperatorDelete())); _S->allocatedType = GetQualifiedType(S->getAllocatedType()); _S->isArray = S->isArray(); - _S->arraySize = static_cast(WalkExpression(S->getArraySize().getValue())); + _S->arraySize = static_cast(WalkExpression(S->getArraySize().value())); _S->numPlacementArgs = S->getNumPlacementArgs(); _S->isParenTypeId = S->isParenTypeId(); _S->isGlobalNew = S->isGlobalNew(); diff --git a/src/CppParser/ParseStmt.cpp b/src/CppParser/ParseStmt.cpp index 31f4703eec..c7eed096f6 100644 --- a/src/CppParser/ParseStmt.cpp +++ b/src/CppParser/ParseStmt.cpp @@ -356,7 +356,7 @@ AST::Stmt* Parser::WalkStatement(const clang::Stmt* Stmt) _S->allocate = static_cast(WalkExpression(S->getAllocate())); _S->deallocate = static_cast(WalkExpression(S->getDeallocate())); _S->returnValueInit = static_cast(WalkExpression(S->getReturnValueInit())); - _S->resultDecl = static_cast(WalkStatement(S->getResultDecl())); + _S->resultDecl = static_cast(WalkStatement(S->getReturnValue())); _S->returnStmt = static_cast(WalkStatement(S->getReturnStmt())); _S->returnStmtOnAllocFailure = static_cast(WalkStatement(S->getReturnStmtOnAllocFailure())); _Stmt = _S; diff --git a/src/CppParser/Parser.cpp b/src/CppParser/Parser.cpp index 4e55c574db..85be06a181 100644 --- a/src/CppParser/Parser.cpp +++ b/src/CppParser/Parser.cpp @@ -13,7 +13,7 @@ #include "ELFDumper.h" #include "APValuePrinter.h" -#include +#include #include #include #include @@ -880,11 +880,9 @@ static clang::CXXRecordDecl* GetCXXRecordDeclFromTemplateName(const clang::Templ switch (Name.getKind()) { case clang::TemplateName::Template: - return dyn_cast( - Name.getAsTemplateDecl()->getTemplatedDecl()); + return dyn_cast(Name.getAsTemplateDecl()->getTemplatedDecl()); case clang::TemplateName::QualifiedTemplate: - return dyn_cast( - Name.getAsQualifiedTemplateName()->getTemplateDecl()->getTemplatedDecl()); + return GetCXXRecordDeclFromTemplateName(Name.getAsQualifiedTemplateName()->getUnderlyingTemplate()); default: assert(0 && "Unknown template name kind"); return nullptr; @@ -902,7 +900,7 @@ static clang::CXXRecordDecl* GetCXXRecordDeclFromBaseType(const clang::QualType& else if (auto Injected = Ty->getAs()) return Injected->getDecl(); - assert("Could not get base CXX record from type"); + assert(0 && "Could not get base CXX record from type"); return nullptr; } @@ -2604,7 +2602,7 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL, { auto TO = Type->getAs(); - Ty = WalkType(TO->getUnderlyingType()); + Ty = WalkType(TO->getUnmodifiedType()); break; } case clang::Type::TypeOfExpr: @@ -2666,8 +2664,7 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL, TSTL = &TSpecTL; } - ArrayRef TSArgs(TS->getArgs(), TS->getNumArgs()); - TemplateArgumentList TArgs(TemplateArgumentList::OnStack, TSArgs); + TemplateArgumentList TArgs(TemplateArgumentList::OnStack, TS->template_arguments()); TST->Arguments = WalkTemplateArgumentList(&TArgs, TSTL); Ty = TST; @@ -2709,8 +2706,7 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL, TSTL = &TSpecTL; } - ArrayRef TSArgs(TS->getArgs(), TS->getNumArgs()); - TemplateArgumentList TArgs(TemplateArgumentList::OnStack, TSArgs); + TemplateArgumentList TArgs(TemplateArgumentList::OnStack, TS->template_arguments()); TST->Arguments = WalkTemplateArgumentList(&TArgs, TSTL); Ty = TST; @@ -2773,9 +2769,9 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL, auto RepTy = TP->getReplacementType(); TPT->replacement = GetQualifiedType(RepTy, &Next); TPT->replacedParameter = (TemplateParameterType*) - WalkType(clang::QualType(TP->getReplacedParameter(), 0), 0); + WalkType(c->getASTContext().getTypeDeclType(TP->getReplacedParameter()), 0); TPT->replacedParameter->parameter = WalkTypeTemplateParameter( - TP->getReplacedParameter()->getDecl()); + TP->getReplacedParameter()); Ty = TPT; break; @@ -4386,7 +4382,7 @@ void Parser::SetupLLVMCodegen() LLVMModule->setTargetTriple(c->getTarget().getTriple().getTriple()); LLVMModule->setDataLayout(c->getTarget().getDataLayoutString()); - CGM.reset(new clang::CodeGen::CodeGenModule(c->getASTContext(), + CGM.reset(new clang::CodeGen::CodeGenModule(c->getASTContext(), nullptr, c->getHeaderSearchOpts(), c->getPreprocessorOpts(), c->getCodeGenOpts(), *LLVMModule, c->getDiagnostics())); @@ -4397,10 +4393,8 @@ bool Parser::SetupSourceFiles(const std::vector& SourceFiles, std::vector& FileEntries) { // Check that the file is reachable. - const clang::DirectoryLookup *Dir; - llvm::SmallVector< - std::pair, - 0> Includers; + clang::ConstSearchDirIterator *Dir = 0; + llvm::ArrayRef> Includers; for (const auto& SourceFile : SourceFiles) { @@ -4863,8 +4857,7 @@ ParserResult* Parser::Compile(const std::string& File) const llvm::Triple Triple = c->getTarget().getTriple(); llvm::StringRef Dir(llvm::sys::path::parent_path(File)); llvm::SmallString<1024> Object(Dir); - llvm::sys::path::append(Object, - (Triple.isOSWindows() ? "" : "lib") + Stem + ".o"); + llvm::sys::path::append(Object, Stem + ".o"); c->getFrontendOpts().OutputFile = std::string(Object); llvm::LLVMContext context; @@ -4920,8 +4913,8 @@ ParserTargetInfo* Parser::GetTargetInfo() parserTargetInfo->longDoubleWidth = TI.getLongDoubleWidth(); parserTargetInfo->longLongAlign = TI.getLongLongAlign(); parserTargetInfo->longLongWidth = TI.getLongLongWidth(); - parserTargetInfo->pointerAlign = TI.getPointerAlign(0); - parserTargetInfo->pointerWidth = TI.getPointerWidth(0); + parserTargetInfo->pointerAlign = TI.getPointerAlign(clang::LangAS::Default); + parserTargetInfo->pointerWidth = TI.getPointerWidth(clang::LangAS::Default); parserTargetInfo->wCharAlign = TI.getWCharAlign(); parserTargetInfo->wCharWidth = TI.getWCharWidth(); parserTargetInfo->float128Align = TI.getFloat128Align(); diff --git a/src/CppParser/premake5.lua b/src/CppParser/premake5.lua index f744c9fa06..a668f77427 100644 --- a/src/CppParser/premake5.lua +++ b/src/CppParser/premake5.lua @@ -4,6 +4,7 @@ clang_msvc_flags = "/wd4355", "/wd4996", "/wd4624", "/wd4291", "/wd4251", "/wd4141", -- 'inline' : used more than once + "/Zc:preprocessor" -- needed for newer Clang Options.inc (VA_ARGS) } if EnableNativeProjects() then @@ -20,6 +21,9 @@ project "CppSharp.CppParser" linkgroups "On" end + filter "toolset:gcc*" + buildoptions { "-Wno-nonnull" } + filter "toolset:msc*" buildoptions { clang_msvc_flags } diff --git a/src/Generator/Driver.cs b/src/Generator/Driver.cs index 86156c93c5..0751fa1c72 100644 --- a/src/Generator/Driver.cs +++ b/src/Generator/Driver.cs @@ -87,7 +87,6 @@ public void Setup() ValidateOptions(); ParserOptions.Setup(Platform.Host); Context = new BindingContext(Options, ParserOptions); - Context.LinkerOptions.Setup(ParserOptions.TargetTriple, ParserOptions.LanguageVersion); Generator = CreateGeneratorFromKind(Options.GeneratorKind); } diff --git a/src/Generator/Generators/CSharp/CSharpCommentPrinter.cs b/src/Generator/Generators/CSharp/CSharpCommentPrinter.cs index dc7ec6cecd..6f7fe7e26b 100644 --- a/src/Generator/Generators/CSharp/CSharpCommentPrinter.cs +++ b/src/Generator/Generators/CSharp/CSharpCommentPrinter.cs @@ -37,6 +37,7 @@ private static void GetCommentSections(this Comment comment, List
secti blockCommandComment.ParagraphComment.GetCommentSections(sections); break; case CommentCommandKind.Return: + case CommentCommandKind.Returns: sections.Add(new Section(CommentElement.Returns)); blockCommandComment.ParagraphComment.GetCommentSections(sections); break; diff --git a/src/Generator/Passes/GenerateSymbolsPass.cs b/src/Generator/Passes/GenerateSymbolsPass.cs index 385771ae36..cca88acbd2 100644 --- a/src/Generator/Passes/GenerateSymbolsPass.cs +++ b/src/Generator/Passes/GenerateSymbolsPass.cs @@ -63,19 +63,7 @@ private void GenerateSymbols() new[] { module }).SelectMany(d => d.Libraries)) linkerOptions.AddLibraries(library); - using (var result = Parser.ClangParser.Build( - Context.ParserOptions, linkerOptions, path, - Last: remainingCompilationTasks == 1)) - { - if (PrintDiagnostics(result)) - { - compiledLibraries[module] = new CompiledLibrary - { - OutputDir = Options.OutputDir, - Library = module.SymbolsLibraryName - }; - } - } + compiledLibraries[module] = Build(linkerOptions, path, module); } } @@ -83,6 +71,66 @@ private void GenerateSymbols() } } + private CompiledLibrary Build(LinkerOptions linkerOptions, string path, Module module) + { + var useBuiltinToolchain = Platform.IsWindows; + if (useBuiltinToolchain) + { + linkerOptions.Setup(Context.ParserOptions.TargetTriple, Context.ParserOptions.LanguageVersion); + using var result = Parser.ClangParser.Build( + Context.ParserOptions, linkerOptions, path, + Last: remainingCompilationTasks == 1); + + if (!PrintDiagnostics(result)) + return null; + } + else + { + using var result = Parser.ClangParser.Compile(Context.ParserOptions, path); + if (result != null) + { + if (!PrintDiagnostics(result)) + return null; + } + + linkerOptions.Setup(Context.ParserOptions.TargetTriple, Context.ParserOptions.LanguageVersion); + linkerOptions.AddArguments("-L" + Path.GetDirectoryName(path)); + + var objectFile = Path.ChangeExtension(path, "o"); + linkerOptions.AddArguments(objectFile); + + var targetPlatform = Options.Compilation.Platform.GetValueOrDefault(Platform.Host); + var sharedObjectFile = LinkerOptions.GetSharedObjectName(path, targetPlatform); + linkerOptions.AddArguments("-o " + sharedObjectFile); + linkerOptions.SetupLibraryArguments(); + + var linker = LinkerOptions.GetLinkerExecutableName(targetPlatform); + var invocation = linkerOptions.GetLinkerInvocation(); + + Diagnostics.Message($"Linking library {Path.GetFileName(sharedObjectFile)}..."); + if (Options.Verbose) + Diagnostics.Message($"Invoking the linker with: {linker} {invocation}"); + + var outMessage = ProcessHelper.Run( + linker, invocation, out var errorCode, out var errorMessage); + + if (errorCode != 0) + { + Diagnostics.Error($"Linking failed with: {outMessage} {errorMessage}"); + } + else + { + Diagnostics.Message($"Linking success."); + } + } + + return new CompiledLibrary + { + OutputDir = Options.OutputDir, + Library = module.SymbolsLibraryName + }; + } + public override bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecialization specialization) { if (!specialization.IsGenerated || diff --git a/src/Parser/LinkerOptions.cs b/src/Parser/LinkerOptions.cs index 6fab1a24a2..c460487aa8 100644 --- a/src/Parser/LinkerOptions.cs +++ b/src/Parser/LinkerOptions.cs @@ -1,4 +1,8 @@ -using System.Linq; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; namespace CppSharp.Parser { @@ -8,6 +12,8 @@ public LinkerOptions() { } + public static bool UseCompilerDriverAsLinker = true; + public LinkerOptions(LinkerOptions other) { for (uint i = 0; i < other.ArgumentsCount; i++) @@ -45,7 +51,7 @@ public void Setup(string triple, LanguageVersion? languageVersion) AddArguments("-L" + (SystemLibraryPath ?? "/usr/lib/x86_64-linux-gnu")); AddArguments("-lc"); AddArguments("--shared"); - AddArguments("-rpath"); + AddArguments(UseCompilerDriverAsLinker ? "-Wl,-rpath" : "-rpath"); AddArguments("."); break; case TargetPlatform.MacOS: @@ -70,5 +76,153 @@ public void Setup(string triple, LanguageVersion? languageVersion) break; } } + + public void SetupLibraryArguments() + { + for (uint i = 0; i < LibraryDirsCount; i++) + { + var dir = GetLibraryDirs(i); + AddArguments("-L" + dir); + } + + for (uint i = 0; i < LibrariesCount; i++) + { + var lib = GetLibraries(i); + AddArguments("-l" + lib); + } + } + + public string GetLinkerInvocation() + { + var args = new List(); + for (uint i = 0; i < ArgumentsCount; i++) + { + var arg = GetArguments(i); + args.Add(arg); + } + + return string.Join(" ", args); + } + + public static string GetSharedObjectName(string path, TargetPlatform targetPlatform) + { + var prefix = GetPlatformSharedObjectPrefix(targetPlatform); + var extension = GetPlatformSharedObjectExtension(targetPlatform); + var name = $"{prefix}{Path.GetFileNameWithoutExtension(path)}.{extension}"; + return Path.Join(Path.GetDirectoryName(path), name); + } + + public static string GetLinkerExecutableName(TargetPlatform targetPlatform) + { + // If LLD exists on the PATH, then prefer it. If not, use the host linker. + var lldLinkerExe = GetLLDLinkerExecutableName(targetPlatform); + return (ExistsOnPath(lldLinkerExe) && !UseCompilerDriverAsLinker) ? + lldLinkerExe : GetPlatformLinkerExecutableName(targetPlatform); + } + + public static string GetPlatformSharedObjectPrefix(TargetPlatform targetPlatform) + { + switch (targetPlatform) + { + case TargetPlatform.Windows: + return ""; + case TargetPlatform.Linux: + case TargetPlatform.Android: + case TargetPlatform.MacOS: + case TargetPlatform.iOS: + case TargetPlatform.WatchOS: + case TargetPlatform.TVOS: + case TargetPlatform.Emscripten: + return "lib"; + default: + throw new ArgumentOutOfRangeException(nameof(targetPlatform), targetPlatform, null); + } + } + + public static string GetPlatformSharedObjectExtension(TargetPlatform targetPlatform) + { + switch (targetPlatform) + { + case TargetPlatform.Windows: + return "dll"; + case TargetPlatform.Linux: + case TargetPlatform.Android: + case TargetPlatform.Emscripten: + return "so"; + case TargetPlatform.MacOS: + case TargetPlatform.iOS: + case TargetPlatform.WatchOS: + case TargetPlatform.TVOS: + return "dylib"; + default: + throw new ArgumentOutOfRangeException(nameof(targetPlatform), targetPlatform, null); + } + } + + public static string GetPlatformLinkerExecutableName(TargetPlatform targetPlatform) + { + switch (targetPlatform) + { + case TargetPlatform.Windows: + return "link.exe"; + case TargetPlatform.Linux: + return UseCompilerDriverAsLinker ? "gcc" : "ld"; + case TargetPlatform.Android: + case TargetPlatform.MacOS: + case TargetPlatform.iOS: + case TargetPlatform.WatchOS: + case TargetPlatform.TVOS: + return "ld"; + case TargetPlatform.Emscripten: + return GetLLDLinkerExecutableName(targetPlatform); + default: + throw new ArgumentOutOfRangeException(nameof(targetPlatform), targetPlatform, null); + } + } + + public static string GetLLDLinkerExecutableName(TargetPlatform targetPlatform) + { + switch (targetPlatform) + { + case TargetPlatform.Windows: + return "lld-link"; + case TargetPlatform.Linux: + case TargetPlatform.Android: + return "ld.lld"; + case TargetPlatform.MacOS: + case TargetPlatform.iOS: + case TargetPlatform.WatchOS: + case TargetPlatform.TVOS: + return "ld64.lld"; + case TargetPlatform.Emscripten: + return "wasm-ld"; + default: + throw new ArgumentOutOfRangeException(nameof(targetPlatform), targetPlatform, null); + } + } + + private static bool ExistsOnPath(string fileName) + { + return GetFullPath(fileName) != null; + } + + private static string GetFullPath(string fileName) + { + if (fileName == null) throw new ArgumentNullException(nameof(fileName)); + if (File.Exists(fileName)) + return Path.GetFullPath(fileName); + + var environmentVariablePath = Environment.GetEnvironmentVariable("PATH"); + if (environmentVariablePath == null) + throw new NullReferenceException(nameof(environmentVariablePath)); + + foreach (var path in environmentVariablePath.Split(Path.PathSeparator)) + { + var fullPath = Path.Combine(path, fileName); + if (File.Exists(fullPath)) + return fullPath; + } + return null; + } } } diff --git a/src/Parser/ParserOptions.cs b/src/Parser/ParserOptions.cs index 7cda0375e3..511709449f 100644 --- a/src/Parser/ParserOptions.cs +++ b/src/Parser/ParserOptions.cs @@ -136,6 +136,9 @@ public void SetupMSVC() case "vs2019": vsVersion = VisualStudioVersion.VS2019; break; + case "vs2022": + vsVersion = VisualStudioVersion.VS2022; + break; #pragma warning restore 162 @@ -374,6 +377,15 @@ private void SetupArguments(TargetPlatform targetPlatform) AddArguments("-fno-rtti"); } + internal string BuiltinsDirBasePath + { + get + { + var version = ClangVersion.Split(".").First(); + return Path.Combine("lib", "clang", version, "include"); + } + } + public string BuiltinsDir { get @@ -382,7 +394,7 @@ public string BuiltinsDir if (assemblyDir == null) throw new InvalidOperationException(); - return Path.Combine(assemblyDir, "lib", "clang", ClangVersion, "include"); + return Path.Combine(assemblyDir, BuiltinsDirBasePath); } } @@ -390,7 +402,7 @@ private void SetupIncludes(TargetPlatform targetPlatform) { // Check that the builtin includes folder exists. if (!Directory.Exists(BuiltinsDir)) - throw new Exception($"Clang resource folder 'lib/clang/{ClangVersion}/include' was not found."); + throw new Exception($"Clang resource folder '{BuiltinsDirBasePath}' was not found."); switch (targetPlatform) {