diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs index 3ebb32a7..b66e0ab4 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitDecl.cs @@ -673,11 +673,19 @@ private void VisitFunctionDecl(FunctionDecl functionDecl) outputBuilder.Write("return "); } - var cxxBaseSpecifier = _cxxRecordDeclContext.Bases.Where((baseSpecifier) => baseSpecifier.Referenced == cxxMethodDecl.Parent).Single(); - var baseFieldName = GetAnonymousName(cxxBaseSpecifier, "Base"); - baseFieldName = GetRemappedName(baseFieldName, cxxBaseSpecifier, tryRemapOperatorName: true, out var wasRemapped, skipUsing: true); + var cxxBaseSpecifier = _cxxRecordDeclContext.Bases.Where((baseSpecifier) => baseSpecifier.Referenced == cxxMethodDecl.Parent).SingleOrDefault(); - outputBuilder.Write(baseFieldName); + if (cxxBaseSpecifier != null) + { + var baseFieldName = GetAnonymousName(cxxBaseSpecifier, "Base"); + baseFieldName = GetRemappedName(baseFieldName, cxxBaseSpecifier, tryRemapOperatorName: true, out var wasRemapped, skipUsing: true); + outputBuilder.Write(baseFieldName); + } + else + { + outputBuilder.Write("Base"); + } + outputBuilder.Write('.'); outputBuilder.Write(name); outputBuilder.Write('('); @@ -3504,7 +3512,12 @@ private bool IsConstant(string targetTypeName, Expr initExpr) // case CX_StmtClass.CX_StmtClass_CXXTemporaryObjectExpr: // case CX_StmtClass.CX_StmtClass_CXXDefaultArgExpr: - // case CX_StmtClass.CX_StmtClass_CXXDefaultInitExpr: + + case CX_StmtClass.CX_StmtClass_CXXDefaultInitExpr: + { + return false; + } + // case CX_StmtClass.CX_StmtClass_CXXDeleteExpr: case CX_StmtClass.CX_StmtClass_CXXDependentScopeMemberExpr: @@ -3669,7 +3682,11 @@ private bool IsConstant(string targetTypeName, Expr initExpr) return true; } - // case CX_StmtClass.CX_StmtClass_LambdaExpr: + case CX_StmtClass.CX_StmtClass_LambdaExpr: + { + return false; + } + // case CX_StmtClass.CX_StmtClass_MSPropertyRefExpr: // case CX_StmtClass.CX_StmtClass_MSPropertySubscriptExpr: // case CX_StmtClass.CX_StmtClass_MaterializeTemporaryExpr: @@ -3741,7 +3758,11 @@ private bool IsConstant(string targetTypeName, Expr initExpr) return true; } - // case CX_StmtClass.CX_StmtClass_SubstNonTypeTemplateParmExpr: + case CX_StmtClass.CX_StmtClass_SubstNonTypeTemplateParmExpr: + { + return false; + } + // case CX_StmtClass.CX_StmtClass_SubstNonTypeTemplateParmPackExpr: // case CX_StmtClass.CX_StmtClass_TypeTraitExpr: // case CX_StmtClass.CX_StmtClass_TypoExpr: diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs index 9b68f248..06923702 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.VisitStmt.cs @@ -115,6 +115,24 @@ private void VisitCallExpr(CallExpr callExpr) } } + var isUnusedValue = false; + + if (callExpr.Type.CanonicalType.Kind != CXTypeKind.CXType_Void) + { + isUnusedValue = IsPrevContextStmt(out _, out _) + || IsPrevContextStmt(out _, out _); + + if ((calleeDecl is FunctionDecl functionDecl) && (functionDecl.Name is "memcpy" or "memset")) + { + isUnusedValue = false; + } + } + + if (isUnusedValue) + { + outputBuilder.Write("_ = "); + } + if (calleeDecl is null) { Visit(callExpr.Callee); @@ -139,22 +157,64 @@ private void VisitCallExpr(CallExpr callExpr) case "memset": { + NamedDecl namedDecl = null; + + if (callExpr.NumArgs == 3) + { + if (IsStmtAsWritten(callExpr.Args[1], out var integerLiteralExpr, removeParens: true) && (integerLiteralExpr.Value == 0) && + IsStmtAsWritten(callExpr.Args[2], out var unaryExprOrTypeTraitExpr, removeParens: true) && (unaryExprOrTypeTraitExpr.Kind == CX_UnaryExprOrTypeTrait.CX_UETT_SizeOf)) + { + var typeOfArgument = unaryExprOrTypeTraitExpr.TypeOfArgument.CanonicalType; + var expr = callExpr.Args[0]; + + if (IsStmtAsWritten(expr, out var unaryOperator, removeParens: true) && (unaryOperator.Opcode == CX_UnaryOperatorKind.CX_UO_AddrOf)) + { + expr = unaryOperator.SubExpr; + } + + if (IsStmtAsWritten(expr, out var declRefExpr, removeParens: true) && (typeOfArgument == declRefExpr.Type.CanonicalType)) + { + namedDecl = declRefExpr.Decl; + } + else if (IsStmtAsWritten(expr, out var memberExpr, removeParens: true) && (typeOfArgument == memberExpr.Type.CanonicalType)) + { + namedDecl = memberExpr.MemberDecl; + } + } + + if (namedDecl is not null) + { + outputBuilder.Write(GetRemappedCursorName(namedDecl)); + outputBuilder.Write(" = default"); + break; + } + } + outputBuilder.AddUsingDirective("System.Runtime.CompilerServices"); outputBuilder.Write("Unsafe.InitBlockUnaligned"); VisitArgs(callExpr); break; } - default: + case "wcslen": { - if ((functionDecl.ReturnType.CanonicalType.Kind != CXTypeKind.CXType_Void) && IsPrevContextStmt(out _, out _)) + if (_config.GenerateCompatibleCode) { - outputBuilder.Write("_ = "); + goto default; } - Visit(callExpr.Callee); + outputBuilder.AddUsingDirective("System.Runtime.InteropServices"); + outputBuilder.Write("MemoryMarshal.CreateReadOnlySpanFromNullTerminated"); + VisitArgs(callExpr); + outputBuilder.Write(".Length"); + break; + } + default: + { + Visit(callExpr.Callee); + VisitArgs(callExpr); break; } } @@ -176,6 +236,15 @@ private void VisitCallExpr(CallExpr callExpr) void VisitArgs(CallExpr callExpr) { + var callExprType = (callExpr.Callee is MemberExpr memberExpr) + ? memberExpr.MemberDecl.Type.CanonicalType + : callExpr.Callee.Type.CanonicalType; + + if (callExprType is PointerType pointerType) + { + callExprType = pointerType.PointeeType.CanonicalType; + } + outputBuilder.Write('('); var args = callExpr.Args; @@ -183,12 +252,37 @@ void VisitArgs(CallExpr callExpr) for (var i = 0; i < args.Count; i++) { - if (needsComma) + var arg = args[i]; + + if (needsComma && (arg is not CXXDefaultArgExpr)) { outputBuilder.Write(", "); } - var arg = args[i]; + if (callExprType is FunctionProtoType functionProtoType) + { + var paramType = functionProtoType.ParamTypes[i].CanonicalType; + + if (paramType is ReferenceType) + { + if (IsStmtAsWritten(arg, out var unaryOperator, removeParens: true) && (unaryOperator.Opcode == CX_UnaryOperatorKind.CX_UO_Deref)) + { + arg = unaryOperator.SubExpr; + } + else if (IsStmtAsWritten(arg, out var declRefExpr, removeParens: true)) + { + if (declRefExpr.Decl.Type.CanonicalType is not ReferenceType and not PointerType) + { + outputBuilder.Write('&'); + } + } + else if (arg.Type.CanonicalType is not ReferenceType and not PointerType) + { + outputBuilder.Write('&'); + } + } + } + Visit(arg); if (arg is not CXXDefaultArgExpr) @@ -651,14 +745,14 @@ private void VisitDeclRefExpr(DeclRefExpr declRefExpr) { var className = GetClass(enumName); - if (outputBuilder.Name != className) + if ((outputBuilder.Name != className) && (namedDecl.Parent is not TagDecl)) { - outputBuilder.AddUsingDirective($"static {GetNamespace(enumName)}.{className}"); + outputBuilder.AddUsingDirective($"static {GetNamespace(enumName, namedDecl)}.{className}"); } } else { - outputBuilder.AddUsingDirective($"static {GetNamespace(enumName)}.{enumName}"); + outputBuilder.AddUsingDirective($"static {GetNamespace(enumName, namedDecl)}.{enumName}"); } } else @@ -1003,12 +1097,33 @@ void ForEnumConstantDecl(ImplicitCastExpr implicitCastExpr, EnumConstantDecl enu if (IsPrevContextStmt(out var binaryOperator, out _) && ((binaryOperator.Opcode == CX_BinaryOperatorKind.CX_BO_EQ) || (binaryOperator.Opcode == CX_BinaryOperatorKind.CX_BO_NE))) { Visit(subExpr); + subExpr = null; + } + else if (IsPrevContextStmt(out _, out _)) + { + var previousContext = _context.Last.Previous; + + do + { + previousContext = previousContext.Previous; + } + while (previousContext.Value.Cursor is ParenExpr or ImplicitCastExpr or CaseStmt or CompoundStmt); + + var value = previousContext.Value; + + if ((value.Cursor is SwitchStmt switchStmt) && (switchStmt.Cond.IgnoreImplicit.Type.CanonicalType is EnumType)) + { + Visit(subExpr); + subExpr = null; + } } else if (IsPrevContextDecl(out _, out _)) { Visit(subExpr); + subExpr = null; } - else + + if (subExpr is not null) { var type = implicitCastExpr.Type; @@ -1272,7 +1387,7 @@ void ForType(InitListExpr initListExpr, Type type) } else { - AddDiagnostic(DiagnosticLevel.Error, $"Unsupported init list expression type: '{type.KindSpelling}'. Generated bindings may be incomplete.", initListExpr); + AddDiagnostic(DiagnosticLevel.Error, $"Unsupported init list expression type: '{type.TypeClassSpelling}'. Generated bindings may be incomplete.", initListExpr); } } @@ -1335,6 +1450,14 @@ void HandleInitStmt(Stmt init) break; } + case CXEvalResultKind.CXEval_StrLiteral: + { + outputBuilder.Write('"'); + outputBuilder.Write(evaluation.AsStr); + outputBuilder.Write('"'); + break; + } + default: { AddDiagnostic(DiagnosticLevel.Error, $"Unsupported evaluation kind: '{evaluation.Kind}'. Generated bindings may be incomplete.", init); @@ -1605,18 +1728,26 @@ private void VisitMemberExpr(MemberExpr memberExpr) { if ((_cxxRecordDeclContext is not null) && (_cxxRecordDeclContext != cxxMethodDecl.Parent) && HasField(cxxMethodDecl.Parent)) { - var cxxBaseSpecifier = _cxxRecordDeclContext.Bases.Where((baseSpecifier) => baseSpecifier.Referenced == cxxMethodDecl.Parent).Single(); - baseFieldName = GetAnonymousName(cxxBaseSpecifier, "Base"); - baseFieldName = GetRemappedName(baseFieldName, cxxBaseSpecifier, tryRemapOperatorName: true, out var wasRemapped, skipUsing: true); + var cxxBaseSpecifier = _cxxRecordDeclContext.Bases.Where((baseSpecifier) => baseSpecifier.Referenced == cxxMethodDecl.Parent).SingleOrDefault(); + + if (cxxBaseSpecifier is not null) + { + baseFieldName = GetAnonymousName(cxxBaseSpecifier, "Base"); + baseFieldName = GetRemappedName(baseFieldName, cxxBaseSpecifier, tryRemapOperatorName: true, out var wasRemapped, skipUsing: true); + } } } else if (memberExpr.MemberDecl is FieldDecl fieldDecl) { if ((_cxxRecordDeclContext is not null) && (_cxxRecordDeclContext != fieldDecl.Parent)) { - var cxxBaseSpecifier = _cxxRecordDeclContext.Bases.Where((baseSpecifier) => baseSpecifier.Referenced == fieldDecl.Parent).Single(); - baseFieldName = GetAnonymousName(cxxBaseSpecifier, "Base"); - baseFieldName = GetRemappedName(baseFieldName, cxxBaseSpecifier, tryRemapOperatorName: true, out var wasRemapped, skipUsing: true); + var cxxBaseSpecifier = _cxxRecordDeclContext.Bases.Where((baseSpecifier) => baseSpecifier.Referenced == fieldDecl.Parent).SingleOrDefault(); + + if (cxxBaseSpecifier is not null) + { + baseFieldName = GetAnonymousName(cxxBaseSpecifier, "Base"); + baseFieldName = GetRemappedName(baseFieldName, cxxBaseSpecifier, tryRemapOperatorName: true, out var wasRemapped, skipUsing: true); + } } } } @@ -1710,6 +1841,15 @@ private void VisitReturnStmt(ReturnStmt returnStmt) if (returnStmt.RetValue != null) { outputBuilder.Write(' '); + + if (functionDecl.ReturnType.CanonicalType is not ReferenceType and not PointerType) + { + if (returnStmt.RetValue.Type.CanonicalType is ReferenceType) + { + outputBuilder.Write('*'); + } + } + Visit(returnStmt.RetValue); } } @@ -2609,8 +2749,21 @@ private void VisitUnaryOperator(UnaryOperator unaryOperator) } else if (canonicalType is PointerType or ReferenceType) { + var needsParens = !IsPrevContextStmt(out _, out _, preserveParen: true) && + !IsPrevContextStmt(out _, out _, preserveParen: true); + + if (needsParens) + { + outputBuilder.Write('('); + } + Visit(subExpr); outputBuilder.Write(" == null"); + + if (needsParens) + { + outputBuilder.Write(')'); + } } else { diff --git a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs index d2fae91d..3cc2039d 100644 --- a/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs +++ b/sources/ClangSharp.PInvokeGenerator/PInvokeGenerator.cs @@ -823,6 +823,11 @@ static void GenerateTransparentStructs(PInvokeGenerator generator) } else { + if (!IsUnsigned(type)) + { + sw.Write("unchecked"); + } + sw.Write("(("); sw.Write(type); sw.WriteLine(")(value));"); @@ -839,7 +844,20 @@ static void GenerateTransparentStructs(PInvokeGenerator generator) } else { - sw.WriteLine(" value) => (void*)(value.Value);"); + var isUnchecked = !IsUnsigned(type); + sw.Write(" value) => "); + + if (isUnchecked) + { + sw.Write("unchecked("); + } + sw.Write("(void*)(value.Value)"); + + if (isUnchecked) + { + sw.Write(")"); + } + sw.WriteLine(); } sw.WriteLine(); @@ -1111,7 +1129,7 @@ static void OutputConversions(StreamWriter sw, string indentString, string name, if ((castFromKind == "explicit") || isPointerToNativeCast) { - sw.Write('('); + sw.Write("unchecked(("); sw.Write(type); sw.Write(")("); } @@ -1120,7 +1138,7 @@ static void OutputConversions(StreamWriter sw, string indentString, string name, if ((castFromKind == "explicit") || isPointerToNativeCast) { - sw.Write(')'); + sw.Write("))"); } sw.WriteLine(");"); @@ -2146,9 +2164,9 @@ private string GetCursorName(NamedDecl namedDecl) return name; } - private string GetCursorQualifiedName(NamedDecl namedDecl, bool truncateFunctionParameters = false) + private string GetCursorQualifiedName(NamedDecl namedDecl, bool truncateParameters = false) { - if (!_cursorQualifiedNames.TryGetValue((namedDecl, truncateFunctionParameters), out var qualifiedName)) + if (!_cursorQualifiedNames.TryGetValue((namedDecl, truncateParameters), out var qualifiedName)) { var parts = new Stack(); Decl decl = namedDecl; @@ -2180,7 +2198,7 @@ private string GetCursorQualifiedName(NamedDecl namedDecl, bool truncateFunction AppendNamedDecl(part, GetCursorName(part), qualifiedNameBuilder); qualifiedName = qualifiedNameBuilder.ToString(); - _cursorQualifiedNames[(namedDecl, truncateFunctionParameters)] = qualifiedName; + _cursorQualifiedNames[(namedDecl, truncateParameters)] = qualifiedName; } Debug.Assert(!string.IsNullOrWhiteSpace(qualifiedName)); @@ -2188,7 +2206,7 @@ private string GetCursorQualifiedName(NamedDecl namedDecl, bool truncateFunction void AppendFunctionParameters(CXType functionType, StringBuilder qualifiedName) { - if (truncateFunctionParameters) + if (truncateParameters) { return; } @@ -2268,6 +2286,11 @@ void AppendTemplateArgument(TemplateArgument templateArgument, Decl parentDecl, void AppendTemplateArguments(ClassTemplateSpecializationDecl classTemplateSpecializationDecl, StringBuilder qualifiedName) { + if (truncateParameters) + { + return; + } + _ = qualifiedName.Append('<'); var templateArgs = classTemplateSpecializationDecl.TemplateArgs; @@ -2289,6 +2312,11 @@ void AppendTemplateArguments(ClassTemplateSpecializationDecl classTemplateSpecia void AppendTemplateParameters(TemplateDecl templateDecl, StringBuilder qualifiedName) { + if (truncateParameters) + { + return; + } + _ = qualifiedName.Append('<'); var templateParameters = templateDecl.TemplateParameters; @@ -2425,7 +2453,8 @@ private string GetRemappedCursorName(NamedDecl namedDecl, out string nativeTypeN return remappedName; } - name = GetCursorQualifiedName(namedDecl, truncateFunctionParameters: true); + + name = GetCursorQualifiedName(namedDecl, truncateParameters: true); remappedName = GetRemappedName(name, namedDecl, tryRemapOperatorName: true, out wasRemapped, skipUsing); if (wasRemapped) @@ -2449,7 +2478,11 @@ private string GetRemappedCursorName(NamedDecl namedDecl, out string nativeTypeN return remappedName; } - if (namedDecl is FieldDecl fieldDecl) + if (namedDecl is CXXConstructorDecl cxxConstructorDecl) + { + remappedName = GetRemappedCursorName(cxxConstructorDecl.Parent); + } + else if (namedDecl is FieldDecl fieldDecl) { if (name.StartsWith("__AnonymousFieldDecl_")) { @@ -2800,11 +2833,10 @@ private string GetTypeName(Cursor cursor, Cursor context, Type rootType, Type ty if (type is ArrayType arrayType) { - result.typeName = GetTypeName(cursor, context, rootType, arrayType.ElementType, ignoreTransparentStructsWhereRequired, out _); + result.typeName = GetRemappedTypeName(cursor, context, arrayType.ElementType, out _, skipUsing: true, ignoreTransparentStructsWhereRequired); if (cursor is FunctionDecl or ParmVarDecl) { - result.typeName = GetRemappedName(result.typeName, cursor, tryRemapOperatorName: false, out _, skipUsing: true); result.typeName += '*'; } } @@ -3023,8 +3055,23 @@ private string GetTypeName(Cursor cursor, Cursor context, Type rootType, Type ty ? recordType.Decl : (NamedDecl)templateSpecializationType.TemplateName.AsTemplateDecl; - _ = nameBuilder.Append(GetRemappedName(templateTypeDecl.Name, templateTypeDecl, tryRemapOperatorName: false, out _, skipUsing: true)); - _ = nameBuilder.Append('<'); + var templateTypeDeclName = GetRemappedCursorName(templateTypeDecl, out _, skipUsing: true); + var isStdAtomic = false; + + if (templateTypeDeclName == "atomic") + { + isStdAtomic = (templateTypeDecl.Parent is NamespaceDecl namespaceDecl) && namespaceDecl.IsStdNamespace; + } + + if (!isStdAtomic) + { + _ = nameBuilder.Append(templateTypeDeclName); + _ = nameBuilder.Append('<'); + } + else + { + _ = nameBuilder.Append("volatile "); + } var shouldWritePrecedingComma = false; @@ -3084,7 +3131,10 @@ private string GetTypeName(Cursor cursor, Cursor context, Type rootType, Type ty shouldWritePrecedingComma = true; } - _ = nameBuilder.Append('>'); + if (!isStdAtomic) + { + _ = nameBuilder.Append('>'); + } result.typeName = nameBuilder.ToString(); } @@ -3108,6 +3158,10 @@ private string GetTypeName(Cursor cursor, Cursor context, Type rootType, Type ty var remappedName = GetRemappedName(result.typeName, cursor, tryRemapOperatorName: false, out var wasRemapped, skipUsing: true); result.typeName = wasRemapped ? remappedName : GetTypeName(cursor, context, rootType, typedefType.Decl.UnderlyingType, ignoreTransparentStructsWhereRequired, out _); } + else if (type is UsingType usingType) + { + result.typeName = GetTypeName(cursor, context, rootType, usingType.Desugar, ignoreTransparentStructsWhereRequired, out _); + } else { AddDiagnostic(DiagnosticLevel.Warning, $"Unsupported type: '{type.TypeClass}'. Falling back '{result.typeName}'.", cursor); @@ -3967,7 +4021,7 @@ bool IsExcludedByName(Cursor cursor, ref uint isExcludedValue) if (namedDecl is FunctionDecl) { - qualifiedNameWithoutParameters = GetCursorQualifiedName(namedDecl, truncateFunctionParameters: true); + qualifiedNameWithoutParameters = GetCursorQualifiedName(namedDecl, truncateParameters: true); } name = GetCursorName(namedDecl); @@ -4625,7 +4679,11 @@ private bool IsUnchecked(string targetTypeName, Stmt stmt) return false; } - // case CX_StmtClass.CX_StmtClass_CXXDefaultInitExpr: + case CX_StmtClass.CX_StmtClass_CXXDefaultInitExpr: + { + return false; + } + // case CX_StmtClass.CX_StmtClass_CXXDeleteExpr: case CX_StmtClass.CX_StmtClass_CXXDependentScopeMemberExpr: @@ -4777,7 +4835,11 @@ private bool IsUnchecked(string targetTypeName, Stmt stmt) return IsUnchecked(targetTypeName, signedValue, integerLiteral.IsNegative, isHex: integerLiteral.ValueString.StartsWith("0x")); } - // case CX_StmtClass.CX_StmtClass_LambdaExpr: + case CX_StmtClass.CX_StmtClass_LambdaExpr: + { + return false; + } + // case CX_StmtClass.CX_StmtClass_MSPropertyRefExpr: // case CX_StmtClass.CX_StmtClass_MSPropertySubscriptExpr: @@ -4854,7 +4916,11 @@ private bool IsUnchecked(string targetTypeName, Stmt stmt) return false; } - // case CX_StmtClass.CX_StmtClass_SubstNonTypeTemplateParmExpr: + case CX_StmtClass.CX_StmtClass_SubstNonTypeTemplateParmExpr: + { + return false; + } + // case CX_StmtClass.CX_StmtClass_SubstNonTypeTemplateParmPackExpr: // case CX_StmtClass.CX_StmtClass_TypeTraitExpr: // case CX_StmtClass.CX_StmtClass_TypoExpr: @@ -5848,11 +5914,16 @@ private bool TryGetClass(string remappedName, out string className, bool disallo return false; } - private string GetNamespace(string remappedName) + private string GetNamespace(string remappedName, NamedDecl namedDecl = null) { if (!TryGetNamespace(remappedName, out var namespaceName)) { - if (s_needsSystemSupportRegex.IsMatch(remappedName)) + if ((namedDecl is not null) && (namedDecl.Parent is TypeDecl parentTypeDecl)) + { + var parentName = GetRemappedCursorName(parentTypeDecl); + namespaceName = $"{GetNamespace(parentName, parentTypeDecl)}.{parentName}"; + } + else if (s_needsSystemSupportRegex.IsMatch(remappedName)) { namespaceName = "System"; } @@ -5899,7 +5970,7 @@ private bool HasRemapping(NamedDecl namedDecl, IReadOnlyCollection entri return true; } - name = GetCursorQualifiedName(namedDecl, truncateFunctionParameters: true); + name = GetCursorQualifiedName(namedDecl, truncateParameters: true); if (name.StartsWith("ClangSharpMacro_")) { @@ -5959,7 +6030,7 @@ private bool TryGetRemappedValue(NamedDecl namedDecl, IReadOnlyDictionary handle.AttrKind switch - { + internal static new Attr Create(CXCursor handle) => handle.AttrKind switch { CX_AttrKind.CX_AttrKind_Invalid => new Attr(handle), CX_AttrKind.CX_AttrKind_AddressSpace => new TypeAttr(handle), CX_AttrKind.CX_AttrKind_ArmMveStrictPolymorphism => new TypeAttr(handle), + CX_AttrKind.CX_AttrKind_BTFTypeTag => new TypeAttr(handle), CX_AttrKind.CX_AttrKind_CmseNSCall => new TypeAttr(handle), CX_AttrKind.CX_AttrKind_NoDeref => new TypeAttr(handle), CX_AttrKind.CX_AttrKind_ObjCGC => new TypeAttr(handle), @@ -113,6 +113,7 @@ private protected Attr(CXCursor handle) : base(handle, handle.Kind) CX_AttrKind.CX_AttrKind_Assumption => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_Availability => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_BPFPreserveAccessIndex => new InheritableAttr(handle), + CX_AttrKind.CX_AttrKind_BTFDeclTag => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_Blocks => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_Builtin => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_C11NoReturn => new InheritableAttr(handle), @@ -156,13 +157,16 @@ private protected Attr(CXCursor handle) : base(handle, handle.Kind) CX_AttrKind.CX_AttrKind_DLLImportStaticLocal => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_Deprecated => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_Destructor => new InheritableAttr(handle), + CX_AttrKind.CX_AttrKind_DiagnoseAsBuiltin => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_DiagnoseIf => new InheritableAttr(handle), + CX_AttrKind.CX_AttrKind_DisableSanitizerInstrumentation => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_DisableTailCalls => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_EmptyBases => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_EnableIf => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_EnforceTCB => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_EnforceTCBLeaf => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_EnumExtensibility => new InheritableAttr(handle), + CX_AttrKind.CX_AttrKind_Error => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_ExcludeFromExplicitInstantiation => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_ExclusiveTrylockFunction => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_ExternalSourceSymbol => new InheritableAttr(handle), @@ -282,6 +286,7 @@ private protected Attr(CXCursor handle) : base(handle, handle.Kind) CX_AttrKind.CX_AttrKind_ReturnsNonNull => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_ReturnsTwice => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_SYCLKernel => new InheritableAttr(handle), + CX_AttrKind.CX_AttrKind_SYCLSpecialClass => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_ScopedLockable => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_Section => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_SelectAny => new InheritableAttr(handle), @@ -303,6 +308,7 @@ private protected Attr(CXCursor handle) : base(handle, handle.Kind) CX_AttrKind.CX_AttrKind_SwiftPrivate => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_TLSModel => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_Target => new InheritableAttr(handle), + CX_AttrKind.CX_AttrKind_TargetClones => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_TestTypestate => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_TransparentUnion => new InheritableAttr(handle), CX_AttrKind.CX_AttrKind_TrivialABI => new InheritableAttr(handle), diff --git a/sources/ClangSharp/Cursors/Decls/Decl.cs b/sources/ClangSharp/Cursors/Decls/Decl.cs index 962dfb63..0059a7ce 100644 --- a/sources/ClangSharp/Cursors/Decls/Decl.cs +++ b/sources/ClangSharp/Cursors/Decls/Decl.cs @@ -145,8 +145,7 @@ public bool IsStdNamespace public TranslationUnitDecl TranslationUnitDecl => _translationUnitDecl.Value; - internal static new Decl Create(CXCursor handle) => handle.DeclKind switch - { + internal static new Decl Create(CXCursor handle) => handle.DeclKind switch { CX_DeclKind.CX_DeclKind_Invalid => new Decl(handle, handle.kind, handle.DeclKind), CX_DeclKind.CX_DeclKind_AccessSpec => new AccessSpecDecl(handle), CX_DeclKind.CX_DeclKind_Block => new BlockDecl(handle), diff --git a/sources/ClangSharp/Cursors/Stmts/Stmt.cs b/sources/ClangSharp/Cursors/Stmts/Stmt.cs index 2b818dd0..3df2909a 100644 --- a/sources/ClangSharp/Cursors/Stmts/Stmt.cs +++ b/sources/ClangSharp/Cursors/Stmts/Stmt.cs @@ -113,8 +113,7 @@ public Stmt StripLabelLikeStatements() } } - internal static new Stmt Create(CXCursor handle) => handle.StmtClass switch - { + internal static new Stmt Create(CXCursor handle) => handle.StmtClass switch { CX_StmtClass.CX_StmtClass_Invalid => new Stmt(handle, handle.Kind, handle.StmtClass), CX_StmtClass.CX_StmtClass_GCCAsmStmt => new GCCAsmStmt(handle), CX_StmtClass.CX_StmtClass_MSAsmStmt => new MSAsmStmt(handle), @@ -151,6 +150,7 @@ public Stmt StripLabelLikeStatements() CX_StmtClass.CX_StmtClass_OMPDistributeSimdDirective => new OMPDistributeSimdDirective(handle), CX_StmtClass.CX_StmtClass_OMPForDirective => new OMPForDirective(handle), CX_StmtClass.CX_StmtClass_OMPForSimdDirective => new OMPForSimdDirective(handle), + CX_StmtClass.CX_StmtClass_OMPGenericLoopDirective => new OMPGenericLoopDirective(handle), CX_StmtClass.CX_StmtClass_OMPMasterTaskLoopDirective => new OMPMasterTaskLoopDirective(handle), CX_StmtClass.CX_StmtClass_OMPMasterTaskLoopSimdDirective => new OMPMasterTaskLoopSimdDirective(handle), CX_StmtClass.CX_StmtClass_OMPParallelForDirective => new OMPParallelForDirective(handle), @@ -174,6 +174,7 @@ public Stmt StripLabelLikeStatements() CX_StmtClass.CX_StmtClass_OMPUnrollDirective => new OMPUnrollDirective(handle), CX_StmtClass.CX_StmtClass_OMPMaskedDirective => new OMPMaskedDirective(handle), CX_StmtClass.CX_StmtClass_OMPMasterDirective => new OMPMasterDirective(handle), + CX_StmtClass.CX_StmtClass_OMPMetaDirective => new OMPMetaDirective(handle), CX_StmtClass.CX_StmtClass_OMPOrderedDirective => new OMPOrderedDirective(handle), CX_StmtClass.CX_StmtClass_OMPParallelDirective => new OMPParallelDirective(handle), CX_StmtClass.CX_StmtClass_OMPParallelMasterDirective => new OMPParallelMasterDirective(handle), diff --git a/sources/ClangSharp/Types/Type.cs b/sources/ClangSharp/Types/Type.cs index f4f43647..69540b53 100644 --- a/sources/ClangSharp/Types/Type.cs +++ b/sources/ClangSharp/Types/Type.cs @@ -114,8 +114,7 @@ public Type UnqualifiedDesugaredType public static bool operator !=(Type left, Type right) => (left is object) ? ((right is null) || (left.Handle != right.Handle)) : (right is object); - internal static Type Create(CXType handle) => handle.TypeClass switch - { + internal static Type Create(CXType handle) => handle.TypeClass switch { CX_TypeClass.CX_TypeClass_Invalid => new Type(handle, handle.kind, handle.TypeClass), CX_TypeClass.CX_TypeClass_Adjusted => new AdjustedType(handle), CX_TypeClass.CX_TypeClass_Decayed => new DecayedType(handle), @@ -167,6 +166,7 @@ public Type UnqualifiedDesugaredType CX_TypeClass.CX_TypeClass_Typedef => new TypedefType(handle), CX_TypeClass.CX_TypeClass_UnaryTransform => new UnaryTransformType(handle), CX_TypeClass.CX_TypeClass_UnresolvedUsing => new UnresolvedUsingType(handle), + CX_TypeClass.CX_TypeClass_Using => new UsingType(handle), CX_TypeClass.CX_TypeClass_Vector => new VectorType(handle), CX_TypeClass.CX_TypeClass_ExtVector => new ExtVectorType(handle), _ => new Type(handle, handle.kind, handle.TypeClass), diff --git a/sources/ClangSharp/Types/UsingType.cs b/sources/ClangSharp/Types/UsingType.cs index 9e222f64..ce0c79d9 100644 --- a/sources/ClangSharp/Types/UsingType.cs +++ b/sources/ClangSharp/Types/UsingType.cs @@ -1,13 +1,19 @@ // Copyright (c) .NET Foundation and Contributors. All Rights Reserved. Licensed under the MIT License (MIT). See License.md in the repository root for more information. +using System; using ClangSharp.Interop; namespace ClangSharp { public sealed class UsingType : Type { + private readonly Lazy _foundDecl; + internal UsingType(CXType handle) : base(handle, CXTypeKind.CXType_Unexposed, CX_TypeClass.CX_TypeClass_Using) { + _foundDecl = new Lazy(() => TranslationUnit.GetOrCreate(Handle.Declaration)); } + + public UsingShadowDecl FoundDecl => _foundDecl.Value; } } diff --git a/sources/libClangSharp/ClangSharp.cpp b/sources/libClangSharp/ClangSharp.cpp index c2556a1b..f567b9d2 100644 --- a/sources/libClangSharp/ClangSharp.cpp +++ b/sources/libClangSharp/ClangSharp.cpp @@ -5063,6 +5063,10 @@ CXCursor clangsharp_Type_getDeclaration(CXType CT) { return MakeCXCursor(UUT->getDecl(), GetTypeTU(CT)); } + if (const UsingType* UT = dyn_cast(TP)) { + return MakeCXCursor(UT->getFoundDecl(), GetTypeTU(CT)); + } + return clang_getTypeDeclaration(CT); }