summaryrefslogtreecommitdiffstats
path: root/source/slang/check.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/check.cpp')
-rw-r--r--source/slang/check.cpp454
1 files changed, 291 insertions, 163 deletions
diff --git a/source/slang/check.cpp b/source/slang/check.cpp
index cc2954fc4..ce9b2de55 100644
--- a/source/slang/check.cpp
+++ b/source/slang/check.cpp
@@ -140,14 +140,14 @@ namespace Slang
}
RefPtr<Expr> ConstructDeclRefExpr(
- DeclRef<Decl> declRef,
+ DeclRef<Decl> declRef,
RefPtr<Expr> baseExpr,
- RefPtr<Expr> originalExpr)
+ SourceLoc loc)
{
if (baseExpr)
{
auto expr = new MemberExpr();
- expr->loc = originalExpr->loc;
+ expr->loc = loc;
expr->BaseExpression = baseExpr;
expr->name = declRef.GetName();
expr->type = GetTypeForDeclRef(declRef);
@@ -157,7 +157,7 @@ namespace Slang
else
{
auto expr = new VarExpr();
- expr->loc = originalExpr->loc;
+ expr->loc = loc;
expr->name = declRef.GetName();
expr->type = GetTypeForDeclRef(declRef);
expr->declRef = declRef;
@@ -166,14 +166,14 @@ namespace Slang
}
RefPtr<Expr> ConstructDerefExpr(
- RefPtr<Expr> base,
- RefPtr<Expr> originalExpr)
+ RefPtr<Expr> base,
+ SourceLoc loc)
{
auto ptrLikeType = base->type->As<PointerLikeType>();
SLANG_ASSERT(ptrLikeType);
auto derefExpr = new DerefExpr();
- derefExpr->loc = originalExpr->loc;
+ derefExpr->loc = loc;
derefExpr->base = base;
derefExpr->type = QualType(ptrLikeType->elementType);
@@ -183,9 +183,9 @@ namespace Slang
}
RefPtr<Expr> ConstructLookupResultExpr(
- LookupResultItem const& item,
- RefPtr<Expr> baseExpr,
- RefPtr<Expr> originalExpr)
+ LookupResultItem const& item,
+ RefPtr<Expr> baseExpr,
+ SourceLoc loc)
{
// If we collected any breadcrumbs, then these represent
// additional segments of the lookup path that we need
@@ -196,28 +196,28 @@ namespace Slang
switch (breadcrumb->kind)
{
case LookupResultItem::Breadcrumb::Kind::Member:
- bb = ConstructDeclRefExpr(breadcrumb->declRef, bb, originalExpr);
+ bb = ConstructDeclRefExpr(breadcrumb->declRef, bb, loc);
break;
case LookupResultItem::Breadcrumb::Kind::Deref:
- bb = ConstructDerefExpr(bb, originalExpr);
+ bb = ConstructDerefExpr(bb, loc);
break;
default:
SLANG_UNREACHABLE("all cases handle");
}
}
- return ConstructDeclRefExpr(item.declRef, bb, originalExpr);
+ return ConstructDeclRefExpr(item.declRef, bb, loc);
}
RefPtr<Expr> createLookupResultExpr(
- LookupResult const& lookupResult,
- RefPtr<Expr> baseExpr,
- RefPtr<Expr> originalExpr)
+ LookupResult const& lookupResult,
+ RefPtr<Expr> baseExpr,
+ SourceLoc loc)
{
if (lookupResult.isOverloaded())
{
auto overloadedExpr = new OverloadedExpr();
- overloadedExpr->loc = originalExpr->loc;
+ overloadedExpr->loc = loc;
overloadedExpr->type = QualType(
getSession()->getOverloadedType());
overloadedExpr->base = baseExpr;
@@ -226,7 +226,7 @@ namespace Slang
}
else
{
- return ConstructLookupResultExpr(lookupResult.item, baseExpr, originalExpr);
+ return ConstructLookupResultExpr(lookupResult.item, baseExpr, loc);
}
}
@@ -264,7 +264,7 @@ namespace Slang
}
// otherwise, we had a single decl and it was valid, hooray!
- return ConstructLookupResultExpr(lookupResult.item, overloadedExpr->base, overloadedExpr);
+ return ConstructLookupResultExpr(lookupResult.item, overloadedExpr->base, overloadedExpr->loc);
}
RefPtr<Expr> ExpectATypeRepr(RefPtr<Expr> expr)
@@ -583,90 +583,6 @@ namespace Slang
public:
- typedef unsigned int ConversionCost;
- enum : ConversionCost
- {
- // No conversion at all
- kConversionCost_None = 0,
-
- // Conversions based on explicit sub-typing relationships are the cheapest
- //
- // TODO(tfoley): We will eventually need a discipline for ranking
- // when two up-casts are comparable.
- kConversionCost_CastToInterface = 50,
-
- // Conversion that is lossless and keeps the "kind" of the value the same
- kConversionCost_RankPromotion = 100,
-
- // Conversions that are lossless, but change "kind"
- kConversionCost_UnsignedToSignedPromotion = 200,
-
- // Conversion from signed->unsigned integer of same or greater size
- kConversionCost_SignedToUnsignedConversion = 300,
-
- // Cost of converting an integer to a floating-point type
- kConversionCost_IntegerToFloatConversion = 400,
-
- // Catch-all for conversions that should be discouraged
- // (i.e., that really shouldn't be made implicitly)
- //
- // TODO: make these conversions not be allowed implicitly in "Slang mode"
- kConversionCost_GeneralConversion = 900,
-
- // Additional conversion cost to add when promoting from a scalar to
- // a vector (this will be added to the cost, if any, of converting
- // the element type of the vector)
- kConversionCost_ScalarToVector = 1,
- };
-
- enum BaseTypeConversionKind : uint8_t
- {
- kBaseTypeConversionKind_Signed,
- kBaseTypeConversionKind_Unsigned,
- kBaseTypeConversionKind_Float,
- kBaseTypeConversionKind_Error,
- };
-
- enum BaseTypeConversionRank : uint8_t
- {
- kBaseTypeConversionRank_Bool,
- kBaseTypeConversionRank_Int8,
- kBaseTypeConversionRank_Int16,
- kBaseTypeConversionRank_Int32,
- kBaseTypeConversionRank_IntPtr,
- kBaseTypeConversionRank_Int64,
- kBaseTypeConversionRank_Error,
- };
-
- struct BaseTypeConversionInfo
- {
- BaseTypeConversionKind kind;
- BaseTypeConversionRank rank;
- };
- static BaseTypeConversionInfo GetBaseTypeConversionInfo(BaseType baseType)
- {
- switch (baseType)
- {
- #define CASE(TAG, KIND, RANK) \
- case BaseType::TAG: { BaseTypeConversionInfo info = {kBaseTypeConversionKind_##KIND, kBaseTypeConversionRank_##RANK}; return info; } break
-
- CASE(Bool, Unsigned, Bool);
- CASE(Int, Signed, Int32);
- CASE(UInt, Unsigned, Int32);
- CASE(UInt64, Unsigned, Int64);
- CASE(Half, Float, Int16);
- CASE(Float, Float, Int32);
- CASE(Double, Float, Int64);
- CASE(Void, Error, Error);
-
- #undef CASE
-
- default:
- break;
- }
- SLANG_UNREACHABLE("all cases handled");
- }
-
bool ValuesAreEqual(
RefPtr<IntVal> left,
RefPtr<IntVal> right)
@@ -692,6 +608,19 @@ namespace Slang
return false;
}
+ // Compute the cost of using a particular declaration to
+ // perform implicit type conversion.
+ ConversionCost getImplicitConversionCost(
+ Decl* decl)
+ {
+ if(auto modifier = decl->FindModifier<ImplicitConversionModifier>())
+ {
+ return modifier->cost;
+ }
+
+ return kConversionCost_Explicit;
+ }
+
// Central engine for implementing implicit coercion logic
bool TryCoerceImpl(
RefPtr<Type> toType, // the target type for conversion
@@ -836,6 +765,7 @@ namespace Slang
//
+#if 0
if (auto toBasicType = toType->AsBasicType())
{
if (auto fromBasicType = fromType->AsBasicType())
@@ -951,6 +881,7 @@ namespace Slang
}
}
}
+#endif
if (auto toDeclRefType = toType->As<DeclRefType>())
{
@@ -971,7 +902,97 @@ namespace Slang
}
}
- // TODO: more cases!
+ // Look for an initializer/constructor declaration in the target type,
+ // which is marked as usable for implicit conversion, and which takes
+ // the source type as an argument.
+
+ OverloadResolveContext overloadContext;
+
+ List<RefPtr<Expr>> args;
+ args.Add(fromExpr);
+
+ overloadContext.disallowNestedConversions = true;
+ overloadContext.argCount = 1;
+ overloadContext.argTypes = &fromType;
+
+ overloadContext.originalExpr = nullptr;
+ if(fromExpr)
+ {
+ overloadContext.loc = fromExpr->loc;
+ overloadContext.funcLoc = fromExpr->loc;
+ overloadContext.args = &fromExpr;
+ }
+
+ overloadContext.baseExpr = nullptr;
+ overloadContext.mode = OverloadResolveContext::Mode::JustTrying;
+
+ AddTypeOverloadCandidates(toType, overloadContext);
+
+ if(overloadContext.bestCandidates.Count() != 0)
+ {
+ // There were multiple candidates that were equally good.
+
+ // First, we will check if these candidates are even applicable.
+ // If they aren't, then they can't be used for conversion.
+ if(overloadContext.bestCandidates[0].status != OverloadCandidate::Status::Appicable)
+ return false;
+
+ // If we reach this point, then we have multiple candidates which are
+ // all equally applicable, which means we have an ambiguity.
+ // If the user is just querying whether a conversion is possible, we
+ // will tell them it is, because ambiguity should trigger an ambiguity
+ // error, and not a "no conversion possible" error.
+
+ // We will compute a nominal conversion cost as the minimum over
+ // all the conversions available.
+ ConversionCost cost = kConversionCost_GeneralConversion;
+ for(auto candidate : overloadContext.bestCandidates)
+ {
+ ConversionCost candidateCost = getImplicitConversionCost(
+ candidate.item.declRef.getDecl());
+
+ if(candidateCost < cost)
+ cost = candidateCost;
+ }
+
+ if(outCost)
+ *outCost = cost;
+
+ if(outToExpr)
+ {
+ // The user is asking for us to actually perform the conversion,
+ // so we need to generate an appropriate expression here.
+
+ throw "foo bar baz";
+ }
+
+ return true;
+ }
+ else if(overloadContext.bestCandidate)
+ {
+ // There is a single best candidate for conversion.
+
+ // It might not actually be usable, so let's check that first.
+ if(overloadContext.bestCandidate->status != OverloadCandidate::Status::Appicable)
+ return false;
+
+ // Okay, it is applicable, and we just need to let the user
+ // know about it, and optionally construct a call.
+
+ // We need to extract the conversion cost from the candidate we found.
+ ConversionCost cost = getImplicitConversionCost(
+ overloadContext.bestCandidate->item.declRef.getDecl());;
+
+ if(outCost)
+ *outCost = cost;
+
+ if(outToExpr)
+ {
+ *outToExpr = CompleteOverloadCandidate(overloadContext, *overloadContext.bestCandidate);
+ }
+
+ return true;
+ }
return false;
}
@@ -991,7 +1012,7 @@ namespace Slang
}
RefPtr<Expr> CreateImplicitCastExpr(
- RefPtr<Type> toType,
+ RefPtr<Type> toType,
RefPtr<Expr> fromExpr)
{
// In "rewrite" mode, we will generate a different syntax node
@@ -1007,10 +1028,17 @@ namespace Slang
castExpr = new ImplicitCastExpr();
}
+ auto typeType = new TypeType();
+ typeType->type = toType;
+
+ auto typeExpr = new SharedTypeExpr();
+ typeExpr->type.type = typeType;
+ typeExpr->base.type = toType;
+
castExpr->loc = fromExpr->loc;
- castExpr->TargetType.type = toType;
+ castExpr->FunctionExpr = typeExpr;
castExpr->type = QualType(toType);
- castExpr->Expression = fromExpr;
+ castExpr->Arguments.Add(fromExpr);
return castExpr;
}
@@ -2272,7 +2300,7 @@ namespace Slang
}
else if(auto castExpr = dynamic_cast<TypeCastExpr*>(expr))
{
- auto val = TryConstantFoldExpr(castExpr->Expression.Ptr());
+ auto val = TryConstantFoldExpr(castExpr->Arguments[0].Ptr());
if(val)
return val;
}
@@ -2457,7 +2485,7 @@ namespace Slang
}
RefPtr<Expr> subscriptFuncExpr = createLookupResultExpr(
- lookupResult, subscriptExpr->BaseExpression, subscriptExpr);
+ lookupResult, subscriptExpr->BaseExpression, subscriptExpr->loc);
// Now that we know there is at least one subscript member,
// we will construct a reference to it and try to call it
@@ -2982,7 +3010,32 @@ namespace Slang
ForReal,
};
- RefPtr<AppExprBase> appExpr;
+ // Location to use when reporting overload-resolution errors.
+ SourceLoc loc;
+
+ // The original expression (if any) that triggered things
+ RefPtr<Expr> originalExpr;
+
+ // Source location of the "function" part of the expression, if any
+ SourceLoc funcLoc;
+
+ // The original arguments to the call
+ UInt argCount = 0;
+ RefPtr<Expr>* args = nullptr;
+ RefPtr<Type>* argTypes = nullptr;
+
+ UInt getArgCount() { return argCount; }
+ RefPtr<Expr>& getArg(UInt index) { return args[index]; }
+ RefPtr<Type>& getArgType(UInt index)
+ {
+ if(argTypes)
+ return argTypes[index];
+ else
+ return getArg(index)->type.type;
+ }
+
+ bool disallowNestedConversions = false;
+
RefPtr<Expr> baseExpr;
// Are we still trying out candidates, or are we
@@ -3060,7 +3113,7 @@ namespace Slang
OverloadResolveContext& context,
OverloadCandidate const& candidate)
{
- UInt argCount = context.appExpr->Arguments.Count();
+ UInt argCount = context.getArgCount();
ParamCounts paramCounts = { 0, 0 };
switch (candidate.flavor)
{
@@ -3087,7 +3140,7 @@ namespace Slang
{
if (!isRewriteMode())
{
- getSink()->diagnose(context.appExpr, Diagnostics::notEnoughArguments, argCount, paramCounts.required);
+ getSink()->diagnose(context.loc, Diagnostics::notEnoughArguments, argCount, paramCounts.required);
}
}
else
@@ -3095,7 +3148,7 @@ namespace Slang
SLANG_ASSERT(argCount > paramCounts.allowed);
if (!isRewriteMode())
{
- getSink()->diagnose(context.appExpr, Diagnostics::tooManyArguments, argCount, paramCounts.allowed);
+ getSink()->diagnose(context.loc, Diagnostics::tooManyArguments, argCount, paramCounts.allowed);
}
}
}
@@ -3107,7 +3160,7 @@ namespace Slang
OverloadResolveContext& context,
OverloadCandidate const& candidate)
{
- auto expr = context.appExpr;
+ auto expr = context.originalExpr;
auto decl = candidate.item.declRef.decl;
@@ -3120,7 +3173,7 @@ namespace Slang
{
if (!isRewriteMode())
{
- getSink()->diagnose(context.appExpr, Diagnostics::expectedPrefixOperator);
+ getSink()->diagnose(context.loc, Diagnostics::expectedPrefixOperator);
getSink()->diagnose(decl, Diagnostics::seeDefinitionOf, decl->getName());
}
}
@@ -3136,7 +3189,7 @@ namespace Slang
{
if (!isRewriteMode())
{
- getSink()->diagnose(context.appExpr, Diagnostics::expectedPostfixOperator);
+ getSink()->diagnose(context.loc, Diagnostics::expectedPostfixOperator);
getSink()->diagnose(decl, Diagnostics::seeDefinitionOf, decl->getName());
}
}
@@ -3155,8 +3208,6 @@ namespace Slang
OverloadResolveContext& context,
OverloadCandidate& candidate)
{
- auto& args = context.appExpr->Arguments;
-
auto genericDeclRef = candidate.item.declRef.As<GenericDecl>();
int aa = 0;
@@ -3164,7 +3215,7 @@ namespace Slang
{
if (auto typeParamRef = memberRef.As<GenericTypeParamDecl>())
{
- auto arg = args[aa++];
+ auto arg = context.getArg(aa++);
if (context.mode == OverloadResolveContext::Mode::JustTrying)
{
@@ -3180,7 +3231,7 @@ namespace Slang
}
else if (auto valParamRef = memberRef.As<GenericValueParamDecl>())
{
- auto arg = args[aa++];
+ auto arg = context.getArg(aa++);
if (context.mode == OverloadResolveContext::Mode::JustTrying)
{
@@ -3210,8 +3261,7 @@ namespace Slang
OverloadResolveContext& context,
OverloadCandidate& candidate)
{
- auto& args = context.appExpr->Arguments;
- UInt argCount = args.Count();
+ UInt argCount = context.getArgCount();
List<DeclRef<ParamDecl>> params;
switch (candidate.flavor)
@@ -3234,13 +3284,20 @@ namespace Slang
for (UInt ii = 0; ii < argCount; ++ii)
{
- auto& arg = args[ii];
+ auto& arg = context.getArg(ii);
+ auto argType = context.getArgType(ii);
auto param = params[ii];
if (context.mode == OverloadResolveContext::Mode::JustTrying)
{
ConversionCost cost = kConversionCost_None;
- if (!CanCoerce(GetType(param), arg->type, &cost))
+ if( context.disallowNestedConversions )
+ {
+ // We need an exact match in this case.
+ if(!GetType(param)->Equals(argType))
+ return false;
+ }
+ else if (!CanCoerce(GetType(param), argType, &cost))
{
return false;
}
@@ -3288,28 +3345,31 @@ namespace Slang
// Create the representation of a given generic applied to some arguments
RefPtr<Expr> CreateGenericDeclRef(
- RefPtr<Expr> baseExpr,
- RefPtr<AppExprBase> appExpr)
+ RefPtr<Expr> baseExpr,
+ RefPtr<Expr> originalExpr,
+ UInt argCount,
+ RefPtr<Expr> const* args)
{
auto baseDeclRefExpr = baseExpr.As<DeclRefExpr>();
if (!baseDeclRefExpr)
{
SLANG_DIAGNOSE_UNEXPECTED(getSink(), baseExpr, "expected a reference to a generic declaration");
- return CreateErrorExpr(appExpr.Ptr());
+ return CreateErrorExpr(originalExpr);
}
auto baseGenericRef = baseDeclRefExpr->declRef.As<GenericDecl>();
if (!baseGenericRef)
{
SLANG_DIAGNOSE_UNEXPECTED(getSink(), baseExpr, "expected a reference to a generic declaration");
- return CreateErrorExpr(appExpr.Ptr());
+ return CreateErrorExpr(originalExpr);
}
RefPtr<Substitutions> subst = new Substitutions();
subst->genericDecl = baseGenericRef.getDecl();
subst->outer = baseGenericRef.substitutions;
- for (auto arg : appExpr->Arguments)
+ for(UInt aa = 0; aa < argCount; ++aa)
{
+ auto arg = args[aa];
subst->args.Add(ExtractGenericArgVal(arg));
}
@@ -3318,7 +3378,7 @@ namespace Slang
return ConstructDeclRefExpr(
innerDeclRef,
nullptr,
- appExpr);
+ originalExpr->loc);
}
// Take an overload candidate that previously got through
@@ -3334,11 +3394,11 @@ namespace Slang
// special case for generic argument inference failure
if (candidate.status == OverloadCandidate::Status::GenericArgumentInferenceFailed)
{
- String callString = GetCallSignatureString(context.appExpr);
+ String callString = getCallSignatureString(context);
if (!isRewriteMode())
{
getSink()->diagnose(
- context.appExpr,
+ context.loc,
Diagnostics::genericArgumentInferenceFailed,
callString);
@@ -3349,7 +3409,6 @@ namespace Slang
}
context.mode = OverloadResolveContext::Mode::ForReal;
- context.appExpr->type = QualType(getSession()->getErrorType());
if (!TryCheckOverloadCandidateArity(context, candidate))
goto error;
@@ -3365,41 +3424,66 @@ namespace Slang
{
auto baseExpr = ConstructLookupResultExpr(
- candidate.item, context.baseExpr, context.appExpr->FunctionExpr);
+ candidate.item, context.baseExpr, context.funcLoc);
switch(candidate.flavor)
{
case OverloadCandidate::Flavor::Func:
- context.appExpr->FunctionExpr = baseExpr;
- context.appExpr->type = QualType(candidate.resultType);
-
- // A call may yield an l-value, and we should take a look at the candidate to be sure
- if(auto subscriptDeclRef = candidate.item.declRef.As<SubscriptDecl>())
{
- for(auto setter : subscriptDeclRef.getDecl()->getMembersOfType<SetterDecl>())
+ RefPtr<AppExprBase> callExpr = context.originalExpr.As<InvokeExpr>();
+ if(!callExpr)
{
- context.appExpr->type.IsLeftValue = true;
+ callExpr = new InvokeExpr();
+ callExpr->loc = context.loc;
+
+ for(UInt aa = 0; aa < context.argCount; ++aa)
+ callExpr->Arguments.Add(context.getArg(aa));
+ }
+
+
+ callExpr->FunctionExpr = baseExpr;
+ callExpr->type = QualType(candidate.resultType);
+
+ // A call may yield an l-value, and we should take a look at the candidate to be sure
+ if(auto subscriptDeclRef = candidate.item.declRef.As<SubscriptDecl>())
+ {
+ for(auto setter : subscriptDeclRef.getDecl()->getMembersOfType<SetterDecl>())
+ {
+ callExpr->type.IsLeftValue = true;
+ }
}
- }
- // TODO: there may be other cases that confer l-value-ness
+ // TODO: there may be other cases that confer l-value-ness
+
+ return callExpr;
+ }
- return context.appExpr;
break;
case OverloadCandidate::Flavor::Generic:
- return CreateGenericDeclRef(baseExpr, context.appExpr);
+ return CreateGenericDeclRef(baseExpr, context.originalExpr,
+ context.argCount,
+ context.args);
break;
default:
- SLANG_DIAGNOSE_UNEXPECTED(getSink(), context.appExpr, "unknown overload candidate flavor");
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), context.loc, "unknown overload candidate flavor");
break;
}
}
error:
- return CreateErrorExpr(context.appExpr.Ptr());
+
+ if(context.originalExpr)
+ {
+ return CreateErrorExpr(context.originalExpr.Ptr());
+ }
+ else
+ {
+ SLANG_DIAGNOSE_UNEXPECTED(getSink(), context.loc, "no original expression for overload result");
+ return nullptr;
+ }
}
// Implement a comparison operation between overload candidates,
@@ -3859,6 +3943,7 @@ namespace Slang
}
}
+#if 0
bool TryUnifyArgAndParamTypes(
ConstraintSystem& system,
RefPtr<Expr> argExpr,
@@ -3869,6 +3954,7 @@ namespace Slang
// an overload group...
return TryUnifyTypes(system, argExpr->type, GetType(paramDeclRef));
}
+#endif
// Take a generic declaration and try to specialize its parameters
// so that the resulting inner declaration can be applicable in
@@ -3889,10 +3975,9 @@ namespace Slang
// to match it up with the arguments accordingly...
if (auto funcDeclRef = unspecializedInnerRef.As<CallableDecl>())
{
- auto& args = context.appExpr->Arguments;
auto params = GetParameters(funcDeclRef).ToArray();
- UInt argCount = args.Count();
+ UInt argCount = context.getArgCount();
UInt paramCount = params.Count();
// Bail out on mismatch.
@@ -3926,7 +4011,7 @@ namespace Slang
// So the question is then whether a mismatch during the
// unification step should be taken as an immediate failure...
- TryUnifyArgAndParamTypes(constraints, args[aa], params[aa]);
+ TryUnifyTypes(constraints, context.getArgType(aa), GetType(params[aa]));
#endif
}
}
@@ -4225,21 +4310,28 @@ namespace Slang
return getDeclSignatureString(item.declRef);
}
- String GetCallSignatureString(RefPtr<AppExprBase> expr)
+ String getCallSignatureString(
+ OverloadResolveContext& context)
{
- StringBuilder argsListBuilder;
+ StringBuilder argsListBuilder;
argsListBuilder << "(";
- bool first = true;
- for (auto a : expr->Arguments)
+
+ UInt argCount = context.getArgCount();
+ for( UInt aa = 0; aa < argCount; ++aa )
{
- if (!first) argsListBuilder << ", ";
- argsListBuilder << a->type->ToString();
- first = false;
+ if(aa != 0) argsListBuilder << ", ";
+ argsListBuilder << context.getArgType(aa)->ToString();
}
argsListBuilder << ")";
return argsListBuilder.ProduceString();
}
+#if 0
+ String GetCallSignatureString(RefPtr<AppExprBase> expr)
+ {
+ return getCallSignatureString(expr->Arguments);
+ }
+#endif
RefPtr<Expr> ResolveInvoke(InvokeExpr * expr)
{
@@ -4262,7 +4354,14 @@ namespace Slang
}
OverloadResolveContext context;
- context.appExpr = expr;
+
+ context.originalExpr = expr;
+ context.funcLoc = funcExpr->loc;
+
+ context.argCount = expr->Arguments.Count();
+ context.args = expr->Arguments.Buffer();
+ context.loc = expr->loc;
+
if (auto funcMemberExpr = funcExpr.As<MemberExpr>())
{
context.baseExpr = funcMemberExpr->BaseExpression;
@@ -4297,7 +4396,7 @@ namespace Slang
else if(auto baseMemberRef = funcExpr.As<MemberExpr>())
funcName = baseMemberRef->name;
- String argsList = GetCallSignatureString(expr);
+ String argsList = getCallSignatureString(context);
if (context.bestCandidates[0].status != OverloadCandidate::Status::Appicable)
{
@@ -4457,7 +4556,12 @@ namespace Slang
// Otherwise, let's start looking at how to find an overload...
OverloadResolveContext context;
- context.appExpr = genericAppExpr;
+ context.originalExpr = genericAppExpr;
+ context.funcLoc = baseExpr->loc;
+ context.argCount = args.Count();
+ context.args = args.Buffer();
+ context.loc = genericAppExpr->loc;
+
context.baseExpr = GetBaseExpr(baseExpr);
AddGenericOverloadCandidates(baseExpr, context);
@@ -4606,7 +4710,7 @@ namespace Slang
return createLookupResultExpr(
lookupResult,
nullptr,
- expr);
+ expr->loc);
}
if (!isRewriteMode())
@@ -4619,6 +4723,29 @@ namespace Slang
RefPtr<Expr> visitTypeCastExpr(TypeCastExpr * expr)
{
+ // Check the term we are applying first
+ auto funcExpr = expr->FunctionExpr;
+ funcExpr = CheckTerm(funcExpr);
+
+ // Now ensure that the term represnets a (proper) type.
+ TypeExp typeExp;
+ typeExp.exp = funcExpr;
+ typeExp = CheckProperType(typeExp);
+
+ expr->FunctionExpr = typeExp.exp;
+ expr->type.type = typeExp.type;
+
+ // Next check the argument expression (there should be only one)
+ for (auto & arg : expr->Arguments)
+ {
+ arg = CheckExpr(arg);
+ }
+
+ // Now process this like any other explicit call (so casts
+ // and constructor calls are semantically equivalent).
+ return CheckInvokeExprWithCheckedOperands(expr);
+
+#if 0
expr->Expression = CheckTerm(expr->Expression);
auto targetType = CheckProperType(expr->TargetType);
expr->TargetType = targetType;
@@ -4659,6 +4786,7 @@ namespace Slang
}
expr->type = QualType(getSession()->getErrorType());
return expr;
+#endif
}
// Get the type to use when referencing a declaration
@@ -4906,7 +5034,7 @@ namespace Slang
return createLookupResultExpr(
lookupResult,
expr->BaseExpression,
- expr);
+ expr->loc);
}
}
}
@@ -4928,7 +5056,7 @@ namespace Slang
return createLookupResultExpr(
lookupResult,
expr->BaseExpression,
- expr);
+ expr->loc);
}
// catch-all