Browse Source

Update to Clang 16 for MSVC 2022 support (#1724)

* support clang 15.0.7

* Fix Premake archive logic to work with official releases.

* Try and upgrade CI to latest OS versions.

* Try and fix LLD link call in parser.

* CI fixes.

* Enable VS 2019 and VS 2022 for LLVM windows workflow.

* Update to a more recent LLVM revision.

* More build fixes.

* Use the system linker for linking symbols libraries outside Windows.

Builtin lld is giving some weird linking errors when linking with the
new LLVM version. We probably need to set some custom options. Using the
system linker should be a better idea anyway, more robust and future
proof.

---------

Co-authored-by: you74674 <you74674@gmail.com>
pull/1766/head
João Matos 2 years ago committed by GitHub
parent
commit
0e1e46836d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      .github/workflows/llvm-win.yml
  2. 7
      .github/workflows/main.yml
  3. 1
      Directory.Build.props
  4. 13
      build/LLVM.lua
  5. 16
      build/build.sh
  6. 2
      build/llvm/LLVM-commit
  7. 7
      build/llvm/LLVM.lua
  8. 6
      src/Core/Toolchains/MSVCToolchain.cs
  9. 2
      src/CppParser/CppParser.cpp
  10. 13
      src/CppParser/Link.cpp
  11. 14
      src/CppParser/ParseExpr.cpp
  12. 2
      src/CppParser/ParseStmt.cpp
  13. 37
      src/CppParser/Parser.cpp
  14. 4
      src/CppParser/premake5.lua
  15. 1
      src/Generator/Driver.cs
  16. 1
      src/Generator/Generators/CSharp/CSharpCommentPrinter.cs
  17. 68
      src/Generator/Passes/GenerateSymbolsPass.cs
  18. 158
      src/Parser/LinkerOptions.cs
  19. 16
      src/Parser/ParserOptions.cs

6
.github/workflows/llvm-win.yml

@ -9,8 +9,8 @@ jobs: @@ -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: @@ -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

7
.github/workflows/main.yml

@ -9,15 +9,16 @@ jobs: @@ -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: @@ -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

1
Directory.Build.props

@ -52,7 +52,6 @@ @@ -52,7 +52,6 @@
</PropertyGroup>
<Target Name="prepack" DependsOnTargets="Build" Condition="'$(IsPackable)' == 'true' AND '$(Platform)' == 'x64'">
<Copy SourceFiles="$(TargetDir)ref\$(TargetFileName)" DestinationFolder="$(PackageDir)ref\$(GlobalTargetFramework)" Condition="'$(ProduceReferenceAssembly)' == 'true' AND '$(RID)' == 'win-x64'" />
<Copy SourceFiles="$(TargetPath)" DestinationFolder="$(PackageDir)runtimes\$(RID)\lib\$(GlobalTargetFramework)" />
</Target>
</Project>

13
build/LLVM.lua

@ -42,6 +42,7 @@ function SetupLLVMIncludes() @@ -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() @@ -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() @@ -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() @@ -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() @@ -170,6 +177,7 @@ function SetupLLVMLibs()
"LLVMVectorize",
"LLVMLinker",
"LLVMIRReader",
"LLVMIRPrinter",
"LLVMAsmParser",
"LLVMMCDisassembler",
"LLVMCFGuard",
@ -178,7 +186,9 @@ function SetupLLVMLibs() @@ -178,7 +186,9 @@ function SetupLLVMLibs()
"LLVMAsmPrinter",
"LLVMDebugInfoDWARF",
"LLVMCodeGen",
"LLVMCodeGenTypes",
"LLVMTarget",
"LLVMTargetParser",
"LLVMScalarOpts",
"LLVMInstCombine",
"LLVMAggressiveInstCombine",
@ -202,7 +212,8 @@ function SetupLLVMLibs() @@ -202,7 +212,8 @@ function SetupLLVMLibs()
"lldCommon",
"lldCOFF",
"lldELF",
"lldMachO"
"lldMachO",
"lldMinGW"
}
filter(c)

16
build/build.sh

@ -2,7 +2,7 @@ @@ -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() @@ -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
}

2
build/llvm/LLVM-commit

@ -1 +1 @@ @@ -1 +1 @@
791523bae6153b13bb41ba05c9fc89e502cc4a1a
6eb36aed86ea276695697093eb8136554c29286b

7
build/llvm/LLVM.lua

@ -251,6 +251,7 @@ function cmake(gen, conf, builddir, options) @@ -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) @@ -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) @@ -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) @@ -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

6
src/Core/Toolchains/MSVCToolchain.cs

@ -16,6 +16,7 @@ namespace CppSharp @@ -16,6 +16,7 @@ namespace CppSharp
VS2015 = 14,
VS2017 = 15,
VS2019 = 16,
VS2022 = 17,
Latest,
}
@ -67,9 +68,12 @@ namespace CppSharp @@ -67,9 +68,12 @@ namespace CppSharp
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");
}

2
src/CppParser/CppParser.cpp

@ -7,7 +7,7 @@ @@ -7,7 +7,7 @@
#include "CppParser.h"
#include "Parser.h"
#include <llvm/Support/Host.h>
#include <llvm/TargetParser/Host.h>
#include <clang/Basic/Version.inc>
namespace CppSharp { namespace CppParser {

13
src/CppParser/Link.cpp

@ -11,6 +11,11 @@ @@ -11,6 +11,11 @@
#include <Driver/ToolChains/Linux.h>
#include <lld/Common/Driver.h>
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, @@ -69,7 +74,7 @@ bool Parser::LinkWindows(const CppLinkerOptions* LinkerOptions,
std::vector<std::string> 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, @@ -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, @@ -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, @@ -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

14
src/CppParser/ParseExpr.cpp

@ -223,7 +223,7 @@ AST::Expr* Parser::WalkExpression(const clang::Expr* Expr) @@ -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) @@ -400,7 +400,7 @@ AST::Expr* Parser::WalkExpression(const clang::Expr* Expr)
_S->calleeDecl = static_cast<AST::Declaration*>(WalkDeclaration(S->getCalleeDecl()));
_S->directCallee = static_cast<AST::Function*>(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) @@ -1172,7 +1172,7 @@ AST::Expr* Parser::WalkExpression(const clang::Expr* Expr)
_S->calleeDecl = static_cast<AST::Declaration*>(WalkDeclaration(S->getCalleeDecl()));
_S->directCallee = static_cast<AST::Function*>(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) @@ -1207,7 +1207,7 @@ AST::Expr* Parser::WalkExpression(const clang::Expr* Expr)
_S->calleeDecl = static_cast<AST::Declaration*>(WalkDeclaration(S->getCalleeDecl()));
_S->directCallee = static_cast<AST::Function*>(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) @@ -1241,7 +1241,7 @@ AST::Expr* Parser::WalkExpression(const clang::Expr* Expr)
_S->calleeDecl = static_cast<AST::Declaration*>(WalkDeclaration(S->getCalleeDecl()));
_S->directCallee = static_cast<AST::Function*>(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) @@ -1391,7 +1391,7 @@ AST::Expr* Parser::WalkExpression(const clang::Expr* Expr)
_S->calleeDecl = static_cast<AST::Declaration*>(WalkDeclaration(S->getCalleeDecl()));
_S->directCallee = static_cast<AST::Function*>(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) @@ -1850,7 +1850,7 @@ AST::Expr* Parser::WalkExpression(const clang::Expr* Expr)
_S->operatorDelete = static_cast<AST::Function*>(WalkDeclaration(S->getOperatorDelete()));
_S->allocatedType = GetQualifiedType(S->getAllocatedType());
_S->isArray = S->isArray();
_S->arraySize = static_cast<AST::Expr*>(WalkExpression(S->getArraySize().getValue()));
_S->arraySize = static_cast<AST::Expr*>(WalkExpression(S->getArraySize().value()));
_S->numPlacementArgs = S->getNumPlacementArgs();
_S->isParenTypeId = S->isParenTypeId();
_S->isGlobalNew = S->isGlobalNew();

2
src/CppParser/ParseStmt.cpp

@ -356,7 +356,7 @@ AST::Stmt* Parser::WalkStatement(const clang::Stmt* Stmt) @@ -356,7 +356,7 @@ AST::Stmt* Parser::WalkStatement(const clang::Stmt* Stmt)
_S->allocate = static_cast<AST::Expr*>(WalkExpression(S->getAllocate()));
_S->deallocate = static_cast<AST::Expr*>(WalkExpression(S->getDeallocate()));
_S->returnValueInit = static_cast<AST::Expr*>(WalkExpression(S->getReturnValueInit()));
_S->resultDecl = static_cast<AST::Stmt*>(WalkStatement(S->getResultDecl()));
_S->resultDecl = static_cast<AST::Stmt*>(WalkStatement(S->getReturnValue()));
_S->returnStmt = static_cast<AST::Stmt*>(WalkStatement(S->getReturnStmt()));
_S->returnStmtOnAllocFailure = static_cast<AST::Stmt*>(WalkStatement(S->getReturnStmtOnAllocFailure()));
_Stmt = _S;

37
src/CppParser/Parser.cpp

@ -13,7 +13,7 @@ @@ -13,7 +13,7 @@
#include "ELFDumper.h"
#include "APValuePrinter.h"
#include <llvm/Support/Host.h>
#include <llvm/TargetParser/Host.h>
#include <llvm/Support/Path.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/Support/TargetSelect.h>
@ -880,11 +880,9 @@ static clang::CXXRecordDecl* GetCXXRecordDeclFromTemplateName(const clang::Templ @@ -880,11 +880,9 @@ static clang::CXXRecordDecl* GetCXXRecordDeclFromTemplateName(const clang::Templ
switch (Name.getKind()) {
case clang::TemplateName::Template:
return dyn_cast<clang::CXXRecordDecl>(
Name.getAsTemplateDecl()->getTemplatedDecl());
return dyn_cast<clang::CXXRecordDecl>(Name.getAsTemplateDecl()->getTemplatedDecl());
case clang::TemplateName::QualifiedTemplate:
return dyn_cast<clang::CXXRecordDecl>(
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& @@ -902,7 +900,7 @@ static clang::CXXRecordDecl* GetCXXRecordDeclFromBaseType(const clang::QualType&
else if (auto Injected = Ty->getAs<clang::InjectedClassNameType>())
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, @@ -2604,7 +2602,7 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL,
{
auto TO = Type->getAs<clang::TypeOfType>();
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, @@ -2666,8 +2664,7 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL,
TSTL = &TSpecTL;
}
ArrayRef<clang::TemplateArgument> 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, @@ -2709,8 +2706,7 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL,
TSTL = &TSpecTL;
}
ArrayRef<clang::TemplateArgument> 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, @@ -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() @@ -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<std::string>& SourceFiles, @@ -4397,10 +4393,8 @@ bool Parser::SetupSourceFiles(const std::vector<std::string>& SourceFiles,
std::vector<const clang::FileEntry*>& FileEntries)
{
// Check that the file is reachable.
const clang::DirectoryLookup *Dir;
llvm::SmallVector<
std::pair<const clang::FileEntry *, const clang::DirectoryEntry *>,
0> Includers;
clang::ConstSearchDirIterator *Dir = 0;
llvm::ArrayRef<std::pair<const clang::FileEntry*, clang::DirectoryEntryRef>> Includers;
for (const auto& SourceFile : SourceFiles)
{
@ -4863,8 +4857,7 @@ ParserResult* Parser::Compile(const std::string& File) @@ -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() @@ -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();

4
src/CppParser/premake5.lua

@ -4,6 +4,7 @@ clang_msvc_flags = @@ -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" @@ -20,6 +21,9 @@ project "CppSharp.CppParser"
linkgroups "On"
end
filter "toolset:gcc*"
buildoptions { "-Wno-nonnull" }
filter "toolset:msc*"
buildoptions { clang_msvc_flags }

1
src/Generator/Driver.cs

@ -87,7 +87,6 @@ namespace CppSharp @@ -87,7 +87,6 @@ namespace CppSharp
ValidateOptions();
ParserOptions.Setup(Platform.Host);
Context = new BindingContext(Options, ParserOptions);
Context.LinkerOptions.Setup(ParserOptions.TargetTriple, ParserOptions.LanguageVersion);
Generator = CreateGeneratorFromKind(Options.GeneratorKind);
}

1
src/Generator/Generators/CSharp/CSharpCommentPrinter.cs

@ -37,6 +37,7 @@ namespace CppSharp.Generators.CSharp @@ -37,6 +37,7 @@ namespace CppSharp.Generators.CSharp
blockCommandComment.ParagraphComment.GetCommentSections(sections);
break;
case CommentCommandKind.Return:
case CommentCommandKind.Returns:
sections.Add(new Section(CommentElement.Returns));
blockCommandComment.ParagraphComment.GetCommentSections(sections);
break;

68
src/Generator/Passes/GenerateSymbolsPass.cs

@ -63,24 +63,72 @@ namespace CppSharp.Passes @@ -63,24 +63,72 @@ namespace CppSharp.Passes
new[] { module }).SelectMany(d => d.Libraries))
linkerOptions.AddLibraries(library);
using (var result = Parser.ClangParser.Build(
Context.ParserOptions, linkerOptions, path,
Last: remainingCompilationTasks == 1))
compiledLibraries[module] = Build(linkerOptions, path, module);
}
}
RemainingCompilationTasks--;
}
}
private CompiledLibrary Build(LinkerOptions linkerOptions, string path, Module module)
{
if (PrintDiagnostics(result))
var useBuiltinToolchain = Platform.IsWindows;
if (useBuiltinToolchain)
{
compiledLibraries[module] = new CompiledLibrary
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
{
OutputDir = Options.OutputDir,
Library = module.SymbolsLibraryName
};
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.");
}
}
RemainingCompilationTasks--;
}
return new CompiledLibrary
{
OutputDir = Options.OutputDir,
Library = module.SymbolsLibraryName
};
}
public override bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecialization specialization)

158
src/Parser/LinkerOptions.cs

@ -1,4 +1,8 @@ @@ -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 @@ namespace CppSharp.Parser @@ -8,6 +12,8 @@ namespace CppSharp.Parser
{
}
public static bool UseCompilerDriverAsLinker = true;
public LinkerOptions(LinkerOptions other)
{
for (uint i = 0; i < other.ArgumentsCount; i++)
@ -45,7 +51,7 @@ namespace CppSharp.Parser @@ -45,7 +51,7 @@ namespace CppSharp.Parser
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 @@ namespace CppSharp.Parser @@ -70,5 +76,153 @@ namespace CppSharp.Parser
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<string>();
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;
}
}
}

16
src/Parser/ParserOptions.cs

@ -136,6 +136,9 @@ namespace CppSharp.Parser @@ -136,6 +136,9 @@ namespace CppSharp.Parser
case "vs2019":
vsVersion = VisualStudioVersion.VS2019;
break;
case "vs2022":
vsVersion = VisualStudioVersion.VS2022;
break;
#pragma warning restore 162
@ -374,6 +377,15 @@ namespace CppSharp.Parser @@ -374,6 +377,15 @@ namespace CppSharp.Parser
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 @@ namespace CppSharp.Parser @@ -382,7 +394,7 @@ namespace CppSharp.Parser
if (assemblyDir == null)
throw new InvalidOperationException();
return Path.Combine(assemblyDir, "lib", "clang", ClangVersion, "include");
return Path.Combine(assemblyDir, BuiltinsDirBasePath);
}
}
@ -390,7 +402,7 @@ namespace CppSharp.Parser @@ -390,7 +402,7 @@ namespace CppSharp.Parser
{
// 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)
{

Loading…
Cancel
Save