[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
Re: [cdt-dev] Bug in autocomplete with simple templates
|
Hi,
I tried to fix this issue as my bedtime sweet today. I'm waiting for the bug
report and add some unit test, then I can push to gerrit. Or someone else
does, since I don't really have time right now.
bye Michi
On Tuesday, 22 September 2015 11:26:40 CEST Sergey Prigogin wrote:
> Please file a bug.
>
> -sergey
>
> On Tue, Sep 22, 2015 at 7:03 AM, Alec Teal <a.teal@xxxxxxxxxxxxx> wrote:
> > Also a problem on
> > 8.7.0.201506070905
> >
> > How has no one spotted this?
> >
> > On 22/09/15 11:30, Alec Teal wrote:
> >> I've got sample code (I've distilled the problem to these, I didn't start
> >> naming at C)
> >>
> >> -----------------------------------------------------
> >> //template<int k>
> >> //any template will do (eg class T)
> >> class D {
> >>
> >> struct C {
> >>
> >> C* c;
> >>
> >> };
> >>
> >> private:
> >> C c;
> >>
> >> public:
> >> void f() {
> >>
> >> //Auto complete on c works great if you keep the template bit
> >>
> >> commented
> >>
> >> }
> >>
> >> };
> >> ----------------------------------------------------------
> >>
> >> I've reproduced on two computers using (I think) the same version, can
> >> confirm one of them is:
> >> 8.3.0.201402142303 (whoa, that's old) the other computer is a recent grab
> >> of Eclipse Kepler.... actually I'll look into updating. Was there an easy
> >> fix (and has it been fixed?)
> >>
> >> Alec
> >> _______________________________________________
> >> cdt-dev mailing list
> >> cdt-dev@xxxxxxxxxxx
> >> To change your delivery options, retrieve your password, or unsubscribe
> >> from this list, visit
> >> https://dev.eclipse.org/mailman/listinfo/cdt-dev
> >
> > _______________________________________________
> > cdt-dev mailing list
> > cdt-dev@xxxxxxxxxxx
> > To change your delivery options, retrieve your password, or unsubscribe
> > from this list, visit
> > https://dev.eclipse.org/mailman/listinfo/cdt-dev
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/HeuristicResolver.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/HeuristicResolver.java
index e2f4d2a..5943128 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/HeuristicResolver.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/HeuristicResolver.java
@@ -22,10 +22,11 @@
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownMember;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
@@ -40,40 +41,59 @@
public static IScope findConcreteScopeForType(IType type, IASTNode point) {
if (type instanceof ICPPDeferredClassInstance) {
// If this scope is for a deferred-class-instance, use the scope of the primary template.
ICPPDeferredClassInstance instance = (ICPPDeferredClassInstance) type;
return instance.getClassTemplate().getCompositeScope();
- } else if (type instanceof TypeOfDependentExpression) {
+ }
+
+ while (type instanceof TypeOfDependentExpression) {
// If this scope is for the id-expression of a field reference, and the field owner
// is a deferred-class-instance, look up the field in the scope of the primary template,
// and use the scope of the resulting field type.
ICPPEvaluation evaluation = ((TypeOfDependentExpression) type).getEvaluation();
+ while (evaluation instanceof EvalUnary) {
+ evaluation = ((EvalUnary) evaluation).getArgument();
+ }
+ if (evaluation instanceof EvalFixed) {
+ type = ((EvalFixed) evaluation).getType();
+ continue;
+ }
if (evaluation instanceof EvalID) {
EvalID evalId = (EvalID) evaluation;
ICPPEvaluation fieldOwner = evalId.getFieldOwner();
if (fieldOwner != null) {
IType fieldOwnerType = fieldOwner.getTypeOrFunctionSet(point);
+ IScope scope = null;
+ if (fieldOwnerType instanceof TypeOfDependentExpression) {
+ scope = findConcreteScopeForType(fieldOwnerType, point);
+ }
if (fieldOwnerType instanceof ICPPDeferredClassInstance) {
ICPPDeferredClassInstance instance = (ICPPDeferredClassInstance) fieldOwnerType;
- IScope scope = instance.getClassTemplate().getCompositeScope();
+ scope = instance.getClassTemplate().getCompositeScope();
+ } else if (fieldOwnerType instanceof ICPPClassType) {
+ scope = ((ICPPClassType) fieldOwnerType).getCompositeScope();
+ }
+ if (scope != null) {
LookupData lookup = new LookupData(evalId.getName(), evalId.getTemplateArgs(), point);
lookup.qualified = evalId.isQualified();
try {
CPPSemantics.lookup(lookup, scope);
} catch (DOMException e) {
return null;
}
IBinding[] bindings = lookup.getFoundBindings();
if (bindings.length == 1 && bindings[0] instanceof IField) {
IType fieldType = ((IField) bindings[0]).getType();
+ fieldType = SemanticUtil.getNestedType(fieldType, SemanticUtil.TDEF|SemanticUtil.PTR);
if (fieldType instanceof ICompositeType) {
return ((ICompositeType) fieldType).getCompositeScope();
}
}
}
}
}
+ break;
}
// TODO(nathanridge): Handle more cases.
return null;
}
@@ -94,13 +114,14 @@
ownerType = SemanticUtil.getSimplifiedType(ownerType);
if (isPointerDeref && ownerType instanceof IPointerType) {
ownerType = ((IPointerType) ownerType).getType();
isPointerDeref = false;
}
+ IType lookupType = ownerType;
if (ownerType instanceof ICPPUnknownType) {
- IType lookupType = resolveUnknownType((ICPPUnknownType) ownerType, point);
- // ... or inside the dependent type.
+ lookupType = resolveUnknownType((ICPPUnknownType) ownerType, point);
+ } // ... or inside the dependent type.
if (isPointerDeref) {
lookupType = SemanticUtil.getSimplifiedType(lookupType);
if (lookupType instanceof IPointerType) {
lookupType = ((IPointerType) lookupType).getType();
} else {
@@ -117,11 +138,10 @@
return foundBindings;
}
} catch (DOMException e) {
}
}
- }
return IBinding.EMPTY_BINDING_ARRAY;
}
/**
* Helper function for resolveUnknownType().
@@ -146,11 +166,11 @@
*
* Returns null if no heuristic resolution could be performed.
* @param point the point of instantiation for lookups
*/
- private static IType resolveUnknownType(ICPPUnknownType type, IASTNode point) {
+ public static IType resolveUnknownType(ICPPUnknownType type, IASTNode point) {
if (type instanceof ICPPDeferredClassInstance) {
return ((ICPPDeferredClassInstance) type).getClassTemplate();
} else if (type instanceof TypeOfDependentExpression) {
ICPPEvaluation evaluation = ((TypeOfDependentExpression) type).getEvaluation();
if (evaluation instanceof EvalUnary) {
@@ -192,11 +212,11 @@
* @param point the point of instantiation for lookups
*/
public static IBinding[] resolveUnknownBinding(ICPPUnknownBinding binding, IASTNode point) {
if (binding instanceof ICPPDeferredClassInstance) {
return new IBinding[] { ((ICPPDeferredClassInstance) binding).getClassTemplate() };
- } else if (binding instanceof ICPPUnknownMember) {
+ } else if (binding instanceof ICPPUnknownMember && !(binding instanceof ICPPTemplateParameter)) {
return lookInside(((ICPPUnknownMember) binding).getOwnerType(), false,
binding.getNameCharArray(), null, point);
}
return IBinding.EMPTY_BINDING_ARRAY;
}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/CContentAssistProcessor.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/CContentAssistProcessor.java
index ad6df3d..077e937 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/CContentAssistProcessor.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/contentassist/CContentAssistProcessor.java
@@ -42,10 +42,12 @@
import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.text.ICCompletionProposal;
import org.eclipse.cdt.ui.text.contentassist.ContentAssistInvocationContext;
import org.eclipse.cdt.ui.text.contentassist.IProposalFilter;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.HeuristicResolver;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.cdt.internal.ui.preferences.ProposalFilterPreferencesUtil;
import org.eclipse.cdt.internal.ui.text.CHeuristicScanner;
import org.eclipse.cdt.internal.ui.text.CParameterListValidator;
@@ -271,10 +273,13 @@
IASTName[] names = node.getNames();
if (names.length > 0 && names[0].getParent() instanceof IASTFieldReference) {
IASTFieldReference ref = (IASTFieldReference) names[0].getParent();
IASTExpression ownerExpr = ref.getFieldOwner();
IType ownerExprType = SemanticUtil.getNestedType(ownerExpr.getExpressionType(), SemanticUtil.TDEF);
+ if (ownerExprType instanceof ICPPUnknownType) {
+ ownerExprType = HeuristicResolver.resolveUnknownType((ICPPUnknownType) ownerExprType,names[0]);
+ }
if (ownerExprType instanceof IPointerType) {
context = replaceDotWithArrow(viewer, offset, isCompletion, context, activationChar);
}
}
}