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) @@ -2499,6 +2499,59 @@ AST::Expression* Parser::WalkExpression(clang::Expr* Expr)
{
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())
{
case Stmt::BinaryOperatorClass:
@ -2514,11 +2567,11 @@ AST::Expression* Parser::WalkExpression(clang::Expr* Expr) @@ -2514,11 +2567,11 @@ AST::Expression* Parser::WalkExpression(clang::Expr* Expr)
case Stmt::CXXStaticCastExprClass:
return new AST::Expression(GetStringFromStatement(Expr), StatementClass::ExplicitCastExpr,
0,
WalkExpression(cast<CastExpr>(Expr)->getSubExpr()));
WalkExpressionEx(cast<CastExpr>(Expr)->getSubExpr()));
case Stmt::ImplicitCastExprClass:
return new AST::Expression(GetStringFromStatement(Expr), StatementClass::ImplicitCastExpr,
0,
WalkExpression(cast<CastExpr>(Expr)->getSubExpr()));
WalkExpressionEx(cast<CastExpr>(Expr)->getSubExpr()));
case Stmt::CXXOperatorCallExprClass:
return new AST::Expression(GetStringFromStatement(Expr), StatementClass::CXXOperatorCallExpr,
WalkDeclaration(cast<CXXOperatorCallExpr>(Expr)->getCalleeDecl()));
@ -2530,13 +2583,13 @@ AST::Expression* Parser::WalkExpression(clang::Expr* Expr) @@ -2530,13 +2583,13 @@ AST::Expression* Parser::WalkExpression(clang::Expr* Expr)
{
if (ConstructorExpr->isElidable())
{
return WalkExpression(ConstructorExpr->getArg(0));
return WalkExpressionEx(ConstructorExpr->getArg(0));
}
else
{
return new AST::Expression(GetStringFromStatement(Expr), StatementClass::CXXConstructExprClass,
WalkDeclaration(ConstructorExpr->getConstructor()),
WalkExpression(ConstructorExpr->getArg(0)));
WalkExpressionEx(ConstructorExpr->getArg(0)));
}
}
else
@ -2546,7 +2599,7 @@ AST::Expression* Parser::WalkExpression(clang::Expr* Expr) @@ -2546,7 +2599,7 @@ AST::Expression* Parser::WalkExpression(clang::Expr* Expr)
}
}
case Stmt::MaterializeTemporaryExprClass:
return WalkExpression(cast<MaterializeTemporaryExpr>(Expr)->GetTemporaryExpr());
return WalkExpressionEx(cast<MaterializeTemporaryExpr>(Expr)->GetTemporaryExpr());
default:
break;
}

1
src/CppParser/Parser.h

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

117
src/Generator/Passes/HandleDefaultParamValuesPass.cs

@ -15,6 +15,7 @@ namespace CppSharp.Passes @@ -15,6 +15,7 @@ namespace CppSharp.Passes
private static readonly Regex regexFunctionParams = new Regex(@"\(?(.+)\)?", 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 regexCtor = new Regex(@"^(\w+)\s*\(\w*\)$", RegexOptions.Compiled);
public override bool VisitFunctionDecl(Function function)
{
@ -44,10 +45,7 @@ namespace CppSharp.Passes @@ -44,10 +45,7 @@ namespace CppSharp.Passes
if (CheckForEnumValue(parameter.DefaultArgument, desugared))
continue;
CheckForAnonExpression(desugared, parameter);
CheckForDefaultEmptyChar(parameter, desugared);
}
GenerateOverloads(function, overloadIndices);
@ -64,21 +62,6 @@ namespace CppSharp.Passes @@ -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)
{
if (desugared.IsPointer())
@ -93,30 +76,6 @@ namespace CppSharp.Passes @@ -93,30 +76,6 @@ namespace CppSharp.Passes
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
Type type;
desugared.IsPointerTo(out type);
@ -126,6 +85,8 @@ namespace CppSharp.Passes @@ -126,6 +85,8 @@ namespace CppSharp.Passes
if (!type.TryGetClass(out decl))
return false;
var ctor = arg.Declaration as Method;
TypeMap typeMap;
if (Driver.TypeDatabase.FindTypeMap(decl, type, out typeMap))
{
@ -153,20 +114,11 @@ namespace CppSharp.Passes @@ -153,20 +114,11 @@ namespace CppSharp.Passes
Enumeration @enum;
if (typeInSignature.TryGetEnum(out @enum))
{
var argCast = (CastExpr)arg;
Expression literal = ((CtorExpr)argCast.SubExpression).SubExpression;
if (CheckForEnumValue(literal, desugared))
{
argCast.String = literal.String;
argCast.SubExpression.String = literal.String;
return true;
}
else
{
return false;
}
return false;
}
if (ctor == null || !ctor.IsConstructor)
return false;
if (mappedTo == "string" && ctor.Parameters.Count == 0)
{
arg.String = "\"\"";
@ -174,23 +126,24 @@ namespace CppSharp.Passes @@ -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();
CheckForDefaultConstruct(innerDesugared, innerArg);
if (innerDesugared.IsPointer() && innerArg.String == "0")
innerArg.String = "";
arg.String = string.Format("new {0}({1})", ctor.Name, innerArg.String);
}
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);
arg.String = string.Format("new {0}", arg.String);
if (ctor != null && ctor.Parameters.Count > 0 && ctor.Parameters[0].Type.IsAddress())
{
arg.String = arg.String.Replace("(0)", "()");
return decl.IsValueType ? true : (bool?) null;
}
}
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;
@ -198,16 +151,7 @@ namespace CppSharp.Passes @@ -198,16 +151,7 @@ namespace CppSharp.Passes
private static bool CheckForEnumValue(Expression arg, Type desugared)
{
// Handle a simple cast (between int and enum, for example)
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;
var enumItem = arg.Declaration as Enumeration.Item;
if (enumItem != null)
{
arg.String = string.Format("{0}{1}{2}.{3}",
@ -217,20 +161,25 @@ namespace CppSharp.Passes @@ -217,20 +161,25 @@ namespace CppSharp.Passes
: enumItem.Namespace.Namespace.Name + ".", enumItem.Namespace.Name, enumItem.Name);
return true;
}
// Handle cases like "Flags::Flag1 | Flags::Flag2"
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;
if (@params.Contains("::"))
arg.String = regexDoubleColon.Replace(@params, desugared + ".");
else
arg.String = regexName.Replace(@params, desugared + ".$1");
TranslateEnumExpression(arg, desugared, @params);
return true;
}
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)
{
if (parameter.DefaultArgument.String == "0" && Driver.Options.MarshalCharAsManagedChar &&

Loading…
Cancel
Save