forked from qt-creator/qt-creator
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>
This commit is contained in:
106
src/libs/3rdparty/cplusplus/Symbols.cpp
vendored
106
src/libs/3rdparty/cplusplus/Symbols.cpp
vendored
@@ -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()
|
||||
{ }
|
||||
|
||||
Reference in New Issue
Block a user