Imported Upstream version 1.9.8
[platform/upstream/doxygen.git] / src / stlsupport.cpp
1 /******************************************************************************
2  *
3  * Copyright (C) 1997-2019 by Dimitri van Heesch.
4  *
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.
10  *
11  * Documents produced by Doxygen are derivative works derived from the
12  * input used in their production; they are not affected by this license.
13  *
14  */
15
16 #include "stlsupport.h"
17 #include "entry.h"
18 #include "config.h"
19
20 /** A struct contained the data for an STL class */
21 struct STLInfo
22 {
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;
31   bool iterators;
32 };
33
34 static STLInfo g_stlinfo[] =
35 {
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 }
137 };
138
139 static void addSTLMember(const std::shared_ptr<Entry> &root,const char *type,const char *name)
140 {
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);
150 }
151
152 static void addSTLIterator(const std::shared_ptr<Entry> &classEntry,const QCString &name)
153 {
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);
163 }
164
165 static void addSTLClass(const std::shared_ptr<Entry> &root,const STLInfo *info)
166 {
167   //printf("Adding STL class %s\n",info->className);
168   QCString fullName = info->className;
169   fullName.prepend("std::");
170
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;
180
181   // add template arguments to class
182   if (info->templType1)
183   {
184     ArgumentList al;
185     Argument a;
186     a.type="typename";
187     a.name=info->templType1;
188     al.push_back(a);
189     if (info->templType2) // another template argument
190     {
191       a.type="typename";
192       a.name=info->templType2;
193       al.push_back(a);
194     }
195     classEntry->tArgLists.push_back(al);
196   }
197   // add member variables
198   if (info->templName1)
199   {
200     addSTLMember(classEntry,info->templType1,info->templName1);
201   }
202   if (info->templName2)
203   {
204     addSTLMember(classEntry,info->templType2,info->templName2);
205   }
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")
211   {
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);
222   }
223   Specifier virt = info->virtualInheritance ? Specifier::Virtual : Specifier::Normal;
224   if (info->baseClass1)
225   {
226     classEntry->extends.push_back(BaseInfo(info->baseClass1, Protection::Public, virt));
227   }
228   if (info->baseClass2)
229   {
230     classEntry->extends.push_back(BaseInfo(info->baseClass2, Protection::Public, virt));
231   }
232   if (info->iterators)
233   {
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");
239   }
240   root->moveToSubEntryAndKeep(classEntry);
241 }
242
243
244 static void addSTLClasses(const std::shared_ptr<Entry> &root)
245 {
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;
254
255   STLInfo *info = g_stlinfo;
256   while (info->className)
257   {
258     addSTLClass(namespaceEntry,info);
259     info++;
260   }
261
262   root->moveToSubEntryAndKeep(namespaceEntry);
263 }
264
265 void addSTLSupport(std::shared_ptr<Entry> &root)
266 {
267   if (Config_getBool(BUILTIN_STL_SUPPORT))
268   {
269     addSTLClasses(root);
270   }
271 }