1/**
2 * @file demangle_symbol.cpp
3 * Demangle a C++ symbol
4 *
5 * @remark Copyright 2002 OProfile authors
6 * @remark Read the file COPYING
7 *
8 * @author John Levon
9 */
10
11#include <cstdlib>
12
13#include "config.h"
14
15#include "demangle_symbol.h"
16#include "demangle_java_symbol.h"
17#include "op_regex.h"
18
19// from libiberty
20/*@{\name demangle option parameter */
21#ifndef DMGL_PARAMS
22# define DMGL_PARAMS     (1 << 0)        /**< Include function args */
23#endif
24#ifndef DMGL_ANSI
25# define DMGL_ANSI       (1 << 1)        /**< Include const, volatile, etc */
26#endif
27/*@}*/
28extern "C" char * cplus_demangle(char const * mangled, int options);
29
30using namespace std;
31
32namespace options {
33	extern demangle_type demangle;
34}
35
36string const demangle_symbol(string const & name)
37{
38	if (options::demangle == dmt_none)
39		return name;
40
41	// Do not try to strip leading underscore, as this leads to many
42	// C++ demangling failures. However we strip off a leading '.'
43        // as generated on PPC64
44	string const & tmp = (name[0] == '.' ? name.substr(1) : name);
45	char * unmangled = cplus_demangle(tmp.c_str(), DMGL_PARAMS | DMGL_ANSI);
46
47	if (!unmangled) {
48		string result = demangle_java_symbol(name);
49		if (!result.empty())
50			return result;
51		return name;
52	}
53
54	string result(unmangled);
55	free(unmangled);
56
57	if (options::demangle == dmt_smart) {
58		static bool init = false;
59		static regular_expression_replace regex;
60		if (init == false) {
61			setup_regex(regex, OP_DATADIR "/stl.pat");
62			init = true;
63		}
64		// we don't protect against exception here, pattern must be
65		// right and user can easily work-around by using -d
66		regex.execute(result);
67	}
68
69	return result;
70}
71