aboutsummaryrefslogtreecommitdiff
path: root/libpp/name_storage.h
blob: 711fbe869523981f393624921a357d8c4f0733d6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/**
 * @file name_storage.h
 * Type-safe unique storage of global names (filenames and symbols)
 *
 * @remark Copyright 2002 OProfile authors
 * @remark Read the file COPYING
 *
 * @author Philippe Elie
 * @author John Levon
 */

#ifndef NAME_STORAGE_H
#define NAME_STORAGE_H

#include <string>

#include "unique_storage.h"

class extra_images;

/// store original name and processed name
struct stored_name {
	stored_name(std::string const & n = std::string())
		: name(n) {}

	bool operator<(stored_name const & rhs) const {
		return name < rhs.name;
	}

	std::string name;
	mutable std::string name_processed;
};


/// partial specialization for unique storage of names
template <typename I> struct name_storage : unique_storage<I, stored_name> {

	typedef typename unique_storage<I, stored_name>::id_value id_value;

	std::string const & name(id_value const & id) const {
		return unique_storage<I, stored_name>::get(id).name;
	}
};


class debug_name_tag;
/// a debug filename
typedef name_storage<debug_name_tag>::id_value debug_name_id;

/// class storing a set of shared debug name (source filename)
struct debug_name_storage : name_storage<debug_name_tag> {
	/// return the basename for the given ID
	std::string const & basename(debug_name_id id) const;
};

/// store original name and processed name
struct stored_filename {
	stored_filename(std::string const & n = std::string())
		: filename(n), extra_images_uid(0) {}

	bool operator<(stored_filename const & rhs) const {
		return filename < rhs.filename;
	}

	std::string filename;
	mutable std::string base_filename;
	mutable std::string real_filename;
	mutable std::string real_base_filename;
	mutable int extra_images_uid;
};

/// partial specialization for unique storage of filenames
template <typename I> 
struct filename_storage : unique_storage<I, stored_filename> {

	typedef typename unique_storage<I, stored_filename>::id_value id_value;

	std::string const & name(id_value const & id) const {
		return unique_storage<I, stored_filename>::get(id).filename;
	}
};

class image_name_tag;
/// an image name
typedef filename_storage<image_name_tag>::id_value image_name_id;

/// class storing a set of shared image name
struct image_name_storage : filename_storage<image_name_tag> {
	enum image_name_type {
		/// image name based on the sample filename w/o path
		int_basename,
		/// image name based on the sample filename
		int_filename,
		/// real image name, can be different for module.
		int_real_basename,
		/// same as int_real_basename + the complete path, including an
		/// optionnal archive_path passed trough profile_spec
		int_real_filename,
	};

	/**
	 * @param id  the image name id
	 * @param type  the image name type
	 * @param extra  extra locations where the image can be found
	 *
	 * If type == int_real_name (resp. int_real_filename) and the image
	 * can't be located the return value is the same as if get_name()
	 * was called with int_name (resp. int_filename).
	 *
	 * multiple call with the image_name_id and different extra parameter
	 * will throw a runtime error, multiple extra_images are possible
	 * with differential profile but the name. FIXME
	 */
	std::string const & get_name(image_name_id id,
				     image_name_type type,
				     extra_images const & extra) const;

	/// return the basename name for the given ID
	std::string const & basename(image_name_id) const;
};


class symbol_name_tag;
/// a (demangled) symbol
typedef name_storage<symbol_name_tag>::id_value symbol_name_id;

/// class storing a set of shared symbol name
struct symbol_name_storage : name_storage<symbol_name_tag> {
	/// return the demangled name for the given ID
	std::string const & demangle(symbol_name_id id) const;
};


/// for images
extern image_name_storage image_names;

/// for debug filenames i.e. source filename
extern debug_name_storage debug_names;

/// for symbols
extern symbol_name_storage symbol_names;


/**
 * debug name specialisation for comparison.
 *
 * We compare by name rather by id since what user will see are
 * filename and when the criteria "samples count" give identical
 * result it's better to obtain result sorted by the user visible
 * property filename rather than by an obscure, invisible from user
 * point of view, file identifier property
 */
template<> inline bool
debug_name_id::operator<(debug_name_id const & rhs) const
{
	return debug_names.name(*this) < debug_names.name(rhs);
}

#endif /* !NAME_STORAGE_H */