1 /******************************************************************************
3 * Copyright (C) 1997-2019 by Dimitri van Heesch.
5 * Permission to use, copy, modify, and distribute this software and its
6 * documentation under the terms of the GNU General Public License is hereby
7 * granted. No representations are made about the suitability of this software
8 * for any purpose. It is provided "as is" without express or implied warranty.
9 * See the GNU General Public License for more details.
11 * Documents produced by Doxygen are derivative works derived from the
12 * input used in their production; they are not affected by this license.
16 #include "stlsupport.h"
20 /** A struct contained the data for an STL class */
23 const char *className;
24 const char *baseClass1;
25 const char *baseClass2;
26 const char *templType1;
27 const char *templName1;
28 const char *templType2;
29 const char *templName2;
30 bool virtualInheritance;
34 static STLInfo g_stlinfo[] =
36 // className baseClass1 baseClass2 templType1 templName1 templType2 templName2 virtInheritance // iterators
37 { "allocator", 0, 0, "T", "elements", 0, 0, FALSE, FALSE },
38 { "auto_ptr", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // deprecated
39 { "smart_ptr", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // C++11
40 { "unique_ptr", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // C++11
41 { "shared_ptr", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // C++14
42 { "weak_ptr", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // C++11
43 { "atomic", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // C++11
44 { "atomic_ref", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // C++20
45 { "lock_guard", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // C++11
46 { "unique_lock", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // C++11
47 { "shared_lock", 0, 0, "T", "ptr", 0, 0, FALSE, FALSE }, // C++14
48 { "ios_base", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11
49 { "error_code", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11
50 { "error_category", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11
51 { "system_error", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11
52 { "error_condition", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11
53 { "thread", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11
54 { "jthread", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11
55 { "mutex", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11
56 { "timed_mutex", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11
57 { "recursive_mutex", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11
58 { "recursive_timed_mutex",0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++11
59 { "shared_mutex", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++17
60 { "shared_timed_mutex", 0, 0, 0, 0, 0, 0, FALSE, FALSE }, // C++14
61 { "basic_ios", "ios_base", 0, "Char", 0, 0, 0, FALSE, FALSE },
62 { "basic_istream", "basic_ios<Char>", 0, "Char", 0, 0, 0, TRUE, FALSE },
63 { "basic_ostream", "basic_ios<Char>", 0, "Char", 0, 0, 0, TRUE, FALSE },
64 { "basic_iostream", "basic_istream<Char>", "basic_ostream<Char>", "Char", 0, 0, 0, FALSE, FALSE },
65 { "basic_ifstream", "basic_istream<Char>", 0, "Char", 0, 0, 0, FALSE, FALSE },
66 { "basic_ofstream", "basic_ostream<Char>", 0, "Char", 0, 0, 0, FALSE, FALSE },
67 { "basic_fstream", "basic_iostream<Char>", 0, "Char", 0, 0, 0, FALSE, FALSE },
68 { "basic_istringstream", "basic_istream<Char>", 0, "Char", 0, 0, 0, FALSE, FALSE },
69 { "basic_ostringstream", "basic_ostream<Char>", 0, "Char", 0, 0, 0, FALSE, FALSE },
70 { "basic_stringstream", "basic_iostream<Char>", 0, "Char", 0, 0, 0, FALSE, FALSE },
71 { "ios", "basic_ios<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
72 { "wios", "basic_ios<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
73 { "istream", "basic_istream<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
74 { "wistream", "basic_istream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
75 { "ostream", "basic_ostream<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
76 { "wostream", "basic_ostream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
77 { "ifstream", "basic_ifstream<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
78 { "wifstream", "basic_ifstream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
79 { "ofstream", "basic_ofstream<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
80 { "wofstream", "basic_ofstream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
81 { "fstream", "basic_fstream<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
82 { "wfstream", "basic_fstream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
83 { "istringstream", "basic_istringstream<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
84 { "wistringstream", "basic_istringstream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
85 { "ostringstream", "basic_ostringstream<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
86 { "wostringstream", "basic_ostringstream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
87 { "stringstream", "basic_stringstream<char>", 0, 0, 0, 0, 0, FALSE, FALSE },
88 { "wstringstream", "basic_stringstream<wchar_t>", 0, 0, 0, 0, 0, FALSE, FALSE },
89 { "basic_string", 0, 0, "Char", 0, 0, 0, FALSE, TRUE },
90 { "string", "basic_string<char>", 0, 0, 0, 0, 0, FALSE, TRUE },
91 { "wstring", "basic_string<wchar_t>", 0, 0, 0, 0, 0, FALSE, TRUE },
92 { "u8string", "basic_string<char8_t>", 0, 0, 0, 0, 0, FALSE, TRUE }, // C++20
93 { "u16string", "basic_string<char16_t>", 0, 0, 0, 0, 0, FALSE, TRUE }, // C++11
94 { "u32string", "basic_string<char32_t>", 0, 0, 0, 0, 0, FALSE, TRUE }, // C++11
95 { "basic_string_view", 0, 0, "Char", 0, 0, 0, FALSE, TRUE },
96 { "string_view", "basic_string_view<char>", 0, 0, 0, 0, 0, FALSE, TRUE }, // C++17
97 { "wstring_view", "basic_string_view<wchar_t>", 0, 0, 0, 0, 0, FALSE, TRUE }, // C++17
98 { "u8string_view", "basic_string_view<char8_t>", 0, 0, 0, 0, 0, FALSE, TRUE }, // C++20
99 { "u16string_view", "basic_string_view<char16_t>", 0, 0, 0, 0, 0, FALSE, TRUE }, // C++17
100 { "u32string_view", "basic_string_view<char32_t>", 0, 0, 0, 0, 0, FALSE, TRUE }, // C++17
101 { "complex", 0, 0, 0, 0, 0, 0, FALSE, FALSE },
102 { "bitset", 0, 0, "Bits", 0, 0, 0, FALSE, FALSE },
103 { "deque", 0, 0, "T", "elements", 0, 0, FALSE, TRUE },
104 { "list", 0, 0, "T", "elements", 0, 0, FALSE, TRUE },
105 { "forward_list", 0, 0, "T", "elements", 0, 0, FALSE, TRUE }, // C++11
106 { "map", 0, 0, "K", "keys", "T", "elements", FALSE, TRUE },
107 { "unordered_map", 0, 0, "K", "keys", "T", "elements", FALSE, TRUE }, // C++11
108 { "multimap", 0, 0, "K", "keys", "T", "elements", FALSE, TRUE },
109 { "unordered_multimap", 0, 0, "K", "keys", "T", "elements", FALSE, TRUE }, // C++11
110 { "set", 0, 0, "K", "keys", 0, 0, FALSE, TRUE },
111 { "unordered_set", 0, 0, "K", "keys", 0, 0, FALSE, TRUE }, // C++11
112 { "multiset", 0, 0, "K", "keys", 0, 0, FALSE, TRUE },
113 { "unordered_multiset", 0, 0, "K", "keys", 0, 0, FALSE, TRUE }, // C++11
114 { "array", 0, 0, "T", "elements", 0, 0, FALSE, TRUE }, // C++11
115 { "vector", 0, 0, "T", "elements", 0, 0, FALSE, TRUE },
116 { "span", 0, 0, "T", "elements", 0, 0, FALSE, TRUE }, // C++20
117 { "queue", 0, 0, "T", "elements", 0, 0, FALSE, FALSE },
118 { "priority_queue", 0, 0, "T", "elements", 0, 0, FALSE, FALSE },
119 { "stack", 0, 0, "T", "elements", 0, 0, FALSE, FALSE },
120 { "valarray", 0, 0, "T", "elements", 0, 0, FALSE, FALSE },
121 { "exception", 0, 0, 0, 0, 0, 0, FALSE, FALSE },
122 { "bad_alloc", "exception", 0, 0, 0, 0, 0, FALSE, FALSE },
123 { "bad_cast", "exception", 0, 0, 0, 0, 0, FALSE, FALSE },
124 { "bad_typeid", "exception", 0, 0, 0, 0, 0, FALSE, FALSE },
125 { "logic_error", "exception", 0, 0, 0, 0, 0, FALSE, FALSE },
126 { "ios_base::failure", "exception", 0, 0, 0, 0, 0, FALSE, FALSE },
127 { "runtime_error", "exception", 0, 0, 0, 0, 0, FALSE, FALSE },
128 { "bad_exception", "exception", 0, 0, 0, 0, 0, FALSE, FALSE },
129 { "domain_error", "logic_error", 0, 0, 0, 0, 0, FALSE, FALSE },
130 { "invalid_argument", "logic_error", 0, 0, 0, 0, 0, FALSE, FALSE },
131 { "length_error", "logic_error", 0, 0, 0, 0, 0, FALSE, FALSE },
132 { "out_of_range", "logic_error", 0, 0, 0, 0, 0, FALSE, FALSE },
133 { "range_error", "runtime_error", 0, 0, 0, 0, 0, FALSE, FALSE },
134 { "overflow_error", "runtime_error", 0, 0, 0, 0, 0, FALSE, FALSE },
135 { "underflow_error", "runtime_error", 0, 0, 0, 0, 0, FALSE, FALSE },
136 { 0, 0, 0, 0, 0, 0, 0, FALSE, FALSE }
139 static void addSTLMember(const std::shared_ptr<Entry> &root,const char *type,const char *name)
141 std::shared_ptr<Entry> memEntry = std::make_shared<Entry>();
142 memEntry->name = name;
143 memEntry->type = type;
144 memEntry->protection = Protection::Public;
145 memEntry->section = Entry::VARIABLE_SEC;
146 memEntry->brief = "STL member";
147 memEntry->hidden = FALSE;
148 memEntry->artificial = TRUE;
149 root->moveToSubEntryAndKeep(memEntry);
152 static void addSTLIterator(const std::shared_ptr<Entry> &classEntry,const QCString &name)
154 std::shared_ptr<Entry> iteratorClassEntry = std::make_shared<Entry>();
155 iteratorClassEntry->fileName = "[STL]";
156 iteratorClassEntry->startLine = 1;
157 iteratorClassEntry->name = name;
158 iteratorClassEntry->section = Entry::CLASS_SEC;
159 iteratorClassEntry->brief = "STL iterator class";
160 iteratorClassEntry->hidden = FALSE;
161 iteratorClassEntry->artificial= TRUE;
162 classEntry->moveToSubEntryAndKeep(iteratorClassEntry);
165 static void addSTLClass(const std::shared_ptr<Entry> &root,const STLInfo *info)
167 //printf("Adding STL class %s\n",info->className);
168 QCString fullName = info->className;
169 fullName.prepend("std::");
171 // add fake Entry for the class
172 std::shared_ptr<Entry> classEntry = std::make_shared<Entry>();
173 classEntry->fileName = "[STL]";
174 classEntry->startLine = 1;
175 classEntry->name = fullName;
176 classEntry->section = Entry::CLASS_SEC;
177 classEntry->brief = "STL class";
178 classEntry->hidden = FALSE;
179 classEntry->artificial= TRUE;
181 // add template arguments to class
182 if (info->templType1)
187 a.name=info->templType1;
189 if (info->templType2) // another template argument
192 a.name=info->templType2;
195 classEntry->tArgLists.push_back(al);
197 // add member variables
198 if (info->templName1)
200 addSTLMember(classEntry,info->templType1,info->templName1);
202 if (info->templName2)
204 addSTLMember(classEntry,info->templType2,info->templName2);
206 if (fullName=="std::auto_ptr" ||
207 fullName=="std::smart_ptr" ||
208 fullName=="std::shared_ptr" ||
209 fullName=="std::weak_ptr" ||
210 fullName=="std::unique_ptr")
212 std::shared_ptr<Entry> memEntry = std::make_shared<Entry>();
213 memEntry->name = "operator->";
214 memEntry->args = "()";
215 memEntry->type = "T*";
216 memEntry->protection = Protection::Public;
217 memEntry->section = Entry::FUNCTION_SEC;
218 memEntry->brief = "STL member";
219 memEntry->hidden = FALSE;
220 memEntry->artificial = FALSE;
221 classEntry->moveToSubEntryAndKeep(memEntry);
223 Specifier virt = info->virtualInheritance ? Specifier::Virtual : Specifier::Normal;
224 if (info->baseClass1)
226 classEntry->extends.push_back(BaseInfo(info->baseClass1, Protection::Public, virt));
228 if (info->baseClass2)
230 classEntry->extends.push_back(BaseInfo(info->baseClass2, Protection::Public, virt));
234 // add iterator class
235 addSTLIterator(classEntry,fullName+"::iterator");
236 addSTLIterator(classEntry,fullName+"::const_iterator");
237 addSTLIterator(classEntry,fullName+"::reverse_iterator");
238 addSTLIterator(classEntry,fullName+"::const_reverse_iterator");
240 root->moveToSubEntryAndKeep(classEntry);
244 static void addSTLClasses(const std::shared_ptr<Entry> &root)
246 std::shared_ptr<Entry> namespaceEntry = std::make_shared<Entry>();
247 namespaceEntry->fileName = "[STL]";
248 namespaceEntry->startLine = 1;
249 namespaceEntry->name = "std";
250 namespaceEntry->section = Entry::NAMESPACE_SEC;
251 namespaceEntry->brief = "STL namespace";
252 namespaceEntry->hidden = FALSE;
253 namespaceEntry->artificial= TRUE;
255 STLInfo *info = g_stlinfo;
256 while (info->className)
258 addSTLClass(namespaceEntry,info);
262 root->moveToSubEntryAndKeep(namespaceEntry);
265 void addSTLSupport(std::shared_ptr<Entry> &root)
267 if (Config_getBool(BUILTIN_STL_SUPPORT))