1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-09 17:25:38 +02:00

Bug 513105 - Store the current lookup point in a thread-local static stack rather than passing it around everywhere

Change-Id: I3da7326d1ce6bede8d4787d98f38fb2064288338
This commit is contained in:
Nathan Ridge 2017-06-11 15:06:25 -04:00
parent 9869cbc9ba
commit 64709c980d
199 changed files with 3378 additions and 3164 deletions

View file

@ -51,7 +51,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.SemanticQueries; import org.eclipse.cdt.core.dom.ast.cpp.SemanticQueries;
import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVariableReadWriteFlags; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVariableReadWriteFlags;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName; import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
@ -90,14 +90,19 @@ public class ClassMembersInitializationChecker extends AbstractIndexAstChecker {
Set<IField> fieldsInConstructor = constructorsStack.push(new HashSet<IField>()); Set<IField> fieldsInConstructor = constructorsStack.push(new HashSet<IField>());
// Add all class fields // Add all class fields
for (IField field : ClassTypeHelper.getDeclaredFields(constructor.getClassOwner(), declaration)) { try {
if (isSimpleType(field.getType()) && !field.isStatic()) { CPPSemantics.pushLookupPoint(declaration);
// In C++11, a field may have an initial value specified at its declaration. for (IField field : constructor.getClassOwner().getDeclaredFields()) {
// Such a field does not need to be initialized in the constructor as well. if (isSimpleType(field.getType()) && !field.isStatic()) {
if (field.getInitialValue() == null) { // In C++11, a field may have an initial value specified at its declaration.
fieldsInConstructor.add(field); // Such a field does not need to be initialized in the constructor as well.
if (field.getInitialValue() == null) {
fieldsInConstructor.add(field);
}
} }
} }
} finally {
CPPSemantics.popLookupPoint();
} }
} }
return PROCESS_CONTINUE; return PROCESS_CONTINUE;

View file

@ -29,6 +29,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
/** /**
* Checker to find that class has virtual method and non virtual destructor * Checker to find that class has virtual method and non virtual destructor
@ -47,8 +48,8 @@ public class NonVirtualDestructor extends AbstractIndexAstChecker {
ast.accept(new OnEachClass()); ast.accept(new OnEachClass());
} }
private static ICPPMethod getDestructor(ICPPClassType classType, IASTNode point) { private static ICPPMethod getDestructor(ICPPClassType classType) {
for (ICPPMethod method : ClassTypeHelper.getDeclaredMethods(classType, point)) { for (ICPPMethod method : classType.getDeclaredMethods()) {
if (method.isDestructor()) { if (method.isDestructor()) {
return method; return method;
} }
@ -56,18 +57,18 @@ public class NonVirtualDestructor extends AbstractIndexAstChecker {
return null; return null;
} }
private static boolean hasVirtualDestructor(ICPPClassType classType, IASTNode point) { private static boolean hasVirtualDestructor(ICPPClassType classType) {
checkedClassTypes.add(classType); checkedClassTypes.add(classType);
ICPPMethod destructor = getDestructor(classType, point); ICPPMethod destructor = getDestructor(classType);
if (destructor != null && destructor.isVirtual()) { if (destructor != null && destructor.isVirtual()) {
return true; return true;
} }
ICPPBase[] bases = ClassTypeHelper.getBases(classType, point); ICPPBase[] bases = classType.getBases();
for (ICPPBase base : bases) { for (ICPPBase base : bases) {
IBinding baseClass = base.getBaseClass(); IBinding baseClass = base.getBaseClass();
if (baseClass instanceof ICPPClassType) { if (baseClass instanceof ICPPClassType) {
ICPPClassType cppClassType = (ICPPClassType) baseClass; ICPPClassType cppClassType = (ICPPClassType) baseClass;
if (!checkedClassTypes.contains(cppClassType) && hasVirtualDestructor(cppClassType, point)) { if (!checkedClassTypes.contains(cppClassType) && hasVirtualDestructor(cppClassType)) {
return true; return true;
} }
} }
@ -89,39 +90,44 @@ public class NonVirtualDestructor extends AbstractIndexAstChecker {
if (!(binding instanceof ICPPClassType)) { if (!(binding instanceof ICPPClassType)) {
return PROCESS_SKIP; return PROCESS_SKIP;
} }
ICPPClassType classType = (ICPPClassType) binding; try {
boolean hasVirtualDestructor = hasVirtualDestructor(classType, className); CPPSemantics.pushLookupPoint(className);
checkedClassTypes.clear(); ICPPClassType classType = (ICPPClassType) binding;
if (hasVirtualDestructor) { boolean hasVirtualDestructor = hasVirtualDestructor(classType);
return PROCESS_SKIP; checkedClassTypes.clear();
} if (hasVirtualDestructor) {
ICPPMethod virtualMethod = null; return PROCESS_SKIP;
for (ICPPMethod method : ClassTypeHelper.getAllDeclaredMethods(classType, className)) {
if (!method.isDestructor() && method.isVirtual()) {
virtualMethod = method;
} }
} ICPPMethod virtualMethod = null;
if (virtualMethod == null) { for (ICPPMethod method : ClassTypeHelper.getAllDeclaredMethods(classType)) {
return PROCESS_SKIP; if (!method.isDestructor() && method.isVirtual()) {
} virtualMethod = method;
ICPPMethod destructor = getDestructor(classType, className); }
if (destructor != null &&
destructor.getVisibility() != ICPPASTVisibilityLabel.v_public &&
classType.getFriends().length == 0) {
// No error if the destructor is protected or private and there are no friends.
return PROCESS_SKIP;
}
IASTNode node = decl;
if (destructor instanceof ICPPInternalBinding) {
IASTNode[] decls = ((ICPPInternalBinding) destructor).getDeclarations();
if (decls != null && decls.length > 0) {
node = decls[0];
} }
if (virtualMethod == null) {
return PROCESS_SKIP;
}
ICPPMethod destructor = getDestructor(classType);
if (destructor != null &&
destructor.getVisibility() != ICPPASTVisibilityLabel.v_public &&
classType.getFriends().length == 0) {
// No error if the destructor is protected or private and there are no friends.
return PROCESS_SKIP;
}
IASTNode node = decl;
if (destructor instanceof ICPPInternalBinding) {
IASTNode[] decls = ((ICPPInternalBinding) destructor).getDeclarations();
if (decls != null && decls.length > 0) {
node = decls[0];
}
}
reportProblem(PROBLEM_ID, node, new String(className.getSimpleID()),
virtualMethod.getName());
return PROCESS_SKIP;
} finally {
CPPSemantics.popLookupPoint();
} }
reportProblem(PROBLEM_ID, node, new String(className.getSimpleID()),
virtualMethod.getName());
return PROCESS_SKIP;
} }
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }

View file

@ -43,7 +43,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.SemanticQueries; import org.eclipse.cdt.core.dom.ast.cpp.SemanticQueries;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
public class ProblemBindingChecker extends AbstractIndexAstChecker { public class ProblemBindingChecker extends AbstractIndexAstChecker {
public static String ERR_ID_OverloadProblem = "org.eclipse.cdt.codan.internal.checkers.OverloadProblem"; //$NON-NLS-1$ public static String ERR_ID_OverloadProblem = "org.eclipse.cdt.codan.internal.checkers.OverloadProblem"; //$NON-NLS-1$
@ -285,12 +285,17 @@ public class ProblemBindingChecker extends AbstractIndexAstChecker {
} }
} else if (candidateBinding instanceof ICPPClassType) { } else if (candidateBinding instanceof ICPPClassType) {
ICPPClassType classType = (ICPPClassType) candidateBinding; ICPPClassType classType = (ICPPClassType) candidateBinding;
for (ICPPFunction constructor : ClassTypeHelper.getConstructors(classType, problemBinding.getASTNode())) { try {
String signature = getFunctionSignature(constructor); CPPSemantics.pushLookupPoint(problemBinding.getASTNode());
if (!signature.equals(lastSignature)) { for (ICPPFunction constructor : classType.getConstructors()) {
candidatesString += signature + "\n"; //$NON-NLS-1$ String signature = getFunctionSignature(constructor);
lastSignature = signature; if (!signature.equals(lastSignature)) {
candidatesString += signature + "\n"; //$NON-NLS-1$
lastSignature = signature;
}
} }
} finally {
CPPSemantics.popLookupPoint();
} }
} }
} }

View file

@ -141,7 +141,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.SemanticQueries;
import org.eclipse.cdt.core.parser.IProblem; import org.eclipse.cdt.core.parser.IProblem;
import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassType;
@ -6469,20 +6468,20 @@ public class AST2CPPTests extends AST2CPPTestBase {
assertFalse(ClassTypeHelper.isOverrider(m5, m2)); assertFalse(ClassTypeHelper.isOverrider(m5, m2));
assertTrue(ClassTypeHelper.isOverrider(m4, m2)); assertTrue(ClassTypeHelper.isOverrider(m4, m2));
ICPPMethod[] ors= ClassTypeHelper.findOverridden(m0, null); ICPPMethod[] ors= ClassTypeHelper.findOverridden(m0);
assertEquals(0, ors.length); assertEquals(0, ors.length);
ors= ClassTypeHelper.findOverridden(m1, null); ors= ClassTypeHelper.findOverridden(m1);
assertEquals(0, ors.length); assertEquals(0, ors.length);
ors= ClassTypeHelper.findOverridden(m2, null); ors= ClassTypeHelper.findOverridden(m2);
assertEquals(1, ors.length); assertEquals(1, ors.length);
assertEquals(ors[0], m1); assertEquals(ors[0], m1);
ors= ClassTypeHelper.findOverridden(m3, null); ors= ClassTypeHelper.findOverridden(m3);
assertEquals(0, ors.length); assertEquals(0, ors.length);
ors= ClassTypeHelper.findOverridden(m4, null); ors= ClassTypeHelper.findOverridden(m4);
assertEquals(2, ors.length); assertEquals(2, ors.length);
assertEquals(ors[0], m2); assertEquals(ors[0], m2);
assertEquals(ors[1], m1); assertEquals(ors[1], m1);
ors= ClassTypeHelper.findOverridden(m5, null); ors= ClassTypeHelper.findOverridden(m5);
assertEquals(1, ors.length); assertEquals(1, ors.length);
assertEquals(ors[0], m1); assertEquals(ors[0], m1);
} }
@ -9254,8 +9253,8 @@ public class AST2CPPTests extends AST2CPPTestBase {
IASTName namep = bh.findName("p"); IASTName namep = bh.findName("p");
ICPPClassType B = (ICPPClassType) nameB.resolveBinding(); ICPPClassType B = (ICPPClassType) nameB.resolveBinding();
IPointerType ptrToA = (IPointerType) ((ICPPVariable) namep.resolveBinding()).getType(); IPointerType ptrToA = (IPointerType) ((ICPPVariable) namep.resolveBinding()).getType();
long pointerSize = SizeofCalculator.getSizeAndAlignment(ptrToA, namep).size; long pointerSize = getSizeAndAlignment(ptrToA, namep).size;
long BSize = SizeofCalculator.getSizeAndAlignment(B, nameB).size; long BSize = getSizeAndAlignment(B, nameB).size;
assertEquals(pointerSize, BSize); assertEquals(pointerSize, BSize);
} }
@ -9264,7 +9263,7 @@ public class AST2CPPTests extends AST2CPPTestBase {
BindingAssertionHelper bh = getAssertionHelper(); BindingAssertionHelper bh = getAssertionHelper();
IASTName nameWaldo = bh.findName("waldo"); IASTName nameWaldo = bh.findName("waldo");
ICPPClassType waldo = (ICPPClassType) nameWaldo.resolveBinding(); ICPPClassType waldo = (ICPPClassType) nameWaldo.resolveBinding();
long waldoSize = SizeofCalculator.getSizeAndAlignment(waldo, nameWaldo).size; long waldoSize = getSizeAndAlignment(waldo, nameWaldo).size;
assertNotEquals(0, waldoSize); assertNotEquals(0, waldoSize);
} }
@ -9389,14 +9388,14 @@ public class AST2CPPTests extends AST2CPPTestBase {
assertFalse(ClassTypeHelper.isOverrider(m3, m0)); assertFalse(ClassTypeHelper.isOverrider(m3, m0));
assertFalse(ClassTypeHelper.isOverrider(m3, m1)); assertFalse(ClassTypeHelper.isOverrider(m3, m1));
ICPPMethod[] ors= ClassTypeHelper.findOverridden(m0, null); ICPPMethod[] ors= ClassTypeHelper.findOverridden(m0);
assertEquals(0, ors.length); assertEquals(0, ors.length);
ors= ClassTypeHelper.findOverridden(m1, null); ors= ClassTypeHelper.findOverridden(m1);
assertEquals(0, ors.length); assertEquals(0, ors.length);
ors= ClassTypeHelper.findOverridden(m2, null); ors= ClassTypeHelper.findOverridden(m2);
assertEquals(1, ors.length); assertEquals(1, ors.length);
assertSame(ors[0], m0); assertSame(ors[0], m0);
ors= ClassTypeHelper.findOverridden(m3, null); ors= ClassTypeHelper.findOverridden(m3);
assertEquals(0, ors.length); assertEquals(0, ors.length);
} }

View file

@ -353,7 +353,7 @@ public class AST2TemplateTests extends AST2CPPTestBase {
BindingAssertionHelper helper = getAssertionHelper(); BindingAssertionHelper helper = getAssertionHelper();
ICPPClassType B = helper.assertNonProblem("A<B>", 4); ICPPClassType B = helper.assertNonProblem("A<B>", 4);
// Check that this line does not cause a StackOverflowError. // Check that this line does not cause a StackOverflowError.
ClassTypeHelper.getBases(B, null); B.getBases();
} }
// template < class T > class A { // template < class T > class A {
@ -1897,7 +1897,7 @@ public class AST2TemplateTests extends AST2CPPTestBase {
ICPPClassType B = (ICPPClassType) col.getName(3).resolveBinding(); ICPPClassType B = (ICPPClassType) col.getName(3).resolveBinding();
ICPPClassType A = (ICPPClassType) col.getName(6).resolveBinding(); ICPPClassType A = (ICPPClassType) col.getName(6).resolveBinding();
ICPPBase[] bases = ClassTypeHelper.getBases(A, tu); ICPPBase[] bases = A.getBases();
assertEquals(bases.length, 1); assertEquals(bases.length, 1);
assertSame(bases[0].getBaseClass(), B); assertSame(bases[0].getBaseClass(), B);
} }
@ -4918,7 +4918,7 @@ public class AST2TemplateTests extends AST2CPPTestBase {
BindingAssertionHelper bh= new AST2AssertionHelper(code, CPP); BindingAssertionHelper bh= new AST2AssertionHelper(code, CPP);
ICPPClassType type= bh.assertNonProblem("X<int&>", 7); ICPPClassType type= bh.assertNonProblem("X<int&>", 7);
ICPPMethod[] ms= ClassTypeHelper.getMethods(type, null); ICPPMethod[] ms= ClassTypeHelper.getMethods(type);
int i= ms[0].getName().equals("f") ? 0 : 1; int i= ms[0].getName().equals("f") ? 0 : 1;
ICPPMethod m= ms[i]; ICPPMethod m= ms[i];
assertEquals("int &", ASTTypeUtil.getType(m.getType().getParameterTypes()[0])); assertEquals("int &", ASTTypeUtil.getType(m.getType().getParameterTypes()[0]));
@ -4926,7 +4926,7 @@ public class AST2TemplateTests extends AST2CPPTestBase {
assertEquals("int &", ASTTypeUtil.getType(m.getType().getParameterTypes()[0])); assertEquals("int &", ASTTypeUtil.getType(m.getType().getParameterTypes()[0]));
type= bh.assertNonProblem("X<const int&&>", 14); type= bh.assertNonProblem("X<const int&&>", 14);
ms= ClassTypeHelper.getMethods(type, null); ms= ClassTypeHelper.getMethods(type);
i= ms[0].getName().equals("f") ? 0 : 1; i= ms[0].getName().equals("f") ? 0 : 1;
m= ms[i]; m= ms[i];
assertEquals("const int &", ASTTypeUtil.getType(m.getType().getParameterTypes()[0])); assertEquals("const int &", ASTTypeUtil.getType(m.getType().getParameterTypes()[0]));

View file

@ -25,6 +25,8 @@ import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.testplugin.util.BaseTestCase; import org.eclipse.cdt.core.testplugin.util.BaseTestCase;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
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.c.CBasicType; import org.eclipse.cdt.internal.core.dom.parser.c.CBasicType;
import org.eclipse.cdt.internal.core.dom.parser.c.CPointerType; import org.eclipse.cdt.internal.core.dom.parser.c.CPointerType;
import org.eclipse.cdt.internal.core.dom.parser.c.CQualifierType; import org.eclipse.cdt.internal.core.dom.parser.c.CQualifierType;
@ -32,6 +34,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPQualifierType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPQualifierType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
/** /**
* Common base class for AST2 and index tests. * Common base class for AST2 and index tests.
@ -104,6 +107,15 @@ public class SemanticTestBase extends BaseTestCase {
ASTTypeUtil.getType(expected, false) + "' and '" + ASTTypeUtil.getType(actual, false) + "'", ASTTypeUtil.getType(expected, false) + "' and '" + ASTTypeUtil.getType(actual, false) + "'",
expected.isSameType(actual)); expected.isSameType(actual));
} }
protected static SizeAndAlignment getSizeAndAlignment(IType type, IASTNode lookupPoint) {
try {
CPPSemantics.pushLookupPoint(lookupPoint);
return SizeofCalculator.getSizeAndAlignment(type);
} finally {
CPPSemantics.popLookupPoint();
}
}
protected class BindingAssertionHelper { protected class BindingAssertionHelper {
protected String contents; protected String contents;

View file

@ -90,7 +90,7 @@ public class SemanticsTests extends AST2TestBase {
// Test getDeclaredConversionOperators() // Test getDeclaredConversionOperators()
BindingAssertionHelper ba= new AST2AssertionHelper(getAboveComment(), true); BindingAssertionHelper ba= new AST2AssertionHelper(getAboveComment(), true);
ICPPClassType c= ba.assertNonProblem("X {", 1, ICPPClassType.class); ICPPClassType c= ba.assertNonProblem("X {", 1, ICPPClassType.class);
ICPPMethod[] cops= SemanticUtil.getDeclaredConversionOperators(c, null); ICPPMethod[] cops= SemanticUtil.getDeclaredConversionOperators(c);
assertEquals(2, cops.length); assertEquals(2, cops.length);
Set actual= new HashSet(); Set actual= new HashSet();
actual.add(cops[0].getName()); actual.add(cops[1].getName()); actual.add(cops[0].getName()); actual.add(cops[1].getName());

View file

@ -61,11 +61,11 @@ public class TypeTraitsTests extends AST2TestBase {
public void testHasTrivialCopyCtor() throws Exception { public void testHasTrivialCopyCtor() throws Exception {
BindingAssertionHelper helper = getAssertionHelper(); BindingAssertionHelper helper = getAssertionHelper();
ICPPClassType classA = helper.assertNonProblemOnFirstIdentifier("A {"); ICPPClassType classA = helper.assertNonProblemOnFirstIdentifier("A {");
assertFalse(TypeTraits.hasTrivialCopyCtor(classA, null)); assertFalse(TypeTraits.hasTrivialCopyCtor(classA));
ICPPClassType classB = helper.assertNonProblemOnFirstIdentifier("B {"); ICPPClassType classB = helper.assertNonProblemOnFirstIdentifier("B {");
assertTrue(TypeTraits.hasTrivialCopyCtor(classB, null)); assertTrue(TypeTraits.hasTrivialCopyCtor(classB));
ICPPClassType classC = helper.assertNonProblemOnFirstIdentifier("C {"); ICPPClassType classC = helper.assertNonProblemOnFirstIdentifier("C {");
assertFalse(TypeTraits.hasTrivialCopyCtor(classC, null)); assertFalse(TypeTraits.hasTrivialCopyCtor(classC));
} }
// struct A { // struct A {
@ -89,11 +89,11 @@ public class TypeTraitsTests extends AST2TestBase {
public void testHasTrivialDestructor() throws Exception { public void testHasTrivialDestructor() throws Exception {
BindingAssertionHelper helper = getAssertionHelper(); BindingAssertionHelper helper = getAssertionHelper();
ICPPClassType classA = helper.assertNonProblemOnFirstIdentifier("A {"); ICPPClassType classA = helper.assertNonProblemOnFirstIdentifier("A {");
assertFalse(TypeTraits.hasTrivialDestructor(classA, null)); assertFalse(TypeTraits.hasTrivialDestructor(classA));
ICPPClassType classB = helper.assertNonProblemOnFirstIdentifier("B {"); ICPPClassType classB = helper.assertNonProblemOnFirstIdentifier("B {");
assertTrue(TypeTraits.hasTrivialDestructor(classB, null)); assertTrue(TypeTraits.hasTrivialDestructor(classB));
ICPPClassType classC = helper.assertNonProblemOnFirstIdentifier("C {"); ICPPClassType classC = helper.assertNonProblemOnFirstIdentifier("C {");
assertFalse(TypeTraits.hasTrivialDestructor(classC, null)); assertFalse(TypeTraits.hasTrivialDestructor(classC));
} }
// struct A { // struct A {
@ -130,25 +130,25 @@ public class TypeTraitsTests extends AST2TestBase {
public void testIsEmpty() throws Exception { public void testIsEmpty() throws Exception {
BindingAssertionHelper helper = getAssertionHelper(); BindingAssertionHelper helper = getAssertionHelper();
ICPPClassType classA = helper.assertNonProblemOnFirstIdentifier("A {"); ICPPClassType classA = helper.assertNonProblemOnFirstIdentifier("A {");
assertTrue(TypeTraits.isEmpty(classA, null)); assertTrue(TypeTraits.isEmpty(classA));
ICPPClassType classB = helper.assertNonProblemOnFirstIdentifier("B :"); ICPPClassType classB = helper.assertNonProblemOnFirstIdentifier("B :");
assertTrue(TypeTraits.isEmpty(classB, null)); assertTrue(TypeTraits.isEmpty(classB));
ICPPClassType classC = helper.assertNonProblemOnFirstIdentifier("C {"); ICPPClassType classC = helper.assertNonProblemOnFirstIdentifier("C {");
assertFalse(TypeTraits.isEmpty(classC, null)); assertFalse(TypeTraits.isEmpty(classC));
ICPPClassType classD = helper.assertNonProblemOnFirstIdentifier("D :"); ICPPClassType classD = helper.assertNonProblemOnFirstIdentifier("D :");
assertFalse(TypeTraits.isEmpty(classD, null)); assertFalse(TypeTraits.isEmpty(classD));
ICPPClassType classE = helper.assertNonProblemOnFirstIdentifier("E {"); ICPPClassType classE = helper.assertNonProblemOnFirstIdentifier("E {");
assertFalse(TypeTraits.isEmpty(classE, null)); assertFalse(TypeTraits.isEmpty(classE));
ICPPClassType classF = helper.assertNonProblemOnFirstIdentifier("F {"); ICPPClassType classF = helper.assertNonProblemOnFirstIdentifier("F {");
assertFalse(TypeTraits.isEmpty(classF, null)); assertFalse(TypeTraits.isEmpty(classF));
ICPPClassType classG = helper.assertNonProblemOnFirstIdentifier("G :"); ICPPClassType classG = helper.assertNonProblemOnFirstIdentifier("G :");
assertFalse(TypeTraits.isEmpty(classG, null)); assertFalse(TypeTraits.isEmpty(classG));
IType typeH = helper.assertNonProblemOnFirstIdentifier("H;"); IType typeH = helper.assertNonProblemOnFirstIdentifier("H;");
assertTrue(TypeTraits.isEmpty(typeH, null)); assertTrue(TypeTraits.isEmpty(typeH));
IType typeI = helper.assertNonProblemOnFirstIdentifier("I;"); IType typeI = helper.assertNonProblemOnFirstIdentifier("I;");
assertFalse(TypeTraits.isEmpty(typeI, null)); assertFalse(TypeTraits.isEmpty(typeI));
IType typeJ = helper.assertNonProblemOnFirstIdentifier("J["); IType typeJ = helper.assertNonProblemOnFirstIdentifier("J[");
assertFalse(TypeTraits.isEmpty(typeJ, null)); assertFalse(TypeTraits.isEmpty(typeJ));
} }
// struct A { // struct A {
@ -170,11 +170,11 @@ public class TypeTraitsTests extends AST2TestBase {
public void testIsPolymorphic() throws Exception { public void testIsPolymorphic() throws Exception {
BindingAssertionHelper helper = getAssertionHelper(); BindingAssertionHelper helper = getAssertionHelper();
ICPPClassType classA = helper.assertNonProblemOnFirstIdentifier("A {"); ICPPClassType classA = helper.assertNonProblemOnFirstIdentifier("A {");
assertTrue(TypeTraits.isPolymorphic(classA, null)); assertTrue(TypeTraits.isPolymorphic(classA));
ICPPClassType classB = helper.assertNonProblemOnFirstIdentifier("B {"); ICPPClassType classB = helper.assertNonProblemOnFirstIdentifier("B {");
assertFalse(TypeTraits.isPolymorphic(classB, null)); assertFalse(TypeTraits.isPolymorphic(classB));
ICPPClassType classC = helper.assertNonProblemOnFirstIdentifier("C"); ICPPClassType classC = helper.assertNonProblemOnFirstIdentifier("C");
assertTrue(TypeTraits.isPolymorphic(classC, null)); assertTrue(TypeTraits.isPolymorphic(classC));
} }
// struct A { // struct A {
@ -217,21 +217,21 @@ public class TypeTraitsTests extends AST2TestBase {
public void testIsStandardLayout() throws Exception { public void testIsStandardLayout() throws Exception {
BindingAssertionHelper helper = getAssertionHelper(); BindingAssertionHelper helper = getAssertionHelper();
ICPPClassType classA = helper.assertNonProblemOnFirstIdentifier("A {"); ICPPClassType classA = helper.assertNonProblemOnFirstIdentifier("A {");
assertTrue(TypeTraits.isStandardLayout(classA, null)); assertTrue(TypeTraits.isStandardLayout(classA));
ICPPClassType classB = helper.assertNonProblemOnFirstIdentifier("B {"); ICPPClassType classB = helper.assertNonProblemOnFirstIdentifier("B {");
assertTrue(TypeTraits.isStandardLayout(classB, null)); assertTrue(TypeTraits.isStandardLayout(classB));
ICPPClassType classC = helper.assertNonProblemOnFirstIdentifier("C :"); ICPPClassType classC = helper.assertNonProblemOnFirstIdentifier("C :");
assertFalse(TypeTraits.isStandardLayout(classC, null)); assertFalse(TypeTraits.isStandardLayout(classC));
ICPPClassType classD = helper.assertNonProblemOnFirstIdentifier("D {"); ICPPClassType classD = helper.assertNonProblemOnFirstIdentifier("D {");
assertFalse(TypeTraits.isStandardLayout(classD, null)); assertFalse(TypeTraits.isStandardLayout(classD));
ICPPClassType classE = helper.assertNonProblemOnFirstIdentifier("E :"); ICPPClassType classE = helper.assertNonProblemOnFirstIdentifier("E :");
assertFalse(TypeTraits.isStandardLayout(classE, null)); assertFalse(TypeTraits.isStandardLayout(classE));
ICPPClassType classF = helper.assertNonProblemOnFirstIdentifier("F :"); ICPPClassType classF = helper.assertNonProblemOnFirstIdentifier("F :");
assertFalse(TypeTraits.isStandardLayout(classF, null)); assertFalse(TypeTraits.isStandardLayout(classF));
ICPPClassType classG = helper.assertNonProblemOnFirstIdentifier("G {"); ICPPClassType classG = helper.assertNonProblemOnFirstIdentifier("G {");
assertFalse(TypeTraits.isStandardLayout(classG, null)); assertFalse(TypeTraits.isStandardLayout(classG));
ICPPClassType classH = helper.assertNonProblemOnFirstIdentifier("H {"); ICPPClassType classH = helper.assertNonProblemOnFirstIdentifier("H {");
assertFalse(TypeTraits.isStandardLayout(classH, null)); assertFalse(TypeTraits.isStandardLayout(classH));
} }
// struct A { // struct A {
@ -275,23 +275,23 @@ public class TypeTraitsTests extends AST2TestBase {
public void testIsTrivial() throws Exception { public void testIsTrivial() throws Exception {
BindingAssertionHelper helper = getAssertionHelper(); BindingAssertionHelper helper = getAssertionHelper();
ICPPClassType classA = helper.assertNonProblemOnFirstIdentifier("A {"); ICPPClassType classA = helper.assertNonProblemOnFirstIdentifier("A {");
assertTrue(TypeTraits.isTrivial(classA, null)); assertTrue(TypeTraits.isTrivial(classA));
ICPPClassType classB = helper.assertNonProblemOnFirstIdentifier("B :"); ICPPClassType classB = helper.assertNonProblemOnFirstIdentifier("B :");
assertTrue(TypeTraits.isTrivial(classB, null)); assertTrue(TypeTraits.isTrivial(classB));
ICPPClassType classC = helper.assertNonProblemOnFirstIdentifier("C {"); ICPPClassType classC = helper.assertNonProblemOnFirstIdentifier("C {");
assertFalse(TypeTraits.isTrivial(classC, null)); assertFalse(TypeTraits.isTrivial(classC));
ICPPClassType classD = helper.assertNonProblemOnFirstIdentifier("D {"); ICPPClassType classD = helper.assertNonProblemOnFirstIdentifier("D {");
assertFalse(TypeTraits.isTrivial(classD, null)); assertFalse(TypeTraits.isTrivial(classD));
ICPPClassType classE = helper.assertNonProblemOnFirstIdentifier("E {"); ICPPClassType classE = helper.assertNonProblemOnFirstIdentifier("E {");
assertFalse(TypeTraits.isTrivial(classE, null)); assertFalse(TypeTraits.isTrivial(classE));
ICPPClassType classF = helper.assertNonProblemOnFirstIdentifier("F {"); ICPPClassType classF = helper.assertNonProblemOnFirstIdentifier("F {");
assertFalse(TypeTraits.isTrivial(classF, null)); assertFalse(TypeTraits.isTrivial(classF));
ICPPClassType classG = helper.assertNonProblemOnFirstIdentifier("G {"); ICPPClassType classG = helper.assertNonProblemOnFirstIdentifier("G {");
assertFalse(TypeTraits.isTrivial(classG, null)); assertFalse(TypeTraits.isTrivial(classG));
ICPPClassType classH = helper.assertNonProblemOnFirstIdentifier("H :"); ICPPClassType classH = helper.assertNonProblemOnFirstIdentifier("H :");
assertFalse(TypeTraits.isTrivial(classH, null)); assertFalse(TypeTraits.isTrivial(classH));
ICPPClassType classI = helper.assertNonProblemOnFirstIdentifier("I {"); ICPPClassType classI = helper.assertNonProblemOnFirstIdentifier("I {");
assertFalse(TypeTraits.isTrivial(classI, null)); assertFalse(TypeTraits.isTrivial(classI));
} }
// int a; // int a;
@ -311,18 +311,18 @@ public class TypeTraitsTests extends AST2TestBase {
public void testIsTriviallyCopyable() throws Exception { public void testIsTriviallyCopyable() throws Exception {
BindingAssertionHelper helper = getAssertionHelper(); BindingAssertionHelper helper = getAssertionHelper();
IVariable a = helper.assertNonProblemOnFirstIdentifier("a;"); IVariable a = helper.assertNonProblemOnFirstIdentifier("a;");
assertTrue(TypeTraits.isTriviallyCopyable(a.getType(), null)); assertTrue(TypeTraits.isTriviallyCopyable(a.getType()));
IVariable b = helper.assertNonProblemOnFirstIdentifier("b;"); IVariable b = helper.assertNonProblemOnFirstIdentifier("b;");
assertTrue(TypeTraits.isTriviallyCopyable(b.getType(), null)); assertTrue(TypeTraits.isTriviallyCopyable(b.getType()));
IVariable c = helper.assertNonProblemOnFirstIdentifier("c;"); IVariable c = helper.assertNonProblemOnFirstIdentifier("c;");
assertFalse(TypeTraits.isTriviallyCopyable(c.getType(), null)); assertFalse(TypeTraits.isTriviallyCopyable(c.getType()));
IVariable d = helper.assertNonProblemOnFirstIdentifier("d["); IVariable d = helper.assertNonProblemOnFirstIdentifier("d[");
assertTrue(TypeTraits.isTriviallyCopyable(d.getType(), null)); assertTrue(TypeTraits.isTriviallyCopyable(d.getType()));
IVariable e = helper.assertNonProblemOnFirstIdentifier("e;"); IVariable e = helper.assertNonProblemOnFirstIdentifier("e;");
assertTrue(TypeTraits.isTriviallyCopyable(e.getType(), null)); assertTrue(TypeTraits.isTriviallyCopyable(e.getType()));
IVariable f = helper.assertNonProblemOnFirstIdentifier("f;"); IVariable f = helper.assertNonProblemOnFirstIdentifier("f;");
assertTrue(TypeTraits.isTriviallyCopyable(f.getType(), null)); assertTrue(TypeTraits.isTriviallyCopyable(f.getType()));
IVariable g = helper.assertNonProblemOnFirstIdentifier("g;"); IVariable g = helper.assertNonProblemOnFirstIdentifier("g;");
assertFalse(TypeTraits.isTriviallyCopyable(g.getType(), null)); assertFalse(TypeTraits.isTriviallyCopyable(g.getType()));
} }
} }

View file

@ -242,7 +242,7 @@ public class FunctionTests extends TestBase {
IASTFunctionCallExpression funcExpr = (IASTFunctionCallExpression)clause; IASTFunctionCallExpression funcExpr = (IASTFunctionCallExpression)clause;
IASTIdExpression idExpr = (IASTIdExpression)funcExpr.getFunctionNameExpression(); IASTIdExpression idExpr = (IASTIdExpression)funcExpr.getFunctionNameExpression();
ICPPFunction function = (ICPPFunction)idExpr.getName().resolveBinding(); ICPPFunction function = (ICPPFunction)idExpr.getName().resolveBinding();
ICPPExecution bodyExec = CPPFunction.getFunctionBodyExecution(function, clause); ICPPExecution bodyExec = CPPFunction.getFunctionBodyExecution(function);
assertNull(bodyExec); assertNull(bodyExec);
} }

View file

@ -40,6 +40,7 @@ import org.eclipse.cdt.internal.core.dom.parser.CStringValue;
import org.eclipse.cdt.internal.core.dom.parser.FloatingPointValue; import org.eclipse.cdt.internal.core.dom.parser.FloatingPointValue;
import org.eclipse.cdt.internal.core.dom.parser.cpp.GNUCPPSourceParser; import org.eclipse.cdt.internal.core.dom.parser.cpp.GNUCPPSourceParser;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.parser.ParserException; import org.eclipse.cdt.internal.core.parser.ParserException;
import org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor; import org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor;
@ -102,7 +103,12 @@ public class TestBase extends IndexBindingResolutionTestBase {
private IValue getValue() throws Exception { private IValue getValue() throws Exception {
ICPPASTInitializerClause point = getLastDeclarationInitializer(); ICPPASTInitializerClause point = getLastDeclarationInitializer();
ICPPEvaluation evaluation = point.getEvaluation(); ICPPEvaluation evaluation = point.getEvaluation();
return evaluation.getValue(point); try {
CPPSemantics.pushLookupPoint(point);
return evaluation.getValue();
} finally {
CPPSemantics.popLookupPoint();
}
} }
protected ICPPASTInitializerClause getLastDeclarationInitializer() throws Exception { protected ICPPASTInitializerClause getLastDeclarationInitializer() throws Exception {

View file

@ -227,7 +227,7 @@ public class IndexCPPBindingResolutionBugs extends IndexBindingResolutionTestBas
ICPPSpecialization inst= ct.getInstance(new ICPPTemplateArgument[]{new CPPTemplateTypeArgument((IType)b0)}); ICPPSpecialization inst= ct.getInstance(new ICPPTemplateArgument[]{new CPPTemplateTypeArgument((IType)b0)});
assertInstance(inst, ICPPClassType.class); assertInstance(inst, ICPPClassType.class);
ICPPClassType c2t= (ICPPClassType) inst; ICPPClassType c2t= (ICPPClassType) inst;
ICPPBase[] bases= ClassTypeHelper.getBases(c2t, null); ICPPBase[] bases= c2t.getBases();
assertEquals(1, bases.length); assertEquals(1, bases.length);
assertInstance(bases[0].getBaseClass(), ICPPClassType.class); assertInstance(bases[0].getBaseClass(), ICPPClassType.class);
} }
@ -973,74 +973,74 @@ public class IndexCPPBindingResolutionBugs extends IndexBindingResolutionTestBas
// class template instance // class template instance
ct= getBindingFromASTName("CT<int>", 7); ct= getBindingFromASTName("CT<int>", 7);
assertInstance(ct, ICPPTemplateInstance.class); assertInstance(ct, ICPPTemplateInstance.class);
assertBindings(new String[] {"B"}, ClassTypeHelper.getBases(ct, null)); assertBindings(new String[] {"B"}, ct.getBases());
assertBindings(new String[] {"n", "m", "B", "CT"}, ClassTypeHelper.getAllDeclaredMethods(ct, null)); assertBindings(new String[] {"n", "m", "B", "CT"}, ClassTypeHelper.getAllDeclaredMethods(ct));
assertBindings(new String[] {"CT", "CT"}, ClassTypeHelper.getConstructors(ct, null)); assertBindings(new String[] {"CT", "CT"}, ct.getConstructors());
assertBindings(new String[] {"g"}, ClassTypeHelper.getDeclaredFields(ct, null)); assertBindings(new String[] {"g"}, ct.getDeclaredFields());
assertBindings(new String[] {"n", "CT"}, ClassTypeHelper.getDeclaredMethods(ct, null)); assertBindings(new String[] {"n", "CT"}, ct.getDeclaredMethods());
assertBindings(new String[] {"f", "g"}, ClassTypeHelper.getFields(ct, null)); assertBindings(new String[] {"f", "g"}, ClassTypeHelper.getFields(ct));
assertBindings(new String[] {"m", "n", "CT", "CT", "~CT", "B", "B", "~B", "operator =", "operator ="}, ClassTypeHelper.getMethods(ct, null)); assertBindings(new String[] {"m", "n", "CT", "CT", "~CT", "B", "B", "~B", "operator =", "operator ="}, ClassTypeHelper.getMethods(ct));
assertBindings(new String[] {"O"}, ClassTypeHelper.getNestedClasses(ct, null)); assertBindings(new String[] {"O"}, ct.getNestedClasses());
// explicit class template instance // explicit class template instance
ct= getBindingFromASTName("CT<char>", 8); ct= getBindingFromASTName("CT<char>", 8);
assertInstance(ct, ICPPTemplateInstance.class); assertInstance(ct, ICPPTemplateInstance.class);
assertBindings(new String[] {"A"}, ClassTypeHelper.getBases(ct, null)); assertBindings(new String[] {"A"}, ct.getBases());
assertBindings(new String[] {"o", "l", "A", "CT", "CT"}, ClassTypeHelper.getAllDeclaredMethods(ct, null)); assertBindings(new String[] {"o", "l", "A", "CT", "CT"}, ClassTypeHelper.getAllDeclaredMethods(ct));
assertBindings(new String[] {"CT", "CT", "CT"}, ClassTypeHelper.getConstructors(ct, null)); assertBindings(new String[] {"CT", "CT", "CT"}, ct.getConstructors());
assertBindings(new String[] {"h"}, ClassTypeHelper.getDeclaredFields(ct, null)); assertBindings(new String[] {"h"}, ct.getDeclaredFields());
assertBindings(new String[] {"o", "CT", "CT"}, ClassTypeHelper.getDeclaredMethods(ct, null)); assertBindings(new String[] {"o", "CT", "CT"}, ct.getDeclaredMethods());
assertBindings(new String[] {"e", "h"}, ClassTypeHelper.getFields(ct, null)); assertBindings(new String[] {"e", "h"}, ClassTypeHelper.getFields(ct));
assertBindings(new String[] {"l", "o", "CT", "CT", "CT", "~CT", "A", "A", "~A", "operator =", "operator ="}, ClassTypeHelper.getMethods(ct, null)); assertBindings(new String[] {"l", "o", "CT", "CT", "CT", "~CT", "A", "A", "~A", "operator =", "operator ="}, ClassTypeHelper.getMethods(ct));
assertBindings(new String[] {"P"}, ClassTypeHelper.getNestedClasses(ct, null)); assertBindings(new String[] {"P"}, ct.getNestedClasses());
// class specialization // class specialization
ct= getBindingFromASTName("C spec", 1); ct= getBindingFromASTName("C spec", 1);
assertInstance(ct, ICPPClassSpecialization.class); assertInstance(ct, ICPPClassSpecialization.class);
assertBindings(new String[] {"B"}, ClassTypeHelper.getBases(ct, null)); assertBindings(new String[] {"B"}, ct.getBases());
assertBindings(new String[] {"n", "m", "B", "C"}, ClassTypeHelper.getAllDeclaredMethods(ct, null)); assertBindings(new String[] {"n", "m", "B", "C"}, ClassTypeHelper.getAllDeclaredMethods(ct));
assertBindings(new String[] {"C", "C"}, ClassTypeHelper.getConstructors(ct, null)); assertBindings(new String[] {"C", "C"}, ct.getConstructors());
assertBindings(new String[] {"g"}, ClassTypeHelper.getDeclaredFields(ct, null)); assertBindings(new String[] {"g"}, ct.getDeclaredFields());
assertBindings(new String[] {"n", "C"}, ClassTypeHelper.getDeclaredMethods(ct, null)); assertBindings(new String[] {"n", "C"}, ct.getDeclaredMethods());
assertBindings(new String[] {"f", "g"}, ClassTypeHelper.getFields(ct, null)); assertBindings(new String[] {"f", "g"}, ClassTypeHelper.getFields(ct));
assertBindings(new String[] {"m", "n", "C", "C", "~C", "B", "B", "~B", "operator =", "operator ="}, ClassTypeHelper.getMethods(ct, null)); assertBindings(new String[] {"m", "n", "C", "C", "~C", "B", "B", "~B", "operator =", "operator ="}, ClassTypeHelper.getMethods(ct));
assertBindings(new String[] {"O"}, ClassTypeHelper.getNestedClasses(ct, null)); assertBindings(new String[] {"O"}, ct.getNestedClasses());
// class template specialization // class template specialization
ct= getBindingFromASTName("CT<int> spect", 2); ct= getBindingFromASTName("CT<int> spect", 2);
assertInstance(ct, ICPPClassTemplate.class, ICPPClassSpecialization.class); assertInstance(ct, ICPPClassTemplate.class, ICPPClassSpecialization.class);
assertBindings(new String[] {"B"}, ClassTypeHelper.getBases(ct, null)); assertBindings(new String[] {"B"}, ct.getBases());
assertBindings(new String[] {"n", "m", "B", "CT"}, ClassTypeHelper.getAllDeclaredMethods(ct, null)); assertBindings(new String[] {"n", "m", "B", "CT"}, ClassTypeHelper.getAllDeclaredMethods(ct));
assertBindings(new String[] {"CT", "CT"}, ClassTypeHelper.getConstructors(ct, null)); assertBindings(new String[] {"CT", "CT"}, ct.getConstructors());
assertBindings(new String[] {"g"}, ClassTypeHelper.getDeclaredFields(ct, null)); assertBindings(new String[] {"g"}, ct.getDeclaredFields());
assertBindings(new String[] {"n", "CT"}, ClassTypeHelper.getDeclaredMethods(ct, null)); assertBindings(new String[] {"n", "CT"}, ct.getDeclaredMethods());
assertBindings(new String[] {"f", "g"}, ClassTypeHelper.getFields(ct, null)); assertBindings(new String[] {"f", "g"}, ClassTypeHelper.getFields(ct));
assertBindings(new String[] {"m", "n", "CT", "CT", "~CT", "B", "B", "~B", "operator =", "operator ="}, ClassTypeHelper.getMethods(ct, null)); assertBindings(new String[] {"m", "n", "CT", "CT", "~CT", "B", "B", "~B", "operator =", "operator ="}, ClassTypeHelper.getMethods(ct));
assertBindings(new String[] {"O"}, ClassTypeHelper.getNestedClasses(ct, null)); assertBindings(new String[] {"O"}, ct.getNestedClasses());
// explicit class specialization // explicit class specialization
ct= getBindingFromASTName("C espec", 1); ct= getBindingFromASTName("C espec", 1);
assertInstance(ct, ICPPClassSpecialization.class); assertInstance(ct, ICPPClassSpecialization.class);
assertBindings(new String[] {"A"}, ClassTypeHelper.getBases(ct, null)); assertBindings(new String[] {"A"}, ct.getBases());
assertBindings(new String[] {"o", "l", "A", "C", "C"}, ClassTypeHelper.getAllDeclaredMethods(ct, null)); assertBindings(new String[] {"o", "l", "A", "C", "C"}, ClassTypeHelper.getAllDeclaredMethods(ct));
assertBindings(new String[] {"C", "C", "C"}, ClassTypeHelper.getConstructors(ct, null)); assertBindings(new String[] {"C", "C", "C"}, ct.getConstructors());
assertBindings(new String[] {"h"}, ClassTypeHelper.getDeclaredFields(ct, null)); assertBindings(new String[] {"h"}, ct.getDeclaredFields());
assertBindings(new String[] {"o", "C", "C"}, ClassTypeHelper.getDeclaredMethods(ct, null)); assertBindings(new String[] {"o", "C", "C"}, ct.getDeclaredMethods());
assertBindings(new String[] {"e", "h"}, ClassTypeHelper.getFields(ct, null)); assertBindings(new String[] {"e", "h"}, ClassTypeHelper.getFields(ct));
assertBindings(new String[] {"l", "o", "C", "C", "C", "~C", "A", "A", "~A", "operator =", "operator ="}, ClassTypeHelper.getMethods(ct, null)); assertBindings(new String[] {"l", "o", "C", "C", "C", "~C", "A", "A", "~A", "operator =", "operator ="}, ClassTypeHelper.getMethods(ct));
assertBindings(new String[] {"P"}, ClassTypeHelper.getNestedClasses(ct, null)); assertBindings(new String[] {"P"}, ct.getNestedClasses());
// explicit class template specialization // explicit class template specialization
ct= getBindingFromASTName("CT<int> espect", 7); ct= getBindingFromASTName("CT<int> espect", 7);
assertInstance(ct, ICPPTemplateInstance.class); assertInstance(ct, ICPPTemplateInstance.class);
assertBindings(new String[] {"A"}, ClassTypeHelper.getBases(ct, null)); assertBindings(new String[] {"A"}, ct.getBases());
assertBindings(new String[] {"o", "l", "A", "CT", "CT"}, ClassTypeHelper.getAllDeclaredMethods(ct, null)); assertBindings(new String[] {"o", "l", "A", "CT", "CT"}, ClassTypeHelper.getAllDeclaredMethods(ct));
assertBindings(new String[] {"CT", "CT", "CT"}, ClassTypeHelper.getConstructors(ct, null)); assertBindings(new String[] {"CT", "CT", "CT"}, ct.getConstructors());
assertBindings(new String[] {"h"}, ClassTypeHelper.getDeclaredFields(ct, null)); assertBindings(new String[] {"h"}, ct.getDeclaredFields());
assertBindings(new String[] {"o", "CT", "CT"}, ClassTypeHelper.getDeclaredMethods(ct, null)); assertBindings(new String[] {"o", "CT", "CT"}, ct.getDeclaredMethods());
assertBindings(new String[] {"e", "h"}, ClassTypeHelper.getFields(ct, null)); assertBindings(new String[] {"e", "h"}, ClassTypeHelper.getFields(ct));
assertBindings(new String[] {"l", "o", "CT", "CT", "CT", "~CT", "A", "A", "~A", "operator =", "operator ="}, ClassTypeHelper.getMethods(ct, null)); assertBindings(new String[] {"l", "o", "CT", "CT", "CT", "~CT", "A", "A", "~A", "operator =", "operator ="}, ClassTypeHelper.getMethods(ct));
assertBindings(new String[] {"P"}, ClassTypeHelper.getNestedClasses(ct, null)); assertBindings(new String[] {"P"}, ct.getNestedClasses());
} }
// void func(const int* x) {} // void func(const int* x) {}

View file

@ -2071,20 +2071,20 @@ public class IndexCPPBindingResolutionTest extends IndexBindingResolutionTestBas
assertFalse(ClassTypeHelper.isOverrider(m5, m2)); assertFalse(ClassTypeHelper.isOverrider(m5, m2));
assertTrue(ClassTypeHelper.isOverrider(m4, m2)); assertTrue(ClassTypeHelper.isOverrider(m4, m2));
ICPPMethod[] ors= ClassTypeHelper.findOverridden(m0, null); ICPPMethod[] ors= ClassTypeHelper.findOverridden(m0);
assertEquals(0, ors.length); assertEquals(0, ors.length);
ors= ClassTypeHelper.findOverridden(m1, null); ors= ClassTypeHelper.findOverridden(m1);
assertEquals(0, ors.length); assertEquals(0, ors.length);
ors= ClassTypeHelper.findOverridden(m2, null); ors= ClassTypeHelper.findOverridden(m2);
assertEquals(1, ors.length); assertEquals(1, ors.length);
assertEquals(ors[0], m1); assertEquals(ors[0], m1);
ors= ClassTypeHelper.findOverridden(m3, null); ors= ClassTypeHelper.findOverridden(m3);
assertEquals(0, ors.length); assertEquals(0, ors.length);
ors= ClassTypeHelper.findOverridden(m4, null); ors= ClassTypeHelper.findOverridden(m4);
assertEquals(2, ors.length); assertEquals(2, ors.length);
assertEquals(ors[0], m2); assertEquals(ors[0], m2);
assertEquals(ors[1], m1); assertEquals(ors[1], m1);
ors= ClassTypeHelper.findOverridden(m5, null); ors= ClassTypeHelper.findOverridden(m5);
assertEquals(1, ors.length); assertEquals(1, ors.length);
assertEquals(ors[0], m1); assertEquals(ors[0], m1);
} }

View file

@ -691,7 +691,7 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
assertInstance(b2, ICPPClassType.class); assertInstance(b2, ICPPClassType.class);
assertInstance(b2, ICPPTemplateInstance.class); assertInstance(b2, ICPPTemplateInstance.class);
ICPPClassType ct2= (ICPPClassType) b2; ICPPClassType ct2= (ICPPClassType) b2;
ICPPBase[] bss2= ClassTypeHelper.getBases(ct2, null); ICPPBase[] bss2= ct2.getBases();
assertEquals(1, bss2.length); assertEquals(1, bss2.length);
assertInstance(bss2[0].getBaseClass(), ICPPClassType.class); assertInstance(bss2[0].getBaseClass(), ICPPClassType.class);
ICPPClassType ct2b= (ICPPClassType) bss2[0].getBaseClass(); ICPPClassType ct2b= (ICPPClassType) bss2[0].getBaseClass();
@ -700,14 +700,14 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
IBinding b0= getBindingFromASTName("B<int>", 6); IBinding b0= getBindingFromASTName("B<int>", 6);
assertInstance(b0, ICPPClassType.class); assertInstance(b0, ICPPClassType.class);
ICPPClassType ct= (ICPPClassType) b0; ICPPClassType ct= (ICPPClassType) b0;
ICPPBase[] bss= ClassTypeHelper.getBases(ct, null); ICPPBase[] bss= ct.getBases();
assertEquals(1, bss.length); assertEquals(1, bss.length);
assertInstance(bss[0].getBaseClass(), ICPPClassType.class); assertInstance(bss[0].getBaseClass(), ICPPClassType.class);
IBinding b1= getBindingFromASTName("B<long>", 7); IBinding b1= getBindingFromASTName("B<long>", 7);
assertInstance(b1, ICPPClassType.class); assertInstance(b1, ICPPClassType.class);
ICPPClassType ct1= (ICPPClassType) b1; ICPPClassType ct1= (ICPPClassType) b1;
ICPPBase[] bss1= ClassTypeHelper.getBases(ct1, null); ICPPBase[] bss1= ct1.getBases();
assertEquals(1, bss1.length); assertEquals(1, bss1.length);
assertInstance(bss1[0].getBaseClass(), ICPPClassType.class); assertInstance(bss1[0].getBaseClass(), ICPPClassType.class);
} }
@ -736,11 +736,11 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
assertInstance(b0, ICPPSpecialization.class); assertInstance(b0, ICPPSpecialization.class);
ICPPClassType ct= (ICPPClassType) b0; ICPPClassType ct= (ICPPClassType) b0;
ICPPMethod[] dms= ClassTypeHelper.getDeclaredMethods(ct, null); ICPPMethod[] dms= ct.getDeclaredMethods();
assertEquals(2, dms.length); assertEquals(2, dms.length);
// if the specialization was used, we have 2 fields. // if the specialization was used, we have 2 fields.
ICPPField[] fs= ClassTypeHelper.getDeclaredFields(ct, null); ICPPField[] fs= ct.getDeclaredFields();
assertEquals(2, fs.length); assertEquals(2, fs.length);
ICPPMethod foo= dms[0].getName().equals("foo") ? dms[0] : dms[1]; ICPPMethod foo= dms[0].getName().equals("foo") ? dms[0] : dms[1];
@ -1702,11 +1702,11 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
ICPPTemplateInstance inst= (ICPPTemplateInstance) t1; ICPPTemplateInstance inst= (ICPPTemplateInstance) t1;
final ICPPClassTemplate tmplDef = (ICPPClassTemplate) inst.getTemplateDefinition(); final ICPPClassTemplate tmplDef = (ICPPClassTemplate) inst.getTemplateDefinition();
IBinding inst2= CPPTemplates.instantiate(tmplDef, inst.getTemplateArguments(), name); IBinding inst2= CPPTemplates.instantiate(tmplDef, inst.getTemplateArguments());
assertSame(inst, inst2); assertSame(inst, inst2);
IBinding charInst1= CPPTemplates.instantiate(tmplDef, new ICPPTemplateArgument[] {new CPPTemplateTypeArgument(new CPPBasicType(Kind.eChar, 0))}, name); IBinding charInst1= CPPTemplates.instantiate(tmplDef, new ICPPTemplateArgument[] {new CPPTemplateTypeArgument(new CPPBasicType(Kind.eChar, 0))});
IBinding charInst2= CPPTemplates.instantiate(tmplDef, new ICPPTemplateArgument[] {new CPPTemplateTypeArgument(new CPPBasicType(Kind.eChar, 0))}, name); IBinding charInst2= CPPTemplates.instantiate(tmplDef, new ICPPTemplateArgument[] {new CPPTemplateTypeArgument(new CPPBasicType(Kind.eChar, 0))});
assertSame(charInst1, charInst2); assertSame(charInst1, charInst2);
} }
@ -1723,7 +1723,7 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
assertInstance(m, ICPPSpecialization.class); assertInstance(m, ICPPSpecialization.class);
ICPPClassType ct= m.getClassOwner(); ICPPClassType ct= m.getClassOwner();
assertInstance(ct, ICPPTemplateInstance.class); assertInstance(ct, ICPPTemplateInstance.class);
ICPPMethod[] ms= ClassTypeHelper.getDeclaredMethods(ct, null); ICPPMethod[] ms= ct.getDeclaredMethods();
assertEquals(1, ms.length); assertEquals(1, ms.length);
assertEquals(m, ms[0]); assertEquals(m, ms[0]);
} }
@ -1997,16 +1997,16 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
methods= ct.getMethods(); methods= ct.getMethods();
assertEquals(14, methods.length); assertEquals(14, methods.length);
ICPPBase[] bases = ClassTypeHelper.getBases(ct, null); ICPPBase[] bases = ct.getBases();
assertEquals(1, bases.length); assertEquals(1, bases.length);
IField field = ct.findField("bfield"); IField field = ct.findField("bfield");
assertNotNull(field); assertNotNull(field);
IField[] fields = ClassTypeHelper.getFields(ct, null); IField[] fields = ClassTypeHelper.getFields(ct);
assertEquals(2, fields.length); assertEquals(2, fields.length);
IBinding[] friends = ClassTypeHelper.getFriends(ct, null); IBinding[] friends = ct.getFriends();
assertEquals(0, friends.length); // not yet supported assertEquals(0, friends.length); // not yet supported
} }
@ -3036,7 +3036,7 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
IType derivedInt = waldo.getType(); IType derivedInt = waldo.getType();
assertInstance(derivedInt, ICPPClassSpecialization.class); assertInstance(derivedInt, ICPPClassSpecialization.class);
ICPPClassType derived = ((ICPPClassSpecialization) derivedInt).getSpecializedBinding(); ICPPClassType derived = ((ICPPClassSpecialization) derivedInt).getSpecializedBinding();
ICPPMethod constructor = ClassTypeHelper.getMethodInClass(derived, MethodKind.DEFAULT_CTOR, null); ICPPMethod constructor = ClassTypeHelper.getMethodInClass(derived, MethodKind.DEFAULT_CTOR);
assertInstance(constructor, ICPPConstructor.class); assertInstance(constructor, ICPPConstructor.class);
// Trigger deserialization of constructor chain execution // Trigger deserialization of constructor chain execution
((ICPPConstructor) constructor).getConstructorChainExecution(waldoName); ((ICPPConstructor) constructor).getConstructorChainExecution(waldoName);

View file

@ -209,7 +209,7 @@ public class CPPClassTemplateTests extends PDOMInlineCodeTestBase {
ICPPVariable var= (ICPPVariable) bs[0]; ICPPVariable var= (ICPPVariable) bs[0];
assertInstance(var.getType(), ICPPClassType.class); assertInstance(var.getType(), ICPPClassType.class);
ICPPClassType ct= (ICPPClassType) var.getType(); ICPPClassType ct= (ICPPClassType) var.getType();
IField[] fields = ClassTypeHelper.getFields(ct, null); IField[] fields = ClassTypeHelper.getFields(ct);
assertEquals(1, fields.length); assertEquals(1, fields.length);
assertInstance(fields[0].getType(), IPointerType.class); assertInstance(fields[0].getType(), IPointerType.class);
IPointerType pt= (IPointerType) fields[0].getType(); IPointerType pt= (IPointerType) fields[0].getType();

View file

@ -27,86 +27,85 @@ public interface ICPPClassSpecialization extends ICPPTypeSpecialization, ICPPCla
ICPPClassType getSpecializedBinding(); ICPPClassType getSpecializedBinding();
/** /**
* @deprecated Specializing a member may require a point of instantiation. * Creates a specialized binding for a member of the original class. The result is
* @noreference This method is not intended to be referenced by clients. * a member of this class specialization.
*/ */
@Deprecated
IBinding specializeMember(IBinding binding); IBinding specializeMember(IBinding binding);
/** /**
* Creates a specialized binding for a member of the original class. The result is
* a member of this class specialization.
* @since 5.5 * @since 5.5
* @deprecated Use {@link ICPPClassSpecialization#specializeMember(IBinding)} instead.
*/ */
@Deprecated
IBinding specializeMember(IBinding binding, IASTNode point); IBinding specializeMember(IBinding binding, IASTNode point);
/** /**
* Similar to {@link ICPPClassType#getBases()} but a accepts a starting point for template
* instantiation.
* @since 5.5 * @since 5.5
* @deprecated Use {@link ICPPClassType#getBases()} instead.
*/ */
@Deprecated
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 * @since 5.5
* @deprecated Use {@link ICPPClassType#getConstructors()} instead.
*/ */
@Deprecated
ICPPConstructor[] getConstructors(IASTNode point); ICPPConstructor[] getConstructors(IASTNode point);
/** /**
* Similar to {@link ICPPClassType#getDeclaredFields()} but a accepts a starting point
* for template instantiation.
* @since 5.5 * @since 5.5
* @deprecated Use {@link ICPPClassType#getDeclaredFields()} instead.
*/ */
@Deprecated
ICPPField[] getDeclaredFields(IASTNode point); ICPPField[] getDeclaredFields(IASTNode point);
/** /**
* Similar to {@link ICPPClassType#getMethods()} but a accepts a starting point
* for template instantiation.
* @since 5.5 * @since 5.5
* @deprecated Use {@link ICPPClassType#getMethods()} instead.
*/ */
@Deprecated
ICPPMethod[] getMethods(IASTNode point); ICPPMethod[] getMethods(IASTNode point);
/** /**
* Similar to {@link ICPPClassType#getAllDeclaredMethods()} but a accepts a starting point
* for template instantiation.
* @since 5.5 * @since 5.5
* @deprecated Use {@link ICPPClassType#getAllDeclaredMethods()} instead.
*/ */
@Deprecated
ICPPMethod[] getAllDeclaredMethods(IASTNode point); ICPPMethod[] getAllDeclaredMethods(IASTNode point);
/** /**
* Similar to {@link ICPPClassType#getDeclaredMethods()} but a accepts a starting point
* for template instantiation.
* @since 5.5 * @since 5.5
* @deprecated Use {@link ICPPClassType#getDeclaredMethods()} instead.
*/ */
@Deprecated
ICPPMethod[] getDeclaredMethods(IASTNode point); ICPPMethod[] getDeclaredMethods(IASTNode point);
/** /**
* Similar to {@link ICPPClassType#getFriends()} but a accepts a starting point
* for template instantiation.
* @since 5.5 * @since 5.5
* @deprecated Use {@link ICPPClassType#getFriends()} instead.
*/ */
@Deprecated
IBinding[] getFriends(IASTNode point); IBinding[] getFriends(IASTNode point);
/** /**
* Similar to {@link ICPPClassType#getFields()} but a accepts a starting point
* for template instantiation.
* @since 5.5 * @since 5.5
* @deprecated Use {@link ICPPClassType#getFields()} instead.
*/ */
@Deprecated
IField[] getFields(IASTNode point); IField[] getFields(IASTNode point);
/** /**
* Similar to {@link ICPPClassType#getNestedClasses()} but a accepts a starting point
* for template instantiation.
* @since 5.5 * @since 5.5
* @deprecated Use {@link ICPPClassType#getNestedClasses()} instead.
*/ */
@Deprecated
ICPPClassType[] getNestedClasses(IASTNode point); ICPPClassType[] getNestedClasses(IASTNode point);
/** /**
* Similar to {@link ICPPClassType#getUsingDeclarations()} but accepts a starting point
* for template instantiation.
* @since 6.3 * @since 6.3
* @deprecated Use {@link ICPPClassType#getUsingDeclarations()} instead.
*/ */
@Deprecated
ICPPUsingDeclaration[] getUsingDeclarations(IASTNode point); ICPPUsingDeclaration[] getUsingDeclarations(IASTNode point);
} }

View file

@ -21,11 +21,18 @@ public interface ICPPConstructor extends ICPPMethod {
public static final ICPPConstructor[] EMPTY_CONSTRUCTOR_ARRAY = {}; public static final ICPPConstructor[] EMPTY_CONSTRUCTOR_ARRAY = {};
/** /**
* For a constexpr constructor returns the ICPPExecution for its constructor chain. Otherwise returns
* {@code null}.
* @param point The point of instantiation for name lookups.
* @since 6.0 * @since 6.0
* @noreference This method is not intended to be referenced by clients. * @noreference This method is not intended to be referenced by clients.
* @deprecated use {@link ICPPConstructor#getConstructorChainExecution()} instead.
*/ */
@Deprecated
public ICPPExecution getConstructorChainExecution(IASTNode point); public ICPPExecution getConstructorChainExecution(IASTNode point);
/**
* For a constexpr constructor returns the ICPPExecution for its constructor chain. Otherwise returns
* {@code null}.
* @since 6.3
* @noreference This method is not intended to be referenced by clients.
*/
public ICPPExecution getConstructorChainExecution();
} }

View file

@ -22,8 +22,8 @@ import org.eclipse.cdt.core.dom.ast.IType;
*/ */
public interface ICPPMethodSpecialization extends ICPPSpecialization, ICPPMethod { public interface ICPPMethodSpecialization extends ICPPSpecialization, ICPPMethod {
/** /**
* Similar to {@link ICPPFunction#getExceptionSpecification()} but a accepts a starting point * @deprecated Use {@link ICPPFunction#getExceptionSpecification()} instead.
* for template instantiation.
*/ */
@Deprecated
IType[] getExceptionSpecification(IASTNode point); IType[] getExceptionSpecification(IASTNode point);
} }

View file

@ -92,12 +92,11 @@ public class SemanticQueries {
* template parameters. * template parameters.
* *
* @param classType the class whose pure virtual methods should be returned * @param classType the class whose pure virtual methods should be returned
* @param point the point of template instantiation, if applicable
* @return an array containing all pure virtual methods of the class * @return an array containing all pure virtual methods of the class
* @since 5.6 * @since 6.3
*/ */
public static ICPPMethod[] getPureVirtualMethods(ICPPClassType classType, IASTNode point) { public static ICPPMethod[] getPureVirtualMethods(ICPPClassType classType) {
FinalOverriderMap finalOverriderMap = CPPInheritance.getFinalOverriderMap(classType, point); FinalOverriderMap finalOverriderMap = CPPInheritance.getFinalOverriderMap(classType);
List<ICPPMethod> pureVirtualMethods = new ArrayList<>(); List<ICPPMethod> pureVirtualMethods = new ArrayList<>();
for (ICPPMethod method : finalOverriderMap.getMap().keySet()) { for (ICPPMethod method : finalOverriderMap.getMap().keySet()) {
if (method.isPureVirtual()) { if (method.isPureVirtual()) {
@ -113,6 +112,15 @@ public class SemanticQueries {
return pureVirtualMethods.toArray(new ICPPMethod[pureVirtualMethods.size()]); return pureVirtualMethods.toArray(new ICPPMethod[pureVirtualMethods.size()]);
} }
/**
* @deprecated Use {@link SemanticQueries}{@link #getPureVirtualMethods(ICPPClassType)} instead.
* @since 5.6
*/
@Deprecated
public static ICPPMethod[] getPureVirtualMethods(ICPPClassType classType, IASTNode point) {
return getPureVirtualMethods(classType);
}
/** /**
* Returns whether a problem binding represents a name resolution error due to an unknown built-in. * Returns whether a problem binding represents a name resolution error due to an unknown built-in.
* Importantly, this will not return true for a misuse of a known builtin, which we want to diagnose. * Importantly, this will not return true for a misuse of a known builtin, which we want to diagnose.

View file

@ -20,6 +20,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit;
import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator; 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.SizeofCalculator.SizeAndAlignment;
import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor; import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeTraits; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeTraits;
@ -46,19 +47,24 @@ public class TypeHelper {
public static boolean shouldBePassedByReference(IType type, IASTTranslationUnit ast) { public static boolean shouldBePassedByReference(IType type, IASTTranslationUnit ast) {
type = SemanticUtil.getNestedType(type, SemanticUtil.CVTYPE | SemanticUtil.TDEF); type = SemanticUtil.getNestedType(type, SemanticUtil.CVTYPE | SemanticUtil.TDEF);
if (type instanceof ICompositeType) { if (type instanceof ICompositeType) {
if (type instanceof ICPPClassType) { try {
ICPPClassType classType = ((ICPPClassType) type); CPPSemantics.pushLookupPoint(ast);
if (!TypeTraits.hasTrivialCopyCtor(classType, ast) || if (type instanceof ICPPClassType) {
!TypeTraits.hasTrivialDestructor(classType, ast)) { ICPPClassType classType = ((ICPPClassType) type);
return true; if (!TypeTraits.hasTrivialCopyCtor(classType) ||
!TypeTraits.hasTrivialDestructor(classType)) {
return true;
}
} }
SizeofCalculator calc = ((ASTTranslationUnit) ast).getSizeofCalculator();
SizeAndAlignment sizeofPointer = calc.sizeAndAlignmentOfPointer();
long maxSize = sizeofPointer != null ? sizeofPointer.size : 4;
SizeAndAlignment sizeofType = calc.sizeAndAlignment(type);
if (sizeofType == null || sizeofType.size > maxSize)
return true;
} finally {
CPPSemantics.popLookupPoint();
} }
SizeofCalculator calc = ((ASTTranslationUnit) ast).getSizeofCalculator();
SizeAndAlignment sizeofPointer = calc.sizeAndAlignmentOfPointer();
long maxSize = sizeofPointer != null ? sizeofPointer.size : 4;
SizeAndAlignment sizeofType = calc.sizeAndAlignment(type);
if (sizeofType == null || sizeofType.size > maxSize)
return true;
} }
return false; return false;
} }

View file

@ -14,7 +14,6 @@ package org.eclipse.cdt.internal.core.dom.parser;
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.TDEF;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumeration;
@ -421,10 +420,9 @@ public abstract class ArithmeticConversion {
* *
* @param target the target integral type * @param target the target integral type
* @param source the source integral type * @param source the source integral type
* @param point point for sizeof lookup
* @return whether the target integral type can represent all values of the source integral type * @return whether the target integral type can represent all values of the source integral type
*/ */
public static boolean fitsIntoType(IBasicType target, IBasicType source, IASTNode point) { public static boolean fitsIntoType(IBasicType target, IBasicType source) {
// A boolean cannot represent any other type. // A boolean cannot represent any other type.
if (target.getKind() == Kind.eBoolean && source.getKind() != Kind.eBoolean) if (target.getKind() == Kind.eBoolean && source.getKind() != Kind.eBoolean)
return false; return false;
@ -437,8 +435,8 @@ public abstract class ArithmeticConversion {
return false; return false;
// Otherwise, go by the size and signedness of the type. // Otherwise, go by the size and signedness of the type.
SizeAndAlignment sourceSizeAndAlignment = SizeofCalculator.getSizeAndAlignment(source, point); SizeAndAlignment sourceSizeAndAlignment = SizeofCalculator.getSizeAndAlignment(source);
SizeAndAlignment targetSizeAndAlignment = SizeofCalculator.getSizeAndAlignment(target, point); SizeAndAlignment targetSizeAndAlignment = SizeofCalculator.getSizeAndAlignment(target);
long sizeofSource = sourceSizeAndAlignment == null ? getApproximateSize(source) : sourceSizeAndAlignment.size; long sizeofSource = sourceSizeAndAlignment == null ? getApproximateSize(source) : sourceSizeAndAlignment.size;
long sizeofTarget = targetSizeAndAlignment == null ? getApproximateSize(target) : targetSizeAndAlignment.size; long sizeofTarget = targetSizeAndAlignment == null ? getApproximateSize(target) : targetSizeAndAlignment.size;

View file

@ -13,7 +13,6 @@ import java.util.TreeSet;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.ICompositeType;
@ -80,12 +79,12 @@ public final class CompositeValue implements IValue {
return 0 <= index && index < values.length; return 0 <= index && index < values.length;
} }
public static IValue create(EvalInitList initList, IASTNode point) { public static IValue create(EvalInitList initList) {
ICPPEvaluation[] clauses = initList.getClauses(); ICPPEvaluation[] clauses = initList.getClauses();
ICPPEvaluation[] values = new ICPPEvaluation[clauses.length]; ICPPEvaluation[] values = new ICPPEvaluation[clauses.length];
for (int i = 0; i < clauses.length; i++) { for (int i = 0; i < clauses.length; i++) {
ICPPEvaluation eval = clauses[i]; ICPPEvaluation eval = clauses[i];
values[i] = new EvalFixed(eval.getType(point), eval.getValueCategory(point), eval.getValue(point)); values[i] = new EvalFixed(eval.getType(), eval.getValueCategory(), eval.getValue());
} }
return new CompositeValue(initList, values); return new CompositeValue(initList, values);
} }
@ -94,7 +93,7 @@ public final class CompositeValue implements IValue {
* Creates a value representing an instance of the given array type initialized with * Creates a value representing an instance of the given array type initialized with
* the elements of the given initializer list. * the elements of the given initializer list.
*/ */
public static IValue create(EvalInitList initList, IArrayType type, IASTNode point) { public static IValue create(EvalInitList initList, IArrayType type) {
Number arraySize = type.getSize().numberValue(); Number arraySize = type.getSize().numberValue();
if (arraySize == null) { if (arraySize == null) {
// Array size is dependent. TODO: Handle this? // Array size is dependent. TODO: Handle this?
@ -108,8 +107,8 @@ public final class CompositeValue implements IValue {
ICPPEvaluation[] values = new ICPPEvaluation[arraySize.intValue()]; ICPPEvaluation[] values = new ICPPEvaluation[arraySize.intValue()];
for (int i = 0; i < initList.getClauses().length; i++) { for (int i = 0; i < initList.getClauses().length; i++) {
ICPPEvaluation eval = initList.getClauses()[i]; ICPPEvaluation eval = initList.getClauses()[i];
IValue value = getValue(elementType, eval, point); IValue value = getValue(elementType, eval);
values[i] = new EvalFixed(elementType, eval.getValueCategory(point), value); values[i] = new EvalFixed(elementType, eval.getValueCategory(), value);
} }
return new CompositeValue(initList, values); return new CompositeValue(initList, values);
} }
@ -117,16 +116,16 @@ public final class CompositeValue implements IValue {
/** /**
* Gets the value of an evaluation, interpreted as a value of the given type. * Gets the value of an evaluation, interpreted as a value of the given type.
*/ */
private static IValue getValue(IType type, ICPPEvaluation eval, IASTNode point) { private static IValue getValue(IType type, ICPPEvaluation eval) {
IValue value; IValue value;
if (type instanceof IArrayType && eval instanceof EvalInitList) { if (type instanceof IArrayType && eval instanceof EvalInitList) {
value = CompositeValue.create((EvalInitList) eval, (IArrayType) type, point); value = CompositeValue.create((EvalInitList) eval, (IArrayType) type);
} else if (type instanceof ICompositeType && eval instanceof EvalInitList) { } else if (type instanceof ICompositeType && eval instanceof EvalInitList) {
value = CompositeValue.create((EvalInitList) eval, (ICompositeType) type, point); value = CompositeValue.create((EvalInitList) eval, (ICompositeType) type);
} else if (eval instanceof EvalInitList) { } else if (eval instanceof EvalInitList) {
value = IntegralValue.UNKNOWN; value = IntegralValue.UNKNOWN;
} else { } else {
value = eval.getValue(null); value = eval.getValue();
} }
return value; return value;
} }
@ -135,10 +134,10 @@ public final class CompositeValue implements IValue {
* Creates a value representing an instance of the given composite type initialized with * Creates a value representing an instance of the given composite type initialized with
* the elements of the given initializer list. * the elements of the given initializer list.
*/ */
public static IValue create(EvalInitList initList, ICompositeType type, IASTNode point) { public static IValue create(EvalInitList initList, ICompositeType type) {
IField[] fields; IField[] fields;
if (type instanceof ICPPClassType) { if (type instanceof ICPPClassType) {
fields = ClassTypeHelper.getFields((ICPPClassType) type, point); fields = ClassTypeHelper.getFields((ICPPClassType) type);
} else { } else {
fields = type.getFields(); fields = type.getFields();
} }
@ -150,8 +149,8 @@ public final class CompositeValue implements IValue {
IField field = fields[i]; IField field = fields[i];
ICPPEvaluation eval = clauses[i]; ICPPEvaluation eval = clauses[i];
IType fieldType = field.getType(); IType fieldType = field.getType();
IValue value = getValue(fieldType, eval, point); IValue value = getValue(fieldType, eval);
values[i] = new EvalFixed(fieldType, eval.getValueCategory(null), value); values[i] = new EvalFixed(fieldType, eval.getValueCategory(), value);
} }
return new CompositeValue(initList, values); return new CompositeValue(initList, values);
} }
@ -175,8 +174,8 @@ public final class CompositeValue implements IValue {
* determined by the default member initializers only. Constructors are not considered * determined by the default member initializers only. Constructors are not considered
* when determining the values of the fields. * when determining the values of the fields.
*/ */
public static CompositeValue create(ICPPClassType classType, IASTNode point) { public static CompositeValue create(ICPPClassType classType) {
return create(classType, point, 0); return create(classType, 0);
} }
/** /**
@ -184,7 +183,7 @@ public final class CompositeValue implements IValue {
* determined by the default member initializers only. Constructors are not considered * determined by the default member initializers only. Constructors are not considered
* when determining the values of the fields. * when determining the values of the fields.
*/ */
public static CompositeValue create(ICPPClassType classType, IASTNode point, int nestingLevel) { public static CompositeValue create(ICPPClassType classType, int nestingLevel) {
Set<ICPPClassType> recursionProtectionSet = fCreateInProgress.get(); Set<ICPPClassType> recursionProtectionSet = fCreateInProgress.get();
if (!recursionProtectionSet.add(classType)) { if (!recursionProtectionSet.add(classType)) {
return new CompositeValue(null, ICPPEvaluation.EMPTY_ARRAY); return new CompositeValue(null, ICPPEvaluation.EMPTY_ARRAY);
@ -195,16 +194,16 @@ public final class CompositeValue implements IValue {
System.out.flush(); System.out.flush();
} }
ActivationRecord record = new ActivationRecord(); ActivationRecord record = new ActivationRecord();
ICPPEvaluation[] values = new ICPPEvaluation[ClassTypeHelper.getFields(classType, point).length]; ICPPEvaluation[] values = new ICPPEvaluation[ClassTypeHelper.getFields(classType).length];
// Recursively create all the base class member variables. // Recursively create all the base class member variables.
ICPPBase[] bases = ClassTypeHelper.getBases(classType, point); ICPPBase[] bases = classType.getBases();
for (ICPPBase base : bases) { for (ICPPBase base : bases) {
IBinding baseClass = base.getBaseClass(); IBinding baseClass = base.getBaseClass();
if (baseClass instanceof ICPPClassType) { if (baseClass instanceof ICPPClassType) {
ICPPClassType baseClassType = (ICPPClassType) baseClass; ICPPClassType baseClassType = (ICPPClassType) baseClass;
ICPPField[] baseFields = ClassTypeHelper.getDeclaredFields(baseClassType, point); ICPPField[] baseFields = baseClassType.getDeclaredFields();
IValue compValue = CompositeValue.create(baseClassType, point, nestingLevel + 1); IValue compValue = CompositeValue.create(baseClassType, nestingLevel + 1);
for (ICPPField baseField : baseFields) { for (ICPPField baseField : baseFields) {
int fieldPos = CPPASTFieldReference.getFieldPosition(baseField); int fieldPos = CPPASTFieldReference.getFieldPosition(baseField);
if (fieldPos == -1) { if (fieldPos == -1) {
@ -219,11 +218,11 @@ public final class CompositeValue implements IValue {
} }
} }
ICPPField[] fields = ClassTypeHelper.getDeclaredFields(classType, point); ICPPField[] fields = classType.getDeclaredFields();
for (ICPPField field : fields) { for (ICPPField field : fields) {
if (field.isStatic()) if (field.isStatic())
continue; continue;
final ICPPEvaluation value = EvalUtil.getVariableValue(field, record, point); final ICPPEvaluation value = EvalUtil.getVariableValue(field, record);
int fieldPos = CPPASTFieldReference.getFieldPosition(field); int fieldPos = CPPASTFieldReference.getFieldPosition(field);
if (fieldPos == -1) { if (fieldPos == -1) {
continue; continue;
@ -274,8 +273,8 @@ public final class CompositeValue implements IValue {
if (eval == EvalFixed.INCOMPLETE) { if (eval == EvalFixed.INCOMPLETE) {
newValues[i] = eval; newValues[i] = eval;
} else { } else {
IValue newValue = eval.getValue(null).clone(); IValue newValue = eval.getValue().clone();
newValues[i] = new EvalFixed(eval.getType(null), eval.getValueCategory(null), newValue); newValues[i] = new EvalFixed(eval.getType(), eval.getValueCategory(), newValue);
} }
} }
return new CompositeValue(evaluation, newValues); return new CompositeValue(evaluation, newValues);

View file

@ -33,7 +33,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeTraits; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeTraits;
@ -86,11 +86,10 @@ public class SizeofCalculator {
* Calculates size and alignment for the given type. * Calculates size and alignment for the given type.
* *
* @param type the type to get size and alignment for. * @param type the type to get size and alignment for.
* @param point a node belonging to the AST of the translation unit defining context for
* the size calculation.
* @return size and alignment, or {@code null} if could not be calculated. * @return size and alignment, or {@code null} if could not be calculated.
*/ */
public static SizeAndAlignment getSizeAndAlignment(IType type, IASTNode point) { public static SizeAndAlignment getSizeAndAlignment(IType type) {
IASTNode point = CPPSemantics.getCurrentLookupPoint();
SizeofCalculator calc = point == null ? SizeofCalculator calc = point == null ?
getDefault() : ((ASTTranslationUnit) point.getTranslationUnit()).getSizeofCalculator(); getDefault() : ((ASTTranslationUnit) point.getTranslationUnit()).getSizeofCalculator();
return calc.sizeAndAlignment(type); return calc.sizeAndAlignment(type);
@ -292,27 +291,32 @@ public class SizeofCalculator {
int maxAlignment = 1; int maxAlignment = 1;
IField[] fields; IField[] fields;
if (type instanceof ICPPClassType) { if (type instanceof ICPPClassType) {
ICPPClassType classType = (ICPPClassType) type; CPPSemantics.pushLookupPoint(ast);
for (ICPPBase base : ClassTypeHelper.getBases(classType, ast)) { try {
if (base.isVirtual()) ICPPClassType classType = (ICPPClassType) type;
return null; // Don't know how to calculate size when there are virtual bases. for (ICPPBase base : classType.getBases()) {
IBinding baseClass = base.getBaseClass(); if (base.isVirtual())
if (!(baseClass instanceof IType)) return null; // Don't know how to calculate size when there are virtual bases.
return null; IBinding baseClass = base.getBaseClass();
SizeAndAlignment info = sizeAndAlignment((IType) baseClass); if (!(baseClass instanceof IType))
if (info == null)
return null;
size += info.alignment - (size - 1) % info.alignment - 1 + info.size;
if (maxAlignment < info.alignment)
maxAlignment = info.alignment;
for (ICPPMethod method : ClassTypeHelper.getDeclaredMethods(classType, ast)) {
if (method.isVirtual()) {
// Don't know how to calculate size when there are virtual functions.
return null; return null;
SizeAndAlignment info = sizeAndAlignment((IType) baseClass);
if (info == null)
return null;
size += info.alignment - (size - 1) % info.alignment - 1 + info.size;
if (maxAlignment < info.alignment)
maxAlignment = info.alignment;
for (ICPPMethod method : classType.getDeclaredMethods()) {
if (method.isVirtual()) {
// Don't know how to calculate size when there are virtual functions.
return null;
}
} }
} }
fields = classType.getDeclaredFields();
} finally {
CPPSemantics.popLookupPoint();
} }
fields = ClassTypeHelper.getDeclaredFields(classType, ast);
} else { } else {
fields = type.getFields(); fields = type.getFields();
} }

View file

@ -45,7 +45,6 @@ import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression; import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
@ -67,6 +66,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeTraits; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeTraits;
@ -78,16 +78,21 @@ public class ValueFactory {
* Creates the value for an expression. * Creates the value for an expression.
*/ */
public static IValue create(IASTExpression expr) { public static IValue create(IASTExpression expr) {
IValue val= evaluate(expr); try {
if (val != null) { CPPSemantics.pushLookupPoint(expr);
return val; IValue val= evaluate(expr);
if (val != null) {
return val;
}
if (expr instanceof ICPPASTInitializerClause) {
ICPPEvaluation evaluation = ((ICPPASTInitializerClause) expr).getEvaluation();
return evaluation.getValue();
}
return IntegralValue.UNKNOWN;
} finally {
CPPSemantics.popLookupPoint();
} }
if (expr instanceof ICPPASTInitializerClause) {
ICPPEvaluation evaluation = ((ICPPASTInitializerClause) expr).getEvaluation();
return evaluation.getValue(expr);
}
return IntegralValue.UNKNOWN;
} }
public static IValue evaluateUnaryExpression(final int unaryOp, final IValue value) { public static IValue evaluateUnaryExpression(final int unaryOp, final IValue value) {
@ -248,16 +253,16 @@ public class ValueFactory {
} }
} }
public static IValue evaluateUnaryTypeIdExpression(int operator, IType type, IASTNode point) { public static IValue evaluateUnaryTypeIdExpression(int operator, IType type) {
IValue val = applyUnaryTypeIdOperator(operator, type, point); IValue val = applyUnaryTypeIdOperator(operator, type);
if (isInvalidValue(val)) if (isInvalidValue(val))
return IntegralValue.UNKNOWN; return IntegralValue.UNKNOWN;
return val; return val;
} }
public static IValue evaluateBinaryTypeIdExpression(IASTBinaryTypeIdExpression.Operator operator, public static IValue evaluateBinaryTypeIdExpression(IASTBinaryTypeIdExpression.Operator operator,
IType type1, IType type2, IASTNode point) { IType type1, IType type2) {
IValue val = applyBinaryTypeIdOperator(operator, type1, type2, point); IValue val = applyBinaryTypeIdOperator(operator, type1, type2);
if (isInvalidValue(val)) if (isInvalidValue(val))
return IntegralValue.UNKNOWN; return IntegralValue.UNKNOWN;
return val; return val;
@ -348,7 +353,7 @@ public class ValueFactory {
final IType type = ast.createType(typeIdExp.getTypeId()); final IType type = ast.createType(typeIdExp.getTypeId());
if (type instanceof ICPPUnknownType) if (type instanceof ICPPUnknownType)
return null; return null;
return applyUnaryTypeIdOperator(typeIdExp.getOperator(), type, exp); return applyUnaryTypeIdOperator(typeIdExp.getOperator(), type);
} }
if (exp instanceof IASTBinaryTypeIdExpression) { if (exp instanceof IASTBinaryTypeIdExpression) {
IASTBinaryTypeIdExpression typeIdExp = (IASTBinaryTypeIdExpression) exp; IASTBinaryTypeIdExpression typeIdExp = (IASTBinaryTypeIdExpression) exp;
@ -357,7 +362,7 @@ public class ValueFactory {
IType t2= ast.createType(typeIdExp.getOperand2()); IType t2= ast.createType(typeIdExp.getOperand2());
if (CPPTemplates.isDependentType(t1) || CPPTemplates.isDependentType(t2)) if (CPPTemplates.isDependentType(t1) || CPPTemplates.isDependentType(t2))
return null; return null;
return applyBinaryTypeIdOperator(typeIdExp.getOperator(), t1, t2, exp); return applyBinaryTypeIdOperator(typeIdExp.getOperator(), t1, t2);
} }
return IntegralValue.UNKNOWN; return IntegralValue.UNKNOWN;
} }
@ -389,14 +394,14 @@ public class ValueFactory {
return value; return value;
} }
private static IValue applyUnaryTypeIdOperator(int operator, IType type, IASTNode point) { private static IValue applyUnaryTypeIdOperator(int operator, IType type) {
type = SemanticUtil.getNestedType(type, TDEF | CVTYPE); type = SemanticUtil.getNestedType(type, TDEF | CVTYPE);
switch (operator) { switch (operator) {
case op_sizeof: case op_sizeof:
return getSize(type, point); return getSize(type);
case op_alignof: case op_alignof:
return getAlignment(type, point); return getAlignment(type);
case op_typeid: case op_typeid:
break; break;
case op_has_nothrow_copy: case op_has_nothrow_copy:
@ -409,19 +414,19 @@ public class ValueFactory {
break; // TODO(sprigogin): Implement break; // TODO(sprigogin): Implement
case op_has_trivial_copy: case op_has_trivial_copy:
return IntegralValue.create(!(type instanceof ICPPClassType) || return IntegralValue.create(!(type instanceof ICPPClassType) ||
TypeTraits.hasTrivialCopyCtor((ICPPClassType) type, point) ? 1 : 0); TypeTraits.hasTrivialCopyCtor((ICPPClassType) type) ? 1 : 0);
case op_has_trivial_destructor: case op_has_trivial_destructor:
break; // TODO(sprigogin): Implement break; // TODO(sprigogin): Implement
case op_has_virtual_destructor: case op_has_virtual_destructor:
break; // TODO(sprigogin): Implement break; // TODO(sprigogin): Implement
case op_is_abstract: case op_is_abstract:
return IntegralValue.create(type instanceof ICPPClassType && return IntegralValue.create(type instanceof ICPPClassType &&
TypeTraits.isAbstract((ICPPClassType) type, point) ? 1 : 0); TypeTraits.isAbstract((ICPPClassType) type) ? 1 : 0);
case op_is_class: case op_is_class:
return IntegralValue.create(type instanceof ICompositeType && return IntegralValue.create(type instanceof ICompositeType &&
((ICompositeType) type).getKey() != ICompositeType.k_union ? 1 : 0); ((ICompositeType) type).getKey() != ICompositeType.k_union ? 1 : 0);
case op_is_empty: case op_is_empty:
return IntegralValue.create(TypeTraits.isEmpty(type, point) ? 1 : 0); return IntegralValue.create(TypeTraits.isEmpty(type) ? 1 : 0);
case op_is_enum: case op_is_enum:
return IntegralValue.create(type instanceof IEnumeration ? 1 : 0); return IntegralValue.create(type instanceof IEnumeration ? 1 : 0);
case op_is_final: case op_is_final:
@ -429,17 +434,17 @@ public class ValueFactory {
case op_is_literal_type: case op_is_literal_type:
break; // TODO(sprigogin): Implement break; // TODO(sprigogin): Implement
case op_is_pod: case op_is_pod:
return IntegralValue.create(TypeTraits.isPOD(type, point) ? 1 : 0); return IntegralValue.create(TypeTraits.isPOD(type) ? 1 : 0);
case op_is_polymorphic: case op_is_polymorphic:
return IntegralValue.create(type instanceof ICPPClassType && return IntegralValue.create(type instanceof ICPPClassType &&
TypeTraits.isPolymorphic((ICPPClassType) type, point) ? 1 : 0); TypeTraits.isPolymorphic((ICPPClassType) type) ? 1 : 0);
case op_is_standard_layout: case op_is_standard_layout:
return IntegralValue.create(TypeTraits.isStandardLayout(type, point) ? 1 : 0); return IntegralValue.create(TypeTraits.isStandardLayout(type) ? 1 : 0);
case op_is_trivial: case op_is_trivial:
return IntegralValue.create(type instanceof ICPPClassType && return IntegralValue.create(type instanceof ICPPClassType &&
TypeTraits.isTrivial((ICPPClassType) type, point) ? 1 : 0); TypeTraits.isTrivial((ICPPClassType) type) ? 1 : 0);
case op_is_trivially_copyable: case op_is_trivially_copyable:
return IntegralValue.create(TypeTraits.isTriviallyCopyable(type, point) ? 1 : 0); return IntegralValue.create(TypeTraits.isTriviallyCopyable(type) ? 1 : 0);
case op_is_union: case op_is_union:
return IntegralValue.create(type instanceof ICompositeType && return IntegralValue.create(type instanceof ICompositeType &&
((ICompositeType) type).getKey() == ICompositeType.k_union ? 1 : 0); ((ICompositeType) type).getKey() == ICompositeType.k_union ? 1 : 0);
@ -449,15 +454,15 @@ public class ValueFactory {
return IntegralValue.UNKNOWN; return IntegralValue.UNKNOWN;
} }
private static IValue getAlignment(IType type, IASTNode point) { private static IValue getAlignment(IType type) {
SizeAndAlignment sizeAndAlignment = SizeofCalculator.getSizeAndAlignment(type, point); SizeAndAlignment sizeAndAlignment = SizeofCalculator.getSizeAndAlignment(type);
if (sizeAndAlignment == null) if (sizeAndAlignment == null)
return IntegralValue.UNKNOWN; return IntegralValue.UNKNOWN;
return IntegralValue.create(sizeAndAlignment.alignment); return IntegralValue.create(sizeAndAlignment.alignment);
} }
private static IValue getSize(IType type, IASTNode point) { private static IValue getSize(IType type) {
SizeAndAlignment sizeAndAlignment = SizeofCalculator.getSizeAndAlignment(type, point); SizeAndAlignment sizeAndAlignment = SizeofCalculator.getSizeAndAlignment(type);
if (sizeAndAlignment == null) if (sizeAndAlignment == null)
return IntegralValue.UNKNOWN; return IntegralValue.UNKNOWN;
return IntegralValue.create(sizeAndAlignment.size); return IntegralValue.create(sizeAndAlignment.size);
@ -574,14 +579,14 @@ public class ValueFactory {
} }
private static IValue applyBinaryTypeIdOperator(IASTBinaryTypeIdExpression.Operator operator, private static IValue applyBinaryTypeIdOperator(IASTBinaryTypeIdExpression.Operator operator,
IType type1, IType type2, IASTNode point) { IType type1, IType type2) {
switch (operator) { switch (operator) {
case __is_base_of: case __is_base_of:
type1 = SemanticUtil.getNestedType(type1, TDEF); type1 = SemanticUtil.getNestedType(type1, TDEF);
type2 = SemanticUtil.getNestedType(type2, TDEF); type2 = SemanticUtil.getNestedType(type2, TDEF);
if (type1 instanceof ICPPClassType && type2 instanceof ICPPClassType && if (type1 instanceof ICPPClassType && type2 instanceof ICPPClassType &&
(type1.isSameType(type2) || (type1.isSameType(type2) ||
ClassTypeHelper.isSubclass((ICPPClassType) type2, (ICPPClassType) type1, point))) { ClassTypeHelper.isSubclass((ICPPClassType) type2, (ICPPClassType) type1))) {
return IntegralValue.create(1); return IntegralValue.create(1);
} }
return IntegralValue.create(0); return IntegralValue.create(0);
@ -609,16 +614,21 @@ public class ValueFactory {
* to a constant * to a constant
*/ */
public static Number getConstantNumericalValue(IASTExpression expr) { public static Number getConstantNumericalValue(IASTExpression expr) {
IValue val = evaluate(expr); try {
if (val != null) { CPPSemantics.pushLookupPoint(expr);
return val.numberValue(); IValue val = evaluate(expr);
if (val != null) {
return val.numberValue();
}
if (expr instanceof ICPPASTInitializerClause) {
ICPPEvaluation eval = ((ICPPASTInitializerClause) expr).getEvaluation();
if (eval.isConstantExpression() && !eval.isValueDependent())
return eval.getValue().numberValue();
}
return null;
} finally {
CPPSemantics.popLookupPoint();
} }
if (expr instanceof ICPPASTInitializerClause) {
ICPPEvaluation eval = ((ICPPASTInitializerClause) expr).getEvaluation();
if (eval.isConstantExpression(expr) && !eval.isValueDependent())
return eval.getValue(expr).numberValue();
}
return null;
} }
} }

View file

@ -213,7 +213,7 @@ public abstract class VariableReadWriteFlags {
private IType getArgumentType(IASTInitializerClause argument) { private IType getArgumentType(IASTInitializerClause argument) {
if (argument instanceof ICPPASTInitializerClause) { if (argument instanceof ICPPASTInitializerClause) {
return ((ICPPASTInitializerClause) argument).getEvaluation().getType(argument); return ((ICPPASTInitializerClause) argument).getEvaluation().getType();
} else if (argument instanceof IASTExpression) { } else if (argument instanceof IASTExpression) {
return ((IASTExpression) argument).getExpressionType(); return ((IASTExpression) argument).getExpressionType();
} }

View file

@ -14,12 +14,10 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IName; import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.EScopeKind; import org.eclipse.cdt.core.dom.ast.EScopeKind;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
@ -97,8 +95,13 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
return null; return null;
IBinding[] specs = IBinding.EMPTY_BINDING_ARRAY; IBinding[] specs = IBinding.EMPTY_BINDING_ARRAY;
for (IBinding binding : bindings) { CPPSemantics.pushLookupPoint(name);
specs = ArrayUtil.append(specs, specialClass.specializeMember(binding, name)); try {
for (IBinding binding : bindings) {
specs = ArrayUtil.append(specs, specialClass.specializeMember(binding));
}
} finally {
CPPSemantics.popLookupPoint();
} }
specs = ArrayUtil.trim(specs); specs = ArrayUtil.trim(specs);
return CPPSemantics.resolveAmbiguities(name, specs); return CPPSemantics.resolveAmbiguities(name, specs);
@ -129,7 +132,7 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
(binding instanceof ICPPClassType && areSameTypesModuloPartialSpecialization(specialized, (IType) binding))) { (binding instanceof ICPPClassType && areSameTypesModuloPartialSpecialization(specialized, (IType) binding))) {
binding= specialClass; binding= specialClass;
} else { } else {
binding= specialClass.specializeMember(binding, lookup.getLookupPoint()); binding= specialClass.specializeMember(binding);
} }
if (binding != null) if (binding != null)
result = ArrayUtil.appendAt(result, n++, binding); result = ArrayUtil.appendAt(result, n++, binding);
@ -153,7 +156,7 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
} }
@Override @Override
public ICPPBase[] getBases(IASTNode point) { public ICPPBase[] getBases() {
if (fBases == null) { if (fBases == null) {
if (fComputingBases.get()) { if (fComputingBases.get()) {
return ICPPBase.EMPTY_BASE_ARRAY; // avoid recursion return ICPPBase.EMPTY_BASE_ARRAY; // avoid recursion
@ -161,7 +164,7 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
fComputingBases.set(true); fComputingBases.set(true);
try { try {
ICPPBase[] result = ICPPBase.EMPTY_BASE_ARRAY; ICPPBase[] result = ICPPBase.EMPTY_BASE_ARRAY;
ICPPBase[] bases = ClassTypeHelper.getBases(specialClass.getSpecializedBinding(), point); ICPPBase[] bases = specialClass.getSpecializedBinding().getBases();
if (bases.length == 0) { if (bases.length == 0) {
fBases= bases; fBases= bases;
} else { } else {
@ -170,7 +173,7 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
IType baseType = base.getBaseClassType(); IType baseType = base.getBaseClassType();
if (baseType instanceof ICPPParameterPackType) { if (baseType instanceof ICPPParameterPackType) {
IType[] specClasses= CPPTemplates.instantiateTypes(new IType[] { baseType }, IType[] specClasses= CPPTemplates.instantiateTypes(new IType[] { baseType },
new InstantiationContext(tpmap, specialClass, point)); new InstantiationContext(tpmap, specialClass));
if (specClasses.length == 1 && specClasses[0] instanceof ICPPParameterPackType) { if (specClasses.length == 1 && specClasses[0] instanceof ICPPParameterPackType) {
result= ArrayUtil.append(result, base); result= ArrayUtil.append(result, base);
} else { } else {
@ -192,7 +195,7 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
specializationContext = (ICPPClassSpecialization) owner; specializationContext = (ICPPClassSpecialization) owner;
} }
IType specClass= CPPTemplates.instantiateType(baseType, IType specClass= CPPTemplates.instantiateType(baseType,
new InstantiationContext(tpmap, specializationContext, point)); new InstantiationContext(tpmap, specializationContext));
specClass = SemanticUtil.getUltimateType(specClass, false); specClass = SemanticUtil.getUltimateType(specClass, false);
if (specClass instanceof IBinding && !(specClass instanceof IProblemBinding)) { if (specClass instanceof IBinding && !(specClass instanceof IProblemBinding)) {
specBase.setBaseClass((IBinding) specClass); specBase.setBaseClass((IBinding) specClass);
@ -212,37 +215,31 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private <T extends IBinding> T[] specializeMembers(T[] array, IASTNode point) { private <T extends IBinding> T[] specializeMembers(T[] array) {
if (array == null || array.length == 0) if (array == null || array.length == 0)
return array; return array;
T[] newArray= array.clone(); T[] newArray= array.clone();
for (int i = 0; i < newArray.length; i++) { for (int i = 0; i < newArray.length; i++) {
IBinding specializedMember = specialClass.specializeMember(array[i], point); IBinding specializedMember = specialClass.specializeMember(array[i]);
newArray[i]= (T) specializedMember; newArray[i]= (T) specializedMember;
} }
return newArray; return newArray;
} }
@Override @Override
public ICPPField[] getDeclaredFields(IASTNode point) { public ICPPField[] getDeclaredFields() {
ICPPField[] fields= ClassTypeHelper.getDeclaredFields(specialClass.getSpecializedBinding(), point); ICPPField[] fields= specialClass.getSpecializedBinding().getDeclaredFields();
return specializeMembers(fields, point); return specializeMembers(fields);
} }
@Override @Override
public ICPPMethod[] getImplicitMethods() { public ICPPMethod[] getImplicitMethods() {
CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
return getImplicitMethods(null);
}
@Override
public ICPPMethod[] getImplicitMethods(IASTNode point) {
ICPPClassType origClass = specialClass.getSpecializedBinding(); ICPPClassType origClass = specialClass.getSpecializedBinding();
ICPPMethod[] methods= ClassTypeHelper.getImplicitMethods(origClass, point); ICPPMethod[] methods= ClassTypeHelper.getImplicitMethods(origClass);
ICPPMethod[] specializedMembers = specializeMembers(methods, point); ICPPMethod[] specializedMembers = specializeMembers(methods);
// Add inherited constructors. // Add inherited constructors.
ICPPMethod[] inheritedConstructors = getOwnInheritedConstructors(point); ICPPMethod[] inheritedConstructors = getOwnInheritedConstructors();
return ArrayUtil.addAll(specializedMembers, inheritedConstructors); return ArrayUtil.addAll(specializedMembers, inheritedConstructors);
} }
@ -255,16 +252,10 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
@Override @Override
public ICPPConstructor[] getConstructors() { public ICPPConstructor[] getConstructors() {
CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$ ICPPConstructor[] ctors= specialClass.getSpecializedBinding().getConstructors();
return getConstructors(null); ICPPConstructor[] specializedCtors = specializeMembers(ctors);
}
@Override
public ICPPConstructor[] getConstructors(IASTNode point) {
ICPPConstructor[] ctors= ClassTypeHelper.getConstructors(specialClass.getSpecializedBinding(), point);
ICPPConstructor[] specializedCtors = specializeMembers(ctors, point);
// Add inherited constructors. // Add inherited constructors.
ICPPMethod[] inheritedConstructors = getOwnInheritedConstructors(specializedCtors, point); ICPPMethod[] inheritedConstructors = getOwnInheritedConstructors(specializedCtors);
return ArrayUtil.addAll(specializedCtors, inheritedConstructors); return ArrayUtil.addAll(specializedCtors, inheritedConstructors);
} }
@ -272,10 +263,9 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
* Returns the inherited constructors that are not specializations of the inherited constructors * Returns the inherited constructors that are not specializations of the inherited constructors
* of the specialized class. * of the specialized class.
*/ */
private ICPPMethod[] getOwnInheritedConstructors(ICPPConstructor[] existingConstructors, private ICPPMethod[] getOwnInheritedConstructors(ICPPConstructor[] existingConstructors) {
IASTNode point) {
if (ownInheritedConstructors == null) { if (ownInheritedConstructors == null) {
if (!hasInheritedConstructorsSources(point)) if (!hasInheritedConstructorsSources())
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
IType[][] existingConstructorParamTypes = new IType[existingConstructors.length][]; IType[][] existingConstructorParamTypes = new IType[existingConstructors.length][];
@ -287,23 +277,23 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
} }
existingConstructorParamTypes[i] = types; existingConstructorParamTypes[i] = types;
} }
ICPPMethod[] constructors = ClassTypeHelper.getInheritedConstructors(this, getBases(point), ICPPMethod[] constructors = ClassTypeHelper.getInheritedConstructors(this, getBases(),
existingConstructorParamTypes, point); existingConstructorParamTypes);
ownInheritedConstructors = constructors; ownInheritedConstructors = constructors;
} }
return ownInheritedConstructors; return ownInheritedConstructors;
} }
private ICPPMethod[] getOwnInheritedConstructors(IASTNode point) { private ICPPMethod[] getOwnInheritedConstructors() {
if (ownInheritedConstructors != null) if (ownInheritedConstructors != null)
return ownInheritedConstructors; return ownInheritedConstructors;
ICPPConstructor[] ctors= ClassTypeHelper.getConstructors(specialClass.getSpecializedBinding(), point); ICPPConstructor[] ctors= specialClass.getSpecializedBinding().getConstructors();
ICPPConstructor[] specializedCtors = specializeMembers(ctors, point); ICPPConstructor[] specializedCtors = specializeMembers(ctors);
return getOwnInheritedConstructors(specializedCtors, point); return getOwnInheritedConstructors(specializedCtors);
} }
private boolean hasInheritedConstructorsSources(IASTNode point) { private boolean hasInheritedConstructorsSources() {
for (ICPPBase base : getBases(point)) { for (ICPPBase base : getBases()) {
if (base.isInheritedConstructorsSource()) if (base.isInheritedConstructorsSource())
return true; return true;
} }
@ -311,27 +301,27 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
} }
@Override @Override
public ICPPMethod[] getDeclaredMethods(IASTNode point) { public ICPPMethod[] getDeclaredMethods() {
ICPPMethod[] bindings = ClassTypeHelper.getDeclaredMethods(specialClass.getSpecializedBinding(), point); ICPPMethod[] bindings = specialClass.getSpecializedBinding().getDeclaredMethods();
return specializeMembers(bindings, point); return specializeMembers(bindings);
} }
@Override @Override
public ICPPClassType[] getNestedClasses(IASTNode point) { public ICPPClassType[] getNestedClasses() {
ICPPClassType[] bindings = ClassTypeHelper.getNestedClasses(specialClass.getSpecializedBinding(), point); ICPPClassType[] bindings = specialClass.getSpecializedBinding().getNestedClasses();
return specializeMembers(bindings, point); return specializeMembers(bindings);
} }
@Override @Override
public ICPPUsingDeclaration[] getUsingDeclarations(IASTNode point) { public ICPPUsingDeclaration[] getUsingDeclarations() {
ICPPUsingDeclaration[] bindings = ClassTypeHelper.getUsingDeclarations(specialClass.getSpecializedBinding(), point); ICPPUsingDeclaration[] bindings = specialClass.getSpecializedBinding().getUsingDeclarations();
return specializeMembers(bindings, point); return specializeMembers(bindings);
} }
@Override @Override
public IBinding[] getFriends(IASTNode point) { public IBinding[] getFriends() {
IBinding[] friends = ClassTypeHelper.getFriends(specialClass.getSpecializedBinding(), point); IBinding[] friends = specialClass.getSpecializedBinding().getFriends();
return specializeMembers(friends, point); return specializeMembers(friends);
} }
@Override @Override

View file

@ -28,6 +28,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinary; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinary;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
@ -132,8 +134,14 @@ public class CPPASTArraySubscriptExpression extends ASTNode
private ICPPFunction getOverload() { private ICPPFunction getOverload() {
ICPPEvaluation eval = getEvaluation(); ICPPEvaluation eval = getEvaluation();
if (eval instanceof EvalBinary) if (eval instanceof EvalBinary) {
return ((EvalBinary) eval).getOverload(this); CPPSemantics.pushLookupPoint(this);
try {
return ((EvalBinary) eval).getOverload();
} finally {
CPPSemantics.popLookupPoint();
}
}
return null; return null;
} }
@ -203,12 +211,12 @@ public class CPPASTArraySubscriptExpression extends ASTNode
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
return getEvaluation().getType(this); return CPPEvaluation.getType(this);
} }
@Override @Override
public ValueCategory getValueCategory() { public ValueCategory getValueCategory() {
return getEvaluation().getValueCategory(this); return CPPEvaluation.getValueCategory(this);
} }
@Override @Override

View file

@ -31,6 +31,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinary; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinary;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
@ -263,8 +265,14 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
@Override @Override
public ICPPFunction getOverload() { public ICPPFunction getOverload() {
ICPPEvaluation eval = getEvaluation(); ICPPEvaluation eval = getEvaluation();
if (eval instanceof EvalBinary) if (eval instanceof EvalBinary) {
return ((EvalBinary) eval).getOverload(this); CPPSemantics.pushLookupPoint(this);
try {
return ((EvalBinary) eval).getOverload();
} finally {
CPPSemantics.popLookupPoint();
}
}
return null; return null;
} }
@ -287,12 +295,12 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
return getEvaluation().getType(this); return CPPEvaluation.getType(this);
} }
@Override @Override
public ValueCategory getValueCategory() { public ValueCategory getValueCategory() {
return getEvaluation().getValueCategory(this); return CPPEvaluation.getValueCategory(this);
} }
@Override @Override

View file

@ -21,6 +21,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinaryTypeId; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinaryTypeId;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
@ -135,7 +136,7 @@ public class CPPASTBinaryTypeIdExpression extends ASTNode implements ICPPASTExpr
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
return getEvaluation().getType(this); return CPPEvaluation.getType(this);
} }
@Override @Override

View file

@ -25,6 +25,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
@ -172,12 +173,12 @@ public class CPPASTCastExpression extends ASTNode implements ICPPASTCastExpressi
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
return getEvaluation().getType(this); return CPPEvaluation.getType(this);
} }
@Override @Override
public ValueCategory getValueCategory() { public ValueCategory getValueCategory() {
return getEvaluation().getValueCategory(this); return CPPEvaluation.getValueCategory(this);
} }
@Override @Override

View file

@ -23,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression; import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalCompoundStatementExpression; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalCompoundStatementExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
@ -127,7 +128,7 @@ public class CPPASTCompoundStatementExpression extends ASTNode
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
return getEvaluation().getType(this); return CPPEvaluation.getType(this);
} }
@Override @Override

View file

@ -24,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalConditional; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalConditional;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
@ -191,12 +192,12 @@ public class CPPASTConditionalExpression extends ASTNode
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
return getEvaluation().getType(this); return CPPEvaluation.getType(this);
} }
@Override @Override
public ValueCategory getValueCategory() { public ValueCategory getValueCategory() {
return getEvaluation().getValueCategory(this); return CPPEvaluation.getValueCategory(this);
} }
@Override @Override

View file

@ -177,7 +177,7 @@ public class CPPASTConstructorChainInitializer extends ASTNode implements
IBinding method= fdef.getDeclarator().getName().resolveBinding(); IBinding method= fdef.getDeclarator().getName().resolveBinding();
if (method instanceof ICPPMethod) { if (method instanceof ICPPMethod) {
ICPPClassType cls= ((ICPPMethod) method).getClassOwner(); ICPPClassType cls= ((ICPPMethod) method).getClassOwner();
for (ICPPBase base : ClassTypeHelper.getBases(cls, fdef)) { for (ICPPBase base : cls.getBases()) {
IType baseType= base.getBaseClassType(); IType baseType= base.getBaseClassType();
if (baseType instanceof IBinding) if (baseType instanceof IBinding)
result.put(((IBinding) baseType).getNameCharArray()); result.put(((IBinding) baseType).getNameCharArray());

View file

@ -27,6 +27,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalComma; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalComma;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
@ -156,7 +158,12 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
private ICPPFunction[] getOverloads() { private ICPPFunction[] getOverloads() {
ICPPEvaluation eval = getEvaluation(); ICPPEvaluation eval = getEvaluation();
if (eval instanceof EvalComma) { if (eval instanceof EvalComma) {
return ((EvalComma) eval).getOverloads(this); CPPSemantics.pushLookupPoint(this);
try {
return ((EvalComma) eval).getOverloads();
} finally {
CPPSemantics.popLookupPoint();
}
} }
return null; return null;
} }
@ -195,12 +202,12 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
return getEvaluation().getType(this); return CPPEvaluation.getType(this);
} }
@Override @Override
public ValueCategory getValueCategory() { public ValueCategory getValueCategory() {
return getEvaluation().getValueCategory(this); return CPPEvaluation.getValueCategory(this);
} }
@Override @Override

View file

@ -46,6 +46,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPFunctionSet; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPFunctionSet;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
@ -146,25 +147,30 @@ public class CPPASTFieldReference extends ASTNode
if (!fIsDeref) if (!fIsDeref)
return fImplicitNames = IASTImplicitName.EMPTY_NAME_ARRAY; return fImplicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
// Collect the function bindings CPPSemantics.pushLookupPoint(this);
List<ICPPFunction> functionBindings = new ArrayList<>(); try {
EvalMemberAccess.getFieldOwnerType(fOwner.getExpressionType(), fIsDeref, this, functionBindings, false); // Collect the function bindings
if (functionBindings.isEmpty()) List<ICPPFunction> functionBindings = new ArrayList<>();
return fImplicitNames = IASTImplicitName.EMPTY_NAME_ARRAY; EvalMemberAccess.getFieldOwnerType(fOwner.getExpressionType(), fIsDeref, functionBindings, false);
if (functionBindings.isEmpty())
// Create a name to wrap each binding return fImplicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
fImplicitNames = new IASTImplicitName[functionBindings.size()];
int i = -1; // Create a name to wrap each binding
for (ICPPFunction op : functionBindings) { fImplicitNames = new IASTImplicitName[functionBindings.size()];
if (op != null && !(op instanceof CPPImplicitFunction)) { int i = -1;
CPPASTImplicitName operatorName = new CPPASTImplicitName(OverloadableOperator.ARROW, for (ICPPFunction op : functionBindings) {
this); if (op != null && !(op instanceof CPPImplicitFunction)) {
operatorName.setBinding(op); CPPASTImplicitName operatorName = new CPPASTImplicitName(OverloadableOperator.ARROW,
operatorName.computeOperatorOffsets(fOwner, true); this);
fImplicitNames[++i] = operatorName; operatorName.setBinding(op);
operatorName.computeOperatorOffsets(fOwner, true);
fImplicitNames[++i] = operatorName;
}
} }
} fImplicitNames = ArrayUtil.trimAt(IASTImplicitName.class, fImplicitNames, i);
fImplicitNames = ArrayUtil.trimAt(IASTImplicitName.class, fImplicitNames, i); } finally {
CPPSemantics.popLookupPoint();
}
} }
return fImplicitNames; return fImplicitNames;
@ -269,7 +275,7 @@ public class CPPASTFieldReference extends ASTNode
*/ */
@Override @Override
public IType getFieldOwnerType() { public IType getFieldOwnerType() {
return EvalMemberAccess.getFieldOwnerType(fOwner.getExpressionType(), fIsDeref, this, null, true); return EvalMemberAccess.getFieldOwnerType(fOwner.getExpressionType(), fIsDeref, null, true);
} }
@Override @Override
@ -283,7 +289,7 @@ public class CPPASTFieldReference extends ASTNode
private ICPPEvaluation createEvaluation() { private ICPPEvaluation createEvaluation() {
ICPPEvaluation ownerEval = fOwner.getEvaluation(); ICPPEvaluation ownerEval = fOwner.getEvaluation();
if (!ownerEval.isTypeDependent()) { if (!ownerEval.isTypeDependent()) {
IType ownerType= EvalMemberAccess.getFieldOwnerType(ownerEval.getType(this), fIsDeref, this, null, false); IType ownerType= EvalMemberAccess.getFieldOwnerType(ownerEval.getType(), fIsDeref, null, false);
if (ownerType != null) { if (ownerType != null) {
IBinding binding = fName.resolvePreBinding(); IBinding binding = fName.resolvePreBinding();
if (binding instanceof CPPFunctionSet) if (binding instanceof CPPFunctionSet)
@ -293,7 +299,7 @@ public class CPPASTFieldReference extends ASTNode
return EvalFixed.INCOMPLETE; return EvalFixed.INCOMPLETE;
} }
return new EvalMemberAccess(ownerType, ownerEval.getValueCategory(this), binding, ownerEval, fIsDeref, this); return new EvalMemberAccess(ownerType, ownerEval.getValueCategory(), binding, ownerEval, fIsDeref, this);
} }
} }
@ -325,10 +331,10 @@ public class CPPASTFieldReference extends ASTNode
if (ownerType == null) { if (ownerType == null) {
return -1; return -1;
} }
final ICPPClassType[] baseClasses = ClassTypeHelper.getAllBases(ownerType, null); final ICPPClassType[] baseClasses = ClassTypeHelper.getAllBases(ownerType);
int baseFields = 0; int baseFields = 0;
for (ICPPClassType baseClass : baseClasses) { for (ICPPClassType baseClass : baseClasses) {
baseFields += ClassTypeHelper.getDeclaredFields(baseClass, null).length; baseFields += baseClass.getDeclaredFields().length;
} }
return baseFields + field.getFieldPosition(); return baseFields + field.getFieldPosition();
} }
@ -344,7 +350,7 @@ public class CPPASTFieldReference extends ASTNode
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
return getEvaluation().getType(this); return CPPEvaluation.getType(this);
} }
@Override @Override
@ -354,6 +360,6 @@ public class CPPASTFieldReference extends ASTNode
@Override @Override
public ValueCategory getValueCategory() { public ValueCategory getValueCategory() {
return getEvaluation().getValueCategory(this); return CPPEvaluation.getValueCategory(this);
} }
} }

View file

@ -42,6 +42,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
@ -242,27 +243,32 @@ public class CPPASTFunctionCallExpression extends ASTNode
@Override @Override
public ICPPFunction getOverload() { public ICPPFunction getOverload() {
ICPPEvaluation eval = getEvaluation(); CPPSemantics.pushLookupPoint(this);
if (eval instanceof EvalFunctionCall) try {
return ((EvalFunctionCall) eval).getOverload(this); ICPPEvaluation eval = getEvaluation();
if (eval instanceof EvalFunctionCall)
if (eval instanceof EvalTypeId) { return ((EvalFunctionCall) eval).getOverload();
if (!eval.isTypeDependent()) {
IType t= getNestedType(((EvalTypeId) eval).getInputType(), TDEF | CVTYPE | REF); if (eval instanceof EvalTypeId) {
if (t instanceof ICPPClassType && !(t instanceof ICPPUnknownBinding)) { if (!eval.isTypeDependent()) {
ICPPClassType cls= (ICPPClassType) t; IType t= getNestedType(((EvalTypeId) eval).getInputType(), TDEF | CVTYPE | REF);
LookupData data= CPPSemantics.createLookupData(((IASTIdExpression) fFunctionName).getName()); if (t instanceof ICPPClassType && !(t instanceof ICPPUnknownBinding)) {
try { ICPPClassType cls= (ICPPClassType) t;
ICPPConstructor[] constructors = ClassTypeHelper.getConstructors(cls, data.getLookupPoint()); LookupData data= CPPSemantics.createLookupData(((IASTIdExpression) fFunctionName).getName());
IBinding b= CPPSemantics.resolveFunction(data, constructors, true, false); try {
if (b instanceof ICPPFunction) ICPPConstructor[] constructors = cls.getConstructors();
return (ICPPFunction) b; IBinding b= CPPSemantics.resolveFunction(data, constructors, true, false);
} catch (DOMException e) { if (b instanceof ICPPFunction)
return (ICPPFunction) b;
} catch (DOMException e) {
}
} }
} }
} }
return null;
} finally {
CPPSemantics.popLookupPoint();
} }
return null;
} }
@Override @Override
@ -313,12 +319,12 @@ public class CPPASTFunctionCallExpression extends ASTNode
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
return getEvaluation().getType(this); return CPPEvaluation.getType(this);
} }
@Override @Override
public ValueCategory getValueCategory() { public ValueCategory getValueCategory() {
return getEvaluation().getValueCategory(this); return CPPEvaluation.getValueCategory(this);
} }
@Override @Override

View file

@ -36,6 +36,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
/** /**
* Models a function definition without a try-block. If used for a constructor definition * Models a function definition without a try-block. If used for a constructor definition
@ -255,36 +256,41 @@ public class CPPASTFunctionDefinition extends CPPASTAttributeOwner
IASTName functionName = ASTQueries.findInnermostDeclarator(declarator).getName(); IASTName functionName = ASTQueries.findInnermostDeclarator(declarator).getName();
IBinding function = functionName.resolveBinding(); IBinding function = functionName.resolveBinding();
if (function instanceof ICPPConstructor) { if (function instanceof ICPPConstructor) {
ICPPClassType classOwner = ((ICPPConstructor) function).getClassOwner(); CPPSemantics.pushLookupPoint(this);
try {
// Determine the bases of 'classOwner' that need to be initialized by this constructor. ICPPClassType classOwner = ((ICPPConstructor) function).getClassOwner();
Set<ICPPClassType> basesThatNeedInitialization = new HashSet<>();
for (ICPPBase base : ClassTypeHelper.getBases(classOwner, this)) { // Determine the bases of 'classOwner' that need to be initialized by this constructor.
IType baseType = base.getBaseClassType(); Set<ICPPClassType> basesThatNeedInitialization = new HashSet<>();
if (baseType instanceof ICPPClassType) { for (ICPPBase base : classOwner.getBases()) {
basesThatNeedInitialization.add((ICPPClassType) baseType); IType baseType = base.getBaseClassType();
if (baseType instanceof ICPPClassType) {
basesThatNeedInitialization.add((ICPPClassType) baseType);
}
} }
} for (ICPPClassType virtualBase : ClassTypeHelper.getVirtualBases(classOwner)) {
for (ICPPClassType virtualBase : ClassTypeHelper.getVirtualBases(classOwner, this)) { basesThatNeedInitialization.add(virtualBase);
basesThatNeedInitialization.add(virtualBase); }
}
// Go through the bases determined above, and see which ones aren't initialized
// Go through the bases determined above, and see which ones aren't initialized // explicitly in the mem-initializer list.
// explicitly in the mem-initializer list. for (ICPPClassType base : basesThatNeedInitialization) {
for (ICPPClassType base : basesThatNeedInitialization) { if (!isInitializedExplicitly(base)) {
if (!isInitializedExplicitly(base)) { // Try to find a default constructor to create an implicit name for.
// Try to find a default constructor to create an implicit name for. for (ICPPConstructor constructor : base.getConstructors()) {
for (ICPPConstructor constructor : ClassTypeHelper.getConstructors(base, this)) { if (constructor.getRequiredArgumentCount() == 0) { // default constructor
if (constructor.getRequiredArgumentCount() == 0) { // default constructor CPPASTImplicitName ctorName = new CPPASTImplicitName(
CPPASTImplicitName ctorName = new CPPASTImplicitName( constructor.getNameCharArray(), this);
constructor.getNameCharArray(), this); ctorName.setBinding(constructor);
ctorName.setBinding(constructor); ctorName.setOffsetAndLength((ASTNode) functionName);
ctorName.setOffsetAndLength((ASTNode) functionName); implicitNames = ArrayUtil.append(implicitNames, ctorName);
implicitNames = ArrayUtil.append(implicitNames, ctorName); break;
break; }
} }
} }
} }
} finally {
CPPSemantics.popLookupPoint();
} }
} }
implicitNames = ArrayUtil.trim(implicitNames); implicitNames = ArrayUtil.trim(implicitNames);

View file

@ -26,6 +26,7 @@ import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalID; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalID;
@ -137,15 +138,20 @@ public class CPPASTIdExpression extends ASTNode
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
IType type= getEvaluation().getType(this); CPPSemantics.pushLookupPoint(this);
if (type instanceof FunctionSetType) { try {
IBinding binding= fName.resolveBinding(); IType type= getEvaluation().getType();
if (binding instanceof IFunction) { if (type instanceof FunctionSetType) {
return SemanticUtil.mapToAST(((IFunction) binding).getType(), this); IBinding binding= fName.resolveBinding();
if (binding instanceof IFunction) {
return SemanticUtil.mapToAST(((IFunction) binding).getType());
}
return ProblemType.UNKNOWN_FOR_EXPRESSION;
} }
return ProblemType.UNKNOWN_FOR_EXPRESSION; return type;
} finally {
CPPSemantics.popLookupPoint();
} }
return type;
} }
@Override @Override
@ -155,6 +161,6 @@ public class CPPASTIdExpression extends ASTNode
@Override @Override
public ValueCategory getValueCategory() { public ValueCategory getValueCategory() {
return getEvaluation().getValueCategory(this); return CPPEvaluation.getValueCategory(this);
} }
} }

View file

@ -24,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue; import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
/** /**
@ -243,7 +244,7 @@ public class CPPASTLambdaExpression extends ASTNode implements ICPPASTLambdaExpr
@Override @Override
public CPPClosureType getExpressionType() { public CPPClosureType getExpressionType() {
return (CPPClosureType) getEvaluation().getType(this); return (CPPClosureType) CPPEvaluation.getType(this);
} }
@Override @Override

View file

@ -38,6 +38,7 @@ import org.eclipse.cdt.internal.core.dom.parser.FloatingPointValue;
import org.eclipse.cdt.internal.core.dom.parser.IntegralValue; import org.eclipse.cdt.internal.core.dom.parser.IntegralValue;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; 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.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinding;
@ -749,7 +750,7 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
return getEvaluation().getType(this); return CPPEvaluation.getType(this);
} }
@Override @Override

View file

@ -59,7 +59,12 @@ public class CPPASTName extends CPPASTNameBase implements ICPPASTCompletionConte
@Override @Override
protected IBinding createIntermediateBinding() { protected IBinding createIntermediateBinding() {
return CPPVisitor.createBinding(this); CPPSemantics.pushLookupPoint(this);
try {
return CPPVisitor.createBinding(this);
} finally {
CPPSemantics.popLookupPoint();
}
} }
@Override @Override

View file

@ -40,6 +40,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.c.CASTExpressionList; import org.eclipse.cdt.internal.core.dom.parser.c.CASTExpressionList;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
@ -304,7 +305,7 @@ public class CPPASTNewExpression extends ASTNode implements ICPPASTNewExpression
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
return getEvaluation().getType(this); return CPPEvaluation.getType(this);
} }
@Override @Override

View file

@ -21,6 +21,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPackExpansionExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPackExpansionExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalParameterPack; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalParameterPack;
/** /**
@ -71,7 +72,7 @@ public class CPPASTPackExpansionExpression extends ASTNode implements ICPPASTPac
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
return getEvaluation().getType(this); return CPPEvaluation.getType(this);
} }
@Override @Override

View file

@ -20,6 +20,7 @@ import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.dom.ast.IASTProblemExpression; import org.eclipse.cdt.core.dom.ast.IASTProblemExpression;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
public class CPPASTProblemExpression extends CPPASTProblemOwner implements IASTProblemExpression, ICPPASTExpression { public class CPPASTProblemExpression extends CPPASTProblemOwner implements IASTProblemExpression, ICPPASTExpression {
@ -75,7 +76,7 @@ public class CPPASTProblemExpression extends CPPASTProblemOwner implements IASTP
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
return getEvaluation().getType(this); return CPPEvaluation.getType(this);
} }
@Override @Override
@ -85,6 +86,6 @@ public class CPPASTProblemExpression extends CPPASTProblemOwner implements IASTP
@Override @Override
public ValueCategory getValueCategory() { public ValueCategory getValueCategory() {
return getEvaluation().getValueCategory(this); return CPPEvaluation.getValueCategory(this);
} }
} }

View file

@ -323,7 +323,7 @@ public class CPPASTQualifiedName extends CPPASTNameBase
List<IBinding> filtered = filterClassScopeBindings(classQualifier, bindings, isDeclaration); List<IBinding> filtered = filterClassScopeBindings(classQualifier, bindings, isDeclaration);
if ((isDeclaration || isUsingDecl) && nameMatches(classQualifier.getNameCharArray(), if ((isDeclaration || isUsingDecl) && nameMatches(classQualifier.getNameCharArray(),
n.getLookupKey(), isPrefix)) { n.getLookupKey(), isPrefix)) {
ICPPConstructor[] constructors = ClassTypeHelper.getConstructors(classQualifier, n); ICPPConstructor[] constructors = classQualifier.getConstructors();
for (int i = 0; i < constructors.length; i++) { for (int i = 0; i < constructors.length; i++) {
if (!constructors[i].isImplicit()) { if (!constructors[i].isImplicit()) {
filtered.add(constructors[i]); filtered.add(constructors[i]);
@ -359,7 +359,7 @@ public class CPPASTQualifiedName extends CPPASTNameBase
while (scope != null) { while (scope != null) {
if (scope instanceof ICPPClassScope) { if (scope instanceof ICPPClassScope) {
ICPPClassType classType = ((ICPPClassScope) scope).getClassType(); ICPPClassType classType = ((ICPPClassScope) scope).getClassType();
if (SemanticUtil.calculateInheritanceDepth(classType, baseClass, this) >= 0) { if (SemanticUtil.calculateInheritanceDepth(classType, baseClass) >= 0) {
return true; return true;
} }
} }

View file

@ -27,6 +27,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalConstructor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalConstructor;
@ -109,12 +111,12 @@ public class CPPASTSimpleTypeConstructorExpression extends ASTNode
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
return getEvaluation().getType(this); return CPPEvaluation.getType(this);
} }
@Override @Override
public ValueCategory getValueCategory() { public ValueCategory getValueCategory() {
return getEvaluation().getValueCategory(this); return CPPEvaluation.getValueCategory(this);
} }
@Override @Override
@ -277,12 +279,17 @@ public class CPPASTSimpleTypeConstructorExpression extends ASTNode
fImplicitNames = IASTImplicitName.EMPTY_NAME_ARRAY; fImplicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
ICPPEvaluation eval = getEvaluation(); ICPPEvaluation eval = getEvaluation();
if (eval instanceof EvalTypeId) { if (eval instanceof EvalTypeId) {
ICPPFunction constructor = ((EvalTypeId) eval).getConstructor(this); CPPSemantics.pushLookupPoint(this);
if (constructor != null && constructor != EvalTypeId.AGGREGATE_INITIALIZATION) { try {
CPPASTImplicitName name = new CPPASTImplicitName(constructor.getNameCharArray(), this); ICPPFunction constructor = ((EvalTypeId) eval).getConstructor();
name.setOffsetAndLength((ASTNode) fDeclSpec); if (constructor != null && constructor != EvalTypeId.AGGREGATE_INITIALIZATION) {
name.setBinding(constructor); CPPASTImplicitName name = new CPPASTImplicitName(constructor.getNameCharArray(), this);
fImplicitNames = new IASTImplicitName[] { name }; name.setOffsetAndLength((ASTNode) fDeclSpec);
name.setBinding(constructor);
fImplicitNames = new IASTImplicitName[] { name };
}
} finally {
CPPSemantics.popLookupPoint();
} }
} }
} }

View file

@ -191,12 +191,11 @@ public class CPPASTTranslationUnit extends ASTTranslationUnit implements ICPPAST
* Maps a class type to the AST. * Maps a class type to the AST.
* *
* @param binding a class type, possibly from index * @param binding a class type, possibly from index
* @param point a lookup point in the AST
* @return the corresponding class in the AST, or the original class type if it doesn't have * @return the corresponding class in the AST, or the original class type if it doesn't have
* a counterpart in the AST. * a counterpart in the AST.
*/ */
public ICPPClassType mapToAST(ICPPClassType binding, IASTNode point) { public ICPPClassType mapToAST(ICPPClassType binding) {
return fScopeMapper.mapToAST(binding, point); return fScopeMapper.mapToAST(binding);
} }
/** /**

View file

@ -20,6 +20,7 @@ import org.eclipse.cdt.core.dom.ast.IProblemType;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeIdExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeIdExpression;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUnaryTypeID; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUnaryTypeID;
@ -117,12 +118,12 @@ public class CPPASTTypeIdExpression extends ASTNode implements ICPPASTTypeIdExpr
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
return getEvaluation().getType(this); return CPPEvaluation.getType(this);
} }
@Override @Override
public ValueCategory getValueCategory() { public ValueCategory getValueCategory() {
return getEvaluation().getValueCategory(this); return CPPEvaluation.getValueCategory(this);
} }
@Override @Override

View file

@ -23,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
@ -151,11 +152,11 @@ public class CPPASTTypeIdInitializerExpression extends ASTNode
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
return getEvaluation().getType(this); return CPPEvaluation.getType(this);
} }
@Override @Override
public ValueCategory getValueCategory() { public ValueCategory getValueCategory() {
return getEvaluation().getValueCategory(this); return CPPEvaluation.getValueCategory(this);
} }
} }

View file

@ -33,6 +33,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.DestructorCallCollector;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUnary; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUnary;
@ -179,8 +181,14 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
@Override @Override
public ICPPFunction getOverload() { public ICPPFunction getOverload() {
ICPPEvaluation eval = getEvaluation(); ICPPEvaluation eval = getEvaluation();
if (eval instanceof EvalUnary) if (eval instanceof EvalUnary) {
return ((EvalUnary) eval).getOverload(this); CPPSemantics.pushLookupPoint(this);
try {
return ((EvalUnary) eval).getOverload();
} finally {
CPPSemantics.popLookupPoint();
}
}
return null; return null;
} }
@ -218,7 +226,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {
IType type= getEvaluation().getType(this); IType type= CPPEvaluation.getType(this);
if (type instanceof FunctionSetType) { if (type instanceof FunctionSetType) {
type= fOperand.getExpressionType(); type= fOperand.getExpressionType();
if (fOperator == op_amper) { if (fOperator == op_amper) {
@ -243,7 +251,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
@Override @Override
public ValueCategory getValueCategory() { public ValueCategory getValueCategory() {
return getEvaluation().getValueCategory(this); return CPPEvaluation.getValueCategory(this);
} }
@Override @Override

View file

@ -151,7 +151,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
* Marks bases that serve as sources of inherited constructors. * Marks bases that serve as sources of inherited constructors.
*/ */
private void markInheritedConstructorsSourceBases(ICPPASTCompositeTypeSpecifier compositeTypeSpec) { private void markInheritedConstructorsSourceBases(ICPPASTCompositeTypeSpecifier compositeTypeSpec) {
ICPPBase[] bases = ClassTypeHelper.getBases(getClassType(), compositeTypeSpec); ICPPBase[] bases = getClassType().getBases();
if (bases.length == 0) if (bases.length == 0)
return; return;
IASTDeclaration[] members = compositeTypeSpec.getMembers(); IASTDeclaration[] members = compositeTypeSpec.getMembers();

View file

@ -17,7 +17,6 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
@ -49,6 +48,7 @@ import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.IRecursionResolvingBinding; import org.eclipse.cdt.internal.core.dom.parser.IRecursionResolvingBinding;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.ProblemFunctionType; import org.eclipse.cdt.internal.core.dom.parser.ProblemFunctionType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.Assert;
@ -59,7 +59,8 @@ public class CPPClassSpecialization extends CPPSpecialization
implements ICPPClassSpecialization, ICPPInternalClassTypeMixinHost { implements ICPPClassSpecialization, ICPPInternalClassTypeMixinHost {
public static class RecursionResolvingBinding extends ProblemBinding implements ICPPMember, IRecursionResolvingBinding { public static class RecursionResolvingBinding extends ProblemBinding implements ICPPMember, IRecursionResolvingBinding {
public static RecursionResolvingBinding createFor(IBinding original, IASTNode point) { public static RecursionResolvingBinding createFor(IBinding original) {
IASTNode point = CPPSemantics.getCurrentLookupPoint();
if (original instanceof ICPPMethod) if (original instanceof ICPPMethod)
return new RecursionResolvingMethod(point, original.getNameCharArray()); return new RecursionResolvingMethod(point, original.getNameCharArray());
if (original instanceof ICPPField) if (original instanceof ICPPField)
@ -177,11 +178,6 @@ public class CPPClassSpecialization extends CPPSpecialization
@Override @Override
public IBinding specializeMember(IBinding original) { public IBinding specializeMember(IBinding original) {
return specializeMember(original, null);
}
@Override
public IBinding specializeMember(IBinding original, IASTNode point) {
synchronized (this) { synchronized (this) {
IBinding result= (IBinding) specializationMap.get(original); IBinding result= (IBinding) specializationMap.get(original);
if (result != null) if (result != null)
@ -191,10 +187,10 @@ public class CPPClassSpecialization extends CPPSpecialization
IBinding result; IBinding result;
Set<IBinding> recursionProtectionSet= fInProgress.get(); Set<IBinding> recursionProtectionSet= fInProgress.get();
if (!recursionProtectionSet.add(original)) if (!recursionProtectionSet.add(original))
return RecursionResolvingBinding.createFor(original, point); return RecursionResolvingBinding.createFor(original);
try { try {
result= CPPTemplates.createSpecialization(this, original, point); result= CPPTemplates.createSpecialization(this, original);
} finally { } finally {
recursionProtectionSet.remove(original); recursionProtectionSet.remove(original);
} }
@ -210,6 +206,11 @@ public class CPPClassSpecialization extends CPPSpecialization
} }
} }
@Override
public IBinding specializeMember(IBinding original, IASTNode point) {
return specializeMember(original);
}
@Override @Override
public void checkForDefinition() { public void checkForDefinition() {
// Ambiguity resolution ensures that declarations and definitions are resolved. // Ambiguity resolution ensures that declarations and definitions are resolved.
@ -230,12 +231,6 @@ public class CPPClassSpecialization extends CPPSpecialization
@Override @Override
public ICPPBase[] getBases() { public ICPPBase[] getBases() {
CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
return getBases(null);
}
@Override
public ICPPBase[] getBases(IASTNode point) {
ICPPClassSpecializationScope scope= getSpecializationScope(); ICPPClassSpecializationScope scope= getSpecializationScope();
if (scope == null) { if (scope == null) {
if (bases == null) { if (bases == null) {
@ -244,108 +239,114 @@ public class CPPClassSpecialization extends CPPSpecialization
return bases; return bases;
} }
return scope.getBases(point); return scope.getBases();
}
@Override
@Deprecated
public ICPPBase[] getBases(IASTNode point) {
return getBases();
} }
@Override @Override
public ICPPField[] getDeclaredFields() { public ICPPField[] getDeclaredFields() {
CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
return getDeclaredFields(null);
}
@Override
public ICPPField[] getDeclaredFields(IASTNode point) {
ICPPClassSpecializationScope scope= getSpecializationScope(); ICPPClassSpecializationScope scope= getSpecializationScope();
if (scope == null) if (scope == null)
return ClassTypeHelper.getDeclaredFields(this); return ClassTypeHelper.getDeclaredFields(this);
return scope.getDeclaredFields(point); return scope.getDeclaredFields();
}
@Override
@Deprecated
public ICPPField[] getDeclaredFields(IASTNode point) {
return getDeclaredFields();
} }
@Override @Override
public ICPPMethod[] getDeclaredMethods() { public ICPPMethod[] getDeclaredMethods() {
CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
return getDeclaredMethods(null);
}
@Override
public ICPPMethod[] getDeclaredMethods(IASTNode point) {
ICPPClassSpecializationScope scope= getSpecializationScope(); ICPPClassSpecializationScope scope= getSpecializationScope();
if (scope == null) if (scope == null)
return ClassTypeHelper.getDeclaredMethods(this); return ClassTypeHelper.getDeclaredMethods(this);
return scope.getDeclaredMethods(point); return scope.getDeclaredMethods();
}
@Override
@Deprecated
public ICPPMethod[] getDeclaredMethods(IASTNode point) {
return getDeclaredMethods();
} }
@Override @Override
public ICPPConstructor[] getConstructors() { public ICPPConstructor[] getConstructors() {
CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
return getConstructors(null);
}
@Override
public ICPPConstructor[] getConstructors(IASTNode point) {
ICPPClassSpecializationScope scope= getSpecializationScope(); ICPPClassSpecializationScope scope= getSpecializationScope();
if (scope == null) if (scope == null)
return ClassTypeHelper.getConstructors(this); return ClassTypeHelper.getConstructors(this);
return scope.getConstructors(point); return scope.getConstructors();
}
@Override
@Deprecated
public ICPPConstructor[] getConstructors(IASTNode point) {
return getConstructors();
} }
@Override @Override
public IBinding[] getFriends() { public IBinding[] getFriends() {
CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
return getFriends(null);
}
@Override
public IBinding[] getFriends(IASTNode point) {
ICPPClassSpecializationScope scope= getSpecializationScope(); ICPPClassSpecializationScope scope= getSpecializationScope();
if (scope == null) if (scope == null)
return ClassTypeHelper.getFriends(this); return ClassTypeHelper.getFriends(this);
return scope.getFriends(point); return scope.getFriends();
}
@Override
@Deprecated
public IBinding[] getFriends(IASTNode point) {
return getFriends();
} }
@Override @Override
public ICPPClassType[] getNestedClasses() { public ICPPClassType[] getNestedClasses() {
CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
return getNestedClasses(null);
}
@Override
public ICPPClassType[] getNestedClasses(IASTNode point) {
ICPPClassSpecializationScope scope= getSpecializationScope(); ICPPClassSpecializationScope scope= getSpecializationScope();
if (scope == null) if (scope == null)
return ClassTypeHelper.getNestedClasses(this); return ClassTypeHelper.getNestedClasses(this);
return scope.getNestedClasses(point); return scope.getNestedClasses();
}
@Override
@Deprecated
public ICPPClassType[] getNestedClasses(IASTNode point) {
return getNestedClasses();
} }
@Override @Override
public ICPPUsingDeclaration[] getUsingDeclarations() { 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(); ICPPClassSpecializationScope scope = getSpecializationScope();
if (scope == null) if (scope == null)
return ClassTypeHelper.getUsingDeclarations(this); return ClassTypeHelper.getUsingDeclarations(this);
return scope.getUsingDeclarations(point); return scope.getUsingDeclarations();
}
@Override
@Deprecated
public ICPPUsingDeclaration[] getUsingDeclarations(IASTNode point) {
return getUsingDeclarations();
} }
@Override @Override
public IField[] getFields() { public IField[] getFields() {
CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$ return ClassTypeHelper.getFields(this);
return getFields(null);
} }
@Override @Override
@Deprecated
public IField[] getFields(IASTNode point) { public IField[] getFields(IASTNode point) {
return ClassTypeHelper.getFields(this, point); return getFields();
} }
@Override @Override
@ -355,24 +356,24 @@ public class CPPClassSpecialization extends CPPSpecialization
@Override @Override
public ICPPMethod[] getMethods() { public ICPPMethod[] getMethods() {
CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$ return ClassTypeHelper.getMethods(this);
return getMethods(null);
} }
@Override @Override
@Deprecated
public ICPPMethod[] getMethods(IASTNode point) { public ICPPMethod[] getMethods(IASTNode point) {
return ClassTypeHelper.getMethods(this, point); return getMethods();
} }
@Override @Override
public ICPPMethod[] getAllDeclaredMethods() { public ICPPMethod[] getAllDeclaredMethods() {
CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$ return ClassTypeHelper.getAllDeclaredMethods(this);
return getAllDeclaredMethods(null);
} }
@Override @Override
@Deprecated
public ICPPMethod[] getAllDeclaredMethods(IASTNode point) { public ICPPMethod[] getAllDeclaredMethods(IASTNode point) {
return ClassTypeHelper.getAllDeclaredMethods(this, point); return getAllDeclaredMethods();
} }
@Override @Override

View file

@ -165,7 +165,7 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements ICPPClass
@Override @Override
public IField[] getFields() { public IField[] getFields() {
return ClassTypeHelper.getFields(this, null); return ClassTypeHelper.getFields(this);
} }
@Override @Override
@ -175,12 +175,12 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements ICPPClass
@Override @Override
public ICPPMethod[] getMethods() { public ICPPMethod[] getMethods() {
return ClassTypeHelper.getMethods(this, null); return ClassTypeHelper.getMethods(this);
} }
@Override @Override
public ICPPMethod[] getAllDeclaredMethods() { public ICPPMethod[] getAllDeclaredMethods() {
return ClassTypeHelper.getAllDeclaredMethods(this, null); return ClassTypeHelper.getAllDeclaredMethods(this);
} }
@Override @Override

View file

@ -15,7 +15,6 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
@ -49,13 +48,12 @@ public class CPPClassTemplateSpecialization extends CPPClassSpecialization
@Override @Override
public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() { public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() {
if (fPartialSpecs == null) { if (fPartialSpecs == null) {
IASTNode point= null; // Instantiation of dependent expressions may not work.
ICPPClassTemplate origTemplate= getSpecializedBinding(); ICPPClassTemplate origTemplate= getSpecializedBinding();
ICPPClassTemplatePartialSpecialization[] orig = origTemplate.getPartialSpecializations(); ICPPClassTemplatePartialSpecialization[] orig = origTemplate.getPartialSpecializations();
ICPPClassTemplatePartialSpecialization[] spec = new ICPPClassTemplatePartialSpecialization[orig.length]; ICPPClassTemplatePartialSpecialization[] spec = new ICPPClassTemplatePartialSpecialization[orig.length];
ICPPClassSpecialization owner = getOwner(); ICPPClassSpecialization owner = getOwner();
for (int i = 0; i < orig.length; i++) { for (int i = 0; i < orig.length; i++) {
spec[i]= (ICPPClassTemplatePartialSpecialization) owner.specializeMember(orig[i], point); spec[i]= (ICPPClassTemplatePartialSpecialization) owner.specializeMember(orig[i]);
} }
fPartialSpecs = spec; fPartialSpecs = spec;
} }

View file

@ -336,7 +336,7 @@ public class CPPClassType extends PlatformObject implements ICPPInternalClassTyp
@Override @Override
public IField[] getFields() { public IField[] getFields() {
return ClassTypeHelper.getFields(this, null); return ClassTypeHelper.getFields(this);
} }
@Override @Override
@ -346,12 +346,12 @@ public class CPPClassType extends PlatformObject implements ICPPInternalClassTyp
@Override @Override
public ICPPMethod[] getMethods() { public ICPPMethod[] getMethods() {
return ClassTypeHelper.getMethods(this, null); return ClassTypeHelper.getMethods(this);
} }
@Override @Override
public ICPPMethod[] getAllDeclaredMethods() { public ICPPMethod[] getAllDeclaredMethods() {
return ClassTypeHelper.getAllDeclaredMethods(this, null); return ClassTypeHelper.getAllDeclaredMethods(this);
} }
@Override @Override

View file

@ -34,16 +34,20 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecConstructorChain; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecConstructorChain;
public class CPPConstructor extends CPPMethod implements ICPPConstructor { public class CPPConstructor extends CPPMethod implements ICPPConstructor {
public CPPConstructor(ICPPASTFunctionDeclarator declarator) { public CPPConstructor(ICPPASTFunctionDeclarator declarator) {
super(declarator); super(declarator);
} }
@Override @Override
public ICPPExecution getConstructorChainExecution(IASTNode point) { public ICPPExecution getConstructorChainExecution() {
return getConstructorChainExecution(this); return getConstructorChainExecution(this);
} }
@Override
public ICPPExecution getConstructorChainExecution(IASTNode point) {
return getConstructorChainExecution();
}
private static ICPPEvaluation getMemberEvaluation(ICPPField member, ICPPASTConstructorChainInitializer chainInitializer, IASTNode point) { private static ICPPEvaluation getMemberEvaluation(ICPPField member, ICPPASTConstructorChainInitializer chainInitializer, IASTNode point) {
final IASTInitializer initializer = chainInitializer.getInitializer(); final IASTInitializer initializer = chainInitializer.getInitializer();
if (initializer instanceof ICPPASTInitializerClause) { if (initializer instanceof ICPPASTInitializerClause) {

View file

@ -24,14 +24,18 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
* Instantiation of a constructor template * Instantiation of a constructor template
*/ */
public class CPPConstructorInstance extends CPPMethodInstance implements ICPPConstructorSpecialization { public class CPPConstructorInstance extends CPPMethodInstance implements ICPPConstructorSpecialization {
public CPPConstructorInstance(ICPPConstructor orig, ICPPClassType owner, ICPPTemplateParameterMap tpmap, public CPPConstructorInstance(ICPPConstructor orig, ICPPClassType owner, ICPPTemplateParameterMap tpmap,
ICPPTemplateArgument[] args, ICPPFunctionType type, IType[] exceptionSpec) { ICPPTemplateArgument[] args, ICPPFunctionType type, IType[] exceptionSpec) {
super(orig, owner, tpmap, args, type, exceptionSpec); super(orig, owner, tpmap, args, type, exceptionSpec);
} }
@Override
public ICPPExecution getConstructorChainExecution() {
return CPPConstructorSpecialization.getConstructorChainExecution(this);
}
@Override @Override
public ICPPExecution getConstructorChainExecution(IASTNode point) { public ICPPExecution getConstructorChainExecution(IASTNode point) {
return CPPConstructorSpecialization.getConstructorChainExecution(this, point); return getConstructorChainExecution();
} }
} }

View file

@ -31,7 +31,7 @@ public class CPPConstructorSpecialization extends CPPMethodSpecialization
super(orig, owner, argMap, type, exceptionSpecs); super(orig, owner, argMap, type, exceptionSpecs);
} }
static <T extends ICPPConstructorSpecialization & ICPPInternalBinding> ICPPExecution static <T extends ICPPConstructorSpecialization & ICPPInternalBinding> ICPPExecution
getConstructorChainExecution(T functionSpec, IASTNode point) { getConstructorChainExecution(T functionSpec) {
if (!functionSpec.isConstexpr()) { if (!functionSpec.isConstexpr()) {
return null; return null;
} }
@ -40,11 +40,16 @@ public class CPPConstructorSpecialization extends CPPMethodSpecialization
if (def != null) { if (def != null) {
return CPPConstructor.computeConstructorChainExecution(def); return CPPConstructor.computeConstructorChainExecution(def);
} }
return CPPTemplates.instantiateConstructorChain(functionSpec, point); return CPPTemplates.instantiateConstructorChain(functionSpec);
} }
@Override
public ICPPExecution getConstructorChainExecution() {
return getConstructorChainExecution(this);
}
@Override @Override
public ICPPExecution getConstructorChainExecution(IASTNode point) { public ICPPExecution getConstructorChainExecution(IASTNode point) {
return getConstructorChainExecution(this, point); return getConstructorChainExecution();
} }
} }

View file

@ -15,16 +15,20 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
public class CPPConstructorTemplate extends CPPMethodTemplate implements ICPPConstructor { public class CPPConstructorTemplate extends CPPMethodTemplate implements ICPPConstructor {
public CPPConstructorTemplate(IASTName name) { public CPPConstructorTemplate(IASTName name) {
super(name); super(name);
} }
@Override @Override
public ICPPExecution getConstructorChainExecution(IASTNode point) { public ICPPExecution getConstructorChainExecution() {
if (!isConstexpr()) { if (!isConstexpr()) {
return null; return null;
} }
return CPPConstructor.computeConstructorChainExecution(getDefinition()); return CPPConstructor.computeConstructorChainExecution(getDefinition());
} }
@Override
public ICPPExecution getConstructorChainExecution(IASTNode point) {
return getConstructorChainExecution();
}
} }

View file

@ -30,8 +30,13 @@ public class CPPConstructorTemplateSpecialization extends CPPMethodTemplateSpeci
super(original, owner, tpmap, type, exceptionSpecs); super(original, owner, tpmap, type, exceptionSpecs);
} }
@Override
public ICPPExecution getConstructorChainExecution() {
return CPPConstructorSpecialization.getConstructorChainExecution(this);
}
@Override @Override
public ICPPExecution getConstructorChainExecution(IASTNode point) { public ICPPExecution getConstructorChainExecution(IASTNode point) {
return CPPConstructorSpecialization.getConstructorChainExecution(this, point); return getConstructorChainExecution();
} }
} }

View file

@ -77,7 +77,12 @@ public class CPPDeferredConstructor extends CPPDeferredFunction implements ICPPC
} }
@Override @Override
public ICPPExecution getConstructorChainExecution(IASTNode point) { public ICPPExecution getConstructorChainExecution() {
return null; return null;
} }
@Override
public ICPPExecution getConstructorChainExecution(IASTNode point) {
return getConstructorChainExecution();
}
} }

View file

@ -12,7 +12,6 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
@ -173,7 +172,7 @@ public class CPPDeferredFunction extends CPPUnknownBinding implements ICPPDeferr
} }
@Override @Override
public ICPPExecution getFunctionBodyExecution(IASTNode point) { public ICPPExecution getFunctionBodyExecution() {
return null; return null;
} }

View file

@ -12,7 +12,6 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IEnumerator;
@ -39,16 +38,16 @@ public class CPPEnumerationSpecialization extends CPPSpecialization implements I
private boolean fInitializationComplete; private boolean fInitializationComplete;
public static IBinding createInstance(ICPPEnumeration enumeration, public static IBinding createInstance(ICPPEnumeration enumeration,
ICPPClassSpecialization owner, ICPPTemplateParameterMap tpMap, IASTNode point) { ICPPClassSpecialization owner, ICPPTemplateParameterMap tpMap) {
IType fixedType = enumeration.getFixedType(); IType fixedType = enumeration.getFixedType();
if (fixedType != null) { if (fixedType != null) {
ICPPClassSpecialization within = CPPTemplates.getSpecializationContext(owner); ICPPClassSpecialization within = CPPTemplates.getSpecializationContext(owner);
InstantiationContext context = new InstantiationContext(tpMap, within, point); InstantiationContext context = new InstantiationContext(tpMap, within);
fixedType = CPPTemplates.instantiateType(fixedType, context); fixedType = CPPTemplates.instantiateType(fixedType, context);
} }
CPPEnumerationSpecialization specializedEnumeration = CPPEnumerationSpecialization specializedEnumeration =
new CPPEnumerationSpecialization(enumeration, owner, tpMap, fixedType); new CPPEnumerationSpecialization(enumeration, owner, tpMap, fixedType);
specializedEnumeration.initialize(point); specializedEnumeration.initialize();
return specializedEnumeration; return specializedEnumeration;
} }
@ -59,13 +58,13 @@ public class CPPEnumerationSpecialization extends CPPSpecialization implements I
fEnumerators = new IEnumerator[specialized.getEnumerators().length]; fEnumerators = new IEnumerator[specialized.getEnumerators().length];
} }
private void initialize(IASTNode point) { private void initialize() {
ICPPTemplateParameterMap tpMap = getTemplateParameterMap(); ICPPTemplateParameterMap tpMap = getTemplateParameterMap();
IEnumerator[] enumerators = getSpecializedBinding().getEnumerators(); IEnumerator[] enumerators = getSpecializedBinding().getEnumerators();
IType previousInternalType = CPPBasicType.INT; IType previousInternalType = CPPBasicType.INT;
for (int i = 0; i < enumerators.length; ++i) { for (int i = 0; i < enumerators.length; ++i) {
IEnumerator enumerator = enumerators[i]; IEnumerator enumerator = enumerators[i];
InstantiationContext context = new InstantiationContext(tpMap, this, point); InstantiationContext context = new InstantiationContext(tpMap, this);
IValue specializedValue = IValue specializedValue =
CPPTemplates.instantiateValue(enumerator.getValue(), context, IntegralValue.MAX_RECURSION_DEPTH); CPPTemplates.instantiateValue(enumerator.getValue(), context, IntegralValue.MAX_RECURSION_DEPTH);
IType internalType = null; IType internalType = null;

View file

@ -105,7 +105,7 @@ public class CPPField extends CPPVariable implements ICPPField {
} }
public static int getFieldPosition(String fieldName, ICPPClassType classOwner) { public static int getFieldPosition(String fieldName, ICPPClassType classOwner) {
IField[] fields = ClassTypeHelper.getDeclaredFields(classOwner, null); IField[] fields = classOwner.getDeclaredFields();
for (int fieldPos = 0; fieldPos < fields.length; fieldPos++) { for (int fieldPos = 0; fieldPos < fields.length; fieldPos++) {
if (fields[fieldPos].getName().equals(fieldName)) { if (fields[fieldPos].getName().equals(fieldName)) {
return fieldPos; return fieldPos;

View file

@ -703,15 +703,15 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
return false; return false;
} }
public static ICPPExecution getFunctionBodyExecution(ICPPFunction function, IASTNode point) { public static ICPPExecution getFunctionBodyExecution(ICPPFunction function) {
if (function instanceof ICPPComputableFunction) { if (function instanceof ICPPComputableFunction) {
return ((ICPPComputableFunction) function).getFunctionBodyExecution(point); return ((ICPPComputableFunction) function).getFunctionBodyExecution();
} }
return null; return null;
} }
@Override @Override
public ICPPExecution getFunctionBodyExecution(IASTNode point) { public ICPPExecution getFunctionBodyExecution() {
if (!isConstexpr()) if (!isConstexpr())
return null; return null;
if (getDefinition() == null) { if (getDefinition() == null) {

View file

@ -327,7 +327,7 @@ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPP
} }
@Override @Override
public ICPPExecution getFunctionBodyExecution(IASTNode point) { public ICPPExecution getFunctionBodyExecution() {
if (!isConstexpr()) { if (!isConstexpr()) {
return null; return null;
} }
@ -336,6 +336,6 @@ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPP
if (def != null) { if (def != null) {
return CPPFunction.computeFunctionBodyExecution(def); return CPPFunction.computeFunctionBodyExecution(def);
} }
return CPPTemplates.instantiateFunctionBody(this, point); return CPPTemplates.instantiateFunctionBody(this);
} }
} }

View file

@ -442,7 +442,7 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
} }
@Override @Override
public ICPPExecution getFunctionBodyExecution(IASTNode point) { public ICPPExecution getFunctionBodyExecution() {
if (!isConstexpr()) { if (!isConstexpr()) {
return null; return null;
} }

View file

@ -27,14 +27,10 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeTraits;
* Binding for implicit constructors (default and copy constructor). * Binding for implicit constructors (default and copy constructor).
*/ */
public class CPPImplicitConstructor extends CPPImplicitMethod implements ICPPConstructor { public class CPPImplicitConstructor extends CPPImplicitMethod implements ICPPConstructor {
IASTNode fPoint; // point of instantiation, if applicable
public CPPImplicitConstructor(ICPPClassScope scope, char[] name, ICPPParameter[] params, IASTNode point) { public CPPImplicitConstructor(ICPPClassScope scope, char[] name, ICPPParameter[] params, IASTNode point) {
// Note: the value passed for the 'isConstexpr' parameter of the CPPImplicitMethod constructor // Note: the value passed for the 'isConstexpr' parameter of the CPPImplicitMethod constructor
// is irrelevant, as CPPImplicitConstructor overrides isConstexpr(). // is irrelevant, as CPPImplicitConstructor overrides isConstexpr().
super(scope, name, createFunctionType(params), params, false); super(scope, name, createFunctionType(params), params, false);
fPoint = point;
} }
private static ICPPFunctionType createFunctionType(IParameter[] params) { private static ICPPFunctionType createFunctionType(IParameter[] params) {
@ -53,11 +49,16 @@ public class CPPImplicitConstructor extends CPPImplicitMethod implements ICPPCon
*/ */
@Override @Override
public boolean isConstexpr() { public boolean isConstexpr() {
return TypeTraits.isLiteralClass(getClassOwner(), fPoint); return TypeTraits.isLiteralClass(getClassOwner());
}
@Override
public ICPPExecution getConstructorChainExecution() {
return CPPConstructor.getConstructorChainExecution(this);
} }
@Override @Override
public ICPPExecution getConstructorChainExecution(IASTNode point) { public ICPPExecution getConstructorChainExecution(IASTNode point) {
return CPPConstructor.getConstructorChainExecution(this); return getConstructorChainExecution();
} }
} }

View file

@ -209,6 +209,6 @@ public class CPPImplicitMethod extends CPPImplicitFunction implements ICPPMethod
@Override @Override
public IType[] getExceptionSpecification() { public IType[] getExceptionSpecification() {
return ClassTypeHelper.getInheritedExceptionSpecification(this, null); return ClassTypeHelper.getInheritedExceptionSpecification(this);
} }
} }

View file

@ -117,10 +117,15 @@ public class CPPMethodSpecialization extends CPPFunctionSpecialization implement
} }
@Override @Override
public IType[] getExceptionSpecification(IASTNode point) { public IType[] getExceptionSpecification() {
if (isImplicit()) { if (isImplicit()) {
return ClassTypeHelper.getInheritedExceptionSpecification(this, point); return ClassTypeHelper.getInheritedExceptionSpecification(this);
} }
return super.getExceptionSpecification(); return super.getExceptionSpecification();
} }
@Override
public IType[] getExceptionSpecification(IASTNode point) {
return getExceptionSpecification();
}
} }

View file

@ -27,7 +27,6 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTName; 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.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
@ -398,14 +397,14 @@ public class CPPScopeMapper {
return scope; return scope;
} }
public ICPPClassType mapToAST(ICPPClassType type, IASTNode point) { public ICPPClassType mapToAST(ICPPClassType type) {
if (type instanceof ICPPTemplateInstance) { if (type instanceof ICPPTemplateInstance) {
ICPPTemplateInstance inst= (ICPPTemplateInstance) type; ICPPTemplateInstance inst= (ICPPTemplateInstance) type;
ICPPTemplateDefinition template= inst.getTemplateDefinition(); ICPPTemplateDefinition template= inst.getTemplateDefinition();
if (template instanceof IIndexBinding && template instanceof ICPPClassType) { if (template instanceof IIndexBinding && template instanceof ICPPClassType) {
IBinding mapped= mapToAST((ICPPClassType) template, point); IBinding mapped= mapToAST((ICPPClassType) template);
if (mapped != template && mapped instanceof ICPPClassType) { if (mapped != template && mapped instanceof ICPPClassType) {
mapped= CPPTemplates.instantiate((ICPPClassTemplate) mapped, inst.getTemplateArguments(), point); mapped= CPPTemplates.instantiate((ICPPClassTemplate) mapped, inst.getTemplateArguments());
if (mapped instanceof ICPPClassType) if (mapped instanceof ICPPClassType)
return (ICPPClassType) mapped; return (ICPPClassType) mapped;
} }

View file

@ -13,7 +13,6 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType;
@ -30,18 +29,18 @@ import org.eclipse.core.runtime.Assert;
public final class CPPTemplateNonTypeArgument implements ICPPTemplateArgument { public final class CPPTemplateNonTypeArgument implements ICPPTemplateArgument {
private final ICPPEvaluation fEvaluation; private final ICPPEvaluation fEvaluation;
public CPPTemplateNonTypeArgument(ICPPEvaluation evaluation, IASTNode point) { public CPPTemplateNonTypeArgument(ICPPEvaluation evaluation) {
Assert.isNotNull(evaluation); Assert.isNotNull(evaluation);
if (evaluation instanceof EvalFixed || point == null || if (evaluation instanceof EvalFixed ||
evaluation.isTypeDependent() || evaluation.isValueDependent()) { evaluation.isTypeDependent() || evaluation.isValueDependent()) {
fEvaluation= evaluation; fEvaluation= evaluation;
} else { } else {
IValue value = evaluation.getValue(point); IValue value = evaluation.getValue();
if (value == IntegralValue.ERROR) { if (value == IntegralValue.ERROR) {
fEvaluation = EvalFixed.INCOMPLETE; fEvaluation = EvalFixed.INCOMPLETE;
} else { } else {
fEvaluation= new EvalFixed(evaluation.getType(point), fEvaluation= new EvalFixed(evaluation.getType(),
evaluation.getValueCategory(point), value); evaluation.getValueCategory(), value);
} }
} }
} }
@ -77,22 +76,22 @@ public final class CPPTemplateNonTypeArgument implements ICPPTemplateArgument {
@Override @Override
public IValue getNonTypeValue() { public IValue getNonTypeValue() {
return fEvaluation.getValue(null); return fEvaluation.getValue();
} }
@Override @Override
public IType getTypeOfNonTypeValue() { public IType getTypeOfNonTypeValue() {
return fEvaluation.getType(null); return fEvaluation.getType();
} }
@Override @Override
public boolean isPackExpansion() { public boolean isPackExpansion() {
return fEvaluation.getType(null) instanceof ICPPParameterPackType; return fEvaluation.getType() instanceof ICPPParameterPackType;
} }
@Override @Override
public ICPPTemplateArgument getExpansionPattern() { public ICPPTemplateArgument getExpansionPattern() {
IType type = fEvaluation.getType(null); IType type = fEvaluation.getType();
if (type instanceof ICPPParameterPackType) { if (type instanceof ICPPParameterPackType) {
IType t= ((ICPPParameterPackType) type).getType(); IType t= ((ICPPParameterPackType) type).getType();
if (t != null) { if (t != null) {
@ -102,7 +101,7 @@ public final class CPPTemplateNonTypeArgument implements ICPPTemplateArgument {
} else { } else {
evaluation = new EvalTypeId(t, fEvaluation.getTemplateDefinition(), false, false, fEvaluation); evaluation = new EvalTypeId(t, fEvaluation.getTemplateDefinition(), false, false, fEvaluation);
} }
return new CPPTemplateNonTypeArgument(evaluation, null); return new CPPTemplateNonTypeArgument(evaluation);
} }
} }
return null; return null;

View file

@ -156,8 +156,7 @@ public class CPPUnknownTypeScope implements ICPPInternalUnknownScope {
if (lookup.isPrefixLookup()) { if (lookup.isPrefixLookup()) {
// If name lookup is performed for the purpose of code completion in a dependent context, // If name lookup is performed for the purpose of code completion in a dependent context,
// try to give some useful results heuristically. // try to give some useful results heuristically.
IScope scope = HeuristicResolver.findConcreteScopeForType(fScopeType, IScope scope = HeuristicResolver.findConcreteScopeForType(fScopeType);
lookup.getLookupPoint());
if (scope != null) { if (scope != null) {
return scope.getBindings(lookup); return scope.getBindings(lookup);
} }

View file

@ -262,7 +262,12 @@ public class CPPVariable extends PlatformObject implements ICPPInternalDeclaredV
} }
if (!initEval.isValueDependent() ) { if (!initEval.isValueDependent() ) {
IASTNode point = fDefinition != null ? fDefinition : fDeclarations[0]; IASTNode point = fDefinition != null ? fDefinition : fDeclarations[0];
return initEval.getValue(point); CPPSemantics.pushLookupPoint(point);
try {
return initEval.getValue();
} finally {
CPPSemantics.popLookupPoint();
}
} }
return DependentValue.create(initEval); return DependentValue.create(initEval);
} }

View file

@ -153,7 +153,7 @@ public class ClassTypeHelper {
if (type.isSameType(classType)) { if (type.isSameType(classType)) {
return true; return true;
} }
for (IBinding friend : getFriends(classType, null)) { for (IBinding friend : classType.getFriends()) {
if (friend instanceof ICPPClassType && type.isSameType((IType) friend)) { if (friend instanceof ICPPClassType && type.isSameType((IType) friend)) {
return true; return true;
} }
@ -161,7 +161,7 @@ public class ClassTypeHelper {
} else if (binding instanceof ICPPFunction) { } else if (binding instanceof ICPPFunction) {
type = ((ICPPFunction) binding).getType(); type = ((ICPPFunction) binding).getType();
char[] name = binding.getNameCharArray(); char[] name = binding.getNameCharArray();
for (IBinding friend : getFriends(classType, null)) { for (IBinding friend : classType.getFriends()) {
if (friend instanceof ICPPFunction && if (friend instanceof ICPPFunction &&
CharArrayUtils.equals(name, friend.getNameCharArray()) && CharArrayUtils.equals(name, friend.getNameCharArray()) &&
SemanticUtil.haveSameOwner(binding, friend) && SemanticUtil.haveSameOwner(binding, friend) &&
@ -251,70 +251,28 @@ public class ClassTypeHelper {
return ArrayUtil.trim(result, resultSize); return ArrayUtil.trim(result, resultSize);
} }
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();
}
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. * Returns all direct and indirect base classes.
* *
* @param classType a class * @param classType a class
* @return An array of base classes in arbitrary order. * @return An array of base classes in arbitrary order.
*/ */
public static ICPPClassType[] getAllBases(ICPPClassType classType, IASTNode point) { public static ICPPClassType[] getAllBases(ICPPClassType classType) {
Set<ICPPClassType> result= new HashSet<>(); Set<ICPPClassType> result= new HashSet<>();
result.add(classType); result.add(classType);
getAllBases(classType, result, point); getAllBases(classType, result);
result.remove(classType); result.remove(classType);
return result.toArray(new ICPPClassType[result.size()]); return result.toArray(new ICPPClassType[result.size()]);
} }
private static void getAllBases(ICPPClassType classType, Set<ICPPClassType> result, IASTNode point) { private static void getAllBases(ICPPClassType classType, Set<ICPPClassType> result) {
ICPPBase[] bases= getBases(classType, point); ICPPBase[] bases= classType.getBases();
for (ICPPBase base : bases) { for (ICPPBase base : bases) {
IBinding b= base.getBaseClass(); IBinding b= base.getBaseClass();
if (b instanceof ICPPClassType) { if (b instanceof ICPPClassType) {
final ICPPClassType baseClass = (ICPPClassType) b; final ICPPClassType baseClass = (ICPPClassType) b;
if (result.add(baseClass)) { if (result.add(baseClass)) {
getAllBases(baseClass, result, point); getAllBases(baseClass, result);
} }
} }
} }
@ -322,35 +280,33 @@ public class ClassTypeHelper {
/** /**
* Returns all (direct or indirect) virtual base classes of {@code classType}. * Returns all (direct or indirect) virtual base classes of {@code classType}.
*
* @param point the point of instantiation for name lookups
*/ */
public static ICPPClassType[] getVirtualBases(ICPPClassType classType, IASTNode point) { public static ICPPClassType[] getVirtualBases(ICPPClassType classType) {
Set<ICPPClassType> virtualBases = new HashSet<>(); Set<ICPPClassType> virtualBases = new HashSet<>();
Set<ICPPClassType> nonvirtualBases = new HashSet<>(); Set<ICPPClassType> nonvirtualBases = new HashSet<>();
nonvirtualBases.add(classType); nonvirtualBases.add(classType);
getVirtualBases(classType, virtualBases, nonvirtualBases, point); getVirtualBases(classType, virtualBases, nonvirtualBases);
return virtualBases.toArray(new ICPPClassType[virtualBases.size()]); return virtualBases.toArray(new ICPPClassType[virtualBases.size()]);
} }
/** /**
* Helper function for {@link #getVirtualBases(ICPPClassType, IASTNode)}. * Helper function for {@link #getVirtualBases(ICPPClassType)}.
*/ */
private static void getVirtualBases(ICPPClassType classType, Set<ICPPClassType> virtualBases, private static void getVirtualBases(ICPPClassType classType, Set<ICPPClassType> virtualBases,
Set<ICPPClassType> nonvirtualBases, IASTNode point) { Set<ICPPClassType> nonvirtualBases) {
ICPPBase[] bases = getBases(classType, point); ICPPBase[] bases = classType.getBases();
for (ICPPBase base : bases) { for (ICPPBase base : bases) {
IBinding b = base.getBaseClass(); IBinding b = base.getBaseClass();
if (b instanceof ICPPClassType) { if (b instanceof ICPPClassType) {
final ICPPClassType baseClass = (ICPPClassType) b; final ICPPClassType baseClass = (ICPPClassType) b;
if (base.isVirtual()) { if (base.isVirtual()) {
if (virtualBases.add(baseClass)) { if (virtualBases.add(baseClass)) {
getVirtualBases(baseClass, virtualBases, nonvirtualBases, point); getVirtualBases(baseClass, virtualBases, nonvirtualBases);
} }
} else { } else {
// A non-virtual base could have virtual bases in its hierarchy. // A non-virtual base could have virtual bases in its hierarchy.
if (nonvirtualBases.add(baseClass)) { if (nonvirtualBases.add(baseClass)) {
getVirtualBases(baseClass, virtualBases, nonvirtualBases, point); getVirtualBases(baseClass, virtualBases, nonvirtualBases);
} }
} }
} }
@ -362,8 +318,8 @@ public class ClassTypeHelper {
* *
* @return {@code true} if {@code subclass} is a subclass of {@code superclass}. * @return {@code true} if {@code subclass} is a subclass of {@code superclass}.
*/ */
public static boolean isSubclass(ICPPClassType subclass, ICPPClassType superclass, IASTNode point) { public static boolean isSubclass(ICPPClassType subclass, ICPPClassType superclass) {
ICPPBase[] bases= getBases(subclass, point); ICPPBase[] bases= subclass.getBases();
for (ICPPBase base : bases) { for (ICPPBase base : bases) {
IBinding b= base.getBaseClass(); IBinding b= base.getBaseClass();
if (b instanceof ICPPClassType) { if (b instanceof ICPPClassType) {
@ -371,7 +327,7 @@ public class ClassTypeHelper {
if (baseClass.isSameType(superclass)) { if (baseClass.isSameType(superclass)) {
return true; return true;
} }
if (isSubclass(baseClass, superclass, point)) { if (isSubclass(baseClass, superclass)) {
return true; return true;
} }
} }
@ -379,22 +335,22 @@ public class ClassTypeHelper {
return false; return false;
} }
public static ICPPMethod[] getAllDeclaredMethods(ICPPClassType ct, IASTNode point) { public static ICPPMethod[] getAllDeclaredMethods(ICPPClassType ct) {
ICPPMethod[] methods= getDeclaredMethods(ct, point); ICPPMethod[] methods= ct.getDeclaredMethods();
ICPPClassType[] bases= getAllBases(ct, point); ICPPClassType[] bases= getAllBases(ct);
for (ICPPClassType base : bases) { for (ICPPClassType base : bases) {
methods = ArrayUtil.addAll(ICPPMethod.class, methods, getDeclaredMethods(base, point)); methods = ArrayUtil.addAll(ICPPMethod.class, methods, base.getDeclaredMethods());
} }
return ArrayUtil.trim(ICPPMethod.class, methods); return ArrayUtil.trim(ICPPMethod.class, methods);
} }
public static ICPPMethod[] getMethods(ICPPClassType ct, IASTNode point) { public static ICPPMethod[] getMethods(ICPPClassType ct) {
ObjectSet<ICPPMethod> set = getOwnMethods(ct, point); ObjectSet<ICPPMethod> set = getOwnMethods(ct);
ICPPClassType[] bases= getAllBases(ct, point); ICPPClassType[] bases= getAllBases(ct);
for (ICPPClassType base : bases) { for (ICPPClassType base : bases) {
set.addAll(getDeclaredMethods(base, point)); set.addAll(base.getDeclaredMethods());
set.addAll(getImplicitMethods(base, point)); set.addAll(getImplicitMethods(base));
} }
return set.keyArray(ICPPMethod.class); return set.keyArray(ICPPMethod.class);
} }
@ -403,21 +359,19 @@ public class ClassTypeHelper {
* Returns methods either declared by the given class or generated by the compiler. Does not * Returns methods either declared by the given class or generated by the compiler. Does not
* include methods declared in base classes. * include methods declared in base classes.
*/ */
public static ObjectSet<ICPPMethod> getOwnMethods(ICPPClassType classType, IASTNode point) { public static ObjectSet<ICPPMethod> getOwnMethods(ICPPClassType classType) {
ObjectSet<ICPPMethod> set= new ObjectSet<>(4); ObjectSet<ICPPMethod> set= new ObjectSet<>(4);
set.addAll(ClassTypeHelper.getDeclaredMethods(classType, point)); set.addAll(classType.getDeclaredMethods());
set.addAll(getImplicitMethods(classType, point)); set.addAll(getImplicitMethods(classType));
return set; return set;
} }
public static ICPPMethod[] getImplicitMethods(ICPPClassType classType, IASTNode point) { public static ICPPMethod[] getImplicitMethods(ICPPClassType classType) {
return getImplicitMethods(classType.getCompositeScope(), point); return getImplicitMethods(classType.getCompositeScope());
} }
public static ICPPMethod[] getImplicitMethods(IScope scope, IASTNode point) { public static ICPPMethod[] getImplicitMethods(IScope scope) {
if (scope instanceof ICPPClassSpecializationScope) { if (scope instanceof ICPPClassScope) {
return ((ICPPClassSpecializationScope) scope).getImplicitMethods(point);
} else if (scope instanceof ICPPClassScope) {
return ((ICPPClassScope) scope).getImplicitMethods(); return ((ICPPClassScope) scope).getImplicitMethods();
} }
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
@ -488,7 +442,7 @@ public class ClassTypeHelper {
return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY; return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY;
} }
ICPPConstructor[] constructors = scope.getConstructors(); ICPPConstructor[] constructors = scope.getConstructors();
return getAllConstructors(host, constructors, null); return getAllConstructors(host, constructors);
} }
/** /**
@ -497,18 +451,17 @@ public class ClassTypeHelper {
* *
* @param classType the class to get the constructors for * @param classType the class to get the constructors for
* @param declaredAndImplicitConstructors the declared and implicit constructors of the class * @param declaredAndImplicitConstructors the declared and implicit constructors of the class
* @param point the point of template instantiation, if applicable
* @return an array of all class constructors * @return an array of all class constructors
*/ */
public static ICPPConstructor[] getAllConstructors(ICPPClassType classType, public static ICPPConstructor[] getAllConstructors(ICPPClassType classType,
ICPPConstructor[] declaredAndImplicitConstructors, IASTNode point) { ICPPConstructor[] declaredAndImplicitConstructors) {
IType[][] paramTypes = new IType[declaredAndImplicitConstructors.length][]; IType[][] paramTypes = new IType[declaredAndImplicitConstructors.length][];
for (int i = 0; i < declaredAndImplicitConstructors.length; i++) { for (int i = 0; i < declaredAndImplicitConstructors.length; i++) {
ICPPConstructor ctor = declaredAndImplicitConstructors[i]; ICPPConstructor ctor = declaredAndImplicitConstructors[i];
paramTypes[i] = ctor.getType().getParameterTypes(); paramTypes[i] = ctor.getType().getParameterTypes();
} }
ICPPConstructor[] inheritedConstructors = getInheritedConstructors( ICPPConstructor[] inheritedConstructors = getInheritedConstructors(
(ICPPClassScope) classType.getCompositeScope(), getBases(classType, point), paramTypes, point); (ICPPClassScope) classType.getCompositeScope(), classType.getBases(), paramTypes);
return ArrayUtil.addAll(declaredAndImplicitConstructors, inheritedConstructors); return ArrayUtil.addAll(declaredAndImplicitConstructors, inheritedConstructors);
} }
@ -518,11 +471,10 @@ public class ClassTypeHelper {
* @param scope the composite scope of the class to get the constructors for * @param scope the composite scope of the class to get the constructors for
* @param bases the base class relationships of the class * @param bases the base class relationships of the class
* @param existingConstructorParamTypes parameter types of the declared and the implicit constructors * @param existingConstructorParamTypes parameter types of the declared and the implicit constructors
* @param point the point of template instantiation, if applicable
* @return an array of all inherited constructors * @return an array of all inherited constructors
*/ */
public static ICPPConstructor[] getInheritedConstructors(ICPPClassScope scope, ICPPBase[] bases, public static ICPPConstructor[] getInheritedConstructors(ICPPClassScope scope, ICPPBase[] bases,
IType[][] existingConstructorParamTypes, IASTNode point) { IType[][] existingConstructorParamTypes) {
ICPPConstructor[] inheritedConstructors = ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY; ICPPConstructor[] inheritedConstructors = ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY;
int n = 0; int n = 0;
for (ICPPBase base : bases) { for (ICPPBase base : bases) {
@ -532,7 +484,7 @@ public class ClassTypeHelper {
if (!(baseType instanceof ICPPClassType)) if (!(baseType instanceof ICPPClassType))
continue; continue;
ICPPClassType baseClass = (ICPPClassType) baseType; ICPPClassType baseClass = (ICPPClassType) baseType;
ICPPConstructor[] ctors = getConstructors(baseClass, point); ICPPConstructor[] ctors = baseClass.getConstructors();
for (ICPPConstructor ctor : ctors) { for (ICPPConstructor ctor : ctors) {
if (canBeInherited(ctor, baseClass, existingConstructorParamTypes)) if (canBeInherited(ctor, baseClass, existingConstructorParamTypes))
inheritedConstructors = appendAt(inheritedConstructors, n++, ctor); inheritedConstructors = appendAt(inheritedConstructors, n++, ctor);
@ -650,11 +602,11 @@ public class ClassTypeHelper {
} }
public static ICPPField[] getFields(ICPPClassType ct, IASTNode point) { public static ICPPField[] getFields(ICPPClassType ct) {
ICPPField[] fields = getDeclaredFields(ct, point); ICPPField[] fields = ct.getDeclaredFields();
ICPPClassType[] bases = getAllBases(ct, point); ICPPClassType[] bases = getAllBases(ct);
for (ICPPClassType base : bases) { for (ICPPClassType base : bases) {
fields = ArrayUtil.addAll(ICPPField.class, fields, getDeclaredFields(base, point)); fields = ArrayUtil.addAll(ICPPField.class, fields, base.getDeclaredFields());
} }
return ArrayUtil.trim(ICPPField.class, fields); return ArrayUtil.trim(ICPPField.class, fields);
} }
@ -690,8 +642,7 @@ public class ClassTypeHelper {
final ICPPClassType mcl= m.getClassOwner(); final ICPPClassType mcl= m.getClassOwner();
if (mcl != null) { if (mcl != null) {
final ICPPFunctionType mft= m.getType(); final ICPPFunctionType mft= m.getType();
IASTNode point = null; // Instantiation of dependent expressions may not work ICPPMethod[] allMethods= ClassTypeHelper.getMethods(mcl);
ICPPMethod[] allMethods= ClassTypeHelper.getMethods(mcl, point);
for (ICPPMethod method : allMethods) { for (ICPPMethod method : allMethods) {
if (CharArrayUtils.equals(mname, method.getNameCharArray()) && functionTypesAllowOverride(mft, method.getType())) { if (CharArrayUtils.equals(mname, method.getNameCharArray()) && functionTypesAllowOverride(mft, method.getType())) {
if (method.isVirtual()) { if (method.isVirtual()) {
@ -747,7 +698,7 @@ public class ClassTypeHelper {
if (sourceClass == null || targetClass == null) if (sourceClass == null || targetClass == null)
return false; return false;
ICPPClassType[] bases= getAllBases(sourceClass, null); ICPPClassType[] bases= getAllBases(sourceClass);
for (ICPPClassType base : bases) { for (ICPPClassType base : bases) {
if (base.isSameType(targetClass)) if (base.isSameType(targetClass))
return true; return true;
@ -759,7 +710,7 @@ public class ClassTypeHelper {
/** /**
* Returns all methods that are overridden by the given {@code method}. * Returns all methods that are overridden by the given {@code method}.
*/ */
public static ICPPMethod[] findOverridden(ICPPMethod method, IASTNode point) { public static ICPPMethod[] findOverridden(ICPPMethod method) {
if (method instanceof ICPPConstructor) if (method instanceof ICPPConstructor)
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
@ -773,11 +724,11 @@ public class ClassTypeHelper {
final ICPPFunctionType methodType= method.getType(); final ICPPFunctionType methodType= method.getType();
virtualInClass.put(mcl, method.isVirtual()); virtualInClass.put(mcl, method.isVirtual());
ICPPBase[] bases= getBases(mcl, point); ICPPBase[] bases= mcl.getBases();
for (ICPPBase base : bases) { for (ICPPBase base : bases) {
IBinding b= base.getBaseClass(); IBinding b= base.getBaseClass();
if (b instanceof ICPPClassType) { if (b instanceof ICPPClassType) {
findOverridden((ICPPClassType) b, point, mname, methodType, virtualInClass, findOverridden((ICPPClassType) b, mname, methodType, virtualInClass,
result, CPPSemantics.MAX_INHERITANCE_DEPTH); result, CPPSemantics.MAX_INHERITANCE_DEPTH);
} }
} }
@ -794,7 +745,7 @@ public class ClassTypeHelper {
* *
* @return whether {@code classType} contains an overridden method. * @return whether {@code classType} contains an overridden method.
*/ */
private static boolean findOverridden(ICPPClassType classType, IASTNode point, char[] methodName, private static boolean findOverridden(ICPPClassType classType, char[] methodName,
ICPPFunctionType methodType, Map<ICPPClassType, Boolean> virtualInClass, ICPPFunctionType methodType, Map<ICPPClassType, Boolean> virtualInClass,
List<ICPPMethod> result, int maxdepth) { List<ICPPMethod> result, int maxdepth) {
// Prevent recursion due to a hierarchy of unbounded depth, e.g. A<I> deriving from A<I - 1>. // Prevent recursion due to a hierarchy of unbounded depth, e.g. A<I> deriving from A<I - 1>.
@ -805,7 +756,7 @@ public class ClassTypeHelper {
if (visitedBefore != null) if (visitedBefore != null)
return visitedBefore; return visitedBefore;
ICPPMethod[] methods= ClassTypeHelper.getDeclaredMethods(classType, point); ICPPMethod[] methods= classType.getDeclaredMethods();
ICPPMethod candidate= null; ICPPMethod candidate= null;
boolean hasOverridden= false; boolean hasOverridden= false;
for (ICPPMethod method : methods) { for (ICPPMethod method : methods) {
@ -820,11 +771,11 @@ public class ClassTypeHelper {
// Prevent recursion due to a class inheriting (directly or indirectly) from itself. // Prevent recursion due to a class inheriting (directly or indirectly) from itself.
virtualInClass.put(classType, hasOverridden); virtualInClass.put(classType, hasOverridden);
ICPPBase[] bases= getBases(classType, point); ICPPBase[] bases= classType.getBases();
for (ICPPBase base : bases) { for (ICPPBase base : bases) {
IBinding b= base.getBaseClass(); IBinding b= base.getBaseClass();
if (b instanceof ICPPClassType) { if (b instanceof ICPPClassType) {
if (findOverridden((ICPPClassType) b, point, methodName, methodType, virtualInClass, if (findOverridden((ICPPClassType) b, methodName, methodType, virtualInClass,
result, maxdepth - 1)) { result, maxdepth - 1)) {
hasOverridden= true; hasOverridden= true;
} }
@ -842,7 +793,7 @@ public class ClassTypeHelper {
/** /**
* Returns all methods found in the index, that override the given {@code method}. * Returns all methods found in the index, that override the given {@code method}.
*/ */
public static ICPPMethod[] findOverriders(IIndex index, ICPPMethod method, IASTNode point) public static ICPPMethod[] findOverriders(IIndex index, ICPPMethod method)
throws CoreException { throws CoreException {
if (!isVirtual(method)) if (!isVirtual(method))
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
@ -852,18 +803,18 @@ public class ClassTypeHelper {
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
ICPPClassType[] subclasses= getSubClasses(index, mcl); ICPPClassType[] subclasses= getSubClasses(index, mcl);
return findOverriders(subclasses, method, point); return findOverriders(subclasses, method);
} }
/** /**
* Returns all methods belonging to the given set of classes that override the given {@code method}. * Returns all methods belonging to the given set of classes that override the given {@code method}.
*/ */
public static ICPPMethod[] findOverriders(ICPPClassType[] subclasses, ICPPMethod method, IASTNode point) { public static ICPPMethod[] findOverriders(ICPPClassType[] subclasses, ICPPMethod method) {
final char[] mname= method.getNameCharArray(); final char[] mname= method.getNameCharArray();
final ICPPFunctionType mft= method.getType(); final ICPPFunctionType mft= method.getType();
final ArrayList<ICPPMethod> result= new ArrayList<>(); final ArrayList<ICPPMethod> result= new ArrayList<>();
for (ICPPClassType subClass : subclasses) { for (ICPPClassType subClass : subclasses) {
ICPPMethod[] methods= ClassTypeHelper.getDeclaredMethods(subClass, point); ICPPMethod[] methods= subClass.getDeclaredMethods();
for (ICPPMethod candidate : methods) { for (ICPPMethod candidate : methods) {
if (CharArrayUtils.equals(mname, candidate.getNameCharArray()) && if (CharArrayUtils.equals(mname, candidate.getNameCharArray()) &&
functionTypesAllowOverride(mft, candidate.getType())) { functionTypesAllowOverride(mft, candidate.getType())) {
@ -972,10 +923,10 @@ public class ClassTypeHelper {
/** /**
* For implicit methods the exception specification is inherited, search it. * For implicit methods the exception specification is inherited, search it.
*/ */
public static IType[] getInheritedExceptionSpecification(ICPPMethod implicitMethod, IASTNode point) { public static IType[] getInheritedExceptionSpecification(ICPPMethod implicitMethod) {
// See 15.4.13 // See 15.4.13
ICPPClassType owner= implicitMethod.getClassOwner(); ICPPClassType owner= implicitMethod.getClassOwner();
if (owner == null || ClassTypeHelper.getBases(owner, point).length == 0) if (owner == null || owner.getBases().length == 0)
return null; return null;
// We use a list as types aren't comparable, and can have duplicates (15.4.6) // We use a list as types aren't comparable, and can have duplicates (15.4.6)
@ -984,10 +935,10 @@ public class ClassTypeHelper {
return null; return null;
List<IType> inheritedTypeids = new ArrayList<>(); List<IType> inheritedTypeids = new ArrayList<>();
ICPPClassType[] bases= getAllBases(owner, point); ICPPClassType[] bases= getAllBases(owner);
for (ICPPClassType base : bases) { for (ICPPClassType base : bases) {
if (!(base instanceof ICPPDeferredClassInstance)) { if (!(base instanceof ICPPDeferredClassInstance)) {
ICPPMethod baseMethod= getMethodInClass(base, kind, point); ICPPMethod baseMethod= getMethodInClass(base, kind);
if (baseMethod != null) { if (baseMethod != null) {
IType[] baseExceptionSpec= baseMethod.getExceptionSpecification(); IType[] baseExceptionSpec= baseMethod.getExceptionSpecification();
if (baseExceptionSpec == null) if (baseExceptionSpec == null)
@ -1025,19 +976,19 @@ public class ClassTypeHelper {
return null; return null;
} }
public static ICPPMethod getMethodInClass(ICPPClassType ct, MethodKind kind, IASTNode point) { public static ICPPMethod getMethodInClass(ICPPClassType ct, MethodKind kind) {
switch (kind) { switch (kind) {
case DEFAULT_CTOR: case DEFAULT_CTOR:
case COPY_CTOR: case COPY_CTOR:
case MOVE_CTOR: case MOVE_CTOR:
for (ICPPConstructor ctor : getConstructors(ct, point)) { for (ICPPConstructor ctor : ct.getConstructors()) {
if (!ctor.isImplicit() && getMethodKind(ct, ctor) == kind) if (!ctor.isImplicit() && getMethodKind(ct, ctor) == kind)
return ctor; return ctor;
} }
return null; return null;
case COPY_ASSIGNMENT_OP: case COPY_ASSIGNMENT_OP:
case MOVE_ASSIGNMENT_OP: case MOVE_ASSIGNMENT_OP:
for (ICPPMethod method : getDeclaredMethods(ct, point)) { for (ICPPMethod method : ct.getDeclaredMethods()) {
if (method instanceof ICPPConstructor) if (method instanceof ICPPConstructor)
continue; continue;
if (getMethodKind(ct, method) == kind) if (getMethodKind(ct, method) == kind)
@ -1045,7 +996,7 @@ public class ClassTypeHelper {
} }
return null; return null;
case DTOR: case DTOR:
for (ICPPMethod method : getDeclaredMethods(ct, point)) { for (ICPPMethod method : ct.getDeclaredMethods()) {
if (method.isDestructor()) if (method.isDestructor())
return method; return method;
} }
@ -1098,7 +1049,7 @@ public class ClassTypeHelper {
if (visibility >= 0) if (visibility >= 0)
return visibility; return visibility;
ICPPMethod[] implicitMethods = getImplicitMethods(classType, null); ICPPMethod[] implicitMethods = getImplicitMethods(classType);
for (ICPPMethod implicitMethod : implicitMethods) { for (ICPPMethod implicitMethod : implicitMethods) {
if (member.equals(implicitMethod)) { if (member.equals(implicitMethod)) {
return ICPPClassType.v_public; return ICPPClassType.v_public;

View file

@ -11,13 +11,11 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; 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.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; 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.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.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
@ -43,42 +41,30 @@ public interface ICPPClassSpecializationScope extends ICPPClassScope {
/** /**
* Computes the bases via the original class. * Computes the bases via the original class.
*/ */
ICPPBase[] getBases(IASTNode point); ICPPBase[] getBases();
/**
* 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. * Computes the methods via the original class.
*/ */
ICPPMethod[] getDeclaredMethods(IASTNode point); ICPPMethod[] getDeclaredMethods();
/** /**
* Computes the fields via the original class. * Computes the fields via the original class.
*/ */
ICPPField[] getDeclaredFields(IASTNode point); ICPPField[] getDeclaredFields();
/** /**
* Computes the friends via the original class. * Computes the friends via the original class.
*/ */
IBinding[] getFriends(IASTNode point); IBinding[] getFriends();
/** /**
* Computes the nested classes via the original class. * Computes the nested classes via the original class.
*/ */
ICPPClassType[] getNestedClasses(IASTNode point); ICPPClassType[] getNestedClasses();
/** /**
* Computes the using declarations via the original class. * Computes the using declarations via the original class.
*/ */
ICPPUsingDeclaration[] getUsingDeclarations(IASTNode point); ICPPUsingDeclaration[] getUsingDeclarations();
} }

View file

@ -10,16 +10,13 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTNode;
/** /**
* Represents a function whose executing may be simulated at parsing time. * Represents a function whose executing may be simulated at parsing time.
*/ */
public interface ICPPComputableFunction { public interface ICPPComputableFunction {
/** /**
* For a constexpr function returns the ICPPExecution for its body. Otherwise returns
* {@code null}. * {@code null}.
* @param point the point of instantiation for name lookups * For a constexpr function returns the ICPPExecution for its body. Otherwise returns
*/ */
public ICPPExecution getFunctionBodyExecution(IASTNode point); public ICPPExecution getFunctionBodyExecution();
} }

View file

@ -13,7 +13,6 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.IValue;
@ -46,31 +45,25 @@ public interface ICPPEvaluation {
* *
* @param point the point of instantiation, determines the scope for name lookups * @param point the point of instantiation, determines the scope for name lookups
*/ */
boolean isConstantExpression(IASTNode point); boolean isConstantExpression();
/** /**
* Returns the type of the expression. * Returns the type of the expression.
* *
* If the expression evaluates to a function set, a {@code FunctionSetType} is returned. * If the expression evaluates to a function set, a {@code FunctionSetType} is returned.
*
* @param point the point of instantiation, determines the scope for name lookups
*/ */
IType getType(IASTNode point); IType getType();
/** /**
* Returns the value of the expression. * Returns the value of the expression.
*
* @param point the point of instantiation, determines the scope for name lookups
*/ */
IValue getValue(IASTNode point); IValue getValue();
/** /**
* Returns the category of the expression value. * Returns the category of the expression value.
* @see ValueCategory * @see ValueCategory
*
* @param point the point of instantiation, determines the scope for name lookups
*/ */
ValueCategory getValueCategory(IASTNode point); ValueCategory getValueCategory();
/** /**
* Returns a signature uniquely identifying the evaluation. Two evaluations with identical * Returns a signature uniquely identifying the evaluation. Two evaluations with identical
@ -98,15 +91,12 @@ public interface ICPPEvaluation {
public static final int MAX_CONSTEXPR_EVALUATION_STEPS = 1024; public static final int MAX_CONSTEXPR_EVALUATION_STEPS = 1024;
private int fStepsPerformed; private int fStepsPerformed;
private IASTNode fPoint;
/** /**
* Constructs a ConstexprEvaluationContext for a new constexpr evaluation. * Constructs a ConstexprEvaluationContext for a new constexpr evaluation.
* @param point the point of instantiation, determines the scope for name lookups
*/ */
public ConstexprEvaluationContext(IASTNode point) { public ConstexprEvaluationContext() {
fStepsPerformed = 0; fStepsPerformed = 0;
fPoint = point;
} }
/** /**
@ -125,13 +115,6 @@ public interface ICPPEvaluation {
public int getStepsPerformed() { public int getStepsPerformed() {
return fStepsPerformed; return fStepsPerformed;
} }
/**
* Returns the point of instantiation.
*/
public IASTNode getPoint() {
return fPoint;
}
} }
/** /**

View file

@ -20,7 +20,6 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
@ -45,7 +44,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
*/ */
final class ImplicitsAnalysis { final class ImplicitsAnalysis {
private final ICPPClassType classType; private final ICPPClassType classType;
private final ICPPASTCompositeTypeSpecifier compositeTypeSpecifier;
private boolean hasConstructor; private boolean hasConstructor;
private boolean hasCopyConstructor; private boolean hasCopyConstructor;
private boolean hasCopyAssignmentOperator; private boolean hasCopyAssignmentOperator;
@ -54,7 +52,6 @@ final class ImplicitsAnalysis {
ImplicitsAnalysis(ICPPASTCompositeTypeSpecifier compositeTypeSpecifier, ICPPClassType classType) { ImplicitsAnalysis(ICPPASTCompositeTypeSpecifier compositeTypeSpecifier, ICPPClassType classType) {
this.classType = classType; this.classType = classType;
this.compositeTypeSpecifier = compositeTypeSpecifier;
analyzeMembers(compositeTypeSpecifier); analyzeMembers(compositeTypeSpecifier);
} }
@ -162,15 +159,15 @@ final class ImplicitsAnalysis {
if (hasNonStaticFields) if (hasNonStaticFields)
return false; return false;
ICPPBase[] bases = ClassTypeHelper.getBases(classType, compositeTypeSpecifier); ICPPBase[] bases = classType.getBases();
for (ICPPBase base : bases) { for (ICPPBase base : bases) {
if (base.isVirtual()) if (base.isVirtual())
return false; return false;
} }
ICPPClassType[] baseClasses = ClassTypeHelper.getAllBases(classType, compositeTypeSpecifier); ICPPClassType[] baseClasses = ClassTypeHelper.getAllBases(classType);
for (ICPPClassType baseClass : baseClasses) { for (ICPPClassType baseClass : baseClasses) {
ICPPConstructor ctor = getDefaultConstructor(baseClass, compositeTypeSpecifier); ICPPConstructor ctor = getDefaultConstructor(baseClass);
if (ctor == null || !ctor.isConstexpr()) if (ctor == null || !ctor.isConstexpr())
return false; return false;
} }
@ -180,8 +177,8 @@ final class ImplicitsAnalysis {
/** /**
* Returns a user-defined or implicit default constructor for the given class. * Returns a user-defined or implicit default constructor for the given class.
*/ */
private static ICPPConstructor getDefaultConstructor(ICPPClassType classType, IASTNode point) { private static ICPPConstructor getDefaultConstructor(ICPPClassType classType) {
for (ICPPConstructor ctor : ClassTypeHelper.getConstructors(classType, point)) { for (ICPPConstructor ctor : classType.getConstructors()) {
if (ClassTypeHelper.getMethodKind(classType, ctor) == ClassTypeHelper.MethodKind.DEFAULT_CTOR) if (ClassTypeHelper.getMethodKind(classType, ctor) == ClassTypeHelper.MethodKind.DEFAULT_CTOR)
return ctor; return ctor;
} }

View file

@ -13,7 +13,6 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumerationSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumerationSpecialization;
@ -30,7 +29,6 @@ public final class InstantiationContext {
private CPPTemplateParameterMap parameterMap; private CPPTemplateParameterMap parameterMap;
private int packOffset; private int packOffset;
private final ICPPSpecialization contextSpecialization; private final ICPPSpecialization contextSpecialization;
private final IASTNode point;
private boolean expandPack; private boolean expandPack;
private boolean packExpanded; private boolean packExpanded;
@ -45,42 +43,37 @@ public final class InstantiationContext {
* @param packOffset parameter pack offset, or -1 if expansion of a parameter pack is not desired pack. * @param packOffset parameter pack offset, or -1 if expansion of a parameter pack is not desired pack.
* @param contextSpecialization the specialization if instantiation happens inside a specialized * @param contextSpecialization the specialization if instantiation happens inside a specialized
* type or function, otherwise {@code null}. * type or function, otherwise {@code null}.
* @param point the point of instantiation
*/ */
public InstantiationContext(ICPPTemplateParameterMap parameterMap, int packOffset, public InstantiationContext(ICPPTemplateParameterMap parameterMap, int packOffset,
ICPPSpecialization contextSpecialization, IASTNode point) { ICPPSpecialization contextSpecialization) {
this.parameterMap = (CPPTemplateParameterMap) parameterMap; this.parameterMap = (CPPTemplateParameterMap) parameterMap;
this.packOffset = packOffset; this.packOffset = packOffset;
this.contextSpecialization = contextSpecialization; this.contextSpecialization = contextSpecialization;
this.point = point;
} }
/** /**
* @param parameterMap mapping of template parameters to arguments, may be {@code null}. * @param parameterMap mapping of template parameters to arguments, may be {@code null}.
* @param contextSpecialization the specialization if instantiation happens inside a specialized * @param contextSpecialization the specialization if instantiation happens inside a specialized
* type or function, otherwise {@code null}. * type or function, otherwise {@code null}.
* @param point the point of instantiation
*/ */
public InstantiationContext(ICPPTemplateParameterMap parameterMap, public InstantiationContext(ICPPTemplateParameterMap parameterMap,
ICPPSpecialization contextSpecialization, IASTNode point) { ICPPSpecialization contextSpecialization) {
this(parameterMap, -1, contextSpecialization, point); this(parameterMap, -1, contextSpecialization);
} }
/** /**
* @param parameterMap mapping of template parameters to arguments, may be {@code null}. * @param parameterMap mapping of template parameters to arguments, may be {@code null}.
* @param packOffset parameter pack offset, or -1 if not known * @param packOffset parameter pack offset, or -1 if not known
* @param point the point of instantiation
*/ */
public InstantiationContext(ICPPTemplateParameterMap parameterMap, int packOffset, IASTNode point) { public InstantiationContext(ICPPTemplateParameterMap parameterMap, int packOffset) {
this(parameterMap, packOffset, null, point); this(parameterMap, packOffset, null);
} }
/** /**
* @param parameterMap mapping of template parameters to arguments, may be {@code null}. * @param parameterMap mapping of template parameters to arguments, may be {@code null}.
* @param point the point of instantiation
*/ */
public InstantiationContext(ICPPTemplateParameterMap parameterMap, IASTNode point) { public InstantiationContext(ICPPTemplateParameterMap parameterMap) {
this(parameterMap, -1, null, point); this(parameterMap, -1, null);
} }
/** /**
@ -146,13 +139,6 @@ public final class InstantiationContext {
return getContextClassSpecialization(contextSpecialization); return getContextClassSpecialization(contextSpecialization);
} }
/**
* Returns the point of instantiation
*/
public final IASTNode getPoint() {
return point;
}
/** /**
* Returns {@code true} if the pack offset is specified. * Returns {@code true} if the pack offset is specified.
*/ */

View file

@ -54,7 +54,12 @@ public class AccessContext {
* @return {@code true} if the binding is accessible. * @return {@code true} if the binding is accessible.
*/ */
public static boolean isAccessible(IBinding binding, IASTName from) { public static boolean isAccessible(IBinding binding, IASTName from) {
return new AccessContext(from).isAccessible(binding); CPPSemantics.pushLookupPoint(from);
try {
return new AccessContext(from).isAccessible(binding);
} finally {
CPPSemantics.popLookupPoint();
}
} }
/** /**
@ -67,7 +72,12 @@ public class AccessContext {
* @return {@code true} if the binding is accessible. * @return {@code true} if the binding is accessible.
*/ */
public static boolean isAccessible(IBinding binding, int bindingVisibility, IASTName from) { public static boolean isAccessible(IBinding binding, int bindingVisibility, IASTName from) {
return new AccessContext(from).isAccessible(binding, bindingVisibility); CPPSemantics.pushLookupPoint(from);
try {
return new AccessContext(from).isAccessible(binding, bindingVisibility);
} finally {
CPPSemantics.popLookupPoint();
}
} }
private final IASTName name; private final IASTName name;
@ -210,7 +220,7 @@ public class AccessContext {
return isAccessible(bindingVisibility, accessLevel); return isAccessible(bindingVisibility, accessLevel);
} }
ICPPUsingDeclaration[] usingDecls = ClassTypeHelper.getUsingDeclarations(derivedClass, name); ICPPUsingDeclaration[] usingDecls = derivedClass.getUsingDeclarations();
for (ICPPUsingDeclaration decl : usingDecls) { for (ICPPUsingDeclaration decl : usingDecls) {
for (IBinding delegate : decl.getDelegates()) { for (IBinding delegate : decl.getDelegates()) {
if (delegate.equals(binding)) { if (delegate.equals(binding)) {
@ -220,7 +230,7 @@ public class AccessContext {
} }
} }
ICPPBase[] bases = ClassTypeHelper.getBases(derivedClass, name); ICPPBase[] bases = derivedClass.getBases();
if (bases != null) { if (bases != null) {
for (ICPPBase base : bases) { for (ICPPBase base : bases) {
IBinding baseBinding = base.getBaseClass(); IBinding baseBinding = base.getBaseClass();
@ -273,7 +283,7 @@ public class AccessContext {
if (derived.isSameType(classType)) if (derived.isSameType(classType))
return true; return true;
ICPPBase[] bases = ClassTypeHelper.getBases(derived, name); ICPPBase[] bases = derived.getBases();
if (bases != null) { if (bases != null) {
for (ICPPBase base : bases) { for (ICPPBase base : bases) {
IBinding baseClass = base.getBaseClass(); IBinding baseClass = base.getBaseClass();
@ -303,8 +313,7 @@ public class AccessContext {
if (scope instanceof ICPPInternalUnknownScope) { if (scope instanceof ICPPInternalUnknownScope) {
IType scopeType = ((ICPPInternalUnknownScope) scope).getScopeType(); IType scopeType = ((ICPPInternalUnknownScope) scope).getScopeType();
if (scopeType instanceof ICPPUnknownType && isPrefixLookup) { if (scopeType instanceof ICPPUnknownType && isPrefixLookup) {
scopeType = HeuristicResolver.resolveUnknownType((ICPPUnknownType) scopeType, scopeType = HeuristicResolver.resolveUnknownType((ICPPUnknownType) scopeType);
name.getParent());
if (scopeType instanceof ICPPClassType) { if (scopeType instanceof ICPPClassType) {
return (ICPPClassType) scopeType; return (ICPPClassType) scopeType;
} }
@ -341,7 +350,7 @@ public class AccessContext {
return true; return true;
} }
if (maxdepth > 0) { if (maxdepth > 0) {
for (ICPPBase cppBase : ClassTypeHelper.getBases(derived, point)) { for (ICPPBase cppBase : derived.getBases()) {
IBinding base = cppBase.getBaseClass(); IBinding base = cppBase.getBaseClass();
if (!(target instanceof ICPPSpecialization)) { if (!(target instanceof ICPPSpecialization)) {
while (base instanceof ICPPSpecialization) { while (base instanceof ICPPSpecialization) {

View file

@ -38,7 +38,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalUnknownScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalUnknownScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
@ -215,7 +214,7 @@ class BaseClassLookup {
// its base classes. // its base classes.
ICPPClassType baseClass= result.getClassType(); ICPPClassType baseClass= result.getClassType();
if (baseClass != null) { if (baseClass != null) {
ICPPBase[] grandBases= ClassTypeHelper.getBases(baseClass, data.getLookupPoint()); ICPPBase[] grandBases= baseClass.getBases();
if (grandBases != null && grandBases.length > 0) { if (grandBases != null && grandBases.length > 0) {
HashSet<IBinding> grandBaseBindings= null; HashSet<IBinding> grandBaseBindings= null;
BitSet selectedBases= null; BitSet selectedBases= null;
@ -318,7 +317,7 @@ class BaseClassLookup {
if (fClassType != null) { if (fClassType != null) {
ICPPBase[] bases= null; ICPPBase[] bases= null;
bases= ClassTypeHelper.getBases(fClassType, fLookupPoint); bases= fClassType.getBases();
if (bases != null && bases.length > 0) { if (bases != null && bases.length > 0) {
for (ICPPBase base : bases) { for (ICPPBase base : bases) {
IBinding baseBinding = base.getBaseClass(); IBinding baseBinding = base.getBaseClass();

View file

@ -63,16 +63,15 @@ class BuiltinOperators {
private static final IType PTR_DIFF = new CPPBasicType(Kind.eInt, 0); private static final IType PTR_DIFF = new CPPBasicType(Kind.eInt, 0);
public static ICPPFunction[] create(OverloadableOperator operator, ICPPEvaluation[] args, public static ICPPFunction[] create(OverloadableOperator operator, ICPPEvaluation[] args,
IASTNode point, Object[] globCandidates) { Object[] globCandidates) {
if (operator == null || args == null || args.length == 0) if (operator == null || args == null || args.length == 0)
return EMPTY; return EMPTY;
return new BuiltinOperators(operator, args, point, globCandidates).create(); return new BuiltinOperators(operator, args, globCandidates).create();
} }
private final OverloadableOperator fOperator; private final OverloadableOperator fOperator;
private final boolean fUnary; private final boolean fUnary;
private final IASTNode fPoint;
private IType fType1; private IType fType1;
private IType fType2; private IType fType2;
private IType[][] fClassConversionTypes= { null, null }; private IType[][] fClassConversionTypes= { null, null };
@ -82,22 +81,22 @@ class BuiltinOperators {
private Set<String> fSignatures; private Set<String> fSignatures;
private Object[] fGlobalCandidates; private Object[] fGlobalCandidates;
BuiltinOperators(OverloadableOperator operator, ICPPEvaluation[] args, IASTNode point, BuiltinOperators(OverloadableOperator operator, ICPPEvaluation[] args,
Object[] globCandidates) { Object[] globCandidates) {
IASTNode point = CPPSemantics.getCurrentLookupPoint();
fFileScope= point == null ? fFileScope= point == null ?
new CPPScope.CPPScopeProblem(null, IProblemBinding.SEMANTIC_BAD_SCOPE) : new CPPScope.CPPScopeProblem(null, IProblemBinding.SEMANTIC_BAD_SCOPE) :
point.getTranslationUnit().getScope(); point.getTranslationUnit().getScope();
fOperator= operator; fOperator= operator;
fPoint = point;
fUnary= args.length < 2; fUnary= args.length < 2;
fGlobalCandidates= globCandidates; fGlobalCandidates= globCandidates;
if (args.length > 0) { if (args.length > 0) {
IType type= args[0].getType(point); IType type= args[0].getType();
if (!(type instanceof ISemanticProblem)) if (!(type instanceof ISemanticProblem))
fType1= type; fType1= type;
} }
if (args.length > 1) { if (args.length > 1) {
IType type= args[1].getType(point); IType type= args[1].getType();
if (!(type instanceof ISemanticProblem)) if (!(type instanceof ISemanticProblem))
fType2= type; fType2= type;
} }
@ -360,7 +359,7 @@ class BuiltinOperators {
IType t2= SemanticUtil.getNestedType(memPtr.getMemberOfClass(), TDEF); IType t2= SemanticUtil.getNestedType(memPtr.getMemberOfClass(), TDEF);
if (t2 instanceof ICPPClassType) { if (t2 instanceof ICPPClassType) {
ICPPClassType c2= (ICPPClassType) t2; ICPPClassType c2= (ICPPClassType) t2;
if (SemanticUtil.calculateInheritanceDepth(c1, c2, fPoint) >= 0) { if (SemanticUtil.calculateInheritanceDepth(c1, c2) >= 0) {
IType cvt= SemanticUtil.getNestedType(memPtr.getType(), TDEF); IType cvt= SemanticUtil.getNestedType(memPtr.getType(), TDEF);
IType rt= new CPPReferenceType( IType rt= new CPPReferenceType(
SemanticUtil.addQualifiers(cvt, cv1.isConst(), cv1.isVolatile(), cv1.isRestrict()), false); SemanticUtil.addQualifiers(cvt, cv1.isConst(), cv1.isVolatile(), cv1.isRestrict()), false);
@ -684,7 +683,7 @@ class BuiltinOperators {
if (type instanceof ICPPClassType) { if (type instanceof ICPPClassType) {
fIsClass[idx]= true; fIsClass[idx]= true;
try { try {
ICPPMethod[] ops = SemanticUtil.getConversionOperators((ICPPClassType) type, fPoint); ICPPMethod[] ops = SemanticUtil.getConversionOperators((ICPPClassType) type);
result= new IType[ops.length]; result= new IType[ops.length];
int j= -1; int j= -1;
for (ICPPMethod op : ops) { for (ICPPMethod op : ops) {

View file

@ -18,10 +18,10 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUti
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
@ -54,6 +54,24 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
} }
return buf.getSignature(); return buf.getSignature();
} }
public static IType getType(ICPPASTExpression expr) {
CPPSemantics.pushLookupPoint(expr);
try {
return expr.getEvaluation().getType();
} finally {
CPPSemantics.popLookupPoint();
}
}
public static ValueCategory getValueCategory(ICPPASTExpression expr) {
CPPSemantics.pushLookupPoint(expr);
try {
return expr.getEvaluation().getValueCategory();
} finally {
CPPSemantics.popLookupPoint();
}
}
protected static IBinding resolveUnknown(ICPPUnknownBinding unknown, InstantiationContext context) { protected static IBinding resolveUnknown(ICPPUnknownBinding unknown, InstantiationContext context) {
try { try {
@ -103,10 +121,9 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
* Checks if all evaluations contained in the given array are constant expressions. * Checks if all evaluations contained in the given array are constant expressions.
* *
* @param evaluations the evaluations to check * @param evaluations the evaluations to check
* @param point the point of instantiation
*/ */
protected static boolean areAllConstantExpressions(ICPPEvaluation[] evaluations, IASTNode point) { protected static boolean areAllConstantExpressions(ICPPEvaluation[] evaluations) {
return areAllConstantExpressions(evaluations, 0, evaluations.length, point); return areAllConstantExpressions(evaluations, 0, evaluations.length);
} }
/** /**
@ -115,19 +132,17 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
* @param evaluations the evaluations to check * @param evaluations the evaluations to check
* @param from the initial index of the range to be checked, inclusive * @param from the initial index of the range to be checked, inclusive
* @param to the final index of the range to be checked, exclusive * @param to the final index of the range to be checked, exclusive
* @param point the point of instantiation
*/ */
protected static boolean areAllConstantExpressions(ICPPEvaluation[] evaluations, int from, int to, protected static boolean areAllConstantExpressions(ICPPEvaluation[] evaluations, int from, int to) {
IASTNode point) {
for (int i = from; i < to; i++) { for (int i = from; i < to; i++) {
if (!evaluations[i].isConstantExpression(point)) { if (!evaluations[i].isConstantExpression()) {
return false; return false;
} }
} }
return true; return true;
} }
protected static boolean isConstexprValue(IValue value, IASTNode point) { protected static boolean isConstexprValue(IValue value) {
if (value == null) { if (value == null) {
return false; return false;
} }
@ -139,7 +154,7 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
return true; return true;
} }
} }
return innerEval.isConstantExpression(point); return innerEval.isConstantExpression();
} }
protected static boolean isNullOrConstexprFunc(ICPPFunction function) { protected static boolean isNullOrConstexprFunc(ICPPFunction function) {
@ -153,12 +168,11 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
* *
* @param argument the evaluation to convert * @param argument the evaluation to convert
* @param targetType the type to convert to * @param targetType the type to convert to
* @param point point of instantiation for name lookups
* @param allowContextualConversion enable/disable explicit contextual conversion * @param allowContextualConversion enable/disable explicit contextual conversion
*/ */
protected static ICPPEvaluation maybeApplyConversion(ICPPEvaluation argument, IType targetType, protected static ICPPEvaluation maybeApplyConversion(ICPPEvaluation argument, IType targetType,
IASTNode point, boolean allowContextualConversion) { boolean allowContextualConversion) {
IType type = argument.getType(point); IType type = argument.getType();
// Types match - don't bother to check for conversions. // Types match - don't bother to check for conversions.
if (targetType.isSameType(type)) { if (targetType.isSameType(type)) {
@ -168,16 +182,17 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
try { try {
// Source type is class type - check for conversion operator. // Source type is class type - check for conversion operator.
IType uqType= SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE); IType uqType= SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE);
ValueCategory valueCategory = argument.getValueCategory(point); ValueCategory valueCategory = argument.getValueCategory();
if (uqType instanceof ICPPClassType) { if (uqType instanceof ICPPClassType) {
Cost cost = Conversions.initializationByConversion(valueCategory, type, (ICPPClassType) uqType, Cost cost = Conversions.initializationByConversion(valueCategory, type, (ICPPClassType) uqType,
targetType, false, point, allowContextualConversion); targetType, false, allowContextualConversion);
ICPPFunction conversion = cost.getUserDefinedConversion(); ICPPFunction conversion = cost.getUserDefinedConversion();
if (conversion != null) { if (conversion != null) {
if (!conversion.isConstexpr()) { if (!conversion.isConstexpr()) {
return EvalFixed.INCOMPLETE; return EvalFixed.INCOMPLETE;
} }
ICPPEvaluation eval = new EvalMemberAccess(uqType, valueCategory, conversion, argument, false, point); ICPPEvaluation eval = new EvalMemberAccess(uqType, valueCategory, conversion, argument,
false, CPPSemantics.getCurrentLookupPoint());
return new EvalFunctionCall(new ICPPEvaluation[] { eval }, null, (IBinding) null); return new EvalFunctionCall(new ICPPEvaluation[] { eval }, null, (IBinding) null);
} }
} }
@ -185,7 +200,7 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
// Source type is not a class type, or is but a conversion operator wasn't used. // Source type is not a class type, or is but a conversion operator wasn't used.
// Check for standard conversions. // Check for standard conversions.
if (!Conversions.checkImplicitConversionSequence(targetType, type, valueCategory, UDCMode.FORBIDDEN, if (!Conversions.checkImplicitConversionSequence(targetType, type, valueCategory, UDCMode.FORBIDDEN,
Context.ORDINARY, point).converts()) { Context.ORDINARY).converts()) {
return EvalFixed.INCOMPLETE; return EvalFixed.INCOMPLETE;
} }
} catch (DOMException e) { } catch (DOMException e) {

View file

@ -121,12 +121,11 @@ public class CPPInheritance {
* Final overrider maps are cached in the AST. * Final overrider maps are cached in the AST.
* *
* @param classType the root of the class hierarchy * @param classType the root of the class hierarchy
* @param point The point of template instantiation, if applicable.
* Also used to access the cache in the AST.
* @return the computed final overrider map * @return the computed final overrider map
*/ */
public static FinalOverriderMap getFinalOverriderMap(ICPPClassType classType, IASTNode point) { public static FinalOverriderMap getFinalOverriderMap(ICPPClassType classType) {
Map<ICPPClassType, FinalOverriderMap> cache = null; Map<ICPPClassType, FinalOverriderMap> cache = null;
IASTNode point = CPPSemantics.getCurrentLookupPoint();
if (point != null && point.getTranslationUnit() instanceof CPPASTTranslationUnit) { if (point != null && point.getTranslationUnit() instanceof CPPASTTranslationUnit) {
cache = ((CPPASTTranslationUnit) point.getTranslationUnit()).getFinalOverriderMapCache(); cache = ((CPPASTTranslationUnit) point.getTranslationUnit()).getFinalOverriderMapCache();
} }
@ -135,7 +134,7 @@ public class CPPInheritance {
result = cache.get(classType); result = cache.get(classType);
} }
if (result == null) { if (result == null) {
result = FinalOverriderAnalysis.computeFinalOverriderMap(classType, point); result = FinalOverriderAnalysis.computeFinalOverriderMap(classType);
} }
if (cache != null) { if (cache != null) {
cache.put(classType, result); cache.put(classType, result);
@ -146,13 +145,9 @@ public class CPPInheritance {
/** /**
* If a given virtual method has a unique final overrider in the class hierarchy rooted at the * If a given virtual method has a unique final overrider in the class hierarchy rooted at the
* given class, returns that final overrider. Otherwise, returns null. * given class, returns that final overrider. Otherwise, returns null.
* @param point The point of template instantiation, if applicable.
* Also used to access the final overrider map cache in the AST.
*/ */
public static ICPPMethod getFinalOverrider(ICPPMethod method, ICPPClassType hierarchyRoot, public static ICPPMethod getFinalOverrider(ICPPMethod method, ICPPClassType hierarchyRoot) {
IASTNode point) { FinalOverriderMap map = getFinalOverriderMap(hierarchyRoot);
FinalOverriderMap map = getFinalOverriderMap(hierarchyRoot, point);
Map<Integer, List<ICPPMethod>> finalOverriders = map.getMap().get(method); Map<Integer, List<ICPPMethod>> finalOverriders = map.getMap().get(method);
if (finalOverriders != null && finalOverriders.size() == 1) { if (finalOverriders != null && finalOverriders.size() == 1) {
for (Integer subobjectNumber : finalOverriders.keySet()) { for (Integer subobjectNumber : finalOverriders.keySet()) {
@ -170,12 +165,11 @@ public class CPPInheritance {
* Computes the final overrider map for a class hierarchy. * Computes the final overrider map for a class hierarchy.
* *
* @param classType the root of the class hierarchy * @param classType the root of the class hierarchy
* @param point the point of template instantiation, if applicable
* @return the computed final overrider map * @return the computed final overrider map
*/ */
public static FinalOverriderMap computeFinalOverriderMap(ICPPClassType classType, IASTNode point) { public static FinalOverriderMap computeFinalOverriderMap(ICPPClassType classType) {
return new FinalOverriderAnalysis().collectFinalOverriders(classType, false, return new FinalOverriderAnalysis().collectFinalOverriders(classType, false,
new HashSet<ICPPClassType>(), CPPSemantics.MAX_INHERITANCE_DEPTH, point); new HashSet<ICPPClassType>(), CPPSemantics.MAX_INHERITANCE_DEPTH);
} }
// The last subobject number used for each type in the hierarchy. This is used to // The last subobject number used for each type in the hierarchy. This is used to
@ -196,11 +190,10 @@ public class CPPInheritance {
* @param isVirtualBase whether 'classType' is inherited virtually * @param isVirtualBase whether 'classType' is inherited virtually
* @param inheritanceChain the chain of classes from the entire hierarchy's root to 'classType'. * @param inheritanceChain the chain of classes from the entire hierarchy's root to 'classType'.
* This is used to guard against circular inheritance. * This is used to guard against circular inheritance.
* @param point the point of template instantiation, if applicable
* @return the computed final overrider map for the subtree * @return the computed final overrider map for the subtree
*/ */
private FinalOverriderMap collectFinalOverriders(ICPPClassType classType, boolean isVirtualBase, private FinalOverriderMap collectFinalOverriders(ICPPClassType classType, boolean isVirtualBase,
Set<ICPPClassType> inheritanceChain, int maxdepth, IASTNode point) { Set<ICPPClassType> inheritanceChain, int maxdepth) {
FinalOverriderMap result = new FinalOverriderMap(); FinalOverriderMap result = new FinalOverriderMap();
inheritanceChain.add(classType); inheritanceChain.add(classType);
@ -214,7 +207,7 @@ public class CPPInheritance {
} }
// Go through our base classes. // Go through our base classes.
for (ICPPBase base : ClassTypeHelper.getBases(classType, point)) { for (ICPPBase base : classType.getBases()) {
IBinding baseClass = base.getBaseClass(); IBinding baseClass = base.getBaseClass();
if (!(baseClass instanceof ICPPClassType)) if (!(baseClass instanceof ICPPClassType))
continue; continue;
@ -237,11 +230,11 @@ public class CPPInheritance {
if (base.isVirtual()) { if (base.isVirtual()) {
baseOverriderMap = virtualBaseCache.get(baseType); baseOverriderMap = virtualBaseCache.get(baseType);
if (baseOverriderMap == null) { if (baseOverriderMap == null) {
baseOverriderMap = collectFinalOverriders(baseType, true, inheritanceChain, maxdepth - 1, point); baseOverriderMap = collectFinalOverriders(baseType, true, inheritanceChain, maxdepth - 1);
virtualBaseCache.put(baseType, baseOverriderMap); virtualBaseCache.put(baseType, baseOverriderMap);
} }
} else { } else {
baseOverriderMap = collectFinalOverriders(baseType, false, inheritanceChain, maxdepth - 1, point); baseOverriderMap = collectFinalOverriders(baseType, false, inheritanceChain, maxdepth - 1);
} }
// Merge final overrider information from base class into this class. // Merge final overrider information from base class into this class.
@ -249,7 +242,7 @@ public class CPPInheritance {
} }
// Go through our own methods. // Go through our own methods.
for (ICPPMethod method : ClassTypeHelper.getOwnMethods(classType, point)) { for (ICPPMethod method : ClassTypeHelper.getOwnMethods(classType)) {
// Skip methods that don't actually belong to us, such as methods brought // Skip methods that don't actually belong to us, such as methods brought
// into scope via a using-declaration. // into scope via a using-declaration.
if (!(method.getOwner() instanceof ICPPClassType && if (!(method.getOwner() instanceof ICPPClassType &&
@ -263,7 +256,7 @@ public class CPPInheritance {
// Find all methods overridden by this method, and set their final overrider // Find all methods overridden by this method, and set their final overrider
// to be this method. // to be this method.
ICPPMethod[] overriddenMethods = ClassTypeHelper.findOverridden(method, point); ICPPMethod[] overriddenMethods = ClassTypeHelper.findOverridden(method);
for (ICPPMethod overriddenMethod : overriddenMethods) for (ICPPMethod overriddenMethod : overriddenMethods)
result.replaceForAllSubobjects(overriddenMethod, method); result.replaceForAllSubobjects(overriddenMethod, method);
} }

View file

@ -245,37 +245,37 @@ public class CPPTemplates {
/** /**
* Instantiates a class or variable template with the given arguments. May return {@code null}. * Instantiates a class or variable template with the given arguments. May return {@code null}.
*/ */
public static IBinding instantiate(ICPPPartiallySpecializable template, ICPPTemplateArgument[] args, IASTNode point) { public static IBinding instantiate(ICPPPartiallySpecializable template, ICPPTemplateArgument[] args) {
return instantiate(template, args, false, false, point); return instantiate(template, args, false, false);
} }
/** /**
* Instantiates a class template with the given arguments. May return {@code null}. * Instantiates a class template with the given arguments. May return {@code null}.
*/ */
private static IBinding instantiate(ICPPPartiallySpecializable template, ICPPTemplateArgument[] args, private static IBinding instantiate(ICPPPartiallySpecializable template, ICPPTemplateArgument[] args,
boolean isDefinition, boolean isExplicitSpecialization, IASTNode point) { boolean isDefinition, boolean isExplicitSpecialization) {
try { try {
ICPPTemplateArgument[] arguments= SemanticUtil.getSimplifiedArguments(args); ICPPTemplateArgument[] arguments= SemanticUtil.getSimplifiedArguments(args);
// Add default arguments, if necessary. // Add default arguments, if necessary.
arguments= addDefaultArguments(template, arguments, point); arguments= addDefaultArguments(template, arguments);
if (arguments == null) if (arguments == null)
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, point); return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS);
if (template instanceof ICPPTemplateTemplateParameter || hasDependentArgument(arguments)) { if (template instanceof ICPPTemplateTemplateParameter || hasDependentArgument(arguments)) {
return deferredInstance(template, arguments, point); return deferredInstance(template, arguments);
} }
if (template instanceof ICPPClassTemplatePartialSpecialization) { if (template instanceof ICPPClassTemplatePartialSpecialization) {
return instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) template, return instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) template,
arguments, isDefinition, null, point); arguments, isDefinition, null);
} }
if (arguments == args) { if (arguments == args) {
arguments= args.clone(); // The createParameterMap call may modify the arguments array. arguments= args.clone(); // The createParameterMap call may modify the arguments array.
} }
CPPTemplateParameterMap map = createParameterMap(template, arguments, point); CPPTemplateParameterMap map = createParameterMap(template, arguments);
if (map == null) { if (map == null) {
return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, point); return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS);
} }
ICPPTemplateInstance prim= getInstance(template, arguments, isDefinition); ICPPTemplateInstance prim= getInstance(template, arguments, isDefinition);
@ -283,12 +283,12 @@ public class CPPTemplates {
return prim; return prim;
if (!isExplicitSpecialization) { if (!isExplicitSpecialization) {
IBinding result= selectSpecialization(template, arguments, isDefinition, point); IBinding result= selectSpecialization(template, arguments, isDefinition);
if (result != null) if (result != null)
return result; return result;
} }
return instantiatePrimaryTemplate(template, arguments, new InstantiationContext(map, point), return instantiatePrimaryTemplate(template, arguments, new InstantiationContext(map),
isDefinition); isDefinition);
} catch (DOMException e) { } catch (DOMException e) {
return e.getProblem(); return e.getProblem();
@ -299,26 +299,26 @@ public class CPPTemplates {
* Instantiates an alias template with the given arguments. * Instantiates an alias template with the given arguments.
*/ */
public static IBinding instantiateAliasTemplate(ICPPAliasTemplate aliasTemplate, public static IBinding instantiateAliasTemplate(ICPPAliasTemplate aliasTemplate,
ICPPTemplateArgument[] args, IASTNode point) { ICPPTemplateArgument[] args) {
try { try {
args = addDefaultArguments(aliasTemplate, args, point); args = addDefaultArguments(aliasTemplate, args);
if (args == null) { if (args == null) {
return createProblem(aliasTemplate, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, point); return createProblem(aliasTemplate, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS);
} }
ICPPTemplateParameterMap parameterMap = createParameterMap(aliasTemplate, args, point); ICPPTemplateParameterMap parameterMap = createParameterMap(aliasTemplate, args);
if (parameterMap == null) { if (parameterMap == null) {
return createProblem(aliasTemplate, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, point); return createProblem(aliasTemplate, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS);
} }
IType aliasedType = aliasTemplate.getType(); IType aliasedType = aliasTemplate.getType();
IBinding owner = aliasTemplate.getOwner(); IBinding owner = aliasTemplate.getOwner();
return createAliasTemplaceInstance(aliasTemplate, args, parameterMap, aliasedType, owner, point); return createAliasTemplaceInstance(aliasTemplate, args, parameterMap, aliasedType, owner);
} catch (DOMException e) { } catch (DOMException e) {
return e.getProblem(); return e.getProblem();
} }
} }
private static IBinding createProblem(ICPPTemplateDefinition template, int id, IASTNode point) { private static IBinding createProblem(ICPPTemplateDefinition template, int id) {
return new ProblemBinding(point, id, template.getNameCharArray()); return new ProblemBinding(CPPSemantics.getCurrentLookupPoint(), id, template.getNameCharArray());
} }
static IBinding isUsedInClassTemplateScope(ICPPClassTemplate ct, IASTName name) { static IBinding isUsedInClassTemplateScope(ICPPClassTemplate ct, IASTName name) {
@ -390,7 +390,7 @@ public class CPPTemplates {
} }
private static IBinding instantiateFunctionTemplate(ICPPFunctionTemplate template, private static IBinding instantiateFunctionTemplate(ICPPFunctionTemplate template,
ICPPTemplateArgument[] arguments, CPPTemplateParameterMap tpMap, IASTNode point) ICPPTemplateArgument[] arguments, CPPTemplateParameterMap tpMap)
throws DOMException { throws DOMException {
ICPPTemplateInstance instance= getInstance(template, arguments, false); ICPPTemplateInstance instance= getInstance(template, arguments, false);
if (instance != null) { if (instance != null) {
@ -398,7 +398,7 @@ public class CPPTemplates {
} }
IBinding owner= template.getOwner(); IBinding owner= template.getOwner();
instance = createInstance(owner, template, tpMap, arguments, point); instance = createInstance(owner, template, tpMap, arguments);
if (instance instanceof ICPPFunction && SemanticUtil.isValidType(((ICPPFunction) instance).getType())) { if (instance instanceof ICPPFunction && SemanticUtil.isValidType(((ICPPFunction) instance).getType())) {
addInstance(template, arguments, instance); addInstance(template, arguments, instance);
} }
@ -409,7 +409,7 @@ public class CPPTemplates {
* Instantiates a partial class template specialization. * Instantiates a partial class template specialization.
*/ */
private static IBinding instantiatePartialSpecialization(ICPPPartialSpecialization partialSpec, private static IBinding instantiatePartialSpecialization(ICPPPartialSpecialization partialSpec,
ICPPTemplateArgument[] args, boolean isDef, CPPTemplateParameterMap tpMap, IASTNode point) ICPPTemplateArgument[] args, boolean isDef, CPPTemplateParameterMap tpMap)
throws DOMException { throws DOMException {
ICPPTemplateInstance instance= getInstance(partialSpec, args, isDef); ICPPTemplateInstance instance= getInstance(partialSpec, args, isDef);
if (instance != null) if (instance != null)
@ -418,12 +418,12 @@ public class CPPTemplates {
if (tpMap == null) { if (tpMap == null) {
tpMap = new CPPTemplateParameterMap(args.length); tpMap = new CPPTemplateParameterMap(args.length);
if (!TemplateArgumentDeduction.fromTemplateArguments(partialSpec.getTemplateParameters(), if (!TemplateArgumentDeduction.fromTemplateArguments(partialSpec.getTemplateParameters(),
partialSpec.getTemplateArguments(), args, tpMap, point)) { partialSpec.getTemplateArguments(), args, tpMap)) {
return null; return null;
} }
} }
instance= createInstance(partialSpec.getOwner(), partialSpec, tpMap, args, point); instance= createInstance(partialSpec.getOwner(), partialSpec, tpMap, args);
addInstance(partialSpec, args, instance); addInstance(partialSpec, args, instance);
return instance; return instance;
} }
@ -441,7 +441,7 @@ public class CPPTemplates {
} }
IBinding owner= template.getOwner(); IBinding owner= template.getOwner();
instance = createInstance(owner, template, context.getParameterMap(), arguments, context.getPoint()); instance = createInstance(owner, template, context.getParameterMap(), arguments);
addInstance(template, arguments, instance); addInstance(template, arguments, instance);
return instance; return instance;
} }
@ -481,7 +481,7 @@ public class CPPTemplates {
} }
private static IBinding deferredInstance(ICPPPartiallySpecializable template, private static IBinding deferredInstance(ICPPPartiallySpecializable template,
ICPPTemplateArgument[] arguments, IASTNode point) throws DOMException { ICPPTemplateArgument[] arguments) throws DOMException {
ICPPTemplateInstance instance= getInstance(template, arguments, false); ICPPTemplateInstance instance= getInstance(template, arguments, false);
if (instance != null) if (instance != null)
return instance; return instance;
@ -498,7 +498,7 @@ public class CPPTemplates {
} }
private static ICPPTemplateArgument[] addDefaultArguments(ICPPTemplateDefinition template, private static ICPPTemplateArgument[] addDefaultArguments(ICPPTemplateDefinition template,
ICPPTemplateArgument[] arguments, IASTNode point) throws DOMException { ICPPTemplateArgument[] arguments) throws DOMException {
if (template instanceof ICPPClassTemplatePartialSpecialization) if (template instanceof ICPPClassTemplatePartialSpecialization)
return arguments; return arguments;
@ -546,7 +546,7 @@ public class CPPTemplates {
ICPPTemplateArgument[] completeArgs= new ICPPTemplateArgument[tparCount]; ICPPTemplateArgument[] completeArgs= new ICPPTemplateArgument[tparCount];
CPPTemplateParameterMap map= new CPPTemplateParameterMap(tparCount); CPPTemplateParameterMap map= new CPPTemplateParameterMap(tparCount);
InstantiationContext context = new InstantiationContext(map, point); InstantiationContext context = new InstantiationContext(map);
for (int i = 0; i < tparCount; i++) { for (int i = 0; i < tparCount; i++) {
final ICPPTemplateParameter tpar = tpars[i]; final ICPPTemplateParameter tpar = tpars[i];
if (tpar.isParameterPack()) { if (tpar.isParameterPack()) {
@ -753,6 +753,7 @@ public class CPPTemplates {
} }
} }
} }
CPPSemantics.pushLookupPoint(id);
try { try {
IBinding result= null; IBinding result= null;
IASTName templateName = id.getTemplateName(); IASTName templateName = id.getTemplateName();
@ -766,7 +767,7 @@ public class CPPTemplates {
if (template instanceof ICPPAliasTemplate) { if (template instanceof ICPPAliasTemplate) {
ICPPAliasTemplate aliasTemplate = (ICPPAliasTemplate) template; ICPPAliasTemplate aliasTemplate = (ICPPAliasTemplate) template;
ICPPTemplateArgument[] args = createTemplateArgumentArray(id); ICPPTemplateArgument[] args = createTemplateArgumentArray(id);
return instantiateAliasTemplate(aliasTemplate, args, id); return instantiateAliasTemplate(aliasTemplate, args);
} }
// Class or variable template. // Class or variable template.
@ -792,7 +793,7 @@ public class CPPTemplates {
if (argsAreTrivial(classTemplate.getTemplateParameters(), args)) { if (argsAreTrivial(classTemplate.getTemplateParameters(), args)) {
result= classTemplate; result= classTemplate;
} else { } else {
args= addDefaultArguments(classTemplate, args, id); args= addDefaultArguments(classTemplate, args);
if (args == null) { if (args == null) {
return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, templateName.toCharArray()); return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, templateName.toCharArray());
} }
@ -832,7 +833,7 @@ public class CPPTemplates {
} }
} }
if (result == null) { if (result == null) {
result= instantiate(classTemplate, args, isDefinition, isExplicitSpecialization, id); result= instantiate(classTemplate, args, isDefinition, isExplicitSpecialization);
if (result instanceof ICPPInternalBinding) { if (result instanceof ICPPInternalBinding) {
if (isDeclaration) { if (isDeclaration) {
ASTInternal.addDeclaration(result, id); ASTInternal.addDeclaration(result, id);
@ -844,13 +845,15 @@ public class CPPTemplates {
return CPPSemantics.postResolution(result, id); return CPPSemantics.postResolution(result, id);
} catch (DOMException e) { } catch (DOMException e) {
return e.getProblem(); return e.getProblem();
} finally {
CPPSemantics.popLookupPoint();
} }
} }
private static IBinding createAliasTemplaceInstance(ICPPAliasTemplate aliasTemplate, private static IBinding createAliasTemplaceInstance(ICPPAliasTemplate aliasTemplate,
ICPPTemplateArgument[] args, ICPPTemplateParameterMap parameterMap, IType aliasedType, ICPPTemplateArgument[] args, ICPPTemplateParameterMap parameterMap, IType aliasedType,
IBinding owner, IASTNode point) { IBinding owner) {
InstantiationContext context = createInstantiationContext(parameterMap, owner, point); InstantiationContext context = createInstantiationContext(parameterMap, owner);
IType instantiatedType = instantiateType(aliasedType, context); IType instantiatedType = instantiateType(aliasedType, context);
return new CPPAliasTemplateInstance(aliasTemplate, instantiatedType, owner, parameterMap, args); return new CPPAliasTemplateInstance(aliasTemplate, instantiatedType, owner, parameterMap, args);
} }
@ -879,7 +882,7 @@ public class CPPTemplates {
} }
public static ICPPTemplateInstance createInstance(IBinding owner, ICPPTemplateDefinition template, public static ICPPTemplateInstance createInstance(IBinding owner, ICPPTemplateDefinition template,
ICPPTemplateParameterMap tpMap, ICPPTemplateArgument[] args, IASTNode point) { ICPPTemplateParameterMap tpMap, ICPPTemplateArgument[] args) {
if (owner instanceof ICPPSpecialization) { if (owner instanceof ICPPSpecialization) {
ICPPTemplateParameterMap map= ((ICPPSpecialization) owner).getTemplateParameterMap(); ICPPTemplateParameterMap map= ((ICPPSpecialization) owner).getTemplateParameterMap();
if (map != null) { if (map != null) {
@ -892,7 +895,7 @@ public class CPPTemplates {
instance = new CPPClassInstance((ICPPClassType) template, owner, tpMap, args); instance = new CPPClassInstance((ICPPClassType) template, owner, tpMap, args);
} else if (template instanceof ICPPFunction) { } else if (template instanceof ICPPFunction) {
ICPPFunction func= (ICPPFunction) template; ICPPFunction func= (ICPPFunction) template;
InstantiationContext context = createInstantiationContext(tpMap, owner, point); InstantiationContext context = createInstantiationContext(tpMap, owner);
ICPPFunctionType type= (ICPPFunctionType) instantiateType(func.getType(), context); ICPPFunctionType type= (ICPPFunctionType) instantiateType(func.getType(), context);
IType[] exceptionSpecs= instantiateTypes(func.getExceptionSpecification(), context); IType[] exceptionSpecs= instantiateTypes(func.getExceptionSpecification(), context);
CPPFunctionSpecialization spec; CPPFunctionSpecialization spec;
@ -911,10 +914,11 @@ public class CPPTemplates {
instance = (ICPPTemplateInstance) spec; instance = (ICPPTemplateInstance) spec;
} else if (template instanceof ICPPVariable) { } else if (template instanceof ICPPVariable) {
ICPPVariable var = (ICPPVariable) template; ICPPVariable var = (ICPPVariable) template;
InstantiationContext context = createInstantiationContext(tpMap, owner, point); InstantiationContext context = createInstantiationContext(tpMap, owner);
IType type = instantiateType(var.getType(), context); IType type = instantiateType(var.getType(), context);
IValue value; IValue value;
IASTNode point = CPPSemantics.getCurrentLookupPoint();
ICPPASTDeclarator decl = ASTQueries.findAncestorWithType(point, ICPPASTDeclarator.class); ICPPASTDeclarator decl = ASTQueries.findAncestorWithType(point, ICPPASTDeclarator.class);
if (point instanceof IASTName && ((IASTName) point).getRoleOfName(false) == IASTNameOwner.r_definition if (point instanceof IASTName && ((IASTName) point).getRoleOfName(false) == IASTNameOwner.r_definition
&& decl != null && decl.getInitializer() != null) { && decl != null && decl.getInitializer() != null) {
@ -972,7 +976,7 @@ public class CPPTemplates {
return newVariable; return newVariable;
} }
public static IBinding createSpecialization(ICPPSpecialization owner, IBinding decl, IASTNode point) { public static IBinding createSpecialization(ICPPSpecialization owner, IBinding decl) {
IBinding spec = null; IBinding spec = null;
final ICPPTemplateParameterMap tpMap= owner.getTemplateParameterMap(); final ICPPTemplateParameterMap tpMap= owner.getTemplateParameterMap();
final ICPPClassSpecialization classOwner = (owner instanceof ICPPClassSpecialization) ? (ICPPClassSpecialization) owner : null; final ICPPClassSpecialization classOwner = (owner instanceof ICPPClassSpecialization) ? (ICPPClassSpecialization) owner : null;
@ -980,7 +984,7 @@ public class CPPTemplates {
// Guard against infinite recursion during template instantiation with a depth limit. // Guard against infinite recursion during template instantiation with a depth limit.
int instantiationDepth = fTemplateInstantiationDepth.get(); int instantiationDepth = fTemplateInstantiationDepth.get();
if (instantiationDepth > TEMPLATE_INSTANTIATION_DEPTH_LIMIT) { if (instantiationDepth > TEMPLATE_INSTANTIATION_DEPTH_LIMIT) {
return RecursionResolvingBinding.createFor(decl, point); return RecursionResolvingBinding.createFor(decl);
} }
// Increment the instantiation depth for the duration of this call. // Increment the instantiation depth for the duration of this call.
fTemplateInstantiationDepth.set(instantiationDepth + 1); fTemplateInstantiationDepth.set(instantiationDepth + 1);
@ -992,8 +996,8 @@ public class CPPTemplates {
ICPPClassTemplate template= pspec.getPrimaryClassTemplate(); ICPPClassTemplate template= pspec.getPrimaryClassTemplate();
ICPPTemplateArgument[] args = pspec.getTemplateArguments(); ICPPTemplateArgument[] args = pspec.getTemplateArguments();
template= (ICPPClassTemplate) classOwner.specializeMember(template, point); template= (ICPPClassTemplate) classOwner.specializeMember(template);
InstantiationContext context = createInstantiationContext(tpMap, owner, point); InstantiationContext context = createInstantiationContext(tpMap, owner);
args= instantiateArguments(args, context, false); args= instantiateArguments(args, context, false);
spec= new CPPClassTemplatePartialSpecializationSpecialization(pspec, tpMap, template, args); spec= new CPPClassTemplatePartialSpecializationSpecialization(pspec, tpMap, template, args);
} catch (DOMException e) { } catch (DOMException e) {
@ -1002,7 +1006,7 @@ public class CPPTemplates {
ICPPClassTemplate template = (ICPPClassTemplate) decl; ICPPClassTemplate template = (ICPPClassTemplate) decl;
CPPClassTemplateSpecialization classTemplateSpec = new CPPClassTemplateSpecialization(template, classOwner, tpMap); CPPClassTemplateSpecialization classTemplateSpec = new CPPClassTemplateSpecialization(template, classOwner, tpMap);
classTemplateSpec.setTemplateParameters(specializeTemplateParameters(classTemplateSpec, classTemplateSpec.setTemplateParameters(specializeTemplateParameters(classTemplateSpec,
(ICPPScope) classTemplateSpec.getScope(), template.getTemplateParameters(), classOwner, point)); (ICPPScope) classTemplateSpec.getScope(), template.getTemplateParameters(), classOwner));
spec = classTemplateSpec; spec = classTemplateSpec;
} else if (decl instanceof ICPPClassType && classOwner != null) { } else if (decl instanceof ICPPClassType && classOwner != null) {
// TODO: Handle local classes // TODO: Handle local classes
@ -1014,7 +1018,7 @@ public class CPPTemplates {
} }
} else if (decl instanceof ICPPField && classOwner != null) { } else if (decl instanceof ICPPField && classOwner != null) {
ICPPField field= (ICPPField) decl; ICPPField field= (ICPPField) decl;
InstantiationContext context = createInstantiationContext(tpMap, owner, point); InstantiationContext context = createInstantiationContext(tpMap, owner);
IType type= instantiateType(field.getType(), context); IType type= instantiateType(field.getType(), context);
IValue value= instantiateValue(field.getInitialValue(), context, IntegralValue.MAX_RECURSION_DEPTH); IValue value= instantiateValue(field.getInitialValue(), context, IntegralValue.MAX_RECURSION_DEPTH);
if (decl instanceof ICPPFieldTemplate) { if (decl instanceof ICPPFieldTemplate) {
@ -1022,7 +1026,7 @@ public class CPPTemplates {
classOwner, tpMap, type, value); classOwner, tpMap, type, value);
ICPPTemplateParameter[] params = specializeTemplateParameters(fieldTempSpec, ICPPTemplateParameter[] params = specializeTemplateParameters(fieldTempSpec,
(ICPPScope) fieldTempSpec.getScope(), (ICPPScope) fieldTempSpec.getScope(),
((ICPPFieldTemplate) decl).getTemplateParameters(), classOwner, point); ((ICPPFieldTemplate) decl).getTemplateParameters(), classOwner);
fieldTempSpec.setTemplateParameters(params); fieldTempSpec.setTemplateParameters(params);
spec = fieldTempSpec; spec = fieldTempSpec;
} else { } else {
@ -1030,7 +1034,7 @@ public class CPPTemplates {
} }
} else if (decl instanceof ICPPFunction) { } else if (decl instanceof ICPPFunction) {
ICPPFunction func= (ICPPFunction) decl; ICPPFunction func= (ICPPFunction) decl;
InstantiationContext context = createInstantiationContext(tpMap, owner, point); InstantiationContext context = createInstantiationContext(tpMap, owner);
ICPPFunctionType type= (ICPPFunctionType) instantiateType(func.getType(), context); ICPPFunctionType type= (ICPPFunctionType) instantiateType(func.getType(), context);
IType[] exceptionSpecs= instantiateTypes(func.getExceptionSpecification(), context); IType[] exceptionSpecs= instantiateTypes(func.getExceptionSpecification(), context);
@ -1047,7 +1051,7 @@ public class CPPTemplates {
} }
methodSpec.setTemplateParameters(specializeTemplateParameters(methodSpec, methodSpec.setTemplateParameters(specializeTemplateParameters(methodSpec,
(ICPPScope) methodSpec.getScope(), (ICPPScope) methodSpec.getScope(),
((ICPPFunctionTemplate) decl).getTemplateParameters(), classOwner, point)); ((ICPPFunctionTemplate) decl).getTemplateParameters(), classOwner));
functionSpec = methodSpec; functionSpec = methodSpec;
} else { } else {
IBinding oldOwner = decl.getOwner(); IBinding oldOwner = decl.getOwner();
@ -1075,33 +1079,32 @@ public class CPPTemplates {
spec = functionSpec; spec = functionSpec;
} }
} else if (decl instanceof ITypedef) { } else if (decl instanceof ITypedef) {
InstantiationContext context = createInstantiationContext(tpMap, owner, point); InstantiationContext context = createInstantiationContext(tpMap, owner);
IType type= instantiateType(((ITypedef) decl).getType(), context); IType type= instantiateType(((ITypedef) decl).getType(), context);
spec = new CPPTypedefSpecialization(decl, owner, tpMap, type); spec = new CPPTypedefSpecialization(decl, owner, tpMap, type);
} else if (decl instanceof ICPPAliasTemplate) { } else if (decl instanceof ICPPAliasTemplate) {
ICPPAliasTemplate aliasTemplate = (ICPPAliasTemplate) decl; ICPPAliasTemplate aliasTemplate = (ICPPAliasTemplate) decl;
InstantiationContext context = createInstantiationContext(tpMap, owner, point); InstantiationContext context = createInstantiationContext(tpMap, owner);
IType type= instantiateType(aliasTemplate.getType(), context); IType type= instantiateType(aliasTemplate.getType(), context);
CPPAliasTemplateSpecialization aliasSpec = CPPAliasTemplateSpecialization aliasSpec =
new CPPAliasTemplateSpecialization(aliasTemplate, owner, tpMap, type); new CPPAliasTemplateSpecialization(aliasTemplate, owner, tpMap, type);
aliasSpec.setTemplateParameters(specializeTemplateParameters(aliasSpec, aliasSpec.setTemplateParameters(specializeTemplateParameters(aliasSpec,
(ICPPScope) aliasSpec.getScope(), aliasTemplate.getTemplateParameters(), classOwner, (ICPPScope) aliasSpec.getScope(), aliasTemplate.getTemplateParameters(), classOwner));
point));
spec = aliasSpec; spec = aliasSpec;
} else if (decl instanceof ICPPEnumeration && classOwner != null) { } else if (decl instanceof ICPPEnumeration && classOwner != null) {
// TODO: Handle local enumerations // TODO: Handle local enumerations
spec = CPPEnumerationSpecialization.createInstance((ICPPEnumeration) decl, classOwner, tpMap, point); spec = CPPEnumerationSpecialization.createInstance((ICPPEnumeration) decl, classOwner, tpMap);
} else if (decl instanceof IEnumerator && classOwner != null) { } else if (decl instanceof IEnumerator && classOwner != null) {
IEnumerator enumerator = (IEnumerator) decl; IEnumerator enumerator = (IEnumerator) decl;
ICPPEnumeration enumeration = (ICPPEnumeration) enumerator.getOwner(); ICPPEnumeration enumeration = (ICPPEnumeration) enumerator.getOwner();
IBinding enumSpec = classOwner.specializeMember(enumeration, point); IBinding enumSpec = classOwner.specializeMember(enumeration);
if (enumSpec instanceof ICPPEnumerationSpecialization) { if (enumSpec instanceof ICPPEnumerationSpecialization) {
spec = ((ICPPEnumerationSpecialization) enumSpec).specializeEnumerator(enumerator); spec = ((ICPPEnumerationSpecialization) enumSpec).specializeEnumerator(enumerator);
} }
} else if (decl instanceof ICPPUsingDeclaration) { } else if (decl instanceof ICPPUsingDeclaration) {
IBinding[] delegates= ((ICPPUsingDeclaration) decl).getDelegates(); IBinding[] delegates= ((ICPPUsingDeclaration) decl).getDelegates();
List<IBinding> result= new ArrayList<>(); List<IBinding> result= new ArrayList<>();
InstantiationContext context = createInstantiationContext(tpMap, owner, point); InstantiationContext context = createInstantiationContext(tpMap, owner);
for (IBinding delegate : delegates) { for (IBinding delegate : delegates) {
try { try {
if (delegate instanceof ICPPUnknownBinding) { if (delegate instanceof ICPPUnknownBinding) {
@ -1130,8 +1133,8 @@ public class CPPTemplates {
} }
private static InstantiationContext createInstantiationContext(ICPPTemplateParameterMap tpMap, private static InstantiationContext createInstantiationContext(ICPPTemplateParameterMap tpMap,
IBinding owner, IASTNode point) { IBinding owner) {
return new InstantiationContext(tpMap, getSpecializationContext(owner), point); return new InstantiationContext(tpMap, getSpecializationContext(owner));
} }
public static ICPPClassSpecialization getSpecializationContext(IBinding owner) { public static ICPPClassSpecialization getSpecializationContext(IBinding owner) {
@ -1161,7 +1164,7 @@ public class CPPTemplates {
ICPPEvaluation instantiated = evaluation.instantiate(context, maxDepth); ICPPEvaluation instantiated = evaluation.instantiate(context, maxDepth);
if (instantiated == evaluation) if (instantiated == evaluation)
return value; return value;
return instantiated.getValue(context.getPoint()); return instantiated.getValue();
} }
public static boolean containsParameterPack(IType type) { public static boolean containsParameterPack(IType type) {
@ -1292,7 +1295,8 @@ public class CPPTemplates {
IType innerType= ((ICPPParameterPackType) origType).getType(); IType innerType= ((ICPPParameterPackType) origType).getType();
int packSize= determinePackSize(innerType, context.getParameterMap()); int packSize= determinePackSize(innerType, context.getParameterMap());
if (packSize == PACK_SIZE_FAIL || packSize == PACK_SIZE_NOT_FOUND) { if (packSize == PACK_SIZE_FAIL || packSize == PACK_SIZE_NOT_FOUND) {
newType= new ProblemBinding(context.getPoint(), IProblemBinding.SEMANTIC_INVALID_TYPE, newType= new ProblemBinding(CPPSemantics.getCurrentLookupPoint(),
IProblemBinding.SEMANTIC_INVALID_TYPE,
types[i] instanceof IBinding ? ((IBinding) types[i]).getNameCharArray() : null); types[i] instanceof IBinding ? ((IBinding) types[i]).getNameCharArray() : null);
} else if (packSize == PACK_SIZE_DEFER) { } else if (packSize == PACK_SIZE_DEFER) {
newType= origType; newType= origType;
@ -1332,7 +1336,8 @@ public class CPPTemplates {
* {@code false}, any invalid instantiated arguments are replaced by the corresponding original * {@code false}, any invalid instantiated arguments are replaced by the corresponding original
* arguments. * arguments.
*/ */
public static ICPPTemplateArgument[] instantiateArguments(ICPPTemplateArgument[] args, InstantiationContext context, boolean strict) throws DOMException { public static ICPPTemplateArgument[] instantiateArguments(ICPPTemplateArgument[] args,
InstantiationContext context, boolean strict) throws DOMException {
// Don't create a new array until it's really needed. // Don't create a new array until it's really needed.
ICPPTemplateArgument[] result = args; ICPPTemplateArgument[] result = args;
int resultShift= 0; int resultShift= 0;
@ -1343,7 +1348,7 @@ public class CPPTemplates {
ICPPTemplateArgument pattern= origArg.getExpansionPattern(); ICPPTemplateArgument pattern= origArg.getExpansionPattern();
int packSize= determinePackSize(pattern, context.getParameterMap()); int packSize= determinePackSize(pattern, context.getParameterMap());
if (packSize == PACK_SIZE_FAIL || packSize == PACK_SIZE_NOT_FOUND) { if (packSize == PACK_SIZE_FAIL || packSize == PACK_SIZE_NOT_FOUND) {
throw new DOMException(new ProblemBinding(context.getPoint(), throw new DOMException(new ProblemBinding(CPPSemantics.getCurrentLookupPoint(),
IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, null)); IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, null));
} else if (packSize == PACK_SIZE_DEFER) { } else if (packSize == PACK_SIZE_DEFER) {
newArg= origArg; newArg= origArg;
@ -1414,7 +1419,7 @@ public class CPPTemplates {
final ICPPEvaluation newEval= eval.instantiate(context, IntegralValue.MAX_RECURSION_DEPTH); final ICPPEvaluation newEval= eval.instantiate(context, IntegralValue.MAX_RECURSION_DEPTH);
if (eval == newEval) if (eval == newEval)
return arg; return arg;
return new CPPTemplateNonTypeArgument(newEval, context.getPoint()); return new CPPTemplateNonTypeArgument(newEval);
} }
// Which to instantiate, getOriginalTypeValue() or getTypeValue()? // Which to instantiate, getOriginalTypeValue() or getTypeValue()?
@ -1523,9 +1528,9 @@ public class CPPTemplates {
ICPPEvaluation instantiated = eval.instantiate(context, IntegralValue.MAX_RECURSION_DEPTH); ICPPEvaluation instantiated = eval.instantiate(context, IntegralValue.MAX_RECURSION_DEPTH);
if (instantiated != eval) { if (instantiated != eval) {
if (dependentType.isForDecltype()) { if (dependentType.isForDecltype()) {
return CPPSemantics.getDeclTypeForEvaluation(instantiated, context.getPoint()); return CPPSemantics.getDeclTypeForEvaluation(instantiated);
} else { } else {
return instantiated.getType(context.getPoint()); return instantiated.getType();
} }
} }
} else { } else {
@ -1572,7 +1577,7 @@ public class CPPTemplates {
} }
if (newOwner != owner && newOwner instanceof ICPPClassSpecialization) { if (newOwner != owner && newOwner instanceof ICPPClassSpecialization) {
return (IType) ((ICPPClassSpecialization) newOwner).specializeMember(typeAsBinding, context.getPoint()); return (IType) ((ICPPClassSpecialization) newOwner).specializeMember(typeAsBinding);
} }
} }
} }
@ -1587,7 +1592,7 @@ public class CPPTemplates {
ICPPTemplateArgument[] newArgs = instantiateArguments(args, context, true); ICPPTemplateArgument[] newArgs = instantiateArguments(args, context, true);
if (newArgs == null) { if (newArgs == null) {
return (IType) createProblem(template, return (IType) createProblem(template,
IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, context.getPoint()); IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS);
} }
if (args != newArgs) { if (args != newArgs) {
IType target = instantiateType(instance.getType(), context); IType target = instantiateType(instance.getType(), context);
@ -1660,15 +1665,14 @@ public class CPPTemplates {
* @param scope the scope of the nested template specialization * @param scope the scope of the nested template specialization
* @param specialized the template parameter to be specialized * @param specialized the template parameter to be specialized
* @param within the specialization of the enclosing class * @param within the specialization of the enclosing class
* @param point the point of template instantiation
* @return the specialized template parameter * @return the specialized template parameter
*/ */
public static ICPPTemplateParameter specializeTemplateParameter(ICPPSpecialization owner, ICPPScope scope, public static ICPPTemplateParameter specializeTemplateParameter(ICPPSpecialization owner, ICPPScope scope,
ICPPTemplateParameter specialized, ICPPClassSpecialization within, IASTNode point) { ICPPTemplateParameter specialized, ICPPClassSpecialization within) {
if (specialized == null) if (specialized == null)
return null; return null;
ICPPTemplateParameterMap tpMap = owner.getTemplateParameterMap(); ICPPTemplateParameterMap tpMap = owner.getTemplateParameterMap();
InstantiationContext context = new InstantiationContext(tpMap, 0, within, point); InstantiationContext context = new InstantiationContext(tpMap, 0, within);
ICPPTemplateArgument defaultValue = instantiateArgument(specialized.getDefaultValue(), context); ICPPTemplateArgument defaultValue = instantiateArgument(specialized.getDefaultValue(), context);
if (specialized instanceof ICPPTemplateNonTypeParameter) { if (specialized instanceof ICPPTemplateNonTypeParameter) {
ICPPTemplateNonTypeParameter spec = (ICPPTemplateNonTypeParameter) specialized; ICPPTemplateNonTypeParameter spec = (ICPPTemplateNonTypeParameter) specialized;
@ -1689,10 +1693,10 @@ public class CPPTemplates {
* See specializeTemplateParameter(). * See specializeTemplateParameter().
*/ */
public static ICPPTemplateParameter[] specializeTemplateParameters(ICPPSpecialization owner, ICPPScope scope, public static ICPPTemplateParameter[] specializeTemplateParameters(ICPPSpecialization owner, ICPPScope scope,
ICPPTemplateParameter[] specialized, ICPPClassSpecialization within, IASTNode point) { ICPPTemplateParameter[] specialized, ICPPClassSpecialization within) {
ICPPTemplateParameter[] result = new ICPPTemplateParameter[specialized.length]; ICPPTemplateParameter[] result = new ICPPTemplateParameter[specialized.length];
for (int i = 0; i < specialized.length; ++i) for (int i = 0; i < specialized.length; ++i)
result[i] = specializeTemplateParameter(owner, scope, specialized[i], within, point); result[i] = specializeTemplateParameter(owner, scope, specialized[i], within);
return result; return result;
} }
@ -1713,7 +1717,7 @@ public class CPPTemplates {
owner = instantiateBinding(owner, context, maxDepth); owner = instantiateBinding(owner, context, maxDepth);
} }
if (owner instanceof ICPPClassSpecialization) { if (owner instanceof ICPPClassSpecialization) {
return ((ICPPClassSpecialization) owner).specializeMember(binding, context.getPoint()); return ((ICPPClassSpecialization) owner).specializeMember(binding);
} }
} else if (binding instanceof IEnumerator) { } else if (binding instanceof IEnumerator) {
IBinding owner = binding.getOwner(); IBinding owner = binding.getOwner();
@ -1772,8 +1776,8 @@ public class CPPTemplates {
ICPPTemplateArgument[] args = context.getPackExpansion(tpar); ICPPTemplateArgument[] args = context.getPackExpansion(tpar);
if (args != null) { if (args != null) {
if (context.getPackOffset() >= args.length) { if (context.getPackOffset() >= args.length) {
return new ProblemBinding(context.getPoint(), IProblemBinding.SEMANTIC_INVALID_TYPE, return new ProblemBinding(CPPSemantics.getCurrentLookupPoint(),
tpar.getNameCharArray()); IProblemBinding.SEMANTIC_INVALID_TYPE, tpar.getNameCharArray());
} }
arg= args[context.getPackOffset()]; arg= args[context.getPackOffset()];
} }
@ -2214,7 +2218,12 @@ public class CPPTemplates {
result[i]= new CPPTemplateTypeArgument(CPPVisitor.createType((IASTTypeId) arg)); result[i]= new CPPTemplateTypeArgument(CPPVisitor.createType((IASTTypeId) arg));
} else if (arg instanceof ICPPASTExpression) { } else if (arg instanceof ICPPASTExpression) {
ICPPASTExpression expr= (ICPPASTExpression) arg; ICPPASTExpression expr= (ICPPASTExpression) arg;
result[i]= new CPPTemplateNonTypeArgument(expr.getEvaluation(), expr); CPPSemantics.pushLookupPoint(expr);
try {
result[i]= new CPPTemplateNonTypeArgument(expr.getEvaluation());
} finally {
CPPSemantics.popLookupPoint();
}
} else if (arg instanceof ICPPASTAmbiguousTemplateArgument) { } else if (arg instanceof ICPPASTAmbiguousTemplateArgument) {
IProblemBinding problem = new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS); IProblemBinding problem = new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS);
throw new DOMException(problem); throw new DOMException(problem);
@ -2227,7 +2236,7 @@ public class CPPTemplates {
} }
static ICPPFunction[] instantiateForFunctionCall(ICPPFunction[] fns, ICPPTemplateArgument[] tmplArgs, static ICPPFunction[] instantiateForFunctionCall(ICPPFunction[] fns, ICPPTemplateArgument[] tmplArgs,
List<IType> fnArgs, List<ValueCategory> argCats, boolean withImpliedObjectArg, IASTNode point) { List<IType> fnArgs, List<ValueCategory> argCats, boolean withImpliedObjectArg) {
// Extract template arguments. // Extract template arguments.
boolean requireTemplate= tmplArgs != null; boolean requireTemplate= tmplArgs != null;
boolean haveTemplate= false; boolean haveTemplate= false;
@ -2257,7 +2266,7 @@ public class CPPTemplates {
if (fn instanceof ICPPFunctionTemplate) { if (fn instanceof ICPPFunctionTemplate) {
ICPPFunctionTemplate fnTmpl= (ICPPFunctionTemplate) fn; ICPPFunctionTemplate fnTmpl= (ICPPFunctionTemplate) fn;
ICPPFunction inst = instantiateForFunctionCall(fnTmpl, tmplArgs, fnArgs, argCats, ICPPFunction inst = instantiateForFunctionCall(fnTmpl, tmplArgs, fnArgs, argCats,
withImpliedObjectArg, point); withImpliedObjectArg);
if (inst != null) if (inst != null)
result.add(inst); result.add(inst);
} else if (!requireTemplate || fn instanceof ICPPUnknownBinding) { } else if (!requireTemplate || fn instanceof ICPPUnknownBinding) {
@ -2270,7 +2279,7 @@ public class CPPTemplates {
private static ICPPFunction instantiateForFunctionCall(ICPPFunctionTemplate template, private static ICPPFunction instantiateForFunctionCall(ICPPFunctionTemplate template,
ICPPTemplateArgument[] tmplArgs, List<IType> fnArgs, List<ValueCategory> argCats, ICPPTemplateArgument[] tmplArgs, List<IType> fnArgs, List<ValueCategory> argCats,
boolean withImpliedObjectArg, IASTNode point) { boolean withImpliedObjectArg) {
if (withImpliedObjectArg && template instanceof ICPPMethod) { if (withImpliedObjectArg && template instanceof ICPPMethod) {
fnArgs= fnArgs.subList(1, fnArgs.size()); fnArgs= fnArgs.subList(1, fnArgs.size());
argCats= argCats.subList(1, argCats.size()); argCats= argCats.subList(1, argCats.size());
@ -2279,9 +2288,9 @@ public class CPPTemplates {
CPPTemplateParameterMap map= new CPPTemplateParameterMap(fnArgs.size()); CPPTemplateParameterMap map= new CPPTemplateParameterMap(fnArgs.size());
try { try {
ICPPTemplateArgument[] args= ICPPTemplateArgument[] args=
TemplateArgumentDeduction.deduceForFunctionCall(template, tmplArgs, fnArgs, argCats, map, point); TemplateArgumentDeduction.deduceForFunctionCall(template, tmplArgs, fnArgs, argCats, map);
if (args != null) { if (args != null) {
IBinding instance= instantiateFunctionTemplate(template, args, map, point); IBinding instance= instantiateFunctionTemplate(template, args, map);
if (instance instanceof ICPPFunction) { if (instance instanceof ICPPFunction) {
final ICPPFunction f = (ICPPFunction) instance; final ICPPFunction f = (ICPPFunction) instance;
if (isValidFunctionType(f.getType())) { if (isValidFunctionType(f.getType())) {
@ -2322,8 +2331,7 @@ public class CPPTemplates {
* 14.8.2.3 Deducing conversion function template arguments * 14.8.2.3 Deducing conversion function template arguments
* @param point * @param point
*/ */
static ICPPFunction[] instantiateConversionTemplates(ICPPFunction[] functions, IType conversionType, static ICPPFunction[] instantiateConversionTemplates(ICPPFunction[] functions, IType conversionType) {
IASTNode point) {
boolean checkedForDependentType= false; boolean checkedForDependentType= false;
ICPPFunction[] result= functions; ICPPFunction[] result= functions;
int i= 0; int i= 0;
@ -2345,9 +2353,9 @@ public class CPPTemplates {
CPPTemplateParameterMap map= new CPPTemplateParameterMap(1); CPPTemplateParameterMap map= new CPPTemplateParameterMap(1);
try { try {
ICPPTemplateArgument[] args= ICPPTemplateArgument[] args=
TemplateArgumentDeduction.deduceForConversion(template, conversionType, map, point); TemplateArgumentDeduction.deduceForConversion(template, conversionType, map);
if (args != null) { if (args != null) {
IBinding instance= instantiateFunctionTemplate(template, args, map, point); IBinding instance= instantiateFunctionTemplate(template, args, map);
if (instance instanceof ICPPFunction) { if (instance instanceof ICPPFunction) {
inst= (ICPPFunction) instance; inst= (ICPPFunction) instance;
} }
@ -2375,12 +2383,12 @@ public class CPPTemplates {
* @return * @return
*/ */
static ICPPFunction instantiateForFunctionDeclaration(ICPPFunctionTemplate template, static ICPPFunction instantiateForFunctionDeclaration(ICPPFunctionTemplate template,
ICPPTemplateArgument[] args, ICPPFunctionType functionType, IASTNode point) { ICPPTemplateArgument[] args, ICPPFunctionType functionType) {
CPPTemplateParameterMap map= new CPPTemplateParameterMap(1); CPPTemplateParameterMap map= new CPPTemplateParameterMap(1);
try { try {
args= TemplateArgumentDeduction.deduceForDeclaration(template, args, functionType, map, point); args= TemplateArgumentDeduction.deduceForDeclaration(template, args, functionType, map);
if (args != null) { if (args != null) {
IBinding instance= instantiateFunctionTemplate(template, args, map, point); IBinding instance= instantiateFunctionTemplate(template, args, map);
if (instance instanceof ICPPFunction) { if (instance instanceof ICPPFunction) {
return (ICPPFunction) instance; return (ICPPFunction) instance;
} }
@ -2396,7 +2404,7 @@ public class CPPTemplates {
* 14.8.2.2 Deducing template arguments taking the address of a function template [temp.deduct.funcaddr] * 14.8.2.2 Deducing template arguments taking the address of a function template [temp.deduct.funcaddr]
*/ */
static ICPPFunction instantiateForAddressOfFunction(ICPPFunctionTemplate template, IFunctionType target, static ICPPFunction instantiateForAddressOfFunction(ICPPFunctionTemplate template, IFunctionType target,
ICPPTemplateArgument[] args, IASTNode point) { ICPPTemplateArgument[] args) {
try { try {
if (target != null && isDependentType(target)) { if (target != null && isDependentType(target)) {
return CPPDeferredFunction.createForCandidates(template); return CPPDeferredFunction.createForCandidates(template);
@ -2406,9 +2414,9 @@ public class CPPTemplates {
args= ICPPTemplateArgument.EMPTY_ARGUMENTS; args= ICPPTemplateArgument.EMPTY_ARGUMENTS;
CPPTemplateParameterMap map= new CPPTemplateParameterMap(4); CPPTemplateParameterMap map= new CPPTemplateParameterMap(4);
args= TemplateArgumentDeduction.deduceForAddressOf(template, args, target, map, point); args= TemplateArgumentDeduction.deduceForAddressOf(template, args, target, map);
if (args != null) { if (args != null) {
IBinding instance= instantiateFunctionTemplate(template, args, map, point); IBinding instance= instantiateFunctionTemplate(template, args, map);
if (instance instanceof ICPPFunction) { if (instance instanceof ICPPFunction) {
return (ICPPFunction) instance; return (ICPPFunction) instance;
} }
@ -2419,7 +2427,7 @@ public class CPPTemplates {
} }
// 14.5.6.2 Partial ordering of function templates // 14.5.6.2 Partial ordering of function templates
static int orderFunctionTemplates(ICPPFunctionTemplate f1, ICPPFunctionTemplate f2, TypeSelection mode, IASTNode point) static int orderFunctionTemplates(ICPPFunctionTemplate f1, ICPPFunctionTemplate f2, TypeSelection mode)
throws DOMException { throws DOMException {
if (f1 == f2) if (f1 == f2)
return 0; return 0;
@ -2428,8 +2436,8 @@ public class CPPTemplates {
if (f2 == null) if (f2 == null)
return 1; return 1;
int s1 = compareSpecialization(f1, f2, mode, point); int s1 = compareSpecialization(f1, f2, mode);
int s2 = compareSpecialization(f2, f1, mode, point); int s2 = compareSpecialization(f2, f1, mode);
if (s1 == s2) if (s1 == s2)
return 0; return 0;
@ -2439,7 +2447,7 @@ public class CPPTemplates {
return 1; return 1;
} }
private static ICPPFunction transferFunctionTemplate(ICPPFunctionTemplate f, IASTNode point) throws DOMException { private static ICPPFunction transferFunctionTemplate(ICPPFunctionTemplate f) throws DOMException {
final ICPPTemplateParameter[] tpars = f.getTemplateParameters(); final ICPPTemplateParameter[] tpars = f.getTemplateParameters();
final int argLen = tpars.length; final int argLen = tpars.length;
@ -2457,7 +2465,7 @@ public class CPPTemplates {
} }
} }
IBinding result = instantiateFunctionTemplate(f, args, map, point); IBinding result = instantiateFunctionTemplate(f, args, map);
if (result instanceof ICPPFunction) if (result instanceof ICPPFunction)
return (ICPPFunction) result; return (ICPPFunction) result;
@ -2494,8 +2502,8 @@ public class CPPTemplates {
originalType.isRValueReference(), originalType.takesVarArgs()); originalType.isRValueReference(), originalType.takesVarArgs());
} }
private static int compareSpecialization(ICPPFunctionTemplate f1, ICPPFunctionTemplate f2, TypeSelection mode, IASTNode point) throws DOMException { private static int compareSpecialization(ICPPFunctionTemplate f1, ICPPFunctionTemplate f2, TypeSelection mode) throws DOMException {
ICPPFunction transF1 = transferFunctionTemplate(f1, point); ICPPFunction transF1 = transferFunctionTemplate(f1);
if (transF1 == null) if (transF1 == null)
return -1; return -1;
@ -2529,7 +2537,7 @@ public class CPPTemplates {
} }
break; break;
} }
return TemplateArgumentDeduction.deduceForPartialOrdering(f2.getTemplateParameters(), pars, args, point); return TemplateArgumentDeduction.deduceForPartialOrdering(f2.getTemplateParameters(), pars, args);
} }
private static boolean isNonStaticMember(ICPPFunctionTemplate f) { private static boolean isNonStaticMember(ICPPFunctionTemplate f) {
@ -2550,7 +2558,7 @@ public class CPPTemplates {
} }
static IBinding selectSpecialization(ICPPPartiallySpecializable template, ICPPTemplateArgument[] args, static IBinding selectSpecialization(ICPPPartiallySpecializable template, ICPPTemplateArgument[] args,
boolean isDef, IASTNode point) throws DOMException { boolean isDef) throws DOMException {
if (template == null) { if (template == null) {
return null; return null;
} }
@ -2566,9 +2574,9 @@ public class CPPTemplates {
final CPPTemplateParameterMap map = new CPPTemplateParameterMap(args.length); final CPPTemplateParameterMap map = new CPPTemplateParameterMap(args.length);
ICPPTemplateArgument[] specializationArguments = specialization.getTemplateArguments(); ICPPTemplateArgument[] specializationArguments = specialization.getTemplateArguments();
if (TemplateArgumentDeduction.fromTemplateArguments( if (TemplateArgumentDeduction.fromTemplateArguments(
specialization.getTemplateParameters(), specializationArguments, args, map, point) && specialization.getTemplateParameters(), specializationArguments, args, map) &&
checkInstantiationOfArguments(specializationArguments, map, point)) { checkInstantiationOfArguments(specializationArguments, map)) {
int compare = orderSpecializations(bestMatch, specialization, point); int compare = orderSpecializations(bestMatch, specialization);
if (compare == 0) { if (compare == 0) {
bestMatchIsBest = false; bestMatchIsBest = false;
} else if (compare < 0) { } else if (compare < 0) {
@ -2583,7 +2591,7 @@ public class CPPTemplates {
// specializations, then the use of the class template is ambiguous and the program is // specializations, then the use of the class template is ambiguous and the program is
// ill-formed. // ill-formed.
if (!bestMatchIsBest) { if (!bestMatchIsBest) {
return new CPPTemplateDefinition.CPPTemplateProblem(point, return new CPPTemplateDefinition.CPPTemplateProblem(CPPSemantics.getCurrentLookupPoint(),
IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, template.getNameCharArray()); IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, template.getNameCharArray());
} }
@ -2591,15 +2599,15 @@ public class CPPTemplates {
return null; return null;
if (bestMatch instanceof ICPPClassTemplatePartialSpecialization) { if (bestMatch instanceof ICPPClassTemplatePartialSpecialization) {
bestMatch = SemanticUtil.mapToAST((ICPPClassTemplatePartialSpecialization) bestMatch, point); bestMatch = SemanticUtil.mapToAST((ICPPClassTemplatePartialSpecialization) bestMatch);
} }
return instantiatePartialSpecialization(bestMatch, args, isDef, bestMap, point); return instantiatePartialSpecialization(bestMatch, args, isDef, bestMap);
} }
private static boolean checkInstantiationOfArguments(ICPPTemplateArgument[] args, private static boolean checkInstantiationOfArguments(ICPPTemplateArgument[] args,
CPPTemplateParameterMap tpMap, IASTNode point) throws DOMException { CPPTemplateParameterMap tpMap) throws DOMException {
return instantiateArguments(args, new InstantiationContext(tpMap, point), true) != null; return instantiateArguments(args, new InstantiationContext(tpMap), true) != null;
} }
/** /**
@ -2611,7 +2619,8 @@ public class CPPTemplates {
* @return * @return
* @throws DOMException * @throws DOMException
*/ */
static private int orderSpecializations(ICPPPartialSpecialization spec1, ICPPPartialSpecialization spec2, IASTNode point) throws DOMException { static private int orderSpecializations(ICPPPartialSpecialization spec1, ICPPPartialSpecialization spec2)
throws DOMException {
if (spec1 == null) { if (spec1 == null) {
return -1; return -1;
} }
@ -2622,8 +2631,8 @@ public class CPPTemplates {
// 14.5.5.2 // 14.5.5.2
// A template is more specialized than another if and only if it is at least as specialized as the // A template is more specialized than another if and only if it is at least as specialized as the
// other template and that template is not at least as specialized as the first. // other template and that template is not at least as specialized as the first.
boolean f1IsAtLeastAsSpecializedAsF2 = isAtLeastAsSpecializedAs(spec1, spec2, point); boolean f1IsAtLeastAsSpecializedAsF2 = isAtLeastAsSpecializedAs(spec1, spec2);
boolean f2IsAtLeastAsSpecializedAsF1 = isAtLeastAsSpecializedAs(spec2, spec1, point); boolean f2IsAtLeastAsSpecializedAsF1 = isAtLeastAsSpecializedAs(spec2, spec1);
if (f1IsAtLeastAsSpecializedAsF2 == f2IsAtLeastAsSpecializedAsF1) if (f1IsAtLeastAsSpecializedAsF2 == f2IsAtLeastAsSpecializedAsF1)
return 0; return 0;
@ -2634,7 +2643,8 @@ public class CPPTemplates {
return -1; return -1;
} }
private static boolean isAtLeastAsSpecializedAs(ICPPPartialSpecialization f1, ICPPPartialSpecialization f2, IASTNode point) throws DOMException { private static boolean isAtLeastAsSpecializedAs(ICPPPartialSpecialization f1, ICPPPartialSpecialization f2)
throws DOMException {
// 14.5.5.2 // 14.5.5.2
// Using the transformed parameter list, perform argument deduction against the other // Using the transformed parameter list, perform argument deduction against the other
// function template // function template
@ -2660,11 +2670,11 @@ public class CPPTemplates {
} }
} }
final ICPPTemplateArgument[] transferredArgs1 = final ICPPTemplateArgument[] transferredArgs1 =
instantiateArguments(targs1, new InstantiationContext(transferMap, point), false); instantiateArguments(targs1, new InstantiationContext(transferMap), false);
// Deduce arguments for specialization 2 // Deduce arguments for specialization 2
final CPPTemplateParameterMap deductionMap= new CPPTemplateParameterMap(2); final CPPTemplateParameterMap deductionMap= new CPPTemplateParameterMap(2);
return TemplateArgumentDeduction.fromTemplateArguments(tpars2, targs2, transferredArgs1, deductionMap, point); return TemplateArgumentDeduction.fromTemplateArguments(tpars2, targs2, transferredArgs1, deductionMap);
} }
static boolean isValidArgument(ICPPTemplateArgument arg) { static boolean isValidArgument(ICPPTemplateArgument arg) {
@ -2672,7 +2682,7 @@ public class CPPTemplates {
} }
static ICPPTemplateArgument matchTemplateParameterAndArgument(ICPPTemplateDefinition template, static ICPPTemplateArgument matchTemplateParameterAndArgument(ICPPTemplateDefinition template,
ICPPTemplateParameter param, ICPPTemplateArgument arg, CPPTemplateParameterMap map, IASTNode point) { ICPPTemplateParameter param, ICPPTemplateArgument arg, CPPTemplateParameterMap map) {
if (!isValidArgument(arg)) { if (!isValidArgument(arg)) {
return null; return null;
} }
@ -2719,7 +2729,7 @@ public class CPPTemplates {
pType= ((ICPPParameterPackType) pType).getType(); pType= ((ICPPParameterPackType) pType).getType();
} }
if (map != null && pType != null) { if (map != null && pType != null) {
pType= instantiateType(pType, new InstantiationContext(map, point)); pType= instantiateType(pType, new InstantiationContext(map));
} }
if (argType instanceof ICPPParameterPackType) { if (argType instanceof ICPPParameterPackType) {
@ -2728,7 +2738,7 @@ public class CPPTemplates {
if (argType instanceof ICPPUnknownType) { if (argType instanceof ICPPUnknownType) {
return new CPPTemplateNonTypeArgument(arg.getNonTypeValue(), pType); return new CPPTemplateNonTypeArgument(arg.getNonTypeValue(), pType);
} }
return convertNonTypeTemplateArgument(template, pType, arg, point); return convertNonTypeTemplateArgument(template, pType, arg);
} catch (DOMException e) { } catch (DOMException e) {
return null; return null;
} }
@ -2797,7 +2807,7 @@ public class CPPTemplates {
* @throws DOMException * @throws DOMException
*/ */
private static ICPPTemplateArgument convertNonTypeTemplateArgument(ICPPTemplateDefinition template, private static ICPPTemplateArgument convertNonTypeTemplateArgument(ICPPTemplateDefinition template,
final IType paramType, ICPPTemplateArgument arg, IASTNode point) throws DOMException { final IType paramType, ICPPTemplateArgument arg) throws DOMException {
// 14.1s8 function to pointer and array to pointer conversions. // 14.1s8 function to pointer and array to pointer conversions.
IType a= arg.getTypeOfNonTypeValue(); IType a= arg.getTypeOfNonTypeValue();
IType p; IType p;
@ -2820,20 +2830,20 @@ public class CPPTemplates {
for (ICPPFunction f : functionSet.getBindings()) { for (ICPPFunction f : functionSet.getBindings()) {
if (p.isSameType(f.getType())) { if (p.isSameType(f.getType())) {
functionSet.applySelectedFunction(f); functionSet.applySelectedFunction(f);
return new CPPTemplateNonTypeArgument(new EvalBinding(f, null, template), point); return new CPPTemplateNonTypeArgument(new EvalBinding(f, null, template));
} }
} }
} }
return null; return null;
} }
Cost cost = Conversions.checkImplicitConversionSequence(p, a, LVALUE, UDCMode.FORBIDDEN, Cost cost = Conversions.checkImplicitConversionSequence(p, a, LVALUE, UDCMode.FORBIDDEN,
Context.ORDINARY, point); Context.ORDINARY);
if (cost == null || !cost.converts()) { if (cost == null || !cost.converts()) {
ICPPEvaluation eval = arg.getNonTypeEvaluation(); ICPPEvaluation eval = arg.getNonTypeEvaluation();
ICPPEvaluation newEval = CPPEvaluation.maybeApplyConversion(eval, p, point, false); ICPPEvaluation newEval = CPPEvaluation.maybeApplyConversion(eval, p, false);
if (newEval == EvalFixed.INCOMPLETE && newEval != eval) if (newEval == EvalFixed.INCOMPLETE && newEval != eval)
return null; return null;
return new CPPTemplateNonTypeArgument(newEval, point); return new CPPTemplateNonTypeArgument(newEval);
} }
return new CPPTemplateNonTypeArgument(arg.getNonTypeValue(), paramType); return new CPPTemplateNonTypeArgument(arg.getNonTypeValue(), paramType);
@ -3007,23 +3017,22 @@ public class CPPTemplates {
} else if (ot1 instanceof ICPPClassType) { } else if (ot1 instanceof ICPPClassType) {
IScope s = ((ICPPClassType) ot1).getCompositeScope(); IScope s = ((ICPPClassType) ot1).getCompositeScope();
if (s != null) { if (s != null) {
result= CPPSemantics.resolveUnknownName(s, unknown, context.getPoint()); result= CPPSemantics.resolveUnknownName(s, unknown);
if (unknown instanceof ICPPUnknownMemberClassInstance && if (unknown instanceof ICPPUnknownMemberClassInstance &&
(result instanceof ICPPTemplateDefinition || (result instanceof ICPPTemplateDefinition ||
result instanceof ICPPAliasTemplateInstance)) { result instanceof ICPPAliasTemplateInstance)) {
ICPPTemplateArgument[] args1 = instantiateArguments( ICPPTemplateArgument[] args1 = instantiateArguments(
((ICPPUnknownMemberClassInstance) unknown).getArguments(), context, false); ((ICPPUnknownMemberClassInstance) unknown).getArguments(), context, false);
if (result instanceof ICPPClassTemplate) { if (result instanceof ICPPClassTemplate) {
result = instantiate((ICPPClassTemplate) result, args1, context.getPoint()); result = instantiate((ICPPClassTemplate) result, args1);
} else if (result instanceof ICPPAliasTemplate) { } else if (result instanceof ICPPAliasTemplate) {
result = instantiateAliasTemplate((ICPPAliasTemplate) result, args1, result = instantiateAliasTemplate((ICPPAliasTemplate) result, args1);
context.getPoint());
} }
} }
} }
} else if (ot1 != ot0) { } else if (ot1 != ot0) {
return new ProblemBinding(new CPPASTName(unknown.getNameCharArray()), context.getPoint(), return new ProblemBinding(new CPPASTName(unknown.getNameCharArray()),
IProblemBinding.SEMANTIC_BAD_SCOPE); CPPSemantics.getCurrentLookupPoint(), IProblemBinding.SEMANTIC_BAD_SCOPE);
} }
} }
@ -3040,7 +3049,7 @@ public class CPPTemplates {
return e.getProblem(); return e.getProblem();
} }
if (newArgs == null) if (newArgs == null)
return createProblem(classTemplate, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, context.getPoint()); return createProblem(classTemplate, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS);
boolean changed= arguments != newArgs; boolean changed= arguments != newArgs;
IType classTemplateSpecialization= instantiateType(classTemplate, context); IType classTemplateSpecialization= instantiateType(classTemplate, context);
@ -3050,7 +3059,7 @@ public class CPPTemplates {
} }
if (changed) { if (changed) {
IBinding inst= instantiate(classTemplate, newArgs, context.getPoint()); IBinding inst= instantiate(classTemplate, newArgs);
if (inst != null) if (inst != null)
return inst; return inst;
} }
@ -3068,15 +3077,14 @@ public class CPPTemplates {
return e.getProblem(); return e.getProblem();
} }
if (newArgs == null) { if (newArgs == null) {
return createProblem(variableTemplate, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, return createProblem(variableTemplate, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS);
context.getPoint());
} }
// Unlike class templates, variable templates cannot be passed as template template arguments, // Unlike class templates, variable templates cannot be passed as template template arguments,
// so there is no need to instantiate the template itself. // so there is no need to instantiate the template itself.
if (arguments != newArgs) { if (arguments != newArgs) {
IBinding inst = instantiate(variableTemplate, newArgs, context.getPoint()); IBinding inst = instantiate(variableTemplate, newArgs);
if (inst != null) if (inst != null)
return inst; return inst;
} }
@ -3103,11 +3111,10 @@ public class CPPTemplates {
* @param template the template definition * @param template the template definition
* @param arguments the template arguments; arguments may be modified by this method due to type * @param arguments the template arguments; arguments may be modified by this method due to type
* conversion performed for non-type arguments * conversion performed for non-type arguments
* @param point the point of instantiation
* @return the created template parameter map, or {@code null} if the arguments are invalid * @return the created template parameter map, or {@code null} if the arguments are invalid
*/ */
private static CPPTemplateParameterMap createParameterMap(ICPPTemplateDefinition template, private static CPPTemplateParameterMap createParameterMap(ICPPTemplateDefinition template,
ICPPTemplateArgument[] arguments, IASTNode point) { ICPPTemplateArgument[] arguments) {
final ICPPTemplateParameter[] parameters= template.getTemplateParameters(); final ICPPTemplateParameter[] parameters= template.getTemplateParameters();
final int numArgs = arguments.length; final int numArgs = arguments.length;
final int numParams= parameters.length; final int numParams= parameters.length;
@ -3127,7 +3134,7 @@ public class CPPTemplates {
if (i < numArgs) { if (i < numArgs) {
ICPPTemplateArgument arg= arguments[i]; ICPPTemplateArgument arg= arguments[i];
ICPPTemplateArgument newArg = ICPPTemplateArgument newArg =
matchTemplateParameterAndArgument(template, param, arg, map, point); matchTemplateParameterAndArgument(template, param, arg, map);
if (newArg == null) if (newArg == null)
return null; return null;
if (newArg != arg) { if (newArg != arg) {
@ -3167,15 +3174,14 @@ public class CPPTemplates {
/** /**
* Returns the instantiated function body of the given function specialization. * Returns the instantiated function body of the given function specialization.
* @param point The point of instantiation for name lookups
*/ */
public static ICPPExecution instantiateFunctionBody(ICPPFunctionSpecialization f, IASTNode point) { public static ICPPExecution instantiateFunctionBody(ICPPFunctionSpecialization f) {
ICPPFunction spec = (ICPPFunction) f.getSpecializedBinding(); ICPPFunction spec = (ICPPFunction) f.getSpecializedBinding();
ICPPExecution exec = null; ICPPExecution exec = null;
if (spec instanceof ICPPComputableFunction) { if (spec instanceof ICPPComputableFunction) {
exec = ((ICPPComputableFunction) spec).getFunctionBodyExecution(point); exec = ((ICPPComputableFunction) spec).getFunctionBodyExecution();
if (exec != null) { if (exec != null) {
InstantiationContext context = new InstantiationContext(f.getTemplateParameterMap(), f, point); InstantiationContext context = new InstantiationContext(f.getTemplateParameterMap(), f);
CPPTemplates.addInstantiatedParameters(context, f); CPPTemplates.addInstantiatedParameters(context, f);
exec = exec.instantiate(context, IntegralValue.MAX_RECURSION_DEPTH); exec = exec.instantiate(context, IntegralValue.MAX_RECURSION_DEPTH);
} }
@ -3199,15 +3205,14 @@ public class CPPTemplates {
/** /**
* Returns the instantiated constructor chain of the given constructor specialization. * Returns the instantiated constructor chain of the given constructor specialization.
* @param point The point of instantiation for name lookups
*/ */
public static ICPPExecution instantiateConstructorChain(ICPPConstructorSpecialization f, IASTNode point) { public static ICPPExecution instantiateConstructorChain(ICPPConstructorSpecialization f) {
ICPPConstructor spec = (ICPPConstructor) f.getSpecializedBinding(); ICPPConstructor spec = (ICPPConstructor) f.getSpecializedBinding();
ICPPExecution exec = null; ICPPExecution exec = null;
if (spec != null) { if (spec != null) {
exec = spec.getConstructorChainExecution(point); exec = spec.getConstructorChainExecution();
if (exec != null) { if (exec != null) {
InstantiationContext context = new InstantiationContext(f.getTemplateParameterMap(), f, point); InstantiationContext context = new InstantiationContext(f.getTemplateParameterMap(), f);
exec = exec.instantiate(context, IntegralValue.MAX_RECURSION_DEPTH); exec = exec.instantiate(context, IntegralValue.MAX_RECURSION_DEPTH);
} }
} }

View file

@ -47,7 +47,12 @@ public final class CPPVariableReadWriteFlags extends VariableReadWriteFlags {
private static CPPVariableReadWriteFlags INSTANCE= new CPPVariableReadWriteFlags(); private static CPPVariableReadWriteFlags INSTANCE= new CPPVariableReadWriteFlags();
public static int getReadWriteFlags(IASTName variable) { public static int getReadWriteFlags(IASTName variable) {
return INSTANCE.rwAnyNode(variable, 0); CPPSemantics.pushLookupPoint(variable);
try {
return INSTANCE.rwAnyNode(variable, 0);
} finally {
CPPSemantics.popLookupPoint();
}
} }
@Override @Override
@ -67,7 +72,7 @@ public final class CPPVariableReadWriteFlags extends VariableReadWriteFlags {
IType type = CPPVisitor.createType(parent); IType type = CPPVisitor.createType(parent);
if (type instanceof ICPPUnknownType || if (type instanceof ICPPUnknownType ||
type instanceof ICPPClassType && type instanceof ICPPClassType &&
!TypeTraits.hasTrivialDefaultConstructor((ICPPClassType) type, parent, CPPSemantics.MAX_INHERITANCE_DEPTH)) { !TypeTraits.hasTrivialDefaultConstructor((ICPPClassType) type, CPPSemantics.MAX_INHERITANCE_DEPTH)) {
return WRITE; return WRITE;
} }
return super.rwInDeclarator(parent, indirection); return super.rwInDeclarator(parent, indirection);

View file

@ -491,7 +491,7 @@ public class CPPVisitor extends ASTQueries {
binding = CPPSemantics.resolveBinding(elabType.getName()); binding = CPPSemantics.resolveBinding(elabType.getName());
} }
if (binding instanceof IIndexBinding && binding instanceof ICPPClassType) { if (binding instanceof IIndexBinding && binding instanceof ICPPClassType) {
binding= (ICPPClassType) SemanticUtil.mapToAST((ICPPClassType) binding, elabType); binding= (ICPPClassType) SemanticUtil.mapToAST((ICPPClassType) binding);
ASTInternal.addDeclaration(binding, elabType); ASTInternal.addDeclaration(binding, elabType);
} }
@ -1289,7 +1289,7 @@ public class CPPVisitor extends ASTQueries {
boolean done= true; boolean done= true;
IScope scope= null; IScope scope= null;
if (binding instanceof ICPPClassType) { if (binding instanceof ICPPClassType) {
binding= (ICPPClassType) SemanticUtil.mapToAST((ICPPClassType) binding, name); binding= (ICPPClassType) SemanticUtil.mapToAST((ICPPClassType) binding);
scope= ((ICPPClassType) binding).getCompositeScope(); scope= ((ICPPClassType) binding).getCompositeScope();
} else if (binding instanceof ICPPNamespace) { } else if (binding instanceof ICPPNamespace) {
scope= ((ICPPNamespace) binding).getNamespaceScope(); scope= ((ICPPNamespace) binding).getNamespaceScope();
@ -1320,7 +1320,7 @@ public class CPPVisitor extends ASTQueries {
} }
type= getUltimateTypeUptoPointers(type); type= getUltimateTypeUptoPointers(type);
if (type instanceof ICPPClassType) { if (type instanceof ICPPClassType) {
type= SemanticUtil.mapToAST(type, fieldReference); type= SemanticUtil.mapToAST(type);
return ((ICPPClassType) type).getCompositeScope(); return ((ICPPClassType) type).getCompositeScope();
} else if (type instanceof ICPPUnknownBinding) { } else if (type instanceof ICPPUnknownBinding) {
return ((ICPPUnknownBinding) type).asScope(); return ((ICPPUnknownBinding) type).asScope();
@ -1346,7 +1346,7 @@ public class CPPVisitor extends ASTQueries {
if (type != null) { if (type != null) {
type= getNestedType(type, TDEF | CVTYPE); type= getNestedType(type, TDEF | CVTYPE);
if (type instanceof ICPPClassType) { if (type instanceof ICPPClassType) {
type= SemanticUtil.mapToAST(type, name); type= SemanticUtil.mapToAST(type);
return ((ICPPClassType) type).getCompositeScope(); return ((ICPPClassType) type).getCompositeScope();
} }
} }
@ -2045,7 +2045,7 @@ public class CPPVisitor extends ASTQueries {
sizeValue = IntegralValue.create(clauses.length); sizeValue = IntegralValue.create(clauses.length);
} else if (clause instanceof ICPPASTLiteralExpression) { } else if (clause instanceof ICPPASTLiteralExpression) {
ICPPEvaluation value = ((ICPPASTExpression) clause).getEvaluation(); ICPPEvaluation value = ((ICPPASTExpression) clause).getEvaluation();
IType valueType = value.getType(clause); IType valueType = value.getType();
if (valueType instanceof IArrayType) { if (valueType instanceof IArrayType) {
sizeValue = ((IArrayType) valueType).getSize(); sizeValue = ((IArrayType) valueType).getSize();
} }
@ -2071,7 +2071,12 @@ public class CPPVisitor extends ASTQueries {
public static IType createType(IASTDeclarator declarator) { public static IType createType(IASTDeclarator declarator) {
// Resolve placeholders by default. // Resolve placeholders by default.
return createType(declarator, RESOLVE_PLACEHOLDERS); try {
CPPSemantics.pushLookupPoint(declarator);
return createType(declarator, RESOLVE_PLACEHOLDERS);
} finally {
CPPSemantics.popLookupPoint();
}
} }
public static IType createType(IASTDeclarator declarator, int flags) { public static IType createType(IASTDeclarator declarator, int flags) {
@ -2259,7 +2264,7 @@ public class CPPVisitor extends ASTQueries {
return cannotDeduce; return cannotDeduce;
} }
if (placeholderKind == PlaceholderKind.Auto) { if (placeholderKind == PlaceholderKind.Auto) {
return createAutoType(autoInitClause.getEvaluation(), declSpec, declarator, autoInitClause); return createAutoType(autoInitClause.getEvaluation(), declSpec, declarator);
} else /* decltype(auto) */ { } else /* decltype(auto) */ {
if (declarator.getPointerOperators().length > 0) { if (declarator.getPointerOperators().length > 0) {
// 'decltype(auto)' cannot be combined with * or & the way 'auto' can. // 'decltype(auto)' cannot be combined with * or & the way 'auto' can.
@ -2277,24 +2282,24 @@ public class CPPVisitor extends ASTQueries {
} }
private static IType createAutoType(final ICPPEvaluation evaluation, IASTDeclSpecifier declSpec, private static IType createAutoType(final ICPPEvaluation evaluation, IASTDeclSpecifier declSpec,
IASTDeclarator declarator, IASTNode point) { IASTDeclarator declarator) {
// C++0x: 7.1.6.4 // C++0x: 7.1.6.4
IType type = AutoTypeResolver.AUTO_TYPE; IType type = AutoTypeResolver.AUTO_TYPE;
IType initType = null; IType initType = null;
ValueCategory valueCat= null; ValueCategory valueCat= null;
initType = evaluation.getType(declarator); initType = evaluation.getType();
valueCat = evaluation.getValueCategory(declarator); valueCat = evaluation.getValueCategory();
if (initType == null || initType instanceof ISemanticProblem) { if (initType == null || initType instanceof ISemanticProblem) {
return ProblemType.CANNOT_DEDUCE_AUTO_TYPE; return ProblemType.CANNOT_DEDUCE_AUTO_TYPE;
} }
ICPPClassTemplate initializer_list_template = null; ICPPClassTemplate initializer_list_template = null;
if (evaluation instanceof EvalInitList) { if (evaluation instanceof EvalInitList) {
initializer_list_template = get_initializer_list(declSpec); initializer_list_template = get_initializer_list();
if (initializer_list_template == null) { if (initializer_list_template == null) {
return ProblemType.CANNOT_DEDUCE_AUTO_TYPE; return ProblemType.CANNOT_DEDUCE_AUTO_TYPE;
} }
type = (IType) CPPTemplates.instantiate(initializer_list_template, type = (IType) CPPTemplates.instantiate(initializer_list_template,
new ICPPTemplateArgument[] { new CPPTemplateTypeArgument(type) }, point); new ICPPTemplateArgument[] { new CPPTemplateTypeArgument(type) });
if (type instanceof IProblemBinding) { if (type instanceof IProblemBinding) {
return ProblemType.CANNOT_DEDUCE_AUTO_TYPE; return ProblemType.CANNOT_DEDUCE_AUTO_TYPE;
} }
@ -2303,7 +2308,7 @@ public class CPPVisitor extends ASTQueries {
ICPPFunctionTemplate template = new AutoTypeResolver(type); ICPPFunctionTemplate template = new AutoTypeResolver(type);
CPPTemplateParameterMap paramMap = new CPPTemplateParameterMap(1); CPPTemplateParameterMap paramMap = new CPPTemplateParameterMap(1);
TemplateArgumentDeduction.deduceFromFunctionArgs(template, Collections.singletonList(initType), TemplateArgumentDeduction.deduceFromFunctionArgs(template, Collections.singletonList(initType),
Collections.singletonList(valueCat), paramMap, point); Collections.singletonList(valueCat), paramMap);
ICPPTemplateArgument argument = paramMap.getArgument(0, 0); ICPPTemplateArgument argument = paramMap.getArgument(0, 0);
if (argument == null) { if (argument == null) {
return ProblemType.CANNOT_DEDUCE_AUTO_TYPE; return ProblemType.CANNOT_DEDUCE_AUTO_TYPE;
@ -2320,7 +2325,7 @@ public class CPPVisitor extends ASTQueries {
type = t; type = t;
if (evaluation instanceof EvalInitList) { if (evaluation instanceof EvalInitList) {
type = (IType) CPPTemplates.instantiate(initializer_list_template, type = (IType) CPPTemplates.instantiate(initializer_list_template,
new ICPPTemplateArgument[] { new CPPTemplateTypeArgument(type) }, point); new ICPPTemplateArgument[] { new CPPTemplateTypeArgument(type) });
} }
return decorateType(type, declSpec, declarator); return decorateType(type, declSpec, declarator);
} }
@ -2347,7 +2352,7 @@ public class CPPVisitor extends ASTQueries {
returnEval = ((ICPPASTInitializerClause) returnExpression).getEvaluation(); returnEval = ((ICPPASTInitializerClause) returnExpression).getEvaluation();
} }
IType returnType = returnEval.getType(stmt); IType returnType = returnEval.getType();
if (returnType instanceof ISemanticProblem) { if (returnType instanceof ISemanticProblem) {
// If a function makes a recursive call in some of its return statements, // If a function makes a recursive call in some of its return statements,
// the type those return expressions will be a problem type. We ignore // the type those return expressions will be a problem type. We ignore
@ -2360,7 +2365,7 @@ public class CPPVisitor extends ASTQueries {
if (fReturnEval == null) { if (fReturnEval == null) {
fReturnEval = returnEval; fReturnEval = returnEval;
} else if (!fReturnEval.getType(stmt).isSameType(returnType)) { } else if (!fReturnEval.getType().isSameType(returnType)) {
fReturnEval = EvalFixed.INCOMPLETE; fReturnEval = EvalFixed.INCOMPLETE;
} }
} }
@ -2400,12 +2405,12 @@ public class CPPVisitor extends ASTQueries {
// 'decltype(auto)' cannot be combined with * or & the way 'auto' can. // 'decltype(auto)' cannot be combined with * or & the way 'auto' can.
return ProblemType.CANNOT_DEDUCE_DECLTYPE_AUTO_TYPE; return ProblemType.CANNOT_DEDUCE_DECLTYPE_AUTO_TYPE;
} }
return CPPSemantics.getDeclTypeForEvaluation(returnEval, point); return CPPSemantics.getDeclTypeForEvaluation(returnEval);
} else /* auto */ { } else /* auto */ {
if (autoDeclSpec == null || autoDeclarator == null) { if (autoDeclSpec == null || autoDeclarator == null) {
return returnEval.getType(point); return returnEval.getType();
} else { } else {
return createAutoType(returnEval, autoDeclSpec, autoDeclarator, autoDeclarator); return createAutoType(returnEval, autoDeclSpec, autoDeclarator);
} }
} }
} }
@ -2666,12 +2671,13 @@ public class CPPVisitor extends ASTQueries {
return null; return null;
} }
public static IType getPointerDiffType(final IASTNode point) { public static IType getPointerDiffType() {
IType t= getStdType(point, PTRDIFF_T); IType t= getStdType(PTRDIFF_T);
return t != null ? t : CPPBasicType.LONG; return t != null ? t : CPPBasicType.LONG;
} }
private static IType getStdType(final IASTNode node, char[] name) { private static IType getStdType(char[] name) {
IASTNode node = CPPSemantics.getCurrentLookupPoint();
if (node == null) if (node == null)
return null; return null;
ASTTranslationUnit ast = (ASTTranslationUnit) node.getTranslationUnit(); ASTTranslationUnit ast = (ASTTranslationUnit) node.getTranslationUnit();
@ -2692,18 +2698,18 @@ public class CPPVisitor extends ASTQueries {
return null; return null;
} }
public static IType get_type_info(IASTNode point) { public static IType get_type_info() {
IType t= getStdType(point, TYPE_INFO); IType t= getStdType(TYPE_INFO);
return t != null ? t : CPPBasicType.INT; return t != null ? t : CPPBasicType.INT;
} }
public static IType get_SIZE_T(IASTNode sizeofExpr) { public static IType get_SIZE_T() {
IType t= getStdType(sizeofExpr, SIZE_T); IType t= getStdType(SIZE_T);
return t != null ? t : CPPBasicType.UNSIGNED_LONG; return t != null ? t : CPPBasicType.UNSIGNED_LONG;
} }
public static ICPPClassTemplate get_initializer_list(IASTNode node) { public static ICPPClassTemplate get_initializer_list() {
IType t= getStdType(node, INITIALIZER_LIST); IType t= getStdType(INITIALIZER_LIST);
if (t instanceof ICPPClassTemplate) if (t instanceof ICPPClassTemplate)
return (ICPPClassTemplate) t; return (ICPPClassTemplate) t;
return null; return null;
@ -2875,7 +2881,7 @@ public class CPPVisitor extends ASTQueries {
break; break;
IBinding binding = segments[i].resolveBinding(); IBinding binding = segments[i].resolveBinding();
if (binding instanceof IIndexBinding && binding instanceof ICPPClassType) { if (binding instanceof IIndexBinding && binding instanceof ICPPClassType) {
binding = (ICPPClassType) SemanticUtil.mapToAST((ICPPClassType) binding, name); binding = (ICPPClassType) SemanticUtil.mapToAST((ICPPClassType) binding);
} }
return bindingToOwner(binding); return bindingToOwner(binding);
} }

View file

@ -31,7 +31,6 @@ import java.util.Collections;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
@ -64,7 +63,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType; 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.CPPPointerType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPQualifierType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPQualifierType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.DeferredUDC; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.DeferredUDC;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.Rank; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.Rank;
@ -97,7 +95,7 @@ public class Conversions {
* @throws DOMException * @throws DOMException
*/ */
public static Cost checkImplicitConversionSequence(IType target, IType exprType, public static Cost checkImplicitConversionSequence(IType target, IType exprType,
ValueCategory valueCat, UDCMode udc, Context ctx, IASTNode point) throws DOMException { ValueCategory valueCat, UDCMode udc, Context ctx) throws DOMException {
final boolean isImpliedObject= final boolean isImpliedObject=
ctx == Context.IMPLICIT_OBJECT_FOR_METHOD_WITHOUT_REF_QUALIFIER || ctx == Context.IMPLICIT_OBJECT_FOR_METHOD_WITHOUT_REF_QUALIFIER ||
ctx == Context.IMPLICIT_OBJECT_FOR_METHOD_WITH_REF_QUALIFIER; ctx == Context.IMPLICIT_OBJECT_FOR_METHOD_WITH_REF_QUALIFIER;
@ -122,7 +120,7 @@ public class Conversions {
if (isLValueRef && getCVQualifier(cv1T1) != CVQualifier.CONST) if (isLValueRef && getCVQualifier(cv1T1) != CVQualifier.CONST)
return Cost.NO_CONVERSION; return Cost.NO_CONVERSION;
Cost cost= listInitializationSequence(((InitializerListType) exprType).getEvaluation(), T1, udc, false, point); Cost cost= listInitializationSequence(((InitializerListType) exprType).getEvaluation(), T1, udc, false);
if (cost.converts()) { if (cost.converts()) {
cost.setReferenceBinding(refBindingType); cost.setReferenceBinding(refBindingType);
} }
@ -144,7 +142,7 @@ public class Conversions {
if (valueCat != LVALUE) if (valueCat != LVALUE)
refBindingType= ReferenceBinding.RVALUE_REF_BINDS_RVALUE; refBindingType= ReferenceBinding.RVALUE_REF_BINDS_RVALUE;
// ... and "cv1 T1" is reference-compatible with "cv2 T2" // ... and "cv1 T1" is reference-compatible with "cv2 T2"
Cost cost= isReferenceCompatible(cv1T1, cv2T2, isImpliedObject, point); Cost cost= isReferenceCompatible(cv1T1, cv2T2, isImpliedObject);
if (cost != null) { if (cost != null) {
cost.setReferenceBinding(refBindingType); cost.setReferenceBinding(refBindingType);
return cost; return cost;
@ -154,8 +152,8 @@ public class Conversions {
// implicitly converted to an lvalue of type 'cv3 T3', where 'cv1 T1' is reference-compatible with // 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) // '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)), // and choosing the best one through overload resolution (13.3)),
if (T2 instanceof ICPPClassType && udc != UDCMode.FORBIDDEN && isReferenceRelated(T1, T2, point) < 0) { if (T2 instanceof ICPPClassType && udc != UDCMode.FORBIDDEN && isReferenceRelated(T1, T2) < 0) {
Cost cost= initializationByConversionForDirectReference(cv1T1, cv2T2, (ICPPClassType) T2, true, false, ctx, point); Cost cost= initializationByConversionForDirectReference(cv1T1, cv2T2, (ICPPClassType) T2, true, false, ctx);
if (cost != null) { if (cost != null) {
cost.setReferenceBinding(refBindingType); cost.setReferenceBinding(refBindingType);
return cost; return cost;
@ -175,7 +173,7 @@ public class Conversions {
if (valueCat == ValueCategory.XVALUE if (valueCat == ValueCategory.XVALUE
|| (valueCat == ValueCategory.PRVALUE && (T2 instanceof ICPPClassType || T2 instanceof IArrayType)) || (valueCat == ValueCategory.PRVALUE && (T2 instanceof ICPPClassType || T2 instanceof IArrayType))
|| (valueCat == ValueCategory.LVALUE && T2 instanceof ICPPFunctionType)) { || (valueCat == ValueCategory.LVALUE && T2 instanceof ICPPFunctionType)) {
Cost cost = isReferenceCompatible(cv1T1, cv2T2, isImpliedObject, point); Cost cost = isReferenceCompatible(cv1T1, cv2T2, isImpliedObject);
if (cost != null) { if (cost != null) {
cost.setReferenceBinding(refBindingType); cost.setReferenceBinding(refBindingType);
return cost; return cost;
@ -190,8 +188,8 @@ public class Conversions {
// sequence of the user-defined conversion sequence includes an lvalue-to-rvalue // sequence of the user-defined conversion sequence includes an lvalue-to-rvalue
// conversion, the program is ill-formed [this is why we pass illFormedIfLValue = true]. // conversion, the program is ill-formed [this is why we pass illFormedIfLValue = true].
if (T2 instanceof ICPPClassType) { if (T2 instanceof ICPPClassType) {
if (udc != UDCMode.FORBIDDEN && isReferenceRelated(T1, T2, point) < 0) { if (udc != UDCMode.FORBIDDEN && isReferenceRelated(T1, T2) < 0) {
Cost cost= initializationByConversionForDirectReference(cv1T1, cv2T2, (ICPPClassType) T2, false, true, ctx, point); Cost cost= initializationByConversionForDirectReference(cv1T1, cv2T2, (ICPPClassType) T2, false, true, ctx);
if (cost != null) { if (cost != null) {
if (cost != Cost.NO_CONVERSION) { if (cost != Cost.NO_CONVERSION) {
cost.setReferenceBinding(refBindingType); cost.setReferenceBinding(refBindingType);
@ -207,11 +205,11 @@ public class Conversions {
// 13.3.3.1.7 no temporary object when converting the implicit object parameter // 13.3.3.1.7 no temporary object when converting the implicit object parameter
if (!isImpliedObject && ctx != Context.REQUIRE_DIRECT_BINDING) { if (!isImpliedObject && ctx != Context.REQUIRE_DIRECT_BINDING) {
Cost cost= nonReferenceConversion(valueCat, cv2T2, T1, udc, point); Cost cost= nonReferenceConversion(valueCat, cv2T2, T1, udc);
if (cost.converts()) { if (cost.converts()) {
cost.setReferenceBinding(refBindingType); cost.setReferenceBinding(refBindingType);
} }
boolean referenceRelated = isReferenceRelated(T1, T2, point) >= 0; boolean referenceRelated = isReferenceRelated(T1, T2) >= 0;
// If T1 is reference-related to T2, cv1 shall be the same cv-qualification as, // If T1 is reference-related to T2, cv1 shall be the same cv-qualification as,
// or greater cv-qualification than, cv2. // or greater cv-qualification than, cv2.
if (referenceRelated && compareQualifications(cv1T1, cv2T2) < 0) { if (referenceRelated && compareQualifications(cv1T1, cv2T2) < 0) {
@ -228,7 +226,7 @@ public class Conversions {
} }
// Non-reference binding // Non-reference binding
return nonReferenceConversion(valueCat, exprType, T1, udc, point); return nonReferenceConversion(valueCat, exprType, T1, udc);
} }
/** /**
@ -241,9 +239,9 @@ public class Conversions {
* in the former case, the caller will continue trying other conversion methods. * in the former case, the caller will continue trying other conversion methods.
*/ */
private static Cost initializationByConversionForDirectReference(final IType cv1T1, final IType cv2T2, final ICPPClassType T2, private static Cost initializationByConversionForDirectReference(final IType cv1T1, final IType cv2T2, final ICPPClassType T2,
boolean needLValue, boolean illFormedIfLValue, Context ctx, IASTNode point) boolean needLValue, boolean illFormedIfLValue, Context ctx)
throws DOMException { throws DOMException {
ICPPMethod[] fcns= SemanticUtil.getConversionOperators(T2, point); ICPPMethod[] fcns= SemanticUtil.getConversionOperators(T2);
Cost operatorCost= null; Cost operatorCost= null;
FunctionCost bestUdcCost= null; FunctionCost bestUdcCost= null;
boolean ambiguousConversionOperator= false; boolean ambiguousConversionOperator= false;
@ -261,14 +259,14 @@ public class Conversions {
continue; continue;
} }
IType implicitParameterType= CPPSemantics.getImplicitParameterType(op); IType implicitParameterType= CPPSemantics.getImplicitParameterType(op);
Cost udcCost= isReferenceCompatible(getNestedType(implicitParameterType, TDEF | REF), cv2T2, true, point); // expression type to implicit object type Cost udcCost= isReferenceCompatible(getNestedType(implicitParameterType, TDEF | REF), cv2T2, true); // expression type to implicit object type
if (udcCost != null) { if (udcCost != null) {
// Make sure top-level cv-qualifiers are compared // Make sure top-level cv-qualifiers are compared
udcCost.setReferenceBinding(ReferenceBinding.LVALUE_REF); udcCost.setReferenceBinding(ReferenceBinding.LVALUE_REF);
FunctionCost udcFuncCost= new FunctionCost(op, udcCost, point); FunctionCost udcFuncCost= new FunctionCost(op, udcCost);
int cmp= udcFuncCost.compareTo(null, bestUdcCost); int cmp= udcFuncCost.compareTo(null, bestUdcCost);
if (cmp <= 0) { if (cmp <= 0) {
Cost cost= isReferenceCompatible(cv1T1, getNestedType(t, TDEF | REF), false, point); // converted to target Cost cost= isReferenceCompatible(cv1T1, getNestedType(t, TDEF | REF), false); // converted to target
if (cost != null) { if (cost != null) {
bestUdcCost= udcFuncCost; bestUdcCost= udcFuncCost;
ambiguousConversionOperator= cmp == 0; ambiguousConversionOperator= cmp == 0;
@ -293,9 +291,9 @@ public class Conversions {
/** /**
* 8.5-16 * 8.5-16
*/ */
private static Cost nonReferenceConversion(ValueCategory valueCat, IType source, IType target, UDCMode udc, IASTNode point) throws DOMException { private static Cost nonReferenceConversion(ValueCategory valueCat, IType source, IType target, UDCMode udc) throws DOMException {
if (source instanceof InitializerListType) { if (source instanceof InitializerListType) {
return listInitializationSequence(((InitializerListType) source).getEvaluation(), target, udc, false, point); return listInitializationSequence(((InitializerListType) source).getEvaluation(), target, udc, false);
} }
IType uqTarget= SemanticUtil.getNestedType(target, TDEF | REF | CVTYPE); IType uqTarget= SemanticUtil.getNestedType(target, TDEF | REF | CVTYPE);
@ -303,7 +301,7 @@ public class Conversions {
if (uqTarget instanceof ICPPClassType) { if (uqTarget instanceof ICPPClassType) {
if (uqSource instanceof ICPPClassType) { if (uqSource instanceof ICPPClassType) {
// 13.3.3.1-6 Conceptual derived to base conversion // 13.3.3.1-6 Conceptual derived to base conversion
int depth= calculateInheritanceDepth(uqSource, uqTarget, point); int depth= calculateInheritanceDepth(uqSource, uqTarget);
if (depth >= 0) { if (depth >= 0) {
if (depth == 0) { if (depth == 0) {
return new Cost(source, target, Rank.IDENTITY); return new Cost(source, target, Rank.IDENTITY);
@ -316,17 +314,17 @@ public class Conversions {
if (udc == UDCMode.FORBIDDEN) if (udc == UDCMode.FORBIDDEN)
return Cost.NO_CONVERSION; return Cost.NO_CONVERSION;
return copyInitializationOfClass(valueCat, source, (ICPPClassType) uqTarget, udc == UDCMode.DEFER, point); return copyInitializationOfClass(valueCat, source, (ICPPClassType) uqTarget, udc == UDCMode.DEFER);
} }
if (uqSource instanceof ICPPClassType) { if (uqSource instanceof ICPPClassType) {
if (udc == UDCMode.FORBIDDEN) if (udc == UDCMode.FORBIDDEN)
return Cost.NO_CONVERSION; return Cost.NO_CONVERSION;
return initializationByConversion(valueCat, source, (ICPPClassType) uqSource, target, udc == UDCMode.DEFER, point, false); return initializationByConversion(valueCat, source, (ICPPClassType) uqSource, target, udc == UDCMode.DEFER, false);
} }
return checkStandardConversionSequence(uqSource, target, point); return checkStandardConversionSequence(uqSource, target);
} }
/** /**
@ -334,8 +332,8 @@ public class Conversions {
* These are the declared fields, excluding static fields and anonymous bit-fields * These are the declared fields, excluding static fields and anonymous bit-fields
* ([decl.init.aggr] p6). * ([decl.init.aggr] p6).
*/ */
static ICPPField[] getFieldsForAggregateInitialization(ICPPClassType targetClass, IASTNode point) { static ICPPField[] getFieldsForAggregateInitialization(ICPPClassType targetClass) {
ICPPField[] fields = ClassTypeHelper.getDeclaredFields(targetClass, point); ICPPField[] fields = targetClass.getDeclaredFields();
ICPPField[] result = fields; ICPPField[] result = fields;
int j = 0; int j = 0;
for (int i = 0; i < fields.length; ++i) { for (int i = 0; i < fields.length; ++i) {
@ -358,9 +356,9 @@ public class Conversions {
* Checks whether 'targetClass' can be initialized from 'list' according to the rules for * Checks whether 'targetClass' can be initialized from 'list' according to the rules for
* aggregate initialization ([dcl.init.aggr]). * aggregate initialization ([dcl.init.aggr]).
*/ */
static boolean checkAggregateInitialization(EvalInitList list, ICPPClassType targetClass, IASTNode point) static boolean checkAggregateInitialization(EvalInitList list, ICPPClassType targetClass)
throws DOMException { throws DOMException {
ICPPField[] fields = getFieldsForAggregateInitialization(targetClass, point); ICPPField[] fields = getFieldsForAggregateInitialization(targetClass);
ICPPEvaluation[] initializers = list.getClauses(); ICPPEvaluation[] initializers = list.getClauses();
// p7: An initializer-list is ill-formed if the number of initializer-clauses exceeds // p7: An initializer-list is ill-formed if the number of initializer-clauses exceeds
@ -377,15 +375,15 @@ public class Conversions {
ICPPField field = fields[i]; ICPPField field = fields[i];
// Each element is copy-initialized from the corresponding initializer-clause. // Each element is copy-initialized from the corresponding initializer-clause.
Cost cost = checkImplicitConversionSequence(field.getType(), initializer.getType(point), Cost cost = checkImplicitConversionSequence(field.getType(), initializer.getType(),
initializer.getValueCategory(point), UDCMode.ALLOWED, Context.ORDINARY, point); initializer.getValueCategory(), UDCMode.ALLOWED, Context.ORDINARY);
if (!cost.converts()) { if (!cost.converts()) {
return false; return false;
} }
// If the initializer-clause is an expression and a narrowing conversion is // If the initializer-clause is an expression and a narrowing conversion is
// required to convert the expression, the program is ill-formed. // required to convert the expression, the program is ill-formed.
if (!(initializer instanceof EvalInitList) && cost.isNarrowingConversion(point)) { if (!(initializer instanceof EvalInitList) && cost.isNarrowingConversion()) {
return false; return false;
} }
} }
@ -409,8 +407,9 @@ public class Conversions {
} }
// Empty initializer list // Empty initializer list
EvalInitList emptyInit = new EvalInitList(ICPPEvaluation.EMPTY_ARRAY, point); EvalInitList emptyInit = new EvalInitList(ICPPEvaluation.EMPTY_ARRAY,
Cost cost = listInitializationSequence(emptyInit, fieldType, UDCMode.ALLOWED, false, point); CPPSemantics.getCurrentLookupPoint());
Cost cost = listInitializationSequence(emptyInit, fieldType, UDCMode.ALLOWED, false);
if (!cost.converts()) { if (!cost.converts()) {
return false; return false;
} }
@ -424,13 +423,13 @@ public class Conversions {
/** /**
* 13.3.3.1.5 List-initialization sequence [over.ics.list] * 13.3.3.1.5 List-initialization sequence [over.ics.list]
*/ */
static Cost listInitializationSequence(EvalInitList arg, IType target, UDCMode udc, boolean isDirect, IASTNode point) throws DOMException { static Cost listInitializationSequence(EvalInitList arg, IType target, UDCMode udc, boolean isDirect) throws DOMException {
Cost result = listInitializationSequenceHelper(arg, target, udc, isDirect, point); Cost result = listInitializationSequenceHelper(arg, target, udc, isDirect);
result.setListInitializationTarget(target); result.setListInitializationTarget(target);
return result; return result;
} }
static Cost listInitializationSequenceHelper(EvalInitList arg, IType target, UDCMode udc, boolean isDirect, IASTNode point) throws DOMException { static Cost listInitializationSequenceHelper(EvalInitList arg, IType target, UDCMode udc, boolean isDirect) throws DOMException {
IType listType= getInitListType(target); IType listType= getInitListType(target);
if (listType == null && target instanceof IArrayType) { if (listType == null && target instanceof IArrayType) {
Number arraySize = ((IArrayType) target).getSize().numberValue(); Number arraySize = ((IArrayType) target).getSize().numberValue();
@ -446,13 +445,13 @@ public class Conversions {
if (listType != null) { if (listType != null) {
ICPPEvaluation[] clauses = arg.getClauses(); ICPPEvaluation[] clauses = arg.getClauses();
Cost worstCost= new Cost(arg.getType(point), target, Rank.IDENTITY); Cost worstCost= new Cost(arg.getType(), target, Rank.IDENTITY);
for (ICPPEvaluation clause : clauses) { for (ICPPEvaluation clause : clauses) {
Cost cost= checkImplicitConversionSequence(listType, clause.getType(point), Cost cost= checkImplicitConversionSequence(listType, clause.getType(),
clause.getValueCategory(point), UDCMode.ALLOWED, Context.ORDINARY, point); clause.getValueCategory(), UDCMode.ALLOWED, Context.ORDINARY);
if (!cost.converts()) if (!cost.converts())
return cost; return cost;
if (cost.isNarrowingConversion(point)) { if (cost.isNarrowingConversion()) {
cost.setRank(Rank.NO_MATCH); cost.setRank(Rank.NO_MATCH);
return cost; return cost;
} }
@ -469,27 +468,26 @@ public class Conversions {
return Cost.NO_CONVERSION; return Cost.NO_CONVERSION;
ICPPClassType classTarget= (ICPPClassType) noCVTarget; ICPPClassType classTarget= (ICPPClassType) noCVTarget;
if (TypeTraits.isAggregateClass(classTarget, point) && if (TypeTraits.isAggregateClass(classTarget) && checkAggregateInitialization(arg, classTarget)) {
checkAggregateInitialization(arg, classTarget, point)) { Cost cost= new Cost(arg.getType(), target, Rank.IDENTITY);
Cost cost= new Cost(arg.getType(point), target, Rank.IDENTITY);
cost.setUserDefinedConversion(null); cost.setUserDefinedConversion(null);
return cost; return cost;
} }
return listInitializationOfClass(arg, classTarget, isDirect, udc == UDCMode.DEFER, point); return listInitializationOfClass(arg, classTarget, isDirect, udc == UDCMode.DEFER);
} }
ICPPEvaluation[] args = arg.getClauses(); ICPPEvaluation[] args = arg.getClauses();
if (args.length == 1) { if (args.length == 1) {
final ICPPEvaluation firstArg = args[0]; final ICPPEvaluation firstArg = args[0];
if (!firstArg.isInitializerList()) { if (!firstArg.isInitializerList()) {
Cost cost= checkImplicitConversionSequence(target, firstArg.getType(point), firstArg.getValueCategory(point), udc, Context.ORDINARY, point); Cost cost= checkImplicitConversionSequence(target, firstArg.getType(), firstArg.getValueCategory(), udc, Context.ORDINARY);
if (cost.isNarrowingConversion(point)) { if (cost.isNarrowingConversion()) {
return Cost.NO_CONVERSION; return Cost.NO_CONVERSION;
} }
return cost; return cost;
} }
} else if (args.length == 0) { } else if (args.length == 0) {
return new Cost(arg.getType(point), target, Rank.IDENTITY); return new Cost(arg.getType(), target, Rank.IDENTITY);
} }
return Cost.NO_CONVERSION; return Cost.NO_CONVERSION;
@ -538,7 +536,7 @@ public class Conversions {
* Note this is not a symmetric relation. * Note this is not a symmetric relation.
* @return inheritance distance, or -1, if <code>cv1t1</code> is not reference-related to <code>cv2t2</code> * @return inheritance distance, or -1, if <code>cv1t1</code> is not reference-related to <code>cv2t2</code>
*/ */
private static final int isReferenceRelated(IType cv1Target, IType cv2Source, IASTNode point) { private static final int isReferenceRelated(IType cv1Target, IType cv2Source) {
IType t= SemanticUtil.getNestedType(cv1Target, TDEF | REF); IType t= SemanticUtil.getNestedType(cv1Target, TDEF | REF);
IType s= SemanticUtil.getNestedType(cv2Source, TDEF | REF); IType s= SemanticUtil.getNestedType(cv2Source, TDEF | REF);
@ -573,7 +571,7 @@ public class Conversions {
s= SemanticUtil.getNestedType(((IQualifierType) s).getType(), TDEF | REF); s= SemanticUtil.getNestedType(((IQualifierType) s).getType(), TDEF | REF);
if (t instanceof ICPPClassType && s instanceof ICPPClassType) { if (t instanceof ICPPClassType && s instanceof ICPPClassType) {
return SemanticUtil.calculateInheritanceDepth(s, t, point); return SemanticUtil.calculateInheritanceDepth(s, t);
} }
} }
if (t == s || (t != null && s != null && t.isSameType(s))) { if (t == s || (t != null && s != null && t.isSameType(s))) {
@ -589,8 +587,8 @@ public class Conversions {
* @return The cost for converting or <code>null</code> if <code>cv1t1</code> is not * @return The cost for converting or <code>null</code> if <code>cv1t1</code> is not
* reference-compatible with <code>cv2t2</code> * reference-compatible with <code>cv2t2</code>
*/ */
private static final Cost isReferenceCompatible(IType cv1Target, IType cv2Source, boolean isImpliedObject, IASTNode point) { private static final Cost isReferenceCompatible(IType cv1Target, IType cv2Source, boolean isImpliedObject) {
int inheritanceDist= isReferenceRelated(cv1Target, cv2Source, point); int inheritanceDist= isReferenceRelated(cv1Target, cv2Source);
if (inheritanceDist < 0) if (inheritanceDist < 0)
return null; return null;
final int cmp= compareQualifications(cv1Target, cv2Source); final int cmp= compareQualifications(cv1Target, cv2Source);
@ -614,7 +612,7 @@ public class Conversions {
* [4] Standard Conversions * [4] Standard Conversions
* Computes the cost of using the standard conversion sequence from source to target. * Computes the cost of using the standard conversion sequence from source to target.
*/ */
private static final Cost checkStandardConversionSequence(IType source, IType target, IASTNode point) { private static final Cost checkStandardConversionSequence(IType source, IType target) {
final Cost cost= new Cost(source, target, Rank.IDENTITY); final Cost cost= new Cost(source, target, Rank.IDENTITY);
if (lvalue_to_rvalue(cost)) if (lvalue_to_rvalue(cost))
return cost; return cost;
@ -622,7 +620,7 @@ public class Conversions {
if (promotion(cost)) if (promotion(cost))
return cost; return cost;
if (conversion(cost, point)) if (conversion(cost))
return cost; return cost;
if (qualificationConversion(cost)) if (qualificationConversion(cost))
@ -634,9 +632,9 @@ public class Conversions {
} }
// 13.3.1.7 Initialization by list-initialization // 13.3.1.7 Initialization by list-initialization
static Cost listInitializationOfClass(EvalInitList arg, ICPPClassType t, boolean isDirect, boolean deferUDC, IASTNode point) throws DOMException { static Cost listInitializationOfClass(EvalInitList arg, ICPPClassType t, boolean isDirect, boolean deferUDC) throws DOMException {
if (deferUDC) { if (deferUDC) {
Cost c= new Cost(arg.getType(point), t, Rank.USER_DEFINED_CONVERSION); Cost c= new Cost(arg.getType(), t, Rank.USER_DEFINED_CONVERSION);
c.setDeferredUDC(isDirect ? DeferredUDC.DIRECT_LIST_INIT_OF_CLASS : DeferredUDC.LIST_INIT_OF_CLASS); c.setDeferredUDC(isDirect ? DeferredUDC.DIRECT_LIST_INIT_OF_CLASS : DeferredUDC.LIST_INIT_OF_CLASS);
return c; return c;
} }
@ -645,13 +643,13 @@ public class Conversions {
ICPPConstructor usedCtor= null; ICPPConstructor usedCtor= null;
Cost bestCost= null; Cost bestCost= null;
boolean hasInitListConstructor= false; boolean hasInitListConstructor= false;
final ICPPConstructor[] constructors = ClassTypeHelper.getConstructors(t, point); final ICPPConstructor[] constructors = t.getConstructors();
ICPPConstructor[] ctors= constructors; ICPPConstructor[] ctors= constructors;
for (ICPPConstructor ctor : ctors) { for (ICPPConstructor ctor : ctors) {
final int minArgCount = ctor.getRequiredArgumentCount(); final int minArgCount = ctor.getRequiredArgumentCount();
if (minArgCount == 0) { if (minArgCount == 0) {
if (arg.getClauses().length == 0) { if (arg.getClauses().length == 0) {
Cost c= new Cost(arg.getType(point), t, Rank.IDENTITY); Cost c= new Cost(arg.getType(), t, Rank.IDENTITY);
c.setUserDefinedConversion(ctor); c.setUserDefinedConversion(ctor);
return c; return c;
} }
@ -661,7 +659,7 @@ public class Conversions {
final IType target = parTypes[0]; final IType target = parTypes[0];
if (getInitListType(target) != null) { if (getInitListType(target) != null) {
hasInitListConstructor= true; hasInitListConstructor= true;
Cost cost= listInitializationSequence(arg, target, UDCMode.FORBIDDEN, isDirect, point); Cost cost= listInitializationSequence(arg, target, UDCMode.FORBIDDEN, isDirect);
if (cost.converts()) { if (cost.converts()) {
int cmp= cost.compareTo(bestCost); int cmp= cost.compareTo(bestCost);
if (bestCost == null || cmp < 0) { if (bestCost == null || cmp < 0) {
@ -694,7 +692,7 @@ public class Conversions {
} }
// No initializer-list constructor // No initializer-list constructor
LookupData data= new LookupData(t.getNameCharArray(), null, point); LookupData data= new LookupData(t.getNameCharArray(), null, CPPSemantics.getCurrentLookupPoint());
final ICPPEvaluation[] expandedArgs = arg.getClauses(); final ICPPEvaluation[] expandedArgs = arg.getClauses();
data.setFunctionArguments(false, expandedArgs); data.setFunctionArguments(false, expandedArgs);
data.fNoNarrowing= true; data.fNoNarrowing= true;
@ -719,11 +717,11 @@ public class Conversions {
final IBinding result= CPPSemantics.resolveFunction(data, filteredConstructors, true, false); final IBinding result= CPPSemantics.resolveFunction(data, filteredConstructors, true, false);
final Cost c; final Cost c;
if (result instanceof ICPPMethod) { if (result instanceof ICPPMethod) {
c= new Cost(arg.getType(point), t, Rank.IDENTITY); c= new Cost(arg.getType(), t, Rank.IDENTITY);
c.setUserDefinedConversion((ICPPMethod) result); c.setUserDefinedConversion((ICPPMethod) result);
} else if (result instanceof IProblemBinding } else if (result instanceof IProblemBinding
&& ((IProblemBinding) result).getID() == IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP) { && ((IProblemBinding) result).getID() == IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP) {
c = new Cost(arg.getType(point), t, Rank.USER_DEFINED_CONVERSION); c = new Cost(arg.getType(), t, Rank.USER_DEFINED_CONVERSION);
c.setAmbiguousUDC(true); c.setAmbiguousUDC(true);
} else { } else {
c= Cost.NO_CONVERSION; c= Cost.NO_CONVERSION;
@ -740,7 +738,7 @@ public class Conversions {
* 13.3.1.4 Copy-initialization of class by user-defined conversion [over.match.copy] * 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, static final Cost copyInitializationOfClass(ValueCategory valueCat, IType source, ICPPClassType t,
boolean deferUDC, IASTNode point) throws DOMException { boolean deferUDC) throws DOMException {
if (deferUDC) { if (deferUDC) {
Cost c= new Cost(source, t, Rank.USER_DEFINED_CONVERSION); Cost c= new Cost(source, t, Rank.USER_DEFINED_CONVERSION);
c.setDeferredUDC(DeferredUDC.COPY_INIT_OF_CLASS); c.setDeferredUDC(DeferredUDC.COPY_INIT_OF_CLASS);
@ -749,9 +747,9 @@ public class Conversions {
FunctionCost cost1= null; FunctionCost cost1= null;
Cost cost2= null; Cost cost2= null;
ICPPFunction[] ctors= ClassTypeHelper.getConstructors(t, point); ICPPFunction[] ctors= t.getConstructors();
ctors = CPPTemplates.instantiateForFunctionCall(ctors, null, ctors = CPPTemplates.instantiateForFunctionCall(ctors, null,
Collections.singletonList(source), Collections.singletonList(valueCat), false, point); Collections.singletonList(source), Collections.singletonList(valueCat), false);
for (ICPPFunction f : ctors) { for (ICPPFunction f : ctors) {
if (!(f instanceof ICPPConstructor) || f instanceof IProblemBinding) if (!(f instanceof ICPPConstructor) || f instanceof IProblemBinding)
@ -767,7 +765,7 @@ public class Conversions {
FunctionCost c1; FunctionCost c1;
if (ptypes.length == 0) { if (ptypes.length == 0) {
if (ctor.takesVarArgs()) { if (ctor.takesVarArgs()) {
c1= new FunctionCost(ctor, new Cost(source, null, Rank.ELLIPSIS_CONVERSION), point); c1= new FunctionCost(ctor, new Cost(source, null, Rank.ELLIPSIS_CONVERSION));
} else { } else {
continue; continue;
} }
@ -779,7 +777,7 @@ public class Conversions {
if (ctor.getRequiredArgumentCount() > 1) if (ctor.getRequiredArgumentCount() > 1)
continue; continue;
c1= new FunctionCost(ctor, checkImplicitConversionSequence(ptype, source, valueCat, UDCMode.FORBIDDEN, Context.ORDINARY, point), point); c1= new FunctionCost(ctor, checkImplicitConversionSequence(ptype, source, valueCat, UDCMode.FORBIDDEN, Context.ORDINARY));
} }
int cmp= c1.compareTo(null, cost1); int cmp= c1.compareTo(null, cost1);
if (cmp <= 0) { if (cmp <= 0) {
@ -795,8 +793,8 @@ public class Conversions {
final IType uqSource= getNestedType(source, TDEF | REF | CVTYPE); final IType uqSource= getNestedType(source, TDEF | REF | CVTYPE);
if (uqSource instanceof ICPPClassType) { if (uqSource instanceof ICPPClassType) {
ICPPFunction[] ops = SemanticUtil.getConversionOperators((ICPPClassType) uqSource, point); ICPPFunction[] ops = SemanticUtil.getConversionOperators((ICPPClassType) uqSource);
ops= CPPTemplates.instantiateConversionTemplates(ops, t, point); ops= CPPTemplates.instantiateConversionTemplates(ops, t);
for (final ICPPFunction f : ops) { for (final ICPPFunction f : ops) {
if (f instanceof ICPPMethod && !(f instanceof IProblemBinding)) { if (f instanceof ICPPMethod && !(f instanceof IProblemBinding)) {
ICPPMethod op= (ICPPMethod) f; ICPPMethod op= (ICPPMethod) f;
@ -804,14 +802,14 @@ public class Conversions {
continue; continue;
final IType returnType = op.getType().getReturnType(); final IType returnType = op.getType().getReturnType();
final IType uqReturnType= getNestedType(returnType, REF | TDEF | CVTYPE); final IType uqReturnType= getNestedType(returnType, REF | TDEF | CVTYPE);
final int dist = SemanticUtil.calculateInheritanceDepth(uqReturnType, t, point); final int dist = SemanticUtil.calculateInheritanceDepth(uqReturnType, t);
if (dist >= 0) { if (dist >= 0) {
IType implicitType= CPPSemantics.getImplicitParameterType(op); IType implicitType= CPPSemantics.getImplicitParameterType(op);
final Cost udcCost = isReferenceCompatible(getNestedType(implicitType, TDEF | REF), source, true, point); final Cost udcCost = isReferenceCompatible(getNestedType(implicitType, TDEF | REF), source, true);
if (udcCost != null) { if (udcCost != null) {
// Make sure top-level cv-qualifiers are compared // Make sure top-level cv-qualifiers are compared
udcCost.setReferenceBinding(ReferenceBinding.LVALUE_REF); udcCost.setReferenceBinding(ReferenceBinding.LVALUE_REF);
FunctionCost c1= new FunctionCost(op, udcCost, point); FunctionCost c1= new FunctionCost(op, udcCost);
int cmp= c1.compareTo(null, cost1); int cmp= c1.compareTo(null, cost1);
if (cmp <= 0) { if (cmp <= 0) {
cost1= c1; cost1= c1;
@ -839,14 +837,15 @@ public class Conversions {
/** /**
* 13.3.1.5 Initialization by conversion function [over.match.conv] * 13.3.1.5 Initialization by conversion function [over.match.conv]
*/ */
static Cost initializationByConversion(ValueCategory valueCat, IType source, ICPPClassType uqSource, IType target, boolean deferUDC, IASTNode point, boolean allowExplicitConversion) throws DOMException { static Cost initializationByConversion(ValueCategory valueCat, IType source, ICPPClassType uqSource,
IType target, boolean deferUDC, boolean allowExplicitConversion) throws DOMException {
if (deferUDC) { if (deferUDC) {
Cost c= new Cost(source, target, Rank.USER_DEFINED_CONVERSION); Cost c= new Cost(source, target, Rank.USER_DEFINED_CONVERSION);
c.setDeferredUDC(DeferredUDC.INIT_BY_CONVERSION); c.setDeferredUDC(DeferredUDC.INIT_BY_CONVERSION);
return c; return c;
} }
ICPPFunction[] ops = SemanticUtil.getConversionOperators(uqSource, point); ICPPFunction[] ops = SemanticUtil.getConversionOperators(uqSource);
ops= CPPTemplates.instantiateConversionTemplates(ops, target, point); ops= CPPTemplates.instantiateConversionTemplates(ops, target);
FunctionCost cost1= null; FunctionCost cost1= null;
Cost cost2= null; Cost cost2= null;
for (final ICPPFunction f : ops) { for (final ICPPFunction f : ops) {
@ -859,12 +858,12 @@ public class Conversions {
ICPPFunctionType functionType = op.getType(); ICPPFunctionType functionType = op.getType();
final IType returnType = functionType.getReturnType(); final IType returnType = functionType.getReturnType();
IType uqReturnType= getNestedType(returnType, TDEF | ALLCVQ); IType uqReturnType= getNestedType(returnType, TDEF | ALLCVQ);
Cost c2= checkImplicitConversionSequence(target, uqReturnType, valueCategoryFromReturnType(uqReturnType), UDCMode.FORBIDDEN, Context.ORDINARY, point); Cost c2= checkImplicitConversionSequence(target, uqReturnType, valueCategoryFromReturnType(uqReturnType), UDCMode.FORBIDDEN, Context.ORDINARY);
if (c2.converts()) { if (c2.converts()) {
if (isExplicitConversion && c2.getRank() != Rank.IDENTITY) if (isExplicitConversion && c2.getRank() != Rank.IDENTITY)
continue; continue;
IType implicitType= CPPSemantics.getImplicitParameterType(op); IType implicitType= CPPSemantics.getImplicitParameterType(op);
final Cost udcCost = isReferenceCompatible(getNestedType(implicitType, TDEF | REF), source, true, point); final Cost udcCost = isReferenceCompatible(getNestedType(implicitType, TDEF | REF), source, true);
if (udcCost != null) { if (udcCost != null) {
// Make sure top-level cv-qualifiers are compared // Make sure top-level cv-qualifiers are compared
if (functionType.hasRefQualifier() && functionType.isRValueReference()) { if (functionType.hasRefQualifier() && functionType.isRValueReference()) {
@ -872,7 +871,7 @@ public class Conversions {
} else { } else {
udcCost.setReferenceBinding(ReferenceBinding.LVALUE_REF); udcCost.setReferenceBinding(ReferenceBinding.LVALUE_REF);
} }
FunctionCost c1= new FunctionCost(op, udcCost, point); FunctionCost c1= new FunctionCost(op, udcCost);
int cmp= c1.compareTo(null, cost1); int cmp= c1.compareTo(null, cost1);
if (cmp <= 0) { if (cmp <= 0) {
cost1= c1; cost1= c1;
@ -1125,7 +1124,7 @@ public class Conversions {
* [4.10] Pointer conversions * [4.10] Pointer conversions
* [4.11] Pointer to member conversions * [4.11] Pointer to member conversions
*/ */
private static final boolean conversion(Cost cost, IASTNode point) { private static final boolean conversion(Cost cost) {
final IType s = cost.source; final IType s = cost.source;
final IType t = cost.target; final IType t = cost.target;
@ -1196,7 +1195,7 @@ public class Conversions {
// to an rvalue of type "pointer to cv B", where B is a base class of D. // 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); IType srcPtrTgt= getNestedType(srcPtr.getType(), TDEF | CVTYPE | REF);
if (tgtPtrTgt instanceof ICPPClassType && srcPtrTgt instanceof ICPPClassType) { if (tgtPtrTgt instanceof ICPPClassType && srcPtrTgt instanceof ICPPClassType) {
int depth= SemanticUtil.calculateInheritanceDepth(srcPtrTgt, tgtPtrTgt, point); int depth= SemanticUtil.calculateInheritanceDepth(srcPtrTgt, tgtPtrTgt);
if (depth == -1) { if (depth == -1) {
cost.setRank(Rank.NO_MATCH); cost.setRank(Rank.NO_MATCH);
return true; return true;
@ -1219,7 +1218,7 @@ public class Conversions {
IType tt = tpm.getType(); IType tt = tpm.getType();
if (st != null && tt != null && st.isSameType(tt)) { if (st != null && tt != null && st.isSameType(tt)) {
int depth = SemanticUtil.calculateInheritanceDepth(tpm.getMemberOfClass(), int depth = SemanticUtil.calculateInheritanceDepth(tpm.getMemberOfClass(),
spm.getMemberOfClass(), point); spm.getMemberOfClass());
if (depth == -1) { if (depth == -1) {
cost.setRank(Rank.NO_MATCH); cost.setRank(Rank.NO_MATCH);
return true; return true;
@ -1274,7 +1273,7 @@ public class Conversions {
* Composite pointer type computed as described in 5.9-2 except that if the conversion to * Composite pointer type computed as described in 5.9-2 except that if the conversion to
* the pointer is not possible, the method returns {@code null}. * the pointer is not possible, the method returns {@code null}.
*/ */
public static IType compositePointerType(IType t1, IType t2, IASTNode point) { public static IType compositePointerType(IType t1, IType t2) {
t1 = SemanticUtil.getNestedType(t1, TDEF); t1 = SemanticUtil.getNestedType(t1, TDEF);
t2 = SemanticUtil.getNestedType(t2, TDEF); t2 = SemanticUtil.getNestedType(t2, TDEF);
final boolean isPtr1 = t1 instanceof IPointerType; final boolean isPtr1 = t1 instanceof IPointerType;
@ -1306,7 +1305,7 @@ public class Conversions {
return addQualifiers(p2, p1.isConst(), p1.isVolatile(), p1.isRestrict()); return addQualifiers(p2, p1.isConst(), p1.isVolatile(), p1.isRestrict());
} }
IType t= mergePointers(target1, target2, point, true, true); IType t= mergePointers(target1, target2, true, true);
if (t == null) if (t == null)
return null; return null;
if (t == target1) if (t == target1)
@ -1316,7 +1315,7 @@ public class Conversions {
return copyPointer(p1, t, false, false); return copyPointer(p1, t, false, false);
} }
private static IType mergePointers(IType t1, IType t2, IASTNode point, boolean allcq, boolean allowInheritance) { private static IType mergePointers(IType t1, IType t2, boolean allcq, boolean allowInheritance) {
t1= getNestedType(t1, TDEF | REF); t1= getNestedType(t1, TDEF | REF);
t2= getNestedType(t2, TDEF | REF); t2= getNestedType(t2, TDEF | REF);
if (t1 instanceof IPointerType && t2 instanceof IPointerType) { if (t1 instanceof IPointerType && t2 instanceof IPointerType) {
@ -1330,7 +1329,7 @@ public class Conversions {
return null; return null;
final IType p1target = p1.getType(); final IType p1target = p1.getType();
IType merged= mergePointers(p1target, p2.getType(), point, allcq && (cv1.isConst() || cv2.isConst()), false); IType merged= mergePointers(p1target, p2.getType(), allcq && (cv1.isConst() || cv2.isConst()), false);
if (merged == null) if (merged == null)
return null; return null;
if (p1target == merged && cv1.isAtLeastAsQualifiedAs(cv2)) if (p1target == merged && cv1.isAtLeastAsQualifiedAs(cv2))
@ -1369,9 +1368,9 @@ public class Conversions {
} else if (allowInheritance) { } else if (allowInheritance) {
// Allow for conversion from pointer-to-derived to pointer-to-base as per [conv.ptr] p3. // Allow for conversion from pointer-to-derived to pointer-to-base as per [conv.ptr] p3.
IType base; IType base;
if (SemanticUtil.calculateInheritanceDepth(uq1, uq2, point) > 0) { if (SemanticUtil.calculateInheritanceDepth(uq1, uq2) > 0) {
base = uq2; base = uq2;
} else if (SemanticUtil.calculateInheritanceDepth(uq2, uq1, point) > 0) { } else if (SemanticUtil.calculateInheritanceDepth(uq2, uq1) > 0) {
base = uq1; base = uq1;
} else { } else {
return null; return null;

View file

@ -14,7 +14,6 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumeration;
@ -305,7 +304,7 @@ public class Cost {
return buf.toString(); return buf.toString();
} }
public boolean isNarrowingConversion(IASTNode point) { public boolean isNarrowingConversion() {
if (!fCouldNarrow) if (!fCouldNarrow)
return false; return false;
@ -356,7 +355,7 @@ public class Cost {
constantExprExceptionApplies = true; constantExprExceptionApplies = true;
} else if (BuiltinOperators.isIntegral(basicSource) } else if (BuiltinOperators.isIntegral(basicSource)
&& BuiltinOperators.isIntegral(basicTarget) && BuiltinOperators.isIntegral(basicTarget)
&& !ArithmeticConversion.fitsIntoType(basicTarget, basicSource, point)) { && !ArithmeticConversion.fitsIntoType(basicTarget, basicSource)) {
// From an integer type or unscoped enumeration type to an integer type that // From an integer type or unscoped enumeration type to an integer type that
// cannot represent all the values of the original type // cannot represent all the values of the original type
constantExprExceptionApplies = true; constantExprExceptionApplies = true;

View file

@ -101,8 +101,8 @@ public class DestructorCallCollector {
return destructorNames; return destructorNames;
} }
static ICPPMethod findDestructor(ICPPClassType classType, IASTNode point) { static ICPPMethod findDestructor(ICPPClassType classType) {
return ClassTypeHelper.getMethodInClass(classType, MethodKind.DTOR, point); return ClassTypeHelper.getMethodInClass(classType, MethodKind.DTOR);
} }
protected void addDestructorCall(IASTName name, ICPPMethod destructor) { protected void addDestructorCall(IASTName name, ICPPMethod destructor) {
@ -129,10 +129,15 @@ public class DestructorCallCollector {
if (name instanceof IASTImplicitName && !(name.getParent() instanceof ICPPASTNewExpression)) { if (name instanceof IASTImplicitName && !(name.getParent() instanceof ICPPASTNewExpression)) {
IBinding binding = name.resolveBinding(); IBinding binding = name.resolveBinding();
if (binding instanceof ICPPConstructor) { if (binding instanceof ICPPConstructor) {
ICPPClassType classType = ((ICPPConstructor) binding).getClassOwner(); CPPSemantics.pushLookupPoint(name);
ICPPMethod destructor = findDestructor(classType, name); try {
if (destructor != null && !isBoundToVariable(name)) { ICPPClassType classType = ((ICPPConstructor) binding).getClassOwner();
addDestructorCall(name, destructor); ICPPMethod destructor = findDestructor(classType);
if (destructor != null && !isBoundToVariable(name)) {
addDestructorCall(name, destructor);
}
} finally {
CPPSemantics.popLookupPoint();
} }
} }
} }
@ -183,14 +188,19 @@ public class DestructorCallCollector {
IASTNode scopeNode = ((ICPPASTInternalScope) scope).getPhysicalNode(); IASTNode scopeNode = ((ICPPASTInternalScope) scope).getPhysicalNode();
if (scopeNode.equals(owner)) { if (scopeNode.equals(owner)) {
IType type = SemanticUtil.getNestedType(var.getType(), TDEF | CVTYPE); IType type = SemanticUtil.getNestedType(var.getType(), TDEF | CVTYPE);
if (type instanceof ICPPClassType) { CPPSemantics.pushLookupPoint(name);
ICPPMethod destructor = findDestructor((ICPPClassType) type, name); try {
if (destructor != null) { if (type instanceof ICPPClassType) {
addDestructorCall(name, destructor); ICPPMethod destructor = findDestructor((ICPPClassType) type);
if (destructor != null) {
addDestructorCall(name, destructor);
}
} else if (type instanceof ICPPReferenceType) {
IASTDeclarator decl = (IASTDeclarator) name.getParent();
addDestructorCallForTemporaryBoundToReference(decl);
} }
} else if (type instanceof ICPPReferenceType) { } finally {
IASTDeclarator decl = (IASTDeclarator) name.getParent(); CPPSemantics.popLookupPoint();
addDestructorCallForTemporaryBoundToReference(decl);
} }
} }
} }
@ -213,7 +223,7 @@ public class DestructorCallCollector {
IBinding binding = name.resolveBinding(); IBinding binding = name.resolveBinding();
if (binding instanceof ICPPConstructor) { if (binding instanceof ICPPConstructor) {
ICPPClassType classType = ((ICPPConstructor) binding).getClassOwner(); ICPPClassType classType = ((ICPPConstructor) binding).getClassOwner();
ICPPMethod destructor = findDestructor(classType, name); ICPPMethod destructor = findDestructor(classType);
if (destructor != null) { if (destructor != null) {
addDestructorCall(name, destructor); addDestructorCall(name, destructor);
} }

View file

@ -134,28 +134,28 @@ public class EvalBinary extends CPPDependentEvaluation {
} }
@Override @Override
public IType getType(IASTNode point) { public IType getType() {
if (fType == null) { if (fType == null) {
if (isTypeDependent()) { if (isTypeDependent()) {
fType= new TypeOfDependentExpression(this); fType= new TypeOfDependentExpression(this);
} else { } else {
ICPPFunction overload = getOverload(point); ICPPFunction overload = getOverload();
if (overload != null) { if (overload != null) {
fType= ExpressionTypes.restoreTypedefs( fType= ExpressionTypes.restoreTypedefs(
ExpressionTypes.typeFromFunctionCall(overload), ExpressionTypes.typeFromFunctionCall(overload), fArg1.getType(), fArg2.getType());
fArg1.getType(point), fArg2.getType(point));
} else { } else {
fType= computeType(point); fType= computeType();
} }
} }
} }
return fType; return fType;
} }
private ICPPEvaluation createOperatorOverloadEvaluation(ICPPFunction overload, IASTNode point, ICPPEvaluation arg1, ICPPEvaluation arg2) { private ICPPEvaluation createOperatorOverloadEvaluation(ICPPFunction overload, ICPPEvaluation arg1, ICPPEvaluation arg2) {
EvalFunctionCall operatorCall; EvalFunctionCall operatorCall;
IASTNode point = CPPSemantics.getCurrentLookupPoint();
if (overload instanceof ICPPMethod) { if (overload instanceof ICPPMethod) {
EvalMemberAccess opAccess = new EvalMemberAccess(arg1.getType(point), ValueCategory.LVALUE, overload, arg1, false, point); EvalMemberAccess opAccess = new EvalMemberAccess(arg1.getType(), ValueCategory.LVALUE, overload, arg1, false, point);
ICPPEvaluation[] args = new ICPPEvaluation[]{opAccess, arg2}; ICPPEvaluation[] args = new ICPPEvaluation[]{opAccess, arg2};
operatorCall = new EvalFunctionCall(args, arg1, point); operatorCall = new EvalFunctionCall(args, arg1, point);
} else { } else {
@ -171,16 +171,16 @@ public class EvalBinary extends CPPDependentEvaluation {
} }
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue() {
ICPPEvaluation arg1 = fArg1; ICPPEvaluation arg1 = fArg1;
ICPPEvaluation arg2 = fArg2; ICPPEvaluation arg2 = fArg2;
ICPPFunction overload = getOverload(point); ICPPFunction overload = getOverload();
if (overload != null) { if (overload != null) {
IType[] parameterTypes = SemanticUtil.getParameterTypesIncludingImplicitThis(overload); IType[] parameterTypes = SemanticUtil.getParameterTypesIncludingImplicitThis(overload);
if (parameterTypes.length >= 2) { if (parameterTypes.length >= 2) {
boolean allowContextualConversion = operatorAllowsContextualConversion(); boolean allowContextualConversion = operatorAllowsContextualConversion();
arg1 = maybeApplyConversion(fArg1, parameterTypes[0], point, allowContextualConversion); arg1 = maybeApplyConversion(fArg1, parameterTypes[0], allowContextualConversion);
arg2 = maybeApplyConversion(fArg2, parameterTypes[1], point, allowContextualConversion); arg2 = maybeApplyConversion(fArg2, parameterTypes[1], allowContextualConversion);
} else { } else {
CCorePlugin.log(IStatus.ERROR, "Unexpected overload for binary operator " + fOperator //$NON-NLS-1$ CCorePlugin.log(IStatus.ERROR, "Unexpected overload for binary operator " + fOperator //$NON-NLS-1$
+ ": '" + overload.getName() + "'"); //$NON-NLS-1$//$NON-NLS-2$ + ": '" + overload.getName() + "'"); //$NON-NLS-1$//$NON-NLS-2$
@ -191,16 +191,16 @@ public class EvalBinary extends CPPDependentEvaluation {
return IntegralValue.ERROR; return IntegralValue.ERROR;
} }
if (fOverloadCall == null) { if (fOverloadCall == null) {
fOverloadCall = createOperatorOverloadEvaluation(overload, point, arg1, arg2); fOverloadCall = createOperatorOverloadEvaluation(overload, arg1, arg2);
} }
return fOverloadCall.getValue(point); return fOverloadCall.getValue();
} }
} }
IValue v1 = arg1.getValue(point); IValue v1 = arg1.getValue();
if (v1 == null || v1 == IntegralValue.UNKNOWN) if (v1 == null || v1 == IntegralValue.UNKNOWN)
return IntegralValue.UNKNOWN; return IntegralValue.UNKNOWN;
IValue v2 = arg2.getValue(point); IValue v2 = arg2.getValue();
if (v2 == null || v2 == IntegralValue.UNKNOWN) if (v2 == null || v2 == IntegralValue.UNKNOWN)
return IntegralValue.UNKNOWN; return IntegralValue.UNKNOWN;
@ -249,26 +249,26 @@ public class EvalBinary extends CPPDependentEvaluation {
} }
@Override @Override
public boolean isConstantExpression(IASTNode point) { public boolean isConstantExpression() {
if (!fCheckedIsConstantExpression) { if (!fCheckedIsConstantExpression) {
fCheckedIsConstantExpression = true; fCheckedIsConstantExpression = true;
fIsConstantExpression = computeIsConstantExpression(point); fIsConstantExpression = computeIsConstantExpression();
} }
return fIsConstantExpression; return fIsConstantExpression;
} }
private boolean computeIsConstantExpression(IASTNode point) { private boolean computeIsConstantExpression() {
return fArg1.isConstantExpression(point) return fArg1.isConstantExpression()
&& fArg2.isConstantExpression(point) && fArg2.isConstantExpression()
&& isNullOrConstexprFunc(getOverload(point)); && isNullOrConstexprFunc(getOverload());
} }
@Override @Override
public ValueCategory getValueCategory(IASTNode point) { public ValueCategory getValueCategory() {
if (isTypeDependent()) if (isTypeDependent())
return ValueCategory.PRVALUE; return ValueCategory.PRVALUE;
ICPPFunction overload = getOverload(point); ICPPFunction overload = getOverload();
if (overload != null) if (overload != null)
return ExpressionTypes.valueCategoryFromFunctionCall(overload); return ExpressionTypes.valueCategoryFromFunctionCall(overload);
@ -288,12 +288,12 @@ public class EvalBinary extends CPPDependentEvaluation {
return LVALUE; return LVALUE;
case op_pmdot: case op_pmdot:
if (!(getType(point) instanceof ICPPFunctionType)) if (!(getType() instanceof ICPPFunctionType))
return fArg1.getValueCategory(point); return fArg1.getValueCategory();
break; break;
case op_pmarrow: case op_pmarrow:
if (!(getType(point) instanceof ICPPFunctionType)) if (!(getType() instanceof ICPPFunctionType))
return LVALUE; return LVALUE;
break; break;
} }
@ -301,47 +301,47 @@ public class EvalBinary extends CPPDependentEvaluation {
return ValueCategory.PRVALUE; return ValueCategory.PRVALUE;
} }
public ICPPFunction getOverload(IASTNode point) { public ICPPFunction getOverload() {
if (fOverload == CPPFunction.UNINITIALIZED_FUNCTION) { if (fOverload == CPPFunction.UNINITIALIZED_FUNCTION) {
fOverload= computeOverload(point); fOverload= computeOverload();
} }
return fOverload; return fOverload;
} }
private ICPPFunction computeOverload(IASTNode point) { private ICPPFunction computeOverload() {
if (isTypeDependent()) if (isTypeDependent())
return null; return null;
if (fOperator == op_arrayAccess) { if (fOperator == op_arrayAccess) {
IType type = fArg1.getType(point); IType type = fArg1.getType();
type= SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE); type= SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE);
if (type instanceof ICPPClassType) { if (type instanceof ICPPClassType) {
return CPPSemantics.findOverloadedBinaryOperator(point, getTemplateDefinitionScope(), return CPPSemantics.findOverloadedBinaryOperator(getTemplateDefinitionScope(),
OverloadableOperator.BRACKET, fArg1, fArg2); OverloadableOperator.BRACKET, fArg1, fArg2);
} }
} else { } else {
final OverloadableOperator op = OverloadableOperator.fromBinaryExpression(fOperator); final OverloadableOperator op = OverloadableOperator.fromBinaryExpression(fOperator);
if (op != null) { if (op != null) {
return CPPSemantics.findOverloadedBinaryOperator(point, getTemplateDefinitionScope(), return CPPSemantics.findOverloadedBinaryOperator(getTemplateDefinitionScope(),
op, fArg1, fArg2); op, fArg1, fArg2);
} }
} }
return null; return null;
} }
public IType computeType(IASTNode point) { public IType computeType() {
// Check for overloaded operator. // Check for overloaded operator.
ICPPFunction o= getOverload(point); ICPPFunction o= getOverload();
if (o != null) if (o != null)
return typeFromFunctionCall(o); return typeFromFunctionCall(o);
final IType originalType1 = fArg1.getType(point); final IType originalType1 = fArg1.getType();
final IType type1 = prvalueTypeWithResolvedTypedefs(originalType1); final IType type1 = prvalueTypeWithResolvedTypedefs(originalType1);
if (type1 instanceof ISemanticProblem) { if (type1 instanceof ISemanticProblem) {
return type1; return type1;
} }
final IType originalType2 = fArg2.getType(point); final IType originalType2 = fArg2.getType();
final IType type2 = prvalueTypeWithResolvedTypedefs(originalType2); final IType type2 = prvalueTypeWithResolvedTypedefs(originalType2);
if (type2 instanceof ISemanticProblem) { if (type2 instanceof ISemanticProblem) {
return type2; return type2;
@ -384,7 +384,7 @@ public class EvalBinary extends CPPDependentEvaluation {
case op_minus: case op_minus:
if (type1 instanceof IPointerType) { if (type1 instanceof IPointerType) {
if (type2 instanceof IPointerType) { if (type2 instanceof IPointerType) {
return CPPVisitor.getPointerDiffType(point); return CPPVisitor.getPointerDiffType();
} }
return originalType1; return originalType1;
} }
@ -396,7 +396,7 @@ public class EvalBinary extends CPPDependentEvaluation {
IType t= ((ICPPPointerToMemberType) type2).getType(); IType t= ((ICPPPointerToMemberType) type2).getType();
if (t instanceof ICPPFunctionType) if (t instanceof ICPPFunctionType)
return t; return t;
if (fOperator == op_pmdot && fArg1.getValueCategory(point) == PRVALUE) { if (fOperator == op_pmdot && fArg1.getValueCategory() == PRVALUE) {
return prvalueType(t); return prvalueType(t);
} }
return glvalueType(t); return glvalueType(t);
@ -434,9 +434,9 @@ public class EvalBinary extends CPPDependentEvaluation {
@Override @Override
public ICPPEvaluation computeForFunctionCall(ActivationRecord record, ConstexprEvaluationContext context) { public ICPPEvaluation computeForFunctionCall(ActivationRecord record, ConstexprEvaluationContext context) {
ICPPFunction overload = getOverload(context.getPoint()); ICPPFunction overload = getOverload();
if (overload != null) { if (overload != null) {
ICPPEvaluation operatorCall = createOperatorOverloadEvaluation(overload, context.getPoint(), fArg1, fArg2); ICPPEvaluation operatorCall = createOperatorOverloadEvaluation(overload, fArg1, fArg2);
return operatorCall.computeForFunctionCall(record, context); return operatorCall.computeForFunctionCall(record, context);
} }
@ -448,10 +448,10 @@ public class EvalBinary extends CPPDependentEvaluation {
ICPPEvaluation eval = fixed1 == fArg1 && fixed2 == fArg2 ? this : new EvalBinary(fOperator, fixed1, fixed2, getTemplateDefinition()); ICPPEvaluation eval = fixed1 == fArg1 && fixed2 == fArg2 ? this : new EvalBinary(fOperator, fixed1, fixed2, getTemplateDefinition());
if (isBinaryOperationWithAssignment(fOperator)) { if (isBinaryOperationWithAssignment(fOperator)) {
if (isPointerToArray(fixed1) && hasIntType(fixed2, context)) { if (isPointerToArray(fixed1) && hasIntType(fixed2)) {
EvalPointer evalPointer = (EvalPointer) fixed1; EvalPointer evalPointer = (EvalPointer) fixed1;
int currentPos = evalPointer.getPosition(); int currentPos = evalPointer.getPosition();
int rhs = fixed2.getValue(context.getPoint()).numberValue().intValue(); int rhs = fixed2.getValue().numberValue().intValue();
if (fOperator == op_plusAssign) { if (fOperator == op_plusAssign) {
evalPointer.setPosition(currentPos + rhs); evalPointer.setPosition(currentPos + rhs);
@ -473,7 +473,7 @@ public class EvalBinary extends CPPDependentEvaluation {
if (fixed2 instanceof EvalPointer) { if (fixed2 instanceof EvalPointer) {
newValue = fixed2; newValue = fixed2;
} else { } else {
newValue = new EvalFixed(fixed2.getType(context.getPoint()), fixed2.getValueCategory(context.getPoint()), fixed2.getValue(context.getPoint())); newValue = new EvalFixed(fixed2.getType(), fixed2.getValueCategory(), fixed2.getValue());
} }
if (updateable1 instanceof EvalReference && !(updateable1 instanceof EvalPointer)) { if (updateable1 instanceof EvalReference && !(updateable1 instanceof EvalPointer)) {
@ -488,29 +488,29 @@ public class EvalBinary extends CPPDependentEvaluation {
} }
return updateable1; return updateable1;
} else if (fOperator == op_arrayAccess) { } else if (fOperator == op_arrayAccess) {
Number numericValue = fixed2.getValue(context.getPoint()).numberValue(); Number numericValue = fixed2.getValue().numberValue();
if (numericValue == null) if (numericValue == null)
return EvalFixed.INCOMPLETE; return EvalFixed.INCOMPLETE;
return new EvalCompositeAccess(fixed1, numericValue.intValue()); return new EvalCompositeAccess(fixed1, numericValue.intValue());
} else if ((isArray(fixed1, context) || isArray(fixed2, context)) && (hasIntType(fixed1, context) || hasIntType(fixed2, context))) { } else if ((isArray(fixed1) || isArray(fixed2)) && (hasIntType(fixed1) || hasIntType(fixed2))) {
int offset = hasIntType(fixed1, context) ? fixed1.getValue(context.getPoint()).numberValue().intValue() : fixed2.getValue(context.getPoint()).numberValue().intValue(); int offset = hasIntType(fixed1) ? fixed1.getValue().numberValue().intValue() : fixed2.getValue().numberValue().intValue();
EvalCompositeAccess evalCompositeAccess = new EvalCompositeAccess(isArray(fixed1, context) ? fixed1 : fixed2, offset); EvalCompositeAccess evalCompositeAccess = new EvalCompositeAccess(isArray(fixed1) ? fixed1 : fixed2, offset);
return new EvalPointer(record, evalCompositeAccess, evalCompositeAccess.getTemplateDefinition()); return new EvalPointer(record, evalCompositeAccess, evalCompositeAccess.getTemplateDefinition());
} else if ((isPointerToArray(fixed1) || isPointerToArray(fixed2)) && (hasIntType(fixed1, context) || hasIntType(fixed2, context))) { } else if ((isPointerToArray(fixed1) || isPointerToArray(fixed2)) && (hasIntType(fixed1) || hasIntType(fixed2))) {
final EvalPointer pointer = isPointerToArray(fixed1) ? ((EvalPointer) fixed1).copy() : ((EvalPointer) fixed2).copy(); final EvalPointer pointer = isPointerToArray(fixed1) ? ((EvalPointer) fixed1).copy() : ((EvalPointer) fixed2).copy();
pointer.setPosition(eval.getValue(context.getPoint()).numberValue().intValue()); pointer.setPosition(eval.getValue().numberValue().intValue());
return pointer; return pointer;
} }
return eval; return eval;
} }
private boolean hasIntType(ICPPEvaluation arg2, ConstexprEvaluationContext context) { private boolean hasIntType(ICPPEvaluation arg2) {
IType type = arg2.getType(context.getPoint()); IType type = arg2.getType();
return (type instanceof IBasicType && ((IBasicType) type).getKind() == IBasicType.Kind.eInt); return (type instanceof IBasicType && ((IBasicType) type).getKind() == IBasicType.Kind.eInt);
} }
private boolean isArray(ICPPEvaluation eval, ConstexprEvaluationContext context) { private boolean isArray(ICPPEvaluation eval) {
return eval.getType(context.getPoint()) instanceof IArrayType; return eval.getType() instanceof IArrayType;
} }
private boolean isPointerToArray(ICPPEvaluation argument) { private boolean isPointerToArray(ICPPEvaluation argument) {

View file

@ -73,7 +73,7 @@ public class EvalBinaryTypeId extends CPPDependentEvaluation {
} }
@Override @Override
public IType getType(IASTNode point) { public IType getType() {
switch (fOperator) { switch (fOperator) {
case __is_base_of: case __is_base_of:
case __is_trivially_assignable: case __is_trivially_assignable:
@ -83,11 +83,11 @@ public class EvalBinaryTypeId extends CPPDependentEvaluation {
} }
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue() {
if (isValueDependent()) if (isValueDependent())
return DependentValue.create(this); return DependentValue.create(this);
return ValueFactory.evaluateBinaryTypeIdExpression(fOperator, fType1, fType2, point); return ValueFactory.evaluateBinaryTypeIdExpression(fOperator, fType1, fType2);
} }
@Override @Override
@ -105,12 +105,12 @@ public class EvalBinaryTypeId extends CPPDependentEvaluation {
} }
@Override @Override
public boolean isConstantExpression(IASTNode point) { public boolean isConstantExpression() {
return true; return true;
} }
@Override @Override
public ValueCategory getValueCategory(IASTNode point) { public ValueCategory getValueCategory() {
return PRVALUE; return PRVALUE;
} }

View file

@ -12,7 +12,6 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
@ -244,29 +243,29 @@ public class EvalBinding extends CPPDependentEvaluation {
} }
@Override @Override
public boolean isConstantExpression(IASTNode point) { public boolean isConstantExpression() {
if (!fCheckedIsConstantExpression) { if (!fCheckedIsConstantExpression) {
fCheckedIsConstantExpression = true; fCheckedIsConstantExpression = true;
fIsConstantExpression = computeIsConstantExpression(point); fIsConstantExpression = computeIsConstantExpression();
} }
return fIsConstantExpression; return fIsConstantExpression;
} }
private boolean computeIsConstantExpression(IASTNode point) { private boolean computeIsConstantExpression() {
return fBinding instanceof IEnumerator return fBinding instanceof IEnumerator
|| fBinding instanceof ICPPFunction || fBinding instanceof ICPPFunction
|| (fBinding instanceof IVariable && isConstexprValue(((IVariable) fBinding).getInitialValue(), point)); || (fBinding instanceof IVariable && isConstexprValue(((IVariable) fBinding).getInitialValue()));
} }
@Override @Override
public IType getType(IASTNode point) { public IType getType() {
if (fType == null) { if (fType == null) {
fType= computeType(point); fType= computeType();
} }
return fType; return fType;
} }
private IType computeType(IASTNode point) { private IType computeType() {
IBinding binding = getBinding(); IBinding binding = getBinding();
if (binding instanceof IEnumerator) { if (binding instanceof IEnumerator) {
return ((IEnumerator) binding).getType(); return ((IEnumerator) binding).getType();
@ -283,6 +282,7 @@ public class EvalBinding extends CPPDependentEvaluation {
} }
if (binding instanceof IVariable) { if (binding instanceof IVariable) {
IType type = ((IVariable) binding).getType(); IType type = ((IVariable) binding).getType();
IASTNode point = CPPSemantics.getCurrentLookupPoint();
if (type instanceof IArrayType && ((IArrayType) type).getSize() == null && if (type instanceof IArrayType && ((IArrayType) type).getSize() == null &&
binding instanceof IIndexBinding && point != null) { binding instanceof IIndexBinding && point != null) {
// Refine the type of the array variable by filling in missing size information. // Refine the type of the array variable by filling in missing size information.
@ -313,17 +313,17 @@ public class EvalBinding extends CPPDependentEvaluation {
} }
} }
} }
return SemanticUtil.mapToAST(glvalueType(type), point); return SemanticUtil.mapToAST(ExpressionTypes.glvalueType(type));
} }
if (binding instanceof IFunction) { if (binding instanceof IFunction) {
final IFunctionType type = ((IFunction) binding).getType(); final IFunctionType type = ((IFunction) binding).getType();
return SemanticUtil.mapToAST(type, point); return SemanticUtil.mapToAST(type);
} }
return ProblemType.UNKNOWN_FOR_EXPRESSION; return ProblemType.UNKNOWN_FOR_EXPRESSION;
} }
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue() {
if (isValueDependent()) if (isValueDependent())
return DependentValue.create(this); return DependentValue.create(this);
@ -331,9 +331,9 @@ public class EvalBinding extends CPPDependentEvaluation {
if (fBinding instanceof ICPPVariable) { if (fBinding instanceof ICPPVariable) {
ICPPEvaluation valueEval = EvalUtil.getVariableValue((ICPPVariable) fBinding, ICPPEvaluation valueEval = EvalUtil.getVariableValue((ICPPVariable) fBinding,
new ActivationRecord(), point); new ActivationRecord());
if (valueEval != null) { if (valueEval != null) {
value = valueEval.getValue(point); value = valueEval.getValue();
} }
} else if (fBinding instanceof IEnumerator) { } else if (fBinding instanceof IEnumerator) {
value= ((IEnumerator) fBinding).getValue(); value= ((IEnumerator) fBinding).getValue();
@ -345,7 +345,7 @@ public class EvalBinding extends CPPDependentEvaluation {
} }
@Override @Override
public ValueCategory getValueCategory(IASTNode point) { public ValueCategory getValueCategory() {
if (fBinding instanceof ICPPTemplateNonTypeParameter) if (fBinding instanceof ICPPTemplateNonTypeParameter)
return ValueCategory.PRVALUE; return ValueCategory.PRVALUE;

View file

@ -76,16 +76,16 @@ public class EvalComma extends CPPDependentEvaluation {
} }
@Override @Override
public boolean isConstantExpression(IASTNode point) { public boolean isConstantExpression() {
if (!fCheckedIsConstantExpression) { if (!fCheckedIsConstantExpression) {
fCheckedIsConstantExpression = true; fCheckedIsConstantExpression = true;
fIsConstantExpression = computeIsConstantExpression(point); fIsConstantExpression = computeIsConstantExpression();
} }
return fIsConstantExpression; return fIsConstantExpression;
} }
private boolean computeIsConstantExpression(IASTNode point) { private boolean computeIsConstantExpression() {
if (!areAllConstantExpressions(fArguments, point)) { if (!areAllConstantExpressions(fArguments)) {
return false; return false;
} }
for (ICPPFunction overload : fOverloads) { for (ICPPFunction overload : fOverloads) {
@ -96,14 +96,14 @@ public class EvalComma extends CPPDependentEvaluation {
return true; return true;
} }
public ICPPFunction[] getOverloads(IASTNode point) { public ICPPFunction[] getOverloads() {
if (fOverloads == null) { if (fOverloads == null) {
fOverloads= computeOverloads(point); fOverloads= computeOverloads();
} }
return fOverloads; return fOverloads;
} }
private ICPPFunction[] computeOverloads(IASTNode point) { private ICPPFunction[] computeOverloads() {
if (fArguments.length < 2) if (fArguments.length < 2)
return NO_FUNCTIONS; return NO_FUNCTIONS;
@ -114,13 +114,13 @@ public class EvalComma extends CPPDependentEvaluation {
ICPPEvaluation e1= fArguments[0]; ICPPEvaluation e1= fArguments[0];
for (int i = 1; i < fArguments.length; i++) { for (int i = 1; i < fArguments.length; i++) {
ICPPEvaluation e2 = fArguments[i]; ICPPEvaluation e2 = fArguments[i];
ICPPFunction overload = CPPSemantics.findOverloadedOperatorComma(point, getTemplateDefinitionScope(), e1, e2); ICPPFunction overload = CPPSemantics.findOverloadedOperatorComma(getTemplateDefinitionScope(), e1, e2);
if (overload == null) { if (overload == null) {
e1= e2; e1= e2;
} else { } else {
overloads[i - 1] = overload; overloads[i - 1] = overload;
e1= new EvalFixed(typeFromFunctionCall(overload), valueCategoryFromFunctionCall(overload), IntegralValue.UNKNOWN); e1= new EvalFixed(typeFromFunctionCall(overload), valueCategoryFromFunctionCall(overload), IntegralValue.UNKNOWN);
if (e1.getType(point) instanceof ISemanticProblem) { if (e1.getType() instanceof ISemanticProblem) {
e1= e2; e1= e2;
} }
} }
@ -129,48 +129,48 @@ public class EvalComma extends CPPDependentEvaluation {
} }
@Override @Override
public IType getType(IASTNode point) { public IType getType() {
if (fType == null) { if (fType == null) {
fType= computeType(point); fType= computeType();
} }
return fType; return fType;
} }
private IType computeType(IASTNode point) { private IType computeType() {
if (isTypeDependent()) { if (isTypeDependent()) {
return new TypeOfDependentExpression(this); return new TypeOfDependentExpression(this);
} }
ICPPFunction[] overloads = getOverloads(point); ICPPFunction[] overloads = getOverloads();
if (overloads.length > 0) { if (overloads.length > 0) {
ICPPFunction last = overloads[overloads.length - 1]; ICPPFunction last = overloads[overloads.length - 1];
if (last != null) { if (last != null) {
return typeFromFunctionCall(last); return typeFromFunctionCall(last);
} }
} }
return fArguments[fArguments.length - 1].getType(point); return fArguments[fArguments.length - 1].getType();
} }
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue() {
ICPPFunction[] overloads = getOverloads(point); ICPPFunction[] overloads = getOverloads();
if (overloads.length > 0) { if (overloads.length > 0) {
// TODO(sprigogin): Simulate execution of a function call. // TODO(sprigogin): Simulate execution of a function call.
return DependentValue.create(this); return DependentValue.create(this);
} }
return fArguments[fArguments.length - 1].getValue(point); return fArguments[fArguments.length - 1].getValue();
} }
@Override @Override
public ValueCategory getValueCategory(IASTNode point) { public ValueCategory getValueCategory() {
ICPPFunction[] overloads = getOverloads(point); ICPPFunction[] overloads = getOverloads();
if (overloads.length > 0) { if (overloads.length > 0) {
ICPPFunction last = overloads[overloads.length - 1]; ICPPFunction last = overloads[overloads.length - 1];
if (last != null) { if (last != null) {
return valueCategoryFromFunctionCall(last); return valueCategoryFromFunctionCall(last);
} }
} }
return fArguments[fArguments.length - 1].getValueCategory(point); return fArguments[fArguments.length - 1].getValueCategory();
} }
@Override @Override

View file

@ -13,7 +13,6 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUti
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.TDEF;
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IField; import org.eclipse.cdt.core.dom.ast.IField;
@ -47,7 +46,7 @@ public final class EvalCompositeAccess implements ICPPEvaluation {
} }
public void update(ICPPEvaluation newValue) { public void update(ICPPEvaluation newValue) {
parent.getValue(null).setSubValue(elementId, newValue); parent.getValue().setSubValue(elementId, newValue);
} }
@Override @Override
@ -56,7 +55,7 @@ public final class EvalCompositeAccess implements ICPPEvaluation {
} }
private ICPPEvaluation getTargetEvaluation() { private ICPPEvaluation getTargetEvaluation() {
return parent.getValue(null).getSubValue(elementId); return parent.getValue().getSubValue(elementId);
} }
@Override @Override
@ -75,13 +74,13 @@ public final class EvalCompositeAccess implements ICPPEvaluation {
} }
@Override @Override
public boolean isConstantExpression(IASTNode point) { public boolean isConstantExpression() {
return getTargetEvaluation().isConstantExpression(point); return getTargetEvaluation().isConstantExpression();
} }
@Override @Override
public IType getType(IASTNode point) { public IType getType() {
IType type = getParent().getType(point); IType type = getParent().getType();
type = SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE); type = SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE);
if (type instanceof IArrayType) { if (type instanceof IArrayType) {
@ -91,13 +90,13 @@ public final class EvalCompositeAccess implements ICPPEvaluation {
InitializerListType initListType = (InitializerListType) type; InitializerListType initListType = (InitializerListType) type;
ICPPEvaluation[] clauses = initListType.getEvaluation().getClauses(); ICPPEvaluation[] clauses = initListType.getEvaluation().getClauses();
if (elementId >= 0 && elementId < clauses.length) { if (elementId >= 0 && elementId < clauses.length) {
return clauses[elementId].getType(point); return clauses[elementId].getType();
} else { } else {
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
} }
} else if (type instanceof ICPPClassType) { } else if (type instanceof ICPPClassType) {
ICPPClassType classType = (ICPPClassType) type; ICPPClassType classType = (ICPPClassType) type;
IField[] fields = ClassTypeHelper.getFields(classType, point); IField[] fields = ClassTypeHelper.getFields(classType);
if (elementId >= 0 && elementId < fields.length) { if (elementId >= 0 && elementId < fields.length) {
return fields[elementId].getType(); return fields[elementId].getType();
} else { } else {
@ -113,13 +112,13 @@ public final class EvalCompositeAccess implements ICPPEvaluation {
} }
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue() {
return getTargetEvaluation().getValue(point); return getTargetEvaluation().getValue();
} }
@Override @Override
public ValueCategory getValueCategory(IASTNode point) { public ValueCategory getValueCategory() {
return getTargetEvaluation().getValueCategory(point); return getTargetEvaluation().getValueCategory();
} }
@Override @Override
@ -133,7 +132,7 @@ public final class EvalCompositeAccess implements ICPPEvaluation {
return getTargetEvaluation().computeForFunctionCall(record, context); return getTargetEvaluation().computeForFunctionCall(record, context);
} else { } else {
ICPPEvaluation evaluatedComposite = parent.computeForFunctionCall(record, context); ICPPEvaluation evaluatedComposite = parent.computeForFunctionCall(record, context);
return evaluatedComposite.getValue(context.getPoint()).getSubValue(elementId).computeForFunctionCall(record, context); return evaluatedComposite.getValue().getSubValue(elementId).computeForFunctionCall(record, context);
} }
} }

View file

@ -69,22 +69,22 @@ public class EvalCompoundStatementExpression extends CPPDependentEvaluation {
} }
@Override @Override
public boolean isConstantExpression(IASTNode point) { public boolean isConstantExpression() {
return fDelegate.isConstantExpression(point); return fDelegate.isConstantExpression();
} }
@Override @Override
public IType getType(IASTNode point) { public IType getType() {
return fDelegate.getType(point); return fDelegate.getType();
} }
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue() {
return fDelegate.getValue(point); return fDelegate.getValue();
} }
@Override @Override
public ValueCategory getValueCategory(IASTNode point) { public ValueCategory getValueCategory() {
return PRVALUE; return PRVALUE;
} }

View file

@ -104,36 +104,36 @@ public class EvalConditional extends CPPDependentEvaluation {
return false; return false;
} }
public ICPPFunction getOverload(IASTNode point) { public ICPPFunction getOverload() {
evaluate(point); evaluate();
return fOverload; return fOverload;
} }
@Override @Override
public IType getType(IASTNode point) { public IType getType() {
evaluate(point); evaluate();
return fType; return fType;
} }
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue() {
IValue condValue = fCondition.getValue(point); IValue condValue = fCondition.getValue();
if (condValue == IntegralValue.UNKNOWN) if (condValue == IntegralValue.UNKNOWN)
return IntegralValue.UNKNOWN; return IntegralValue.UNKNOWN;
Number cond = condValue.numberValue(); Number cond = condValue.numberValue();
if (cond != null) { if (cond != null) {
if (cond.longValue() != 0) { if (cond.longValue() != 0) {
return fPositive == null ? condValue : fPositive.getValue(point); return fPositive == null ? condValue : fPositive.getValue();
} else { } else {
return fNegative.getValue(point); return fNegative.getValue();
} }
} }
return DependentValue.create(this); return DependentValue.create(this);
} }
@Override @Override
public ValueCategory getValueCategory(IASTNode point) { public ValueCategory getValueCategory() {
evaluate(point); evaluate();
return fValueCategory; return fValueCategory;
} }
@ -150,21 +150,21 @@ public class EvalConditional extends CPPDependentEvaluation {
} }
@Override @Override
public boolean isConstantExpression(IASTNode point) { public boolean isConstantExpression() {
if (!fCheckedIsConstantExpression) { if (!fCheckedIsConstantExpression) {
fCheckedIsConstantExpression = true; fCheckedIsConstantExpression = true;
fIsConstantExpression = computeIsConstantExpression(point); fIsConstantExpression = computeIsConstantExpression();
} }
return fIsConstantExpression; return fIsConstantExpression;
} }
private boolean computeIsConstantExpression(IASTNode point) { private boolean computeIsConstantExpression() {
return fCondition.isConstantExpression(point) return fCondition.isConstantExpression()
&& (fPositive == null || fPositive.isConstantExpression(point)) && (fPositive == null || fPositive.isConstantExpression())
&& fNegative.isConstantExpression(point); && fNegative.isConstantExpression();
} }
private void evaluate(IASTNode point) { private void evaluate() {
if (fValueCategory != null) if (fValueCategory != null)
return; return;
@ -172,8 +172,8 @@ public class EvalConditional extends CPPDependentEvaluation {
final ICPPEvaluation positive = fPositive == null ? fCondition : fPositive; final ICPPEvaluation positive = fPositive == null ? fCondition : fPositive;
IType t2 = positive.getType(point); IType t2 = positive.getType();
IType t3 = fNegative.getType(point); IType t3 = fNegative.getType();
final IType uqt2= getNestedType(t2, TDEF | REF | CVTYPE); final IType uqt2= getNestedType(t2, TDEF | REF | CVTYPE);
final IType uqt3= getNestedType(t3, TDEF | REF | CVTYPE); final IType uqt3= getNestedType(t3, TDEF | REF | CVTYPE);
@ -203,8 +203,8 @@ public class EvalConditional extends CPPDependentEvaluation {
return; return;
} }
final ValueCategory vcat2= positive.getValueCategory(point); final ValueCategory vcat2= positive.getValueCategory();
final ValueCategory vcat3= fNegative.getValueCategory(point); final ValueCategory vcat3= fNegative.getValueCategory();
// Same type // Same type
if (t2.isSameType(t3)) { if (t2.isSameType(t3)) {
@ -223,8 +223,8 @@ public class EvalConditional extends CPPDependentEvaluation {
// Different types with at least one class type // Different types with at least one class type
if (isClassType2 || isClassType3) { if (isClassType2 || isClassType3) {
final Cost cost2= convertToMatch(t2, vcat2, uqt2, t3, vcat3, uqt3, point); // sets fType and fValueCategory final Cost cost2= convertToMatch(t2, vcat2, uqt2, t3, vcat3, uqt3); // sets fType and fValueCategory
final Cost cost3= convertToMatch(t3, vcat3, uqt3, t2, vcat2, uqt2, point); // sets fType and fValueCategory final Cost cost3= convertToMatch(t3, vcat3, uqt3, t2, vcat2, uqt2); // sets fType and fValueCategory
if (cost2.converts() || cost3.converts()) { if (cost2.converts() || cost3.converts()) {
if (cost2.converts()) { if (cost2.converts()) {
if (cost3.converts() || cost2.isAmbiguousUDC()) { if (cost3.converts() || cost2.isAmbiguousUDC()) {
@ -253,7 +253,7 @@ public class EvalConditional extends CPPDependentEvaluation {
// 5.16-5: At least one class type but no conversion // 5.16-5: At least one class type but no conversion
if (isClassType2 || isClassType3) { if (isClassType2 || isClassType3) {
fOverload = CPPSemantics.findOverloadedConditionalOperator(point, getTemplateDefinitionScope(), positive, fNegative); fOverload = CPPSemantics.findOverloadedConditionalOperator(getTemplateDefinitionScope(), positive, fNegative);
if (fOverload != null) { if (fOverload != null) {
fType= ExpressionTypes.typeFromFunctionCall(fOverload); fType= ExpressionTypes.typeFromFunctionCall(fOverload);
} else { } else {
@ -270,7 +270,7 @@ public class EvalConditional extends CPPDependentEvaluation {
} else { } else {
fType= CPPArithmeticConversion.convertCppOperandTypes(IASTBinaryExpression.op_plus, t2, t3); fType= CPPArithmeticConversion.convertCppOperandTypes(IASTBinaryExpression.op_plus, t2, t3);
if (fType == null) { if (fType == null) {
fType= Conversions.compositePointerType(t2, t3, point); fType= Conversions.compositePointerType(t2, t3);
if (fType == null) { if (fType == null) {
fType= ProblemType.UNKNOWN_FOR_EXPRESSION; fType= ProblemType.UNKNOWN_FOR_EXPRESSION;
} }
@ -278,12 +278,12 @@ public class EvalConditional extends CPPDependentEvaluation {
} }
} }
private Cost convertToMatch(IType t1, ValueCategory vcat1, IType uqt1, IType t2, ValueCategory vcat2, IType uqt2, IASTNode point) { private Cost convertToMatch(IType t1, ValueCategory vcat1, IType uqt1, IType t2, ValueCategory vcat2, IType uqt2) {
// E2 is an lvalue or E2 is an xvalue // E2 is an lvalue or E2 is an xvalue
try { try {
if (vcat2.isGLValue()) { if (vcat2.isGLValue()) {
IType target= new CPPReferenceType(t2, vcat2 == XVALUE); IType target= new CPPReferenceType(t2, vcat2 == XVALUE);
Cost c= Conversions.checkImplicitConversionSequence(target, t1, vcat1, UDCMode.ALLOWED, Context.REQUIRE_DIRECT_BINDING, point); Cost c= Conversions.checkImplicitConversionSequence(target, t1, vcat1, UDCMode.ALLOWED, Context.REQUIRE_DIRECT_BINDING);
if (c.converts()) { if (c.converts()) {
fType= t2; fType= t2;
fValueCategory= vcat2; fValueCategory= vcat2;
@ -292,7 +292,7 @@ public class EvalConditional extends CPPDependentEvaluation {
} }
// Both are class types and one derives from the other // Both are class types and one derives from the other
if (uqt1 instanceof ICPPClassType && uqt2 instanceof ICPPClassType) { if (uqt1 instanceof ICPPClassType && uqt2 instanceof ICPPClassType) {
int dist= SemanticUtil.calculateInheritanceDepth(uqt1, uqt2, point); int dist= SemanticUtil.calculateInheritanceDepth(uqt1, uqt2);
if (dist >= 0) { if (dist >= 0) {
CVQualifier cv1 = SemanticUtil.getCVQualifier(t1); CVQualifier cv1 = SemanticUtil.getCVQualifier(t1);
CVQualifier cv2 = SemanticUtil.getCVQualifier(t2); CVQualifier cv2 = SemanticUtil.getCVQualifier(t2);
@ -303,14 +303,14 @@ public class EvalConditional extends CPPDependentEvaluation {
} }
return Cost.NO_CONVERSION; return Cost.NO_CONVERSION;
} }
if (SemanticUtil.calculateInheritanceDepth(uqt2, uqt1, point) >= 0) if (SemanticUtil.calculateInheritanceDepth(uqt2, uqt1) >= 0)
return Cost.NO_CONVERSION; return Cost.NO_CONVERSION;
} }
// Unrelated class types or just one class: // Unrelated class types or just one class:
if (vcat2 != PRVALUE) { if (vcat2 != PRVALUE) {
t2= Conversions.lvalue_to_rvalue(t2, false); t2= Conversions.lvalue_to_rvalue(t2, false);
} }
Cost c= Conversions.checkImplicitConversionSequence(t2, t1, vcat1, UDCMode.ALLOWED, Context.ORDINARY, point); Cost c= Conversions.checkImplicitConversionSequence(t2, t1, vcat1, UDCMode.ALLOWED, Context.ORDINARY);
if (c.converts()) { if (c.converts()) {
fType= t2; fType= t2;
fValueCategory= PRVALUE; fValueCategory= PRVALUE;
@ -368,7 +368,7 @@ public class EvalConditional extends CPPDependentEvaluation {
// just the branch that is taken. This avoids infinite recursion // just the branch that is taken. This avoids infinite recursion
// when computing a recursive constexpr function where the base // when computing a recursive constexpr function where the base
// case of the recursion is one of the branches of the conditional. // case of the recursion is one of the branches of the conditional.
Number conditionValue = condition.getValue(context.getPoint()).numberValue(); Number conditionValue = condition.getValue().numberValue();
if (conditionValue != null) { if (conditionValue != null) {
if (conditionValue.longValue() != 0) { if (conditionValue.longValue() != 0) {
return fPositive == null ? null : fPositive.computeForFunctionCall(record, context.recordStep()); return fPositive == null ? null : fPositive.computeForFunctionCall(record, context.recordStep());

View file

@ -101,35 +101,35 @@ public final class EvalConstructor extends CPPDependentEvaluation {
} }
@Override @Override
public boolean isConstantExpression(IASTNode point) { public boolean isConstantExpression() {
if (!fCheckedIsConstantExpression) { if (!fCheckedIsConstantExpression) {
fCheckedIsConstantExpression = true; fCheckedIsConstantExpression = true;
fIsConstantExpression = computeIsConstantExpression(point); fIsConstantExpression = computeIsConstantExpression();
} }
return fIsConstantExpression; return fIsConstantExpression;
} }
private boolean computeIsConstantExpression(IASTNode point) { private boolean computeIsConstantExpression() {
return fConstructor.isConstexpr() && areAllConstantExpressions(fArguments, point); return fConstructor.isConstexpr() && areAllConstantExpressions(fArguments);
} }
@Override @Override
public IType getType(IASTNode point) { public IType getType() {
return fType; return fType;
} }
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue() {
ICPPEvaluation computed = ICPPEvaluation computed =
computeForFunctionCall(new ActivationRecord(), new ConstexprEvaluationContext(point)); computeForFunctionCall(new ActivationRecord(), new ConstexprEvaluationContext());
if (computed == this) if (computed == this)
return IntegralValue.ERROR; return IntegralValue.ERROR;
return computed.getValue(point); return computed.getValue();
} }
@Override @Override
public ValueCategory getValueCategory(IASTNode point) { public ValueCategory getValueCategory() {
return null; return null;
} }
@ -141,17 +141,16 @@ public final class EvalConstructor extends CPPDependentEvaluation {
return this; return this;
} }
final ICPPClassType classType = (ICPPClassType) unwrappedType; final ICPPClassType classType = (ICPPClassType) unwrappedType;
final CompositeValue compositeValue = CompositeValue.create(classType, context.getPoint()); final CompositeValue compositeValue = CompositeValue.create(classType);
ICPPEvaluation[] argList = evaluateArguments(fArguments, callSiteRecord, context); ICPPEvaluation[] argList = evaluateArguments(fArguments, callSiteRecord, context);
EvalFixed constructedObject = new EvalFixed(fType, ValueCategory.PRVALUE, compositeValue); EvalFixed constructedObject = new EvalFixed(fType, ValueCategory.PRVALUE, compositeValue);
CPPVariable binding = new CPPVariable(TEMP_NAME); CPPVariable binding = new CPPVariable(TEMP_NAME);
IASTNode point = context.getPoint(); ActivationRecord localRecord = EvalFunctionCall.createActivationRecord(fConstructor.getParameters(),
ActivationRecord localRecord = EvalFunctionCall.createActivationRecord( argList, constructedObject);
fConstructor.getParameters(), argList, constructedObject, point);
localRecord.update(binding, constructedObject); localRecord.update(binding, constructedObject);
ICPPExecution exec = fConstructor.getConstructorChainExecution(point); ICPPExecution exec = fConstructor.getConstructorChainExecution();
if (exec instanceof ExecConstructorChain) { if (exec instanceof ExecConstructorChain) {
ExecConstructorChain memberInitList = (ExecConstructorChain) exec; ExecConstructorChain memberInitList = (ExecConstructorChain) exec;
Map<IBinding, ICPPEvaluation> ccInitializers = memberInitList.getConstructorChainInitializers(); Map<IBinding, ICPPEvaluation> ccInitializers = memberInitList.getConstructorChainInitializers();
@ -161,21 +160,21 @@ public final class EvalConstructor extends CPPDependentEvaluation {
final ICPPEvaluation memberEval = ccInitializer.getValue(); final ICPPEvaluation memberEval = ccInitializer.getValue();
ICPPEvaluation memberValue = ICPPEvaluation memberValue =
memberEval.computeForFunctionCall(localRecord, context.recordStep()); memberEval.computeForFunctionCall(localRecord, context.recordStep());
ICPPEvaluation[] baseClassValues = memberValue.getValue(point).getAllSubValues(); ICPPEvaluation[] baseClassValues = memberValue.getValue().getAllSubValues();
ICPPField[] baseFields = ClassTypeHelper.getFields(baseClassType, point); ICPPField[] baseFields = ClassTypeHelper.getFields(baseClassType);
for (ICPPField baseField : baseFields) { for (ICPPField baseField : baseFields) {
// TODO: This has the same problem with multiple inheritance as // TODO: This has the same problem with multiple inheritance as
// CompositeValue.create(ICPPClassType). // CompositeValue.create(ICPPClassType).
int fieldPos = CPPASTFieldReference.getFieldPosition(baseField); int fieldPos = CPPASTFieldReference.getFieldPosition(baseField);
constructedObject.getValue(point).setSubValue(fieldPos, baseClassValues[fieldPos]); constructedObject.getValue().setSubValue(fieldPos, baseClassValues[fieldPos]);
} }
} }
} }
} }
ICPPField[] fields = ClassTypeHelper.getDeclaredFields(classType, point); ICPPField[] fields = classType.getDeclaredFields();
for (ICPPField field : fields) { for (ICPPField field : fields) {
final Map.Entry<IBinding, ICPPEvaluation> initializer = final Map.Entry<IBinding, ICPPEvaluation> initializer =
getInitializerFromMemberInitializerList(field, exec); getInitializerFromMemberInitializerList(field, exec);
@ -185,7 +184,7 @@ public final class EvalConstructor extends CPPDependentEvaluation {
ExecDeclarator declaratorExec = getDeclaratorExecutionFromMemberInitializerList(initializer); ExecDeclarator declaratorExec = getDeclaratorExecutionFromMemberInitializerList(initializer);
value = getFieldValue(declaratorExec, classType, localRecord, context); value = getFieldValue(declaratorExec, classType, localRecord, context);
} else { } else {
value = EvalUtil.getVariableValue(field, localRecord, point); value = EvalUtil.getVariableValue(field, localRecord);
} }
final int fieldPos = CPPASTFieldReference.getFieldPosition(field); final int fieldPos = CPPASTFieldReference.getFieldPosition(field);
compositeValue.setSubValue(fieldPos, value); compositeValue.setSubValue(fieldPos, value);
@ -195,8 +194,8 @@ public final class EvalConstructor extends CPPDependentEvaluation {
// - evaluate the arguments again // - evaluate the arguments again
// - create another ActivationRecord (inside evaluateFunctionBody()) // - create another ActivationRecord (inside evaluateFunctionBody())
// Are these necessary? // Are these necessary?
new EvalFunctionCall(argList, constructedObject, point).computeForFunctionCall( new EvalFunctionCall(argList, constructedObject, CPPSemantics.getCurrentLookupPoint())
localRecord, context.recordStep()); .computeForFunctionCall(localRecord, context.recordStep());
return localRecord.getVariable(binding); return localRecord.getVariable(binding);
} }
@ -349,8 +348,9 @@ public final class EvalConstructor extends CPPDependentEvaluation {
CPPFunctionSet functionSet = CPPFunctionSet functionSet =
new CPPFunctionSet(candidates, new ICPPTemplateArgument[]{}, null); new CPPFunctionSet(candidates, new ICPPTemplateArgument[]{}, null);
EvalFunctionSet evalFunctionSet = EvalFunctionSet evalFunctionSet =
new EvalFunctionSet(functionSet, false, false, newType, context.getPoint()); new EvalFunctionSet(functionSet, false, false, newType,
ICPPEvaluation resolved = evalFunctionSet.resolveFunction(newArguments, context.getPoint()); CPPSemantics.getCurrentLookupPoint());
ICPPEvaluation resolved = evalFunctionSet.resolveFunction(newArguments);
if (resolved instanceof EvalBinding) { if (resolved instanceof EvalBinding) {
EvalBinding evalBinding = (EvalBinding) resolved; EvalBinding evalBinding = (EvalBinding) resolved;
newConstructor = (ICPPConstructor) evalBinding.getBinding(); newConstructor = (ICPPConstructor) evalBinding.getBinding();

View file

@ -16,7 +16,6 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.XVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.XVALUE;
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
@ -70,18 +69,6 @@ public final class EvalFixed extends CPPEvaluation {
fValue= value; fValue= value;
} }
public IType getType() {
return fType;
}
public IValue getValue() {
return fValue;
}
public ValueCategory getValueCategory() {
return fValueCategory;
}
@Override @Override
public boolean isInitializerList() { public boolean isInitializerList() {
return false; return false;
@ -111,31 +98,31 @@ public final class EvalFixed extends CPPEvaluation {
} }
@Override @Override
public boolean isConstantExpression(IASTNode point) { public boolean isConstantExpression() {
if (!fCheckedIsConstantExpression) { if (!fCheckedIsConstantExpression) {
fCheckedIsConstantExpression = true; fCheckedIsConstantExpression = true;
fIsConstantExpression = computeIsConstantExpression(point); fIsConstantExpression = computeIsConstantExpression();
} }
return fIsConstantExpression; return fIsConstantExpression;
} }
private boolean computeIsConstantExpression(IASTNode point) { private boolean computeIsConstantExpression() {
return (fType instanceof ICPPClassType && TypeTraits.isEmpty(fType, point)) return (fType instanceof ICPPClassType && TypeTraits.isEmpty(fType))
|| isConstexprValue(fValue, point); || isConstexprValue(fValue);
} }
@Override @Override
public IType getType(IASTNode point) { public IType getType() {
return fType; return fType;
} }
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue() {
return fValue; return fValue;
} }
@Override @Override
public ValueCategory getValueCategory(IASTNode point) { public ValueCategory getValueCategory() {
return fValueCategory; return fValueCategory;
} }

Some files were not shown because too many files have changed in this diff Show more