if (funcArgs[i].corType == ELEMENT_TYPE_VALUETYPE || funcArgs[i].corType == ELEMENT_TYPE_CLASS)
IfFailRet(TypePrinter::NameForTypeByValue(iCorValueArg, funcArgs[i].typeName));
+ else if (funcArgs[i].corType == ELEMENT_TYPE_SZARRAY || funcArgs[i].corType == ELEMENT_TYPE_ARRAY)
+ IfFailRet(TypePrinter::GetTypeOfValue(iCorValueArg, funcArgs[i].typeName));
}
ToRelease<ICorDebugFunction> iCorFunc;
// LoBounds ::= 29-bit-encoded-integer
// Number ::= 29-bit-encoded-integer
-static HRESULT ParseElementType(IMetaDataImport *pMD, PCCOR_SIGNATURE *ppSig, Evaluator::ArgElementType &argElementType)
+static void GetCorTypeName(ULONG corType, std::string &typeName)
+{
+ switch (corType)
+ {
+ case ELEMENT_TYPE_VOID:
+ typeName = "void";
+ break;
+ case ELEMENT_TYPE_BOOLEAN:
+ typeName = "bool";
+ break;
+ case ELEMENT_TYPE_CHAR:
+ typeName = "char";
+ break;
+ case ELEMENT_TYPE_I1:
+ typeName = "sbyte";
+ break;
+ case ELEMENT_TYPE_U1:
+ typeName = "byte";
+ break;
+ case ELEMENT_TYPE_I2:
+ typeName = "short";
+ break;
+ case ELEMENT_TYPE_U2:
+ typeName = "ushort";
+ break;
+ case ELEMENT_TYPE_I4:
+ typeName = "int";
+ break;
+ case ELEMENT_TYPE_U4:
+ typeName = "uint";
+ break;
+ case ELEMENT_TYPE_I8:
+ typeName = "long";
+ break;
+ case ELEMENT_TYPE_U8:
+ typeName = "ulong";
+ break;
+ case ELEMENT_TYPE_R4:
+ typeName = "float";
+ break;
+ case ELEMENT_TYPE_R8:
+ typeName = "double";
+ break;
+ case ELEMENT_TYPE_STRING:
+ typeName = "string";
+ break;
+ case ELEMENT_TYPE_OBJECT:
+ typeName = "object";
+ break;
+ default:
+ typeName = "";
+ break;
+ }
+}
+
+static HRESULT ParseElementType(IMetaDataImport *pMD, PCCOR_SIGNATURE *ppSig, Evaluator::ArgElementType &argElementType, bool addCorTypeName = false)
{
HRESULT Status;
ULONG corType;
case ELEMENT_TYPE_R8:
case ELEMENT_TYPE_STRING:
case ELEMENT_TYPE_OBJECT:
+ if (addCorTypeName)
+ GetCorTypeName(argElementType.corType, argElementType.typeName);
break;
case ELEMENT_TYPE_VALUETYPE:
IfFailRet(TypePrinter::NameForTypeByToken(tk, pMD, argElementType.typeName, nullptr));
break;
+ case ELEMENT_TYPE_SZARRAY:
+ if (FAILED(Status = ParseElementType(pMD, ppSig, argElementType, true)) || Status == S_FALSE)
+ return Status;
+ argElementType.corType = (CorElementType)corType;
+ argElementType.typeName += "[]";
+ break;
+ case ELEMENT_TYPE_ARRAY:
+ {
+ if (FAILED(Status = ParseElementType(pMD, ppSig, argElementType, true)) || Status == S_FALSE)
+ return Status;
+ argElementType.corType = (CorElementType)corType;
+ // Parse for the rank
+ ULONG rank = 0;
+ *ppSig += CorSigUncompressData(*ppSig, &rank);
+ // if rank == 0, we are done
+ if (rank == 0)
+ break;
+ // any size of dimension specified?
+ ULONG sizeDim;
+ ULONG ulTemp;
+ *ppSig += CorSigUncompressData(*ppSig, &sizeDim);
+ while (sizeDim--)
+ {
+ *ppSig += CorSigUncompressData(*ppSig, &ulTemp);
+ }
+ // any lower bound specified?
+ ULONG lowerBound;
+ int iTemp;
+ *ppSig += CorSigUncompressData(*ppSig, &lowerBound);
+ while (lowerBound--)
+ {
+ *ppSig += CorSigUncompressSignedInt(*ppSig, &iTemp);
+ }
+ argElementType.typeName += "[" + std::string(rank - 1, ',') + "]";
+ break;
+ }
+
// TODO
case ELEMENT_TYPE_U: // "nuint" - error CS8652: The feature 'native-sized integers' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
case ELEMENT_TYPE_I: // "nint" - error CS8652: The feature 'native-sized integers' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
case ELEMENT_TYPE_TYPEDBYREF:
- case ELEMENT_TYPE_ARRAY:
case ELEMENT_TYPE_PTR: // int* ptr (unsafe code only)
case ELEMENT_TYPE_BYREF: // ref, in, out
- case ELEMENT_TYPE_SZARRAY:
case ELEMENT_TYPE_VAR: // Generic parameter in a generic type definition, represented as number
case ELEMENT_TYPE_MVAR: // Generic parameter in a generic method definition, represented as number
case ELEMENT_TYPE_GENERICINST: // A type modifier for generic types - List<>, Dictionary<>, ...
return 5;
}
+ static int TestArrayArg(int[] arrayArg, int i)
+ {
+ return arrayArg[0] + i;
+ }
+
+ static int TestArrayArg(test_array[] arrayT, int i)
+ {
+ return i;
+ }
+
+ static int TestArrayArg2(short[] arrayArg, int i)
+ {
+ return arrayArg[0] + i;
+ }
+
+ static int TestArray2Arg(int[,] multiArray2, int i)
+ {
+ return multiArray2[0,0] + i;
+ }
+
+ static int TestArray2Arg2(short[,] multiArray2, int i)
+ {
+ return multiArray2[0,0] + i;
+ }
+
static void Main(string[] args)
{
Label.Checkpoint("init", "values_test", (Object context) => {
Context.GetAndCheckValue(@"__FILE__:__LINE__", "10", "int", "array1[ 0]"); // check spaces
Context.GetAndCheckValue(@"__FILE__:__LINE__", "30", "int", "array1[2 ]"); // check spaces
Context.GetAndCheckValue(@"__FILE__:__LINE__", "50", "int", "array1 [ 4 ]"); // check spaces
+ Context.GetAndCheckValue(@"__FILE__:__LINE__", "15", "int", "TestArrayArg(array1, 5)");
+ Context.GetAndCheckValue(@"__FILE__:__LINE__", "11", "int", "TestArrayArg(array2, 11)");
+ Context.CheckErrorAtRequest(@"__FILE__:__LINE__", "TestArrayArg2(array1, 5)", "Error:");
Context.GetAndCheckValue(@"__FILE__:__LINE__", "{int[2, 3]}", "int[,]", "multi_array2");
Context.GetAndCheckValue(@"__FILE__:__LINE__", "101", "int", "multi_array2[0,0]");
Context.GetAndCheckValue(@"__FILE__:__LINE__", "102", "int", "multi_array2[i1,i4]");
Context.GetAndCheckValue(@"__FILE__:__LINE__", "101", "int", "multi_array2[ 0 , 0 ]"); // check spaces
Context.GetAndCheckValue(@"__FILE__:__LINE__", "105", "int", "multi_array2 [ 1,1 ]"); // check spaces
+ Context.GetAndCheckValue(@"__FILE__:__LINE__", "106", "int", "TestArray2Arg(multi_array2, 5)");
+ Context.CheckErrorAtRequest(@"__FILE__:__LINE__", "TestArray2Arg2(multi_array2, 5)", "Error:");
Context.GetAndCheckValue(@"__FILE__:__LINE__", "{MITestEvaluate.test_array[4]}", "MITestEvaluate.test_array[]", "array2");
Context.GetAndCheckValue(@"__FILE__:__LINE__", "{MITestEvaluate.test_array}", "MITestEvaluate.test_array", "array2[0]");
return 5;
}
+ static int TestArrayArg(int[] arrayArg, int i)
+ {
+ return arrayArg[0] + i;
+ }
+
+ static int TestArrayArg(test_array[] arrayT, int i)
+ {
+ return i;
+ }
+
+ static int TestArrayArg2(short[] arrayArg, int i)
+ {
+ return arrayArg[0] + i;
+ }
+
+ static int TestArray2Arg(int[,] multiArray2, int i)
+ {
+ return multiArray2[0,0] + i;
+ }
+
+ static int TestArray2Arg2(short[,] multiArray2, int i)
+ {
+ return multiArray2[0,0] + i;
+ }
+
static void Main(string[] args)
{
Label.Checkpoint("init", "values_test", (Object context) => {
Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, "10", "int", "array1[ 0]"); // check spaces
Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, "30", "int", "array1[2 ]"); // check spaces
Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, "50", "int", "array1 [ 4 ]"); // check spaces
+ Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, "15", "int", "TestArrayArg(array1, 5)");
+ Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, "11", "int", "TestArrayArg(array2, 11)");
+ Context.CheckErrorAtRequest(@"__FILE__:__LINE__", frameId, "TestArrayArg2(array1, 5)", "error:");
Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, "{int[2, 3]}", "int[,]", "multi_array2");
Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, "101", "int", "multi_array2[0,0]");
Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, "102", "int", "multi_array2[i1,i4]");
Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, "101", "int", "multi_array2[ 0 , 0 ]"); // check spaces
Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, "105", "int", "multi_array2 [ 1,1 ]"); // check spaces
+ Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, "106", "int", "TestArray2Arg(multi_array2, 5)");
+ Context.CheckErrorAtRequest(@"__FILE__:__LINE__", frameId, "TestArray2Arg2(multi_array2, 5)", "error:");
Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, "{VSCodeTestEvaluate.test_array[4]}", "VSCodeTestEvaluate.test_array[]", "array2");
Context.GetAndCheckValue(@"__FILE__:__LINE__", frameId, "{VSCodeTestEvaluate.test_array}", "VSCodeTestEvaluate.test_array", "array2[0]");