Browse Source

Split into files

pull/1914/head
duckdoom5 4 months ago
parent
commit
bc800d5e69
  1. 1194
      src/CppParser/Bootstrap/Bootstrap.cs
  2. 551
      src/CppParser/Bootstrap/CodeGeneratorHelpers.cs
  3. 526
      src/CppParser/Bootstrap/StmtCodeGenerators.cs

1194
src/CppParser/Bootstrap/Bootstrap.cs

File diff suppressed because it is too large Load Diff

551
src/CppParser/Bootstrap/CodeGeneratorHelpers.cs

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

526
src/CppParser/Bootstrap/StmtCodeGenerators.cs

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