Skip to content

Commit

Permalink
Parse some C++/CLI symbols
Browse files Browse the repository at this point in the history
  • Loading branch information
cpplearner committed Mar 7, 2024
1 parent 4fcf6aa commit cd274bc
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 6 deletions.
55 changes: 51 additions & 4 deletions msvc-demangler.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class Demangler {
this.index++;
return map['0-9'](+c);
}
return call(map.default || error);
return call(map['default'] || error);
};
}
parse_list(f) {
Expand Down Expand Up @@ -277,6 +277,28 @@ export class Demangler {
}
parse_modifiers() {
const optional_modifiers = this.parse_optional_modifiers();
const cli_type = this.parse("cli type")({
'$': () => this.parse("cli type", '$')({
'A': () => ({ cli_type: '^' }),
'B': () => ({ cli_type: 'pin_ptr' }),
'C': () => ({ cli_type: '%' }),
default: () => {
const dimension = this.input.slice(this.index, this.index + 2);
const rank = +('0x' + dimension);
if (rank > 0 && rank <= 32) {
this.index += 2;
return this.parse("cli type", '$' + dimension)({
'$': () => ({ cli_type: 'array', cli_array_rank: rank }),
default: () => ({ cli_type: 'array^', cli_array_rank: rank }),
});
}
return this.parse("cli type")({
default: error,
});
},
}),
default: () => ({}),
});
const modifiers = this.parse("type qualifier")({
'A': () => ({}),
'B': () => ({ cv: 'const' }),
Expand All @@ -296,7 +318,7 @@ export class Demangler {
'P': () => ({ cv: 'const volatile', based: this.parse_based_modifier() }),
default: error,
});
return { ...optional_modifiers, ...modifiers };
return { ...optional_modifiers, ...cli_type, ...modifiers };
}
parse_member_function_type() {
return { ...this.parse_modifiers(), ...this.parse_function_type() };
Expand Down Expand Up @@ -336,7 +358,7 @@ export class Demangler {
'@': () => ({}),
default: () => ({ return_type: this.parse_type() }),
});
const { params, variadic } = this.parse("function parameter list")({
const param_list = this.parse("function parameter list")({
'X': () => ({ params: [] }),
default: () => this.parse_parameter_list(),
});
Expand All @@ -346,7 +368,7 @@ export class Demangler {
'E': () => ({ noexcept: 'noexcept' }),
})
});
return { typekind: 'function', ...cc, ...return_type, params, variadic, ...except };
return { typekind: 'function', ...cc, ...return_type, ...param_list, ...except };
}
parse_array_type() {
const dimension = this.parse_integer();
Expand Down Expand Up @@ -592,6 +614,7 @@ export class Demangler {
'9': error,
'_': () => this.parse('type', '__')({
'R': () => ({ typekind: 'builtin', typename: 'unknown-type' }),
'Z': () => ({ cli_typekind: 'value class', ...this.parse_type() }),
}),
'$': todo,
}),
Expand Down Expand Up @@ -693,6 +716,11 @@ export class Demangler {
vtordisp: this.parse_integer(), adjustment: this.parse_integer(), ...this.parse_member_function_type()
}),
'$': () => this.parse("entity info", '$$')({
'F': () => ({ cli_kind: 'C++ managed-IL function', ...this.parse_extra_info() }),
'H': () => ({ cli_kind: 'C++ managed-IL main', ...this.parse_extra_info() }),
'J': () => this.parse("entity info", '$$J')({
'0': () => ({ cli_kind: 'C managed-IL function', ...this.parse_extra_info() }),
}),
'h': () => ({ target: 'ARM64EC', ...this.parse_extra_info() }),
}),
default: () => ({
Expand Down Expand Up @@ -875,6 +903,25 @@ function print_type(ast) {
case 'pointer':
case 'reference':
const [left, right] = print_type(ast.pointee_type);
if (ast.pointee_type.cli_type) {
switch (ast.pointee_type.cli_type) {
case 'pin_ptr':
return [filter_join(' ')([ast.cv, `cli::pin_ptr<${left + right}>`]), ''];
case 'array^':
case 'array':
const rank = ast.pointee_type.cli_array_rank;
const args = filter_join(', ')([left + right, rank === 1 ? '' : '' + rank]);
if (ast.pointee_type.cli_type == 'array^') {
return [filter_join(' ')([ast.cv, `cli::array<${args}>^`]), ''];
}
else {
return [filter_join(' ')([ast.cv, `cli::array<${args}>`]), ''];
}
case '^':
case '%':
return [filter_join(' ')([left, ast.pointee_type.cli_type, ast.cv]), right];
}
}
const class_name = ast.pointee_type.class_name;
const typename = class_name ? print_qualified_name(class_name) + '::' + ast.typename : ast.typename;
if (ast.pointee_type.typekind === 'array' || ast.pointee_type.typekind === 'function')
Expand Down
3 changes: 2 additions & 1 deletion tests/check.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ async function read_input(filename) {
async function test(filename, outname) {
const { options, mangled, demangled } = await read_input(filename);

const ls = spawn('cl', [...options, '/nologo', '/Fa'+outname, '/c', '/FoNUL', filename]);
const ls = spawn('cl.exe', [...options, '/nologo', '/Fa'+outname, '/c', '/FoNUL', filename]);

let stdout = '';

Expand Down Expand Up @@ -77,3 +77,4 @@ async function test(filename, outname) {
test('test1.cpp', 'test1.asm');
test('test2.cpp', 'test2.asm');
test('test3.cpp', 'test3.asm');
test('test4.cpp', 'test4.asm');
2 changes: 1 addition & 1 deletion tests/test1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ type1 type7::var5;
// DEMANGLED: void type7::'dynamic atexit destructor for 'type7::var6<int>''()

template<class T> type1 type7::var6;
int x = (false ? type7::var6<int> -> ~type1() : void(), 1);
int x = (false ? ++type7::var6<int> : void(), 1);

// MANGLED: ??__K_a@@YAXPBD@Z
// DEMANGLED: void operator""_a(const char *)
Expand Down
51 changes: 51 additions & 0 deletions tests/test4.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// OPTIONS: /clr

// MANGLED: ?main@@$$HYAHXZ
// DEMANGLED: int main()
int main() {}

// MANGLED: ?f1@@$$FYAXXZ
// DEMANGLED: void f1()
void f1() {}

// MANGLED: ?f2@@YMXP$AA__ZVInt32@System@@@Z
// DEMANGLED: void f2(System::Int32 ^)
void f2(int^) {}

// MANGLED: ?f3@@YAXA$CAH@Z
// DEMANGLED: void f3(int %)
void f3(int%) {}

// MANGLED: ?f4@@YMXP$01AH@Z
// DEMANGLED: void f4(cli::array<int>^)
void f4(array<int>^) {}

template<class> void f5() {}

void f6() {

// MANGLED: ??$f5@Q$CAH@@$$FYAXXZ
// DEMANGLED: void f5<int % const>()
f5<const interior_ptr<int>>();

// MANGLED: ??$f5@R$BAH@@$$FYAXXZ
// DEMANGLED: void f5<volatile cli::pin_ptr<int>>()
f5<pin_ptr<int>>();

// MANGLED: ??$f5@S$BAH@@$$FYAXXZ
// DEMANGLED: void f5<const volatile cli::pin_ptr<int>>()
f5<const pin_ptr<int>>();

// MANGLED: ??$f5@P$20$AH@@$$FYAXXZ
// DEMANGLED: void f5<cli::array<int, 32>>()
f5<array<int, 32>>();

// MANGLED: ??$f5@Q$20$AH@@$$FYAXXZ
// DEMANGLED: void f5<const cli::array<int, 32>>()
f5<const array<int, 32>>();

// MANGLED: ??$f5@Q$20AH@@$$FYAXXZ
// DEMANGLED: void f5<const cli::array<int, 32>^>()
f5<const array<int, 32>^>();

}

0 comments on commit cd274bc

Please sign in to comment.