Browse Source

Bootstrap code changes (#1914)

* Ignore 'BootstrapPatch' folder

Just in case

* Split into files

* Abstract some `ASTConverterCodeGenerator` code

* Code cleanup

* Abstraction improvements
pull/1920/head
Jelle 2 months ago committed by GitHub
parent
commit
7105da02fe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      .gitignore
  2. 117
      src/AST/Type.cs
  3. 148
      src/AST/TypeExtensions.cs
  4. 2
      src/AST/Typedef.cs
  5. 1246
      src/CppParser/Bootstrap/Bootstrap.cs
  6. 551
      src/CppParser/Bootstrap/CodeGeneratorHelpers.cs
  7. 535
      src/CppParser/Bootstrap/StmtCodeGenerators.cs
  8. 26
      src/CppParser/Sources.h
  9. 49
      src/Generator/Generators/C/CppTypePrinter.cs
  10. 18
      src/Generator/Generators/CodeGenerator.cs
  11. 17
      src/Generator/Generators/TypePrinter.cs
  12. 14
      src/Generator/Passes/GetterSetterToPropertyPass.cs
  13. 4
      src/Parser/ASTConverter.Expr.cs
  14. 4
      src/Parser/ASTConverter.Stmt.cs

1
.gitignore vendored

@ -13,6 +13,7 @@ bin/ @@ -13,6 +13,7 @@ bin/
*.userprefs
tests/output
src/generator/generator
src/BootstrapPatch
*.pc
.DS_Store
*.user

117
src/AST/Type.cs

@ -26,7 +26,7 @@ namespace CppSharp.AST @@ -26,7 +26,7 @@ namespace CppSharp.AST
}
public abstract T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals
= new TypeQualifiers());
= new());
public override string ToString()
{
@ -90,9 +90,9 @@ namespace CppSharp.AST @@ -90,9 +90,9 @@ namespace CppSharp.AST
public override bool Equals(object obj)
{
if (!(obj is QualifiedType)) return false;
if (obj is not QualifiedType type)
return false;
var type = (QualifiedType)obj;
return Type.Equals(type.Type) && Qualifiers.Equals(type.Qualifiers);
}
@ -132,7 +132,7 @@ namespace CppSharp.AST @@ -132,7 +132,7 @@ namespace CppSharp.AST
public Declaration Declaration;
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new TypeQualifiers())
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new())
{
return visitor.VisitTagType(this, quals);
}
@ -144,8 +144,8 @@ namespace CppSharp.AST @@ -144,8 +144,8 @@ namespace CppSharp.AST
public override bool Equals(object obj)
{
var type = obj as TagType;
if (type == null) return false;
if (obj is not TagType type)
return false;
return Declaration.Equals(type.Declaration);
}
@ -198,7 +198,7 @@ namespace CppSharp.AST @@ -198,7 +198,7 @@ namespace CppSharp.AST
public Type Type => QualifiedType.Type;
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new TypeQualifiers())
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new())
{
return visitor.VisitArrayType(this, quals);
}
@ -210,8 +210,9 @@ namespace CppSharp.AST @@ -210,8 +210,9 @@ namespace CppSharp.AST
public override bool Equals(object obj)
{
var type = obj as ArrayType;
if (type == null) return false;
if (obj is not ArrayType type)
return false;
var equals = QualifiedType.Equals(type.QualifiedType) && SizeType.Equals(type.SizeType);
if (SizeType == ArraySize.Constant)
@ -251,7 +252,7 @@ namespace CppSharp.AST @@ -251,7 +252,7 @@ namespace CppSharp.AST
public QualifiedType ReturnType;
// Argument types.
public List<Parameter> Parameters { get; } = new List<Parameter>();
public List<Parameter> Parameters { get; } = new();
public CallingConvention CallingConvention { get; set; }
@ -270,7 +271,7 @@ namespace CppSharp.AST @@ -270,7 +271,7 @@ namespace CppSharp.AST
IsDependent = type.IsDependent;
}
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new TypeQualifiers())
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new())
{
return visitor.VisitFunctionType(this, quals);
}
@ -282,8 +283,7 @@ namespace CppSharp.AST @@ -282,8 +283,7 @@ namespace CppSharp.AST
public override bool Equals(object obj)
{
var type = obj as FunctionType;
if (type == null) return false;
if (obj is not FunctionType type) return false;
return ReturnType.Equals(type.ReturnType) && Parameters.SequenceEqual(type.Parameters);
}
@ -300,7 +300,7 @@ namespace CppSharp.AST @@ -300,7 +300,7 @@ namespace CppSharp.AST
/// </summary>
public class PointerType : Type
{
public PointerType(QualifiedType pointee = new QualifiedType())
public PointerType(QualifiedType pointee = new())
{
Modifier = TypeModifier.Pointer;
QualifiedPointee = pointee;
@ -331,21 +331,14 @@ namespace CppSharp.AST @@ -331,21 +331,14 @@ namespace CppSharp.AST
Modifier = type.Modifier;
}
public bool IsReference
{
get
{
return Modifier == TypeModifier.LVReference ||
Modifier == TypeModifier.RVReference;
}
}
public bool IsReference => Modifier is TypeModifier.LVReference or TypeModifier.RVReference;
public QualifiedType QualifiedPointee;
public Type Pointee { get { return QualifiedPointee.Type; } }
public Type Pointee => QualifiedPointee.Type;
public TypeModifier Modifier;
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new TypeQualifiers())
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new())
{
return visitor.VisitPointerType(this, quals);
}
@ -357,8 +350,8 @@ namespace CppSharp.AST @@ -357,8 +350,8 @@ namespace CppSharp.AST
public override bool Equals(object obj)
{
var type = obj as PointerType;
if (type == null) return false;
if (obj is not PointerType type)
return false;
return QualifiedPointee.Equals(type.QualifiedPointee)
&& Modifier == type.Modifier;
@ -386,12 +379,9 @@ namespace CppSharp.AST @@ -386,12 +379,9 @@ namespace CppSharp.AST
type.QualifiedPointee.Qualifiers);
}
public Type Pointee
{
get { return QualifiedPointee.Type; }
}
public Type Pointee => QualifiedPointee.Type;
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new TypeQualifiers())
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new())
{
return visitor.VisitMemberPointerType(this, quals);
}
@ -403,8 +393,7 @@ namespace CppSharp.AST @@ -403,8 +393,7 @@ namespace CppSharp.AST
public override bool Equals(object obj)
{
var pointer = obj as MemberPointerType;
if (pointer == null) return false;
if (obj is not MemberPointerType pointer) return false;
return QualifiedPointee.Equals(pointer.QualifiedPointee);
}
@ -434,7 +423,7 @@ namespace CppSharp.AST @@ -434,7 +423,7 @@ namespace CppSharp.AST
Declaration = type.Declaration;
}
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new TypeQualifiers())
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new())
{
return visitor.VisitTypedefType(this, quals);
}
@ -446,8 +435,7 @@ namespace CppSharp.AST @@ -446,8 +435,7 @@ namespace CppSharp.AST
public override bool Equals(object obj)
{
var typedef = obj as TypedefType;
if (typedef == null)
if (obj is not TypedefType typedef)
return false;
return Declaration.OriginalName == typedef.Declaration.OriginalName &&
@ -485,7 +473,7 @@ namespace CppSharp.AST @@ -485,7 +473,7 @@ namespace CppSharp.AST
Equivalent = new QualifiedType((Type)type.Equivalent.Type.Clone(), type.Equivalent.Qualifiers);
}
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new TypeQualifiers())
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new())
{
return visitor.VisitAttributedType(this, quals);
}
@ -502,8 +490,7 @@ namespace CppSharp.AST @@ -502,8 +490,7 @@ namespace CppSharp.AST
public override bool Equals(object obj)
{
var attributed = obj as AttributedType;
if (attributed == null) return false;
if (obj is not AttributedType attributed) return false;
return Modified.Equals(attributed.Modified)
&& Equivalent.Equals(attributed.Equivalent);
@ -538,7 +525,7 @@ namespace CppSharp.AST @@ -538,7 +525,7 @@ namespace CppSharp.AST
}
public override T Visit<T>(ITypeVisitor<T> visitor,
TypeQualifiers quals = new TypeQualifiers())
TypeQualifiers quals = new())
{
return visitor.VisitDecayedType(this, quals);
}
@ -550,8 +537,7 @@ namespace CppSharp.AST @@ -550,8 +537,7 @@ namespace CppSharp.AST
public override bool Equals(object obj)
{
var decay = obj as DecayedType;
if (decay == null) return false;
if (obj is not DecayedType decay) return false;
return Original.Equals(decay.Original);
}
@ -704,7 +690,7 @@ namespace CppSharp.AST @@ -704,7 +690,7 @@ namespace CppSharp.AST
}
public override T Visit<T>(ITypeVisitor<T> visitor,
TypeQualifiers quals = new TypeQualifiers())
TypeQualifiers quals = new())
{
return visitor.VisitTemplateSpecializationType(this, quals);
}
@ -716,8 +702,7 @@ namespace CppSharp.AST @@ -716,8 +702,7 @@ namespace CppSharp.AST
public override bool Equals(object obj)
{
var type = obj as TemplateSpecializationType;
if (type == null) return false;
if (obj is not TemplateSpecializationType type) return false;
return Arguments.SequenceEqual(type.Arguments) &&
((Template != null && Template.Name == type.Template.Name) ||
@ -759,7 +744,7 @@ namespace CppSharp.AST @@ -759,7 +744,7 @@ namespace CppSharp.AST
public QualifiedType Desugared;
public override T Visit<T>(ITypeVisitor<T> visitor,
TypeQualifiers quals = new TypeQualifiers())
TypeQualifiers quals = new())
{
return visitor.VisitDependentTemplateSpecializationType(this, quals);
}
@ -771,8 +756,7 @@ namespace CppSharp.AST @@ -771,8 +756,7 @@ namespace CppSharp.AST
public override bool Equals(object obj)
{
var type = obj as TemplateSpecializationType;
if (type == null) return false;
if (obj is not TemplateSpecializationType type) return false;
return Arguments.SequenceEqual(type.Arguments) &&
Desugared == type.Desugared;
@ -815,7 +799,7 @@ namespace CppSharp.AST @@ -815,7 +799,7 @@ namespace CppSharp.AST
}
public override T Visit<T>(ITypeVisitor<T> visitor,
TypeQualifiers quals = new TypeQualifiers())
TypeQualifiers quals = new())
{
return visitor.VisitTemplateParameterType(this, quals);
}
@ -827,8 +811,7 @@ namespace CppSharp.AST @@ -827,8 +811,7 @@ namespace CppSharp.AST
public override bool Equals(object obj)
{
var type = obj as TemplateParameterType;
if (type == null) return false;
if (obj is not TemplateParameterType type) return false;
return Parameter == type.Parameter
&& Depth == type.Depth
@ -865,7 +848,7 @@ namespace CppSharp.AST @@ -865,7 +848,7 @@ namespace CppSharp.AST
}
public override T Visit<T>(ITypeVisitor<T> visitor,
TypeQualifiers quals = new TypeQualifiers())
TypeQualifiers quals = new())
{
return visitor.VisitTemplateParameterSubstitutionType(this, quals);
}
@ -877,8 +860,7 @@ namespace CppSharp.AST @@ -877,8 +860,7 @@ namespace CppSharp.AST
public override bool Equals(object obj)
{
var type = obj as TemplateParameterSubstitutionType;
if (type == null) return false;
if (obj is not TemplateParameterSubstitutionType type) return false;
return ReplacedParameter.Equals(type.ReplacedParameter) &&
Replacement.Equals(type.Replacement);
@ -915,7 +897,7 @@ namespace CppSharp.AST @@ -915,7 +897,7 @@ namespace CppSharp.AST
public QualifiedType InjectedSpecializationType { get; set; }
public override T Visit<T>(ITypeVisitor<T> visitor,
TypeQualifiers quals = new TypeQualifiers())
TypeQualifiers quals = new())
{
return visitor.VisitInjectedClassNameType(this, quals);
}
@ -927,8 +909,7 @@ namespace CppSharp.AST @@ -927,8 +909,7 @@ namespace CppSharp.AST
public override bool Equals(object obj)
{
var type = obj as InjectedClassNameType;
if (type == null) return false;
if (obj is not InjectedClassNameType type) return false;
if (TemplateSpecialization == null || type.TemplateSpecialization == null)
return TemplateSpecialization == type.TemplateSpecialization;
@ -962,7 +943,7 @@ namespace CppSharp.AST @@ -962,7 +943,7 @@ namespace CppSharp.AST
public string Identifier { get; set; }
public override T Visit<T>(ITypeVisitor<T> visitor,
TypeQualifiers quals = new TypeQualifiers())
TypeQualifiers quals = new())
{
return visitor.VisitDependentNameType(this, quals);
}
@ -999,7 +980,7 @@ namespace CppSharp.AST @@ -999,7 +980,7 @@ namespace CppSharp.AST
public System.Type Type;
public override T Visit<T>(ITypeVisitor<T> visitor,
TypeQualifiers quals = new TypeQualifiers())
TypeQualifiers quals = new())
{
return visitor.VisitCILType(this, quals);
}
@ -1011,8 +992,7 @@ namespace CppSharp.AST @@ -1011,8 +992,7 @@ namespace CppSharp.AST
public override bool Equals(object obj)
{
var type = obj as CILType;
if (type == null) return false;
if (obj is not CILType type) return false;
return Type == type.Type;
}
@ -1031,7 +1011,7 @@ namespace CppSharp.AST @@ -1031,7 +1011,7 @@ namespace CppSharp.AST
{
}
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new TypeQualifiers())
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new())
{
return visitor.VisitPackExpansionType(this, quals);
}
@ -1058,7 +1038,7 @@ namespace CppSharp.AST @@ -1058,7 +1038,7 @@ namespace CppSharp.AST
public QualifiedType Desugared { get; set; }
public QualifiedType BaseType { get; set; }
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new TypeQualifiers())
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new())
{
return visitor.VisitUnaryTransformType(this, quals);
}
@ -1085,7 +1065,7 @@ namespace CppSharp.AST @@ -1085,7 +1065,7 @@ namespace CppSharp.AST
public UnresolvedUsingTypename Declaration { get; set; }
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new TypeQualifiers())
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new())
{
return visitor.VisitUnresolvedUsingType(this, quals);
}
@ -1112,7 +1092,7 @@ namespace CppSharp.AST @@ -1112,7 +1092,7 @@ namespace CppSharp.AST
public QualifiedType ElementType { get; set; }
public uint NumElements { get; set; }
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new TypeQualifiers())
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new())
{
return visitor.VisitVectorType(this, quals);
}
@ -1144,7 +1124,7 @@ namespace CppSharp.AST @@ -1144,7 +1124,7 @@ namespace CppSharp.AST
public string Description;
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new TypeQualifiers())
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new())
{
return visitor.VisitUnsupportedType(this, quals);
}
@ -1243,7 +1223,7 @@ namespace CppSharp.AST @@ -1243,7 +1223,7 @@ namespace CppSharp.AST
// Primitive type of built-in type.
public PrimitiveType Type;
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new TypeQualifiers())
public override T Visit<T>(ITypeVisitor<T> visitor, TypeQualifiers quals = new())
{
return visitor.VisitBuiltinType(this, quals);
}
@ -1255,8 +1235,7 @@ namespace CppSharp.AST @@ -1255,8 +1235,7 @@ namespace CppSharp.AST
public override bool Equals(object obj)
{
var type = obj as BuiltinType;
if (type == null) return false;
if (obj is not BuiltinType type) return false;
return Type == type.Type;
}

148
src/AST/TypeExtensions.cs

@ -4,14 +4,12 @@ @@ -4,14 +4,12 @@
{
public static bool IsPrimitiveType(this Type t)
{
PrimitiveType type;
return t.IsPrimitiveType(out type);
return t.IsPrimitiveType(out PrimitiveType _);
}
public static bool IsPrimitiveType(this Type t, out PrimitiveType primitive)
{
var builtin = t.Desugar() as BuiltinType;
if (builtin != null)
if (t.Desugar() is BuiltinType builtin)
{
primitive = builtin.Type;
return true;
@ -32,9 +30,7 @@ @@ -32,9 +30,7 @@
public static bool IsEnumType(this Type t)
{
var tag = t.Desugar() as TagType;
if (tag == null)
if (t.Desugar() is not TagType tag)
return false;
return tag.Declaration is Enumeration;
@ -47,36 +43,28 @@ @@ -47,36 +43,28 @@
public static bool IsPointer(this Type t)
{
var functionPointer = t as MemberPointerType;
if (functionPointer != null)
if (t is MemberPointerType)
return true;
var pointer = t as PointerType;
if (pointer == null)
if (t is not PointerType pointer)
return false;
return pointer.Modifier == PointerType.TypeModifier.Pointer;
}
public static bool IsReference(this Type t)
{
var pointer = t as PointerType;
if (pointer == null)
return false;
return pointer.IsReference;
return t is PointerType { IsReference: true };
}
public static bool IsPointerToPrimitiveType(this Type t)
{
var ptr = t as PointerType;
if (ptr == null)
return false;
PrimitiveType primitiveType;
return ptr.Pointee.IsPrimitiveType(out primitiveType);
return t is PointerType ptr && ptr.Pointee.IsPrimitiveType(out _);
}
public static bool IsPointerToPrimitiveType(this Type t, out PrimitiveType primitive)
{
var ptr = t as PointerType;
if (ptr == null)
if (t is not PointerType ptr)
{
primitive = PrimitiveType.Null;
return false;
@ -86,24 +74,21 @@ @@ -86,24 +74,21 @@
public static bool IsPointerToPrimitiveType(this Type t, PrimitiveType primitive)
{
var ptr = t as PointerType;
if (ptr == null)
if (t is not PointerType ptr)
return false;
return ptr.Pointee.IsPrimitiveType(primitive);
}
public static bool IsPointerToEnum(this Type t)
{
var ptr = t as PointerType;
if (ptr == null)
if (t is not PointerType ptr)
return false;
return ptr.Pointee.IsEnumType();
}
public static bool IsPointerToEnum(this Type t, out Enumeration @enum)
{
var ptr = t as PointerType;
if (ptr == null)
if (t is not PointerType ptr)
{
@enum = null;
return false;
@ -111,23 +96,22 @@ @@ -111,23 +96,22 @@
return ptr.Pointee.TryGetEnum(out @enum);
}
public static bool IsPointerTo<T>(this Type t, out T type) where T : Type
public static bool IsPointerTo<T>(this Type t, out T type)
where T : Type
{
var pointee = t.GetPointee();
type = pointee as T;
if (type == null)
type = t.GetPointee() switch
{
var attributedType = pointee as AttributedType;
if (attributedType != null)
type = attributedType.Modified.Type as T;
}
T tType => tType,
AttributedType attributedType => attributedType.Modified.Type as T,
_ => null
};
return type != null;
}
public static bool IsClass(this Type t)
{
Class @class;
return t.TryGetClass(out @class);
return t.TryGetClass(out _);
}
public static bool TryGetClass(this Type t, out Class @class, Class value = null)
@ -135,11 +119,12 @@ @@ -135,11 +119,12 @@
return TryGetDeclaration(t, out @class, value);
}
public static bool TryGetDeclaration<T>(this Type t, out T decl, T value = null) where T : Declaration
public static bool TryGetDeclaration<T>(this Type t, out T decl, T value = null)
where T : Declaration
{
t = t.Desugar();
TagType tagType = null;
TagType tagType;
if (t is TemplateSpecializationType type)
{
if (type.IsDependent)
@ -150,20 +135,20 @@ @@ -150,20 +135,20 @@
type.Desugared.Type.TryGetDeclaration(out decl, value);
return decl != null;
case ClassTemplate classTemplate:
{
var templatedClass = classTemplate.TemplatedClass;
decl = templatedClass.CompleteDeclaration == null
? templatedClass as T
: (T)templatedClass.CompleteDeclaration;
{
var templatedClass = classTemplate.TemplatedClass;
decl = templatedClass.CompleteDeclaration == null
? templatedClass as T
: (T)templatedClass.CompleteDeclaration;
if (decl == null)
return false;
if (decl == null)
return false;
if (value != null)
type.Template = new ClassTemplate { TemplatedDecl = value };
if (value != null)
type.Template = new ClassTemplate { TemplatedDecl = value };
return true;
}
return true;
}
case TemplateTemplateParameter templateTemplateParameter:
return (decl = templateTemplateParameter.TemplatedDecl as T) != null;
}
@ -193,15 +178,12 @@ @@ -193,15 +178,12 @@
public static bool IsEnum(this Type t)
{
Enumeration @enum;
return t.TryGetEnum(out @enum);
return t.TryGetEnum(out _);
}
public static bool TryGetEnum(this Type t, out Enumeration @enum)
{
var tag = t.Desugar() as TagType;
if (tag == null)
if (t.Desugar() is not TagType tag)
{
@enum = null;
return false;
@ -269,13 +251,12 @@ @@ -269,13 +251,12 @@
/// </summary>
public static Type GetPointee(this Type t)
{
var ptr = t as PointerType;
if (ptr != null)
return ptr.Pointee;
var memberPtr = t as MemberPointerType;
if (memberPtr != null)
return memberPtr.QualifiedPointee.Type;
return null;
return t switch
{
PointerType ptr => ptr.Pointee,
MemberPointerType memberPtr => memberPtr.QualifiedPointee.Type,
_ => null
};
}
/// <summary>
@ -296,17 +277,28 @@ @@ -296,17 +277,28 @@
return finalPointee;
}
public static PointerType GetFinalPointer(this Type t)
{
if (t is not PointerType type)
return null;
var pointee = type.Desugar().GetPointee();
if (pointee.IsPointer())
return pointee.GetFinalPointer();
return type;
}
/// <summary>
/// If t is a pointer type the type pointed to by t will be returned.
/// Otherwise the default qualified type.
/// </summary>
public static QualifiedType GetQualifiedPointee(this Type t)
{
var ptr = t as PointerType;
if (ptr != null)
if (t is PointerType ptr)
return ptr.QualifiedPointee;
var memberPtr = t as MemberPointerType;
if (memberPtr != null)
if (t is MemberPointerType memberPtr)
return memberPtr.QualifiedPointee;
return new QualifiedType();
}
@ -329,21 +321,6 @@ @@ -329,21 +321,6 @@
return finalPointee;
}
public static PointerType GetFinalPointer(this Type t)
{
var type = t as PointerType;
if (type == null)
return null;
var pointee = type.Desugar().GetPointee();
if (pointee.IsPointer())
return pointee.GetFinalPointer();
return type;
}
public static bool ResolvesTo(this QualifiedType type, QualifiedType other)
{
if (!type.Qualifiers.Equals(other.Qualifiers))
@ -351,9 +328,7 @@ @@ -351,9 +328,7 @@
var left = type.Type.Desugar();
var right = other.Type.Desugar();
var leftPointer = left as PointerType;
var rightPointer = right as PointerType;
if (leftPointer != null && rightPointer != null)
if (left is PointerType leftPointer && right is PointerType rightPointer)
{
return leftPointer.Modifier == rightPointer.Modifier &&
leftPointer.QualifiedPointee.ResolvesTo(rightPointer.QualifiedPointee);
@ -388,8 +363,7 @@ @@ -388,8 +363,7 @@
qualifiers.IsConst = false;
type.Qualifiers = qualifiers;
var ptr = type.Type as PointerType;
if (ptr != null)
if (type.Type is PointerType ptr)
{
var pointee = ptr.QualifiedPointee;
var pointeeQualifiers = pointee.Qualifiers;

2
src/AST/Typedef.cs

@ -5,7 +5,7 @@ namespace CppSharp.AST @@ -5,7 +5,7 @@ namespace CppSharp.AST
/// </summary>
public abstract class TypedefNameDecl : Declaration, ITypedDecl
{
public Type Type { get { return QualifiedType.Type; } }
public Type Type => QualifiedType.Type;
public QualifiedType QualifiedType { get; set; }
public bool IsSynthetized { get; set; }
}

1246
src/CppParser/Bootstrap/Bootstrap.cs

File diff suppressed because it is too large Load Diff

551
src/CppParser/Bootstrap/CodeGeneratorHelpers.cs

@ -0,0 +1,551 @@ @@ -0,0 +1,551 @@
using System;
using System.Collections.Generic;
using CppSharp.AST;
using CppSharp.AST.Extensions;
using CppSharp.Generators;
using CppSharp.Generators.C;
using CppSharp.Generators.CSharp;
using CppSharp.Passes;
namespace CppSharp
{
internal static class CodeGeneratorHelpers
{
internal static CppTypePrinter CppTypePrinter;
public static bool IsAbstractStmt(Class @class) =>
IsAbstractStmt(@class.Name);
public static bool IsAbstractStmt(string @class) =>
@class is "Stmt"
or "ValueStmt"
or "NoStmt"
or "SwitchCase"
or "AsmStmt"
or "Expr"
or "FullExpr"
or "CastExpr"
or "ExplicitCastExpr"
or "AbstractConditionalOperator"
or "CXXNamedCastExpr"
or "OverloadExpr"
or "CoroutineSuspendExpr";
public static bool SkipProperty(Property property, bool skipBaseCheck = false)
{
if (!property.IsGenerated)
return true;
if (property.Access != AccessSpecifier.Public)
return true;
var @class = property.Namespace as Class;
if (!skipBaseCheck)
{
if (@class.GetBaseProperty(property) != null)
return true;
}
if (property.Name is "beginLoc" or "endLoc" &&
@class.Name != "Stmt")
return true;
switch (property.Name)
{
case "stmtClass":
case "stmtClassName":
return true;
case "isOMPStructuredBlock":
return true;
}
var typeName = property.Type.Visit(CppTypePrinter).Type;
//
// Statement properties.
//
if (typeName.Contains("LabelDecl") ||
typeName.Contains("VarDecl") ||
typeName.Contains("Token") ||
typeName.Contains("CapturedDecl") ||
typeName.Contains("CapturedRegionKind") ||
typeName.Contains("RecordDecl") ||
typeName.Contains("StringLiteral") ||
typeName.Contains("SwitchCase") ||
typeName.Contains("CharSourceRange") ||
typeName.Contains("NestedNameSpecifierLoc") ||
typeName.Contains("DeclarationNameInfo") ||
typeName.Contains("DeclGroupRef"))
return true;
//
// Expressions
//
// CastExpr
if (property.Name == "targetUnionField")
return true;
// ShuffleVectorExprClass
if (property.Name == "subExprs")
return true;
// InitListExprClass
if (property.Name == "initializedFieldInUnion")
return true;
// ParenListExprClass
if (property.Name == "exprs" && @class.Name == "ParenListExpr")
return true;
// EvalResult
if (typeName.Contains("ExprValueKind") ||
typeName.Contains("ExprObjectKind") ||
typeName.Contains("ObjC"))
return true;
// DeclRefExpr
if (typeName.Contains("ValueDecl") ||
typeName.Contains("NestedNameSpecifier") ||
typeName.Contains("TemplateArgumentLoc"))
return true;
// FloatingLiteral
if (typeName.Contains("APFloatSemantics") ||
typeName.Contains("fltSemantics") ||
typeName.Contains("APFloat"))
return true;
// OffsetOfExpr
// UnaryExprOrTypeTraitExpr
// CompoundLiteralExpr
// ExplicitCastExpr
// ConvertVectorExpr
// VAArgExpr
if (typeName.Contains("TypeSourceInfo"))
return true;
// MemberExpr
if (typeName.Contains("ValueDecl") ||
typeName.Contains("DeclAccessPair") ||
typeName.Contains("NestedNameSpecifier") ||
typeName.Contains("TemplateArgumentLoc"))
return true;
// BinaryOperator
if (typeName.Contains("FPOptions"))
return true;
// DesignatedInitExpr
// ExtVectorElementExpr
if (typeName.Contains("IdentifierInfo"))
return true;
// BlockExpr
if (typeName.Contains("BlockDecl"))
return true;
// ArrayInitLoopExpr
if (typeName.Contains("APInt"))
return true;
// MemberExpr
if (typeName.Contains("BlockExpr") ||
typeName.Contains("FunctionProtoType"))
return true;
//
// C++ expression properties.
//
// MSPropertyRefExpr
if (typeName.Contains("MSPropertyDecl"))
return true;
// CXXBindTemporaryExpr
if (typeName.Contains("CXXTemporary"))
return true;
// CXXConstructExpr
// CXXInheritedCtorInitExpr
if (typeName.Contains("CXXConstructorDecl") ||
typeName.Contains("ConstructionKind"))
return true;
// CXXInheritedCtorInitExpr
if (typeName.Contains("LambdaCaptureDefault") ||
typeName.Contains("TemplateParameterList"))
return true;
// CXXNewExpr
if (property.Name == "placementArgs")
return true;
// TypeTraitExpr
if (typeName == "TypeTrait")
return true;
// ArrayTypeTraitExpr
if (typeName.Contains("ArrayTypeTrait"))
return true;
// ExpressionTraitExpr
if (typeName.Contains("ExpressionTrait"))
return true;
// OverloadExpr
// DependentScopeDeclRefExpr
// UnresolvedMemberExpr
if (typeName.Contains("DeclarationName"))
return true;
// SubstNonTypeTemplateParmExpr
// SubstNonTypeTemplateParmPackExpr
if (typeName.Contains("NonTypeTemplateParmDecl"))
return true;
// MaterializeTemporaryExpr
if (typeName.Contains("StorageDuration"))
return true;
// General properties.
if (typeName.Contains("_iterator") ||
typeName.Contains("_range"))
return true;
if (typeName.Contains("ArrayRef"))
return true;
// AtomicExpr
if (typeName.Contains("unique_ptr<AtomicScopeModel, default_delete<AtomicScopeModel>>"))
return true;
if (typeName.Contains("Expr**"))
return true;
// GenericSelectionExpr
if (typeName.Contains("AssociationIteratorTy"))
return true;
// CXXRewrittenBinaryOperator
if (typeName.Contains("DecomposedForm"))
return true;
if (typeName.Contains("optional"))
return true;
// ConstantExpr (TODO: Fix this properly)
if (property.Name.Contains("resultAsAP") ||
property.Name.Contains("aPValueResult") ||
property.Name.Contains("resultAPValueKind"))
return true;
return false;
}
public static bool SkipMethod(Method method)
{
if (method.Ignore)
return true;
var @class = method.Namespace as Class;
if (@class.GetBaseMethod(method) != null)
return true;
if (method.Name == "children")
return true;
// CastExpr
if (method.Name == "path")
return true;
// CXXNewExpr
if (method.Name == "placement_arguments" && method.IsConst)
return true;
var typeName = method.ReturnType.Visit(CppTypePrinter).Type;
if (typeName.Contains("const"))
return true;
if (!typeName.Contains("range"))
return true;
// OverloadExpr
if (typeName.Contains("UnresolvedSet"))
return true;
// LambdaExpr
if (method.Name == "captures")
return true;
var iteratorType = GetIteratorType(method);
string iteratorTypeName = GetIteratorTypeName(iteratorType, CppTypePrinter);
if (iteratorTypeName.Contains("LambdaCapture"))
return true;
// GenericSelectionExpr
if (iteratorTypeName.Contains("AssociationIteratorTy"))
return true;
return false;
}
public static string GetQualifiedName(Declaration decl,
TypePrinter typePrinter)
{
typePrinter.PushScope(TypePrintScopeKind.Qualified);
var qualifiedName = decl.Visit(typePrinter).Type;
typePrinter.PopScope();
qualifiedName = CleanClangNamespaceFromName(qualifiedName);
if (qualifiedName.Contains("ExprDependenceScope"))
qualifiedName = qualifiedName
.Replace("ExprDependenceScope" + (typePrinter is CppTypePrinter ? "::" : ".")
, "");
else if (qualifiedName.Contains("Semantics"))
qualifiedName = qualifiedName.Replace(
typePrinter is CppTypePrinter ? "llvm::APFloatBase::Semantics" : "llvm.APFloatBase.Semantics"
, "FloatSemantics");
return qualifiedName;
}
public static string GetQualifiedName(Declaration decl) =>
GetQualifiedName(decl, CppTypePrinter);
private static string CleanClangNamespaceFromName(string qualifiedName)
{
qualifiedName = qualifiedName.StartsWith("clang::") ?
qualifiedName.Substring("clang::".Length) : qualifiedName;
qualifiedName = qualifiedName.StartsWith("clang.") ?
qualifiedName.Substring("clang.".Length) : qualifiedName;
return qualifiedName;
}
public static string GetDeclName(Declaration decl, GeneratorKind kind)
{
string name = decl.Name;
if (kind == GeneratorKind.CPlusPlus)
{
if (Generators.C.CCodeGenerator.IsReservedKeyword(name))
name = $"_{name}";
}
else if (kind == GeneratorKind.CSharp)
{
bool hasConflict = false;
switch (name)
{
case "identKind":
case "literalOperatorKind":
case "resultStorageKind":
case "aDLCallKind":
case "initializationStyle":
case "capturedStmt":
hasConflict = true;
break;
}
if (!hasConflict)
name = CSharpSources.SafeIdentifier(
CaseRenamePass.ConvertCaseString(decl,
RenameCasePattern.UpperCamelCase));
}
else throw new NotImplementedException();
return name;
}
public static string GetDeclName(Declaration decl)
{
return GetDeclName(decl, GeneratorKind.CPlusPlus);
}
public static AST.Type GetDeclType(AST.Type type,
TypePrinter typePrinter)
{
var qualifiedType = new QualifiedType(type);
if (qualifiedType.Type.IsPointerTo(out TagType tagType))
qualifiedType = qualifiedType.StripConst();
var typeName = qualifiedType.Type.Visit(typePrinter).Type;
if (typeName.Contains("StringRef") || typeName.Contains("string"))
type = new BuiltinType(PrimitiveType.String);
return type;
}
public static string GetDeclTypeName(ITypedDecl decl) =>
GetDeclTypeName(decl.Type, CppTypePrinter);
public static string GetDeclTypeName(AST.Type type,
TypePrinter typePrinter)
{
var declType = GetDeclType(type, typePrinter);
var typeResult = declType.Visit(typePrinter);
if (typeResult.Type.Contains("MSGuidDecl"))
return typePrinter is CppTypePrinter
? "std::string" : "string";
var typeName = typeResult.ToString();
typeName = CleanClangNamespaceFromName(typeName);
if (typeName.Contains("QualType"))
typeName = "QualifiedType";
else if (typeName.Contains("UnaryOperator::Opcode"))
typeName = "UnaryOperatorKind";
else if (typeName.Contains("BinaryOperator::Opcode"))
typeName = "BinaryOperatorKind";
else if (typeName.Contains("Semantics"))
typeName = "FloatSemantics";
else if (typeName.Contains("optional"))
{
if (typePrinter is CppTypePrinter)
{
typeName = "std::" + typeName;
}
else
{
var optType = (declType as TemplateSpecializationType)!.Arguments[0].Type;
typeResult = optType.Visit(typePrinter);
typeName = $"{typeResult}?";
}
}
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;
TemplateSpecializationType templateSpecType;
TypedefType typedefType;
TypedefNameDecl typedefNameDecl;
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;
}
var iteratorType = typedefNameDecl.Type;
if (iteratorType.IsPointerTo(out PointerType pointee))
iteratorType = iteratorType.GetPointee();
return iteratorType;
}
public static string GetIteratorTypeName(AST.Type iteratorType,
TypePrinter typePrinter)
{
if (iteratorType.IsPointer())
iteratorType = iteratorType.GetFinalPointee();
typePrinter.PushScope(TypePrintScopeKind.Qualified);
var iteratorTypeName = iteratorType.Visit(typePrinter).Type;
typePrinter.PopScope();
iteratorTypeName = CleanClangNamespaceFromName(iteratorTypeName);
if (iteratorTypeName.Contains("ExprIterator"))
iteratorTypeName = "Expr";
else if (iteratorTypeName.Contains("StmtIterator"))
iteratorTypeName = "Stmt";
else if (iteratorTypeName.Contains("CastIterator"))
{
if (iteratorType is TypedefType typedefType)
iteratorType = typedefType.Declaration.Type;
var templateArg = ((TemplateSpecializationType)iteratorType).Arguments[0];
iteratorType = templateArg.Type.Type;
typePrinter.PushScope(TypePrintScopeKind.Qualified);
iteratorTypeName = iteratorType.Visit(typePrinter).Type;
typePrinter.PopScope();
iteratorTypeName = CleanClangNamespaceFromName(iteratorTypeName);
}
if (iteratorTypeName == "Decl")
iteratorTypeName = "Declaration";
if (typePrinter is CppTypePrinter)
return $"{iteratorTypeName}*";
return iteratorTypeName;
}
public static List<Class> GetBaseClasses(Class @class)
{
var baseClasses = new List<Class>();
Class currentClass = @class;
while (currentClass != null)
{
baseClasses.Add(currentClass);
currentClass = currentClass.HasBaseClass ?
currentClass.BaseClass : null;
}
baseClasses.Reverse();
return baseClasses;
}
public static string RemoveFromEnd(string s, string suffix)
{
return s.EndsWith(suffix) ? s.Substring(0, s.Length - suffix.Length) : s;
}
public static string FirstLetterToUpperCase(string s)
{
if (string.IsNullOrEmpty(s))
throw new ArgumentException("There is no first letter");
char[] a = s.ToCharArray();
a[0] = char.ToUpper(a[0]);
return new string(a);
}
}
}

535
src/CppParser/Bootstrap/StmtCodeGenerators.cs

@ -0,0 +1,535 @@ @@ -0,0 +1,535 @@
using CppSharp.Generators;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CppSharp.AST;
using CppSharp.AST.Extensions;
using CppSharp.Generators.C;
using static CppSharp.CodeGeneratorHelpers;
namespace CppSharp
{
internal class StmtDeclarationsCodeGenerator : DeclarationsCodeGenerator
{
public StmtDeclarationsCodeGenerator(BindingContext context, IEnumerable<Declaration> declarations)
: base(context, declarations)
{
}
public override string BaseTypeName => "Stmt";
public override bool VisitDeclaration(Declaration decl)
{
if (!base.VisitDeclaration(decl))
return false;
if (decl.Name == "GCCAsmStmt")
{
WriteLine("class StringLiteral;");
WriteLine("class AddrLabelExpr;");
NewLine();
}
return true;
}
public override void GenerateForwardDecls()
{
WriteLine("class Expr;");
WriteLine("class Declaration;");
}
public override bool GenerateClassBody(Class @class)
{
Unindent();
WriteLine("public:");
Indent();
PushBlock();
VisitDeclContext(@class);
PopBlock(NewLineKind.Always);
WriteLine($"{@class.Name}();");
if (IsInheritedClass(@class))
WriteLine($"{@class.Name}(StmtClass klass);");
if (@class.Name == "Stmt")
WriteLine("StmtClass stmtClass;");
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))
continue;
string typeName = GetDeclTypeName(property);
WriteLine($"{typeName} {GetDeclName(property)};");
}
return true;
}
}
internal class StmtDefinitionsCodeGenerator : DefinitionsCodeGenerator
{
public StmtDefinitionsCodeGenerator(BindingContext context, IEnumerable<Declaration> declarations)
: base(context, declarations)
{
}
public override string BaseTypeName => "Stmt";
public override void GenerateIncludes()
{
GenerateCommonIncludes();
WriteInclude("Stmt.h", CInclude.IncludeKind.Quoted);
}
public override bool VisitClassDecl(Class @class)
{
VisitDeclContext(@class);
var isStmt = @class.Name == "Stmt";
if (!isStmt && !@class.HasBaseClass)
{
WriteLine($"{GetQualifiedName(@class)}::{@class.Name}()");
WriteOpenBraceAndIndent();
UnindentAndWriteCloseBrace();
NewLine();
return true;
}
WriteLine($"{@class.Name}::{@class.Name}()");
var stmtMember = isStmt ? "stmtClass" : @class.BaseClass.Name;
var stmtClass = IsAbstractStmt(@class) ? "NoStmt" : @class.Name;
WriteLineIndent($": {stmtMember}(StmtClass::{stmtClass})");
GenerateMemberInits(@class);
WriteOpenBraceAndIndent();
UnindentAndWriteCloseBrace();
NewLine();
var isInherited = IsInheritedClass(@class);
if (isInherited)
{
WriteLine($"{@class.Name}::{@class.Name}(StmtClass klass)");
var member = isStmt ? "stmtClass" : @class.BaseClass.Name;
WriteLineIndent($": {member}(klass)");
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 StmtParserCodeGenerator : NativeParserCodeGenerator
{
private IEnumerable<Class> ExpressionClasses;
public StmtParserCodeGenerator(BindingContext context,
IEnumerable<Declaration> declarations, IEnumerable<Class> exprs)
: base(context, declarations)
{
ExpressionClasses = exprs;
}
public override bool GeneratePragmaOnce => false;
public void GenerateParser()
{
Process();
WriteInclude("AST.h", CInclude.IncludeKind.Quoted);
WriteInclude("Parser.h", CInclude.IncludeKind.Quoted);
GenerateIncludes();
NewLine();
WriteLine("namespace CppSharp::CppParser {");
NewLine();
GenerateWalkStatement();
NewLine();
WriteLine("}");
}
public virtual void GenerateIncludes()
{
WriteInclude("clang/AST/Stmt.h", CInclude.IncludeKind.Angled);
WriteInclude("clang/AST/StmtCXX.h", CInclude.IncludeKind.Angled);
}
public virtual string MethodSig =>
"AST::Stmt* Parser::WalkStatement(const clang::Stmt* Stmt)";
public virtual string BaseTypeName => "Stmt";
private void GenerateWalkStatement()
{
WriteLine(MethodSig);
WriteOpenBraceAndIndent();
WriteLine($"if (!{BaseTypeName})");
WriteLineIndent("return nullptr;");
NewLine();
WriteLine($"AST::{BaseTypeName}* _{BaseTypeName}= nullptr;");
NewLine();
WriteLine($"switch ({BaseTypeName}->getStmtClass())");
WriteLine("{");
foreach (var @class in Declarations.OfType<Class>())
{
if (IsAbstractStmt(@class))
continue;
WriteLine($"case clang::Stmt::{@class.Name}Class:");
WriteOpenBraceAndIndent();
WriteLine($"auto S = const_cast<clang::{@class.Name}*>(" +
$"llvm::cast<clang::{@class.Name}>({BaseTypeName}));");
WriteLine($"auto _S = new AST::{@class.Name}();");
var classHierarchy = GetBaseClasses(@class);
foreach (var baseClass in classHierarchy)
baseClass.Visit(this);
WriteLine($"_{BaseTypeName} = _S;");
WriteLine("break;");
UnindentAndWriteCloseBrace();
}
if (ExpressionClasses != null)
{
foreach (var @class in ExpressionClasses.Where(c => !IsAbstractStmt(c)))
WriteLine($"case clang::Stmt::{@class.Name}Class:");
WriteOpenBraceAndIndent();
WriteLine("return WalkExpression(llvm::cast<clang::Expr>(Stmt));");
UnindentAndWriteCloseBrace();
}
WriteLine("default:");
WriteLineIndent("printf(\"Unhandled statement kind: %s\\n\"," +
$" {BaseTypeName}->getStmtClassName());");
WriteLine("}");
NewLine();
WriteLine($"return _{BaseTypeName};");
UnindentAndWriteCloseBrace();
}
public override bool VisitClassDecl(Class @class)
{
foreach (var property in @class.Properties)
{
if (SkipProperty(property, skipBaseCheck: true))
continue;
property.Visit(this);
}
foreach (var method in @class.Methods)
{
if (SkipMethod(method))
continue;
method.Visit(this);
}
return true;
}
public override bool VisitMethodDecl(Method method)
{
var iteratorType = GetIteratorType(method);
string iteratorTypeName = GetIteratorTypeName(iteratorType,
CodeGeneratorHelpers.CppTypePrinter);
WriteLine($"for (auto _E : S->{method.Name}())");
WriteOpenBraceAndIndent();
bool isBaseType = iteratorTypeName switch
{
"Declaration*" or "Expr*" or "Stmt*" => true,
_ => false
};
string walkMethod;
if (iteratorTypeName.Contains("Decl"))
{
walkMethod = "WalkDeclaration";
}
else if (iteratorTypeName.Contains("Expr"))
{
walkMethod = "WalkExpression";
}
else if (iteratorTypeName.Contains("Stmt"))
{
walkMethod = "WalkStatement";
}
else
{
throw new NotImplementedException();
}
WriteLine("auto _ES = {0}{1}(_E);", isBaseType ? string.Empty : $"(AST::{iteratorTypeName})", walkMethod);
WriteLine($"_S->add{method.Name}(_ES);");
UnindentAndWriteCloseBrace();
return true;
}
public override bool VisitProperty(Property property)
{
var typeName = GetDeclTypeName(property);
var fieldName = GetDeclName(property);
var methodName = property.GetMethod?.Name;
var validMethod = $"is{FirstLetterToUpperCase(property.Name)}";
var @class = (property.Namespace as Class)!;
var validMethodExists = @class.Methods.Exists(m => m.Name == validMethod)
&& methodName != validMethod;
if (validMethodExists)
{
WriteLine($"if (S->{validMethod}())");
Indent();
}
if (property.Type.TryGetEnum(out Enumeration @enum))
WriteLine($"_S->{fieldName} = (AST::{GetQualifiedName(@enum)})S->{methodName}();");
else if (typeName.Contains("SourceLocation"))
return false;
else if (typeName.Contains("SourceRange"))
return false;
else if (typeName.Contains("Stmt"))
WriteLine($"_S->{fieldName} = static_cast<AST::{typeName}>(" +
$"WalkStatement(S->{methodName}()));");
else if (typeName.Contains("Expr"))
WriteLine($"_S->{fieldName} = static_cast<AST::{typeName}>(" +
$"WalkExpression(S->{methodName}()));");
else if (fieldName == "guidDecl")
WriteLine($"_S->{fieldName} = S->getGuidDecl()->getNameAsString();");
else if (typeName.Contains("Decl") || typeName.Contains("Method") ||
typeName.Contains("Function") || typeName.Contains("Field"))
WriteLine($"_S->{fieldName} = static_cast<AST::{typeName}>(" +
$"WalkDeclaration(S->{methodName}()));");
else if (typeName.Contains("TemplateArgument"))
WriteLine($"_S->{fieldName} = WalkTemplateArgument(S->{methodName}());");
else if (typeName.Contains("QualifiedType"))
WriteLine($"_S->{fieldName} = GetQualifiedType(S->{methodName}());");
else if (fieldName == "value" && @class.Bases.Exists(b => b.Class.Name.Contains("AP")))
{
// Use llvm::APInt or llvm::APFloat conversion methods
methodName = property.Type.IsPrimitiveType(PrimitiveType.ULongLong) ?
"getLimitedValue" : "convertToDouble";
WriteLine($"_S->{fieldName} = S->getValue().{methodName}();");
}
else
WriteLine($"_S->{fieldName} = S->{methodName}();");
if (validMethodExists)
Unindent();
return true;
}
}
internal class StmtASTConverterCodeGenerator : ASTConverterCodeGenerator
{
private readonly Enumeration StmtClassEnum;
public StmtASTConverterCodeGenerator(BindingContext context, IEnumerable<Declaration> declarations, Enumeration stmtClassEnum)
: base(context, declarations)
{
StmtClassEnum = stmtClassEnum;
}
public override string BaseTypeName => "Stmt";
public override bool IsAbstractASTNode(Class kind)
{
return CodeGeneratorHelpers.IsAbstractStmt(kind);
}
protected override void GenerateVisitorSwitch(IEnumerable<string> classes)
{
WriteLine($"switch({ParamName}.StmtClass)");
WriteOpenBraceAndIndent();
var enumItems = StmtClassEnum != null ?
StmtClassEnum.Items.Where(item => item.IsGenerated)
.Select(item => RemoveFromEnd(item.Name, "Class"))
.Where(@class => !IsAbstractStmt(@class))
: classes;
GenerateSwitchCases(enumItems);
UnindentAndWriteCloseBrace();
}
private void GenerateSwitchCases(IEnumerable<string> classes)
{
foreach (var className in classes)
{
WriteLine($"case StmtClass.{className}:");
WriteOpenBraceAndIndent();
WriteLine($"var _{ParamName} = {className}.__CreateInstance({ParamName}.__Instance);");
var isExpression = Declarations
.OfType<Class>()
.All(c => c.Name != className);
if (isExpression)
WriteLine($"return VisitExpression(_{ParamName} as Expr) as TRet;");
else
WriteLine($"return Visit{className}(_{ParamName});");
UnindentAndWriteCloseBrace();
}
WriteLine("default:");
WriteLineIndent($"throw new System.NotImplementedException({ParamName}.StmtClass.ToString());");
}
}
internal class ExprDeclarationsCodeGenerator : StmtDeclarationsCodeGenerator
{
public ExprDeclarationsCodeGenerator(BindingContext context,
IEnumerable<Declaration> declarations)
: base(context, declarations)
{
}
public override string BaseTypeName => "Expr";
public override void GenerateIncludes()
{
WriteInclude("Stmt.h", CInclude.IncludeKind.Quoted);
}
public override void GenerateForwardDecls()
{
WriteLine("class Field;");
WriteLine("class Method;");
WriteLine("class Function;");
WriteLine("class FunctionTemplate;");
}
}
internal class ExprDefinitionsCodeGenerator : StmtDefinitionsCodeGenerator
{
public ExprDefinitionsCodeGenerator(BindingContext context,
IEnumerable<Declaration> declarations)
: base(context, declarations)
{
}
public override string BaseTypeName => "Expr";
public override void GenerateIncludes()
{
GenerateCommonIncludes();
WriteInclude("Expr.h", CInclude.IncludeKind.Quoted);
}
}
internal class ExprParserCodeGenerator : StmtParserCodeGenerator
{
public ExprParserCodeGenerator(BindingContext context,
IEnumerable<Declaration> declarations)
: base(context, declarations, null)
{
}
public override void GenerateIncludes()
{
WriteInclude("clang/AST/Expr.h", CInclude.IncludeKind.Angled);
WriteInclude("clang/AST/ExprCXX.h", CInclude.IncludeKind.Angled);
}
public override string BaseTypeName => "Expr";
public override string MethodSig =>
"AST::Expr* Parser::WalkExpression(const clang::Expr* Expr)";
}
internal class ExprASTConverterCodeGenerator : StmtASTConverterCodeGenerator
{
public ExprASTConverterCodeGenerator(BindingContext context, IEnumerable<Declaration> declarations)
: base(context, declarations, null)
{
}
public override string BaseTypeName => "Expr";
public override bool IsAbstractASTNode(Class kind)
{
return CodeGeneratorHelpers.IsAbstractStmt(kind);
}
protected override void GenerateVisitorSwitch(IEnumerable<string> classes)
{
WriteLine($"switch({ParamName}.StmtClass)");
WriteOpenBraceAndIndent();
GenerateSwitchCases(classes);
UnindentAndWriteCloseBrace();
}
private void GenerateSwitchCases(IEnumerable<string> classes)
{
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}.StmtClass.ToString());");
}
}
}

26
src/CppParser/Sources.h

@ -9,19 +9,19 @@ @@ -9,19 +9,19 @@
#include "Helpers.h"
namespace CppSharp { namespace CppParser {
namespace CppSharp::CppParser {
struct CS_API CS_VALUE_TYPE SourceLocation
{
SourceLocation();
SourceLocation(unsigned ID);
unsigned ID;
};
struct CS_API CS_VALUE_TYPE SourceLocation
{
SourceLocation();
SourceLocation(unsigned ID);
unsigned ID;
};
struct CS_API SourceRange
{
SourceLocation beginLoc;
SourceLocation endLoc;
};
struct CS_API SourceRange
{
SourceLocation beginLoc;
SourceLocation endLoc;
};
}} // namespace CppSharp::CppParser
} // namespace CppSharp::CppParser

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

@ -74,8 +74,7 @@ namespace CppSharp.Generators.C @@ -74,8 +74,7 @@ namespace CppSharp.Generators.C
return true;
}
public override TypePrinterResult VisitTagType(TagType tag,
TypeQualifiers quals)
public override TypePrinterResult VisitTagType(TagType tag, TypeQualifiers quals)
{
if (FindTypeMap(tag, out var result))
return result;
@ -122,8 +121,7 @@ namespace CppSharp.Generators.C @@ -122,8 +121,7 @@ namespace CppSharp.Generators.C
return string.Empty;
}
public override TypePrinterResult VisitPointerType(PointerType pointer,
TypeQualifiers quals)
public override TypePrinterResult VisitPointerType(PointerType pointer, TypeQualifiers quals)
{
if (FindTypeMap(pointer, out TypePrinterResult result))
return result;
@ -139,10 +137,10 @@ namespace CppSharp.Generators.C @@ -139,10 +137,10 @@ namespace CppSharp.Generators.C
var paren = array != null && pointer.Modifier == PointerType.TypeModifier.LVReference;
if (paren)
pointeeType.NamePrefix.Append("(");
pointeeType.NamePrefix.Append('(');
pointeeType.NamePrefix.Append(mod);
if (paren)
pointeeType.NameSuffix.Insert(0, ")");
pointeeType.NameSuffix.Insert(0, ')');
var qual = GetStringQuals(quals, false);
if (!string.IsNullOrEmpty(qual))
@ -151,21 +149,18 @@ namespace CppSharp.Generators.C @@ -151,21 +149,18 @@ namespace CppSharp.Generators.C
return pointeeType;
}
public override TypePrinterResult VisitMemberPointerType(MemberPointerType member,
TypeQualifiers quals)
public override TypePrinterResult VisitMemberPointerType(MemberPointerType member, TypeQualifiers quals)
{
return string.Empty;
}
public override TypePrinterResult VisitBuiltinType(BuiltinType builtin,
TypeQualifiers quals)
public override TypePrinterResult VisitBuiltinType(BuiltinType builtin, TypeQualifiers quals)
{
var qual = GetStringQuals(quals);
return $"{qual}{VisitPrimitiveType(builtin.Type)}";
}
public override TypePrinterResult VisitPrimitiveType(PrimitiveType primitive,
TypeQualifiers quals)
public override TypePrinterResult VisitPrimitiveType(PrimitiveType primitive, TypeQualifiers quals)
{
var qual = GetStringQuals(quals);
return $"{qual}{VisitPrimitiveType(primitive)}";
@ -235,8 +230,7 @@ namespace CppSharp.Generators.C @@ -235,8 +230,7 @@ namespace CppSharp.Generators.C
throw new NotSupportedException();
}
public override TypePrinterResult VisitTypedefType(TypedefType typedef,
TypeQualifiers quals)
public override TypePrinterResult VisitTypedefType(TypedefType typedef, TypeQualifiers quals)
{
var qual = GetStringQuals(quals);
if (ResolveTypedefs && !typedef.Declaration.Type.IsPointerTo(out FunctionType _))
@ -269,8 +263,7 @@ namespace CppSharp.Generators.C @@ -269,8 +263,7 @@ namespace CppSharp.Generators.C
return decayed.Decayed.Visit(this);
}
public override TypePrinterResult VisitTemplateSpecializationType(
TemplateSpecializationType template, TypeQualifiers quals)
public override TypePrinterResult VisitTemplateSpecializationType(TemplateSpecializationType template, TypeQualifiers quals)
{
var specialization = template.GetClassTemplateSpecialization();
if (specialization == null)
@ -324,11 +317,11 @@ namespace CppSharp.Generators.C @@ -324,11 +317,11 @@ namespace CppSharp.Generators.C
{
if (unaryTransformType.Desugared.Type != null)
return unaryTransformType.Desugared.Visit(this);
return unaryTransformType.BaseType.Visit(this);
}
public override TypePrinterResult VisitVectorType(VectorType vectorType,
TypeQualifiers quals)
public override TypePrinterResult VisitVectorType(VectorType vectorType, TypeQualifiers quals)
{
// an incomplete implementation but we'd hardly need anything better
return "__attribute__()";
@ -606,24 +599,16 @@ namespace CppSharp.Generators.C @@ -606,24 +599,16 @@ namespace CppSharp.Generators.C
public override TypePrinterResult VisitFunctionDecl(Function function)
{
string @class;
switch (MethodScopeKind)
string @class = MethodScopeKind switch
{
case TypePrintScopeKind.Qualified:
@class = $"{function.Namespace.Visit(this)}::";
break;
case TypePrintScopeKind.GlobalQualified:
@class = $"::{function.Namespace.Visit(this)}::";
break;
default:
@class = string.Empty;
break;
}
TypePrintScopeKind.Qualified => $"{function.Namespace.Visit(this)}::",
TypePrintScopeKind.GlobalQualified => $"::{function.Namespace.Visit(this)}::",
_ => string.Empty,
};
var @params = string.Join(", ", function.Parameters.Select(p => p.Visit(this)));
var @const = function is Method method && method.IsConst ? " const" : string.Empty;
var name = function.OperatorKind == CXXOperatorKind.Conversion ||
function.OperatorKind == CXXOperatorKind.ExplicitConversion ?
var name = function.OperatorKind is CXXOperatorKind.Conversion or CXXOperatorKind.ExplicitConversion ?
$"operator {function.OriginalReturnType.Visit(this)}" :
function.OriginalName;

18
src/Generator/Generators/CodeGenerator.cs

@ -1058,27 +1058,33 @@ namespace CppSharp.Generators @@ -1058,27 +1058,33 @@ namespace CppSharp.Generators
throw new NotImplementedException();
}
public virtual bool VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr stmt){
public virtual bool VisitSYCLUniqueStableNameExpr(SYCLUniqueStableNameExpr stmt)
{
throw new NotImplementedException();
}
public virtual bool VisitSourceLocExpr(SourceLocExpr stmt){
public virtual bool VisitSourceLocExpr(SourceLocExpr stmt)
{
throw new NotImplementedException();
}
public virtual bool VisitRecoveryExpr(RecoveryExpr stmt){
public virtual bool VisitRecoveryExpr(RecoveryExpr stmt)
{
throw new NotImplementedException();
}
public virtual bool VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator stmt){
public virtual bool VisitCXXRewrittenBinaryOperator(CXXRewrittenBinaryOperator stmt)
{
throw new NotImplementedException();
}
public virtual bool VisitCXXAddrspaceCastExpr(CXXAddrspaceCastExpr stmt){
public virtual bool VisitCXXAddrspaceCastExpr(CXXAddrspaceCastExpr stmt)
{
throw new NotImplementedException();
}
public virtual bool VisitCXXParenListInitExpr(CXXParenListInitExpr stmt){
public virtual bool VisitCXXParenListInitExpr(CXXParenListInitExpr stmt)
{
throw new NotImplementedException();
}

17
src/Generator/Generators/TypePrinter.cs

@ -10,8 +10,8 @@ namespace CppSharp.Generators @@ -10,8 +10,8 @@ namespace CppSharp.Generators
{
public string Type { get; set; }
public string Name { get; set; } = string.Empty;
public StringBuilder NamePrefix { get; set; } = new StringBuilder();
public StringBuilder NameSuffix { get; set; } = new StringBuilder();
public StringBuilder NamePrefix { get; set; } = new();
public StringBuilder NameSuffix { get; set; } = new();
public TypeMap TypeMap { get; set; }
public GeneratorKind Kind { get; set; }
@ -25,11 +25,11 @@ namespace CppSharp.Generators @@ -25,11 +25,11 @@ namespace CppSharp.Generators
{
var index = Type.LastIndexOf('.');
if (index != -1)
Type = Type.Substring(index + 1);
Type = Type[(index + 1)..];
}
public static implicit operator TypePrinterResult(string type) =>
new TypePrinterResult { Type = type };
new() { Type = type };
public static implicit operator string(TypePrinterResult result) =>
result.ToString();
@ -196,20 +196,17 @@ namespace CppSharp.Generators @@ -196,20 +196,17 @@ namespace CppSharp.Generators
throw new NotImplementedException();
}
public virtual TypePrinterResult VisitFunctionTemplateDecl(
FunctionTemplate template)
public virtual TypePrinterResult VisitFunctionTemplateDecl(FunctionTemplate template)
{
throw new NotImplementedException();
}
public virtual TypePrinterResult VisitFunctionTemplateSpecializationDecl(
FunctionTemplateSpecialization specialization)
public virtual TypePrinterResult VisitFunctionTemplateSpecializationDecl(FunctionTemplateSpecialization specialization)
{
throw new NotImplementedException();
}
public virtual TypePrinterResult VisitFunctionType(FunctionType function,
TypeQualifiers quals)
public virtual TypePrinterResult VisitFunctionType(FunctionType function, TypeQualifiers quals)
{
throw new NotImplementedException();
}

14
src/Generator/Passes/GetterSetterToPropertyPass.cs

@ -143,14 +143,14 @@ namespace CppSharp.Passes @@ -143,14 +143,14 @@ namespace CppSharp.Passes
var firstWord = GetFirstWord(property.GetMethod.Name);
var isKeyword = firstWord.Length < property.GetMethod.Name.Length &&
Match(firstWord, new[] {"get", "is", "has"});
Match(firstWord, new[] { "get", "is", "has" });
switch (Options.PropertyDetectionMode)
{
case PropertyDetectionMode.Keywords:
return isKeyword;
case PropertyDetectionMode.Dictionary:
var isAction = Match(firstWord, new[] {"to", "new", "on"}) || Verbs.Contains(firstWord);
var isAction = Match(firstWord, new[] { "to", "new", "on" }) || Verbs.Contains(firstWord);
return isKeyword || !isAction;
default:
return false;
@ -287,8 +287,7 @@ namespace CppSharp.Passes @@ -287,8 +287,7 @@ namespace CppSharp.Passes
m => m.IsGenerated && m.Name == property.Name))
{
var oldName = method.Name;
method.Name = $@"get{char.ToUpperInvariant(method.Name[0])}{
method.Name.Substring(1)}";
method.Name = $@"get{char.ToUpperInvariant(method.Name[0])}{method.Name.Substring(1)}";
Diagnostics.Debug("Method {0}::{1} renamed to {2}",
method.Namespace.Name, oldName, method.Name);
}
@ -296,8 +295,7 @@ namespace CppSharp.Passes @@ -296,8 +295,7 @@ namespace CppSharp.Passes
e => e.Name == property.Name))
{
var oldName = @event.Name;
@event.Name = $@"on{char.ToUpperInvariant(@event.Name[0])}{
@event.Name.Substring(1)}";
@event.Name = $@"on{char.ToUpperInvariant(@event.Name[0])}{@event.Name.Substring(1)}";
Diagnostics.Debug("Event {0}::{1} renamed to {2}",
@event.Namespace.Name, oldName, @event.Name);
}
@ -345,7 +343,7 @@ namespace CppSharp.Passes @@ -345,7 +343,7 @@ namespace CppSharp.Passes
private static string GetPropertyName(string name)
{
var firstWord = GetFirstWord(name);
if (!Match(firstWord, new[] {"get"}) ||
if (!Match(firstWord, new[] { "get" }) ||
(string.Compare(name, firstWord, StringComparison.InvariantCultureIgnoreCase) == 0) ||
char.IsNumber(name[3])) return name;
@ -368,7 +366,7 @@ namespace CppSharp.Passes @@ -368,7 +366,7 @@ namespace CppSharp.Passes
private bool IsGetter(Method method) =>
!method.IsDestructor &&
!method.OriginalReturnType.Type.IsPrimitiveType(PrimitiveType.Void) &&
!method.OriginalReturnType.Type.IsPrimitiveType(PrimitiveType.Void) &&
method.Parameters.All(p => p.Kind == ParameterKind.IndirectReturnType);
private static bool IsSetter(Method method)

4
src/Parser/ASTConverter.Expr.cs

@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
// ----------------------------------------------------------------------------
using CppSharp.Parser.AST;
using static CppSharp.ConversionUtils;
namespace CppSharp
@ -13,7 +14,8 @@ namespace CppSharp @@ -13,7 +14,8 @@ namespace CppSharp
// <summary>
// <para>Implements the visitor pattern for the generated expr bindings.</para>
// </summary>
public abstract class ExprVisitor<TRet> where TRet : class
public abstract class ExprVisitor<TRet>
where TRet : class
{
public abstract TRet VisitConstantExpr(ConstantExpr expr);
public abstract TRet VisitOpaqueValueExpr(OpaqueValueExpr expr);

4
src/Parser/ASTConverter.Stmt.cs

@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
// ----------------------------------------------------------------------------
using CppSharp.Parser.AST;
using static CppSharp.ConversionUtils;
namespace CppSharp
@ -13,7 +14,8 @@ namespace CppSharp @@ -13,7 +14,8 @@ namespace CppSharp
// <summary>
// <para>Implements the visitor pattern for the generated stmt bindings.</para>
// </summary>
public abstract class StmtVisitor<TRet> where TRet : class
public abstract class StmtVisitor<TRet>
where TRet : class
{
public abstract TRet VisitDeclStmt(DeclStmt stmt);
public abstract TRet VisitNullStmt(NullStmt stmt);

Loading…
Cancel
Save