From 7bcf4831891536992607b5a7b43675590790ee59 Mon Sep 17 00:00:00 2001 From: Przemyslaw Gorszkowski Date: Wed, 24 May 2017 11:08:24 +0200 Subject: 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 unique_ptr { typedef some_strange_things pointer; pointer operator->(); } is replace with template 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 --- src/libs/3rdparty/cplusplus/Symbols.cpp | 106 ++++++++++++++++++++++++++++++-- 1 file changed, 101 insertions(+), 5 deletions(-) (limited to 'src/libs/3rdparty/cplusplus') 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 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() { } -- cgit v1.2.3