From c74cc8a309084c1aaee128b750eeefd834b3f550 Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Fri, 3 Aug 2012 15:35:06 -0700 Subject: [PATCH] Bug 299911. Improved propagation of name lookup context. --- .../parser/tests/ast2/SemanticsTests.java | 2 +- .../dom/ast/cpp/ICPPClassSpecialization.java | 40 +++++++- .../AbstractCPPClassSpecializationScope.java | 34 ++++--- .../CPPASTConstructorChainInitializer.java | 3 +- .../dom/parser/cpp/CPPASTQualifiedName.java | 6 +- .../parser/cpp/CPPClassSpecialization.java | 37 ++++++-- .../cpp/ICPPClassSpecializationScope.java | 26 ++++-- .../parser/cpp/semantics/BaseClassLookup.java | 8 +- .../cpp/semantics/BuiltinOperators.java | 8 +- .../parser/cpp/semantics/CPPEvaluation.java | 7 ++ .../parser/cpp/semantics/CPPSemantics.java | 45 ++++----- .../parser/cpp/semantics/CPPTemplates.java | 2 +- .../dom/parser/cpp/semantics/CPPVisitor.java | 12 ++- .../dom/parser/cpp/semantics/Conversions.java | 91 ++++++++++--------- .../core/dom/parser/cpp/semantics/Cost.java | 12 +-- .../parser/cpp/semantics/EvalConditional.java | 4 +- .../core/dom/parser/cpp/semantics/EvalID.java | 3 + .../dom/parser/cpp/semantics/EvalUnary.java | 13 +-- .../parser/cpp/semantics/EvalUnaryTypeID.java | 11 +-- .../parser/cpp/semantics/FunctionCost.java | 16 ++-- .../parser/cpp/semantics/SemanticUtil.java | 69 +++++++++++--- .../cpp/CompositeCPPClassSpecialization.java | 39 ++++++-- .../CompositeCPPClassSpecializationScope.java | 30 ++++-- .../dom/cpp/PDOMCPPClassSpecialization.java | 40 ++++++-- 24 files changed, 369 insertions(+), 189 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/SemanticsTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/SemanticsTests.java index 760aedb62bc..e4d259c68bc 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/SemanticsTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/SemanticsTests.java @@ -90,7 +90,7 @@ public class SemanticsTests extends AST2BaseTest { // Test getDeclaredConversionOperators() BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true); ICPPClassType c= ba.assertNonProblem("X {", 1, ICPPClassType.class); - ICPPMethod[] cops= SemanticUtil.getDeclaredConversionOperators(c); + ICPPMethod[] cops= SemanticUtil.getDeclaredConversionOperators(c, null); assertEquals(2, cops.length); Set actual= new HashSet(); actual.add(cops[0].getName()); actual.add(cops[1].getName()); 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 8f77959f00b..229697cb7d8 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2009 Wind River Systems, Inc. and others. + * Copyright (c) 2008, 2012 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * Markus Schorn - initial API and implementation + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.core.dom.ast.cpp; @@ -42,5 +43,40 @@ public interface ICPPClassSpecialization extends ICPPSpecialization, ICPPClassTy * instantiation. * @since 5.5 */ - public ICPPBase[] getBases(IASTNode point); + ICPPBase[] getBases(IASTNode point); + + /** + * Similar to {@link ICPPClassType#getConstructors()} but a accepts a starting point + * for template instantiation. + * @since 5.5 + */ + ICPPConstructor[] getConstructors(IASTNode point); + + /** + * Similar to {@link ICPPClassType#getDeclaredFields()} but a accepts a starting point + * for template instantiation. + * @since 5.5 + */ + ICPPField[] getDeclaredFields(IASTNode point); + + /** + * Similar to {@link ICPPClassType#getDeclaredMethods()} but a accepts a starting point + * for template instantiation. + * @since 5.5 + */ + ICPPMethod[] getDeclaredMethods(IASTNode point); + + /** + * Similar to {@link ICPPClassType#getFriends()} but a accepts a starting point + * for template instantiation. + * @since 5.5 + */ + IBinding[] getFriends(IASTNode point); + + /** + * Similar to {@link ICPPClassType#getNestedClasses()} but a accepts a starting point + * for template instantiation. + * @since 5.5 + */ + ICPPClassType[] getNestedClasses(IASTNode point); } 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 82af915cf26..0c02d4274c4 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2011 IBM Corporation and others. + * Copyright (c) 2005, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,6 +10,7 @@ * Markus Schorn (Wind River Systems) * Bryan Wilkinson (QNX) * Andrew Ferguson (Symbian) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -181,15 +182,18 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat } @Override - public ICPPField[] getDeclaredFields() { - IASTNode point= null; // Instantiation of dependent expression may not work. + public ICPPField[] getDeclaredFields(IASTNode point) { ICPPField[] fields= specialClass.getSpecializedBinding().getDeclaredFields(); return specializeMembers(fields, point); } - + @Override public ICPPMethod[] getImplicitMethods() { - IASTNode point= null; // Instantiation of dependent expression may not work. + return getImplicitMethods(null); // Instantiation of dependent expression may not work. + } + + @Override + public ICPPMethod[] getImplicitMethods(IASTNode point) { ICPPClassScope origClassScope= (ICPPClassScope) specialClass.getSpecializedBinding().getCompositeScope(); if (origClassScope == null) { return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; @@ -207,29 +211,29 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat @Override public ICPPConstructor[] getConstructors() { - // mstodo need to pass the point of instantiation - IASTNode point= null; // Instantiation of dependent expression may not work. - ICPPConstructor[] ctors= specialClass.getSpecializedBinding().getConstructors(); - return specializeMembers(ctors, point); + return getConstructors(null); // Instantiation of dependent expression may not work. } @Override - public ICPPMethod[] getDeclaredMethods() { - IASTNode point= null; // Instantiation of dependent expression may not work. + public ICPPConstructor[] getConstructors(IASTNode point) { + ICPPConstructor[] ctors= specialClass.getSpecializedBinding().getConstructors(); + return specializeMembers(ctors, point); + } + + @Override + public ICPPMethod[] getDeclaredMethods(IASTNode point) { ICPPMethod[] bindings = specialClass.getSpecializedBinding().getDeclaredMethods(); return specializeMembers(bindings, point); } @Override - public ICPPClassType[] getNestedClasses() { - IASTNode point= null; // Instantiation of dependent expression may not work. + public ICPPClassType[] getNestedClasses(IASTNode point) { ICPPClassType[] bindings = specialClass.getSpecializedBinding().getNestedClasses(); return specializeMembers(bindings, point); } @Override - public IBinding[] getFriends() { - IASTNode point= null; // Instantiation of dependent expression may not work. + public IBinding[] getFriends(IASTNode point) { IBinding[] friends = specialClass.getSpecializedBinding().getFriends(); return specializeMembers(friends, point); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorChainInitializer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorChainInitializer.java index a07965123db..bc482f514c9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorChainInitializer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorChainInitializer.java @@ -35,6 +35,7 @@ import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.CharArraySet; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; /** * For example in the constructor definition
@@ -174,7 +175,7 @@ public class CPPASTConstructorChainInitializer extends ASTNode implements IBinding method= fdef.getDeclarator().getName().resolveBinding(); if (method instanceof ICPPMethod) { ICPPClassType cls= ((ICPPMethod) method).getClassOwner(); - for (ICPPBase base : cls.getBases()) { + for (ICPPBase base : SemanticUtil.getBases(cls, fdef)) { result.put(base.getBaseClassSpecifierName().getSimpleID()); } return result; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java index 68a6a9938aa..5c7e349989a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java @@ -271,14 +271,14 @@ public class CPPASTQualifiedName extends CPPASTNameBase IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix, namespaces); if (namesPos > 0) { - IBinding binding = names[namesPos-1].resolveBinding(); + IBinding binding = names[namesPos - 1].resolveBinding(); if (binding instanceof ICPPClassType) { ICPPClassType classType = (ICPPClassType) binding; final boolean isDeclaration = getParent().getParent() instanceof IASTSimpleDeclaration; List filtered = filterClassScopeBindings(classType, bindings, isDeclaration); if (isDeclaration && nameMatches(classType.getNameCharArray(), n.getLookupKey(), isPrefix)) { - ICPPConstructor[] constructors = classType.getConstructors(); + ICPPConstructor[] constructors = SemanticUtil.getConstructors(classType, n); for (int i = 0; i < constructors.length; i++) { if (!constructors[i].isImplicit()) { filtered.add(constructors[i]); @@ -303,7 +303,7 @@ public class CPPASTQualifiedName extends CPPASTNameBase while(scope != null) { if (scope instanceof ICPPClassScope) { ICPPClassType classType = ((ICPPClassScope) scope).getClassType(); - if (SemanticUtil.calculateInheritanceDepth(classType, baseClass) >= 0) { + if (SemanticUtil.calculateInheritanceDepth(classType, baseClass, this) >= 0) { return true; } } 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 1f3c24d52f5..1d6cea256da 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 @@ -136,47 +136,72 @@ public class CPPClassSpecialization extends CPPSpecialization @Override public ICPPField[] getDeclaredFields() { + return getDeclaredFields(null); // Instantiation of dependent expression may not work. + } + + @Override + public ICPPField[] getDeclaredFields(IASTNode point) { ICPPClassSpecializationScope scope= getSpecializationScope(); if (scope == null) return ClassTypeHelper.getDeclaredFields(this); - return scope.getDeclaredFields(); + return scope.getDeclaredFields(point); } @Override public ICPPMethod[] getDeclaredMethods() { + return getDeclaredMethods(null); // Instantiation of dependent expression may not work. + } + + @Override + public ICPPMethod[] getDeclaredMethods(IASTNode point) { ICPPClassSpecializationScope scope= getSpecializationScope(); if (scope == null) return ClassTypeHelper.getDeclaredMethods(this); - return scope.getDeclaredMethods(); + return scope.getDeclaredMethods(point); } @Override public ICPPConstructor[] getConstructors() { + return getConstructors(null); + } + + @Override + public ICPPConstructor[] getConstructors(IASTNode point) { ICPPClassSpecializationScope scope= getSpecializationScope(); if (scope == null) return ClassTypeHelper.getConstructors(this); - return scope.getConstructors(); + return scope.getConstructors(point); } @Override public IBinding[] getFriends() { + return getFriends(null); // Instantiation of dependent expression may not work. + } + + @Override + public IBinding[] getFriends(IASTNode point) { ICPPClassSpecializationScope scope= getSpecializationScope(); if (scope == null) return ClassTypeHelper.getFriends(this); - return scope.getFriends(); + return scope.getFriends(point); } @Override public ICPPClassType[] getNestedClasses() { + return getNestedClasses(null); // Instantiation of dependent expression may not work. + } + + @Override + public ICPPClassType[] getNestedClasses(IASTNode point) { ICPPClassSpecializationScope scope= getSpecializationScope(); if (scope == null) return ClassTypeHelper.getNestedClasses(this); - return scope.getNestedClasses(); + return scope.getNestedClasses(point); } @Override @@ -231,7 +256,7 @@ public class CPPClassSpecialization extends CPPSpecialization if (getDefinition() != null) return null; - //implicit specialization: must specialize bindings in scope + // Implicit specialization: must specialize bindings in scope. if (specScope == null) { specScope = new CPPClassSpecializationScope(this); } 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 eb4bbffc704..55da58c8586 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 @@ -1,12 +1,13 @@ /******************************************************************************* - * Copyright (c) 2008, 2010 Wind River Systems, Inc. and others. + * Copyright (c) 2008, 2012 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * Markus Schorn - initial API and implementation + * Markus Schorn - initial API and implementation + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; @@ -16,6 +17,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; 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; @@ -42,23 +44,35 @@ public interface ICPPClassSpecializationScope extends ICPPClassScope { */ ICPPBase[] getBases(IASTNode point); + /** + * Similar to {@link ICPPClassScope#getConstructors()} but a accepts a starting point + * for template instantiation. + */ + ICPPConstructor[] getConstructors(IASTNode point); + + /** + * Similar to {@link ICPPClassScope#getImplicitMethods()} but a accepts a starting point + * for template instantiation. + */ + ICPPMethod[] getImplicitMethods(IASTNode point); + /** * Computes the methods via the original class. */ - ICPPMethod[] getDeclaredMethods(); + ICPPMethod[] getDeclaredMethods(IASTNode point); /** * Computes the fields via the original class. */ - ICPPField[] getDeclaredFields(); + ICPPField[] getDeclaredFields(IASTNode point); /** * Computes the friends via the original class. */ - IBinding[] getFriends(); + IBinding[] getFriends(IASTNode point); /** * Computes the nested classes via the original class. */ - ICPPClassType[] getNestedClasses(); + ICPPClassType[] getNestedClasses(IASTNode point); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BaseClassLookup.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BaseClassLookup.java index def3ed540db..d8de2c8590d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BaseClassLookup.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BaseClassLookup.java @@ -24,7 +24,6 @@ import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember; import org.eclipse.cdt.core.parser.util.ArrayUtil; @@ -182,12 +181,7 @@ class BaseClassLookup { // base-classes ICPPClassType baseClass= result.getClassType(); if (baseClass != null) { - ICPPBase[] grandBases= null; - if (baseClass instanceof ICPPClassSpecialization) { - grandBases = ((ICPPClassSpecialization) baseClass).getBases(data.getLookupPoint()); - } else { - grandBases= baseClass.getBases(); - } + ICPPBase[] grandBases= SemanticUtil.getBases(baseClass, data.getLookupPoint()); if (grandBases != null && grandBases.length > 0) { HashSet grandBaseBindings= null; BitSet selectedBases= null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BuiltinOperators.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BuiltinOperators.java index 5cc74b55ef7..4032094ee4b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BuiltinOperators.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BuiltinOperators.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010, 2011 Wind River Systems, Inc. and others. + * Copyright (c) 2010, 2012 Wind River Systems, Inc. and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -70,6 +70,7 @@ class BuiltinOperators { private final OverloadableOperator fOperator; private final boolean fUnary; + private final IASTNode fPoint; private IType fType1; private IType fType2; private IType[][] fClassConversionTypes= { null, null }; @@ -83,6 +84,7 @@ class BuiltinOperators { Object[] globCandidates) { fFileScope= point.getTranslationUnit().getScope(); fOperator= operator; + fPoint = point; fUnary= args.length < 2; fGlobalCandidates= globCandidates; if (args.length > 0) { @@ -355,7 +357,7 @@ class BuiltinOperators { IType t2= SemanticUtil.getNestedType(memPtr.getMemberOfClass(), TDEF); if (t2 instanceof ICPPClassType) { ICPPClassType c2= (ICPPClassType) t2; - if (SemanticUtil.calculateInheritanceDepth(c1, c2) >= 0) { + if (SemanticUtil.calculateInheritanceDepth(c1, c2, fPoint) >= 0) { IType cvt= SemanticUtil.getNestedType(memPtr.getType(), TDEF); IType rt= new CPPReferenceType( SemanticUtil.addQualifiers(cvt, cv1.isConst(), cv1.isVolatile(), cv1.isRestrict()), false); @@ -664,7 +666,7 @@ class BuiltinOperators { if (type instanceof ICPPClassType) { fIsClass[idx]= true; try { - ICPPMethod[] ops = SemanticUtil.getConversionOperators((ICPPClassType) type); + ICPPMethod[] ops = SemanticUtil.getConversionOperators((ICPPClassType) type, fPoint); result= new IType[ops.length]; int j= -1; for (ICPPMethod op : ops) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java index 3faa3341be6..45edc144710 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPEvaluation.java @@ -23,9 +23,11 @@ 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.ICPPTemplateParameterMap; import org.eclipse.cdt.core.parser.util.CharArrayUtils; +import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; 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.SizeofCalculator.SizeAndAlignment; import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; @@ -244,4 +246,9 @@ public abstract class CPPEvaluation implements ICPPEvaluation { } return args; } + + protected static SizeAndAlignment getSizeAndAlignment(IType type, IASTNode point) { + ASTTranslationUnit ast = (ASTTranslationUnit) point.getTranslationUnit(); + return ast.getSizeofCalculator().sizeAndAlignment(type); + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index ed466a91df0..f2d1602f903 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -244,7 +244,7 @@ public class CPPSemantics { public static int traceIndent= 0; // special return value for costForFunctionCall - private static final FunctionCost CONTAINS_DEPENDENT_TYPES = new FunctionCost(null, 0); + private static final FunctionCost CONTAINS_DEPENDENT_TYPES = new FunctionCost(null, 0, null); static protected IBinding resolveBinding(IASTName name) { if (traceBindingResolution) { @@ -257,11 +257,11 @@ public class CPPSemantics { ((CPPASTNameBase) name).incResolutionDepth(); } - // 1: get some context info off of the name to figure out what kind of lookup we want + // 1: Get some context info off of the name to figure out what kind of lookup we want LookupData data = createLookupData(name); try { - // 2: lookup + // 2: Lookup lookup(data, null); // Perform argument dependent lookup @@ -274,14 +274,14 @@ public class CPPSemantics { if (data.problem != null) return data.problem; - // 3: resolve ambiguities + // 3: Resolve ambiguities IBinding binding; try { binding = resolveAmbiguities(data); } catch (DOMException e) { binding = e.getProblem(); } - // 4: post processing + // 4: Post processing binding = postResolution(binding, data); if (traceBindingResolution) { traceIndent--; @@ -306,6 +306,8 @@ public class CPPSemantics { if (lookupName == null) return binding; + IASTNode lookupPoint = data.getLookupPoint(); + if (binding == null && data.checkClassContainingFriend()) { // 3.4.1-10 if we don't find a name used in a friend declaration in the member declaration's class // we should look in the class granting friendship @@ -403,7 +405,7 @@ public class CPPSemantics { if (data.getTranslationUnit() != null) { ICPPASTTemplateId id = (ICPPASTTemplateId) lookupName; ICPPTemplateArgument[] args = CPPTemplates.createTemplateArgumentArray(id); - IBinding inst= CPPTemplates.instantiate((ICPPClassTemplate) cls, args, data.getLookupPoint()); + IBinding inst= CPPTemplates.instantiate((ICPPClassTemplate) cls, args, lookupPoint); if (inst instanceof ICPPClassType) { cls= (ICPPClassType) inst; } @@ -412,7 +414,7 @@ public class CPPSemantics { if (cls instanceof ICPPUnknownBinding) { binding= new CPPUnknownConstructor(cls); } else { - binding= CPPSemantics.resolveFunction(data, cls.getConstructors(), true); + binding= CPPSemantics.resolveFunction(data, SemanticUtil.getConstructors(cls, lookupPoint), true); } } catch (DOMException e) { return e.getProblem(); @@ -712,7 +714,7 @@ public class CPPSemantics { } if (t instanceof ICPPClassType && !(t instanceof ICPPClassTemplate)) { ICPPClassType ct= (ICPPClassType) t; - ICPPBase[] bases = ct.getBases(); + ICPPBase[] bases = SemanticUtil.getBases(ct, tu); for (ICPPBase base : bases) { IBinding b = base.getBaseClass(); if (b instanceof IType) @@ -2413,7 +2415,7 @@ public class CPPSemantics { potentialCosts.add(fnCost); continue; } - int cmp= fnCost.compareTo(tu, bestFnCost, lookupPoint); + int cmp= fnCost.compareTo(tu, bestFnCost); if (cmp < 0) { bestFnCost= fnCost; ambiguousFunctions= null; @@ -2425,7 +2427,7 @@ public class CPPSemantics { if (potentialCosts != null) { for (FunctionCost fnCost : potentialCosts) { if (!fnCost.mustBeWorse(bestFnCost) && fnCost.performUDC(lookupPoint)) { - int cmp= fnCost.compareTo(tu, bestFnCost, lookupPoint); + int cmp= fnCost.compareTo(tu, bestFnCost); if (cmp < 0) { bestFnCost= fnCost; ambiguousFunctions= null; @@ -2630,9 +2632,9 @@ public class CPPSemantics { final int sourceLen= argTypes.length - skipArg; final FunctionCost result; if (implicitParameterType == null) { - result= new FunctionCost(fn, sourceLen); + result= new FunctionCost(fn, sourceLen, data.getLookupPoint()); } else { - result= new FunctionCost(fn, sourceLen + 1); + result= new FunctionCost(fn, sourceLen + 1, data.getLookupPoint()); ValueCategory sourceIsLValue= LVALUE; if (impliedObjectType == null) { @@ -2656,7 +2658,7 @@ public class CPPSemantics { if (CPPTemplates.isDependentType(implicitParameterType) || CPPTemplates.isDependentType(impliedObjectType)) { IType s= getNestedType(impliedObjectType, TDEF|REF|CVTYPE); IType t= getNestedType(implicitParameterType, TDEF|REF|CVTYPE); - if (SemanticUtil.calculateInheritanceDepth(s, t) >= 0) + if (SemanticUtil.calculateInheritanceDepth(s, t, data.getLookupPoint()) >= 0) return null; return CONTAINS_DEPENDENT_TYPES; @@ -2671,7 +2673,7 @@ public class CPPSemantics { final UDCMode udc = allowUDC ? UDCMode.DEFER : UDCMode.FORBIDDEN; for (int j = 0; j < sourceLen; j++) { - final IType argType= SemanticUtil.getNestedType(argTypes[j+skipArg], TDEF | REF); + final IType argType= SemanticUtil.getNestedType(argTypes[j + skipArg], TDEF | REF); if (argType == null) return null; @@ -2815,7 +2817,7 @@ public class CPPSemantics { LookupData data= new LookupData(name); data.setFunctionArguments(false, init.getArguments()); try { - IBinding ctor = CPPSemantics.resolveFunction(data, ((ICPPClassType) targetType).getConstructors(), true); + IBinding ctor = CPPSemantics.resolveFunction(data, SemanticUtil.getConstructors((ICPPClassType) targetType, name), true); if (ctor instanceof ICPPConstructor) { int i= 0; for (IASTNode arg : init.getArguments()) { @@ -3086,7 +3088,7 @@ public class CPPSemantics { ValueCategory isLValue= evaluation.getValueCategory(name); if (sourceType != null) { Cost c; - if (calculateInheritanceDepth(sourceType, classType) >= 0) { + if (calculateInheritanceDepth(sourceType, classType, name) >= 0) { c = Conversions.copyInitializationOfClass(isLValue, sourceType, classType, false, name); } else { c = Conversions.checkImplicitConversionSequence(type, sourceType, isLValue, UDCMode.ALLOWED, Context.ORDINARY, name); @@ -3122,13 +3124,13 @@ public class CPPSemantics { LookupData data = new LookupData(astName); data.setFunctionArguments(false, arguments); data.qualified = true; - data.foundItems = classType.getConstructors(); + data.foundItems = SemanticUtil.getConstructors(classType, name); binding = resolveAmbiguities(data); if (binding instanceof ICPPConstructor) return (ICPPConstructor) binding; } else if (initializer == null) { // Default initialization - ICPPConstructor[] ctors = classType.getConstructors(); + ICPPConstructor[] ctors = SemanticUtil.getConstructors(classType, name); for (ICPPConstructor ctor : ctors) { if (ctor.getRequiredArgumentCount() == 0) return ctor; @@ -3342,7 +3344,7 @@ public class CPPSemantics { if (callToObjectOfClassType != null) { try { // 13.3.1.1.2 call to object of class type - ICPPMethod[] ops = SemanticUtil.getConversionOperators(callToObjectOfClassType); + ICPPMethod[] ops = SemanticUtil.getConversionOperators(callToObjectOfClassType, point); for (ICPPMethod op : ops) { if (op.isExplicit()) continue; @@ -3652,9 +3654,10 @@ public class CPPSemantics { return false; } - protected static IBinding resolveUnknownName(IScope scope, ICPPUnknownBinding unknown) { + protected static IBinding resolveUnknownName(IScope scope, ICPPUnknownBinding unknown, IASTNode point) { final IASTName unknownName = unknown.getUnknownName(); - LookupData data = new LookupData(unknownName); + LookupData data = unknownName.getTranslationUnit() != null ? + new LookupData(unknownName) : new LookupData(unknownName.getSimpleID(), null, point); data.setIgnorePointOfDeclaration(true); data.typesOnly= unknown instanceof IType; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index b7382678968..338e683b912 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -2405,7 +2405,7 @@ public class CPPTemplates { } else if (t instanceof ICPPClassType) { IScope s = ((ICPPClassType) t).getCompositeScope(); if (s != null) { - result= CPPSemantics.resolveUnknownName(s, unknown); + result= CPPSemantics.resolveUnknownName(s, unknown, point); if (unknown instanceof ICPPUnknownClassInstance && result instanceof ICPPTemplateDefinition) { ICPPTemplateArgument[] newArgs = CPPTemplates.instantiateArguments( ((ICPPUnknownClassInstance) unknown).getArguments(), tpMap, packOffset, within, point); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index 4f5aa61113e..b3b5d1c82ad 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -13,7 +13,11 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.ALLCVQ; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateTypeUptoPointers; import java.util.ArrayList; import java.util.Arrays; @@ -157,6 +161,7 @@ import org.eclipse.cdt.core.parser.util.AttributeUtil; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; +import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator; @@ -191,8 +196,8 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPScope; -import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTypedef; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownTypeScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariable; @@ -2236,7 +2241,8 @@ public class CPPVisitor extends ASTQueries { } private static IType getStdType(final IASTNode node, char[] name) { - IBinding[] std= node.getTranslationUnit().getScope().find(STD); + ASTTranslationUnit ast = (ASTTranslationUnit) node.getTranslationUnit(); + IBinding[] std= ast.getScope().find(STD); for (IBinding binding : std) { if (binding instanceof ICPPNamespace) { final ICPPNamespaceScope scope = ((ICPPNamespace) binding).getNamespaceScope(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java index 1a63d462fee..a32ce424546 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java @@ -1,16 +1,16 @@ /******************************************************************************* - * Copyright (c) 2004, 2010 IBM Corporation and others. + * Copyright (c) 2004, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM - Initial API and implementation - * Markus Schorn (Wind River Systems) - * Bryan Wilkinson (QNX) - * Andrew Ferguson (Symbian) - * Sergey Prigogin (Google) + * IBM - Initial API and implementation + * Markus Schorn (Wind River Systems) + * Bryan Wilkinson (QNX) + * Andrew Ferguson (Symbian) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; @@ -75,8 +75,8 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.ReferenceBind * Routines for calculating the cost of conversions. */ public class Conversions { - public enum UDCMode {ALLOWED, FORBIDDEN, DEFER} - public enum Context {ORDINARY, IMPLICIT_OBJECT, FIRST_PARAM_OF_DIRECT_COPY_CTOR, REQUIRE_DIRECT_BINDING} + public enum UDCMode { ALLOWED, FORBIDDEN, DEFER } + public enum Context { ORDINARY, IMPLICIT_OBJECT, FIRST_PARAM_OF_DIRECT_COPY_CTOR, REQUIRE_DIRECT_BINDING } private static final char[] INITIALIZER_LIST_NAME = "initializer_list".toCharArray(); //$NON-NLS-1$ private static final char[] STD_NAME = "std".toCharArray(); //$NON-NLS-1$ @@ -135,7 +135,7 @@ public class Conversions { // [for overload resolution bit-fields are treated the same, error if selected as best match] if (valueCat == LVALUE) { // ... and "cv1 T1" is reference-compatible with "cv2 T2" - Cost cost= isReferenceCompatible(cv1T1, cv2T2, isImpliedObject); + Cost cost= isReferenceCompatible(cv1T1, cv2T2, isImpliedObject, point); if (cost != null) { cost.setReferenceBinding(refBindingType); return cost; @@ -145,7 +145,7 @@ public class Conversions { // implicitly converted to an lvalue of type 'cv3 T3', where 'cv1 T1' is reference-compatible with // 'cv3 T3' (this conversion is selected by enumerating the applicable conversion functions (13.3.1.6) // and choosing the best one through overload resolution (13.3)), - if (T2 instanceof ICPPClassType && udc != UDCMode.FORBIDDEN && isReferenceRelated(T1, T2) < 0) { + if (T2 instanceof ICPPClassType && udc != UDCMode.FORBIDDEN && isReferenceRelated(T1, T2, point) < 0) { Cost cost= initializationByConversionForDirectReference(cv1T1, cv2T2, (ICPPClassType) T2, true, ctx, point); if (cost != null) { cost.setReferenceBinding(refBindingType); @@ -195,7 +195,7 @@ public class Conversions { // ... the initializer expression is an rvalue and 'cv1 T1' is reference-compatible with 'cv2 T2' // ..., then the reference is bound to the initializer expression rvalue in the first case if (valueCat.isRValue()) { - Cost cost= isReferenceCompatible(cv1T1, cv2T2, isImpliedObject); + Cost cost= isReferenceCompatible(cv1T1, cv2T2, isImpliedObject, point); if (cost != null) { // [13.3.3.1.4-1] direct binding has either identity or conversion rank. if (cost.getInheritanceDistance() > 0) { @@ -212,7 +212,7 @@ public class Conversions { // resolution (13.3)), then the reference is bound to the initializer expression rvalue in the // first case and to the object that is the result of the conversion in the second case (or, // in either case, to the appropriate base class sub-object of the object). - if (udc != UDCMode.FORBIDDEN && isReferenceRelated(T1, T2) < 0) { + if (udc != UDCMode.FORBIDDEN && isReferenceRelated(T1, T2, point) < 0) { Cost cost= initializationByConversionForDirectReference(cv1T1, cv2T2, (ICPPClassType) T2, false, ctx, point); if (cost != null) { cost.setReferenceBinding(refBindingType); @@ -225,7 +225,7 @@ public class Conversions { // reference-compatible with 'cv2 T2' the reference is bound to the object represented by the // rvalue (see 3.10). if (T2 instanceof IArrayType && valueCat.isRValue()) { - Cost cost= isReferenceCompatible(cv1T1, cv2T2, isImpliedObject); + Cost cost= isReferenceCompatible(cv1T1, cv2T2, isImpliedObject, point); if (cost != null) { cost.setReferenceBinding(refBindingType); return cost; @@ -239,7 +239,7 @@ public class Conversions { // 13.3.3.1.7 no temporary object when converting the implicit object parameter if (!isImpliedObject && ctx != Context.REQUIRE_DIRECT_BINDING) { - if (isReferenceRelated(T1, T2) < 0 || compareQualifications(cv1T1, cv2T2) >= 0) { + if (isReferenceRelated(T1, T2, point) < 0 || compareQualifications(cv1T1, cv2T2) >= 0) { Cost cost= nonReferenceConversion(valueCat, cv2T2, T1, udc, point); if (cost.converts()) { cost.setReferenceBinding(refBindingType); @@ -260,7 +260,7 @@ public class Conversions { */ private static Cost initializationByConversionForDirectReference(final IType cv1T1, final IType cv2T2, final ICPPClassType T2, boolean needLValue, Context ctx, IASTNode point) throws DOMException { - ICPPMethod[] fcns= SemanticUtil.getConversionOperators(T2); + ICPPMethod[] fcns= SemanticUtil.getConversionOperators(T2, point); Cost operatorCost= null; FunctionCost bestUdcCost= null; boolean ambiguousConversionOperator= false; @@ -276,14 +276,14 @@ public class Conversions { final boolean isLValueRef= t instanceof ICPPReferenceType && !((ICPPReferenceType) t).isRValueReference(); if (isLValueRef == needLValue) { // require an lvalue or rvalue IType implicitParameterType= CPPSemantics.getImplicitParameterType(op); - Cost udcCost= isReferenceCompatible(getNestedType(implicitParameterType, TDEF | REF), cv2T2, true); // expression type to implicit object type + Cost udcCost= isReferenceCompatible(getNestedType(implicitParameterType, TDEF | REF), cv2T2, true, point); // expression type to implicit object type if (udcCost != null) { // Make sure top-level cv-qualifiers are compared udcCost.setReferenceBinding(ReferenceBinding.LVALUE_REF); - FunctionCost udcFuncCost= new FunctionCost(op, udcCost); - int cmp= udcFuncCost.compareTo(null, bestUdcCost, point); + FunctionCost udcFuncCost= new FunctionCost(op, udcCost, point); + int cmp= udcFuncCost.compareTo(null, bestUdcCost); if (cmp <= 0) { - Cost cost= isReferenceCompatible(cv1T1, getNestedType(t, TDEF | REF), false); // converted to target + Cost cost= isReferenceCompatible(cv1T1, getNestedType(t, TDEF | REF), false, point); // converted to target if (cost != null) { bestUdcCost= udcFuncCost; ambiguousConversionOperator= cmp == 0; @@ -315,7 +315,7 @@ public class Conversions { if (uqTarget instanceof ICPPClassType) { if (uqSource instanceof ICPPClassType) { // 13.3.3.1-6 Conceptual derived to base conversion - int depth= calculateInheritanceDepth(uqSource, uqTarget); + int depth= calculateInheritanceDepth(uqSource, uqTarget, point); if (depth >= 0) { if (depth == 0) { return new Cost(source, target, Rank.IDENTITY); @@ -338,7 +338,7 @@ public class Conversions { return initializationByConversion(valueCat, source, (ICPPClassType) uqSource, target, udc == UDCMode.DEFER, point); } - return checkStandardConversionSequence(uqSource, target); + return checkStandardConversionSequence(uqSource, target, point); } /** @@ -439,7 +439,7 @@ public class Conversions { * Note this is not a symmetric relation. * @return inheritance distance, or -1, if cv1t1 is not reference-related to cv2t2 */ - private static final int isReferenceRelated(IType cv1Target, IType cv2Source) { + private static final int isReferenceRelated(IType cv1Target, IType cv2Source, IASTNode point) { IType t= SemanticUtil.getNestedType(cv1Target, TDEF | REF); IType s= SemanticUtil.getNestedType(cv2Source, TDEF | REF); @@ -474,7 +474,7 @@ public class Conversions { s= SemanticUtil.getNestedType(((IQualifierType) s).getType(), TDEF | REF); if (t instanceof ICPPClassType && s instanceof ICPPClassType) { - return SemanticUtil.calculateInheritanceDepth(s, t); + return SemanticUtil.calculateInheritanceDepth(s, t, point); } } if (t == s || (t != null && s != null && t.isSameType(s))) { @@ -490,8 +490,8 @@ public class Conversions { * @return The cost for converting or null if cv1t1 is not * reference-compatible with cv2t2 */ - private static final Cost isReferenceCompatible(IType cv1Target, IType cv2Source, boolean isImpliedObject) { - int inheritanceDist= isReferenceRelated(cv1Target, cv2Source); + private static final Cost isReferenceCompatible(IType cv1Target, IType cv2Source, boolean isImpliedObject, IASTNode point) { + int inheritanceDist= isReferenceRelated(cv1Target, cv2Source, point); if (inheritanceDist < 0) return null; final int cmp= compareQualifications(cv1Target, cv2Source); @@ -515,7 +515,7 @@ public class Conversions { * [4] Standard Conversions * Computes the cost of using the standard conversion sequence from source to target. */ - private static final Cost checkStandardConversionSequence(IType source, IType target) { + private static final Cost checkStandardConversionSequence(IType source, IType target, IASTNode point) { final Cost cost= new Cost(source, target, Rank.IDENTITY); if (lvalue_to_rvalue(cost)) return cost; @@ -523,7 +523,7 @@ public class Conversions { if (promotion(cost)) return cost; - if (conversion(cost)) + if (conversion(cost, point)) return cost; if (qualificationConversion(cost)) @@ -546,7 +546,7 @@ public class Conversions { ICPPConstructor usedCtor= null; Cost bestCost= null; boolean hasInitListConstructor= false; - final ICPPConstructor[] constructors = t.getConstructors(); + final ICPPConstructor[] constructors = SemanticUtil.getConstructors(t, point); ICPPConstructor[] ctors= constructors; for (ICPPConstructor ctor : ctors) { final int minArgCount = ctor.getRequiredArgumentCount(); @@ -630,7 +630,8 @@ public class Conversions { /** * 13.3.1.4 Copy-initialization of class by user-defined conversion [over.match.copy] */ - static final Cost copyInitializationOfClass(ValueCategory valueCat, IType source, ICPPClassType t, boolean deferUDC, IASTNode point) throws DOMException { + static final Cost copyInitializationOfClass(ValueCategory valueCat, IType source, ICPPClassType t, + boolean deferUDC, IASTNode point) throws DOMException { if (deferUDC) { Cost c= new Cost(source, t, Rank.USER_DEFINED_CONVERSION); c.setDeferredUDC(DeferredUDC.COPY_INIT_OF_CLASS); @@ -639,7 +640,7 @@ public class Conversions { FunctionCost cost1= null; Cost cost2= null; - ICPPFunction[] ctors= t.getConstructors(); + ICPPFunction[] ctors= SemanticUtil.getConstructors(t, point); ctors = CPPTemplates.instantiateForFunctionCall(ctors, null, Collections.singletonList(source), Collections.singletonList(valueCat), false, point); @@ -657,7 +658,7 @@ public class Conversions { FunctionCost c1; if (ptypes.length == 0) { if (ctor.takesVarArgs()) { - c1= new FunctionCost(ctor, new Cost(source, null, Rank.ELLIPSIS_CONVERSION)); + c1= new FunctionCost(ctor, new Cost(source, null, Rank.ELLIPSIS_CONVERSION), point); } else { continue; } @@ -669,9 +670,9 @@ public class Conversions { if (ctor.getRequiredArgumentCount() > 1) continue; - c1= new FunctionCost(ctor, checkImplicitConversionSequence(ptype, source, valueCat, UDCMode.FORBIDDEN, Context.ORDINARY, point)); + c1= new FunctionCost(ctor, checkImplicitConversionSequence(ptype, source, valueCat, UDCMode.FORBIDDEN, Context.ORDINARY, point), point); } - int cmp= c1.compareTo(null, cost1, point); + int cmp= c1.compareTo(null, cost1); if (cmp <= 0) { cost1= c1; cost2= new Cost(t, t, Rank.IDENTITY); @@ -685,7 +686,7 @@ public class Conversions { final IType uqSource= getNestedType(source, TDEF | REF | CVTYPE); if (uqSource instanceof ICPPClassType) { - ICPPFunction[] ops = SemanticUtil.getConversionOperators((ICPPClassType) uqSource); + ICPPFunction[] ops = SemanticUtil.getConversionOperators((ICPPClassType) uqSource, point); ops= CPPTemplates.instantiateConversionTemplates(ops, t, point); for (final ICPPFunction f : ops) { if (f instanceof ICPPMethod && !(f instanceof IProblemBinding)) { @@ -694,15 +695,15 @@ public class Conversions { continue; final IType returnType = op.getType().getReturnType(); final IType uqReturnType= getNestedType(returnType, REF | TDEF | CVTYPE); - final int dist = SemanticUtil.calculateInheritanceDepth(uqReturnType, t); + final int dist = SemanticUtil.calculateInheritanceDepth(uqReturnType, t, point); if (dist >= 0) { IType implicitType= CPPSemantics.getImplicitParameterType(op); - final Cost udcCost = isReferenceCompatible(getNestedType(implicitType, TDEF | REF), source, true); + final Cost udcCost = isReferenceCompatible(getNestedType(implicitType, TDEF | REF), source, true, point); if (udcCost != null) { // Make sure top-level cv-qualifiers are compared udcCost.setReferenceBinding(ReferenceBinding.LVALUE_REF); - FunctionCost c1= new FunctionCost(op, udcCost); - int cmp= c1.compareTo(null, cost1, point); + FunctionCost c1= new FunctionCost(op, udcCost, point); + int cmp= c1.compareTo(null, cost1); if (cmp <= 0) { cost1= c1; cost2= new Cost(t, t, Rank.IDENTITY); @@ -735,7 +736,7 @@ public class Conversions { c.setDeferredUDC(DeferredUDC.INIT_BY_CONVERSION); return c; } - ICPPFunction[] ops = SemanticUtil.getConversionOperators(uqSource); + ICPPFunction[] ops = SemanticUtil.getConversionOperators(uqSource, point); ops= CPPTemplates.instantiateConversionTemplates(ops, target, point); FunctionCost cost1= null; Cost cost2= null; @@ -753,12 +754,12 @@ public class Conversions { if (isExplicitConversion && c2.getRank() != Rank.IDENTITY) continue; IType implicitType= CPPSemantics.getImplicitParameterType(op); - final Cost udcCost = isReferenceCompatible(getNestedType(implicitType, TDEF | REF), source, true); + final Cost udcCost = isReferenceCompatible(getNestedType(implicitType, TDEF | REF), source, true, point); if (udcCost != null) { // Make sure top-level cv-qualifiers are compared udcCost.setReferenceBinding(ReferenceBinding.LVALUE_REF); - FunctionCost c1= new FunctionCost(op, udcCost); - int cmp= c1.compareTo(null, cost1, point); + FunctionCost c1= new FunctionCost(op, udcCost, point); + int cmp= c1.compareTo(null, cost1); if (cmp <= 0) { cost1= c1; cost2= c2; @@ -1014,7 +1015,7 @@ public class Conversions { * [4.10] Pointer conversions * [4.11] Pointer to member conversions */ - private static final boolean conversion(Cost cost){ + private static final boolean conversion(Cost cost, IASTNode point) { final IType s = cost.source; final IType t = cost.target; @@ -1085,7 +1086,7 @@ public class Conversions { // to an rvalue of type "pointer to cv B", where B is a base class of D. IType srcPtrTgt= getNestedType(srcPtr.getType(), TDEF | CVTYPE | REF); if (tgtPtrTgt instanceof ICPPClassType && srcPtrTgt instanceof ICPPClassType) { - int depth= SemanticUtil.calculateInheritanceDepth(srcPtrTgt, tgtPtrTgt); + int depth= SemanticUtil.calculateInheritanceDepth(srcPtrTgt, tgtPtrTgt, point); if (depth == -1) { cost.setRank(Rank.NO_MATCH); return true; @@ -1108,7 +1109,7 @@ public class Conversions { IType tt = tpm.getType(); if (st != null && tt != null && st.isSameType(tt)) { int depth = SemanticUtil.calculateInheritanceDepth(tpm.getMemberOfClass(), - spm.getMemberOfClass()); + spm.getMemberOfClass(), point); if (depth == -1) { cost.setRank(Rank.NO_MATCH); return true; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java index e054cc9ddbd..70a67d20b7a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java @@ -6,10 +6,10 @@ * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM - Initial API and implementation - * Markus Schorn (Wind River Systems) - * Bryan Wilkinson (QNX) - * Andrew Ferguson (Symbian) + * IBM - Initial API and implementation + * Markus Schorn (Wind River Systems) + * Bryan Wilkinson (QNX) + * Andrew Ferguson (Symbian) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; @@ -114,7 +114,6 @@ public class Cost { public void setRank(Rank rank) { fRank= rank; } - public ReferenceBinding getReferenceBinding() { return fReferenceBinding; @@ -123,7 +122,6 @@ public class Cost { public void setReferenceBinding(ReferenceBinding binding) { fReferenceBinding= binding; } - public boolean isAmbiguousUDC() { return fAmbiguousUDC; @@ -303,7 +301,7 @@ public class Cost { public void setSelectedFunction(ICPPFunction function) { fSelectedFunction= function; } - + public ICPPFunction getSelectedFunction() { return fSelectedFunction; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java index d918929a3c2..7d564ad1ecb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java @@ -268,7 +268,7 @@ public class EvalConditional extends CPPEvaluation { } // Both are class types and one derives from the other if (uqt1 instanceof ICPPClassType && uqt2 instanceof ICPPClassType) { - int dist= SemanticUtil.calculateInheritanceDepth(uqt1, uqt2); + int dist= SemanticUtil.calculateInheritanceDepth(uqt1, uqt2, point); if (dist >= 0) { CVQualifier cv1 = SemanticUtil.getCVQualifier(t1); CVQualifier cv2 = SemanticUtil.getCVQualifier(t2); @@ -279,7 +279,7 @@ public class EvalConditional extends CPPEvaluation { } return Cost.NO_CONVERSION; } - if (SemanticUtil.calculateInheritanceDepth(uqt2, uqt1) >= 0) + if (SemanticUtil.calculateInheritanceDepth(uqt2, uqt1, point) >= 0) return Cost.NO_CONVERSION; } // Unrelated class types or just one class: diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java index da50a23c01e..f618cd64020 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java @@ -304,6 +304,9 @@ public class EvalID extends CPPEvaluation { nameOwner = resolveUnknown(CPPTemplates.createDeferredInstance((ICPPClassTemplate) nameOwner), tpMap, packOffset, within, point); } + if (fieldOwner instanceof IProblemBinding || nameOwner instanceof IProblemBinding) + return this; + if (Arrays.equals(templateArgs, fTemplateArgs) && fieldOwner == fFieldOwner && nameOwner == fNameOwner) return this; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java index 17017f2770a..cde19a8c8d8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java @@ -48,7 +48,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.ProblemType; -import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator; import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator.SizeAndAlignment; import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArithmeticConversion; @@ -216,11 +215,11 @@ public class EvalUnary extends CPPEvaluation { switch (fOperator) { case op_sizeof: { - SizeAndAlignment info = getSizeAndAlignment(point); + SizeAndAlignment info = getSizeAndAlignment(fArgument.getTypeOrFunctionSet(point), point); return info == null ? Value.UNKNOWN : Value.create(info.size); } case op_alignOf: { - SizeAndAlignment info = getSizeAndAlignment(point); + SizeAndAlignment info = getSizeAndAlignment(fArgument.getTypeOrFunctionSet(point), point); return info == null ? Value.UNKNOWN : Value.create(info.alignment); } case op_sizeofParameterPack: @@ -239,14 +238,6 @@ public class EvalUnary extends CPPEvaluation { return Value.create(this); } - private SizeAndAlignment getSizeAndAlignment(IASTNode point) { - if (point == null) - return null; - - IType type = fArgument.getTypeOrFunctionSet(point); - return new SizeofCalculator(point.getTranslationUnit()).sizeAndAlignment(type); - } - @Override public ValueCategory getValueCategory(IASTNode point) { ICPPFunction overload = getOverload(point); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java index e7e97cc5c12..43f8cbdd3db 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java @@ -43,7 +43,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.ProblemType; -import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator; import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator.SizeAndAlignment; import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; @@ -157,11 +156,11 @@ public class EvalUnaryTypeID extends CPPEvaluation { switch (fOperator) { case op_sizeof: { - SizeAndAlignment info = getSizeAndAlignment(point); + SizeAndAlignment info = getSizeAndAlignment(fOrigType, point); return info == null ? Value.UNKNOWN : Value.create(info.size); } case op_alignof: { - SizeAndAlignment info = getSizeAndAlignment(point); + SizeAndAlignment info = getSizeAndAlignment(fOrigType, point); return info == null ? Value.UNKNOWN : Value.create(info.alignment); } case op_typeid: @@ -200,12 +199,6 @@ public class EvalUnaryTypeID extends CPPEvaluation { return Value.create(this); } - private SizeAndAlignment getSizeAndAlignment(IASTNode point) { - if (point == null) - return null; - return new SizeofCalculator(point.getTranslationUnit()).sizeAndAlignment(fOrigType); - } - @Override public ValueCategory getValueCategory(IASTNode point) { return fOperator == op_typeid ? LVALUE : PRVALUE; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionCost.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionCost.java index ef6dd69e55a..81ba5a75dd5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionCost.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionCost.java @@ -40,18 +40,21 @@ class FunctionCost { private final ICPPFunction fFunction; private final Cost[] fCosts; private final ValueCategory[] fValueCategories; + private final IASTNode fPoint; private boolean fIsDirectCopyCtor; - public FunctionCost(ICPPFunction fn, int paramCount) { + public FunctionCost(ICPPFunction fn, int paramCount, IASTNode point) { fFunction= fn; fCosts= new Cost[paramCount]; fValueCategories= new ValueCategory[paramCount]; + fPoint = point; } - public FunctionCost(ICPPFunction fn, Cost cost) { + public FunctionCost(ICPPFunction fn, Cost cost, IASTNode point) { fFunction= fn; fCosts= new Cost[] {cost}; fValueCategories= null; // no udc will be performed + fPoint = point; } public int getLength() { @@ -127,9 +130,8 @@ class FunctionCost { /** * Compares this function call cost to another one. - * @param point */ - public int compareTo(IASTTranslationUnit tu, FunctionCost other, IASTNode point) throws DOMException { + public int compareTo(IASTTranslationUnit tu, FunctionCost other) throws DOMException { if (other == null) return -1; @@ -169,7 +171,7 @@ class FunctionCost { haveBetter = true; } else if (isTemplate && otherIsTemplate) { TypeSelection ts= SemanticUtil.isConversionOperator(f1) ? RETURN_TYPE : PARAMETERS; - int order = CPPTemplates.orderFunctionTemplates(otherAsTemplate, asTemplate, ts, point); + int order = CPPTemplates.orderFunctionTemplates(otherAsTemplate, asTemplate, ts, fPoint); if (order < 0) { haveBetter= true; } else if (order > 0) { @@ -215,10 +217,10 @@ class FunctionCost { if (!parameterTypesMatch(ft1, ft2)) return 0; - int diff= SemanticUtil.calculateInheritanceDepth(o2, o1); + int diff= SemanticUtil.calculateInheritanceDepth(o2, o1, fPoint); if (diff >= 0) return diff; - return -SemanticUtil.calculateInheritanceDepth(o1, o2); + return -SemanticUtil.calculateInheritanceDepth(o1, o2, fPoint); } private boolean parameterTypesMatch(final ICPPFunctionType ft1, final ICPPFunctionType ft2) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java index 817bb8b37c3..9779ceb971c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2010 IBM Corporation and others. + * Copyright (c) 2004, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -40,7 +40,10 @@ import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; 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.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; @@ -100,12 +103,12 @@ public class SemanticUtil { * @param clazz * @return an array of conversion operators. */ - public static final ICPPMethod[] getDeclaredConversionOperators(ICPPClassType clazz) throws DOMException { + public static final ICPPMethod[] getDeclaredConversionOperators(ICPPClassType clazz, IASTNode point) throws DOMException { ICPPMethod[] methods= ICPPMethod.EMPTY_CPPMETHOD_ARRAY; if (clazz instanceof ICPPDeferredClassInstance) { clazz= (ICPPClassType) ((ICPPDeferredClassInstance) clazz).getTemplateDefinition(); } - ICPPMethod[] decs= clazz.getDeclaredMethods(); + ICPPMethod[] decs= getDeclaredMethods(clazz, point); if (decs != null) { for (ICPPMethod method : decs) { if (isConversionOperator(method)) { @@ -123,11 +126,11 @@ public class SemanticUtil { * @param clazz * @return an array of conversion operators. */ - public static ICPPMethod[] getConversionOperators(ICPPClassType clazz) throws DOMException { + public static ICPPMethod[] getConversionOperators(ICPPClassType clazz, IASTNode point) throws DOMException { ICPPMethod[] methods= ICPPMethod.EMPTY_CPPMETHOD_ARRAY; - ObjectSet ancestry= inheritanceClosure(clazz); + ObjectSet ancestry= inheritanceClosure(clazz, point); for (int i = 0; i < ancestry.size(); i++) { - methods= ArrayUtil.addAll(methods, getDeclaredConversionOperators(ancestry.keyAt(i))); + methods= ArrayUtil.addAll(methods, getDeclaredConversionOperators(ancestry.keyAt(i), point)); } return methods; } @@ -137,7 +140,7 @@ public class SemanticUtil { * @return the root and all its ancestor classes * @throws DOMException */ - public static ObjectSet inheritanceClosure(ICPPClassType root) throws DOMException { + public static ObjectSet inheritanceClosure(ICPPClassType root, IASTNode point) throws DOMException { ObjectSet done= new ObjectSet(2); ObjectSet current= new ObjectSet(2); current.put(root); @@ -148,8 +151,8 @@ public class SemanticUtil { for (int i = 0; i < current.size(); i++) { ICPPClassType clazz= current.keyAt(i); done.put(clazz); - - for (ICPPBase base : clazz.getBases()) { + + for (ICPPBase base : getBases(clazz, point)) { IBinding binding= base.getBaseClass(); if (binding instanceof ICPPClassType && !(binding instanceof IProblemBinding)) { ICPPClassType ct= (ICPPClassType) binding; @@ -165,7 +168,43 @@ public class SemanticUtil { return done; } - + + public static ICPPBase[] getBases(ICPPClassType classType, IASTNode point) { + if (classType instanceof ICPPClassSpecialization) + return ((ICPPClassSpecialization) classType).getBases(point); + return classType.getBases(); + } + + public static ICPPConstructor[] getConstructors(ICPPClassType classType, IASTNode point) { + if (classType instanceof ICPPClassSpecialization) + return ((ICPPClassSpecialization) classType).getConstructors(point); + return classType.getConstructors(); + } + + public static ICPPField[] getDeclaredFields(ICPPClassType classType, IASTNode point) { + if (classType instanceof ICPPClassSpecialization) + return ((ICPPClassSpecialization) classType).getDeclaredFields(point); + return classType.getDeclaredFields(); + } + + public static ICPPMethod[] getDeclaredMethods(ICPPClassType classType, IASTNode point) { + if (classType instanceof ICPPClassSpecialization) + return ((ICPPClassSpecialization) classType).getDeclaredMethods(point); + return classType.getDeclaredMethods(); + } + + public static IBinding[] getFriends(ICPPClassType classType, IASTNode point) { + if (classType instanceof ICPPClassSpecialization) + return ((ICPPClassSpecialization) classType).getFriends(point); + return classType.getFriends(); + } + + public static ICPPClassType[] getNestedClasses(ICPPClassType classType, IASTNode point) { + if (classType instanceof ICPPClassSpecialization) + return ((ICPPClassSpecialization) classType).getNestedClasses(point); + return classType.getNestedClasses(); + } + /** * @param method * @return true if the specified method is a conversion operator @@ -622,11 +661,11 @@ public class SemanticUtil { * @return the number of edges in the inheritance graph, or -1 if the specified classes have * no inheritance relation */ - public static final int calculateInheritanceDepth(IType type, IType baseClass) { - return calculateInheritanceDepth(CPPSemantics.MAX_INHERITANCE_DEPTH, new HashSet(), type, baseClass); + public static final int calculateInheritanceDepth(IType type, IType baseClass, IASTNode point) { + return calculateInheritanceDepth(CPPSemantics.MAX_INHERITANCE_DEPTH, new HashSet(), type, baseClass, point); } - private static final int calculateInheritanceDepth(int maxdepth, Set hashSet, IType type, IType baseClass) { + private static final int calculateInheritanceDepth(int maxdepth, Set hashSet, IType type, IType baseClass, IASTNode point) { if (type == baseClass || type.isSameType(baseClass)) { return 0; } @@ -637,7 +676,7 @@ public class SemanticUtil { clazz= (ICPPClassType) ((ICPPDeferredClassInstance) clazz).getSpecializedBinding(); } - for (ICPPBase cppBase : clazz.getBases()) { + for (ICPPBase cppBase : getBases(clazz, point)) { IBinding base= cppBase.getBaseClass(); if (base instanceof IType && hashSet.add(base)) { IType tbase= (IType) base; @@ -648,7 +687,7 @@ public class SemanticUtil { } if (tbase instanceof ICPPClassType) { - int n= calculateInheritanceDepth(maxdepth - 1, hashSet, tbase, baseClass); + int n= calculateInheritanceDepth(maxdepth - 1, hashSet, tbase, baseClass, point); if (n > 0) return n + 1; } 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 618de5509f2..c33fa703f25 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2010 Symbian Software Systems and others. + * Copyright (c) 2007, 2012 Symbian Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * Contributors: * Andrew Ferguson (Symbian) - Initial implementation * Markus Schorn (Wind River Systems) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.index.composite.cpp; @@ -40,7 +41,6 @@ public class CompositeCPPClassSpecialization extends CompositeCPPClassType imple private ObjectMap specializationMap; private final ThreadLocal> fInProgress= new ThreadLocal>(); - public CompositeCPPClassSpecialization(ICompositesFactory cf, ICPPClassType rbinding) { super(cf, rbinding); } @@ -143,45 +143,70 @@ public class CompositeCPPClassSpecialization extends CompositeCPPClassType imple @Override public final ICPPConstructor[] getConstructors() { + return getConstructors(null); + } + + @Override + public final ICPPConstructor[] getConstructors(IASTNode point) { IScope scope= getCompositeScope(); if (scope instanceof ICPPClassSpecializationScope) { - return ((ICPPClassSpecializationScope) scope).getConstructors(); + return ((ICPPClassSpecializationScope) scope).getConstructors(point); } return super.getConstructors(); } @Override public final ICPPMethod[] getDeclaredMethods() { + return getDeclaredMethods(null); + } + + @Override + public final ICPPMethod[] getDeclaredMethods(IASTNode point) { IScope scope= getCompositeScope(); if (scope instanceof ICPPClassSpecializationScope) { - return ((ICPPClassSpecializationScope) scope).getDeclaredMethods(); + return ((ICPPClassSpecializationScope) scope).getDeclaredMethods(point); } return super.getDeclaredMethods(); } @Override public final ICPPField[] getDeclaredFields() { + return getDeclaredFields(null); + } + + @Override + public final ICPPField[] getDeclaredFields(IASTNode point) { IScope scope= getCompositeScope(); if (scope instanceof ICPPClassSpecializationScope) { - return ((ICPPClassSpecializationScope) scope).getDeclaredFields(); + return ((ICPPClassSpecializationScope) scope).getDeclaredFields(point); } return super.getDeclaredFields(); } @Override public final IBinding[] getFriends() { + return getFriends(null); + } + + @Override + public final IBinding[] getFriends(IASTNode point) { IScope scope= getCompositeScope(); if (scope instanceof ICPPClassSpecializationScope) { - return ((ICPPClassSpecializationScope) scope).getFriends(); + return ((ICPPClassSpecializationScope) scope).getFriends(point); } return super.getFriends(); } @Override public final ICPPClassType[] getNestedClasses() { + return getNestedClasses(null); + } + + @Override + public final ICPPClassType[] getNestedClasses(IASTNode point) { IScope scope= getCompositeScope(); if (scope instanceof ICPPClassSpecializationScope) { - return ((ICPPClassSpecializationScope) scope).getNestedClasses(); + return ((ICPPClassSpecializationScope) scope).getNestedClasses(point); } return super.getNestedClasses(); } 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 671ba7884b8..e184fb5baec 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 @@ -66,6 +66,11 @@ public class CompositeCPPClassSpecializationScope extends CompositeScope impleme } } + @Override + public ICPPMethod[] getImplicitMethods(IASTNode point) { + return getImplicitMethods(null); + } + @Override public ICPPMethod[] getImplicitMethods() { createDelegate(); @@ -98,14 +103,19 @@ public class CompositeCPPClassSpecializationScope extends CompositeScope impleme @Override public ICPPConstructor[] getConstructors() { - createDelegate(); - return fDelegate.getConstructors(); + return getConstructors(null); } @Override - public ICPPMethod[] getDeclaredMethods() { + public ICPPConstructor[] getConstructors(IASTNode point) { createDelegate(); - return fDelegate.getDeclaredMethods(); + return fDelegate.getConstructors(point); + } + + @Override + public ICPPMethod[] getDeclaredMethods(IASTNode point) { + createDelegate(); + return fDelegate.getDeclaredMethods(point); } @Override @@ -115,20 +125,20 @@ public class CompositeCPPClassSpecializationScope extends CompositeScope impleme } @Override - public ICPPField[] getDeclaredFields() { + public ICPPField[] getDeclaredFields(IASTNode point) { createDelegate(); - return fDelegate.getDeclaredFields(); + return fDelegate.getDeclaredFields(point); } @Override - public IBinding[] getFriends() { + public IBinding[] getFriends(IASTNode point) { createDelegate(); - return fDelegate.getFriends(); + return fDelegate.getFriends(point); } @Override - public ICPPClassType[] getNestedClasses() { + public ICPPClassType[] getNestedClasses(IASTNode point) { createDelegate(); - return fDelegate.getNestedClasses(); + return fDelegate.getNestedClasses(point); } } 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 b3fea4a1fca..2af5f563b82 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2007, 2011 QNX Software Systems and others. + * Copyright (c) 2007, 2012 QNX Software Systems and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -9,6 +9,7 @@ * QNX - Initial API and implementation * Andrew Ferguson (Symbian) * Markus Schorn (Wind River Systems) + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.cpp; @@ -64,7 +65,7 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements protected static final int RECORD_SIZE = PDOMCPPSpecialization.RECORD_SIZE + 8; private volatile ICPPClassScope fScope; - private ObjectMap specializationMap= null; // Obtained from the synchronized PDOM cache + private ObjectMap specializationMap; // Obtained from the synchronized PDOM cache private final ThreadLocal> fInProgress= new ThreadLocal>(); public PDOMCPPClassSpecialization(PDOMLinkage linkage, PDOMNode parent, ICPPClassType classType, @@ -240,9 +241,14 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements @Override public ICPPConstructor[] getConstructors() { + return getConstructors(null); + } + + @Override + public ICPPConstructor[] getConstructors(IASTNode point) { IScope scope= getCompositeScope(); if (scope instanceof ICPPClassSpecializationScope) { - return ((ICPPClassSpecializationScope) scope).getConstructors(); + return ((ICPPClassSpecializationScope) scope).getConstructors(point); } try { PDOMClassUtil.ConstructorCollector visitor= new PDOMClassUtil.ConstructorCollector(); @@ -256,9 +262,14 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements @Override public ICPPMethod[] getDeclaredMethods() { + return getDeclaredMethods(null); + } + + @Override + public ICPPMethod[] getDeclaredMethods(IASTNode point) { IScope scope= getCompositeScope(); if (scope instanceof ICPPClassSpecializationScope) { - return ((ICPPClassSpecializationScope) scope).getDeclaredMethods(); + return ((ICPPClassSpecializationScope) scope).getDeclaredMethods(point); } try { PDOMClassUtil.MethodCollector methods = new PDOMClassUtil.MethodCollector(false); @@ -272,9 +283,14 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements @Override public ICPPField[] getDeclaredFields() { + return getDeclaredFields(null); + } + + @Override + public ICPPField[] getDeclaredFields(IASTNode point) { IScope scope= getCompositeScope(); if (scope instanceof ICPPClassSpecializationScope) { - return ((ICPPClassSpecializationScope) scope).getDeclaredFields(); + return ((ICPPClassSpecializationScope) scope).getDeclaredFields(point); } try { PDOMClassUtil.FieldCollector visitor = new PDOMClassUtil.FieldCollector(); @@ -288,9 +304,14 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements @Override public ICPPClassType[] getNestedClasses() { + return getNestedClasses(null); + } + + @Override + public ICPPClassType[] getNestedClasses(IASTNode point) { IScope scope= getCompositeScope(); if (scope instanceof ICPPClassSpecializationScope) { - return ((ICPPClassSpecializationScope) scope).getNestedClasses(); + return ((ICPPClassSpecializationScope) scope).getNestedClasses(point); } try { PDOMClassUtil.NestedClassCollector visitor = new PDOMClassUtil.NestedClassCollector(); @@ -304,7 +325,12 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements @Override public IBinding[] getFriends() { - // not yet supported. + return getFriends(null); + } + + @Override + public IBinding[] getFriends(IASTNode point) { + // Not yet supported. return IBinding.EMPTY_BINDING_ARRAY; }