Browse Source

Fixed a few regressions introduced by the updated code for default args.

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/397/head
Dimitar Dobrev 11 years ago
parent
commit
58fb80f571
  1. 63
      src/CppParser/Parser.cpp
  2. 1
      src/CppParser/Parser.h
  3. 117
      src/Generator/Passes/HandleDefaultParamValuesPass.cs

63
src/CppParser/Parser.cpp

@ -2499,6 +2499,59 @@ AST::Expression* Parser::WalkExpression(clang::Expr* Expr)
{ {
using namespace clang; using namespace clang;
switch (Expr->getStmtClass())
{
case Stmt::BinaryOperatorClass:
return new AST::Expression(GetStringFromStatement(Expr), StatementClass::BinaryOperator);
case Stmt::DeclRefExprClass:
return new AST::Expression(GetStringFromStatement(Expr), StatementClass::DeclRefExprClass,
WalkDeclaration(cast<DeclRefExpr>(Expr)->getDecl()));
case Stmt::CStyleCastExprClass:
case Stmt::CXXConstCastExprClass:
case Stmt::CXXDynamicCastExprClass:
case Stmt::CXXFunctionalCastExprClass:
case Stmt::CXXReinterpretCastExprClass:
case Stmt::CXXStaticCastExprClass:
case Stmt::ImplicitCastExprClass:
return WalkExpression(cast<CastExpr>(Expr)->getSubExprAsWritten());
case Stmt::CXXOperatorCallExprClass:
return new AST::Expression(GetStringFromStatement(Expr), StatementClass::CXXOperatorCallExpr,
WalkDeclaration(cast<CXXOperatorCallExpr>(Expr)->getCalleeDecl()));
case Stmt::CXXConstructExprClass:
case Stmt::CXXTemporaryObjectExprClass:
{
auto ConstructorExpr = cast<CXXConstructExpr>(Expr);
if (ConstructorExpr->getNumArgs() == 1)
{
auto Arg = ConstructorExpr->getArg(0);
auto TemporaryExpr = dyn_cast<MaterializeTemporaryExpr>(Arg);
if (TemporaryExpr)
{
auto Cast = dyn_cast<CastExpr>(TemporaryExpr->GetTemporaryExpr());
if (Cast && Cast->getSubExprAsWritten()->getStmtClass() != Stmt::IntegerLiteralClass)
return WalkExpression(Cast->getSubExprAsWritten());
}
}
return new AST::Expression(GetStringFromStatement(Expr), StatementClass::CXXConstructExprClass,
WalkDeclaration(ConstructorExpr->getConstructor()));
}
case Stmt::MaterializeTemporaryExprClass:
return WalkExpression(cast<MaterializeTemporaryExpr>(Expr)->GetTemporaryExpr());
default:
break;
}
llvm::APSInt integer;
if (Expr->getStmtClass() != Stmt::CharacterLiteralClass &&
Expr->getStmtClass() != Stmt::CXXBoolLiteralExprClass &&
Expr->EvaluateAsInt(integer, C->getASTContext()))
return new AST::Expression(integer.toString(10));
return new AST::Expression(GetStringFromStatement(Expr));
}
AST::Expression* Parser::WalkExpressionEx(clang::Expr* Expr)
{
using namespace clang;
switch (Expr->getStmtClass()) switch (Expr->getStmtClass())
{ {
case Stmt::BinaryOperatorClass: case Stmt::BinaryOperatorClass:
@ -2514,11 +2567,11 @@ AST::Expression* Parser::WalkExpression(clang::Expr* Expr)
case Stmt::CXXStaticCastExprClass: case Stmt::CXXStaticCastExprClass:
return new AST::Expression(GetStringFromStatement(Expr), StatementClass::ExplicitCastExpr, return new AST::Expression(GetStringFromStatement(Expr), StatementClass::ExplicitCastExpr,
0, 0,
WalkExpression(cast<CastExpr>(Expr)->getSubExpr())); WalkExpressionEx(cast<CastExpr>(Expr)->getSubExpr()));
case Stmt::ImplicitCastExprClass: case Stmt::ImplicitCastExprClass:
return new AST::Expression(GetStringFromStatement(Expr), StatementClass::ImplicitCastExpr, return new AST::Expression(GetStringFromStatement(Expr), StatementClass::ImplicitCastExpr,
0, 0,
WalkExpression(cast<CastExpr>(Expr)->getSubExpr())); WalkExpressionEx(cast<CastExpr>(Expr)->getSubExpr()));
case Stmt::CXXOperatorCallExprClass: case Stmt::CXXOperatorCallExprClass:
return new AST::Expression(GetStringFromStatement(Expr), StatementClass::CXXOperatorCallExpr, return new AST::Expression(GetStringFromStatement(Expr), StatementClass::CXXOperatorCallExpr,
WalkDeclaration(cast<CXXOperatorCallExpr>(Expr)->getCalleeDecl())); WalkDeclaration(cast<CXXOperatorCallExpr>(Expr)->getCalleeDecl()));
@ -2530,13 +2583,13 @@ AST::Expression* Parser::WalkExpression(clang::Expr* Expr)
{ {
if (ConstructorExpr->isElidable()) if (ConstructorExpr->isElidable())
{ {
return WalkExpression(ConstructorExpr->getArg(0)); return WalkExpressionEx(ConstructorExpr->getArg(0));
} }
else else
{ {
return new AST::Expression(GetStringFromStatement(Expr), StatementClass::CXXConstructExprClass, return new AST::Expression(GetStringFromStatement(Expr), StatementClass::CXXConstructExprClass,
WalkDeclaration(ConstructorExpr->getConstructor()), WalkDeclaration(ConstructorExpr->getConstructor()),
WalkExpression(ConstructorExpr->getArg(0))); WalkExpressionEx(ConstructorExpr->getArg(0)));
} }
} }
else else
@ -2546,7 +2599,7 @@ AST::Expression* Parser::WalkExpression(clang::Expr* Expr)
} }
} }
case Stmt::MaterializeTemporaryExprClass: case Stmt::MaterializeTemporaryExprClass:
return WalkExpression(cast<MaterializeTemporaryExpr>(Expr)->GetTemporaryExpr()); return WalkExpressionEx(cast<MaterializeTemporaryExpr>(Expr)->GetTemporaryExpr());
default: default:
break; break;
} }

1
src/CppParser/Parser.h

@ -98,6 +98,7 @@ protected:
PreprocessedEntity* WalkPreprocessedEntity(Declaration* Decl, PreprocessedEntity* WalkPreprocessedEntity(Declaration* Decl,
clang::PreprocessedEntity* PPEntity); clang::PreprocessedEntity* PPEntity);
AST::Expression* WalkExpression(clang::Expr* Expression); AST::Expression* WalkExpression(clang::Expr* Expression);
AST::Expression* WalkExpressionEx(clang::Expr* Expression);
std::string GetStringFromStatement(const clang::Stmt* Statement); std::string GetStringFromStatement(const clang::Stmt* Statement);
// Clang helpers // Clang helpers

117
src/Generator/Passes/HandleDefaultParamValuesPass.cs

@ -15,6 +15,7 @@ namespace CppSharp.Passes
private static readonly Regex regexFunctionParams = new Regex(@"\(?(.+)\)?", RegexOptions.Compiled); private static readonly Regex regexFunctionParams = new Regex(@"\(?(.+)\)?", RegexOptions.Compiled);
private static readonly Regex regexDoubleColon = new Regex(@"\w+::", RegexOptions.Compiled); private static readonly Regex regexDoubleColon = new Regex(@"\w+::", RegexOptions.Compiled);
private static readonly Regex regexName = new Regex(@"(\w+)", RegexOptions.Compiled); private static readonly Regex regexName = new Regex(@"(\w+)", RegexOptions.Compiled);
private static readonly Regex regexCtor = new Regex(@"^(\w+)\s*\(\w*\)$", RegexOptions.Compiled);
public override bool VisitFunctionDecl(Function function) public override bool VisitFunctionDecl(Function function)
{ {
@ -44,10 +45,7 @@ namespace CppSharp.Passes
if (CheckForEnumValue(parameter.DefaultArgument, desugared)) if (CheckForEnumValue(parameter.DefaultArgument, desugared))
continue; continue;
CheckForAnonExpression(desugared, parameter);
CheckForDefaultEmptyChar(parameter, desugared); CheckForDefaultEmptyChar(parameter, desugared);
} }
GenerateOverloads(function, overloadIndices); GenerateOverloads(function, overloadIndices);
@ -64,21 +62,6 @@ namespace CppSharp.Passes
} }
} }
private bool CheckForAnonExpression(Type desugared, Parameter parameter)
{
var cast = parameter.DefaultArgument as CastExpr;
if (cast != null)
{
if (cast.SubExpression is BuiltinTypeExpression)
{
// The output string is correct in the deepest expression. Copy it to the outernmost.
cast.String = cast.SubExpression.String;
return true;
}
}
return true;
}
private static bool CheckForDefaultPointer(Type desugared, Parameter parameter) private static bool CheckForDefaultPointer(Type desugared, Parameter parameter)
{ {
if (desugared.IsPointer()) if (desugared.IsPointer())
@ -93,30 +76,6 @@ namespace CppSharp.Passes
private bool? CheckForDefaultConstruct(Type desugared, Expression arg) private bool? CheckForDefaultConstruct(Type desugared, Expression arg)
{ {
// Unwrapping the constructor and a possible cast
Method ctor = null;
CastExpr castExpression = null;
CtorExpr ctorExpression = null;
if (arg is CtorExpr)
{
ctorExpression = (CtorExpr)arg;
ctor = (Method)ctorExpression.Declaration;
}
else if (arg is CastExpr && ((CastExpr)arg).SubExpression is CtorExpr)
{
castExpression = (CastExpr)arg;
ctorExpression = (CtorExpr)castExpression.SubExpression;
ctor = (Method)ctorExpression.Declaration;
}
else
{
return false;
}
var innerArg = ctorExpression.SubExpression;
if (ctor == null || !ctor.IsConstructor)
return false;
// Unwrapping the underlying type behind a possible pointer/reference // Unwrapping the underlying type behind a possible pointer/reference
Type type; Type type;
desugared.IsPointerTo(out type); desugared.IsPointerTo(out type);
@ -126,6 +85,8 @@ namespace CppSharp.Passes
if (!type.TryGetClass(out decl)) if (!type.TryGetClass(out decl))
return false; return false;
var ctor = arg.Declaration as Method;
TypeMap typeMap; TypeMap typeMap;
if (Driver.TypeDatabase.FindTypeMap(decl, type, out typeMap)) if (Driver.TypeDatabase.FindTypeMap(decl, type, out typeMap))
{ {
@ -153,20 +114,11 @@ namespace CppSharp.Passes
Enumeration @enum; Enumeration @enum;
if (typeInSignature.TryGetEnum(out @enum)) if (typeInSignature.TryGetEnum(out @enum))
{ {
var argCast = (CastExpr)arg; return false;
Expression literal = ((CtorExpr)argCast.SubExpression).SubExpression;
if (CheckForEnumValue(literal, desugared))
{
argCast.String = literal.String;
argCast.SubExpression.String = literal.String;
return true;
}
else
{
return false;
}
} }
if (ctor == null || !ctor.IsConstructor)
return false;
if (mappedTo == "string" && ctor.Parameters.Count == 0) if (mappedTo == "string" && ctor.Parameters.Count == 0)
{ {
arg.String = "\"\""; arg.String = "\"\"";
@ -174,23 +126,24 @@ namespace CppSharp.Passes
} }
} }
if (innerArg is CtorExpr || innerArg is CastExpr) if (regexCtor.IsMatch(arg.String))
{ {
Type innerDesugared = ctor.Parameters[0].Type.Desugar(); arg.String = string.Format("new {0}", arg.String);
CheckForDefaultConstruct(innerDesugared, innerArg); if (ctor != null && ctor.Parameters.Count > 0 && ctor.Parameters[0].Type.IsAddress())
if (innerDesugared.IsPointer() && innerArg.String == "0") {
innerArg.String = ""; arg.String = arg.String.Replace("(0)", "()");
arg.String = string.Format("new {0}({1})", ctor.Name, innerArg.String); return decl.IsValueType ? true : (bool?) null;
} }
else if (innerArg != null)
{
Type innerDesugared = ctor.Parameters[0].Type.Desugar();
CheckForEnumValue(innerArg, innerDesugared);
arg.String = string.Format("new {0}({1})", ctor.Name, innerArg.String);
} }
else else
{ {
arg.String = string.Format("new {0}()", ctor.Name); if (ctor != null && ctor.Parameters.Count > 0)
{
var finalPointee = ctor.Parameters[0].Type.SkipPointerRefs().Desugar();
Enumeration @enum;
if (finalPointee.TryGetEnum(out @enum))
TranslateEnumExpression(arg, finalPointee, arg.String);
}
} }
return decl.IsValueType ? true : (bool?) null; return decl.IsValueType ? true : (bool?) null;
@ -198,16 +151,7 @@ namespace CppSharp.Passes
private static bool CheckForEnumValue(Expression arg, Type desugared) private static bool CheckForEnumValue(Expression arg, Type desugared)
{ {
// Handle a simple cast (between int and enum, for example) var enumItem = arg.Declaration as Enumeration.Item;
var argCast = arg as CastExpr;
Expression literal;
if (argCast != null)
literal = argCast.SubExpression;
else
literal = arg;
// The default case
var enumItem = literal.Declaration as Enumeration.Item;
if (enumItem != null) if (enumItem != null)
{ {
arg.String = string.Format("{0}{1}{2}.{3}", arg.String = string.Format("{0}{1}{2}.{3}",
@ -217,20 +161,25 @@ namespace CppSharp.Passes
: enumItem.Namespace.Namespace.Name + ".", enumItem.Namespace.Name, enumItem.Name); : enumItem.Namespace.Namespace.Name + ".", enumItem.Namespace.Name, enumItem.Name);
return true; return true;
} }
// Handle cases like "Flags::Flag1 | Flags::Flag2"
var call = arg.Declaration as Function; var call = arg.Declaration as Function;
if ((call != null && call.ReturnType.Type.IsEnum()) || arg.Class == StatementClass.BinaryOperator) if ((call != null || arg.Class == StatementClass.BinaryOperator) && arg.String != "0")
{ {
string @params = regexFunctionParams.Match(arg.String).Groups[1].Value; string @params = regexFunctionParams.Match(arg.String).Groups[1].Value;
if (@params.Contains("::")) TranslateEnumExpression(arg, desugared, @params);
arg.String = regexDoubleColon.Replace(@params, desugared + ".");
else
arg.String = regexName.Replace(@params, desugared + ".$1");
return true; return true;
} }
return false; return false;
} }
private static void TranslateEnumExpression(Expression arg, Type desugared, string @params)
{
if (@params.Contains("::"))
arg.String = regexDoubleColon.Replace(@params, desugared + ".");
else
arg.String = regexName.Replace(@params, desugared + ".$1");
}
private void CheckForDefaultEmptyChar(Parameter parameter, Type desugared) private void CheckForDefaultEmptyChar(Parameter parameter, Type desugared)
{ {
if (parameter.DefaultArgument.String == "0" && Driver.Options.MarshalCharAsManagedChar && if (parameter.DefaultArgument.String == "0" && Driver.Options.MarshalCharAsManagedChar &&

Loading…
Cancel
Save