Browse Source

Merge pull request #363 from ddobrev/master

Improved the handling of numeric default values
pull/364/head
João Matos 11 years ago
parent
commit
1793061de5
  1. 33
      src/CppParser/Parser.cpp
  2. 2
      src/CppParser/Parser.h
  3. 14
      src/Generator/Passes/HandleDefaultParamValuesPass.cs
  4. 6
      tests/CSharpTemp/CSharpTemp.cpp
  5. 3
      tests/CSharpTemp/CSharpTemp.h

33
src/CppParser/Parser.cpp

@ -2216,7 +2216,7 @@ void Parser::WalkFunction(clang::FunctionDecl* FD, Function* F,
P->Index = VD->getFunctionScopeIndex(); P->Index = VD->getFunctionScopeIndex();
if (VD->hasDefaultArg() && !VD->hasUnparsedDefaultArg() && !VD->hasUninstantiatedDefaultArg()) if (VD->hasDefaultArg() && !VD->hasUnparsedDefaultArg() && !VD->hasUninstantiatedDefaultArg())
{ {
P->DefaultArgument = WalkStatement(VD->getDefaultArg()); P->DefaultArgument = WalkExpression(VD->getDefaultArg());
} }
HandleDeclaration(VD, P); HandleDeclaration(VD, P);
@ -2493,17 +2493,17 @@ void Parser::HandlePreprocessedEntities(Declaration* Decl)
} }
} }
AST::Expression* Parser::WalkStatement(clang::Stmt* Statement) AST::Expression* Parser::WalkExpression(clang::Expr* Expr)
{ {
using namespace clang; using namespace clang;
switch (Statement->getStmtClass()) switch (Expr->getStmtClass())
{ {
case Stmt::BinaryOperatorClass: case Stmt::BinaryOperatorClass:
return new AST::Expression(GetStringFromStatement(Statement), StatementClass::BinaryOperator); return new AST::Expression(GetStringFromStatement(Expr), StatementClass::BinaryOperator);
case Stmt::DeclRefExprClass: case Stmt::DeclRefExprClass:
return new AST::Expression(GetStringFromStatement(Statement), StatementClass::DeclRefExprClass, return new AST::Expression(GetStringFromStatement(Expr), StatementClass::DeclRefExprClass,
WalkDeclaration(cast<DeclRefExpr>(Statement)->getDecl())); WalkDeclaration(cast<DeclRefExpr>(Expr)->getDecl()));
case Stmt::CStyleCastExprClass: case Stmt::CStyleCastExprClass:
case Stmt::CXXConstCastExprClass: case Stmt::CXXConstCastExprClass:
case Stmt::CXXDynamicCastExprClass: case Stmt::CXXDynamicCastExprClass:
@ -2511,14 +2511,14 @@ AST::Expression* Parser::WalkStatement(clang::Stmt* Statement)
case Stmt::CXXReinterpretCastExprClass: case Stmt::CXXReinterpretCastExprClass:
case Stmt::CXXStaticCastExprClass: case Stmt::CXXStaticCastExprClass:
case Stmt::ImplicitCastExprClass: case Stmt::ImplicitCastExprClass:
return WalkStatement(cast<CastExpr>(Statement)->getSubExprAsWritten()); return WalkExpression(cast<CastExpr>(Expr)->getSubExprAsWritten());
case Stmt::CXXOperatorCallExprClass: case Stmt::CXXOperatorCallExprClass:
return new AST::Expression(GetStringFromStatement(Statement), StatementClass::CXXOperatorCallExpr, return new AST::Expression(GetStringFromStatement(Expr), StatementClass::CXXOperatorCallExpr,
WalkDeclaration(cast<CXXOperatorCallExpr>(Statement)->getCalleeDecl())); WalkDeclaration(cast<CXXOperatorCallExpr>(Expr)->getCalleeDecl()));
case Stmt::CXXConstructExprClass: case Stmt::CXXConstructExprClass:
case Stmt::CXXTemporaryObjectExprClass: case Stmt::CXXTemporaryObjectExprClass:
{ {
auto ConstructorExpr = cast<CXXConstructExpr>(Statement); auto ConstructorExpr = cast<CXXConstructExpr>(Expr);
if (ConstructorExpr->getNumArgs() == 1) if (ConstructorExpr->getNumArgs() == 1)
{ {
auto Arg = ConstructorExpr->getArg(0); auto Arg = ConstructorExpr->getArg(0);
@ -2527,18 +2527,23 @@ AST::Expression* Parser::WalkStatement(clang::Stmt* Statement)
{ {
auto Cast = dyn_cast<CastExpr>(TemporaryExpr->GetTemporaryExpr()); auto Cast = dyn_cast<CastExpr>(TemporaryExpr->GetTemporaryExpr());
if (Cast && Cast->getSubExprAsWritten()->getStmtClass() != Stmt::IntegerLiteralClass) if (Cast && Cast->getSubExprAsWritten()->getStmtClass() != Stmt::IntegerLiteralClass)
return WalkStatement(Cast->getSubExprAsWritten()); return WalkExpression(Cast->getSubExprAsWritten());
} }
} }
return new AST::Expression(GetStringFromStatement(Statement), StatementClass::CXXConstructExprClass, return new AST::Expression(GetStringFromStatement(Expr), StatementClass::CXXConstructExprClass,
WalkDeclaration(ConstructorExpr->getConstructor())); WalkDeclaration(ConstructorExpr->getConstructor()));
} }
case Stmt::MaterializeTemporaryExprClass: case Stmt::MaterializeTemporaryExprClass:
return WalkStatement(cast<MaterializeTemporaryExpr>(Statement)->GetTemporaryExpr()); return WalkExpression(cast<MaterializeTemporaryExpr>(Expr)->GetTemporaryExpr());
default: default:
break; break;
} }
return new AST::Expression(GetStringFromStatement(Statement)); 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));
} }
std::string Parser::GetStringFromStatement(const clang::Stmt* Statement) std::string Parser::GetStringFromStatement(const clang::Stmt* Statement)

2
src/CppParser/Parser.h

@ -97,7 +97,7 @@ protected:
VTableComponent WalkVTableComponent(const clang::VTableComponent& Component); VTableComponent WalkVTableComponent(const clang::VTableComponent& Component);
PreprocessedEntity* WalkPreprocessedEntity(Declaration* Decl, PreprocessedEntity* WalkPreprocessedEntity(Declaration* Decl,
clang::PreprocessedEntity* PPEntity); clang::PreprocessedEntity* PPEntity);
AST::Expression* WalkStatement(clang::Stmt* Statement); AST::Expression* WalkExpression(clang::Expr* Expression);
std::string GetStringFromStatement(const clang::Stmt* Statement); std::string GetStringFromStatement(const clang::Stmt* Statement);
// Clang helpers // Clang helpers

14
src/Generator/Passes/HandleDefaultParamValuesPass.cs

@ -1,5 +1,4 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using CppSharp.AST; using CppSharp.AST;
@ -43,8 +42,6 @@ namespace CppSharp.Passes
if (CheckForEnumValue(parameter, desugared)) if (CheckForEnumValue(parameter, desugared))
continue; continue;
CheckForULongValue(parameter, desugared);
CheckForDefaultEmptyChar(parameter, desugared); CheckForDefaultEmptyChar(parameter, desugared);
} }
@ -139,17 +136,6 @@ namespace CppSharp.Passes
return false; return false;
} }
private static void CheckForULongValue(Parameter parameter, Type desugared)
{
ulong value;
string @default = parameter.DefaultArgument.String;
// HACK: .NET's Parse/TryParse have a bug preventing them from parsing UL-suffixed ulongs
if (desugared.IsPrimitiveType() && @default.EndsWith("UL"))
@default = @default.Substring(0, @default.Length - 2);
if (ulong.TryParse(@default, out value))
parameter.DefaultArgument.String = value.ToString(CultureInfo.InvariantCulture);
}
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 &&

6
tests/CSharpTemp/CSharpTemp.cpp

@ -285,6 +285,10 @@ void MethodsWithDefaultValues::defaultMappedToEnum(QFlags<Flags> qFlags)
{ {
} }
void MethodsWithDefaultValues::defaultIntWithLongExpression(unsigned int i)
{
}
void HasPrivateOverrideBase::privateOverride(int i) void HasPrivateOverrideBase::privateOverride(int i)
{ {
} }
@ -301,4 +305,4 @@ IgnoredType<int> PropertyWithIgnoredType::ignoredType()
void PropertyWithIgnoredType::setIgnoredType(const IgnoredType<int> &value) void PropertyWithIgnoredType::setIgnoredType(const IgnoredType<int> &value)
{ {
_ignoredType = value; _ignoredType = value;
} }

3
tests/CSharpTemp/CSharpTemp.h

@ -212,6 +212,8 @@ private:
const char* _name; const char* _name;
}; };
#define DEFAULT_INT (2 * 1000UL + 500UL)
class DLL_API MethodsWithDefaultValues class DLL_API MethodsWithDefaultValues
{ {
public: public:
@ -231,6 +233,7 @@ public:
void defaultEnumAssignedBitwiseOrShort(UntypedFlags flags = Flag1 | Flag2); void defaultEnumAssignedBitwiseOrShort(UntypedFlags flags = Flag1 | Flag2);
void defaultNonEmptyCtor(QGenericArgument arg = QGenericArgument(0)); void defaultNonEmptyCtor(QGenericArgument arg = QGenericArgument(0));
void defaultMappedToEnum(QFlags<Flags> qFlags = Flags::Flag1); void defaultMappedToEnum(QFlags<Flags> qFlags = Flags::Flag1);
void defaultIntWithLongExpression(unsigned int i = DEFAULT_INT);
}; };
class DLL_API HasPrivateOverrideBase class DLL_API HasPrivateOverrideBase

Loading…
Cancel
Save