Browse Source

Add LanguageVersion.CPP23

295227ce-f4a3-466b-a694-65c571873871
josetr 4 years ago
parent
commit
7e825c4dd3
  1. 760
      src/Parser/ParserOptions.cs

760
src/Parser/ParserOptions.cs

@ -11,377 +11,391 @@ using LanguageVersion = CppSharp.Parser.LanguageVersion;
namespace CppSharp.Parser namespace CppSharp.Parser
{ {
public enum LanguageVersion public enum LanguageVersion
{ {
/// <summary> /// <summary>
/// C programming language (year 1999). /// C programming language (year 1999).
/// </summary> /// </summary>
C99, C99,
/// <summary> /// <summary>
/// C programming language (year 1999, GNU variant). /// C programming language (year 1999, GNU variant).
/// </summary> /// </summary>
C99_GNU, C99_GNU,
/// <summary> /// <summary>
/// C++ programming language (year 1998). /// C++ programming language (year 1998).
/// </summary> /// </summary>
CPP98, CPP98,
/// <summary> /// <summary>
/// C++ programming language (year 1998, GNU variant). /// C++ programming language (year 1998, GNU variant).
/// </summary> /// </summary>
CPP98_GNU, CPP98_GNU,
/// <summary> /// <summary>
/// C++ programming language (year 2011). /// C++ programming language (year 2011).
/// </summary> /// </summary>
CPP11, CPP11,
/// <summary> /// <summary>
/// C++ programming language (year 2011, GNU variant). /// C++ programming language (year 2011, GNU variant).
/// </summary> /// </summary>
CPP11_GNU, CPP11_GNU,
/// <summary> /// <summary>
/// C++ programming language (year 2014). /// C++ programming language (year 2014).
/// </summary> /// </summary>
CPP14, CPP14,
/// <summary> /// <summary>
/// C++ programming language (year 2014, GNU variant). /// C++ programming language (year 2014, GNU variant).
/// </summary> /// </summary>
CPP14_GNU, CPP14_GNU,
/// <summary> /// <summary>
/// C++ programming language (year 2017). /// C++ programming language (year 2017).
/// </summary> /// </summary>
CPP17, CPP17,
/// <summary> /// <summary>
/// C++ programming language (year 2017, GNU variant). /// C++ programming language (year 2017, GNU variant).
/// </summary> /// </summary>
CPP17_GNU, CPP17_GNU,
/// <summary> /// <summary>
/// C++ programming language (year 2020). /// C++ programming language (year 2020).
/// </summary> /// </summary>
CPP20, CPP20,
/// <summary> /// <summary>
/// C++ programming language (year 2020, GNU variant). /// C++ programming language (year 2020, GNU variant).
/// </summary> /// </summary>
CPP20_GNU, CPP20_GNU,
} /// <summary>
/// C++ programming language (year 2023).
public class ParserOptions : CppParserOptions /// </summary>
{ CPP23,
public ParserOptions() /// <summary>
{ /// C++ programming language (year 2023, GNU variant).
MicrosoftMode = !Platform.IsUnixPlatform; /// </summary>
AddCompilationOptions("-flto"); CPP23_GNU,
AddCompilationOptions("-O3"); }
AddCompilationOptions("-fno-use-cxa-atexit");
} public class ParserOptions : CppParserOptions
{
public bool IsItaniumLikeAbi => !IsMicrosoftAbi; public ParserOptions()
public bool IsMicrosoftAbi => TargetTriple.Contains("win32") || {
TargetTriple.Contains("windows") || TargetTriple.Contains("msvc"); MicrosoftMode = !Platform.IsUnixPlatform;
AddCompilationOptions("-flto");
public bool EnableRTTI { get; set; } AddCompilationOptions("-O3");
public LanguageVersion? LanguageVersion { get; set; } AddCompilationOptions("-fno-use-cxa-atexit");
}
public void BuildForSourceFile(
IEnumerable<CppSharp.AST.Module> modules, string file = null) public bool IsItaniumLikeAbi => !IsMicrosoftAbi;
{ public bool IsMicrosoftAbi => TargetTriple.Contains("win32") ||
// This eventually gets passed to Clang's MSCompatibilityVersion, which TargetTriple.Contains("windows") || TargetTriple.Contains("msvc");
// is in turn used to derive the value of the built-in define _MSC_VER.
// It used to receive a 4-digit based identifier but now expects a full public bool EnableRTTI { get; set; }
// version MSVC digit, so check if we still have the old version and public LanguageVersion? LanguageVersion { get; set; }
// convert to the right format.
public void BuildForSourceFile(
if (ToolSetToUse.ToString(CultureInfo.InvariantCulture).Length == 4) IEnumerable<CppSharp.AST.Module> modules, string file = null)
ToolSetToUse *= 100000; {
// This eventually gets passed to Clang's MSCompatibilityVersion, which
foreach (var module in modules.Where( // is in turn used to derive the value of the built-in define _MSC_VER.
m => file == null || m.Headers.Contains(file))) // It used to receive a 4-digit based identifier but now expects a full
{ // version MSVC digit, so check if we still have the old version and
foreach (var include in module.IncludeDirs) // convert to the right format.
AddIncludeDirs(include);
if (ToolSetToUse.ToString(CultureInfo.InvariantCulture).Length == 4)
foreach (var define in module.Defines) ToolSetToUse *= 100000;
AddDefines(define);
foreach (var module in modules.Where(
foreach (var undefine in module.Undefines) m => file == null || m.Headers.Contains(file)))
AddUndefines(undefine); {
} foreach (var include in module.IncludeDirs)
} AddIncludeDirs(include);
public void SetupMSVC() foreach (var define in module.Defines)
{ AddDefines(define);
var vsVersion = VisualStudioVersion.Latest;
foreach (var undefine in module.Undefines)
// Silence "warning CS0162: Unreachable code detected" AddUndefines(undefine);
#pragma warning disable 162 }
}
switch (BuildConfig.Choice)
{ public void SetupMSVC()
case "vs2012": {
vsVersion = VisualStudioVersion.VS2012; var vsVersion = VisualStudioVersion.Latest;
break;
case "vs2013": // Silence "warning CS0162: Unreachable code detected"
vsVersion = VisualStudioVersion.VS2013; #pragma warning disable 162
break;
case "vs2015": switch (BuildConfig.Choice)
vsVersion = VisualStudioVersion.VS2015; {
break; case "vs2012":
case "vs2017": vsVersion = VisualStudioVersion.VS2012;
vsVersion = VisualStudioVersion.VS2017; break;
break; case "vs2013":
case "vs2019": vsVersion = VisualStudioVersion.VS2013;
vsVersion = VisualStudioVersion.VS2019; break;
break; case "vs2015":
vsVersion = VisualStudioVersion.VS2015;
#pragma warning restore 162 break;
case "vs2017":
} vsVersion = VisualStudioVersion.VS2017;
break;
SetupMSVC(vsVersion); case "vs2019":
} vsVersion = VisualStudioVersion.VS2019;
break;
/// <summary>
/// Sets up the parser options to work with the given Visual Studio toolchain. #pragma warning restore 162
/// </summary>
/// <param name="vsVersion">The version of Visual Studio to look for.</param> }
public void SetupMSVC(VisualStudioVersion vsVersion)
{ SetupMSVC(vsVersion);
MicrosoftMode = true; }
var clVersion = MSVCToolchain.GetCLVersion(vsVersion); /// <summary>
ToolSetToUse = clVersion.Major * 10000000 + clVersion.Minor * 100000; /// Sets up the parser options to work with the given Visual Studio toolchain.
/// </summary>
// do not remove the CppSharp prefix becase the Mono C# compiler breaks /// <param name="vsVersion">The version of Visual Studio to look for.</param>
if (!LanguageVersion.HasValue) public void SetupMSVC(VisualStudioVersion vsVersion)
LanguageVersion = CppSharp.Parser.LanguageVersion.CPP14_GNU; {
MicrosoftMode = true;
AddArguments("-fms-extensions");
AddArguments("-fms-compatibility"); var clVersion = MSVCToolchain.GetCLVersion(vsVersion);
AddArguments("-fdelayed-template-parsing"); ToolSetToUse = clVersion.Major * 10000000 + clVersion.Minor * 100000;
}
// do not remove the CppSharp prefix becase the Mono C# compiler breaks
/// <summary> if (!LanguageVersion.HasValue)
/// Set to true to opt for Xcode Clang builtin headers LanguageVersion = CppSharp.Parser.LanguageVersion.CPP14_GNU;
/// </summary>
public bool UseXcodeBuiltins; AddArguments("-fms-extensions");
AddArguments("-fms-compatibility");
public void SetupXcode() AddArguments("-fdelayed-template-parsing");
{ }
var cppIncPath = XcodeToolchain.GetXcodeCppIncludesFolder();
AddSystemIncludeDirs(cppIncPath); /// <summary>
/// Set to true to opt for Xcode Clang builtin headers
var builtinsPath = XcodeToolchain.GetXcodeBuiltinIncludesFolder(); /// </summary>
AddSystemIncludeDirs(UseXcodeBuiltins ? builtinsPath : BuiltinsDir); public bool UseXcodeBuiltins;
var includePath = XcodeToolchain.GetXcodeIncludesFolder(); public void SetupXcode()
AddSystemIncludeDirs(includePath); {
var cppIncPath = XcodeToolchain.GetXcodeCppIncludesFolder();
NoBuiltinIncludes = true; AddSystemIncludeDirs(cppIncPath);
NoStandardIncludes = true;
var builtinsPath = XcodeToolchain.GetXcodeBuiltinIncludesFolder();
AddArguments("-fgnuc-version=4.2.1"); AddSystemIncludeDirs(UseXcodeBuiltins ? builtinsPath : BuiltinsDir);
AddArguments("-stdlib=libc++");
} var includePath = XcodeToolchain.GetXcodeIncludesFolder();
AddSystemIncludeDirs(includePath);
private void GetUnixCompilerInfo(string headersPath, out string compiler,
out string longVersion, out string shortVersion) NoBuiltinIncludes = true;
{ NoStandardIncludes = true;
if (!Platform.IsLinux)
{ AddArguments("-fgnuc-version=4.2.1");
compiler = "gcc"; AddArguments("-stdlib=libc++");
}
// Search for the available GCC versions on the provided headers.
var versions = Directory.EnumerateDirectories(Path.Combine(headersPath, private void GetUnixCompilerInfo(string headersPath, out string compiler,
"usr", "include", "c++")); out string longVersion, out string shortVersion)
{
if (versions.Count() == 0) if (!Platform.IsLinux)
throw new Exception("No valid GCC version found on system include paths"); {
compiler = "gcc";
string gccVersionPath = versions.First();
longVersion = shortVersion = gccVersionPath.Substring( // Search for the available GCC versions on the provided headers.
gccVersionPath.LastIndexOf(Path.DirectorySeparatorChar) + 1); var versions = Directory.EnumerateDirectories(Path.Combine(headersPath,
"usr", "include", "c++"));
return;
} if (versions.Count() == 0)
throw new Exception("No valid GCC version found on system include paths");
var info = new ProcessStartInfo(Environment.GetEnvironmentVariable("CXX") ?? "gcc", "-v");
info.RedirectStandardError = true; string gccVersionPath = versions.First();
info.CreateNoWindow = true; longVersion = shortVersion = gccVersionPath.Substring(
info.UseShellExecute = false; gccVersionPath.LastIndexOf(Path.DirectorySeparatorChar) + 1);
var process = Process.Start(info); return;
if (process == null) }
throw new SystemException("GCC compiler was not found.");
var info = new ProcessStartInfo(Environment.GetEnvironmentVariable("CXX") ?? "gcc", "-v");
process.WaitForExit(); info.RedirectStandardError = true;
info.CreateNoWindow = true;
var output = process.StandardError.ReadToEnd(); info.UseShellExecute = false;
var match = Regex.Match(output, "(gcc|clang) version (([0-9]+\\.[0-9]+)\\.[0-9]+)");
if (!match.Success) var process = Process.Start(info);
throw new SystemException("GCC compiler was not found."); if (process == null)
throw new SystemException("GCC compiler was not found.");
compiler = match.Groups[1].ToString();
longVersion = match.Groups[2].ToString(); process.WaitForExit();
shortVersion = match.Groups[3].ToString();
} var output = process.StandardError.ReadToEnd();
var match = Regex.Match(output, "(gcc|clang) version (([0-9]+\\.[0-9]+)\\.[0-9]+)");
public void SetupLinux(string headersPath = "") if (!match.Success)
{ throw new SystemException("GCC compiler was not found.");
MicrosoftMode = false;
NoBuiltinIncludes = true; compiler = match.Groups[1].ToString();
NoStandardIncludes = true; longVersion = match.Groups[2].ToString();
shortVersion = match.Groups[3].ToString();
string compiler, longVersion, shortVersion; }
GetUnixCompilerInfo(headersPath, out compiler, out longVersion, out shortVersion);
public void SetupLinux(string headersPath = "")
AddSystemIncludeDirs(BuiltinsDir); {
AddArguments($"-fgnuc-version={longVersion}"); MicrosoftMode = false;
NoBuiltinIncludes = true;
string majorVersion = shortVersion.Split('.')[0]; NoStandardIncludes = true;
string[] versions = { longVersion, shortVersion, majorVersion };
string[] triples = { "x86_64-linux-gnu", "x86_64-pc-linux-gnu" }; string compiler, longVersion, shortVersion;
if (compiler == "gcc") GetUnixCompilerInfo(headersPath, out compiler, out longVersion, out shortVersion);
{
foreach (var version in versions) AddSystemIncludeDirs(BuiltinsDir);
{ AddArguments($"-fgnuc-version={longVersion}");
AddSystemIncludeDirs($"{headersPath}/usr/include/c++/{version}");
AddSystemIncludeDirs($"{headersPath}/usr/include/c++/{version}/backward"); string majorVersion = shortVersion.Split('.')[0];
string[] versions = { longVersion, shortVersion, majorVersion };
foreach (var triple in triples) string[] triples = { "x86_64-linux-gnu", "x86_64-pc-linux-gnu" };
{ if (compiler == "gcc")
AddSystemIncludeDirs($"{headersPath}/usr/include/{triple}/c++/{version}"); {
AddSystemIncludeDirs($"{headersPath}/usr/include/c++/{version}/{triple}"); foreach (var version in versions)
} {
} AddSystemIncludeDirs($"{headersPath}/usr/include/c++/{version}");
} AddSystemIncludeDirs($"{headersPath}/usr/include/c++/{version}/backward");
foreach (var triple in triples) foreach (var triple in triples)
{ {
foreach (var version in versions) AddSystemIncludeDirs($"{headersPath}/usr/include/{triple}/c++/{version}");
{ AddSystemIncludeDirs($"{headersPath}/usr/include/c++/{version}/{triple}");
AddSystemIncludeDirs($"{headersPath}/usr/lib/{compiler}/{triple}/{version}/include"); }
AddSystemIncludeDirs($"{headersPath}/usr/lib/{compiler}/{triple}/{version}/include/c++"); }
AddSystemIncludeDirs($"{headersPath}/usr/lib/{compiler}/{triple}/{version}/include/c++/{triple}"); }
}
foreach (var triple in triples)
AddSystemIncludeDirs($"{headersPath}/usr/include/{triple}"); {
} foreach (var version in versions)
{
AddSystemIncludeDirs($"{headersPath}/usr/include"); AddSystemIncludeDirs($"{headersPath}/usr/lib/{compiler}/{triple}/{version}/include");
AddSystemIncludeDirs($"{headersPath}/usr/include/linux"); AddSystemIncludeDirs($"{headersPath}/usr/lib/{compiler}/{triple}/{version}/include/c++");
} AddSystemIncludeDirs($"{headersPath}/usr/lib/{compiler}/{triple}/{version}/include/c++/{triple}");
}
public void Setup()
{ AddSystemIncludeDirs($"{headersPath}/usr/include/{triple}");
SetupArguments(); }
if (!NoBuiltinIncludes) AddSystemIncludeDirs($"{headersPath}/usr/include");
SetupIncludes(); AddSystemIncludeDirs($"{headersPath}/usr/include/linux");
} }
private void SetupArguments() public void Setup()
{ {
// do not remove the CppSharp prefix becase the Mono C# compiler breaks SetupArguments();
if (!LanguageVersion.HasValue)
LanguageVersion = CppSharp.Parser.LanguageVersion.CPP14_GNU; if (!NoBuiltinIncludes)
SetupIncludes();
// As of Clang revision 5e866e411caa we are required to pass "-fgnuc-version=" }
// to get the __GNUC__ symbol defined. macOS and Linux system headers require
// this define, so we need explicitly pass it to Clang. private void SetupArguments()
{
// Note that this setup is more accurately done in the platform-specific // do not remove the CppSharp prefix becase the Mono C# compiler breaks
// setup methods, below is generic fallback in case that logic was disabled. if (!LanguageVersion.HasValue)
if (NoBuiltinIncludes) LanguageVersion = CppSharp.Parser.LanguageVersion.CPP14_GNU;
{
switch (Platform.Host) // As of Clang revision 5e866e411caa we are required to pass "-fgnuc-version="
{ // to get the __GNUC__ symbol defined. macOS and Linux system headers require
case TargetPlatform.MacOS: // this define, so we need explicitly pass it to Clang.
case TargetPlatform.Linux:
AddArguments("-fgnuc-version=4.2.1"); // Note that this setup is more accurately done in the platform-specific
break; // setup methods, below is generic fallback in case that logic was disabled.
} if (NoBuiltinIncludes)
} {
switch (Platform.Host)
switch (LanguageVersion) {
{ case TargetPlatform.MacOS:
case CppSharp.Parser.LanguageVersion.C99: case TargetPlatform.Linux:
case CppSharp.Parser.LanguageVersion.C99_GNU: AddArguments("-fgnuc-version=4.2.1");
AddArguments("-xc"); break;
break; }
default: }
AddArguments("-xc++");
break; switch (LanguageVersion)
} {
case CppSharp.Parser.LanguageVersion.C99:
switch (LanguageVersion) case CppSharp.Parser.LanguageVersion.C99_GNU:
{ AddArguments("-xc");
case CppSharp.Parser.LanguageVersion.C99: break;
AddArguments("-std=c99"); default:
break; AddArguments("-xc++");
case CppSharp.Parser.LanguageVersion.C99_GNU: break;
AddArguments("-std=gnu99"); }
break;
case CppSharp.Parser.LanguageVersion.CPP98: switch (LanguageVersion)
AddArguments("-std=c++98"); {
break; case CppSharp.Parser.LanguageVersion.C99:
case CppSharp.Parser.LanguageVersion.CPP98_GNU: AddArguments("-std=c99");
AddArguments("-std=gnu++98"); break;
break; case CppSharp.Parser.LanguageVersion.C99_GNU:
case CppSharp.Parser.LanguageVersion.CPP11: AddArguments("-std=gnu99");
AddArguments("-std=c++11"); break;
break; case CppSharp.Parser.LanguageVersion.CPP98:
case CppSharp.Parser.LanguageVersion.CPP11_GNU: AddArguments("-std=c++98");
AddArguments("-std=gnu++11"); break;
break; case CppSharp.Parser.LanguageVersion.CPP98_GNU:
case CppSharp.Parser.LanguageVersion.CPP14: AddArguments("-std=gnu++98");
AddArguments("-std=c++14"); break;
break; case CppSharp.Parser.LanguageVersion.CPP11:
case CppSharp.Parser.LanguageVersion.CPP14_GNU: AddArguments("-std=c++11");
AddArguments("-std=gnu++14"); break;
break; case CppSharp.Parser.LanguageVersion.CPP11_GNU:
case CppSharp.Parser.LanguageVersion.CPP17: AddArguments("-std=gnu++11");
AddArguments("-std=c++17"); break;
break; case CppSharp.Parser.LanguageVersion.CPP14:
case CppSharp.Parser.LanguageVersion.CPP17_GNU: AddArguments("-std=c++14");
AddArguments("-std=gnu++17"); break;
break; case CppSharp.Parser.LanguageVersion.CPP14_GNU:
case CppSharp.Parser.LanguageVersion.CPP20: AddArguments("-std=gnu++14");
AddArguments("-std=c++20"); break;
break; case CppSharp.Parser.LanguageVersion.CPP17:
case CppSharp.Parser.LanguageVersion.CPP20_GNU: AddArguments("-std=c++17");
AddArguments("-std=gnu++20"); break;
break; case CppSharp.Parser.LanguageVersion.CPP17_GNU:
} AddArguments("-std=gnu++17");
break;
if (!EnableRTTI) case CppSharp.Parser.LanguageVersion.CPP20:
AddArguments("-fno-rtti"); AddArguments("-std=c++20");
} break;
case CppSharp.Parser.LanguageVersion.CPP20_GNU:
public string BuiltinsDir AddArguments("-std=gnu++20");
{ break;
get case CppSharp.Parser.LanguageVersion.CPP23:
{ AddArguments("-std=c++2b");
var assemblyDir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); break;
return Path.Combine(assemblyDir, "lib", "clang", ClangVersion, "include"); case CppSharp.Parser.LanguageVersion.CPP23_GNU:
} AddArguments("-std=gnu++2b");
} break;
}
private void SetupIncludes()
{ if (!EnableRTTI)
// Check that the builtin includes folder exists. AddArguments("-fno-rtti");
if (!Directory.Exists(BuiltinsDir)) }
throw new Exception($"Clang resource folder 'lib/clang/{ClangVersion}/include' was not found.");
public string BuiltinsDir
switch (Platform.Host) {
{ get
case TargetPlatform.Windows: {
SetupMSVC(); var assemblyDir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
break; return Path.Combine(assemblyDir, "lib", "clang", ClangVersion, "include");
case TargetPlatform.MacOS: }
SetupXcode(); }
break;
case TargetPlatform.Linux: private void SetupIncludes()
SetupLinux(); {
break; // Check that the builtin includes folder exists.
} if (!Directory.Exists(BuiltinsDir))
} throw new Exception($"Clang resource folder 'lib/clang/{ClangVersion}/include' was not found.");
}
switch (Platform.Host)
{
case TargetPlatform.Windows:
SetupMSVC();
break;
case TargetPlatform.MacOS:
SetupXcode();
break;
case TargetPlatform.Linux:
SetupLinux();
break;
}
}
}
} }

Loading…
Cancel
Save