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 d2a8d059425..a1b3233fec1 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 @@ -23,11 +23,13 @@ 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.ICPPEnumeration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; 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.ICPPUnknownMemberClass; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType; public class HeuristicResolver { @@ -107,11 +109,17 @@ public class HeuristicResolver { lookupType = null; } } + IScope lookupScope = null; if (lookupType instanceof ICPPClassType) { + lookupScope = ((ICPPClassType) lookupType).getCompositeScope(); + } else if (lookupType instanceof ICPPEnumeration) { + lookupScope = ((ICPPEnumeration) lookupType).asScope(); + } + if (lookupScope != null) { LookupData lookup = new LookupData(name, templateArgs, point); lookup.fHeuristicBaseLookup = true; try { - CPPSemantics.lookup(lookup, ((ICPPClassType) lookupType).getCompositeScope()); + CPPSemantics.lookup(lookup, lookupScope); IBinding[] foundBindings = lookup.getFoundBindings(); if (foundBindings.length > 0) { return foundBindings; @@ -179,6 +187,15 @@ public class HeuristicResolver { } } // TODO(nathanridge): Handle more cases. + } else if (type instanceof ICPPUnknownMemberClass) { + ICPPUnknownMemberClass member = (ICPPUnknownMemberClass) type; + IBinding[] candidates = lookInside(member.getOwnerType(), false, member.getNameCharArray(), + null, point); + if (candidates.length == 1) { + if (candidates[0] instanceof IType) { + return (IType) candidates[0]; + } + } } return null; } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/SemanticHighlightingTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/SemanticHighlightingTest.java index 559c4b68607..c9e24f07377 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/SemanticHighlightingTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/SemanticHighlightingTest.java @@ -491,4 +491,20 @@ public class SemanticHighlightingTest extends TestCase { public void testLocalVariableInLambdaCapture_486679() throws Exception { makeAssertions(); } + + // template //$templateParameter + // struct Base { //$class + // enum E { A }; //$enum,enumerator + // enum class F { B }; //$enum,enumerator + // }; + // template //$templateParameter + // struct Derived : Base { //$class,class,templateParameter + // static typename Base::E x //$class,templateParameter,enum,staticField + // = Base::A; //$class,templateParameter,enumerator + // static typename Base::F y //$class,templateParameter,enum,staticField + // = Base::F::B; //$class,templateParameter,enum,enumerator + // }; + public void testDependentEnum_486688() throws Exception { + makeAssertions(); + } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java index 8a2c6869bcb..c4e6ac69eef 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java @@ -76,6 +76,7 @@ import org.eclipse.cdt.ui.text.ISemanticToken; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.HeuristicResolver; /** * Semantic highlightings. @@ -304,6 +305,11 @@ public class SemanticHighlightings { } IBinding binding= token.getBinding(); if (binding instanceof IField) { + if (binding instanceof ICPPUnknownBinding) { + if (heuristicallyResolvesToEnumerator((ICPPUnknownBinding) binding, node)) { + return false; + } + } return true; } } @@ -990,6 +996,11 @@ public class SemanticHighlightings { if (node instanceof IASTName) { IBinding binding= token.getBinding(); if (binding instanceof ICompositeType && !(binding instanceof ICPPTemplateParameter)) { + if (binding instanceof ICPPUnknownBinding) { + if (heuristicallyResolvesToEnumeration((ICPPUnknownBinding) binding, node)) { + return false; + } + } return true; } } @@ -1042,6 +1053,11 @@ public class SemanticHighlightings { if (binding instanceof IEnumeration) { return true; } + if (binding instanceof ICPPUnknownBinding) { + if (heuristicallyResolvesToEnumeration((ICPPUnknownBinding) binding, node)) { + return true; + } + } } return false; } @@ -1338,6 +1354,11 @@ public class SemanticHighlightings { if (binding instanceof IEnumerator) { return true; } + if (binding instanceof ICPPUnknownBinding) { + if (heuristicallyResolvesToEnumerator((ICPPUnknownBinding) binding, node)) { + return true; + } + } } return false; } @@ -1595,7 +1616,17 @@ public class SemanticHighlightings { || token.getNode() instanceof ICPPASTClassVirtSpecifier; } } - + + private static boolean heuristicallyResolvesToEnumeration(ICPPUnknownBinding binding, IASTNode point) { + IBinding[] resolved = HeuristicResolver.resolveUnknownBinding(binding, point); + return resolved.length == 1 && resolved[0] instanceof IEnumeration; + } + + private static boolean heuristicallyResolvesToEnumerator(ICPPUnknownBinding binding, IASTNode point) { + IBinding[] resolved = HeuristicResolver.resolveUnknownBinding(binding, point); + return resolved.length == 1 && resolved[0] instanceof IEnumerator; + } + // Note on the get___PreferenceKey() functions below: // - For semantic highlightings deriving from SemanticHighlightingWithOwnPreference, // these functions return keys for accessing the highlighting's own preferences.