Browse Source

Code cleanup and some optimizations (#1911)

* Code cleanup

* Run symbol conversion in parallel

* Fix build error in p/invoke move

* Fix debug compile

* Address review comments
pull/1888/head
Jelle 4 months ago committed by GitHub
parent
commit
f0b44b4421
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 43
      src/AST/Class.cs
  2. 30
      src/AST/DeclarationsList.cs
  3. 14
      src/AST/Namespace.cs
  4. 14
      src/AST/SymbolContext.cs
  5. 55
      src/Core/Platform.cs
  6. 2
      src/CppParser/AST.cpp
  7. 12
      src/CppParser/ASTNameMangler.cpp
  8. 8
      src/CppParser/ASTNameMangler.h
  9. 8
      src/CppParser/Bindings/CSharp/i686-pc-win32-msvc-d/CppSharp.CppParser.cs
  10. 8
      src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/CppSharp.CppParser.cs
  11. 4
      src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc-d/CppSharp.CppParser.cs
  12. 4
      src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/CppSharp.CppParser.cs
  13. 3
      src/CppParser/Comments.cpp
  14. 14
      src/CppParser/CppParser.cpp
  15. 24
      src/CppParser/CppParser.h
  16. 2
      src/CppParser/Decl.h
  17. 5
      src/CppParser/ParseExpr.cpp
  18. 375
      src/CppParser/Parser.cpp
  19. 133
      src/CppParser/Parser.h
  20. 34
      src/Generator/Generators/CLI/CLITypeReferences.cs
  21. 9
      src/Generator/Generators/CSharp/CSharpSources.cs
  22. 2
      src/Generator/Passes/FindSymbolsPass.cs
  23. 135
      src/Generator/Passes/GenerateSymbolsPass.cs
  24. 35
      src/Generator/Passes/StripUnusedSystemTypesPass.cs
  25. 11
      src/Parser/ParserOptions.cs
  26. 6
      tests/dotnet/Common/Common.h

43
src/AST/Class.cs

@ -74,31 +74,31 @@ namespace CppSharp.AST @@ -74,31 +74,31 @@ namespace CppSharp.AST
// Represents a C++ record decl.
public class Class : DeclarationContext
{
public List<BaseClassSpecifier> Bases;
public List<Field> Fields;
public List<Property> Properties;
public List<Method> Methods;
public List<AccessSpecifierDecl> Specifiers;
public List<BaseClassSpecifier> Bases = new();
public List<Field> Fields = new();
public List<Property> Properties = new();
public List<Method> Methods = new();
public List<AccessSpecifierDecl> Specifiers = new();
// True if the record is a POD (Plain Old Data) type.
public bool IsPOD;
public bool IsPOD = false;
// Semantic type of the class.
public ClassType Type;
public ClassType Type = ClassType.RefType;
// ABI-specific class layout.
public ClassLayout Layout;
public ClassLayout Layout = new();
// True if class provides pure virtual methods.
public bool IsAbstract;
public bool IsAbstract = false;
// True if the type is to be treated as a union.
public bool IsUnion;
public bool IsUnion = false;
public TagKind TagKind { get; set; }
// True if the class is final / sealed.
public bool IsFinal { get; set; }
public bool IsFinal { get; set; } = false;
private bool? isOpaque;
@ -129,23 +129,6 @@ namespace CppSharp.AST @@ -129,23 +129,6 @@ namespace CppSharp.AST
// True if the class represents a static class.
public bool IsStatic;
public Class()
{
Bases = new List<BaseClassSpecifier>();
Fields = new List<Field>();
Properties = new List<Property>();
Methods = new List<Method>();
Specifiers = new List<AccessSpecifierDecl>();
IsAbstract = false;
IsUnion = false;
IsFinal = false;
IsPOD = false;
Type = ClassType.RefType;
Layout = new ClassLayout();
templateParameters = new List<Declaration>();
specializations = new List<ClassTemplateSpecialization>();
}
public bool HasBase => Bases.Count > 0;
public bool HasBaseClass => BaseClass != null;
@ -296,7 +279,7 @@ namespace CppSharp.AST @@ -296,7 +279,7 @@ namespace CppSharp.AST
return visitor.VisitClassDecl(this);
}
private List<Declaration> templateParameters;
private List<ClassTemplateSpecialization> specializations;
private readonly List<Declaration> templateParameters = new();
private readonly List<ClassTemplateSpecialization> specializations = new();
}
}

30
src/AST/DeclarationsList.cs

@ -59,7 +59,10 @@ namespace CppSharp.AST @@ -59,7 +59,10 @@ namespace CppSharp.AST
base.RemoveItem(index);
for (var i = Kind.Namespace; i <= Kind.Event; i++)
{
if (offsets.ContainsKey(i) && index < offsets[i])
if (!offsets.TryGetValue(i, out int start))
continue;
if (index < start)
{
offsets[i]--;
}
@ -74,12 +77,11 @@ namespace CppSharp.AST @@ -74,12 +77,11 @@ namespace CppSharp.AST
private IEnumerable<T> OfType<T>(Kind kind) where T : Declaration
{
if (!offsets.ContainsKey(kind))
if (!offsets.TryGetValue(kind, out var offset))
{
yield break;
}
var offset = offsets[kind];
for (var i = GetStart(kind); i < offset; i++)
{
yield return (T)this[i];
@ -105,28 +107,30 @@ namespace CppSharp.AST @@ -105,28 +107,30 @@ namespace CppSharp.AST
private int GetOffset(Kind kind)
{
if (offsets.ContainsKey(kind))
return offsets[kind];
if (offsets.TryGetValue(kind, out int o))
return o;
// First time we see this kind of declaration. Insert it between the previous and next kinds.
for (var i = kind - 1; i >= Kind.Namespace; i--)
{
if (offsets.ContainsKey(i))
{
return offsets[kind] = offsets[i];
}
if (!offsets.TryGetValue(i, out var start))
continue;
offsets[kind] = start;
return start;
}
offsets[kind] = 0;
return offsets[kind];
return 0;
}
private int GetStart(Kind kind)
{
for (var i = kind - 1; i >= Kind.Namespace; i--)
{
if (offsets.ContainsKey(i))
if (offsets.TryGetValue(i, out var start))
{
return offsets[i];
return start;
}
}
return 0;
@ -154,7 +158,7 @@ namespace CppSharp.AST @@ -154,7 +158,7 @@ namespace CppSharp.AST
return middle;
}
private Dictionary<Kind, int> offsets = new Dictionary<Kind, int>();
private readonly Dictionary<Kind, int> offsets = new();
private enum Kind
{

14
src/AST/Namespace.cs

@ -36,15 +36,9 @@ namespace CppSharp.AST @@ -36,15 +36,9 @@ namespace CppSharp.AST
// True if the context is inside an extern "C" context.
public bool IsExternCContext;
public override string LogicalName
{
get { return IsAnonymous ? "<anonymous>" : base.Name; }
}
public override string LogicalName => IsAnonymous ? "<anonymous>" : base.Name;
public override string LogicalOriginalName
{
get { return IsAnonymous ? "<anonymous>" : base.OriginalName; }
}
public override string LogicalOriginalName => IsAnonymous ? "<anonymous>" : base.OriginalName;
protected DeclarationContext()
{
@ -80,7 +74,7 @@ namespace CppSharp.AST @@ -80,7 +74,7 @@ namespace CppSharp.AST
public Declaration FindAnonymous(ulong key)
{
return Anonymous.ContainsKey(key) ? Anonymous[key] : null;
return Anonymous.GetValueOrDefault(key);
}
public Namespace FindNamespace(string name)
@ -172,7 +166,7 @@ namespace CppSharp.AST @@ -172,7 +166,7 @@ namespace CppSharp.AST
{
var functions = Functions.Where(e => e.Name.Equals(name));
if (!functions.Any() && createDecl)
if (createDecl && !functions.Any())
{
var function = new Function() { Name = name, Namespace = this };
Declarations.Add(function);

14
src/AST/SymbolContext.cs

@ -80,14 +80,12 @@ namespace CppSharp.AST @@ -80,14 +80,12 @@ namespace CppSharp.AST
{
foreach (var symbol in library.Symbols)
{
if (!Symbols.ContainsKey(symbol))
Symbols[symbol] = library;
if (symbol.StartsWith("__", StringComparison.Ordinal))
{
string stripped = symbol.Substring(1);
if (!Symbols.ContainsKey(stripped))
Symbols[stripped] = library;
}
Symbols.TryAdd(symbol, library);
if (!symbol.StartsWith("__", StringComparison.Ordinal))
continue;
Symbols.TryAdd(symbol[1..], library);
}
}
}

55
src/Core/Platform.cs

@ -17,29 +17,19 @@ namespace CppSharp @@ -17,29 +17,19 @@ namespace CppSharp
public static class Platform
{
public static bool IsWindows
{
get
{
switch (Environment.OSVersion.Platform)
{
case PlatformID.Win32NT:
case PlatformID.Win32S:
case PlatformID.Win32Windows:
case PlatformID.WinCE:
return true;
}
public static bool IsWindows =>
Environment.OSVersion.Platform switch
{
PlatformID.Win32NT => true,
PlatformID.Win32S => true,
PlatformID.Win32Windows => true,
PlatformID.WinCE => true,
_ => false
};
return false;
}
}
[DllImport("libc")]
static extern int uname(IntPtr buf);
public static bool IsMacOS { get; } = GetIsMacOS();
public static bool IsMacOS
{
get
private static bool GetIsMacOS()
{
if (Environment.OSVersion.Platform != PlatformID.Unix)
return false;
@ -57,31 +47,27 @@ namespace CppSharp @@ -57,31 +47,27 @@ namespace CppSharp
Marshal.FreeHGlobal(buf);
return false;
}
}
public static bool IsLinux
{
get { return Environment.OSVersion.Platform == PlatformID.Unix && !IsMacOS; }
[DllImport("libc")]
static extern int uname(IntPtr buf);
}
public static bool IsMono
{
get { return Type.GetType("Mono.Runtime") != null; }
}
public static bool IsLinux => Environment.OSVersion.Platform == PlatformID.Unix && !IsMacOS;
public static bool IsMono => Type.GetType("Mono.Runtime") != null;
public static bool IsUnixPlatform
{
get
{
var platform = Environment.OSVersion.Platform;
return platform == PlatformID.Unix || platform == PlatformID.MacOSX;
return platform is PlatformID.Unix or PlatformID.MacOSX;
}
}
public static TargetPlatform Host
{
get
public static TargetPlatform Host { get; } = GetHostPlatform();
private static TargetPlatform GetHostPlatform()
{
if (IsWindows)
return TargetPlatform.Windows;
@ -96,4 +82,3 @@ namespace CppSharp @@ -96,4 +82,3 @@ namespace CppSharp
}
}
}
}

2
src/CppParser/AST.cpp

@ -935,7 +935,7 @@ ASTContext::ASTContext() {} @@ -935,7 +935,7 @@ ASTContext::ASTContext() {}
ASTContext::~ASTContext() {}
TranslationUnit* ASTContext::FindOrCreateModule(std::string File)
TranslationUnit* ASTContext::FindOrCreateModule(const std::string& File)
{
auto normalizedFile = normalizePath(File);

12
src/CppParser/ASTNameMangler.cpp

@ -40,7 +40,7 @@ ASTNameMangler::ASTNameMangler(ASTContext& Ctx) @@ -40,7 +40,7 @@ ASTNameMangler::ASTNameMangler(ASTContext& Ctx)
{
}
std::string ASTNameMangler::GetName(const Decl* D) {
std::string ASTNameMangler::GetName(const Decl* D) const {
std::string Name;
{
llvm::raw_string_ostream OS(Name);
@ -49,8 +49,7 @@ std::string ASTNameMangler::GetName(const Decl* D) { @@ -49,8 +49,7 @@ std::string ASTNameMangler::GetName(const Decl* D) {
return Name;
}
bool ASTNameMangler::WriteName(const Decl* D, raw_ostream& OS) {
// First apply frontend mangling.
bool ASTNameMangler::WriteName(const Decl* D, raw_ostream& OS) const {
if (auto* FD = dyn_cast<FunctionDecl>(D)) {
if (FD->isDependentContext())
return true;
@ -62,8 +61,7 @@ bool ASTNameMangler::WriteName(const Decl* D, raw_ostream& OS) { @@ -62,8 +61,7 @@ bool ASTNameMangler::WriteName(const Decl* D, raw_ostream& OS) {
return true;
}
else if (auto* MD = dyn_cast<ObjCMethodDecl>(D)) {
MC->mangleObjCMethodName(MD, OS, /*includePrefixByte=*/false,
/*includeCategoryNamespace=*/true);
MC->mangleObjCMethodName(MD, OS, /*includePrefixByte=*/false, /*includeCategoryNamespace=*/true);
return false;
}
else if (auto* ID = dyn_cast<ObjCInterfaceDecl>(D)) {
@ -76,7 +74,7 @@ bool ASTNameMangler::WriteName(const Decl* D, raw_ostream& OS) { @@ -76,7 +74,7 @@ bool ASTNameMangler::WriteName(const Decl* D, raw_ostream& OS) {
return false;
}
std::string ASTNameMangler::GetMangledStructor(const NamedDecl* ND, unsigned StructorType) {
std::string ASTNameMangler::GetMangledStructor(const NamedDecl* ND, unsigned StructorType) const {
std::string FrontendBuf;
llvm::raw_string_ostream FOS(FrontendBuf);
@ -90,7 +88,7 @@ std::string ASTNameMangler::GetMangledStructor(const NamedDecl* ND, unsigned Str @@ -90,7 +88,7 @@ std::string ASTNameMangler::GetMangledStructor(const NamedDecl* ND, unsigned Str
return FrontendBuf;
}
std::string ASTNameMangler::GetMangledThunk(const CXXMethodDecl* MD, const ThunkInfo& T, bool /*ElideOverrideInfo*/) {
std::string ASTNameMangler::GetMangledThunk(const CXXMethodDecl* MD, const ThunkInfo& T, bool /*ElideOverrideInfo*/) const {
std::string FrontendBuf;
llvm::raw_string_ostream FOS(FrontendBuf);

8
src/CppParser/ASTNameMangler.h

@ -35,12 +35,12 @@ class ASTNameMangler @@ -35,12 +35,12 @@ class ASTNameMangler
public:
explicit ASTNameMangler(clang::ASTContext& Ctx);
std::string GetName(const clang::Decl* D);
bool WriteName(const clang::Decl* D, llvm::raw_ostream& OS);
std::string GetName(const clang::Decl* D) const;
bool WriteName(const clang::Decl* D, llvm::raw_ostream& OS) const;
private:
std::string GetMangledStructor(const clang::NamedDecl* ND, unsigned StructorType);
std::string GetMangledThunk(const clang::CXXMethodDecl* MD, const clang::ThunkInfo& T, bool ElideOverrideInfo);
std::string GetMangledStructor(const clang::NamedDecl* ND, unsigned StructorType) const;
std::string GetMangledThunk(const clang::CXXMethodDecl* MD, const clang::ThunkInfo& T, bool ElideOverrideInfo) const;
bool WriteFuncOrVarName(const clang::NamedDecl* D, llvm::raw_ostream& OS) const;
llvm::DataLayout DL;

8
src/CppParser/Bindings/CSharp/i686-pc-win32-msvc-d/CppSharp.CppParser.cs

@ -15795,8 +15795,8 @@ namespace CppSharp @@ -15795,8 +15795,8 @@ namespace CppSharp
[SuppressUnmanagedCodeSecurity, DllImport("CppSharp.CppParser.dll", EntryPoint = "??1ASTContext@AST@CppParser@CppSharp@@QAE@XZ", CallingConvention = __CallingConvention.ThisCall)]
internal static extern void dtor(__IntPtr __instance);
[SuppressUnmanagedCodeSecurity, DllImport("CppSharp.CppParser.dll", EntryPoint = "?FindOrCreateModule@ASTContext@AST@CppParser@CppSharp@@QAEPAVTranslationUnit@234@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z", CallingConvention = __CallingConvention.ThisCall)]
internal static extern __IntPtr FindOrCreateModule(__IntPtr __instance, global::Std.BasicString.__Internalc__N_std_S_basic_string__C___N_std_S_char_traits__C___N_std_S_allocator__C File);
[SuppressUnmanagedCodeSecurity, DllImport("CppSharp.CppParser.dll", EntryPoint = "?FindOrCreateModule@ASTContext@AST@CppParser@CppSharp@@QAEPAVTranslationUnit@234@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z", CallingConvention = __CallingConvention.ThisCall)]
internal static extern __IntPtr FindOrCreateModule(__IntPtr __instance, __IntPtr File);
[SuppressUnmanagedCodeSecurity, DllImport("CppSharp.CppParser.dll", EntryPoint = "?getTranslationUnits@ASTContext@AST@CppParser@CppSharp@@QAEPAVTranslationUnit@234@I@Z", CallingConvention = __CallingConvention.ThisCall)]
internal static extern __IntPtr GetTranslationUnits(__IntPtr __instance, uint i);
@ -15917,9 +15917,9 @@ namespace CppSharp @@ -15917,9 +15917,9 @@ namespace CppSharp
{
var __basicString0 = new global::Std.BasicString<sbyte, global::Std.CharTraits<sbyte>, global::Std.Allocator<sbyte>>();
global::Std.BasicStringExtensions.Assign(__basicString0, File);
var __arg0 = *(global::Std.BasicString.__Internalc__N_std_S_basic_string__C___N_std_S_char_traits__C___N_std_S_allocator__C*) __basicString0.__Instance;
var __arg0 = __basicString0.__Instance;
var ___ret = __Internal.FindOrCreateModule(__Instance, __arg0);
__basicString0.Dispose(disposing: true, callNativeDtor:false);
__basicString0.Dispose();
var __result0 = global::CppSharp.Parser.AST.TranslationUnit.__GetOrCreateInstance(___ret, false);
return __result0;
}

8
src/CppParser/Bindings/CSharp/i686-pc-win32-msvc/CppSharp.CppParser.cs

@ -15795,8 +15795,8 @@ namespace CppSharp @@ -15795,8 +15795,8 @@ namespace CppSharp
[SuppressUnmanagedCodeSecurity, DllImport("CppSharp.CppParser.dll", EntryPoint = "??1ASTContext@AST@CppParser@CppSharp@@QAE@XZ", CallingConvention = __CallingConvention.ThisCall)]
internal static extern void dtor(__IntPtr __instance);
[SuppressUnmanagedCodeSecurity, DllImport("CppSharp.CppParser.dll", EntryPoint = "?FindOrCreateModule@ASTContext@AST@CppParser@CppSharp@@QAEPAVTranslationUnit@234@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z", CallingConvention = __CallingConvention.ThisCall)]
internal static extern __IntPtr FindOrCreateModule(__IntPtr __instance, global::Std.BasicString.__Internalc__N_std_S_basic_string__C___N_std_S_char_traits__C___N_std_S_allocator__C File);
[SuppressUnmanagedCodeSecurity, DllImport("CppSharp.CppParser.dll", EntryPoint = "?FindOrCreateModule@ASTContext@AST@CppParser@CppSharp@@QAEPAVTranslationUnit@234@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z", CallingConvention = __CallingConvention.ThisCall)]
internal static extern __IntPtr FindOrCreateModule(__IntPtr __instance, __IntPtr File);
[SuppressUnmanagedCodeSecurity, DllImport("CppSharp.CppParser.dll", EntryPoint = "?getTranslationUnits@ASTContext@AST@CppParser@CppSharp@@QAEPAVTranslationUnit@234@I@Z", CallingConvention = __CallingConvention.ThisCall)]
internal static extern __IntPtr GetTranslationUnits(__IntPtr __instance, uint i);
@ -15917,9 +15917,9 @@ namespace CppSharp @@ -15917,9 +15917,9 @@ namespace CppSharp
{
var __basicString0 = new global::Std.BasicString<sbyte, global::Std.CharTraits<sbyte>, global::Std.Allocator<sbyte>>();
global::Std.BasicStringExtensions.Assign(__basicString0, File);
var __arg0 = *(global::Std.BasicString.__Internalc__N_std_S_basic_string__C___N_std_S_char_traits__C___N_std_S_allocator__C*) __basicString0.__Instance;
var __arg0 = __basicString0.__Instance;
var ___ret = __Internal.FindOrCreateModule(__Instance, __arg0);
__basicString0.Dispose(disposing: true, callNativeDtor:false);
__basicString0.Dispose();
var __result0 = global::CppSharp.Parser.AST.TranslationUnit.__GetOrCreateInstance(___ret, false);
return __result0;
}

4
src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc-d/CppSharp.CppParser.cs

@ -15796,7 +15796,7 @@ namespace CppSharp @@ -15796,7 +15796,7 @@ namespace CppSharp
[SuppressUnmanagedCodeSecurity, DllImport("CppSharp.CppParser.dll", EntryPoint = "??1ASTContext@AST@CppParser@CppSharp@@QEAA@XZ", CallingConvention = __CallingConvention.Cdecl)]
internal static extern void dtor(__IntPtr __instance);
[SuppressUnmanagedCodeSecurity, DllImport("CppSharp.CppParser.dll", EntryPoint = "?FindOrCreateModule@ASTContext@AST@CppParser@CppSharp@@QEAAPEAVTranslationUnit@234@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z", CallingConvention = __CallingConvention.Cdecl)]
[SuppressUnmanagedCodeSecurity, DllImport("CppSharp.CppParser.dll", EntryPoint = "?FindOrCreateModule@ASTContext@AST@CppParser@CppSharp@@QEAAPEAVTranslationUnit@234@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z", CallingConvention = __CallingConvention.Cdecl)]
internal static extern __IntPtr FindOrCreateModule(__IntPtr __instance, __IntPtr File);
[SuppressUnmanagedCodeSecurity, DllImport("CppSharp.CppParser.dll", EntryPoint = "?getTranslationUnits@ASTContext@AST@CppParser@CppSharp@@QEAAPEAVTranslationUnit@234@I@Z", CallingConvention = __CallingConvention.Cdecl)]
@ -15920,7 +15920,7 @@ namespace CppSharp @@ -15920,7 +15920,7 @@ namespace CppSharp
global::Std.BasicStringExtensions.Assign(__basicString0, File);
var __arg0 = __basicString0.__Instance;
var ___ret = __Internal.FindOrCreateModule(__Instance, __arg0);
__basicString0.Dispose(disposing: true, callNativeDtor:false);
__basicString0.Dispose();
var __result0 = global::CppSharp.Parser.AST.TranslationUnit.__GetOrCreateInstance(___ret, false);
return __result0;
}

4
src/CppParser/Bindings/CSharp/x86_64-pc-win32-msvc/CppSharp.CppParser.cs

@ -15796,7 +15796,7 @@ namespace CppSharp @@ -15796,7 +15796,7 @@ namespace CppSharp
[SuppressUnmanagedCodeSecurity, DllImport("CppSharp.CppParser.dll", EntryPoint = "??1ASTContext@AST@CppParser@CppSharp@@QEAA@XZ", CallingConvention = __CallingConvention.Cdecl)]
internal static extern void dtor(__IntPtr __instance);
[SuppressUnmanagedCodeSecurity, DllImport("CppSharp.CppParser.dll", EntryPoint = "?FindOrCreateModule@ASTContext@AST@CppParser@CppSharp@@QEAAPEAVTranslationUnit@234@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z", CallingConvention = __CallingConvention.Cdecl)]
[SuppressUnmanagedCodeSecurity, DllImport("CppSharp.CppParser.dll", EntryPoint = "?FindOrCreateModule@ASTContext@AST@CppParser@CppSharp@@QEAAPEAVTranslationUnit@234@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z", CallingConvention = __CallingConvention.Cdecl)]
internal static extern __IntPtr FindOrCreateModule(__IntPtr __instance, __IntPtr File);
[SuppressUnmanagedCodeSecurity, DllImport("CppSharp.CppParser.dll", EntryPoint = "?getTranslationUnits@ASTContext@AST@CppParser@CppSharp@@QEAAPEAVTranslationUnit@234@I@Z", CallingConvention = __CallingConvention.Cdecl)]
@ -15920,7 +15920,7 @@ namespace CppSharp @@ -15920,7 +15920,7 @@ namespace CppSharp
global::Std.BasicStringExtensions.Assign(__basicString0, File);
var __arg0 = __basicString0.__Instance;
var ___ret = __Internal.FindOrCreateModule(__Instance, __arg0);
__basicString0.Dispose(disposing: true, callNativeDtor:false);
__basicString0.Dispose();
var __result0 = global::CppSharp.Parser.AST.TranslationUnit.__GetOrCreateInstance(___ret, false);
return __result0;
}

3
src/CppParser/Comments.cpp

@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
#include <clang/AST/ASTContext.h>
using namespace CppSharp::CppParser;
using namespace CppSharp::CppParser::AST;
//-----------------------------------//
@ -39,7 +40,7 @@ RawComment* Parser::WalkRawComment(const clang::RawComment* RC) @@ -39,7 +40,7 @@ RawComment* Parser::WalkRawComment(const clang::RawComment* RC)
using namespace clang;
auto& SM = c->getSourceManager();
auto Comment = new RawComment();
auto Comment = new AST::RawComment();
Comment->kind = ConvertRawCommentKind(RC->getKind());
Comment->text = RC->getRawText(SM).str();
Comment->briefText = RC->getBriefText(c->getASTContext());

14
src/CppParser/CppParser.cpp

@ -13,17 +13,7 @@ @@ -13,17 +13,7 @@
namespace CppSharp { namespace CppParser {
CppParserOptions::CppParserOptions()
: ASTContext(0)
, toolSetToUse(0)
, noStandardIncludes(false)
, noBuiltinIncludes(false)
, microsoftMode(false)
, verbose(false)
, unityBuild(false)
, skipPrivateDeclarations(true)
, skipLayoutInfo(false)
, skipFunctionBodies(true)
, clangVersion(CLANG_VERSION_STRING)
: clangVersion(CLANG_VERSION_STRING)
{
}
@ -59,7 +49,7 @@ ParserResult::~ParserResult() @@ -59,7 +49,7 @@ ParserResult::~ParserResult()
}
DEF_VECTOR(ParserResult, ParserDiagnostic, Diagnostics)
DEF_VECTOR(ParserResult, NativeLibrary*, Libraries)
DEF_VECTOR(ParserResult, AST::NativeLibrary*, Libraries)
CppLinkerOptions::CppLinkerOptions()
{

24
src/CppParser/CppParser.h

@ -16,8 +16,6 @@ @@ -16,8 +16,6 @@
namespace CppSharp { namespace CppParser {
using namespace CppSharp::CppParser::AST;
struct CS_API CppParserOptions
{
CppParserOptions();
@ -38,19 +36,19 @@ struct CS_API CppParserOptions @@ -38,19 +36,19 @@ struct CS_API CppParserOptions
VECTOR_STRING(SupportedStdTypes)
VECTOR_STRING(SupportedFunctionTemplates)
CppSharp::CppParser::AST::ASTContext* ASTContext;
AST::ASTContext* ASTContext = nullptr;
int toolSetToUse;
int toolSetToUse = 0;
std::string targetTriple;
bool noStandardIncludes;
bool noBuiltinIncludes;
bool microsoftMode;
bool verbose;
bool unityBuild;
bool skipPrivateDeclarations;
bool skipLayoutInfo;
bool skipFunctionBodies;
bool noStandardIncludes = false;
bool noBuiltinIncludes = false;
bool microsoftMode = false;
bool verbose = false;
bool unityBuild = false;
bool skipPrivateDeclarations = true;
bool skipLayoutInfo = false;
bool skipFunctionBodies = true;
private:
std::string clangVersion;
@ -104,7 +102,7 @@ struct CS_API ParserResult @@ -104,7 +102,7 @@ struct CS_API ParserResult
ParserResultKind kind = ParserResultKind::Error;
VECTOR(ParserDiagnostic, Diagnostics)
VECTOR(NativeLibrary*, Libraries)
VECTOR(AST::NativeLibrary*, Libraries)
ParserTargetInfo* targetInfo = nullptr;
};

2
src/CppParser/Decl.h

@ -839,7 +839,7 @@ namespace CppSharp @@ -839,7 +839,7 @@ namespace CppSharp
public:
ASTContext();
~ASTContext();
TranslationUnit *FindOrCreateModule(std::string File);
TranslationUnit *FindOrCreateModule(const std::string& File);
VECTOR(TranslationUnit *, TranslationUnits)
};

5
src/CppParser/ParseExpr.cpp

@ -11,7 +11,8 @@ @@ -11,7 +11,8 @@
#include <clang/AST/Expr.h>
#include <clang/AST/ExprCXX.h>
namespace CppSharp { namespace CppParser {
namespace CppSharp::CppParser {
using namespace AST;
AST::Expr* Parser::WalkExpression(const clang::Expr* Expr)
{
@ -2402,4 +2403,4 @@ AST::Expr* Parser::WalkExpression(const clang::Expr* Expr) @@ -2402,4 +2403,4 @@ AST::Expr* Parser::WalkExpression(const clang::Expr* Expr)
return _Expr;
}
} }
}

375
src/CppParser/Parser.cpp

File diff suppressed because it is too large Load Diff

133
src/CppParser/Parser.h

@ -51,6 +51,7 @@ namespace CppSharp { namespace CppParser { @@ -51,6 +51,7 @@ namespace CppSharp { namespace CppParser {
class Parser
{
friend class ASTNodeVisitor;
public:
Parser(CppParserOptions* Opts);
@ -61,8 +62,8 @@ public: @@ -61,8 +62,8 @@ public:
ParserResult* Compile(const std::string& File);
bool Link(const std::string& File, const CppLinkerOptions* LinkerOptions);
void WalkAST(clang::TranslationUnitDecl* TU);
void HandleDeclaration(const clang::Decl* D, Declaration* Decl);
CppParserOptions* opts;
void HandleDeclaration(const clang::Decl* D, AST::Declaration* Decl);
CppParserOptions* opts = nullptr;
private:
@ -73,54 +74,54 @@ private: @@ -73,54 +74,54 @@ private:
bool IsSupported(const clang::NamedDecl* ND);
bool IsSupported(const clang::CXXMethodDecl* MD);
// AST traversers
Declaration* WalkDeclaration(const clang::Decl* D);
Declaration* WalkDeclarationDef(clang::Decl* D);
Enumeration* WalkEnum(const clang::EnumDecl* ED);
Enumeration::Item* WalkEnumItem(clang::EnumConstantDecl* ECD);
Function* WalkFunction(const clang::FunctionDecl* FD);
void EnsureCompleteRecord(const clang::RecordDecl* Record, DeclarationContext* NS, Class* RC);
Class* GetRecord(const clang::RecordDecl* Record, bool& IsComplete);
Class* WalkRecord(const clang::RecordDecl* Record);
void WalkRecord(const clang::RecordDecl* Record, Class* RC);
Class* WalkRecordCXX(const clang::CXXRecordDecl* Record);
void WalkRecordCXX(const clang::CXXRecordDecl* Record, Class* RC);
ClassTemplateSpecialization*
AST::Declaration* WalkDeclaration(const clang::Decl* D);
AST::Declaration* WalkDeclarationDef(clang::Decl* D);
AST::Enumeration* WalkEnum(const clang::EnumDecl* ED);
AST::Enumeration::Item* WalkEnumItem(clang::EnumConstantDecl* ECD);
AST::Function* WalkFunction(const clang::FunctionDecl* FD);
void EnsureCompleteRecord(const clang::RecordDecl* Record, AST::DeclarationContext* NS, AST::Class* RC);
AST::Class* GetRecord(const clang::RecordDecl* Record, bool& IsComplete);
AST::Class* WalkRecord(const clang::RecordDecl* Record);
void WalkRecord(const clang::RecordDecl* Record, AST::Class* RC);
AST::Class* WalkRecordCXX(const clang::CXXRecordDecl* Record);
void WalkRecordCXX(const clang::CXXRecordDecl* Record, AST::Class* RC);
AST::ClassTemplateSpecialization*
WalkClassTemplateSpecialization(const clang::ClassTemplateSpecializationDecl* CTS);
ClassTemplatePartialSpecialization*
AST::ClassTemplatePartialSpecialization*
WalkClassTemplatePartialSpecialization(const clang::ClassTemplatePartialSpecializationDecl* CTS);
Method* WalkMethodCXX(const clang::CXXMethodDecl* MD);
Field* WalkFieldCXX(const clang::FieldDecl* FD, Class* Class);
FunctionTemplateSpecialization* WalkFunctionTemplateSpec(clang::FunctionTemplateSpecializationInfo* FTS, Function* Function);
Variable* WalkVariable(const clang::VarDecl* VD);
void WalkVariable(const clang::VarDecl* VD, Variable* Var);
Friend* WalkFriend(const clang::FriendDecl* FD);
RawComment* WalkRawComment(const clang::RawComment* RC);
Type* WalkType(clang::QualType QualType, const clang::TypeLoc* TL = 0,
AST::Method* WalkMethodCXX(const clang::CXXMethodDecl* MD);
AST::Field* WalkFieldCXX(const clang::FieldDecl* FD, AST::Class* Class);
AST::FunctionTemplateSpecialization* WalkFunctionTemplateSpec(clang::FunctionTemplateSpecializationInfo* FTS, AST::Function* Function);
AST::Variable* WalkVariable(const clang::VarDecl* VD);
void WalkVariable(const clang::VarDecl* VD, AST::Variable* Var);
AST::Friend* WalkFriend(const clang::FriendDecl* FD);
AST::RawComment* WalkRawComment(const clang::RawComment* RC);
AST::Type* WalkType(clang::QualType QualType, const clang::TypeLoc* TL = 0,
bool DesugarType = false);
TemplateArgument WalkTemplateArgument(const clang::TemplateArgument& TA, clang::TemplateArgumentLoc* ArgLoc = 0);
TemplateTemplateParameter* WalkTemplateTemplateParameter(const clang::TemplateTemplateParmDecl* TTP);
TypeTemplateParameter* WalkTypeTemplateParameter(const clang::TemplateTypeParmDecl* TTPD);
NonTypeTemplateParameter* WalkNonTypeTemplateParameter(const clang::NonTypeTemplateParmDecl* TTPD);
UnresolvedUsingTypename* WalkUnresolvedUsingTypename(const clang::UnresolvedUsingTypenameDecl* UUTD);
std::vector<Declaration*> WalkTemplateParameterList(const clang::TemplateParameterList* TPL);
TypeAliasTemplate* WalkTypeAliasTemplate(const clang::TypeAliasTemplateDecl* TD);
ClassTemplate* WalkClassTemplate(const clang::ClassTemplateDecl* TD);
FunctionTemplate* WalkFunctionTemplate(const clang::FunctionTemplateDecl* TD);
VarTemplate* WalkVarTemplate(const clang::VarTemplateDecl* VT);
VarTemplateSpecialization*
AST::TemplateArgument WalkTemplateArgument(const clang::TemplateArgument& TA, clang::TemplateArgumentLoc* ArgLoc = 0);
AST::TemplateTemplateParameter* WalkTemplateTemplateParameter(const clang::TemplateTemplateParmDecl* TTP);
AST::TypeTemplateParameter* WalkTypeTemplateParameter(const clang::TemplateTypeParmDecl* TTPD);
AST::NonTypeTemplateParameter* WalkNonTypeTemplateParameter(const clang::NonTypeTemplateParmDecl* TTPD);
AST::UnresolvedUsingTypename* WalkUnresolvedUsingTypename(const clang::UnresolvedUsingTypenameDecl* UUTD);
std::vector<AST::Declaration*> WalkTemplateParameterList(const clang::TemplateParameterList* TPL);
AST::TypeAliasTemplate* WalkTypeAliasTemplate(const clang::TypeAliasTemplateDecl* TD);
AST::ClassTemplate* WalkClassTemplate(const clang::ClassTemplateDecl* TD);
AST::FunctionTemplate* WalkFunctionTemplate(const clang::FunctionTemplateDecl* TD);
AST::VarTemplate* WalkVarTemplate(const clang::VarTemplateDecl* VT);
AST::VarTemplateSpecialization*
WalkVarTemplateSpecialization(const clang::VarTemplateSpecializationDecl* VTS);
VarTemplatePartialSpecialization*
AST::VarTemplatePartialSpecialization*
WalkVarTemplatePartialSpecialization(const clang::VarTemplatePartialSpecializationDecl* VTS);
template<typename TypeLoc>
std::vector<TemplateArgument> WalkTemplateArgumentList(const clang::TemplateArgumentList* TAL, TypeLoc* TSTL);
std::vector<TemplateArgument> WalkTemplateArgumentList(const clang::TemplateArgumentList* TAL, const clang::ASTTemplateArgumentListInfo* TSTL);
void WalkVTable(const clang::CXXRecordDecl* RD, Class* C);
QualifiedType GetQualifiedType(clang::QualType qual, const clang::TypeLoc* TL = 0);
void ReadClassLayout(Class* Class, const clang::RecordDecl* RD, clang::CharUnits Offset, bool IncludeVirtualBases);
LayoutField WalkVTablePointer(Class* Class, const clang::CharUnits& Offset, const std::string& prefix);
VTableLayout WalkVTableLayout(const clang::VTableLayout& VTLayout);
VTableComponent WalkVTableComponent(const clang::VTableComponent& Component);
PreprocessedEntity* WalkPreprocessedEntity(Declaration* Decl,
std::vector<AST::TemplateArgument> WalkTemplateArgumentList(const clang::TemplateArgumentList* TAL, TypeLoc* TSTL);
std::vector<AST::TemplateArgument> WalkTemplateArgumentList(const clang::TemplateArgumentList* TAL, const clang::ASTTemplateArgumentListInfo* TSTL);
void WalkVTable(const clang::CXXRecordDecl* RD, AST::Class* C);
AST::QualifiedType GetQualifiedType(clang::QualType qual, const clang::TypeLoc* TL = 0);
void ReadClassLayout(AST::Class* Class, const clang::RecordDecl* RD, clang::CharUnits Offset, bool IncludeVirtualBases);
AST::LayoutField WalkVTablePointer(AST::Class* Class, const clang::CharUnits& Offset, const std::string& prefix);
AST::VTableLayout WalkVTableLayout(const clang::VTableLayout& VTLayout);
AST::VTableComponent WalkVTableComponent(const clang::VTableComponent& Component);
AST::PreprocessedEntity* WalkPreprocessedEntity(AST::Declaration* Decl,
clang::PreprocessedEntity* PPEntity);
AST::ExpressionObsolete* WalkVariableInitializerExpression(const clang::Expr* Expression);
AST::ExpressionObsolete* WalkExpressionObsolete(const clang::Expr* Expression);
@ -138,38 +139,38 @@ private: @@ -138,38 +139,38 @@ private:
std::string GetTypeName(const clang::Type* Type) const;
bool CanCheckCodeGenInfo(const clang::Type* Ty);
void CompleteIfSpecializationType(const clang::QualType& QualType);
Parameter* WalkParameter(const clang::ParmVarDecl* PVD,
AST::Parameter* WalkParameter(const clang::ParmVarDecl* PVD,
const clang::SourceLocation& ParamStartLoc);
void SetBody(const clang::FunctionDecl* FD, Function* F);
void MarkValidity(Function* F);
void WalkFunction(const clang::FunctionDecl* FD, Function* F);
void SetBody(const clang::FunctionDecl* FD, AST::Function* F);
void MarkValidity(AST::Function* F);
void WalkFunction(const clang::FunctionDecl* FD, AST::Function* F);
int GetAlignAs(const clang::AlignedAttr* alignedAttr);
void HandlePreprocessedEntities(Declaration* Decl);
void HandlePreprocessedEntities(Declaration* Decl, clang::SourceRange sourceRange,
MacroLocation macroLocation = MacroLocation::Unknown);
void HandlePreprocessedEntities(AST::Declaration* Decl);
void HandlePreprocessedEntities(AST::Declaration* Decl, clang::SourceRange sourceRange,
AST::MacroLocation macroLocation = AST::MacroLocation::Unknown);
bool GetDeclText(clang::SourceRange SR, std::string& Text);
bool HasLayout(const clang::RecordDecl* Record);
TranslationUnit* GetTranslationUnit(clang::SourceLocation Loc,
AST::TranslationUnit* GetTranslationUnit(clang::SourceLocation Loc,
SourceLocationKind *Kind = 0);
TranslationUnit* GetTranslationUnit(const clang::Decl* D);
AST::TranslationUnit* GetTranslationUnit(const clang::Decl* D);
DeclarationContext* GetNamespace(const clang::Decl* D, const clang::DeclContext* Ctx);
DeclarationContext* GetNamespace(const clang::Decl* D);
AST::DeclarationContext* GetNamespace(const clang::Decl* D, const clang::DeclContext* Ctx);
AST::DeclarationContext* GetNamespace(const clang::Decl* D);
void HandleOriginalText(const clang::Decl* D, Declaration* Decl);
void HandleComments(const clang::Decl* D, Declaration* Decl);
void HandleOriginalText(const clang::Decl* D, AST::Declaration* Decl);
void HandleComments(const clang::Decl* D, AST::Declaration* Decl);
void HandleDiagnostics(ParserResult* res);
ParserResultKind ReadSymbols(llvm::StringRef File,
llvm::object::basic_symbol_iterator Begin,
llvm::object::basic_symbol_iterator End,
CppSharp::CppParser::NativeLibrary*& NativeLib);
Declaration* GetDeclarationFromFriend(clang::NamedDecl* FriendDecl);
AST::NativeLibrary*& NativeLib);
AST::Declaration* GetDeclarationFromFriend(clang::NamedDecl* FriendDecl);
static ParserResultKind ParseArchive(const std::string& File,
llvm::object::Archive* Archive, std::vector<CppSharp::CppParser::NativeLibrary*>& NativeLibs);
llvm::object::Archive* Archive, std::vector<AST::NativeLibrary*>& NativeLibs);
static ParserResultKind ParseSharedLib(const std::string& File,
llvm::object::ObjectFile* ObjectFile, std::vector<CppSharp::CppParser::NativeLibrary*>& NativeLibs);
llvm::object::ObjectFile* ObjectFile, std::vector<AST::NativeLibrary*>& NativeLibs);
ParserTargetInfo* GetTargetInfo();
bool LinkWindows(const CppLinkerOptions* LinkerOptions, std::vector<const char*>& args,
@ -179,17 +180,17 @@ private: @@ -179,17 +180,17 @@ private:
bool LinkMachO(const CppLinkerOptions* LinkerOptions, std::vector<const char*>& args,
llvm::StringRef& Dir, llvm::StringRef& Stem);
int index;
int index = 0;
std::unique_ptr<clang::CompilerInstance> c;
llvm::LLVMContext LLVMCtx;
std::unique_ptr<ASTNameMangler> NameMangler;
std::unique_ptr<llvm::Module> LLVMModule;
std::unique_ptr<clang::CodeGen::CodeGenModule> CGM;
std::unique_ptr<clang::CodeGen::CodeGenTypes> codeGenTypes;
std::unordered_map<const clang::TemplateTypeParmDecl*, TypeTemplateParameter*> walkedTypeTemplateParameters;
std::unordered_map<const clang::TemplateTemplateParmDecl*, TemplateTemplateParameter*> walkedTemplateTemplateParameters;
std::unordered_map<const clang::NonTypeTemplateParmDecl*, NonTypeTemplateParameter*> walkedNonTypeTemplateParameters;
std::unordered_map<const clang::ParmVarDecl*, Parameter*> walkedParameters;
std::unordered_map<const clang::TemplateTypeParmDecl*, AST::TypeTemplateParameter*> walkedTypeTemplateParameters;
std::unordered_map<const clang::TemplateTemplateParmDecl*, AST::TemplateTemplateParameter*> walkedTemplateTemplateParameters;
std::unordered_map<const clang::NonTypeTemplateParmDecl*, AST::NonTypeTemplateParameter*> walkedNonTypeTemplateParameters;
std::unordered_map<const clang::ParmVarDecl*, AST::Parameter*> walkedParameters;
std::unordered_set<std::string> supportedStdTypes;
std::unordered_set<std::string> supportedFunctionTemplates;
};

34
src/Generator/Generators/CLI/CLITypeReferences.cs

@ -30,7 +30,7 @@ namespace CppSharp.Generators.CLI @@ -30,7 +30,7 @@ namespace CppSharp.Generators.CLI
private readonly DriverOptions DriverOptions;
private TranslationUnit TranslationUnit;
private Dictionary<Declaration, CLITypeReference> typeReferences;
private readonly Dictionary<Declaration, CLITypeReference> typeReferences;
public IEnumerable<CLITypeReference> TypeReferences => typeReferences.Values;
public HashSet<Declaration> GeneratedDeclarations;
@ -45,28 +45,29 @@ namespace CppSharp.Generators.CLI @@ -45,28 +45,29 @@ namespace CppSharp.Generators.CLI
public CLITypeReference GetTypeReference(Declaration decl)
{
if (typeReferences.ContainsKey(decl))
return typeReferences[decl];
if (typeReferences.TryGetValue(decl, out CLITypeReference reference))
return reference;
var translationUnit = decl.Namespace.TranslationUnit;
if (ShouldIncludeTranslationUnit(translationUnit) && decl.IsGenerated && !IsBuiltinTypedef(decl))
{
var @ref = new CLITypeReference { Declaration = decl };
if (!ShouldIncludeTranslationUnit(translationUnit) || !decl.IsGenerated || IsBuiltinTypedef(decl))
return null;
@ref.Include = new CInclude
var @ref = new CLITypeReference
{
Declaration = decl,
Include = new CInclude
{
File = DriverOptions.GetIncludePath(translationUnit),
TranslationUnit = translationUnit,
Kind = translationUnit.IsGenerated ? CInclude.IncludeKind.Quoted : CInclude.IncludeKind.Angled
}
};
typeReferences.Add(decl, @ref);
return @ref;
}
return null;
}
static Namespace GetEffectiveNamespace(Declaration decl)
@ -145,15 +146,16 @@ namespace CppSharp.Generators.CLI @@ -145,15 +146,16 @@ namespace CppSharp.Generators.CLI
private bool IsBuiltinTypedef(Declaration decl)
{
var typedefDecl = decl as TypedefDecl;
if (typedefDecl == null) return false;
if (typedefDecl.Type is BuiltinType) return true;
if (decl is not TypedefDecl typedefDecl)
return false;
var typedefType = typedefDecl.Type as TypedefType;
if (typedefType == null) return false;
if (typedefType.Declaration == null) return false;
if (typedefDecl.Type is BuiltinType)
return true;
if (typedefDecl.Type is not TypedefType typedefType)
return false;
return typedefType.Declaration.Type is BuiltinType;
return typedefType.Declaration?.Type is BuiltinType;
}
public bool IsIncludeInHeader(ASTRecord<Declaration> record)

9
src/Generator/Generators/CSharp/CSharpSources.cs

@ -1163,8 +1163,7 @@ internal static bool {Helpers.TryGetNativeToManagedMappingIdentifier}(IntPtr nat @@ -1163,8 +1163,7 @@ internal static bool {Helpers.TryGetNativeToManagedMappingIdentifier}(IntPtr nat
}
else
{
Class @class;
if (type.TryGetClass(out @class) && @class.HasNonTrivialCopyConstructor)
if (type.TryGetClass(out Class @class) && @class.HasNonTrivialCopyConstructor)
{
Method cctor = @class.Methods.First(c => c.IsCopyConstructor);
WriteLine($@"{TypePrinter.PrintNative(type)}.{GetFunctionNativeIdentifier(cctor)}({call}, {marshal.Context.Return});");
@ -3513,10 +3512,10 @@ internal static{(@new ? " new" : string.Empty)} {printedClass} __GetInstance({Ty @@ -3513,10 +3512,10 @@ internal static{(@new ? " new" : string.Empty)} {printedClass} __GetInstance({Ty
var method = function as Method;
if (method != null)
{
if (method.IsConstructor && !method.IsCopyConstructor)
identifier.Append("ctor");
else if (method.IsCopyConstructor)
if (method.IsCopyConstructor)
identifier.Append("cctor");
else if (method.IsConstructor)
identifier.Append("ctor");
else if (method.IsDestructor)
identifier.Append("dtor");
else

2
src/Generator/Passes/FindSymbolsPass.cs

@ -87,7 +87,7 @@ namespace CppSharp.Passes @@ -87,7 +87,7 @@ namespace CppSharp.Passes
{
if (!Context.Symbols.FindLibraryBySymbol(mangledDecl.Mangled, out _))
{
if (mangledDecl is Variable variable && variable.IsConstExpr)
if (mangledDecl is Variable { IsConstExpr: true })
return true;
Diagnostics.Warning("Symbol not found: {0}", mangledDecl.Mangled);

135
src/Generator/Passes/GenerateSymbolsPass.cs

@ -19,9 +19,12 @@ namespace CppSharp.Passes @@ -19,9 +19,12 @@ namespace CppSharp.Passes
{
var result = base.VisitASTContext(context);
var findSymbolsPass = Context.TranslationUnitPasses.FindPass<FindSymbolsPass>();
GenerateSymbols();
if (remainingCompilationTasks > 0)
if (RemainingCompilationTasks > 0)
findSymbolsPass.Wait = true;
return result;
}
@ -30,7 +33,8 @@ namespace CppSharp.Passes @@ -30,7 +33,8 @@ namespace CppSharp.Passes
private void GenerateSymbols()
{
var modules = Options.Modules.Where(symbolsCodeGenerators.ContainsKey).ToList();
remainingCompilationTasks = modules.Count;
RemainingCompilationTasks = modules.Count;
foreach (var module in modules)
{
var symbolsCodeGenerator = symbolsCodeGenerators[module];
@ -53,21 +57,26 @@ namespace CppSharp.Passes @@ -53,21 +57,26 @@ namespace CppSharp.Passes
// if the user's provided no libraries, he only wants to generate code
(module.LibraryDirs.Count > 0 && module.Libraries.Count > 0)))
{
using (var linkerOptions = new LinkerOptions(Context.LinkerOptions))
using var linkerOptions = new LinkerOptions(Context.LinkerOptions);
foreach (var libraryDir in module.Dependencies
.Union(new[] { module })
.SelectMany(d => d.LibraryDirs))
{
foreach (var libraryDir in module.Dependencies.Union(
new[] { module }).SelectMany(d => d.LibraryDirs))
linkerOptions.AddLibraryDirs(libraryDir);
}
foreach (var library in module.Dependencies.Union(
new[] { module }).SelectMany(d => d.Libraries))
foreach (var library in module.Dependencies
.Union(new[] { module })
.SelectMany(d => d.Libraries))
{
linkerOptions.AddLibraries(library);
}
compiledLibraries[module] = Build(linkerOptions, path, module);
}
}
RemainingCompilationTasks--;
--RemainingCompilationTasks;
}
}
@ -79,7 +88,7 @@ namespace CppSharp.Passes @@ -79,7 +88,7 @@ namespace CppSharp.Passes
linkerOptions.Setup(Context.ParserOptions.TargetTriple, Context.ParserOptions.LanguageVersion);
using var result = Parser.ClangParser.Build(
Context.ParserOptions, linkerOptions, path,
Last: remainingCompilationTasks == 1);
Last: RemainingCompilationTasks == 1);
if (!PrintDiagnostics(result))
return null;
@ -120,7 +129,7 @@ namespace CppSharp.Passes @@ -120,7 +129,7 @@ namespace CppSharp.Passes
}
else
{
Diagnostics.Message($"Linking success.");
Diagnostics.Message("Linking success.");
}
}
@ -180,7 +189,7 @@ namespace CppSharp.Passes @@ -180,7 +189,7 @@ namespace CppSharp.Passes
public override bool VisitVariableDecl(Variable variable)
{
if (!base.VisitVariableDecl(variable) ||
!(variable.Namespace is ClassTemplateSpecialization specialization) ||
variable.Namespace is not ClassTemplateSpecialization specialization ||
specialization.SpecializationKind == TemplateSpecializationKind.ExplicitSpecialization)
return false;
@ -227,8 +236,8 @@ namespace CppSharp.Passes @@ -227,8 +236,8 @@ namespace CppSharp.Passes
private SymbolsCodeGenerator GetSymbolsCodeGenerator(Module module)
{
if (symbolsCodeGenerators.ContainsKey(module))
return symbolsCodeGenerators[module];
if (symbolsCodeGenerators.TryGetValue(module, out SymbolsCodeGenerator generator))
return generator;
var symbolsCodeGenerator = new SymbolsCodeGenerator(Context, module.Units);
symbolsCodeGenerators[module] = symbolsCodeGenerator;
@ -277,9 +286,7 @@ namespace CppSharp.Passes @@ -277,9 +286,7 @@ namespace CppSharp.Passes
{
new Thread(() =>
{
int error;
string errorMessage;
ProcessHelper.Run(compiler, arguments, out error, out errorMessage);
ProcessHelper.Run(compiler, arguments, out _, out var errorMessage);
var output = GetOutputFile(module.SymbolsLibraryName);
if (!File.Exists(Path.Combine(outputDir, output)))
Diagnostics.Error(errorMessage);
@ -294,8 +301,7 @@ namespace CppSharp.Passes @@ -294,8 +301,7 @@ namespace CppSharp.Passes
{
foreach (var @base in @class.Bases.Where(b => b.IsClass))
{
var specialization = @base.Class as ClassTemplateSpecialization;
if (specialization != null && !specialization.IsExplicitlyGenerated &&
if (@base.Class is ClassTemplateSpecialization { IsExplicitlyGenerated: false } specialization &&
specialization.SpecializationKind != TemplateSpecializationKind.ExplicitSpecialization)
ASTUtils.CheckTypeForSpecialization(@base.Type, @class, Add, Context.TypeMaps);
CheckBasesForSpecialization(@base.Class);
@ -304,30 +310,34 @@ namespace CppSharp.Passes @@ -304,30 +310,34 @@ namespace CppSharp.Passes
private void Add(ClassTemplateSpecialization specialization)
{
ICollection<ClassTemplateSpecialization> specs;
if (specializations.ContainsKey(specialization.TranslationUnit.Module))
specs = specializations[specialization.TranslationUnit.Module];
else specs = specializations[specialization.TranslationUnit.Module] =
new HashSet<ClassTemplateSpecialization>();
if (!specs.Contains(specialization))
if (!specializations.TryGetValue(specialization.TranslationUnit.Module, out var specs))
{
specs = new HashSet<ClassTemplateSpecialization>();
specializations[specialization.TranslationUnit.Module] = specs;
}
if (specs.Add(specialization))
{
specs.Add(specialization);
foreach (Method method in specialization.Methods)
method.Visit(this);
}
GetSymbolsCodeGenerator(specialization.TranslationUnit.Module);
}
private int _remainingCompilationTasks;
private int RemainingCompilationTasks
{
get { return remainingCompilationTasks; }
get => _remainingCompilationTasks;
set
{
if (remainingCompilationTasks != value)
{
remainingCompilationTasks = value;
if (remainingCompilationTasks == 0)
{
if (_remainingCompilationTasks == value)
return;
_remainingCompilationTasks = value;
if (_remainingCompilationTasks != 0)
return;
foreach (var module in Context.Options.Modules.Where(compiledLibraries.ContainsKey))
{
CompiledLibrary compiledLibrary = compiledLibraries[module];
@ -337,56 +347,65 @@ namespace CppSharp.Passes @@ -337,56 +347,65 @@ namespace CppSharp.Passes
findSymbolsPass.Wait = false;
}
}
}
}
private void CollectSymbols(string outputDir, string library)
{
using (var linkerOptions = new LinkerOptions(Context.LinkerOptions))
{
using var linkerOptions = new LinkerOptions(Context.LinkerOptions);
linkerOptions.AddLibraryDirs(outputDir);
var output = GetOutputFile(library);
linkerOptions.AddLibraries(output);
using (var parserResult = Parser.ClangParser.ParseLibrary(linkerOptions))
{
if (parserResult.Kind == ParserResultKind.Success)
using var parserResult = Parser.ClangParser.ParseLibrary(linkerOptions);
if (parserResult.Kind != ParserResultKind.Success)
{
lock (@lock)
Diagnostics.Error($"Parsing of {Path.Combine(outputDir, output)} failed.");
return;
}
var results = GetLibraries(parserResult).AsParallel()
.Select(ClangParser.ConvertLibrary);
lock (symbolsLock)
{
for (uint i = 0; i < parserResult.LibrariesCount; i++)
foreach (var nativeLibrary in results)
{
var nativeLibrary = ClangParser.ConvertLibrary(parserResult.GetLibraries(i));
Context.Symbols.Libraries.Add(nativeLibrary);
Context.Symbols.IndexSymbols();
}
}
}
else
Diagnostics.Error($"Parsing of {Path.Combine(outputDir, output)} failed.");
}
return;
IEnumerable<Parser.AST.NativeLibrary> GetLibraries(ParserResult p)
{
for (uint i = 0; i < p.LibrariesCount; i++)
yield return p.GetLibraries(i);
}
}
private static string GetOutputFile(string library)
{
return Path.GetFileName($@"{(Platform.IsWindows ?
string.Empty : "lib")}{library}.{
(Platform.IsMacOS ? "dylib" : Platform.IsWindows ? "dll" : "so")}");
var extension = Platform.Host switch
{
TargetPlatform.Windows => "lib",
TargetPlatform.Linux => "so",
TargetPlatform.MacOS => "dylib",
_ => throw new NotImplementedException()
};
return Path.GetFileName($"{(Platform.IsWindows ? string.Empty : "lib")}{library}.{extension}");
}
private int remainingCompilationTasks;
private static readonly object @lock = new object();
private static readonly object symbolsLock = new();
private Dictionary<Module, SymbolsCodeGenerator> symbolsCodeGenerators =
new Dictionary<Module, SymbolsCodeGenerator>();
private Dictionary<Module, HashSet<ClassTemplateSpecialization>> specializations =
new Dictionary<Module, HashSet<ClassTemplateSpecialization>>();
private Dictionary<Module, CompiledLibrary> compiledLibraries = new Dictionary<Module, CompiledLibrary>();
private readonly Dictionary<Module, SymbolsCodeGenerator> symbolsCodeGenerators = new();
private readonly Dictionary<Module, HashSet<ClassTemplateSpecialization>> specializations = new();
private readonly Dictionary<Module, CompiledLibrary> compiledLibraries = new();
private class CompiledLibrary
{
public string OutputDir { get; set; }
public string Library { get; set; }
public string OutputDir { get; init; }
public string Library { get; init; }
}
}
}

35
src/Generator/Passes/StripUnusedSystemTypesPass.cs

@ -15,9 +15,15 @@ namespace CppSharp.Passes @@ -15,9 +15,15 @@ namespace CppSharp.Passes
{
// we need this one for marshalling std::string
foreach (var name in new[] { "allocator", "char_traits" })
foreach (var usedStdType in context.FindClass(name, false, true).Where(
a => a.TranslationUnit.IsSystemHeader))
{
var forceIncludedClasses = context.FindClass(name, false, true)
.Where(a => a.TranslationUnit.IsSystemHeader);
foreach (var usedStdType in forceIncludedClasses)
{
usedStdTypes.Add(usedStdType);
}
}
var result = base.VisitASTContext(context);
@ -44,8 +50,7 @@ namespace CppSharp.Passes @@ -44,8 +50,7 @@ namespace CppSharp.Passes
var tagType = desugared as TagType ?? templateType?.Desugared.Type as TagType;
if (tagType != null)
{
var specialization = tagType.Declaration as ClassTemplateSpecialization;
if (specialization != null)
if (tagType.Declaration is ClassTemplateSpecialization specialization)
{
MarkAsUsed(specialization.TemplatedDecl);
MarkAsUsed(specialization.TemplatedDecl.TemplatedDecl);
@ -57,8 +62,9 @@ namespace CppSharp.Passes @@ -57,8 +62,9 @@ namespace CppSharp.Passes
return true;
}
if (templateType != null)
{
if (templateType == null)
return false;
var template = templateType.Template;
if (template.TemplatedDecl is TypeAlias typeAlias &&
typeAlias.Type.Desugar() is TemplateSpecializationType specializationType)
@ -70,14 +76,12 @@ namespace CppSharp.Passes @@ -70,14 +76,12 @@ namespace CppSharp.Passes
MarkAsUsed(template);
MarkAsUsed(template.TemplatedDecl);
return true;
}
return false;
}
private void MarkAsUsed(Declaration declaration)
{
while (declaration != null && !(declaration is Namespace))
while (declaration != null && declaration is not Namespace)
{
usedStdTypes.Add(declaration);
declaration = declaration.Namespace;
@ -89,15 +93,18 @@ namespace CppSharp.Passes @@ -89,15 +93,18 @@ namespace CppSharp.Passes
for (int i = context.Declarations.Count - 1; i >= 0; i--)
{
var declaration = context.Declarations[i];
var nestedContext = declaration as Namespace;
if (nestedContext != null)
if (declaration is Namespace nestedContext)
{
RemoveUnusedStdTypes(nestedContext);
else if (!this.usedStdTypes.Contains(declaration) &&
!declaration.IsExplicitlyGenerated)
continue;
}
if (!usedStdTypes.Contains(declaration) && !declaration.IsExplicitlyGenerated)
context.Declarations.RemoveAt(i);
}
}
private readonly HashSet<Declaration> usedStdTypes = new HashSet<Declaration>();
private readonly HashSet<Declaration> usedStdTypes = new();
}
}

11
src/Parser/ParserOptions.cs

@ -84,10 +84,9 @@ namespace CppSharp.Parser @@ -84,10 +84,9 @@ namespace CppSharp.Parser
TargetTriple.Contains("windows") || TargetTriple.Contains("msvc");
public bool EnableRTTI { get; set; }
public LanguageVersion? LanguageVersion { get; set; }
public LanguageVersion LanguageVersion { get; set; } = CppSharp.Parser.LanguageVersion.CPP14_GNU;
public void BuildForSourceFile(
IEnumerable<CppSharp.AST.Module> modules, string file = null)
public void BuildForSourceFile(IEnumerable<CppSharp.AST.Module> modules, string file = null)
{
// This eventually gets passed to Clang's MSCompatibilityVersion, which
// is in turn used to derive the value of the built-in define _MSC_VER.
@ -158,10 +157,6 @@ namespace CppSharp.Parser @@ -158,10 +157,6 @@ namespace CppSharp.Parser
var clVersion = MSVCToolchain.GetCLVersion(vsVersion);
ToolSetToUse = clVersion.Major * 10000000 + clVersion.Minor * 100000;
// do not remove the CppSharp prefix becase the Mono C# compiler breaks
if (!LanguageVersion.HasValue)
LanguageVersion = CppSharp.Parser.LanguageVersion.CPP14_GNU;
AddArguments("-fms-extensions");
AddArguments("-fms-compatibility");
AddArguments("-fdelayed-template-parsing");
@ -297,8 +292,6 @@ namespace CppSharp.Parser @@ -297,8 +292,6 @@ namespace CppSharp.Parser
private void SetupArguments(TargetPlatform targetPlatform)
{
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
// this define, so we need explicitly pass it to Clang.

6
tests/dotnet/Common/Common.h

@ -121,9 +121,9 @@ struct DLL_API Bar @@ -121,9 +121,9 @@ struct DLL_API Bar
explicit Bar(const Foo* foo);
Bar(Foo foo);
Item RetItem1() const;
int A;
float B;
Item fixedEnumArray[3];
int A = -1;
float B = -1.0f;
Item fixedEnumArray[3]{};
Bar* returnPointerToValueType();

Loading…
Cancel
Save