From 9ef33da690913603aa64871b1950d4b5da441e5f Mon Sep 17 00:00:00 2001 From: duckdoom5 Date: Thu, 27 Feb 2025 15:46:11 +0100 Subject: [PATCH 1/9] Parser improvements --- src/CppParser/Parser.cpp | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/CppParser/Parser.cpp b/src/CppParser/Parser.cpp index 6f268823f..22a500af2 100644 --- a/src/CppParser/Parser.cpp +++ b/src/CppParser/Parser.cpp @@ -165,6 +165,12 @@ Parser::Parser(CppParserOptions* Opts) { supportedStdTypes.insert("allocator"); supportedStdTypes.insert("basic_string"); + + walkedNamespaces.reserve(8192); + walkedTypeTemplateParameters.reserve(8192); + walkedTemplateTemplateParameters.reserve(32); + walkedNonTypeTemplateParameters.reserve(1024); + walkedParameters.reserve(65536); } LayoutField Parser::WalkVTablePointer(Class* Class, @@ -424,27 +430,23 @@ void Parser::Setup(bool Compile) if (opts->verbose) HSOpts.Verbose = true; - for (unsigned I = 0, E = opts->IncludeDirs.size(); I != E; ++I) + for (const auto& s : opts->IncludeDirs) { - const auto& s = opts->IncludeDirs[I]; HSOpts.AddPath(s, frontend::Angled, false, false); } - for (unsigned I = 0, E = opts->SystemIncludeDirs.size(); I != E; ++I) + for (const auto& s : opts->SystemIncludeDirs) { - const auto& s = opts->SystemIncludeDirs[I]; HSOpts.AddPath(s, frontend::System, false, false); } - for (unsigned I = 0, E = opts->Defines.size(); I != E; ++I) + for (const auto& define : opts->Defines) { - const auto& define = opts->Defines[I]; PPOpts.addMacroDef(define); } - for (unsigned I = 0, E = opts->Undefines.size(); I != E; ++I) + for (const auto& undefine : opts->Undefines) { - const auto& undefine = opts->Undefines[I]; PPOpts.addMacroUndef(undefine); } @@ -480,8 +482,7 @@ void Parser::Setup(bool Compile) } } - if (TC) - delete TC; + delete TC; // Enable preprocessing record. PPOpts.DetailedRecord = true; @@ -2537,7 +2538,7 @@ Type* Parser::WalkType(clang::QualType QualType, const clang::TypeLoc* TL, bool EnumDecl* ED = ET->getDecl(); auto TT = new AST::TagType(); - TT->declaration = TT->declaration = WalkDeclaration(ED); + TT->declaration = WalkDeclaration(ED); Ty = TT; break; @@ -4430,8 +4431,8 @@ Declaration* Parser::WalkDeclaration(const clang::Decl* D) { auto MD = cast(D); Decl = WalkMethodCXX(MD); - if (Decl == nullptr) - return Decl; + if (!Decl) + return nullptr; auto NS = GetNamespace(MD); Decl->_namespace = NS; @@ -4609,7 +4610,7 @@ void Parser::SetupLLVMCodegen() c->getHeaderSearchOpts(), c->getPreprocessorOpts(), c->getCodeGenOpts(), *LLVMModule, c->getDiagnostics())); - codeGenTypes.reset(new clang::CodeGen::CodeGenTypes(*CGM.get())); + codeGenTypes.reset(new clang::CodeGen::CodeGenTypes(*CGM)); } bool Parser::SetupSourceFiles(const std::vector& SourceFiles, @@ -4710,7 +4711,7 @@ ParserResult* Parser::Parse(const std::vector& SourceFiles) DiagClient->BeginSourceFile(c->getLangOpts(), &c->getPreprocessor()); - ParseAST(c->getSema()); + ParseAST(c->getSema(), opts->verbose, opts->skipFunctionBodies); DiagClient->EndSourceFile(); From c09b1a56dbffe0bbf2b9e7cf4739422e21bdfeaa Mon Sep 17 00:00:00 2001 From: duckdoom5 Date: Fri, 28 Feb 2025 14:47:36 +0100 Subject: [PATCH 2/9] Fix AST Converter missing conversion data --- src/Parser/ASTConverter.cs | 363 +++++++++++++++++++------------------ 1 file changed, 183 insertions(+), 180 deletions(-) diff --git a/src/Parser/ASTConverter.cs b/src/Parser/ASTConverter.cs index 81bb8c7ea..ca1275867 100644 --- a/src/Parser/ASTConverter.cs +++ b/src/Parser/ASTConverter.cs @@ -41,100 +41,100 @@ public TRet Visit(Parser.AST.Type type) switch (type.Kind) { case TypeKind.Tag: - { - var _type = TagType.__CreateInstance(type.__Instance); - return VisitTag(_type); - } + { + var _type = TagType.__CreateInstance(type.__Instance); + return VisitTag(_type); + } case TypeKind.Array: - { - var _type = ArrayType.__CreateInstance(type.__Instance); - return VisitArray(_type); - } + { + var _type = ArrayType.__CreateInstance(type.__Instance); + return VisitArray(_type); + } case TypeKind.Function: - { - var _type = FunctionType.__CreateInstance(type.__Instance); - return VisitFunction(_type); - } + { + var _type = FunctionType.__CreateInstance(type.__Instance); + return VisitFunction(_type); + } case TypeKind.Pointer: - { - var _type = PointerType.__CreateInstance(type.__Instance); - return VisitPointer(_type); - } + { + var _type = PointerType.__CreateInstance(type.__Instance); + return VisitPointer(_type); + } case TypeKind.MemberPointer: - { - var _type = MemberPointerType.__CreateInstance(type.__Instance); - return VisitMemberPointer(_type); - } + { + var _type = MemberPointerType.__CreateInstance(type.__Instance); + return VisitMemberPointer(_type); + } case TypeKind.Typedef: - { - var _type = TypedefType.__CreateInstance(type.__Instance); - return VisitTypedef(_type); - } + { + var _type = TypedefType.__CreateInstance(type.__Instance); + return VisitTypedef(_type); + } case TypeKind.Attributed: - { - var _type = AttributedType.__CreateInstance(type.__Instance); - return VisitAttributed(_type); - } + { + var _type = AttributedType.__CreateInstance(type.__Instance); + return VisitAttributed(_type); + } case TypeKind.Decayed: - { - var _type = DecayedType.__CreateInstance(type.__Instance); - return VisitDecayed(_type); - } + { + var _type = DecayedType.__CreateInstance(type.__Instance); + return VisitDecayed(_type); + } case TypeKind.TemplateSpecialization: - { - var _type = TemplateSpecializationType.__CreateInstance(type.__Instance); - return VisitTemplateSpecialization(_type); - } + { + var _type = TemplateSpecializationType.__CreateInstance(type.__Instance); + return VisitTemplateSpecialization(_type); + } case TypeKind.DependentTemplateSpecialization: - { - var _type = DependentTemplateSpecializationType.__CreateInstance(type.__Instance); - return VisitDependentTemplateSpecialization(_type); - } + { + var _type = DependentTemplateSpecializationType.__CreateInstance(type.__Instance); + return VisitDependentTemplateSpecialization(_type); + } case TypeKind.TemplateParameter: - { - var _type = TemplateParameterType.__CreateInstance(type.__Instance); - return VisitTemplateParameter(_type); - } + { + var _type = TemplateParameterType.__CreateInstance(type.__Instance); + return VisitTemplateParameter(_type); + } case TypeKind.TemplateParameterSubstitution: - { - var _type = TemplateParameterSubstitutionType.__CreateInstance(type.__Instance); - return VisitTemplateParameterSubstitution(_type); - } + { + var _type = TemplateParameterSubstitutionType.__CreateInstance(type.__Instance); + return VisitTemplateParameterSubstitution(_type); + } case TypeKind.InjectedClassName: - { - var _type = InjectedClassNameType.__CreateInstance(type.__Instance); - return VisitInjectedClassName(_type); - } + { + var _type = InjectedClassNameType.__CreateInstance(type.__Instance); + return VisitInjectedClassName(_type); + } case TypeKind.DependentName: - { - var _type = DependentNameType.__CreateInstance(type.__Instance); - return VisitDependentName(_type); - } + { + var _type = DependentNameType.__CreateInstance(type.__Instance); + return VisitDependentName(_type); + } case TypeKind.Builtin: - { - var _type = BuiltinType.__CreateInstance(type.__Instance); - return VisitBuiltin(_type); - } + { + var _type = BuiltinType.__CreateInstance(type.__Instance); + return VisitBuiltin(_type); + } case TypeKind.PackExpansion: - { - var _type = PackExpansionType.__CreateInstance(type.__Instance); - return VisitPackExpansion(_type); - } + { + var _type = PackExpansionType.__CreateInstance(type.__Instance); + return VisitPackExpansion(_type); + } case TypeKind.UnaryTransform: - { - var _type = UnaryTransformType.__CreateInstance(type.__Instance); - return VisitUnaryTransform(_type); - } + { + var _type = UnaryTransformType.__CreateInstance(type.__Instance); + return VisitUnaryTransform(_type); + } case TypeKind.UnresolvedUsing: - { - var _type = UnresolvedUsingType.__CreateInstance(type.__Instance); - return VisitUnresolvedUsing(_type); - } + { + var _type = UnresolvedUsingType.__CreateInstance(type.__Instance); + return VisitUnresolvedUsing(_type); + } case TypeKind.Vector: - { - var _type = VectorType.__CreateInstance(type.__Instance); - return VisitVector(_type); - } + { + var _type = VectorType.__CreateInstance(type.__Instance); + return VisitVector(_type); + } } throw new ArgumentOutOfRangeException(); @@ -182,135 +182,135 @@ public virtual TRet Visit(Parser.AST.Declaration decl) switch (decl.Kind) { case DeclarationKind.TranslationUnit: - { - var _decl = TranslationUnit.__CreateInstance(decl.__Instance); - return VisitTranslationUnit(_decl); - } + { + var _decl = TranslationUnit.__CreateInstance(decl.__Instance); + return VisitTranslationUnit(_decl); + } case DeclarationKind.Namespace: - { - var _decl = Namespace.__CreateInstance(decl.__Instance); - return VisitNamespace(_decl); - } + { + var _decl = Namespace.__CreateInstance(decl.__Instance); + return VisitNamespace(_decl); + } case DeclarationKind.Typedef: - { - var _decl = TypedefDecl.__CreateInstance(decl.__Instance); - return VisitTypedef(_decl); - } + { + var _decl = TypedefDecl.__CreateInstance(decl.__Instance); + return VisitTypedef(_decl); + } case DeclarationKind.TypeAlias: - { - var _decl = TypeAlias.__CreateInstance(decl.__Instance); - return VisitTypeAlias(_decl); - } + { + var _decl = TypeAlias.__CreateInstance(decl.__Instance); + return VisitTypeAlias(_decl); + } case DeclarationKind.Parameter: - { - var _decl = Parameter.__CreateInstance(decl.__Instance); - return VisitParameter(_decl); - } + { + var _decl = Parameter.__CreateInstance(decl.__Instance); + return VisitParameter(_decl); + } case DeclarationKind.Function: - { - var _decl = Function.__CreateInstance(decl.__Instance); - return VisitFunction(_decl); - } + { + var _decl = Function.__CreateInstance(decl.__Instance); + return VisitFunction(_decl); + } case DeclarationKind.Method: - { - var _decl = Method.__CreateInstance(decl.__Instance); - return VisitMethod(_decl); - } + { + var _decl = Method.__CreateInstance(decl.__Instance); + return VisitMethod(_decl); + } case DeclarationKind.Enumeration: - { - var _decl = Enumeration.__CreateInstance(decl.__Instance); - return VisitEnumeration(_decl); - } + { + var _decl = Enumeration.__CreateInstance(decl.__Instance); + return VisitEnumeration(_decl); + } case DeclarationKind.EnumerationItem: - { - var _decl = Enumeration.Item.__CreateInstance(decl.__Instance); - return VisitEnumerationItem(_decl); - } + { + var _decl = Enumeration.Item.__CreateInstance(decl.__Instance); + return VisitEnumerationItem(_decl); + } case DeclarationKind.Variable: - { - var _decl = Variable.__CreateInstance(decl.__Instance); - return VisitVariable(_decl); - } + { + var _decl = Variable.__CreateInstance(decl.__Instance); + return VisitVariable(_decl); + } case DeclarationKind.VarTemplate: - { - var _decl = VarTemplate.__CreateInstance(decl.__Instance); - return VisitVarTemplate(_decl); - } + { + var _decl = VarTemplate.__CreateInstance(decl.__Instance); + return VisitVarTemplate(_decl); + } case DeclarationKind.VarTemplateSpecialization: - { - var _decl = VarTemplateSpecialization.__CreateInstance(decl.__Instance); - return VisitVarTemplateSpecialization(_decl); - } + { + var _decl = VarTemplateSpecialization.__CreateInstance(decl.__Instance); + return VisitVarTemplateSpecialization(_decl); + } case DeclarationKind.VarTemplatePartialSpecialization: - { - var _decl = VarTemplatePartialSpecialization.__CreateInstance(decl.__Instance); - return VisitVarTemplatePartialSpecialization(_decl); - } + { + var _decl = VarTemplatePartialSpecialization.__CreateInstance(decl.__Instance); + return VisitVarTemplatePartialSpecialization(_decl); + } case DeclarationKind.Friend: - { - var _decl = Friend.__CreateInstance(decl.__Instance); - return VisitFriend(_decl); - } + { + var _decl = Friend.__CreateInstance(decl.__Instance); + return VisitFriend(_decl); + } case DeclarationKind.Field: - { - var _decl = Field.__CreateInstance(decl.__Instance); - return VisitField(_decl); - } + { + var _decl = Field.__CreateInstance(decl.__Instance); + return VisitField(_decl); + } case DeclarationKind.AccessSpecifier: - { - var _decl = AccessSpecifierDecl.__CreateInstance(decl.__Instance); - return VisitAccessSpecifier(_decl); - } + { + var _decl = AccessSpecifierDecl.__CreateInstance(decl.__Instance); + return VisitAccessSpecifier(_decl); + } case DeclarationKind.Class: - { - var _decl = Class.__CreateInstance(decl.__Instance); - return VisitClass(_decl); - } + { + var _decl = Class.__CreateInstance(decl.__Instance); + return VisitClass(_decl); + } case DeclarationKind.ClassTemplate: - { - var _decl = ClassTemplate.__CreateInstance(decl.__Instance); - return VisitClassTemplate(_decl); - } + { + var _decl = ClassTemplate.__CreateInstance(decl.__Instance); + return VisitClassTemplate(_decl); + } case DeclarationKind.ClassTemplateSpecialization: - { - var _decl = ClassTemplateSpecialization.__CreateInstance(decl.__Instance); - return VisitClassTemplateSpecialization(_decl); - } + { + var _decl = ClassTemplateSpecialization.__CreateInstance(decl.__Instance); + return VisitClassTemplateSpecialization(_decl); + } case DeclarationKind.ClassTemplatePartialSpecialization: - { - var _decl = ClassTemplatePartialSpecialization.__CreateInstance(decl.__Instance); - return VisitClassTemplatePartialSpecialization(_decl); - } + { + var _decl = ClassTemplatePartialSpecialization.__CreateInstance(decl.__Instance); + return VisitClassTemplatePartialSpecialization(_decl); + } case DeclarationKind.FunctionTemplate: - { - var _decl = FunctionTemplate.__CreateInstance(decl.__Instance); - return VisitFunctionTemplate(_decl); - } + { + var _decl = FunctionTemplate.__CreateInstance(decl.__Instance); + return VisitFunctionTemplate(_decl); + } case DeclarationKind.TypeAliasTemplate: - { - var _decl = TypeAliasTemplate.__CreateInstance(decl.__Instance); - return VisitTypeAliasTemplate(_decl); - } + { + var _decl = TypeAliasTemplate.__CreateInstance(decl.__Instance); + return VisitTypeAliasTemplate(_decl); + } case DeclarationKind.TemplateTemplateParm: - { - var _decl = TemplateTemplateParameter.__CreateInstance(decl.__Instance); - return VisitTemplateTemplateParameter(_decl); - } + { + var _decl = TemplateTemplateParameter.__CreateInstance(decl.__Instance); + return VisitTemplateTemplateParameter(_decl); + } case DeclarationKind.TemplateTypeParm: - { - var _decl = TypeTemplateParameter.__CreateInstance(decl.__Instance); - return VisitTypeTemplateParameter(_decl); - } + { + var _decl = TypeTemplateParameter.__CreateInstance(decl.__Instance); + return VisitTypeTemplateParameter(_decl); + } case DeclarationKind.NonTypeTemplateParm: - { - var _decl = NonTypeTemplateParameter.__CreateInstance(decl.__Instance); - return VisitNonTypeTemplateParameter(_decl); - } + { + var _decl = NonTypeTemplateParameter.__CreateInstance(decl.__Instance); + return VisitNonTypeTemplateParameter(_decl); + } case DeclarationKind.UnresolvedUsingTypename: - { - var _decl = UnresolvedUsingTypename.__CreateInstance(decl.__Instance); - return VisitUnresolvedUsingTypename(_decl); - } + { + var _decl = UnresolvedUsingTypename.__CreateInstance(decl.__Instance); + return VisitUnresolvedUsingTypename(_decl); + } } throw new ArgumentOutOfRangeException(); @@ -1833,6 +1833,8 @@ public override AST.Declaration VisitClassTemplate(ClassTemplate decl) var _spec = (AST.ClassTemplateSpecialization)Visit(spec); _decl.Specializations.Add(_spec); } + _decl.TemplatedClass.TemplateParameters.AddRange(_decl.Parameters); + _decl.TemplatedClass.Specializations.AddRange(_decl.Specializations); return _decl; } @@ -1927,6 +1929,7 @@ public override AST.Declaration VisitClassTemplatePartialSpecialization( var _param = Visit(param); _decl.Parameters.Add(_param); } + _decl.TemplateParameters.AddRange(_decl.TemplatedDecl.Parameters); return _decl; } From 277dc5c2ac43fcf4a2a3969d1a09c34a18420cab Mon Sep 17 00:00:00 2001 From: duckdoom5 Date: Thu, 27 Feb 2025 10:46:44 +0100 Subject: [PATCH 3/9] Misc changes --- CppSharp.sln.DotSettings | 1 + .../Bootstrap/CodeGeneratorHelpers.cs | 24 +++++++++---------- .../Generators/CSharp/CSharpTypePrinter.cs | 2 +- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/CppSharp.sln.DotSettings b/CppSharp.sln.DotSettings index 68fb4a1a3..dd0332a7b 100644 --- a/CppSharp.sln.DotSettings +++ b/CppSharp.sln.DotSettings @@ -1,5 +1,6 @@  CLI + MD MSVC True True \ No newline at end of file diff --git a/src/CppParser/Bootstrap/CodeGeneratorHelpers.cs b/src/CppParser/Bootstrap/CodeGeneratorHelpers.cs index 810a6ea49..95033edee 100644 --- a/src/CppParser/Bootstrap/CodeGeneratorHelpers.cs +++ b/src/CppParser/Bootstrap/CodeGeneratorHelpers.cs @@ -47,8 +47,7 @@ public static bool SkipProperty(Property property, bool skipBaseCheck = false) 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) @@ -309,7 +308,7 @@ public static string GetQualifiedName(Declaration decl, else if (qualifiedName.Contains("Semantics")) qualifiedName = qualifiedName.Replace( typePrinter is CppTypePrinter ? "llvm::APFloatBase::Semantics" : "llvm.APFloatBase.Semantics" - , "FloatSemantics"); + , "FloatSemantics"); return qualifiedName; } @@ -319,11 +318,13 @@ public static string GetQualifiedName(Declaration decl) => 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; } @@ -392,7 +393,8 @@ public static string GetDeclTypeName(AST.Type type, if (typeResult.Type.Contains("MSGuidDecl")) return typePrinter is CppTypePrinter - ? "std::string" : "string"; + ? "std::string" + : "string"; var typeName = typeResult.ToString(); typeName = CleanClangNamespaceFromName(typeName); @@ -436,8 +438,7 @@ public static string GetDeclTypeName(AST.Type type, className = "Declaration"; if (className != null) - return (typePrinter is CppTypePrinter) ? - $"{className}*" : className; + return (typePrinter is CppTypePrinter) ? $"{className}*" : className; return typeName; } @@ -525,8 +526,7 @@ public static List GetBaseClasses(Class @class) while (currentClass != null) { baseClasses.Add(currentClass); - currentClass = currentClass.HasBaseClass ? - currentClass.BaseClass : null; + currentClass = currentClass.HasBaseClass ? currentClass.BaseClass : null; } baseClasses.Reverse(); diff --git a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs index ba100fc79..095ecde93 100644 --- a/src/Generator/Generators/CSharp/CSharpTypePrinter.cs +++ b/src/Generator/Generators/CSharp/CSharpTypePrinter.cs @@ -315,7 +315,7 @@ public override TypePrinterResult VisitTemplateSpecializationType( 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; } From dc50ec435fbf80786820467e684ed41b39012a66 Mon Sep 17 00:00:00 2001 From: duckdoom5 Date: Fri, 28 Feb 2025 11:06:59 +0100 Subject: [PATCH 4/9] Print default if normal context --- src/Generator/Generators/C/CppTypePrinter.cs | 126 ++++++++++--------- 1 file changed, 66 insertions(+), 60 deletions(-) diff --git a/src/Generator/Generators/C/CppTypePrinter.cs b/src/Generator/Generators/C/CppTypePrinter.cs index 23f46c299..2c05a40f5 100644 --- a/src/Generator/Generators/C/CppTypePrinter.cs +++ b/src/Generator/Generators/C/CppTypePrinter.cs @@ -199,32 +199,32 @@ public virtual TypePrinterResult VisitPrimitiveType(PrimitiveType primitive) return PrintFlavorKind == CppTypePrintFlavorKind.Cpp ? "std::nullptr_t" : "NULL"; case PrimitiveType.String: + { + switch (PrintFlavorKind) { - switch (PrintFlavorKind) - { - case CppTypePrintFlavorKind.C: - return "const char*"; - case CppTypePrintFlavorKind.Cpp: - return "std::string"; - case CppTypePrintFlavorKind.ObjC: - return "NSString"; - default: - throw new ArgumentOutOfRangeException(); - } + case CppTypePrintFlavorKind.C: + return "const char*"; + case CppTypePrintFlavorKind.Cpp: + return "std::string"; + case CppTypePrintFlavorKind.ObjC: + return "NSString"; + default: + throw new ArgumentOutOfRangeException(); } + } case PrimitiveType.Decimal: + { + switch (PrintFlavorKind) { - switch (PrintFlavorKind) - { - case CppTypePrintFlavorKind.C: - case CppTypePrintFlavorKind.Cpp: - return "_Decimal32"; - case CppTypePrintFlavorKind.ObjC: - return "NSDecimalNumber"; - default: - throw new ArgumentOutOfRangeException(); - } + case CppTypePrintFlavorKind.C: + case CppTypePrintFlavorKind.Cpp: + return "_Decimal32"; + case CppTypePrintFlavorKind.ObjC: + return "NSDecimalNumber"; + default: + throw new ArgumentOutOfRangeException(); } + } } throw new NotSupportedException(); @@ -472,58 +472,64 @@ public virtual TypePrinterResult GetDeclName(Declaration declaration, switch (scope) { case TypePrintScopeKind.Local: + { + if (ContextKind is TypePrinterContextKind.Managed or TypePrinterContextKind.Normal) { - if (ContextKind == TypePrinterContextKind.Managed) - { - return PrintLogicalNames ? declaration.LogicalName : declaration.Name; - } - - if (PrefixSpecialFunctions) - { - if (declaration is Function { IsOperator: true } function) - return $"operator_{function.OperatorKind}"; - } + return PrintLogicalNames ? declaration.LogicalName : declaration.Name; + } - return PrintLogicalNames ? declaration.LogicalOriginalName - : declaration.OriginalName; + if (PrefixSpecialFunctions) + { + if (declaration is Function { IsOperator: true } function) + return $"operator_{function.OperatorKind}"; } + + return PrintLogicalNames ? declaration.LogicalOriginalName + : declaration.OriginalName; + } case TypePrintScopeKind.Qualified: + { + if (ContextKind == TypePrinterContextKind.Managed) { - if (ContextKind == TypePrinterContextKind.Managed) + var outputNamespace = GlobalNamespace(declaration); + if (!string.IsNullOrEmpty(outputNamespace)) { - var outputNamespace = GlobalNamespace(declaration); - if (!string.IsNullOrEmpty(outputNamespace)) - { - return $"{outputNamespace}{NamespaceSeparator}{declaration.QualifiedName}"; - } - - return declaration.QualifiedName; + return $"{outputNamespace}{NamespaceSeparator}{declaration.QualifiedName}"; } - if (declaration.Namespace is Class) - { - var declName = GetDeclName(declaration, TypePrintScopeKind.Local); - bool printTags = PrintTags; - PrintTags = false; - TypePrinterResult declContext = declaration.Namespace.Visit(this); - PrintTags = printTags; - return $"{declContext}{NamespaceSeparator}{declName}"; - } + return declaration.QualifiedName; + } - return PrintLogicalNames ? declaration.QualifiedLogicalOriginalName - : declaration.QualifiedOriginalName; + if (declaration.Namespace is Class) + { + var declName = GetDeclName(declaration, TypePrintScopeKind.Local); + bool printTags = PrintTags; + PrintTags = false; + TypePrinterResult declContext = declaration.Namespace.Visit(this); + PrintTags = printTags; + return $"{declContext}{NamespaceSeparator}{declName}"; } - case TypePrintScopeKind.GlobalQualified: + + if (ContextKind == TypePrinterContextKind.Normal) { - var name = (ContextKind == TypePrinterContextKind.Managed) ? - declaration.Name : declaration.OriginalName; + return PrintLogicalNames ? declaration.QualifiedLogicalName + : declaration.QualifiedName; + } + + return PrintLogicalNames ? declaration.QualifiedLogicalOriginalName + : declaration.QualifiedOriginalName; + } + case TypePrintScopeKind.GlobalQualified: + { + var name = (ContextKind == TypePrinterContextKind.Managed) ? + declaration.Name : declaration.OriginalName; - if (declaration.Namespace is Class) - return $"{declaration.Namespace.Visit(this)}{NamespaceSeparator}{name}"; + if (declaration.Namespace is Class) + return $"{declaration.Namespace.Visit(this)}{NamespaceSeparator}{name}"; - var qualifier = HasGlobalNamespacePrefix ? NamespaceSeparator : string.Empty; - return qualifier + GetDeclName(declaration, TypePrintScopeKind.Qualified); - } + var qualifier = HasGlobalNamespacePrefix ? NamespaceSeparator : string.Empty; + return qualifier + GetDeclName(declaration, TypePrintScopeKind.Qualified); + } } throw new NotSupportedException(); From f6ce878071cdeb4faa3a4d217b18ab8312dcddc4 Mon Sep 17 00:00:00 2001 From: duckdoom5 Date: Fri, 28 Feb 2025 16:40:21 +0100 Subject: [PATCH 5/9] `FindClass` patch --- src/AST/ASTContext.cs | 12 +++---- src/AST/Namespace.cs | 36 +++++++++++++------ .../Passes/MoveFunctionToClassPass.cs | 2 +- .../Passes/StripUnusedSystemTypesPass.cs | 2 +- 4 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/AST/ASTContext.cs b/src/AST/ASTContext.cs index e52107e0d..e478a2fe4 100644 --- a/src/AST/ASTContext.cs +++ b/src/AST/ASTContext.cs @@ -75,20 +75,18 @@ public Enumeration FindCompleteEnum(string name) } /// Finds an existing struct/class in the library modules. - public IEnumerable FindClass(string name, bool create = false, - bool ignoreCase = false) + public IEnumerable 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. diff --git a/src/AST/Namespace.cs b/src/AST/Namespace.cs index 13f9cf322..b7af87fb2 100644 --- a/src/AST/Namespace.cs +++ b/src/AST/Namespace.cs @@ -203,17 +203,33 @@ Class CreateClass(string name, bool isComplete) }; } - public Class FindClass(string name, - StringComparison stringComparison = StringComparison.Ordinal) + public Class FindClass(string name) { - 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; - return null; + if (string.IsNullOrEmpty(name)) + return null; + + 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, diff --git a/src/Generator/Passes/MoveFunctionToClassPass.cs b/src/Generator/Passes/MoveFunctionToClassPass.cs index ebfe808ed..a72974663 100644 --- a/src/Generator/Passes/MoveFunctionToClassPass.cs +++ b/src/Generator/Passes/MoveFunctionToClassPass.cs @@ -61,7 +61,7 @@ private Class FindClassToMoveFunctionTo(Function function) 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); } diff --git a/src/Generator/Passes/StripUnusedSystemTypesPass.cs b/src/Generator/Passes/StripUnusedSystemTypesPass.cs index 46aa1c0f7..875020de3 100644 --- a/src/Generator/Passes/StripUnusedSystemTypesPass.cs +++ b/src/Generator/Passes/StripUnusedSystemTypesPass.cs @@ -16,7 +16,7 @@ public override bool VisitASTContext(ASTContext context) // 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) From cb64f1bbf0ba9e5ede2552af062af6b0be6c90d1 Mon Sep 17 00:00:00 2001 From: duckdoom5 Date: Sat, 1 Mar 2025 11:32:57 +0100 Subject: [PATCH 6/9] Add some missing verbs --- src/Generator/Passes/verbs.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Generator/Passes/verbs.txt b/src/Generator/Passes/verbs.txt index 204dcce97..678da6c18 100644 --- a/src/Generator/Passes/verbs.txt +++ b/src/Generator/Passes/verbs.txt @@ -840,6 +840,7 @@ caponize capsize capsulize captivate +capture caramelise caramelize carbolise @@ -5001,6 +5002,7 @@ overresist overrestrain overrestrict overreward +override overripen overroast overromanticize From 210e79c903698644a8f17028b4a1fccfdee815a9 Mon Sep 17 00:00:00 2001 From: duckdoom5 Date: Thu, 27 Feb 2025 11:17:00 +0100 Subject: [PATCH 7/9] Temp --- src/AST/Class.cs | 10 + src/AST/Declaration.cs | 16 + src/CppParser/AST.cpp | 1 - src/CppParser/Bootstrap/Bootstrap.cs | 347 ++++++++++++++++-- .../Bootstrap/CodeGeneratorHelpers.cs | 243 +++++++++--- src/CppParser/Bootstrap/DeclCodeGenerators.cs | 221 +++++++++++ .../Bootstrap/InheritanceValidator.cs | 55 +++ .../Bootstrap/ParserCodeGenerators.cs | 104 ++++++ .../Bootstrap/Properties/launchSettings.json | 2 +- src/CppParser/Bootstrap/StmtCodeGenerators.cs | 24 +- src/CppParser/Bootstrap/TypeCodeGenerators.cs | 323 ++++++++++++++++ src/CppParser/Decl.h | 9 - src/CppParser/Types.h | 21 ++ src/Generator/Generators/CodeGenerator.cs | 4 +- 14 files changed, 1280 insertions(+), 100 deletions(-) create mode 100644 src/CppParser/Bootstrap/DeclCodeGenerators.cs create mode 100644 src/CppParser/Bootstrap/InheritanceValidator.cs create mode 100644 src/CppParser/Bootstrap/ParserCodeGenerators.cs create mode 100644 src/CppParser/Bootstrap/TypeCodeGenerators.cs diff --git a/src/AST/Class.cs b/src/AST/Class.cs index 442fe937c..c2b41de30 100644 --- a/src/AST/Class.cs +++ b/src/AST/Class.cs @@ -274,6 +274,16 @@ public Variable FindVariable(string name) 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(IDeclVisitor visitor) { return visitor.VisitClassDecl(this); diff --git a/src/AST/Declaration.cs b/src/AST/Declaration.cs index 2fc50d312..c2107da9d 100644 --- a/src/AST/Declaration.cs +++ b/src/AST/Declaration.cs @@ -223,6 +223,22 @@ public static IEnumerable GatherNamespaces(DeclarationContext @name 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 diff --git a/src/CppParser/AST.cpp b/src/CppParser/AST.cpp index e5823a23b..6dc61151d 100644 --- a/src/CppParser/AST.cpp +++ b/src/CppParser/AST.cpp @@ -1153,7 +1153,6 @@ namespace CppSharp { namespace CppParser { namespace AST { kind = DeclarationKind::TranslationUnit; } - TranslationUnit::~TranslationUnit() {} DEF_VECTOR(TranslationUnit, MacroDefinition*, Macros) NativeLibrary::NativeLibrary() diff --git a/src/CppParser/Bootstrap/Bootstrap.cs b/src/CppParser/Bootstrap/Bootstrap.cs index 916e7214d..a42f27dec 100644 --- a/src/CppParser/Bootstrap/Bootstrap.cs +++ b/src/CppParser/Bootstrap/Bootstrap.cs @@ -19,7 +19,7 @@ namespace CppSharp /// 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 @@ public void Setup(Driver driver) { 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 @@ public void Setup(Driver driver) 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 @@ public void SetupPasses(Driver driver) 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 @@ public void Preprocess(Driver driver, ASTContext ctx) 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 @@ private void GenerateStmt(BindingContext ctx) 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 @@ internal class PreprocessDeclarations : AstVisitor { 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 @@ private static void Check(Declaration decl) 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 @@ public override bool VisitClassDecl(Class @class) } } - 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 @@ public override bool VisitEnumDecl(Enumeration @enum) RemoveEnumItemsPrefix(@enum); - return base.VisitEnumDecl(@enum); + return true; } private void RemoveEnumItemsPrefix(Enumeration @enum) @@ -586,7 +877,7 @@ public override bool VisitNamespace(Namespace @namespace) public override bool VisitClassDecl(Class @class) { - if (!@class.IsGenerated) + if (SkipClass(@class)) return false; GenerateClassSpecifier(@class); @@ -953,6 +1244,7 @@ public override void Process() { Context.Options.GeneratorKind = GeneratorKind.CPlusPlus; CTypePrinter.PushScope(TypePrintScopeKind.Local); + CTypePrinter.PushContext(TypePrinterContextKind.Normal); GenerateFilePreamble(CommentKind.BCPL); NewLine(); @@ -1042,7 +1334,12 @@ protected virtual string GenerateInit(Property property) 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"; } diff --git a/src/CppParser/Bootstrap/CodeGeneratorHelpers.cs b/src/CppParser/Bootstrap/CodeGeneratorHelpers.cs index 95033edee..6505c9e40 100644 --- a/src/CppParser/Bootstrap/CodeGeneratorHelpers.cs +++ b/src/CppParser/Bootstrap/CodeGeneratorHelpers.cs @@ -9,6 +9,44 @@ 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 @@ @class is "Stmt" 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) @@ -61,11 +110,22 @@ public static bool SkipProperty(Property property, bool skipBaseCheck = false) 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") || @@ -77,7 +137,7 @@ public static bool SkipProperty(Property property, bool skipBaseCheck = false) typeName.Contains("NestedNameSpecifierLoc") || typeName.Contains("DeclarationNameInfo") || typeName.Contains("DeclGroupRef")) - return true; + return true;*/ // // Expressions @@ -209,11 +269,6 @@ public static bool SkipProperty(Property property, bool skipBaseCheck = false) if (typeName.Contains("StorageDuration")) return true; - // General properties. - if (typeName.Contains("_iterator") || - typeName.Contains("_range")) - return true; - if (typeName.Contains("ArrayRef")) return true; @@ -246,7 +301,7 @@ public static bool SkipProperty(Property property, bool skipBaseCheck = false) public static bool SkipMethod(Method method) { - if (method.Ignore) + if (method.IsGenerated) return true; var @class = method.Namespace as Class; @@ -335,8 +390,14 @@ public static string GetDeclName(Declaration decl, GeneratorKind kind) 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) { @@ -372,7 +433,7 @@ public static AST.Type GetDeclType(AST.Type type, 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; @@ -423,61 +484,23 @@ public static string GetDeclTypeName(AST.Type type, } } - 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; + var retType = method.ReturnType.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 is TemplateSpecializationType templateSpecType) + retType = templateSpecType.Arguments[0].Type.Type.Desugar(); - var iteratorType = typedefNameDecl.Type; - if (iteratorType.IsPointerTo(out PointerType pointee)) - iteratorType = iteratorType.GetPointee(); + if (retType.IsPointerTo(out PointerType pointee)) + retType = pointee; - 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(); @@ -494,7 +517,8 @@ public static string GetIteratorTypeName(AST.Type iteratorType, 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; @@ -509,9 +533,6 @@ public static string GetIteratorTypeName(AST.Type iteratorType, iteratorTypeName = CleanClangNamespaceFromName(iteratorTypeName); } - if (iteratorTypeName == "Decl") - iteratorTypeName = "Declaration"; - if (typePrinter is CppTypePrinter) return $"{iteratorTypeName}*"; @@ -547,5 +568,109 @@ public static string FirstLetterToUpperCase(string s) 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")); + } } } \ No newline at end of file diff --git a/src/CppParser/Bootstrap/DeclCodeGenerators.cs b/src/CppParser/Bootstrap/DeclCodeGenerators.cs new file mode 100644 index 000000000..ead8b8551 --- /dev/null +++ b/src/CppParser/Bootstrap/DeclCodeGenerators.cs @@ -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 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 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 declarations) + : base(context, declarations) + { + } + + public override string BaseTypeName => "Decl"; + + public override bool IsAbstractASTNode(Class kind) + { + return IsAbstractDecl(kind); + } + + protected override void GenerateVisitorSwitch(IEnumerable classes) + { + WriteLine($"switch({ParamName}.DeclKind)"); + WriteOpenBraceAndIndent(); + + GenerateSwitchCases(classes); + + UnindentAndWriteCloseBrace(); + } + + private void GenerateSwitchCases(IEnumerable 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());"); + } + } +} \ No newline at end of file diff --git a/src/CppParser/Bootstrap/InheritanceValidator.cs b/src/CppParser/Bootstrap/InheritanceValidator.cs new file mode 100644 index 000000000..920b9aff7 --- /dev/null +++ b/src/CppParser/Bootstrap/InheritanceValidator.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using CppSharp.AST; + +namespace CppSharp +{ + class InheritanceValidator + { + private readonly HashSet _processedClasses = new(); + + public void ValidateInheritance(IEnumerable declarations) + { + foreach (var decl in declarations.OfType()) + { + 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(); + } + } + } + } +} \ No newline at end of file diff --git a/src/CppParser/Bootstrap/ParserCodeGenerators.cs b/src/CppParser/Bootstrap/ParserCodeGenerators.cs new file mode 100644 index 000000000..acc7b922e --- /dev/null +++ b/src/CppParser/Bootstrap/ParserCodeGenerators.cs @@ -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 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 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; + } + } +} \ No newline at end of file diff --git a/src/CppParser/Bootstrap/Properties/launchSettings.json b/src/CppParser/Bootstrap/Properties/launchSettings.json index a689a483b..9b11eed07 100644 --- a/src/CppParser/Bootstrap/Properties/launchSettings.json +++ b/src/CppParser/Bootstrap/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "CppSharp.Parser.Bootstrap": { "commandName": "Project", - "nativeDebugging": true + "nativeDebugging": false } } } \ No newline at end of file diff --git a/src/CppParser/Bootstrap/StmtCodeGenerators.cs b/src/CppParser/Bootstrap/StmtCodeGenerators.cs index 77ed94f11..1d50a9186 100644 --- a/src/CppParser/Bootstrap/StmtCodeGenerators.cs +++ b/src/CppParser/Bootstrap/StmtCodeGenerators.cs @@ -66,8 +66,7 @@ public override bool GenerateClassBody(Class @class) 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 @@ public override bool VisitClassDecl(Class @class) 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 @@ public override bool VisitMethodDecl(Method method) { 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); diff --git a/src/CppParser/Bootstrap/TypeCodeGenerators.cs b/src/CppParser/Bootstrap/TypeCodeGenerators.cs new file mode 100644 index 000000000..7961b59d0 --- /dev/null +++ b/src/CppParser/Bootstrap/TypeCodeGenerators.cs @@ -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 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 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 declarations) + : base(context, declarations) + { + } + + public override string BaseTypeName => "Type"; + + public override bool IsAbstractASTNode(Class kind) + { + return IsAbstractType(kind); + } + + protected override void GenerateVisitorSwitch(IEnumerable classes) + { + WriteLine($"switch({ParamName}.DeclKind)"); + WriteOpenBraceAndIndent(); + + GenerateSwitchCases(classes); + + UnindentAndWriteCloseBrace(); + } + + public void GenerateSwitchCases(IEnumerable 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());"); + } + } +} \ No newline at end of file diff --git a/src/CppParser/Decl.h b/src/CppParser/Decl.h index b931e88eb..f66deb359 100644 --- a/src/CppParser/Decl.h +++ b/src/CppParser/Decl.h @@ -566,15 +566,6 @@ namespace AST { VECTOR(LayoutBase, Bases) }; - enum class TagKind - { - Struct, - Interface, - Union, - Class, - Enum - }; - class CS_API Class : public DeclarationContext { public: diff --git a/src/CppParser/Types.h b/src/CppParser/Types.h index e8a05f32f..70184e2b3 100644 --- a/src/CppParser/Types.h +++ b/src/CppParser/Types.h @@ -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 { 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 { long elementSize; }; + class CS_API VariableArrayType : public ArrayType + { + public: + VariableArrayType() + { + sizeType = ArraySize::Variable; + } + + Expr* sizeExpr = nullptr; + }; + class Parameter; enum class CallingConvention diff --git a/src/Generator/Generators/CodeGenerator.cs b/src/Generator/Generators/CodeGenerator.cs index 793b98734..a39263e5f 100644 --- a/src/Generator/Generators/CodeGenerator.cs +++ b/src/Generator/Generators/CodeGenerator.cs @@ -427,7 +427,7 @@ public virtual bool VisitFriend(Friend friend) public virtual bool VisitClassTemplateDecl(ClassTemplate template) { - throw new NotImplementedException(); + return true; } public virtual bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecialization specialization) @@ -437,7 +437,7 @@ public virtual bool VisitClassTemplateSpecializationDecl(ClassTemplateSpecializa public virtual bool VisitFunctionTemplateDecl(FunctionTemplate template) { - throw new NotImplementedException(); + return true; } public virtual bool VisitFunctionTemplateSpecializationDecl(FunctionTemplateSpecialization specialization) From da6a9d4946a8d646172a44860fc0df404405611a Mon Sep 17 00:00:00 2001 From: duckdoom5 Date: Sat, 1 Mar 2025 12:14:26 +0100 Subject: [PATCH 8/9] Cleanup --- src/CppParser/Decl.h | 1632 +++++++++++++++++++++--------------------- 1 file changed, 814 insertions(+), 818 deletions(-) diff --git a/src/CppParser/Decl.h b/src/CppParser/Decl.h index f66deb359..3c2d91c16 100644 --- a/src/CppParser/Decl.h +++ b/src/CppParser/Decl.h @@ -10,830 +10,826 @@ #include "Helpers.h" #include "Sources.h" #include "Types.h" -#include -namespace CppSharp { -namespace CppParser { -namespace AST { +#include - enum class DeclarationKind - { - DeclarationContext, - Typedef, - TypeAlias, - Parameter, - Function, - Method, - Enumeration, - EnumerationItem, - Variable, - Field, - AccessSpecifier, - Class, - Template, - TypeAliasTemplate, - ClassTemplate, - ClassTemplateSpecialization, - ClassTemplatePartialSpecialization, - FunctionTemplate, - Namespace, - PreprocessedEntity, - MacroDefinition, - MacroExpansion, - TranslationUnit, - Friend, - TemplateTemplateParm, - TemplateTypeParm, - NonTypeTemplateParm, - VarTemplate, - VarTemplateSpecialization, - VarTemplatePartialSpecialization, - UnresolvedUsingTypename, - }; +namespace CppSharp::CppParser::AST { + +enum class DeclarationKind +{ + DeclarationContext, + Typedef, + TypeAlias, + Parameter, + Function, + Method, + Enumeration, + EnumerationItem, + Variable, + Field, + AccessSpecifier, + Class, + Template, + TypeAliasTemplate, + ClassTemplate, + ClassTemplateSpecialization, + ClassTemplatePartialSpecialization, + FunctionTemplate, + Namespace, + PreprocessedEntity, + MacroDefinition, + MacroExpansion, + TranslationUnit, + Friend, + TemplateTemplateParm, + TemplateTypeParm, + NonTypeTemplateParm, + VarTemplate, + VarTemplateSpecialization, + VarTemplatePartialSpecialization, + UnresolvedUsingTypename, +}; #define DECLARE_DECL_KIND(klass, kind) \ klass(); - enum class AccessSpecifier - { - Private, - Protected, - Public - }; - - class DeclarationContext; - class RawComment; - class PreprocessedEntity; - - class ExpressionObsolete; - class CS_API Declaration - { - public: - Declaration(DeclarationKind kind); - Declaration(const Declaration&); - ~Declaration(); - - DeclarationKind kind; - int alignAs; - int maxFieldAlignment; - AccessSpecifier access; - DeclarationContext* _namespace; - SourceLocation location; - int lineNumberStart; - int lineNumberEnd; - std::string name; - std::string USR; - std::string debugText; - bool isIncomplete; - bool isDependent; - bool isImplicit; - bool isInvalid; - bool isDeprecated; - Declaration* completeDeclaration; - unsigned definitionOrder; - VECTOR(PreprocessedEntity*, PreprocessedEntities) - VECTOR(Declaration*, Redeclarations) - void* originalPtr; - RawComment* comment; - }; - - class Class; - class Enumeration; - class Function; - class TypedefDecl; - class TypeAlias; - class Namespace; - class Template; - class TypeAliasTemplate; - class ClassTemplate; - class FunctionTemplate; - class Variable; - class Friend; - - class CS_API DeclarationContext : public Declaration - { - public: - DeclarationContext(DeclarationKind kind); - - CS_IGNORE Declaration* FindAnonymous(const std::string& USR); - - CS_IGNORE Namespace* FindNamespace(const std::string& Name); - CS_IGNORE Namespace* FindNamespace(const std::vector&); - CS_IGNORE Namespace* FindCreateNamespace(const std::string& Name); - - CS_IGNORE Class* CreateClass(const std::string& Name, bool IsComplete); - CS_IGNORE Class* FindClass(const void* OriginalPtr, const std::string& Name, bool IsComplete); - CS_IGNORE Class* FindClass(const void* OriginalPtr, const std::string& Name, bool IsComplete, bool Create); - - CS_IGNORE template - T* FindTemplate(const std::string& USR); - - CS_IGNORE Enumeration* FindEnum(const void* OriginalPtr); - CS_IGNORE Enumeration* FindEnum(const std::string& Name, bool Create = false); - CS_IGNORE Enumeration* FindEnumWithItem(const std::string& Name); - - CS_IGNORE Function* FindFunction(const std::string& USR); - - CS_IGNORE TypedefDecl* FindTypedef(const std::string& Name, bool Create = false); - - CS_IGNORE TypeAlias* FindTypeAlias(const std::string& Name, bool Create = false); - - CS_IGNORE Variable* FindVariable(const std::string& USR); - - CS_IGNORE Friend* FindFriend(const std::string& USR); - - VECTOR(Namespace*, Namespaces) - VECTOR(Enumeration*, Enums) - VECTOR(Function*, Functions) - VECTOR(Class*, Classes) - VECTOR(Template*, Templates) - VECTOR(TypedefDecl*, Typedefs) - VECTOR(TypeAlias*, TypeAliases) - VECTOR(Variable*, Variables) - VECTOR(Friend*, Friends) - - std::map anonymous; - - bool isAnonymous; - }; - - class CS_API TypedefNameDecl : public Declaration - { - public: - TypedefNameDecl(DeclarationKind kind); - ~TypedefNameDecl(); - QualifiedType qualifiedType; - }; - - class CS_API TypedefDecl : public TypedefNameDecl - { - public: - DECLARE_DECL_KIND(TypedefDecl, Typedef) - ~TypedefDecl(); - }; - - class CS_API TypeAlias : public TypedefNameDecl - { - public: - TypeAlias(); - ~TypeAlias(); - TypeAliasTemplate* describedAliasTemplate; - }; - - class CS_API Friend : public Declaration - { - public: - DECLARE_DECL_KIND(Friend, Friend) - ~Friend(); - Declaration* declaration; - }; - - enum class StatementClassObsolete - { - Any, - BinaryOperator, - CallExprClass, - DeclRefExprClass, - CXXConstructExprClass, - CXXOperatorCallExpr, - ImplicitCastExpr, - ExplicitCastExpr, - }; - - class CS_API StatementObsolete - { - public: - StatementObsolete(const std::string& str, StatementClassObsolete Class = StatementClassObsolete::Any, Declaration* decl = 0); - StatementClassObsolete _class; - Declaration* decl; - std::string string; - }; - - class CS_API ExpressionObsolete : public StatementObsolete - { - public: - ExpressionObsolete(const std::string& str, StatementClassObsolete Class = StatementClassObsolete::Any, Declaration* decl = 0); - }; - - class Expr; - - class CS_API BinaryOperatorObsolete : public ExpressionObsolete - { - public: - BinaryOperatorObsolete(const std::string& str, ExpressionObsolete* lhs, ExpressionObsolete* rhs, const std::string& opcodeStr); - ~BinaryOperatorObsolete(); - ExpressionObsolete* LHS; - ExpressionObsolete* RHS; - std::string opcodeStr; - }; - - class CS_API CallExprObsolete : public ExpressionObsolete - { - public: - CallExprObsolete(const std::string& str, Declaration* decl); - ~CallExprObsolete(); - VECTOR(ExpressionObsolete*, Arguments) - }; - - class CS_API CXXConstructExprObsolete : public ExpressionObsolete - { - public: - CXXConstructExprObsolete(const std::string& str, Declaration* decl = 0); - ~CXXConstructExprObsolete(); - VECTOR(ExpressionObsolete*, Arguments) - }; - - class CS_API Parameter : public Declaration - { - public: - Parameter(); - ~Parameter(); - - QualifiedType qualifiedType; - bool isIndirect; - bool hasDefaultValue; - unsigned int index; - ExpressionObsolete* defaultArgument; - Expr* defaultValue; - }; - - enum class CXXMethodKind - { - Normal, - Constructor, - Destructor, - Conversion, - Operator, - UsingDirective - }; - - enum class CXXOperatorKind - { - None, - New, - Delete, - Array_New, - Array_Delete, - Plus, - Minus, - Star, - Slash, - Percent, - Caret, - Amp, - Pipe, - Tilde, - Exclaim, - Equal, - Less, - Greater, - PlusEqual, - MinusEqual, - StarEqual, - SlashEqual, - PercentEqual, - CaretEqual, - AmpEqual, - PipeEqual, - LessLess, - GreaterGreater, - LessLessEqual, - GreaterGreaterEqual, - EqualEqual, - ExclaimEqual, - LessEqual, - GreaterEqual, - Spaceship, - AmpAmp, - PipePipe, - PlusPlus, - MinusMinus, - Comma, - ArrowStar, - Arrow, - Call, - Subscript, - Conditional, - Coawait - }; - - class FunctionTemplateSpecialization; - - enum class FriendKind - { - None, - Declared, - Undeclared - }; - - class Stmt; - - class CS_API Function : public DeclarationContext - { - public: - Function(); - ~Function(); - - QualifiedType returnType; - bool isReturnIndirect; - bool hasThisReturn; - - bool isConstExpr; - bool isVariadic; - bool isInline; - bool isPure; - bool isDeleted; - bool isDefaulted; - FriendKind friendKind; - CXXOperatorKind operatorKind; - std::string mangled; - std::string signature; - std::string body; - Stmt* bodyStmt; - CallingConvention callingConvention; - VECTOR(Parameter*, Parameters) - FunctionTemplateSpecialization* specializationInfo; - Function* instantiatedFrom; - QualifiedType qualifiedType; - }; - - class AccessSpecifierDecl; - - enum class RefQualifierKind - { - None, - LValue, - RValue - }; - - class CS_API Method : public Function - { - public: - Method(); - ~Method(); - - bool isVirtual; - bool isStatic; - bool isConst; - bool isExplicit; - bool isVolatile; - - CXXMethodKind methodKind; - - bool isDefaultConstructor; - bool isCopyConstructor; - bool isMoveConstructor; - - QualifiedType conversionType; - RefQualifierKind refQualifier; - VECTOR(Method*, OverriddenMethods) - }; - - class CS_API Enumeration : public DeclarationContext - { - public: - DECLARE_DECL_KIND(Enumeration, Enumeration) - ~Enumeration(); - - class CS_API Item : public Declaration - { - public: - DECLARE_DECL_KIND(Item, EnumerationItem) - Item(const Item&); - ~Item(); - std::string expression; - uint64_t value; - }; - - enum class CS_FLAGS EnumModifiers - { - Anonymous = 1 << 0, - Scoped = 1 << 1, - Flags = 1 << 2, - }; - - EnumModifiers modifiers; - Type* type; - BuiltinType* builtinType; - VECTOR(Item*, Items) - - Item* FindItemByName(const std::string& Name); - }; - - class CS_API Variable : public Declaration - { - public: - DECLARE_DECL_KIND(Variable, Variable) - ~Variable(); - bool isConstExpr; - std::string mangled; - QualifiedType qualifiedType; - ExpressionObsolete* initializer; - }; - - class PreprocessedEntity; - - struct CS_API BaseClassSpecifier - { - BaseClassSpecifier(); - AccessSpecifier access; - bool isVirtual; - Type* type; - int offset; - }; - - class Class; - - class CS_API Field : public Declaration - { - public: - DECLARE_DECL_KIND(Field, Field) - ~Field(); - QualifiedType qualifiedType; - Class* _class; - bool isBitField; - unsigned bitWidth; - }; - - class CS_API AccessSpecifierDecl : public Declaration - { - public: - DECLARE_DECL_KIND(AccessSpecifierDecl, AccessSpecifier) - ~AccessSpecifierDecl(); - }; - - enum class CppAbi - { - Itanium, - Microsoft, - ARM, - AArch64, - iOS, - AppleARM64, - WebAssembly - }; - - enum class VTableComponentKind - { - VCallOffset, - VBaseOffset, - OffsetToTop, - RTTI, - FunctionPointer, - CompleteDtorPointer, - DeletingDtorPointer, - UnusedFunctionPointer, - }; - - struct CS_API VTableComponent - { - VTableComponent(); - VTableComponentKind kind; - unsigned offset; - Declaration* declaration; - }; - - struct CS_API VTableLayout - { - VTableLayout(); - VTableLayout(const VTableLayout&); - ~VTableLayout(); - VECTOR(VTableComponent, Components) - }; - - struct CS_API VFTableInfo - { - VFTableInfo(); - VFTableInfo(const VFTableInfo&); - uint64_t VBTableIndex; - uint32_t VFPtrOffset; - uint32_t VFPtrFullOffset; - VTableLayout layout; - }; - - class CS_API LayoutField - { - public: - LayoutField(); - LayoutField(const LayoutField& other); - ~LayoutField(); - unsigned offset; - std::string name; - QualifiedType qualifiedType; - void* fieldPtr; - }; - - class Class; - - class CS_API LayoutBase - { - public: - LayoutBase(); - LayoutBase(const LayoutBase& other); - ~LayoutBase(); - unsigned offset; - Class* _class; - }; - - enum class RecordArgABI - { - /// Pass it using the normal C aggregate rules for the ABI, - /// potentially introducing extra copies and passing some - /// or all of it in registers. - Default = 0, - /// Pass it on the stack using its defined layout. - /// The argument must be evaluated directly into the correct - /// stack position in the arguments area, and the call machinery - /// must not move it or introduce extra copies. - DirectInMemory, - /// Pass it as a pointer to temporary memory. - Indirect - }; - - struct CS_API ClassLayout - { - ClassLayout(); - CppAbi ABI; - RecordArgABI argABI; - VECTOR(VFTableInfo, VFTables) - VTableLayout layout; - bool hasOwnVFPtr; - long VBPtrOffset; - int alignment; - int size; - int dataSize; - VECTOR(LayoutField, Fields) - VECTOR(LayoutBase, Bases) - }; - - class CS_API Class : public DeclarationContext - { - public: - Class(); - ~Class(); - - VECTOR(BaseClassSpecifier*, Bases) - VECTOR(Field*, Fields) - VECTOR(Method*, Methods) - VECTOR(AccessSpecifierDecl*, Specifiers) - - bool isPOD; - bool isAbstract; - bool isUnion; - bool isDynamic; - bool isPolymorphic; - bool hasNonTrivialDefaultConstructor; - bool hasNonTrivialCopyConstructor; - bool hasNonTrivialDestructor; - bool isExternCContext; - bool isInjected; - TagKind tagKind; - - ClassLayout* layout; - }; - - class CS_API Template : public Declaration - { - public: - Template(DeclarationKind kind); - DECLARE_DECL_KIND(Template, Template) - Declaration* TemplatedDecl; - VECTOR(Declaration*, Parameters) - }; - - template - T* DeclarationContext::FindTemplate(const std::string& USR) - { - auto foundTemplate = std::find_if(Templates.begin(), Templates.end(), - [&](Template* t) - { - return t->USR == USR; - }); - - if (foundTemplate != Templates.end()) - return static_cast(*foundTemplate); - - return nullptr; - } - - class CS_API TypeAliasTemplate : public Template - { - public: - TypeAliasTemplate(); - ~TypeAliasTemplate(); - - Declaration* CanonicalDecl = nullptr; - }; - - class CS_API TemplateParameter : public Declaration - { - public: - TemplateParameter(DeclarationKind kind); - ~TemplateParameter(); - unsigned int depth; - unsigned int index; - bool isParameterPack; - }; - - class CS_API TemplateTemplateParameter : public Template - { - public: - TemplateTemplateParameter(); - ~TemplateTemplateParameter(); - - bool isParameterPack; - bool isPackExpansion; - bool isExpandedParameterPack; - }; - - class CS_API TypeTemplateParameter : public TemplateParameter - { - public: - TypeTemplateParameter(); - TypeTemplateParameter(const TypeTemplateParameter&); - ~TypeTemplateParameter(); - - QualifiedType defaultArgument; - }; - - class CS_API NonTypeTemplateParameter : public TemplateParameter - { - public: - NonTypeTemplateParameter(); - NonTypeTemplateParameter(const NonTypeTemplateParameter&); - ~NonTypeTemplateParameter(); - ExpressionObsolete* defaultArgument; - Expr* defaultArgumentNew; - unsigned int position; - bool isPackExpansion; - bool isExpandedParameterPack; - QualifiedType type; - }; - - class ClassTemplateSpecialization; - class ClassTemplatePartialSpecialization; - - class CS_API ClassTemplate : public Template - { - public: - ClassTemplate(); - ~ClassTemplate(); - VECTOR(ClassTemplateSpecialization*, Specializations) - ClassTemplateSpecialization* FindSpecialization(const std::string& usr); - ClassTemplatePartialSpecialization* FindPartialSpecialization(const std::string& usr); - }; - - enum class TemplateSpecializationKind - { - Undeclared, - ImplicitInstantiation, - ExplicitSpecialization, - ExplicitInstantiationDeclaration, - ExplicitInstantiationDefinition - }; - - class CS_API ClassTemplateSpecialization : public Class - { - public: - ClassTemplateSpecialization(); - ~ClassTemplateSpecialization(); - ClassTemplate* templatedDecl; - VECTOR(TemplateArgument, Arguments) - TemplateSpecializationKind specializationKind; - }; - - class CS_API ClassTemplatePartialSpecialization : public ClassTemplateSpecialization - { - public: - ClassTemplatePartialSpecialization(); - ~ClassTemplatePartialSpecialization(); - VECTOR(Declaration*, Parameters) - }; - - class CS_API FunctionTemplate : public Template - { - public: - FunctionTemplate(); - ~FunctionTemplate(); - VECTOR(FunctionTemplateSpecialization*, Specializations) - FunctionTemplateSpecialization* FindSpecialization(const std::string& usr); - }; - - class CS_API FunctionTemplateSpecialization - { - public: - FunctionTemplateSpecialization(); - ~FunctionTemplateSpecialization(); - FunctionTemplate* _template; - VECTOR(TemplateArgument, Arguments) - Function* specializedFunction; - TemplateSpecializationKind specializationKind; - }; - - class VarTemplateSpecialization; - class VarTemplatePartialSpecialization; - - class CS_API VarTemplate : public Template - { - public: - VarTemplate(); - ~VarTemplate(); - VECTOR(VarTemplateSpecialization*, Specializations) - VarTemplateSpecialization* FindSpecialization(const std::string& usr); - VarTemplatePartialSpecialization* FindPartialSpecialization(const std::string& usr); - }; - - class CS_API VarTemplateSpecialization : public Variable - { - public: - VarTemplateSpecialization(); - ~VarTemplateSpecialization(); - VarTemplate* templatedDecl; - VECTOR(TemplateArgument, Arguments) - TemplateSpecializationKind specializationKind; - }; - - class CS_API VarTemplatePartialSpecialization : public VarTemplateSpecialization - { - public: - VarTemplatePartialSpecialization(); - ~VarTemplatePartialSpecialization(); - }; - - class CS_API UnresolvedUsingTypename : public Declaration - { - public: - UnresolvedUsingTypename(); - ~UnresolvedUsingTypename(); - }; - - class CS_API Namespace : public DeclarationContext - { - public: - Namespace(); - ~Namespace(); - bool isInline; - }; - - enum class MacroLocation - { - Unknown, - ClassHead, - ClassBody, - FunctionHead, - FunctionParameters, - FunctionBody, - }; - - class CS_API PreprocessedEntity - { - public: - PreprocessedEntity(); - MacroLocation macroLocation; - void* originalPtr; - DeclarationKind kind; - }; - - class CS_API MacroDefinition : public PreprocessedEntity - { - public: - MacroDefinition(); - ~MacroDefinition(); - std::string name; +enum class AccessSpecifier +{ + Private, + Protected, + Public +}; + +class DeclarationContext; +class RawComment; +class PreprocessedEntity; + +class ExpressionObsolete; +class CS_API Declaration +{ +public: + Declaration(DeclarationKind kind); + Declaration(const Declaration&); + ~Declaration(); + + DeclarationKind kind; + int alignAs; + int maxFieldAlignment; + AccessSpecifier access; + DeclarationContext* _namespace; + SourceLocation location; + int lineNumberStart; + int lineNumberEnd; + std::string name; + std::string USR; + std::string debugText; + bool isIncomplete; + bool isDependent; + bool isImplicit; + bool isInvalid; + bool isDeprecated; + Declaration* completeDeclaration; + unsigned definitionOrder; + VECTOR(PreprocessedEntity*, PreprocessedEntities) + VECTOR(Declaration*, Redeclarations) + void* originalPtr; + RawComment* comment; +}; + +class Class; +class Enumeration; +class Function; +class TypedefDecl; +class TypeAlias; +class Namespace; +class Template; +class TypeAliasTemplate; +class ClassTemplate; +class FunctionTemplate; +class Variable; +class Friend; + +class CS_API DeclarationContext : public Declaration +{ +public: + DeclarationContext(DeclarationKind kind); + + CS_IGNORE Declaration* FindAnonymous(const std::string& USR); + + CS_IGNORE Namespace* FindNamespace(const std::string& Name); + CS_IGNORE Namespace* FindNamespace(const std::vector&); + CS_IGNORE Namespace* FindCreateNamespace(const std::string& Name); + + CS_IGNORE Class* CreateClass(const std::string& Name, bool IsComplete); + CS_IGNORE Class* FindClass(const void* OriginalPtr, const std::string& Name, bool IsComplete); + CS_IGNORE Class* FindClass(const void* OriginalPtr, const std::string& Name, bool IsComplete, bool Create); + + CS_IGNORE template + T* FindTemplate(const std::string& USR); + + CS_IGNORE Enumeration* FindEnum(const void* OriginalPtr); + CS_IGNORE Enumeration* FindEnum(const std::string& Name, bool Create = false); + CS_IGNORE Enumeration* FindEnumWithItem(const std::string& Name); + + CS_IGNORE Function* FindFunction(const std::string& USR); + + CS_IGNORE TypedefDecl* FindTypedef(const std::string& Name, bool Create = false); + + CS_IGNORE TypeAlias* FindTypeAlias(const std::string& Name, bool Create = false); + + CS_IGNORE Variable* FindVariable(const std::string& USR); + + CS_IGNORE Friend* FindFriend(const std::string& USR); + + VECTOR(Namespace*, Namespaces) + VECTOR(Enumeration*, Enums) + VECTOR(Function*, Functions) + VECTOR(Class*, Classes) + VECTOR(Template*, Templates) + VECTOR(TypedefDecl*, Typedefs) + VECTOR(TypeAlias*, TypeAliases) + VECTOR(Variable*, Variables) + VECTOR(Friend*, Friends) + + std::map anonymous; + + bool isAnonymous; +}; + +class CS_API TypedefNameDecl : public Declaration +{ +public: + TypedefNameDecl(DeclarationKind kind); + ~TypedefNameDecl(); + QualifiedType qualifiedType; +}; + +class CS_API TypedefDecl : public TypedefNameDecl +{ +public: + DECLARE_DECL_KIND(TypedefDecl, Typedef) + ~TypedefDecl(); +}; + +class CS_API TypeAlias : public TypedefNameDecl +{ +public: + TypeAlias(); + ~TypeAlias(); + TypeAliasTemplate* describedAliasTemplate; +}; + +class CS_API Friend : public Declaration +{ +public: + DECLARE_DECL_KIND(Friend, Friend) + ~Friend(); + Declaration* declaration; +}; + +enum class StatementClassObsolete +{ + Any, + BinaryOperator, + CallExprClass, + DeclRefExprClass, + CXXConstructExprClass, + CXXOperatorCallExpr, + ImplicitCastExpr, + ExplicitCastExpr, +}; + +class CS_API StatementObsolete +{ +public: + StatementObsolete(const std::string& str, StatementClassObsolete Class = StatementClassObsolete::Any, Declaration* decl = 0); + StatementClassObsolete _class; + Declaration* decl; + std::string string; +}; + +class CS_API ExpressionObsolete : public StatementObsolete +{ +public: + ExpressionObsolete(const std::string& str, StatementClassObsolete Class = StatementClassObsolete::Any, Declaration* decl = 0); +}; + +class Expr; + +class CS_API BinaryOperatorObsolete : public ExpressionObsolete +{ +public: + BinaryOperatorObsolete(const std::string& str, ExpressionObsolete* lhs, ExpressionObsolete* rhs, const std::string& opcodeStr); + ~BinaryOperatorObsolete(); + ExpressionObsolete* LHS; + ExpressionObsolete* RHS; + std::string opcodeStr; +}; + +class CS_API CallExprObsolete : public ExpressionObsolete +{ +public: + CallExprObsolete(const std::string& str, Declaration* decl); + ~CallExprObsolete(); + VECTOR(ExpressionObsolete*, Arguments) +}; + +class CS_API CXXConstructExprObsolete : public ExpressionObsolete +{ +public: + CXXConstructExprObsolete(const std::string& str, Declaration* decl = 0); + ~CXXConstructExprObsolete(); + VECTOR(ExpressionObsolete*, Arguments) +}; + +class CS_API Parameter : public Declaration +{ +public: + Parameter(); + ~Parameter(); + + QualifiedType qualifiedType; + bool isIndirect; + bool hasDefaultValue; + unsigned int index; + ExpressionObsolete* defaultArgument; + Expr* defaultValue; +}; + +enum class CXXMethodKind +{ + Normal, + Constructor, + Destructor, + Conversion, + Operator, + UsingDirective +}; + +enum class CXXOperatorKind +{ + None, + New, + Delete, + Array_New, + Array_Delete, + Plus, + Minus, + Star, + Slash, + Percent, + Caret, + Amp, + Pipe, + Tilde, + Exclaim, + Equal, + Less, + Greater, + PlusEqual, + MinusEqual, + StarEqual, + SlashEqual, + PercentEqual, + CaretEqual, + AmpEqual, + PipeEqual, + LessLess, + GreaterGreater, + LessLessEqual, + GreaterGreaterEqual, + EqualEqual, + ExclaimEqual, + LessEqual, + GreaterEqual, + Spaceship, + AmpAmp, + PipePipe, + PlusPlus, + MinusMinus, + Comma, + ArrowStar, + Arrow, + Call, + Subscript, + Conditional, + Coawait +}; + +class FunctionTemplateSpecialization; + +enum class FriendKind +{ + None, + Declared, + Undeclared +}; + +class Stmt; + +class CS_API Function : public DeclarationContext +{ +public: + Function(); + ~Function(); + + QualifiedType returnType; + bool isReturnIndirect; + bool hasThisReturn; + + bool isConstExpr; + bool isVariadic; + bool isInline; + bool isPure; + bool isDeleted; + bool isDefaulted; + FriendKind friendKind; + CXXOperatorKind operatorKind; + std::string mangled; + std::string signature; + std::string body; + Stmt* bodyStmt; + CallingConvention callingConvention; + VECTOR(Parameter*, Parameters) + FunctionTemplateSpecialization* specializationInfo; + Function* instantiatedFrom; + QualifiedType qualifiedType; +}; + +class AccessSpecifierDecl; + +enum class RefQualifierKind +{ + None, + LValue, + RValue +}; + +class CS_API Method : public Function +{ +public: + Method(); + ~Method(); + + bool isVirtual; + bool isStatic; + bool isConst; + bool isExplicit; + bool isVolatile; + + CXXMethodKind methodKind; + + bool isDefaultConstructor; + bool isCopyConstructor; + bool isMoveConstructor; + + QualifiedType conversionType; + RefQualifierKind refQualifier; + VECTOR(Method*, OverriddenMethods) +}; + +class CS_API Enumeration : public DeclarationContext +{ +public: + DECLARE_DECL_KIND(Enumeration, Enumeration) + ~Enumeration(); + + class CS_API Item : public Declaration + { + public: + DECLARE_DECL_KIND(Item, EnumerationItem) + Item(const Item&); + ~Item(); std::string expression; - int lineNumberStart; - int lineNumberEnd; - }; - - class CS_API MacroExpansion : public PreprocessedEntity - { - public: - MacroExpansion(); - ~MacroExpansion(); - std::string name; - std::string text; - MacroDefinition* definition; - }; - - class CS_API TranslationUnit : public Namespace - { - public: - TranslationUnit(); - ~TranslationUnit(); - std::string fileName; - bool isSystemHeader; - VECTOR(MacroDefinition*, Macros) - }; - - class CS_API ASTContext - { - public: - ASTContext(); - ~ASTContext(); - TranslationUnit* FindOrCreateModule(const std::string& File); - VECTOR(TranslationUnit*, TranslationUnits) - }; - -} + uint64_t value; + }; + + enum class CS_FLAGS EnumModifiers + { + Anonymous = 1 << 0, + Scoped = 1 << 1, + Flags = 1 << 2, + }; + + EnumModifiers modifiers; + Type* type; + BuiltinType* builtinType; + VECTOR(Item*, Items) + + Item* FindItemByName(const std::string& Name); +}; + +class CS_API Variable : public Declaration +{ +public: + DECLARE_DECL_KIND(Variable, Variable) + ~Variable(); + bool isConstExpr; + std::string mangled; + QualifiedType qualifiedType; + ExpressionObsolete* initializer; +}; + +class PreprocessedEntity; + +struct CS_API BaseClassSpecifier +{ + BaseClassSpecifier(); + AccessSpecifier access; + bool isVirtual; + Type* type; + int offset; +}; + +class Class; + +class CS_API Field : public Declaration +{ +public: + DECLARE_DECL_KIND(Field, Field) + ~Field(); + QualifiedType qualifiedType; + Class* _class; + bool isBitField; + unsigned bitWidth; +}; + +class CS_API AccessSpecifierDecl : public Declaration +{ +public: + DECLARE_DECL_KIND(AccessSpecifierDecl, AccessSpecifier) + ~AccessSpecifierDecl(); +}; + +enum class CppAbi +{ + Itanium, + Microsoft, + ARM, + AArch64, + iOS, + AppleARM64, + WebAssembly +}; + +enum class VTableComponentKind +{ + VCallOffset, + VBaseOffset, + OffsetToTop, + RTTI, + FunctionPointer, + CompleteDtorPointer, + DeletingDtorPointer, + UnusedFunctionPointer, +}; + +struct CS_API VTableComponent +{ + VTableComponent(); + VTableComponentKind kind; + unsigned offset; + Declaration* declaration; +}; + +struct CS_API VTableLayout +{ + VTableLayout(); + VTableLayout(const VTableLayout&); + ~VTableLayout(); + VECTOR(VTableComponent, Components) +}; + +struct CS_API VFTableInfo +{ + VFTableInfo(); + VFTableInfo(const VFTableInfo&); + uint64_t VBTableIndex; + uint32_t VFPtrOffset; + uint32_t VFPtrFullOffset; + VTableLayout layout; +}; + +class CS_API LayoutField +{ +public: + LayoutField(); + LayoutField(const LayoutField& other); + ~LayoutField(); + unsigned offset; + std::string name; + QualifiedType qualifiedType; + void* fieldPtr; +}; + +class Class; + +class CS_API LayoutBase +{ +public: + LayoutBase(); + LayoutBase(const LayoutBase& other); + ~LayoutBase(); + unsigned offset; + Class* _class; +}; + +enum class RecordArgABI +{ + /// Pass it using the normal C aggregate rules for the ABI, + /// potentially introducing extra copies and passing some + /// or all of it in registers. + Default = 0, + /// Pass it on the stack using its defined layout. + /// The argument must be evaluated directly into the correct + /// stack position in the arguments area, and the call machinery + /// must not move it or introduce extra copies. + DirectInMemory, + /// Pass it as a pointer to temporary memory. + Indirect +}; + +struct CS_API ClassLayout +{ + ClassLayout(); + CppAbi ABI; + RecordArgABI argABI; + VECTOR(VFTableInfo, VFTables) + VTableLayout layout; + bool hasOwnVFPtr; + long VBPtrOffset; + int alignment; + int size; + int dataSize; + VECTOR(LayoutField, Fields) + VECTOR(LayoutBase, Bases) +}; + +class CS_API Class : public DeclarationContext +{ +public: + Class(); + ~Class(); + + VECTOR(BaseClassSpecifier*, Bases) + VECTOR(Field*, Fields) + VECTOR(Method*, Methods) + VECTOR(AccessSpecifierDecl*, Specifiers) + + bool isPOD; + bool isAbstract; + bool isUnion; + bool isDynamic; + bool isPolymorphic; + bool hasNonTrivialDefaultConstructor; + bool hasNonTrivialCopyConstructor; + bool hasNonTrivialDestructor; + bool isExternCContext; + bool isInjected; + TagKind tagKind; + + ClassLayout* layout; +}; + +class CS_API Template : public Declaration +{ +public: + Template(DeclarationKind kind); + DECLARE_DECL_KIND(Template, Template) + Declaration* TemplatedDecl; + VECTOR(Declaration*, Parameters) +}; + +template +T* DeclarationContext::FindTemplate(const std::string& USR) +{ + auto foundTemplate = std::find_if(Templates.begin(), Templates.end(), + [&](Template* t) + { + return t->USR == USR; + }); + + if (foundTemplate != Templates.end()) + return static_cast(*foundTemplate); + + return nullptr; } + +class CS_API TypeAliasTemplate : public Template +{ +public: + TypeAliasTemplate(); + ~TypeAliasTemplate(); + + Declaration* CanonicalDecl = nullptr; +}; + +class CS_API TemplateParameter : public Declaration +{ +public: + TemplateParameter(DeclarationKind kind); + ~TemplateParameter(); + unsigned int depth; + unsigned int index; + bool isParameterPack; +}; + +class CS_API TemplateTemplateParameter : public Template +{ +public: + TemplateTemplateParameter(); + ~TemplateTemplateParameter(); + + bool isParameterPack; + bool isPackExpansion; + bool isExpandedParameterPack; +}; + +class CS_API TypeTemplateParameter : public TemplateParameter +{ +public: + TypeTemplateParameter(); + TypeTemplateParameter(const TypeTemplateParameter&); + ~TypeTemplateParameter(); + + QualifiedType defaultArgument; +}; + +class CS_API NonTypeTemplateParameter : public TemplateParameter +{ +public: + NonTypeTemplateParameter(); + NonTypeTemplateParameter(const NonTypeTemplateParameter&); + ~NonTypeTemplateParameter(); + ExpressionObsolete* defaultArgument; + Expr* defaultArgumentNew; + unsigned int position; + bool isPackExpansion; + bool isExpandedParameterPack; + QualifiedType type; +}; + +class ClassTemplateSpecialization; +class ClassTemplatePartialSpecialization; + +class CS_API ClassTemplate : public Template +{ +public: + ClassTemplate(); + ~ClassTemplate(); + VECTOR(ClassTemplateSpecialization*, Specializations) + ClassTemplateSpecialization* FindSpecialization(const std::string& usr); + ClassTemplatePartialSpecialization* FindPartialSpecialization(const std::string& usr); +}; + +enum class TemplateSpecializationKind +{ + Undeclared, + ImplicitInstantiation, + ExplicitSpecialization, + ExplicitInstantiationDeclaration, + ExplicitInstantiationDefinition +}; + +class CS_API ClassTemplateSpecialization : public Class +{ +public: + ClassTemplateSpecialization(); + ~ClassTemplateSpecialization(); + ClassTemplate* templatedDecl; + VECTOR(TemplateArgument, Arguments) + TemplateSpecializationKind specializationKind; +}; + +class CS_API ClassTemplatePartialSpecialization : public ClassTemplateSpecialization +{ +public: + ClassTemplatePartialSpecialization(); + ~ClassTemplatePartialSpecialization(); + VECTOR(Declaration*, Parameters) +}; + +class CS_API FunctionTemplate : public Template +{ +public: + FunctionTemplate(); + ~FunctionTemplate(); + VECTOR(FunctionTemplateSpecialization*, Specializations) + FunctionTemplateSpecialization* FindSpecialization(const std::string& usr); +}; + +class CS_API FunctionTemplateSpecialization +{ +public: + FunctionTemplateSpecialization(); + ~FunctionTemplateSpecialization(); + FunctionTemplate* _template; + VECTOR(TemplateArgument, Arguments) + Function* specializedFunction; + TemplateSpecializationKind specializationKind; +}; + +class VarTemplateSpecialization; +class VarTemplatePartialSpecialization; + +class CS_API VarTemplate : public Template +{ +public: + VarTemplate(); + ~VarTemplate(); + VECTOR(VarTemplateSpecialization*, Specializations) + VarTemplateSpecialization* FindSpecialization(const std::string& usr); + VarTemplatePartialSpecialization* FindPartialSpecialization(const std::string& usr); +}; + +class CS_API VarTemplateSpecialization : public Variable +{ +public: + VarTemplateSpecialization(); + ~VarTemplateSpecialization(); + VarTemplate* templatedDecl; + VECTOR(TemplateArgument, Arguments) + TemplateSpecializationKind specializationKind; +}; + +class CS_API VarTemplatePartialSpecialization : public VarTemplateSpecialization +{ +public: + VarTemplatePartialSpecialization(); + ~VarTemplatePartialSpecialization(); +}; + +class CS_API UnresolvedUsingTypename : public Declaration +{ +public: + UnresolvedUsingTypename(); + ~UnresolvedUsingTypename(); +}; + +class CS_API Namespace : public DeclarationContext +{ +public: + Namespace(); + ~Namespace(); + bool isInline; +}; + +enum class MacroLocation +{ + Unknown, + ClassHead, + ClassBody, + FunctionHead, + FunctionParameters, + FunctionBody, +}; + +class CS_API PreprocessedEntity +{ +public: + PreprocessedEntity(); + MacroLocation macroLocation; + void* originalPtr; + DeclarationKind kind; +}; + +class CS_API MacroDefinition : public PreprocessedEntity +{ +public: + MacroDefinition(); + ~MacroDefinition(); + std::string name; + std::string expression; + int lineNumberStart; + int lineNumberEnd; +}; + +class CS_API MacroExpansion : public PreprocessedEntity +{ +public: + MacroExpansion(); + ~MacroExpansion(); + std::string name; + std::string text; + MacroDefinition* definition; +}; + +class CS_API TranslationUnit : public Namespace +{ +public: + TranslationUnit(); + + std::string fileName; + bool isSystemHeader; + VECTOR(MacroDefinition*, Macros) +}; + +class CS_API ASTContext +{ +public: + ASTContext(); + ~ASTContext(); + TranslationUnit* FindOrCreateModule(const std::string& File); + VECTOR(TranslationUnit*, TranslationUnits) +}; } // namespace CppSharp::CppParser::AST \ No newline at end of file From f81f8e6f1f2dbe2806e148ae02c8cafecc4893d5 Mon Sep 17 00:00:00 2001 From: duckdoom5 Date: Thu, 27 Feb 2025 17:24:58 +0100 Subject: [PATCH 9/9] Create Declaration.h --- src/CppParser/Declaration.h | 2191 +++++++++++++++++++++++++++++++++++ 1 file changed, 2191 insertions(+) create mode 100644 src/CppParser/Declaration.h diff --git a/src/CppParser/Declaration.h b/src/CppParser/Declaration.h new file mode 100644 index 000000000..1d1ff9a64 --- /dev/null +++ b/src/CppParser/Declaration.h @@ -0,0 +1,2191 @@ +// ---------------------------------------------------------------------------- +// +// This is autogenerated code by CppSharp. +// Do not edit this file or all your changes will be lost after re-generation. +// +// ---------------------------------------------------------------------------- + +#pragma once + +#include "Sources.h" +#include "Types.h" +#include + +namespace CppSharp::CppParser::AST { + +class Expr; +class Stmt; +class LabelStmt; +class EvaluatedStmt; +class CompoundStmt; +enum class OverloadedOperatorKind; + +class Decl; +class UsingDirectiveDecl; +class FriendDecl; +class ConstructorUsingShadowDecl; +class LinkageSpecDecl; +class NamedDecl; +class NamespaceDecl; +class TemplateDecl; +class ClassTemplateDecl; +class VarTemplateDecl; +class TypeAliasTemplateDecl; +class FunctionDecl; +class FunctionTemplateDecl; +class CXXMethodDecl; +class CXXConstructorDecl; +class CXXDestructorDecl; +class BaseUsingDecl; + +/// Lists the kind of concrete classes of Decl. +enum class DeclarationKind +{ + AccessSpec = 0, + Block = 1, + Captured = 2, + ClassScopeFunctionSpecialization = 3, + Empty = 4, + Export = 5, + ExternCContext = 6, + FileScopeAsm = 7, + Friend = 8, + FriendTemplate = 9, + ImplicitConceptSpecialization = 10, + Import = 11, + LifetimeExtendedTemporary = 12, + LinkageSpec = 13, + Using = 14, + UsingEnum = 15, + HLSLBuffer = 16, + Label = 17, + Namespace = 18, + NamespaceAlias = 19, + BuiltinTemplate = 28, + Concept = 29, + ClassTemplate = 30, + FunctionTemplate = 31, + TypeAliasTemplate = 32, + VarTemplate = 33, + TemplateTemplateParm = 34, + Enum = 35, + Record = 36, + CXXRecord = 37, + ClassTemplateSpecialization = 38, + ClassTemplatePartialSpecialization = 39, + TemplateTypeParm = 40, + TypeAlias = 42, + Typedef = 43, + UnresolvedUsingTypename = 44, + UnresolvedUsingIfExists = 45, + UsingDirective = 46, + UsingPack = 47, + UsingShadow = 48, + ConstructorUsingShadow = 49, + Binding = 50, + Field = 51, + Function = 54, + CXXDeductionGuide = 55, + CXXMethod = 56, + CXXConstructor = 57, + CXXConversion = 58, + CXXDestructor = 59, + MSProperty = 60, + NonTypeTemplateParm = 61, + Var = 62, + Decomposition = 63, + ImplicitParam = 64, + ParmVar = 66, + VarTemplateSpecialization = 67, + VarTemplatePartialSpecialization = 68, + EnumConstant = 69, + IndirectField = 70, + MSGuid = 71, + TemplateParamObject = 74, + UnnamedGlobalConstant = 75, + UnresolvedUsingValue = 76, + PragmaComment = 81, + PragmaDetectMismatch = 82, + RequiresExprBody = 83, + StaticAssert = 84, + TopLevelStmt = 85, + TranslationUnit = 86, +}; + +enum class MultiVersionKind +{ + None = 0, + Target = 1, + CPUSpecific = 2, + CPUDispatch = 3, + TargetClones = 4, + TargetVersion = 5 +}; + +/// Define the meaning of possible values of the kind in ExplicitSpecifier. +enum class ExplicitSpecKind : unsigned int +{ + ResolvedFalse = 0, + ResolvedTrue = 1, + Unresolved = 2 +}; + +class CS_API ExplicitSpecifier +{ +public: + ExplicitSpecifier(); + ExplicitSpecKind kind; + Expr* expr; + bool isSpecified; + bool isExplicit; + bool isInvalid; +}; + +class CS_API InheritedConstructor +{ +public: + InheritedConstructor(); + ConstructorUsingShadowDecl* shadowDecl; + CXXConstructorDecl* constructor; +}; + +/// +/// A C++ access specifier (public, private, protected), plus the +/// special value "none" which means different things in different contexts. +/// +enum class AccessSpecifier +{ + Public = 0, + Protected = 1, + Private = 2, + None = 3 +}; + +/// Storage classes. +enum class StorageClass +{ + None = 0, + Extern = 1, + Static = 2, + PrivateExtern = 3, + Auto = 4, + Register = 5 +}; + +/// Thread storage-class-specifier. +enum class ThreadStorageClassSpecifier +{ + Unspecified = 0, + /// GNU __thread. + Thread = 1, + /// + /// C++11 thread_local. Implies 'static' at block scope, but not at + /// class scope. + /// + ThreadLocal = 2, + /// + /// C11 _Thread_local. Must be combined with either 'static' or 'extern' + /// if used at block scope. + /// + ThreadLocal = 3 +}; + +/// +/// Describes the kind of template specialization that a +/// particular template specialization declaration represents. +/// +enum class TemplateSpecializationKind +{ + /// + /// This template specialization was formed from a template-id but + /// has not yet been declared, defined, or instantiated. + /// + Undeclared = 0, + /// + /// This template specialization was implicitly instantiated from a + /// template. (C++ [temp.inst]). + /// + ImplicitInstantiation = 1, + /// + /// This template specialization was declared or defined by an + /// explicit specialization (C++ [temp.expl.spec]) or partial + /// specialization (C++ [temp.class.spec]). + /// + ExplicitSpecialization = 2, + /// + /// This template specialization was instantiated from a template + /// due to an explicit instantiation declaration request + /// (C++11 [temp.explicit]). + /// + ExplicitInstantiationDeclaration = 3, + /// + /// This template specialization was instantiated from a template + /// due to an explicit instantiation definition request + /// (C++ [temp.explicit]). + /// + ExplicitInstantiationDefinition = 4 +}; + +/// Kinds of BuiltinTemplateDecl. +enum class BuiltinTemplateKind +{ + /// This names the __make_integer_seq BuiltinTemplateDecl. + BTK__make_integer_seq = 0, + /// This names the __type_pack_element BuiltinTemplateDecl. + BTK__type_pack_element = 1 +}; + +/// In-class initialization styles for non-static data members. +enum class InClassInitStyle +{ + /// No in-class initializer. + NoInit = 0, + /// Copy initialization. + CopyInit = 1, + /// Direct list-initialization. + ListInit = 2 +}; + +/// Define the kind of constexpr specifier. +enum class ConstexprSpecKind +{ + Unspecified = 0, + Constexpr = 1, + Consteval = 2, + Constinit = 3 +}; + +/// +/// Describes the different kinds of linkage +/// (C++ [basic.link], C99 6.2.2) that an entity may have. +/// +enum class Linkage : unsigned char +{ + /// + /// No linkage, which means that the entity is unique and + /// can only be referred to from within its scope. + /// + NoLinkage = 0, + /// + /// Internal linkage, which indicates that the entity can + /// be referred to from within the translation unit (but not other + /// translation units). + /// + InternalLinkage = 1, + /// External linkage within a unique namespace. + /// + /// From the language perspective, these entities have external + /// linkage. However, since they reside in an anonymous namespace, + /// their names are unique to this translation unit, which is + /// equivalent to having internal linkage from the code-generation + /// point of view. + /// + UniqueExternalLinkage = 2, + /// + /// No linkage according to the standard, but is visible from other + /// translation units because of types defined in a inline function. + /// + VisibleNoLinkage = 3, + /// + /// Module linkage, which indicates that the entity can be referred + /// to from other translation units within the same module, and indirectly + /// from arbitrary other translation units through inline functions and + /// templates in the module interface. + /// + ModuleLinkage = 4, + /// + /// External linkage, which indicates that the entity can + /// be referred to from other translation units. + /// + ExternalLinkage = 5 +}; + +/// +/// Describes the different kinds of language linkage +/// (C++ [dcl.link]) that an entity may have. +/// +enum class LanguageLinkage +{ + CLanguageLinkage = 0, + CXXLanguageLinkage = 1, + NoLanguageLinkage = 2 +}; + +/// +/// Describes the different kinds of visibility that a declaration +/// may have. +/// +/// +/// Visibility determines how a declaration interacts with the dynamic +/// linker. It may also affect whether the symbol can be found by runtime +/// symbol lookup APIs. +/// Visibility is not described in any language standard and +/// (nonetheless) sometimes has odd behavior. Not all platforms +/// support all visibility kinds. +/// +enum class Visibility +{ + /// + /// Objects with "hidden" visibility are not seen by the dynamic + /// linker. + /// + HiddenVisibility = 0, + /// + /// Objects with "protected" visibility are seen by the dynamic + /// linker but always dynamically resolve to an object within this + /// shared object. + /// + ProtectedVisibility = 1, + /// + /// Objects with "default" visibility are seen by the dynamic linker + /// and act like normal objects. + /// + DefaultVisibility = 2 +}; + +class CS_API LinkageInfo +{ +public: + LinkageInfo(); + Linkage linkage; + Visibility visibility; + bool isVisibilityExplicit; +}; + +enum class PragmaMSCommentKind +{ + Unknown = 0, + Linker = 1, + Lib = 2, + Compiler = 3, + ExeStr = 4, + User = 5 +}; + +/// The various types of exception specifications that exist in C++11. +enum class ExceptionSpecificationType +{ + /// no exception specification + None = 0, + /// throw() + DynamicNone = 1, + /// throw(T1, T2) + Dynamic = 2, + /// Microsoft throw(...) extension + MSAny = 3, + /// Microsoft __declspec(nothrow) extension + NoThrow = 4, + /// noexcept + BasicNoexcept = 5, + /// noexcept(expression), value-dependent + DependentNoexcept = 6, + /// noexcept(expression), evals to 'false' + NoexceptFalse = 7, + /// noexcept(expression), evals to 'true' + NoexceptTrue = 8, + /// not evaluated yet, for special member function + Unevaluated = 9, + /// not instantiated yet + Uninstantiated = 10, + /// not parsed yet + Unparsed = 11 +}; + +class CS_API DeclContext +{ +public: + DeclContext(); + VECTOR(Decl*, decls) + VECTOR(Decl*, noload_decls) + VECTOR(all_lookups_iterator*, lookups) + VECTOR(all_lookups_iterator*, noload_lookups) + VECTOR(UsingDirectiveDecl*, using_directives) + VECTOR(ddiag_iterator*, ddiags) + bool hasValidDeclKind; + DeclarationKind declKind; + bool isClosure; + BlockDecl* innermostBlockDecl; + bool isObjCContainer; + bool isFunctionOrMethod; + bool isLookupContext; + bool isFileContext; + bool isTranslationUnit; + bool isRecord; + bool isNamespace; + bool isStdNamespace; + bool isInlineNamespace; + bool isDependentContext; + bool isTransparentContext; + bool isExternCContext; + LinkageSpecDecl* externCContext; + bool isExternCXXContext; + bool hasExternalLexicalStorage; + bool hasExternalVisibleStorage; +}; + +class CS_API Redeclarable +{ +public: + Redeclarable(); + VECTOR(Decl*, redecls) + Decl* previousDecl; + bool isFirstDecl; +}; + +class CS_API Mergeable +{ +public: + Mergeable(); + bool isFirstDecl; +}; + +class CS_API MemberSpecializationInfo +{ +public: + MemberSpecializationInfo(); + NamedDecl* instantiatedFrom; + TemplateSpecializationKind templateSpecializationKind; + bool isExplicitSpecialization; + SourceLocation pointOfInstantiation; +}; + +class CS_API FunctionTemplateSpecializationInfo +{ +public: + FunctionTemplateSpecializationInfo(); + FunctionDecl* function; + FunctionTemplateDecl* _template; + TemplateSpecializationKind templateSpecializationKind; + bool isExplicitSpecialization; + bool isExplicitInstantiationOrSpecialization; + SourceLocation pointOfInstantiation; + MemberSpecializationInfo* memberSpecializationInfo; +}; + +class CS_API DependentFunctionTemplateSpecializationInfo +{ +public: + DependentFunctionTemplateSpecializationInfo(); + unsigned int numTemplates; + TemplateArgumentLoc* templateArgs; + unsigned int numTemplateArgs; + ArrayRef arguments; + SourceLocation lAngleLoc; + SourceLocation rAngleLoc; +}; + +class CS_API ASTTemplateArgumentListInfo +{ +public: + ASTTemplateArgumentListInfo(); + SourceLocation lAngleLoc; + SourceLocation rAngleLoc; + TemplateArgumentLoc* templateArgs; + unsigned int numTemplateArgs; + ArrayRef arguments; +}; + +class CS_API TemplateParmPosition +{ +public: + TemplateParmPosition(); + unsigned int depth; + unsigned int position; + unsigned int index; +}; + +/// Only used by CXXDeductionGuideDecl. +enum class DeductionCandidate : unsigned char +{ + Normal = 0, + Copy = 1, + Aggregate = 2 +}; + +/// +/// The kind of C++11 ref-qualifier associated with a function type. +/// This determines whether a member function's "this" object can be an +/// lvalue, rvalue, or neither. +/// +enum class RefQualifierKind +{ + /// No ref-qualifier was provided. + None = 0, + /// An lvalue ref-qualifier was provided ( + LValue = 1, + /// An rvalue ref-qualifier was provided ( + RValue = 2 +}; + +class CS_API Qualifiers +{ +public: + enum class TQ + { + Const = 1, + Restrict = 2, + Volatile = 4, + CVRMask = 7 + }; + + enum class GC + { + GCNone = 0, + Weak = 1, + Strong = 2 + }; + + enum class ObjCLifetime + { + /// There is no lifetime qualification on this type. + None = 0, + /// + /// This object can be modified without requiring retains or + /// releases. + /// + ExplicitNone = 1, + /// + /// Assigning into this object requires the old value to be + /// released and the new value to be retained. The timing of the + /// release of the old value is inexact: it may be moved to + /// immediately after the last known point where the value is + /// live. + /// + Strong = 2, + /// Reading or writing from this object requires a barrier call. + Weak = 3, + /// Assigning into this object requires a lifetime extension. + Autoreleasing = 4 + }; + + Qualifiers(); + unsigned int asOpaqueValue; + bool hasConst; + bool hasOnlyConst; + Qualifiers withConst; + bool hasVolatile; + bool hasOnlyVolatile; + Qualifiers withVolatile; + bool hasRestrict; + bool hasOnlyRestrict; + Qualifiers withRestrict; + bool hasCVRQualifiers; + unsigned int cVRQualifiers; + unsigned int cVRUQualifiers; + bool hasUnaligned; + bool hasObjCGCAttr; + GC objCGCAttr; + Qualifiers withoutObjCGCAttr; + Qualifiers withoutObjCLifetime; + Qualifiers withoutAddressSpace; + bool hasObjCLifetime; + ObjCLifetime objCLifetime; + bool hasNonTrivialObjCLifetime; + bool hasStrongOrWeakObjCLifetime; + bool hasAddressSpace; + LangAS addressSpace; + bool hasTargetSpecificAddressSpace; + unsigned int addressSpaceAttributePrintValue; + bool hasFastQualifiers; + unsigned int fastQualifiers; + bool hasNonFastQualifiers; + Qualifiers nonFastQualifiers; + bool hasQualifiers; + bool empty; + std::string asString; +}; + +class CS_API Decl +{ +public: + /// + /// The kind of ownership a declaration has, for visibility purposes. + /// This enumeration is designed such that higher values represent higher + /// levels of name hiding. + /// + enum class ModuleOwnershipKind : unsigned int + { + /// This declaration is not owned by a module. + Unowned = 0, + /// + /// This declaration has an owning module, but is globally visible + /// (typically because its owning module is visible and we know that + /// modules cannot later become hidden in this compilation). + /// After serialization and deserialization, this will be converted + /// to VisibleWhenImported. + /// + Visible = 1, + /// + /// This declaration has an owning module, and is visible when that + /// module is imported. + /// + VisibleWhenImported = 2, + /// + /// This declaration has an owning module, and is visible to lookups + /// that occurs within that module. And it is reachable in other module + /// when the owning module is transitively imported. + /// + ReachableWhenImported = 3, + /// + /// This declaration has an owning module, but is only visible to + /// lookups that occur within that module. + /// The discarded declarations in global module fragment belongs + /// to this group too. + /// + ModulePrivate = 4 + }; + + /// + /// IdentifierNamespace - The different namespaces in which + /// declarations may appear. According to C99 6.2.3, there are + /// four namespaces, labels, tags, members and ordinary + /// identifiers. C++ describes lookup completely differently: + /// certain lookups merely "ignore" certain kinds of declarations, + /// usually based on whether the declaration is of a type, etc. + /// + /// + /// These are meant as bitmasks, so that searches in + /// C++ can look into the "tag" namespace during ordinary lookup. + /// Decl currently provides 15 bits of IDNS bits. + /// + enum class IdentifierNamespace + { + /// Labels, declared with 'x:' and referenced with 'goto x'. + Label = 1, + /// + /// Tags, declared with 'struct foo;' and referenced with + /// 'struct foo'. All tags are also types. This is what + /// elaborated-type-specifiers look for in C. + /// This also contains names that conflict with tags in the + /// same scope but that are otherwise ordinary names (non-type + /// template parameters and indirect field declarations). + /// + Tag = 2, + /// + /// Types, declared with 'struct foo', typedefs, etc. + /// This is what elaborated-type-specifiers look for in C++, + /// but note that it's ill-formed to find a non-tag. + /// + Type = 4, + /// + /// Members, declared with object declarations within tag + /// definitions. In C, these can only be found by "qualified" + /// lookup in member expressions. In C++, they're found by + /// normal lookup. + /// + Member = 8, + /// + /// Namespaces, declared with 'namespace foo {}'. + /// Lookup for nested-name-specifiers find these. + /// + Namespace = 16, + /// + /// Ordinary names. In C, everything that's not a label, tag, + /// member, or function-local extern ends up here. + /// + Ordinary = 32, + /// Objective C@protocol. + ObjCProtocol = 64, + /// + /// This declaration is a friend function. A friend function + /// declaration is always in this namespace but may also be in + /// IDNS_Ordinary if it was previously declared. + /// + OrdinaryFriend = 128, + /// + /// This declaration is a friend class. A friend class + /// declaration is always in this namespace but may also be in + /// IDNS_Tag|IDNS_Type if it was previously declared. + /// + TagFriend = 256, + /// + /// This declaration is a using declaration. A using declaration + /// *introduces* a number of other declarations into the current + /// scope, and those declarations use the IDNS of their targets, + /// but the actual using declarations go in this namespace. + /// + Using = 512, + /// + /// This declaration is a C++ operator declared in a non-class + /// context. All such operators are also in IDNS_Ordinary. + /// C++ lexical operator lookup looks for these. + /// + NonMemberOperator = 1024, + /// + /// This declaration is a function-local extern declaration of a + /// variable or function. This may also be IDNS_Ordinary if it + /// has been declared outside any function. These act mostly like + /// invisible friend declarations, but are also visible to unqualified + /// lookup within the scope of the declaring function. + /// + LocalExtern = 2048, + /// This declaration is an OpenMP user defined reduction construction. + OMPReduction = 4096, + /// This declaration is an OpenMP user defined mapper. + OMPMapper = 8192 + }; + + /// + /// ObjCDeclQualifier - 'Qualifiers' written next to the return and + /// parameter types in method declarations. Other than remembering + /// them and mangling them into the method's signature string, these + /// are ignored by the compiler; they are consumed by certain + /// remote-messaging frameworks. + /// + /// + /// in, inout, and out are mutually exclusive and apply only to + /// method parameters. bycopy and byref are mutually exclusive and + /// apply only to method parameters (?). oneway applies only to + /// results. All of these expect their corresponding parameter to + /// have a particular type. None of this is currently enforced by + /// clang. + /// This should be kept in sync with ObjCDeclSpec::ObjCDeclQualifier. + /// + enum class ObjCDeclQualifier + { + TQ_None = 0, + TQ_In = 1, + TQ_Inout = 2, + TQ_Out = 4, + TQ_Bycopy = 8, + TQ_Byref = 16, + TQ_Oneway = 32, + /// + /// The nullability qualifier is set when the nullability of the + /// result or parameter was expressed via a context-sensitive + /// keyword. + /// + TQ_CSNullability = 64 + }; + + enum class FriendObjectKind + { + /// Not a friend object. + None = 0, + /// A friend of a previously-declared entity. + Declared = 1, + /// A friend of a previously-undeclared entity. + Undeclared = 2 + }; + + Decl(); + VECTOR(Decl*, redecls) + SourceRange sourceRange; + bool isOutOfLine; + bool hasBody; + Stmt* body; + SourceLocation location; + DeclarationKind kind; + bool isInAnonymousNamespace; + bool isInStdNamespace; + bool isFileContextDecl; + AccessSpecifier access; + AccessSpecifier accessUnsafe; + bool hasAttrs; + AttrVec& attrs; + T* attr; + bool hasAttr; + unsigned int maxAlignment; + bool invalidDecl; + bool implicit; + bool referenced; + bool isThisDeclarationReferenced; + bool topLevelDeclInObjCContainer; + ExternalSourceSymbolAttr* externalSourceSymbolAttr; + bool isInExportDeclContext; + bool hasDefiningAttr; + Attr* definingAttr; + bool isWeakImported; + bool isFromASTFile; + unsigned int globalID; + bool isUnconditionallyVisible; + bool isReachable; + unsigned int identifierNamespace; + bool hasTagIdentifierNamespace; + bool isTemplated; + unsigned int templateDepth; + bool isDefinedOutsideFunctionOrMethod; + bool isInLocalScopeForInstantiation; + bool isCanonicalDecl; + bool isFirstDecl; + SourceLocation bodyRBrace; + bool isTemplateParameter; + bool isTemplateParameterPack; + bool isParameterPack; + bool isTemplateDecl; + bool isFunctionOrFunctionTemplate; + TemplateDecl* describedTemplate; + VECTOR(NamedDecl*, describedTemplateParams) + bool isLocalExternDecl; + FriendObjectKind friendObjectKind; + int64_t iD; + bool isFunctionPointerType; +}; + +class CS_API TranslationUnitDecl : public Decl, public DeclContext, public Redeclarable +{ +public: + TranslationUnitDecl(); + NamespaceDecl* anonymousNamespace; +}; + +class CS_API PragmaCommentDecl : public Decl +{ +public: + PragmaCommentDecl(); + PragmaMSCommentKind commentKind; + std::string arg; +}; + +class CS_API PragmaDetectMismatchDecl : public Decl +{ +public: + PragmaDetectMismatchDecl(); + std::string name; + std::string value; +}; + +class CS_API ExternCContextDecl : public Decl, public DeclContext +{ +public: + ExternCContextDecl(); +}; + +class CS_API NamedDecl : public Decl +{ +public: + /// Kinds of explicit visibility. + enum class ExplicitVisibilityKind + { + /// + /// Do an LV computation for, ultimately, a type. + /// Visibility may be restricted by type visibility settings and + /// the visibility of template arguments. + /// + VisibilityForType = 0, + /// + /// Do an LV computation for, ultimately, a non-type declaration. + /// Visibility may be restricted by value visibility settings and + /// the visibility of template arguments. + /// + VisibilityForValue = 1 + }; + + NamedDecl(); + IdentifierInfo* identifier; + std::string name; + std::string nameAsString; + DeclarationName declName; + std::string qualifiedNameAsString; + bool hasLinkage; + bool isCXXClassMember; + bool isCXXInstanceMember; + Linkage linkageInternal; + Linkage formalLinkage; + bool hasExternalFormalLinkage; + bool isExternallyVisible; + bool isExternallyDeclarable; + Visibility visibility; + LinkageInfo linkageAndVisibility; + bool isLinkageValid; + bool hasLinkageBeenComputed; + ObjCStringFormatFamily objCFStringFormattingFamily; +}; + +class CS_API LabelDecl : public NamedDecl +{ +public: + LabelDecl(); + LabelStmt* stmt; + bool isGnuLocal; + bool isMSAsmLabel; + bool isResolvedMSAsmLabel; + std::string mSAsmLabel; +}; + +class CS_API NamespaceDecl : public NamedDecl, public DeclContext, public Redeclarable +{ +public: + enum class Flags : unsigned int + { + F_Inline = 1, + F_Nested = 2 + }; + + NamespaceDecl(); + bool isAnonymousNamespace; + bool isInline; + bool nested; + bool isOriginalNamespace; + NamespaceDecl* anonymousNamespace; + SourceLocation rBraceLoc; +}; + +class CS_API ValueDecl : public NamedDecl +{ +public: + ValueDecl(); + QualifiedType type; + bool isWeak; + bool isInitCapture; +}; + +class CS_API DeclaratorDecl : public ValueDecl +{ +public: + DeclaratorDecl(); + TypeSourceInfo* typeSourceInfo; + SourceLocation innerLocStart; + SourceLocation outerLocStart; + NestedNameSpecifier* qualifier; + NestedNameSpecifierLoc qualifierLoc; + Expr* trailingRequiresClause; + unsigned int numTemplateParameterLists; + SourceLocation typeSpecStartLoc; + SourceLocation typeSpecEndLoc; +}; + +class CS_API VarDecl : public DeclaratorDecl, public Redeclarable +{ +public: + /// Initialization styles. + enum class InitializationStyle + { + /// C-style initialization with assignment + CInit = 0, + /// Call-style initialization (C++98) + CallInit = 1, + /// Direct list-initialization (C++11) + ListInit = 2, + /// Parenthesized list-initialization (C++20) + ParenListInit = 3 + }; + + /// Kinds of thread-local storage. + enum class TLSKind + { + /// Not a TLS variable. + None = 0, + /// TLS with a known-constant initializer. + Static = 1, + /// TLS with a dynamic initializer. + Dynamic = 2 + }; + + enum class DefaultArgKind + { + None = 0, + Unparsed = 1, + Uninstantiated = 2, + Normal = 3 + }; + + enum class DefinitionKind + { + /// This declaration is only a declaration. + DeclarationOnly = 0, + /// This declaration is a tentative definition. + TentativeDefinition = 1, + /// This declaration is definitely a definition. + Definition = 2 + }; + + VarDecl(); + StorageClass storageClass; + ThreadStorageClassSpecifier tSCSpec; + TLSKind tLSKind; + bool hasLocalStorage; + bool isStaticLocal; + bool hasExternalStorage; + bool hasGlobalStorage; + StorageDuration storageDuration; + LanguageLinkage languageLinkage; + bool isExternC; + bool isInExternCContext; + bool isInExternCXXContext; + bool isLocalVarDecl; + bool isLocalVarDeclOrParm; + bool isFunctionOrMethodVarDecl; + bool isStaticDataMember; + DefinitionKind isThisDeclarationADefinition; + DefinitionKind hasDefinition; + bool isFileVarDecl; + Expr* anyInitializer; + bool hasInit; + Expr* init; + Stmt** initAddress; + EvaluatedStmt* ensureEvaluatedStmt; + EvaluatedStmt* evaluatedStmt; + APValue* evaluatedValue; + bool hasConstantInitialization; + InitializationStyle initStyle; + bool isDirectInit; + bool isThisDeclarationADemotedDefinition; + bool exceptionVariable; + bool nRVOVariable; + bool cXXForRangeDecl; + bool objCForDecl; + bool aRCPseudoStrong; + bool isInline; + bool isInlineSpecified; + bool _constexpr; + bool initCapture; + bool isParameterPack; + bool previousDeclInSameBlockScope; + bool isEscapingByref; + bool isNonEscapingByref; + bool hasDependentAlignment; + VarDecl* templateInstantiationPattern; + VarDecl* instantiatedFromStaticDataMember; + TemplateSpecializationKind templateSpecializationKind; + TemplateSpecializationKind templateSpecializationKindForInstantiation; + SourceLocation pointOfInstantiation; + MemberSpecializationInfo* memberSpecializationInfo; + VarTemplateDecl* describedVarTemplate; + bool isKnownToBeDefined; +}; + +class CS_API ImplicitParamDecl : public VarDecl +{ +public: + /// + /// Defines the kind of the implicit parameter: is this an implicit parameter + /// with pointer to 'this', 'self', '_cmd', virtual table pointers, captured + /// context or something else. + /// + enum class ImplicitParamKind : unsigned int + { + /// Parameter for Objective-C 'self' argument + ObjCSelf = 0, + /// Parameter for Objective-C '_cmd' argument + ObjCCmd = 1, + /// Parameter for C++ 'this' argument + CXXThis = 2, + /// Parameter for C++ virtual table pointers + CXXVTT = 3, + /// Parameter for captured context + CapturedContext = 4, + /// Parameter for Thread private variable + ThreadPrivateVar = 5, + /// Other implicit parameter + Other = 6 + }; + + ImplicitParamDecl(); + ImplicitParamKind parameterKind; +}; + +class CS_API ParmVarDecl : public VarDecl +{ +public: + ParmVarDecl(); + bool isObjCMethodParameter; + bool isDestroyedInCallee; + unsigned int functionScopeDepth; + unsigned int functionScopeIndex; + ObjCDeclQualifier objCDeclQualifier; + bool kNRPromoted; + Expr* defaultArg; + SourceRange defaultArgRange; + Expr* uninstantiatedDefaultArg; + bool hasDefaultArg; + bool hasUnparsedDefaultArg; + bool hasUninstantiatedDefaultArg; + bool hasInheritedDefaultArg; + QualifiedType originalType; +}; + +class CS_API FunctionDecl : public DeclaratorDecl, public DeclContext, public Redeclarable +{ +public: + /// The kind of templated function a FunctionDecl can be. + enum class TemplatedKind + { + NonTemplate = 0, + FunctionTemplate = 1, + MemberSpecialization = 2, + FunctionTemplateSpecialization = 3, + DependentFunctionTemplateSpecialization = 4, + DependentNonTemplate = 5 + }; + + class CS_API DefaultedFunctionInfo + { + public: + DefaultedFunctionInfo(); + ArrayRef unqualifiedLookups; + }; + + FunctionDecl(); + DeclarationNameInfo nameInfo; + SourceLocation ellipsisLoc; + bool hasTrivialBody; + bool isDefined; + bool isThisDeclarationADefinition; + bool isThisDeclarationInstantiatedFromAFriendDefinition; + DefaultedFunctionInfo* defaultedFunctionInfo; + bool isVariadic; + bool virtualAsWritten; + bool pure; + bool lateTemplateParsed; + bool trivial; + bool trivialForCall; + bool defaulted; + bool explicitlyDefaulted; + SourceLocation defaultLoc; + bool isUserProvided; + bool ineligibleOrNotSelected; + bool hasImplicitReturnZero; + bool hasPrototype; + bool hasWrittenPrototype; + bool hasInheritedPrototype; + bool isConstexpr; + ConstexprSpecKind constexprKind; + bool isConstexprSpecified; + bool isConsteval; + bool bodyContainsImmediateEscalatingExpressions; + bool isImmediateEscalating; + bool isImmediateFunction; + bool instantiationIsPending; + bool usesSEHTry; + bool isDeleted; + bool deletedAsWritten; + bool isMain; + bool isMSVCRTEntryPoint; + bool isReservedGlobalPlacementOperator; + bool isInlineBuiltinDeclaration; + bool isDestroyingOperatorDelete; + LanguageLinkage languageLinkage; + bool isExternC; + bool isInExternCContext; + bool isInExternCXXContext; + bool isGlobal; + bool isNoReturn; + bool hasSkippedBody; + bool willHaveBody; + bool isMultiVersion; + bool friendConstraintRefersToEnclosingTemplate; + bool isMemberLikeConstrainedFriend; + MultiVersionKind multiVersionKind; + bool isCPUDispatchMultiVersion; + bool isCPUSpecificMultiVersion; + bool isTargetMultiVersion; + bool isTargetClonesMultiVersion; + unsigned int numParams; + unsigned int minRequiredArguments; + bool hasOneParamOrDefaultArgs; + QualifiedType returnType; + SourceRange returnTypeSourceRange; + SourceRange parametersSourceRange; + QualifiedType declaredReturnType; + ExceptionSpecificationType exceptionSpecType; + SourceRange exceptionSpecSourceRange; + QualifiedType callResultType; + StorageClass storageClass; + bool inlineSpecified; + bool usesFPIntrin; + bool isInlined; + bool isInlineDefinitionExternallyVisible; + bool isMSExternInline; + bool isStatic; + bool isOverloadedOperator; + OverloadedOperatorKind overloadedOperator; + IdentifierInfo* literalIdentifier; + FunctionDecl* instantiatedFromMemberFunction; + TemplatedKind templatedKind; + MemberSpecializationInfo* memberSpecializationInfo; + FunctionDecl* instantiatedFromDecl; + FunctionTemplateDecl* describedFunctionTemplate; + bool isFunctionTemplateSpecialization; + FunctionTemplateSpecializationInfo* templateSpecializationInfo; + bool isImplicitlyInstantiable; + bool isTemplateInstantiation; + FunctionTemplateDecl* primaryTemplate; + VECTOR(TemplateArgument*, templateSpecializationArgs) + ASTTemplateArgumentListInfo* templateSpecializationArgsAsWritten; + DependentFunctionTemplateSpecializationInfo* dependentSpecializationInfo; + TemplateSpecializationKind templateSpecializationKind; + TemplateSpecializationKind templateSpecializationKindForInstantiation; + SourceLocation pointOfInstantiation; + unsigned int memoryFunctionKind; +}; + +class CS_API FieldDecl : public DeclaratorDecl, public Mergeable +{ +public: + /// The kinds of value we can store in StorageKind. + /// + /// Note that this is compatible with InClassInitStyle except for + /// ISK_CapturedVLAType. + /// + enum class InitStorageKind + { + /// + /// If the pointer is null, there's nothing special. Otherwise, + /// this is a bitfield and the pointer is the Expr* storing the + /// bit-width. + /// + NoInit = 0, + /// + /// The pointer is an (optional due to delayed parsing) Expr* + /// holding the copy-initializer. + /// + InClassCopyInit = 1, + /// + /// The pointer is an (optional due to delayed parsing) Expr* + /// holding the list-initializer. + /// + InClassListInit = 2, + /// + /// The pointer is a VariableArrayType* that's been captured; + /// the enclosing context is a lambda or captured statement. + /// + CapturedVLAType = 3 + }; + + FieldDecl(); + unsigned int fieldIndex; + bool isMutable; + bool isBitField; + bool isUnnamedBitfield; + bool isAnonymousStructOrUnion; + Expr* bitWidth; + bool isPotentiallyOverlapping; + InClassInitStyle inClassInitStyle; + bool hasInClassInitializer; + bool hasNonNullInClassInitializer; + Expr* inClassInitializer; + bool hasCapturedVLAType; + VariableArrayType* capturedVLAType; +}; + +class CS_API EnumConstantDecl : public ValueDecl, public Mergeable +{ +public: + EnumConstantDecl(); + Expr* initExpr; + APSInt& initVal; +}; + +class CS_API IndirectFieldDecl : public ValueDecl, public Mergeable +{ +public: + IndirectFieldDecl(); + ArrayRef chain; + unsigned int chainingSize; + FieldDecl* anonField; + VarDecl* varDecl; +}; + +class CS_API TypeDecl : public NamedDecl +{ +public: + TypeDecl(); + Type* typeForDecl; +}; + +class CS_API TypedefNameDecl : public TypeDecl, public Redeclarable +{ +public: + TypedefNameDecl(); + bool isModed; + TypeSourceInfo* typeSourceInfo; + QualifiedType underlyingType; + bool isTransparentTag; +}; + +class CS_API TypedefDecl : public TypedefNameDecl +{ +public: + TypedefDecl(); +}; + +class CS_API TypeAliasDecl : public TypedefNameDecl +{ +public: + TypeAliasDecl(); + TypeAliasTemplateDecl* describedAliasTemplate; +}; + +class CS_API TagDecl : public TypeDecl, public DeclContext, public Redeclarable +{ +public: + TagDecl(); + bool beingDefined; + bool mayHaveOutOfDateDef; + SourceRange braceRange; + SourceLocation innerLocStart; + SourceLocation outerLocStart; + bool isThisDeclarationADefinition; + bool completeDefinition; + bool completeDefinitionRequired; + bool embeddedInDeclarator; + bool freeStanding; + bool isDependentType; + bool isThisDeclarationADemotedDefinition; + TagDecl* definition; + std::string kindName; + TagKind tagKind; + bool isStruct; + bool isInterface; + bool isClass; + bool isUnion; + bool isEnum; + bool hasNameForLinkage; + TypedefNameDecl* typedefNameForAnonDecl; + NestedNameSpecifier* qualifier; + NestedNameSpecifierLoc qualifierLoc; + unsigned int numTemplateParameterLists; +}; + +class CS_API EnumDecl : public TagDecl +{ +public: + EnumDecl(); + VECTOR(EnumConstantDecl*, enumerators) + bool scoped; + bool scopedUsingClassTag; + bool fixed; + EnumDecl* definition; + QualifiedType promotionType; + QualifiedType integerType; + TypeSourceInfo* integerTypeSourceInfo; + SourceRange integerTypeRange; + unsigned int numPositiveBits; + unsigned int numNegativeBits; + unsigned int oDRHash; + bool isComplete; + bool isClosed; + bool isClosedFlag; + bool isClosedNonFlag; + EnumDecl* templateInstantiationPattern; + EnumDecl* instantiatedFromMemberEnum; + TemplateSpecializationKind templateSpecializationKind; + MemberSpecializationInfo* memberSpecializationInfo; +}; + +class CS_API RecordDecl : public TagDecl +{ +public: + /// + /// Enum that represents the different ways arguments are passed to and + /// returned from function calls. This takes into account the target-specific + /// and version-specific rules along with the rules determined by the + /// language. + /// + enum class ArgPassingKind : unsigned int + { + /// The argument of this type can be passed directly in registers. + CanPassInRegs = 0, + /// + /// The argument of this type cannot be passed directly in registers. + /// Records containing this type as a subobject are not forced to be passed + /// indirectly. This value is used only in C++. This value is required by + /// C++ because, in uncommon situations, it is possible for a class to have + /// only trivial copy/move constructors even when one of its subobjects has + /// a non-trivial copy/move constructor (if e.g. the corresponding copy/move + /// constructor in the derived class is deleted). + /// + CannotPassInRegs = 1, + /// + /// The argument of this type cannot be passed directly in registers. + /// Records containing this type as a subobject are forced to be passed + /// indirectly. + /// + CanNeverPassInRegs = 2 + }; + + RecordDecl(); + VECTOR(FieldDecl*, fields) + bool hasFlexibleArrayMember; + bool anonymousStructOrUnion; + bool hasObjectMember; + bool hasVolatileMember; + bool hasLoadedFieldsFromExternalStorage; + bool nonTrivialToPrimitiveDefaultInitialize; + bool nonTrivialToPrimitiveCopy; + bool nonTrivialToPrimitiveDestroy; + bool hasNonTrivialToPrimitiveDefaultInitializeCUnion; + bool hasNonTrivialToPrimitiveDestructCUnion; + bool hasNonTrivialToPrimitiveCopyCUnion; + ArgPassingKind argPassingRestrictions; + bool paramDestroyedInCallee; + bool isRandomized; + bool isInjectedClassName; + bool isLambda; + bool isCapturedRecord; + RecordDecl* definition; + bool isOrContainsUnion; + FieldDecl* findFirstNamedDataMember; + unsigned int oDRHash; +}; + +class CS_API FileScopeAsmDecl : public Decl +{ +public: + FileScopeAsmDecl(); + SourceLocation asmLoc; + SourceLocation rParenLoc; + StringLiteral* asmString; +}; + +class CS_API TopLevelStmtDecl : public Decl +{ +public: + TopLevelStmtDecl(); + Stmt* stmt; + bool semiMissing; +}; + +class CS_API BlockDecl : public Decl, public DeclContext +{ +public: + class CS_API Capture + { + public: + Capture(); + VarDecl* variable; + bool isByRef; + bool isEscapingByref; + bool isNonEscapingByref; + bool isNested; + bool hasCopyExpr; + Expr* copyExpr; + }; + + BlockDecl(); + SourceLocation caretLocation; + bool isVariadic; + CompoundStmt* compoundBody; + TypeSourceInfo* signatureAsWritten; + unsigned int numParams; + bool hasCaptures; + unsigned int numCaptures; + ArrayRef captures; + bool capturesCXXThis; + bool blockMissingReturnType; + bool isConversionFromLambda; + bool doesNotEscape; + bool canAvoidCopyToHeap; + unsigned int blockManglingNumber; + Decl* blockManglingContextDecl; +}; + +class CS_API CapturedDecl : public Decl, public DeclContext +{ +public: + CapturedDecl(); + bool nothrow; + unsigned int numParams; + ImplicitParamDecl* contextParam; + unsigned int contextParamPosition; +}; + +class CS_API ImportDecl : public Decl +{ +public: + ImportDecl(); + Module* importedModule; + ArrayRef identifierLocs; +}; + +class CS_API ExportDecl : public Decl, public DeclContext +{ +public: + ExportDecl(); + SourceLocation exportLoc; + SourceLocation rBraceLoc; + bool hasBraces; +}; + +class CS_API EmptyDecl : public Decl +{ +public: + EmptyDecl(); +}; + +class CS_API HLSLBufferDecl : public NamedDecl, public DeclContext +{ +public: + HLSLBufferDecl(); + SourceLocation locStart; + SourceLocation lBraceLoc; + SourceLocation rBraceLoc; + bool isCBuffer; +}; + +class CS_API AccessSpecDecl : public Decl +{ +public: + AccessSpecDecl(); + SourceLocation accessSpecifierLoc; + SourceLocation colonLoc; +}; + +class CS_API CXXRecordDecl : public RecordDecl +{ +public: + /// Values used in DefinitionData fields to represent special members. + enum class SpecialMemberFlags + { + DefaultConstructor = 1, + CopyConstructor = 2, + MoveConstructor = 4, + CopyAssignment = 8, + MoveAssignment = 16, + Destructor = 32, + All = 63 + }; + + enum class LambdaDependencyKind + { + Unknown = 0, + AlwaysDependent = 1, + NeverDependent = 2 + }; + + class CS_API LambdaNumbering + { + public: + LambdaNumbering(); + }; + + CXXRecordDecl(); + VECTOR(CXXMethodDecl*, methods) + VECTOR(CXXConstructorDecl*, ctors) + VECTOR(FriendDecl*, friends) + CXXRecordDecl* definition; + bool hasDefinition; + bool isDynamicClass; + bool mayBeDynamicClass; + bool mayBeNonDynamicClass; + bool isParsingBaseSpecifiers; + unsigned int oDRHash; + unsigned int numBases; + unsigned int numVBases; + bool hasAnyDependentBases; + bool hasFriends; + bool defaultedCopyConstructorIsDeleted; + bool defaultedMoveConstructorIsDeleted; + bool defaultedDestructorIsDeleted; + bool hasSimpleCopyConstructor; + bool hasSimpleMoveConstructor; + bool hasSimpleCopyAssignment; + bool hasSimpleMoveAssignment; + bool hasSimpleDestructor; + bool hasDefaultConstructor; + bool needsImplicitDefaultConstructor; + bool hasUserDeclaredConstructor; + bool hasUserProvidedDefaultConstructor; + bool hasUserDeclaredCopyConstructor; + bool needsImplicitCopyConstructor; + bool needsOverloadResolutionForCopyConstructor; + bool implicitCopyConstructorHasConstParam; + bool hasCopyConstructorWithConstParam; + bool hasUserDeclaredMoveOperation; + bool hasUserDeclaredMoveConstructor; + bool hasMoveConstructor; + bool needsImplicitMoveConstructor; + bool needsOverloadResolutionForMoveConstructor; + bool hasUserDeclaredCopyAssignment; + bool needsImplicitCopyAssignment; + bool needsOverloadResolutionForCopyAssignment; + bool implicitCopyAssignmentHasConstParam; + bool hasCopyAssignmentWithConstParam; + bool hasUserDeclaredMoveAssignment; + bool hasMoveAssignment; + bool needsImplicitMoveAssignment; + bool needsOverloadResolutionForMoveAssignment; + bool hasUserDeclaredDestructor; + bool needsImplicitDestructor; + bool needsOverloadResolutionForDestructor; + bool isLambda; + bool isGenericLambda; + bool lambdaIsDefaultConstructibleAndAssignable; + CXXMethodDecl* lambdaCallOperator; + FunctionTemplateDecl* dependentLambdaCallOperator; + CXXMethodDecl* lambdaStaticInvoker; + VECTOR(NamedDecl*, genericLambdaTemplateParameterList) + ArrayRef lambdaExplicitTemplateParameters; + LambdaCaptureDefault lambdaCaptureDefault; + bool isAggregate; + bool hasInClassInitializer; + bool hasUninitializedReferenceMember; + bool isPOD; + bool isCLike; + bool isEmpty; + bool hasInitMethod; + bool hasPrivateFields; + bool hasProtectedFields; + bool hasDirectFields; + bool isPolymorphic; + bool isAbstract; + bool isStandardLayout; + bool isCXX11StandardLayout; + bool hasMutableFields; + bool hasVariantMembers; + bool hasTrivialDefaultConstructor; + bool hasNonTrivialDefaultConstructor; + bool hasConstexprNonCopyMoveConstructor; + bool defaultedDefaultConstructorIsConstexpr; + bool hasConstexprDefaultConstructor; + bool hasTrivialCopyConstructor; + bool hasTrivialCopyConstructorForCall; + bool hasNonTrivialCopyConstructor; + bool hasNonTrivialCopyConstructorForCall; + bool hasTrivialMoveConstructor; + bool hasTrivialMoveConstructorForCall; + bool hasNonTrivialMoveConstructor; + bool hasNonTrivialMoveConstructorForCall; + bool hasTrivialCopyAssignment; + bool hasNonTrivialCopyAssignment; + bool hasTrivialMoveAssignment; + bool hasNonTrivialMoveAssignment; + bool defaultedDestructorIsConstexpr; + bool hasConstexprDestructor; + bool hasTrivialDestructor; + bool hasTrivialDestructorForCall; + bool hasNonTrivialDestructor; + bool hasNonTrivialDestructorForCall; + bool hasIrrelevantDestructor; + bool hasNonLiteralTypeFieldsOrBases; + bool hasInheritedConstructor; + bool hasInheritedAssignment; + bool isTriviallyCopyable; + bool isTrivial; + bool isLiteral; + bool isStructural; + CXXRecordDecl* instantiatedFromMemberClass; + MemberSpecializationInfo* memberSpecializationInfo; + ClassTemplateDecl* describedClassTemplate; + TemplateSpecializationKind templateSpecializationKind; + CXXDestructorDecl* destructor; + bool isAnyDestructorNoReturn; + bool mayBeAbstract; + bool isEffectivelyFinal; + unsigned int lambdaManglingNumber; + bool hasKnownLambdaInternalLinkage; + Decl* lambdaContextDecl; + unsigned int lambdaIndexInContext; + LambdaNumbering lambdaNumbering; + unsigned int deviceLambdaManglingNumber; + MSInheritanceModel mSInheritanceModel; + bool nullFieldOffsetIsZero; + MSVtorDispMode mSVtorDispMode; + bool isDependentLambda; + bool isNeverDependentLambda; + unsigned int lambdaDependencyKind; + TypeSourceInfo* lambdaTypeInfo; + bool isInterfaceLike; +}; + +class CS_API CXXDeductionGuideDecl : public FunctionDecl +{ +public: + CXXDeductionGuideDecl(); + bool isExplicit; + TemplateDecl* deducedTemplate; + CXXConstructorDecl* correspondingConstructor; + DeductionCandidate deductionCandidateKind; +}; + +class CS_API RequiresExprBodyDecl : public Decl, public DeclContext +{ +public: + RequiresExprBodyDecl(); +}; + +class CS_API CXXMethodDecl : public FunctionDecl +{ +public: + CXXMethodDecl(); + VECTOR(const clang::CXXMethodDecl*, overridden_methods) + bool isStatic; + bool isInstance; + bool isConst; + bool isVolatile; + bool isVirtual; + bool isCopyAssignmentOperator; + bool isMoveAssignmentOperator; + unsigned int size_overridden_methods; + QualifiedType thisType; + QualifiedType thisObjectType; + Qualifiers methodQualifiers; + RefQualifierKind refQualifier; + bool hasInlineBody; + bool isLambdaStaticInvoker; +}; + +class CS_API CXXConstructorDecl : public CXXMethodDecl +{ +public: + enum class TrailingAllocKind + { + TAKInheritsConstructor = 1, + TAKHasTailExplicit = 2 + }; + + CXXConstructorDecl(); + ExplicitSpecifier explicitSpecifier; + bool isExplicit; + unsigned int numCtorInitializers; + bool isDelegatingConstructor; + CXXConstructorDecl* targetConstructor; + bool isDefaultConstructor; + bool isCopyConstructor; + bool isMoveConstructor; + bool isCopyOrMoveConstructor; + bool isSpecializationCopyingObject; + bool inheritingConstructor; + InheritedConstructor inheritedConstructor; +}; + +class CS_API CXXDestructorDecl : public CXXMethodDecl +{ +public: + CXXDestructorDecl(); + FunctionDecl* operatorDelete; + Expr* operatorDeleteThisArg; +}; + +class CS_API CXXConversionDecl : public CXXMethodDecl +{ +public: + CXXConversionDecl(); + ExplicitSpecifier explicitSpecifier; + bool isExplicit; + QualifiedType conversionType; + bool isLambdaToBlockPointerConversion; +}; + +class CS_API LinkageSpecDecl : public Decl, public DeclContext +{ +public: + /// Represents the language in a linkage specification. + /// + /// The values are part of the serialization ABI for + /// ASTs and cannot be changed without altering that ABI. + /// + enum class LanguageIDs + { + lang_c = 1, + lang_cxx = 2 + }; + + LinkageSpecDecl(); + LanguageIDs language; + bool hasBraces; + SourceLocation externLoc; + SourceLocation rBraceLoc; +}; + +class CS_API UsingDirectiveDecl : public NamedDecl +{ +public: + UsingDirectiveDecl(); + NestedNameSpecifierLoc qualifierLoc; + NestedNameSpecifier* qualifier; + SourceLocation usingLoc; + SourceLocation namespaceKeyLocation; + SourceLocation identLocation; +}; + +class CS_API NamespaceAliasDecl : public NamedDecl, public Redeclarable +{ +public: + NamespaceAliasDecl(); + NestedNameSpecifierLoc qualifierLoc; + NestedNameSpecifier* qualifier; + SourceLocation aliasLoc; + SourceLocation namespaceLoc; + SourceLocation targetNameLoc; + NamedDecl* aliasedNamespace; +}; + +class CS_API LifetimeExtendedTemporaryDecl : public Decl, public Mergeable +{ +public: + LifetimeExtendedTemporaryDecl(); + StorageDuration storageDuration; + unsigned int manglingNumber; + APValue* value; +}; + +class CS_API UsingShadowDecl : public NamedDecl, public Redeclarable +{ +public: + UsingShadowDecl(); + NamedDecl* targetDecl; + BaseUsingDecl* introducer; + UsingShadowDecl* nextUsingShadowDecl; +}; + +class CS_API BaseUsingDecl : public NamedDecl +{ +public: + class CS_API shadow_iterator + { + public: + shadow_iterator(); + }; + + BaseUsingDecl(); + VECTOR(BaseUsingDecl::shadow_iterator*, shadows) +}; + +class CS_API UsingDecl : public BaseUsingDecl, public Mergeable +{ +public: + UsingDecl(); + SourceLocation usingLoc; + NestedNameSpecifierLoc qualifierLoc; + NestedNameSpecifier* qualifier; + DeclarationNameInfo nameInfo; + bool isAccessDeclaration; + bool hasTypename; +}; + +class CS_API ConstructorUsingShadowDecl : public UsingShadowDecl +{ +public: + ConstructorUsingShadowDecl(); + UsingDecl* introducer; + ConstructorUsingShadowDecl* nominatedBaseClassShadowDecl; + ConstructorUsingShadowDecl* constructedBaseClassShadowDecl; + CXXRecordDecl* nominatedBaseClass; + CXXRecordDecl* constructedBaseClass; + bool constructsVirtualBase; +}; + +class CS_API UsingEnumDecl : public BaseUsingDecl, public Mergeable +{ +public: + UsingEnumDecl(); + SourceLocation usingLoc; + SourceLocation enumLoc; + NestedNameSpecifier* qualifier; + NestedNameSpecifierLoc qualifierLoc; + TypeSourceInfo* enumType; + EnumDecl* enumDecl; +}; + +class CS_API UsingPackDecl : public NamedDecl, public Mergeable +{ +public: + UsingPackDecl(); + NamedDecl* instantiatedFromUsingDecl; + ArrayRef expansions; +}; + +class CS_API UnresolvedUsingValueDecl : public ValueDecl, public Mergeable +{ +public: + UnresolvedUsingValueDecl(); + SourceLocation usingLoc; + bool isAccessDeclaration; + NestedNameSpecifierLoc qualifierLoc; + NestedNameSpecifier* qualifier; + DeclarationNameInfo nameInfo; + bool isPackExpansion; + SourceLocation ellipsisLoc; +}; + +class CS_API UnresolvedUsingTypenameDecl : public TypeDecl, public Mergeable +{ +public: + UnresolvedUsingTypenameDecl(); + SourceLocation usingLoc; + SourceLocation typenameLoc; + NestedNameSpecifierLoc qualifierLoc; + NestedNameSpecifier* qualifier; + DeclarationNameInfo nameInfo; + bool isPackExpansion; + SourceLocation ellipsisLoc; +}; + +class CS_API UnresolvedUsingIfExistsDecl : public NamedDecl +{ +public: + UnresolvedUsingIfExistsDecl(); +}; + +class CS_API StaticAssertDecl : public Decl +{ +public: + StaticAssertDecl(); + bool isFailed; + SourceLocation rParenLoc; +}; + +class CS_API BindingDecl : public ValueDecl +{ +public: + BindingDecl(); + Expr* binding; + ValueDecl* decomposedDecl; + VarDecl* holdingVar; +}; + +class CS_API DecompositionDecl : public VarDecl +{ +public: + DecompositionDecl(); + ArrayRef bindings; +}; + +class CS_API MSPropertyDecl : public DeclaratorDecl +{ +public: + MSPropertyDecl(); + bool hasGetter; + IdentifierInfo* getterId; + bool hasSetter; + IdentifierInfo* setterId; +}; + +class CS_API MSGuidDecl : public ValueDecl, public Mergeable +{ +public: + MSGuidDecl(); + Parts parts; + APValue& asAPValue; +}; + +class CS_API UnnamedGlobalConstantDecl : public ValueDecl, public Mergeable +{ +public: + UnnamedGlobalConstantDecl(); + APValue& value; +}; + +class CS_API TemplateDecl : public NamedDecl +{ +public: + TemplateDecl(); + VECTOR(NamedDecl*, templateParameters) + bool hasAssociatedConstraints; + NamedDecl* templatedDecl; + bool isTypeAlias; +}; + +class CS_API RedeclarableTemplateDecl : public TemplateDecl, public Redeclarable +{ +public: + class CS_API SpecEntryTraits + { + public: + SpecEntryTraits(); + }; + + RedeclarableTemplateDecl(); + bool isMemberSpecialization; + RedeclarableTemplateDecl* instantiatedFromMemberTemplate; + ArrayRef injectedTemplateArgs; +}; + +class CS_API FunctionTemplateDecl : public RedeclarableTemplateDecl +{ +public: + FunctionTemplateDecl(); + FunctionDecl* templatedDecl; + bool isThisDeclarationADefinition; + FunctionTemplateDecl* instantiatedFromMemberTemplate; + bool isAbbreviated; +}; + +class CS_API TemplateTypeParmDecl : public TypeDecl +{ +public: + TemplateTypeParmDecl(); + DefArgStorage& defaultArgStorage; + bool hasDefaultArgument; + QualifiedType defaultArgument; + TypeSourceInfo* defaultArgumentInfo; + SourceLocation defaultArgumentLoc; + bool defaultArgumentWasInherited; + unsigned int depth; + unsigned int index; + bool isParameterPack; + bool isPackExpansion; + bool isExpandedParameterPack; + unsigned int numExpansionParameters; + TypeConstraint* typeConstraint; + bool hasTypeConstraint; +}; + +class CS_API NonTypeTemplateParmDecl : public DeclaratorDecl, protected TemplateParmPosition +{ +public: + NonTypeTemplateParmDecl(); + DefArgStorage& defaultArgStorage; + bool hasDefaultArgument; + Expr* defaultArgument; + SourceLocation defaultArgumentLoc; + bool defaultArgumentWasInherited; + bool isParameterPack; + bool isPackExpansion; + bool isExpandedParameterPack; + unsigned int numExpansionTypes; + Expr* placeholderTypeConstraint; + bool hasPlaceholderTypeConstraint; +}; + +class CS_API TemplateTemplateParmDecl : public TemplateDecl, protected TemplateParmPosition +{ +public: + TemplateTemplateParmDecl(); + bool isParameterPack; + bool isPackExpansion; + bool isExpandedParameterPack; + unsigned int numExpansionTemplateParameters; + DefArgStorage& defaultArgStorage; + bool hasDefaultArgument; + TemplateArgumentLoc& defaultArgument; + SourceLocation defaultArgumentLoc; + bool defaultArgumentWasInherited; +}; + +class CS_API BuiltinTemplateDecl : public TemplateDecl +{ +public: + BuiltinTemplateDecl(); + BuiltinTemplateKind builtinTemplateKind; +}; + +class CS_API ClassTemplateSpecializationDecl : public CXXRecordDecl +{ +public: + ClassTemplateSpecializationDecl(); + ClassTemplateSpecializationDecl* mostRecentDecl; + ClassTemplateDecl* specializedTemplate; + VECTOR(TemplateArgument*, templateArgs) + TemplateSpecializationKind specializationKind; + bool isExplicitSpecialization; + bool isClassScopeExplicitSpecialization; + bool isExplicitInstantiationOrSpecialization; + SourceLocation pointOfInstantiation; + PointerUnion<> instantiatedFrom; + PointerUnion<> specializedTemplateOrPartial; + VECTOR(TemplateArgument*, templateInstantiationArgs) + TypeSourceInfo* typeAsWritten; + SourceLocation externLoc; + SourceLocation templateKeywordLoc; +}; + +class CS_API ClassTemplatePartialSpecializationDecl : public ClassTemplateSpecializationDecl +{ +public: + ClassTemplatePartialSpecializationDecl(); + ClassTemplatePartialSpecializationDecl* mostRecentDecl; + VECTOR(NamedDecl*, templateParameters) + bool hasAssociatedConstraints; + ASTTemplateArgumentListInfo* templateArgsAsWritten; + ClassTemplatePartialSpecializationDecl* instantiatedFromMember; + ClassTemplatePartialSpecializationDecl* instantiatedFromMemberTemplate; + bool isMemberSpecialization; + QualifiedType injectedSpecializationType; +}; + +class CS_API ClassTemplateDecl : public RedeclarableTemplateDecl +{ +public: + ClassTemplateDecl(); + CXXRecordDecl* templatedDecl; + bool isThisDeclarationADefinition; + ClassTemplateDecl* instantiatedFromMemberTemplate; + QualifiedType injectedClassNameSpecialization; +}; + +class CS_API FriendTemplateDecl : public Decl +{ +public: + FriendTemplateDecl(); + TypeSourceInfo* friendType; + NamedDecl* friendDecl; + SourceLocation friendLoc; + unsigned int numTemplateParameters; +}; + +class CS_API TypeAliasTemplateDecl : public RedeclarableTemplateDecl +{ +public: + TypeAliasTemplateDecl(); + TypeAliasDecl* templatedDecl; + TypeAliasTemplateDecl* instantiatedFromMemberTemplate; +}; + +class CS_API ClassScopeFunctionSpecializationDecl : public Decl +{ +public: + ClassScopeFunctionSpecializationDecl(); + CXXMethodDecl* specialization; + bool hasExplicitTemplateArgs; + ASTTemplateArgumentListInfo* templateArgsAsWritten; +}; + +class CS_API VarTemplateSpecializationDecl : public VarDecl +{ +public: + VarTemplateSpecializationDecl(); + VarTemplateSpecializationDecl* mostRecentDecl; + VarTemplateDecl* specializedTemplate; + VECTOR(TemplateArgument*, templateArgs) + ASTTemplateArgumentListInfo* templateArgsInfo; + TemplateSpecializationKind specializationKind; + bool isExplicitSpecialization; + bool isClassScopeExplicitSpecialization; + bool isExplicitInstantiationOrSpecialization; + SourceLocation pointOfInstantiation; + PointerUnion<> instantiatedFrom; + PointerUnion<> specializedTemplateOrPartial; + VECTOR(TemplateArgument*, templateInstantiationArgs) + TypeSourceInfo* typeAsWritten; + SourceLocation externLoc; + SourceLocation templateKeywordLoc; +}; + +class CS_API VarTemplatePartialSpecializationDecl : public VarTemplateSpecializationDecl +{ +public: + VarTemplatePartialSpecializationDecl(); + VarTemplatePartialSpecializationDecl* mostRecentDecl; + VECTOR(NamedDecl*, templateParameters) + ASTTemplateArgumentListInfo* templateArgsAsWritten; + bool hasAssociatedConstraints; + VarTemplatePartialSpecializationDecl* instantiatedFromMember; + bool isMemberSpecialization; +}; + +class CS_API VarTemplateDecl : public RedeclarableTemplateDecl +{ +public: + VarTemplateDecl(); + VarDecl* templatedDecl; + bool isThisDeclarationADefinition; + VarTemplateDecl* definition; + VarTemplateDecl* instantiatedFromMemberTemplate; +}; + +class CS_API ConceptDecl : public TemplateDecl, public Mergeable +{ +public: + ConceptDecl(); + Expr* constraintExpr; + bool isTypeConcept; +}; + +class CS_API ImplicitConceptSpecializationDecl : public Decl +{ +public: + ImplicitConceptSpecializationDecl(); + ArrayRef templateArguments; +}; + +class CS_API TemplateParamObjectDecl : public ValueDecl, public Mergeable +{ +public: + TemplateParamObjectDecl(); + APValue& value; +}; + +}