diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassSpecialization.java index cd970e2a291..1f35a5fc4a2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassSpecialization.java @@ -102,4 +102,11 @@ public interface ICPPClassSpecialization extends ICPPTypeSpecialization, ICPPCla * @since 5.5 */ ICPPClassType[] getNestedClasses(IASTNode point); + + /** + * Similar to {@link ICPPClassType#getUsingDeclarations()} but accepts a starting point + * for template instantiation. + * @since 6.2 + */ + ICPPUsingDeclaration[] getUsingDeclarations(IASTNode point); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassType.java index e2026bf3db5..d88b6f26614 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassType.java @@ -107,6 +107,11 @@ public interface ICPPClassType extends ICompositeType, ICPPBinding { * Returns an array of nested classes/structures */ public ICPPClassType[] getNestedClasses(); + + /** + * Returns an array of using declarations in this class. + */ + public ICPPUsingDeclaration[] getUsingDeclarations(); /** * Returns whether this type is declared final. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPUsingDeclaration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPUsingDeclaration.java index 45d7f6c4409..dbcbd214d65 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPUsingDeclaration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPUsingDeclaration.java @@ -23,6 +23,8 @@ import org.eclipse.cdt.core.dom.ast.IBinding; * @noimplement This interface is not intended to be implemented by clients. */ public interface ICPPUsingDeclaration extends ICPPBinding { + /** @since 6.2 */ + public static final ICPPUsingDeclaration[] EMPTY_USING_DECL_ARRAY = {}; /** * Return an array of bindings that were declared by this using declaration. * Each of these bindings delegates to some previously declared binding to which it diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/AbstractCPPClassSpecializationScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/AbstractCPPClassSpecializationScope.java index e4c4af6320f..4732b8ba8af 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/AbstractCPPClassSpecializationScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/AbstractCPPClassSpecializationScope.java @@ -36,6 +36,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.index.IIndexFileSet; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.CharArrayUtils; @@ -317,6 +318,12 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat ICPPClassType[] bindings = ClassTypeHelper.getNestedClasses(specialClass.getSpecializedBinding(), point); return specializeMembers(bindings, point); } + + @Override + public ICPPUsingDeclaration[] getUsingDeclarations(IASTNode point) { + ICPPUsingDeclaration[] bindings = ClassTypeHelper.getUsingDeclarations(specialClass.getSpecializedBinding(), point); + return specializeMembers(bindings, point); + } @Override public IBinding[] getFriends(IASTNode point) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java index 7e469af3e33..1d1cc7d212e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java @@ -43,6 +43,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.internal.core.dom.parser.IRecursionResolvingBinding; @@ -315,6 +316,21 @@ public class CPPClassSpecialization extends CPPSpecialization return scope.getNestedClasses(point); } + + @Override + public ICPPUsingDeclaration[] getUsingDeclarations() { + CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$ + return getUsingDeclarations(null); + } + + @Override + public ICPPUsingDeclaration[] getUsingDeclarations(IASTNode point) { + ICPPClassSpecializationScope scope = getSpecializationScope(); + if (scope == null) + return ClassTypeHelper.getUsingDeclarations(this); + + return scope.getUsingDeclarations(point); + } @Override public IField[] getFields() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java index ce18ed3f430..8628fc46eea 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplate.java @@ -37,6 +37,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexFileSet; import org.eclipse.cdt.core.parser.util.ArrayUtil; @@ -201,6 +202,11 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements ICPPClass public ICPPClassType[] getNestedClasses() { return ClassTypeHelper.getNestedClasses(this); } + + @Override + public ICPPUsingDeclaration[] getUsingDeclarations() { + return ClassTypeHelper.getUsingDeclarations(this); + } @Override public IField findField(String name) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java index 8732dc6a879..519858a03ed 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassType.java @@ -37,6 +37,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.parser.util.ArrayUtil; @@ -110,6 +111,10 @@ public class CPPClassType extends PlatformObject implements ICPPInternalClassTyp return ICPPClassType.EMPTY_CLASS_ARRAY; } @Override + public ICPPUsingDeclaration[] getUsingDeclarations() { + return ICPPUsingDeclaration.EMPTY_USING_DECL_ARRAY; + } + @Override public boolean isFinal() { return false; } @@ -368,6 +373,11 @@ public class CPPClassType extends PlatformObject implements ICPPInternalClassTyp public ICPPClassType[] getNestedClasses() { return ClassTypeHelper.getNestedClasses(this); } + + @Override + public ICPPUsingDeclaration[] getUsingDeclarations() { + return ClassTypeHelper.getUsingDeclarations(this); + } @Override public IField findField(String name) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java index a40e0f83ec8..991f4d758dd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java @@ -46,6 +46,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexFileSet; import org.eclipse.cdt.core.parser.util.CharArrayUtils; @@ -294,6 +295,11 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP public ICPPClassType[] getNestedClasses() { return ICPPClassType.EMPTY_CLASS_ARRAY; } + + @Override + public ICPPUsingDeclaration[] getUsingDeclarations() { + return ICPPUsingDeclaration.EMPTY_USING_DECL_ARRAY; + } @Override public IField findField(String name) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java index 0b88d219420..040ff241881 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java @@ -29,6 +29,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.internal.core.dom.parser.ISerializableType; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; @@ -157,6 +158,11 @@ public class CPPDeferredClassInstance extends CPPUnknownBinding implements ICPPD public ICPPClassType[] getNestedClasses() { return ICPPClassType.EMPTY_CLASS_ARRAY; } + + @Override + public ICPPUsingDeclaration[] getUsingDeclarations() { + return ICPPUsingDeclaration.EMPTY_USING_DECL_ARRAY; + } @Override public boolean isAnonymous() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java index e84aeb81be3..e08ece02ed4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameter.java @@ -36,6 +36,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; @@ -177,6 +178,11 @@ public class CPPTemplateTemplateParameter extends CPPTemplateParameter public ICPPClassType[] getNestedClasses() { return ICPPClassType.EMPTY_CLASS_ARRAY; } + + @Override + public ICPPUsingDeclaration[] getUsingDeclarations() { + return ICPPUsingDeclaration.EMPTY_USING_DECL_ARRAY; + } @Override public int getKey() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameterSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameterSpecialization.java index 4e65fb086f5..c36b53de1b0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameterSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateTemplateParameterSpecialization.java @@ -28,6 +28,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; /** * A specialization of a template template parameter. This is needed when a nested template @@ -108,6 +109,11 @@ public class CPPTemplateTemplateParameterSpecialization extends CPPTemplateParam public ICPPClassType[] getNestedClasses() { return ICPPClassType.EMPTY_CLASS_ARRAY; } + + @Override + public ICPPUsingDeclaration[] getUsingDeclarations() { + return ICPPUsingDeclaration.EMPTY_USING_DECL_ARRAY; + } @Override public boolean isFinal() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownMemberClass.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownMemberClass.java index 2b29295e8e9..0d851fb1a80 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownMemberClass.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownMemberClass.java @@ -24,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.parser.util.CharArrayUtils; /** @@ -114,6 +115,11 @@ public class CPPUnknownMemberClass extends CPPUnknownMember implements ICPPUnkno public ICPPClassType[] getNestedClasses() { return ICPPClassType.EMPTY_CLASS_ARRAY; } + + @Override + public ICPPUsingDeclaration[] getUsingDeclarations() { + return ICPPUsingDeclaration.EMPTY_USING_DECL_ARRAY; + } @Override public boolean isAnonymous() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java index e833378395d..62ee1a8ca98 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ClassTypeHelper.java @@ -40,6 +40,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IField; import org.eclipse.cdt.core.dom.ast.IProblemBinding; @@ -285,6 +286,12 @@ public class ClassTypeHelper { return ((ICPPClassSpecialization) classType).getNestedClasses(point); return classType.getNestedClasses(); } + + public static ICPPUsingDeclaration[] getUsingDeclarations(ICPPClassType classType, IASTNode point) { + if (classType instanceof ICPPClassSpecialization) + return ((ICPPClassSpecialization) classType).getUsingDeclarations(point); + return classType.getUsingDeclarations(); + } /** * Returns all direct and indirect base classes. @@ -613,6 +620,32 @@ public class ClassTypeHelper { } return ArrayUtil.trim(result); } + + public static ICPPUsingDeclaration[] getUsingDeclarations(ICPPInternalClassTypeMixinHost host) { + if (host.getDefinition() == null) { + host.checkForDefinition(); + if (host.getDefinition() == null) { + ICPPClassType backup= getBackupDefinition(host); + if (backup != null) + return backup.getUsingDeclarations(); + + return ICPPUsingDeclaration.EMPTY_USING_DECL_ARRAY; + } + } + ICPPUsingDeclaration[] result = ICPPUsingDeclaration.EMPTY_USING_DECL_ARRAY; + + IASTDeclaration[] decls = host.getCompositeTypeSpecifier().getMembers(); + for (IASTDeclaration decl : decls) { + if (decl instanceof ICPPASTUsingDeclaration) { + IBinding binding = ((ICPPASTUsingDeclaration) decl).getName().resolveBinding(); + if (binding instanceof ICPPUsingDeclaration) { + result = ArrayUtil.append(result, (ICPPUsingDeclaration) binding); + } + } + } + return ArrayUtil.trim(result); + + } public static IField[] getFields(ICPPClassType ct, IASTNode point) { IField[] fields = getDeclaredFields(ct, point); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPClassSpecializationScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPClassSpecializationScope.java index 23a33a01e9e..a6386ebde6e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPClassSpecializationScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPClassSpecializationScope.java @@ -20,6 +20,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; /** * Composite scope of a class specialization. Supports creating instances for bindings found @@ -75,4 +76,9 @@ public interface ICPPClassSpecializationScope extends ICPPClassScope { * Computes the nested classes via the original class. */ ICPPClassType[] getNestedClasses(IASTNode point); + + /** + * Computes the using declarations via the original class. + */ + ICPPUsingDeclaration[] getUsingDeclarations(IASTNode point); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AccessContext.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AccessContext.java index 5b51b4cd373..fc290600c7b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AccessContext.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AccessContext.java @@ -30,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClosureType; import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; @@ -200,6 +201,16 @@ public class AccessContext { return isAccessible(bindingVisibility, accessLevel); } + ICPPUsingDeclaration[] usingDecls = ClassTypeHelper.getUsingDeclarations(derivedClass, name); + for (ICPPUsingDeclaration decl : usingDecls) { + for (IBinding delegate : decl.getDelegates()) { + if (delegate.equals(binding)) { + derivedClass.getVisibility(decl); + return isAccessible(derivedClass.getVisibility(decl), accessLevel); + } + } + } + ICPPBase[] bases = ClassTypeHelper.getBases(derivedClass, name); if (bases != null) { for (ICPPBase base : bases) { 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 040b23aa3d2..1b51d0bc107 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 @@ -36,6 +36,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; @@ -204,6 +205,11 @@ public class HeuristicResolver { public ICPPClassType[] getNestedClasses(IASTNode point) { throw new UnsupportedOperationException(); } + + @Override + public ICPPUsingDeclaration[] getUsingDeclarations(IASTNode point) { + throw new UnsupportedOperationException(); + } } /** diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecialization.java index b71c3d8461b..15c17ff07e3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecialization.java @@ -29,6 +29,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassSpecialization.RecursionResolvingBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap; @@ -263,4 +264,20 @@ public class CompositeCPPClassSpecialization extends CompositeCPPClassType imple ICPPClassType[] result = ClassTypeHelper.getNestedClasses((ICPPClassType) rbinding, point); return wrapBindings(result); } + + @Override + public ICPPUsingDeclaration[] getUsingDeclarations() { + CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$ + return getUsingDeclarations(null); + } + + @Override + public ICPPUsingDeclaration[] getUsingDeclarations(IASTNode point) { + IScope scope= getCompositeScope(); + if (scope instanceof ICPPClassSpecializationScope) { + return ((ICPPClassSpecializationScope) scope).getUsingDeclarations(point); + } + ICPPUsingDeclaration[] result = ClassTypeHelper.getUsingDeclarations((ICPPClassType) rbinding, point); + return wrapBindings(result); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecializationScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecializationScope.java index fa09bd10abd..ae40154c925 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecializationScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecializationScope.java @@ -24,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexFileSet; import org.eclipse.cdt.internal.core.dom.parser.cpp.AbstractCPPClassSpecializationScope; @@ -152,4 +153,10 @@ public class CompositeCPPClassSpecializationScope extends CompositeScope impleme createDelegate(); return fDelegate.getNestedClasses(point); } + + @Override + public ICPPUsingDeclaration[] getUsingDeclarations(IASTNode point) { + createDelegate(); + return fDelegate.getUsingDeclarations(point); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassType.java index c828c13a7dd..3ff0299b711 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassType.java @@ -28,6 +28,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; import org.eclipse.cdt.internal.core.index.IIndexType; @@ -173,6 +174,12 @@ class CompositeCPPClassType extends CompositeCPPBinding implements ICPPClassType ICPPClassType[] result = ((ICPPClassType) rbinding).getNestedClasses(); return wrapBindings(result); } + + @Override + public ICPPUsingDeclaration[] getUsingDeclarations() { + ICPPUsingDeclaration[] result = ((ICPPClassType) rbinding).getUsingDeclarations(); + return wrapBindings(result); + } @Override public ICPPScope getCompositeScope() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPTemplateTemplateParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPTemplateTemplateParameter.java index 4d3f597951d..2ebf791d010 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPTemplateTemplateParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPTemplateTemplateParameter.java @@ -27,6 +27,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; @@ -154,6 +155,11 @@ public class CompositeCPPTemplateTemplateParameter extends CompositeCPPBinding public ICPPClassType[] getNestedClasses() { return ICPPClassType.EMPTY_CLASS_ARRAY; } + + @Override + public ICPPUsingDeclaration[] getUsingDeclarations() { + return ICPPUsingDeclaration.EMPTY_USING_DECL_ARRAY; + } @Override public IScope getCompositeScope() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java index a9d74762eb2..ca339a7be77 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java @@ -43,6 +43,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding; @@ -636,6 +637,11 @@ public class PDOMASTAdapter { public ICPPClassType[] getNestedClasses() { return ((ICPPClassType) fDelegate).getNestedClasses(); } + + @Override + public ICPPUsingDeclaration[] getUsingDeclarations() { + return ((ICPPClassType) fDelegate).getUsingDeclarations(); + } @Override public boolean isSameType(IType type) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java index eecd7f27bbc..a92949ff091 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java @@ -36,6 +36,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassSpecialization.RecursionResolvingBinding; @@ -361,6 +362,28 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization return ICPPClassType.EMPTY_CLASS_ARRAY; } } + + @Override + public ICPPUsingDeclaration[] getUsingDeclarations() { + CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$ + return getUsingDeclarations(null); + } + + @Override + public ICPPUsingDeclaration[] getUsingDeclarations(IASTNode point) { + IScope scope= getCompositeScope(); + if (scope instanceof ICPPClassSpecializationScope) { + return ((ICPPClassSpecializationScope) scope).getUsingDeclarations(point); + } + try { + PDOMClassUtil.UsingDeclarationCollector visitor = new PDOMClassUtil.UsingDeclarationCollector(); + PDOMCPPClassScope.acceptViaCache(this, visitor, false); + return visitor.getUsingDeclarations(); + } catch (CoreException e) { + CCorePlugin.log(e); + return ICPPUsingDeclaration.EMPTY_USING_DECL_ARRAY; + } + } @Override public IBinding[] getFriends() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java index 6eae0307abb..f2a36792d1e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassType.java @@ -33,6 +33,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; @@ -373,6 +374,18 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO return ICPPClassType.EMPTY_CLASS_ARRAY; } } + + @Override + public ICPPUsingDeclaration[] getUsingDeclarations() { + try { + PDOMClassUtil.UsingDeclarationCollector visitor = new PDOMClassUtil.UsingDeclarationCollector(); + PDOMCPPClassScope.acceptViaCache(this, visitor, false); + return visitor.getUsingDeclarations(); + } catch (CoreException e) { + CCorePlugin.log(e); + return ICPPUsingDeclaration.EMPTY_USING_DECL_ARRAY; + } + } @Override public IBinding[] getFriends() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateTemplateParameter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateTemplateParameter.java index da1b0d4487a..5c2f2da54ea 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateTemplateParameter.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTemplateTemplateParameter.java @@ -32,6 +32,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; @@ -319,6 +320,11 @@ public class PDOMCPPTemplateTemplateParameter extends PDOMCPPBinding public ICPPClassType[] getNestedClasses() { return ICPPClassType.EMPTY_CLASS_ARRAY; } + + @Override + public ICPPUsingDeclaration[] getUsingDeclarations() { + return ICPPUsingDeclaration.EMPTY_USING_DECL_ARRAY; + } @Override public IScope getCompositeScope() { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMClassUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMClassUtil.java index 63e28480fad..7e32cfe75b3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMClassUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMClassUtil.java @@ -21,6 +21,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.index.IndexFilter; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; import org.eclipse.core.runtime.CoreException; @@ -136,4 +137,24 @@ class PDOMClassUtil { return nestedClasses.toArray(new ICPPClassType[nestedClasses.size()]); } } + + static class UsingDeclarationCollector implements IPDOMVisitor { + private final List usingDeclarations = new ArrayList<>(); + + @Override + public boolean visit(IPDOMNode node) throws CoreException { + if (node instanceof ICPPUsingDeclaration) { + usingDeclarations.add((ICPPUsingDeclaration) node); + } + return false; + } + + @Override + public void leave(IPDOMNode node) throws CoreException { + } + + public ICPPUsingDeclaration[] getUsingDeclarations() { + return usingDeclarations.toArray(new ICPPUsingDeclaration[usingDeclarations.size()]); + } + } } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java index e09d03ff10a..6a58f911f53 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java @@ -1880,4 +1880,36 @@ public class CompletionTests extends AbstractContentAssistTest { assertCompletionResults(fCursorOffset, expected, ID); assertDotReplacedWithArrow(); } + + // struct A { + // int waldo; + // }; + // class B : private A { + // public: + // using A::waldo; // allows public access despire private inheritance + // }; + // void test() { + // B obj; + // obj./*cursor*/ + // } + public void testMemberExposedViaUsingDecl_bug292236a() throws Exception { + final String[] expected = { "B", "A", "waldo" }; + assertCompletionResults(fCursorOffset, expected, ID); + } + + // struct A { + // int waldo; + // }; + // class B : private A { + // public: + // A::waldo; // allows public access despire private inheritance + // }; + // void test() { + // B obj; + // obj./*cursor*/ + // } + public void testMemberExposedViaUsingDecl_bug292236b() throws Exception { + final String[] expected = { "B", "A", "waldo" }; + assertCompletionResults(fCursorOffset, expected, ID); + } }