aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/3rdparty/cplusplus
diff options
context:
space:
mode:
authorPrzemyslaw Gorszkowski <pgorszkowski@gmail.com>2017-05-24 11:08:24 +0200
committerPrzemyslaw Gorszkowski <pgorszkowski@gmail.com>2017-06-15 17:18:20 +0000
commit7bcf4831891536992607b5a7b43675590790ee59 (patch)
tree4b71a2479d5dd31d500d2d0a8c17b4538866ee42 /src/libs/3rdparty/cplusplus
parentd3d3e2ace5485d3812d98b5b3f3ccd8e7c12b4f1 (diff)
C++: fix code completion of stl containers in internal code model
This fix makes some trick and replaces existing typedef of 'pointer' to the simplest one(only in class unique_ptr), e.g.: template <class _Tp> class unique_ptr { typedef some_strange_things pointer; pointer operator->(); } is replace with template <class _Tp> class unique_ptr { typedef _Tp* pointer; pointer operator->(); } In most of the implementation of unique_ptr it should work. Similar approach is done for std::list, std::vector, std::queue, std::set, std::multiset, std::unordered_set. It is done in this hacky way to omit problems with cyclic and complex resolving of typedefs. Change-Id: I1363dfc5e23d3cd2fa7af7fc27423bfbac2d894d Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
Diffstat (limited to 'src/libs/3rdparty/cplusplus')
-rw-r--r--src/libs/3rdparty/cplusplus/Symbols.cpp106
1 files changed, 101 insertions, 5 deletions
diff --git a/src/libs/3rdparty/cplusplus/Symbols.cpp b/src/libs/3rdparty/cplusplus/Symbols.cpp
index 253bb04788..f7423e7742 100644
--- a/src/libs/3rdparty/cplusplus/Symbols.cpp
+++ b/src/libs/3rdparty/cplusplus/Symbols.cpp
@@ -18,13 +18,18 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
-#include "Symbols.h"
-#include "Names.h"
-#include "TypeVisitor.h"
-#include "SymbolVisitor.h"
+#include "Control.h"
+#include "CoreTypes.h"
+#include "Literals.h"
#include "Matcher.h"
+#include "Names.h"
#include "Scope.h"
+#include "Symbols.h"
+#include "SymbolVisitor.h"
#include "Templates.h"
+#include "TypeVisitor.h"
+
+#include <cstring>
using namespace CPlusPlus;
@@ -99,7 +104,98 @@ Declaration::Declaration(Clone *clone, Subst *subst, Declaration *original)
: Symbol(clone, subst, original)
, _type(clone->type(original->_type, subst))
, _initializer(clone->stringLiteral(original->_initializer))
-{ }
+{
+ const char* nameId = nullptr;
+ if (const Identifier* identifier = name()->identifier())
+ nameId = identifier->chars();
+ else
+ return;
+
+ Class *enClass = original->enclosingClass();
+ const char* enClassNameId = nullptr;
+ if (enClass && enClass->name() && enClass->name()->identifier()) {
+ enClassNameId = enClass->name()->identifier()->chars();
+ } else {
+ return;
+ }
+
+ if (!enClassNameId)
+ return;
+
+ Template *templSpec = enClass->enclosingTemplate();
+ const char* enNamespaceNameId = nullptr;
+ if (templSpec) {
+ if (Namespace* ns = templSpec->enclosingNamespace()) {
+ if (ns->isInline())
+ ns = ns->enclosingNamespace();
+
+ if (ns->name() && ns->name()->identifier())
+ enNamespaceNameId =ns->name()->identifier()->chars();
+ }
+ }
+
+ if (!enNamespaceNameId || templSpec->templateParameterCount() < 1)
+ return;
+
+ const Name *firstTemplParamName = nullptr;
+ if (const TypenameArgument *templParam =
+ templSpec->templateParameterAt(0)->asTypenameArgument()) {
+ firstTemplParamName = templParam->name();
+ }
+
+ if (!firstTemplParamName)
+ return;
+
+ FullySpecifiedType newType;
+ if (std::strcmp(enNamespaceNameId, "std") == 0 ||
+ std::strcmp(enNamespaceNameId, "__cxx11") == 0) {
+ if (std::strcmp(enClassNameId, "unique_ptr") == 0) {
+ if (std::strcmp(nameId, "pointer") == 0) {
+ newType = clone->type(subst->apply(firstTemplParamName), 0);
+ newType = FullySpecifiedType(clone->control()->pointerType(newType));
+ }
+ } else if (std::strcmp(enClassNameId, "list") == 0 ||
+ std::strcmp(enClassNameId, "forward_list") == 0 ||
+ std::strcmp(enClassNameId, "vector") == 0 ||
+ std::strcmp(enClassNameId, "queue") == 0 ||
+ std::strcmp(enClassNameId, "deque") == 0 ||
+ std::strcmp(enClassNameId, "set") == 0 ||
+ std::strcmp(enClassNameId, "unordered_set") == 0 ||
+ std::strcmp(enClassNameId, "multiset") == 0 ||
+ std::strcmp(enClassNameId, "array") == 0) {
+ if (std::strcmp(nameId, "reference") == 0 ||
+ std::strcmp(nameId, "const_reference") == 0) {
+ newType = clone->type(subst->apply(firstTemplParamName), 0);
+ } else if (std::strcmp(nameId, "iterator") == 0 ||
+ std::strcmp(nameId, "reverse_iterator") == 0 ||
+ std::strcmp(nameId, "const_reverse_iterator") == 0 ||
+ std::strcmp(nameId, "const_iterator") == 0) {
+ newType = clone->type(subst->apply(firstTemplParamName), 0);
+ newType = FullySpecifiedType(clone->control()->pointerType(newType));
+ }
+ } else if (std::strcmp(enClassNameId, "_Hash") == 0 ||
+ std::strcmp(enClassNameId, "_Tree") == 0 ) {
+ if (std::strcmp(nameId, "iterator") == 0 ||
+ std::strcmp(nameId, "reverse_iterator") == 0 ||
+ std::strcmp(nameId, "const_reverse_iterator") == 0 ||
+ std::strcmp(nameId, "const_iterator") == 0) {
+ FullySpecifiedType clonedType = clone->type(subst->apply(firstTemplParamName), 0);
+ if (NamedType *namedType = clonedType.type()->asNamedType()) {
+ if (const TemplateNameId * templateNameId =
+ namedType->name()->asTemplateNameId()) {
+ if (templateNameId->templateArgumentCount()) {
+ newType = clone->type(templateNameId->templateArgumentAt(0), 0);
+ newType = FullySpecifiedType(clone->control()->pointerType(newType));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (newType.isValid())
+ _type = newType;
+}
Declaration::~Declaration()
{ }