1 /*
2  * (C) Copyright 2002-2015 Diomidis Spinellis
3  *
4  * This file is part of CScout.
5  *
6  * CScout is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * CScout is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with CScout.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  *
20  * Equivalence class attributes.  Also used by token and tokid functions.
21  *
22  */
23 
24 #ifndef ATTR_
25 #define ATTR_
26 
27 #include <vector>
28 #include <string>
29 #include <map>
30 
31 using namespace std;
32 
33 // Attributes that can be set for an EC
34 // Keep in sync with attribute_names[] and short_names[]
35 enum e_attribute {
36 	is_declared_unused,	// Declared with __unused__ attribute
37 	is_macro_token,		// Identifier stored in a macro
38 
39 	is_readonly,		// Read-only; true if any member
40 				// comes from an ro file
41 	// The four C namespaces
42 	is_suetag,		// Struct/union/enum tag
43 	is_sumember,		// Struct/union member
44 	is_label,		// Goto label
45 	is_ordinary,		// Ordinary identifier
46 
47 	is_macro,		// Name of an object or function-like macro
48 	is_undefined_macro,	// Macro (heuristic: ifdef, defined)
49 	is_macro_arg,		// Macro argument
50 	// The following are valid if is_ordinary is true:
51 	is_cscope,		// Compilation-unit (file) scoped
52 				// identifier  (static)
53 	is_lscope,		// Linkage-unit scoped identifier
54 	is_typedef,		// Typedef
55 	is_enumeration,		// Enumeration member
56 	is_yacc,		// Yacc identifier
57 	is_cfunction,		// Function
58 
59 	attr_end,		// From here-on we store projects
60 	attr_begin = is_readonly // First user-visible attribute
61 };
62 
63 class Attributes {
64 public:
65 	typedef vector<bool>::size_type size_type;
66 private:
67 	static size_type size;		// Size of the vector for all objects
68 	vector <bool> attr;		// Attributes and projects
69 					// Hopefully specialized to 1 bit/val
fix_size()70 	void fix_size() { if (attr.size() < size) attr.resize(size, false); }
71 	static string attribute_names[];
72 	static string attribute_short_names[];
73 public:
74 	// Add another attribute (typically project)
add_attribute()75 	static void add_attribute() { size++; }
76 	// Return the number of active attributes
get_num_attributes()77 	static size_type get_num_attributes() { return size; }
78 	// Return the name given the enumeration member
name(int n)79 	static const string &name(int n) { return attribute_names[n]; }
80 	// Return the short name given the enumeration member
shortname(int n)81 	static const string &shortname(int n) { return attribute_short_names[n]; }
Attributes()82 	Attributes() : attr(size, false) {}
set_attribute(int v)83 	void set_attribute(int v) { fix_size(); attr[v] = true; }
set_attribute_val(int v,bool n)84 	void set_attribute_val(int v, bool n) { fix_size(); attr[v] = n; }
get_attribute(int v)85 	bool get_attribute(int v)
86 		{ fix_size(); return attr[v]; }
87 	// Return true if the set attributes specify an identifier
is_identifier()88 	bool is_identifier() {
89 		return
90 			attr[is_ordinary] ||
91 			attr[is_sumember] ||
92 			attr[is_suetag] ||
93 			attr[is_macro] ||
94 			attr[is_macro_arg] ||
95 			attr[is_undefined_macro] ||
96 			attr[is_label] ||
97 			attr[is_yacc];
98 	}
merge_with(Attributes & b)99 	void merge_with(Attributes &b) {
100 		this->fix_size();
101 		b.fix_size();
102 		for (size_type i = 0; i < size; i++)
103 			this->attr[i] = (b.attr[i] || this->attr[i]);
104 	}
105 };
106 
107 class Project {
108 	// Current and next project-id
109 	static int current_projid;
110 	static int next_projid;
111 	// Maps between ids and names
112 	static map<string, int> projids;
113 	static vector<string> projnames;
114 public:
115 	// Set the name of the current project
116 	static void set_current_project(const string &name);
117 	// The a unique identifier for the current project
get_current_projid()118 	static int get_current_projid() { return current_projid; }
119 	// Map access functions
get_projid(const string & name)120 	static int get_projid(const string &name) { return projids[name]; }
get_projname(int i)121 	static const string &get_projname(int i) { return projnames[i]; }
122 	// Return the map of all projects
123 	typedef map<string, int> proj_map_type;
get_project_map()124 	static const proj_map_type &get_project_map() { return projids; }
125 };
126 
127 #endif /* ATTR_ */
128