Browse Source

Removed functions made ambiguous by different qualifiers on the same type in their parameter.

Signed-off-by: Dimitar Dobrev <dpldobrev@protonmail.com>
pull/696/head
Dimitar Dobrev 9 years ago
parent
commit
deea8d8cda
  1. 10
      src/AST/Function.cs
  2. 8
      src/CppParser/Parser.cpp
  3. 2
      src/CppParser/Parser.h
  4. 5
      src/Generator.Tests/AST/TestAST.cs
  5. 80
      src/Generator/Passes/CheckAmbiguousFunctions.cs
  6. 22
      tests/Common/Common.cpp
  7. 1
      tests/Common/Common.cs
  8. 9
      tests/Common/Common.h

10
src/AST/Function.cs

@ -74,6 +74,16 @@ namespace CppSharp.AST @@ -74,6 +74,16 @@ namespace CppSharp.AST
{
return visitor.VisitParameterDecl(this);
}
/// <summary>
/// HACK: in many cases QualifiedType.Qualifiers.IsConst does not work.
/// It's false in Clang to begin with. I tried fixing it to no avail.
/// I don't have any more time at the moment.
/// </summary>
public bool IsConst
{
get { return DebugText.StartsWith("const ", System.StringComparison.Ordinal); }
}
}
public class ParameterTypeComparer : IEqualityComparer<Parameter>

8
src/CppParser/Parser.cpp

@ -568,7 +568,7 @@ std::string Parser::GetTypeName(const clang::Type* Type) @@ -568,7 +568,7 @@ std::string Parser::GetTypeName(const clang::Type* Type)
return TypeName;
}
static TypeQualifiers GetTypeQualifiers(clang::QualType Type)
static TypeQualifiers GetTypeQualifiers(const clang::QualType& Type)
{
TypeQualifiers quals;
quals.IsConst = Type.isLocalConstQualified();
@ -577,7 +577,7 @@ static TypeQualifiers GetTypeQualifiers(clang::QualType Type) @@ -577,7 +577,7 @@ static TypeQualifiers GetTypeQualifiers(clang::QualType Type)
return quals;
}
QualifiedType Parser::GetQualifiedType(clang::QualType qual, clang::TypeLoc* TL)
QualifiedType Parser::GetQualifiedType(const clang::QualType& qual, clang::TypeLoc* TL)
{
QualifiedType qualType;
qualType.Type = WalkType(qual, TL);
@ -2276,7 +2276,7 @@ Type* Parser::WalkType(clang::QualType QualType, clang::TypeLoc* TL, @@ -2276,7 +2276,7 @@ Type* Parser::WalkType(clang::QualType QualType, clang::TypeLoc* TL,
auto PTL = PVD->getTypeSourceInfo()->getTypeLoc();
FA->Name = PVD->getNameAsString();
FA->QualifiedType = GetQualifiedType(PVD->getType(), &PTL);
FA->QualifiedType = GetQualifiedType(PVD->getOriginalType(), &PTL);
}
else
{
@ -2807,7 +2807,7 @@ void Parser::WalkFunction(const clang::FunctionDecl* FD, Function* F, @@ -2807,7 +2807,7 @@ void Parser::WalkFunction(const clang::FunctionDecl* FD, Function* F,
HandlePreprocessedEntities(P, paramRange, MacroLocation::FunctionParameters);
P->QualifiedType = GetQualifiedType(VD->getType(), &PTL);
P->QualifiedType = GetQualifiedType(VD->getOriginalType(), &PTL);
P->HasDefaultValue = VD->hasDefaultArg();
P->_Namespace = NS;
P->Index = VD->getFunctionScopeIndex();

2
src/CppParser/Parser.h

@ -103,7 +103,7 @@ private: @@ -103,7 +103,7 @@ private:
std::vector<TemplateArgument> WalkTemplateArgumentList(const clang::TemplateArgumentList* TAL, clang::TemplateSpecializationTypeLoc* TSTL);
std::vector<TemplateArgument> WalkTemplateArgumentList(const clang::TemplateArgumentList* TAL, const clang::ASTTemplateArgumentListInfo* TSTL);
void WalkVTable(const clang::CXXRecordDecl* RD, Class* C);
QualifiedType GetQualifiedType(clang::QualType qual, clang::TypeLoc* TL = 0);
QualifiedType GetQualifiedType(const clang::QualType& qual, clang::TypeLoc* TL = 0);
void ReadClassLayout(Class* Class, const clang::RecordDecl* RD, clang::CharUnits Offset, bool IncludeVirtualBases);
LayoutField WalkVTablePointer(Class* Class, const clang::CharUnits& Offset, const std::string& prefix);
VTableLayout WalkVTableLayout(const clang::VTableLayout& VTLayout);

5
src/Generator.Tests/AST/TestAST.cs

@ -19,11 +19,6 @@ namespace CppSharp.Generator.Tests.AST @@ -19,11 +19,6 @@ namespace CppSharp.Generator.Tests.AST
PrimitiveType primitiveType;
return type.IsPrimitiveType(out primitiveType) ? primitiveType.ToString() : string.Empty;
};
}
[SetUp]
public void Setup()
{
ParseLibrary("AST.h", "ASTExtensions.h");
}

80
src/Generator/Passes/CheckAmbiguousFunctions.cs

@ -1,22 +1,36 @@ @@ -1,22 +1,36 @@
using System;
using System.Linq;
using CppSharp.AST;
using CppSharp.AST.Extensions;
namespace CppSharp.Passes
{
/// <summary>
/// Checks for ambiguous functions/method declarations.
/// <para/>
/// Example:
///
/// <para/>
/// struct S
/// <para/>
/// {
/// <para/>
/// void Foo(int a, int b = 0);
/// <para/>
/// void Foo(int a);
///
/// <para/>
/// void Bar();
/// <para/>
/// void Bar() const;
/// };
///
/// <para/>
/// void Qux(int&amp; i);
/// <para/>
/// void Qux(int&amp;&amp; i);
/// <para/>
/// void Qux(const int&amp; i);
/// <para/>
/// };
/// <para/>
/// When we call Foo(0) the compiler will not know which call we want and
/// will error out so we need to detect this and either ignore the methods
/// or flag them such that the generator can explicitly disambiguate when
@ -46,7 +60,8 @@ namespace CppSharp.Passes @@ -46,7 +60,8 @@ namespace CppSharp.Passes
if (!overload.IsGenerated) continue;
if (CheckConstnessForAmbiguity(function, overload) ||
CheckDefaultParametersForAmbiguity(function, overload))
CheckDefaultParametersForAmbiguity(function, overload) ||
CheckSingleParameterPointerConstnessForAmbiguity(function, overload))
{
function.IsAmbiguous = true;
overload.IsAmbiguous = true;
@ -120,5 +135,62 @@ namespace CppSharp.Passes @@ -120,5 +135,62 @@ namespace CppSharp.Passes
return false;
}
private static bool CheckSingleParameterPointerConstnessForAmbiguity(
Function function, Function overload)
{
var functionParams = function.Parameters.Where(
p => p.Kind == ParameterKind.Regular && p.Type.IsAddress()).ToList();
// It's difficult to handle this case for more than one parameter
// For example, if we have:
// void f(float&, const int&);
// void f(const float&, int&);
// what should we do? Generate both? Generate the first one encountered?
// Generate the one with the least amount of "complex" parameters?
// So let's just start with the simplest case for the time being
if (functionParams.Count != 1)
return false;
var overloadParams = overload.Parameters.Where(
p => p.Kind == ParameterKind.Regular && p.Type.IsAddress()).ToList();
if (overloadParams.Count != 1)
return false;
var parameterFunction = functionParams[0];
var parameterOverload = overloadParams[0];
if (!parameterFunction.Type.GetPointee().Equals(parameterOverload.Type.GetPointee()))
return false;
if (parameterFunction.IsConst && !parameterOverload.IsConst)
{
function.ExplicitlyIgnore();
return true;
}
if (parameterOverload.IsConst && !parameterFunction.IsConst)
{
overload.ExplicitlyIgnore();
return true;
}
var pointerParamFunction = (PointerType) parameterFunction.Type;
var pointerParamOverload = (PointerType) parameterOverload.Type;
if (pointerParamFunction.Modifier == PointerType.TypeModifier.RVReference &&
pointerParamOverload.Modifier != PointerType.TypeModifier.RVReference)
{
function.ExplicitlyIgnore();
return true;
}
if (pointerParamFunction.Modifier != PointerType.TypeModifier.RVReference &&
pointerParamOverload.Modifier == PointerType.TypeModifier.RVReference)
{
overload.ExplicitlyIgnore();
return true;
}
return false;
}
}
}

22
tests/Common/Common.cpp

@ -626,4 +626,24 @@ void FuncWithTypeAlias(custom_int_t i) @@ -626,4 +626,24 @@ void FuncWithTypeAlias(custom_int_t i)
void FuncWithTemplateTypeAlias(TypeAliasTemplate<int> i)
{
}
}
HasOverloadsWithDifferentPointerKindsToSameType::HasOverloadsWithDifferentPointerKindsToSameType()
{
}
HasOverloadsWithDifferentPointerKindsToSameType::~HasOverloadsWithDifferentPointerKindsToSameType()
{
}
void HasOverloadsWithDifferentPointerKindsToSameType::overload(int& i)
{
}
void HasOverloadsWithDifferentPointerKindsToSameType::overload(int&& i)
{
}
void HasOverloadsWithDifferentPointerKindsToSameType::overload(const int& i)
{
}

1
tests/Common/Common.cs

@ -56,6 +56,7 @@ namespace CppSharp.Tests @@ -56,6 +56,7 @@ namespace CppSharp.Tests
base.Setup(driver);
driver.Options.OutputNamespace = "CommonTest";
driver.Options.UnityBuild = true;
}
public override void SetupPasses(Driver driver)

9
tests/Common/Common.h

@ -1202,3 +1202,12 @@ enum @@ -1202,3 +1202,12 @@ enum
EmptyEnumsWithSameMemberPrefixAndUnderscore_4
};
class DLL_API HasOverloadsWithDifferentPointerKindsToSameType
{
public:
HasOverloadsWithDifferentPointerKindsToSameType();
~HasOverloadsWithDifferentPointerKindsToSameType();
void overload(int& i);
void overload(int&& i);
void overload(const int& i);
};

Loading…
Cancel
Save