diff --git a/.github/workflows/llvm-win.yml b/.github/workflows/llvm-win.yml
index 6bf9e8c0e5..455c4f4dcf 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-2019, platform: x86, vs: 2019 }
- - { os: windows-2019, platform: x64, vs: 2019 }
+ - { os: windows-2022, platform: x86, vs: 2022 }
+ - { os: windows-2022, platform: x64, vs: 2022 }
runs-on: ${{ matrix.config.os }}
@@ -23,7 +23,7 @@ jobs:
steps:
- name: Inject slug/short variables
- uses: rlespinasse/github-slug-action@v3.x
+ uses: rlespinasse/github-slug-action@v4
- name: Check out
shell: cmd
@@ -35,7 +35,7 @@ jobs:
- name: Environment
shell: cmd
run: |
- call "C:\Program Files (x86)\Microsoft Visual Studio\%VS_VERSION%\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" %PLATFORM%
+ call "C:\Program Files\Microsoft Visual Studio\%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
@@ -60,7 +60,7 @@ jobs:
working-directory: C:\CppSharp
- name: 'Upload Artifact'
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v3
with:
name: llvm
path: C:\CppSharp\build\llvm\llvm-*-*.*
\ No newline at end of file
diff --git a/.github/workflows/llvm.yml b/.github/workflows/llvm.yml
index aa3ffe278e..d8b3f10b82 100644
--- a/.github/workflows/llvm.yml
+++ b/.github/workflows/llvm.yml
@@ -9,9 +9,9 @@ jobs:
fail-fast: false
matrix:
config:
- - { os: ubuntu-20.04, platform: x64, cxx: g++-9, cc: gcc-9 }
- - { os: ubuntu-20.04, platform: x64, cxx: g++-10, cc: gcc-10 }
- - { os: macos-10.15, platform: x64, cxx: clang++, cc: clang }
+ - { os: ubuntu-22.04, platform: x64, cxx: g++-11, cc: gcc-11 }
+ - { os: macos-11, platform: x64, cxx: clang++, cc: clang }
+ - { os: macos-12, platform: x64, cxx: clang++, cc: clang }
runs-on: ${{ matrix.config.os }}
@@ -22,7 +22,7 @@ jobs:
ACTIONS_ALLOW_UNSECURE_COMMANDS: true
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v3
- uses: lukka/get-cmake@latest
- name: Clone LLVM
@@ -38,7 +38,7 @@ jobs:
run: build/build.sh package_llvm -platform $PLATFORM
- name: 'Upload Artifact'
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v3
with:
name: llvm
path: build/llvm/llvm-*-*.*
\ No newline at end of file
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index ae538fd464..6756de7613 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -73,8 +73,8 @@ jobs:
runs-on: windows-2019
needs: build
if: |
- (github.event_name == 'push' && (github.ref == 'refs/heads/main' || contains(github.ref, 'nuget'))) ||
- (github.event.pull_request.head.repo.full_name != github.repository && contains(github.event.pull_request.head.ref, 'nuget'))
+ (github.event_name == 'push' && (github.ref == 'refs/heads/main' || contains(github.ref, 'nuget') || startsWith(github.ref, 'refs/tags/v'))) ||
+ (github.event.pull_request.head.repo.full_name != github.repository && (contains(github.event.pull_request.head.ref, 'nuget') || startsWith(github.event.pull_request.head.ref, 'refs/tags/v')))
env:
DOTNET_NOLOGO: true
@@ -111,3 +111,9 @@ jobs:
run: |
cd artifacts
dotnet nuget push "*.nupkg" --api-key ${{ secrets.GITHUB_TOKEN }} --source "https://nuget.pkg.github.com/mono/index.json" --skip-duplicate
+
+ - name: Publish package to nuget.org
+ if: startsWith(github.ref, 'refs/tags/v')
+ run: |
+ cd artifacts
+ dotnet nuget push "*.nupkg" --api-key ${{ secrets.NUGET_API_KEY }} --source "https://api.nuget.org/v3/index.json" --skip-duplicate
diff --git a/.gitmodules b/.gitmodules
index cababe3d56..e69de29bb2 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +0,0 @@
-[submodule "build/modules/premake-qt"]
- path = build/modules/premake-qt
- url = https://github.com/dcourtois/premake-qt.git
diff --git a/Directory.Build.props b/Directory.Build.props
index 69c39a4e28..3fe84b36b1 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -34,7 +34,7 @@
dll
"$(MSBuildProgramFiles32)\dotnet\dotnet.exe"
"$(ProgramW6432)\dotnet\dotnet.exe"
- win
+ win
linux
osx
$(RID)-$(PlatformTarget)
diff --git a/README.md b/README.md
index 259d97b950..b3b3a9495c 100644
--- a/README.md
+++ b/README.md
@@ -76,8 +76,6 @@ Please see the following resources for more information:
Feel free to open up issues on Github for any problems you find.
-You can also join us at our [#managed-interop](https://gitter.im/managed-interop) Gitter discussion channel.
-
## Support
For building wrappers and priority support please write to cppsharp@protonmail.com.
diff --git a/build/Helpers.lua b/build/Helpers.lua
index b68da9a261..68c4c91d3e 100644
--- a/build/Helpers.lua
+++ b/build/Helpers.lua
@@ -43,11 +43,16 @@ newoption {
description = "Only generate configuration file",
}
+newoption {
+ trigger = "target-framework",
+ description = ".NET target framework version",
+}
+
rootdir = path.getabsolute("../")
srcdir = path.join(rootdir, "src");
incdir = path.join(rootdir, "include");
examplesdir = path.join(rootdir, "examples");
-testsdir = path.join(rootdir, "tests");
+testsdir = path.join(rootdir, "tests/dotnet");
builddir = path.join(rootdir, "build")
bindir = path.join(rootdir, "bin")
objsdir = path.join(builddir, "obj");
@@ -61,7 +66,17 @@ msvc_cpp_defines = { }
default_gcc_version = "9.0.0"
generate_build_config = true
premake.path = premake.path .. ";" .. path.join(builddir, "modules")
-targetframework = "netcoreapp3.1"
+
+function string.isempty(s)
+ return s == nil or s == ''
+end
+
+local function target_framework()
+ local value = _OPTIONS["target-framework"]
+ return string.isempty(value) and "net6.0" or value
+end
+
+targetframework = target_framework()
function string.starts(str, start)
if str == nil then return end
diff --git a/build/build.sh b/build/build.sh
index de1368dc90..6f7a086fee 100755
--- a/build/build.sh
+++ b/build/build.sh
@@ -6,6 +6,7 @@ vs=vs2019
configuration=Release
build_only=false
ci=false
+target_framework=
verbosity=minimal
rootdir="$builddir/.."
bindir="$rootdir/bin"
@@ -46,7 +47,7 @@ build()
generate_config()
{
- "$builddir/premake.sh" --file="$builddir/premake5.lua" $vs --os=$os --arch=$platform --configuration=$configuration --config_only
+ "$builddir/premake.sh" --file="$builddir/premake5.lua" $vs --os=$os --arch=$platform --configuration=$configuration --target-framework=$target_framework --config_only
}
generate()
@@ -54,10 +55,10 @@ generate()
download_llvm
if [ "$os" = "linux" ] || [ "$os" = "macosx" ]; then
- "$builddir/premake.sh" --file="$builddir/premake5.lua" gmake2 --os=$os --arch=$platform --configuration=$configuration "$@"
+ "$builddir/premake.sh" --file="$builddir/premake5.lua" gmake2 --os=$os --arch=$platform --configuration=$configuration --target-framework=$target_framework "$@"
fi
- "$builddir/premake.sh" --file="$builddir/premake5.lua" $vs --os=$os --arch=$platform --configuration=$configuration
+ "$builddir/premake.sh" --file="$builddir/premake5.lua" $vs --os=$os --arch=$platform --configuration=$configuration --target-framework=$target_framework
}
restore()
@@ -194,6 +195,11 @@ while [[ $# > 0 ]]; do
os=$2
shift
;;
+ -target-framework)
+ target_framework=$2
+ echo $target_framework
+ shift
+ ;;
-ci)
ci=true
export CI=true
diff --git a/build/llvm/Directory.Build.props b/build/llvm/Directory.Build.props
new file mode 100644
index 0000000000..8d7621c6b0
--- /dev/null
+++ b/build/llvm/Directory.Build.props
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/build/llvm/LLVM.lua b/build/llvm/LLVM.lua
index fc15650167..30a3943314 100644
--- a/build/llvm/LLVM.lua
+++ b/build/llvm/LLVM.lua
@@ -53,13 +53,15 @@ end
function get_vs_version()
local function map_msvc_to_vs_version(major, minor)
- if major == "19" and minor >= "20" then return "vs2019"
+ if major == "19" and minor >= "30" then return "vs2022"
+ elseif major == "19" and minor >= "20" then return "vs2019"
elseif major == "19" and minor >= "10" then return "vs2017"
end
end
local function map_msbuild_to_vs_version(major, minor)
- if major == "16" then return "vs2019"
+ if major == "17" then return "vs2022"
+ elseif major == "16" then return "vs2019"
elseif major == "15" then return "vs2017"
end
end
@@ -379,8 +381,6 @@ function cmake(gen, conf, builddir, options)
.. ' -DCLANG_TOOL_C_INDEX_TEST_BUILD=false'
.. ' -DCLANG_TOOL_DIAGTOOL_BUILD=false'
.. ' -DCLANG_TOOL_DRIVER_BUILD=false'
- .. ' -DCLANG_TOOL_HANDLE_CXX_BUILD=false'
- .. ' -DCLANG_TOOL_HANDLE_LLVM_BUILD=false'
.. ' -DCLANG_TOOL_LIBCLANG_BUILD=false'
.. ' -DCLANG_TOOL_SCAN_BUILD_BUILD=false'
.. ' -DCLANG_TOOL_SCAN_BUILD_PY_BUILD=false'
@@ -399,7 +399,9 @@ end
function get_cmake_generator()
local vsver = get_vs_version()
- if vsver == "vs2019" then
+ if vsver == "vs2022" then
+ return "Visual Studio 17 2022", (target_architecture() == "x86") and "-A Win32" or nil
+ elseif vsver == "vs2019" then
return "Visual Studio 16 2019", (target_architecture() == "x86") and "-A Win32" or nil
elseif vsver == "vs2017" then
return "Visual Studio 15 2017" .. (target_architecture() == "x64" and " Win64" or ""), nil
diff --git a/build/modules/premake-qt b/build/modules/premake-qt
deleted file mode 160000
index 0ddc49715c..0000000000
--- a/build/modules/premake-qt
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 0ddc49715c7892211774d4b5e705a7c5559aeed4
diff --git a/build/premake5.lua b/build/premake5.lua
index 7139ba02cd..f7b10fc24d 100644
--- a/build/premake5.lua
+++ b/build/premake5.lua
@@ -44,7 +44,7 @@ workspace "CppSharp"
workspacefiles(path.join(builddir, "premake5.lua"))
workspacefiles(path.join(builddir, "*.sh"))
workspacefiles(path.join(rootdir, ".github/workflows/*.yml"))
- workspacefiles(path.join(rootdir, "tests/Test*.props"))
+ workspacefiles(path.join(testsdir, "Test*.props"))
group "Libraries"
if EnableNativeProjects() then
diff --git a/docs/GettingStarted.md b/docs/GettingStarted.md
index ff8017b4a3..a6711727f0 100644
--- a/docs/GettingStarted.md
+++ b/docs/GettingStarted.md
@@ -35,27 +35,46 @@ make sure those are installed on your system.
## Compiling on Windows/Visual Studio
+The following steps should be called from the VS developer command prompt.
+
1. Generate the VS solution
```shell
cd \build
- ./build.sh generate -configuration Release -platform x64
+ build.sh generate -configuration Release -platform x64
```
+> :information_source: You can use the `-target-framework` option to target any valid .NET target framework.
+
2. Compile the VS projects
You can open `CppSharp.sln` and hit F5 or compile via the command line:
```
- ./build.sh -configuration Release -platform x64
+ build.sh -configuration Release -platform x64
```
Building in *Release* is recommended because else we will use the Clang parser
debug configuration, which will be too slow for practical use beyond debugging.
+The solution generated will be for Visual Studio 2019.
+
+If you have a more recent version of Visual Studio, you can either:
+- install Visual Studio 2019
+- install Visual Studio 2019 build tools, from [Visual Studio Installer](https://visualstudio.microsoft.com/downloads/)
+ - select the payload *MSVC v142 - VS 2019 C++ x64/x86 build tools (v14.29-16.11)*
+
+Please note that Windows isn't natively able to run sh scripts, to remediate this, you can either:
+
+- use the one from Visual Studio if present
+ - e.g. `C:\Program Files\Microsoft Visual Studio\2022\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\Git\usr\bin\sh.exe`
+- use the one from [Git for Windows](https://gitforwindows.org/)
+ - e.g. `C:\Program Files\Git\bin\sh.exe`
+
+When opening the solution for the first time on a more recent version than Visual Studio 2019, you will be prompted to retarget projects to one of the platform toolset available on your system.
+
## Compiling on macOS or Linux
-The following steps should be called from the VS developer command prompt.
1. Generate the VS solution and makefiles
@@ -65,6 +84,8 @@ The following steps should be called from the VS developer command prompt.
./build.sh generate -configuration Release -platform x64
```
+> :information_source: You can use the `-target-framework` option to target any valid .NET target framework.
+
2. Compile the csproj files and makefiles
```
diff --git a/docs/UsersManual.md b/docs/UsersManual.md
index bd4865f93d..0c45a91acb 100644
--- a/docs/UsersManual.md
+++ b/docs/UsersManual.md
@@ -39,6 +39,7 @@ There is also experimental support for these JavaScript-related targets:
- N-API (Node.js)
- QuickJS
- TypeScript
+- Emscripten
# 3. Native Targets
diff --git a/examples/Parser/Parser.cs b/examples/Parser/Parser.cs
index a39518cdd2..bbad7b6ce7 100644
--- a/examples/Parser/Parser.cs
+++ b/examples/Parser/Parser.cs
@@ -23,12 +23,12 @@ public static void Main(string[] args)
ParseSourceFile(file);
}
- public static bool ParseSourceFile(string file)
+ private static bool ParseSourceFile(string file)
{
// Lets setup the options for parsing the file.
var parserOptions = new ParserOptions
{
- LanguageVersion = LanguageVersion.CPP11,
+ LanguageVersion = LanguageVersion.CPP20_GNU,
// Verbose here will make sure the parser outputs some extra debugging
// information regarding include directories, which can be helpful when
@@ -37,13 +37,10 @@ public static bool ParseSourceFile(string file)
};
// This will setup the necessary system include paths and arguments for parsing.
- // It will probe into the registry (on Windows) and filesystem to find the paths
- // of the system toolchains and necessary include directories.
- parserOptions.Setup();
+ parserOptions.Setup(Platform.Host);
// We create the Clang parser and parse the source code.
- var parser = new ClangParser();
- var parserResult = parser.ParseSourceFile(file, parserOptions);
+ var parserResult = ClangParser.ParseSourceFile(file, parserOptions);
// If there was some kind of error parsing, then lets print some diagnostics.
if (parserResult.Kind != ParserResultKind.Success)
diff --git a/src/AST/ASTContext.cs b/src/AST/ASTContext.cs
index 9aafd38a23..827ce261f4 100644
--- a/src/AST/ASTContext.cs
+++ b/src/AST/ASTContext.cs
@@ -11,7 +11,8 @@ public enum CppAbi
Microsoft,
ARM,
iOS,
- iOS64
+ iOS64,
+ WebAssembly
}
///
diff --git a/src/AST/Class.cs b/src/AST/Class.cs
index 2b1206a7ff..535236e350 100644
--- a/src/AST/Class.cs
+++ b/src/AST/Class.cs
@@ -291,6 +291,11 @@ public Method FindMethodByUSR(string usr)
.FirstOrDefault(m => m.USR == usr);
}
+ public Variable FindVariable(string name)
+ {
+ return Variables.FirstOrDefault(m => m.Name == name);
+ }
+
public override T Visit(IDeclVisitor visitor)
{
return visitor.VisitClassDecl(this);
diff --git a/src/AST/ClassLayout.cs b/src/AST/ClassLayout.cs
index f22a278d92..06d97e47c8 100644
--- a/src/AST/ClassLayout.cs
+++ b/src/AST/ClassLayout.cs
@@ -31,14 +31,7 @@ public struct VTableComponent
public Declaration Declaration;
/// Method declaration (if Kind == FunctionPointer).
- public Method Method
- {
- get
- {
- Debug.Assert(Kind == VTableComponentKind.FunctionPointer);
- return Declaration as Method;
- }
- }
+ public Method Method => Declaration as Method;
}
///
diff --git a/src/AST/Declaration.cs b/src/AST/Declaration.cs
index 02176d6a87..2fc50d3122 100644
--- a/src/AST/Declaration.cs
+++ b/src/AST/Declaration.cs
@@ -189,15 +189,16 @@ public virtual string Name
public static string QualifiedNameSeparator = "::";
public string GetQualifiedName(Func getName,
- Func getNamespace)
+ Func getNamespace, bool getOriginal)
{
- if (Namespace == null)
+ DeclarationContext @namespace = getNamespace(this);
+ if (@namespace == null)
return getName(this);
- if (Namespace.IsRoot)
+ if (@namespace.IsRoot)
return getName(this);
- var namespaces = GatherNamespaces(getNamespace(this));
+ var namespaces = GatherNamespaces(@namespace, getOriginal);
var names = namespaces.Select(getName).ToList();
names.Add(getName(this));
@@ -206,7 +207,7 @@ public string GetQualifiedName(Func getName,
return string.Join(QualifiedNameSeparator, names);
}
- public static IEnumerable GatherNamespaces(DeclarationContext @namespace)
+ public static IEnumerable GatherNamespaces(DeclarationContext @namespace, bool getOriginal)
{
var namespaces = new Stack();
@@ -216,7 +217,7 @@ public static IEnumerable GatherNamespaces(DeclarationContext @name
var isInlineNamespace = currentNamespace is Namespace { IsInline: true };
if (!isInlineNamespace)
namespaces.Push(currentNamespace);
- currentNamespace = currentNamespace.Namespace;
+ currentNamespace = getOriginal ? currentNamespace.OriginalNamespace : currentNamespace.Namespace;
}
return namespaces;
@@ -226,7 +227,7 @@ public string QualifiedName
{
get
{
- return GetQualifiedName(decl => GetDeclName(decl, decl.Name), decl => decl.Namespace);
+ return GetQualifiedName(decl => GetDeclName(decl, decl.Name), decl => decl.Namespace, false);
}
}
@@ -235,7 +236,7 @@ public string QualifiedOriginalName
get
{
return GetQualifiedName(
- decl => GetDeclName(decl, decl.OriginalName), decl => decl.OriginalNamespace);
+ decl => GetDeclName(decl, decl.OriginalName), decl => decl.OriginalNamespace, true);
}
}
@@ -244,7 +245,7 @@ public string QualifiedLogicalName
get
{
return GetQualifiedName(
- decl => GetDeclName(decl, decl.LogicalName), decl => decl.Namespace);
+ decl => GetDeclName(decl, decl.LogicalName), decl => decl.Namespace, false);
}
}
@@ -253,7 +254,7 @@ public string QualifiedLogicalOriginalName
get
{
return GetQualifiedName(
- decl => GetDeclName(decl, decl.LogicalOriginalName), decl => decl.OriginalNamespace);
+ decl => GetDeclName(decl, decl.LogicalOriginalName), decl => decl.OriginalNamespace, true);
}
}
diff --git a/src/AST/Property.cs b/src/AST/Property.cs
index 9b78ea7dee..f0c469a3cb 100644
--- a/src/AST/Property.cs
+++ b/src/AST/Property.cs
@@ -22,109 +22,62 @@ public Property(Property property)
parameters.AddRange(property.Parameters);
}
- public Type Type
- {
- get { return QualifiedType.Type; }
- }
+ public Type Type => QualifiedType.Type;
public QualifiedType QualifiedType { get; set; }
- public bool IsStatic
- {
- get
- {
- return (GetMethod != null && GetMethod.IsStatic) ||
- (SetMethod != null && SetMethod.IsStatic);
- }
- }
+ public bool IsStatic =>
+ GetMethod is {IsStatic: true} ||
+ SetMethod is {IsStatic: true};
- public bool IsPure
- {
- get
- {
- return (GetMethod != null && GetMethod.IsPure) ||
- (SetMethod != null && SetMethod.IsPure);
- }
- }
+ public bool IsPure =>
+ GetMethod is {IsPure: true} ||
+ SetMethod is {IsPure: true};
- public bool IsVirtual
- {
- get
- {
- return (GetMethod != null && GetMethod.IsVirtual) ||
- (SetMethod != null && SetMethod.IsVirtual);
- }
- }
+ public bool IsVirtual =>
+ GetMethod is {IsVirtual: true} ||
+ SetMethod is {IsVirtual: true};
- public bool IsOverride
- {
- get
- {
- return (GetMethod != null && GetMethod.IsOverride) ||
- (SetMethod != null && SetMethod.IsOverride);
- }
- }
+ public bool IsOverride =>
+ GetMethod is {IsOverride: true} ||
+ SetMethod is {IsOverride: true};
public Method GetMethod { get; set; }
public Method SetMethod { get; set; }
- public bool HasGetter
- {
- get
- {
- return (GetMethod != null &&
- GetMethod.GenerationKind != GenerationKind.None) ||
- (Field != null &&
- Field.GenerationKind != GenerationKind.None);
- }
- }
+ public bool HasGetter =>
+ (GetMethod != null &&
+ GetMethod.GenerationKind != GenerationKind.None) ||
+ (Field != null &&
+ Field.GenerationKind != GenerationKind.None);
- public bool HasSetter
- {
- get
- {
- return (SetMethod != null &&
- SetMethod.GenerationKind != GenerationKind.None) ||
- (Field != null &&
- (!Field.QualifiedType.IsConst() ||
- Field.Type.IsConstCharString()) &&
- Field.GenerationKind != GenerationKind.None);
- }
- }
+ public bool HasSetter =>
+ (SetMethod != null &&
+ SetMethod.GenerationKind != GenerationKind.None) ||
+ (Field != null &&
+ (!Field.QualifiedType.IsConst() ||
+ Field.Type.IsConstCharString()) &&
+ Field.GenerationKind != GenerationKind.None);
// The field that should be get and set by this property
public Field Field { get; set; }
public Class ExplicitInterfaceImpl { get; set; }
- private readonly List parameters = new List();
+ private readonly List parameters = new();
///
/// Only applicable to index ([]) properties.
///
- public List Parameters
- {
- get { return parameters; }
- }
+ public List Parameters => parameters;
- public bool IsIndexer
- {
- get
- {
- return GetMethod != null &&
- GetMethod.OperatorKind == CXXOperatorKind.Subscript;
- }
- }
+ public bool IsIndexer =>
+ GetMethod is {OperatorKind: CXXOperatorKind.Subscript};
- public bool IsSynthetized
- {
- get
- {
- return (GetMethod != null && GetMethod.IsSynthetized) ||
- (SetMethod != null && SetMethod.IsSynthetized);
- }
- }
+ public bool IsSynthetized =>
+ (GetMethod != null && GetMethod.IsSynthetized) ||
+ (SetMethod != null && SetMethod.IsSynthetized);
public override T Visit(IDeclVisitor visitor)
{
diff --git a/src/AST/Template.cs b/src/AST/Template.cs
index 062254ee80..e71ee5b815 100644
--- a/src/AST/Template.cs
+++ b/src/AST/Template.cs
@@ -124,6 +124,8 @@ public class NonTypeTemplateParameter : Declaration
///
public bool IsExpandedParameterPack { get; set; }
+ public QualifiedType Type { get; set; }
+
public override T Visit(IDeclVisitor visitor)
{
return visitor.VisitNonTypeTemplateParameterDecl(this);
diff --git a/src/AST/Type.cs b/src/AST/Type.cs
index 831b9f677b..d686f5d9a3 100644
--- a/src/AST/Type.cs
+++ b/src/AST/Type.cs
@@ -30,7 +30,7 @@ public abstract T Visit(ITypeVisitor visitor, TypeQualifiers quals
public override string ToString()
{
- return TypePrinterDelegate(this);
+ return TypePrinterDelegate == null ? base.ToString() : TypePrinterDelegate(this);
}
public abstract object Clone();
diff --git a/src/AST/TypeExtensions.cs b/src/AST/TypeExtensions.cs
index eb447d09fa..32333d6e6b 100644
--- a/src/AST/TypeExtensions.cs
+++ b/src/AST/TypeExtensions.cs
@@ -92,6 +92,25 @@ public static bool IsPointerToPrimitiveType(this Type t, PrimitiveType primitive
return ptr.Pointee.IsPrimitiveType(primitive);
}
+ public static bool IsPointerToEnum(this Type t)
+ {
+ var ptr = t as PointerType;
+ if (ptr == null)
+ return false;
+ return ptr.Pointee.IsEnumType();
+ }
+
+ public static bool IsPointerToEnum(this Type t, out Enumeration @enum)
+ {
+ var ptr = t as PointerType;
+ if (ptr == null)
+ {
+ @enum = null;
+ return false;
+ }
+ return ptr.Pointee.TryGetEnum(out @enum);
+ }
+
public static bool IsPointerTo(this Type t, out T type) where T : Type
{
var pointee = t.GetPointee();
diff --git a/src/ASTViewer/AstModel.cpp b/src/ASTViewer/AstModel.cpp
deleted file mode 100644
index e0d8a388d9..0000000000
--- a/src/ASTViewer/AstModel.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-#include "AstModel.h"
-#include
-
-
-AstModel::AstModel(GenericAstNode *data, QObject *parent):
- QAbstractItemModel(parent),
- rootItem(data)
-{
-}
-
-AstModel::~AstModel()
-{
-}
-
-int AstModel::columnCount(const QModelIndex &parent) const
-{
- return 1;
-}
-
-QVariant AstModel::data(const QModelIndex &index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- if (role != Qt::DisplayRole && role != Qt::ForegroundRole && role != Qt::NodeRole)
- return QVariant();
-
- auto item = static_cast(index.internalPointer());
- switch (role)
- {
- case Qt::DisplayRole:
- return QVariant(QString::fromStdString(item->name));
- case Qt::ForegroundRole:
- switch (item->getColor())
- {
- case 0:
- return QVariant(QBrush(Qt::GlobalColor::darkBlue));
- case 1:
- return QVariant(QBrush(Qt::GlobalColor::darkGreen));
- default:
- return QVariant(QBrush(Qt::GlobalColor::black));
- }
- case Qt::NodeRole:
- return QVariant::fromValue(item);
- }
- return QVariant(QString::fromStdString(item->name));
-}
-
-Qt::ItemFlags AstModel::flags(const QModelIndex &index) const
-{
- if (!index.isValid())
- return 0;
-
- return QAbstractItemModel::flags(index);
-}
-
-QVariant AstModel::headerData(int section, Qt::Orientation orientation, int role) const
-{
- if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
- return QVariant("Test");
-
- return QVariant();
-}
-
-QModelIndex AstModel::index(int row, int column, const QModelIndex &parent) const
-{
- if (!hasIndex(row, column, parent))
- return QModelIndex();
-
-
- if (!parent.isValid())
- {
- return rootIndex();
- }
-
- auto parentItem = static_cast(parent.internalPointer());
- auto &childItem = parentItem->myChidren[row];
- if (childItem)
- return createIndex(row, column, childItem.get());
- else
- return QModelIndex();
-}
-
-QModelIndex AstModel::rootIndex() const
-{
- return createIndex(0, 0, rootItem);
-}
-
-QModelIndex AstModel::parent(const QModelIndex &index) const
-{
- if (!index.isValid())
- return QModelIndex();
-
- GenericAstNode *childItem = static_cast(index.internalPointer());
- if (childItem == rootItem || childItem->myParent == nullptr)
- return QModelIndex();
-
- GenericAstNode *parentItem = childItem->myParent;
-
- if (parentItem == rootItem)
- return rootIndex();
- auto grandFather = parentItem->myParent;
- auto parentRow = grandFather == nullptr ?
- 0 :
- grandFather->findChildIndex(parentItem);
-
- return createIndex(parentRow, 0, parentItem);
-}
-
-int AstModel::rowCount(const QModelIndex &parent) const
-{
- GenericAstNode *parentItem;
- if (parent.column() > 0)
- return 0;
-
- if (parent.isValid())
- {
- parentItem = static_cast(parent.internalPointer());
- return parentItem->myChidren.size();
- }
- else
- {
- return 1;
- }
-}
-
-bool AstModel::hasChildren(const QModelIndex &parent) const
-{
- GenericAstNode *parentItem;
- if (parent.column() > 0)
- return false;
-
- if (parent.isValid())
- parentItem = static_cast(parent.internalPointer());
- else
- parentItem = rootItem;
-
- return !parentItem->myChidren.empty();
-
-}
-
diff --git a/src/ASTViewer/AstModel.h b/src/ASTViewer/AstModel.h
deleted file mode 100644
index 3c6c46a56b..0000000000
--- a/src/ASTViewer/AstModel.h
+++ /dev/null
@@ -1,35 +0,0 @@
-#pragma once
-
-#include
-#include "AstReader.h"
-
-namespace Qt
-{
-int const NodeRole = UserRole + 1;
-}
-
-Q_DECLARE_METATYPE(GenericAstNode*)
-
-class AstModel : public QAbstractItemModel
-{
- Q_OBJECT
-
-public:
- explicit AstModel(GenericAstNode *data, QObject *parent = 0);
- ~AstModel();
-
- QVariant data(const QModelIndex &index, int role) const override;
- Qt::ItemFlags flags(const QModelIndex &index) const override;
- QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
- QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
- QModelIndex parent(const QModelIndex &index) const override;
- int rowCount(const QModelIndex &parent = QModelIndex()) const override;
- int columnCount(const QModelIndex &parent = QModelIndex()) const override;
- QModelIndex rootIndex() const;
- bool hasChildren(const QModelIndex &parent = QModelIndex()) const override;
-
-private:
- void setupModelData(const QStringList &lines, GenericAstNode *parent);
-
- GenericAstNode *rootItem;
-};
\ No newline at end of file
diff --git a/src/ASTViewer/AstReader.cpp b/src/ASTViewer/AstReader.cpp
deleted file mode 100644
index 4b07a8edad..0000000000
--- a/src/ASTViewer/AstReader.cpp
+++ /dev/null
@@ -1,543 +0,0 @@
-#include "AstReader.h"
-#include
-#include "CommandLineSplitter.h"
-#include
-#include "ClangUtilities/StringLiteralExtractor.h"
-#include "ClangUtilities/TemplateUtilities.h"
-
-
-#pragma warning (push)
-#pragma warning (disable:4100 4127 4800 4512 4245 4291 4510 4610 4324 4267 4244 4996)
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#pragma warning (pop)
-
-using namespace clang;
-
-namespace props
-{
- std::string const Name = "Name";
- std::string const Mangling = "Mangling";
- std::string const Referenced = "Referenced name";
- std::string const Resolved = "Resolved name";
- std::string const Value = "Value";
- std::string const InterpretedValue = "Interpreted value";
- std::string const IsTemplateDecl = "Is template declaration";
- std::string const IsGenerated = "Generated";
- std::string const Type = "Type";
-}
-
-
-CFG::BuildOptions getCFGBuildOptions()
-{
- CFG::BuildOptions cfgBuildOptions; // TODO: Initialize it correctly
- cfgBuildOptions.AddImplicitDtors = true;
- cfgBuildOptions.AddTemporaryDtors = true;
- cfgBuildOptions.AddCXXDefaultInitExprInCtors = true;
- cfgBuildOptions.AddInitializers = true;
- return cfgBuildOptions;
-}
-
-std::string getCFG(clang::FunctionDecl const *FD)
-{
- try
- {
- auto& astContext = FD->getASTContext();
- auto cfgBuildOptions = getCFGBuildOptions();
- auto cfg = CFG::buildCFG(FD, FD->getBody(), &astContext, cfgBuildOptions);
- if (!cfg)
- return "";
- std::string dumpBuf;
- llvm::raw_string_ostream dumpBufOS(dumpBuf);
-
- cfg->print(dumpBufOS, astContext.getLangOpts(), false);
- auto dumped = dumpBufOS.str();
- return dumped;
- }
- catch (std::exception &e)
- {
- return std::string("";
- }
-}
-
-
-
-GenericAstNode::GenericAstNode() :
-myParent(nullptr), hasDetails(false)
-{
-
-}
-
-int GenericAstNode::findChildIndex(GenericAstNode *node)
-{
- auto it = std::find_if(myChidren.begin(), myChidren.end(), [node](std::unique_ptr const & n){return n.get() == node; });
- return it == myChidren.end() ?
- -1 :
- it - myChidren.begin();
-}
-
-void GenericAstNode::attach(std::unique_ptr child)
-{
- child->myParent = this;
- myChidren.push_back(std::move(child));
-}
-
-//struct SourceRangeVisitor : boost::static_visitor
-//{
-// template
-// SourceRange operator()(T const *t) const
-// {
-// if (t == nullptr)
-// return SourceRange();
-// return t->getSourceRange();
-// }
-//};
-
-SourceRange GenericAstNode::getRange()
-{
- //return boost::apply_visitor(SourceRangeVisitor(), myAstNode);
- return SourceRange();
-}
-
-bool GenericAstNode::getRangeInMainFile(std::pair &result, clang::SourceManager const &manager, clang::ASTContext &context)
-{
- auto range = getRange();
- if (range.isInvalid())
- {
- return false;
- }
- auto start = manager.getDecomposedSpellingLoc(range.getBegin());
- auto end = manager.getDecomposedSpellingLoc(clang::Lexer::getLocForEndOfToken(range.getEnd(), 0, manager, context.getLangOpts()));
- if (start.first != end.first || start.first != manager.getMainFileID())
- {
- //Not in the same file, or not in the main file (probably #included)
- return false;
- }
- result = std::make_pair(start.second, end.second);
- return true;
-}
-
-
-//struct NodeColorVisitor : boost::static_visitor
-//{
-// int operator()(Decl const *) const
-// {
-// return 0;
-// }
-// int operator()(Stmt const *) const
-// {
-// return 1;
-// }
-//};
-
-int GenericAstNode::getColor()
-{
- //return boost::apply_visitor(NodeColorVisitor(), myAstNode);
- return 0;
-}
-
-
-void GenericAstNode::setProperty(std::string const &propertyName, std::string const &value)
-{
- myProperties[propertyName] = value;
-}
-
-GenericAstNode::Properties const &GenericAstNode::getProperties() const
-{
- return myProperties;
-}
-
-
-
-
-class AstDumpVisitor : public RecursiveASTVisitor
-{
-public:
- using PARENT = clang::RecursiveASTVisitor;
- AstDumpVisitor(clang::ASTContext &context, GenericAstNode *rootNode) :
- myRootNode(rootNode),
- myAstContext(context)
- {
- myStack.push_back(myRootNode);
- }
-
- bool shouldVisitTemplateInstantiations() const
- {
- return true;
- }
-
- bool shouldVisitImplicitCode() const
- {
- return true;
- }
-
- std::string getMangling(clang::NamedDecl const *ND)
- {
- if (auto funcContext = dyn_cast(ND->getDeclContext()))
- {
- if (funcContext->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate)
- {
- return "";
- }
- }
-
- std::vector containers;
- auto currentElement = dyn_cast(ND->getDeclContext());
- while (currentElement)
- {
- containers.push_back(currentElement);
- currentElement = dyn_cast(currentElement->getDeclContext());
- }
- for (auto tag : containers)
- {
- if (auto partialSpe = dyn_cast(tag))
- {
- return "getNameAsString() + ": " + ND->getNameAsString() + ">";
- }
- else if (auto recContext = dyn_cast(tag))
- {
- if (recContext->getDescribedClassTemplate() != nullptr)
- {
- return "getNameAsString() + ": " + ND->getNameAsString() + ">";
- }
- }
- }
-
- auto mangleContext = std::unique_ptr{ND->getASTContext().createMangleContext()};
- std::string FrontendBuf;
- llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
-
- if (auto ctor = dyn_cast(ND))
- {
- mangleContext->mangleCXXCtor(ctor, CXXCtorType::Ctor_Complete, FrontendBufOS);
- }
- else if (auto dtor = dyn_cast(ND))
- {
- mangleContext->mangleCXXDtor(dtor, CXXDtorType::Dtor_Complete, FrontendBufOS);
- }
- else if (mangleContext->shouldMangleDeclName(ND) && !isa(ND))
- {
- mangleContext->mangleName(ND, FrontendBufOS);
- }
- else
- {
- return ND->getNameAsString();
- }
- return FrontendBufOS.str();
- }
-
-
- bool TraverseDecl(clang::Decl *decl)
- {
- if (decl == nullptr)
- {
- return PARENT::TraverseDecl(decl);
- }
- auto node = std::make_unique();
- node->myAstNode = decl;
- node->name = decl->getDeclKindName() + std::string("Decl"); // Try to mimick clang default dump
- if (auto *FD = dyn_cast(decl))
- {
-#ifndef NDEBUG
- auto &mngr = FD->getASTContext().getSourceManager();
- auto fileName = mngr.getFilename(FD->getLocation()).str();
- bool invalid;
- auto startingLine = mngr.getExpansionLineNumber(FD->getLocation(), &invalid);
-
- std::string FrontendBuf;
- llvm::raw_string_ostream FrontendBufOS(FrontendBuf);
- clang::PrintingPolicy policyForDebug(FD->getASTContext().getLangOpts());
- FD->getNameForDiagnostic(FrontendBufOS, policyForDebug, true);
- auto debugName = FrontendBufOS.str();
-
- RecordDecl const*containingClass = nullptr;
- if (FD->isCXXClassMember())
- {
- auto methodDecl = cast(FD);
- containingClass = cast(methodDecl->getDeclContext());
- }
-#endif
-
- node->name += " " + clang_utilities::getFunctionPrototype(FD, false);
- if (FD->getTemplatedKind() != FunctionDecl::TK_FunctionTemplate)
- {
- node->setProperty(props::Mangling, getMangling(FD));
- }
- node->setProperty(props::Name, clang_utilities::getFunctionPrototype(FD, true));
- if (auto *MD = dyn_cast(FD))
- {
- node->setProperty(props::IsGenerated, MD->isUserProvided() ? "False" : "True");
-
- }
- node->hasDetails = true;
- node->detailsTitle = "Control flow graph";
- node->detailsComputer = [FD]() {return getCFG(FD); };
- }
- else if (auto *PVD = dyn_cast(decl))
- {
- if (auto *PFD = dyn_cast_or_null(decl->getParentFunctionOrMethod()))
- {
- if (PFD->getTemplatedKind() != FunctionDecl::TK_FunctionTemplate)
- {
- node->setProperty(props::Mangling, getMangling(PFD));
- }
- }
- else
- {
- node->setProperty(props::Mangling, getMangling(PVD));
- }
- node->setProperty(props::Name, PVD->getNameAsString());
- }
- else if (auto *VD = dyn_cast(decl))
- {
- //node->setProperty(props::Mangling, getMangling(VD));
- node->setProperty(props::Name, VD->getNameAsString());
- node->setProperty(props::Type, clang_utilities::getTypeName(VD->getType(), true));
- }
- else if (auto *ECD = dyn_cast(decl))
- {
- node->setProperty(props::Name, ECD->getNameAsString());
- node->setProperty(props::Value, ECD->getInitVal().toString(10));
- }
- else if (auto *tag = dyn_cast(decl))
- {
- std::string nameBuf;
- llvm::raw_string_ostream os(nameBuf);
-
- if (TypedefNameDecl *Typedef = tag->getTypedefNameForAnonDecl())
- os << Typedef->getIdentifier()->getName();
- else if (tag->getIdentifier())
- os << tag->getIdentifier()->getName();
- else
- os << "No name";
-
- if (auto templateInstance = dyn_cast(tag))
- {
- clang::PrintingPolicy policy(templateInstance->getASTContext().getLangOpts());
- clang_utilities::printTemplateArguments(os, policy, &templateInstance->getTemplateArgs(), false);
- }
- node->name += " " + tag->getNameAsString();
- node->setProperty(props::Name, os.str());
- }
- else if (auto *ND = dyn_cast(decl))
- {
-
-
- node->name += " " + ND->getNameAsString();
- node->setProperty(props::Name, ND->getNameAsString());
- }
-
- auto nodePtr = node.get();
- myStack.back()->attach(std::move(node));
- myStack.push_back(nodePtr);
- auto res = PARENT::TraverseDecl(decl);
- myStack.pop_back();
- return res;
- }
-
- bool TraverseStmt(clang::Stmt *stmt)
- {
- if (stmt == nullptr)
- {
- return PARENT::TraverseStmt(stmt);
- }
- auto node = std::make_unique();
- node->myAstNode = stmt;
- node->name = stmt->getStmtClassName();
- auto nodePtr = node.get();
- myStack.back()->attach(std::move(node));
- myStack.push_back(nodePtr);
- auto res = PARENT::TraverseStmt(stmt);
- myStack.pop_back();
- return res;
- }
-
- bool VisitStringLiteral(clang::StringLiteral *s)
- {
- myStack.back()->name += (" " + s->getBytes()).str();
- myStack.back()->setProperty(props::InterpretedValue, s->getBytes());
- auto parts = clang_utilities::splitStringLiteral(s, myAstContext.getSourceManager(), myAstContext.getLangOpts(), myAstContext.getTargetInfo());
- if (parts.size() == 1)
- {
- myStack.back()->setProperty(props::Value, parts[0]);
-
- }
- else
- {
- int i = 0;
- for (auto &part : parts)
- {
- ++i;
- myStack.back()->setProperty(props::Value + " " + std::to_string(i), part);
-
- }
- }
- return true;
- }
-
- bool VisitIntegerLiteral(clang::IntegerLiteral *i)
- {
- bool isSigned = i->getType()->isSignedIntegerType();
- myStack.back()->setProperty(props::Value, i->getValue().toString(10, isSigned));
- return true;
- }
-
- bool VisitCharacterLiteral(clang::CharacterLiteral *c)
- {
- myStack.back()->setProperty(props::Value, std::string(1, c->getValue()));
- return true;
- }
-
- bool VisitFloatingLiteral(clang::FloatingLiteral *f)
- {
- myStack.back()->setProperty(props::Value, std::to_string(f->getValueAsApproximateDouble()));
- return true;
- }
-
- bool VisitCXXRecordDecl(clang::CXXRecordDecl *r)
- {
- myStack.back()->setProperty(props::IsTemplateDecl, std::to_string(r->getDescribedClassTemplate() != nullptr));
- return true;
- }
-
-
- void addReference(GenericAstNode *node, clang::NamedDecl *referenced, std::string const &label)
- {
- auto funcDecl = dyn_cast(referenced);
- myStack.back()->setProperty(label, funcDecl == nullptr ?
- referenced->getNameAsString() :
- clang_utilities::getFunctionPrototype(funcDecl, false));
- }
-
- bool VisitDeclRefExpr(clang::DeclRefExpr *ref)
- {
- addReference(myStack.back(), ref->getDecl(), props::Referenced);
- addReference(myStack.back(), ref->getFoundDecl(), props::Resolved);
-
- return true;
- }
-
- bool TraverseType(clang::QualType type)
- {
- if (type.isNull())
- {
- return PARENT::TraverseType(type);
- }
- auto node = std::make_unique();
- //node->myType = d;
- node->name = type->getTypeClassName();
- auto nodePtr = node.get();
- myStack.back()->attach(std::move(node));
- myStack.push_back(nodePtr);
- auto res = PARENT::TraverseType(type);
- myStack.pop_back();
- return res;
- }
-
-private:
- std::vector myStack;
- GenericAstNode *myRootNode;
- ASTContext &myAstContext;
-};
-
-
-AstReader::AstReader() : isReady(false)
-{
-}
-
-clang::SourceManager &AstReader::getManager()
-{
- return myAst->getSourceManager();
-}
-
-clang::ASTContext &AstReader::getContext()
-{
- return myAst->getASTContext();
-}
-
-GenericAstNode *AstReader::getRealRoot()
-{
- return myArtificialRoot->myChidren.front().get();
-}
-
-GenericAstNode *AstReader::findPosInChildren(std::vector> const &candidates, int position)
-{
- for (auto &candidate : candidates)
- {
- std::pair location;
- if (!candidate->getRangeInMainFile(location, getManager(), getContext()))
- {
- continue;
- }
- if (location.first <= position && position <= location.second)
- {
- return candidate.get();
- }
- }
- return nullptr;
-}
-
-std::vector AstReader::getBestNodeMatchingPosition(int position)
-{
- std::vector result;
- auto currentNode = getRealRoot();
- result.push_back(currentNode);
- currentNode = currentNode->myChidren[0].get();
- result.push_back(currentNode); // Translation unit does not have position
- while (true)
- {
- auto bestChild = findPosInChildren(currentNode->myChidren, position);
- if (bestChild == nullptr)
- {
- return result;
- }
- result.push_back(bestChild);
- currentNode = bestChild;
- }
-}
-
-GenericAstNode *AstReader::readAst(std::string const &sourceCode, std::string const &options)
-{
- mySourceCode = sourceCode;
- myArtificialRoot = std::make_unique();
- auto root = std::make_unique();
- root->name = "AST";
- myArtificialRoot->attach(std::move(root));
-
- auto args = splitCommandLine(options);
-
- std::cout << "Launching Clang to create AST" << std::endl;
- //myAst = clang::tooling::buildASTFromCodeWithArgs(mySourceCode, args);
- myAst = nullptr;
- if (myAst != nullptr)
- {
- for (auto it = myAst->top_level_begin(); it != myAst->top_level_end(); ++it)
- {
- //(*it)->dumpColor();
- }
- std::cout << "Visiting AST and creating Qt Tree" << std::endl;
- auto visitor = AstDumpVisitor{ myAst->getASTContext(), getRealRoot() };
- visitor.TraverseDecl(myAst->getASTContext().getTranslationUnitDecl());
- }
- isReady = true;
- return myArtificialRoot.get();
-}
-
-bool AstReader::ready()
-{
- return isReady;
-}
-
-void AstReader::dirty()
-{
- isReady = false;
-}
-
diff --git a/src/ASTViewer/AstReader.h b/src/ASTViewer/AstReader.h
deleted file mode 100644
index 3796aa9b22..0000000000
--- a/src/ASTViewer/AstReader.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#pragma once
-
-#pragma warning (push)
-#pragma warning (disable:4100 4127 4800 4512 4245 4291 4510 4610 4324 4267 4244 4996)
-#include "clang/Frontend/TextDiagnosticBuffer.h"
-#include "clang/Tooling/CommonOptionsParser.h"
-#include "clang/Tooling/Tooling.h"
-#include "llvm/Support/CommandLine.h"
-#include "clang/Basic/SourceLocation.h"
-#pragma warning(pop)
-#include
-#include
-
-
-class GenericAstNode
-{
-public:
- GenericAstNode();
- int findChildIndex(GenericAstNode *node); // Return -1 if not found
- void attach(std::unique_ptr child);
- std::string name;
- std::vector> myChidren;
- bool getRangeInMainFile(std::pair &result, clang::SourceManager const &manager, clang::ASTContext &context); // Return false if the range is not fully in the main file
- clang::SourceRange getRange();
- int getColor(); // Will return a color identifier How this is linked to the real color is up to the user
- using Properties = std::map;
- void setProperty(std::string const &propertyName, std::string const &value);
- Properties const &getProperties() const;
- std::variant myAstNode;
- GenericAstNode *myParent;
-
- bool hasDetails;
- std::string detailsTitle;
- std::string details;
- std::function detailsComputer;
-
-private:
- Properties myProperties;
-};
-
-class AstReader
-{
-public:
- AstReader();
- GenericAstNode *readAst(std::string const &sourceCode, std::string const &options);
- clang::SourceManager &getManager();
- clang::ASTContext &getContext();
- GenericAstNode *getRealRoot();
- std::vector getBestNodeMatchingPosition(int position); // Return the path from root to the node
- bool ready();
- void dirty(); // Ready will be false until the reader is run again
-private:
- GenericAstNode *findPosInChildren(std::vector> const &candidates, int position);
- std::string args;
- std::string mySourceCode; // Needs to stay alive while we navigate the tree
- std::unique_ptr myAst;
- std::unique_ptr myArtificialRoot; // We need an artificial root on top of the real root, because the root is not displayed by Qt
- bool isReady;
-};
-
diff --git a/src/ASTViewer/ClangUtilities/StringLiteralExtractor.cpp b/src/ASTViewer/ClangUtilities/StringLiteralExtractor.cpp
deleted file mode 100644
index 70f601270d..0000000000
--- a/src/ASTViewer/ClangUtilities/StringLiteralExtractor.cpp
+++ /dev/null
@@ -1,304 +0,0 @@
-#include "StringLiteralExtractor.h"
-
-#pragma warning (push)
-#pragma warning (disable:4100 4127 4800 4512 4245 4291 4510 4610 4324 4267 4244 4996 4146)
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#pragma warning (pop)
-
-using namespace llvm;
-using namespace clang;
-
-namespace clang_utilities {
-
-// This function is an direct adaptation from ProcessCharEscape in llvm-3.7.1\src\tools\clang\lib\Lex\LiteralSupport.cpp (just removed the diag part)
-unsigned ProcessCharEscape(const char *ThisTokBegin,
- const char *&ThisTokBuf,
- const char *ThisTokEnd, bool &HadError,
- FullSourceLoc Loc, unsigned CharWidth,
- const LangOptions &Features)
-{
- // Skip the '\' char.
- ++ThisTokBuf;
-
- // We know that this character can't be off the end of the buffer, because
- // that would have been \", which would not have been the end of string.
- unsigned ResultChar = *ThisTokBuf++;
- switch (ResultChar) {
- // These map to themselves.
- case '\\': case '\'': case '"': case '?': break;
-
- // These have fixed mappings.
- case 'a':
- // TODO: K&R: the meaning of '\\a' is different in traditional C
- ResultChar = 7;
- break;
- case 'b':
- ResultChar = 8;
- break;
- case 'e':
- ResultChar = 27;
- break;
- case 'E':
- ResultChar = 27;
- break;
- case 'f':
- ResultChar = 12;
- break;
- case 'n':
- ResultChar = 10;
- break;
- case 'r':
- ResultChar = 13;
- break;
- case 't':
- ResultChar = 9;
- break;
- case 'v':
- ResultChar = 11;
- break;
- case 'x': { // Hex escape.
- ResultChar = 0;
- if (ThisTokBuf == ThisTokEnd || !isHexDigit(*ThisTokBuf)) {
- HadError = 1;
- break;
- }
-
- // Hex escapes are a maximal series of hex digits.
- bool Overflow = false;
- for (; ThisTokBuf != ThisTokEnd; ++ThisTokBuf) {
- int CharVal = llvm::hexDigitValue(ThisTokBuf[0]);
- if (CharVal == -1) break;
- // About to shift out a digit?
- if (ResultChar & 0xF0000000)
- Overflow = true;
- ResultChar <<= 4;
- ResultChar |= CharVal;
- }
-
- // See if any bits will be truncated when evaluated as a character.
- if (CharWidth != 32 && (ResultChar >> CharWidth) != 0) {
- Overflow = true;
- ResultChar &= ~0U >> (32 - CharWidth);
- }
-
- // Check for overflow.
- break;
- }
- case '0': case '1': case '2': case '3':
- case '4': case '5': case '6': case '7': {
- // Octal escapes.
- --ThisTokBuf;
- ResultChar = 0;
-
- // Octal escapes are a series of octal digits with maximum length 3.
- // "\0123" is a two digit sequence equal to "\012" "3".
- unsigned NumDigits = 0;
- do {
- ResultChar <<= 3;
- ResultChar |= *ThisTokBuf++ - '0';
- ++NumDigits;
- } while (ThisTokBuf != ThisTokEnd && NumDigits < 3 &&
- ThisTokBuf[0] >= '0' && ThisTokBuf[0] <= '7');
-
- // Check for overflow. Reject '\777', but not L'\777'.
- if (CharWidth != 32 && (ResultChar >> CharWidth) != 0) {
- ResultChar &= ~0U >> (32 - CharWidth);
- }
- break;
- }
-
- // Otherwise, these are not valid escapes.
- case '(': case '{': case '[': case '%':
- // GCC accepts these as extensions. We warn about them as such though.
- break;
- default:
- break;
- }
- return ResultChar;
-}
-
-
-// This function is an direct adaptation from ProcessUCNEscape in llvm-3.7.1\src\tools\clang\lib\Lex\LiteralSupport.cpp (just removed the diag part)
-bool ProcessUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf,
- const char *ThisTokEnd,
- uint32_t &UcnVal, unsigned short &UcnLen,
- FullSourceLoc Loc,
- const LangOptions &Features,
- bool in_char_string_literal) {
- const char *UcnBegin = ThisTokBuf;
-
- // Skip the '\u' char's.
- ThisTokBuf += 2;
-
- if (ThisTokBuf == ThisTokEnd || !isHexDigit(*ThisTokBuf)) {
- return false;
- }
- UcnLen = (ThisTokBuf[-1] == 'u' ? 4 : 8);
- unsigned short UcnLenSave = UcnLen;
- for (; ThisTokBuf != ThisTokEnd && UcnLenSave; ++ThisTokBuf, UcnLenSave--) {
- int CharVal = llvm::hexDigitValue(ThisTokBuf[0]);
- if (CharVal == -1) break;
- UcnVal <<= 4;
- UcnVal |= CharVal;
- }
- // If we didn't consume the proper number of digits, there is a problem.
- if (UcnLenSave) {
- return false;
- }
-
- // Check UCN constraints (C99 6.4.3p2) [C++11 lex.charset p2]
- if ((0xD800 <= UcnVal && UcnVal <= 0xDFFF) || // surrogate codepoints
- UcnVal > 0x10FFFF) { // maximum legal UTF32 value
- return false;
- }
-
- // C++11 allows UCNs that refer to control characters and basic source
- // characters inside character and string literals
- if (UcnVal < 0xa0 &&
- (UcnVal != 0x24 && UcnVal != 0x40 && UcnVal != 0x60)) { // $, @, `
- bool IsError = (!Features.CPlusPlus11 || !in_char_string_literal);
- if (IsError)
- return false;
- }
- return true;
-}
-
-// This function is an direct adaptation from ProcessUCNEscape in llvm-3.7.1\src\tools\clang\lib\Lex\LiteralSupport.cpp (just removed the diag part)
-int MeasureUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf,
- const char *ThisTokEnd, unsigned CharByteWidth,
- const LangOptions &Features, bool &HadError) {
- // UTF-32: 4 bytes per escape.
- if (CharByteWidth == 4)
- return 4;
-
- uint32_t UcnVal = 0;
- unsigned short UcnLen = 0;
- FullSourceLoc Loc;
-
- if (!ProcessUCNEscape(ThisTokBegin, ThisTokBuf, ThisTokEnd, UcnVal,
- UcnLen, Loc, Features, true)) {
- HadError = true;
- return 0;
- }
-
- // UTF-16: 2 bytes for BMP, 4 bytes otherwise.
- if (CharByteWidth == 2)
- return UcnVal <= 0xFFFF ? 2 : 4;
-
- // UTF-8.
- if (UcnVal < 0x80)
- return 1;
- if (UcnVal < 0x800)
- return 2;
- if (UcnVal < 0x10000)
- return 3;
- return 4;
-}
-
-
-
-// This function is just the same as convertUTF16ToUTF8String, but adapted to UTF32, since it did not exist in clang
-bool convertUTF32ToUTF8String(ArrayRef SrcBytes, std::string &Out) {
- assert(Out.empty());
-
- // Error out on an uneven byte count.
- if (SrcBytes.size() % 4)
- return false;
-
- // Avoid OOB by returning early on empty input.
- if (SrcBytes.empty())
- return true;
-
- const UTF32 *Src = reinterpret_cast(SrcBytes.begin());
- const UTF32 *SrcEnd = reinterpret_cast(SrcBytes.end());
-
- // Byteswap if necessary.
- // Ignore any potential BOM: We won't have the here...
-
- // Just allocate enough space up front. We'll shrink it later. Allocate
- // enough that we can fit a null terminator without reallocating.
- Out.resize(SrcBytes.size() * UNI_MAX_UTF8_BYTES_PER_CODE_POINT + 1);
- UTF8 *Dst = reinterpret_cast(&Out[0]);
- UTF8 *DstEnd = Dst + Out.size();
-
- ConversionResult CR =
- ConvertUTF32toUTF8(&Src, SrcEnd, &Dst, DstEnd, strictConversion);
- assert(CR != targetExhausted);
-
- if (CR != conversionOK) {
- Out.clear();
- return false;
- }
-
- Out.resize(reinterpret_cast(Dst)-&Out[0]);
- Out.push_back(0);
- Out.pop_back();
- return true;
-}
-
-
-// This function is an adaptation from StringLiteral::getLocationOfByte in llvm-3.7.1\src\tools\clang\lib\AST\Expr.cpp
-std::vector
-splitStringLiteral(clang::StringLiteral *S, const SourceManager &SM, const LangOptions &Features, const TargetInfo &Target)
-{
- // Loop over all of the tokens in this string until we find the one that
- // contains the byte we're looking for.
- unsigned TokNo = 0;
-
- std::vector result;
- for (TokNo = 0; TokNo < S->getNumConcatenated(); ++TokNo)
- {
- SourceLocation StrTokLoc = S->getStrTokenLoc(TokNo);
-
- // Get the spelling of the string so that we can get the data that makes up
- // the string literal, not the identifier for the macro it is potentially
- // expanded through.
- SourceLocation StrTokSpellingLoc = SM.getSpellingLoc(StrTokLoc);
-
- // Re-lex the token to get its length and original spelling.
- std::pair LocInfo = SM.getDecomposedLoc(StrTokSpellingLoc);
- bool Invalid = false;
- StringRef Buffer = SM.getBufferData(LocInfo.first, &Invalid);
- if (Invalid)
- continue; // We ignore this part
-
- const char *StrData = Buffer.data() + LocInfo.second;
-
- // Create a lexer starting at the beginning of this token.
- Lexer TheLexer(SM.getLocForStartOfFile(LocInfo.first), Features,
- Buffer.begin(), StrData, Buffer.end());
- Token TheTok;
- TheLexer.LexFromRawLexer(TheTok);
- if (TheTok.isAnyIdentifier())
- {
- // It should not be, since we are parsing inside a string literal, but it can happen with special macros such as __func__
- // of __PRETTY_FUNCTION__ that are not resolved at this time. In that case, we just ignore them...
- continue;
- }
- // Get the spelling of the token.
- SmallString<32> SpellingBuffer;
- SpellingBuffer.resize(TheTok.getLength());
-
- bool StringInvalid = false;
- const char *SpellingPtr = &SpellingBuffer[0];
- unsigned TokLen = Lexer::getSpelling(TheTok, SpellingPtr, SM, Features, &StringInvalid);
- if (StringInvalid)
- continue;
-
- const char *SpellingStart = SpellingPtr;
- const char *SpellingEnd = SpellingPtr + TokLen;
- result.push_back(std::string(SpellingStart, SpellingEnd));
-
- }
- return result;
-}
-
-} // namespace clang_utilities
diff --git a/src/ASTViewer/ClangUtilities/StringLiteralExtractor.h b/src/ASTViewer/ClangUtilities/StringLiteralExtractor.h
deleted file mode 100644
index 72d7ca264c..0000000000
--- a/src/ASTViewer/ClangUtilities/StringLiteralExtractor.h
+++ /dev/null
@@ -1,46 +0,0 @@
-#pragma once
-
-#include
-#include
-#pragma warning (push)
-#pragma warning (disable:4100 4127 4800 4512 4245 4291 4510 4610 4324 4267 4244 4996 4146)
-#include
-#include
-#include
-#include
-#include
-#pragma warning (pop)
-
-
-namespace clang_utilities {
-
-// This function is an direct adaptation from ProcessCharEscape in llvm-3.7.1\src\tools\clang\lib\Lex\LiteralSupport.cpp (just removed the diag part)
-unsigned ProcessCharEscape(const char *ThisTokBegin,
- const char *&ThisTokBuf,
- const char *ThisTokEnd, bool &HadError,
- clang::FullSourceLoc Loc, unsigned CharWidth,
- const clang::LangOptions &Features);
-
-// This function is an direct adaptation from ProcessUCNEscape in llvm-3.7.1\src\tools\clang\lib\Lex\LiteralSupport.cpp (just removed the diag part)
-bool ProcessUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf,
- const char *ThisTokEnd,
- uint32_t &UcnVal, unsigned short &UcnLen,
- clang::FullSourceLoc Loc,
- const clang::LangOptions &Features,
- bool in_char_string_literal = false);
-
-
-// This function is an direct adaptation from ProcessUCNEscape in llvm-3.7.1\src\tools\clang\lib\Lex\LiteralSupport.cpp (just removed the diag part)
-int MeasureUCNEscape(const char *ThisTokBegin, const char *&ThisTokBuf,
- const char *ThisTokEnd, unsigned CharByteWidth,
- const clang::LangOptions &Features, bool &HadError);
-
-
-bool convertUTF32ToUTF8String(llvm::ArrayRef SrcBytes, std::string &Out);
-
-
-std::vector
-splitStringLiteral(clang::StringLiteral *S, const clang::SourceManager &SM, const clang::LangOptions &Features, const clang::TargetInfo &Target);
-
-} // namespace clang_utilities
-
diff --git a/src/ASTViewer/ClangUtilities/TemplateUtilities.cpp b/src/ASTViewer/ClangUtilities/TemplateUtilities.cpp
deleted file mode 100644
index 1aa554994f..0000000000
--- a/src/ASTViewer/ClangUtilities/TemplateUtilities.cpp
+++ /dev/null
@@ -1,287 +0,0 @@
-#include "TemplateUtilities.h"
-
-#pragma warning (push)
-#pragma warning (disable:4100 4127 4800 4512 4245 4291 4510 4610 4324 4267 4244 4996)
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#pragma warning (pop)
-
-using namespace clang;
-namespace clang_utilities {
-
-
-void printDeclType(raw_ostream &out, PrintingPolicy const &policy, QualType T, StringRef DeclName, bool Pack) {
- // Normally, a PackExpansionType is written as T[3]... (for instance, as a
- // template argument), but if it is the type of a declaration, the ellipsis
- // is placed before the name being declared.
- if (auto *PET = T->getAs()) {
- Pack = true;
- T = PET->getPattern();
- }
- T.print(out, policy, (Pack ? "..." : "") + DeclName);
-}
-
-void printTemplateParameters(raw_ostream &out, PrintingPolicy const &policy, TemplateParameterList const *params)
-{
- if (params == nullptr)
- {
- return;
- }
-
- out << "<";
- for (unsigned i = 0, e = params->size(); i != e; ++i) {
- if (i != 0)
- out << ", ";
-
- auto param = params->getParam(i);
- printTemplateParameter(out, policy, param);
- }
- out << ">";
-
-}
-
-// Adapted from tools\clang\lib\AST\DeclPrinter.cpp DeclPrinter::PrintTemplateParameters
-void printTemplateParameter(raw_ostream &out, PrintingPolicy const &policy, NamedDecl const *param)
-{
- if (const TemplateTypeParmDecl *TTP =
- dyn_cast(param)) {
-
- if (TTP->wasDeclaredWithTypename())
- out << "typename ";
- else
- out << "class ";
-
- if (TTP->isParameterPack())
- out << "...";
-
- out << *TTP;
-
- if (TTP->hasDefaultArgument()) {
- out << " = ";
- out << TTP->getDefaultArgument().getAsString(policy);
- };
- }
- else if (const NonTypeTemplateParmDecl *NTTP =
- dyn_cast(param)) {
- StringRef Name;
- if (IdentifierInfo *II = NTTP->getIdentifier())
- Name = II->getName();
- printDeclType(out, policy, NTTP->getType(), Name, NTTP->isParameterPack());
-
- if (NTTP->hasDefaultArgument()) {
- out << " = ";
- NTTP->getDefaultArgument()->printPretty(out, nullptr, policy, 0);
- }
- }
- else if (const TemplateTemplateParmDecl *TTPD =
- dyn_cast(param)) {
- out << "template";
- printTemplateParameters(out, policy, TTPD->getTemplateParameters());
- out << " class " << TTPD->getNameAsString();
- //VisitTemplateDecl(TTPD);
- // FIXME: print the default argument, if present.
- }
-}
-
-
-static void printIntegral(const TemplateArgument &TemplArg,
- raw_ostream &out, const PrintingPolicy& policy) {
- const ::clang::Type *T = TemplArg.getIntegralType().getTypePtr();
- const llvm::APSInt &Val = TemplArg.getAsIntegral();
-
- if (const EnumType *ET = T->getAs()) {
- for (const EnumConstantDecl* ECD : ET->getDecl()->enumerators()) {
- // In Sema::CheckTemplateArugment, enum template arguments value are
- // extended to the size of the integer underlying the enum type. This
- // may create a size difference between the enum value and template
- // argument value, requiring isSameValue here instead of operator==.
- if (llvm::APSInt::isSameValue(ECD->getInitVal(), Val)) {
- ECD->printQualifiedName(out, policy);
- return;
- }
- }
- }
-
- if (T->isBooleanType()) {
- out << (Val.getBoolValue() ? "true" : "false");
- }
- else if (T->isCharType()) {
- const char Ch = Val.getZExtValue();
- out << ((Ch == '\'') ? "'\\" : "'");
- out.write_escaped(StringRef(&Ch, 1), /*UseHexEscapes=*/ true);
- out << "'";
- }
- else {
- out << Val;
- }
-}
-
-void printTemplateName(raw_ostream &OS, const PrintingPolicy &policy, TemplateName const &name, bool qualifyNames = false)
-{
- if (auto Template = name.getAsTemplateDecl())
- OS << (qualifyNames ? Template->getQualifiedNameAsString() : Template->getNameAsString());
- else if (auto QTN = name.getAsQualifiedTemplateName()) {
- OS << (qualifyNames ? QTN->getDecl()->getQualifiedNameAsString() : QTN->getDecl()->getNameAsString());
- }
- else if (auto DTN = name.getAsDependentTemplateName()) {
- if (qualifyNames && DTN->getQualifier())
- DTN->getQualifier()->print(OS, policy);
- OS << "template ";
-
- if (DTN->isIdentifier())
- OS << DTN->getIdentifier()->getName();
- else
- OS << "operator " << getOperatorSpelling(DTN->getOperator());
- }
- else if (auto subst = name.getAsSubstTemplateTemplateParm()) {
- subst->getReplacement().print(OS, policy, !qualifyNames);
- }
- else if (auto SubstPack = name.getAsSubstTemplateTemplateParmPack())
- OS << *SubstPack->getParameterPack();
- else {
- auto OTS = name.getAsOverloadedTemplate();
- (*OTS->begin())->printName(OS);
- }
-}
-
-
-
-// Adapted from tools\clang\lib\AST\TemplateBase.cpp TemplateArgument::print
-void printTemplateArgument(raw_ostream &out, const PrintingPolicy &policy, TemplateArgument const &arg, bool qualifyNames)
-{
- switch (arg.getKind()) {
- case TemplateArgument::Null:
- out << "(no value)";
- break;
-
- case TemplateArgument::Type: {
- PrintingPolicy SubPolicy(policy);
- SubPolicy.SuppressStrongLifetime = true;
- arg.getAsType().print(out, SubPolicy);
- break;
- }
-
- case TemplateArgument::Declaration: {
- NamedDecl *ND = cast(arg.getAsDecl());
- out << '&';
- if (ND->getDeclName()) {
- // FIXME: distinguish between pointer and reference args?
- ND->printQualifiedName(out);
- }
- else {
- out << "(anonymous)";
- }
- break;
- }
-
- case TemplateArgument::NullPtr:
- out << "nullptr";
- break;
-
- case TemplateArgument::Template:
- // Orig: arg.getAsTemplate().print(out, policy);
- {
- auto templateName = arg.getAsTemplate();
- printTemplateName(out, policy, templateName, qualifyNames);
- break;
- }
-
- case TemplateArgument::TemplateExpansion:
- arg.getAsTemplateOrTemplatePattern().print(out, policy);
- out << "...";
- break;
-
- case TemplateArgument::Integral: {
- printIntegral(arg, out, policy);
- break;
- }
-
- case TemplateArgument::Expression:
- arg.getAsExpr()->printPretty(out, nullptr, policy);
- break;
-
- case TemplateArgument::Pack:
- out << "<";
- bool First = true;
- for (const auto &P : arg.pack_elements()) {
- if (First)
- First = false;
- else
- out << ", ";
-
- P.print(policy, out);
- }
- out << ">";
- break;
- }
-}
-
-void printTemplateArguments(raw_ostream &out, const PrintingPolicy &policy, TemplateArgumentList const *args, bool qualifyNames)
-{
- if (args == nullptr)
- {
- return;
- }
- out << "<";
- for (unsigned i = 0, e = args->size(); i != e; ++i) {
- if (i != 0)
- out << ", ";
-
- auto arg = args->get(i);
- printTemplateArgument(out, policy, arg, qualifyNames);
- }
- out << ">";
-
-}
-
-std::string getTypeName(QualType qualType, bool qualifyNames)
-{
- auto langOptions = clang::LangOptions{};
- auto printPolicy = PrintingPolicy{ langOptions };
- printPolicy.SuppressSpecifiers = false;
- printPolicy.ConstantArraySizeAsWritten = false;
- return qualType.getAsString(printPolicy);
-
-}
-
-std::string getFunctionPrototype(FunctionDecl *f, bool qualifyNames)
-{
- std::string prototypeBuf;
- llvm::raw_string_ostream os(prototypeBuf);
- PrintingPolicy policy(f->getASTContext().getLangOpts());
- policy.TerseOutput = false;
- os << getTypeName(f->getReturnType(), qualifyNames) << ' ' << f->getNameAsString();
- if (f->getTemplatedKind() == FunctionDecl::TK_FunctionTemplateSpecialization ||
- // f->getTemplatedKind() == FunctionDecl::TK_MemberSpecialization ||
- f->getTemplatedKind() == FunctionDecl::TK_DependentFunctionTemplateSpecialization)
- {
- printTemplateArguments(os, policy, f->getTemplateSpecializationArgs(), qualifyNames);
- }
- if (f->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate)
- {
- printTemplateParameters(os, policy, f->getDescribedFunctionTemplate()->getTemplateParameters());
- }
- os << '(';
- bool first = true;
- for (auto param : f->parameters())
- {
- if (!first)
- {
- os << ", ";
- }
- first = false;
-
- os << getTypeName(param->getType(), qualifyNames) << ' ' << param->getNameAsString();
- }
- os << ')';
- return os.str();
-}
-
-
-} // namespace clang_utilities
diff --git a/src/ASTViewer/ClangUtilities/TemplateUtilities.h b/src/ASTViewer/ClangUtilities/TemplateUtilities.h
deleted file mode 100644
index 60b4fb113f..0000000000
--- a/src/ASTViewer/ClangUtilities/TemplateUtilities.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#pragma once
-
-#pragma warning (push)
-#pragma warning (disable:4100 4127 4800 4512 4245 4291 4510 4610 4324 4267 4244 4996)
-#include
-#include
-#include
-#include
-#pragma warning (pop)
-
-namespace clang_utilities {
-
-// Adapted from tools\clang\lib\AST\DeclPrinter.cpp DeclPrinter::PrintTemplateParameters
-void printTemplateParameters(llvm::raw_ostream &out, clang::PrintingPolicy const &policy, const clang::TemplateParameterList *params);
-void printTemplateParameter(llvm::raw_ostream &out, clang::PrintingPolicy const &policy, clang::NamedDecl const *param);
-
-
-void printTemplateArguments(llvm::raw_ostream &out, const clang::PrintingPolicy &policy, clang::TemplateArgumentList const *args, bool qualifyNames);
-// Adapted from tools\clang\lib\AST\TemplateBase.cpp TemplateArgument::print
-void printTemplateArgument(llvm::raw_ostream &out, const clang::PrintingPolicy &policy, clang::TemplateArgument const &arg, bool qualifyNames);
-
-std::string getFunctionPrototype(clang::FunctionDecl *f, bool qualifyNames);
-std::string getTypeName(clang::QualType qualType, bool qualifyNames);
-
-
-} // namespace clang_utilities
-
diff --git a/src/ASTViewer/CommandLineSplitter.cpp b/src/ASTViewer/CommandLineSplitter.cpp
deleted file mode 100644
index a0ea6ccc58..0000000000
--- a/src/ASTViewer/CommandLineSplitter.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-#ifdef _WIN32
-#include
-#else
-#include
-#endif
-
-#include
-#include
-#include
-
-std::vector splitCommandLine(std::string const &cmdline)
-{
- int i;
- char **argv = NULL;
- int argc;
- std::vector result;
- // Posix.
-#ifndef _WIN32
- {
- wordexp_t p;
-
- // Note! This expands shell variables.
- if (wordexp(cmdline.c_str(), &p, 0))
- {
- return result;
- }
-
- argc = p.we_wordc;
-
- if (!(argv = (char**) calloc(argc, sizeof(char *))))
- {
- goto fail;
- }
-
- for (i = 0; i < p.we_wordc; i++)
- {
- result.push_back(p.we_wordv[i]);
- }
-
- wordfree(&p);
-
- return result;
- fail:
- wordfree(&p);
- return result;
- }
-#else // WIN32
- {
- wchar_t **wargs = NULL;
- size_t needed = 0;
- wchar_t *cmdlinew = NULL;
- size_t len = cmdline.size() + 1;
-
- if (!(cmdlinew = static_cast(calloc(len, sizeof(wchar_t)))))
- goto fail;
-
- if (!MultiByteToWideChar(CP_ACP, 0, cmdline.c_str(), -1, cmdlinew, len))
- goto fail;
-
- if (!(wargs = CommandLineToArgvW(cmdlinew, &argc)))
- goto fail;
-
- // Convert from wchar_t * to ANSI char *
- for (i = 0; i < argc; i++)
- {
- // Get the size needed for the target buffer.
- // CP_ACP = Ansi Codepage.
- needed = WideCharToMultiByte(CP_ACP, 0, wargs[i], -1,
- NULL, 0, NULL, NULL);
- char *argv;
- if (!(argv = static_cast(malloc(needed))))
- goto fail;
-
- // Do the conversion.
- needed = WideCharToMultiByte(CP_ACP, 0, wargs[i], -1,
- argv, needed, NULL, NULL);
- result.push_back(argv);
- free(argv);
- }
-
- if (wargs) LocalFree(wargs);
- if (cmdlinew) free(cmdlinew);
- return result;
-
- fail:
- if (wargs) LocalFree(wargs);
- if (cmdlinew) free(cmdlinew);
- }
-#endif // WIN32
-}
\ No newline at end of file
diff --git a/src/ASTViewer/CommandLineSplitter.h b/src/ASTViewer/CommandLineSplitter.h
deleted file mode 100644
index 0f59566b18..0000000000
--- a/src/ASTViewer/CommandLineSplitter.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#pragma once
-
-#include
-#include
-
-std::vector splitCommandLine(std::string const &cmdline);
diff --git a/src/ASTViewer/Highlighter.cpp b/src/ASTViewer/Highlighter.cpp
deleted file mode 100644
index a225857811..0000000000
--- a/src/ASTViewer/Highlighter.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "Highlighter.h"
-
-//! [0]
-Highlighter::Highlighter(QTextDocument *parent)
- : QSyntaxHighlighter(parent)
-{
- HighlightingRule rule;
-
- keywordFormat.setForeground(Qt::darkBlue);
- QStringList keywordPatterns;
- keywordPatterns << "\\bchar\\b" << "\\bclass\\b" << "\\bconst\\b"
- << "\\bdouble\\b" << "\\benum\\b" << "\\bexplicit\\b"
- << "\\bfriend\\b" << "\\binline\\b" << "\\bint\\b"
- << "\\blong\\b" << "\\bnamespace\\b" << "\\boperator\\b"
- << "\\bprivate\\b" << "\\bprotected\\b" << "\\bpublic\\b"
- << "\\bshort\\b" << "\\bsignals\\b" << "\\bsigned\\b"
- << "\\bslots\\b" << "\\bstatic\\b" << "\\bstruct\\b"
- << "\\btemplate\\b" << "\\btypedef\\b" << "\\btypename\\b"
- << "\\bunion\\b" << "\\bunsigned\\b" << "\\bvirtual\\b"
- << "\\bvoid\\b" << "\\bvolatile\\b";
- foreach (const QString &pattern, keywordPatterns) {
- rule.pattern = QRegExp(pattern);
- rule.format = keywordFormat;
- highlightingRules.append(rule);
-//! [0] //! [1]
- }
-//! [1]
-
-//! [2]
- classFormat.setFontWeight(QFont::Bold);
- classFormat.setForeground(Qt::darkMagenta);
- rule.pattern = QRegExp("\\bQ[A-Za-z]+\\b");
- rule.format = classFormat;
- highlightingRules.append(rule);
-//! [2]
-
-//! [3]
- singleLineCommentFormat.setForeground(Qt::darkGreen);
- rule.pattern = QRegExp("//[^\n]*");
- rule.format = singleLineCommentFormat;
- highlightingRules.append(rule);
-
- multiLineCommentFormat.setForeground(Qt::darkGreen);
-//! [3]
-
-//! [4]
- quotationFormat.setForeground(Qt::darkMagenta);
- rule.pattern = QRegExp("\".*\"");
- rule.format = quotationFormat;
- highlightingRules.append(rule);
-//! [4]
-
-//! [5]
- functionFormat.setForeground(Qt::blue);
- rule.pattern = QRegExp("\\b[A-Za-z0-9_]+(?=\\()");
- rule.format = functionFormat;
- highlightingRules.append(rule);
-//! [5]
-
-//! [6]
- commentStartExpression = QRegExp("/\\*");
- commentEndExpression = QRegExp("\\*/");
-}
-//! [6]
-
-//! [7]
-void Highlighter::highlightBlock(const QString &text)
-{
- foreach (const HighlightingRule &rule, highlightingRules) {
- QRegExp expression(rule.pattern);
- int index = expression.indexIn(text);
- while (index >= 0) {
- int length = expression.matchedLength();
- setFormat(index, length, rule.format);
- index = expression.indexIn(text, index + length);
- }
- }
-//! [7] //! [8]
- setCurrentBlockState(0);
-//! [8]
-
-//! [9]
- int startIndex = 0;
- if (previousBlockState() != 1)
- startIndex = commentStartExpression.indexIn(text);
-
-//! [9] //! [10]
- while (startIndex >= 0) {
-//! [10] //! [11]
- int endIndex = commentEndExpression.indexIn(text, startIndex);
- int commentLength;
- if (endIndex == -1) {
- setCurrentBlockState(1);
- commentLength = text.length() - startIndex;
- } else {
- commentLength = endIndex - startIndex
- + commentEndExpression.matchedLength();
- }
- setFormat(startIndex, commentLength, multiLineCommentFormat);
- startIndex = commentStartExpression.indexIn(text, startIndex + commentLength);
- }
-}
-//! [11]
diff --git a/src/ASTViewer/Highlighter.h b/src/ASTViewer/Highlighter.h
deleted file mode 100644
index a034194dff..0000000000
--- a/src/ASTViewer/Highlighter.h
+++ /dev/null
@@ -1,84 +0,0 @@
-#pragma once
-
-/****************************************************************************
-**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of The Qt Company Ltd nor the names of its
-** contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef HIGHLIGHTER_H
-#define HIGHLIGHTER_H
-
-#include
-#include
-
-QT_BEGIN_NAMESPACE
-class QTextDocument;
-QT_END_NAMESPACE
-
-//! [0]
-class Highlighter : public QSyntaxHighlighter
-{
- Q_OBJECT
-
-public:
- Highlighter(QTextDocument *parent = 0);
-
-protected:
- void highlightBlock(const QString &text) Q_DECL_OVERRIDE;
-
-private:
- struct HighlightingRule
- {
- QRegExp pattern;
- QTextCharFormat format;
- };
- QVector highlightingRules;
-
- QRegExp commentStartExpression;
- QRegExp commentEndExpression;
-
- QTextCharFormat keywordFormat;
- QTextCharFormat classFormat;
- QTextCharFormat singleLineCommentFormat;
- QTextCharFormat multiLineCommentFormat;
- QTextCharFormat quotationFormat;
- QTextCharFormat functionFormat;
-};
-//! [0]
-
-#endif // HIGHLIGHTER_H
diff --git a/src/ASTViewer/LICENSE b/src/ASTViewer/LICENSE
deleted file mode 100644
index 65c5ca88a6..0000000000
--- a/src/ASTViewer/LICENSE
+++ /dev/null
@@ -1,165 +0,0 @@
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-
- This version of the GNU Lesser General Public License incorporates
-the terms and conditions of version 3 of the GNU General Public
-License, supplemented by the additional permissions listed below.
-
- 0. Additional Definitions.
-
- As used herein, "this License" refers to version 3 of the GNU Lesser
-General Public License, and the "GNU GPL" refers to version 3 of the GNU
-General Public License.
-
- "The Library" refers to a covered work governed by this License,
-other than an Application or a Combined Work as defined below.
-
- An "Application" is any work that makes use of an interface provided
-by the Library, but which is not otherwise based on the Library.
-Defining a subclass of a class defined by the Library is deemed a mode
-of using an interface provided by the Library.
-
- A "Combined Work" is a work produced by combining or linking an
-Application with the Library. The particular version of the Library
-with which the Combined Work was made is also called the "Linked
-Version".
-
- The "Minimal Corresponding Source" for a Combined Work means the
-Corresponding Source for the Combined Work, excluding any source code
-for portions of the Combined Work that, considered in isolation, are
-based on the Application, and not on the Linked Version.
-
- The "Corresponding Application Code" for a Combined Work means the
-object code and/or source code for the Application, including any data
-and utility programs needed for reproducing the Combined Work from the
-Application, but excluding the System Libraries of the Combined Work.
-
- 1. Exception to Section 3 of the GNU GPL.
-
- You may convey a covered work under sections 3 and 4 of this License
-without being bound by section 3 of the GNU GPL.
-
- 2. Conveying Modified Versions.
-
- If you modify a copy of the Library, and, in your modifications, a
-facility refers to a function or data to be supplied by an Application
-that uses the facility (other than as an argument passed when the
-facility is invoked), then you may convey a copy of the modified
-version:
-
- a) under this License, provided that you make a good faith effort to
- ensure that, in the event an Application does not supply the
- function or data, the facility still operates, and performs
- whatever part of its purpose remains meaningful, or
-
- b) under the GNU GPL, with none of the additional permissions of
- this License applicable to that copy.
-
- 3. Object Code Incorporating Material from Library Header Files.
-
- The object code form of an Application may incorporate material from
-a header file that is part of the Library. You may convey such object
-code under terms of your choice, provided that, if the incorporated
-material is not limited to numerical parameters, data structure
-layouts and accessors, or small macros, inline functions and templates
-(ten or fewer lines in length), you do both of the following:
-
- a) Give prominent notice with each copy of the object code that the
- Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the object code with a copy of the GNU GPL and this license
- document.
-
- 4. Combined Works.
-
- You may convey a Combined Work under terms of your choice that,
-taken together, effectively do not restrict modification of the
-portions of the Library contained in the Combined Work and reverse
-engineering for debugging such modifications, if you also do each of
-the following:
-
- a) Give prominent notice with each copy of the Combined Work that
- the Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the Combined Work with a copy of the GNU GPL and this license
- document.
-
- c) For a Combined Work that displays copyright notices during
- execution, include the copyright notice for the Library among
- these notices, as well as a reference directing the user to the
- copies of the GNU GPL and this license document.
-
- d) Do one of the following:
-
- 0) Convey the Minimal Corresponding Source under the terms of this
- License, and the Corresponding Application Code in a form
- suitable for, and under terms that permit, the user to
- recombine or relink the Application with a modified version of
- the Linked Version to produce a modified Combined Work, in the
- manner specified by section 6 of the GNU GPL for conveying
- Corresponding Source.
-
- 1) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (a) uses at run time
- a copy of the Library already present on the user's computer
- system, and (b) will operate properly with a modified version
- of the Library that is interface-compatible with the Linked
- Version.
-
- e) Provide Installation Information, but only if you would otherwise
- be required to provide such information under section 6 of the
- GNU GPL, and only to the extent that such information is
- necessary to install and execute a modified version of the
- Combined Work produced by recombining or relinking the
- Application with a modified version of the Linked Version. (If
- you use option 4d0, the Installation Information must accompany
- the Minimal Corresponding Source and Corresponding Application
- Code. If you use option 4d1, you must provide the Installation
- Information in the manner specified by section 6 of the GNU GPL
- for conveying Corresponding Source.)
-
- 5. Combined Libraries.
-
- You may place library facilities that are a work based on the
-Library side by side in a single library together with other library
-facilities that are not Applications and are not covered by this
-License, and convey such a combined library under terms of your
-choice, if you do both of the following:
-
- a) Accompany the combined library with a copy of the same work based
- on the Library, uncombined with any other library facilities,
- conveyed under the terms of this License.
-
- b) Give prominent notice with the combined library that part of it
- is a work based on the Library, and explaining where to find the
- accompanying uncombined form of the same work.
-
- 6. Revised Versions of the GNU Lesser General Public License.
-
- The Free Software Foundation may publish revised and/or new versions
-of the GNU Lesser General Public License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Library as you received it specifies that a certain numbered version
-of the GNU Lesser General Public License "or any later version"
-applies to it, you have the option of following the terms and
-conditions either of that published version or of any later version
-published by the Free Software Foundation. If the Library as you
-received it does not specify a version number of the GNU Lesser
-General Public License, you may choose any version of the GNU Lesser
-General Public License ever published by the Free Software Foundation.
-
- If the Library as you received it specifies that a proxy can decide
-whether future versions of the GNU Lesser General Public License shall
-apply, that proxy's public statement of acceptance of any version is
-permanent authorization for you to choose that version for the
-Library.
diff --git a/src/ASTViewer/MainWindow.cpp b/src/ASTViewer/MainWindow.cpp
deleted file mode 100644
index a9c489921d..0000000000
--- a/src/ASTViewer/MainWindow.cpp
+++ /dev/null
@@ -1,169 +0,0 @@
-#include "MainWindow.h"
-#include
-#include
-#include
-#include
-#include "AstModel.h"
-
-class UpdateLock
-{
-public:
- UpdateLock(bool &lock) : myLock(lock)
- {
- myLock = true;
- }
- ~UpdateLock()
- {
- myLock = false;
- }
- bool & myLock;
-};
-
-MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- isUpdateInProgress(false)
-{
- myUi.setupUi(this);
-
- connect(myUi.actionRefresh, &QAction::triggered, this, &MainWindow::RefreshAst);
-
- myHighlighter = new Highlighter(myUi.codeViewer->document());
- myUi.nodeProperties->setHeaderLabels({ "Property", "Value" });
- connect(myUi.codeViewer, &QTextEdit::cursorPositionChanged, this, &MainWindow::HighlightNodeMatchingCode);
- connect(myUi.codeViewer, &QTextEdit::textChanged, this, &MainWindow::OnCodeChange);
- connect(myUi.showDetails, &QPushButton::clicked, this, &MainWindow::ShowNodeDetails);
-}
-
-void MainWindow::RefreshAst()
-{
- auto ast = myReader.readAst(myUi.codeViewer->document()->toPlainText().toStdString(),
- myUi.commandLineArgs->document()->toPlainText().toStdString());
- auto model = new AstModel(std::move(ast));
-
- myUi.astTreeView->setModel(model);
- myUi.astTreeView->setRootIndex(model->rootIndex());
- connect(myUi.astTreeView->selectionModel(), &QItemSelectionModel::currentChanged,
- this, &MainWindow::HighlightCodeMatchingNode);
- connect(myUi.astTreeView->selectionModel(), &QItemSelectionModel::currentChanged,
- this, &MainWindow::DisplayNodeProperties);
- myUi.astTreeView->setEnabled(myReader.ready());
-}
-
-void MainWindow::HighlightCodeMatchingNode(const QModelIndex &newNode, const QModelIndex &previousNode)
-{
- if (isUpdateInProgress)
- {
- return;
- }
- auto lock = UpdateLock{ isUpdateInProgress };
- auto node = myUi.astTreeView->model()->data(newNode, Qt::NodeRole).value();
- auto &manager = myReader.getManager();
- std::pair location;
- if (!node->getRangeInMainFile(location, manager, myReader.getContext()))
- {
- return;
- }
- auto cursor = myUi.codeViewer->textCursor();
- cursor.setPosition(location.first);
- cursor.setPosition(location.second, QTextCursor::KeepAnchor);
- myUi.codeViewer->setTextCursor(cursor);
-}
-
-void MainWindow::DisplayNodeProperties(const QModelIndex &newNode, const QModelIndex &previousNode)
-{
- myUi.nodeProperties->clear();
- auto node = myUi.astTreeView->model()->data(newNode, Qt::NodeRole).value();
- for (auto &prop : node->getProperties())
- {
- new QTreeWidgetItem(myUi.nodeProperties, QStringList{ QString::fromStdString(prop.first), QString::fromStdString(prop.second) });
- }
- myUi.showDetails->setVisible(node->hasDetails);
-}
-
-void MainWindow::HighlightNodeMatchingCode()
-{
- if (isUpdateInProgress || !myReader.ready())
- {
- return;
- }
- auto lock = UpdateLock{ isUpdateInProgress };
- auto cursorPosition = myUi.codeViewer->textCursor().position();
- auto nodePath = myReader.getBestNodeMatchingPosition(cursorPosition);
- auto model = myUi.astTreeView->model();
- if (!nodePath.empty())
- {
- auto currentIndex = model->index(0, 0); // Returns the root
- currentIndex = model->index(0, 0, currentIndex); // Returns the AST node
- auto currentNode = nodePath.front();
- bool first = true;
- for (auto node : nodePath)
- {
- if (first)
- {
- first = false;
- }
- else
- {
- auto index = currentNode->findChildIndex(node);
- if (index == -1)
- {
- // Something wrong, just silently return
- return;
- }
- currentIndex = model->index(index, 0, currentIndex);
- currentNode = node;
- }
- }
- myUi.astTreeView->scrollTo(currentIndex, QAbstractItemView::EnsureVisible);
- auto selectionModel = myUi.astTreeView->selectionModel();
-// selectionModel->select(currentIndex, QItemSelectionModel::ClearAndSelect);
- selectionModel->setCurrentIndex(currentIndex, QItemSelectionModel::ClearAndSelect);
- DisplayNodeProperties(currentIndex, currentIndex); // Since we won't use the previous node, it's not an issue if it is wrong...
- }
-}
-
-void MainWindow::ShowNodeDetails()
-{
- auto selectionModel = myUi.astTreeView->selectionModel();
- auto model = myUi.astTreeView->model();
- auto node = myUi.astTreeView->model()->data(selectionModel->currentIndex(), Qt::NodeRole).value();
- if (! node || !node->hasDetails)
- {
- QMessageBox::warning(this, windowTitle() + " - Error in details",
- "The currently selected node does not have details", QMessageBox::Ok);
- return;
- }
- if (node->details.empty())
- {
- node->details = node->detailsComputer();
- }
-
- auto win = new QDialog(this);
- win->setLayout(new QGridLayout());
- win->resize(size());
- win->move(pos());
- win->setWindowTitle(windowTitle() + " - " + QString::fromStdString(node->name) + " - " + QString::fromStdString(node->detailsTitle));
- auto edit = new QTextEdit(win);
- win->layout()->addWidget(edit);
- edit->setText(QString::fromStdString(node->details));
- edit->setReadOnly(true);
- myDetailWindows.push_back(win);
- win->show();
-}
-
-
-void MainWindow::closeEvent(QCloseEvent *event)
-{
- for (auto win : myDetailWindows)
- {
- win->close();
- }
- event->accept();
-}
-
-void MainWindow::OnCodeChange()
-{
- myUi.astTreeView->setEnabled(false);
- myReader.dirty();
-}
-
diff --git a/src/ASTViewer/MainWindow.h b/src/ASTViewer/MainWindow.h
deleted file mode 100644
index ed076e2504..0000000000
--- a/src/ASTViewer/MainWindow.h
+++ /dev/null
@@ -1,27 +0,0 @@
-#pragma once
-
-#include "ui_MainWindow.h"
-#include "Highlighter.h"
-#include "AstReader.h"
-
-
-class MainWindow : public QMainWindow
-{
- Q_OBJECT
-public:
- MainWindow(QWidget *parent = nullptr);
-public slots:
- void RefreshAst();
- void HighlightCodeMatchingNode(const QModelIndex &newNode, const QModelIndex &previousNode);
- void DisplayNodeProperties(const QModelIndex &newNode, const QModelIndex &previousNode);
- void HighlightNodeMatchingCode();
- void ShowNodeDetails();
- void OnCodeChange();
- void closeEvent(QCloseEvent *event) override;
-private:
- Ui::MainWindow myUi;
- Highlighter *myHighlighter; // No need to delete, since is will have a parent that will take care of that
- AstReader myReader;
- std::vector myDetailWindows;
- bool isUpdateInProgress;
-};
diff --git a/src/ASTViewer/MainWindow.ui b/src/ASTViewer/MainWindow.ui
deleted file mode 100644
index eb716cc7f6..0000000000
--- a/src/ASTViewer/MainWindow.ui
+++ /dev/null
@@ -1,151 +0,0 @@
-
-
- MainWindow
-
-
-
- 0
- 0
- 800
- 600
-
-
-
- Clang AST viewer
-
-
-
- -
-
-
-
- Consolas
- 10
-
-
-
- selection-background-color: rgb(170, 85, 255);
-selection-color: white
-
-
- 25
-
-
-
-
-
-
-
-
-
- Clang AST
-
-
- 2
-
-
-
- -
-
-
- false
-
-
- QTreeView::item:selected { color:white; background:rgb(170, 85, 255); }
-
-
- 10
-
-
- true
-
-
-
-
-
-
-
-
- toolBar
-
-
- TopToolBarArea
-
-
- false
-
-
-
-
-
- Command line arguments
-
-
- 8
-
-
-
- -
-
-
- -std=c++14 "-IC:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include" -I"C:\Program Files (x86)\Windows Kits\10\Include\10.0.10150.0\ucrt" -fcxx-exceptions -fms-compatibility -fdelayed-template-parsing
-
-
-
-
-
-
-
-
- Properties
-
-
- 2
-
-
-
- -
-
-
- 2
-
-
-
- 1
-
-
-
-
- 2
-
-
-
-
- -
-
-
- Show details
-
-
-
-
-
-
-
-
- Refresh
-
-
-
-
-
-
diff --git a/src/ASTViewer/README.md b/src/ASTViewer/README.md
deleted file mode 100644
index faa3af271f..0000000000
--- a/src/ASTViewer/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# Clang-ast-viewer
-## Introduction
-
-Fork of [https://github.com/CAST-projects/Clang-ast-viewer](https://github.com/CAST-projects/Clang-ast-viewer).
-
-## License
-This product is provided under LGPL. See the `LICENCE` file for more information.
\ No newline at end of file
diff --git a/src/ASTViewer/main.cpp b/src/ASTViewer/main.cpp
deleted file mode 100644
index 14dfa7f717..0000000000
--- a/src/ASTViewer/main.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-#include
-#include
-#include "MainWindow.h"
-
-int main(int argc, char **argv)
-{
- QApplication app (argc, argv);
-
- MainWindow mainWindow;
- mainWindow.show();
-
- return app.exec();
-}
-
diff --git a/src/ASTViewer/premake5.lua b/src/ASTViewer/premake5.lua
deleted file mode 100644
index f27afaa992..0000000000
--- a/src/ASTViewer/premake5.lua
+++ /dev/null
@@ -1,32 +0,0 @@
-require("premake-qt/qt")
-local qt = premake.extensions.qt
-
-project "CppSharp.ASTViewer"
- SetupNativeProject()
- kind "ConsoleApp"
- systemversion("latest")
- cppdialect "C++17"
-
- qt.enable()
-
- filter { "system:linux" }
- buildoptions { "-fPIC" }
- links { "pthread" }
- qtincludepath "/usr/include/x86_64-linux-gnu/qt5"
- qtlibpath "/usr/lib/x86_64-linux-gnu"
- qtbinpath "/usr/lib/qt5/bin"
-
- filter { "system:windows" }
- qtpath "C:\\Qt\\5.12.0\\msvc2017"
-
- filter {}
-
- qtmodules { "core", "gui", "widgets" }
- qtprefix "Qt5"
- files { "**.h", "**.cpp", "**.ui", "**.qrc" }
-
- SetupLLVMIncludes()
- SetupLLVMLibs()
-
- filter { "toolset:msc*" }
- buildoptions { "/wd4141", "/wd4146", "/wd4996" }
diff --git a/src/CLI/CLI.cs b/src/CLI/CLI.cs
index 54b2ed6c5d..44889307cb 100644
--- a/src/CLI/CLI.cs
+++ b/src/CLI/CLI.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
+using CppSharp.Generators;
using Mono.Options;
namespace CppSharp
@@ -15,11 +16,11 @@ static bool ParseCommandLineArgs(string[] args, List errorMessages, ref
{
var showHelp = false;
- optionSet.Add("I=", "the {PATH} of a folder to search for include files", (i) => { AddIncludeDirs(i, errorMessages); });
+ optionSet.Add("I=", "the {PATH} of a folder to search for include files", i => { AddIncludeDirs(i, errorMessages); });
optionSet.Add("l=", "{LIBRARY} that that contains the symbols of the generated code", l => options.Libraries.Add(l));
optionSet.Add("L=", "the {PATH} of a folder to search for additional libraries", l => options.LibraryDirs.Add(l));
optionSet.Add("D:", "additional define with (optional) value to add to be used while parsing the given header files", (n, v) => AddDefine(n, v, errorMessages));
- optionSet.Add("A=", "additional Clang arguments to pass to the compiler while parsing the given header files", (v) => AddArgument(v, errorMessages));
+ optionSet.Add("A=", "additional Clang arguments to pass to the compiler while parsing the given header files", v => AddArgument(v, errorMessages));
optionSet.Add("o=|output=", "the {PATH} for the generated bindings file (doesn't need the extension since it will depend on the generator)", v => HandleOutputArg(v, errorMessages));
optionSet.Add("on=|outputnamespace=", "the {NAMESPACE} that will be used for the generated code", on => options.OutputNamespace = on);
@@ -30,8 +31,8 @@ static bool ParseCommandLineArgs(string[] args, List errorMessages, ref
optionSet.Add("d|debug", "enables debug mode which generates more verbose code to aid debugging", v => options.Debug = true);
optionSet.Add("c|compile", "enables automatic compilation of the generated code", v => options.Compile = true);
optionSet.Add("g=|gen=|generator=", "the {TYPE} of generated code: 'csharp' or 'cli' ('cli' supported only for Windows)", g => { GetGeneratorKind(g, errorMessages); });
- optionSet.Add("p=|platform=", "the {PLATFORM} that the generated code will target: 'win', 'osx' or 'linux'", p => { GetDestinationPlatform(p, errorMessages); });
- optionSet.Add("a=|arch=", "the {ARCHITECTURE} that the generated code will target: 'x86' or 'x64'", a => { GetDestinationArchitecture(a, errorMessages); });
+ optionSet.Add("p=|platform=", "the {PLATFORM} that the generated code will target: 'win', 'osx' or 'linux' or 'emscripten'", p => { GetDestinationPlatform(p, errorMessages); });
+ optionSet.Add("a=|arch=", "the {ARCHITECTURE} that the generated code will target: 'x86' or 'x64' or 'wasm32' or 'wasm64'", a => { GetDestinationArchitecture(a, errorMessages); });
optionSet.Add("prefix=", "sets a string prefix to the names of generated files", a => { options.Prefix = a; });
optionSet.Add("exceptions", "enables support for C++ exceptions in the parser", v => { options.EnableExceptions = true; });
@@ -208,26 +209,29 @@ static void GetGeneratorKind(string generator, List errorMessages)
switch (generator.ToLower())
{
case "csharp":
- options.Kind = CppSharp.Generators.GeneratorKind.CSharp;
+ options.Kind = GeneratorKind.CSharp;
return;
case "cli":
- options.Kind = CppSharp.Generators.GeneratorKind.CLI;
+ options.Kind = GeneratorKind.CLI;
return;
case "c":
- options.Kind = CppSharp.Generators.GeneratorKind.C;
+ options.Kind = GeneratorKind.C;
return;
case "cpp":
- options.Kind = CppSharp.Generators.GeneratorKind.CPlusPlus;
+ options.Kind = GeneratorKind.CPlusPlus;
return;
case "napi":
- options.Kind = CppSharp.Generators.GeneratorKind.NAPI;
+ options.Kind = GeneratorKind.NAPI;
return;
case "qjs":
- options.Kind = CppSharp.Generators.GeneratorKind.QuickJS;
+ options.Kind = GeneratorKind.QuickJS;
return;
case "ts":
case "typescript":
- options.Kind = CppSharp.Generators.GeneratorKind.TypeScript;
+ options.Kind = GeneratorKind.TypeScript;
+ return;
+ case "emscripten":
+ options.Kind = GeneratorKind.Emscripten;
return;
}
@@ -247,6 +251,9 @@ static void GetDestinationPlatform(string platform, List errorMessages)
case "linux":
options.Platform = TargetPlatform.Linux;
return;
+ case "emscripten":
+ options.Platform = TargetPlatform.Emscripten;
+ return;
}
errorMessages.Add($"Unknown target platform: {platform}. Defaulting to {options.Platform}");
@@ -262,6 +269,12 @@ static void GetDestinationArchitecture(string architecture, List errorMe
case "x64":
options.Architecture = TargetArchitecture.x64;
return;
+ case "wasm32":
+ options.Architecture = TargetArchitecture.WASM32;
+ return;
+ case "wasm64":
+ options.Architecture = TargetArchitecture.WASM64;
+ return;
}
errorMessages.Add($"Unknown target architecture: {architecture}. Defaulting to {options.Architecture}");
@@ -286,9 +299,9 @@ static void Main(string[] args)
return;
}
- Generator gen = new Generator(options);
+ var gen = new Generator(options);
- bool validOptions = gen.ValidateOptions(errorMessages);
+ var validOptions = gen.ValidateOptions(errorMessages);
PrintErrorMessages(errorMessages);
if (errorMessages.Any() || !validOptions)
diff --git a/src/CLI/Generator.cs b/src/CLI/Generator.cs
index 5c6f72be77..58db9ac72d 100644
--- a/src/CLI/Generator.cs
+++ b/src/CLI/Generator.cs
@@ -13,58 +13,64 @@ namespace CppSharp
{
class Generator : ILibrary
{
- private Options options = null;
+ private readonly Options options;
private string triple = "";
private CppAbi abi = CppAbi.Microsoft;
public Generator(Options options)
{
- if (options == null)
- throw new ArgumentNullException(nameof(options));
-
- this.options = options;
- }
-
- static TargetPlatform GetCurrentPlatform()
- {
- if (Platform.IsWindows)
- return TargetPlatform.Windows;
-
- if (Platform.IsMacOS)
- return TargetPlatform.MacOS;
-
- if (Platform.IsLinux)
- return TargetPlatform.Linux;
-
- throw new System.NotImplementedException("Unknown host platform");
+ this.options = options ?? throw new ArgumentNullException(nameof(options));
}
void SetupTargetTriple()
{
var tripleBuilder = new StringBuilder();
- if (options.Architecture == TargetArchitecture.x64)
- tripleBuilder.Append("x86_64-");
- else if (options.Architecture == TargetArchitecture.x86)
- tripleBuilder.Append("i686-");
-
- if (options.Platform == TargetPlatform.Windows)
- {
- tripleBuilder.Append("pc-win32-msvc");
- abi = CppAbi.Microsoft;
- }
- else if (options.Platform == TargetPlatform.MacOS)
+ switch (options.Architecture)
{
- tripleBuilder.Append("apple-darwin12.4.0");
- abi = CppAbi.Itanium;
+ case TargetArchitecture.x64:
+ tripleBuilder.Append("x86_64-");
+ break;
+ case TargetArchitecture.x86:
+ tripleBuilder.Append("i686-");
+ break;
+ case TargetArchitecture.WASM32:
+ tripleBuilder.Append("wasm32-");
+ break;
+ case TargetArchitecture.WASM64:
+ tripleBuilder.Append("wasm64-");
+ break;
}
- else if (options.Platform == TargetPlatform.Linux)
- {
- tripleBuilder.Append("linux-gnu");
- abi = CppAbi.Itanium;
- if (options.Cpp11ABI)
- tripleBuilder.Append("-cxx11abi");
+ switch (options.Platform)
+ {
+ case TargetPlatform.Windows:
+ tripleBuilder.Append("pc-win32-msvc");
+ abi = CppAbi.Microsoft;
+ break;
+ case TargetPlatform.MacOS:
+ tripleBuilder.Append("apple-darwin12.4.0");
+ abi = CppAbi.Itanium;
+ break;
+ case TargetPlatform.Linux:
+ {
+ tripleBuilder.Append("linux-gnu");
+ abi = CppAbi.Itanium;
+
+ if (options.Cpp11ABI)
+ tripleBuilder.Append("-cxx11abi");
+ break;
+ }
+ case TargetPlatform.Emscripten:
+ {
+ if (options.Architecture != TargetArchitecture.WASM32 &&
+ options.Architecture != TargetArchitecture.WASM64)
+ throw new Exception("Emscripten target is only compatible with WASM architectures");
+
+ tripleBuilder.Append("unknown-emscripten");
+ abi = CppAbi.Itanium;
+ break;
+ }
}
triple = tripleBuilder.ToString();
@@ -78,8 +84,7 @@ public bool ValidateOptions(List messages)
return false;
}
- if (!options.Platform.HasValue)
- options.Platform = GetCurrentPlatform();
+ options.Platform ??= Platform.Host;
if (string.IsNullOrEmpty(options.OutputDir))
{
@@ -103,6 +108,9 @@ public bool ValidateOptions(List messages)
if (string.IsNullOrEmpty(options.OutputNamespace))
options.OutputNamespace = moduleName;
+ if (options.IncludeDirs.Count == 0)
+ options.IncludeDirs.Add(Path.GetDirectoryName(options.HeaderFiles.First()));
+
SetupTargetTriple();
return true;
@@ -133,7 +141,7 @@ public void Setup(Driver driver)
parserOptions.UnityBuild = options.UnityBuild;
parserOptions.EnableRTTI = options.EnableRTTI;
- parserOptions.Setup();
+ parserOptions.Setup(options.Platform ?? Platform.Host);
if (triple.Contains("linux"))
SetupLinuxOptions(parserOptions);
@@ -189,7 +197,7 @@ public void Postprocess(Driver driver, ASTContext ctx)
public void Run()
{
- StringBuilder messageBuilder = new StringBuilder();
+ var messageBuilder = new StringBuilder();
messageBuilder.Append($"Generating {GetGeneratorKindName(options.Kind)}");
messageBuilder.Append($" bindings for {GetPlatformName(options.Platform)} {options.Architecture}");
diff --git a/src/CLI/Options.cs b/src/CLI/Options.cs
index f679287c0f..bbcb2f3894 100644
--- a/src/CLI/Options.cs
+++ b/src/CLI/Options.cs
@@ -6,7 +6,9 @@ namespace CppSharp
enum TargetArchitecture
{
x86,
- x64
+ x64,
+ WASM32,
+ WASM64
}
class Options
diff --git a/src/Core/Platform.cs b/src/Core/Platform.cs
index d0500f290f..90740dfc66 100644
--- a/src/Core/Platform.cs
+++ b/src/Core/Platform.cs
@@ -11,7 +11,8 @@ public enum TargetPlatform
MacOS,
iOS,
WatchOS,
- TVOS
+ TVOS,
+ Emscripten,
}
public static class Platform
diff --git a/src/CppParser/AST.cpp b/src/CppParser/AST.cpp
index d0442df015..ae9e176360 100644
--- a/src/CppParser/AST.cpp
+++ b/src/CppParser/AST.cpp
@@ -164,6 +164,7 @@ NonTypeTemplateParameter::NonTypeTemplateParameter(const NonTypeTemplateParamete
, position(rhs.position)
, isPackExpansion(rhs.isPackExpansion)
, isExpandedParameterPack(rhs.isExpandedParameterPack)
+ , type(rhs.type)
{
}
diff --git a/src/CppParser/Bindings/CLI/Decl.cpp b/src/CppParser/Bindings/CLI/Decl.cpp
index 2465c7ef4e..3de0e48dec 100644
--- a/src/CppParser/Bindings/CLI/Decl.cpp
+++ b/src/CppParser/Bindings/CLI/Decl.cpp
@@ -4224,6 +4224,18 @@ void CppSharp::Parser::AST::NonTypeTemplateParameter::IsExpandedParameterPack::s
((class ::CppSharp::CppParser::AST::NonTypeTemplateParameter*)NativePtr)->isExpandedParameterPack = value;
}
+CppSharp::Parser::AST::QualifiedType^ CppSharp::Parser::AST::NonTypeTemplateParameter::Type::get()
+{
+ return (&((class ::CppSharp::CppParser::AST::NonTypeTemplateParameter*)NativePtr)->type == nullptr) ? nullptr : gcnew ::CppSharp::Parser::AST::QualifiedType((struct ::CppSharp::CppParser::AST::QualifiedType*)&((class ::CppSharp::CppParser::AST::NonTypeTemplateParameter*)NativePtr)->type);
+}
+
+void CppSharp::Parser::AST::NonTypeTemplateParameter::Type::set(CppSharp::Parser::AST::QualifiedType^ value)
+{
+ if (ReferenceEquals(value, nullptr))
+ throw gcnew ::System::ArgumentNullException("value", "Cannot be null because it is passed by value.");
+ ((class ::CppSharp::CppParser::AST::NonTypeTemplateParameter*)NativePtr)->type = *(struct ::CppSharp::CppParser::AST::QualifiedType*)value->NativePtr;
+}
+
CppSharp::Parser::AST::ClassTemplate::ClassTemplate(class ::CppSharp::CppParser::AST::ClassTemplate* native)
: CppSharp::Parser::AST::Template((::CppSharp::CppParser::AST::Template*)native)
{
diff --git a/src/CppParser/Bindings/CLI/Decl.h b/src/CppParser/Bindings/CLI/Decl.h
index a96a160c8a..8c9044c774 100644
--- a/src/CppParser/Bindings/CLI/Decl.h
+++ b/src/CppParser/Bindings/CLI/Decl.h
@@ -256,7 +256,8 @@ namespace CppSharp
Microsoft = 1,
ARM = 2,
iOS = 3,
- iOS64 = 4
+ iOS64 = 4,
+ WebAssembly = 5
};
public enum class RecordArgABI
@@ -2097,6 +2098,12 @@ namespace CppSharp
bool get();
void set(bool);
}
+
+ property CppSharp::Parser::AST::QualifiedType^ Type
+ {
+ CppSharp::Parser::AST::QualifiedType^ get();
+ void set(CppSharp::Parser::AST::QualifiedType^);
+ }
};
public ref class ClassTemplate : CppSharp::Parser::AST::Template
diff --git a/src/CppParser/Bindings/CSharp/CppSharp.Parser.CSharp.csproj b/src/CppParser/Bindings/CSharp/CppSharp.Parser.CSharp.csproj
index b026b257be..cb09d65642 100644
--- a/src/CppParser/Bindings/CSharp/CppSharp.Parser.CSharp.csproj
+++ b/src/CppParser/Bindings/CSharp/CppSharp.Parser.CSharp.csproj
@@ -5,6 +5,7 @@
true
true
true
+ 0109
x86_64-pc-win32-msvc
x86_64-linux-gnu-cxx11abi
x86_64-linux-gnu
diff --git a/src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/CppSharp.CppParser.cs b/src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/CppSharp.CppParser.cs
index f12e2fa508..5fcdfc4ebd 100644
--- a/src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/CppSharp.CppParser.cs
+++ b/src/CppParser/Bindings/CSharp/i686-apple-darwin12.4.0/CppSharp.CppParser.cs
@@ -6301,7 +6301,8 @@ public enum CppAbi
Microsoft = 1,
ARM = 2,
iOS = 3,
- iOS64 = 4
+ iOS64 = 4,
+ WebAssembly = 5
}
public enum RecordArgABI
@@ -13016,6 +13017,7 @@ public unsafe partial class NonTypeTemplateParameter : global::CppSharp.Parser.A
internal uint position;
internal byte isPackExpansion;
internal byte isExpandedParameterPack;
+ internal global::CppSharp.Parser.AST.QualifiedType.__Internal type;
[SuppressUnmanagedCodeSecurity, DllImport("CppSharp.CppParser", EntryPoint = "_ZN8CppSharp9CppParser3AST24NonTypeTemplateParameterC2Ev", CallingConvention = __CallingConvention.Cdecl)]
internal static extern void ctor(__IntPtr __instance);
@@ -13170,6 +13172,21 @@ public bool IsExpandedParameterPack
((__Internal*)__Instance)->isExpandedParameterPack = (byte) (value ? 1 : 0);
}
}
+
+ public global::CppSharp.Parser.AST.QualifiedType Type
+ {
+ get
+ {
+ return global::CppSharp.Parser.AST.QualifiedType.__CreateInstance(new __IntPtr(&((__Internal*)__Instance)->type));
+ }
+
+ set
+ {
+ if (ReferenceEquals(value, null))
+ throw new global::System.ArgumentNullException("value", "Cannot be null because it is passed by value.");
+ ((__Internal*)__Instance)->type = *(global::CppSharp.Parser.AST.QualifiedType.__Internal*) value.__Instance;
+ }
+ }
}
public unsafe partial class ClassTemplate : global::CppSharp.Parser.AST.Template, IDisposable
diff --git a/src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/CppSharp.CppParser.cs b/src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/CppSharp.CppParser.cs
index e6d43d9596..de89c3f760 100644
--- a/src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/CppSharp.CppParser.cs
+++ b/src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/CppSharp.CppParser.cs
@@ -6301,7 +6301,8 @@ public enum CppAbi
Microsoft = 1,
ARM = 2,
iOS = 3,
- iOS64 = 4
+ iOS64 = 4,
+ WebAssembly = 5
}
public enum RecordArgABI
@@ -13016,6 +13017,7 @@ public unsafe partial class NonTypeTemplateParameter : global::CppSharp.Parser.A
internal uint position;
internal byte isPackExpansion;
internal byte isExpandedParameterPack;
+ internal global::CppSharp.Parser.AST.QualifiedType.__Internal type;
[SuppressUnmanagedCodeSecurity, DllImport("CppSharp.CppParser.dll", EntryPoint = "??0NonTypeTemplateParameter@AST@CppParser@CppSharp@@QAE@XZ", CallingConvention = __CallingConvention.ThisCall)]
internal static extern __IntPtr ctor(__IntPtr __instance);
@@ -13170,6 +13172,21 @@ public bool IsExpandedParameterPack
((__Internal*)__Instance)->isExpandedParameterPack = (byte) (value ? 1 : 0);
}
}
+
+ public global::CppSharp.Parser.AST.QualifiedType Type
+ {
+ get
+ {
+ return global::CppSharp.Parser.AST.QualifiedType.__CreateInstance(new __IntPtr(&((__Internal*)__Instance)->type));
+ }
+
+ set
+ {
+ if (ReferenceEquals(value, null))
+ throw new global::System.ArgumentNullException("value", "Cannot be null because it is passed by value.");
+ ((__Internal*)__Instance)->type = *(global::CppSharp.Parser.AST.QualifiedType.__Internal*) value.__Instance;
+ }
+ }
}
public unsafe partial class ClassTemplate : global::CppSharp.Parser.AST.Template, IDisposable
diff --git a/src/CppParser/Bindings/CSharp/x86_64-apple-darwin12.4.0/CppSharp.CppParser.cs b/src/CppParser/Bindings/CSharp/x86_64-apple-darwin12.4.0/CppSharp.CppParser.cs
index 4ce7bfff71..576edd3c17 100644
--- a/src/CppParser/Bindings/CSharp/x86_64-apple-darwin12.4.0/CppSharp.CppParser.cs
+++ b/src/CppParser/Bindings/CSharp/x86_64-apple-darwin12.4.0/CppSharp.CppParser.cs
@@ -6301,7 +6301,8 @@ public enum CppAbi
Microsoft = 1,
ARM = 2,
iOS = 3,
- iOS64 = 4
+ iOS64 = 4,
+ WebAssembly = 5
}
public enum RecordArgABI
@@ -13015,6 +13016,7 @@ public unsafe partial class NonTypeTemplateParameter : global::CppSharp.Parser.A
internal uint position;
internal byte isPackExpansion;
internal byte isExpandedParameterPack;
+ internal global::CppSharp.Parser.AST.QualifiedType.__Internal type;
[SuppressUnmanagedCodeSecurity, DllImport("CppSharp.CppParser", EntryPoint = "_ZN8CppSharp9CppParser3AST24NonTypeTemplateParameterC2Ev", CallingConvention = __CallingConvention.Cdecl)]
internal static extern void ctor(__IntPtr __instance);
@@ -13169,6 +13171,21 @@ public bool IsExpandedParameterPack
((__Internal*)__Instance)->isExpandedParameterPack = (byte) (value ? 1 : 0);
}
}
+
+ public global::CppSharp.Parser.AST.QualifiedType Type
+ {
+ get
+ {
+ return global::CppSharp.Parser.AST.QualifiedType.__CreateInstance(new __IntPtr(&((__Internal*)__Instance)->type));
+ }
+
+ set
+ {
+ if (ReferenceEquals(value, null))
+ throw new global::System.ArgumentNullException("value", "Cannot be null because it is passed by value.");
+ ((__Internal*)__Instance)->type = *(global::CppSharp.Parser.AST.QualifiedType.__Internal*) value.__Instance;
+ }
+ }
}
public unsafe partial class ClassTemplate : global::CppSharp.Parser.AST.Template, IDisposable
diff --git a/src/CppParser/Bindings/CSharp/x86_64-linux-gnu-cxx11abi/CppSharp.CppParser.cs b/src/CppParser/Bindings/CSharp/x86_64-linux-gnu-cxx11abi/CppSharp.CppParser.cs
index 82844c1059..4c6201974c 100644
--- a/src/CppParser/Bindings/CSharp/x86_64-linux-gnu-cxx11abi/CppSharp.CppParser.cs
+++ b/src/CppParser/Bindings/CSharp/x86_64-linux-gnu-cxx11abi/CppSharp.CppParser.cs
@@ -6301,7 +6301,8 @@ public enum CppAbi
Microsoft = 1,
ARM = 2,
iOS = 3,
- iOS64 = 4
+ iOS64 = 4,
+ WebAssembly = 5
}
public enum RecordArgABI
@@ -13015,6 +13016,7 @@ public unsafe partial class NonTypeTemplateParameter : global::CppSharp.Parser.A
internal uint position;
internal byte isPackExpansion;
internal byte isExpandedParameterPack;
+ internal global::CppSharp.Parser.AST.QualifiedType.__Internal type;
[SuppressUnmanagedCodeSecurity, DllImport("CppSharp.CppParser", EntryPoint = "_ZN8CppSharp9CppParser3AST24NonTypeTemplateParameterC2Ev", CallingConvention = __CallingConvention.Cdecl)]
internal static extern void ctor(__IntPtr __instance);
@@ -13169,6 +13171,21 @@ public bool IsExpandedParameterPack
((__Internal*)__Instance)->isExpandedParameterPack = (byte) (value ? 1 : 0);
}
}
+
+ public global::CppSharp.Parser.AST.QualifiedType Type
+ {
+ get
+ {
+ return global::CppSharp.Parser.AST.QualifiedType.__CreateInstance(new __IntPtr(&((__Internal*)__Instance)->type));
+ }
+
+ set
+ {
+ if (ReferenceEquals(value, null))
+ throw new global::System.ArgumentNullException("value", "Cannot be null because it is passed by value.");
+ ((__Internal*)__Instance)->type = *(global::CppSharp.Parser.AST.QualifiedType.__Internal*) value.__Instance;
+ }
+ }
}
public unsafe partial class ClassTemplate : global::CppSharp.Parser.AST.Template, IDisposable
diff --git a/src/CppParser/Bindings/CSharp/x86_64-linux-gnu/CppSharp.CppParser.cs b/src/CppParser/Bindings/CSharp/x86_64-linux-gnu/CppSharp.CppParser.cs
index 612f1f207f..2b7e1e837c 100644
--- a/src/CppParser/Bindings/CSharp/x86_64-linux-gnu/CppSharp.CppParser.cs
+++ b/src/CppParser/Bindings/CSharp/x86_64-linux-gnu/CppSharp.CppParser.cs
@@ -6301,7 +6301,8 @@ public enum CppAbi
Microsoft = 1,
ARM = 2,
iOS = 3,
- iOS64 = 4
+ iOS64 = 4,
+ WebAssembly = 5
}
public enum RecordArgABI
@@ -13015,6 +13016,7 @@ public unsafe partial class NonTypeTemplateParameter : global::CppSharp.Parser.A
internal uint position;
internal byte isPackExpansion;
internal byte isExpandedParameterPack;
+ internal global::CppSharp.Parser.AST.QualifiedType.__Internal type;
[SuppressUnmanagedCodeSecurity, DllImport("CppSharp.CppParser", EntryPoint = "_ZN8CppSharp9CppParser3AST24NonTypeTemplateParameterC2Ev", CallingConvention = __CallingConvention.Cdecl)]
internal static extern void ctor(__IntPtr __instance);
@@ -13169,6 +13171,21 @@ public bool IsExpandedParameterPack
((__Internal*)__Instance)->isExpandedParameterPack = (byte) (value ? 1 : 0);
}
}
+
+ public global::CppSharp.Parser.AST.QualifiedType Type
+ {
+ get
+ {
+ return global::CppSharp.Parser.AST.QualifiedType.__CreateInstance(new __IntPtr(&((__Internal*)__Instance)->type));
+ }
+
+ set
+ {
+ if (ReferenceEquals(value, null))
+ throw new global::System.ArgumentNullException("value", "Cannot be null because it is passed by value.");
+ ((__Internal*)__Instance)->type = *(global::CppSharp.Parser.AST.QualifiedType.__Internal*) value.__Instance;
+ }
+ }
}
public unsafe partial class ClassTemplate : global::CppSharp.Parser.AST.Template, IDisposable
diff --git a/src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/CppSharp.CppParser.cs b/src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/CppSharp.CppParser.cs
index 85846584a7..5c6dadc5fe 100644
--- a/src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/CppSharp.CppParser.cs
+++ b/src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/CppSharp.CppParser.cs
@@ -6301,7 +6301,8 @@ public enum CppAbi
Microsoft = 1,
ARM = 2,
iOS = 3,
- iOS64 = 4
+ iOS64 = 4,
+ WebAssembly = 5
}
public enum RecordArgABI
@@ -13017,6 +13018,7 @@ public unsafe partial class NonTypeTemplateParameter : global::CppSharp.Parser.A
internal uint position;
internal byte isPackExpansion;
internal byte isExpandedParameterPack;
+ internal global::CppSharp.Parser.AST.QualifiedType.__Internal type;
[SuppressUnmanagedCodeSecurity, DllImport("CppSharp.CppParser.dll", EntryPoint = "??0NonTypeTemplateParameter@AST@CppParser@CppSharp@@QEAA@XZ", CallingConvention = __CallingConvention.Cdecl)]
internal static extern __IntPtr ctor(__IntPtr __instance);
@@ -13171,6 +13173,21 @@ public bool IsExpandedParameterPack
((__Internal*)__Instance)->isExpandedParameterPack = (byte) (value ? 1 : 0);
}
}
+
+ public global::CppSharp.Parser.AST.QualifiedType Type
+ {
+ get
+ {
+ return global::CppSharp.Parser.AST.QualifiedType.__CreateInstance(new __IntPtr(&((__Internal*)__Instance)->type));
+ }
+
+ set
+ {
+ if (ReferenceEquals(value, null))
+ throw new global::System.ArgumentNullException("value", "Cannot be null because it is passed by value.");
+ ((__Internal*)__Instance)->type = *(global::CppSharp.Parser.AST.QualifiedType.__Internal*) value.__Instance;
+ }
+ }
}
public unsafe partial class ClassTemplate : global::CppSharp.Parser.AST.Template, IDisposable
diff --git a/src/CppParser/Decl.h b/src/CppParser/Decl.h
index 7132a11080..b51929c45d 100644
--- a/src/CppParser/Decl.h
+++ b/src/CppParser/Decl.h
@@ -1,9 +1,9 @@
/************************************************************************
-*
-* CppSharp
-* Licensed under the MIT license.
-*
-************************************************************************/
+ *
+ * CppSharp
+ * Licensed under the MIT license.
+ *
+ ************************************************************************/
#pragma once
@@ -12,823 +12,834 @@
#include "Types.h"
#include
-namespace CppSharp { namespace CppParser { namespace AST {
-
-enum class DeclarationKind
+namespace CppSharp
{
- DeclarationContext,
- Typedef,
- TypeAlias,
- Parameter,
- Function,
- Method,
- Enumeration,
- EnumerationItem,
- Variable,
- Field,
- AccessSpecifier,
- Class,
- Template,
- TypeAliasTemplate,
- ClassTemplate,
- ClassTemplateSpecialization,
- ClassTemplatePartialSpecialization,
- FunctionTemplate,
- Namespace,
- PreprocessedEntity,
- MacroDefinition,
- MacroExpansion,
- TranslationUnit,
- Friend,
- TemplateTemplateParm,
- TemplateTypeParm,
- NonTypeTemplateParm,
- VarTemplate,
- VarTemplateSpecialization,
- VarTemplatePartialSpecialization,
- UnresolvedUsingTypename,
-};
+ namespace CppParser
+ {
+ namespace AST
+ {
+
+ enum class DeclarationKind
+ {
+ DeclarationContext,
+ Typedef,
+ TypeAlias,
+ Parameter,
+ Function,
+ Method,
+ Enumeration,
+ EnumerationItem,
+ Variable,
+ Field,
+ AccessSpecifier,
+ Class,
+ Template,
+ TypeAliasTemplate,
+ ClassTemplate,
+ ClassTemplateSpecialization,
+ ClassTemplatePartialSpecialization,
+ FunctionTemplate,
+ Namespace,
+ PreprocessedEntity,
+ MacroDefinition,
+ MacroExpansion,
+ TranslationUnit,
+ Friend,
+ TemplateTemplateParm,
+ TemplateTypeParm,
+ NonTypeTemplateParm,
+ VarTemplate,
+ VarTemplateSpecialization,
+ VarTemplatePartialSpecialization,
+ UnresolvedUsingTypename,
+ };
#define DECLARE_DECL_KIND(klass, kind) \
klass();
-enum class AccessSpecifier
-{
- Private,
- Protected,
- Public
-};
-
-class DeclarationContext;
-class RawComment;
-class PreprocessedEntity;
-
-class ExpressionObsolete;
-class CS_API Declaration
-{
-public:
- Declaration(DeclarationKind kind);
- Declaration(const Declaration&);
- ~Declaration();
-
- DeclarationKind kind;
- int alignAs;
- int maxFieldAlignment;
- AccessSpecifier access;
- DeclarationContext* _namespace;
- SourceLocation location;
- int lineNumberStart;
- int lineNumberEnd;
- std::string name;
- std::string USR;
- std::string debugText;
- bool isIncomplete;
- bool isDependent;
- bool isImplicit;
- bool isInvalid;
- bool isDeprecated;
- Declaration* completeDeclaration;
- unsigned definitionOrder;
- VECTOR(PreprocessedEntity*, PreprocessedEntities)
- VECTOR(Declaration*, Redeclarations)
- void* originalPtr;
- RawComment* comment;
-};
-
-class Class;
-class Enumeration;
-class Function;
-class TypedefDecl;
-class TypeAlias;
-class Namespace;
-class Template;
-class TypeAliasTemplate;
-class ClassTemplate;
-class FunctionTemplate;
-class Variable;
-class Friend;
-
-class CS_API DeclarationContext : public Declaration
-{
-public:
- DeclarationContext(DeclarationKind kind);
-
- CS_IGNORE Declaration* FindAnonymous(const std::string& USR);
-
- CS_IGNORE Namespace* FindNamespace(const std::string& Name);
- CS_IGNORE Namespace* FindNamespace(const std::vector&);
- CS_IGNORE Namespace* FindCreateNamespace(const std::string& Name);
-
- CS_IGNORE Class* CreateClass(const std::string& Name, bool IsComplete);
- CS_IGNORE Class* FindClass(const void* OriginalPtr, const std::string& Name, bool IsComplete);
- CS_IGNORE Class* FindClass(const void* OriginalPtr, const std::string& Name, bool IsComplete,
- bool Create);
-
- CS_IGNORE template T* FindTemplate(const std::string& USR);
-
- CS_IGNORE Enumeration* FindEnum(const void* OriginalPtr);
- CS_IGNORE Enumeration* FindEnum(const std::string& Name, bool Create = false);
- CS_IGNORE Enumeration* FindEnumWithItem(const std::string& Name);
-
- CS_IGNORE Function* FindFunction(const std::string& USR);
-
- CS_IGNORE TypedefDecl* FindTypedef(const std::string& Name, bool Create = false);
-
- CS_IGNORE TypeAlias* FindTypeAlias(const std::string& Name, bool Create = false);
-
- CS_IGNORE Variable* FindVariable(const std::string& USR);
-
- CS_IGNORE Friend* FindFriend(const std::string& USR);
-
- VECTOR(Namespace*, Namespaces)
- VECTOR(Enumeration*, Enums)
- VECTOR(Function*, Functions)
- VECTOR(Class*, Classes)
- VECTOR(Template*, Templates)
- VECTOR(TypedefDecl*, Typedefs)
- VECTOR(TypeAlias*, TypeAliases)
- VECTOR(Variable*, Variables)
- VECTOR(Friend*, Friends)
-
- std::map anonymous;
-
- bool isAnonymous;
-};
-
-class CS_API TypedefNameDecl : public Declaration
-{
-public:
- TypedefNameDecl(DeclarationKind kind);
- ~TypedefNameDecl();
- QualifiedType qualifiedType;
-};
-
-class CS_API TypedefDecl : public TypedefNameDecl
-{
-public:
- DECLARE_DECL_KIND(TypedefDecl, Typedef)
- ~TypedefDecl();
-};
-
-class CS_API TypeAlias : public TypedefNameDecl
-{
-public:
- TypeAlias();
- ~TypeAlias();
- TypeAliasTemplate* describedAliasTemplate;
-};
-
-class CS_API Friend : public Declaration
-{
-public:
- DECLARE_DECL_KIND(Friend, Friend)
- ~Friend();
- Declaration* declaration;
-};
-
-enum class StatementClassObsolete
-{
- Any,
- BinaryOperator,
- CallExprClass,
- DeclRefExprClass,
- CXXConstructExprClass,
- CXXOperatorCallExpr,
- ImplicitCastExpr,
- ExplicitCastExpr,
-};
-
-class CS_API StatementObsolete
-{
-public:
- StatementObsolete(const std::string& str, StatementClassObsolete Class = StatementClassObsolete::Any, Declaration* decl = 0);
- StatementClassObsolete _class;
- Declaration* decl;
- std::string string;
-};
-
-class CS_API ExpressionObsolete : public StatementObsolete
-{
-public:
- ExpressionObsolete(const std::string& str, StatementClassObsolete Class = StatementClassObsolete::Any, Declaration* decl = 0);
-};
-
-class Expr;
-
-class CS_API BinaryOperatorObsolete : public ExpressionObsolete
-{
-public:
- BinaryOperatorObsolete(const std::string& str, ExpressionObsolete* lhs, ExpressionObsolete* rhs, const std::string& opcodeStr);
- ~BinaryOperatorObsolete();
- ExpressionObsolete* LHS;
- ExpressionObsolete* RHS;
- std::string opcodeStr;
-};
-
-class CS_API CallExprObsolete : public ExpressionObsolete
-{
-public:
- CallExprObsolete(const std::string& str, Declaration* decl);
- ~CallExprObsolete();
- VECTOR(ExpressionObsolete*, Arguments)
-};
-
-class CS_API CXXConstructExprObsolete : public ExpressionObsolete
-{
-public:
- CXXConstructExprObsolete(const std::string& str, Declaration* decl = 0);
- ~CXXConstructExprObsolete();
- VECTOR(ExpressionObsolete*, Arguments)
-};
-
-class CS_API Parameter : public Declaration
-{
-public:
- Parameter();
- ~Parameter();
-
- QualifiedType qualifiedType;
- bool isIndirect;
- bool hasDefaultValue;
- unsigned int index;
- ExpressionObsolete* defaultArgument;
- Expr* defaultValue;
-};
-
-enum class CXXMethodKind
-{
- Normal,
- Constructor,
- Destructor,
- Conversion,
- Operator,
- UsingDirective
-};
-
-enum class CXXOperatorKind
-{
- None,
- New,
- Delete,
- Array_New,
- Array_Delete,
- Plus,
- Minus,
- Star,
- Slash,
- Percent,
- Caret,
- Amp,
- Pipe,
- Tilde,
- Exclaim,
- Equal,
- Less,
- Greater,
- PlusEqual,
- MinusEqual,
- StarEqual,
- SlashEqual,
- PercentEqual,
- CaretEqual,
- AmpEqual,
- PipeEqual,
- LessLess,
- GreaterGreater,
- LessLessEqual,
- GreaterGreaterEqual,
- EqualEqual,
- ExclaimEqual,
- LessEqual,
- GreaterEqual,
- Spaceship,
- AmpAmp,
- PipePipe,
- PlusPlus,
- MinusMinus,
- Comma,
- ArrowStar,
- Arrow,
- Call,
- Subscript,
- Conditional,
- Coawait
-};
-
-class FunctionTemplateSpecialization;
-
-enum class FriendKind
-{
- None,
- Declared,
- Undeclared
-};
-
-class Stmt;
-
-class CS_API Function : public DeclarationContext
-{
-public:
- Function();
- ~Function();
-
- QualifiedType returnType;
- bool isReturnIndirect;
- bool hasThisReturn;
-
- bool isConstExpr;
- bool isVariadic;
- bool isInline;
- bool isPure;
- bool isDeleted;
- bool isDefaulted;
- FriendKind friendKind;
- CXXOperatorKind operatorKind;
- std::string mangled;
- std::string signature;
- std::string body;
- Stmt* bodyStmt;
- CallingConvention callingConvention;
- VECTOR(Parameter*, Parameters)
- FunctionTemplateSpecialization* specializationInfo;
- Function* instantiatedFrom;
- QualifiedType qualifiedType;
-};
-
-class AccessSpecifierDecl;
-
-enum class RefQualifierKind
-{
- None,
- LValue,
- RValue
-};
-
-class CS_API Method : public Function
-{
-public:
- Method();
- ~Method();
-
- bool isVirtual;
- bool isStatic;
- bool isConst;
- bool isExplicit;
-
- CXXMethodKind methodKind;
-
- bool isDefaultConstructor;
- bool isCopyConstructor;
- bool isMoveConstructor;
-
- QualifiedType conversionType;
- RefQualifierKind refQualifier;
- VECTOR(Method*, OverriddenMethods)
-};
-
-class CS_API Enumeration : public DeclarationContext
-{
-public:
- DECLARE_DECL_KIND(Enumeration, Enumeration)
- ~Enumeration();
-
- class CS_API Item : public Declaration
- {
- public:
- DECLARE_DECL_KIND(Item, EnumerationItem)
- Item(const Item&);
- ~Item();
- std::string expression;
- uint64_t value;
- };
-
- enum class CS_FLAGS EnumModifiers
- {
- Anonymous = 1 << 0,
- Scoped = 1 << 1,
- Flags = 1 << 2,
- };
-
- EnumModifiers modifiers;
- Type* type;
- BuiltinType* builtinType;
- VECTOR(Item*, Items)
-
- Item* FindItemByName(const std::string& Name);
-};
-
-class CS_API Variable : public Declaration
-{
-public:
- DECLARE_DECL_KIND(Variable, Variable)
- ~Variable();
- bool isConstExpr;
- std::string mangled;
- QualifiedType qualifiedType;
- ExpressionObsolete* initializer;
-};
-
-class PreprocessedEntity;
-
-struct CS_API BaseClassSpecifier
-{
- BaseClassSpecifier();
- AccessSpecifier access;
- bool isVirtual;
- Type* type;
- int offset;
-};
-
-class Class;
-
-class CS_API Field : public Declaration
-{
-public:
- DECLARE_DECL_KIND(Field, Field)
- ~Field();
- QualifiedType qualifiedType;
- Class* _class;
- bool isBitField;
- unsigned bitWidth;
-};
-
-class CS_API AccessSpecifierDecl : public Declaration
-{
-public:
- DECLARE_DECL_KIND(AccessSpecifierDecl, AccessSpecifier)
- ~AccessSpecifierDecl();
-};
-
-enum class CppAbi
-{
- Itanium,
- Microsoft,
- ARM,
- iOS,
- iOS64
-};
-
-enum class VTableComponentKind
-{
- VCallOffset,
- VBaseOffset,
- OffsetToTop,
- RTTI,
- FunctionPointer,
- CompleteDtorPointer,
- DeletingDtorPointer,
- UnusedFunctionPointer,
-};
-
-struct CS_API VTableComponent
-{
- VTableComponent();
- VTableComponentKind kind;
- unsigned offset;
- Declaration* declaration;
-};
-
-struct CS_API VTableLayout
-{
- VTableLayout();
- VTableLayout(const VTableLayout&);
- ~VTableLayout();
- VECTOR(VTableComponent, Components)
-};
-
-struct CS_API VFTableInfo
-{
- VFTableInfo();
- VFTableInfo(const VFTableInfo&);
- uint64_t VBTableIndex;
- uint32_t VFPtrOffset;
- uint32_t VFPtrFullOffset;
- VTableLayout layout;
-};
-
-class CS_API LayoutField
-{
-public:
- LayoutField();
- LayoutField(const LayoutField& other);
- ~LayoutField();
- unsigned offset;
- std::string name;
- QualifiedType qualifiedType;
- void* fieldPtr;
-};
-
-class Class;
-
-class CS_API LayoutBase
-{
-public:
- LayoutBase();
- LayoutBase(const LayoutBase& other);
- ~LayoutBase();
- unsigned offset;
- Class* _class;
-};
-
-enum class RecordArgABI
-{
- /// Pass it using the normal C aggregate rules for the ABI,
- /// potentially introducing extra copies and passing some
- /// or all of it in registers.
- Default = 0,
- /// Pass it on the stack using its defined layout.
- /// The argument must be evaluated directly into the correct
- /// stack position in the arguments area, and the call machinery
- /// must not move it or introduce extra copies.
- DirectInMemory,
- /// Pass it as a pointer to temporary memory.
- Indirect
-};
-
-struct CS_API ClassLayout
-{
- ClassLayout();
- CppAbi ABI;
- RecordArgABI argABI;
- VECTOR(VFTableInfo, VFTables)
- VTableLayout layout;
- bool hasOwnVFPtr;
- long VBPtrOffset;
- int alignment;
- int size;
- int dataSize;
- VECTOR(LayoutField, Fields)
- VECTOR(LayoutBase, Bases)
-};
-
-enum class TagKind
-{
- Struct,
- Interface,
- Union,
- Class,
- Enum
-};
-
-class CS_API Class : public DeclarationContext
-{
-public:
- Class();
- ~Class();
-
- VECTOR(BaseClassSpecifier*, Bases)
- VECTOR(Field*, Fields)
- VECTOR(Method*, Methods)
- VECTOR(AccessSpecifierDecl*, Specifiers)
-
- bool isPOD;
- bool isAbstract;
- bool isUnion;
- bool isDynamic;
- bool isPolymorphic;
- bool hasNonTrivialDefaultConstructor;
- bool hasNonTrivialCopyConstructor;
- bool hasNonTrivialDestructor;
- bool isExternCContext;
- bool isInjected;
- TagKind tagKind;
-
- ClassLayout* layout;
-};
-
-class CS_API Template : public Declaration
-{
-public:
- Template(DeclarationKind kind);
- DECLARE_DECL_KIND(Template, Template)
- Declaration* TemplatedDecl;
- VECTOR(Declaration*, Parameters)
-};
-
-template
-T* DeclarationContext::FindTemplate(const std::string& USR)
-{
- auto foundTemplate = std::find_if(Templates.begin(), Templates.end(),
- [&](Template* t) { return t->USR == USR; });
-
- if (foundTemplate != Templates.end())
- return static_cast(*foundTemplate);
-
- return nullptr;
-}
-
-class CS_API TypeAliasTemplate : public Template
-{
-public:
- TypeAliasTemplate();
- ~TypeAliasTemplate();
-};
-
-class CS_API TemplateParameter : public Declaration
-{
-public:
- TemplateParameter(DeclarationKind kind);
- ~TemplateParameter();
- unsigned int depth;
- unsigned int index;
- bool isParameterPack;
-};
-
-class CS_API TemplateTemplateParameter : public Template
-{
-public:
- TemplateTemplateParameter();
- ~TemplateTemplateParameter();
-
- bool isParameterPack;
- bool isPackExpansion;
- bool isExpandedParameterPack;
-};
-
-class CS_API TypeTemplateParameter : public TemplateParameter
-{
-public:
- TypeTemplateParameter();
- TypeTemplateParameter(const TypeTemplateParameter&);
- ~TypeTemplateParameter();
-
- QualifiedType defaultArgument;
-};
-
-class CS_API NonTypeTemplateParameter : public TemplateParameter
-{
-public:
- NonTypeTemplateParameter();
- NonTypeTemplateParameter(const NonTypeTemplateParameter&);
- ~NonTypeTemplateParameter();
- ExpressionObsolete* defaultArgument;
- Expr* defaultArgumentNew;
- unsigned int position;
- bool isPackExpansion;
- bool isExpandedParameterPack;
-};
-
-class ClassTemplateSpecialization;
-class ClassTemplatePartialSpecialization;
-
-class CS_API ClassTemplate : public Template
-{
-public:
- ClassTemplate();
- ~ClassTemplate();
- VECTOR(ClassTemplateSpecialization*, Specializations)
- ClassTemplateSpecialization* FindSpecialization(const std::string& usr);
- ClassTemplatePartialSpecialization* FindPartialSpecialization(const std::string& usr);
-};
-
-enum class TemplateSpecializationKind
-{
- Undeclared,
- ImplicitInstantiation,
- ExplicitSpecialization,
- ExplicitInstantiationDeclaration,
- ExplicitInstantiationDefinition
-};
-
-class CS_API ClassTemplateSpecialization : public Class
-{
-public:
- ClassTemplateSpecialization();
- ~ClassTemplateSpecialization();
- ClassTemplate* templatedDecl;
- VECTOR(TemplateArgument, Arguments)
- TemplateSpecializationKind specializationKind;
-};
-
-class CS_API ClassTemplatePartialSpecialization : public ClassTemplateSpecialization
-{
-public:
- ClassTemplatePartialSpecialization();
- ~ClassTemplatePartialSpecialization();
-};
-
-class CS_API FunctionTemplate : public Template
-{
-public:
- FunctionTemplate();
- ~FunctionTemplate();
- VECTOR(FunctionTemplateSpecialization*, Specializations)
- FunctionTemplateSpecialization* FindSpecialization(const std::string& usr);
-};
-
-class CS_API FunctionTemplateSpecialization
-{
-public:
- FunctionTemplateSpecialization();
- ~FunctionTemplateSpecialization();
- FunctionTemplate* _template;
- VECTOR(TemplateArgument, Arguments)
- Function* specializedFunction;
- TemplateSpecializationKind specializationKind;
-};
-
-class VarTemplateSpecialization;
-class VarTemplatePartialSpecialization;
-
-class CS_API VarTemplate : public Template
-{
-public:
- VarTemplate();
- ~VarTemplate();
- VECTOR(VarTemplateSpecialization*, Specializations)
- VarTemplateSpecialization* FindSpecialization(const std::string& usr);
- VarTemplatePartialSpecialization* FindPartialSpecialization(const std::string& usr);
-};
-
-class CS_API VarTemplateSpecialization : public Variable
-{
-public:
- VarTemplateSpecialization();
- ~VarTemplateSpecialization();
- VarTemplate* templatedDecl;
- VECTOR(TemplateArgument, Arguments)
- TemplateSpecializationKind specializationKind;
-};
-
-class CS_API VarTemplatePartialSpecialization : public VarTemplateSpecialization
-{
-public:
- VarTemplatePartialSpecialization();
- ~VarTemplatePartialSpecialization();
-};
-
-class CS_API UnresolvedUsingTypename : public Declaration
-{
-public:
- UnresolvedUsingTypename();
- ~UnresolvedUsingTypename();
-};
-
-class CS_API Namespace : public DeclarationContext
-{
-public:
- Namespace();
- ~Namespace();
- bool isInline;
-};
-
-enum class MacroLocation
-{
- Unknown,
- ClassHead,
- ClassBody,
- FunctionHead,
- FunctionParameters,
- FunctionBody,
-};
-
-class CS_API PreprocessedEntity
-{
-public:
- PreprocessedEntity();
- MacroLocation macroLocation;
- void* originalPtr;
- DeclarationKind kind;
-};
-
-class CS_API MacroDefinition : public PreprocessedEntity
-{
-public:
- MacroDefinition();
- ~MacroDefinition();
- std::string name;
- std::string expression;
- int lineNumberStart;
- int lineNumberEnd;
-};
-
-class CS_API MacroExpansion : public PreprocessedEntity
-{
-public:
- MacroExpansion();
- ~MacroExpansion();
- std::string name;
- std::string text;
- MacroDefinition* definition;
-};
-
-class CS_API TranslationUnit : public Namespace
-{
-public:
- TranslationUnit();
- ~TranslationUnit();
- std::string fileName;
- bool isSystemHeader;
- VECTOR(MacroDefinition*, Macros)
-};
-
-class CS_API ASTContext
-{
-public:
- ASTContext();
- ~ASTContext();
- TranslationUnit* FindOrCreateModule(std::string File);
- VECTOR(TranslationUnit*, TranslationUnits)
-};
-
-} } }
\ No newline at end of file
+ enum class AccessSpecifier
+ {
+ Private,
+ Protected,
+ Public
+ };
+
+ class DeclarationContext;
+ class RawComment;
+ class PreprocessedEntity;
+
+ class ExpressionObsolete;
+ class CS_API Declaration
+ {
+ public:
+ Declaration(DeclarationKind kind);
+ Declaration(const Declaration &);
+ ~Declaration();
+
+ DeclarationKind kind;
+ int alignAs;
+ int maxFieldAlignment;
+ AccessSpecifier access;
+ DeclarationContext *_namespace;
+ SourceLocation location;
+ int lineNumberStart;
+ int lineNumberEnd;
+ std::string name;
+ std::string USR;
+ std::string debugText;
+ bool isIncomplete;
+ bool isDependent;
+ bool isImplicit;
+ bool isInvalid;
+ bool isDeprecated;
+ Declaration *completeDeclaration;
+ unsigned definitionOrder;
+ VECTOR(PreprocessedEntity *, PreprocessedEntities)
+ VECTOR(Declaration *, Redeclarations)
+ void *originalPtr;
+ RawComment *comment;
+ };
+
+ class Class;
+ class Enumeration;
+ class Function;
+ class TypedefDecl;
+ class TypeAlias;
+ class Namespace;
+ class Template;
+ class TypeAliasTemplate;
+ class ClassTemplate;
+ class FunctionTemplate;
+ class Variable;
+ class Friend;
+
+ class CS_API DeclarationContext : public Declaration
+ {
+ public:
+ DeclarationContext(DeclarationKind kind);
+
+ CS_IGNORE Declaration *FindAnonymous(const std::string &USR);
+
+ CS_IGNORE Namespace *FindNamespace(const std::string &Name);
+ CS_IGNORE Namespace *FindNamespace(const std::vector &);
+ CS_IGNORE Namespace *FindCreateNamespace(const std::string &Name);
+
+ CS_IGNORE Class *CreateClass(const std::string &Name, bool IsComplete);
+ CS_IGNORE Class *FindClass(const void *OriginalPtr, const std::string &Name, bool IsComplete);
+ CS_IGNORE Class *FindClass(const void *OriginalPtr, const std::string &Name, bool IsComplete,
+ bool Create);
+
+ CS_IGNORE template
+ T *FindTemplate(const std::string &USR);
+
+ CS_IGNORE Enumeration *FindEnum(const void *OriginalPtr);
+ CS_IGNORE Enumeration *FindEnum(const std::string &Name, bool Create = false);
+ CS_IGNORE Enumeration *FindEnumWithItem(const std::string &Name);
+
+ CS_IGNORE Function *FindFunction(const std::string &USR);
+
+ CS_IGNORE TypedefDecl *FindTypedef(const std::string &Name, bool Create = false);
+
+ CS_IGNORE TypeAlias *FindTypeAlias(const std::string &Name, bool Create = false);
+
+ CS_IGNORE Variable *FindVariable(const std::string &USR);
+
+ CS_IGNORE Friend *FindFriend(const std::string &USR);
+
+ VECTOR(Namespace *, Namespaces)
+ VECTOR(Enumeration *, Enums)
+ VECTOR(Function *, Functions)
+ VECTOR(Class *, Classes)
+ VECTOR(Template *, Templates)
+ VECTOR(TypedefDecl *, Typedefs)
+ VECTOR(TypeAlias *, TypeAliases)
+ VECTOR(Variable *, Variables)
+ VECTOR(Friend *, Friends)
+
+ std::map anonymous;
+
+ bool isAnonymous;
+ };
+
+ class CS_API TypedefNameDecl : public Declaration
+ {
+ public:
+ TypedefNameDecl(DeclarationKind kind);
+ ~TypedefNameDecl();
+ QualifiedType qualifiedType;
+ };
+
+ class CS_API TypedefDecl : public TypedefNameDecl
+ {
+ public:
+ DECLARE_DECL_KIND(TypedefDecl, Typedef)
+ ~TypedefDecl();
+ };
+
+ class CS_API TypeAlias : public TypedefNameDecl
+ {
+ public:
+ TypeAlias();
+ ~TypeAlias();
+ TypeAliasTemplate *describedAliasTemplate;
+ };
+
+ class CS_API Friend : public Declaration
+ {
+ public:
+ DECLARE_DECL_KIND(Friend, Friend)
+ ~Friend();
+ Declaration *declaration;
+ };
+
+ enum class StatementClassObsolete
+ {
+ Any,
+ BinaryOperator,
+ CallExprClass,
+ DeclRefExprClass,
+ CXXConstructExprClass,
+ CXXOperatorCallExpr,
+ ImplicitCastExpr,
+ ExplicitCastExpr,
+ };
+
+ class CS_API StatementObsolete
+ {
+ public:
+ StatementObsolete(const std::string &str, StatementClassObsolete Class = StatementClassObsolete::Any, Declaration *decl = 0);
+ StatementClassObsolete _class;
+ Declaration *decl;
+ std::string string;
+ };
+
+ class CS_API ExpressionObsolete : public StatementObsolete
+ {
+ public:
+ ExpressionObsolete(const std::string &str, StatementClassObsolete Class = StatementClassObsolete::Any, Declaration *decl = 0);
+ };
+
+ class Expr;
+
+ class CS_API BinaryOperatorObsolete : public ExpressionObsolete
+ {
+ public:
+ BinaryOperatorObsolete(const std::string &str, ExpressionObsolete *lhs, ExpressionObsolete *rhs, const std::string &opcodeStr);
+ ~BinaryOperatorObsolete();
+ ExpressionObsolete *LHS;
+ ExpressionObsolete *RHS;
+ std::string opcodeStr;
+ };
+
+ class CS_API CallExprObsolete : public ExpressionObsolete
+ {
+ public:
+ CallExprObsolete(const std::string &str, Declaration *decl);
+ ~CallExprObsolete();
+ VECTOR(ExpressionObsolete *, Arguments)
+ };
+
+ class CS_API CXXConstructExprObsolete : public ExpressionObsolete
+ {
+ public:
+ CXXConstructExprObsolete(const std::string &str, Declaration *decl = 0);
+ ~CXXConstructExprObsolete();
+ VECTOR(ExpressionObsolete *, Arguments)
+ };
+
+ class CS_API Parameter : public Declaration
+ {
+ public:
+ Parameter();
+ ~Parameter();
+
+ QualifiedType qualifiedType;
+ bool isIndirect;
+ bool hasDefaultValue;
+ unsigned int index;
+ ExpressionObsolete *defaultArgument;
+ Expr *defaultValue;
+ };
+
+ enum class CXXMethodKind
+ {
+ Normal,
+ Constructor,
+ Destructor,
+ Conversion,
+ Operator,
+ UsingDirective
+ };
+
+ enum class CXXOperatorKind
+ {
+ None,
+ New,
+ Delete,
+ Array_New,
+ Array_Delete,
+ Plus,
+ Minus,
+ Star,
+ Slash,
+ Percent,
+ Caret,
+ Amp,
+ Pipe,
+ Tilde,
+ Exclaim,
+ Equal,
+ Less,
+ Greater,
+ PlusEqual,
+ MinusEqual,
+ StarEqual,
+ SlashEqual,
+ PercentEqual,
+ CaretEqual,
+ AmpEqual,
+ PipeEqual,
+ LessLess,
+ GreaterGreater,
+ LessLessEqual,
+ GreaterGreaterEqual,
+ EqualEqual,
+ ExclaimEqual,
+ LessEqual,
+ GreaterEqual,
+ Spaceship,
+ AmpAmp,
+ PipePipe,
+ PlusPlus,
+ MinusMinus,
+ Comma,
+ ArrowStar,
+ Arrow,
+ Call,
+ Subscript,
+ Conditional,
+ Coawait
+ };
+
+ class FunctionTemplateSpecialization;
+
+ enum class FriendKind
+ {
+ None,
+ Declared,
+ Undeclared
+ };
+
+ class Stmt;
+
+ class CS_API Function : public DeclarationContext
+ {
+ public:
+ Function();
+ ~Function();
+
+ QualifiedType returnType;
+ bool isReturnIndirect;
+ bool hasThisReturn;
+
+ bool isConstExpr;
+ bool isVariadic;
+ bool isInline;
+ bool isPure;
+ bool isDeleted;
+ bool isDefaulted;
+ FriendKind friendKind;
+ CXXOperatorKind operatorKind;
+ std::string mangled;
+ std::string signature;
+ std::string body;
+ Stmt *bodyStmt;
+ CallingConvention callingConvention;
+ VECTOR(Parameter *, Parameters)
+ FunctionTemplateSpecialization *specializationInfo;
+ Function *instantiatedFrom;
+ QualifiedType qualifiedType;
+ };
+
+ class AccessSpecifierDecl;
+
+ enum class RefQualifierKind
+ {
+ None,
+ LValue,
+ RValue
+ };
+
+ class CS_API Method : public Function
+ {
+ public:
+ Method();
+ ~Method();
+
+ bool isVirtual;
+ bool isStatic;
+ bool isConst;
+ bool isExplicit;
+
+ CXXMethodKind methodKind;
+
+ bool isDefaultConstructor;
+ bool isCopyConstructor;
+ bool isMoveConstructor;
+
+ QualifiedType conversionType;
+ RefQualifierKind refQualifier;
+ VECTOR(Method *, OverriddenMethods)
+ };
+
+ class CS_API Enumeration : public DeclarationContext
+ {
+ public:
+ DECLARE_DECL_KIND(Enumeration, Enumeration)
+ ~Enumeration();
+
+ class CS_API Item : public Declaration
+ {
+ public:
+ DECLARE_DECL_KIND(Item, EnumerationItem)
+ Item(const Item &);
+ ~Item();
+ std::string expression;
+ uint64_t value;
+ };
+
+ enum class CS_FLAGS EnumModifiers
+ {
+ Anonymous = 1 << 0,
+ Scoped = 1 << 1,
+ Flags = 1 << 2,
+ };
+
+ EnumModifiers modifiers;
+ Type *type;
+ BuiltinType *builtinType;
+ VECTOR(Item *, Items)
+
+ Item *FindItemByName(const std::string &Name);
+ };
+
+ class CS_API Variable : public Declaration
+ {
+ public:
+ DECLARE_DECL_KIND(Variable, Variable)
+ ~Variable();
+ bool isConstExpr;
+ std::string mangled;
+ QualifiedType qualifiedType;
+ ExpressionObsolete *initializer;
+ };
+
+ class PreprocessedEntity;
+
+ struct CS_API BaseClassSpecifier
+ {
+ BaseClassSpecifier();
+ AccessSpecifier access;
+ bool isVirtual;
+ Type *type;
+ int offset;
+ };
+
+ class Class;
+
+ class CS_API Field : public Declaration
+ {
+ public:
+ DECLARE_DECL_KIND(Field, Field)
+ ~Field();
+ QualifiedType qualifiedType;
+ Class *_class;
+ bool isBitField;
+ unsigned bitWidth;
+ };
+
+ class CS_API AccessSpecifierDecl : public Declaration
+ {
+ public:
+ DECLARE_DECL_KIND(AccessSpecifierDecl, AccessSpecifier)
+ ~AccessSpecifierDecl();
+ };
+
+ enum class CppAbi
+ {
+ Itanium,
+ Microsoft,
+ ARM,
+ iOS,
+ iOS64,
+ WebAssembly
+ };
+
+ enum class VTableComponentKind
+ {
+ VCallOffset,
+ VBaseOffset,
+ OffsetToTop,
+ RTTI,
+ FunctionPointer,
+ CompleteDtorPointer,
+ DeletingDtorPointer,
+ UnusedFunctionPointer,
+ };
+
+ struct CS_API VTableComponent
+ {
+ VTableComponent();
+ VTableComponentKind kind;
+ unsigned offset;
+ Declaration *declaration;
+ };
+
+ struct CS_API VTableLayout
+ {
+ VTableLayout();
+ VTableLayout(const VTableLayout &);
+ ~VTableLayout();
+ VECTOR(VTableComponent, Components)
+ };
+
+ struct CS_API VFTableInfo
+ {
+ VFTableInfo();
+ VFTableInfo(const VFTableInfo &);
+ uint64_t VBTableIndex;
+ uint32_t VFPtrOffset;
+ uint32_t VFPtrFullOffset;
+ VTableLayout layout;
+ };
+
+ class CS_API LayoutField
+ {
+ public:
+ LayoutField();
+ LayoutField(const LayoutField &other);
+ ~LayoutField();
+ unsigned offset;
+ std::string name;
+ QualifiedType qualifiedType;
+ void *fieldPtr;
+ };
+
+ class Class;
+
+ class CS_API LayoutBase
+ {
+ public:
+ LayoutBase();
+ LayoutBase(const LayoutBase &other);
+ ~LayoutBase();
+ unsigned offset;
+ Class *_class;
+ };
+
+ enum class RecordArgABI
+ {
+ /// Pass it using the normal C aggregate rules for the ABI,
+ /// potentially introducing extra copies and passing some
+ /// or all of it in registers.
+ Default = 0,
+ /// Pass it on the stack using its defined layout.
+ /// The argument must be evaluated directly into the correct
+ /// stack position in the arguments area, and the call machinery
+ /// must not move it or introduce extra copies.
+ DirectInMemory,
+ /// Pass it as a pointer to temporary memory.
+ Indirect
+ };
+
+ struct CS_API ClassLayout
+ {
+ ClassLayout();
+ CppAbi ABI;
+ RecordArgABI argABI;
+ VECTOR(VFTableInfo, VFTables)
+ VTableLayout layout;
+ bool hasOwnVFPtr;
+ long VBPtrOffset;
+ int alignment;
+ int size;
+ int dataSize;
+ VECTOR(LayoutField, Fields)
+ VECTOR(LayoutBase, Bases)
+ };
+
+ enum class TagKind
+ {
+ Struct,
+ Interface,
+ Union,
+ Class,
+ Enum
+ };
+
+ class CS_API Class : public DeclarationContext
+ {
+ public:
+ Class();
+ ~Class();
+
+ VECTOR(BaseClassSpecifier *, Bases)
+ VECTOR(Field *, Fields)
+ VECTOR(Method *, Methods)
+ VECTOR(AccessSpecifierDecl *, Specifiers)
+
+ bool isPOD;
+ bool isAbstract;
+ bool isUnion;
+ bool isDynamic;
+ bool isPolymorphic;
+ bool hasNonTrivialDefaultConstructor;
+ bool hasNonTrivialCopyConstructor;
+ bool hasNonTrivialDestructor;
+ bool isExternCContext;
+ bool isInjected;
+ TagKind tagKind;
+
+ ClassLayout *layout;
+ };
+
+ class CS_API Template : public Declaration
+ {
+ public:
+ Template(DeclarationKind kind);
+ DECLARE_DECL_KIND(Template, Template)
+ Declaration *TemplatedDecl;
+ VECTOR(Declaration *, Parameters)
+ };
+
+ template
+ T *DeclarationContext::FindTemplate(const std::string &USR)
+ {
+ auto foundTemplate = std::find_if(Templates.begin(), Templates.end(),
+ [&](Template *t)
+ { return t->USR == USR; });
+
+ if (foundTemplate != Templates.end())
+ return static_cast(*foundTemplate);
+
+ return nullptr;
+ }
+
+ class CS_API TypeAliasTemplate : public Template
+ {
+ public:
+ TypeAliasTemplate();
+ ~TypeAliasTemplate();
+ };
+
+ class CS_API TemplateParameter : public Declaration
+ {
+ public:
+ TemplateParameter(DeclarationKind kind);
+ ~TemplateParameter();
+ unsigned int depth;
+ unsigned int index;
+ bool isParameterPack;
+ };
+
+ class CS_API TemplateTemplateParameter : public Template
+ {
+ public:
+ TemplateTemplateParameter();
+ ~TemplateTemplateParameter();
+
+ bool isParameterPack;
+ bool isPackExpansion;
+ bool isExpandedParameterPack;
+ };
+
+ class CS_API TypeTemplateParameter : public TemplateParameter
+ {
+ public:
+ TypeTemplateParameter();
+ TypeTemplateParameter(const TypeTemplateParameter &);
+ ~TypeTemplateParameter();
+
+ QualifiedType defaultArgument;
+ };
+
+ class CS_API NonTypeTemplateParameter : public TemplateParameter
+ {
+ public:
+ NonTypeTemplateParameter();
+ NonTypeTemplateParameter(const NonTypeTemplateParameter &);
+ ~NonTypeTemplateParameter();
+ ExpressionObsolete *defaultArgument;
+ Expr *defaultArgumentNew;
+ unsigned int position;
+ bool isPackExpansion;
+ bool isExpandedParameterPack;
+ QualifiedType type;
+ };
+
+ class ClassTemplateSpecialization;
+ class ClassTemplatePartialSpecialization;
+
+ class CS_API ClassTemplate : public Template
+ {
+ public:
+ ClassTemplate();
+ ~ClassTemplate();
+ VECTOR(ClassTemplateSpecialization *, Specializations)
+ ClassTemplateSpecialization *FindSpecialization(const std::string &usr);
+ ClassTemplatePartialSpecialization *FindPartialSpecialization(const std::string &usr);
+ };
+
+ enum class TemplateSpecializationKind
+ {
+ Undeclared,
+ ImplicitInstantiation,
+ ExplicitSpecialization,
+ ExplicitInstantiationDeclaration,
+ ExplicitInstantiationDefinition
+ };
+
+ class CS_API ClassTemplateSpecialization : public Class
+ {
+ public:
+ ClassTemplateSpecialization();
+ ~ClassTemplateSpecialization();
+ ClassTemplate *templatedDecl;
+ VECTOR(TemplateArgument, Arguments)
+ TemplateSpecializationKind specializationKind;
+ };
+
+ class CS_API ClassTemplatePartialSpecialization : public ClassTemplateSpecialization
+ {
+ public:
+ ClassTemplatePartialSpecialization();
+ ~ClassTemplatePartialSpecialization();
+ };
+
+ class CS_API FunctionTemplate : public Template
+ {
+ public:
+ FunctionTemplate();
+ ~FunctionTemplate();
+ VECTOR(FunctionTemplateSpecialization *, Specializations)
+ FunctionTemplateSpecialization *FindSpecialization(const std::string &usr);
+ };
+
+ class CS_API FunctionTemplateSpecialization
+ {
+ public:
+ FunctionTemplateSpecialization();
+ ~FunctionTemplateSpecialization();
+ FunctionTemplate *_template;
+ VECTOR(TemplateArgument, Arguments)
+ Function *specializedFunction;
+ TemplateSpecializationKind specializationKind;
+ };
+
+ class VarTemplateSpecialization;
+ class VarTemplatePartialSpecialization;
+
+ class CS_API VarTemplate : public Template
+ {
+ public:
+ VarTemplate();
+ ~VarTemplate();
+ VECTOR(VarTemplateSpecialization *, Specializations)
+ VarTemplateSpecialization *FindSpecialization(const std::string &usr);
+ VarTemplatePartialSpecialization *FindPartialSpecialization(const std::string &usr);
+ };
+
+ class CS_API VarTemplateSpecialization : public Variable
+ {
+ public:
+ VarTemplateSpecialization();
+ ~VarTemplateSpecialization();
+ VarTemplate *templatedDecl;
+ VECTOR(TemplateArgument, Arguments)
+ TemplateSpecializationKind specializationKind;
+ };
+
+ class CS_API VarTemplatePartialSpecialization : public VarTemplateSpecialization
+ {
+ public:
+ VarTemplatePartialSpecialization();
+ ~VarTemplatePartialSpecialization();
+ };
+
+ class CS_API UnresolvedUsingTypename : public Declaration
+ {
+ public:
+ UnresolvedUsingTypename();
+ ~UnresolvedUsingTypename();
+ };
+
+ class CS_API Namespace : public DeclarationContext
+ {
+ public:
+ Namespace();
+ ~Namespace();
+ bool isInline;
+ };
+
+ enum class MacroLocation
+ {
+ Unknown,
+ ClassHead,
+ ClassBody,
+ FunctionHead,
+ FunctionParameters,
+ FunctionBody,
+ };
+
+ class CS_API PreprocessedEntity
+ {
+ public:
+ PreprocessedEntity();
+ MacroLocation macroLocation;
+ void *originalPtr;
+ DeclarationKind kind;
+ };
+
+ class CS_API MacroDefinition : public PreprocessedEntity
+ {
+ public:
+ MacroDefinition();
+ ~MacroDefinition();
+ std::string name;
+ std::string expression;
+ int lineNumberStart;
+ int lineNumberEnd;
+ };
+
+ class CS_API MacroExpansion : public PreprocessedEntity
+ {
+ public:
+ MacroExpansion();
+ ~MacroExpansion();
+ std::string name;
+ std::string text;
+ MacroDefinition *definition;
+ };
+
+ class CS_API TranslationUnit : public Namespace
+ {
+ public:
+ TranslationUnit();
+ ~TranslationUnit();
+ std::string fileName;
+ bool isSystemHeader;
+ VECTOR(MacroDefinition *, Macros)
+ };
+
+ class CS_API ASTContext
+ {
+ public:
+ ASTContext();
+ ~ASTContext();
+ TranslationUnit *FindOrCreateModule(std::string File);
+ VECTOR(TranslationUnit *, TranslationUnits)
+ };
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/CppParser/Parser.cpp b/src/CppParser/Parser.cpp
index a64b091c95..97d7736643 100644
--- a/src/CppParser/Parser.cpp
+++ b/src/CppParser/Parser.cpp
@@ -104,6 +104,8 @@ static CppAbi GetClassLayoutAbi(clang::TargetCXXABI::Kind abi)
return CppAbi::iOS;
case clang::TargetCXXABI::AppleARM64:
return CppAbi::iOS64;
+ case clang::TargetCXXABI::WebAssembly:
+ return CppAbi::WebAssembly;
default:
llvm_unreachable("Unsupported C++ ABI kind");
}
@@ -872,14 +874,31 @@ static bool IsRecordValid(const clang::RecordDecl* RC)
return IsRecordValid(RC, Visited);
}
-static clang::CXXRecordDecl* GetCXXRecordDeclFromBaseType(const clang::QualType& Ty) {
+static clang::CXXRecordDecl* GetCXXRecordDeclFromTemplateName(const clang::TemplateName& Name)
+{
+ using namespace clang;
+
+ switch (Name.getKind()) {
+ case clang::TemplateName::Template:
+ return dyn_cast(
+ Name.getAsTemplateDecl()->getTemplatedDecl());
+ case clang::TemplateName::QualifiedTemplate:
+ return dyn_cast(
+ Name.getAsQualifiedTemplateName()->getTemplateDecl()->getTemplatedDecl());
+ default:
+ assert(0 && "Unknown template name kind");
+ return nullptr;
+ }
+}
+
+static clang::CXXRecordDecl* GetCXXRecordDeclFromBaseType(const clang::QualType& Ty)
+{
using namespace clang;
if (auto RT = Ty->getAs())
return dyn_cast(RT->getDecl());
else if (auto TST = Ty->getAs())
- return dyn_cast(
- TST->getTemplateName().getAsTemplateDecl()->getTemplatedDecl());
+ return GetCXXRecordDeclFromTemplateName(TST->getTemplateName());
else if (auto Injected = Ty->getAs())
return Injected->getDecl();
@@ -1428,6 +1447,7 @@ NonTypeTemplateParameter* Parser::WalkNonTypeTemplateParameter(const clang::NonT
HandleDeclaration(NTTPD, NTP);
if (NTTPD->hasDefaultArgument())
NTP->defaultArgument = WalkExpressionObsolete(NTTPD->getDefaultArgument());
+ NTP->type = GetQualifiedType(NTTPD->getType());
NTP->depth = NTTPD->getDepth();
NTP->index = NTTPD->getIndex();
NTP->isParameterPack = NTTPD->isParameterPack();
diff --git a/src/Generator.Tests/GeneratorTest.cs b/src/Generator.Tests/GeneratorTest.cs
index feff986fb8..3805353ad7 100644
--- a/src/Generator.Tests/GeneratorTest.cs
+++ b/src/Generator.Tests/GeneratorTest.cs
@@ -35,23 +35,21 @@ public virtual void Setup(Driver driver)
testModule.LibraryName, options.GeneratorKind.ToString());
if (Platform.IsMacOS)
- driver.ParserOptions.TargetTriple = Environment.Is64BitProcess ?
- "x86_64-apple-darwin" : "i686-apple-darwin";
+ driver.ParserOptions.TargetTriple = "x86_64-apple-darwin";
var path = Path.GetFullPath(GetTestsDirectory(name));
testModule.IncludeDirs.Add(path);
testModule.LibraryDirs.Add(options.OutputDir);
testModule.Libraries.Add($"{name}.Native");
- Diagnostics.Message("Looking for tests in: {0}", path);
var files = Directory.EnumerateFiles(path, "*.h", SearchOption.AllDirectories);
foreach (var file in files)
{
- string includeDir = Path.GetDirectoryName(file);
+ var includeDir = Path.GetDirectoryName(file);
+
if (!testModule.IncludeDirs.Contains(includeDir))
- {
testModule.IncludeDirs.Add(includeDir);
- }
+
testModule.Headers.Add(Path.GetFileName(file));
}
}
@@ -72,16 +70,16 @@ public virtual void SetupPasses(Driver driver)
public static string GetTestsDirectory(string name)
{
var directory = new DirectoryInfo(
- Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
+ Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ?? string.Empty);
while (directory != null)
{
- var path = Path.Combine(directory.FullName, "tests", name);
+ var path = Path.Combine(directory.FullName, "tests", "dotnet", name);
if (Directory.Exists(path))
return path;
- path = Path.Combine(directory.FullName, "external", "CppSharp", "tests", name);
+ path = Path.Combine(directory.FullName, "external", "CppSharp", "tests", "dotnet", name);
if (Directory.Exists(path))
return path;
@@ -89,15 +87,12 @@ public static string GetTestsDirectory(string name)
directory = directory.Parent;
}
- throw new Exception(string.Format(
- "Tests directory for project '{0}' was not found", name));
+ throw new Exception($"Tests directory for project '{name}' was not found");
}
static string GetOutputDirectory()
{
- string exePath = new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath;
- var directory = Directory.GetParent(exePath);
-
+ var directory = Directory.GetParent(Assembly.GetExecutingAssembly().Location);
while (directory != null)
{
var path = Path.Combine(directory.FullName, "build");
diff --git a/src/Generator/AST/VTables.cs b/src/Generator/AST/VTables.cs
index 13add5b8fc..93e59ed9dc 100644
--- a/src/Generator/AST/VTables.cs
+++ b/src/Generator/AST/VTables.cs
@@ -34,6 +34,7 @@ private static List GatherVTableMethodEntries(VTableLayout layo
where component.Kind != VTableComponentKind.CompleteDtorPointer &&
component.Kind != VTableComponentKind.RTTI &&
component.Kind != VTableComponentKind.UnusedFunctionPointer &&
+ component.Kind != VTableComponentKind.OffsetToTop &&
component.Method != null
select component);
diff --git a/src/Generator/Driver.cs b/src/Generator/Driver.cs
index 3f9a847ec5..82780bfa2c 100644
--- a/src/Generator/Driver.cs
+++ b/src/Generator/Driver.cs
@@ -8,6 +8,7 @@
using CppSharp.Generators.CLI;
using CppSharp.Generators.Cpp;
using CppSharp.Generators.CSharp;
+using CppSharp.Generators.Emscripten;
using CppSharp.Generators.TS;
using CppSharp.Parser;
using CppSharp.Passes;
@@ -43,6 +44,8 @@ Generator CreateGeneratorFromKind(GeneratorKind kind)
return new CLIGenerator(Context);
case GeneratorKind.CSharp:
return new CSharpGenerator(Context);
+ case GeneratorKind.Emscripten:
+ return new EmscriptenGenerator(Context);
case GeneratorKind.QuickJS:
return new QuickJSGenerator(Context);
case GeneratorKind.NAPI:
@@ -82,7 +85,7 @@ void ValidateOptions()
public void Setup()
{
ValidateOptions();
- ParserOptions.Setup();
+ ParserOptions.Setup(Platform.Host);
Context = new BindingContext(Options, ParserOptions);
Context.LinkerOptions.Setup(ParserOptions.TargetTriple, ParserOptions.LanguageVersion);
Generator = CreateGeneratorFromKind(Options.GeneratorKind);
@@ -109,7 +112,8 @@ void OnFileParsed(IEnumerable files, ParserResult result)
switch (result.Kind)
{
case ParserResultKind.Success:
- Diagnostics.Message("Parsed '{0}'", string.Join(", ", files));
+ if (!Options.Quiet)
+ Diagnostics.Message("Parsed '{0}'", string.Join(", ", files));
break;
case ParserResultKind.Error:
Diagnostics.Error("Error parsing '{0}'", string.Join(", ", files));
@@ -180,27 +184,22 @@ public bool ParseLibraries()
ClangParser.LibraryParsed += OnFileParsed;
foreach (var module in Options.Modules)
{
- using (var linkerOptions = new LinkerOptions(Context.LinkerOptions))
+ using var linkerOptions = new LinkerOptions(Context.LinkerOptions);
+ foreach (var libraryDir in module.LibraryDirs)
+ linkerOptions.AddLibraryDirs(libraryDir);
+
+ foreach (var library in module.Libraries.Where(library =>
+ Context.Symbols.Libraries.All(l => l.FileName != library)))
{
- foreach (var libraryDir in module.LibraryDirs)
- linkerOptions.AddLibraryDirs(libraryDir);
-
- foreach (string library in module.Libraries)
- {
- if (Context.Symbols.Libraries.Any(l => l.FileName == library))
- continue;
- linkerOptions.AddLibraries(library);
- }
-
- using (var res = ClangParser.ParseLibrary(linkerOptions))
- {
- if (res.Kind != ParserResultKind.Success)
- continue;
-
- for (uint i = 0; i < res.LibrariesCount; i++)
- Context.Symbols.Libraries.Add(ClangParser.ConvertLibrary(res.GetLibraries(i)));
- }
+ linkerOptions.AddLibraries(library);
}
+
+ using var res = ClangParser.ParseLibrary(linkerOptions);
+ if (res.Kind != ParserResultKind.Success)
+ continue;
+
+ for (uint i = 0; i < res.LibrariesCount; i++)
+ Context.Symbols.Libraries.Add(ClangParser.ConvertLibrary(res.GetLibraries(i)));
}
ClangParser.LibraryParsed -= OnFileParsed;
@@ -212,95 +211,99 @@ public bool ParseLibraries()
public void SetupPasses(ILibrary library)
{
- var TranslationUnitPasses = Context.TranslationUnitPasses;
+ var passes = Context.TranslationUnitPasses;
- TranslationUnitPasses.AddPass(new ResolveIncompleteDeclsPass());
- TranslationUnitPasses.AddPass(new IgnoreSystemDeclarationsPass());
- TranslationUnitPasses.AddPass(new MatchParamNamesWithInstantiatedFromPass());
+ passes.AddPass(new ResolveIncompleteDeclsPass());
+ passes.AddPass(new IgnoreSystemDeclarationsPass());
+ passes.AddPass(new MatchParamNamesWithInstantiatedFromPass());
if (Options.IsCSharpGenerator)
- TranslationUnitPasses.AddPass(new EqualiseAccessOfOverrideAndBasePass());
+ passes.AddPass(new EqualiseAccessOfOverrideAndBasePass());
- TranslationUnitPasses.AddPass(new FlattenAnonymousTypesToFields());
- TranslationUnitPasses.AddPass(new CheckIgnoredDeclsPass());
- TranslationUnitPasses.AddPass(new MarkUsedClassInternalsPass());
+ passes.AddPass(new FlattenAnonymousTypesToFields());
+ passes.AddPass(new CheckIgnoredDeclsPass());
+ passes.AddPass(new MarkUsedClassInternalsPass());
if (Options.IsCSharpGenerator)
{
- TranslationUnitPasses.AddPass(new TrimSpecializationsPass());
- TranslationUnitPasses.AddPass(new CheckAmbiguousFunctions());
- TranslationUnitPasses.AddPass(new GenerateSymbolsPass());
- TranslationUnitPasses.AddPass(new CheckIgnoredDeclsPass());
+ passes.AddPass(new TrimSpecializationsPass());
+ passes.AddPass(new CheckAmbiguousFunctions());
+ passes.AddPass(new GenerateSymbolsPass());
+ passes.AddPass(new CheckIgnoredDeclsPass());
}
if (Options.IsCLIGenerator || Options.IsCSharpGenerator)
{
- TranslationUnitPasses.AddPass(new MoveFunctionToClassPass());
- TranslationUnitPasses.AddPass(new ValidateOperatorsPass());
+ passes.AddPass(new MoveFunctionToClassPass());
+ passes.AddPass(new ValidateOperatorsPass());
}
library.SetupPasses(this);
- TranslationUnitPasses.AddPass(new FindSymbolsPass());
- TranslationUnitPasses.AddPass(new CheckMacroPass());
- TranslationUnitPasses.AddPass(new CheckStaticClass());
+ passes.AddPass(new FindSymbolsPass());
+ passes.AddPass(new CheckMacroPass());
+ passes.AddPass(new CheckStaticClass());
if (Options.IsCLIGenerator || Options.IsCSharpGenerator || Options.IsCppGenerator)
{
- TranslationUnitPasses.AddPass(new CheckAmbiguousFunctions());
+ passes.AddPass(new CheckAmbiguousFunctions());
}
- TranslationUnitPasses.AddPass(new ConstructorToConversionOperatorPass());
- TranslationUnitPasses.AddPass(new MarshalPrimitivePointersAsRefTypePass());
+ passes.AddPass(new ConstructorToConversionOperatorPass());
+ passes.AddPass(new MarshalPrimitivePointersAsRefTypePass());
if (Options.IsCLIGenerator || Options.IsCSharpGenerator)
{
- TranslationUnitPasses.AddPass(new CheckOperatorsOverloadsPass());
+ passes.AddPass(new CheckOperatorsOverloadsPass());
}
- TranslationUnitPasses.AddPass(new CheckVirtualOverrideReturnCovariance());
- TranslationUnitPasses.AddPass(new CleanCommentsPass());
+ passes.AddPass(new CheckVirtualOverrideReturnCovariance());
+ passes.AddPass(new CleanCommentsPass());
Generator.SetupPasses();
- TranslationUnitPasses.AddPass(new CleanInvalidDeclNamesPass());
- TranslationUnitPasses.AddPass(new FastDelegateToDelegatesPass());
- TranslationUnitPasses.AddPass(new FieldToPropertyPass());
- TranslationUnitPasses.AddPass(new CheckIgnoredDeclsPass());
- TranslationUnitPasses.AddPass(new CheckFlagEnumsPass());
- TranslationUnitPasses.AddPass(new MakeProtectedNestedTypesPublicPass());
+ passes.AddPass(new CleanInvalidDeclNamesPass());
+ passes.AddPass(new FastDelegateToDelegatesPass());
+ passes.AddPass(new FieldToPropertyPass());
+ passes.AddPass(new CheckIgnoredDeclsPass());
+ passes.AddPass(new CheckFlagEnumsPass());
+ passes.AddPass(new MakeProtectedNestedTypesPublicPass());
if (Options.IsCSharpGenerator)
{
- TranslationUnitPasses.AddPass(new GenerateAbstractImplementationsPass());
- TranslationUnitPasses.AddPass(new MultipleInheritancePass());
+ passes.AddPass(new GenerateAbstractImplementationsPass());
+ passes.AddPass(new MultipleInheritancePass());
}
if (Options.IsCLIGenerator || Options.IsCSharpGenerator)
{
- TranslationUnitPasses.AddPass(new DelegatesPass());
- TranslationUnitPasses.AddPass(new GetterSetterToPropertyPass());
+ passes.AddPass(new DelegatesPass());
}
- TranslationUnitPasses.AddPass(new StripUnusedSystemTypesPass());
+ if (Options.GeneratorKind != GeneratorKind.C)
+ {
+ passes.AddPass(new GetterSetterToPropertyPass());
+ }
+
+ passes.AddPass(new StripUnusedSystemTypesPass());
if (Options.IsCSharpGenerator)
{
- TranslationUnitPasses.AddPass(new SpecializationMethodsWithDependentPointersPass());
- TranslationUnitPasses.AddPass(new ParamTypeToInterfacePass());
+ passes.AddPass(new SpecializationMethodsWithDependentPointersPass());
+ passes.AddPass(new ParamTypeToInterfacePass());
}
- TranslationUnitPasses.AddPass(new CheckDuplicatedNamesPass());
+ passes.AddPass(new CheckDuplicatedNamesPass());
if (Options.IsCLIGenerator || Options.IsCSharpGenerator)
{
- TranslationUnitPasses.RenameDeclsUpperCase(RenameTargets.Any & ~RenameTargets.Parameter);
- TranslationUnitPasses.AddPass(new CheckKeywordNamesPass());
+ passes.RenameDeclsUpperCase(RenameTargets.Any & ~RenameTargets.Parameter);
+ passes.AddPass(new CheckKeywordNamesPass());
}
- Context.TranslationUnitPasses.AddPass(new HandleVariableInitializerPass());
+ passes.AddPass(new HandleVariableInitializerPass());
- TranslationUnitPasses.AddPass(new MarkEventsWithUniqueIdPass());
+ passes.AddPass(new MarkEventsWithUniqueIdPass());
}
public void ProcessCode()
@@ -342,10 +345,10 @@ public void SaveCode(IEnumerable outputs)
var file = Path.Combine(outputPath, fileRelativePath);
WriteGeneratedCodeToFile(file, template.Generate());
- if (output.TranslationUnit.Module != null)
- output.TranslationUnit.Module.CodeFiles.Add(file);
+ output.TranslationUnit.Module?.CodeFiles.Add(file);
- Diagnostics.Message("Generated '{0}'", fileRelativePath);
+ if (!Options.Quiet)
+ Diagnostics.Message("Generated '{0}'", fileRelativePath);
}
}
}
@@ -364,7 +367,7 @@ private void WriteGeneratedCodeToFile(string file, string generatedCode)
public bool CompileCode(Module module)
{
- var msBuildGenerator = new MSBuildGenerator(Context, module, libraryMappings);
+ var msBuildGenerator = new MSBuildGenerator(Context, module, LibraryMappings);
msBuildGenerator.Process();
string csproj = Path.Combine(Options.OutputDir,
$"{module.LibraryName}.{msBuildGenerator.FileExtension}");
@@ -375,7 +378,7 @@ public bool CompileCode(Module module)
if (error == 0)
{
Diagnostics.Message($@"Compilation succeeded: {
- libraryMappings[module] = Path.Combine(
+ LibraryMappings[module] = Path.Combine(
Options.OutputDir, $"{module.LibraryName}.dll")}.");
return true;
}
@@ -404,7 +407,7 @@ public void Dispose()
}
private bool hasParsingErrors;
- private static readonly Dictionary libraryMappings = new Dictionary();
+ private static readonly Dictionary LibraryMappings = new();
}
public static class ConsoleDriver
@@ -412,67 +415,68 @@ public static class ConsoleDriver
public static void Run(ILibrary library)
{
var options = new DriverOptions();
- using (var driver = new Driver(options))
- {
- library.Setup(driver);
+ using var driver = new Driver(options);
+ library.Setup(driver);
- driver.Setup();
+ driver.Setup();
- if (driver.Options.Verbose)
- Diagnostics.Level = DiagnosticKind.Debug;
+ if (driver.Options.Verbose)
+ Diagnostics.Level = DiagnosticKind.Debug;
- if (!options.Quiet)
- Diagnostics.Message("Parsing libraries...");
+ if (!options.Quiet)
+ Diagnostics.Message("Parsing libraries...");
- if (!driver.ParseLibraries())
- return;
+ if (!driver.ParseLibraries())
+ return;
- if (!options.Quiet)
- Diagnostics.Message("Parsing code...");
+ if (!options.Quiet)
+ Diagnostics.Message("Parsing code...");
- if (!driver.ParseCode())
- {
- Diagnostics.Error("CppSharp has encountered an error while parsing code.");
- return;
- }
+ if (!driver.ParseCode())
+ {
+ Diagnostics.Error("CppSharp has encountered an error while parsing code.");
+ return;
+ }
- new CleanUnitPass { Context = driver.Context }.VisitASTContext(driver.Context.ASTContext);
- options.Modules.RemoveAll(m => m != options.SystemModule && !m.Units.GetGenerated().Any());
+ new CleanUnitPass { Context = driver.Context }.VisitASTContext(driver.Context.ASTContext);
+ foreach (var module in options.Modules.Where(
+ m => m != options.SystemModule && !m.Units.GetGenerated().Any()))
+ {
+ Diagnostics.Message($"Removing module {module} because no translation units are generated...");
+ options.Modules.Remove(module);
+ }
- if (!options.Quiet)
- Diagnostics.Message("Processing code...");
+ if (!options.Quiet)
+ Diagnostics.Message("Processing code...");
- driver.SetupPasses(library);
- driver.SetupTypeMaps();
- driver.SetupDeclMaps();
+ driver.SetupPasses(library);
+ driver.SetupTypeMaps();
+ driver.SetupDeclMaps();
- library.Preprocess(driver, driver.Context.ASTContext);
+ library.Preprocess(driver, driver.Context.ASTContext);
- driver.ProcessCode();
- library.Postprocess(driver, driver.Context.ASTContext);
+ driver.ProcessCode();
+ library.Postprocess(driver, driver.Context.ASTContext);
- if (!options.Quiet)
- Diagnostics.Message("Generating code...");
+ if (!options.Quiet)
+ Diagnostics.Message("Generating code...");
- if (!options.DryRun)
- {
- var outputs = driver.GenerateCode();
+ if (options.DryRun)
+ return;
- library.GenerateCode(driver, outputs);
+ var outputs = driver.GenerateCode();
- foreach (var output in outputs)
- {
- foreach (var pass in driver.Context.GeneratorOutputPasses.Passes)
- {
- pass.VisitGeneratorOutput(output);
- }
- }
+ library.GenerateCode(driver, outputs);
- driver.SaveCode(outputs);
- if (driver.Options.IsCSharpGenerator && driver.Options.CompileCode)
- driver.Options.Modules.Any(m => !driver.CompileCode(m));
- }
+ foreach (var output in outputs)
+ {
+ foreach (var pass in driver.Context.GeneratorOutputPasses.Passes)
+ pass.VisitGeneratorOutput(output);
}
+
+ driver.SaveCode(outputs);
+ if (driver.Options.IsCSharpGenerator && driver.Options.CompileCode)
+ driver.Options.Modules.Any(m => !driver.CompileCode(m));
}
}
}
diff --git a/src/Generator/Generator.cs b/src/Generator/Generator.cs
index e9bcc3e818..cf414b4823 100644
--- a/src/Generator/Generator.cs
+++ b/src/Generator/Generator.cs
@@ -14,6 +14,7 @@ public enum GeneratorKind
CSharp = 2,
C,
CPlusPlus,
+ Emscripten,
ObjectiveC,
Java,
Swift,
diff --git a/src/Generator/Generators/C/CppTypePrinter.cs b/src/Generator/Generators/C/CppTypePrinter.cs
index 8acd62c7cf..f289705f76 100644
--- a/src/Generator/Generators/C/CppTypePrinter.cs
+++ b/src/Generator/Generators/C/CppTypePrinter.cs
@@ -584,7 +584,8 @@ public override TypePrinterResult VisitClassTemplateSpecializationDecl(
args.Add(arg.Type.Visit(this));
break;
case TemplateArgument.ArgumentKind.Declaration:
- args.Add(arg.Declaration.Visit(this));
+ if (arg.Declaration != null)
+ args.Add(arg.Declaration.Visit(this));
break;
case TemplateArgument.ArgumentKind.Integral:
ClassTemplate template = specialization.TemplatedDecl;
@@ -596,6 +597,7 @@ public override TypePrinterResult VisitClassTemplateSpecializationDecl(
{
args.Add(arg.Integral.ToString(CultureInfo.InvariantCulture));
}
+
break;
}
}
@@ -634,7 +636,7 @@ public override TypePrinterResult VisitFunctionDecl(Function function)
CppSharp.AST.Type desugared = function.FunctionType.Type.Desugar();
if (!desugared.IsPointerTo(out functionType))
functionType = (FunctionType)desugared;
- string exceptionType = Print(functionType.ExceptionSpecType);
+ string exceptionType = functionType != null ? Print(functionType.ExceptionSpecType) : "";
var @return = function.OriginalReturnType.Visit(this);
@return.Name = @class + name;
diff --git a/src/Generator/Generators/CLI/CLIMarshal.cs b/src/Generator/Generators/CLI/CLIMarshal.cs
index 1376592c92..c641651754 100644
--- a/src/Generator/Generators/CLI/CLIMarshal.cs
+++ b/src/Generator/Generators/CLI/CLIMarshal.cs
@@ -61,7 +61,8 @@ public override bool VisitArrayType(ArrayType array, TypeQualifiers quals)
break;
case ArrayType.ArraySize.Incomplete:
// const char* and const char[] are the same so we can use a string
- if (array.Type.Desugar().IsPrimitiveType(PrimitiveType.Char) &&
+ if (Context.Context.Options.MarshalConstCharArrayAsString &&
+ array.Type.Desugar().IsPrimitiveType(PrimitiveType.Char) &&
array.QualifiedType.Qualifiers.IsConst)
{
var pointer = new PointerType { QualifiedPointee = array.QualifiedType };
diff --git a/src/Generator/Generators/CLI/CLITypePrinter.cs b/src/Generator/Generators/CLI/CLITypePrinter.cs
index 50ff8d46d4..69077affe2 100644
--- a/src/Generator/Generators/CLI/CLITypePrinter.cs
+++ b/src/Generator/Generators/CLI/CLITypePrinter.cs
@@ -35,7 +35,8 @@ public override TypePrinterResult VisitArrayType(ArrayType array,
TypeQualifiers quals)
{
// const char* and const char[] are the same so we can use a string
- if (array.SizeType == ArrayType.ArraySize.Incomplete &&
+ if (Context.Options.MarshalConstCharArrayAsString &&
+ array.SizeType == ArrayType.ArraySize.Incomplete &&
array.Type.Desugar().IsPrimitiveType(PrimitiveType.Char) &&
array.QualifiedType.Qualifiers.IsConst)
return VisitCILType(new CILType(typeof(string)), quals);
diff --git a/src/Generator/Generators/CSharp/CSharpExpressionPrinter.cs b/src/Generator/Generators/CSharp/CSharpExpressionPrinter.cs
index c4c2f1d5d7..3884d1694c 100644
--- a/src/Generator/Generators/CSharp/CSharpExpressionPrinter.cs
+++ b/src/Generator/Generators/CSharp/CSharpExpressionPrinter.cs
@@ -27,11 +27,11 @@ public string VisitParameter(Parameter parameter)
if (desugared.IsPrimitiveType() &&
(parameter.DefaultArgument.Declaration != null ||
parameter.DefaultArgument.Class == StatementClass.BinaryOperator))
- return $"({desugared.Visit(typePrinter)}) {expression}";
+ return $"({desugared.Visit(typePrinter)}) ({expression})";
var finalType = (desugared.GetFinalPointee() ?? desugared).Desugar();
if (finalType.TryGetClass(out var @class) && @class.IsInterface)
return $@"({@class.Visit(typePrinter)}) ({
- @class.OriginalClass.Visit(typePrinter)}) {expression}";
+ @class.OriginalClass.Visit(typePrinter)}) ({expression})";
return expression;
}
@@ -61,20 +61,15 @@ public string VisitExpression(ExpressionObsolete expr)
case StatementClass.BinaryOperator:
var binaryOperator = (BinaryOperatorObsolete)expr;
- var lhsResult = binaryOperator.LHS.String;
- if (binaryOperator.LHS.Declaration is Enumeration.Item)
- lhsResult = binaryOperator.LHS.Declaration.Visit(typePrinter).Type;
-
- var rhsResult = binaryOperator.RHS.String;
- if (binaryOperator.RHS.Declaration is Enumeration.Item)
- rhsResult = binaryOperator.RHS.Declaration.Visit(typePrinter).Type;
+ var lhsResult = VisitExpression(binaryOperator.LHS);
+ var rhsResult = VisitExpression(binaryOperator.RHS);
return $"{lhsResult} {binaryOperator.OpcodeStr} {rhsResult}";
case StatementClass.ConstructorReference:
var constructorExpr = (CXXConstructExprObsolete)expr;
if (constructorExpr.Arguments.Count == 1 &&
- constructorExpr.Arguments[0].Declaration is Enumeration.Item)
- return constructorExpr.Arguments[0].Declaration.Visit(typePrinter).Type;
+ constructorExpr.Arguments[0].Class != StatementClass.Any)
+ return VisitExpression(constructorExpr.Arguments[0]);
goto default;
default:
return expr.String;
@@ -88,4 +83,4 @@ public string ToString(Type type)
private readonly TypePrinter typePrinter;
}
-}
\ No newline at end of file
+}
diff --git a/src/Generator/Generators/CSharp/CSharpMarshal.cs b/src/Generator/Generators/CSharp/CSharpMarshal.cs
index 8f64f72b27..21d7279ca7 100644
--- a/src/Generator/Generators/CSharp/CSharpMarshal.cs
+++ b/src/Generator/Generators/CSharp/CSharpMarshal.cs
@@ -116,7 +116,8 @@ public override bool VisitArrayType(ArrayType array, TypeQualifiers quals)
break;
case ArrayType.ArraySize.Incomplete:
// const char* and const char[] are the same so we can use a string
- if (array.Type.Desugar().IsPrimitiveType(PrimitiveType.Char) &&
+ if (Context.Context.Options.MarshalConstCharArrayAsString &&
+ array.Type.Desugar().IsPrimitiveType(PrimitiveType.Char) &&
array.QualifiedType.Qualifiers.IsConst)
{
var pointer = new PointerType { QualifiedPointee = array.QualifiedType };
@@ -906,7 +907,8 @@ private void MarshalArray(ArrayType arrayType)
var elementType = arrayType.Type.Desugar();
- if (elementType.IsPrimitiveType() ||
+ if ((elementType.IsPrimitiveType() &&
+ !(elementType.IsPrimitiveType(PrimitiveType.Char) && Context.Context.Options.MarshalCharAsManagedChar)) ||
elementType.IsPointerToPrimitiveType())
{
if (Context.Context.Options.UseSpan && !elementType.IsConstCharString())
@@ -948,6 +950,10 @@ private void MarshalArray(ArrayType arrayType)
Context.Before.WriteLine($@"{intermediateArray}[i] = {
element} is null ? {intPtrZero} : {element}.{Helpers.InstanceIdentifier};");
}
+ else if (elementType.IsPrimitiveType(PrimitiveType.Char) &&
+ Context.Context.Options.MarshalCharAsManagedChar)
+ Context.Before.WriteLine($@"{intermediateArray}[i] = global::System.Convert.ToSByte({
+ element});");
else
Context.Before.WriteLine($@"{intermediateArray}[i] = {
element} is null ? new {intermediateArrayType}() : *({
diff --git a/src/Generator/Generators/CSharp/CSharpSources.cs b/src/Generator/Generators/CSharp/CSharpSources.cs
index d9da8b46c6..3ee9104b1a 100644
--- a/src/Generator/Generators/CSharp/CSharpSources.cs
+++ b/src/Generator/Generators/CSharp/CSharpSources.cs
@@ -256,9 +256,9 @@ public virtual void GenerateNamespaceFunctionsAndVariables(DeclarationContext co
.Any();
using (PushWriteBlock(BlockKind.Functions, $"public unsafe partial {(isStruct ? "struct" : "class")} {parentName}", NewLineKind.BeforeNextBlock))
- {
+ {
using (PushWriteBlock(BlockKind.InternalsClass, GetClassInternalHead(new Class { Name = parentName }), NewLineKind.BeforeNextBlock))
- {
+ {
// Generate all the internal function declarations.
foreach (var function in context.Functions)
{
@@ -301,7 +301,7 @@ template.OriginalNamespace is Class &&
template.Name);
using (PushWriteBlock(BlockKind.Namespace, namespaceName, NewLineKind.BeforeNextBlock))
- {
+ {
var generated = GetGeneratedClasses(template, specializations);
foreach (var nestedTemplate in template.Classes.Where(
@@ -972,7 +972,7 @@ private string GeneratePointerTo(Variable var)
string ptr = Generator.GeneratedIdentifier("ptr");
if (arrayType != null)
{
- if (arrayType.Type.IsPrimitiveType(PrimitiveType.Char) && arrayType.SizeType != ArrayType.ArraySize.Constant)
+ if (Context.Options.MarshalConstCharArrayAsString && arrayType.Type.IsPrimitiveType(PrimitiveType.Char) && arrayType.SizeType != ArrayType.ArraySize.Constant)
WriteLine($"var {ptr} = {location};");
else
WriteLine($"var {ptr} = ({arrayType.Type.Visit(TypePrinter)}*){location};");
@@ -1310,6 +1310,17 @@ private bool GenerateVariableGetter(Variable var)
};
ctx.PushMarshalKind(MarshalKind.ReturnVariableArray);
+ if (var.Type.Desugar().IsPointer())
+ {
+ var pointerType = var.Type.Desugar() as PointerType;
+ while (pointerType != null && !pointerType.Pointee.Desugar().IsPrimitiveType(PrimitiveType.Char))
+ {
+ ptr = $"*{ptr}";
+ pointerType = pointerType.Pointee.Desugar() as PointerType;
+ }
+ ptr = $"({TypePrinter.IntPtrType}*)({ptr})";
+ }
+
var arrayType = var.Type.Desugar() as ArrayType;
var isRefTypeArray = arrayType != null && var.Namespace is Class context && context.IsRefType;
var elementType = arrayType?.Type.Desugar();
@@ -1645,19 +1656,27 @@ private void GenerateVariable(Class @class, Variable variable)
var variableType = variable.Type.Visit(TypePrinter);
TypePrinter.PopMarshalKind();
- var signature = $"public static {variableType} {variable.Name}";
+ bool hasInitializer = variable.Initializer != null && !string.IsNullOrWhiteSpace(variable.Initializer.String);
- if (variable.Initializer != null && !string.IsNullOrWhiteSpace(variable.Initializer.String))
- GeneratePropertyGetterForVariableWithInitializer(variable, signature);
+ if (hasInitializer && variable.QualifiedType.Qualifiers.IsConst &&
+ (variable.Type.Desugar() is BuiltinType || variableType.ToString() == "string"))
+ Write($"public const {variableType} {variable.Name} = {variable.Initializer.String};");
else
{
- using (WriteBlock(signature))
+ var signature = $"public static {variableType} {variable.Name}";
+
+ if (hasInitializer)
+ GeneratePropertyGetterForVariableWithInitializer(variable, signature);
+ else
{
- GeneratePropertyGetter(variable, @class);
+ using (WriteBlock(signature))
+ {
+ GeneratePropertyGetter(variable, @class);
- if (!variable.QualifiedType.Qualifiers.IsConst &&
- !(variable.Type.Desugar() is ArrayType))
- GeneratePropertySetter(variable, @class);
+ if (!variable.QualifiedType.Qualifiers.IsConst &&
+ !(variable.Type.Desugar() is ArrayType))
+ GeneratePropertySetter(variable, @class);
+ }
}
}
@@ -1810,7 +1829,7 @@ public void GenerateVTable(Class @class)
return __vtables;
}}
- set {{
+ set {{
__vtables = value;
}}", trimIndentation: true);
}
@@ -2326,13 +2345,13 @@ private void GenerateDisposeMethods(Class @class)
// Normally, calling the native dtor should be controlled by whether or not we
// we own the underlying instance. (i.e. Helpers.OwnsNativeInstanceIdentifier).
// However, there are 2 situations when the caller needs to have direct control
- //
+ //
// 1. When we have a virtual dtor on the native side we detour the vtable entry
// even when we don't own the underlying native instance. I think we do this
// so that the managed side can null out the __Instance pointer and remove the
// instance from the NativeToManagedMap. Of course, this is somewhat half-hearted
// since we can't/don't do this when there's no virtual dtor available to detour.
- // Anyway, we must be able to call the native dtor in this case even if we don't
+ // Anyway, we must be able to call the native dtor in this case even if we don't
/// own the underlying native instance.
//
// 2. When we we pass a disposable object to a function "by value" then the callee
@@ -2343,7 +2362,7 @@ private void GenerateDisposeMethods(Class @class)
// ....
// compiler generates call to f.dtor() at the end of function
// }
- //
+ //
// IDisposable.Dispose() and Object.Finalize() set callNativeDtor = Helpers.OwnsNativeInstanceIdentifier
WriteLine("if (callNativeDtor)");
if (@class.IsDependent || dtor.IsVirtual)
@@ -2364,7 +2383,7 @@ c is ClassTemplateSpecialization ?
}
// If we have any fields holding references to unmanaged memory allocated here, free the
- // referenced memory. Don't rely on testing if the field's IntPtr is IntPtr.Zero since
+ // referenced memory. Don't rely on testing if the field's IntPtr is IntPtr.Zero since
// unmanaged memory isn't always initialized and/or a reference may be owned by the
// native side.
//
@@ -2616,7 +2635,7 @@ private void Generate__CopyValue(Class @class, string @internal)
using (WriteBlock($"private static void* __CopyValue({@internal} native)"))
{
var copyCtorMethod = @class.Methods.FirstOrDefault(method => method.IsCopyConstructor);
-
+
if (@class.HasNonTrivialCopyConstructor && copyCtorMethod != null && copyCtorMethod.IsGenerated)
{
// Allocate memory for a new native object and call the ctor.
@@ -2851,7 +2870,7 @@ private bool GenerateMethodBody(Class @class, Method method,
private string OverloadParamNameWithDefValue(Parameter p, ref int index)
{
- return p.Type.IsPointerToPrimitiveType() && p.Usage == ParameterUsage.InOut && p.HasDefaultValue
+ return (p.Type.IsPointerToPrimitiveType() || p.Type.IsPointerToEnum()) && p.Usage == ParameterUsage.InOut && p.HasDefaultValue
? "ref param" + index++
: ExpressionPrinter.VisitParameter(p);
}
@@ -2870,13 +2889,15 @@ private void GenerateOverloadCall(Function function)
for (int i = 0, j = 0; i < function.Parameters.Count; i++)
{
var parameter = function.Parameters[i];
- PrimitiveType primitiveType;
+ PrimitiveType primitiveType = PrimitiveType.Null;
+ Enumeration enumeration = null;
if (parameter.Kind == ParameterKind.Regular && parameter.Ignore &&
- parameter.Type.IsPointerToPrimitiveType(out primitiveType) &&
+ (parameter.Type.IsPointerToPrimitiveType(out primitiveType) ||
+ parameter.Type.IsPointerToEnum(out enumeration)) &&
parameter.Usage == ParameterUsage.InOut && parameter.HasDefaultValue)
{
var pointeeType = ((PointerType)parameter.Type).Pointee.ToString();
- WriteLine($@"{pointeeType} param{j++} = {(primitiveType == PrimitiveType.Bool ? "false" : "0")};");
+ WriteLine($@"{pointeeType} param{j++} = {(primitiveType == PrimitiveType.Bool ? "false" : $"({pointeeType})0")};");
}
}
@@ -2924,7 +2945,7 @@ private void GenerateEquals(Class @class)
private void GenerateGetHashCode(Class @class)
{
using (WriteBlock("public override int GetHashCode()"))
- {
+ {
if (!@class.IsRefType)
WriteLine($"return {Helpers.InstanceIdentifier}.GetHashCode();");
else
@@ -3075,7 +3096,7 @@ private void GenerateClassConstructor(Method method, Class @class)
// Copy any string references owned by the source to the new instance so we
// don't have to ref count them.
// If there is no property or no setter then this instance can never own the native
- // memory. Worry about the case where there's only a setter (write-only) when we
+ // memory. Worry about the case where there's only a setter (write-only) when we
// understand the use case and how it can occur.
foreach (var prop in @class.GetConstCharFieldProperties())
{
diff --git a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs
index c31a0df833..7271179569 100644
--- a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs
+++ b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs
@@ -111,7 +111,8 @@ public override TypePrinterResult VisitArrayType(ArrayType array,
}
// const char* and const char[] are the same so we can use a string
- if (array.SizeType == ArrayType.ArraySize.Incomplete &&
+ if (Context.Options.MarshalConstCharArrayAsString &&
+ array.SizeType == ArrayType.ArraySize.Incomplete &&
arrayType.IsPrimitiveType(PrimitiveType.Char) &&
array.QualifiedType.Qualifiers.IsConst)
return "string";
@@ -123,6 +124,13 @@ public override TypePrinterResult VisitArrayType(ArrayType array,
return $"{prefix}string[]";
}
+ if (arrayType.IsPrimitiveType(PrimitiveType.Bool))
+ {
+ var prefix = ContextKind == TypePrinterContextKind.Managed ? string.Empty :
+ "[MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.I1)] ";
+ return $"{prefix}bool[]";
+ }
+
if (Context.Options.UseSpan && !(array.SizeType != ArrayType.ArraySize.Constant &&
MarshalKind == MarshalKind.ReturnVariableArray))
{
diff --git a/src/Generator/Generators/CodeGenerator.cs b/src/Generator/Generators/CodeGenerator.cs
index 39eb7e4984..e0057a13d1 100644
--- a/src/Generator/Generators/CodeGenerator.cs
+++ b/src/Generator/Generators/CodeGenerator.cs
@@ -316,7 +316,7 @@ public virtual bool VisitClassDeclContext(Class @class)
property.Visit(this);
}
- VisitClassConstructors(@class);
+ VisitClassConstructors(@class.Constructors.Where(c => !ASTUtils.CheckIgnoreMethod(c)));
VisitClassMethods(@class);
return true;
@@ -333,9 +333,9 @@ public virtual void VisitClassMethods(Class @class)
}
}
- public virtual void VisitClassConstructors(Class @class)
+ public virtual void VisitClassConstructors(IEnumerable constructors)
{
- foreach (var ctor in @class.Constructors.Where(c => !ASTUtils.CheckIgnoreMethod(c)))
+ foreach (var ctor in constructors)
{
ctor.Visit(this);
}
diff --git a/src/Generator/Generators/Emscripten/EmscriptenGenerator.cs b/src/Generator/Generators/Emscripten/EmscriptenGenerator.cs
new file mode 100644
index 0000000000..f2f7e71a14
--- /dev/null
+++ b/src/Generator/Generators/Emscripten/EmscriptenGenerator.cs
@@ -0,0 +1,73 @@
+using System.Collections.Generic;
+using System.Linq;
+using CppSharp.AST;
+using CppSharp.Generators.Cpp;
+
+namespace CppSharp.Generators.Emscripten
+{
+ ///
+ /// Emscripten generator responsible for driving the generation of binding files.
+ /// Embind documentation: https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html
+ ///
+ public class EmscriptenGenerator : CppGenerator
+ {
+ public EmscriptenGenerator(BindingContext context) : base(context)
+ {
+ }
+
+ public override List Generate()
+ {
+ var outputs = base.Generate();
+
+ foreach (var module in Context.Options.Modules)
+ {
+ if (module == Context.Options.SystemModule)
+ continue;
+
+ var output = GenerateModule(module);
+ if (output != null)
+ {
+ OnUnitGenerated(output);
+ outputs.Add(output);
+ }
+ }
+
+ return outputs;
+ }
+
+ public override List Generate(IEnumerable units)
+ {
+ var outputs = new List();
+
+ var header = new EmscriptenHeaders(Context, units);
+ outputs.Add(header);
+
+ var source = new EmscriptenSources(Context, units);
+ outputs.Add(source);
+
+ return outputs;
+ }
+
+ public override GeneratorOutput GenerateModule(Module module)
+ {
+ if (module == Context.Options.SystemModule)
+ return null;
+
+ var moduleGen = new EmscriptenModule(Context, module);
+
+ var output = new GeneratorOutput
+ {
+ TranslationUnit = new TranslationUnit
+ {
+ FilePath = $"{module.LibraryName}_embind_module.cpp",
+ Module = module
+ },
+ Outputs = new List { moduleGen }
+ };
+
+ output.Outputs[0].Process();
+
+ return output;
+ }
+ }
+}
diff --git a/src/Generator/Generators/Emscripten/EmscriptenHeaders.cs b/src/Generator/Generators/Emscripten/EmscriptenHeaders.cs
new file mode 100644
index 0000000000..2cd8a3e400
--- /dev/null
+++ b/src/Generator/Generators/Emscripten/EmscriptenHeaders.cs
@@ -0,0 +1,48 @@
+using System.Collections.Generic;
+using CppSharp.AST;
+
+namespace CppSharp.Generators.Emscripten
+{
+ ///
+ /// Generates Emscripten Embind C/C++ header files.
+ /// Embind documentation: https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html
+ ///
+ public sealed class EmscriptenHeaders : EmscriptenCodeGenerator
+ {
+ public EmscriptenHeaders(BindingContext context, IEnumerable units)
+ : base(context, units)
+ {
+ CTypePrinter.PushContext(TypePrinterContextKind.Managed);
+ }
+
+ //public override bool ShouldGenerateNamespaces => false;
+
+ public override void Process()
+ {
+ GenerateFilePreamble(CommentKind.BCPL);
+
+ PushBlock(BlockKind.Includes);
+ WriteLine("#pragma once");
+ NewLine();
+ PopBlock();
+
+ var name = GetTranslationUnitName(TranslationUnit);
+ WriteLine($"extern \"C\" void embind_init_{name}();");
+ }
+
+ public override bool VisitClassDecl(Class @class)
+ {
+ return true;
+ }
+
+ public override bool VisitEvent(Event @event)
+ {
+ return true;
+ }
+
+ public override bool VisitFieldDecl(Field field)
+ {
+ return true;
+ }
+ }
+}
diff --git a/src/Generator/Generators/Emscripten/EmscriptenMarshal.cs b/src/Generator/Generators/Emscripten/EmscriptenMarshal.cs
new file mode 100644
index 0000000000..0e05a74042
--- /dev/null
+++ b/src/Generator/Generators/Emscripten/EmscriptenMarshal.cs
@@ -0,0 +1,21 @@
+using CppSharp.Generators.C;
+
+namespace CppSharp.Generators.Emscripten
+{
+ public class EmscriptenMarshalNativeToManagedPrinter : MarshalPrinter
+ {
+ public EmscriptenMarshalNativeToManagedPrinter(MarshalContext marshalContext)
+ : base(marshalContext)
+ {
+ }
+ }
+
+ public class EmscriptenMarshalManagedToNativePrinter : MarshalPrinter
+ {
+ public EmscriptenMarshalManagedToNativePrinter(MarshalContext ctx)
+ : base(ctx)
+ {
+ Context.MarshalToNative = this;
+ }
+ }
+}
diff --git a/src/Generator/Generators/Emscripten/EmscriptenModule.cs b/src/Generator/Generators/Emscripten/EmscriptenModule.cs
new file mode 100644
index 0000000000..e92c4bcf7c
--- /dev/null
+++ b/src/Generator/Generators/Emscripten/EmscriptenModule.cs
@@ -0,0 +1,89 @@
+using System.IO;
+using System.Linq;
+using CppSharp.AST;
+using CppSharp.Generators.C;
+
+namespace CppSharp.Generators.Emscripten
+{
+ ///
+ /// Generates Emscripten module init files.
+ /// Embind documentation: https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html
+ ///
+ public class EmscriptenModule : EmscriptenCodeGenerator
+ {
+ private readonly Module module;
+
+ public EmscriptenModule(BindingContext context, Module module)
+ : base(context, module.Units.GetGenerated())
+ {
+ this.module = module;
+ }
+
+ public override string FileExtension { get; } = "cpp";
+
+ public override void Process()
+ {
+ GenerateFilePreamble(CommentKind.BCPL);
+ NewLine();
+
+ PushBlock(BlockKind.Includes);
+ {
+ WriteInclude(new CInclude()
+ {
+ File = "emscripten/bind.h",
+ Kind = CInclude.IncludeKind.Angled
+ });
+
+ foreach (var unit in TranslationUnits)
+ WriteInclude(GetIncludeFileName(Context, unit), CInclude.IncludeKind.Quoted);
+ }
+ PopBlock(NewLineKind.Always);
+
+ WriteLine("extern \"C\" {");
+ NewLine();
+
+ PushBlock(BlockKind.ForwardReferences);
+ {
+ foreach (var unit in TranslationUnits.Where(unit => unit.IsGenerated))
+ {
+ var name = GetTranslationUnitName(unit);
+ WriteLine($"void embind_init_{name}();");
+ }
+ }
+ PopBlock(NewLineKind.Always);
+
+ var moduleName = module.LibraryName;
+ WriteLine($"void embind_init_{moduleName}()");
+ WriteOpenBraceAndIndent();
+
+ foreach (var unit in TranslationUnits)
+ {
+ var name = GetTranslationUnitName(unit);
+ WriteLine($"embind_init_{name}();");
+ }
+
+ UnindentAndWriteCloseBrace();
+
+ NewLine();
+ WriteLine("}");
+ NewLine();
+
+ WriteLine($"static struct EmBindInit_{moduleName} : emscripten::internal::InitFunc {{");
+ WriteLineIndent($"EmBindInit_{moduleName}() : InitFunc(embind_init_{moduleName}) {{}}");
+ WriteLine($"}} EmBindInit_{moduleName}_instance;");
+ }
+
+ public static string GetIncludeFileName(BindingContext context, TranslationUnit unit)
+ {
+ // TODO: Replace with GetIncludePath
+ string file;
+ if (context.Options.GenerateName != null)
+ file = context.Options.GenerateName(unit);
+ else
+ file = Path.GetFileNameWithoutExtension(unit.FileName)
+ .Replace('\\', '/');
+
+ return $"{file}.h";
+ }
+ }
+}
diff --git a/src/Generator/Generators/Emscripten/EmscriptenSources.cs b/src/Generator/Generators/Emscripten/EmscriptenSources.cs
new file mode 100644
index 0000000000..4e786b0400
--- /dev/null
+++ b/src/Generator/Generators/Emscripten/EmscriptenSources.cs
@@ -0,0 +1,202 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using CppSharp.AST;
+using CppSharp.AST.Extensions;
+using CppSharp.Generators.C;
+using CppSharp.Generators.Cpp;
+
+namespace CppSharp.Generators.Emscripten
+{
+ public class EmscriptenCodeGenerator : MethodGroupCodeGenerator
+ {
+ protected EmscriptenCodeGenerator(BindingContext context, IEnumerable units)
+ : base(context, units)
+ {
+ }
+
+ public virtual MarshalPrinter GetMarshalManagedToNativePrinter(MarshalContext ctx)
+ {
+ return new EmscriptenMarshalManagedToNativePrinter(ctx);
+ }
+
+ public virtual MarshalPrinter GetMarshalNativeToManagedPrinter(MarshalContext ctx)
+ {
+ return new EmscriptenMarshalNativeToManagedPrinter(ctx);
+ }
+
+ public override bool VisitClassTemplateDecl(ClassTemplate template)
+ {
+ return true;
+ }
+
+ public override bool VisitFunctionTemplateDecl(FunctionTemplate template)
+ {
+ return true;
+ }
+ }
+
+ ///
+ /// Generates Emscripten C/C++ source files.
+ /// Embind documentation: https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html
+ ///
+ public class EmscriptenSources : EmscriptenCodeGenerator
+ {
+ public override string FileExtension => "cpp";
+
+ public EmscriptenSources(BindingContext context, IEnumerable units)
+ : base(context, units)
+ {
+ }
+
+ public override void Process()
+ {
+ GenerateFilePreamble(CommentKind.BCPL);
+
+ PushBlock(BlockKind.Includes);
+ {
+ WriteInclude(new CInclude()
+ {
+ File = "emscripten/bind.h",
+ Kind = CInclude.IncludeKind.Angled
+ });
+
+ foreach (var unit in TranslationUnits)
+ {
+ WriteInclude(unit.IncludePath, CInclude.IncludeKind.Angled);
+ }
+ }
+ PopBlock(NewLineKind.Always);
+
+ var name = GetTranslationUnitName(TranslationUnit);
+ WriteLine($"extern \"C\" void embind_init_{name}()");
+ WriteOpenBraceAndIndent();
+ VisitNamespace(TranslationUnit);
+ UnindentAndWriteCloseBrace();
+ }
+
+ public override bool VisitClassDecl(Class @class)
+ {
+ if (@class.IsIncomplete)
+ return true;
+
+ PushBlock();
+ Write($"emscripten::class_<{@class.QualifiedOriginalName}");
+ if (@class.HasBaseClass)
+ Write($", emscripten::base<{@class.BaseClass.QualifiedOriginalName}>");
+ WriteLine($">(\"{@class.Name}\")");
+
+ VisitClassDeclContext(@class);
+
+ WriteLineIndent(";");
+ PopBlock(NewLineKind.BeforeNextBlock);
+ return true;
+ }
+
+ public override void VisitClassConstructors(IEnumerable ctors)
+ {
+ var overloadCheck = new HashSet();
+ foreach (var ctor in ctors)
+ {
+ if (overloadCheck.Contains(ctor.Parameters.Count))
+ {
+ Console.WriteLine($"Ignoring overloaded ctor: {ctor.QualifiedOriginalName}");
+ continue;
+ }
+
+ var cppTypePrinter = new CppTypePrinter(Context)
+ {
+ PrintFlavorKind = CppTypePrintFlavorKind.Cpp
+ };
+ cppTypePrinter.PushContext(TypePrinterContextKind.Native);
+
+ var parameters = ctor.Parameters.Select(p => p.Type.Visit(cppTypePrinter).Type);
+ WriteLineIndent($".constructor<{string.Join(", ", parameters)}>()");
+
+ overloadCheck.Add(ctor.Parameters.Count);
+ }
+ }
+
+ public override bool VisitMethodDecl(Method method)
+ {
+ Indent();
+ var ret = VisitFunctionDecl(method);
+ Unindent();
+ return ret;
+ }
+
+ public override bool VisitFieldDecl(Field field)
+ {
+ WriteLineIndent($".field(\"{field.Name}\", &{field.Class.QualifiedOriginalName}::{field.OriginalName})");
+ return true;
+ }
+
+ public override void GenerateMethodGroup(List @group)
+ {
+ if (@group.Count > 1)
+ {
+ Console.WriteLine($"Ignoring method group: {@group.First().QualifiedOriginalName}");
+ return;
+ }
+
+ base.GenerateMethodGroup(@group);
+ }
+
+ public override void GenerateFunctionGroup(List @group)
+ {
+ if (@group.Count > 1)
+ {
+ Console.WriteLine($"Ignoring function group: {@group.First().QualifiedOriginalName}");
+ return;
+ }
+
+ base.GenerateFunctionGroup(@group);
+ }
+
+ public override void VisitDeclContextFunctions(DeclarationContext context)
+ {
+ PushBlock();
+ base.VisitDeclContextFunctions(context);
+ PopBlock(NewLineKind.BeforeNextBlock);
+ }
+
+ public override bool VisitFunctionDecl(Function function)
+ {
+ var prefix = function is Method ? ".function" : "emscripten::function";
+ Write($"{prefix}(\"{function.Name}\", &{function.QualifiedOriginalName}");
+
+ var hasPointers = function.ReturnType.Type.IsPointer() ||
+ function.Parameters.Any(p => p.Type.IsPointer());
+ if (hasPointers)
+ Write(", emscripten::allow_raw_pointers()");
+
+ WriteLine(function is not Method ? ");" : $")");
+ return true;
+ }
+
+ public override bool VisitEnumDecl(Enumeration @enum)
+ {
+ if (@enum.IsIncomplete)
+ return false;
+
+ PushBlock();
+
+ WriteLine($"emscripten::enum_<{@enum.Name}>(\"{@enum.QualifiedOriginalName}\")");
+ foreach (var item in @enum.Items)
+ {
+ WriteLineIndent(@enum.IsScoped
+ ? $".value(\"{item.Name}\", {@enum.QualifiedOriginalName}::{item.OriginalName})"
+ : $".value(\"{item.Name}\", {item.QualifiedOriginalName})");
+ }
+ WriteLineIndent(";");
+
+ PopBlock(NewLineKind.BeforeNextBlock);
+ return true;
+ }
+
+ public override bool VisitTypedefDecl(TypedefDecl typedef)
+ {
+ return true;
+ }
+ }
+}
diff --git a/src/Generator/Generators/Emscripten/EmscriptenTypePrinter.cs b/src/Generator/Generators/Emscripten/EmscriptenTypePrinter.cs
new file mode 100644
index 0000000000..b5d5cd8816
--- /dev/null
+++ b/src/Generator/Generators/Emscripten/EmscriptenTypePrinter.cs
@@ -0,0 +1,11 @@
+using CppSharp.Generators.C;
+
+namespace CppSharp.Generators.Emscripten
+{
+ public class EmscriptenTypePrinter : CppTypePrinter
+ {
+ public EmscriptenTypePrinter(BindingContext context) : base(context)
+ {
+ }
+ }
+}
diff --git a/src/Generator/Generators/NAPI/NAPIHelpers.cs b/src/Generator/Generators/NAPI/NAPIHelpers.cs
index a1f4b93971..858c488cea 100644
--- a/src/Generator/Generators/NAPI/NAPIHelpers.cs
+++ b/src/Generator/Generators/NAPI/NAPIHelpers.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
+using System.IO;
using System.Linq;
using CppSharp.AST;
using CppSharp.AST.Extensions;
@@ -9,11 +10,9 @@
namespace CppSharp.Generators.Cpp
{
- public class NAPICodeGenerator : CCodeGenerator
+ public class MethodGroupCodeGenerator : CCodeGenerator
{
- public override string FileExtension => "cpp";
-
- public NAPICodeGenerator(BindingContext context, IEnumerable units)
+ protected MethodGroupCodeGenerator(BindingContext context, IEnumerable units)
: base(context, units)
{
}
@@ -43,9 +42,9 @@ public override bool VisitClassDecl(Class @class)
return VisitClassDeclContext(@class);
}
- public override void VisitClassConstructors(Class @class)
+ public override void VisitClassConstructors(IEnumerable ctors)
{
- var constructors = @class.Constructors.Where(c => c.IsGenerated && !c.IsCopyConstructor)
+ var constructors = ctors.Where(c => c.IsGenerated && !c.IsCopyConstructor)
.ToList();
if (!constructors.Any())
@@ -59,7 +58,7 @@ public static bool ShouldGenerate(Function function)
if (!function.IsGenerated)
return false;
- if (!(function is Method method))
+ if (function is not Method method)
return true;
if (method.IsConstructor || method.IsDestructor)
@@ -88,10 +87,27 @@ public virtual void GenerateMethodGroup(List @group)
foreach (var method in @group)
{
method.Visit(this);
- return;
}
}
+ public static string GetTranslationUnitName(TranslationUnit unit)
+ {
+ var paths = unit.FileRelativePath.Split('/').ToList();
+ paths = paths.Select(p => Path.GetFileNameWithoutExtension(p.ToLowerInvariant())).ToList();
+ var name = string.Join('_', paths);
+ return name;
+ }
+ }
+
+ public class NAPICodeGenerator : MethodGroupCodeGenerator
+ {
+ public override string FileExtension => "cpp";
+
+ public NAPICodeGenerator(BindingContext context, IEnumerable units)
+ : base(context, units)
+ {
+ }
+
public virtual MarshalPrinter GetMarshalManagedToNativePrinter(MarshalContext ctx)
{
return new NAPIMarshalManagedToNativePrinter(ctx);
diff --git a/src/Generator/Generators/NAPI/NAPISources.cs b/src/Generator/Generators/NAPI/NAPISources.cs
index b6676f8b11..a78d2948b4 100644
--- a/src/Generator/Generators/NAPI/NAPISources.cs
+++ b/src/Generator/Generators/NAPI/NAPISources.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Globalization;
using System.IO;
using System.Linq;
using CppSharp.AST;
@@ -24,14 +23,6 @@ public NAPISources(BindingContext context, IEnumerable units)
{
}
- public static string GetTranslationUnitName(TranslationUnit unit)
- {
- var paths = unit.FileRelativePath.Split('/').ToList();
- paths = paths.Select(p => Path.GetFileNameWithoutExtension(p.ToLowerInvariant())).ToList();
- var name = string.Join('_', paths);
- return name;
- }
-
public override void Process()
{
GenerateFilePreamble(CommentKind.BCPL);
diff --git a/src/Generator/Generators/QuickJS/QuickJSSources.cs b/src/Generator/Generators/QuickJS/QuickJSSources.cs
index 3facf63fd1..7f98a8017a 100644
--- a/src/Generator/Generators/QuickJS/QuickJSSources.cs
+++ b/src/Generator/Generators/QuickJS/QuickJSSources.cs
@@ -198,7 +198,7 @@ public QuickJSClassFuncDef(BindingContext context) : base(context, null)
{
}
- public override void VisitClassConstructors(Class @class)
+ public override void VisitClassConstructors(IEnumerable ctors)
{
}
diff --git a/src/Generator/Options.cs b/src/Generator/Options.cs
index 0f0bc25790..df924b86f3 100644
--- a/src/Generator/Options.cs
+++ b/src/Generator/Options.cs
@@ -115,7 +115,7 @@ public bool DoAllModulesHaveLibraries() =>
///
/// Enable this option to enable generation of finalizers. Works in both CLI and
- /// C# backends.
+ /// C# backends.
///
///
/// Use to specify a filter so that
@@ -125,7 +125,7 @@ public bool DoAllModulesHaveLibraries() =>
///
/// A filter that can restrict the classes for which finalizers are generated when
- /// is true.
+ /// is true.
///
///
/// The default filter performs no filtering so that whenever
public readonly List DependentNameSpaces = new List();
public bool MarshalCharAsManagedChar { get; set; }
+ public bool MarshalConstCharArrayAsString { get; set; } = true;
///
/// Use Span Struct instead of Managed Array
diff --git a/src/Generator/Passes/CheckAmbiguousFunctions.cs b/src/Generator/Passes/CheckAmbiguousFunctions.cs
index 964a12c694..a2001c0a7c 100644
--- a/src/Generator/Passes/CheckAmbiguousFunctions.cs
+++ b/src/Generator/Passes/CheckAmbiguousFunctions.cs
@@ -62,7 +62,7 @@ public override bool VisitFunctionDecl(AST.Function function)
}
if (function.IsAmbiguous)
- Diagnostics.Message($"Found ambiguous overload: {function.QualifiedOriginalName}");
+ Diagnostics.Debug($"Found ambiguous overload: {function.QualifiedOriginalName}");
return true;
}
diff --git a/src/Generator/Passes/CheckDuplicatedNamesPass.cs b/src/Generator/Passes/CheckDuplicatedNamesPass.cs
index 1ccefa4261..0a2d7622ab 100644
--- a/src/Generator/Passes/CheckDuplicatedNamesPass.cs
+++ b/src/Generator/Passes/CheckDuplicatedNamesPass.cs
@@ -7,6 +7,7 @@
using CppSharp.Generators.C;
using CppSharp.Generators.CLI;
using CppSharp.Generators.CSharp;
+using CppSharp.Generators.Emscripten;
using CppSharp.Types;
namespace CppSharp.Passes
@@ -204,6 +205,9 @@ private TypePrinter GetTypePrinter(GeneratorKind kind, BindingContext context)
case GeneratorKind.C:
typePrinter = new CppTypePrinter(Context) { PrintFlavorKind = CppTypePrintFlavorKind.C };
break;
+ case GeneratorKind.Emscripten:
+ typePrinter = new EmscriptenTypePrinter(Context);
+ break;;
case GeneratorKind.CPlusPlus:
case GeneratorKind.QuickJS:
case GeneratorKind.NAPI:
diff --git a/src/Generator/Passes/CleanUnitPass.cs b/src/Generator/Passes/CleanUnitPass.cs
index 4d1b3750d4..3afaa028fd 100644
--- a/src/Generator/Passes/CleanUnitPass.cs
+++ b/src/Generator/Passes/CleanUnitPass.cs
@@ -31,6 +31,11 @@ private Module GetModule(TranslationUnit unit)
includeDir = ".";
includeDir = Path.GetFullPath(includeDir);
+ // Added in https://github.com/mono/CppSharp/pull/1736, but causes us issues.
+ // return Options.Modules.FirstOrDefault(
+ // m => m.IncludeDirs.Any(i => Path.GetFullPath(i) == includeDir)) ??
+ // Options.Modules[1];
+
Module module = Options.Modules.Find(
m => m.IncludeDirs.Any(i => Path.GetFullPath(i) == includeDir));
if (module == null)
diff --git a/src/Generator/Passes/FieldToPropertyPass.cs b/src/Generator/Passes/FieldToPropertyPass.cs
index d94adebb68..9b90a431b8 100644
--- a/src/Generator/Passes/FieldToPropertyPass.cs
+++ b/src/Generator/Passes/FieldToPropertyPass.cs
@@ -33,8 +33,7 @@ public override bool VisitFieldDecl(Field field)
return false;
}
- var @class = field.Namespace as Class;
- if (@class == null)
+ if (field.Namespace is not Class @class)
return false;
// Check if we already have a synthetized property.
diff --git a/src/Generator/Passes/GetterSetterToPropertyPass.cs b/src/Generator/Passes/GetterSetterToPropertyPass.cs
index 62640744f0..4d49a4a4ab 100644
--- a/src/Generator/Passes/GetterSetterToPropertyPass.cs
+++ b/src/Generator/Passes/GetterSetterToPropertyPass.cs
@@ -21,19 +21,16 @@ static GetterSetterToPropertyPass()
private static void LoadVerbs()
{
var assembly = Assembly.GetAssembly(typeof(GetterSetterToPropertyPass));
- using (var resourceStream = GetResourceStream(assembly))
- {
- using (var streamReader = new StreamReader(resourceStream))
- while (!streamReader.EndOfStream)
- verbs.Add(streamReader.ReadLine());
- }
+ using var resourceStream = GetResourceStream(assembly);
+ using var streamReader = new StreamReader(resourceStream);
+ while (!streamReader.EndOfStream)
+ Verbs.Add(streamReader.ReadLine());
}
private static Stream GetResourceStream(Assembly assembly)
{
var resources = assembly.GetManifestResourceNames();
-
- if (resources.Count() == 0)
+ if (!resources.Any())
throw new Exception("Cannot find embedded verbs data resource.");
// We are relying on this fact that there is only one resource embedded.
@@ -54,13 +51,12 @@ public override bool VisitClassDecl(Class @class)
return false;
}
- protected virtual List GetProperties(Class @class) =>
- new List();
+ protected virtual List GetProperties() => new();
protected IEnumerable GenerateProperties(Class @class)
{
- List properties = GetProperties(@class);
- foreach (Method method in @class.Methods.Where(
+ var properties = GetProperties();
+ foreach (var method in @class.Methods.Where(
m => !m.IsConstructor && !m.IsDestructor && !m.IsOperator && m.IsGenerated &&
(properties.All(p => p.GetMethod != m && p.SetMethod != m) ||
m.OriginalFunction != null) &&
@@ -72,15 +68,16 @@ protected IEnumerable GenerateProperties(Class @class)
if (IsGetter(method))
{
string name = GetPropertyName(method.Name);
- GetProperty(properties, method, name, method.OriginalReturnType);
+ CreateOrUpdateProperty(properties, method, name, method.OriginalReturnType);
continue;
}
+
if (IsSetter(method))
{
string name = GetPropertyNameFromSetter(method.Name);
QualifiedType type = method.Parameters.First(
p => p.Kind == ParameterKind.Regular).QualifiedType;
- GetProperty(properties, method, name, type, true);
+ CreateOrUpdateProperty(properties, method, name, type, true);
}
}
@@ -104,7 +101,7 @@ private IEnumerable CleanUp(Class @class, List properties)
continue;
if (Match(firstWord, new[] { "to", "new", "on" }) ||
- verbs.Contains(firstWord))
+ Verbs.Contains(firstWord))
{
property.GetMethod.GenerationKind = GenerationKind.Generate;
@class.Properties.Remove(property);
@@ -115,12 +112,10 @@ private IEnumerable CleanUp(Class @class, List properties)
return properties;
}
- private static void GetProperty(List properties, Method method,
+ private static void CreateOrUpdateProperty(List properties, Method method,
string name, QualifiedType type, bool isSetter = false)
{
Type underlyingType = GetUnderlyingType(type);
- Class @class = (Class)method.Namespace;
-
Property property = properties.Find(
p => p.Field == null &&
((!isSetter && p.SetMethod?.IsStatic == method.IsStatic) ||
@@ -255,14 +250,13 @@ private static void RenameConflictingMethods(Class @class, Property property)
private static Type GetUnderlyingType(QualifiedType type)
{
- TagType tagType = type.Type as TagType;
- if (tagType != null)
+ if (type.Type is TagType)
return type.Type;
+
// TODO: we should normally check pointer types for const;
// however, there's some bug, probably in the parser, that returns IsConst = false for "const Type& arg"
// so skip the check for the time being
- PointerType pointerType = type.Type as PointerType;
- return pointerType != null ? pointerType.Pointee : type.Type;
+ return type.Type is PointerType pointerType ? pointerType.Pointee : type.Type;
}
private static void CombineComments(Property property)
@@ -277,6 +271,7 @@ private static void CombineComments(Property property)
BriefText = getter.Comment.BriefText,
Text = getter.Comment.Text
};
+
if (getter.Comment.FullComment != null)
{
comment.FullComment = new FullComment();
@@ -295,20 +290,18 @@ private static void CombineComments(Property property)
private static string GetPropertyName(string name)
{
var firstWord = GetFirstWord(name);
- if (Match(firstWord, new[] { "get" }) &&
- (string.Compare(name, firstWord, StringComparison.InvariantCultureIgnoreCase) != 0) &&
- !char.IsNumber(name[3]))
+ if (!Match(firstWord, new[] {"get"}) ||
+ (string.Compare(name, firstWord, StringComparison.InvariantCultureIgnoreCase) == 0) ||
+ char.IsNumber(name[3])) return name;
+
+ if (name.Length == 4)
{
- if (name.Length == 4)
- {
- return char.ToLowerInvariant(
- name[3]).ToString(CultureInfo.InvariantCulture);
- }
return char.ToLowerInvariant(
- name[3]).ToString(CultureInfo.InvariantCulture) +
- name.Substring(4);
+ name[3]).ToString(CultureInfo.InvariantCulture);
}
- return name;
+
+ return string.Concat(char.ToLowerInvariant(
+ name[3]).ToString(CultureInfo.InvariantCulture), name.AsSpan(4));
}
private static string GetPropertyNameFromSetter(string name)
@@ -327,8 +320,8 @@ private static string GetPropertyNameFromSetter(string name)
private bool IsGetter(Method method) =>
!method.IsDestructor &&
- !method.OriginalReturnType.Type.IsPrimitiveType(PrimitiveType.Void) &&
- !method.Parameters.Any(p => p.Kind != ParameterKind.IndirectReturnType);
+ !method.OriginalReturnType.Type.IsPrimitiveType(PrimitiveType.Void) &&
+ method.Parameters.All(p => p.Kind == ParameterKind.IndirectReturnType);
private static bool IsSetter(Method method)
{
@@ -365,6 +358,6 @@ private static string GetFirstWord(string name)
return new string(firstWord.ToArray());
}
- private static readonly HashSet verbs = new HashSet();
+ private static readonly HashSet Verbs = new();
}
}
diff --git a/src/Generator/Types/Std/Stdlib.CSharp.cs b/src/Generator/Types/Std/Stdlib.CSharp.cs
index 9f46125c00..83df7b1cd2 100644
--- a/src/Generator/Types/Std/Stdlib.CSharp.cs
+++ b/src/Generator/Types/Std/Stdlib.CSharp.cs
@@ -227,8 +227,6 @@ public override void CSharpMarshalToManaged(CSharpMarshalContext ctx)
return (Context.Options.Encoding, nameof(Encoding.ASCII));
if (Context.Options.Encoding == Encoding.UTF8)
return (Context.Options.Encoding, nameof(Encoding.UTF8));
- if (Context.Options.Encoding == Encoding.UTF7)
- return (Context.Options.Encoding, nameof(Encoding.UTF7));
if (Context.Options.Encoding == Encoding.BigEndianUnicode)
return (Context.Options.Encoding, nameof(Encoding.BigEndianUnicode));
if (Context.Options.Encoding == Encoding.Unicode)
diff --git a/src/Generator/Utils/Options.cs b/src/Generator/Utils/Options.cs
index f5740700f9..845c41db0a 100644
--- a/src/Generator/Utils/Options.cs
+++ b/src/Generator/Utils/Options.cs
@@ -710,7 +710,6 @@ public string OptionName
get { return this.option; }
}
- [SecurityPermission(SecurityAction.LinkDemand, SerializationFormatter = true)]
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
diff --git a/src/Parser/ASTConverter.cs b/src/Parser/ASTConverter.cs
index 5e682d4971..f32f63c75b 100644
--- a/src/Parser/ASTConverter.cs
+++ b/src/Parser/ASTConverter.cs
@@ -1719,6 +1719,8 @@ AST.CppAbi VisitCppAbi(CppAbi abi)
return AST.CppAbi.iOS;
case CppAbi.iOS64:
return AST.CppAbi.iOS64;
+ case CppAbi.WebAssembly:
+ return AST.CppAbi.WebAssembly;
default:
throw new ArgumentOutOfRangeException("abi");
}
@@ -2081,6 +2083,7 @@ public override AST.Declaration VisitNonTypeTemplateParameter(NonTypeTemplatePar
nonTypeTemplateParameter.IsParameterPack = decl.IsParameterPack;
nonTypeTemplateParameter.IsPackExpansion = decl.IsPackExpansion;
nonTypeTemplateParameter.IsExpandedParameterPack = decl.IsExpandedParameterPack;
+ nonTypeTemplateParameter.Type = typeConverter.VisitQualified(decl.Type);
return nonTypeTemplateParameter;
}
diff --git a/src/Parser/Parser.cs b/src/Parser/Parser.cs
index fa1a889b65..66d5daceaa 100644
--- a/src/Parser/Parser.cs
+++ b/src/Parser/Parser.cs
@@ -59,7 +59,7 @@ public static ParserResult ParseLibrary(LinkerOptions options)
///
/// Converts a native parser AST to a managed AST.
///
- static public AST.ASTContext ConvertASTContext(ASTContext context)
+ public static AST.ASTContext ConvertASTContext(ASTContext context)
{
var converter = new ASTConverter(context);
return converter.Convert();
diff --git a/src/Parser/ParserOptions.cs b/src/Parser/ParserOptions.cs
index 41dffa66d3..7cda0375e3 100644
--- a/src/Parser/ParserOptions.cs
+++ b/src/Parser/ParserOptions.cs
@@ -5,9 +5,7 @@
using System.IO;
using System.Linq;
using System.Reflection;
-using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
-using LanguageVersion = CppSharp.Parser.LanguageVersion;
namespace CppSharp.Parser
{
@@ -200,20 +198,22 @@ private void GetUnixCompilerInfo(string headersPath, out string compiler,
var versions = Directory.EnumerateDirectories(Path.Combine(headersPath,
"usr", "include", "c++"));
- if (versions.Count() == 0)
+ if (!versions.Any())
throw new Exception("No valid GCC version found on system include paths");
- string gccVersionPath = versions.First();
+ var gccVersionPath = versions.First();
longVersion = shortVersion = gccVersionPath.Substring(
gccVersionPath.LastIndexOf(Path.DirectorySeparatorChar) + 1);
return;
}
- var info = new ProcessStartInfo(Environment.GetEnvironmentVariable("CXX") ?? "gcc", "-v");
- info.RedirectStandardError = true;
- info.CreateNoWindow = true;
- info.UseShellExecute = false;
+ var info = new ProcessStartInfo(Environment.GetEnvironmentVariable("CXX") ?? "gcc", "-v")
+ {
+ RedirectStandardError = true,
+ CreateNoWindow = true,
+ UseShellExecute = false
+ };
var process = Process.Start(info);
if (process == null)
@@ -237,13 +237,14 @@ public void SetupLinux(string headersPath = "")
NoBuiltinIncludes = true;
NoStandardIncludes = true;
- string compiler, longVersion, shortVersion;
- GetUnixCompilerInfo(headersPath, out compiler, out longVersion, out shortVersion);
+ GetUnixCompilerInfo(headersPath, out var compiler, out var longVersion, out var shortVersion);
AddSystemIncludeDirs(BuiltinsDir);
- AddArguments($"-fgnuc-version={longVersion}");
- string majorVersion = shortVersion.Split('.')[0];
+ var majorVersion = shortVersion.Split('.')[0];
+ // Workaround https://github.com/llvm/llvm-project/issues/53152, remove once bug is fixed.
+ AddArguments(int.Parse(majorVersion) >= 11 ? $"-fgnuc-version=10.1" : $"-fgnuc-version={longVersion}");
+
string[] versions = { longVersion, shortVersion, majorVersion };
string[] triples = { "x86_64-linux-gnu", "x86_64-pc-linux-gnu" };
if (compiler == "gcc")
@@ -277,19 +278,23 @@ public void SetupLinux(string headersPath = "")
AddSystemIncludeDirs($"{headersPath}/usr/include/linux");
}
- public void Setup()
+ private bool setupDone;
+
+ public void Setup(TargetPlatform targetPlatform)
{
- SetupArguments();
+ if (setupDone) return;
+
+ SetupArguments(targetPlatform);
if (!NoBuiltinIncludes)
- SetupIncludes();
+ SetupIncludes(targetPlatform);
+
+ setupDone = true;
}
- private void SetupArguments()
+ private void SetupArguments(TargetPlatform targetPlatform)
{
- // do not remove the CppSharp prefix becase the Mono C# compiler breaks
- if (!LanguageVersion.HasValue)
- LanguageVersion = CppSharp.Parser.LanguageVersion.CPP14_GNU;
+ LanguageVersion ??= CppSharp.Parser.LanguageVersion.CPP14_GNU;
// As of Clang revision 5e866e411caa we are required to pass "-fgnuc-version="
// to get the __GNUC__ symbol defined. macOS and Linux system headers require
@@ -299,7 +304,7 @@ private void SetupArguments()
// setup methods, below is generic fallback in case that logic was disabled.
if (NoBuiltinIncludes)
{
- switch (Platform.Host)
+ switch (targetPlatform)
{
case TargetPlatform.MacOS:
case TargetPlatform.Linux:
@@ -373,18 +378,21 @@ public string BuiltinsDir
{
get
{
- var assemblyDir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
+ var assemblyDir = Path.GetDirectoryName(Assembly.GetEntryAssembly()?.Location);
+ if (assemblyDir == null)
+ throw new InvalidOperationException();
+
return Path.Combine(assemblyDir, "lib", "clang", ClangVersion, "include");
}
}
- private void SetupIncludes()
+ 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.");
- switch (Platform.Host)
+ switch (targetPlatform)
{
case TargetPlatform.Windows:
SetupMSVC();
@@ -395,6 +403,16 @@ private void SetupIncludes()
case TargetPlatform.Linux:
SetupLinux();
break;
+ case TargetPlatform.Android:
+ throw new NotImplementedException();
+ case TargetPlatform.iOS:
+ case TargetPlatform.WatchOS:
+ case TargetPlatform.TVOS:
+ throw new NotImplementedException();
+ case TargetPlatform.Emscripten:
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
}
}
}
diff --git a/src/Runtime/SymbolResolver.cs b/src/Runtime/SymbolResolver.cs
index cc2c3680eb..19e1645bc2 100644
--- a/src/Runtime/SymbolResolver.cs
+++ b/src/Runtime/SymbolResolver.cs
@@ -1,5 +1,5 @@
/* Copyright (c) 2013 Xamarin, Inc and contributors
- *
+ *
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
@@ -7,10 +7,10 @@
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
- *
+ *
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -80,8 +80,8 @@ public static IntPtr LoadImage(ref string name)
break;
}
}
- if (!File.Exists(attempted))
- continue;
+ if (attempted == null)
+ attempted = filename;
var ptr = loadImage(attempted);
diff --git a/tests2/Builtins.h b/tests/Builtins.h
similarity index 97%
rename from tests2/Builtins.h
rename to tests/Builtins.h
index 3aa8015cbf..9b270e5385 100644
--- a/tests2/Builtins.h
+++ b/tests/Builtins.h
@@ -1,3 +1,4 @@
+#include
#include
void ReturnsVoid () { }
@@ -40,8 +41,10 @@ int16_t ReturnsInt16 () { return -5; }
uint16_t ReturnsUInt16 () { return 5; }
int32_t ReturnsInt32 () { return -5; }
uint32_t ReturnsUInt32 () { return 5; }
+#if !defined(__EMSCRIPTEN__)
int64_t ReturnsInt64 () { return -5; }
uint64_t ReturnsUInt64 () { return 5; }
+#endif
int8_t PassAndReturnsInt8 (int8_t v) { return v; }
uint8_t PassAndReturnsUInt8 (uint8_t v) { return v; }
diff --git a/tests2/Classes.h b/tests/Classes.h
similarity index 100%
rename from tests2/Classes.h
rename to tests/Classes.h
diff --git a/tests2/Classes2.h b/tests/Classes2.h
similarity index 100%
rename from tests2/Classes2.h
rename to tests/Classes2.h
diff --git a/tests2/Delegates.h b/tests/Delegates.h
similarity index 100%
rename from tests2/Delegates.h
rename to tests/Delegates.h
diff --git a/tests2/Enums.h b/tests/Enums.h
similarity index 100%
rename from tests2/Enums.h
rename to tests/Enums.h
diff --git a/tests/NamespacesBase/premake4.lua b/tests/NamespacesBase/premake4.lua
deleted file mode 100644
index 0c46c42af1..0000000000
--- a/tests/NamespacesBase/premake4.lua
+++ /dev/null
@@ -1,11 +0,0 @@
-function SetupWrapper(name)
- if not EnabledManagedProjects() then
- return
- end
-
- SetupExternalManagedTestProject(name .. ".CSharp")
-end
-
-group "Tests/Namespaces"
- SetupTestNativeProject("NamespacesBase")
- targetdir (path.join(gendir, "NamespacesDerived"))
\ No newline at end of file
diff --git a/tests2/Overloads.h b/tests/Overloads.h
similarity index 100%
rename from tests2/Overloads.h
rename to tests/Overloads.h
diff --git a/tests/CLI/CLI.Gen.cs b/tests/dotnet/CLI/CLI.Gen.cs
similarity index 100%
rename from tests/CLI/CLI.Gen.cs
rename to tests/dotnet/CLI/CLI.Gen.cs
diff --git a/tests/CLI/CLI.Gen.csproj b/tests/dotnet/CLI/CLI.Gen.csproj
similarity index 100%
rename from tests/CLI/CLI.Gen.csproj
rename to tests/dotnet/CLI/CLI.Gen.csproj
diff --git a/tests/CLI/CLI.Tests.CLI.csproj b/tests/dotnet/CLI/CLI.Tests.CLI.csproj
similarity index 100%
rename from tests/CLI/CLI.Tests.CLI.csproj
rename to tests/dotnet/CLI/CLI.Tests.CLI.csproj
diff --git a/tests/CLI/CLI.Tests.cs b/tests/dotnet/CLI/CLI.Tests.cs
similarity index 100%
rename from tests/CLI/CLI.Tests.cs
rename to tests/dotnet/CLI/CLI.Tests.cs
diff --git a/tests/CLI/CLI.cpp b/tests/dotnet/CLI/CLI.cpp
similarity index 100%
rename from tests/CLI/CLI.cpp
rename to tests/dotnet/CLI/CLI.cpp
diff --git a/tests/CLI/CLI.h b/tests/dotnet/CLI/CLI.h
similarity index 100%
rename from tests/CLI/CLI.h
rename to tests/dotnet/CLI/CLI.h
diff --git a/tests/CLI/NestedEnumInClassTest/ClassWithNestedEnum.cpp b/tests/dotnet/CLI/NestedEnumInClassTest/ClassWithNestedEnum.cpp
similarity index 100%
rename from tests/CLI/NestedEnumInClassTest/ClassWithNestedEnum.cpp
rename to tests/dotnet/CLI/NestedEnumInClassTest/ClassWithNestedEnum.cpp
diff --git a/tests/CLI/NestedEnumInClassTest/ClassWithNestedEnum.h b/tests/dotnet/CLI/NestedEnumInClassTest/ClassWithNestedEnum.h
similarity index 100%
rename from tests/CLI/NestedEnumInClassTest/ClassWithNestedEnum.h
rename to tests/dotnet/CLI/NestedEnumInClassTest/ClassWithNestedEnum.h
diff --git a/tests/CLI/NestedEnumInClassTest/NestedEnumConsumer.cpp b/tests/dotnet/CLI/NestedEnumInClassTest/NestedEnumConsumer.cpp
similarity index 100%
rename from tests/CLI/NestedEnumInClassTest/NestedEnumConsumer.cpp
rename to tests/dotnet/CLI/NestedEnumInClassTest/NestedEnumConsumer.cpp
diff --git a/tests/CLI/NestedEnumInClassTest/NestedEnumConsumer.h b/tests/dotnet/CLI/NestedEnumInClassTest/NestedEnumConsumer.h
similarity index 100%
rename from tests/CLI/NestedEnumInClassTest/NestedEnumConsumer.h
rename to tests/dotnet/CLI/NestedEnumInClassTest/NestedEnumConsumer.h
diff --git a/tests/CLI/UseTemplateTypeFromIgnoredClassTemplate/Employee.cpp b/tests/dotnet/CLI/UseTemplateTypeFromIgnoredClassTemplate/Employee.cpp
similarity index 100%
rename from tests/CLI/UseTemplateTypeFromIgnoredClassTemplate/Employee.cpp
rename to tests/dotnet/CLI/UseTemplateTypeFromIgnoredClassTemplate/Employee.cpp
diff --git a/tests/CLI/UseTemplateTypeFromIgnoredClassTemplate/Employee.h b/tests/dotnet/CLI/UseTemplateTypeFromIgnoredClassTemplate/Employee.h
similarity index 100%
rename from tests/CLI/UseTemplateTypeFromIgnoredClassTemplate/Employee.h
rename to tests/dotnet/CLI/UseTemplateTypeFromIgnoredClassTemplate/Employee.h
diff --git a/tests/CLI/UseTemplateTypeFromIgnoredClassTemplate/EmployeeForwardDecl.h b/tests/dotnet/CLI/UseTemplateTypeFromIgnoredClassTemplate/EmployeeForwardDecl.h
similarity index 100%
rename from tests/CLI/UseTemplateTypeFromIgnoredClassTemplate/EmployeeForwardDecl.h
rename to tests/dotnet/CLI/UseTemplateTypeFromIgnoredClassTemplate/EmployeeForwardDecl.h
diff --git a/tests/CLI/UseTemplateTypeFromIgnoredClassTemplate/EmployeeOrg.cpp b/tests/dotnet/CLI/UseTemplateTypeFromIgnoredClassTemplate/EmployeeOrg.cpp
similarity index 100%
rename from tests/CLI/UseTemplateTypeFromIgnoredClassTemplate/EmployeeOrg.cpp
rename to tests/dotnet/CLI/UseTemplateTypeFromIgnoredClassTemplate/EmployeeOrg.cpp
diff --git a/tests/CLI/UseTemplateTypeFromIgnoredClassTemplate/EmployeeOrg.h b/tests/dotnet/CLI/UseTemplateTypeFromIgnoredClassTemplate/EmployeeOrg.h
similarity index 100%
rename from tests/CLI/UseTemplateTypeFromIgnoredClassTemplate/EmployeeOrg.h
rename to tests/dotnet/CLI/UseTemplateTypeFromIgnoredClassTemplate/EmployeeOrg.h
diff --git a/tests/CLI/UseTemplateTypeFromIgnoredClassTemplate/IgnoredClassTemplateForEmployee.h b/tests/dotnet/CLI/UseTemplateTypeFromIgnoredClassTemplate/IgnoredClassTemplateForEmployee.h
similarity index 100%
rename from tests/CLI/UseTemplateTypeFromIgnoredClassTemplate/IgnoredClassTemplateForEmployee.h
rename to tests/dotnet/CLI/UseTemplateTypeFromIgnoredClassTemplate/IgnoredClassTemplateForEmployee.h
diff --git a/tests/CLI/premake4.lua b/tests/dotnet/CLI/premake4.lua
similarity index 100%
rename from tests/CLI/premake4.lua
rename to tests/dotnet/CLI/premake4.lua
diff --git a/tests/CSharp/AnonTypes.h b/tests/dotnet/CSharp/AnonTypes.h
similarity index 100%
rename from tests/CSharp/AnonTypes.h
rename to tests/dotnet/CSharp/AnonTypes.h
diff --git a/tests/CSharp/AnotherUnit.cpp b/tests/dotnet/CSharp/AnotherUnit.cpp
similarity index 100%
rename from tests/CSharp/AnotherUnit.cpp
rename to tests/dotnet/CSharp/AnotherUnit.cpp
diff --git a/tests/CSharp/AnotherUnit.h b/tests/dotnet/CSharp/AnotherUnit.h
similarity index 100%
rename from tests/CSharp/AnotherUnit.h
rename to tests/dotnet/CSharp/AnotherUnit.h
diff --git a/tests/CSharp/CSharp.CSharp.csproj b/tests/dotnet/CSharp/CSharp.CSharp.csproj
similarity index 65%
rename from tests/CSharp/CSharp.CSharp.csproj
rename to tests/dotnet/CSharp/CSharp.CSharp.csproj
index a253523095..6a6c4bf76a 100644
--- a/tests/CSharp/CSharp.CSharp.csproj
+++ b/tests/dotnet/CSharp/CSharp.CSharp.csproj
@@ -1,4 +1,7 @@
+
+ 0108
+
diff --git a/tests/CSharp/CSharp.Gen.cs b/tests/dotnet/CSharp/CSharp.Gen.cs
similarity index 100%
rename from tests/CSharp/CSharp.Gen.cs
rename to tests/dotnet/CSharp/CSharp.Gen.cs
diff --git a/tests/CSharp/CSharp.Gen.csproj b/tests/dotnet/CSharp/CSharp.Gen.csproj
similarity index 100%
rename from tests/CSharp/CSharp.Gen.csproj
rename to tests/dotnet/CSharp/CSharp.Gen.csproj
diff --git a/tests/CSharp/CSharp.Tests.CSharp.csproj b/tests/dotnet/CSharp/CSharp.Tests.CSharp.csproj
similarity index 100%
rename from tests/CSharp/CSharp.Tests.CSharp.csproj
rename to tests/dotnet/CSharp/CSharp.Tests.CSharp.csproj
diff --git a/tests/CSharp/CSharp.Tests.cs b/tests/dotnet/CSharp/CSharp.Tests.cs
similarity index 99%
rename from tests/CSharp/CSharp.Tests.cs
rename to tests/dotnet/CSharp/CSharp.Tests.cs
index 185c1d518a..7050fa744c 100644
--- a/tests/CSharp/CSharp.Tests.cs
+++ b/tests/dotnet/CSharp/CSharp.Tests.cs
@@ -346,6 +346,10 @@ public void TestDefaultArguments()
methodsWithDefaultValues.DefaultWithSpecialization();
methodsWithDefaultValues.DefaultOverloadedImplicitCtor();
methodsWithDefaultValues.DefaultWithParamNamedSameAsMethod(5);
+ Assert.That(methodsWithDefaultValues.DefaultIntAssignedAnEnumWithBinaryOperatorAndFlags(), Is.EqualTo((int)(Bar.Items.Item1 | Bar.Items.Item2)));
+ Assert.That(methodsWithDefaultValues.DefaultWithConstantFlags(), Is.EqualTo(CSharp.CSharp.ConstFlag1 | CSharp.CSharp.ConstFlag2 | CSharp.CSharp.ConstFlag3));
+ Assert.IsTrue(methodsWithDefaultValues.DefaultWithPointerToEnum());
+ Assert.AreEqual(CSharp.CSharp.DefaultSmallPODInstance.__Instance, methodsWithDefaultValues.DefaultWithNonPrimitiveType().__Instance);
}
}
@@ -1999,4 +2003,11 @@ public void TestCallByValueCopyConstructor()
Assert.That(CallByValueCopyConstructor.CopyConstructorCalls, Is.EqualTo(1));
Assert.That(CallByValueCopyConstructor.DestructorCalls, Is.EqualTo(2));
}
+
+ [Test]
+ public void TestPointerToClass()
+ {
+ Assert.IsTrue(CSharp.CSharp.PointerToClass.IsDefaultInstance);
+ Assert.IsTrue(CSharp.CSharp.PointerToClass.IsValid);
+ }
}
diff --git a/tests/CSharp/CSharp.cpp b/tests/dotnet/CSharp/CSharp.cpp
similarity index 96%
rename from tests/CSharp/CSharp.cpp
rename to tests/dotnet/CSharp/CSharp.cpp
index 33ff64b040..8d1d091260 100644
--- a/tests/CSharp/CSharp.cpp
+++ b/tests/dotnet/CSharp/CSharp.cpp
@@ -568,6 +568,8 @@ MethodsWithDefaultValues::QMargins::QMargins(int left, int top, int right, int b
{
}
+struct SmallPOD DefaultSmallPODInstance;
+
const char* MethodsWithDefaultValues::stringConstant = "test";
int MethodsWithDefaultValues::intConstant = 5;
@@ -808,6 +810,26 @@ int MethodsWithDefaultValues::DefaultWithParamNamedSameAsMethod(int DefaultWithP
return 1;
}
+int MethodsWithDefaultValues::defaultIntAssignedAnEnumWithBinaryOperatorAndFlags(int f)
+{
+ return f;
+}
+
+int MethodsWithDefaultValues::defaultWithConstantFlags(int f)
+{
+ return f;
+}
+
+bool MethodsWithDefaultValues::defaultWithPointerToEnum(UntypedFlags* f1, int* f2)
+{
+ return (f1 == NULL || *f1 == (UntypedFlags)0) && (f2 == NULL || *f2 == 0);
+}
+
+SmallPOD* MethodsWithDefaultValues::defaultWithNonPrimitiveType(SmallPOD& pod)
+{
+ return &pod;
+}
+
int MethodsWithDefaultValues::getA()
{
return m_foo.A;
@@ -1299,7 +1321,7 @@ TestString::TestString() : unicodeConst(L"ქართული ენა"), uni
{
}
-TestChar32String::TestChar32String() :
+TestChar32String::TestChar32String() :
thirtyTwoBitConst(U"ქართული ენა")
{
static std::u32string nonConst = U"Test String";
@@ -1307,8 +1329,8 @@ TestChar32String::TestChar32String() :
}
TestChar32String::~TestChar32String() {}
-void TestChar32String::UpdateString(const char32_t* s)
-{
+void TestChar32String::UpdateString(const char32_t* s)
+{
static std::u32string nativeOwnedMemory = s;
thirtyTwoBitConst = nativeOwnedMemory.data();
}
@@ -1316,8 +1338,8 @@ void TestChar32String::UpdateString(const char32_t* s)
const char32_t* TestChar32String::RetrieveString() { return thirtyTwoBitConst; }
void TestChar32String::functionPointerUTF32(void(*ptr)(const char32_t*)) {}
-TestChar16String::TestChar16String() :
- sixteenBitConst(u"ქართული ენა")
+TestChar16String::TestChar16String() :
+ sixteenBitConst(u"ქართული ენა")
{
static std::u16string nonConst = u"Test String";
sixteenBitNonConst = &nonConst[0];
@@ -1325,10 +1347,10 @@ TestChar16String::TestChar16String() :
TestChar16String::~TestChar16String() {}
-void TestChar16String::UpdateString(const char16_t* s)
-{
+void TestChar16String::UpdateString(const char16_t* s)
+{
static std::u16string nativeOwnedMemory = s;
- sixteenBitConst = nativeOwnedMemory.data();
+ sixteenBitConst = nativeOwnedMemory.data();
}
const char16_t* TestChar16String::RetrieveString() { return sixteenBitConst; }
@@ -1667,7 +1689,7 @@ const unsigned ClassCustomTypeAlignmentOffsets[5]
offsetof(ClassCustomTypeAlignment, align8),
};
-const unsigned ClassCustomObjectAlignmentOffsets[2] {
+const unsigned ClassCustomObjectAlignmentOffsets[2] {
offsetof(ClassCustomObjectAlignment, boolean),
offsetof(ClassCustomObjectAlignment, charAligned8),
};
@@ -1776,3 +1798,21 @@ void CallByValueCopyConstructorFunction(CallByValueCopyConstructor s)
{
s.a = 99999;
}
+static PointerTester internalPointerTesterInstance;
+
+PointerTester::PointerTester()
+{
+ a = 0;
+}
+
+bool PointerTester::IsDefaultInstance()
+{
+ return this == &internalPointerTesterInstance;
+}
+
+bool PointerTester::IsValid()
+{
+ return a == 0;
+}
+
+PointerTester* PointerToClass = &internalPointerTesterInstance;
diff --git a/tests/CSharp/CSharp.h b/tests/dotnet/CSharp/CSharp.h
similarity index 97%
rename from tests/CSharp/CSharp.h
rename to tests/dotnet/CSharp/CSharp.h
index 6bd021b68f..7986dbe14f 100644
--- a/tests/CSharp/CSharp.h
+++ b/tests/dotnet/CSharp/CSharp.h
@@ -405,6 +405,12 @@ enum class Empty : unsigned long long int
class _ClassWithLeadingUnderscore {
};
+const int ConstFlag1 = 1;
+const int ConstFlag2 = 2;
+const int ConstFlag3 = 4;
+
+extern DLL_API struct SmallPOD DefaultSmallPODInstance;
+
class DLL_API MethodsWithDefaultValues : public Quux
{
public:
@@ -480,6 +486,10 @@ class DLL_API MethodsWithDefaultValues : public Quux
void defaultWithSpecialization(IndependentFields specialization = IndependentFields());
void defaultOverloadedImplicitCtor(P p);
void defaultOverloadedImplicitCtor(Qux q = Qux());
+ int defaultIntAssignedAnEnumWithBinaryOperatorAndFlags(int f = Bar::Item1 | Bar::Item2);
+ int defaultWithConstantFlags(int f = ConstFlag1 | ConstFlag2 | ConstFlag3);
+ bool defaultWithPointerToEnum(UntypedFlags* f1 = NULL, int* f2 = NULL);
+ SmallPOD* defaultWithNonPrimitiveType(SmallPOD& pod = DefaultSmallPODInstance);
int DefaultWithParamNamedSameAsMethod(int DefaultWithParamNamedSameAsMethod, const Foo& defaultArg = Foo());
int getA();
private:
@@ -1082,9 +1092,9 @@ class DLL_API VariablesWithInitializer {
static constexpr const char* StringArray1[1] { "Str" "F,\"or" };
static constexpr const char* StringArray3[3] { "Str" "F,\"or", "C#", String };
static constexpr const char* StringArray30[30] {
- "Str", "Str", "Str", "Str", "Str", "Str", "Str", "Str", "Str", "Str",
- "Str", "Str", "Str", "Str", "Str", "Str", "Str", "Str", "Str", "Str",
- "Str", "Str", "Str", "Str", "Str", "Str", "Str", "Str", "Str", "Str",
+ "Str", "Str", "Str", "Str", "Str", "Str", "Str", "Str", "Str", "Str",
+ "Str", "Str", "Str", "Str", "Str", "Str", "Str", "Str", "Str", "Str",
+ "Str", "Str", "Str", "Str", "Str", "Str", "Str", "Str", "Str", "Str",
};
static constexpr const char* StringArray3EmptyInitList[3] { };
static constexpr const wchar_t* WideStringArray[2] { L"Str", L"C#" };
@@ -1278,7 +1288,7 @@ struct StructTestArrayTypeFromTypedef
#define MY_MACRO_TEST2_4 (1 << 3)
#define MY_MACRO_TEST2_ALL (1 << 4) - 1
-#define SIGNED_MACRO_VALUES_TO_ENUM_TEST_1 1 << 5
+#define SIGNED_MACRO_VALUES_TO_ENUM_TEST_1 1 << 5
#define SIGNED_MACRO_VALUES_TO_ENUM_TEST_2 1 << 22
#define SIGNED_MACRO_VALUES_TO_ENUM_TEST_3 1L << 32
#define SIGNED_MACRO_VALUES_TO_ENUM_TEST_4 -1
@@ -1465,9 +1475,9 @@ struct DLL_API ConversionFunctions
short field = 100;
};
-struct DLL_API ClassCustomTypeAlignment
+struct DLL_API ClassCustomTypeAlignment
{
- struct alignas(1) Align1 { };
+ struct alignas(1) Align1 { };
struct alignas(8) Align8 { };
struct alignas(16) Align16 {
double a;
@@ -1476,7 +1486,7 @@ struct DLL_API ClassCustomTypeAlignment
bool boolean;
Align16 align16;
- Align1 align1;
+ Align1 align1;
double dbl;
Align8 align8;
};
@@ -1524,7 +1534,7 @@ DLL_API extern const unsigned StructWithEmbeddedArrayOfStructObjectAlignmentOffs
DLL_API const char* TestCSharpString(const char* in, CS_OUT const char** out);
DLL_API const wchar_t* TestCSharpStringWide(const wchar_t* in, CS_OUT const wchar_t** out);
-DLL_API const char16_t* TestCSharpString16(const char16_t* in, CS_OUT const char16_t** out);
+DLL_API const char16_t* TestCSharpString16(const char16_t* in, CS_OUT const char16_t** out);
DLL_API const char32_t* TestCSharpString32(const char32_t* in, CS_OUT const char32_t** out);
struct DLL_API FTIStruct { int a; };
@@ -1595,3 +1605,13 @@ struct DLL_API CallByValueCopyConstructor {
};
DLL_API void CallByValueCopyConstructorFunction(CallByValueCopyConstructor s);
+class DLL_API PointerTester
+{
+ int a;
+public:
+ PointerTester();
+ bool IsDefaultInstance();
+ bool IsValid();
+};
+
+DLL_API extern PointerTester* PointerToClass;
diff --git a/tests/CSharp/CSharpPartialMethods.cs b/tests/dotnet/CSharp/CSharpPartialMethods.cs
similarity index 100%
rename from tests/CSharp/CSharpPartialMethods.cs
rename to tests/dotnet/CSharp/CSharpPartialMethods.cs
diff --git a/tests/CSharp/CSharpTemplates.cpp b/tests/dotnet/CSharp/CSharpTemplates.cpp
similarity index 100%
rename from tests/CSharp/CSharpTemplates.cpp
rename to tests/dotnet/CSharp/CSharpTemplates.cpp
diff --git a/tests/CSharp/CSharpTemplates.h b/tests/dotnet/CSharp/CSharpTemplates.h
similarity index 100%
rename from tests/CSharp/CSharpTemplates.h
rename to tests/dotnet/CSharp/CSharpTemplates.h
diff --git a/tests/CSharp/ExcludedUnit.hpp b/tests/dotnet/CSharp/ExcludedUnit.hpp
similarity index 100%
rename from tests/CSharp/ExcludedUnit.hpp
rename to tests/dotnet/CSharp/ExcludedUnit.hpp
diff --git a/tests/CSharp/premake4.lua b/tests/dotnet/CSharp/premake4.lua
similarity index 100%
rename from tests/CSharp/premake4.lua
rename to tests/dotnet/CSharp/premake4.lua
diff --git a/tests/Common/AnotherUnit.cpp b/tests/dotnet/Common/AnotherUnit.cpp
similarity index 100%
rename from tests/Common/AnotherUnit.cpp
rename to tests/dotnet/Common/AnotherUnit.cpp
diff --git a/tests/Common/AnotherUnit.h b/tests/dotnet/Common/AnotherUnit.h
similarity index 100%
rename from tests/Common/AnotherUnit.h
rename to tests/dotnet/Common/AnotherUnit.h
diff --git a/tests/Common/Common.CSharp.csproj b/tests/dotnet/Common/Common.CSharp.csproj
similarity index 100%
rename from tests/Common/Common.CSharp.csproj
rename to tests/dotnet/Common/Common.CSharp.csproj
diff --git a/tests/Common/Common.Gen.cs b/tests/dotnet/Common/Common.Gen.cs
similarity index 100%
rename from tests/Common/Common.Gen.cs
rename to tests/dotnet/Common/Common.Gen.cs
diff --git a/tests/Common/Common.Gen.csproj b/tests/dotnet/Common/Common.Gen.csproj
similarity index 100%
rename from tests/Common/Common.Gen.csproj
rename to tests/dotnet/Common/Common.Gen.csproj
diff --git a/tests/Common/Common.Tests.CLI.csproj b/tests/dotnet/Common/Common.Tests.CLI.csproj
similarity index 100%
rename from tests/Common/Common.Tests.CLI.csproj
rename to tests/dotnet/Common/Common.Tests.CLI.csproj
diff --git a/tests/Common/Common.Tests.CSharp.csproj b/tests/dotnet/Common/Common.Tests.CSharp.csproj
similarity index 100%
rename from tests/Common/Common.Tests.CSharp.csproj
rename to tests/dotnet/Common/Common.Tests.CSharp.csproj
diff --git a/tests/Common/Common.Tests.cs b/tests/dotnet/Common/Common.Tests.cs
similarity index 100%
rename from tests/Common/Common.Tests.cs
rename to tests/dotnet/Common/Common.Tests.cs
diff --git a/tests/Common/Common.cpp b/tests/dotnet/Common/Common.cpp
similarity index 99%
rename from tests/Common/Common.cpp
rename to tests/dotnet/Common/Common.cpp
index 04d63cdd09..47076a023d 100644
--- a/tests/Common/Common.cpp
+++ b/tests/dotnet/Common/Common.cpp
@@ -1273,4 +1273,4 @@ extern "C"
s.field2 = 10;
return s;
}
-} // extern "C"
\ No newline at end of file
+} // extern "C"
diff --git a/tests/Common/Common.h b/tests/dotnet/Common/Common.h
similarity index 100%
rename from tests/Common/Common.h
rename to tests/dotnet/Common/Common.h
diff --git a/tests/Common/interface.h b/tests/dotnet/Common/interface.h
similarity index 100%
rename from tests/Common/interface.h
rename to tests/dotnet/Common/interface.h
diff --git a/tests/Common/premake4.lua b/tests/dotnet/Common/premake4.lua
similarity index 100%
rename from tests/Common/premake4.lua
rename to tests/dotnet/Common/premake4.lua
diff --git a/tests/Directory.Build.props b/tests/dotnet/Directory.Build.props
similarity index 83%
rename from tests/Directory.Build.props
rename to tests/dotnet/Directory.Build.props
index 9b32f3ecd5..5402b2c443 100644
--- a/tests/Directory.Build.props
+++ b/tests/dotnet/Directory.Build.props
@@ -1,5 +1,5 @@
-
+
diff --git a/tests/Empty/Empty.Gen.cs b/tests/dotnet/Empty/Empty.Gen.cs
similarity index 100%
rename from tests/Empty/Empty.Gen.cs
rename to tests/dotnet/Empty/Empty.Gen.cs
diff --git a/tests/Empty/Empty.Tests.cs b/tests/dotnet/Empty/Empty.Tests.cs
similarity index 100%
rename from tests/Empty/Empty.Tests.cs
rename to tests/dotnet/Empty/Empty.Tests.cs
diff --git a/tests/Empty/Empty.cpp b/tests/dotnet/Empty/Empty.cpp
similarity index 100%
rename from tests/Empty/Empty.cpp
rename to tests/dotnet/Empty/Empty.cpp
diff --git a/tests/Empty/Empty.h b/tests/dotnet/Empty/Empty.h
similarity index 100%
rename from tests/Empty/Empty.h
rename to tests/dotnet/Empty/Empty.h
diff --git a/tests/Empty/premake4.lua b/tests/dotnet/Empty/premake4.lua
similarity index 100%
rename from tests/Empty/premake4.lua
rename to tests/dotnet/Empty/premake4.lua
diff --git a/tests/Encodings/Encodings.CSharp.csproj b/tests/dotnet/Encodings/Encodings.CSharp.csproj
similarity index 100%
rename from tests/Encodings/Encodings.CSharp.csproj
rename to tests/dotnet/Encodings/Encodings.CSharp.csproj
diff --git a/tests/Encodings/Encodings.Gen.cs b/tests/dotnet/Encodings/Encodings.Gen.cs
similarity index 100%
rename from tests/Encodings/Encodings.Gen.cs
rename to tests/dotnet/Encodings/Encodings.Gen.cs
diff --git a/tests/Encodings/Encodings.Gen.csproj b/tests/dotnet/Encodings/Encodings.Gen.csproj
similarity index 100%
rename from tests/Encodings/Encodings.Gen.csproj
rename to tests/dotnet/Encodings/Encodings.Gen.csproj
diff --git a/tests/Encodings/Encodings.Tests.CSharp.csproj b/tests/dotnet/Encodings/Encodings.Tests.CSharp.csproj
similarity index 100%
rename from tests/Encodings/Encodings.Tests.CSharp.csproj
rename to tests/dotnet/Encodings/Encodings.Tests.CSharp.csproj
diff --git a/tests/Encodings/Encodings.Tests.cs b/tests/dotnet/Encodings/Encodings.Tests.cs
similarity index 100%
rename from tests/Encodings/Encodings.Tests.cs
rename to tests/dotnet/Encodings/Encodings.Tests.cs
diff --git a/tests/Encodings/Encodings.cpp b/tests/dotnet/Encodings/Encodings.cpp
similarity index 100%
rename from tests/Encodings/Encodings.cpp
rename to tests/dotnet/Encodings/Encodings.cpp
diff --git a/tests/Encodings/Encodings.h b/tests/dotnet/Encodings/Encodings.h
similarity index 100%
rename from tests/Encodings/Encodings.h
rename to tests/dotnet/Encodings/Encodings.h
diff --git a/tests/Encodings/premake4.lua b/tests/dotnet/Encodings/premake4.lua
similarity index 100%
rename from tests/Encodings/premake4.lua
rename to tests/dotnet/Encodings/premake4.lua
diff --git a/tests/NamespacesBase/NamespacesBase.cpp b/tests/dotnet/NamespacesBase/NamespacesBase.cpp
similarity index 100%
rename from tests/NamespacesBase/NamespacesBase.cpp
rename to tests/dotnet/NamespacesBase/NamespacesBase.cpp
diff --git a/tests/NamespacesBase/NamespacesBase.h b/tests/dotnet/NamespacesBase/NamespacesBase.h
similarity index 100%
rename from tests/NamespacesBase/NamespacesBase.h
rename to tests/dotnet/NamespacesBase/NamespacesBase.h
diff --git a/tests/dotnet/NamespacesBase/premake4.lua b/tests/dotnet/NamespacesBase/premake4.lua
new file mode 100644
index 0000000000..632b1083a9
--- /dev/null
+++ b/tests/dotnet/NamespacesBase/premake4.lua
@@ -0,0 +1,3 @@
+group "Tests/Namespaces"
+ SetupTestNativeProject("NamespacesBase")
+ targetdir (path.join(gendir, "NamespacesDerived"))
\ No newline at end of file
diff --git a/tests/NamespacesBase/test.cs b/tests/dotnet/NamespacesBase/test.cs
similarity index 100%
rename from tests/NamespacesBase/test.cs
rename to tests/dotnet/NamespacesBase/test.cs
diff --git a/tests/NamespacesDerived/Independent.h b/tests/dotnet/NamespacesDerived/Independent.h
similarity index 100%
rename from tests/NamespacesDerived/Independent.h
rename to tests/dotnet/NamespacesDerived/Independent.h
diff --git a/tests/NamespacesDerived/NamespacesDerived.Gen.cs b/tests/dotnet/NamespacesDerived/NamespacesDerived.Gen.cs
similarity index 100%
rename from tests/NamespacesDerived/NamespacesDerived.Gen.cs
rename to tests/dotnet/NamespacesDerived/NamespacesDerived.Gen.cs
diff --git a/tests/NamespacesDerived/NamespacesDerived.Gen.csproj b/tests/dotnet/NamespacesDerived/NamespacesDerived.Gen.csproj
similarity index 100%
rename from tests/NamespacesDerived/NamespacesDerived.Gen.csproj
rename to tests/dotnet/NamespacesDerived/NamespacesDerived.Gen.csproj
diff --git a/tests/NamespacesDerived/NamespacesDerived.Tests.CSharp.csproj b/tests/dotnet/NamespacesDerived/NamespacesDerived.Tests.CSharp.csproj
similarity index 65%
rename from tests/NamespacesDerived/NamespacesDerived.Tests.CSharp.csproj
rename to tests/dotnet/NamespacesDerived/NamespacesDerived.Tests.CSharp.csproj
index b6509a70d3..d1aefe5089 100644
--- a/tests/NamespacesDerived/NamespacesDerived.Tests.CSharp.csproj
+++ b/tests/dotnet/NamespacesDerived/NamespacesDerived.Tests.CSharp.csproj
@@ -4,10 +4,10 @@
- ..\..\build\gen\NamespacesDerived\NamespacesBase.dll
+ ..\..\..\build\gen\NamespacesDerived\NamespacesBase.dll
- ..\..\build\gen\NamespacesDerived\NamespacesDerived.dll
+ ..\..\..\build\gen\NamespacesDerived\NamespacesDerived.dll
\ No newline at end of file
diff --git a/tests/NamespacesDerived/NamespacesDerived.Tests.cs b/tests/dotnet/NamespacesDerived/NamespacesDerived.Tests.cs
similarity index 100%
rename from tests/NamespacesDerived/NamespacesDerived.Tests.cs
rename to tests/dotnet/NamespacesDerived/NamespacesDerived.Tests.cs
diff --git a/tests/NamespacesDerived/NamespacesDerived.cpp b/tests/dotnet/NamespacesDerived/NamespacesDerived.cpp
similarity index 100%
rename from tests/NamespacesDerived/NamespacesDerived.cpp
rename to tests/dotnet/NamespacesDerived/NamespacesDerived.cpp
diff --git a/tests/NamespacesDerived/NamespacesDerived.h b/tests/dotnet/NamespacesDerived/NamespacesDerived.h
similarity index 100%
rename from tests/NamespacesDerived/NamespacesDerived.h
rename to tests/dotnet/NamespacesDerived/NamespacesDerived.h
diff --git a/tests/NamespacesDerived/premake4.lua b/tests/dotnet/NamespacesDerived/premake4.lua
similarity index 100%
rename from tests/NamespacesDerived/premake4.lua
rename to tests/dotnet/NamespacesDerived/premake4.lua
diff --git a/tests/Native/AST.h b/tests/dotnet/Native/AST.h
similarity index 100%
rename from tests/Native/AST.h
rename to tests/dotnet/Native/AST.h
diff --git a/tests/Native/ASTExtensions.h b/tests/dotnet/Native/ASTExtensions.h
similarity index 100%
rename from tests/Native/ASTExtensions.h
rename to tests/dotnet/Native/ASTExtensions.h
diff --git a/tests/Native/Enums.h b/tests/dotnet/Native/Enums.h
similarity index 100%
rename from tests/Native/Enums.h
rename to tests/dotnet/Native/Enums.h
diff --git a/tests/Native/Passes.h b/tests/dotnet/Native/Passes.h
similarity index 100%
rename from tests/Native/Passes.h
rename to tests/dotnet/Native/Passes.h
diff --git a/tests/Native/Templates.h b/tests/dotnet/Native/Templates.h
similarity index 100%
rename from tests/Native/Templates.h
rename to tests/dotnet/Native/Templates.h
diff --git a/tests/Native/linux/libexpat.so.0 b/tests/dotnet/Native/linux/libexpat.so.0
similarity index 100%
rename from tests/Native/linux/libexpat.so.0
rename to tests/dotnet/Native/linux/libexpat.so.0
diff --git a/tests/Native/macos/libexpat.dylib b/tests/dotnet/Native/macos/libexpat.dylib
similarity index 100%
rename from tests/Native/macos/libexpat.dylib
rename to tests/dotnet/Native/macos/libexpat.dylib
diff --git a/tests/Native/windows/libexpat.dll b/tests/dotnet/Native/windows/libexpat.dll
similarity index 100%
rename from tests/Native/windows/libexpat.dll
rename to tests/dotnet/Native/windows/libexpat.dll
diff --git a/tests/StandardLib/StandardLib.Gen.cs b/tests/dotnet/StandardLib/StandardLib.Gen.cs
similarity index 100%
rename from tests/StandardLib/StandardLib.Gen.cs
rename to tests/dotnet/StandardLib/StandardLib.Gen.cs
diff --git a/tests/StandardLib/StandardLib.Gen.csproj b/tests/dotnet/StandardLib/StandardLib.Gen.csproj
similarity index 100%
rename from tests/StandardLib/StandardLib.Gen.csproj
rename to tests/dotnet/StandardLib/StandardLib.Gen.csproj
diff --git a/tests/StandardLib/StandardLib.Tests.CLI.csproj b/tests/dotnet/StandardLib/StandardLib.Tests.CLI.csproj
similarity index 100%
rename from tests/StandardLib/StandardLib.Tests.CLI.csproj
rename to tests/dotnet/StandardLib/StandardLib.Tests.CLI.csproj
diff --git a/tests/StandardLib/StandardLib.Tests.cs b/tests/dotnet/StandardLib/StandardLib.Tests.cs
similarity index 100%
rename from tests/StandardLib/StandardLib.Tests.cs
rename to tests/dotnet/StandardLib/StandardLib.Tests.cs
diff --git a/tests/StandardLib/StandardLib.cpp b/tests/dotnet/StandardLib/StandardLib.cpp
similarity index 100%
rename from tests/StandardLib/StandardLib.cpp
rename to tests/dotnet/StandardLib/StandardLib.cpp
diff --git a/tests/StandardLib/StandardLib.h b/tests/dotnet/StandardLib/StandardLib.h
similarity index 100%
rename from tests/StandardLib/StandardLib.h
rename to tests/dotnet/StandardLib/StandardLib.h
diff --git a/tests/StandardLib/premake4.lua b/tests/dotnet/StandardLib/premake4.lua
similarity index 100%
rename from tests/StandardLib/premake4.lua
rename to tests/dotnet/StandardLib/premake4.lua
diff --git a/tests/Test.Bindings.props b/tests/dotnet/Test.Bindings.props
similarity index 100%
rename from tests/Test.Bindings.props
rename to tests/dotnet/Test.Bindings.props
diff --git a/tests/Test.Common.props b/tests/dotnet/Test.Common.props
similarity index 100%
rename from tests/Test.Common.props
rename to tests/dotnet/Test.Common.props
diff --git a/tests/Test.Generator.props b/tests/dotnet/Test.Generator.props
similarity index 100%
rename from tests/Test.Generator.props
rename to tests/dotnet/Test.Generator.props
diff --git a/tests/Test.props b/tests/dotnet/Test.props
similarity index 100%
rename from tests/Test.props
rename to tests/dotnet/Test.props
diff --git a/tests/Tests.h b/tests/dotnet/Tests.h
similarity index 100%
rename from tests/Tests.h
rename to tests/dotnet/Tests.h
diff --git a/tests/VTables/VTables.CSharp.csproj b/tests/dotnet/VTables/VTables.CSharp.csproj
similarity index 100%
rename from tests/VTables/VTables.CSharp.csproj
rename to tests/dotnet/VTables/VTables.CSharp.csproj
diff --git a/tests/VTables/VTables.Gen.cs b/tests/dotnet/VTables/VTables.Gen.cs
similarity index 100%
rename from tests/VTables/VTables.Gen.cs
rename to tests/dotnet/VTables/VTables.Gen.cs
diff --git a/tests/VTables/VTables.Gen.csproj b/tests/dotnet/VTables/VTables.Gen.csproj
similarity index 100%
rename from tests/VTables/VTables.Gen.csproj
rename to tests/dotnet/VTables/VTables.Gen.csproj
diff --git a/tests/VTables/VTables.Tests.CSharp.csproj b/tests/dotnet/VTables/VTables.Tests.CSharp.csproj
similarity index 100%
rename from tests/VTables/VTables.Tests.CSharp.csproj
rename to tests/dotnet/VTables/VTables.Tests.CSharp.csproj
diff --git a/tests/VTables/VTables.Tests.cs b/tests/dotnet/VTables/VTables.Tests.cs
similarity index 100%
rename from tests/VTables/VTables.Tests.cs
rename to tests/dotnet/VTables/VTables.Tests.cs
diff --git a/tests/VTables/VTables.cpp b/tests/dotnet/VTables/VTables.cpp
similarity index 100%
rename from tests/VTables/VTables.cpp
rename to tests/dotnet/VTables/VTables.cpp
diff --git a/tests/VTables/VTables.h b/tests/dotnet/VTables/VTables.h
similarity index 100%
rename from tests/VTables/VTables.h
rename to tests/dotnet/VTables/VTables.h
diff --git a/tests/VTables/premake4.lua b/tests/dotnet/VTables/premake4.lua
similarity index 100%
rename from tests/VTables/premake4.lua
rename to tests/dotnet/VTables/premake4.lua
diff --git a/tests2/quickjs/.gitignore b/tests/emscripten/.gitignore
similarity index 100%
rename from tests2/quickjs/.gitignore
rename to tests/emscripten/.gitignore
diff --git a/tests/emscripten/premake5.lua b/tests/emscripten/premake5.lua
new file mode 100644
index 0000000000..8fa7a73885
--- /dev/null
+++ b/tests/emscripten/premake5.lua
@@ -0,0 +1,21 @@
+
+workspace "emscripten"
+ configurations { "debug", "release" }
+ location "gen"
+ symbols "On"
+ optimize "Off"
+
+ project "test"
+ kind "SharedLib"
+ language "C++"
+ files
+ {
+ "gen/**.cpp",
+ }
+ includedirs
+ {
+ "..",
+ "../../include"
+ }
+ linkoptions { "--bind -sENVIRONMENT=node -sMODULARIZE=1 -sEXPORT_ALL -sEXPORT_ES6=1 -sUSE_ES6_IMPORT_META=1" }
+ targetextension ".mjs"
\ No newline at end of file
diff --git a/tests/emscripten/test.mjs b/tests/emscripten/test.mjs
new file mode 100644
index 0000000000..95b8b0bf0b
--- /dev/null
+++ b/tests/emscripten/test.mjs
@@ -0,0 +1,114 @@
+import wasmModule from "./gen/bin/debug/libtest.mjs";
+import { eq, ascii, floateq } from "./utils.mjs"
+
+const test = await wasmModule({
+ onRuntimeInitialized() {
+
+ }
+});
+
+function builtins() {
+ eq(test.ReturnsVoid(), undefined)
+
+ eq(test.ReturnsBool(), true)
+ eq(test.PassAndReturnsBool(false), false)
+
+ eq(test.ReturnsNullptr(), null)
+ eq(test.PassAndReturnsNullptr(null), null)
+
+ eq(test.ReturnsChar(), ascii('a'));
+ eq(test.ReturnsSChar(), ascii('a'));
+ eq(test.ReturnsUChar(), ascii('a'));
+
+ eq(test.PassAndReturnsChar(ascii('a')), ascii('a'));
+ eq(test.PassAndReturnsSChar(ascii('b')), ascii('b'));
+ eq(test.PassAndReturnsUChar(ascii('c')), ascii('c'));
+
+ // TODO: add wchar_t tests
+
+ eq(test.ReturnsFloat(), 5.0);
+ eq(test.ReturnsDouble(), -5.0);
+ //eq(test.ReturnsLongDouble(), -5.0);
+
+ floateq(test.PassAndReturnsFloat(1.32), 1.32);
+ floateq(test.PassAndReturnsDouble(1.32), 1.32);
+ //float(test.PassAndReturnsLongDouble(1.32), 1.32);
+
+ eq(test.ReturnsInt8(), -5);
+ eq(test.ReturnsUInt8(), 5);
+ eq(test.ReturnsInt16(), -5);
+ eq(test.ReturnsUInt16(), 5);
+ eq(test.ReturnsInt32(), -5);
+ eq(test.ReturnsUInt32(), 5);
+
+ // TODO:
+ // https://github.com/WebAssembly/proposals/issues/7
+ // https://github.com/emscripten-core/emscripten/issues/11140
+ //eq(test.ReturnsInt64(), -5n);
+ //eq(test.ReturnsUInt64(), 5n);
+
+ const int8 = { min: -(2 ** 7), max: (2 ** 7) - 1 };
+ eq(test.PassAndReturnsInt8(int8.min), int8.min);
+ eq(test.PassAndReturnsInt8(int8.max), int8.max);
+
+ const uint8 = { min: 0, max: (2 ** 8) - 1 };
+ eq(test.PassAndReturnsUInt8(uint8.min), uint8.min);
+ eq(test.PassAndReturnsUInt8(uint8.max), uint8.max);
+
+ const int16 = { min: -(2 ** 15), max: (2 ** 15) - 1 };
+ eq(test.PassAndReturnsInt16(int16.min), int16.min);
+ eq(test.PassAndReturnsInt16(int16.max), int16.max);
+
+ const uint16 = { min: 0, max: (2 ** 16) - 1 };
+ eq(test.PassAndReturnsUInt16(uint16.min), uint16.min);
+ eq(test.PassAndReturnsUInt16(uint16.max), uint16.max);
+
+ const int32 = { min: -(2 ** 31), max: (2 ** 31) - 1 };
+ eq(test.PassAndReturnsInt32(int32.min), int32.min);
+ eq(test.PassAndReturnsInt32(int32.max), int32.max);
+
+ const uint32 = { min: 0, max: (2 ** 32) - 1 };
+ eq(test.PassAndReturnsUInt32(uint32.min), uint32.min);
+ eq(test.PassAndReturnsUInt32(uint32.max), uint32.max);
+
+ //const int64 = { min: BigInt(2 ** 63) * -1n, max: BigInt(2 ** 63) - 1n };
+ //eq(test.PassAndReturnsInt64(int64.min), int64.min);
+ //eq(test.PassAndReturnsInt64(int64.max), int64.max);
+
+ //const uint64 = { min: BigInt(0), max: BigInt(2 ** 64) - 1n };
+ //eq(test.PassAndReturnsUInt64(uint64.min), uint64.min);
+ //eq(test.PassAndReturnsUInt64(uint64.max), uint64.max);
+}
+
+function enums() {
+ eq(test.Enum0.Item0.value, 0);
+ eq(test.Enum0.Item1.value, 1);
+ eq(test.Enum0.Item2.value, 5);
+
+ eq(test.ReturnsEnum(), test.Enum0.Item0);
+ eq(test.PassAndReturnsEnum(test.Enum0.Item1), test.Enum0.Item1);
+}
+
+function classes() {
+ var c = new test.Class();
+ eq(typeof (c), "object")
+ eq(c.ReturnsVoid(), undefined)
+ eq(c.ReturnsInt(), 0)
+ eq(c.PassAndReturnsClassPtr(null), null)
+
+ var c1 = new test.ClassWithSingleInheritance();
+ eq(c1.__proto__.constructor.name, 'ClassWithSingleInheritance')
+ eq(c1.__proto__.__proto__.constructor.name, 'Class')
+ eq(c1.ReturnsVoid(), undefined);
+ eq(c1.ReturnsInt(), 0);
+ eq(c1.ChildMethod(), 2);
+
+ var classWithField = new test.ClassWithField();
+ eq(classWithField.ReturnsField(), 10);
+ eq(classWithField.Field, 10);
+}
+
+
+builtins();
+enums();
+classes();
\ No newline at end of file
diff --git a/tests/emscripten/test.sh b/tests/emscripten/test.sh
new file mode 100755
index 0000000000..52807e87dd
--- /dev/null
+++ b/tests/emscripten/test.sh
@@ -0,0 +1,30 @@
+#!/usr/bin/env bash
+set -e
+dir=$(cd "$(dirname "$0")"; pwd)
+rootdir="$dir/../.."
+dotnet_configuration=Release
+configuration=debug
+platform=x64
+jsinterp=node
+
+red=`tput setaf 1`
+green=`tput setaf 2`
+reset=`tput sgr0`
+
+generate=true
+
+if [ $generate = true ]; then
+ echo "${green}Generating bindings${reset}"
+ dotnet $rootdir/bin/${dotnet_configuration}_${platform}/CppSharp.CLI.dll \
+ --gen=emscripten --platform=emscripten --arch=wasm32 \
+ -I$dir/.. -I$rootdir/include -o $dir/gen -m tests $dir/../*.h
+fi
+
+echo "${green}Building generated binding files${reset}"
+premake=$rootdir/build/premake.sh
+config=$configuration $premake --file=$dir/premake5.lua gmake
+emmake make -C $dir/gen
+echo
+
+echo "${green}Executing JS tests with Node${reset}"
+$jsinterp $dir/test.mjs
\ No newline at end of file
diff --git a/tests/emscripten/utils.mjs b/tests/emscripten/utils.mjs
new file mode 100644
index 0000000000..fb0eb6c73d
--- /dev/null
+++ b/tests/emscripten/utils.mjs
@@ -0,0 +1,21 @@
+export function assert(actual, expected, message) {
+ if (arguments.length == 1)
+ expected = true;
+
+ if (actual === expected)
+ return;
+
+ if (actual !== null && expected !== null
+ && typeof actual == 'object' && typeof expected == 'object'
+ && actual.toString() === expected.toString())
+ return;
+
+ throw Error("assertion failed: got |" + actual + "|" +
+ ", expected |" + expected + "|" +
+ (message ? " (" + message + ")" : ""));
+}
+
+export const eq = assert;
+export const floateq = (actual, expected) => { assert(Math.abs(actual - expected) < 0.01) }
+
+export const ascii = v => v.charCodeAt(0)
diff --git a/tests2/napi/.gitignore b/tests/napi/.gitignore
similarity index 100%
rename from tests2/napi/.gitignore
rename to tests/napi/.gitignore
diff --git a/tests2/napi/premake5.lua b/tests/napi/premake5.lua
similarity index 100%
rename from tests2/napi/premake5.lua
rename to tests/napi/premake5.lua
diff --git a/tests2/napi/test.js b/tests/napi/test.js
similarity index 100%
rename from tests2/napi/test.js
rename to tests/napi/test.js
diff --git a/tests2/napi/test.sh b/tests/napi/test.sh
similarity index 100%
rename from tests2/napi/test.sh
rename to tests/napi/test.sh
diff --git a/tests/quickjs/.gitignore b/tests/quickjs/.gitignore
new file mode 100644
index 0000000000..36316b019c
--- /dev/null
+++ b/tests/quickjs/.gitignore
@@ -0,0 +1,4 @@
+gen
+*.so
+*.dylib
+*.dll
diff --git a/tests2/quickjs/premake5.lua b/tests/quickjs/premake5.lua
similarity index 100%
rename from tests2/quickjs/premake5.lua
rename to tests/quickjs/premake5.lua
diff --git a/tests2/quickjs/test-prop.js b/tests/quickjs/test-prop.js
similarity index 100%
rename from tests2/quickjs/test-prop.js
rename to tests/quickjs/test-prop.js
diff --git a/tests2/quickjs/test.js b/tests/quickjs/test.js
similarity index 100%
rename from tests2/quickjs/test.js
rename to tests/quickjs/test.js
diff --git a/tests2/quickjs/test.sh b/tests/quickjs/test.sh
similarity index 100%
rename from tests2/quickjs/test.sh
rename to tests/quickjs/test.sh
diff --git a/tests2/test.sh b/tests/test.sh
similarity index 80%
rename from tests2/test.sh
rename to tests/test.sh
index 622401efcf..f5abc712b9 100755
--- a/tests2/test.sh
+++ b/tests/test.sh
@@ -4,3 +4,4 @@ dir=$(cd "$(dirname "$0")"; pwd)
$dir/napi/test.sh
$dir/quickjs/test.sh
+$dir/emscripten/test.sh
diff --git a/tests2/ts/.gitignore b/tests/ts/.gitignore
similarity index 100%
rename from tests2/ts/.gitignore
rename to tests/ts/.gitignore
diff --git a/tests2/ts/test.sh b/tests/ts/test.sh
similarity index 100%
rename from tests2/ts/test.sh
rename to tests/ts/test.sh
diff --git a/tests2/ts/test.ts b/tests/ts/test.ts
similarity index 100%
rename from tests2/ts/test.ts
rename to tests/ts/test.ts
diff --git a/tests2/ts/tsconfig.json b/tests/ts/tsconfig.json
similarity index 100%
rename from tests2/ts/tsconfig.json
rename to tests/ts/tsconfig.json