Browse Source

Merge f81f8e6f1f into e093f713b9

pull/1918/merge
Jelle 2 months ago committed by GitHub
parent
commit
e40b5eb219
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      CppSharp.sln.DotSettings
  2. 12
      src/AST/ASTContext.cs
  3. 10
      src/AST/Class.cs
  4. 16
      src/AST/Declaration.cs
  5. 32
      src/AST/Namespace.cs
  6. 1
      src/CppParser/AST.cpp
  7. 347
      src/CppParser/Bootstrap/Bootstrap.cs
  8. 263
      src/CppParser/Bootstrap/CodeGeneratorHelpers.cs
  9. 221
      src/CppParser/Bootstrap/DeclCodeGenerators.cs
  10. 55
      src/CppParser/Bootstrap/InheritanceValidator.cs
  11. 104
      src/CppParser/Bootstrap/ParserCodeGenerators.cs
  12. 2
      src/CppParser/Bootstrap/Properties/launchSettings.json
  13. 24
      src/CppParser/Bootstrap/StmtCodeGenerators.cs
  14. 323
      src/CppParser/Bootstrap/TypeCodeGenerators.cs
  15. 523
      src/CppParser/Decl.h
  16. 2191
      src/CppParser/Declaration.h
  17. 21
      src/CppParser/Types.h
  18. 8
      src/Generator/Generators/C/CppTypePrinter.cs
  19. 2
      src/Generator/Generators/CSharp/CSharpTypePrinter.cs
  20. 4
      src/Generator/Generators/CodeGenerator.cs
  21. 2
      src/Generator/Passes/MoveFunctionToClassPass.cs
  22. 2
      src/Generator/Passes/StripUnusedSystemTypesPass.cs
  23. 2
      src/Generator/Passes/verbs.txt

1
CppSharp.sln.DotSettings

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CLI/@EntryIndexedValue">CLI</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MD/@EntryIndexedValue">MD</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MSVC/@EntryIndexedValue">MSVC</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=diag/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=undefine/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

12
src/AST/ASTContext.cs

@ -75,20 +75,18 @@ namespace CppSharp.AST @@ -75,20 +75,18 @@ namespace CppSharp.AST
}
/// Finds an existing struct/class in the library modules.
public IEnumerable<Class> FindClass(string name, bool create = false,
bool ignoreCase = false)
public IEnumerable<Class> FindClass(string name, bool create = false)
{
return TranslationUnits.Select(
module => module.FindClass(name,
ignoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal))
module => module.FindClass(name))
.Where(type => type != null);
}
/// Finds the complete declaration of a class.
public Class FindCompleteClass(string name, bool ignoreCase = false)
public Class FindCompleteClass(string name)
{
return FindClass(name, ignoreCase: ignoreCase).FirstOrDefault(
@class => !@class.IsIncomplete);
return FindClass(name)
.FirstOrDefault(@class => !@class.IsIncomplete);
}
/// Finds an existing function in the library modules.

10
src/AST/Class.cs

@ -272,6 +272,16 @@ namespace CppSharp.AST @@ -272,6 +272,16 @@ namespace CppSharp.AST
return Variables.FirstOrDefault(m => m.Name == name);
}
public Property FindProperty(string name)
{
return Properties.FirstOrDefault(m => m.Name == name);
}
public Field FindField(string name)
{
return Fields.FirstOrDefault(m => m.Name == name);
}
public override T Visit<T>(IDeclVisitor<T> visitor)
{
return visitor.VisitClassDecl(this);

16
src/AST/Declaration.cs

@ -223,6 +223,22 @@ namespace CppSharp.AST @@ -223,6 +223,22 @@ namespace CppSharp.AST
return namespaces;
}
public DeclarationContext GetRootNamespace()
{
var currentNamespace = Namespace;
while (currentNamespace.Namespace != null)
currentNamespace = currentNamespace.Namespace;
return currentNamespace;
}
public void MoveToNamespace(DeclarationContext @namespace)
{
Namespace = @namespace;
OriginalNamespace?.Declarations.Remove(this);
Namespace?.Declarations.Add(this);
}
public string QualifiedName
{
get

32
src/AST/Namespace.cs

@ -203,17 +203,33 @@ namespace CppSharp.AST @@ -203,17 +203,33 @@ namespace CppSharp.AST
};
}
public Class FindClass(string name,
StringComparison stringComparison = StringComparison.Ordinal)
public Class FindClass(string name)
{
if (string.IsNullOrEmpty(name)) return null;
if (string.IsNullOrEmpty(name))
return null;
var @class = Classes.FirstOrDefault(c => c.Name.Equals(name, stringComparison)) ??
Namespaces.Select(n => n.FindClass(name, stringComparison)).FirstOrDefault(c => c != null);
if (@class != null)
return @class.CompleteDeclaration == null ?
@class : (Class)@class.CompleteDeclaration;
var entries = name.Split(new[] { "::" }, StringSplitOptions.RemoveEmptyEntries)
.ToArray();
if (entries.Length <= 1)
{
var @class = Classes.FirstOrDefault(e => e.Name.Equals(name));
if (@class == null)
return null;
if (@class.CompleteDeclaration == null)
return @class;
return (Class)@class.CompleteDeclaration;
}
var className = entries[^1];
var namespaces = entries.Take(entries.Length - 1);
var @namespace = FindNamespace(namespaces);
return @namespace?.FindClass(className);
}
public Class FindClass(string name, bool isComplete,

1
src/CppParser/AST.cpp

@ -1153,7 +1153,6 @@ namespace CppSharp { namespace CppParser { namespace AST { @@ -1153,7 +1153,6 @@ namespace CppSharp { namespace CppParser { namespace AST {
kind = DeclarationKind::TranslationUnit;
}
TranslationUnit::~TranslationUnit() {}
DEF_VECTOR(TranslationUnit, MacroDefinition*, Macros)
NativeLibrary::NativeLibrary()

347
src/CppParser/Bootstrap/Bootstrap.cs

@ -19,7 +19,7 @@ namespace CppSharp @@ -19,7 +19,7 @@ namespace CppSharp
/// </summary>
internal class Bootstrap : ILibrary
{
private static bool CreatePatch = true;
private static bool CreatePatch = false;
private static string OutputPath = CreatePatch ? "BootstrapPatch" : "";
private static string GetSourceDirectory(string dir)
@ -55,6 +55,7 @@ namespace CppSharp @@ -55,6 +55,7 @@ namespace CppSharp
{
driver.Options.GeneratorKind = GeneratorKind.CSharp;
driver.Options.DryRun = true;
driver.ParserOptions.Verbose = true;
driver.ParserOptions.EnableRTTI = true;
driver.ParserOptions.LanguageVersion = LanguageVersion.CPP17_GNU;
driver.ParserOptions.SkipLayoutInfo = true;
@ -80,10 +81,16 @@ namespace CppSharp @@ -80,10 +81,16 @@ namespace CppSharp
module.Headers.AddRange(new[]
{
"clang/AST/Stmt.h",
"clang/AST/StmtCXX.h",
"clang/AST/Expr.h",
"clang/AST/ExprCXX.h",
//"clang/AST/Stmt.h",
//"clang/AST/StmtCXX.h",
//"clang/AST/Expr.h",
//"clang/AST/ExprCXX.h",
"clang/AST/DeclBase.h",
"clang/AST/Decl.h",
"clang/AST/DeclCXX.h",
"clang/AST/DeclTemplate.h",
"clang/Basic/Builtins.h",
//"clang/AST/Type.h",
});
module.LibraryDirs.Add(Path.Combine(llvmPath, "lib"));
@ -95,12 +102,18 @@ namespace CppSharp @@ -95,12 +102,18 @@ namespace CppSharp
public void Preprocess(Driver driver, ASTContext ctx)
{
CodeGeneratorHelpers.CppTypePrinter = new CppTypePrinter(driver.Context);
CodeGeneratorHelpers.CppTypePrinter.PushScope(TypePrintScopeKind.Local);
new IgnoreMethodsWithParametersPass { Context = driver.Context }
.VisitASTContext(ctx);
new GetterSetterToPropertyPass { Context = driver.Context }
.VisitASTContext(ctx);
new CheckEnumsPass { Context = driver.Context }
.VisitASTContext(ctx);
new CleanCommentsPass { Context = driver.Context }
.VisitASTContext(ctx);
var preprocessDecls = new PreprocessDeclarations();
foreach (var unit in ctx.TranslationUnits)
@ -114,14 +127,13 @@ namespace CppSharp @@ -114,14 +127,13 @@ namespace CppSharp
var exprClass = exprUnit.FindNamespace("clang").FindClass("Expr");
var exprSubclassVisitor = new SubclassVisitor(exprClass);
exprUnit.Visit(exprSubclassVisitor);
exprCxxUnit.Visit(exprSubclassVisitor);
//exprCxxUnit.Visit(exprSubclassVisitor);
ExprClasses = exprSubclassVisitor.Classes;
CodeGeneratorHelpers.CppTypePrinter = new CppTypePrinter(driver.Context);
CodeGeneratorHelpers.CppTypePrinter.PushScope(TypePrintScopeKind.Local);
GenerateStmt(driver.Context);
GenerateExpr(driver.Context);
GenerateDecl(driver.Context);
//GenerateType(driver.Context);
//GenerateStmt(driver.Context);
//GenerateExpr(driver.Context);
}
public void Postprocess(Driver driver, ASTContext ctx)
@ -251,6 +263,262 @@ namespace CppSharp @@ -251,6 +263,262 @@ namespace CppSharp
WriteFile(managedCodeGen, Path.Combine(OutputPath, "Parser", "ASTConverter.Stmt.cs"));
}
private void GenerateType(BindingContext ctx)
{
var typeUnit = ctx.ASTContext.TranslationUnits.Find(unit =>
unit.FileName.Contains("Type.h"));
var typeCxxUnit = ctx.ASTContext.TranslationUnits.Find(unit =>
unit.FileName.Contains("CXXType.h"));
var typeBaseClass = typeUnit.FindNamespace("clang").FindClass("Type");
var typeSubclassVisitor = new SubclassVisitor(typeBaseClass);
typeUnit.Visit(typeSubclassVisitor);
typeCxxUnit?.Visit(typeSubclassVisitor);
var types = typeSubclassVisitor.Classes;
// Validate inheritance for types
var validator = new InheritanceValidator();
validator.ValidateInheritance(types);
// Write the native declarations headers
var declsCodeGen = new TypeDeclarationsCodeGenerator(ctx, types);
declsCodeGen.GenerateDeclarations();
WriteFile(declsCodeGen, Path.Combine(OutputPath, "CppParser", "Type.h"));
var defsCodeGen = new TypeDefinitionsCodeGenerator(ctx, types);
defsCodeGen.GenerateDefinitions();
WriteFile(defsCodeGen, Path.Combine(OutputPath, "CppParser", "Type.cpp"));
// Write the native parsing routines
var parserCodeGen = new TypeParserCodeGenerator(ctx, types);
parserCodeGen.GenerateParser();
WriteFile(parserCodeGen, Path.Combine(OutputPath, "CppParser", "ParseType.cpp"));
// Write the managed declarations
var managedCodeGen = new ManagedParserCodeGenerator(ctx, types);
managedCodeGen.GenerateDeclarations();
WriteFile(managedCodeGen, Path.Combine(OutputPath, "AST", "Type.cs"));
managedCodeGen = new TypeASTConverterCodeGenerator(ctx, types);
managedCodeGen.Process();
WriteFile(managedCodeGen, Path.Combine(OutputPath, "Parser", "ASTConverter.Type.cs"));
}
private void GenerateDecl(BindingContext ctx)
{
var declBaseUnit = ctx.ASTContext.TranslationUnits.Find(unit =>
unit.FileName.Contains("DeclBase.h"));
var declUnit = ctx.ASTContext.TranslationUnits.Find(unit =>
unit.FileName.Contains("Decl.h"));
var declTemplateUnit = ctx.ASTContext.TranslationUnits.Find(unit =>
unit.FileName.Contains("DeclTemplate.h"));
var declCxxUnit = ctx.ASTContext.TranslationUnits.Find(unit =>
unit.FileName.Contains("DeclCXX.h"));
var declClass = declBaseUnit.FindClass("clang::Decl");
var declSubclassVisitor = new SubclassVisitor(declClass);
declBaseUnit.Visit(declSubclassVisitor);
declUnit.Visit(declSubclassVisitor);
declCxxUnit.Visit(declSubclassVisitor);
declTemplateUnit.Visit(declSubclassVisitor);
var declKindEnum = declClass.FindEnum("Kind");
declKindEnum.MoveToNamespace(declKindEnum.GetRootNamespace());
declKindEnum.Name = "DeclarationKind";
CleanupEnumItems(declKindEnum);
CleanupDeclClass(declClass);
var declContextClass = declBaseUnit.FindClass("clang::DeclContext");
var deductionCandidate = declBaseUnit.FindEnum("clang::DeductionCandidate");
CleanupDeclContext(declContextClass);
var multiVersionKind = declUnit.FindEnum("clang::MultiVersionKind");
var explicitSpecifier = declCxxUnit.FindClass("clang::ExplicitSpecifier");
var inheritedConstructor = declCxxUnit.FindClass("clang::InheritedConstructor");
var specifiersUnit = ctx.ASTContext.TranslationUnits.Find(unit => unit.FileName == "Specifiers.h");
var explicitSpecKind = specifiersUnit.FindEnum("clang::ExplicitSpecKind");
var accessSpecifier = specifiersUnit.FindEnum("clang::AccessSpecifier");
var storageClass = specifiersUnit.FindEnum("clang::StorageClass");
var threadStorageClassSpecifier = specifiersUnit.FindEnum("clang::ThreadStorageClassSpecifier");
var templateSpecializationKind = specifiersUnit.FindEnum("clang::TemplateSpecializationKind");
var constexprSpecKind = specifiersUnit.FindEnum("clang::ConstexprSpecKind");
var inClassInitStyle = specifiersUnit.FindEnum("clang::InClassInitStyle");
var linkageUnit = ctx.ASTContext.TranslationUnits.Find(unit => unit.FileName == "Linkage.h");
var linkage = linkageUnit.FindEnum("clang::Linkage");
var languageLinkage = linkageUnit.FindEnum("clang::LanguageLinkage");
var visibilityUnit = ctx.ASTContext.TranslationUnits.Find(unit => unit.FileName == "Visibility.h");
var visibility = visibilityUnit.FindEnum("clang::Visibility");
var linkageInfo = visibilityUnit.FindClass("clang::LinkageInfo");
var pragmaKindsUnit = ctx.ASTContext.TranslationUnits.Find(unit => unit.FileName == "PragmaKinds.h");
var pragmaMSCommentKind = pragmaKindsUnit.FindEnum("clang::PragmaMSCommentKind");
var exceptionSpecificationTypeUnit = ctx.ASTContext.TranslationUnits.Find(unit => unit.FileName == "ExceptionSpecificationType.h");
var exceptionSpecificationType = exceptionSpecificationTypeUnit.FindEnum("clang::ExceptionSpecificationType");
var builtinsUnit = ctx.ASTContext.TranslationUnits.Find(unit => unit.FileName == "Builtins.h");
var builtinTemplateKind = builtinsUnit.FindEnum("clang::BuiltinTemplateKind");
var redeclarableUnit = ctx.ASTContext.TranslationUnits.Find(unit => unit.FileName.Contains("Redeclarable.h"));
var redeclarableClass = redeclarableUnit.FindClass("clang::Redeclarable");
redeclarableClass.TemplateParameters.First().Name = "Decl";
var itr = redeclarableClass.FindClass("redecl_iterator");
itr.Name = "Decl";
itr.MoveToNamespace(itr.GetRootNamespace());
itr.ExplicitlyIgnore();
var CXXRecordDeclClass = declCxxUnit.FindClass("clang::CXXRecordDecl");
var friend_itr = CXXRecordDeclClass.FindClass("friend_iterator");
friend_itr.Name = "FriendDecl";
friend_itr.MoveToNamespace(friend_itr.GetRootNamespace());
friend_itr.ExplicitlyIgnore();
var mergeableClass = redeclarableUnit.FindClass("clang::Mergeable");
mergeableClass.TemplateParameters.First().Name = "Decl";
var memberSpecializationInfo = declTemplateUnit.FindClass("clang::MemberSpecializationInfo");
var functionTemplateSpecializationInfo = declTemplateUnit.FindClass("clang::FunctionTemplateSpecializationInfo");
var dependentFunctionTemplateSpecializationInfo = declTemplateUnit.FindClass("clang::DependentFunctionTemplateSpecializationInfo");
var templateParmPosition = declTemplateUnit.FindClass("clang::TemplateParmPosition");
var templateBaseUnit = ctx.ASTContext.TranslationUnits.Find(unit => unit.FileName.Contains("TemplateBase.h"));
var aSTTemplateArgumentListInfo = templateBaseUnit.FindClass("clang::ASTTemplateArgumentListInfo");
// TODO: Move to type
var typeUnit = ctx.ASTContext.TranslationUnits.Find(unit => unit.FileName == "Type.h");
var refQualifierKind = typeUnit.FindEnum("clang::RefQualifierKind");
var qualifiers = typeUnit.FindClass("clang::Qualifiers");
var decls = new Declaration[]
{
declKindEnum,
multiVersionKind,
explicitSpecKind,
explicitSpecifier,
inheritedConstructor,
accessSpecifier,
storageClass,
threadStorageClassSpecifier,
templateSpecializationKind,
builtinTemplateKind,
inClassInitStyle,
constexprSpecKind,
linkage,
languageLinkage,
visibility,
linkageInfo,
pragmaMSCommentKind,
exceptionSpecificationType,
declContextClass,
redeclarableClass,
mergeableClass,
memberSpecializationInfo,
functionTemplateSpecializationInfo,
dependentFunctionTemplateSpecializationInfo,
aSTTemplateArgumentListInfo,
templateParmPosition,
deductionCandidate,
refQualifierKind, // TODO: Move to type
qualifiers, // TODO: Move to type
}
.Union(declSubclassVisitor.Classes);
// Validate inheritance for declarations
var validator = new InheritanceValidator();
validator.ValidateInheritance(decls);
// Write the native declarations headers
CodeGeneratorHelpers.CppTypePrinter.PushContext(TypePrinterContextKind.Normal);
{
var declsCodeGen = new DeclDeclarationsCodeGenerator(ctx, decls);
declsCodeGen.GenerateDeclarations();
WriteFile(declsCodeGen, Path.Combine(OutputPath, "CppParser", "Declaration.h"));
}
CodeGeneratorHelpers.CppTypePrinter.PopContext();
/*var defsCodeGen = new DeclDefinitionsCodeGenerator(ctx, decls);
defsCodeGen.GenerateDefinitions();
WriteFile(defsCodeGen, Path.Combine(OutputPath, "CppParser", "Decl.cpp"));
// Write the native parsing routines
var parserCodeGen = new DeclParserCodeGenerator(ctx, decls);
parserCodeGen.GenerateParser();
WriteFile(parserCodeGen, Path.Combine(OutputPath, "CppParser", "ParseDecl.cpp"));
// Write the managed declarations
var managedCodeGen = new ManagedParserCodeGenerator(ctx, decls);
managedCodeGen.GenerateDeclarations();
WriteFile(managedCodeGen, Path.Combine(OutputPath, "AST", "Decl.cs"));
managedCodeGen = new DeclASTConverterCodeGenerator(ctx, decls);
managedCodeGen.Process();
WriteFile(managedCodeGen, Path.Combine(OutputPath, "Parser", "ASTConverter.Decl.cs"));*/
}
private void CleanupDeclClass(Class declClass)
{
var decl_itr = declClass.FindClass("redecl_iterator");
decl_itr.Name = "Decl";
decl_itr.MoveToNamespace(decl_itr.GetRootNamespace());
decl_itr.ExplicitlyIgnore();
declClass.Properties
.FindAll(x => x.Name
is "langOpts" // Reason: Not needed
or "declKindName" // Reason: Can use Enum.ToString()
or "specific_attrs" // Reason: Handled in C#
or "versionIntroduced" // Reason: Not needed
|| x.Name.Contains("module", StringComparison.InvariantCultureIgnoreCase) // TODO: Modules are not supported currently
)
.ForEach(x => x.ExplicitlyIgnore());
}
private void CleanupDeclContext(Class declContextClass)
{
foreach (Class @class in declContextClass.Classes.ToArray()
.Where(c => c.OriginalName.EndsWith("_iterator")))
{
// Move to root namespace to prevent qualified names
@class.MoveToNamespace(@class.GetRootNamespace());
if (@class.OriginalName.Contains("decl"))
{
@class.Name = "Decl";
}
else if (@class.OriginalName.Contains("udir"))
{
@class.Name = "UsingDirectiveDecl";
}
@class.ExplicitlyIgnore();
}
declContextClass.Methods
.FindAll(x => x.Name
is "noload_decls" // Reason: No longer relevant
or "ddiags" // Reason: No longer relevant
or "lookups" // TODO: Difficult to map
).ForEach(x => x.ExplicitlyIgnore());
declContextClass.Properties
.FindAll(x => x.Name
is "declKindName" // Reason: In C# you can use Enum.ToString()
or "decls_empty" // Reason: This is a simple IsEmpty() check
or "lookupPtr" // TODO: Difficult to map
)
.ForEach(x => x.ExplicitlyIgnore());
}
private static void CleanupEnumItems(Enumeration exprClassEnum)
{
foreach (var item in exprClassEnum.Items)
@ -320,7 +588,7 @@ namespace CppSharp @@ -320,7 +588,7 @@ namespace CppSharp
{
private static void Check(Declaration decl)
{
if (string.IsNullOrWhiteSpace(decl.Name))
if (decl is not TranslationUnit && string.IsNullOrWhiteSpace(decl.Name))
{
decl.ExplicitlyIgnore();
return;
@ -345,16 +613,26 @@ namespace CppSharp @@ -345,16 +613,26 @@ namespace CppSharp
decl.ExplicitlyIgnore();
}
public override bool VisitDeclaration(Declaration decl)
{
if (!base.VisitDeclaration(decl) || decl.Ignore)
return false;
Check(decl);
return !decl.Ignore;
}
public override bool VisitClassDecl(Class @class)
{
//
// Statements
//
if (@class.Ignore)
return false;
if (CodeGeneratorHelpers.IsAbstractStmt(@class))
if (IsAbstractType(@class) || IsAbstractDecl(@class) || IsAbstractStmt(@class))
@class.IsAbstract = true;
Check(@class);
//
// Statements
//
foreach (var @base in @class.Bases)
{
@ -426,32 +704,45 @@ namespace CppSharp @@ -426,32 +704,45 @@ namespace CppSharp
}
}
return base.VisitClassDecl(@class);
return base.VisitClassDecl(@class) && !@class.Ignore;
}
public override bool VisitClassTemplateDecl(ClassTemplate template)
{
Check(template);
return base.VisitClassTemplateDecl(template);
}
public override bool VisitTypeAliasTemplateDecl(TypeAliasTemplate template)
{
Check(template);
return base.VisitTypeAliasTemplateDecl(template);
}
public override bool VisitProperty(Property property)
{
if (property.Name == "stripLabelLikeStatements")
if (!base.VisitProperty(property))
return false;
// TODO: Remove null check once auto types are handled properly
if (property.Type == null || property.Name == "stripLabelLikeStatements")
{
property.ExplicitlyIgnore();
return false;
}
var typeName = property.Type.Visit(CodeGeneratorHelpers.CppTypePrinter).Type;
// Ignore properties that use internal Clang types
if (typeName.Contains("DeclContext") ||
typeName.Contains("ASTContext") ||
typeName.Contains("TypeLoc"))
property.ExplicitlyIgnore();
return base.VisitProperty(property);
return true;
}
public override bool VisitEnumDecl(Enumeration @enum)
{
if (AlreadyVisited(@enum))
if (!base.VisitEnumDecl(@enum))
return false;
if (@enum.Name == "APFloatSemantics")
@ -464,7 +755,7 @@ namespace CppSharp @@ -464,7 +755,7 @@ namespace CppSharp
RemoveEnumItemsPrefix(@enum);
return base.VisitEnumDecl(@enum);
return true;
}
private void RemoveEnumItemsPrefix(Enumeration @enum)
@ -586,7 +877,7 @@ namespace CppSharp @@ -586,7 +877,7 @@ namespace CppSharp
public override bool VisitClassDecl(Class @class)
{
if (!@class.IsGenerated)
if (SkipClass(@class))
return false;
GenerateClassSpecifier(@class);
@ -953,6 +1244,7 @@ namespace CppSharp @@ -953,6 +1244,7 @@ namespace CppSharp
{
Context.Options.GeneratorKind = GeneratorKind.CPlusPlus;
CTypePrinter.PushScope(TypePrintScopeKind.Local);
CTypePrinter.PushContext(TypePrinterContextKind.Normal);
GenerateFilePreamble(CommentKind.BCPL);
NewLine();
@ -1042,7 +1334,12 @@ namespace CppSharp @@ -1042,7 +1334,12 @@ namespace CppSharp
return $"{typeName}()";
if (property.Type.TryGetEnum(out Enumeration @enum))
{
if (@enum.Items.Count == 0) // Strongly typed integer?
return $"({GetQualifiedName(@enum)})0";
return $"{GetQualifiedName(@enum)}::{@enum.Items.First().Name}";
}
return "0";
}

263
src/CppParser/Bootstrap/CodeGeneratorHelpers.cs

@ -9,6 +9,44 @@ using CppSharp.Passes; @@ -9,6 +9,44 @@ using CppSharp.Passes;
namespace CppSharp
{
class TemplateArgumentHandler
{
public static string GetTemplateArgumentTypeName(TemplateArgument arg, CppTypePrinter printer)
{
switch (arg.Kind)
{
case TemplateArgument.ArgumentKind.Type:
return GetTemplateTypeArgName(arg.Type, printer);
case TemplateArgument.ArgumentKind.Declaration:
return GetTemplateDeclArgName(arg.Declaration, printer);
case TemplateArgument.ArgumentKind.NullPtr:
return "nullptr_t";
case TemplateArgument.ArgumentKind.Integral:
return GetTemplateIntegralArgName(arg.Integral, printer);
default:
throw new NotImplementedException($"Unhandled template argument kind: {arg.Kind}");
}
}
private static string GetTemplateTypeArgName(QualifiedType type, CppTypePrinter printer)
{
var typeStr = type.Type.Visit(printer).Type;
if (type.Type.IsPointer())
return $"{typeStr}*";
return typeStr;
}
private static string GetTemplateDeclArgName(Declaration decl, CppTypePrinter printer)
{
return decl?.Visit(printer).Type ?? "nullptr";
}
private static string GetTemplateIntegralArgName(long value, CppTypePrinter printer)
{
return value.ToString();
}
}
internal static class CodeGeneratorHelpers
{
internal static CppTypePrinter CppTypePrinter;
@ -31,6 +69,17 @@ namespace CppSharp @@ -31,6 +69,17 @@ namespace CppSharp
or "OverloadExpr"
or "CoroutineSuspendExpr";
public static bool SkipClass(Class @class)
{
if (!@class.IsGenerated)
return true;
if (@class.Access != AccessSpecifier.Public)
return true;
return false;
}
public static bool SkipProperty(Property property, bool skipBaseCheck = false)
{
if (!property.IsGenerated)
@ -47,8 +96,7 @@ namespace CppSharp @@ -47,8 +96,7 @@ namespace CppSharp
return true;
}
if (property.Name is "beginLoc" or "endLoc" &&
@class.Name != "Stmt")
if (property.Name is "beginLoc" or "endLoc" && @class.Name != "Stmt")
return true;
switch (property.Name)
@ -62,11 +110,22 @@ namespace CppSharp @@ -62,11 +110,22 @@ namespace CppSharp
var typeName = property.Type.Visit(CppTypePrinter).Type;
// General properties.
if (typeName.Contains("_iterator") ||
typeName.Contains("_range") ||
property.Name.Contains("_begin") ||
property.Name.Contains("_end") ||
property.Name.Contains("_empty") ||
property.Name.Contains("_size"))
return true;
return false;
//
// Statement properties.
//
if (typeName.Contains("LabelDecl") ||
/*if (typeName.Contains("LabelDecl") ||
typeName.Contains("VarDecl") ||
typeName.Contains("Token") ||
typeName.Contains("CapturedDecl") ||
@ -78,7 +137,7 @@ namespace CppSharp @@ -78,7 +137,7 @@ namespace CppSharp
typeName.Contains("NestedNameSpecifierLoc") ||
typeName.Contains("DeclarationNameInfo") ||
typeName.Contains("DeclGroupRef"))
return true;
return true;*/
//
// Expressions
@ -210,11 +269,6 @@ namespace CppSharp @@ -210,11 +269,6 @@ namespace CppSharp
if (typeName.Contains("StorageDuration"))
return true;
// General properties.
if (typeName.Contains("_iterator") ||
typeName.Contains("_range"))
return true;
if (typeName.Contains("ArrayRef"))
return true;
@ -247,7 +301,7 @@ namespace CppSharp @@ -247,7 +301,7 @@ namespace CppSharp
public static bool SkipMethod(Method method)
{
if (method.Ignore)
if (method.IsGenerated)
return true;
var @class = method.Namespace as Class;
@ -319,11 +373,13 @@ namespace CppSharp @@ -319,11 +373,13 @@ namespace CppSharp
private static string CleanClangNamespaceFromName(string qualifiedName)
{
qualifiedName = qualifiedName.StartsWith("clang::") ?
qualifiedName.Substring("clang::".Length) : qualifiedName;
qualifiedName = qualifiedName.StartsWith("clang::")
? qualifiedName.Substring("clang::".Length)
: qualifiedName;
qualifiedName = qualifiedName.StartsWith("clang.") ?
qualifiedName.Substring("clang.".Length) : qualifiedName;
qualifiedName = qualifiedName.StartsWith("clang.")
? qualifiedName.Substring("clang.".Length)
: qualifiedName;
return qualifiedName;
}
@ -334,9 +390,15 @@ namespace CppSharp @@ -334,9 +390,15 @@ namespace CppSharp
if (kind == GeneratorKind.CPlusPlus)
{
if (Generators.C.CCodeGenerator.IsReservedKeyword(name))
if (name == "inline")
{
name = "isInline";
}
else if (Generators.C.CCodeGenerator.IsReservedKeyword(name))
{
name = $"_{name}";
}
}
else if (kind == GeneratorKind.CSharp)
{
bool hasConflict = false;
@ -371,7 +433,7 @@ namespace CppSharp @@ -371,7 +433,7 @@ namespace CppSharp
TypePrinter typePrinter)
{
var qualifiedType = new QualifiedType(type);
if (qualifiedType.Type.IsPointerTo(out TagType tagType))
if (qualifiedType.Type.IsPointerTo(out TagType _))
qualifiedType = qualifiedType.StripConst();
var typeName = qualifiedType.Type.Visit(typePrinter).Type;
@ -392,7 +454,8 @@ namespace CppSharp @@ -392,7 +454,8 @@ namespace CppSharp
if (typeResult.Type.Contains("MSGuidDecl"))
return typePrinter is CppTypePrinter
? "std::string" : "string";
? "std::string"
: "string";
var typeName = typeResult.ToString();
typeName = CleanClangNamespaceFromName(typeName);
@ -421,62 +484,23 @@ namespace CppSharp @@ -421,62 +484,23 @@ namespace CppSharp
}
}
string className = null;
if (typeName.Contains("FieldDecl"))
className = "Field";
else if (typeName.Contains("NamedDecl"))
className = "Declaration";
else if (typeName.Contains("CXXMethodDecl"))
className = "Method";
else if (typeName.Contains("FunctionDecl"))
className = "Function";
else if (typeName.Contains("FunctionTemplateDecl"))
className = "FunctionTemplate";
else if (typeName is "Decl" or "Decl*")
className = "Declaration";
if (className != null)
return (typePrinter is CppTypePrinter) ?
$"{className}*" : className;
return typeName;
}
public static AST.Type GetIteratorType(Method method)
{
var retType = method.ReturnType.Type;
var retType = method.ReturnType.Type.Desugar();
TemplateSpecializationType templateSpecType;
TypedefType typedefType;
TypedefNameDecl typedefNameDecl;
if (retType is TemplateSpecializationType templateSpecType)
retType = templateSpecType.Arguments[0].Type.Type.Desugar();
if (retType is TemplateSpecializationType)
{
templateSpecType = retType as TemplateSpecializationType;
typedefType = templateSpecType.Arguments[0].Type.Type as TypedefType;
typedefNameDecl = typedefType.Declaration as TypedefNameDecl;
}
else
{
typedefType = retType as TypedefType;
typedefNameDecl = typedefType.Declaration as TypedefNameDecl;
templateSpecType = typedefNameDecl.Type as TemplateSpecializationType;
typedefType = templateSpecType.Arguments[0].Type.Type as TypedefType;
typedefNameDecl = typedefType.Declaration as TypedefNameDecl;
typedefType = typedefNameDecl.Type as TypedefType;
if (typedefType != null)
typedefNameDecl = typedefType.Declaration as TypedefNameDecl;
}
if (retType.IsPointerTo(out PointerType pointee))
retType = pointee;
var iteratorType = typedefNameDecl.Type;
if (iteratorType.IsPointerTo(out PointerType pointee))
iteratorType = iteratorType.GetPointee();
return iteratorType;
return retType;
}
public static string GetIteratorTypeName(AST.Type iteratorType,
TypePrinter typePrinter)
public static string GetIteratorTypeName(AST.Type iteratorType, TypePrinter typePrinter)
{
if (iteratorType.IsPointer())
iteratorType = iteratorType.GetFinalPointee();
@ -493,7 +517,8 @@ namespace CppSharp @@ -493,7 +517,8 @@ namespace CppSharp
else if (iteratorTypeName.Contains("StmtIterator"))
iteratorTypeName = "Stmt";
else if (iteratorTypeName.Contains("CastIterator"))
else if (iteratorTypeName.Contains("CastIterator") ||
iteratorTypeName.Contains("DeclContext::"))
{
if (iteratorType is TypedefType typedefType)
iteratorType = typedefType.Declaration.Type;
@ -508,9 +533,6 @@ namespace CppSharp @@ -508,9 +533,6 @@ namespace CppSharp
iteratorTypeName = CleanClangNamespaceFromName(iteratorTypeName);
}
if (iteratorTypeName == "Decl")
iteratorTypeName = "Declaration";
if (typePrinter is CppTypePrinter)
return $"{iteratorTypeName}*";
@ -525,8 +547,7 @@ namespace CppSharp @@ -525,8 +547,7 @@ namespace CppSharp
while (currentClass != null)
{
baseClasses.Add(currentClass);
currentClass = currentClass.HasBaseClass ?
currentClass.BaseClass : null;
currentClass = currentClass.HasBaseClass ? currentClass.BaseClass : null;
}
baseClasses.Reverse();
@ -547,5 +568,109 @@ namespace CppSharp @@ -547,5 +568,109 @@ namespace CppSharp
a[0] = char.ToUpper(a[0]);
return new string(a);
}
public static bool SkipDeclProperty(Property property)
{
if (!property.IsGenerated || property.Access != AccessSpecifier.Public)
return true;
var @class = property.Namespace as Class;
if (@class.GetBaseProperty(property) != null)
return true;
var typeName = property.Type.Visit(CppTypePrinter).Type;
// Skip properties that deal with source locations/ranges
if (typeName.Contains("SourceLocation") || typeName.Contains("SourceRange"))
return true;
// Skip Clang-specific internal properties
if (typeName.Contains("ASTContext") || typeName.Contains("DeclContext"))
return true;
// Skip template-specific properties that are handled separately
if (typeName.Contains("TemplateParameterList") ||
typeName.Contains("TemplateArgument"))
return true;
return false;
}
public static bool SkipTypeProperty(Property property)
{
if (!property.IsGenerated || property.Access != AccessSpecifier.Public)
return true;
var @class = property.Namespace as Class;
if (@class.GetBaseProperty(property) != null)
return true;
var typeName = property.Type.Visit(CppTypePrinter).Type;
// Skip source location properties
if (typeName.Contains("SourceLocation"))
return true;
// Skip internal Clang type properties
if (typeName.Contains("TypeLoc") || typeName.Contains("ASTContext"))
return true;
return false;
}
public static bool IsAbstractType(Class @class) =>
@class.Name is "Type"
or "ArrayType"
or "TagType"
or "FunctionType";
public static bool IsAbstractDecl(Class @class) =>
@class.Name is "Decl"
or "NamedDecl"
or "ValueDecl"
or "TypeDecl"
or "DeclContext";
public static string GetPropertyAccessorName(Property property, bool isGetter)
{
var baseName = FirstLetterToUpperCase(GetDeclName(property));
return isGetter ? $"Get{baseName}" : $"Set{baseName}";
}
public static string GetPropertyTypeName(Property property, bool includeNamespace = true)
{
var typeName = GetDeclTypeName(property);
// Handle special cases
if (typeName.Contains("QualType") ||
(property.Type.IsPointerTo(out TagType tagType) &&
tagType.Declaration?.Name.Contains("Type") == true))
{
return includeNamespace ? $"AST::{typeName}" : typeName;
}
// Handle template types
if (property.Type is TemplateSpecializationType templateType)
{
var templateName = templateType.Template.TemplatedDecl.Name;
return includeNamespace ? $"AST::{templateName}" : templateName;
}
return typeName;
}
public static bool IsTypeProperty(Property property)
{
if (property.Type.IsPointerTo(out TagType tagType))
return tagType.Declaration?.Name.Contains("Type") == true;
var typeName = GetDeclTypeName(property);
return typeName.Contains("QualType") ||
typeName.Contains("Type") ||
(property.Type is TemplateSpecializationType templateType &&
templateType.Template.TemplatedDecl.Name.Contains("Type"));
}
}
}

221
src/CppParser/Bootstrap/DeclCodeGenerators.cs

@ -0,0 +1,221 @@ @@ -0,0 +1,221 @@
using System;
using System.Collections.Generic;
using System.Linq;
using CppSharp.AST;
using CppSharp.AST.Extensions;
using CppSharp.Generators;
using CppSharp.Generators.C;
using CppSharp.Generators.CSharp;
using static CppSharp.CodeGeneratorHelpers;
namespace CppSharp
{
internal class DeclDeclarationsCodeGenerator : DeclarationsCodeGenerator
{
public DeclDeclarationsCodeGenerator(BindingContext context, IEnumerable<Declaration> declarations)
: base(context, declarations)
{
}
public override string BaseTypeName => "Decl";
public override void GenerateIncludes()
{
WriteInclude("Sources.h", CInclude.IncludeKind.Quoted);
WriteInclude("Types.h", CInclude.IncludeKind.Quoted);
WriteInclude("string", CInclude.IncludeKind.Angled);
}
public override void GenerateForwardDecls()
{
WriteLine("class Expr;");
WriteLine("class Stmt;");
WriteLine("class LabelStmt;");
WriteLine("class EvaluatedStmt;");
WriteLine("class CompoundStmt;");
WriteLine("enum class OverloadedOperatorKind;");
NewLine();
WriteLine("class Declaration;");
WriteLine("class UsingDirectiveDecl;");
WriteLine("class FriendDecl;");
WriteLine("class ConstructorUsingShadowDecl;");
WriteLine("class LinkageSpecDecl;");
WriteLine("class NamedDecl;");
WriteLine("class NamespaceDecl;");
WriteLine("class TemplateDecl;");
WriteLine("class ClassTemplateDecl;");
WriteLine("class VarTemplateDecl;");
WriteLine("class TypeAliasTemplateDecl;");
WriteLine("class FunctionDecl;");
WriteLine("class FunctionTemplateDecl;");
WriteLine("class CXXMethodDecl;");
WriteLine("class CXXConstructorDecl;");
WriteLine("class CXXDestructorDecl;");
WriteLine("class BaseUsingDecl;");
}
public override bool VisitClassDecl(Class @class)
{
if (SkipClass(@class))
return false;
@class.Bases.Find(x => x.Class?.Name == "Node")
?.ExplicitlyIgnore();
return base.VisitClassDecl(@class);
}
public override bool GenerateClassBody(Class @class)
{
Unindent();
WriteLine("public:");
Indent();
PushBlock();
VisitDeclContext(@class);
PopBlock(NewLineKind.Always);
WriteLine($"{@class.Name}();");
foreach (var method in @class.Methods)
{
if (SkipMethod(method))
continue;
var iteratorType = GetIteratorType(method);
string iteratorTypeName = GetIteratorTypeName(iteratorType, CodeGeneratorHelpers.CppTypePrinter);
WriteLine($"VECTOR({iteratorTypeName}, {method.Name})");
}
foreach (var property in @class.Properties)
{
if (SkipProperty(property) || property.IsStatic)
continue;
string typeName = GetDeclTypeName(property);
if (typeName.StartsWith("TemplateArgumentList"))
{
WriteLine($"VECTOR(TemplateArgument*, {GetDeclName(property)})");
}
else if (typeName.StartsWith("TemplateParameterList"))
{
WriteLine($"VECTOR(NamedDecl*, {GetDeclName(property)})");
}
else
{
WriteLine($"{typeName} {GetDeclName(property)};");
}
}
return true;
}
}
internal class DeclDefinitionsCodeGenerator : DefinitionsCodeGenerator
{
public DeclDefinitionsCodeGenerator(BindingContext context, IEnumerable<Declaration> declarations)
: base(context, declarations)
{
}
public override string BaseTypeName => "Decl";
public override void GenerateIncludes()
{
GenerateCommonIncludes();
NewLine();
WriteInclude("Decl.h", CInclude.IncludeKind.Quoted);
WriteInclude("Types.h", CInclude.IncludeKind.Quoted);
}
public override bool VisitClassDecl(Class @class)
{
if (!@class.IsGenerated)
return false;
VisitDeclContext(@class);
var isBaseType = @class.Name == BaseTypeName;
if (!isBaseType && !@class.HasBaseClass)
{
WriteLine($"{GetQualifiedName(@class)}::{@class.Name}()");
WriteOpenBraceAndIndent();
UnindentAndWriteCloseBrace();
NewLine();
return true;
}
WriteLine($"{@class.Name}::{@class.Name}()");
GenerateMemberInits(@class);
WriteOpenBraceAndIndent();
UnindentAndWriteCloseBrace();
NewLine();
foreach (var method in @class.Methods)
{
if (SkipMethod(method))
continue;
var iteratorType = GetIteratorType(method);
string iteratorTypeName = GetIteratorTypeName(iteratorType,
CodeGeneratorHelpers.CppTypePrinter);
WriteLine($"DEF_VECTOR({@class.Name}, {iteratorTypeName}, {method.Name})");
NewLine();
}
return true;
}
}
internal class DeclASTConverterCodeGenerator : ASTConverterCodeGenerator
{
public DeclASTConverterCodeGenerator(BindingContext context, IEnumerable<Declaration> declarations)
: base(context, declarations)
{
}
public override string BaseTypeName => "Decl";
public override bool IsAbstractASTNode(Class kind)
{
return IsAbstractDecl(kind);
}
protected override void GenerateVisitorSwitch(IEnumerable<string> classes)
{
WriteLine($"switch({ParamName}.DeclKind)");
WriteOpenBraceAndIndent();
GenerateSwitchCases(classes);
UnindentAndWriteCloseBrace();
}
private void GenerateSwitchCases(IEnumerable<string> classes)
{
foreach (var className in classes)
{
WriteLine($"case Parser.AST.{BaseTypeName}Kind.{className}:");
WriteLineIndent($"return Visit{className}({ParamName} as Parser.AST.{className}Decl);");
}
foreach (var className in classes)
{
WriteLine($"case StmtClass.{className}:");
WriteOpenBraceAndIndent();
WriteLine($"var _{ParamName} = {className}.__CreateInstance({ParamName}.__Instance);");
WriteLine($"return Visit{className}(_{ParamName});");
UnindentAndWriteCloseBrace();
}
WriteLine("default:");
WriteLineIndent($"throw new System.NotImplementedException({ParamName}.DeclKind.ToString());");
}
}
}

55
src/CppParser/Bootstrap/InheritanceValidator.cs

@ -0,0 +1,55 @@ @@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Linq;
using CppSharp.AST;
namespace CppSharp
{
class InheritanceValidator
{
private readonly HashSet<string> _processedClasses = new();
public void ValidateInheritance(IEnumerable<Declaration> declarations)
{
foreach (var decl in declarations.OfType<Class>())
{
if (!_processedClasses.Add(decl.Name))
continue;
ValidateClassInheritance(decl);
}
}
private static void ValidateClassInheritance(Class @class)
{
if (@class.Bases.Count == 0)
return;
foreach (var @base in @class.Bases)
{
if (@base.Class == null)
continue;
ValidateClassInheritance(@base.Class);
}
// Ensure base class properties don't conflict
foreach (var property in @class.Properties)
{
if (@class.GetBaseProperty(property) != null)
{
property.ExplicitlyIgnore();
}
}
// Handle method overrides
foreach (var method in @class.Methods)
{
if (@class.GetBaseMethod(method) != null)
{
method.ExplicitlyIgnore();
}
}
}
}
}

104
src/CppParser/Bootstrap/ParserCodeGenerators.cs

@ -0,0 +1,104 @@ @@ -0,0 +1,104 @@
using System;
using System.Collections.Generic;
using System.Linq;
using CppSharp.AST;
using CppSharp.AST.Extensions;
using CppSharp.Generators;
using CppSharp.Generators.C;
using CppSharp.Generators.CSharp;
using static CppSharp.CodeGeneratorHelpers;
namespace CppSharp
{
class DeclParserCodeGenerator : StmtParserCodeGenerator
{
public DeclParserCodeGenerator(BindingContext context,
IEnumerable<Declaration> declarations)
: base(context, declarations, null)
{
}
public override void GenerateIncludes()
{
WriteInclude("clang/AST/Decl.h", CInclude.IncludeKind.Angled);
WriteInclude("clang/AST/DeclCXX.h", CInclude.IncludeKind.Angled);
WriteInclude("clang/AST/DeclTemplate.h", CInclude.IncludeKind.Angled);
}
public override string BaseTypeName => "Decl";
public override string MethodSig =>
"AST::Decl* Parser::WalkDeclaration(const clang::Decl* Decl)";
public override bool VisitProperty(Property property)
{
if (SkipDeclProperty(property))
return false;
var typeName = GetDeclTypeName(property);
var fieldName = GetDeclName(property);
var methodName = property.GetMethod?.Name;
Write($"_D->{fieldName} = ");
if (property.Type.TryGetClass(out Class @class))
{
if (@class.Name.Contains("Type"))
WriteLine($"GetQualifiedType(D->{methodName}());");
else if (@class.Name.Contains("Decl"))
WriteLine($"WalkDeclaration(D->{methodName}());");
else
WriteLine($"D->{methodName}();");
}
else
WriteLine($"D->{methodName}();");
return true;
}
}
class TypeParserCodeGenerator : StmtParserCodeGenerator
{
public TypeParserCodeGenerator(BindingContext context,
IEnumerable<Declaration> declarations)
: base(context, declarations, null)
{
}
public override void GenerateIncludes()
{
WriteInclude("clang/AST/Type.h", CInclude.IncludeKind.Angled);
WriteInclude("clang/AST/CXXType.h", CInclude.IncludeKind.Angled);
}
public override string BaseTypeName => "Type";
public override string MethodSig =>
"AST::Type* Parser::WalkType(const clang::Type* Type)";
public override bool VisitProperty(Property property)
{
if (CodeGeneratorHelpers.SkipTypeProperty(property))
return false;
var typeName = GetDeclTypeName(property);
var fieldName = GetDeclName(property);
var methodName = property.GetMethod?.Name;
WriteLine($"_T->{fieldName} = ");
if (property.Type.TryGetClass(out Class @class))
{
if (@class.Name.Contains("Type"))
WriteLine($"GetQualifiedType(T->{methodName}());");
else if (@class.Name.Contains("Decl"))
WriteLine($"WalkDeclaration(T->{methodName}());");
else
WriteLine($"T->{methodName}();");
}
else
WriteLine($"T->{methodName}();");
return true;
}
}
}

2
src/CppParser/Bootstrap/Properties/launchSettings.json

@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
"profiles": {
"CppSharp.Parser.Bootstrap": {
"commandName": "Project",
"nativeDebugging": true
"nativeDebugging": false
}
}
}

24
src/CppParser/Bootstrap/StmtCodeGenerators.cs

@ -66,8 +66,7 @@ namespace CppSharp @@ -66,8 +66,7 @@ namespace CppSharp
continue;
var iteratorType = GetIteratorType(method);
string iteratorTypeName = GetIteratorTypeName(iteratorType,
CodeGeneratorHelpers.CppTypePrinter);
string iteratorTypeName = GetIteratorTypeName(iteratorType, CodeGeneratorHelpers.CppTypePrinter);
WriteLine($"VECTOR({iteratorTypeName}, {method.Name})");
}
@ -114,6 +113,12 @@ namespace CppSharp @@ -114,6 +113,12 @@ namespace CppSharp
return true;
}
//PushBlock(BlockKind.Class, @class);
//GenerateDeclarationCommon(@class);
//GenerateClassSpecifier(@class);
WriteLine($"{@class.Name}::{@class.Name}()");
var stmtMember = isStmt ? "stmtClass" : @class.BaseClass.Name;
var stmtClass = IsAbstractStmt(@class) ? "NoStmt" : @class.Name;
@ -301,9 +306,22 @@ namespace CppSharp @@ -301,9 +306,22 @@ namespace CppSharp
{
walkMethod = "WalkStatement";
}
else if (iteratorTypeName.Contains("Attr"))
{
walkMethod = "WalkDeclaration";
}
else if (iteratorTypeName.Contains("CXXBaseSpecifier"))
{
walkMethod = "WalkDeclaration";
}
else if (iteratorTypeName.Contains("CXXCtorInitializer"))
{
walkMethod = "WalkDeclaration";
}
else
{
throw new NotImplementedException();
//throw new NotImplementedException();
walkMethod = "WalkDeclaration";
}
WriteLine("auto _ES = {0}{1}(_E);", isBaseType ? string.Empty : $"(AST::{iteratorTypeName})", walkMethod);

323
src/CppParser/Bootstrap/TypeCodeGenerators.cs

@ -0,0 +1,323 @@ @@ -0,0 +1,323 @@
using System;
using System.Collections.Generic;
using System.Linq;
using CppSharp.AST;
using CppSharp.AST.Extensions;
using CppSharp.Generators;
using CppSharp.Generators.C;
using CppSharp.Generators.CSharp;
using static CppSharp.CodeGeneratorHelpers;
namespace CppSharp
{
class TypeDeclarationsCodeGenerator : StmtDeclarationsCodeGenerator
{
public TypeDeclarationsCodeGenerator(BindingContext context,
IEnumerable<Declaration> declarations)
: base(context, declarations)
{
}
public override void GenerateIncludes()
{
WriteInclude("Sources.h", CInclude.IncludeKind.Quoted);
WriteInclude("string", CInclude.IncludeKind.Angled);
WriteInclude("memory", CInclude.IncludeKind.Angled);
WriteInclude("vector", CInclude.IncludeKind.Angled);
}
public override void GenerateForwardDecls()
{
WriteLine("class Decl;");
WriteLine("class TemplateArgument;");
WriteLine("class TemplateParameterList;");
}
public override bool VisitClassDecl(Class @class)
{
if (!@class.IsGenerated)
return false;
GenerateClassSpecifier(@class);
NewLine();
WriteOpenBraceAndIndent();
PushBlock();
VisitDeclContext(@class);
PopBlock(NewLineKind.Always);
WriteLine($"public:");
Indent();
WriteLine($"{@class.Name}();");
if (@class.Name == "Type")
WriteLine("TypeClass typeClass;");
foreach (var method in @class.Methods)
{
if (SkipMethod(method))
continue;
GenerateMethod(method);
}
foreach (var property in @class.Properties)
{
if (SkipProperty(property))
continue;
GenerateProperty(property);
}
Unindent();
UnindentAndWriteCloseBrace();
return true;
}
protected void GenerateMethod(Method method)
{
// Validate all method parameters first
foreach (var param in method.Parameters)
{
ValidateTypeMethodParameter(param);
}
var iteratorType = GetIteratorType(method);
var iteratorTypeName = GetIteratorTypeName(iteratorType, CodeGeneratorHelpers.CppTypePrinter);
// Handle special cases for type-specific methods
if (method.ReturnType.Type.IsPointer())
{
var returnTypeName = ValidateTypeMethodReturnType(method.ReturnType.Type);
WriteLine($"{returnTypeName} Get{method.Name}(uint i);");
}
else
WriteLine($"{iteratorTypeName} Get{method.Name}(uint i);");
WriteLine($"uint Get{method.Name}Count();");
}
private string ValidateTypeMethodReturnType(AST.Type type)
{
if (type.IsPointerTo(out TagType tagType))
{
var pointeeType = tagType.Declaration?.Visit(CodeGeneratorHelpers.CppTypePrinter).Type ?? "void";
if (pointeeType.Contains("Type") || pointeeType.Contains("QualType"))
return $"AST::{pointeeType}*";
return $"{pointeeType}*";
}
if (type is TemplateSpecializationType template)
{
if (template.Template.TemplatedDecl.Name.Contains("Type"))
return $"AST::{template.Template.TemplatedDecl.Name}";
}
return type.Visit(CodeGeneratorHelpers.CppTypePrinter).ToString();
}
private void ValidateTypeMethodParameter(Parameter param)
{
// Handle pointer types
if (param.Type.IsPointer())
{
var pointee = param.Type.GetFinalPointee();
if (pointee is ArrayType)
{
param.ExplicitlyIgnore();
return;
}
// Special handling for type-related pointers
if (pointee is TagType tagType &&
tagType.Declaration?.Name.Contains("Type") == true)
{
// These are valid, don't ignore
return;
}
}
// Handle template parameters specific to types
if (param.Type is TemplateSpecializationType template)
{
var templateName = template.Template.TemplatedDecl.Name;
if (!templateName.Contains("Type") &&
!templateName.Contains("QualType"))
{
param.ExplicitlyIgnore();
}
}
}
protected void GenerateProperty(Property property)
{
var typeName = GetDeclTypeName(property);
var fieldName = GetDeclName(property);
// Handle special type properties
if (typeName.Contains("QualType"))
{
WriteLine($"AST::{typeName} {fieldName};");
if (property.GetMethod != null)
WriteLine($"AST::{typeName} Get{FirstLetterToUpperCase(fieldName)}() const;");
if (property.SetMethod != null)
WriteLine($"void Set{FirstLetterToUpperCase(fieldName)}(AST::{typeName} value);");
}
else if (property.Type.IsPointerTo(out TagType tagType))
{
var pointeeType = tagType.Declaration?.Visit(CodeGeneratorHelpers.CppTypePrinter).Type ?? typeName;
if (pointeeType.Contains("Type") || pointeeType.Contains("QualType"))
{
WriteLine($"AST::{pointeeType}* {fieldName};");
if (property.GetMethod != null)
WriteLine($"AST::{pointeeType}* Get{FirstLetterToUpperCase(fieldName)}() const;");
if (property.SetMethod != null)
WriteLine($"void Set{FirstLetterToUpperCase(fieldName)}(AST::{pointeeType}* value);");
}
else
{
WriteLine($"{pointeeType}* {fieldName};");
if (property.GetMethod != null)
WriteLine($"{pointeeType}* Get{FirstLetterToUpperCase(fieldName)}() const;");
if (property.SetMethod != null)
WriteLine($"void Set{FirstLetterToUpperCase(fieldName)}({pointeeType}* value);");
}
}
// Handle template specialization types
else if (property.Type is TemplateSpecializationType templateType)
{
var templateName = templateType.Template.TemplatedDecl.Name;
WriteLine($"AST::{templateName} {fieldName};");
if (property.GetMethod != null)
WriteLine($"AST::{templateName} Get{FirstLetterToUpperCase(fieldName)}() const;");
if (property.SetMethod != null)
WriteLine($"void Set{FirstLetterToUpperCase(fieldName)}(AST::{templateName} value);");
}
else
{
WriteLine($"{typeName} {fieldName};");
if (property.GetMethod != null)
WriteLine($"{typeName} Get{FirstLetterToUpperCase(fieldName)}() const;");
if (property.SetMethod != null)
WriteLine($"void Set{FirstLetterToUpperCase(fieldName)}({typeName} value);");
}
}
}
class TypeDefinitionsCodeGenerator : StmtDefinitionsCodeGenerator
{
public TypeDefinitionsCodeGenerator(BindingContext context,
IEnumerable<Declaration> declarations)
: base(context, declarations)
{
}
public override void GenerateIncludes()
{
GenerateCommonIncludes();
WriteInclude("Type.h", CInclude.IncludeKind.Quoted);
}
protected void GenerateMethodDefinition(Class @class, Method method)
{
var iteratorType = GetIteratorType(method);
var iteratorTypeName = GetIteratorTypeName(iteratorType, CodeGeneratorHelpers.CppTypePrinter);
WriteLine($"uint {GetQualifiedName(@class)}::Get{method.Name}Count()");
WriteOpenBraceAndIndent();
WriteLine($"return {method.Name}().size();");
UnindentAndWriteCloseBrace();
NewLine();
// Handle pointer types specially
if (method.ReturnType.Type.IsPointerTo(out TagType tagType))
{
var pointeeType = tagType.Declaration?.Name ?? iteratorTypeName;
WriteLine($"AST::{pointeeType}* {GetQualifiedName(@class)}::Get{method.Name}(uint i)");
}
else
WriteLine($"{iteratorTypeName} {GetQualifiedName(@class)}::Get{method.Name}(uint i)");
WriteOpenBraceAndIndent();
WriteLine($"auto elements = {method.Name}();");
WriteLine($"auto it = elements.begin();");
WriteLine($"std::advance(it, i);");
WriteLine($"return *it;");
UnindentAndWriteCloseBrace();
NewLine();
}
public override bool VisitClassDecl(Class @class)
{
if (!@class.IsGenerated)
return false;
WriteLine($"{@class.Name}::{@class.Name}()");
var isBaseType = @class.Name == "Type";
var typeMember = isBaseType ? "typeClass" : @class.BaseClass.Name;
var typeClass = @class.Name == "Type" ? "None" : @class.Name;
WriteLineIndent($": {typeMember}(TypeClass::{typeClass})");
GenerateMemberInits(@class);
WriteOpenBraceAndIndent();
UnindentAndWriteCloseBrace();
NewLine();
foreach (var method in @class.Methods)
{
if (SkipMethod(method))
continue;
GenerateMethodDefinition(@class, method);
}
return true;
}
}
class TypeASTConverterCodeGenerator : ASTConverterCodeGenerator
{
public TypeASTConverterCodeGenerator(BindingContext context, IEnumerable<Declaration> declarations)
: base(context, declarations)
{
}
public override string BaseTypeName => "Type";
public override bool IsAbstractASTNode(Class kind)
{
return IsAbstractType(kind);
}
protected override void GenerateVisitorSwitch(IEnumerable<string> classes)
{
WriteLine($"switch({ParamName}.DeclKind)");
WriteOpenBraceAndIndent();
GenerateSwitchCases(classes);
UnindentAndWriteCloseBrace();
}
public void GenerateSwitchCases(IEnumerable<string> classes)
{
foreach (var className in classes)
{
WriteLine($"case Parser.AST.TypeClass.{className}:");
WriteLineIndent($"return Visit{className}({ParamName} as Parser.AST.{className}Type);");
}
WriteLine("default:");
WriteLineIndent($"throw new System.NotImplementedException(" +
$"{ParamName}.TypeClass.ToString());");
}
}
}

523
src/CppParser/Decl.h

@ -10,14 +10,13 @@ @@ -10,14 +10,13 @@
#include "Helpers.h"
#include "Sources.h"
#include "Types.h"
#include <algorithm>
namespace CppSharp {
namespace CppParser {
namespace AST {
namespace CppSharp::CppParser::AST {
enum class DeclarationKind
{
enum class DeclarationKind
{
DeclarationContext,
Typedef,
TypeAlias,
@ -49,26 +48,26 @@ namespace AST { @@ -49,26 +48,26 @@ namespace AST {
VarTemplateSpecialization,
VarTemplatePartialSpecialization,
UnresolvedUsingTypename,
};
};
#define DECLARE_DECL_KIND(klass, kind) \
klass();
enum class AccessSpecifier
{
enum class AccessSpecifier
{
Private,
Protected,
Public
};
};
class DeclarationContext;
class RawComment;
class PreprocessedEntity;
class DeclarationContext;
class RawComment;
class PreprocessedEntity;
class ExpressionObsolete;
class CS_API Declaration
{
public:
class ExpressionObsolete;
class CS_API Declaration
{
public:
Declaration(DeclarationKind kind);
Declaration(const Declaration&);
~Declaration();
@ -95,24 +94,24 @@ namespace AST { @@ -95,24 +94,24 @@ namespace AST {
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:
};
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);
@ -155,41 +154,41 @@ namespace AST { @@ -155,41 +154,41 @@ namespace AST {
std::map<std::string, Declaration*> anonymous;
bool isAnonymous;
};
};
class CS_API TypedefNameDecl : public Declaration
{
public:
class CS_API TypedefNameDecl : public Declaration
{
public:
TypedefNameDecl(DeclarationKind kind);
~TypedefNameDecl();
QualifiedType qualifiedType;
};
};
class CS_API TypedefDecl : public TypedefNameDecl
{
public:
class CS_API TypedefDecl : public TypedefNameDecl
{
public:
DECLARE_DECL_KIND(TypedefDecl, Typedef)
~TypedefDecl();
};
};
class CS_API TypeAlias : public TypedefNameDecl
{
public:
class CS_API TypeAlias : public TypedefNameDecl
{
public:
TypeAlias();
~TypeAlias();
TypeAliasTemplate* describedAliasTemplate;
};
};
class CS_API Friend : public Declaration
{
public:
class CS_API Friend : public Declaration
{
public:
DECLARE_DECL_KIND(Friend, Friend)
~Friend();
Declaration* declaration;
};
};
enum class StatementClassObsolete
{
enum class StatementClassObsolete
{
Any,
BinaryOperator,
CallExprClass,
@ -198,54 +197,54 @@ namespace AST { @@ -198,54 +197,54 @@ namespace AST {
CXXOperatorCallExpr,
ImplicitCastExpr,
ExplicitCastExpr,
};
};
class CS_API StatementObsolete
{
public:
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:
class CS_API ExpressionObsolete : public StatementObsolete
{
public:
ExpressionObsolete(const std::string& str, StatementClassObsolete Class = StatementClassObsolete::Any, Declaration* decl = 0);
};
};
class Expr;
class Expr;
class CS_API BinaryOperatorObsolete : public ExpressionObsolete
{
public:
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:
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:
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:
class CS_API Parameter : public Declaration
{
public:
Parameter();
~Parameter();
@ -255,20 +254,20 @@ namespace AST { @@ -255,20 +254,20 @@ namespace AST {
unsigned int index;
ExpressionObsolete* defaultArgument;
Expr* defaultValue;
};
};
enum class CXXMethodKind
{
enum class CXXMethodKind
{
Normal,
Constructor,
Destructor,
Conversion,
Operator,
UsingDirective
};
};
enum class CXXOperatorKind
{
enum class CXXOperatorKind
{
None,
New,
Delete,
@ -315,22 +314,22 @@ namespace AST { @@ -315,22 +314,22 @@ namespace AST {
Subscript,
Conditional,
Coawait
};
};
class FunctionTemplateSpecialization;
class FunctionTemplateSpecialization;
enum class FriendKind
{
enum class FriendKind
{
None,
Declared,
Undeclared
};
};
class Stmt;
class Stmt;
class CS_API Function : public DeclarationContext
{
public:
class CS_API Function : public DeclarationContext
{
public:
Function();
~Function();
@ -355,20 +354,20 @@ namespace AST { @@ -355,20 +354,20 @@ namespace AST {
FunctionTemplateSpecialization* specializationInfo;
Function* instantiatedFrom;
QualifiedType qualifiedType;
};
};
class AccessSpecifierDecl;
class AccessSpecifierDecl;
enum class RefQualifierKind
{
enum class RefQualifierKind
{
None,
LValue,
RValue
};
};
class CS_API Method : public Function
{
public:
class CS_API Method : public Function
{
public:
Method();
~Method();
@ -387,11 +386,11 @@ namespace AST { @@ -387,11 +386,11 @@ namespace AST {
QualifiedType conversionType;
RefQualifierKind refQualifier;
VECTOR(Method*, OverriddenMethods)
};
};
class CS_API Enumeration : public DeclarationContext
{
public:
class CS_API Enumeration : public DeclarationContext
{
public:
DECLARE_DECL_KIND(Enumeration, Enumeration)
~Enumeration();
@ -418,52 +417,52 @@ namespace AST { @@ -418,52 +417,52 @@ namespace AST {
VECTOR(Item*, Items)
Item* FindItemByName(const std::string& Name);
};
};
class CS_API Variable : public Declaration
{
public:
class CS_API Variable : public Declaration
{
public:
DECLARE_DECL_KIND(Variable, Variable)
~Variable();
bool isConstExpr;
std::string mangled;
QualifiedType qualifiedType;
ExpressionObsolete* initializer;
};
};
class PreprocessedEntity;
class PreprocessedEntity;
struct CS_API BaseClassSpecifier
{
struct CS_API BaseClassSpecifier
{
BaseClassSpecifier();
AccessSpecifier access;
bool isVirtual;
Type* type;
int offset;
};
};
class Class;
class Class;
class CS_API Field : public Declaration
{
public:
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:
class CS_API AccessSpecifierDecl : public Declaration
{
public:
DECLARE_DECL_KIND(AccessSpecifierDecl, AccessSpecifier)
~AccessSpecifierDecl();
};
};
enum class CppAbi
{
enum class CppAbi
{
Itanium,
Microsoft,
ARM,
@ -471,10 +470,10 @@ namespace AST { @@ -471,10 +470,10 @@ namespace AST {
iOS,
AppleARM64,
WebAssembly
};
};
enum class VTableComponentKind
{
enum class VTableComponentKind
{
VCallOffset,
VBaseOffset,
OffsetToTop,
@ -483,37 +482,37 @@ namespace AST { @@ -483,37 +482,37 @@ namespace AST {
CompleteDtorPointer,
DeletingDtorPointer,
UnusedFunctionPointer,
};
};
struct CS_API VTableComponent
{
struct CS_API VTableComponent
{
VTableComponent();
VTableComponentKind kind;
unsigned offset;
Declaration* declaration;
};
};
struct CS_API VTableLayout
{
struct CS_API VTableLayout
{
VTableLayout();
VTableLayout(const VTableLayout&);
~VTableLayout();
VECTOR(VTableComponent, Components)
};
};
struct CS_API VFTableInfo
{
struct CS_API VFTableInfo
{
VFTableInfo();
VFTableInfo(const VFTableInfo&);
uint64_t VBTableIndex;
uint32_t VFPtrOffset;
uint32_t VFPtrFullOffset;
VTableLayout layout;
};
};
class CS_API LayoutField
{
public:
class CS_API LayoutField
{
public:
LayoutField();
LayoutField(const LayoutField& other);
~LayoutField();
@ -521,22 +520,22 @@ namespace AST { @@ -521,22 +520,22 @@ namespace AST {
std::string name;
QualifiedType qualifiedType;
void* fieldPtr;
};
};
class Class;
class Class;
class CS_API LayoutBase
{
public:
class CS_API LayoutBase
{
public:
LayoutBase();
LayoutBase(const LayoutBase& other);
~LayoutBase();
unsigned offset;
Class* _class;
};
};
enum class RecordArgABI
{
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.
@ -548,10 +547,10 @@ namespace AST { @@ -548,10 +547,10 @@ namespace AST {
DirectInMemory,
/// Pass it as a pointer to temporary memory.
Indirect
};
};
struct CS_API ClassLayout
{
struct CS_API ClassLayout
{
ClassLayout();
CppAbi ABI;
RecordArgABI argABI;
@ -564,20 +563,11 @@ namespace AST { @@ -564,20 +563,11 @@ namespace AST {
int dataSize;
VECTOR(LayoutField, Fields)
VECTOR(LayoutBase, Bases)
};
};
enum class TagKind
{
Struct,
Interface,
Union,
Class,
Enum
};
class CS_API Class : public DeclarationContext
{
public:
class CS_API Class : public DeclarationContext
{
public:
Class();
~Class();
@ -599,20 +589,20 @@ namespace AST { @@ -599,20 +589,20 @@ namespace AST {
TagKind tagKind;
ClassLayout* layout;
};
};
class CS_API Template : public Declaration
{
public:
class CS_API Template : public Declaration
{
public:
Template(DeclarationKind kind);
DECLARE_DECL_KIND(Template, Template)
Declaration* TemplatedDecl;
VECTOR(Declaration*, Parameters)
};
};
template <typename T>
T* DeclarationContext::FindTemplate(const std::string& USR)
{
template <typename T>
T* DeclarationContext::FindTemplate(const std::string& USR)
{
auto foundTemplate = std::find_if(Templates.begin(), Templates.end(),
[&](Template* t)
{
@ -623,51 +613,51 @@ namespace AST { @@ -623,51 +613,51 @@ namespace AST {
return static_cast<T*>(*foundTemplate);
return nullptr;
}
}
class CS_API TypeAliasTemplate : public Template
{
public:
class CS_API TypeAliasTemplate : public Template
{
public:
TypeAliasTemplate();
~TypeAliasTemplate();
Declaration* CanonicalDecl = nullptr;
};
};
class CS_API TemplateParameter : public Declaration
{
public:
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:
class CS_API TemplateTemplateParameter : public Template
{
public:
TemplateTemplateParameter();
~TemplateTemplateParameter();
bool isParameterPack;
bool isPackExpansion;
bool isExpandedParameterPack;
};
};
class CS_API TypeTemplateParameter : public TemplateParameter
{
public:
class CS_API TypeTemplateParameter : public TemplateParameter
{
public:
TypeTemplateParameter();
TypeTemplateParameter(const TypeTemplateParameter&);
~TypeTemplateParameter();
QualifiedType defaultArgument;
};
};
class CS_API NonTypeTemplateParameter : public TemplateParameter
{
public:
class CS_API NonTypeTemplateParameter : public TemplateParameter
{
public:
NonTypeTemplateParameter();
NonTypeTemplateParameter(const NonTypeTemplateParameter&);
~NonTypeTemplateParameter();
@ -677,172 +667,169 @@ namespace AST { @@ -677,172 +667,169 @@ namespace AST {
bool isPackExpansion;
bool isExpandedParameterPack;
QualifiedType type;
};
};
class ClassTemplateSpecialization;
class ClassTemplatePartialSpecialization;
class ClassTemplateSpecialization;
class ClassTemplatePartialSpecialization;
class CS_API ClassTemplate : public Template
{
public:
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
{
enum class TemplateSpecializationKind
{
Undeclared,
ImplicitInstantiation,
ExplicitSpecialization,
ExplicitInstantiationDeclaration,
ExplicitInstantiationDefinition
};
};
class CS_API ClassTemplateSpecialization : public Class
{
public:
class CS_API ClassTemplateSpecialization : public Class
{
public:
ClassTemplateSpecialization();
~ClassTemplateSpecialization();
ClassTemplate* templatedDecl;
VECTOR(TemplateArgument, Arguments)
TemplateSpecializationKind specializationKind;
};
};
class CS_API ClassTemplatePartialSpecialization : public ClassTemplateSpecialization
{
public:
class CS_API ClassTemplatePartialSpecialization : public ClassTemplateSpecialization
{
public:
ClassTemplatePartialSpecialization();
~ClassTemplatePartialSpecialization();
VECTOR(Declaration*, Parameters)
};
};
class CS_API FunctionTemplate : public Template
{
public:
class CS_API FunctionTemplate : public Template
{
public:
FunctionTemplate();
~FunctionTemplate();
VECTOR(FunctionTemplateSpecialization*, Specializations)
FunctionTemplateSpecialization* FindSpecialization(const std::string& usr);
};
};
class CS_API FunctionTemplateSpecialization
{
public:
class CS_API FunctionTemplateSpecialization
{
public:
FunctionTemplateSpecialization();
~FunctionTemplateSpecialization();
FunctionTemplate* _template;
VECTOR(TemplateArgument, Arguments)
Function* specializedFunction;
TemplateSpecializationKind specializationKind;
};
};
class VarTemplateSpecialization;
class VarTemplatePartialSpecialization;
class VarTemplateSpecialization;
class VarTemplatePartialSpecialization;
class CS_API VarTemplate : public Template
{
public:
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:
class CS_API VarTemplateSpecialization : public Variable
{
public:
VarTemplateSpecialization();
~VarTemplateSpecialization();
VarTemplate* templatedDecl;
VECTOR(TemplateArgument, Arguments)
TemplateSpecializationKind specializationKind;
};
};
class CS_API VarTemplatePartialSpecialization : public VarTemplateSpecialization
{
public:
class CS_API VarTemplatePartialSpecialization : public VarTemplateSpecialization
{
public:
VarTemplatePartialSpecialization();
~VarTemplatePartialSpecialization();
};
};
class CS_API UnresolvedUsingTypename : public Declaration
{
public:
class CS_API UnresolvedUsingTypename : public Declaration
{
public:
UnresolvedUsingTypename();
~UnresolvedUsingTypename();
};
};
class CS_API Namespace : public DeclarationContext
{
public:
class CS_API Namespace : public DeclarationContext
{
public:
Namespace();
~Namespace();
bool isInline;
};
};
enum class MacroLocation
{
enum class MacroLocation
{
Unknown,
ClassHead,
ClassBody,
FunctionHead,
FunctionParameters,
FunctionBody,
};
};
class CS_API PreprocessedEntity
{
public:
class CS_API PreprocessedEntity
{
public:
PreprocessedEntity();
MacroLocation macroLocation;
void* originalPtr;
DeclarationKind kind;
};
};
class CS_API MacroDefinition : public PreprocessedEntity
{
public:
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:
class CS_API MacroExpansion : public PreprocessedEntity
{
public:
MacroExpansion();
~MacroExpansion();
std::string name;
std::string text;
MacroDefinition* definition;
};
};
class CS_API TranslationUnit : public Namespace
{
public:
class CS_API TranslationUnit : public Namespace
{
public:
TranslationUnit();
~TranslationUnit();
std::string fileName;
bool isSystemHeader;
VECTOR(MacroDefinition*, Macros)
};
};
class CS_API ASTContext
{
public:
class CS_API ASTContext
{
public:
ASTContext();
~ASTContext();
TranslationUnit* FindOrCreateModule(const std::string& File);
VECTOR(TranslationUnit*, TranslationUnits)
};
}
}
};
} // namespace CppSharp::CppParser::AST

2191
src/CppParser/Declaration.h

File diff suppressed because it is too large Load Diff

21
src/CppParser/Types.h

@ -10,6 +10,7 @@ @@ -10,6 +10,7 @@
#include "Helpers.h"
namespace CppSharp { namespace CppParser { namespace AST {
class Expr;
enum class TypeKind
{
@ -34,6 +35,15 @@ namespace CppSharp { namespace CppParser { namespace AST { @@ -34,6 +35,15 @@ namespace CppSharp { namespace CppParser { namespace AST {
Vector
};
enum class TagKind
{
Struct,
Interface,
Union,
Class,
Enum
};
#define DECLARE_TYPE_KIND(kind) \
kind##Type();
@ -88,6 +98,17 @@ namespace CppSharp { namespace CppParser { namespace AST { @@ -88,6 +98,17 @@ namespace CppSharp { namespace CppParser { namespace AST {
long elementSize;
};
class CS_API VariableArrayType : public ArrayType
{
public:
VariableArrayType()
{
sizeType = ArraySize::Variable;
}
Expr* sizeExpr = nullptr;
};
class Parameter;
enum class CallingConvention

8
src/Generator/Generators/C/CppTypePrinter.cs

@ -473,7 +473,7 @@ namespace CppSharp.Generators.C @@ -473,7 +473,7 @@ namespace CppSharp.Generators.C
{
case TypePrintScopeKind.Local:
{
if (ContextKind == TypePrinterContextKind.Managed)
if (ContextKind is TypePrinterContextKind.Managed or TypePrinterContextKind.Normal)
{
return PrintLogicalNames ? declaration.LogicalName : declaration.Name;
}
@ -510,6 +510,12 @@ namespace CppSharp.Generators.C @@ -510,6 +510,12 @@ namespace CppSharp.Generators.C
return $"{declContext}{NamespaceSeparator}{declName}";
}
if (ContextKind == TypePrinterContextKind.Normal)
{
return PrintLogicalNames ? declaration.QualifiedLogicalName
: declaration.QualifiedName;
}
return PrintLogicalNames ? declaration.QualifiedLogicalOriginalName
: declaration.QualifiedOriginalName;
}

2
src/Generator/Generators/CSharp/CSharpTypePrinter.cs

@ -315,7 +315,7 @@ namespace CppSharp.Generators.CSharp @@ -315,7 +315,7 @@ namespace CppSharp.Generators.CSharp
TemplateArgument lastArg = args.Last();
TypePrinterResult typePrinterResult = VisitDeclaration(decl);
typePrinterResult.NameSuffix.Append($@"<{string.Join(", ",
args.Concat(Enumerable.Range(0, @class.TemplateParameters.Count - args.Count).Select(
args.Concat(Enumerable.Range(0, @class.TemplateParameters?.Count ?? 0 - args.Count).Select(
i => lastArg)).Select(this.VisitTemplateArgument))}>");
return typePrinterResult;
}

4
src/Generator/Generators/CodeGenerator.cs

@ -427,7 +427,7 @@ namespace CppSharp.Generators @@ -427,7 +427,7 @@ namespace CppSharp.Generators
public virtual bool VisitClassTemplateDecl(ClassTemplate template)
{
throw new NotImplementedException();
return true;
}
public virtual bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecialization specialization)
@ -437,7 +437,7 @@ namespace CppSharp.Generators @@ -437,7 +437,7 @@ namespace CppSharp.Generators
public virtual bool VisitFunctionTemplateDecl(FunctionTemplate template)
{
throw new NotImplementedException();
return true;
}
public virtual bool VisitFunctionTemplateSpecializationDecl(FunctionTemplateSpecialization specialization)

2
src/Generator/Passes/MoveFunctionToClassPass.cs

@ -61,7 +61,7 @@ namespace CppSharp.Passes @@ -61,7 +61,7 @@ namespace CppSharp.Passes
string name = tu != null ? Options.GenerateFreeStandingFunctionsClassName(tu) :
function.Namespace.Name;
@class = ASTContext.FindClass(
name, ignoreCase: true).FirstOrDefault(
name).FirstOrDefault(
c => c.TranslationUnit.Module == function.TranslationUnit.Module &&
!c.IsIncomplete);
}

2
src/Generator/Passes/StripUnusedSystemTypesPass.cs

@ -16,7 +16,7 @@ namespace CppSharp.Passes @@ -16,7 +16,7 @@ namespace CppSharp.Passes
// we need this one for marshalling std::string
foreach (var name in new[] { "allocator", "char_traits" })
{
var forceIncludedClasses = context.FindClass(name, false, true)
var forceIncludedClasses = context.FindClass(name)
.Where(a => a.TranslationUnit.IsSystemHeader);
foreach (var usedStdType in forceIncludedClasses)

2
src/Generator/Passes/verbs.txt

@ -840,6 +840,7 @@ caponize @@ -840,6 +840,7 @@ caponize
capsize
capsulize
captivate
capture
caramelise
caramelize
carbolise
@ -5001,6 +5002,7 @@ overresist @@ -5001,6 +5002,7 @@ overresist
overrestrain
overrestrict
overreward
override
overripen
overroast
overromanticize

Loading…
Cancel
Save