1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Merge remote-tracking branch 'origin/bug_299911'

This commit is contained in:
Sergey Prigogin 2012-08-08 17:54:16 -07:00
commit e39899ec23
118 changed files with 3611 additions and 2359 deletions

View file

@ -188,7 +188,7 @@ public class AbstractClassInstantiationChecker extends AbstractIndexAstChecker {
* Checks whether specified type (class or typedef to the class) is an abstract class. * Checks whether specified type (class or typedef to the class) is an abstract class.
* If it is, reports violations on each pure virtual method * If it is, reports violations on each pure virtual method
*/ */
private void reportProblemsIfAbstract(IType typeToCheck, IASTNode problemNode ) { private void reportProblemsIfAbstract(IType typeToCheck, IASTNode problemNode) {
IType unwindedType = CxxAstUtils.unwindTypedef(typeToCheck); IType unwindedType = CxxAstUtils.unwindTypedef(typeToCheck);
if (!(unwindedType instanceof ICPPClassType) || unwindedType instanceof IProblemBinding) { if (!(unwindedType instanceof ICPPClassType) || unwindedType instanceof IProblemBinding) {
return; return;
@ -196,7 +196,7 @@ public class AbstractClassInstantiationChecker extends AbstractIndexAstChecker {
ICPPClassType classType = (ICPPClassType) unwindedType; ICPPClassType classType = (ICPPClassType) unwindedType;
ICPPMethod[] pureVirtualMethods = pureVirtualMethodsCache.get(classType); ICPPMethod[] pureVirtualMethods = pureVirtualMethodsCache.get(classType);
if (pureVirtualMethods == null) { if (pureVirtualMethods == null) {
pureVirtualMethods = ClassTypeHelper.getPureVirtualMethods(classType); pureVirtualMethods = ClassTypeHelper.getPureVirtualMethods(classType, problemNode);
pureVirtualMethodsCache.put(classType, pureVirtualMethods); pureVirtualMethodsCache.put(classType, pureVirtualMethods);
} }

View file

@ -27,6 +27,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel;
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.ICPPClassType; 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.ICPPInternalBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
/** /**
@ -46,8 +47,8 @@ public class NonVirtualDestructor extends AbstractIndexAstChecker {
ast.accept(new OnEachClass()); ast.accept(new OnEachClass());
} }
private static ICPPMethod getDestructor(ICPPClassType classType) { private static ICPPMethod getDestructor(ICPPClassType classType, IASTNode point) {
for (ICPPMethod method : classType.getDeclaredMethods()) { for (ICPPMethod method : ClassTypeHelper.getDeclaredMethods(classType, point)) {
if (method.isDestructor()) { if (method.isDestructor()) {
return method; return method;
} }
@ -55,18 +56,18 @@ public class NonVirtualDestructor extends AbstractIndexAstChecker {
return null; return null;
} }
private static boolean hasVirtualDestructor(ICPPClassType classType) { private static boolean hasVirtualDestructor(ICPPClassType classType, IASTNode point) {
checkedClassTypes.add(classType); checkedClassTypes.add(classType);
ICPPMethod destructor = getDestructor(classType); ICPPMethod destructor = getDestructor(classType, point);
if (destructor != null && destructor.isVirtual()) { if (destructor != null && destructor.isVirtual()) {
return true; return true;
} }
ICPPBase[] bases = classType.getBases(); ICPPBase[] bases = ClassTypeHelper.getBases(classType, point);
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)) { if (!checkedClassTypes.contains(cppClassType) && hasVirtualDestructor(cppClassType, point)) {
return true; return true;
} }
} }
@ -89,13 +90,13 @@ public class NonVirtualDestructor extends AbstractIndexAstChecker {
return PROCESS_SKIP; return PROCESS_SKIP;
} }
ICPPClassType classType = (ICPPClassType) binding; ICPPClassType classType = (ICPPClassType) binding;
boolean hasVirtualDestructor = hasVirtualDestructor(classType); boolean hasVirtualDestructor = hasVirtualDestructor(classType, className);
checkedClassTypes.clear(); checkedClassTypes.clear();
if (hasVirtualDestructor) { if (hasVirtualDestructor) {
return PROCESS_SKIP; return PROCESS_SKIP;
} }
ICPPMethod virtualMethod = null; ICPPMethod virtualMethod = null;
for (ICPPMethod method : classType.getAllDeclaredMethods()) { for (ICPPMethod method : ClassTypeHelper.getAllDeclaredMethods(classType, className)) {
if (!method.isDestructor() && method.isVirtual()) { if (!method.isDestructor() && method.isVirtual()) {
virtualMethod = method; virtualMethod = method;
} }
@ -103,7 +104,7 @@ public class NonVirtualDestructor extends AbstractIndexAstChecker {
if (virtualMethod == null) { if (virtualMethod == null) {
return PROCESS_SKIP; return PROCESS_SKIP;
} }
ICPPMethod destructor = getDestructor(classType); ICPPMethod destructor = getDestructor(classType, className);
if (destructor != null && if (destructor != null &&
destructor.getVisibility() != ICPPASTVisibilityLabel.v_public && destructor.getVisibility() != ICPPASTVisibilityLabel.v_public &&
classType.getFriends().length == 0) { classType.getFriends().length == 0) {

View file

@ -5747,7 +5747,7 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
// g<C>(0); // The N member of C is not a non-type // g<C>(0); // The N member of C is not a non-type
// h<D>(0); // The TT member of D is not a template // h<D>(0); // The TT member of D is not a template
// } // }
public void _test14_8_2s8d() throws Exception { public void test14_8_2s8d() throws Exception {
final String content= getAboveComment(); final String content= getAboveComment();
BindingAssertionHelper bh= new BindingAssertionHelper(content, true); BindingAssertionHelper bh= new BindingAssertionHelper(content, true);
bh.assertProblem("f<A>", 0); bh.assertProblem("f<A>", 0);

View file

@ -6252,20 +6252,20 @@ public class AST2CPPTests extends AST2BaseTest {
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); ICPPMethod[] ors= ClassTypeHelper.findOverridden(m0, null);
assertEquals(0, ors.length); assertEquals(0, ors.length);
ors= ClassTypeHelper.findOverridden(m1); ors= ClassTypeHelper.findOverridden(m1, null);
assertEquals(0, ors.length); assertEquals(0, ors.length);
ors= ClassTypeHelper.findOverridden(m2); ors= ClassTypeHelper.findOverridden(m2, null);
assertEquals(1, ors.length); assertEquals(1, ors.length);
assertSame(ors[0], m1); assertSame(ors[0], m1);
ors= ClassTypeHelper.findOverridden(m3); ors= ClassTypeHelper.findOverridden(m3, null);
assertEquals(0, ors.length); assertEquals(0, ors.length);
ors= ClassTypeHelper.findOverridden(m4); ors= ClassTypeHelper.findOverridden(m4, null);
assertEquals(2, ors.length); assertEquals(2, ors.length);
assertSame(ors[0], m2); assertSame(ors[0], m2);
assertSame(ors[1], m1); assertSame(ors[1], m1);
ors= ClassTypeHelper.findOverridden(m5); ors= ClassTypeHelper.findOverridden(m5, null);
assertEquals(1, ors.length); assertEquals(1, ors.length);
assertSame(ors[0], m1); assertSame(ors[0], m1);
} }
@ -8732,14 +8732,14 @@ public class AST2CPPTests extends AST2BaseTest {
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); ICPPMethod[] ors= ClassTypeHelper.findOverridden(m0, null);
assertEquals(0, ors.length); assertEquals(0, ors.length);
ors= ClassTypeHelper.findOverridden(m1); ors= ClassTypeHelper.findOverridden(m1, null);
assertEquals(0, ors.length); assertEquals(0, ors.length);
ors= ClassTypeHelper.findOverridden(m2); ors= ClassTypeHelper.findOverridden(m2, null);
assertEquals(1, ors.length); assertEquals(1, ors.length);
assertSame(ors[0], m0); assertSame(ors[0], m0);
ors= ClassTypeHelper.findOverridden(m3); ors= ClassTypeHelper.findOverridden(m3, null);
assertEquals(0, ors.length); assertEquals(0, ors.length);
} }
@ -9288,7 +9288,7 @@ public class AST2CPPTests extends AST2BaseTest {
// auto f2 (); // missing late return type. // auto f2 (); // missing late return type.
public void testBug332114a() throws Exception { public void testBug332114a() throws Exception {
BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), true); BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), CPP);
IBinding b= bh.assertNonProblem("f2", 0); IBinding b= bh.assertNonProblem("f2", 0);
// Must not throw a NPE // Must not throw a NPE
IndexCPPSignatureUtil.getSignature(b); IndexCPPSignatureUtil.getSignature(b);
@ -9546,7 +9546,7 @@ public class AST2CPPTests extends AST2BaseTest {
public void testRecursiveClassInheritance_Bug357256() throws Exception { public void testRecursiveClassInheritance_Bug357256() throws Exception {
BindingAssertionHelper bh= getAssertionHelper(); BindingAssertionHelper bh= getAssertionHelper();
ICPPClassType c= bh.assertNonProblem("A", 1); ICPPClassType c= bh.assertNonProblem("A", 1);
assertEquals(0, ClassTypeHelper.getPureVirtualMethods(c).length); assertEquals(0, ClassTypeHelper.getPureVirtualMethods(c, null).length);
} }
// template <typename T> struct CT1 {}; // template <typename T> struct CT1 {};
@ -9713,7 +9713,7 @@ public class AST2CPPTests extends AST2BaseTest {
// g( nullptr ); // error // g( nullptr ); // error
// } // }
public void testNullptr_327298b() throws Exception { public void testNullptr_327298b() throws Exception {
BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), true); BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), CPP);
bh.assertProblem("checkNullPtr(1)", 12); bh.assertProblem("checkNullPtr(1)", 12);
bh.assertProblem("checklvalue(nullptr)", 11); bh.assertProblem("checklvalue(nullptr)", 11);
bh.assertProblem("g( nullptr )", 1); bh.assertProblem("g( nullptr )", 1);
@ -9727,7 +9727,7 @@ public class AST2CPPTests extends AST2BaseTest {
// } // }
public void testNullptr_327298c() throws Exception { public void testNullptr_327298c() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), true); BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), CPP);
IFunction f= bh.assertNonProblem("f( nullptr )", 1); IFunction f= bh.assertNonProblem("f( nullptr )", 1);
assertEquals("void (char *)", ASTTypeUtil.getType(f.getType())); assertEquals("void (char *)", ASTTypeUtil.getType(f.getType()));
f= bh.assertNonProblem("f( 0 )", 1); f= bh.assertNonProblem("f( 0 )", 1);
@ -9736,7 +9736,7 @@ public class AST2CPPTests extends AST2BaseTest {
// void foo(struct S s); // void foo(struct S s);
public void testParameterForwardDeclaration_379511() throws Exception { public void testParameterForwardDeclaration_379511() throws Exception {
BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), true); BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), CPP);
ICPPClassType struct= bh.assertNonProblem("S", 1, ICPPClassType.class); ICPPClassType struct= bh.assertNonProblem("S", 1, ICPPClassType.class);
IName[] declarations= bh.getTranslationUnit().getDeclarations(struct); IName[] declarations= bh.getTranslationUnit().getDeclarations(struct);
assertEquals(1, declarations.length); assertEquals(1, declarations.length);

View file

@ -90,7 +90,7 @@ public class SemanticsTests extends AST2BaseTest {
// Test getDeclaredConversionOperators() // Test getDeclaredConversionOperators()
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true); BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
ICPPClassType c= ba.assertNonProblem("X {", 1, ICPPClassType.class); ICPPClassType c= ba.assertNonProblem("X {", 1, ICPPClassType.class);
ICPPMethod[] cops= SemanticUtil.getDeclaredConversionOperators(c); ICPPMethod[] cops= SemanticUtil.getDeclaredConversionOperators(c, null);
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

@ -55,8 +55,10 @@ import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexMacro; import org.eclipse.cdt.core.index.IIndexMacro;
import org.eclipse.cdt.core.index.IndexFilter; import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
/** /**
@ -226,10 +228,10 @@ public class IndexCPPBindingResolutionBugs extends IndexBindingResolutionTestBas
assertInstance(b1, ICPPInstanceCache.class); assertInstance(b1, ICPPInstanceCache.class);
ICPPInstanceCache ct= (ICPPInstanceCache) b1; ICPPInstanceCache ct= (ICPPInstanceCache) b1;
ICPPSpecialization inst= ct.getInstance(new ICPPTemplateArgument[]{new CPPTemplateArgument((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= c2t.getBases(); ICPPBase[] bases= ClassTypeHelper.getBases(c2t, null);
assertEquals(1, bases.length); assertEquals(1, bases.length);
assertInstance(bases[0].getBaseClass(), ICPPClassType.class); assertInstance(bases[0].getBaseClass(), ICPPClassType.class);
} }
@ -998,74 +1000,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"}, ct.getBases()); assertBindings(new String[] {"B"}, ClassTypeHelper.getBases(ct, null));
assertBindings(new String[] {"n", "m", "B", "CT"}, ct.getAllDeclaredMethods()); assertBindings(new String[] {"n", "m", "B", "CT"}, ClassTypeHelper.getAllDeclaredMethods(ct, null));
assertBindings(new String[] {"CT", "CT"}, ct.getConstructors()); assertBindings(new String[] {"CT", "CT"}, ClassTypeHelper.getConstructors(ct, null));
assertBindings(new String[] {"g"}, ct.getDeclaredFields()); assertBindings(new String[] {"g"}, ClassTypeHelper.getDeclaredFields(ct, null));
assertBindings(new String[] {"n", "CT"}, ct.getDeclaredMethods()); assertBindings(new String[] {"n", "CT"}, ClassTypeHelper.getDeclaredMethods(ct, null));
assertBindings(new String[] {"f", "g"}, ct.getFields()); assertBindings(new String[] {"f", "g"}, ClassTypeHelper.getFields(ct, null));
assertBindings(new String[] {"m", "n", "CT", "CT", "~CT", "B", "B", "~B", "operator =", "operator ="}, ct.getMethods()); assertBindings(new String[] {"m", "n", "CT", "CT", "~CT", "B", "B", "~B", "operator =", "operator ="}, ClassTypeHelper.getMethods(ct, null));
assertBindings(new String[] {"O"}, ct.getNestedClasses()); assertBindings(new String[] {"O"}, ClassTypeHelper.getNestedClasses(ct, null));
// 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"}, ct.getBases()); assertBindings(new String[] {"A"}, ClassTypeHelper.getBases(ct, null));
assertBindings(new String[] {"o", "l", "A", "CT", "CT"}, ct.getAllDeclaredMethods()); assertBindings(new String[] {"o", "l", "A", "CT", "CT"}, ClassTypeHelper.getAllDeclaredMethods(ct, null));
assertBindings(new String[] {"CT", "CT", "CT"}, ct.getConstructors()); assertBindings(new String[] {"CT", "CT", "CT"}, ClassTypeHelper.getConstructors(ct, null));
assertBindings(new String[] {"h"}, ct.getDeclaredFields()); assertBindings(new String[] {"h"}, ClassTypeHelper.getDeclaredFields(ct, null));
assertBindings(new String[] {"o", "CT", "CT"}, ct.getDeclaredMethods()); assertBindings(new String[] {"o", "CT", "CT"}, ClassTypeHelper.getDeclaredMethods(ct, null));
assertBindings(new String[] {"e", "h"}, ct.getFields()); assertBindings(new String[] {"e", "h"}, ClassTypeHelper.getFields(ct, null));
assertBindings(new String[] {"l", "o", "CT", "CT", "CT", "~CT", "A", "A", "~A", "operator =", "operator ="}, ct.getMethods()); assertBindings(new String[] {"l", "o", "CT", "CT", "CT", "~CT", "A", "A", "~A", "operator =", "operator ="}, ClassTypeHelper.getMethods(ct, null));
assertBindings(new String[] {"P"}, ct.getNestedClasses()); assertBindings(new String[] {"P"}, ClassTypeHelper.getNestedClasses(ct, null));
// 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"}, ct.getBases()); assertBindings(new String[] {"B"}, ClassTypeHelper.getBases(ct, null));
assertBindings(new String[] {"n", "m", "B", "C"}, ct.getAllDeclaredMethods()); assertBindings(new String[] {"n", "m", "B", "C"}, ClassTypeHelper.getAllDeclaredMethods(ct, null));
assertBindings(new String[] {"C", "C"}, ct.getConstructors()); assertBindings(new String[] {"C", "C"}, ClassTypeHelper.getConstructors(ct, null));
assertBindings(new String[] {"g"}, ct.getDeclaredFields()); assertBindings(new String[] {"g"}, ClassTypeHelper.getDeclaredFields(ct, null));
assertBindings(new String[] {"n", "C"}, ct.getDeclaredMethods()); assertBindings(new String[] {"n", "C"}, ClassTypeHelper.getDeclaredMethods(ct, null));
assertBindings(new String[] {"f", "g"}, ct.getFields()); assertBindings(new String[] {"f", "g"}, ClassTypeHelper.getFields(ct, null));
assertBindings(new String[] {"m", "n", "C", "C", "~C", "B", "B", "~B", "operator =", "operator ="}, ct.getMethods()); assertBindings(new String[] {"m", "n", "C", "C", "~C", "B", "B", "~B", "operator =", "operator ="}, ClassTypeHelper.getMethods(ct, null));
assertBindings(new String[] {"O"}, ct.getNestedClasses()); assertBindings(new String[] {"O"}, ClassTypeHelper.getNestedClasses(ct, null));
// 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"}, ct.getBases()); assertBindings(new String[] {"B"}, ClassTypeHelper.getBases(ct, null));
assertBindings(new String[] {"n", "m", "B", "CT"}, ct.getAllDeclaredMethods()); assertBindings(new String[] {"n", "m", "B", "CT"}, ClassTypeHelper.getAllDeclaredMethods(ct, null));
assertBindings(new String[] {"CT", "CT"}, ct.getConstructors()); assertBindings(new String[] {"CT", "CT"}, ClassTypeHelper.getConstructors(ct, null));
assertBindings(new String[] {"g"}, ct.getDeclaredFields()); assertBindings(new String[] {"g"}, ClassTypeHelper.getDeclaredFields(ct, null));
assertBindings(new String[] {"n", "CT"}, ct.getDeclaredMethods()); assertBindings(new String[] {"n", "CT"}, ClassTypeHelper.getDeclaredMethods(ct, null));
assertBindings(new String[] {"f", "g"}, ct.getFields()); assertBindings(new String[] {"f", "g"}, ClassTypeHelper.getFields(ct, null));
assertBindings(new String[] {"m", "n", "CT", "CT", "~CT", "B", "B", "~B", "operator =", "operator ="}, ct.getMethods()); assertBindings(new String[] {"m", "n", "CT", "CT", "~CT", "B", "B", "~B", "operator =", "operator ="}, ClassTypeHelper.getMethods(ct, null));
assertBindings(new String[] {"O"}, ct.getNestedClasses()); assertBindings(new String[] {"O"}, ClassTypeHelper.getNestedClasses(ct, null));
// 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"}, ct.getBases()); assertBindings(new String[] {"A"}, ClassTypeHelper.getBases(ct, null));
assertBindings(new String[] {"o", "l", "A", "C", "C"}, ct.getAllDeclaredMethods()); assertBindings(new String[] {"o", "l", "A", "C", "C"}, ClassTypeHelper.getAllDeclaredMethods(ct, null));
assertBindings(new String[] {"C", "C", "C"}, ct.getConstructors()); assertBindings(new String[] {"C", "C", "C"}, ClassTypeHelper.getConstructors(ct, null));
assertBindings(new String[] {"h"}, ct.getDeclaredFields()); assertBindings(new String[] {"h"}, ClassTypeHelper.getDeclaredFields(ct, null));
assertBindings(new String[] {"o", "C", "C"}, ct.getDeclaredMethods()); assertBindings(new String[] {"o", "C", "C"}, ClassTypeHelper.getDeclaredMethods(ct, null));
assertBindings(new String[] {"e", "h"}, ct.getFields()); assertBindings(new String[] {"e", "h"}, ClassTypeHelper.getFields(ct, null));
assertBindings(new String[] {"l", "o", "C", "C", "C", "~C", "A", "A", "~A", "operator =", "operator ="}, ct.getMethods()); assertBindings(new String[] {"l", "o", "C", "C", "C", "~C", "A", "A", "~A", "operator =", "operator ="}, ClassTypeHelper.getMethods(ct, null));
assertBindings(new String[] {"P"}, ct.getNestedClasses()); assertBindings(new String[] {"P"}, ClassTypeHelper.getNestedClasses(ct, null));
// 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"}, ct.getBases()); assertBindings(new String[] {"A"}, ClassTypeHelper.getBases(ct, null));
assertBindings(new String[] {"o", "l", "A", "CT", "CT"}, ct.getAllDeclaredMethods()); assertBindings(new String[] {"o", "l", "A", "CT", "CT"}, ClassTypeHelper.getAllDeclaredMethods(ct, null));
assertBindings(new String[] {"CT", "CT", "CT"}, ct.getConstructors()); assertBindings(new String[] {"CT", "CT", "CT"}, ClassTypeHelper.getConstructors(ct, null));
assertBindings(new String[] {"h"}, ct.getDeclaredFields()); assertBindings(new String[] {"h"}, ClassTypeHelper.getDeclaredFields(ct, null));
assertBindings(new String[] {"o", "CT", "CT"}, ct.getDeclaredMethods()); assertBindings(new String[] {"o", "CT", "CT"}, ClassTypeHelper.getDeclaredMethods(ct, null));
assertBindings(new String[] {"e", "h"}, ct.getFields()); assertBindings(new String[] {"e", "h"}, ClassTypeHelper.getFields(ct, null));
assertBindings(new String[] {"l", "o", "CT", "CT", "CT", "~CT", "A", "A", "~A", "operator =", "operator ="}, ct.getMethods()); assertBindings(new String[] {"l", "o", "CT", "CT", "CT", "~CT", "A", "A", "~A", "operator =", "operator ="}, ClassTypeHelper.getMethods(ct, null));
assertBindings(new String[] {"P"}, ct.getNestedClasses()); assertBindings(new String[] {"P"}, ClassTypeHelper.getNestedClasses(ct, null));
} }
// void func(const int* x) {} // void func(const int* x) {}

View file

@ -10,6 +10,7 @@
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.index.tests; package org.eclipse.cdt.internal.index.tests;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -56,14 +57,14 @@ import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IndexFilter; import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.core.parser.util.ObjectMap;
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.CPPTemplateArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
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.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.index.IIndexScope; import org.eclipse.cdt.internal.core.index.IIndexScope;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
/** /**
* Tests for exercising resolution of template bindings against IIndex * Tests for exercising resolution of template bindings against IIndex
*/ */
@ -629,23 +630,23 @@ 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= ct2.getBases(); ICPPBase[] bss2= ClassTypeHelper.getBases(ct2, null);
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();
assertInstance(ct2b, ICPPTemplateInstance.class); assertInstance(ct2b, ICPPTemplateInstance.class);
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= ct.getBases(); ICPPBase[] bss= ClassTypeHelper.getBases(ct, null);
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= ct1.getBases(); ICPPBase[] bss1= ClassTypeHelper.getBases(ct1, null);
assertEquals(1, bss1.length); assertEquals(1, bss1.length);
assertInstance(bss1[0].getBaseClass(), ICPPClassType.class); assertInstance(bss1[0].getBaseClass(), ICPPClassType.class);
} }
@ -672,13 +673,13 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
IBinding b0= getBindingFromASTName("A<B> ab", 4); IBinding b0= getBindingFromASTName("A<B> ab", 4);
assertInstance(b0, ICPPClassType.class); assertInstance(b0, ICPPClassType.class);
assertInstance(b0, ICPPSpecialization.class); assertInstance(b0, ICPPSpecialization.class);
ICPPClassType ct= (ICPPClassType) b0; ICPPClassType ct= (ICPPClassType) b0;
ICPPMethod[] dms= ct.getDeclaredMethods(); ICPPMethod[] dms= ClassTypeHelper.getDeclaredMethods(ct, null);
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= ct.getDeclaredFields(); ICPPField[] fs= ClassTypeHelper.getDeclaredFields(ct, null);
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];
@ -1556,8 +1557,8 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
IBinding inst2= CPPTemplates.instantiate(tmplDef, inst.getTemplateArguments(), name); IBinding inst2= CPPTemplates.instantiate(tmplDef, inst.getTemplateArguments(), name);
assertSame(inst, inst2); assertSame(inst, inst2);
IBinding charInst1= CPPTemplates.instantiate(tmplDef, new ICPPTemplateArgument[] {new CPPTemplateArgument(new CPPBasicType(Kind.eChar, 0))}, name); IBinding charInst1= CPPTemplates.instantiate(tmplDef, new ICPPTemplateArgument[] {new CPPTemplateTypeArgument(new CPPBasicType(Kind.eChar, 0))}, name);
IBinding charInst2= CPPTemplates.instantiate(tmplDef, new ICPPTemplateArgument[] {new CPPTemplateArgument(new CPPBasicType(Kind.eChar, 0))}, name); IBinding charInst2= CPPTemplates.instantiate(tmplDef, new ICPPTemplateArgument[] {new CPPTemplateTypeArgument(new CPPBasicType(Kind.eChar, 0))}, name);
assertSame(charInst1, charInst2); assertSame(charInst1, charInst2);
} }
@ -1574,7 +1575,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= ct.getDeclaredMethods(); ICPPMethod[] ms= ClassTypeHelper.getDeclaredMethods(ct, null);
assertEquals(1, ms.length); assertEquals(1, ms.length);
assertEquals(m, ms[0]); assertEquals(m, ms[0]);
} }
@ -1849,16 +1850,16 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
methods= ct.getMethods(); methods= ct.getMethods();
assertEquals(14, methods.length); assertEquals(14, methods.length);
ICPPBase[] bases = ct.getBases(); ICPPBase[] bases = ClassTypeHelper.getBases(ct, null);
assertEquals(1, bases.length); assertEquals(1, bases.length);
IField field = ct.findField("bfield"); IField field = ct.findField("bfield");
assertNotNull(field); assertNotNull(field);
IField[] fields = ct.getFields(); IField[] fields = ClassTypeHelper.getFields(ct, null);
assertEquals(2, fields.length); assertEquals(2, fields.length);
IBinding[] friends = ct.getFriends(); IBinding[] friends = ClassTypeHelper.getFriends(ct, null);
assertEquals(0, friends.length); // not yet supported assertEquals(0, friends.length); // not yet supported
} }

View file

@ -18,6 +18,7 @@ import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMManager; import org.eclipse.cdt.core.dom.IPDOMManager;
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.IField;
import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
@ -34,6 +35,7 @@ import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.core.testplugin.CTestPlugin; import org.eclipse.cdt.core.testplugin.CTestPlugin;
import org.eclipse.cdt.core.testplugin.util.TestSourceReader; import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
import org.eclipse.cdt.internal.core.CCoreInternals; import org.eclipse.cdt.internal.core.CCoreInternals;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences; import org.eclipse.cdt.internal.core.pdom.indexer.IndexerPreferences;
@ -237,9 +239,10 @@ public class CPPClassTemplateTests extends PDOMTestBase {
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();
assertEquals(1, ct.getFields().length); IField[] fields = ClassTypeHelper.getFields(ct, null);
assertInstance(ct.getFields()[0].getType(), IPointerType.class); assertEquals(1, fields.length);
IPointerType pt= (IPointerType) ct.getFields()[0].getType(); assertInstance(fields[0].getType(), IPointerType.class);
IPointerType pt= (IPointerType) fields[0].getType();
assertInstance(pt.getType(), IFunctionType.class); assertInstance(pt.getType(), IFunctionType.class);
IFunctionType ft= (IFunctionType) pt.getType(); IFunctionType ft= (IFunctionType) pt.getType();
assertInstance(ft.getReturnType(), ICPPClassType.class); assertInstance(ft.getReturnType(), ICPPClassType.class);

View file

@ -7,9 +7,12 @@
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.dom.ast; package org.eclipse.cdt.core.dom.ast;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
/** /**
* Models a value of a variable, enumerator or expression. * Models a value of a variable, enumerator or expression.
* *
@ -19,27 +22,33 @@ package org.eclipse.cdt.core.dom.ast;
*/ */
public interface IValue { public interface IValue {
/** /**
* Returns the value as a number, or <code>null</code> if this is not possible. * Returns the value as a number, or {@code null} if it is not possible.
*/ */
Long numericalValue(); Long numericalValue();
/** /**
* Returns an internal representation of the expression that builds up * Returns the evaluation object if this value is dependent, or {@code null} otherwise.
* the value. It is suitable for instantiating dependent values but may not be * If {@link #numericalValue()} returns {@code null}, {@link #getEvaluation()} returns
* used for the purpose of displaying values. * not {@code null} and vice versa.
* @noreference This method is not intended to be referenced by clients.
*/ */
char[] getInternalExpression(); ICPPEvaluation getEvaluation();
/** /**
* A value may be dependent on template parameters, in which case a list * Returns a signature uniquely identifying the value. Two values with identical
* of unknown bindings is maintained for later instantiation. * signatures are guaranteed to be equal.
*/
IBinding[] getUnknownBindings();
/**
* Returns a signature containing both the internal representation and
* the unknown bindings. The representation is sufficient to distinguish values
* for the purpose of instantiation, it may not be used to display the value.
*/ */
char[] getSignature(); char[] getSignature();
/**
* @deprecated Returns an empty character array.
*/
@Deprecated
char[] getInternalExpression();
/**
* @deprecated Returns an empty array.
*/
@Deprecated
IBinding[] getUnknownBindings();
} }

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp; package org.eclipse.cdt.core.dom.ast.cpp;
@ -20,7 +20,6 @@ import org.eclipse.cdt.core.dom.ast.IASTInitializerList;
* @noimplement This interface is not intended to be implemented by clients. * @noimplement This interface is not intended to be implemented by clients.
*/ */
public interface ICPPASTInitializerList extends IASTInitializerList, ICPPASTInitializerClause, ICPPASTPackExpandable { public interface ICPPASTInitializerList extends IASTInitializerList, ICPPASTInitializerClause, ICPPASTPackExpandable {
@Override @Override
ICPPASTInitializerList copy(); ICPPASTInitializerList copy();

View file

@ -1,17 +1,16 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2010 IBM Corporation and others. * Copyright (c) 2004, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Andrew Niefer (IBM Corporation) - initial API and implementation * Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp; package org.eclipse.cdt.core.dom.ast.cpp;
/** /**
* Interface for class scopes. * Interface for class scopes.
* *
@ -20,17 +19,15 @@ package org.eclipse.cdt.core.dom.ast.cpp;
*/ */
public interface ICPPClassScope extends ICPPScope { public interface ICPPClassScope extends ICPPScope {
/** /**
* Get the binding for the class this scope is associated with * Returns the binding for the class this scope is associated with.
*
*/ */
ICPPClassType getClassType(); ICPPClassType getClassType();
/** /**
* Returns an array of methods that were implicitly added to this class * Returns an array of methods that were implicitly added to this class
* scope. These methods may or may not have been explicitly declared in the * scope. These methods may or may not have been explicitly declared in
* code. The methods that will be implicitly declared are: the default * the code. The methods that will be implicitly declared are: the default
* constructor, copy constructor, copy assignment operator, and destructor * constructor, copy constructor, copy assignment operator, and destructor
*
*/ */
public ICPPMethod[] getImplicitMethods(); public ICPPMethod[] getImplicitMethods();

View file

@ -1,17 +1,19 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2008, 2009 Wind River Systems, Inc. and others. * Copyright (c) 2008, 2012 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp; package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.IASTNode; 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.IField;
/** /**
* Specializations of all sorts of class types. * Specializations of all sorts of class types.
@ -21,7 +23,6 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
* @noimplement This interface is not intended to be implemented by clients. * @noimplement This interface is not intended to be implemented by clients.
*/ */
public interface ICPPClassSpecialization extends ICPPSpecialization, ICPPClassType { public interface ICPPClassSpecialization extends ICPPSpecialization, ICPPClassType {
@Override @Override
ICPPClassType getSpecializedBinding(); ICPPClassType getSpecializedBinding();
@ -37,4 +38,67 @@ public interface ICPPClassSpecialization extends ICPPSpecialization, ICPPClassTy
* @since 5.5 * @since 5.5
*/ */
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
*/
ICPPBase[] getBases(IASTNode point);
/**
* Similar to {@link ICPPClassType#getConstructors()} but a accepts a starting point
* for template instantiation.
* @since 5.5
*/
ICPPConstructor[] getConstructors(IASTNode point);
/**
* Similar to {@link ICPPClassType#getDeclaredFields()} but a accepts a starting point
* for template instantiation.
* @since 5.5
*/
ICPPField[] getDeclaredFields(IASTNode point);
/**
* Similar to {@link ICPPClassType#getMethods()} but a accepts a starting point
* for template instantiation.
* @since 5.5
*/
ICPPMethod[] getMethods(IASTNode point);
/**
* Similar to {@link ICPPClassType#getAllDeclaredMethods()} but a accepts a starting point
* for template instantiation.
* @since 5.5
*/
ICPPMethod[] getAllDeclaredMethods(IASTNode point);
/**
* Similar to {@link ICPPClassType#getDeclaredMethods()} but a accepts a starting point
* for template instantiation.
* @since 5.5
*/
ICPPMethod[] getDeclaredMethods(IASTNode point);
/**
* Similar to {@link ICPPClassType#getFriends()} but a accepts a starting point
* for template instantiation.
* @since 5.5
*/
IBinding[] getFriends(IASTNode point);
/**
* Similar to {@link ICPPClassType#getFriends()} but a accepts a starting point
* for template instantiation.
* @since 5.5
*/
IField[] getFields(IASTNode point);
/**
* Similar to {@link ICPPClassType#getNestedClasses()} but a accepts a starting point
* for template instantiation.
* @since 5.5
*/
ICPPClassType[] getNestedClasses(IASTNode point);
} }

View file

@ -6,12 +6,11 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Andrew Niefer (IBM) - Initial API and implementation * Andrew Niefer (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp; package org.eclipse.cdt.core.dom.ast.cpp;
/** /**
* @noextend This interface is not intended to be extended by clients. * @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients. * @noimplement This interface is not intended to be implemented by clients.

View file

@ -25,10 +25,8 @@ public interface ICPPClassType extends ICompositeType, ICPPBinding {
public static final int k_class = ICPPASTCompositeTypeSpecifier.k_class; public static final int k_class = ICPPASTCompositeTypeSpecifier.k_class;
/** /**
* Returns a list of base class relationships. The list is empty if there * Returns an array of base class relationships. The returned array is empty if there
* are none. * are none.
*
* @return List of ICPPBase
*/ */
public ICPPBase[] getBases(); public ICPPBase[] getBases();
@ -88,18 +86,17 @@ public interface ICPPClassType extends ICompositeType, ICPPBinding {
* Returns an array of ICPPConstructor objects representing the constructors * Returns an array of ICPPConstructor objects representing the constructors
* for this class. This list includes both declared and implicit * for this class. This list includes both declared and implicit
* constructors. * constructors.
*
*/ */
public ICPPConstructor[] getConstructors(); public ICPPConstructor[] getConstructors();
/** /**
* return an array of bindings for those classes/functions declared as * Returns an array of bindings for those classes/functions declared as
* friends of this class. * friends of this class.
*/ */
public IBinding[] getFriends(); public IBinding[] getFriends();
/** /**
* return an array of nested classes/structures * Returns an array of nested classes/structures
*/ */
public ICPPClassType[] getNestedClasses(); public ICPPClassType[] getNestedClasses();
} }

View file

@ -0,0 +1,30 @@
/*******************************************************************************
* Copyright (c) 2012 Google, Inc and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Sergey Prigogin (Google) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IType;
/**
* Specialization of a method.
* @since 5.5
*
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface ICPPMethodSpecialization extends ICPPSpecialization, ICPPMethod {
/**
* Similar to {@link ICPPFunction#getExceptionSpecification()} but a accepts a starting point
* for template instantiation.
* @since 5.5
*/
IType[] getExceptionSpecification(IASTNode point);
}

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM Rational Software - Initial API and implementation * IBM Rational Software - Initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.parser; package org.eclipse.cdt.core.parser;
@ -19,11 +19,10 @@ import java.util.Map;
*/ */
public interface IScannerInfo { public interface IScannerInfo {
/** /**
* Returns a <code>Map</code> containing all the defined preprocessor * Returns a {@link Map} containing all the defined preprocessor symbols and their values.
* symbols and their values.
* Symbols defined without values have an empty string for a value. For * Symbols defined without values have an empty string for a value. For
* example,-Dsymbol=value would have a map entry (symbol,value). A symbol * example, -Dsymbol=value would have a map entry (symbol, value). A symbol
* defined as -Dsymbol= would have a map entry of (symbol,""). * defined as -Dsymbol= would have a map entry of (symbol, "").
*/ */
public Map<String, String> getDefinedSymbols(); public Map<String, String> getDefinedSymbols();
@ -41,9 +40,10 @@ public interface IScannerInfo {
* <br> E.g.: /System/Library/Frameworks/__framework__.framework/Headers/__header__, * <br> E.g.: /System/Library/Frameworks/__framework__.framework/Headers/__header__,
* /System/Library/Frameworks/__framework__.framework/PrivateHeaders/__header__ * /System/Library/Frameworks/__framework__.framework/PrivateHeaders/__header__
* would handle the framework search for '/System/Library/Frameworks' * would handle the framework search for '/System/Library/Frameworks'
* <br> The variables are handled only, if a search path element makes use of both of the variables. * <br> The variables are handled only, if a search path element makes use of both of
* The __framework__ variable will receive the first segment of the include, the __header__ variable * the variables. The __framework__ variable will receive the first segment of the include,
* the rest. Such a search path element is not used for directives with a single segment (e.g. 'header.h') * the __header__ variable the rest. Such a search path element is not used for directives
* with a single segment (e.g. 'header.h')
*/ */
public String[] getIncludePaths(); public String[] getIncludePaths();
} }

View file

@ -6,9 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.parser; package org.eclipse.cdt.core.parser;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;

View file

@ -329,7 +329,7 @@ public class CharArrayUtils {
} }
/** /**
* Find an array of chars in an array of arrays of chars. * Finds an array of chars in an array of arrays of chars.
* @return offset where the array was found or <code>-1</code> * @return offset where the array was found or <code>-1</code>
*/ */
public static int indexOf(final char[] searchFor, final char[][] searchIn) { public static int indexOf(final char[] searchFor, final char[][] searchIn) {
@ -340,4 +340,15 @@ public class CharArrayUtils {
} }
return -1; return -1;
} }
/**
* Converts a {@link StringBuilder} to a character array.
* @since 5.5
*/
public static char[] extractChars(StringBuilder buf) {
final int len = buf.length();
char[] result= new char[len];
buf.getChars(0, len, result, 0);
return result;
}
} }

View file

@ -0,0 +1,151 @@
/*******************************************************************************
* Copyright (c) 2012 Google, Inc and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Sergey Prigogin (Google) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.parser.util;
import java.util.Arrays;
/**
* Automatically growing integer array.
*
* @since 5.5
*/
public class IntArray {
private static final int INITIAL_CAPACITY = 10;
private static final int[] EMPTY_ARRAY = {};
private int[] buffer = EMPTY_ARRAY;
private int size;
public IntArray() {
}
public IntArray(int initialCapacity) {
this.buffer = new int[initialCapacity];
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
public void add(int value) {
grow(size + 1);
buffer[size++] = value;
}
public void add(int index, int value) {
checkBounds(index);
grow(size + 1);
System.arraycopy(buffer, index, buffer, index + 1, size - index);
buffer[index] = value;
size++;
}
public void addAll(IntArray other) {
grow(size + other.size());
System.arraycopy(other.buffer, 0, buffer, size, other.size);
size += other.size;
return;
}
public void addAll(int[] array) {
grow(size + array.length);
System.arraycopy(array, 0, buffer, size, array.length);
size += array.length;
return;
}
public int remove(int index) {
checkBounds(index);
int old = buffer[index];
int n = size - index - 1;
if (n > 0) {
System.arraycopy(buffer, index + 1, buffer, index, n);
}
return old;
}
public void remove(int from, int to) {
checkBounds(from);
checkBounds(to);
System.arraycopy(buffer, to, buffer, from, size - to);
}
public void clear() {
size = 0;
}
public int get(int index) {
checkRange(index);
return buffer[index];
}
public int set(int index, int value) {
checkBounds(index);
int old = buffer[index];
buffer[index] = value;
return old;
}
public int[] toArray() {
return size == 0 ? EMPTY_ARRAY : Arrays.copyOf(buffer, size);
}
public void trimToSize() {
if (size == 0) {
buffer = EMPTY_ARRAY;
} else if (size < buffer.length) {
buffer = Arrays.copyOf(buffer, size);
}
}
public void ensureCapacity(int minCapacity) {
if (minCapacity > 0) {
grow(minCapacity);
}
}
private void grow(int minCapacity) {
if (minCapacity < 0) // Overflow
throw new OutOfMemoryError();
int capacity = buffer.length;
if (minCapacity > capacity) {
int newCapacity = capacity == 0 ? INITIAL_CAPACITY : capacity + (capacity >> 1);
// newCapacity may be negative due to overflow.
if (newCapacity < minCapacity)
newCapacity = minCapacity;
// newCapacity is guaranteed to be non negative.
try {
buffer = Arrays.copyOf(buffer, newCapacity);
} catch (OutOfMemoryError e) {
// Try again it case we were too aggressive in reserving capacity.
buffer = Arrays.copyOf(buffer, minCapacity);
}
}
}
private void checkBounds(int index) {
if (index < 0) {
throw new IndexOutOfBoundsException("Negative index: " + index); //$NON-NLS-1$
}
checkRange(index);
}
private void checkRange(int index) {
if (index >= size) {
throw new IndexOutOfBoundsException("Index: " + index + ", size: " + size); //$NON-NLS-1$//$NON-NLS-2$
}
}
}

View file

@ -33,7 +33,7 @@ public class Linkage implements ILinkage {
} }
public static String getLinkageName(int linkageID) throws CoreException { public static String getLinkageName(int linkageID) throws CoreException {
switch(linkageID) { switch (linkageID) {
case NO_LINKAGE_ID: return NO_LINKAGE_NAME; case NO_LINKAGE_ID: return NO_LINKAGE_NAME;
case C_LINKAGE_ID: return C_LINKAGE_NAME; case C_LINKAGE_ID: return C_LINKAGE_NAME;
case CPP_LINKAGE_ID: return CPP_LINKAGE_NAME; case CPP_LINKAGE_ID: return CPP_LINKAGE_NAME;

View file

@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.core.dom.parser;
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.ICPPTemplateArgument;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
/** /**
@ -61,6 +62,7 @@ public interface ITypeMarshalBuffer {
IValue unmarshalValue() throws CoreException; IValue unmarshalValue() throws CoreException;
IBinding unmarshalBinding() throws CoreException; IBinding unmarshalBinding() throws CoreException;
ISerializableEvaluation unmarshalEvaluation() throws CoreException; ISerializableEvaluation unmarshalEvaluation() throws CoreException;
ICPPTemplateArgument unmarshalTemplateArgument() throws CoreException;
int getByte() throws CoreException; int getByte() throws CoreException;
int getShort() throws CoreException; int getShort() throws CoreException;
int getInt() throws CoreException; int getInt() throws CoreException;
@ -71,6 +73,7 @@ public interface ITypeMarshalBuffer {
void marshalValue(IValue value) throws CoreException; void marshalValue(IValue value) throws CoreException;
void marshalBinding(IBinding binding) throws CoreException; void marshalBinding(IBinding binding) throws CoreException;
void marshalEvaluation(ISerializableEvaluation eval, boolean includeValue) throws CoreException; void marshalEvaluation(ISerializableEvaluation eval, boolean includeValue) throws CoreException;
void marshalTemplateArgument(ICPPTemplateArgument arg) throws CoreException;
void putByte(byte data); void putByte(byte data);
void putShort(short data); void putShort(short data);
void putInt(int data); void putInt(int data);

View file

@ -22,6 +22,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IField; import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IPointerType;
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;
@ -48,6 +49,8 @@ public class SizeofCalculator {
} }
} }
private static final SizeofCalculator defaultInstance = new SizeofCalculator();
private static final SizeAndAlignment SIZE_1 = new SizeAndAlignment(1, 1); private static final SizeAndAlignment SIZE_1 = new SizeAndAlignment(1, 1);
public final SizeAndAlignment size_2; public final SizeAndAlignment size_2;
@ -67,6 +70,15 @@ public class SizeofCalculator {
public final SizeAndAlignment sizeof_long_double; public final SizeAndAlignment sizeof_long_double;
public final SizeAndAlignment sizeof_complex_long_double; public final SizeAndAlignment sizeof_complex_long_double;
/**
* Returns the default instance of sizeof calculator. The default instance is not aware
* of the parser configuration and can only calculate sizes that are the same across all
* C/C++ implementations.
*/
public static SizeofCalculator getDefault() {
return defaultInstance;
}
public SizeofCalculator(IASTTranslationUnit ast) { public SizeofCalculator(IASTTranslationUnit ast) {
int maxAlignment = 32; int maxAlignment = 32;
Map<String, String> sizeofMacros = new HashMap<String, String>(); Map<String, String> sizeofMacros = new HashMap<String, String>();
@ -102,6 +114,25 @@ public class SizeofCalculator {
sizeof_complex_long_double = getSizeOfPair(sizeof_long_double); sizeof_complex_long_double = getSizeOfPair(sizeof_long_double);
} }
private SizeofCalculator() {
size_2 = new SizeAndAlignment(2, 2);
size_4 = new SizeAndAlignment(4, 4);
size_8 = new SizeAndAlignment(8, 8);
sizeof_pointer = null;
sizeof_int = null;
sizeof_long = null;
sizeof_long_long = null;
sizeof_short = null;
sizeof_bool = null;
sizeof_wchar_t = null;
sizeof_float = null;
sizeof_complex_float = null;
sizeof_double = null;
sizeof_complex_double = null;
sizeof_long_double = null;
sizeof_complex_long_double = null;
}
/** /**
* 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.
@ -109,7 +140,9 @@ public class SizeofCalculator {
*/ */
public SizeAndAlignment sizeAndAlignment(IType type) { public SizeAndAlignment sizeAndAlignment(IType type) {
type = SemanticUtil.getNestedType(type, SemanticUtil.CVTYPE | SemanticUtil.TDEF); type = SemanticUtil.getNestedType(type, SemanticUtil.CVTYPE | SemanticUtil.TDEF);
if (type instanceof IFunctionType) {
return sizeAndAlignment(((IFunctionType) type).getReturnType());
}
if (type instanceof IBasicType) { if (type instanceof IBasicType) {
return sizeAndAlignment((IBasicType) type); return sizeAndAlignment((IBasicType) type);
} }

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Devin Steffler (IBM Corporation) - initial API and implementation * Devin Steffler (IBM Corporation) - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c; package org.eclipse.cdt.internal.core.dom.parser.c;
@ -157,7 +157,6 @@ public class CArrayType implements ICArrayType, ITypeContainer, ISerializableTyp
return ASTTypeUtil.getType(this); return ASTTypeUtil.getType(this);
} }
@Override @Override
public void marshal(ITypeMarshalBuffer buffer) throws CoreException { public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
int firstByte= ITypeMarshalBuffer.ARRAY_TYPE; int firstByte= ITypeMarshalBuffer.ARRAY_TYPE;
@ -174,14 +173,13 @@ public class CArrayType implements ICArrayType, ITypeContainer, ISerializableTyp
firstByte |= ITypeMarshalBuffer.FLAG1; firstByte |= ITypeMarshalBuffer.FLAG1;
} }
val= getSize(); val= getSize();
if (val != null) { if (val != null) {
firstByte |= ITypeMarshalBuffer.FLAG2; firstByte |= ITypeMarshalBuffer.FLAG2;
Long num= val.numericalValue(); Long num= val.numericalValue();
if (num != null) { if (num != null) {
long l= num; long l= num;
if (l>=0 && l <= Short.MAX_VALUE) { if (l >= 0 && l <= Short.MAX_VALUE) {
nval= (short) l; nval= (short) l;
firstByte |= ITypeMarshalBuffer.FLAG3; firstByte |= ITypeMarshalBuffer.FLAG3;
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2011 IBM Corporation and others. * Copyright (c) 2005, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -10,9 +10,11 @@
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Bryan Wilkinson (QNX) * Bryan Wilkinson (QNX)
* Andrew Ferguson (Symbian) * Andrew Ferguson (Symbian)
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
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;
@ -124,19 +126,19 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
} }
@Override @Override
public ICPPBase[] getBases() { public ICPPBase[] getBases(IASTNode point) {
if (fBases == null) { if (fBases == null) {
ICPPBase[] result = null; ICPPBase[] result = null;
ICPPBase[] bases = specialClass.getSpecializedBinding().getBases(); ICPPBase[] bases = ClassTypeHelper.getBases(specialClass.getSpecializedBinding(), point);
if (bases.length == 0) { if (bases.length == 0) {
fBases= bases; fBases= bases;
} else { } else {
IASTNode point= null; // Instantiation of dependent expression may not work.
final ICPPTemplateParameterMap tpmap = specialClass.getTemplateParameterMap(); final ICPPTemplateParameterMap tpmap = specialClass.getTemplateParameterMap();
for (ICPPBase base : bases) { for (ICPPBase base : bases) {
IBinding origClass = base.getBaseClass(); IBinding origClass = base.getBaseClass();
if (origClass instanceof ICPPTemplateParameter && ((ICPPTemplateParameter) origClass).isParameterPack()) { if (origClass instanceof ICPPTemplateParameter && ((ICPPTemplateParameter) origClass).isParameterPack()) {
IType[] specClasses= CPPTemplates.instantiateTypes(new IType[]{new CPPParameterPackType((IType) origClass)}, tpmap, -1, specialClass, point); IType[] specClasses= CPPTemplates.instantiateTypes(new IType[] { new CPPParameterPackType((IType) origClass) },
tpmap, -1, specialClass, point);
if (specClasses.length == 1 && specClasses[0] instanceof ICPPParameterPackType) { if (specClasses.length == 1 && specClasses[0] instanceof ICPPParameterPackType) {
result= ArrayUtil.append(ICPPBase.class, result, base); result= ArrayUtil.append(ICPPBase.class, result, base);
} else { } else {
@ -182,15 +184,19 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
} }
@Override @Override
public ICPPField[] getDeclaredFields() { public ICPPField[] getDeclaredFields(IASTNode point) {
IASTNode point= null; // Instantiation of dependent expression may not work. ICPPField[] fields= ClassTypeHelper.getDeclaredFields(specialClass.getSpecializedBinding(), point);
ICPPField[] fields= specialClass.getSpecializedBinding().getDeclaredFields();
return specializeMembers(fields, point); return specializeMembers(fields, point);
} }
@Override @Override
public ICPPMethod[] getImplicitMethods() { public ICPPMethod[] getImplicitMethods() {
IASTNode point= null; // Instantiation of dependent expression may not work. 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) {
ICPPClassScope origClassScope= (ICPPClassScope) specialClass.getSpecializedBinding().getCompositeScope(); ICPPClassScope origClassScope= (ICPPClassScope) specialClass.getSpecializedBinding().getCompositeScope();
if (origClassScope == null) { if (origClassScope == null) {
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
@ -208,30 +214,31 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
@Override @Override
public ICPPConstructor[] getConstructors() { public ICPPConstructor[] getConstructors() {
// mstodo need to pass the point of instantiation CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
IASTNode point= null; // Instantiation of dependent expression may not work. return getConstructors(null);
ICPPConstructor[] ctors= specialClass.getSpecializedBinding().getConstructors();
return specializeMembers(ctors, point);
} }
@Override @Override
public ICPPMethod[] getDeclaredMethods() { public ICPPConstructor[] getConstructors(IASTNode point) {
IASTNode point= null; // Instantiation of dependent expression may not work. ICPPConstructor[] ctors= ClassTypeHelper.getConstructors(specialClass.getSpecializedBinding(), point);
ICPPMethod[] bindings = specialClass.getSpecializedBinding().getDeclaredMethods(); return specializeMembers(ctors, point);
}
@Override
public ICPPMethod[] getDeclaredMethods(IASTNode point) {
ICPPMethod[] bindings = ClassTypeHelper.getDeclaredMethods(specialClass.getSpecializedBinding(), point);
return specializeMembers(bindings, point); return specializeMembers(bindings, point);
} }
@Override @Override
public ICPPClassType[] getNestedClasses() { public ICPPClassType[] getNestedClasses(IASTNode point) {
IASTNode point= null; // Instantiation of dependent expression may not work. ICPPClassType[] bindings = ClassTypeHelper.getNestedClasses(specialClass.getSpecializedBinding(), point);
ICPPClassType[] bindings = specialClass.getSpecializedBinding().getNestedClasses();
return specializeMembers(bindings, point); return specializeMembers(bindings, point);
} }
@Override @Override
public IBinding[] getFriends() { public IBinding[] getFriends(IASTNode point) {
IASTNode point= null; // Instantiation of dependent expression may not work. IBinding[] friends = ClassTypeHelper.getFriends(specialClass.getSpecializedBinding(), point);
IBinding[] friends = specialClass.getSpecializedBinding().getFriends();
return specializeMembers(friends, point); return specializeMembers(friends, point);
} }

View file

@ -35,6 +35,7 @@ import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArraySet; import org.eclipse.cdt.core.parser.util.CharArraySet;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
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.SemanticUtil;
/** /**
* For example in the constructor definition <br> * For example in the constructor definition <br>
@ -174,7 +175,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 : cls.getBases()) { for (ICPPBase base : ClassTypeHelper.getBases(cls, fdef)) {
result.put(base.getBaseClassSpecifierName().getSimpleID()); result.put(base.getBaseClassSpecifierName().getSimpleID());
} }
return result; return result;

View file

@ -53,7 +53,7 @@ public class CPPASTFieldReference extends ASTNode
private boolean isDeref; private boolean isDeref;
private IASTImplicitName[] implicitNames; private IASTImplicitName[] implicitNames;
private ICPPEvaluation fEvaluation; private ICPPEvaluation fEvaluation;
public CPPASTFieldReference() { public CPPASTFieldReference() {
} }
@ -74,11 +74,7 @@ public class CPPASTFieldReference extends ASTNode
copy.setFieldOwner(owner == null ? null : owner.copy(style)); copy.setFieldOwner(owner == null ? null : owner.copy(style));
copy.isTemplate = isTemplate; copy.isTemplate = isTemplate;
copy.isDeref = isDeref; copy.isDeref = isDeref;
copy.setOffsetAndLength(this); return copy(copy, style);
if (style == CopyStyle.withLocations) {
copy.setCopyLocation(this);
}
return copy;
} }
@Override @Override
@ -282,7 +278,7 @@ public class CPPASTFieldReference extends ASTNode
if (n instanceof ICPPASTTemplateId) { if (n instanceof ICPPASTTemplateId) {
args= CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) n); args= CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) n);
} }
return new EvalID(ownerEval, qualifier, name.getSimpleID(), false, qualifier != null, args); return new EvalID(ownerEval, qualifier, name.getSimpleID(), false, true, args);
} }
@Override @Override

View file

@ -13,7 +13,10 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType;
import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
@ -40,6 +43,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFunctionCall; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFunctionCall;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.LookupData; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.LookupData;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
public class CPPASTFunctionCallExpression extends ASTNode public class CPPASTFunctionCallExpression extends ASTNode
implements ICPPASTFunctionCallExpression, IASTAmbiguityParent { implements ICPPASTFunctionCallExpression, IASTAmbiguityParent {
@ -163,7 +167,7 @@ public class CPPASTFunctionCallExpression extends ASTNode
} }
} else { } else {
n1.computeOperatorOffsets(functionName, true); n1.computeOperatorOffsets(functionName, true);
n2.computeOperatorOffsets(fArguments[fArguments.length-1], true); n2.computeOperatorOffsets(fArguments[fArguments.length - 1], true);
} }
implicitNames = new IASTImplicitName[] { n1, n2 }; implicitNames = new IASTImplicitName[] { n1, n2 };
@ -219,8 +223,6 @@ public class CPPASTFunctionCallExpression extends ASTNode
} }
} }
@Override @Override
@Deprecated @Deprecated
public IASTExpression getParameterExpression() { public IASTExpression getParameterExpression() {
@ -269,7 +271,7 @@ public class CPPASTFunctionCallExpression extends ASTNode
ICPPClassType cls= (ICPPClassType) t; ICPPClassType cls= (ICPPClassType) t;
LookupData data= CPPSemantics.createLookupData(((IASTIdExpression) functionName).getName()); LookupData data= CPPSemantics.createLookupData(((IASTIdExpression) functionName).getName());
try { try {
IBinding b= CPPSemantics.resolveFunction(data, cls.getConstructors(), true); IBinding b= CPPSemantics.resolveFunction(data, ClassTypeHelper.getConstructors(cls, data.getLookupPoint()), true);
if (b instanceof ICPPFunction) if (b instanceof ICPPFunction)
return (ICPPFunction) b; return (ICPPFunction) b;
} catch (DOMException e) { } catch (DOMException e) {
@ -296,10 +298,10 @@ public class CPPASTFunctionCallExpression extends ASTNode
if (conversion != null) if (conversion != null)
return conversion; return conversion;
ICPPEvaluation[] args= new ICPPEvaluation[fArguments.length+1]; ICPPEvaluation[] args= new ICPPEvaluation[fArguments.length + 1];
args[0]= functionName.getEvaluation(); args[0]= functionName.getEvaluation();
for (int i = 1; i < args.length; i++) { for (int i = 1; i < args.length; i++) {
args[i]= ((ICPPASTExpression) fArguments[i-1]).getEvaluation(); args[i]= ((ICPPASTExpression) fArguments[i - 1]).getEvaluation();
} }
return new EvalFunctionCall(args); return new EvalFunctionCall(args);
} }
@ -318,7 +320,6 @@ public class CPPASTFunctionCallExpression extends ASTNode
} }
return null; return null;
} }
@Override @Override
public IType getExpressionType() { public IType getExpressionType() {

View file

@ -271,14 +271,14 @@ public class CPPASTQualifiedName extends CPPASTNameBase
IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix, namespaces); IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix, namespaces);
if (namesPos > 0) { if (namesPos > 0) {
IBinding binding = names[namesPos-1].resolveBinding(); IBinding binding = names[namesPos - 1].resolveBinding();
if (binding instanceof ICPPClassType) { if (binding instanceof ICPPClassType) {
ICPPClassType classType = (ICPPClassType) binding; ICPPClassType classType = (ICPPClassType) binding;
final boolean isDeclaration = getParent().getParent() instanceof IASTSimpleDeclaration; final boolean isDeclaration = getParent().getParent() instanceof IASTSimpleDeclaration;
List<IBinding> filtered = filterClassScopeBindings(classType, bindings, isDeclaration); List<IBinding> filtered = filterClassScopeBindings(classType, bindings, isDeclaration);
if (isDeclaration && nameMatches(classType.getNameCharArray(), if (isDeclaration && nameMatches(classType.getNameCharArray(),
n.getLookupKey(), isPrefix)) { n.getLookupKey(), isPrefix)) {
ICPPConstructor[] constructors = classType.getConstructors(); ICPPConstructor[] constructors = ClassTypeHelper.getConstructors(classType, n);
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]);
@ -303,7 +303,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) >= 0) { if (SemanticUtil.calculateInheritanceDepth(classType, baseClass, this) >= 0) {
return true; return true;
} }
} }

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM - Initial API and implementation * IBM - Initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -40,8 +40,8 @@ import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContent;
* C++-specific implementation of a translation-unit. * C++-specific implementation of a translation-unit.
*/ */
public class CPPASTTranslationUnit extends ASTTranslationUnit implements ICPPASTTranslationUnit, IASTAmbiguityParent { public class CPPASTTranslationUnit extends ASTTranslationUnit implements ICPPASTTranslationUnit, IASTAmbiguityParent {
private CPPNamespaceScope fScope = null; private CPPNamespaceScope fScope;
private ICPPNamespace fBinding = null; private ICPPNamespace fBinding;
private final CPPScopeMapper fScopeMapper= new CPPScopeMapper(this); private final CPPScopeMapper fScopeMapper= new CPPScopeMapper(this);
public CPPASTTranslationUnit() { public CPPASTTranslationUnit() {

View file

@ -211,7 +211,7 @@ public class CPPBasicType implements ICPPBasicType, ISerializableType {
int modifiers= 0; int modifiers= 0;
int kind; int kind;
if (dense) { if (dense) {
kind= (firstByte & (ITypeMarshalBuffer.FLAG4-1))/ITypeMarshalBuffer.FLAG1; kind= (firstByte & (ITypeMarshalBuffer.FLAG4 - 1)) / ITypeMarshalBuffer.FLAG1;
} else { } else {
kind= buffer.getByte(); kind= buffer.getByte();
modifiers= buffer.getByte(); modifiers= buffer.getByte();

View file

@ -15,6 +15,7 @@ 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;
@ -122,61 +123,103 @@ 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)
return ClassTypeHelper.getBases(this); return ClassTypeHelper.getBases(this);
return scope.getBases(); return scope.getBases(point);
} }
@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(); return scope.getDeclaredFields(point);
} }
@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(); return scope.getDeclaredMethods(point);
} }
@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(); return scope.getConstructors(point);
} }
@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(); return scope.getFriends(point);
} }
@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(); return scope.getNestedClasses(point);
} }
@Override @Override
public IField[] getFields() { public IField[] getFields() {
return ClassTypeHelper.getFields(this); CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
return getFields(null);
}
@Override
public IField[] getFields(IASTNode point) {
return ClassTypeHelper.getFields(this, point);
} }
@Override @Override
@ -186,12 +229,24 @@ public class CPPClassSpecialization extends CPPSpecialization
@Override @Override
public ICPPMethod[] getMethods() { public ICPPMethod[] getMethods() {
return ClassTypeHelper.getMethods(this); CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
return getMethods(null);
}
@Override
public ICPPMethod[] getMethods(IASTNode point) {
return ClassTypeHelper.getMethods(this, point);
} }
@Override @Override
public ICPPMethod[] getAllDeclaredMethods() { public ICPPMethod[] getAllDeclaredMethods() {
return ClassTypeHelper.getAllDeclaredMethods(this); CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
return getAllDeclaredMethods(null);
}
@Override
public ICPPMethod[] getAllDeclaredMethods(IASTNode point) {
return ClassTypeHelper.getAllDeclaredMethods(this, point);
} }
/* (non-Javadoc) /* (non-Javadoc)
@ -226,7 +281,7 @@ public class CPPClassSpecialization extends CPPSpecialization
if (getDefinition() != null) if (getDefinition() != null)
return null; return null;
//implicit specialization: must specialize bindings in scope // Implicit specialization: must specialize bindings in scope.
if (specScope == null) { if (specScope == null) {
specScope = new CPPClassSpecializationScope(this); specScope = new CPPClassSpecializationScope(this);
} }

View file

@ -6,10 +6,10 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Andrew Niefer (IBM) - Initial API and implementation * Andrew Niefer (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Bryan Wilkinson (QNX) * Bryan Wilkinson (QNX)
* Andrew Ferguson (Symbian) * Andrew Ferguson (Symbian)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;

View file

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

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -30,8 +30,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
*/ */
public class CPPClassTemplatePartialSpecializationSpecialization extends CPPClassSpecialization public class CPPClassTemplatePartialSpecializationSpecialization extends CPPClassSpecialization
implements ICPPClassTemplatePartialSpecializationSpecialization, ICPPInternalClassTemplate { implements ICPPClassTemplatePartialSpecializationSpecialization, ICPPInternalClassTemplate {
private ObjectMap instances;
private ObjectMap instances = null;
private ICPPDeferredClassInstance fDeferredInstance; private ICPPDeferredClassInstance fDeferredInstance;
private final ICPPClassTemplate fClassTemplate; private final ICPPClassTemplate fClassTemplate;
private final ICPPTemplateArgument[] fArguments; private final ICPPTemplateArgument[] fArguments;
@ -70,7 +69,7 @@ public class CPPClassTemplatePartialSpecializationSpecialization extends CPPClas
public synchronized ICPPTemplateInstance[] getAllInstances() { public synchronized ICPPTemplateInstance[] getAllInstances() {
if (instances != null) { if (instances != null) {
ICPPTemplateInstance[] result= new ICPPTemplateInstance[instances.size()]; ICPPTemplateInstance[] result= new ICPPTemplateInstance[instances.size()];
for (int i=0; i < instances.size(); i++) { for (int i= 0; i < instances.size(); i++) {
result[i]= (ICPPTemplateInstance) instances.getAt(i); result[i]= (ICPPTemplateInstance) instances.getAt(i);
} }
return result; return result;
@ -142,7 +141,7 @@ public class CPPClassTemplatePartialSpecializationSpecialization extends CPPClas
@Override @Override
public ICPPTemplateArgument getDefaultArgFromIndex(int paramPos) throws DOMException { public ICPPTemplateArgument getDefaultArgFromIndex(int paramPos) throws DOMException {
// no default arguments for partial specializations // No default arguments for partial specializations
return null; return null;
} }
} }

View file

@ -43,7 +43,7 @@ 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 expression may not work. IASTNode point= null; // Instantiation of dependent expressions may not work.
ICPPClassTemplate origTemplate= (ICPPClassTemplate) getSpecializedBinding(); ICPPClassTemplate origTemplate= (ICPPClassTemplate) getSpecializedBinding();
ICPPClassTemplatePartialSpecialization[] orig = origTemplate.getPartialSpecializations(); ICPPClassTemplatePartialSpecialization[] orig = origTemplate.getPartialSpecializations();
ICPPClassTemplatePartialSpecialization[] spec = new ICPPClassTemplatePartialSpecialization[orig.length]; ICPPClassTemplatePartialSpecialization[] spec = new ICPPClassTemplatePartialSpecialization[orig.length];

View file

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

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Andrew Niefer (IBM) - Initial API and implementation * Andrew Niefer (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -23,8 +23,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
* Binding for a specialization of a field. * Binding for a specialization of a field.
*/ */
public class CPPFieldSpecialization extends CPPSpecialization implements ICPPField { public class CPPFieldSpecialization extends CPPSpecialization implements ICPPField {
private IType type = null; private final IType type;
private IValue value= null; private final IValue value;
public CPPFieldSpecialization(IBinding orig, ICPPClassType owner, ICPPTemplateParameterMap tpmap, public CPPFieldSpecialization(IBinding orig, ICPPClassType owner, ICPPTemplateParameterMap tpmap,
IType type, IValue value) { IType type, IValue value) {
@ -36,7 +36,7 @@ public class CPPFieldSpecialization extends CPPSpecialization implements ICPPFie
private ICPPField getField() { private ICPPField getField() {
return (ICPPField) getSpecializedBinding(); return (ICPPField) getSpecializedBinding();
} }
@Override @Override
public int getVisibility() { public int getVisibility() {
return getField().getVisibility(); return getField().getVisibility();
@ -46,7 +46,7 @@ public class CPPFieldSpecialization extends CPPSpecialization implements ICPPFie
public ICPPClassType getClassOwner() { public ICPPClassType getClassOwner() {
return getField().getClassOwner(); return getField().getClassOwner();
} }
@Override @Override
public IType getType() { public IType getType() {
return type; return type;

View file

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

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2010 IBM Corporation and others. * Copyright (c) 2005, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -8,6 +8,7 @@
* Contributors: * Contributors:
* Andrew Niefer (IBM) - Initial API and implementation * Andrew Niefer (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -20,20 +21,27 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
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.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethodSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
/** /**
* The specialization of a method in the context of a class-specialization. * The specialization of a method in the context of a class-specialization.
*/ */
public class CPPMethodSpecialization extends CPPFunctionSpecialization implements ICPPMethod { public class CPPMethodSpecialization extends CPPFunctionSpecialization implements ICPPMethodSpecialization {
public CPPMethodSpecialization(ICPPMethod orig, ICPPClassType owner, ICPPTemplateParameterMap argMap, ICPPFunctionType type, IType[] exceptionSpec ) { public CPPMethodSpecialization(ICPPMethod orig, ICPPClassType owner, ICPPTemplateParameterMap argMap,
super(orig, owner, argMap, type, exceptionSpec ); ICPPFunctionType type, IType[] exceptionSpec) {
super(orig, owner, argMap, type, exceptionSpec);
}
@Override
public ICPPMethod getSpecializedBinding() {
return (ICPPMethod) super.getSpecializedBinding();
} }
@Override @Override
public boolean isVirtual() { public boolean isVirtual() {
ICPPMethod f = (ICPPMethod) getSpecializedBinding(); ICPPMethod f = getSpecializedBinding();
if (f != null) if (f != null)
return f.isVirtual(); return f.isVirtual();
IASTNode definition = getDefinition(); IASTNode definition = getDefinition();
@ -58,7 +66,7 @@ public class CPPMethodSpecialization extends CPPFunctionSpecialization implement
@Override @Override
public int getVisibility() { public int getVisibility() {
ICPPMethod f = (ICPPMethod) getSpecializedBinding(); ICPPMethod f = getSpecializedBinding();
if (f != null) if (f != null)
return f.getVisibility(); return f.getVisibility();
return 0; return 0;
@ -80,17 +88,17 @@ public class CPPMethodSpecialization extends CPPFunctionSpecialization implement
@Override @Override
public boolean isExplicit() { public boolean isExplicit() {
return ((ICPPMethod) getSpecializedBinding()).isExplicit(); return getSpecializedBinding().isExplicit();
} }
@Override @Override
public boolean isImplicit() { public boolean isImplicit() {
return ((ICPPMethod) getSpecializedBinding()).isImplicit(); return getSpecializedBinding().isImplicit();
} }
@Override @Override
public boolean isPureVirtual() { public boolean isPureVirtual() {
ICPPMethod f = (ICPPMethod) getSpecializedBinding(); ICPPMethod f = getSpecializedBinding();
if (f != null) if (f != null)
return f.isPureVirtual(); return f.isPureVirtual();
@ -98,9 +106,9 @@ public class CPPMethodSpecialization extends CPPFunctionSpecialization implement
} }
@Override @Override
public IType[] getExceptionSpecification() { public IType[] getExceptionSpecification(IASTNode point) {
if (isImplicit()) { if (isImplicit()) {
return ClassTypeHelper.getInheritedExceptionSpecification(this); return ClassTypeHelper.getInheritedExceptionSpecification(this, point);
} }
return super.getExceptionSpecification(); return super.getExceptionSpecification();
} }

View file

@ -184,7 +184,7 @@ abstract public class CPPScope implements ICPPASTInternalScope {
@Override @Override
public IBinding[] getBindings(ScopeLookupData lookup) { public IBinding[] getBindings(ScopeLookupData lookup) {
IBinding[] result = getBindingsInAST(lookup); IBinding[] result = getBindingsInAST(lookup);
final IASTTranslationUnit tu = lookup.getLookupPoint().getTranslationUnit(); final IASTTranslationUnit tu = lookup.getTranslationUnit();
if (tu != null) { if (tu != null) {
IIndex index = tu.getIndex(); IIndex index = tu.getIndex();
if (index != null) { if (index != null) {

View file

@ -0,0 +1,101 @@
/*******************************************************************************
* Copyright (c) 2008, 2012 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import org.eclipse.cdt.core.dom.ast.IType;
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.ICPPTemplateArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId;
import org.eclipse.core.runtime.Assert;
/**
* Implementation of non-type template argument, used by AST and index.
*/
public class CPPTemplateNonTypeArgument implements ICPPTemplateArgument {
private final ICPPEvaluation fEvaluation;
public CPPTemplateNonTypeArgument(ICPPEvaluation evaluation) {
Assert.isNotNull(evaluation);
fEvaluation= evaluation;
}
public CPPTemplateNonTypeArgument(IValue value, IType type) {
fEvaluation = new EvalFixed(type, PRVALUE, value);
}
@Override
public boolean isTypeValue() {
return false;
}
@Override
public boolean isNonTypeValue() {
return true;
}
@Override
public IType getTypeValue() {
return null;
}
@Override
public IValue getNonTypeValue() {
return fEvaluation.getValue(null);
}
@Override
public IType getTypeOfNonTypeValue() {
return fEvaluation.getTypeOrFunctionSet(null);
}
@Override
public boolean isPackExpansion() {
return fEvaluation.getTypeOrFunctionSet(null) instanceof ICPPParameterPackType;
}
@Override
public ICPPTemplateArgument getExpansionPattern() {
IType type = fEvaluation.getTypeOrFunctionSet(null);
if (type instanceof ICPPParameterPackType) {
IType t= ((ICPPParameterPackType) type).getType();
if (t != null) {
ICPPEvaluation evaluation;
if (fEvaluation instanceof EvalFixed) {
EvalFixed fixed = (EvalFixed) fEvaluation;
evaluation = new EvalFixed(t, fixed.getValueCategory(), fixed.getValue());
} else {
evaluation = new EvalTypeId(t, fEvaluation);
}
return new CPPTemplateNonTypeArgument(evaluation);
}
}
return null;
}
@Override
public boolean isSameValue(ICPPTemplateArgument arg) {
return getNonTypeValue().equals(arg.getNonTypeValue());
}
@Override
public String toString() {
return getNonTypeValue().toString();
}
public ICPPEvaluation getEvaluation() {
return fEvaluation;
}
}

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2010 IBM Corporation and others. * Copyright (c) 2005, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -32,10 +32,9 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
/** /**
* Binding for a non-type template parameter. * Binding for a non-type template parameter.
*/ */
public class CPPTemplateNonTypeParameter extends CPPTemplateParameter implements public class CPPTemplateNonTypeParameter extends CPPTemplateParameter
ICPPTemplateNonTypeParameter { implements ICPPTemplateNonTypeParameter {
private IType type;
private IType type = null;
public CPPTemplateNonTypeParameter(IASTName name) { public CPPTemplateNonTypeParameter(IASTName name) {
super(name); super(name);
@ -80,9 +79,9 @@ public class CPPTemplateNonTypeParameter extends CPPTemplateParameter implements
d= (IASTExpression) dc; d= (IASTExpression) dc;
} else if (dc instanceof ICPPASTInitializerList) { } else if (dc instanceof ICPPASTInitializerList) {
ICPPASTInitializerList list= (ICPPASTInitializerList) dc; ICPPASTInitializerList list= (ICPPASTInitializerList) dc;
switch(list.getSize()) { switch (list.getSize()) {
case 0: case 0:
return new CPPTemplateArgument(Value.create(0), getType()); return new CPPTemplateNonTypeArgument(Value.create(0), getType());
case 1: case 1:
dc= list.getClauses()[0]; dc= list.getClauses()[0];
if (dc instanceof IASTExpression) { if (dc instanceof IASTExpression) {
@ -96,7 +95,7 @@ public class CPPTemplateNonTypeParameter extends CPPTemplateParameter implements
IValue val= Value.create(d, Value.MAX_RECURSION_DEPTH); IValue val= Value.create(d, Value.MAX_RECURSION_DEPTH);
IType t= getType(); IType t= getType();
return new CPPTemplateArgument(val, t); return new CPPTemplateNonTypeArgument(val, t);
} }
@Override @Override
@ -123,26 +122,32 @@ public class CPPTemplateNonTypeParameter extends CPPTemplateParameter implements
public boolean isStatic() { public boolean isStatic() {
return false; return false;
} }
@Override @Override
public boolean isExtern() { public boolean isExtern() {
return false; return false;
} }
@Override @Override
public boolean isAuto() { public boolean isAuto() {
return false; return false;
} }
@Override @Override
public boolean isRegister() { public boolean isRegister() {
return false; return false;
} }
@Override @Override
public IValue getInitialValue() { public IValue getInitialValue() {
return null; return null;
} }
@Override @Override
public boolean isExternC() { public boolean isExternC() {
return false; return false;
} }
@Override @Override
public boolean isMutable() { public boolean isMutable() {
return false; return false;

View file

@ -131,7 +131,7 @@ public class CPPTemplateTemplateParameter extends CPPTemplateParameter implement
if (d == null) if (d == null)
return null; return null;
return new CPPTemplateArgument(d); return new CPPTemplateTypeArgument(d);
} }
@Override @Override

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2008, 2009 Wind River Systems, Inc. and others. * Copyright (c) 2008, 2012 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -17,47 +18,39 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.Assert;
/** /**
* Implementation of template arguments, used by ast and index. * Implementation of type template arguments, used by AST and index.
*/ */
public class CPPTemplateArgument implements ICPPTemplateArgument { public class CPPTemplateTypeArgument implements ICPPTemplateArgument {
private final IType fType; private final IType fType;
private final IValue fValue;
public CPPTemplateArgument(IValue value, IType type) { public CPPTemplateTypeArgument(IType type) {
Assert.isNotNull(value);
fType= type;
fValue= value;
}
public CPPTemplateArgument(IType type) {
Assert.isNotNull(type); Assert.isNotNull(type);
fType= type; fType= type;
fValue= null;
} }
@Override @Override
public boolean isTypeValue() { public boolean isTypeValue() {
return fValue == null; return true;
} }
@Override @Override
public boolean isNonTypeValue() { public boolean isNonTypeValue() {
return fValue != null; return false;
} }
@Override @Override
public IType getTypeValue() { public IType getTypeValue() {
return isTypeValue() ? fType : null; return fType;
} }
@Override @Override
public IValue getNonTypeValue() { public IValue getNonTypeValue() {
return fValue; return null;
} }
@Override @Override
public IType getTypeOfNonTypeValue() { public IType getTypeOfNonTypeValue() {
return isNonTypeValue() ? fType : null; return null;
} }
@Override @Override
@ -70,10 +63,7 @@ public class CPPTemplateArgument implements ICPPTemplateArgument {
if (fType instanceof ICPPParameterPackType) { if (fType instanceof ICPPParameterPackType) {
IType t= ((ICPPParameterPackType) fType).getType(); IType t= ((ICPPParameterPackType) fType).getType();
if (t != null) { if (t != null) {
if (fValue != null) { return new CPPTemplateTypeArgument(t);
return new CPPTemplateArgument(fValue, t);
}
return new CPPTemplateArgument(t);
} }
} }
return null; return null;
@ -81,16 +71,11 @@ public class CPPTemplateArgument implements ICPPTemplateArgument {
@Override @Override
public boolean isSameValue(ICPPTemplateArgument arg) { public boolean isSameValue(ICPPTemplateArgument arg) {
if (fValue != null) {
return fValue.equals(arg.getNonTypeValue());
}
return fType.isSameType(arg.getTypeValue()); return fType.isSameType(arg.getTypeValue());
} }
@Override @Override
public String toString() { public String toString() {
if (fValue != null)
return fValue.toString();
return fType.toString(); return fType.toString();
} }
} }

View file

@ -78,7 +78,7 @@ public class CPPTemplateTypeParameter extends CPPTemplateParameter implements
if (t == null) if (t == null)
return null; return null;
return new CPPTemplateArgument(t); return new CPPTemplateTypeArgument(t);
} }
@Override @Override

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Sergey Prigogin (Google) - initial API and implementation * Sergey Prigogin (Google) - initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;

View file

@ -47,9 +47,9 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.core.runtime.PlatformObject; import org.eclipse.core.runtime.PlatformObject;
public class CPPVariable extends PlatformObject implements ICPPVariable, ICPPInternalBinding, IInternalVariable { public class CPPVariable extends PlatformObject implements ICPPVariable, ICPPInternalBinding, IInternalVariable {
private IASTName fDefinition = null; private IASTName fDefinition;
private IASTName fDeclarations[] = null; private IASTName fDeclarations[];
private IType fType = null; private IType fType;
private boolean fAllResolved; private boolean fAllResolved;
public CPPVariable(IASTName name) { public CPPVariable(IASTName name) {
@ -59,10 +59,11 @@ public class CPPVariable extends PlatformObject implements ICPPVariable, ICPPInt
name = ns[ns.length - 1]; name = ns[ns.length - 1];
} }
if (isDef) if (isDef) {
fDefinition = name; fDefinition = name;
else } else {
fDeclarations = new IASTName[] { name }; fDeclarations = new IASTName[] { name };
}
// built-in variables supply a null // built-in variables supply a null
if (name != null) { if (name != null) {

View file

@ -54,6 +54,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
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.ICPPBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
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.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.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
@ -101,14 +102,14 @@ public class ClassTypeHelper {
IASTDeclaration[] members = host.getCompositeTypeSpecifier().getMembers(); IASTDeclaration[] members = host.getCompositeTypeSpecifier().getMembers();
for (IASTDeclaration decl : members) { for (IASTDeclaration decl : members) {
while (decl instanceof ICPPASTTemplateDeclaration) while (decl instanceof ICPPASTTemplateDeclaration)
decl = ((ICPPASTTemplateDeclaration)decl).getDeclaration(); decl = ((ICPPASTTemplateDeclaration) decl).getDeclaration();
if (decl instanceof IASTSimpleDeclaration) { if (decl instanceof IASTSimpleDeclaration) {
ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) ((IASTSimpleDeclaration)decl).getDeclSpecifier(); ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) ((IASTSimpleDeclaration) decl).getDeclSpecifier();
if (declSpec.isFriend()) { if (declSpec.isFriend()) {
IASTDeclarator[] dtors = ((IASTSimpleDeclaration)decl).getDeclarators(); IASTDeclarator[] dtors = ((IASTSimpleDeclaration) decl).getDeclarators();
if (declSpec instanceof ICPPASTElaboratedTypeSpecifier && dtors.length == 0) { if (declSpec instanceof ICPPASTElaboratedTypeSpecifier && dtors.length == 0) {
resultSet.put(((ICPPASTElaboratedTypeSpecifier)declSpec).getName().resolveBinding()); resultSet.put(((ICPPASTElaboratedTypeSpecifier) declSpec).getName().resolveBinding());
} else { } else {
for (IASTDeclarator dtor : dtors) { for (IASTDeclarator dtor : dtors) {
if (dtor == null) break; if (dtor == null) break;
@ -118,9 +119,9 @@ public class ClassTypeHelper {
} }
} }
} else if (decl instanceof IASTFunctionDefinition) { } else if (decl instanceof IASTFunctionDefinition) {
ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) ((IASTFunctionDefinition)decl).getDeclSpecifier(); ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) ((IASTFunctionDefinition) decl).getDeclSpecifier();
if (declSpec.isFriend()) { if (declSpec.isFriend()) {
IASTDeclarator dtor = ((IASTFunctionDefinition)decl).getDeclarator(); IASTDeclarator dtor = ((IASTFunctionDefinition) decl).getDeclarator();
dtor= ASTQueries.findInnermostDeclarator(dtor); dtor= ASTQueries.findInnermostDeclarator(dtor);
resultSet.put(dtor.getName().resolveBinding()); resultSet.put(dtor.getName().resolveBinding());
} }
@ -144,7 +145,7 @@ public class ClassTypeHelper {
if (type.isSameType(classType)) { if (type.isSameType(classType)) {
return true; return true;
} }
for (IBinding friend : classType.getFriends()) { for (IBinding friend : getFriends(classType, null)) {
if (friend instanceof ICPPClassType && type.isSameType((IType) friend)) { if (friend instanceof ICPPClassType && type.isSameType((IType) friend)) {
return true; return true;
} }
@ -152,7 +153,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 : classType.getFriends()) { for (IBinding friend : getFriends(classType, null)) {
if (friend instanceof ICPPFunction && if (friend instanceof ICPPFunction &&
CharArrayUtils.equals(name, friend.getNameCharArray()) && CharArrayUtils.equals(name, friend.getNameCharArray()) &&
SemanticUtil.isSameOwner(binding.getOwner(), friend.getOwner()) && SemanticUtil.isSameOwner(binding.getOwner(), friend.getOwner()) &&
@ -217,17 +218,17 @@ public class ClassTypeHelper {
IASTDeclaration[] decls = host.getCompositeTypeSpecifier().getMembers(); IASTDeclaration[] decls = host.getCompositeTypeSpecifier().getMembers();
for (IASTDeclaration decl : decls) { for (IASTDeclaration decl : decls) {
if (decl instanceof IASTSimpleDeclaration) { if (decl instanceof IASTSimpleDeclaration) {
IASTDeclarator[] dtors = ((IASTSimpleDeclaration)decl).getDeclarators(); IASTDeclarator[] dtors = ((IASTSimpleDeclaration) decl).getDeclarators();
for (IASTDeclarator dtor : dtors) { for (IASTDeclarator dtor : dtors) {
binding = ASTQueries.findInnermostDeclarator(dtor).getName().resolveBinding(); binding = ASTQueries.findInnermostDeclarator(dtor).getName().resolveBinding();
if (binding instanceof ICPPField) if (binding instanceof ICPPField)
result = ArrayUtil.append(ICPPField.class, result, (ICPPField) binding); result = ArrayUtil.append(ICPPField.class, result, (ICPPField) binding);
} }
} else if (decl instanceof ICPPASTUsingDeclaration) { } else if (decl instanceof ICPPASTUsingDeclaration) {
IASTName n = ((ICPPASTUsingDeclaration)decl).getName(); IASTName n = ((ICPPASTUsingDeclaration) decl).getName();
binding = n.resolveBinding(); binding = n.resolveBinding();
if (binding instanceof ICPPUsingDeclaration) { if (binding instanceof ICPPUsingDeclaration) {
IBinding[] bs = ((ICPPUsingDeclaration)binding).getDelegates(); IBinding[] bs = ((ICPPUsingDeclaration) binding).getDelegates();
for (IBinding element : bs) { for (IBinding element : bs) {
if (element instanceof ICPPField) if (element instanceof ICPPField)
result = ArrayUtil.append(ICPPField.class, result, (ICPPField) element); result = ArrayUtil.append(ICPPField.class, result, (ICPPField) element);
@ -240,27 +241,63 @@ public class ClassTypeHelper {
return ArrayUtil.trim(ICPPField.class, result); return ArrayUtil.trim(ICPPField.class, result);
} }
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();
}
/** /**
* 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 visible base classes in arbitrary order. * @return An array of visible base classes in arbitrary order.
*/ */
public static ICPPClassType[] getAllBases(ICPPClassType classType) { public static ICPPClassType[] getAllBases(ICPPClassType classType, IASTNode point) {
HashSet<ICPPClassType> result= new HashSet<ICPPClassType>(); HashSet<ICPPClassType> result= new HashSet<ICPPClassType>();
result.add(classType); result.add(classType);
getAllBases(classType, result); getAllBases(classType, result, point);
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, HashSet<ICPPClassType> result) { private static void getAllBases(ICPPClassType classType, HashSet<ICPPClassType> result, IASTNode point) {
ICPPBase[] bases= classType.getBases(); ICPPBase[] bases= ClassTypeHelper.getBases(classType, point);
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); getAllBases(baseClass, result, point);
} }
} }
} }
@ -287,25 +324,22 @@ public class ClassTypeHelper {
return false; return false;
} }
public static ICPPMethod[] getAllDeclaredMethods(ICPPClassType ct) { public static ICPPMethod[] getAllDeclaredMethods(ICPPClassType ct, IASTNode point) {
ICPPMethod[] methods= ct.getDeclaredMethods(); ICPPMethod[] methods= getDeclaredMethods(ct, point);
ICPPClassType[] bases= getAllBases(ct); ICPPClassType[] bases= getAllBases(ct, point);
for (ICPPClassType base : bases) { for (ICPPClassType base : bases) {
methods = ArrayUtil.addAll(ICPPMethod.class, methods, base.getDeclaredMethods()); methods = ArrayUtil.addAll(ICPPMethod.class, methods, getDeclaredMethods(base, point));
} }
return ArrayUtil.trim(ICPPMethod.class, methods); return ArrayUtil.trim(ICPPMethod.class, methods);
} }
public static ICPPMethod[] getMethods(ICPPClassType ct) { public static ICPPMethod[] getMethods(ICPPClassType ct, IASTNode point) {
ObjectSet<ICPPMethod> set = getOwnMethods(ct); ObjectSet<ICPPMethod> set = getOwnMethods(ct, point);
ICPPClassType[] bases= getAllBases(ct); ICPPClassType[] bases= getAllBases(ct, point);
for (ICPPClassType base : bases) { for (ICPPClassType base : bases) {
set.addAll(base.getDeclaredMethods()); set.addAll(getDeclaredMethods(base, point));
final IScope compositeScope = base.getCompositeScope(); set.addAll(getImplicitMethods(base, point));
if (compositeScope instanceof ICPPClassScope) {
set.addAll(((ICPPClassScope) compositeScope).getImplicitMethods());
}
} }
return set.keyArray(ICPPMethod.class); return set.keyArray(ICPPMethod.class);
} }
@ -314,16 +348,23 @@ 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.
*/ */
private static ObjectSet<ICPPMethod> getOwnMethods(ICPPClassType classType) { private static ObjectSet<ICPPMethod> getOwnMethods(ICPPClassType classType, IASTNode point) {
ObjectSet<ICPPMethod> set= new ObjectSet<ICPPMethod>(4); ObjectSet<ICPPMethod> set= new ObjectSet<ICPPMethod>(4);
set.addAll(classType.getDeclaredMethods()); set.addAll(ClassTypeHelper.getDeclaredMethods(classType, point));
IScope scope = classType.getCompositeScope(); set.addAll(getImplicitMethods(classType, point));
if (scope instanceof ICPPClassScope) {
set.addAll(((ICPPClassScope) scope).getImplicitMethods());
}
return set; return set;
} }
public static ICPPMethod[] getImplicitMethods(ICPPClassType classType, IASTNode point) {
IScope scope = classType.getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getImplicitMethods(point);
} else if (scope instanceof ICPPClassScope) {
return ((ICPPClassScope) scope).getImplicitMethods();
}
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
}
public static ICPPMethod[] getDeclaredMethods(ICPPInternalClassTypeMixinHost host) { public static ICPPMethod[] getDeclaredMethods(ICPPInternalClassTypeMixinHost host) {
if (host.getDefinition() == null) { if (host.getDefinition() == null) {
host.checkForDefinition(); host.checkForDefinition();
@ -341,9 +382,9 @@ public class ClassTypeHelper {
IASTDeclaration[] decls = host.getCompositeTypeSpecifier().getMembers(); IASTDeclaration[] decls = host.getCompositeTypeSpecifier().getMembers();
for (IASTDeclaration decl : decls) { for (IASTDeclaration decl : decls) {
while (decl instanceof ICPPASTTemplateDeclaration) while (decl instanceof ICPPASTTemplateDeclaration)
decl = ((ICPPASTTemplateDeclaration)decl).getDeclaration(); decl = ((ICPPASTTemplateDeclaration) decl).getDeclaration();
if (decl instanceof IASTSimpleDeclaration) { if (decl instanceof IASTSimpleDeclaration) {
final IASTSimpleDeclaration sdecl = (IASTSimpleDeclaration)decl; final IASTSimpleDeclaration sdecl = (IASTSimpleDeclaration) decl;
if (!((ICPPASTDeclSpecifier) sdecl.getDeclSpecifier()).isFriend()) { if (!((ICPPASTDeclSpecifier) sdecl.getDeclSpecifier()).isFriend()) {
IASTDeclarator[] dtors = sdecl.getDeclarators(); IASTDeclarator[] dtors = sdecl.getDeclarators();
for (IASTDeclarator dtor : dtors) { for (IASTDeclarator dtor : dtors) {
@ -353,7 +394,7 @@ public class ClassTypeHelper {
} }
} }
} else if (decl instanceof IASTFunctionDefinition) { } else if (decl instanceof IASTFunctionDefinition) {
final IASTFunctionDefinition fdef = (IASTFunctionDefinition)decl; final IASTFunctionDefinition fdef = (IASTFunctionDefinition) decl;
if (!((ICPPASTDeclSpecifier) fdef.getDeclSpecifier()).isFriend()) { if (!((ICPPASTDeclSpecifier) fdef.getDeclSpecifier()).isFriend()) {
IASTDeclarator dtor = fdef.getDeclarator(); IASTDeclarator dtor = fdef.getDeclarator();
dtor = ASTQueries.findInnermostDeclarator(dtor); dtor = ASTQueries.findInnermostDeclarator(dtor);
@ -363,10 +404,10 @@ public class ClassTypeHelper {
} }
} }
} else if (decl instanceof ICPPASTUsingDeclaration) { } else if (decl instanceof ICPPASTUsingDeclaration) {
IASTName n = ((ICPPASTUsingDeclaration)decl).getName(); IASTName n = ((ICPPASTUsingDeclaration) decl).getName();
binding = n.resolveBinding(); binding = n.resolveBinding();
if (binding instanceof ICPPUsingDeclaration) { if (binding instanceof ICPPUsingDeclaration) {
IBinding[] bs = ((ICPPUsingDeclaration)binding).getDelegates(); IBinding[] bs = ((ICPPUsingDeclaration) binding).getDelegates();
for (IBinding element : bs) { for (IBinding element : bs) {
if (element instanceof ICPPMethod) if (element instanceof ICPPMethod)
result = ArrayUtil.append(ICPPMethod.class, result, (ICPPMethod) element); result = ArrayUtil.append(ICPPMethod.class, result, (ICPPMethod) element);
@ -407,15 +448,15 @@ public class ClassTypeHelper {
IASTDeclaration[] decls = host.getCompositeTypeSpecifier().getMembers(); IASTDeclaration[] decls = host.getCompositeTypeSpecifier().getMembers();
for (IASTDeclaration decl : decls) { for (IASTDeclaration decl : decls) {
while (decl instanceof ICPPASTTemplateDeclaration) while (decl instanceof ICPPASTTemplateDeclaration)
decl = ((ICPPASTTemplateDeclaration)decl).getDeclaration(); decl = ((ICPPASTTemplateDeclaration) decl).getDeclaration();
if (decl instanceof IASTSimpleDeclaration) { if (decl instanceof IASTSimpleDeclaration) {
IBinding binding = null; IBinding binding = null;
IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration) decl).getDeclSpecifier(); IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration) decl).getDeclSpecifier();
if (declSpec instanceof ICPPASTCompositeTypeSpecifier) { if (declSpec instanceof ICPPASTCompositeTypeSpecifier) {
binding = ((ICPPASTCompositeTypeSpecifier)declSpec).getName().resolveBinding(); binding = ((ICPPASTCompositeTypeSpecifier) declSpec).getName().resolveBinding();
} else if (declSpec instanceof ICPPASTElaboratedTypeSpecifier && } else if (declSpec instanceof ICPPASTElaboratedTypeSpecifier &&
((IASTSimpleDeclaration)decl).getDeclarators().length == 0) { ((IASTSimpleDeclaration) decl).getDeclarators().length == 0) {
binding = ((ICPPASTElaboratedTypeSpecifier)declSpec).getName().resolveBinding(); binding = ((ICPPASTElaboratedTypeSpecifier) declSpec).getName().resolveBinding();
} }
if (binding instanceof ICPPClassType) if (binding instanceof ICPPClassType)
result = ArrayUtil.append(ICPPClassType.class, result, (ICPPClassType) binding); result = ArrayUtil.append(ICPPClassType.class, result, (ICPPClassType) binding);
@ -424,11 +465,11 @@ public class ClassTypeHelper {
return ArrayUtil.trim(ICPPClassType.class, result); return ArrayUtil.trim(ICPPClassType.class, result);
} }
public static IField[] getFields(ICPPClassType ct) { public static IField[] getFields(ICPPClassType ct, IASTNode point) {
IField[] fields = ct.getDeclaredFields(); IField[] fields = getDeclaredFields(ct, point);
ICPPClassType[] bases = getAllBases(ct); ICPPClassType[] bases = getAllBases(ct, point);
for (ICPPClassType base : bases) { for (ICPPClassType base : bases) {
fields = ArrayUtil.addAll(IField.class, fields, base.getDeclaredFields()); fields = ArrayUtil.addAll(IField.class, fields, getDeclaredFields(base, point));
} }
return ArrayUtil.trim(IField.class, fields); return ArrayUtil.trim(IField.class, fields);
} }
@ -464,7 +505,8 @@ 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();
ICPPMethod[] allMethods= mcl.getMethods(); IASTNode point = null; // Instantiation of dependent expressions may not work
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()) {
@ -520,7 +562,7 @@ public class ClassTypeHelper {
if (sourceClass == null || targetClass == null) if (sourceClass == null || targetClass == null)
return false; return false;
ICPPClassType[] bases= getAllBases(sourceClass); ICPPClassType[] bases= getAllBases(sourceClass, null);
for (ICPPClassType base : bases) { for (ICPPClassType base : bases) {
if (base.isSameType(targetClass)) if (base.isSameType(targetClass))
return true; return true;
@ -532,7 +574,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) { public static ICPPMethod[] findOverridden(ICPPMethod method, IASTNode point) {
if (method instanceof ICPPConstructor) if (method instanceof ICPPConstructor)
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
@ -546,7 +588,7 @@ public class ClassTypeHelper {
final ICPPFunctionType mft= method.getType(); final ICPPFunctionType mft= method.getType();
virtualInClass.put(mcl, method.isVirtual()); virtualInClass.put(mcl, method.isVirtual());
ICPPBase[] bases= mcl.getBases(); ICPPBase[] bases= getBases(mcl, point);
for (ICPPBase base : bases) { for (ICPPBase base : bases) {
IBinding b= base.getBaseClass(); IBinding b= base.getBaseClass();
if (b instanceof ICPPClassType) { if (b instanceof ICPPClassType) {
@ -681,10 +723,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) { public static IType[] getInheritedExceptionSpecification(ICPPMethod implicitMethod, IASTNode point) {
// See 15.4.13 // See 15.4.13
ICPPClassType owner= implicitMethod.getClassOwner(); ICPPClassType owner= implicitMethod.getClassOwner();
if (owner == null || owner.getBases().length == 0) if (owner == null || ClassTypeHelper.getBases(owner, point).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)
@ -693,7 +735,7 @@ public class ClassTypeHelper {
return null; return null;
List<IType> inheritedTypeids = new ArrayList<IType>(); List<IType> inheritedTypeids = new ArrayList<IType>();
ICPPClassType[] bases= getAllBases(owner); ICPPClassType[] bases= getAllBases(owner, point);
for (ICPPClassType base : bases) { for (ICPPClassType base : bases) {
if (!(base instanceof ICPPDeferredClassInstance)) { if (!(base instanceof ICPPDeferredClassInstance)) {
ICPPMethod baseMethod= getMethodInClass(base, kind); ICPPMethod baseMethod= getMethodInClass(base, kind);
@ -792,10 +834,10 @@ public class ClassTypeHelper {
* no private or protected non-static data members (Clause 11), * no private or protected non-static data members (Clause 11),
* no base classes (Clause 10), and no virtual functions (10.3). * no base classes (Clause 10), and no virtual functions (10.3).
*/ */
public static boolean isAggregateClass(ICPPClassType classTarget) { public static boolean isAggregateClass(ICPPClassType classTarget, IASTNode point) {
if (classTarget.getBases().length > 0) if (ClassTypeHelper.getBases(classTarget, point).length > 0)
return false; return false;
ICPPMethod[] methods = classTarget.getDeclaredMethods(); ICPPMethod[] methods = ClassTypeHelper.getDeclaredMethods(classTarget, point);
for (ICPPMethod m : methods) { for (ICPPMethod m : methods) {
if (m instanceof ICPPConstructor) if (m instanceof ICPPConstructor)
return false; return false;
@ -803,7 +845,7 @@ public class ClassTypeHelper {
return false; return false;
} }
} }
ICPPField[] fields = classTarget.getDeclaredFields(); ICPPField[] fields = ClassTypeHelper.getDeclaredFields(classTarget, point);
for (ICPPField field : fields) { for (ICPPField field : fields) {
if (!(field.getVisibility() == ICPPMember.v_public || field.isStatic())) { if (!(field.getVisibility() == ICPPMember.v_public || field.isStatic())) {
return false; return false;
@ -837,7 +879,7 @@ public class ClassTypeHelper {
if (base.isVirtual()) if (base.isVirtual())
return false; return false;
} }
for (ICPPClassType baseClass : getAllBases(classTarget)) { for (ICPPClassType baseClass : getAllBases(classTarget, null)) {
if (!classTarget.isSameType(baseClass) && !hasTrivialCopyCtor(baseClass)) if (!classTarget.isSameType(baseClass) && !hasTrivialCopyCtor(baseClass))
return false; return false;
} }
@ -889,7 +931,7 @@ public class ClassTypeHelper {
if (!ctor.isImplicit() && ctor.getParameters().length == 0) if (!ctor.isImplicit() && ctor.getParameters().length == 0)
return false; return false;
} }
for (ICPPClassType baseClass : getAllBases(classTarget)) { for (ICPPClassType baseClass : getAllBases(classTarget, null)) {
if (!classTarget.isSameType(baseClass) && !hasTrivialDefaultConstructor(baseClass)) if (!classTarget.isSameType(baseClass) && !hasTrivialDefaultConstructor(baseClass))
return false; return false;
} }
@ -925,7 +967,7 @@ public class ClassTypeHelper {
if (method.isDestructor()) if (method.isDestructor())
return false; return false;
} }
for (ICPPClassType baseClass : getAllBases(classTarget)) { for (ICPPClassType baseClass : getAllBases(classTarget, null)) {
if (!classTarget.isSameType(baseClass) && !hasTrivialDestructor(baseClass)) if (!classTarget.isSameType(baseClass) && !hasTrivialDestructor(baseClass))
return false; return false;
} }
@ -952,7 +994,7 @@ public class ClassTypeHelper {
public static boolean isPolymorphic(ICPPClassType classTarget) { public static boolean isPolymorphic(ICPPClassType classTarget) {
if (hasDeclaredVirtualMethod(classTarget)) if (hasDeclaredVirtualMethod(classTarget))
return true; return true;
for (ICPPClassType baseClass : getAllBases(classTarget)) { for (ICPPClassType baseClass : getAllBases(classTarget, null)) {
if (hasDeclaredVirtualMethod(baseClass)) if (hasDeclaredVirtualMethod(baseClass))
return true; return true;
} }
@ -976,9 +1018,9 @@ public class ClassTypeHelper {
* but doesn't take into account base classes and methods dependent on unspecified * but doesn't take into account base classes and methods dependent on unspecified
* template parameters. * template parameters.
*/ */
public static ICPPMethod[] getPureVirtualMethods(ICPPClassType classType) { public static ICPPMethod[] getPureVirtualMethods(ICPPClassType classType, IASTNode point) {
Map<String, List<ICPPMethod>> result= collectPureVirtualMethods(classType, Map<String, List<ICPPMethod>> result= collectPureVirtualMethods(classType,
new HashMap<ICPPClassType, Map<String, List<ICPPMethod>>>()); new HashMap<ICPPClassType, Map<String, List<ICPPMethod>>>(), point);
int resultArraySize = 0; int resultArraySize = 0;
for (List<ICPPMethod> methods : result.values()) { for (List<ICPPMethod> methods : result.values()) {
@ -995,7 +1037,7 @@ public class ClassTypeHelper {
} }
private static Map<String, List<ICPPMethod>> collectPureVirtualMethods(ICPPClassType classType, private static Map<String, List<ICPPMethod>> collectPureVirtualMethods(ICPPClassType classType,
Map<ICPPClassType, Map<String, List<ICPPMethod>>> cache) { Map<ICPPClassType, Map<String, List<ICPPMethod>>> cache, IASTNode point) {
Map<String, List<ICPPMethod>> result = cache.get(classType); Map<String, List<ICPPMethod>> result = cache.get(classType);
if (result != null) if (result != null)
return result; return result;
@ -1005,10 +1047,10 @@ public class ClassTypeHelper {
// Look at the pure virtual methods of the base classes // Look at the pure virtual methods of the base classes
Set<IBinding> handledBaseClasses= new HashSet<IBinding>(); Set<IBinding> handledBaseClasses= new HashSet<IBinding>();
for (ICPPBase base : classType.getBases()) { for (ICPPBase base : ClassTypeHelper.getBases(classType, point)) {
final IBinding baseClass = base.getBaseClass(); final IBinding baseClass = base.getBaseClass();
if (baseClass instanceof ICPPClassType && handledBaseClasses.add(baseClass)) { if (baseClass instanceof ICPPClassType && handledBaseClasses.add(baseClass)) {
Map<String, List<ICPPMethod>> pureVirtuals = collectPureVirtualMethods((ICPPClassType) baseClass, cache); Map<String, List<ICPPMethod>> pureVirtuals = collectPureVirtualMethods((ICPPClassType) baseClass, cache, point);
// Merge derived pure virtual methods // Merge derived pure virtual methods
for (String key : pureVirtuals.keySet()) { for (String key : pureVirtuals.keySet()) {
List<ICPPMethod> list = result.get(key); List<ICPPMethod> list = result.get(key);
@ -1021,8 +1063,8 @@ public class ClassTypeHelper {
} }
} }
// Remove overridden pure-virtual methods and add in new pure virutals. // Remove overridden pure-virtual methods and add in new pure virtuals.
final ObjectSet<ICPPMethod> methods = getOwnMethods(classType); final ObjectSet<ICPPMethod> methods = getOwnMethods(classType, point);
for (ICPPMethod method : methods) { for (ICPPMethod method : methods) {
String key= getMethodNameForOverrideKey(method); String key= getMethodNameForOverrideKey(method);
List<ICPPMethod> list = result.get(key); List<ICPPMethod> list = result.get(key);

View file

@ -1,20 +1,23 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2008, 2010 Wind River Systems, Inc. and others. * Copyright (c) 2008, 2012 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; 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;
@ -39,25 +42,37 @@ public interface ICPPClassSpecializationScope extends ICPPClassScope {
/** /**
* Computes the bases via the original class. * Computes the bases via the original class.
*/ */
ICPPBase[] getBases(); ICPPBase[] getBases(IASTNode point);
/**
* Similar to {@link ICPPClassScope#getConstructors()} but a accepts a starting point
* for template instantiation.
*/
ICPPConstructor[] getConstructors(IASTNode point);
/**
* Similar to {@link ICPPClassScope#getImplicitMethods()} but a accepts a starting point
* for template instantiation.
*/
ICPPMethod[] getImplicitMethods(IASTNode point);
/** /**
* Computes the methods via the original class. * Computes the methods via the original class.
*/ */
ICPPMethod[] getDeclaredMethods(); ICPPMethod[] getDeclaredMethods(IASTNode point);
/** /**
* Computes the fields via the original class. * Computes the fields via the original class.
*/ */
ICPPField[] getDeclaredFields(); ICPPField[] getDeclaredFields(IASTNode point);
/** /**
* Computes the friends via the original class. * Computes the friends via the original class.
*/ */
IBinding[] getFriends(); IBinding[] getFriends(IASTNode point);
/** /**
* Computes the nested classes via the original class. * Computes the nested classes via the original class.
*/ */
ICPPClassType[] getNestedClasses(); ICPPClassType[] getNestedClasses(IASTNode point);
} }

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* QNX - Initial API and implementation * QNX - Initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -19,7 +19,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
* Interface for deferred class template instances. * Interface for deferred class template instances.
*/ */
public interface ICPPDeferredClassInstance extends ICPPUnknownClassType, ICPPTemplateInstance { public interface ICPPDeferredClassInstance extends ICPPUnknownClassType, ICPPTemplateInstance {
/** /**
* Returns the class template for the deferred instantiation. * Returns the class template for the deferred instantiation.
*/ */

View file

@ -14,6 +14,8 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTNode; 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.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
/** /**
@ -59,4 +61,25 @@ public interface ICPPEvaluation extends ISerializableEvaluation {
* signatures are guaranteed to produce the same results. * signatures are guaranteed to produce the same results.
*/ */
char[] getSignature(); char[] getSignature();
/**
* Instantiates the evaluation with the provided template parameter map and pack offset.
* The context is used to replace templates with their specialization, where appropriate.
* @return a fully or partially instantiated evaluation, or the original evaluation
*/
ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within, int maxdepth, IASTNode point);
/**
* Determines size of the template parameter pack.
*
* @noreference This method is not intended to be referenced by clients.
*/
int determinePackSize(ICPPTemplateParameterMap tpMap);
/**
* Checks if the evaluation references a template parameter either directly or though nested
* evaluations.
*/
boolean referencesTemplateParameter();
} }

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Sergey Prigogin (Google) - initial API and implementation * Sergey Prigogin (Google) - initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -20,5 +20,4 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
* @since 5.0 * @since 5.0
*/ */
public interface ICPPUnknownClassType extends ICPPUnknownBinding, ICPPUnknownType, ICPPClassType { public interface ICPPUnknownClassType extends ICPPUnknownBinding, ICPPUnknownType, ICPPClassType {
} }

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -16,5 +16,4 @@ import org.eclipse.cdt.core.dom.ast.IType;
* Marks types that depend on a template parameter and are thus unknown. * Marks types that depend on a template parameter and are thus unknown.
*/ */
public interface ICPPUnknownType extends IType { public interface ICPPUnknownType extends IType {
} }

View file

@ -152,7 +152,7 @@ public class AccessContext {
return isAccessible(bindingVisibility, accessLevel); return isAccessible(bindingVisibility, accessLevel);
} }
ICPPBase[] bases = derivedClass.getBases(); ICPPBase[] bases = ClassTypeHelper.getBases(derivedClass, name);
if (bases != null) { if (bases != null) {
for (ICPPBase base : bases) { for (ICPPBase base : bases) {
IBinding baseBinding = base.getBaseClass(); IBinding baseBinding = base.getBaseClass();

View file

@ -29,6 +29,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
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;
@ -181,8 +182,7 @@ class BaseClassLookup {
// base-classes // base-classes
ICPPClassType baseClass= result.getClassType(); ICPPClassType baseClass= result.getClassType();
if (baseClass != null) { if (baseClass != null) {
ICPPBase[] grandBases= null; ICPPBase[] grandBases= ClassTypeHelper.getBases(baseClass, data.getLookupPoint());
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;

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2010, 2011 Wind River Systems, Inc. and others. * Copyright (c) 2010, 2012 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -10,7 +10,10 @@
*******************************************************************************/ *******************************************************************************/
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.SemanticUtil.*; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.ALLCVQ;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
@ -67,6 +70,7 @@ class BuiltinOperators {
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 };
@ -80,7 +84,8 @@ class BuiltinOperators {
Object[] globCandidates) { Object[] globCandidates) {
fFileScope= point.getTranslationUnit().getScope(); fFileScope= point.getTranslationUnit().getScope();
fOperator= operator; fOperator= operator;
fUnary= args.length<2; fPoint = point;
fUnary= args.length < 2;
fGlobalCandidates= globCandidates; fGlobalCandidates= globCandidates;
if (args.length > 0) { if (args.length > 0) {
IType type= args[0].getTypeOrFunctionSet(point); IType type= args[0].getTypeOrFunctionSet(point);
@ -95,7 +100,6 @@ class BuiltinOperators {
} }
} }
private ICPPFunction[] create() { private ICPPFunction[] create() {
switch (fOperator) { switch (fOperator) {
case ARROW: case ARROW:
@ -231,8 +235,6 @@ class BuiltinOperators {
return fResult.toArray(new ICPPFunction[fResult.size()]); return fResult.toArray(new ICPPFunction[fResult.size()]);
} }
// 13.6-3, 13.6-4, 13.6-5 // 13.6-3, 13.6-4, 13.6-5
private void opIncOrDec() { private void opIncOrDec() {
IType[] types= getClassConversionTypes(FIRST); IType[] types= getClassConversionTypes(FIRST);
@ -355,7 +357,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) >= 0) { if (SemanticUtil.calculateInheritanceDepth(c1, c2, fPoint) >= 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);
@ -424,7 +426,6 @@ class BuiltinOperators {
return p1; return p1;
} }
// 13.6-13, 13.6.14 // 13.6-13, 13.6.14
private void pointerArithmetic(boolean useRef, boolean isDiff) { private void pointerArithmetic(boolean useRef, boolean isDiff) {
IType[] types= getClassConversionTypes(FIRST); IType[] types= getClassConversionTypes(FIRST);
@ -665,7 +666,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); ICPPMethod[] ops = SemanticUtil.getConversionOperators((ICPPClassType) type, fPoint);
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

@ -12,14 +12,27 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
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.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.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.ICPPBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableType; import org.eclipse.cdt.internal.core.dom.parser.ISerializableType;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator;
import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator.SizeAndAlignment;
import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeArgument;
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.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
public abstract class CPPEvaluation implements ICPPEvaluation { public abstract class CPPEvaluation implements ICPPEvaluation {
@ -27,11 +40,8 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
private static class SignatureBuilder implements ITypeMarshalBuffer { private static class SignatureBuilder implements ITypeMarshalBuffer {
private static final byte NULL_TYPE= 0; private static final byte NULL_TYPE= 0;
private static final byte UNSTORABLE_TYPE= (byte) -1; private static final byte UNSTORABLE_TYPE= (byte) -1;
private static final char[] HEX_DIGITS =
{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
private final StringBuilder fBuffer; private final StringBuilder fBuffer;
private boolean hexMode;
/** /**
* Constructor for input buffer. * Constructor for input buffer.
@ -45,6 +55,10 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
return fBuffer.toString(); return fBuffer.toString();
} }
public char[] getSignature() {
return CharArrayUtils.extractChars(fBuffer);
}
@Override @Override
public void marshalBinding(IBinding binding) throws CoreException { public void marshalBinding(IBinding binding) throws CoreException {
if (binding instanceof ISerializableType) { if (binding instanceof ISerializableType) {
@ -53,12 +67,17 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
putByte(NULL_TYPE); putByte(NULL_TYPE);
} else { } else {
appendSeparator(); appendSeparator();
IBinding owner= binding.getOwner(); if (binding instanceof ICPPBinding) {
if (owner instanceof IType) { if (binding instanceof ICPPTemplateParameter) {
ASTTypeUtil.appendType((IType) owner, true, fBuffer); ICPPTemplateParameter param = (ICPPTemplateParameter) binding;
fBuffer.append("::"); //$NON-NLS-1$ fBuffer.append(param.isParameterPack() ? '*' : '#');
fBuffer.append(param.getParameterID());
} else {
fBuffer.append(ASTTypeUtil.getQualifiedName((ICPPBinding) binding));
}
} else {
fBuffer.append(binding.getNameCharArray());
} }
fBuffer.append(binding.getName());
} }
} }
@ -95,49 +114,37 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
} }
@Override @Override
public void putByte(byte b) { public void marshalTemplateArgument(ICPPTemplateArgument arg) throws CoreException {
appendHexDigit(b >> 4); if (arg instanceof CPPTemplateNonTypeArgument) {
appendHexDigit(b); putByte(VALUE);
((CPPTemplateNonTypeArgument) arg).getEvaluation().marshal(this, true);
} else {
marshalType(arg.getTypeValue());
}
}
@Override
public void putByte(byte value) {
appendSeparator();
fBuffer.append(value);
} }
@Override @Override
public void putShort(short value) { public void putShort(short value) {
appendHexDigit(value >> 12); appendSeparator();
appendHexDigit(value >> 8); fBuffer.append(value);
appendHexDigit(value >> 4);
appendHexDigit(value);
} }
@Override @Override
public void putInt(int value) { public void putInt(int value) {
appendHexDigit(value >> 28); appendSeparator();
appendHexDigit(value >> 24); fBuffer.append(value);
appendHexDigit(value >> 20);
appendHexDigit(value >> 16);
appendHexDigit(value >> 12);
appendHexDigit(value >> 8);
appendHexDigit(value >> 4);
appendHexDigit(value);
} }
@Override @Override
public void putLong(long value) { public void putLong(long value) {
appendHexDigit((int) (value >> 60)); appendSeparator();
appendHexDigit((int) (value >> 56)); fBuffer.append(value);
appendHexDigit((int) (value >> 52));
appendHexDigit((int) (value >> 48));
appendHexDigit((int) (value >> 44));
appendHexDigit((int) (value >> 40));
appendHexDigit((int) (value >> 36));
appendHexDigit((int) (value >> 32));
appendHexDigit((int) (value >> 28));
appendHexDigit((int) (value >> 24));
appendHexDigit((int) (value >> 20));
appendHexDigit((int) (value >> 16));
appendHexDigit((int) (value >> 12));
appendHexDigit((int) (value >> 8));
appendHexDigit((int) (value >> 4));
appendHexDigit((int) value);
} }
@Override @Override
@ -148,19 +155,9 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
} }
} }
private void appendHexDigit(int val) {
if (hexMode) {
appendSeparator();
fBuffer.append("0x"); //$NON-NLS-1$
hexMode = true;
}
fBuffer.append(HEX_DIGITS[val & 0xF]);
}
private void appendSeparator() { private void appendSeparator() {
if (fBuffer.length() != 0) if (fBuffer.length() != 0)
fBuffer.append(' '); fBuffer.append(' ');
hexMode = false;
} }
@Override @Override
@ -183,6 +180,11 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override
public ICPPTemplateArgument unmarshalTemplateArgument() throws CoreException {
throw new UnsupportedOperationException();
}
@Override @Override
public int getByte() throws CoreException { public int getByte() throws CoreException {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
@ -214,6 +216,9 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
} }
} }
CPPEvaluation() {
}
@Override @Override
public char[] getSignature() { public char[] getSignature() {
SignatureBuilder buf = new SignatureBuilder(); SignatureBuilder buf = new SignatureBuilder();
@ -223,6 +228,33 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
CCorePlugin.log(e); CCorePlugin.log(e);
return new char[] { '?' }; return new char[] { '?' };
} }
return buf.toString().toCharArray(); return buf.getSignature();
}
protected static IBinding resolveUnknown(ICPPUnknownBinding unknown, ICPPTemplateParameterMap tpMap,
int packOffset, ICPPClassSpecialization within, IASTNode point) {
try {
return CPPTemplates.resolveUnknown(unknown, tpMap, packOffset, within, point);
} catch (DOMException e) {
CCorePlugin.log(e);
}
return unknown;
}
protected static ICPPTemplateArgument[] instantiateArguments(ICPPTemplateArgument[] args,
ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, IASTNode point) {
try {
return CPPTemplates.instantiateArguments(args, tpMap, packOffset, within, point);
} catch (DOMException e) {
CCorePlugin.log(e);
}
return args;
}
protected static SizeAndAlignment getSizeAndAlignment(IType type, IASTNode point) {
SizeofCalculator calc = point == null ?
SizeofCalculator.getDefault() :
((ASTTranslationUnit) point.getTranslationUnit()).getSizeofCalculator();
return calc.sizeAndAlignment(type);
} }
} }

View file

@ -203,6 +203,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUsingDeclaration; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUsingDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUsingDirective; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUsingDirective;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariable; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariable;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
@ -244,7 +245,7 @@ public class CPPSemantics {
public static int traceIndent= 0; public static int traceIndent= 0;
// special return value for costForFunctionCall // special return value for costForFunctionCall
private static final FunctionCost CONTAINS_DEPENDENT_TYPES = new FunctionCost(null, 0); private static final FunctionCost CONTAINS_DEPENDENT_TYPES = new FunctionCost(null, 0, null);
static protected IBinding resolveBinding(IASTName name) { static protected IBinding resolveBinding(IASTName name) {
if (traceBindingResolution) { if (traceBindingResolution) {
@ -257,11 +258,11 @@ public class CPPSemantics {
((CPPASTNameBase) name).incResolutionDepth(); ((CPPASTNameBase) name).incResolutionDepth();
} }
// 1: get some context info off of the name to figure out what kind of lookup we want // 1: Get some context info off of the name to figure out what kind of lookup we want
LookupData data = createLookupData(name); LookupData data = createLookupData(name);
try { try {
// 2: lookup // 2: Lookup
lookup(data, null); lookup(data, null);
// Perform argument dependent lookup // Perform argument dependent lookup
@ -274,14 +275,14 @@ public class CPPSemantics {
if (data.problem != null) if (data.problem != null)
return data.problem; return data.problem;
// 3: resolve ambiguities // 3: Resolve ambiguities
IBinding binding; IBinding binding;
try { try {
binding = resolveAmbiguities(data); binding = resolveAmbiguities(data);
} catch (DOMException e) { } catch (DOMException e) {
binding = e.getProblem(); binding = e.getProblem();
} }
// 4: post processing // 4: Post processing
binding = postResolution(binding, data); binding = postResolution(binding, data);
if (traceBindingResolution) { if (traceBindingResolution) {
traceIndent--; traceIndent--;
@ -306,6 +307,8 @@ public class CPPSemantics {
if (lookupName == null) if (lookupName == null)
return binding; return binding;
IASTNode lookupPoint = data.getLookupPoint();
if (binding == null && data.checkClassContainingFriend()) { if (binding == null && data.checkClassContainingFriend()) {
// 3.4.1-10 if we don't find a name used in a friend declaration in the member declaration's class // 3.4.1-10 if we don't find a name used in a friend declaration in the member declaration's class
// we should look in the class granting friendship // we should look in the class granting friendship
@ -403,7 +406,7 @@ public class CPPSemantics {
if (data.getTranslationUnit() != null) { if (data.getTranslationUnit() != null) {
ICPPASTTemplateId id = (ICPPASTTemplateId) lookupName; ICPPASTTemplateId id = (ICPPASTTemplateId) lookupName;
ICPPTemplateArgument[] args = CPPTemplates.createTemplateArgumentArray(id); ICPPTemplateArgument[] args = CPPTemplates.createTemplateArgumentArray(id);
IBinding inst= CPPTemplates.instantiate((ICPPClassTemplate) cls, args, data.getLookupPoint()); IBinding inst= CPPTemplates.instantiate((ICPPClassTemplate) cls, args, lookupPoint);
if (inst instanceof ICPPClassType) { if (inst instanceof ICPPClassType) {
cls= (ICPPClassType) inst; cls= (ICPPClassType) inst;
} }
@ -412,7 +415,7 @@ public class CPPSemantics {
if (cls instanceof ICPPUnknownBinding) { if (cls instanceof ICPPUnknownBinding) {
binding= new CPPUnknownConstructor(cls); binding= new CPPUnknownConstructor(cls);
} else { } else {
binding= CPPSemantics.resolveFunction(data, cls.getConstructors(), true); binding= CPPSemantics.resolveFunction(data, ClassTypeHelper.getConstructors(cls, lookupPoint), true);
} }
} catch (DOMException e) { } catch (DOMException e) {
return e.getProblem(); return e.getProblem();
@ -712,7 +715,7 @@ public class CPPSemantics {
} }
if (t instanceof ICPPClassType && !(t instanceof ICPPClassTemplate)) { if (t instanceof ICPPClassType && !(t instanceof ICPPClassTemplate)) {
ICPPClassType ct= (ICPPClassType) t; ICPPClassType ct= (ICPPClassType) t;
ICPPBase[] bases = ct.getBases(); ICPPBase[] bases = ClassTypeHelper.getBases(ct, tu);
for (ICPPBase base : bases) { for (ICPPBase base : bases) {
IBinding b = base.getBaseClass(); IBinding b = base.getBaseClass();
if (b instanceof IType) if (b instanceof IType)
@ -723,7 +726,7 @@ public class CPPSemantics {
// (excluding template template parameters); // (excluding template template parameters);
// * ... owners of which any template template arguments are members; // * ... owners of which any template template arguments are members;
if (ct instanceof ICPPTemplateInstance) { if (ct instanceof ICPPTemplateInstance) {
for (IBinding friend : ct.getFriends()) { for (IBinding friend : ClassTypeHelper.getFriends(ct, tu)) {
if (friend instanceof ICPPFunction) { if (friend instanceof ICPPFunction) {
friendFns.add((ICPPFunction) friend); friendFns.add((ICPPFunction) friend);
} }
@ -2413,7 +2416,7 @@ public class CPPSemantics {
potentialCosts.add(fnCost); potentialCosts.add(fnCost);
continue; continue;
} }
int cmp= fnCost.compareTo(tu, bestFnCost, lookupPoint); int cmp= fnCost.compareTo(tu, bestFnCost);
if (cmp < 0) { if (cmp < 0) {
bestFnCost= fnCost; bestFnCost= fnCost;
ambiguousFunctions= null; ambiguousFunctions= null;
@ -2425,7 +2428,7 @@ public class CPPSemantics {
if (potentialCosts != null) { if (potentialCosts != null) {
for (FunctionCost fnCost : potentialCosts) { for (FunctionCost fnCost : potentialCosts) {
if (!fnCost.mustBeWorse(bestFnCost) && fnCost.performUDC(lookupPoint)) { if (!fnCost.mustBeWorse(bestFnCost) && fnCost.performUDC(lookupPoint)) {
int cmp= fnCost.compareTo(tu, bestFnCost, lookupPoint); int cmp= fnCost.compareTo(tu, bestFnCost);
if (cmp < 0) { if (cmp < 0) {
bestFnCost= fnCost; bestFnCost= fnCost;
ambiguousFunctions= null; ambiguousFunctions= null;
@ -2630,9 +2633,9 @@ public class CPPSemantics {
final int sourceLen= argTypes.length - skipArg; final int sourceLen= argTypes.length - skipArg;
final FunctionCost result; final FunctionCost result;
if (implicitParameterType == null) { if (implicitParameterType == null) {
result= new FunctionCost(fn, sourceLen); result= new FunctionCost(fn, sourceLen, data.getLookupPoint());
} else { } else {
result= new FunctionCost(fn, sourceLen + 1); result= new FunctionCost(fn, sourceLen + 1, data.getLookupPoint());
ValueCategory sourceIsLValue= LVALUE; ValueCategory sourceIsLValue= LVALUE;
if (impliedObjectType == null) { if (impliedObjectType == null) {
@ -2656,7 +2659,7 @@ public class CPPSemantics {
if (CPPTemplates.isDependentType(implicitParameterType) || CPPTemplates.isDependentType(impliedObjectType)) { if (CPPTemplates.isDependentType(implicitParameterType) || CPPTemplates.isDependentType(impliedObjectType)) {
IType s= getNestedType(impliedObjectType, TDEF|REF|CVTYPE); IType s= getNestedType(impliedObjectType, TDEF|REF|CVTYPE);
IType t= getNestedType(implicitParameterType, TDEF|REF|CVTYPE); IType t= getNestedType(implicitParameterType, TDEF|REF|CVTYPE);
if (SemanticUtil.calculateInheritanceDepth(s, t) >= 0) if (SemanticUtil.calculateInheritanceDepth(s, t, data.getLookupPoint()) >= 0)
return null; return null;
return CONTAINS_DEPENDENT_TYPES; return CONTAINS_DEPENDENT_TYPES;
@ -2671,7 +2674,7 @@ public class CPPSemantics {
final UDCMode udc = allowUDC ? UDCMode.DEFER : UDCMode.FORBIDDEN; final UDCMode udc = allowUDC ? UDCMode.DEFER : UDCMode.FORBIDDEN;
for (int j = 0; j < sourceLen; j++) { for (int j = 0; j < sourceLen; j++) {
final IType argType= SemanticUtil.getNestedType(argTypes[j+skipArg], TDEF | REF); final IType argType= SemanticUtil.getNestedType(argTypes[j + skipArg], TDEF | REF);
if (argType == null) if (argType == null)
return null; return null;
@ -2815,7 +2818,7 @@ public class CPPSemantics {
LookupData data= new LookupData(name); LookupData data= new LookupData(name);
data.setFunctionArguments(false, init.getArguments()); data.setFunctionArguments(false, init.getArguments());
try { try {
IBinding ctor = CPPSemantics.resolveFunction(data, ((ICPPClassType) targetType).getConstructors(), true); IBinding ctor = CPPSemantics.resolveFunction(data, ClassTypeHelper.getConstructors((ICPPClassType) targetType, name), true);
if (ctor instanceof ICPPConstructor) { if (ctor instanceof ICPPConstructor) {
int i= 0; int i= 0;
for (IASTNode arg : init.getArguments()) { for (IASTNode arg : init.getArguments()) {
@ -3086,7 +3089,7 @@ public class CPPSemantics {
ValueCategory isLValue= evaluation.getValueCategory(name); ValueCategory isLValue= evaluation.getValueCategory(name);
if (sourceType != null) { if (sourceType != null) {
Cost c; Cost c;
if (calculateInheritanceDepth(sourceType, classType) >= 0) { if (calculateInheritanceDepth(sourceType, classType, name) >= 0) {
c = Conversions.copyInitializationOfClass(isLValue, sourceType, classType, false, name); c = Conversions.copyInitializationOfClass(isLValue, sourceType, classType, false, name);
} else { } else {
c = Conversions.checkImplicitConversionSequence(type, sourceType, isLValue, UDCMode.ALLOWED, Context.ORDINARY, name); c = Conversions.checkImplicitConversionSequence(type, sourceType, isLValue, UDCMode.ALLOWED, Context.ORDINARY, name);
@ -3122,13 +3125,13 @@ public class CPPSemantics {
LookupData data = new LookupData(astName); LookupData data = new LookupData(astName);
data.setFunctionArguments(false, arguments); data.setFunctionArguments(false, arguments);
data.qualified = true; data.qualified = true;
data.foundItems = classType.getConstructors(); data.foundItems = ClassTypeHelper.getConstructors(classType, name);
binding = resolveAmbiguities(data); binding = resolveAmbiguities(data);
if (binding instanceof ICPPConstructor) if (binding instanceof ICPPConstructor)
return (ICPPConstructor) binding; return (ICPPConstructor) binding;
} else if (initializer == null) { } else if (initializer == null) {
// Default initialization // Default initialization
ICPPConstructor[] ctors = classType.getConstructors(); ICPPConstructor[] ctors = ClassTypeHelper.getConstructors(classType, name);
for (ICPPConstructor ctor : ctors) { for (ICPPConstructor ctor : ctors) {
if (ctor.getRequiredArgumentCount() == 0) if (ctor.getRequiredArgumentCount() == 0)
return ctor; return ctor;
@ -3342,7 +3345,7 @@ public class CPPSemantics {
if (callToObjectOfClassType != null) { if (callToObjectOfClassType != null) {
try { try {
// 13.3.1.1.2 call to object of class type // 13.3.1.1.2 call to object of class type
ICPPMethod[] ops = SemanticUtil.getConversionOperators(callToObjectOfClassType); ICPPMethod[] ops = SemanticUtil.getConversionOperators(callToObjectOfClassType, point);
for (ICPPMethod op : ops) { for (ICPPMethod op : ops) {
if (op.isExplicit()) if (op.isExplicit())
continue; continue;
@ -3652,9 +3655,10 @@ public class CPPSemantics {
return false; return false;
} }
protected static IBinding resolveUnknownName(IScope scope, ICPPUnknownBinding unknown) { protected static IBinding resolveUnknownName(IScope scope, ICPPUnknownBinding unknown, IASTNode point) {
final IASTName unknownName = unknown.getUnknownName(); final IASTName unknownName = unknown.getUnknownName();
LookupData data = new LookupData(unknownName); LookupData data = unknownName.getTranslationUnit() != null ?
new LookupData(unknownName) : new LookupData(unknownName.getSimpleID(), null, point);
data.setIgnorePointOfDeclaration(true); data.setIgnorePointOfDeclaration(true);
data.typesOnly= unknown instanceof IType; data.typesOnly= unknown instanceof IType;

View file

@ -51,7 +51,6 @@ import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTAmbiguousTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
@ -124,11 +123,12 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethodTemplateSpecializat
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPParameterPackType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPParameterPackType;
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.CPPTemplateArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateDefinition; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateDefinition;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeParameter; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeParameter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTemplateParameter; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTemplateParameter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeParameter; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeParameter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTypedefSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTypedefSpecialization;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownBinding;
@ -138,6 +138,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUsingDeclarationSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUsingDeclarationSpecialization;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalTemplateDeclaration; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalTemplateDeclaration;
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.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
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.ICPPInternalClassTemplate; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalClassTemplate;
@ -153,9 +154,9 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.UDCMod
* type instantiation. * type instantiation.
*/ */
public class CPPTemplates { public class CPPTemplates {
private static final int PACK_SIZE_DEFER = -1; static final int PACK_SIZE_DEFER = -1;
private static final int PACK_SIZE_FAIL = -2; static final int PACK_SIZE_FAIL = -2;
private static final int PACK_SIZE_NOT_FOUND = Integer.MAX_VALUE; static final int PACK_SIZE_NOT_FOUND = Integer.MAX_VALUE;
private static final ICPPFunction[] NO_FUNCTIONS = {}; private static final ICPPFunction[] NO_FUNCTIONS = {};
static enum TypeSelection { PARAMETERS, RETURN_TYPE, PARAMETERS_AND_RETURN_TYPE } static enum TypeSelection { PARAMETERS, RETURN_TYPE, PARAMETERS_AND_RETURN_TYPE }
@ -225,7 +226,7 @@ public class CPPTemplates {
} }
if (isPack) { if (isPack) {
int packOffset= numParams - 1; int packOffset= numParams-1;
int packSize= numArgs - packOffset; int packSize= numArgs - packOffset;
ICPPTemplateArgument[] pack= new ICPPTemplateArgument[packSize]; ICPPTemplateArgument[] pack= new ICPPTemplateArgument[packSize];
System.arraycopy(arguments, packOffset, pack, 0, packSize); System.arraycopy(arguments, packOffset, pack, 0, packSize);
@ -402,7 +403,7 @@ public class CPPTemplates {
for (int i = 0; i < arguments.length; i++) { for (int i = 0; i < arguments.length; i++) {
ICPPTemplateArgument arg = arguments[i]; ICPPTemplateArgument arg = arguments[i];
if (arg.isPackExpansion()) { if (arg.isPackExpansion()) {
if (i != arguments.length - 1) { if (i != arguments.length-1) {
return arguments; return arguments;
} }
havePackExpansion= true; havePackExpansion= true;
@ -421,10 +422,10 @@ public class CPPTemplates {
// More arguments allowed if we have a parameter pack. // More arguments allowed if we have a parameter pack.
if (tparCount < argCount) { if (tparCount < argCount) {
if (tpars[tparCount - 1].isParameterPack()) if (tpars[tparCount-1].isParameterPack())
return arguments; return arguments;
if (havePackExpansion && tparCount + 1 == argCount) if (havePackExpansion && tparCount+1 == argCount)
return arguments; return arguments;
return null; return null;
} }
@ -434,7 +435,7 @@ public class CPPTemplates {
return arguments; return arguments;
// Fewer arguments are allowed with default arguments // Fewer arguments are allowed with default arguments
if (tpars[tparCount - 1].isParameterPack()) if (tpars[tparCount-1].isParameterPack())
tparCount--; tparCount--;
if (tparCount == argCount) if (tparCount == argCount)
@ -492,11 +493,11 @@ public class CPPTemplates {
if (tp.isParameterPack()) { if (tp.isParameterPack()) {
t= new CPPParameterPackType(t); t= new CPPParameterPackType(t);
} }
args[i] = new CPPTemplateArgument(t); args[i] = new CPPTemplateTypeArgument(t);
} else if (tp instanceof ICPPTemplateNonTypeParameter) { } else if (tp instanceof ICPPTemplateNonTypeParameter) {
// Non-type template parameter pack already has type 'ICPPParameterPackType' // Non-type template parameter pack already has type 'ICPPParameterPackType'
final ICPPTemplateNonTypeParameter nttp = (ICPPTemplateNonTypeParameter) tp; final ICPPTemplateNonTypeParameter nttp = (ICPPTemplateNonTypeParameter) tp;
args[i] = new CPPTemplateArgument(Value.create(nttp), nttp.getType()); args[i] = new CPPTemplateNonTypeArgument(Value.create(nttp), nttp.getType());
} else { } else {
assert false; assert false;
} }
@ -795,12 +796,13 @@ public class CPPTemplates {
IType[] exceptionSpecs= instantiateTypes(func.getExceptionSpecification(), tpMap, -1, within, point); IType[] exceptionSpecs= instantiateTypes(func.getExceptionSpecification(), tpMap, -1, within, point);
if (decl instanceof ICPPFunctionTemplate) { if (decl instanceof ICPPFunctionTemplate) {
if (decl instanceof ICPPConstructor) if (decl instanceof ICPPConstructor) {
spec = new CPPConstructorTemplateSpecialization((ICPPConstructor) decl, owner, tpMap, type, exceptionSpecs); spec = new CPPConstructorTemplateSpecialization((ICPPConstructor) decl, owner, tpMap, type, exceptionSpecs);
else if (decl instanceof ICPPMethod) } else if (decl instanceof ICPPMethod) {
spec = new CPPMethodTemplateSpecialization((ICPPMethod) decl, owner, tpMap, type, exceptionSpecs); spec = new CPPMethodTemplateSpecialization((ICPPMethod) decl, owner, tpMap, type, exceptionSpecs);
else } else {
spec = new CPPFunctionTemplateSpecialization((ICPPFunctionTemplate) decl, owner, tpMap, type, exceptionSpecs); spec = new CPPFunctionTemplateSpecialization((ICPPFunctionTemplate) decl, owner, tpMap, type, exceptionSpecs);
}
} else if (decl instanceof ICPPConstructor) { } else if (decl instanceof ICPPConstructor) {
spec = new CPPConstructorSpecialization((ICPPConstructor) decl, owner, tpMap, type, exceptionSpecs); spec = new CPPConstructorSpecialization((ICPPConstructor) decl, owner, tpMap, type, exceptionSpecs);
} else if (decl instanceof ICPPMethod) { } else if (decl instanceof ICPPMethod) {
@ -862,43 +864,20 @@ public class CPPTemplates {
ICPPClassSpecialization within, int maxdepth, IASTNode point) { ICPPClassSpecialization within, int maxdepth, IASTNode point) {
if (value == null) if (value == null)
return null; return null;
IBinding[] unknowns= value.getUnknownBindings(); ICPPEvaluation evaluation = value.getEvaluation();
IBinding[] resolvedUnknowns= null; if (evaluation == null)
if (unknowns.length != 0) { return value;
for (int i = 0; i < unknowns.length; i++) { ICPPEvaluation instantiated = evaluation.instantiate(tpMap, packOffset, within, maxdepth, point);
IBinding unknown= unknowns[i]; if (instantiated == evaluation)
IBinding resolved= unknown; return value;
if (unknown instanceof ICPPUnknownBinding) { return instantiated.getValue(point);
try {
resolved= resolveUnknown((ICPPUnknownBinding) unknown, tpMap, packOffset, within, point);
} catch (DOMException e) {
return Value.UNKNOWN;
}
}
if (resolvedUnknowns != null) {
resolvedUnknowns[i]= resolved;
} else if (resolved != unknown) {
resolvedUnknowns= new IBinding[unknowns.length];
System.arraycopy(unknowns, 0, resolvedUnknowns, 0, i);
resolvedUnknowns[i]= resolved;
}
}
}
if (resolvedUnknowns != null)
return Value.reevaluate(value, packOffset, resolvedUnknowns, tpMap, maxdepth);
if (Value.referencesTemplateParameter(value))
return Value.reevaluate(value, packOffset, unknowns, tpMap, maxdepth);
return value;
} }
public static boolean containsParameterPack(IType type) { public static boolean containsParameterPack(IType type) {
return determinePackSize(type, CPPTemplateParameterMap.EMPTY) == PACK_SIZE_DEFER; return determinePackSize(type, CPPTemplateParameterMap.EMPTY) == PACK_SIZE_DEFER;
} }
private static int determinePackSize(IType type, ICPPTemplateParameterMap tpMap) { static int determinePackSize(IType type, ICPPTemplateParameterMap tpMap) {
if (type instanceof ICPPFunctionType) { if (type instanceof ICPPFunctionType) {
final ICPPFunctionType ft = (ICPPFunctionType) type; final ICPPFunctionType ft = (ICPPFunctionType) type;
final IType rt = ft.getReturnType(); final IType rt = ft.getReturnType();
@ -907,7 +886,7 @@ public class CPPTemplates {
return r; return r;
IType[] ps = ft.getParameterTypes(); IType[] ps = ft.getParameterTypes();
for (IType pt : ps) { for (IType pt : ps) {
r= combine(r, determinePackSize(pt, tpMap)); r= combinePackSize(r, determinePackSize(pt, tpMap));
if (r < 0) if (r < 0)
return r; return r;
} }
@ -915,37 +894,17 @@ public class CPPTemplates {
} }
if (type instanceof ICPPTemplateParameter) { if (type instanceof ICPPTemplateParameter) {
final ICPPTemplateParameter tpar = (ICPPTemplateParameter) type; return determinePackSize((ICPPTemplateParameter) type, tpMap);
if (tpar.isParameterPack()) {
ICPPTemplateArgument[] args= tpMap.getPackExpansion(tpar);
if (args != null)
return args.length;
return PACK_SIZE_DEFER;
}
return PACK_SIZE_NOT_FOUND;
} }
int r= PACK_SIZE_NOT_FOUND;
if (type instanceof ICPPUnknownBinding) { if (type instanceof ICPPUnknownBinding) {
if (type instanceof ICPPDeferredClassInstance) { return determinePackSize((ICPPUnknownBinding) type, tpMap);
ICPPDeferredClassInstance dcl= (ICPPDeferredClassInstance) type;
ICPPTemplateArgument[] args = dcl.getTemplateArguments();
for (ICPPTemplateArgument arg : args) {
r= combine(r, determinePackSize(arg, tpMap));
if (r < 0)
return r;
}
}
IBinding binding= ((ICPPUnknownBinding) type).getOwner();
if (binding instanceof IType)
r= combine(r, determinePackSize((IType) binding, tpMap));
return r;
} }
if (type instanceof ICPPParameterPackType) if (type instanceof ICPPParameterPackType)
return PACK_SIZE_NOT_FOUND; return PACK_SIZE_NOT_FOUND;
int r= PACK_SIZE_NOT_FOUND;
if (type instanceof IArrayType) { if (type instanceof IArrayType) {
IArrayType at= (IArrayType) type; IArrayType at= (IArrayType) type;
IValue asize= at.getSize(); IValue asize= at.getSize();
@ -956,12 +915,54 @@ public class CPPTemplates {
if (type instanceof ITypeContainer) { if (type instanceof ITypeContainer) {
final ITypeContainer typeContainer = (ITypeContainer) type; final ITypeContainer typeContainer = (ITypeContainer) type;
r= combine(r, determinePackSize(typeContainer.getType(), tpMap)); r= combinePackSize(r, determinePackSize(typeContainer.getType(), tpMap));
} }
return r; return r;
} }
private static int combine(int ps1, int ps2) { static int determinePackSize(ICPPTemplateParameter tpar, ICPPTemplateParameterMap tpMap) {
if (tpar.isParameterPack()) {
ICPPTemplateArgument[] args= tpMap.getPackExpansion(tpar);
if (args != null)
return args.length;
return PACK_SIZE_DEFER;
}
return PACK_SIZE_NOT_FOUND;
}
static int determinePackSize(ICPPUnknownBinding binding, ICPPTemplateParameterMap tpMap) {
int r= PACK_SIZE_NOT_FOUND;
if (binding instanceof ICPPDeferredClassInstance) {
ICPPDeferredClassInstance dcl= (ICPPDeferredClassInstance) binding;
ICPPTemplateArgument[] args = dcl.getTemplateArguments();
for (ICPPTemplateArgument arg : args) {
r= combinePackSize(r, determinePackSize(arg, tpMap));
if (r < 0)
return r;
}
}
IBinding ownerBinding= binding.getOwner();
if (ownerBinding instanceof IType)
r= combinePackSize(r, determinePackSize((IType) ownerBinding, tpMap));
return r;
}
static int determinePackSize(IValue value, ICPPTemplateParameterMap tpMap) {
ICPPEvaluation eval = value.getEvaluation();
if (eval == null)
return PACK_SIZE_NOT_FOUND;
return ((CPPEvaluation) eval).determinePackSize(tpMap);
}
static int determinePackSize(ICPPTemplateArgument arg, ICPPTemplateParameterMap tpMap) {
if (arg.isTypeValue())
return determinePackSize(arg.getTypeValue(), tpMap);
return determinePackSize(arg.getNonTypeValue(), tpMap);
}
static int combinePackSize(int ps1, int ps2) {
if (ps1 < 0 || ps2 == PACK_SIZE_NOT_FOUND) if (ps1 < 0 || ps2 == PACK_SIZE_NOT_FOUND)
return ps1; return ps1;
if (ps2 < 0 || ps1 == PACK_SIZE_NOT_FOUND) if (ps2 < 0 || ps1 == PACK_SIZE_NOT_FOUND)
@ -971,35 +972,6 @@ public class CPPTemplates {
return ps1; return ps1;
} }
private static int determinePackSize(IValue value, ICPPTemplateParameterMap tpMap) {
int r= PACK_SIZE_NOT_FOUND;
IBinding[] unknown= value.getUnknownBindings();
for (IBinding binding : unknown) {
if (binding instanceof IType) {
r= combine(r, determinePackSize((IType) binding, tpMap));
if (r < 0)
return r;
}
}
int[] tpars= Value.getParameterPackReferences(value);
for (int parID : tpars) {
ICPPTemplateArgument[] args= tpMap.getPackExpansion(parID);
if (args != null) {
r= combine(r, args.length);
if (r < 0)
return r;
}
return PACK_SIZE_DEFER;
}
return r;
}
private static int determinePackSize(ICPPTemplateArgument arg, ICPPTemplateParameterMap tpMap) {
if (arg.isTypeValue())
return determinePackSize(arg.getTypeValue(), tpMap);
return determinePackSize(arg.getNonTypeValue(), tpMap);
}
/** /**
* Instantiates types contained in an array. * Instantiates types contained in an array.
* @param types an array of types * @param types an array of types
@ -1025,7 +997,7 @@ public class CPPTemplates {
} else if (packSize == PACK_SIZE_DEFER) { } else if (packSize == PACK_SIZE_DEFER) {
newType= origType; newType= origType;
} else { } else {
IType[] newResult= new IType[result.length + packSize - 1]; IType[] newResult= new IType[result.length+packSize-1];
System.arraycopy(result, 0, newResult, 0, j); System.arraycopy(result, 0, newResult, 0, j);
result= newResult; result= newResult;
for (int k= 0; k < packSize; k++) { for (int k= 0; k < packSize; k++) {
@ -1113,14 +1085,14 @@ public class CPPTemplates {
final IType instType= instantiateType(origType, tpMap, packOffset, within, point); final IType instType= instantiateType(origType, tpMap, packOffset, within, point);
if (origType == instType && origValue == instValue) if (origType == instType && origValue == instValue)
return arg; return arg;
return new CPPTemplateArgument(instValue, instType); return new CPPTemplateNonTypeArgument(instValue, instType);
} }
final IType orig= arg.getTypeValue(); final IType orig= arg.getTypeValue();
final IType inst= instantiateType(orig, tpMap, packOffset, within, point); final IType inst= instantiateType(orig, tpMap, packOffset, within, point);
if (orig == inst) if (orig == inst)
return arg; return arg;
return new CPPTemplateArgument(inst); return new CPPTemplateTypeArgument(inst);
} }
private static CPPTemplateParameterMap instantiateArgumentMap(ICPPTemplateParameterMap orig, ICPPTemplateParameterMap tpMap, private static CPPTemplateParameterMap instantiateArgumentMap(ICPPTemplateParameterMap orig, ICPPTemplateParameterMap tpMap,
@ -1287,6 +1259,13 @@ public class CPPTemplates {
return typeContainer; return typeContainer;
} }
if (type instanceof TypeOfDependentExpression) {
ICPPEvaluation eval = ((TypeOfDependentExpression) type).getEvaluation();
ICPPEvaluation instantiated = eval.instantiate(tpMap, packOffset, within, Value.MAX_RECURSION_DEPTH, point);
if (instantiated != eval)
return instantiated.getTypeOrFunctionSet(point);
}
return type; return type;
} catch (DOMException e) { } catch (DOMException e) {
return e.getProblem(); return e.getProblem();
@ -1294,11 +1273,11 @@ public class CPPTemplates {
} }
/** /**
* Checks whether a given name corresponds to a template declaration and returns the ast node for it. * Checks whether a given name corresponds to a template declaration and returns the AST node
* This works for the name of a template-definition and also for a name needed to qualify a member * for it. This works for the name of a template-definition and also for a name needed to
* definition: * qualify a member definition:
* <pre> * <pre>
* template &lttypename T&gt void MyTemplate&ltT&gt::member() {} * template &lt;typename T&gt; void MyTemplate&ltT&gt;::member() {}
* </pre> * </pre>
* @param name a name for which the corresponding template declaration is searched for. * @param name a name for which the corresponding template declaration is searched for.
* @return the template declaration or <code>null</code> if <code>name</code> does not * @return the template declaration or <code>null</code> if <code>name</code> does not
@ -1396,7 +1375,7 @@ public class CPPTemplates {
int depIDCount= 0; int depIDCount= 0;
IASTName owner= null; IASTName owner= null;
final IASTName[] ns= qname.getNames(); final IASTName[] ns= qname.getNames();
for (int i = 0; i < ns.length - 1; i++) { for (int i = 0; i < ns.length-1; i++) {
IASTName n= ns[i]; IASTName n= ns[i];
if (n instanceof ICPPASTTemplateId) { if (n instanceof ICPPASTTemplateId) {
if (depIDCount > 0 || usesTemplateParameter((ICPPASTTemplateId) n, tparnames)) { if (depIDCount > 0 || usesTemplateParameter((ICPPASTTemplateId) n, tparnames)) {
@ -1439,17 +1418,17 @@ public class CPPTemplates {
b= b.getOwner(); b= b.getOwner();
} }
if (depIDCount > 0) { if (depIDCount > 0) {
nestingLevel += depIDCount; nestingLevel+= depIDCount;
} else if (consumesTDecl < tdeclCount && !lastIsTemplate) { } else if (consumesTDecl < tdeclCount && !lastIsTemplate) {
nestingLevel++; nestingLevel++;
lastIsTemplate= true; lastIsTemplate= true;
} }
} else { } else {
nestingLevel += depIDCount; nestingLevel+= depIDCount;
node= outerMostTDecl.getParent(); node= outerMostTDecl.getParent();
while (node != null) { while (node != null) {
if (node instanceof ICPPASTInternalTemplateDeclaration) { if (node instanceof ICPPASTInternalTemplateDeclaration) {
nestingLevel += ((ICPPASTInternalTemplateDeclaration) node).getNestingLevel() + 1; nestingLevel+= ((ICPPASTInternalTemplateDeclaration) node).getNestingLevel() + 1;
break; break;
} }
node= node.getParent(); node= node.getParent();
@ -1462,7 +1441,7 @@ public class CPPTemplates {
node= outerMostTDecl.getParent(); node= outerMostTDecl.getParent();
while (node != null) { while (node != null) {
if (node instanceof ICPPASTInternalTemplateDeclaration) { if (node instanceof ICPPASTInternalTemplateDeclaration) {
nestingLevel += ((ICPPASTInternalTemplateDeclaration) node).getNestingLevel() + 1; nestingLevel+= ((ICPPASTInternalTemplateDeclaration) node).getNestingLevel() + 1;
break; break;
} }
node= node.getParent(); node= node.getParent();
@ -1471,7 +1450,7 @@ public class CPPTemplates {
} }
node= innerMostTDecl; node= innerMostTDecl;
while (node instanceof ICPPASTInternalTemplateDeclaration) { while(node instanceof ICPPASTInternalTemplateDeclaration) {
if (--nestingLevel < 0) if (--nestingLevel < 0)
nestingLevel= 0; nestingLevel= 0;
tdecl= (ICPPASTInternalTemplateDeclaration) node; tdecl= (ICPPASTInternalTemplateDeclaration) node;
@ -1501,7 +1480,7 @@ public class CPPTemplates {
private static CharArraySet collectTemplateParameterNames(ICPPASTTemplateDeclaration tdecl) { private static CharArraySet collectTemplateParameterNames(ICPPASTTemplateDeclaration tdecl) {
CharArraySet set= new CharArraySet(4); CharArraySet set= new CharArraySet(4);
while (true) { while(true) {
ICPPASTTemplateParameter[] pars = tdecl.getTemplateParameters(); ICPPASTTemplateParameter[] pars = tdecl.getTemplateParameters();
for (ICPPASTTemplateParameter par : pars) { for (ICPPASTTemplateParameter par : pars) {
IASTName name= CPPTemplates.getTemplateParameterName(par); IASTName name= CPPTemplates.getTemplateParameterName(par);
@ -1521,7 +1500,7 @@ public class CPPTemplates {
private static boolean usesTemplateParameter(final ICPPASTTemplateId id, final CharArraySet names) { private static boolean usesTemplateParameter(final ICPPASTTemplateId id, final CharArraySet names) {
final boolean[] result= {false}; final boolean[] result= {false};
ASTVisitor v= new ASTVisitor(false) { ASTVisitor v= new ASTVisitor(false) {
{ shouldVisitNames= true; shouldVisitAmbiguousNodes= true; } { shouldVisitNames= true; shouldVisitAmbiguousNodes=true;}
@Override @Override
public int visit(IASTName name) { public int visit(IASTName name) {
if (name instanceof ICPPASTTemplateId) if (name instanceof ICPPASTTemplateId)
@ -1613,7 +1592,7 @@ public class CPPTemplates {
} }
private static ICPPASTInternalTemplateDeclaration getDirectlyEnclosingTemplateDeclaration( private static ICPPASTInternalTemplateDeclaration getDirectlyEnclosingTemplateDeclaration(
ICPPASTInternalTemplateDeclaration tdecl) { ICPPASTInternalTemplateDeclaration tdecl ) {
final IASTNode parent= tdecl.getParent(); final IASTNode parent= tdecl.getParent();
if (parent instanceof ICPPASTInternalTemplateDeclaration) if (parent instanceof ICPPASTInternalTemplateDeclaration)
return (ICPPASTInternalTemplateDeclaration) parent; return (ICPPASTInternalTemplateDeclaration) parent;
@ -1643,10 +1622,11 @@ public class CPPTemplates {
name = dtor.getName(); name = dtor.getName();
} else if (simple.getDeclarators().length == 0) { } else if (simple.getDeclarators().length == 0) {
IASTDeclSpecifier spec = simple.getDeclSpecifier(); IASTDeclSpecifier spec = simple.getDeclSpecifier();
if (spec instanceof ICPPASTCompositeTypeSpecifier) if (spec instanceof ICPPASTCompositeTypeSpecifier) {
name = ((ICPPASTCompositeTypeSpecifier) spec).getName(); name = ((ICPPASTCompositeTypeSpecifier) spec).getName();
else if (spec instanceof ICPPASTElaboratedTypeSpecifier) } else if (spec instanceof ICPPASTElaboratedTypeSpecifier) {
name = ((ICPPASTElaboratedTypeSpecifier) spec).getName(); name = ((ICPPASTElaboratedTypeSpecifier) spec).getName();
}
} }
} else if (nestedDecl instanceof IASTFunctionDefinition) { } else if (nestedDecl instanceof IASTFunctionDefinition) {
IASTDeclarator declarator = ((IASTFunctionDefinition) nestedDecl).getDeclarator(); IASTDeclarator declarator = ((IASTFunctionDefinition) nestedDecl).getDeclarator();
@ -1662,11 +1642,10 @@ public class CPPTemplates {
if (currDecl == templateDecl) { if (currDecl == templateDecl) {
return ns[j]; return ns[j];
} }
if (currDecl instanceof ICPPASTTemplateDeclaration) { if (!(currDecl instanceof ICPPASTTemplateDeclaration)) {
currDecl = ((ICPPASTTemplateDeclaration) currDecl).getDeclaration();
} else {
return null; return null;
} }
currDecl = ((ICPPASTTemplateDeclaration) currDecl).getDeclaration();
} }
} }
} else { } else {
@ -1701,16 +1680,12 @@ public class CPPTemplates {
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
IASTNode arg= args[i]; IASTNode arg= args[i];
if (arg instanceof IASTTypeId) { if (arg instanceof IASTTypeId) {
result[i]= new CPPTemplateArgument(CPPVisitor.createType((IASTTypeId) arg)); result[i]= new CPPTemplateTypeArgument(CPPVisitor.createType((IASTTypeId) arg));
} else if (arg instanceof IASTExpression) { } else if (arg instanceof IASTExpression) {
IASTExpression expr= (IASTExpression) arg; IASTExpression expr= (IASTExpression) arg;
IType type= expr.getExpressionType(); IType type= expr.getExpressionType();
IValue value= Value.create((IASTExpression) arg, Value.MAX_RECURSION_DEPTH); IValue value= Value.create((IASTExpression) arg, Value.MAX_RECURSION_DEPTH);
result[i]= new CPPTemplateArgument(value, type); result[i]= new CPPTemplateNonTypeArgument(value, type);
} else if (arg instanceof ICPPASTAmbiguousTemplateArgument) {
throw new IllegalArgumentException(id.getRawSignature()
+ " contains an ambiguous template argument at position " + i + " in " //$NON-NLS-1$ //$NON-NLS-2$
+ id.getContainingFilename());
} else { } else {
throw new IllegalArgumentException("Unexpected type: " + arg.getClass().getName()); //$NON-NLS-1$ throw new IllegalArgumentException("Unexpected type: " + arg.getClass().getName()); //$NON-NLS-1$
} }
@ -1922,7 +1897,7 @@ public class CPPTemplates {
CPPTemplateParameterMap map = new CPPTemplateParameterMap(argLen); CPPTemplateParameterMap map = new CPPTemplateParameterMap(argLen);
for (int i = 0; i < argLen; i++) { for (int i = 0; i < argLen; i++) {
final ICPPTemplateParameter tpar = tpars[i]; final ICPPTemplateParameter tpar = tpars[i];
final CPPTemplateArgument arg = uniqueArg(tpar); final ICPPTemplateArgument arg = uniqueArg(tpar);
args[i]= arg; args[i]= arg;
if (tpar.isParameterPack()) { if (tpar.isParameterPack()) {
map.put(tpar, new ICPPTemplateArgument[] {arg}); map.put(tpar, new ICPPTemplateArgument[] {arg});
@ -1938,12 +1913,12 @@ public class CPPTemplates {
return null; return null;
} }
private static CPPTemplateArgument uniqueArg(final ICPPTemplateParameter tpar) throws DOMException { private static ICPPTemplateArgument uniqueArg(final ICPPTemplateParameter tpar) throws DOMException {
final CPPTemplateArgument arg; final ICPPTemplateArgument arg;
if (tpar instanceof ICPPTemplateNonTypeParameter) { if (tpar instanceof ICPPTemplateNonTypeParameter) {
arg = new CPPTemplateArgument(Value.unique(), ((ICPPTemplateNonTypeParameter) tpar).getType()); arg = new CPPTemplateNonTypeArgument(Value.unique(), ((ICPPTemplateNonTypeParameter) tpar).getType());
} else { } else {
arg = new CPPTemplateArgument(new UniqueType(tpar.isParameterPack())); arg = new CPPTemplateTypeArgument(new UniqueType(tpar.isParameterPack()));
} }
return arg; return arg;
} }
@ -1998,7 +1973,7 @@ public class CPPTemplates {
} }
private static IType[] concat(final IType t, IType[] types) { private static IType[] concat(final IType t, IType[] types) {
IType[] result= new IType[types.length + 1]; IType[] result= new IType[types.length+1];
result[0]= t; result[0]= t;
System.arraycopy(types, 0, result, 1, types.length); System.arraycopy(types, 0, result, 1, types.length);
return result; return result;
@ -2108,7 +2083,7 @@ public class CPPTemplates {
final CPPTemplateParameterMap transferMap= new CPPTemplateParameterMap(tpars1Len); final CPPTemplateParameterMap transferMap= new CPPTemplateParameterMap(tpars1Len);
for (int i = 0; i < tpars1Len; i++) { for (int i = 0; i < tpars1Len; i++) {
final ICPPTemplateParameter param = tpars1[i]; final ICPPTemplateParameter param = tpars1[i];
final CPPTemplateArgument arg = uniqueArg(param); final ICPPTemplateArgument arg = uniqueArg(param);
args[i]= arg; args[i]= arg;
transferMap.put(param, arg); transferMap.put(param, arg);
} }
@ -2207,7 +2182,7 @@ public class CPPTemplates {
pType= instantiateType(pType, map, -1, null, point); pType= instantiateType(pType, map, -1, null, point);
} }
if (argType instanceof ICPPUnknownType || argType instanceof ISemanticProblem || isNonTypeArgumentConvertible(pType, argType, point)) { if (argType instanceof ICPPUnknownType || argType instanceof ISemanticProblem || isNonTypeArgumentConvertible(pType, argType, point)) {
return new CPPTemplateArgument(arg.getNonTypeValue(), pType); return new CPPTemplateNonTypeArgument(arg.getNonTypeValue(), pType);
} }
return null; return null;
@ -2255,9 +2230,8 @@ public class CPPTemplates {
} }
if (!matchTemplateTemplateParameters(((ICPPTemplateTemplateParameter) pp).getTemplateParameters(), if (!matchTemplateTemplateParameters(((ICPPTemplateTemplateParameter) pp).getTemplateParameters(),
((ICPPTemplateTemplateParameter) ap).getTemplateParameters())) { ((ICPPTemplateTemplateParameter) ap).getTemplateParameters()) )
return false; return false;
}
} }
} }
if (!pp.isParameterPack()) if (!pp.isParameterPack())
@ -2395,7 +2369,7 @@ public class CPPTemplates {
public static boolean containsDependentArg(ObjectMap tpMap) { public static boolean containsDependentArg(ObjectMap tpMap) {
for (Object arg : tpMap.valueArray()) { for (Object arg : tpMap.valueArray()) {
if (isDependentType((IType)arg)) if (isDependentType((IType) arg))
return true; return true;
} }
return false; return false;
@ -2429,9 +2403,9 @@ public class CPPTemplates {
} }
} else if (!t.equals(owner)) { } else if (!t.equals(owner)) {
if (unknown instanceof ICPPUnknownClassType) { if (unknown instanceof ICPPUnknownClassType) {
result= new CPPUnknownClass((ICPPUnknownBinding)t, unknown.getNameCharArray()); result= new CPPUnknownClass((ICPPUnknownBinding) t, unknown.getNameCharArray());
} else if (unknown instanceof IFunction) { } else if (unknown instanceof IFunction) {
result= new CPPUnknownClass((ICPPUnknownBinding)t, unknown.getNameCharArray()); result= new CPPUnknownClass((ICPPUnknownBinding) t, unknown.getNameCharArray());
} else { } else {
result= new CPPUnknownBinding((ICPPUnknownBinding) t, unknown.getNameCharArray()); result= new CPPUnknownBinding((ICPPUnknownBinding) t, unknown.getNameCharArray());
} }
@ -2439,7 +2413,7 @@ public class CPPTemplates {
} else if (t instanceof ICPPClassType) { } else if (t instanceof ICPPClassType) {
IScope s = ((ICPPClassType) t).getCompositeScope(); IScope s = ((ICPPClassType) t).getCompositeScope();
if (s != null) { if (s != null) {
result= CPPSemantics.resolveUnknownName(s, unknown); result= CPPSemantics.resolveUnknownName(s, unknown, point);
if (unknown instanceof ICPPUnknownClassInstance && result instanceof ICPPTemplateDefinition) { if (unknown instanceof ICPPUnknownClassInstance && result instanceof ICPPTemplateDefinition) {
ICPPTemplateArgument[] newArgs = CPPTemplates.instantiateArguments( ICPPTemplateArgument[] newArgs = CPPTemplates.instantiateArguments(
((ICPPUnknownClassInstance) unknown).getArguments(), tpMap, packOffset, within, point); ((ICPPUnknownClassInstance) unknown).getArguments(), tpMap, packOffset, within, point);

View file

@ -13,7 +13,11 @@
*******************************************************************************/ *******************************************************************************/
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.SemanticUtil.*; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.ALLCVQ;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateTypeUptoPointers;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -157,6 +161,7 @@ import org.eclipse.cdt.core.parser.util.AttributeUtil;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.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.SizeofCalculator; import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator;
@ -191,8 +196,8 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
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.CPPScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTypedef; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTypedef;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownTypeScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownTypeScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariable; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariable;
@ -2029,7 +2034,7 @@ public class CPPVisitor extends ASTQueries {
return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE); return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE);
} }
type = (IType) CPPTemplates.instantiate(initializer_list_template, type = (IType) CPPTemplates.instantiate(initializer_list_template,
new ICPPTemplateArgument[] { new CPPTemplateArgument(type) }, initClause); new ICPPTemplateArgument[] { new CPPTemplateTypeArgument(type) }, initClause);
if (type instanceof IProblemBinding) { if (type instanceof IProblemBinding) {
return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE); return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE);
} }
@ -2058,7 +2063,7 @@ public class CPPVisitor extends ASTQueries {
type = t; type = t;
if (initClause instanceof ICPPASTInitializerList) { if (initClause instanceof ICPPASTInitializerList) {
type = (IType) CPPTemplates.instantiate(initializer_list_template, type = (IType) CPPTemplates.instantiate(initializer_list_template,
new ICPPTemplateArgument[] { new CPPTemplateArgument(type) }, initClause); new ICPPTemplateArgument[] { new CPPTemplateTypeArgument(type) }, initClause);
} }
return decorateType(type, declSpec, declarator); return decorateType(type, declSpec, declarator);
} }
@ -2236,7 +2241,10 @@ public class CPPVisitor extends ASTQueries {
} }
private static IType getStdType(final IASTNode node, char[] name) { private static IType getStdType(final IASTNode node, char[] name) {
IBinding[] std= node.getTranslationUnit().getScope().find(STD); if (node == null)
return null;
ASTTranslationUnit ast = (ASTTranslationUnit) node.getTranslationUnit();
IBinding[] std= ast.getScope().find(STD);
for (IBinding binding : std) { for (IBinding binding : std) {
if (binding instanceof ICPPNamespace) { if (binding instanceof ICPPNamespace) {
final ICPPNamespaceScope scope = ((ICPPNamespace) binding).getNamespaceScope(); final ICPPNamespaceScope scope = ((ICPPNamespace) binding).getNamespaceScope();

View file

@ -6,11 +6,10 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
/** /**
* Represents the possible cv-qualification of a type. * Represents the possible cv-qualification of a type.
*/ */
@ -23,16 +22,19 @@ public enum CVQualifier {
private static final int R = 4; private static final int R = 4;
final private int fQualifiers; final private int fQualifiers;
private CVQualifier(int qualifiers) { private CVQualifier(int qualifiers) {
fQualifiers= qualifiers; fQualifiers= qualifiers;
} }
public boolean isConst() { public boolean isConst() {
return (fQualifiers & C) != 0; return (fQualifiers & C) != 0;
} }
public boolean isVolatile() { public boolean isVolatile() {
return (fQualifiers & V) != 0; return (fQualifiers & V) != 0;
} }
public boolean isRestrict() { public boolean isRestrict() {
return (fQualifiers & R) != 0; return (fQualifiers & R) != 0;
} }
@ -54,7 +56,7 @@ public enum CVQualifier {
} }
private CVQualifier fromQualifier(final int q) { private CVQualifier fromQualifier(final int q) {
switch(q) { switch (q) {
case C|V|R: return CONST_VOLATILE_RESTRICT; case C|V|R: return CONST_VOLATILE_RESTRICT;
case V|R: return VOLATILE_RESTRICT; case V|R: return VOLATILE_RESTRICT;
case C|R: return CONST_RESTRICT; case C|R: return CONST_RESTRICT;
@ -65,7 +67,7 @@ public enum CVQualifier {
case 0: default: return NONE; case 0: default: return NONE;
} }
} }
/** /**
* [3.9.3-4] Implements cv-qualification (partial) comparison. There is a (partial) * [3.9.3-4] Implements cv-qualification (partial) comparison. There is a (partial)
* ordering on cv-qualifiers, so that a type can be said to be more * ordering on cv-qualifiers, so that a type can be said to be more
@ -83,12 +85,12 @@ public enum CVQualifier {
* </ul> * </ul>
*/ */
public int partialComparison(CVQualifier cv2) { public int partialComparison(CVQualifier cv2) {
// same qualifications // Same qualifications.
if (this == cv2) if (this == cv2)
return 0; return 0;
if (!isAtLeastAsQualifiedAs(cv2)) if (!isAtLeastAsQualifiedAs(cv2))
return -1; return -1;
return fQualifiers-cv2.fQualifiers; return fQualifiers - cv2.fQualifiers;
} }
} }

View file

@ -1,16 +1,16 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2010 IBM Corporation and others. * Copyright (c) 2004, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM - Initial API and implementation * IBM - Initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Bryan Wilkinson (QNX) * Bryan Wilkinson (QNX)
* Andrew Ferguson (Symbian) * Andrew Ferguson (Symbian)
* Sergey Prigogin (Google) * Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
@ -75,8 +75,8 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.ReferenceBind
* Routines for calculating the cost of conversions. * Routines for calculating the cost of conversions.
*/ */
public class Conversions { public class Conversions {
public enum UDCMode {ALLOWED, FORBIDDEN, DEFER} public enum UDCMode { ALLOWED, FORBIDDEN, DEFER }
public enum Context {ORDINARY, IMPLICIT_OBJECT, FIRST_PARAM_OF_DIRECT_COPY_CTOR, REQUIRE_DIRECT_BINDING} public enum Context { ORDINARY, IMPLICIT_OBJECT, FIRST_PARAM_OF_DIRECT_COPY_CTOR, REQUIRE_DIRECT_BINDING }
private static final char[] INITIALIZER_LIST_NAME = "initializer_list".toCharArray(); //$NON-NLS-1$ private static final char[] INITIALIZER_LIST_NAME = "initializer_list".toCharArray(); //$NON-NLS-1$
private static final char[] STD_NAME = "std".toCharArray(); //$NON-NLS-1$ private static final char[] STD_NAME = "std".toCharArray(); //$NON-NLS-1$
@ -135,7 +135,7 @@ public class Conversions {
// [for overload resolution bit-fields are treated the same, error if selected as best match] // [for overload resolution bit-fields are treated the same, error if selected as best match]
if (valueCat == LVALUE) { if (valueCat == LVALUE) {
// ... and "cv1 T1" is reference-compatible with "cv2 T2" // ... and "cv1 T1" is reference-compatible with "cv2 T2"
Cost cost= isReferenceCompatible(cv1T1, cv2T2, isImpliedObject); Cost cost= isReferenceCompatible(cv1T1, cv2T2, isImpliedObject, point);
if (cost != null) { if (cost != null) {
cost.setReferenceBinding(refBindingType); cost.setReferenceBinding(refBindingType);
return cost; return cost;
@ -145,7 +145,7 @@ public class Conversions {
// implicitly converted to an lvalue of type 'cv3 T3', where 'cv1 T1' is reference-compatible with // 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) < 0) { if (T2 instanceof ICPPClassType && udc != UDCMode.FORBIDDEN && isReferenceRelated(T1, T2, point) < 0) {
Cost cost= initializationByConversionForDirectReference(cv1T1, cv2T2, (ICPPClassType) T2, true, ctx, point); Cost cost= initializationByConversionForDirectReference(cv1T1, cv2T2, (ICPPClassType) T2, true, ctx, point);
if (cost != null) { if (cost != null) {
cost.setReferenceBinding(refBindingType); cost.setReferenceBinding(refBindingType);
@ -195,7 +195,7 @@ public class Conversions {
// ... the initializer expression is an rvalue and 'cv1 T1' is reference-compatible with 'cv2 T2' // ... the initializer expression is an rvalue and 'cv1 T1' is reference-compatible with 'cv2 T2'
// ..., then the reference is bound to the initializer expression rvalue in the first case // ..., then the reference is bound to the initializer expression rvalue in the first case
if (valueCat.isRValue()) { if (valueCat.isRValue()) {
Cost cost= isReferenceCompatible(cv1T1, cv2T2, isImpliedObject); Cost cost= isReferenceCompatible(cv1T1, cv2T2, isImpliedObject, point);
if (cost != null) { if (cost != null) {
// [13.3.3.1.4-1] direct binding has either identity or conversion rank. // [13.3.3.1.4-1] direct binding has either identity or conversion rank.
if (cost.getInheritanceDistance() > 0) { if (cost.getInheritanceDistance() > 0) {
@ -212,7 +212,7 @@ public class Conversions {
// resolution (13.3)), then the reference is bound to the initializer expression rvalue in the // resolution (13.3)), then the reference is bound to the initializer expression rvalue in the
// first case and to the object that is the result of the conversion in the second case (or, // first case and to the object that is the result of the conversion in the second case (or,
// in either case, to the appropriate base class sub-object of the object). // in either case, to the appropriate base class sub-object of the object).
if (udc != UDCMode.FORBIDDEN && isReferenceRelated(T1, T2) < 0) { if (udc != UDCMode.FORBIDDEN && isReferenceRelated(T1, T2, point) < 0) {
Cost cost= initializationByConversionForDirectReference(cv1T1, cv2T2, (ICPPClassType) T2, false, ctx, point); Cost cost= initializationByConversionForDirectReference(cv1T1, cv2T2, (ICPPClassType) T2, false, ctx, point);
if (cost != null) { if (cost != null) {
cost.setReferenceBinding(refBindingType); cost.setReferenceBinding(refBindingType);
@ -225,7 +225,7 @@ public class Conversions {
// reference-compatible with 'cv2 T2' the reference is bound to the object represented by the // reference-compatible with 'cv2 T2' the reference is bound to the object represented by the
// rvalue (see 3.10). // rvalue (see 3.10).
if (T2 instanceof IArrayType && valueCat.isRValue()) { if (T2 instanceof IArrayType && valueCat.isRValue()) {
Cost cost= isReferenceCompatible(cv1T1, cv2T2, isImpliedObject); Cost cost= isReferenceCompatible(cv1T1, cv2T2, isImpliedObject, point);
if (cost != null) { if (cost != null) {
cost.setReferenceBinding(refBindingType); cost.setReferenceBinding(refBindingType);
return cost; return cost;
@ -239,7 +239,7 @@ 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) {
if (isReferenceRelated(T1, T2) < 0 || compareQualifications(cv1T1, cv2T2) >= 0) { if (isReferenceRelated(T1, T2, point) < 0 || compareQualifications(cv1T1, cv2T2) >= 0) {
Cost cost= nonReferenceConversion(valueCat, cv2T2, T1, udc, point); Cost cost= nonReferenceConversion(valueCat, cv2T2, T1, udc, point);
if (cost.converts()) { if (cost.converts()) {
cost.setReferenceBinding(refBindingType); cost.setReferenceBinding(refBindingType);
@ -260,7 +260,7 @@ public class Conversions {
*/ */
private static Cost initializationByConversionForDirectReference(final IType cv1T1, final IType cv2T2, final ICPPClassType T2, boolean needLValue, Context ctx, IASTNode point) private static Cost initializationByConversionForDirectReference(final IType cv1T1, final IType cv2T2, final ICPPClassType T2, boolean needLValue, Context ctx, IASTNode point)
throws DOMException { throws DOMException {
ICPPMethod[] fcns= SemanticUtil.getConversionOperators(T2); ICPPMethod[] fcns= SemanticUtil.getConversionOperators(T2, point);
Cost operatorCost= null; Cost operatorCost= null;
FunctionCost bestUdcCost= null; FunctionCost bestUdcCost= null;
boolean ambiguousConversionOperator= false; boolean ambiguousConversionOperator= false;
@ -276,14 +276,14 @@ public class Conversions {
final boolean isLValueRef= t instanceof ICPPReferenceType && !((ICPPReferenceType) t).isRValueReference(); final boolean isLValueRef= t instanceof ICPPReferenceType && !((ICPPReferenceType) t).isRValueReference();
if (isLValueRef == needLValue) { // require an lvalue or rvalue if (isLValueRef == needLValue) { // require an lvalue or rvalue
IType implicitParameterType= CPPSemantics.getImplicitParameterType(op); IType implicitParameterType= CPPSemantics.getImplicitParameterType(op);
Cost udcCost= isReferenceCompatible(getNestedType(implicitParameterType, TDEF | REF), cv2T2, true); // expression type to implicit object type Cost udcCost= isReferenceCompatible(getNestedType(implicitParameterType, TDEF | REF), cv2T2, true, point); // expression type to implicit object type
if (udcCost != null) { 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); FunctionCost udcFuncCost= new FunctionCost(op, udcCost, point);
int cmp= udcFuncCost.compareTo(null, bestUdcCost, point); int cmp= udcFuncCost.compareTo(null, bestUdcCost);
if (cmp <= 0) { if (cmp <= 0) {
Cost cost= isReferenceCompatible(cv1T1, getNestedType(t, TDEF | REF), false); // converted to target Cost cost= isReferenceCompatible(cv1T1, getNestedType(t, TDEF | REF), false, point); // converted to target
if (cost != null) { if (cost != null) {
bestUdcCost= udcFuncCost; bestUdcCost= udcFuncCost;
ambiguousConversionOperator= cmp == 0; ambiguousConversionOperator= cmp == 0;
@ -315,7 +315,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); int depth= calculateInheritanceDepth(uqSource, uqTarget, point);
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);
@ -338,7 +338,7 @@ public class Conversions {
return initializationByConversion(valueCat, source, (ICPPClassType) uqSource, target, udc == UDCMode.DEFER, point); return initializationByConversion(valueCat, source, (ICPPClassType) uqSource, target, udc == UDCMode.DEFER, point);
} }
return checkStandardConversionSequence(uqSource, target); return checkStandardConversionSequence(uqSource, target, point);
} }
/** /**
@ -371,7 +371,7 @@ public class Conversions {
return Cost.NO_CONVERSION; return Cost.NO_CONVERSION;
ICPPClassType classTarget= (ICPPClassType) noCVTarget; ICPPClassType classTarget= (ICPPClassType) noCVTarget;
if (ClassTypeHelper.isAggregateClass(classTarget)) { if (ClassTypeHelper.isAggregateClass(classTarget, point)) {
Cost cost= new Cost(arg.getTypeOrFunctionSet(point), target, Rank.IDENTITY); Cost cost= new Cost(arg.getTypeOrFunctionSet(point), target, Rank.IDENTITY);
cost.setUserDefinedConversion(null); cost.setUserDefinedConversion(null);
return cost; return cost;
@ -439,7 +439,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) { private static final int isReferenceRelated(IType cv1Target, IType cv2Source, IASTNode point) {
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);
@ -474,7 +474,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); return SemanticUtil.calculateInheritanceDepth(s, t, point);
} }
} }
if (t == s || (t != null && s != null && t.isSameType(s))) { if (t == s || (t != null && s != null && t.isSameType(s))) {
@ -490,8 +490,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) { private static final Cost isReferenceCompatible(IType cv1Target, IType cv2Source, boolean isImpliedObject, IASTNode point) {
int inheritanceDist= isReferenceRelated(cv1Target, cv2Source); int inheritanceDist= isReferenceRelated(cv1Target, cv2Source, point);
if (inheritanceDist < 0) if (inheritanceDist < 0)
return null; return null;
final int cmp= compareQualifications(cv1Target, cv2Source); final int cmp= compareQualifications(cv1Target, cv2Source);
@ -515,7 +515,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) { private static final Cost checkStandardConversionSequence(IType source, IType target, IASTNode point) {
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;
@ -523,7 +523,7 @@ public class Conversions {
if (promotion(cost)) if (promotion(cost))
return cost; return cost;
if (conversion(cost)) if (conversion(cost, point))
return cost; return cost;
if (qualificationConversion(cost)) if (qualificationConversion(cost))
@ -546,7 +546,7 @@ public class Conversions {
ICPPConstructor usedCtor= null; ICPPConstructor usedCtor= null;
Cost bestCost= null; Cost bestCost= null;
boolean hasInitListConstructor= false; boolean hasInitListConstructor= false;
final ICPPConstructor[] constructors = t.getConstructors(); final ICPPConstructor[] constructors = ClassTypeHelper.getConstructors(t, point);
ICPPConstructor[] ctors= constructors; ICPPConstructor[] ctors= constructors;
for (ICPPConstructor ctor : ctors) { for (ICPPConstructor ctor : ctors) {
final int minArgCount = ctor.getRequiredArgumentCount(); final int minArgCount = ctor.getRequiredArgumentCount();
@ -630,7 +630,8 @@ public class Conversions {
/** /**
* 13.3.1.4 Copy-initialization of class by user-defined conversion [over.match.copy] * 13.3.1.4 Copy-initialization of class by user-defined conversion [over.match.copy]
*/ */
static final Cost copyInitializationOfClass(ValueCategory valueCat, IType source, ICPPClassType t, boolean deferUDC, IASTNode point) throws DOMException { static final Cost copyInitializationOfClass(ValueCategory valueCat, IType source, ICPPClassType t,
boolean deferUDC, IASTNode point) throws DOMException {
if (deferUDC) { 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);
@ -639,7 +640,7 @@ public class Conversions {
FunctionCost cost1= null; FunctionCost cost1= null;
Cost cost2= null; Cost cost2= null;
ICPPFunction[] ctors= t.getConstructors(); ICPPFunction[] ctors= ClassTypeHelper.getConstructors(t, point);
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, point);
@ -657,7 +658,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)); c1= new FunctionCost(ctor, new Cost(source, null, Rank.ELLIPSIS_CONVERSION), point);
} else { } else {
continue; continue;
} }
@ -669,9 +670,9 @@ 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)); c1= new FunctionCost(ctor, checkImplicitConversionSequence(ptype, source, valueCat, UDCMode.FORBIDDEN, Context.ORDINARY, point), point);
} }
int cmp= c1.compareTo(null, cost1, point); int cmp= c1.compareTo(null, cost1);
if (cmp <= 0) { if (cmp <= 0) {
cost1= c1; cost1= c1;
cost2= new Cost(t, t, Rank.IDENTITY); cost2= new Cost(t, t, Rank.IDENTITY);
@ -685,7 +686,7 @@ 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); ICPPFunction[] ops = SemanticUtil.getConversionOperators((ICPPClassType) uqSource, point);
ops= CPPTemplates.instantiateConversionTemplates(ops, t, point); ops= CPPTemplates.instantiateConversionTemplates(ops, t, point);
for (final ICPPFunction f : ops) { for (final ICPPFunction f : ops) {
if (f instanceof ICPPMethod && !(f instanceof IProblemBinding)) { if (f instanceof ICPPMethod && !(f instanceof IProblemBinding)) {
@ -694,15 +695,15 @@ 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); final int dist = SemanticUtil.calculateInheritanceDepth(uqReturnType, t, point);
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); final Cost udcCost = isReferenceCompatible(getNestedType(implicitType, TDEF | REF), source, true, point);
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); FunctionCost c1= new FunctionCost(op, udcCost, point);
int cmp= c1.compareTo(null, cost1, point); int cmp= c1.compareTo(null, cost1);
if (cmp <= 0) { if (cmp <= 0) {
cost1= c1; cost1= c1;
cost2= new Cost(t, t, Rank.IDENTITY); cost2= new Cost(t, t, Rank.IDENTITY);
@ -735,7 +736,7 @@ public class Conversions {
c.setDeferredUDC(DeferredUDC.INIT_BY_CONVERSION); c.setDeferredUDC(DeferredUDC.INIT_BY_CONVERSION);
return c; return c;
} }
ICPPFunction[] ops = SemanticUtil.getConversionOperators(uqSource); ICPPFunction[] ops = SemanticUtil.getConversionOperators(uqSource, point);
ops= CPPTemplates.instantiateConversionTemplates(ops, target, point); ops= CPPTemplates.instantiateConversionTemplates(ops, target, point);
FunctionCost cost1= null; FunctionCost cost1= null;
Cost cost2= null; Cost cost2= null;
@ -753,12 +754,12 @@ public class Conversions {
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); final Cost udcCost = isReferenceCompatible(getNestedType(implicitType, TDEF | REF), source, true, point);
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); FunctionCost c1= new FunctionCost(op, udcCost, point);
int cmp= c1.compareTo(null, cost1, point); int cmp= c1.compareTo(null, cost1);
if (cmp <= 0) { if (cmp <= 0) {
cost1= c1; cost1= c1;
cost2= c2; cost2= c2;
@ -1014,7 +1015,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){ private static final boolean conversion(Cost cost, IASTNode point) {
final IType s = cost.source; final IType s = cost.source;
final IType t = cost.target; final IType t = cost.target;
@ -1085,7 +1086,7 @@ public class Conversions {
// to an rvalue of type "pointer to cv B", where B is a base class of D. // 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); int depth= SemanticUtil.calculateInheritanceDepth(srcPtrTgt, tgtPtrTgt, point);
if (depth == -1) { if (depth == -1) {
cost.setRank(Rank.NO_MATCH); cost.setRank(Rank.NO_MATCH);
return true; return true;
@ -1108,7 +1109,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()); spm.getMemberOfClass(), point);
if (depth == -1) { if (depth == -1) {
cost.setRank(Rank.NO_MATCH); cost.setRank(Rank.NO_MATCH);
return true; return true;

View file

@ -6,10 +6,10 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM - Initial API and implementation * IBM - Initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Bryan Wilkinson (QNX) * Bryan Wilkinson (QNX)
* Andrew Ferguson (Symbian) * Andrew Ferguson (Symbian)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
@ -114,7 +114,6 @@ public class Cost {
public void setRank(Rank rank) { public void setRank(Rank rank) {
fRank= rank; fRank= rank;
} }
public ReferenceBinding getReferenceBinding() { public ReferenceBinding getReferenceBinding() {
return fReferenceBinding; return fReferenceBinding;
@ -123,7 +122,6 @@ public class Cost {
public void setReferenceBinding(ReferenceBinding binding) { public void setReferenceBinding(ReferenceBinding binding) {
fReferenceBinding= binding; fReferenceBinding= binding;
} }
public boolean isAmbiguousUDC() { public boolean isAmbiguousUDC() {
return fAmbiguousUDC; return fAmbiguousUDC;
@ -303,7 +301,7 @@ public class Cost {
public void setSelectedFunction(ICPPFunction function) { public void setSelectedFunction(ICPPFunction function) {
fSelectedFunction= function; fSelectedFunction= function;
} }
public ICPPFunction getSelectedFunction() { public ICPPFunction getSelectedFunction() {
return fSelectedFunction; return fSelectedFunction;
} }

View file

@ -7,28 +7,55 @@
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_assign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_binaryAndAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_binaryOrAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_binaryXorAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_divideAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_equals;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_greaterEqual;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_greaterThan;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_lessEqual;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_lessThan;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_logicalAnd;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_logicalOr;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_minus;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_minusAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_moduloAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_multiplyAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_notequals;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_plus;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_plusAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_pmarrow;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_pmdot;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_shiftLeftAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_shiftRightAssign;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.*; 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.prvalueTypeWithResolvedTypedefs;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromFunctionCall;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
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.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.IASTNode;
import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
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.ICPPASTBinaryExpression; 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.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
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.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
@ -102,7 +129,43 @@ public class EvalBinary extends CPPEvaluation {
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue(IASTNode point) {
return Value.create(this, point); if (getOverload(point) != null) {
// TODO(sprigogin): Simulate execution of a function call.
return Value.create(this);
}
IValue v1 = fArg1.getValue(point);
if (v1 == Value.UNKNOWN)
return Value.UNKNOWN;
IValue v2 = fArg2.getValue(point);
if (v2 == Value.UNKNOWN)
return Value.UNKNOWN;
switch (fOperator) {
case op_equals:
if (v1.equals(v2))
return Value.create(1);
break;
case op_notequals:
if (v1.equals(v2))
return Value.create(0);
break;
}
Long num1 = v1.numericalValue();
if (num1 != null) {
if (num1 == 0) {
if (fOperator == op_logicalAnd)
return v1;
} else if (fOperator == op_logicalOr) {
return v1;
}
Long num2 = v2.numericalValue();
if (num2 != null) {
return Value.evaluateBinaryExpression(fOperator, num1, num2);
}
}
return Value.create(this);
} }
@Override @Override
@ -129,25 +192,25 @@ public class EvalBinary extends CPPEvaluation {
switch (fOperator) { switch (fOperator) {
case op_arrayAccess: case op_arrayAccess:
case IASTBinaryExpression.op_assign: case op_assign:
case IASTBinaryExpression.op_binaryAndAssign: case op_binaryAndAssign:
case IASTBinaryExpression.op_binaryOrAssign: case op_binaryOrAssign:
case IASTBinaryExpression.op_binaryXorAssign: case op_binaryXorAssign:
case IASTBinaryExpression.op_divideAssign: case op_divideAssign:
case IASTBinaryExpression.op_minusAssign: case op_minusAssign:
case IASTBinaryExpression.op_moduloAssign: case op_moduloAssign:
case IASTBinaryExpression.op_multiplyAssign: case op_multiplyAssign:
case IASTBinaryExpression.op_plusAssign: case op_plusAssign:
case IASTBinaryExpression.op_shiftLeftAssign: case op_shiftLeftAssign:
case IASTBinaryExpression.op_shiftRightAssign: case op_shiftRightAssign:
return LVALUE; return LVALUE;
case IASTBinaryExpression.op_pmdot: case op_pmdot:
if (!(getTypeOrFunctionSet(point) instanceof ICPPFunctionType)) if (!(getTypeOrFunctionSet(point) instanceof ICPPFunctionType))
return fArg1.getValueCategory(point); return fArg1.getValueCategory(point);
break; break;
case IASTBinaryExpression.op_pmarrow: case op_pmarrow:
if (!(getTypeOrFunctionSet(point) instanceof ICPPFunctionType)) if (!(getTypeOrFunctionSet(point) instanceof ICPPFunctionType))
return LVALUE; return LVALUE;
break; break;
@ -215,17 +278,17 @@ public class EvalBinary extends CPPEvaluation {
} }
return ProblemType.UNKNOWN_FOR_EXPRESSION; return ProblemType.UNKNOWN_FOR_EXPRESSION;
case IASTBinaryExpression.op_lessEqual: case op_lessEqual:
case IASTBinaryExpression.op_lessThan: case op_lessThan:
case IASTBinaryExpression.op_greaterEqual: case op_greaterEqual:
case IASTBinaryExpression.op_greaterThan: case op_greaterThan:
case IASTBinaryExpression.op_logicalAnd: case op_logicalAnd:
case IASTBinaryExpression.op_logicalOr: case op_logicalOr:
case IASTBinaryExpression.op_equals: case op_equals:
case IASTBinaryExpression.op_notequals: case op_notequals:
return CPPBasicType.BOOLEAN; return CPPBasicType.BOOLEAN;
case IASTBinaryExpression.op_plus: case op_plus:
if (type1 instanceof IPointerType) { if (type1 instanceof IPointerType) {
return ExpressionTypes.restoreTypedefs(type1, originalType1); return ExpressionTypes.restoreTypedefs(type1, originalType1);
} }
@ -234,7 +297,7 @@ public class EvalBinary extends CPPEvaluation {
} }
break; break;
case IASTBinaryExpression.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(point);
@ -243,13 +306,13 @@ public class EvalBinary extends CPPEvaluation {
} }
break; break;
case ICPPASTBinaryExpression.op_pmarrow: case op_pmarrow:
case ICPPASTBinaryExpression.op_pmdot: case op_pmdot:
if (type2 instanceof ICPPPointerToMemberType) { if (type2 instanceof ICPPPointerToMemberType) {
IType t= ((ICPPPointerToMemberType) type2).getType(); IType t= ((ICPPPointerToMemberType) type2).getType();
if (t instanceof ICPPFunctionType) if (t instanceof ICPPFunctionType)
return t; return t;
if (fOperator == ICPPASTBinaryExpression.op_pmdot && fArg1.getValueCategory(point) == PRVALUE) { if (fOperator == op_pmdot && fArg1.getValueCategory(point) == PRVALUE) {
return prvalueType(t); return prvalueType(t);
} }
return glvalueType(t); return glvalueType(t);
@ -273,4 +336,24 @@ public class EvalBinary extends CPPEvaluation {
ICPPEvaluation arg2= (ICPPEvaluation) buffer.unmarshalEvaluation(); ICPPEvaluation arg2= (ICPPEvaluation) buffer.unmarshalEvaluation();
return new EvalBinary(op, arg1, arg2); return new EvalBinary(op, arg1, arg2);
} }
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within, int maxdepth, IASTNode point) {
ICPPEvaluation arg1 = fArg1.instantiate(tpMap, packOffset, within, maxdepth, point);
ICPPEvaluation arg2 = fArg2.instantiate(tpMap, packOffset, within, maxdepth, point);
if (arg1 == fArg1 && arg2 == fArg2)
return this;
return new EvalBinary(fOperator, arg1, arg2);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
return CPPTemplates.combinePackSize(fArg1.determinePackSize(tpMap), fArg2.determinePackSize(tpMap));
}
@Override
public boolean referencesTemplateParameter() {
return fArg1.referencesTemplateParameter() || fArg2.referencesTemplateParameter();
}
} }

View file

@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
@ -18,11 +19,16 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
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.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.Value;
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.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
/** /**
@ -74,7 +80,16 @@ public class EvalBinaryTypeId extends CPPEvaluation {
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue(IASTNode point) {
return Value.create(this, point); if (isValueDependent())
return Value.create(this);
switch (fOperator) {
case __is_base_of:
if (!(fType1 instanceof ICPPClassType) || !(fType1 instanceof ICPPClassType))
return Value.UNKNOWN;
return Value.create(ClassTypeHelper.isSubclass((ICPPClassType) fType2, (ICPPClassType) fType1));
}
return Value.create(this);
} }
@Override @Override
@ -110,4 +125,25 @@ public class EvalBinaryTypeId extends CPPEvaluation {
IType arg2= buffer.unmarshalType(); IType arg2= buffer.unmarshalType();
return new EvalBinaryTypeId(Operator.values()[op], arg1, arg2); return new EvalBinaryTypeId(Operator.values()[op], arg1, arg2);
} }
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within, int maxdepth, IASTNode point) {
IType type1 = CPPTemplates.instantiateType(fType1, tpMap, packOffset, within, point);
IType type2 = CPPTemplates.instantiateType(fType2, tpMap, packOffset, within, point);
if (type1 == fType1 && type2 == fType2)
return this;
return new EvalBinaryTypeId(fOperator, type1, type2);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
return CPPTemplates.combinePackSize(CPPTemplates.determinePackSize(fType1, tpMap),
CPPTemplates.determinePackSize(fType2, tpMap));
}
@Override
public boolean referencesTemplateParameter() {
return false;
}
} }

View file

@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
@ -22,11 +23,21 @@ import org.eclipse.cdt.core.dom.ast.IFunctionType;
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.IVariable; import org.eclipse.cdt.core.dom.ast.IVariable;
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.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.IInternalVariable;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
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.Value; import org.eclipse.cdt.internal.core.dom.parser.Value;
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.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
@ -40,7 +51,6 @@ public class EvalBinding extends CPPEvaluation {
private boolean fIsTypeDependent; private boolean fIsTypeDependent;
private boolean fCheckedIsTypeDependent; private boolean fCheckedIsTypeDependent;
public EvalBinding(IBinding binding, IType type) { public EvalBinding(IBinding binding, IType type) {
fBinding= binding; fBinding= binding;
fType= type; fType= type;
@ -75,20 +85,19 @@ public class EvalBinding extends CPPEvaluation {
} }
private boolean computeIsTypeDependent() { private boolean computeIsTypeDependent() {
if (fBinding instanceof ICPPUnknownBinding)
return true;
IType t= null; IType t= null;
if (fBinding instanceof IEnumerator) { if (fFixedType) {
t = fType;
} else if (fBinding instanceof IEnumerator) {
t= ((IEnumerator) fBinding).getType(); t= ((IEnumerator) fBinding).getType();
} else if (fBinding instanceof ICPPTemplateNonTypeParameter) { } else if (fBinding instanceof ICPPTemplateNonTypeParameter) {
t= ((ICPPTemplateNonTypeParameter) fBinding).getType(); t= ((ICPPTemplateNonTypeParameter) fBinding).getType();
} else if (fBinding instanceof IVariable) { } else if (fBinding instanceof IVariable) {
t = ((IVariable) fBinding).getType(); t = ((IVariable) fBinding).getType();
} else if (fBinding instanceof IFunction) {
t= ((IFunction) fBinding).getType();
} else if (fBinding instanceof ICPPUnknownBinding) { } else if (fBinding instanceof ICPPUnknownBinding) {
return true; return true;
} else if (fBinding instanceof IFunction) {
t= ((IFunction) fBinding).getType();
} else { } else {
return false; return false;
} }
@ -114,12 +123,12 @@ public class EvalBinding extends CPPEvaluation {
if (fBinding instanceof IVariable) { if (fBinding instanceof IVariable) {
return Value.isDependentValue(((IVariable) fBinding).getInitialValue()); return Value.isDependentValue(((IVariable) fBinding).getInitialValue());
} }
if (fBinding instanceof IFunction) {
return false;
}
if (fBinding instanceof ICPPUnknownBinding) { if (fBinding instanceof ICPPUnknownBinding) {
return true; return true;
} }
if (fBinding instanceof IFunction) {
return false;
}
return false; return false;
} }
@ -151,14 +160,28 @@ public class EvalBinding extends CPPEvaluation {
final IFunctionType type = ((IFunction) fBinding).getType(); final IFunctionType type = ((IFunction) fBinding).getType();
if (CPPTemplates.isDependentType(type)) if (CPPTemplates.isDependentType(type))
return new TypeOfDependentExpression(this); return new TypeOfDependentExpression(this);
return SemanticUtil.mapToAST(type, point); return SemanticUtil.mapToAST(type, point);
} }
return ProblemType.UNKNOWN_FOR_EXPRESSION; return ProblemType.UNKNOWN_FOR_EXPRESSION;
} }
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue(IASTNode point) {
return Value.create(this, point); if (isValueDependent())
return Value.create(this);
IValue value= null;
if (fBinding instanceof IInternalVariable) {
value= ((IInternalVariable) fBinding).getInitialValue(Value.MAX_RECURSION_DEPTH);
} else if (fBinding instanceof IVariable) {
value= ((IVariable) fBinding).getInitialValue();
} else if (fBinding instanceof IEnumerator) {
value= ((IEnumerator) fBinding).getValue();
}
if (value == null)
value = Value.UNKNOWN;
return value;
} }
@Override @Override
@ -184,4 +207,75 @@ public class EvalBinding extends CPPEvaluation {
IType type= buffer.unmarshalType(); IType type= buffer.unmarshalType();
return new EvalBinding(binding, type); return new EvalBinding(binding, type);
} }
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within, int maxdepth, IASTNode point) {
IBinding binding = fBinding;
if (fBinding instanceof IEnumerator) {
IEnumerator enumerator = (IEnumerator) binding;
IType originalType = enumerator.getType();
IType type = CPPTemplates.instantiateType(originalType, tpMap, packOffset, within, point);
IValue originalValue = enumerator.getValue();
IValue value = CPPTemplates.instantiateValue(originalValue, tpMap, packOffset, within, maxdepth, point);
// TODO(sprigogin): Not sure if following condition is correct.
if (type != originalType || value != originalValue)
return new EvalFixed(type, ValueCategory.PRVALUE, value);
} else if (fBinding instanceof ICPPTemplateNonTypeParameter) {
ICPPTemplateArgument argument = tpMap.getArgument((ICPPTemplateNonTypeParameter) fBinding);
if (argument != null) {
IValue value = argument.getNonTypeValue();
return new EvalFixed(null, ValueCategory.PRVALUE, value);
}
// TODO(sprigogin): Do we need something similar for pack expansion?
} else if (fBinding instanceof ICPPUnknownBinding) {
binding = resolveUnknown((ICPPUnknownBinding) fBinding, tpMap, packOffset, within, point);
} else if (fBinding instanceof ICPPMethod) {
IBinding owner = fBinding.getOwner();
if (owner instanceof ICPPClassTemplate) {
owner = resolveUnknown(CPPTemplates.createDeferredInstance((ICPPClassTemplate) owner),
tpMap, packOffset, within, point);
}
if (owner instanceof ICPPClassSpecialization) {
binding = CPPTemplates.createSpecialization((ICPPClassSpecialization) owner,
fBinding, point);
}
}
if (binding == fBinding)
return this;
return new EvalBinding(binding, getFixedType());
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
if (fBinding instanceof IEnumerator) {
return CPPTemplates.determinePackSize(((IEnumerator) fBinding).getValue(), tpMap);
}
if (fBinding instanceof ICPPTemplateNonTypeParameter) {
return CPPTemplates.determinePackSize((ICPPTemplateNonTypeParameter) fBinding, tpMap);
}
if (fBinding instanceof ICPPUnknownBinding) {
return CPPTemplates.determinePackSize((ICPPUnknownBinding) fBinding, tpMap);
}
IBinding binding = fBinding;
if (fBinding instanceof ICPPSpecialization) {
binding = ((ICPPSpecialization) fBinding).getSpecializedBinding();
}
int r = CPPTemplates.PACK_SIZE_NOT_FOUND;
if (binding instanceof ICPPTemplateDefinition) {
ICPPTemplateParameter[] parameters = ((ICPPTemplateDefinition) binding).getTemplateParameters();
for (ICPPTemplateParameter param : parameters) {
r = CPPTemplates.combinePackSize(r, CPPTemplates.determinePackSize(param, tpMap));
}
}
return r;
}
@Override
public boolean referencesTemplateParameter() {
return fBinding instanceof ICPPTemplateParameter;
}
} }

View file

@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
@ -18,7 +19,9 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
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.ICPPClassSpecialization;
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.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.Value;
@ -123,12 +126,18 @@ public class EvalComma extends CPPEvaluation {
return typeFromFunctionCall(last); return typeFromFunctionCall(last);
} }
} }
return fArguments[fArguments.length-1].getTypeOrFunctionSet(point); return fArguments[fArguments.length - 1].getTypeOrFunctionSet(point);
} }
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue(IASTNode point) {
return Value.create(this, point); ICPPFunction[] overloads = getOverloads(point);
if (overloads.length > 0) {
// TODO(sprigogin): Simulate execution of a function call.
return Value.create(this);
}
return fArguments[fArguments.length - 1].getValue(point);
} }
@Override @Override
@ -140,7 +149,7 @@ public class EvalComma extends CPPEvaluation {
return valueCategoryFromFunctionCall(last); return valueCategoryFromFunctionCall(last);
} }
} }
return fArguments[fArguments.length-1].getValueCategory(point); return fArguments[fArguments.length - 1].getValueCategory(point);
} }
@Override @Override
@ -160,4 +169,41 @@ public class EvalComma extends CPPEvaluation {
} }
return new EvalComma(args); return new EvalComma(args);
} }
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within, int maxdepth, IASTNode point) {
ICPPEvaluation[] args = fArguments;
for (int i = 0; i < fArguments.length; i++) {
ICPPEvaluation arg = fArguments[i].instantiate(tpMap, packOffset, within, maxdepth, point);
if (arg != fArguments[i]) {
if (args == fArguments) {
args = new ICPPEvaluation[fArguments.length];
System.arraycopy(fArguments, 0, args, 0, fArguments.length);
}
args[i] = arg;
}
}
if (args == fArguments)
return this;
return new EvalComma(args);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
int r = CPPTemplates.PACK_SIZE_NOT_FOUND;
for (ICPPEvaluation arg : fArguments) {
r = CPPTemplates.combinePackSize(r, arg.determinePackSize(tpMap));
}
return r;
}
@Override
public boolean referencesTemplateParameter() {
for (ICPPEvaluation arg : fArguments) {
if (arg.referencesTemplateParameter())
return true;
}
return false;
}
} }

View file

@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
@ -16,14 +17,16 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTNode; 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.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
/** /**
* Performs evaluation of an expression. * Performs evaluation of a compound statement expression. Most but not all methods
* delegate to the evaluation of the last expression in the compound one.
*/ */
public class EvalCompound extends CPPEvaluation { public class EvalCompound extends CPPEvaluation {
private final ICPPEvaluation fDelegate; private final ICPPEvaluation fDelegate;
@ -63,7 +66,7 @@ public class EvalCompound extends CPPEvaluation {
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue(IASTNode point) {
return Value.create(this, point); return fDelegate.getValue(point);
} }
@Override @Override
@ -81,4 +84,23 @@ public class EvalCompound extends CPPEvaluation {
ICPPEvaluation arg= (ICPPEvaluation) buffer.unmarshalEvaluation(); ICPPEvaluation arg= (ICPPEvaluation) buffer.unmarshalEvaluation();
return new EvalCompound(arg); return new EvalCompound(arg);
} }
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within, int maxdepth, IASTNode point) {
ICPPEvaluation delegate = fDelegate.instantiate(tpMap, packOffset, within, maxdepth, point);
if (delegate == fDelegate)
return this;
return new EvalCompound(delegate);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
return fDelegate.determinePackSize(tpMap);
}
@Override
public boolean referencesTemplateParameter() {
return fDelegate.referencesTemplateParameter();
}
} }

View file

@ -7,13 +7,17 @@
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; 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 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 static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
@ -23,8 +27,10 @@ import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
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.ICPPBasicType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
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.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
@ -49,13 +55,12 @@ public class EvalConditional extends CPPEvaluation {
private IType fType; private IType fType;
private ICPPFunction fOverload; private ICPPFunction fOverload;
public EvalConditional(ICPPEvaluation condition, ICPPEvaluation positive, ICPPEvaluation negative,
public EvalConditional(ICPPEvaluation arg1, ICPPEvaluation arg2, ICPPEvaluation arg3,
boolean positiveThrows, boolean negativeThrows) { boolean positiveThrows, boolean negativeThrows) {
// Gnu-extension: Empty positive expression is replaced by condition. // Gnu-extension: Empty positive expression is replaced by condition.
fCondition= arg1; fCondition= condition;
fPositive= arg2; fPositive= positive;
fNegative= arg3; fNegative= negative;
fPositiveThrows= positiveThrows; fPositiveThrows= positiveThrows;
fNegativeThrows= negativeThrows; fNegativeThrows= negativeThrows;
} }
@ -103,7 +108,18 @@ public class EvalConditional extends CPPEvaluation {
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue(IASTNode point) {
return Value.create(this, point); IValue condValue = fCondition.getValue(point);
if (condValue == Value.UNKNOWN)
return Value.UNKNOWN;
Long cond = condValue.numericalValue();
if (cond != null) {
if (cond.longValue() != 0) {
return fPositive == null ? condValue : fPositive.getValue(point);
} else {
return fNegative.getValue(point);
}
}
return Value.create(this);
} }
@Override @Override
@ -252,7 +268,7 @@ public class EvalConditional extends CPPEvaluation {
} }
// 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); int dist= SemanticUtil.calculateInheritanceDepth(uqt1, uqt2, point);
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);
@ -263,7 +279,7 @@ public class EvalConditional extends CPPEvaluation {
} }
return Cost.NO_CONVERSION; return Cost.NO_CONVERSION;
} }
if (SemanticUtil.calculateInheritanceDepth(uqt2, uqt1) >= 0) if (SemanticUtil.calculateInheritanceDepth(uqt2, uqt1, point) >= 0)
return Cost.NO_CONVERSION; return Cost.NO_CONVERSION;
} }
// Unrelated class types or just one class: // Unrelated class types or just one class:
@ -307,4 +323,32 @@ public class EvalConditional extends CPPEvaluation {
ICPPEvaluation neg= (ICPPEvaluation) buffer.unmarshalEvaluation(); ICPPEvaluation neg= (ICPPEvaluation) buffer.unmarshalEvaluation();
return new EvalConditional(cond, pos, neg, pth, nth); return new EvalConditional(cond, pos, neg, pth, nth);
} }
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within, int maxdepth, IASTNode point) {
ICPPEvaluation condition = fCondition.instantiate(tpMap, packOffset, within, maxdepth, point);
ICPPEvaluation positive = fPositive == null ?
null : fPositive.instantiate(tpMap, packOffset, within, maxdepth, point);
ICPPEvaluation negative = fNegative.instantiate(tpMap, packOffset, within, maxdepth, point);
if (condition == fCondition && positive == fPositive && negative == fNegative)
return this;
return new EvalConditional(condition, positive, negative, fPositiveThrows, fNegativeThrows);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
int r = fCondition.determinePackSize(tpMap);
r = CPPTemplates.combinePackSize(r, fNegative.determinePackSize(tpMap));
if (fPositive != null)
r = CPPTemplates.combinePackSize(r, fPositive.determinePackSize(tpMap));
return r;
}
@Override
public boolean referencesTemplateParameter() {
return fCondition.referencesTemplateParameter() ||
(fPositive != null && fPositive.referencesTemplateParameter()) ||
fNegative.referencesTemplateParameter();
}
} }

View file

@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
@ -18,6 +19,8 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTNode; 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.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
@ -145,4 +148,24 @@ public class EvalFixed extends CPPEvaluation {
value= readValue ? buffer.unmarshalValue() : Value.UNKNOWN; value= readValue ? buffer.unmarshalValue() : Value.UNKNOWN;
return new EvalFixed(type, cat, value); return new EvalFixed(type, cat, value);
} }
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within, int maxdepth, IASTNode point) {
IType type = CPPTemplates.instantiateType(fType, tpMap, packOffset, within, point);
IValue value = CPPTemplates.instantiateValue(fValue, tpMap, packOffset, within, maxdepth, point);
if (type == fType && value == fValue)
return this;
return new EvalFixed(type, fValueCategory, value);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
return CPPTemplates.determinePackSize(fValue, tpMap);
}
@Override
public boolean referencesTemplateParameter() {
return false;
}
} }

View file

@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
@ -17,6 +18,8 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUti
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
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 java.util.Arrays;
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.IASTNode;
import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IFunctionType;
@ -24,8 +27,10 @@ import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
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.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.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
@ -45,6 +50,10 @@ public class EvalFunctionCall extends CPPEvaluation {
fArguments= args; fArguments= args;
} }
/**
* Returns arguments of the function call. The first argument is the function name, the rest
* are arguments passed to the function.
*/
public ICPPEvaluation[] getArguments() { public ICPPEvaluation[] getArguments() {
return fArguments; return fArguments;
} }
@ -132,7 +141,8 @@ public class EvalFunctionCall extends CPPEvaluation {
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue(IASTNode point) {
return Value.create(this, point); // TODO(sprigogin): Simulate execution of a function call if the value is not dependent.
return Value.create(this);
} }
@Override @Override
@ -167,6 +177,48 @@ public class EvalFunctionCall extends CPPEvaluation {
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation(); args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation();
} }
return new EvalComma(args); return new EvalFunctionCall(args);
}
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within, int maxdepth, IASTNode point) {
ICPPEvaluation[] args = fArguments;
for (int i = 0; i < fArguments.length; i++) {
ICPPEvaluation arg = fArguments[i].instantiate(tpMap, packOffset, within, maxdepth, point);
if (arg != fArguments[i]) {
if (args == fArguments) {
args = new ICPPEvaluation[fArguments.length];
System.arraycopy(fArguments, 0, args, 0, fArguments.length);
}
args[i] = arg;
}
}
if (args == fArguments)
return this;
if (args[0] instanceof EvalFunctionSet && getOverload(point) == null) {
// Resolve the function using the parameters of the function call.
args[0] = ((EvalFunctionSet) args[0]).resolveFunction(Arrays.copyOfRange(args, 1, args.length), point);
}
return new EvalFunctionCall(args);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
int r = CPPTemplates.PACK_SIZE_NOT_FOUND;
for (ICPPEvaluation arg : fArguments) {
r = CPPTemplates.combinePackSize(r, arg.determinePackSize(tpMap));
}
return r;
}
@Override
public boolean referencesTemplateParameter() {
for (ICPPEvaluation arg : fArguments) {
if (arg.referencesTemplateParameter())
return true;
}
return false;
} }
} }

View file

@ -7,20 +7,29 @@
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import java.util.Arrays;
import org.eclipse.cdt.core.CCorePlugin;
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.IASTNode;
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.ICPPClassSpecialization;
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;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.Value;
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.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
@ -106,7 +115,10 @@ public class EvalFunctionSet extends CPPEvaluation {
buffer.marshalBinding(binding); buffer.marshalBinding(binding);
} }
if (args != null) { if (args != null) {
// mstodo marshall arguments buffer.putShort((short) args.length);
for (ICPPTemplateArgument arg : args) {
buffer.marshalTemplateArgument(arg);
}
} }
} }
@ -119,8 +131,80 @@ public class EvalFunctionSet extends CPPEvaluation {
} }
ICPPTemplateArgument[] args= null; ICPPTemplateArgument[] args= null;
if ((firstByte & ITypeMarshalBuffer.FLAG2) != 0) { if ((firstByte & ITypeMarshalBuffer.FLAG2) != 0) {
// mstodo marshall arguments int len= buffer.getShort();
args = new ICPPTemplateArgument[len];
for (int i = 0; i < args.length; i++) {
args[i]= buffer.unmarshalTemplateArgument();
}
} }
return new EvalFunctionSet(new CPPFunctionSet(bindings, args, null), addressOf); return new EvalFunctionSet(new CPPFunctionSet(bindings, args, null), addressOf);
} }
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within, int maxdepth, IASTNode point) {
ICPPTemplateArgument[] originalArguments = fFunctionSet.getTemplateArguments();
ICPPTemplateArgument[] arguments = originalArguments;
arguments = instantiateArguments(originalArguments, tpMap, packOffset, within, point);
IBinding originalOwner = fFunctionSet.getOwner();
IBinding owner = originalOwner;
if (originalOwner instanceof ICPPUnknownBinding) {
owner = resolveUnknown((ICPPUnknownBinding) owner, tpMap, packOffset, within, point);
} else if (owner instanceof IType) {
IType type = CPPTemplates.instantiateType((IType) owner, tpMap, packOffset, within, point);
if (type instanceof IBinding)
owner = (IBinding) type;
}
ICPPFunction[] originalFunctions = fFunctionSet.getBindings();
ICPPFunction[] functions = originalFunctions;
if (owner instanceof ICPPClassSpecialization && owner != originalOwner) {
functions = new ICPPFunction[originalFunctions.length];
for (int i = 0; i < originalFunctions.length; i++) {
functions[i] = (ICPPFunction) CPPTemplates.createSpecialization((ICPPClassSpecialization) owner,
originalFunctions[i], point);
}
}
if (Arrays.equals(arguments, originalArguments) && functions == originalFunctions)
return this;
return new EvalFunctionSet(new CPPFunctionSet(functions, arguments, null), fAddressOf);
}
/**
* Attempts to resolve the function using the parameters of a function call.
*
* @param args the arguments of a function call
* @param point the name lookup context
* @return the resolved or the original evaluation depending on whether function resolution
* succeeded or not
*/
public ICPPEvaluation resolveFunction(ICPPEvaluation[] args, IASTNode point) {
ICPPFunction[] functions = fFunctionSet.getBindings();
LookupData data = new LookupData(functions[0].getNameCharArray(),
fFunctionSet.getTemplateArguments(), point);
data.setFunctionArguments(false, args);
try {
IBinding binding = CPPSemantics.resolveFunction(data, functions, true);
if (binding instanceof ICPPFunction && !(binding instanceof ICPPUnknownBinding))
return new EvalBinding(binding, null);
} catch (DOMException e) {
CCorePlugin.log(e);
}
return this;
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
int r = CPPTemplates.PACK_SIZE_NOT_FOUND;
ICPPTemplateArgument[] templateArguments = fFunctionSet.getTemplateArguments();
for (ICPPTemplateArgument arg : templateArguments) {
r = CPPTemplates.combinePackSize(r, CPPTemplates.determinePackSize(arg, tpMap));
}
return r;
}
@Override
public boolean referencesTemplateParameter() {
return false;
}
} }

View file

@ -7,12 +7,14 @@
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
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.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
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.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
@ -30,12 +32,17 @@ import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
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.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
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.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.Value;
@ -51,7 +58,8 @@ public class EvalID extends CPPEvaluation {
private final boolean fQualified; private final boolean fQualified;
private final ICPPTemplateArgument[] fTemplateArgs; private final ICPPTemplateArgument[] fTemplateArgs;
public EvalID(ICPPEvaluation fieldOwner, IBinding nameOwner, char[] simpleID, boolean addressOf, boolean qualified, ICPPTemplateArgument[] templateArgs) { public EvalID(ICPPEvaluation fieldOwner, IBinding nameOwner, char[] simpleID, boolean addressOf,
boolean qualified, ICPPTemplateArgument[] templateArgs) {
fFieldOwner= fieldOwner; fFieldOwner= fieldOwner;
fName= simpleID; fName= simpleID;
fNameOwner= nameOwner; fNameOwner= nameOwner;
@ -60,6 +68,9 @@ public class EvalID extends CPPEvaluation {
fTemplateArgs= templateArgs; fTemplateArgs= templateArgs;
} }
/**
* Returns the field owner expression, or {@code null}.
*/
public ICPPEvaluation getFieldOwner() { public ICPPEvaluation getFieldOwner() {
return fFieldOwner; return fFieldOwner;
} }
@ -80,6 +91,9 @@ public class EvalID extends CPPEvaluation {
return fQualified; return fQualified;
} }
/**
* Returns the template arguments, or {@code null} if there are no template arguments.
*/
public ICPPTemplateArgument[] getTemplateArgs() { public ICPPTemplateArgument[] getTemplateArgs() {
return fTemplateArgs; return fTemplateArgs;
} }
@ -111,7 +125,17 @@ public class EvalID extends CPPEvaluation {
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue(IASTNode point) {
return Value.create(this, point); // Name lookup is not needed here because it was already done in the "instantiate" method.
// IBinding nameOwner = fNameOwner;
// if (nameOwner == null && fFieldOwner != null)
// nameOwner = (IBinding) fFieldOwner.getTypeOrFunctionSet(point);
//
// if (nameOwner instanceof ICPPClassType) {
// ICPPEvaluation eval = resolveName((ICPPClassType) nameOwner, fTemplateArgs, point);
// if (eval != null)
// return eval.getValue(point);
// }
return Value.create(this);
} }
@Override @Override
@ -134,7 +158,10 @@ public class EvalID extends CPPEvaluation {
buffer.putCharArray(fName); buffer.putCharArray(fName);
buffer.marshalBinding(fNameOwner); buffer.marshalBinding(fNameOwner);
if (fTemplateArgs != null) { if (fTemplateArgs != null) {
// mstodo marshall arguments buffer.putShort((short) fTemplateArgs.length);
for (ICPPTemplateArgument arg : fTemplateArgs) {
buffer.marshalTemplateArgument(arg);
}
} }
} }
@ -146,7 +173,11 @@ public class EvalID extends CPPEvaluation {
IBinding nameOwner= buffer.unmarshalBinding(); IBinding nameOwner= buffer.unmarshalBinding();
ICPPTemplateArgument[] args= null; ICPPTemplateArgument[] args= null;
if ((firstByte & ITypeMarshalBuffer.FLAG3) != 0) { if ((firstByte & ITypeMarshalBuffer.FLAG3) != 0) {
// mstodo marshall arguments int len= buffer.getShort();
args = new ICPPTemplateArgument[len];
for (int i = 0; i < args.length; i++) {
args[i]= buffer.unmarshalTemplateArgument();
}
} }
return new EvalID(fieldOwner, nameOwner, name, addressOf, qualified, args); return new EvalID(fieldOwner, nameOwner, name, addressOf, qualified, args);
} }
@ -242,4 +273,79 @@ public class EvalID extends CPPEvaluation {
} }
return false; return false;
} }
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within, int maxdepth, IASTNode point) {
ICPPTemplateArgument[] templateArgs = fTemplateArgs;
if (templateArgs != null) {
templateArgs = instantiateArguments(templateArgs, tpMap, packOffset, within, point);
}
ICPPEvaluation fieldOwner = fFieldOwner;
if (fieldOwner != null) {
fieldOwner = fieldOwner.instantiate(tpMap, packOffset, within, maxdepth, point);
}
IBinding nameOwner = fNameOwner;
if (nameOwner instanceof ICPPClassTemplate) {
nameOwner = resolveUnknown(CPPTemplates.createDeferredInstance((ICPPClassTemplate) nameOwner),
tpMap, packOffset, within, point);
} else if (nameOwner instanceof IType) {
IType type = CPPTemplates.instantiateType((IType) nameOwner, tpMap, packOffset, within, point);
if (type instanceof IBinding)
nameOwner = (IBinding) type;
}
if (fieldOwner instanceof IProblemBinding || nameOwner instanceof IProblemBinding)
return this;
if (templateArgs == fTemplateArgs && fieldOwner == fFieldOwner && nameOwner == fNameOwner)
return this;
ICPPEvaluation eval = resolveName((ICPPClassType) nameOwner, templateArgs, point);
if (eval != null)
return eval;
return new EvalID(fieldOwner, nameOwner, fName, fAddressOf, fQualified, templateArgs);
}
private ICPPEvaluation resolveName(ICPPClassType nameOwner, ICPPTemplateArgument[] templateArgs,
IASTNode point) {
LookupData data = new LookupData(fName, templateArgs, point);
data.qualified = fQualified;
try {
CPPSemantics.lookup(data, nameOwner.getCompositeScope());
} catch (DOMException e) {
}
IBinding[] bindings = data.getFoundBindings();
if (bindings.length > 1 && bindings[0] instanceof ICPPFunction) {
ICPPFunction[] functions = new ICPPFunction[bindings.length];
System.arraycopy(bindings, 0, functions, 0, bindings.length);
return new EvalFunctionSet(new CPPFunctionSet(functions, templateArgs, null), fAddressOf);
}
IBinding binding = bindings.length == 1 ? bindings[0] : null;
if (binding instanceof IEnumerator) {
return new EvalBinding(binding, null);
} else if (binding instanceof ICPPMember) {
return new EvalMemberAccess(nameOwner, ValueCategory.PRVALUE, binding, false);
} else if (binding instanceof CPPFunctionSet) {
return new EvalFunctionSet((CPPFunctionSet) binding, fAddressOf);
}
return null;
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
int r = fFieldOwner.determinePackSize(tpMap);
for (ICPPTemplateArgument arg : fTemplateArgs) {
r = CPPTemplates.combinePackSize(r, CPPTemplates.determinePackSize(arg, tpMap));
}
return r;
}
@Override
public boolean referencesTemplateParameter() {
return fFieldOwner.referencesTemplateParameter();
}
} }

View file

@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
@ -16,6 +17,8 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTNode; 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.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.Value;
@ -71,7 +74,9 @@ public class EvalInitList extends CPPEvaluation {
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue(IASTNode point) {
return Value.create(this, point); if (isValueDependent())
return Value.create(this);
return Value.UNKNOWN; // TODO(sprigogin): Is this correct?
} }
@Override @Override
@ -94,6 +99,43 @@ public class EvalInitList extends CPPEvaluation {
for (int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation(); args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation();
} }
return new EvalComma(args); return new EvalInitList(args);
}
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within, int maxdepth, IASTNode point) {
ICPPEvaluation[] clauses = fClauses;
for (int i = 0; i < fClauses.length; i++) {
ICPPEvaluation clause = fClauses[i].instantiate(tpMap, packOffset, within, maxdepth, point);
if (clause != fClauses[i]) {
if (clauses == fClauses) {
clauses = new ICPPEvaluation[fClauses.length];
System.arraycopy(fClauses, 0, clauses, 0, fClauses.length);
}
clauses[i] = clause;
}
}
if (clauses == fClauses)
return this;
return new EvalInitList(clauses);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
int r = CPPTemplates.PACK_SIZE_NOT_FOUND;
for (ICPPEvaluation arg : fClauses) {
r = CPPTemplates.combinePackSize(r, arg.determinePackSize(tpMap));
}
return r;
}
@Override
public boolean referencesTemplateParameter() {
for (ICPPEvaluation clause : fClauses) {
if (clause.referencesTemplateParameter())
return true;
}
return false;
} }
} }

View file

@ -7,14 +7,21 @@
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; 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 static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.*; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*; 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.prvalueTypeWithResolvedTypedefs;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromFunctionCall;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.ALLCVQ;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
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.getUltimateTypeUptoPointers;
import java.util.Collection; import java.util.Collection;
@ -29,10 +36,12 @@ import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
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.IVariable; import org.eclipse.cdt.core.dom.ast.IVariable;
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.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
@ -245,7 +254,16 @@ public class EvalMemberAccess extends CPPEvaluation {
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue(IASTNode point) {
return Value.create(this, point); if (fMember instanceof IEnumerator) {
return ((IEnumerator) fMember).getValue();
}
if (fMember instanceof IVariable) {
return ((IVariable) fMember).getInitialValue();
}
if (fMember instanceof IFunction) {
return Value.UNKNOWN;
}
return Value.create(this);
} }
@Override @Override
@ -301,4 +319,28 @@ public class EvalMemberAccess extends CPPEvaluation {
IBinding member= buffer.unmarshalBinding(); IBinding member= buffer.unmarshalBinding();
return new EvalMemberAccess(ownerType, ownerValueCat, member, isDeref); return new EvalMemberAccess(ownerType, ownerValueCat, member, isDeref);
} }
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within, int maxdepth, IASTNode point) {
IType ownerType = CPPTemplates.instantiateType(fOwnerType, tpMap, packOffset, within, point);
if (ownerType == fOwnerType)
return this;
IBinding member = fMember;
if (ownerType instanceof ICPPClassSpecialization) {
member = CPPTemplates.createSpecialization((ICPPClassSpecialization) ownerType, fMember, point);
}
return new EvalMemberAccess(ownerType, fOwnerValueCategory, member, fIsPointerDeref);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
return CPPTemplates.determinePackSize(fOwnerType, tpMap);
}
@Override
public boolean referencesTemplateParameter() {
return false;
}
} }

View file

@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
@ -17,6 +18,9 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTNode; 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.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.Value;
@ -70,7 +74,20 @@ public class EvalTypeId extends CPPEvaluation {
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue(IASTNode point) {
return Value.create(this, point); if (isValueDependent())
return Value.create(this);
if (fArguments == null)
return Value.UNKNOWN;
if (isTypeDependent())
return Value.create(this);
if (fOutputType instanceof ICPPClassType) {
// TODO(sprigogin): Simulate execution of a ctor call.
return Value.UNKNOWN;
}
if (fArguments.length == 1)
return fArguments[0].getValue(point);
return Value.UNKNOWN;
} }
@Override @Override
@ -125,4 +142,42 @@ public class EvalTypeId extends CPPEvaluation {
} }
return new EvalTypeId(type, args); return new EvalTypeId(type, args);
} }
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within, int maxdepth, IASTNode point) {
ICPPEvaluation[] args = fArguments;
for (int i = 0; i < fArguments.length; i++) {
ICPPEvaluation arg = fArguments[i].instantiate(tpMap, packOffset, within, maxdepth, point);
if (arg != fArguments[i]) {
if (args == fArguments) {
args = new ICPPEvaluation[fArguments.length];
System.arraycopy(fArguments, 0, args, 0, fArguments.length);
}
args[i] = arg;
}
}
IType type = CPPTemplates.instantiateType(fInputType, tpMap, packOffset, within, point);
if (args == fArguments && type == fInputType)
return this;
return new EvalTypeId(type, args);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
int r = CPPTemplates.determinePackSize(fInputType, tpMap);
for (ICPPEvaluation arg : fArguments) {
r = CPPTemplates.combinePackSize(r, arg.determinePackSize(tpMap));
}
return r;
}
@Override
public boolean referencesTemplateParameter() {
for (ICPPEvaluation arg : fArguments) {
if (arg.referencesTemplateParameter())
return true;
}
return false;
}
} }

View file

@ -7,28 +7,48 @@
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.*; import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_alignOf;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.*; import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_amper;
import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_minus;
import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_not;
import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_plus;
import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_postFixDecr;
import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_postFixIncr;
import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_prefixDecr;
import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_prefixIncr;
import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_sizeof;
import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_sizeofParameterPack;
import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_star;
import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_throw;
import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_tilde;
import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.op_typeid;
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.prvalueTypeWithResolvedTypedefs;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromFunctionCall;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
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.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
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.ICPPClassSpecialization;
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.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
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.SizeofCalculator.SizeAndAlignment;
import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArithmeticConversion; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArithmeticConversion;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
@ -90,7 +110,7 @@ public class EvalUnary extends CPPEvaluation {
@Override @Override
public boolean isValueDependent() { public boolean isValueDependent() {
switch(fOperator) { switch (fOperator) {
case op_alignOf: case op_alignOf:
case op_sizeof: case op_sizeof:
case op_sizeofParameterPack: case op_sizeofParameterPack:
@ -124,7 +144,7 @@ public class EvalUnary extends CPPEvaluation {
return null; return null;
ICPPEvaluation[] args; ICPPEvaluation[] args;
if (fOperator == IASTUnaryExpression.op_postFixDecr || fOperator == IASTUnaryExpression.op_postFixIncr) { if (fOperator == op_postFixDecr || fOperator == op_postFixIncr) {
args = new ICPPEvaluation[] { fArgument, ZERO_EVAL }; args = new ICPPEvaluation[] { fArgument, ZERO_EVAL };
} else { } else {
args = new ICPPEvaluation[] { fArgument }; args = new ICPPEvaluation[] { fArgument };
@ -185,7 +205,37 @@ public class EvalUnary extends CPPEvaluation {
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue(IASTNode point) {
return Value.create(this, point); if (isValueDependent())
return Value.create(this);
if (getOverload(point) != null) {
// TODO(sprigogin): Simulate execution of a function call.
return Value.create(this);
}
switch (fOperator) {
case op_sizeof: {
SizeAndAlignment info = getSizeAndAlignment(fArgument.getTypeOrFunctionSet(point), point);
return info == null ? Value.UNKNOWN : Value.create(info.size);
}
case op_alignOf: {
SizeAndAlignment info = getSizeAndAlignment(fArgument.getTypeOrFunctionSet(point), point);
return info == null ? Value.UNKNOWN : Value.create(info.alignment);
}
case op_sizeofParameterPack:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_typeid:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_throw:
return Value.UNKNOWN; // TODO(sprigogin): Implement
}
IValue val = fArgument.getValue(point);
Long num = val.numericalValue();
if (num != null) {
return Value.evaluateUnaryExpression(fOperator, num);
}
return Value.create(this);
} }
@Override @Override
@ -217,4 +267,23 @@ public class EvalUnary extends CPPEvaluation {
ICPPEvaluation arg= (ICPPEvaluation) buffer.unmarshalEvaluation(); ICPPEvaluation arg= (ICPPEvaluation) buffer.unmarshalEvaluation();
return new EvalUnary(op, arg); return new EvalUnary(op, arg);
} }
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within, int maxdepth, IASTNode point) {
ICPPEvaluation argument = fArgument.instantiate(tpMap, packOffset, within, maxdepth, point);
if (argument == fArgument)
return this;
return new EvalUnary(fOperator, argument);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
return fArgument.determinePackSize(tpMap);
}
@Override
public boolean referencesTemplateParameter() {
return fArgument.referencesTemplateParameter();
}
} }

View file

@ -7,22 +7,46 @@
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.*; import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_alignof;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_has_nothrow_constructor;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_has_nothrow_copy;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_has_trivial_assign;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_has_trivial_constructor;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_has_trivial_copy;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_has_trivial_destructor;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_has_virtual_destructor;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_abstract;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_class;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_empty;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_enum;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_pod;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_polymorphic;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_is_union;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_sizeof;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_typeid;
import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.op_typeof;
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.IASTNode;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
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.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator.SizeAndAlignment;
import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.Value;
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.ICPPEvaluation;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
public class EvalUnaryTypeID extends CPPEvaluation { public class EvalUnaryTypeID extends CPPEvaluation {
@ -127,7 +151,52 @@ public class EvalUnaryTypeID extends CPPEvaluation {
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue(IASTNode point) {
return Value.create(this, point); if (isValueDependent())
return Value.create(this);
switch (fOperator) {
case op_sizeof: {
SizeAndAlignment info = getSizeAndAlignment(fOrigType, point);
return info == null ? Value.UNKNOWN : Value.create(info.size);
}
case op_alignof: {
SizeAndAlignment info = getSizeAndAlignment(fOrigType, point);
return info == null ? Value.UNKNOWN : Value.create(info.alignment);
}
case op_typeid:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_has_nothrow_copy:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_has_nothrow_constructor:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_has_trivial_assign:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_has_trivial_constructor:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_has_trivial_copy:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_has_trivial_destructor:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_has_virtual_destructor:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_is_abstract:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_is_class:
return Value.create(fOrigType instanceof ICompositeType && ((ICompositeType) fOrigType).getKey() != ICompositeType.k_union);
case op_is_empty:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_is_enum:
return Value.create(fOrigType instanceof IEnumeration);
case op_is_pod:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_is_polymorphic:
return Value.UNKNOWN; // TODO(sprigogin): Implement
case op_is_union:
return Value.create(fOrigType instanceof ICompositeType && ((ICompositeType) fOrigType).getKey() == ICompositeType.k_union);
case op_typeof:
return Value.UNKNOWN; // TODO(sprigogin): Implement
}
return Value.create(this);
} }
@Override @Override
@ -139,7 +208,7 @@ public class EvalUnaryTypeID extends CPPEvaluation {
public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException { public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException {
buffer.putByte(ITypeMarshalBuffer.EVAL_UNARY_TYPE_ID); buffer.putByte(ITypeMarshalBuffer.EVAL_UNARY_TYPE_ID);
buffer.putByte((byte) fOperator); buffer.putByte((byte) fOperator);
buffer.marshalType(fType); buffer.marshalType(fOrigType);
} }
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException { public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
@ -147,4 +216,23 @@ public class EvalUnaryTypeID extends CPPEvaluation {
IType arg= buffer.unmarshalType(); IType arg= buffer.unmarshalType();
return new EvalUnaryTypeID(op, arg); return new EvalUnaryTypeID(op, arg);
} }
@Override
public ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within, int maxdepth, IASTNode point) {
IType type = CPPTemplates.instantiateType(fOrigType, tpMap, packOffset, within, point);
if (type == fOrigType)
return this;
return new EvalUnaryTypeID(fOperator, type);
}
@Override
public int determinePackSize(ICPPTemplateParameterMap tpMap) {
return CPPTemplates.determinePackSize(fOrigType, tpMap);
}
@Override
public boolean referencesTemplateParameter() {
return false;
}
} }

View file

@ -40,18 +40,21 @@ class FunctionCost {
private final ICPPFunction fFunction; private final ICPPFunction fFunction;
private final Cost[] fCosts; private final Cost[] fCosts;
private final ValueCategory[] fValueCategories; private final ValueCategory[] fValueCategories;
private final IASTNode fPoint;
private boolean fIsDirectCopyCtor; private boolean fIsDirectCopyCtor;
public FunctionCost(ICPPFunction fn, int paramCount) { public FunctionCost(ICPPFunction fn, int paramCount, IASTNode point) {
fFunction= fn; fFunction= fn;
fCosts= new Cost[paramCount]; fCosts= new Cost[paramCount];
fValueCategories= new ValueCategory[paramCount]; fValueCategories= new ValueCategory[paramCount];
fPoint = point;
} }
public FunctionCost(ICPPFunction fn, Cost cost) { public FunctionCost(ICPPFunction fn, Cost cost, IASTNode point) {
fFunction= fn; fFunction= fn;
fCosts= new Cost[] {cost}; fCosts= new Cost[] {cost};
fValueCategories= null; // no udc will be performed fValueCategories= null; // no udc will be performed
fPoint = point;
} }
public int getLength() { public int getLength() {
@ -127,9 +130,8 @@ class FunctionCost {
/** /**
* Compares this function call cost to another one. * Compares this function call cost to another one.
* @param point
*/ */
public int compareTo(IASTTranslationUnit tu, FunctionCost other, IASTNode point) throws DOMException { public int compareTo(IASTTranslationUnit tu, FunctionCost other) throws DOMException {
if (other == null) if (other == null)
return -1; return -1;
@ -169,7 +171,7 @@ class FunctionCost {
haveBetter = true; haveBetter = true;
} else if (isTemplate && otherIsTemplate) { } else if (isTemplate && otherIsTemplate) {
TypeSelection ts= SemanticUtil.isConversionOperator(f1) ? RETURN_TYPE : PARAMETERS; TypeSelection ts= SemanticUtil.isConversionOperator(f1) ? RETURN_TYPE : PARAMETERS;
int order = CPPTemplates.orderFunctionTemplates(otherAsTemplate, asTemplate, ts, point); int order = CPPTemplates.orderFunctionTemplates(otherAsTemplate, asTemplate, ts, fPoint);
if (order < 0) { if (order < 0) {
haveBetter= true; haveBetter= true;
} else if (order > 0) { } else if (order > 0) {
@ -215,10 +217,10 @@ class FunctionCost {
if (!parameterTypesMatch(ft1, ft2)) if (!parameterTypesMatch(ft1, ft2))
return 0; return 0;
int diff= SemanticUtil.calculateInheritanceDepth(o2, o1); int diff= SemanticUtil.calculateInheritanceDepth(o2, o1, fPoint);
if (diff >= 0) if (diff >= 0)
return diff; return diff;
return -SemanticUtil.calculateInheritanceDepth(o1, o2); return -SemanticUtil.calculateInheritanceDepth(o1, o2, fPoint);
} }
private boolean parameterTypesMatch(final ICPPFunctionType ft1, final ICPPFunctionType ft2) { private boolean parameterTypesMatch(final ICPPFunctionType ft1, final ICPPFunctionType ft2) {

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2010 IBM Corporation and others. * Copyright (c) 2004, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -62,7 +62,8 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
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.CPPTemplateArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeArgument;
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.OverloadableOperator; import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
@ -100,12 +101,12 @@ public class SemanticUtil {
* @param clazz * @param clazz
* @return an array of conversion operators. * @return an array of conversion operators.
*/ */
public static final ICPPMethod[] getDeclaredConversionOperators(ICPPClassType clazz) throws DOMException { public static final ICPPMethod[] getDeclaredConversionOperators(ICPPClassType clazz, IASTNode point) throws DOMException {
ICPPMethod[] methods= ICPPMethod.EMPTY_CPPMETHOD_ARRAY; ICPPMethod[] methods= ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
if (clazz instanceof ICPPDeferredClassInstance) { if (clazz instanceof ICPPDeferredClassInstance) {
clazz= (ICPPClassType) ((ICPPDeferredClassInstance) clazz).getTemplateDefinition(); clazz= (ICPPClassType) ((ICPPDeferredClassInstance) clazz).getTemplateDefinition();
} }
ICPPMethod[] decs= clazz.getDeclaredMethods(); ICPPMethod[] decs= ClassTypeHelper.getDeclaredMethods(clazz, point);
if (decs != null) { if (decs != null) {
for (ICPPMethod method : decs) { for (ICPPMethod method : decs) {
if (isConversionOperator(method)) { if (isConversionOperator(method)) {
@ -123,11 +124,11 @@ public class SemanticUtil {
* @param clazz * @param clazz
* @return an array of conversion operators. * @return an array of conversion operators.
*/ */
public static ICPPMethod[] getConversionOperators(ICPPClassType clazz) throws DOMException { public static ICPPMethod[] getConversionOperators(ICPPClassType clazz, IASTNode point) throws DOMException {
ICPPMethod[] methods= ICPPMethod.EMPTY_CPPMETHOD_ARRAY; ICPPMethod[] methods= ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
ObjectSet<ICPPClassType> ancestry= inheritanceClosure(clazz); ObjectSet<ICPPClassType> ancestry= inheritanceClosure(clazz, point);
for (int i = 0; i < ancestry.size(); i++) { for (int i = 0; i < ancestry.size(); i++) {
methods= ArrayUtil.addAll(methods, getDeclaredConversionOperators(ancestry.keyAt(i))); methods= ArrayUtil.addAll(methods, getDeclaredConversionOperators(ancestry.keyAt(i), point));
} }
return methods; return methods;
} }
@ -137,7 +138,7 @@ public class SemanticUtil {
* @return the root and all its ancestor classes * @return the root and all its ancestor classes
* @throws DOMException * @throws DOMException
*/ */
public static ObjectSet<ICPPClassType> inheritanceClosure(ICPPClassType root) throws DOMException { public static ObjectSet<ICPPClassType> inheritanceClosure(ICPPClassType root, IASTNode point) throws DOMException {
ObjectSet<ICPPClassType> done= new ObjectSet<ICPPClassType>(2); ObjectSet<ICPPClassType> done= new ObjectSet<ICPPClassType>(2);
ObjectSet<ICPPClassType> current= new ObjectSet<ICPPClassType>(2); ObjectSet<ICPPClassType> current= new ObjectSet<ICPPClassType>(2);
current.put(root); current.put(root);
@ -148,8 +149,8 @@ public class SemanticUtil {
for (int i = 0; i < current.size(); i++) { for (int i = 0; i < current.size(); i++) {
ICPPClassType clazz= current.keyAt(i); ICPPClassType clazz= current.keyAt(i);
done.put(clazz); done.put(clazz);
for (ICPPBase base : clazz.getBases()) { for (ICPPBase base : ClassTypeHelper.getBases(clazz, point)) {
IBinding binding= base.getBaseClass(); IBinding binding= base.getBaseClass();
if (binding instanceof ICPPClassType && !(binding instanceof IProblemBinding)) { if (binding instanceof ICPPClassType && !(binding instanceof IProblemBinding)) {
ICPPClassType ct= (ICPPClassType) binding; ICPPClassType ct= (ICPPClassType) binding;
@ -165,7 +166,7 @@ public class SemanticUtil {
return done; return done;
} }
/** /**
* @param method * @param method
* @return true if the specified method is a conversion operator * @return true if the specified method is a conversion operator
@ -511,7 +512,7 @@ public class SemanticUtil {
final IType type= arg.getTypeValue(); final IType type= arg.getTypeValue();
final IType newType= getSimplifiedType(type); final IType newType= getSimplifiedType(type);
if (newType != type) { if (newType != type) {
return new CPPTemplateArgument(newType); return new CPPTemplateTypeArgument(newType);
} }
} }
return arg; return arg;
@ -622,11 +623,11 @@ public class SemanticUtil {
* @return the number of edges in the inheritance graph, or -1 if the specified classes have * @return the number of edges in the inheritance graph, or -1 if the specified classes have
* no inheritance relation * no inheritance relation
*/ */
public static final int calculateInheritanceDepth(IType type, IType baseClass) { public static final int calculateInheritanceDepth(IType type, IType baseClass, IASTNode point) {
return calculateInheritanceDepth(CPPSemantics.MAX_INHERITANCE_DEPTH, new HashSet<Object>(), type, baseClass); return calculateInheritanceDepth(CPPSemantics.MAX_INHERITANCE_DEPTH, new HashSet<Object>(), type, baseClass, point);
} }
private static final int calculateInheritanceDepth(int maxdepth, Set<Object> hashSet, IType type, IType baseClass) { private static final int calculateInheritanceDepth(int maxdepth, Set<Object> hashSet, IType type, IType baseClass, IASTNode point) {
if (type == baseClass || type.isSameType(baseClass)) { if (type == baseClass || type.isSameType(baseClass)) {
return 0; return 0;
} }
@ -637,7 +638,7 @@ public class SemanticUtil {
clazz= (ICPPClassType) ((ICPPDeferredClassInstance) clazz).getSpecializedBinding(); clazz= (ICPPClassType) ((ICPPDeferredClassInstance) clazz).getSpecializedBinding();
} }
for (ICPPBase cppBase : clazz.getBases()) { for (ICPPBase cppBase : ClassTypeHelper.getBases(clazz, point)) {
IBinding base= cppBase.getBaseClass(); IBinding base= cppBase.getBaseClass();
if (base instanceof IType && hashSet.add(base)) { if (base instanceof IType && hashSet.add(base)) {
IType tbase= (IType) base; IType tbase= (IType) base;
@ -648,7 +649,7 @@ public class SemanticUtil {
} }
if (tbase instanceof ICPPClassType) { if (tbase instanceof ICPPClassType) {
int n= calculateInheritanceDepth(maxdepth - 1, hashSet, tbase, baseClass); int n= calculateInheritanceDepth(maxdepth - 1, hashSet, tbase, baseClass, point);
if (n > 0) if (n > 0)
return n + 1; return n + 1;
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009, 2010 Wind River Systems, Inc. and others. * Copyright (c) 2009, 2012 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
@ -60,8 +61,10 @@ 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.CPPReferenceType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.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;
@ -70,9 +73,9 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
*/ */
public class TemplateArgumentDeduction { public class TemplateArgumentDeduction {
/** /**
* Deduce arguments for a template function from the template id + the template function parameters. * Deduce arguments for a template function from the template id and the template function
* parameters.
* 14.8.2.1 * 14.8.2.1
* @param point
*/ */
static ICPPTemplateArgument[] deduceForFunctionCall(ICPPFunctionTemplate template, static ICPPTemplateArgument[] deduceForFunctionCall(ICPPFunctionTemplate template,
ICPPTemplateArgument[] tmplArgs, List<IType> fnArgs, List<ValueCategory> argIsLValue, ICPPTemplateArgument[] tmplArgs, List<IType> fnArgs, List<ValueCategory> argIsLValue,
@ -235,7 +238,7 @@ public class TemplateArgumentDeduction {
ICPPTemplateInstance pInst = (ICPPTemplateInstance) pcheck; ICPPTemplateInstance pInst = (ICPPTemplateInstance) pcheck;
ICPPClassTemplate pTemplate= getPrimaryTemplate(pInst); ICPPClassTemplate pTemplate= getPrimaryTemplate(pInst);
if (pTemplate != null) { if (pTemplate != null) {
ICPPClassType aInst= findBaseInstance((ICPPClassType) argcheck, pTemplate); ICPPClassType aInst= findBaseInstance((ICPPClassType) argcheck, pTemplate, point);
if (aInst != null && aInst != argcheck) { if (aInst != null && aInst != argcheck) {
par= pcheck; par= pcheck;
arg= aInst; arg= aInst;
@ -290,7 +293,6 @@ public class TemplateArgumentDeduction {
/** /**
* Deduce arguments for a user defined conversion template * Deduce arguments for a user defined conversion template
* 14.8.2.3 * 14.8.2.3
* @param point
*/ */
static ICPPTemplateArgument[] deduceForConversion(ICPPFunctionTemplate template, static ICPPTemplateArgument[] deduceForConversion(ICPPFunctionTemplate template,
IType conversionType, CPPTemplateParameterMap map, IASTNode point) throws DOMException { IType conversionType, CPPTemplateParameterMap map, IASTNode point) throws DOMException {
@ -325,7 +327,6 @@ public class TemplateArgumentDeduction {
/** /**
* Deduce arguments for a function declaration * Deduce arguments for a function declaration
* 14.8.2.6 * 14.8.2.6
* @param point
*/ */
static ICPPTemplateArgument[] deduceForDeclaration(ICPPFunctionTemplate template, static ICPPTemplateArgument[] deduceForDeclaration(ICPPFunctionTemplate template,
ICPPTemplateArgument[] args, ICPPFunctionType ftype, CPPTemplateParameterMap map, IASTNode point) throws DOMException { ICPPTemplateArgument[] args, ICPPFunctionType ftype, CPPTemplateParameterMap map, IASTNode point) throws DOMException {
@ -360,7 +361,6 @@ public class TemplateArgumentDeduction {
/** /**
* Deduces the mapping for the template parameters from the function parameters, * Deduces the mapping for the template parameters from the function parameters,
* returns <code>false</code> if there is no mapping. * returns <code>false</code> if there is no mapping.
* @param point
*/ */
static int deduceForPartialOrdering(ICPPTemplateParameter[] tmplPars, IType[] fnPars, IType[] fnArgs, IASTNode point) { static int deduceForPartialOrdering(ICPPTemplateParameter[] tmplPars, IType[] fnPars, IType[] fnArgs, IASTNode point) {
try { try {
@ -423,7 +423,6 @@ public class TemplateArgumentDeduction {
/** /**
* Adds the explicit arguments to the map. * Adds the explicit arguments to the map.
* @param point
*/ */
private static boolean addExplicitArguments(final ICPPTemplateParameter[] tmplParams, private static boolean addExplicitArguments(final ICPPTemplateParameter[] tmplParams,
ICPPTemplateArgument[] tmplArgs, CPPTemplateParameterMap map, IASTNode point) { ICPPTemplateArgument[] tmplArgs, CPPTemplateParameterMap map, IASTNode point) {
@ -481,13 +480,14 @@ public class TemplateArgumentDeduction {
} }
/** /**
* 14.8.2.1.3 If P is a class and has the form template-id, then A can be a derived class of the deduced A. * 14.8.2.1.3 If P is a class and has the form template-id, then A can be a derived class of
* the deduced A.
*/ */
private static ICPPClassType findBaseInstance(ICPPClassType a, ICPPClassTemplate pTemplate) throws DOMException { private static ICPPClassType findBaseInstance(ICPPClassType a, ICPPClassTemplate pTemplate, IASTNode point) throws DOMException {
return findBaseInstance(a, pTemplate, CPPSemantics.MAX_INHERITANCE_DEPTH, new HashSet<Object>()); return findBaseInstance(a, pTemplate, CPPSemantics.MAX_INHERITANCE_DEPTH, new HashSet<Object>(), point);
} }
private static ICPPClassType findBaseInstance(ICPPClassType a, ICPPClassTemplate pTemplate, int maxdepth, HashSet<Object> handled) throws DOMException { private static ICPPClassType findBaseInstance(ICPPClassType a, ICPPClassTemplate pTemplate, int maxdepth, HashSet<Object> handled, IASTNode point) throws DOMException {
if (a instanceof ICPPTemplateInstance) { if (a instanceof ICPPTemplateInstance) {
final ICPPTemplateInstance inst = (ICPPTemplateInstance) a; final ICPPTemplateInstance inst = (ICPPTemplateInstance) a;
ICPPClassTemplate tmpl= getPrimaryTemplate(inst); ICPPClassTemplate tmpl= getPrimaryTemplate(inst);
@ -495,10 +495,10 @@ public class TemplateArgumentDeduction {
return a; return a;
} }
if (maxdepth-- > 0) { if (maxdepth-- > 0) {
for (ICPPBase cppBase : a.getBases()) { for (ICPPBase cppBase : ClassTypeHelper.getBases(a, point)) {
IBinding base= cppBase.getBaseClass(); IBinding base= cppBase.getBaseClass();
if (base instanceof ICPPClassType && handled.add(base)) { if (base instanceof ICPPClassType && handled.add(base)) {
final ICPPClassType inst= findBaseInstance((ICPPClassType) base, pTemplate, maxdepth, handled); final ICPPClassType inst= findBaseInstance((ICPPClassType) base, pTemplate, maxdepth, handled, point);
if (inst != null) if (inst != null)
return inst; return inst;
} }
@ -546,7 +546,6 @@ public class TemplateArgumentDeduction {
/** /**
* Deduces the template parameter mapping from pairs of template arguments. * Deduces the template parameter mapping from pairs of template arguments.
* @param point
*/ */
public static boolean fromTemplateArguments(final ICPPTemplateParameter[] pars, public static boolean fromTemplateArguments(final ICPPTemplateParameter[] pars,
final ICPPTemplateArgument[] p, final ICPPTemplateArgument[] a, CPPTemplateParameterMap map, final ICPPTemplateArgument[] p, final ICPPTemplateArgument[] a, CPPTemplateParameterMap map,
@ -639,7 +638,6 @@ public class TemplateArgumentDeduction {
/** /**
* Deduces the template parameter mapping from one pair of template arguments. * Deduces the template parameter mapping from one pair of template arguments.
* @param point
*/ */
private boolean fromTemplateArgument(ICPPTemplateArgument p, ICPPTemplateArgument a, IASTNode point) throws DOMException { private boolean fromTemplateArgument(ICPPTemplateArgument p, ICPPTemplateArgument a, IASTNode point) throws DOMException {
if (p.isNonTypeValue() != a.isNonTypeValue()) if (p.isNonTypeValue() != a.isNonTypeValue())
@ -723,7 +721,7 @@ public class TemplateArgumentDeduction {
if (parID >= 0) { if (parID >= 0) {
ICPPTemplateArgument old= fDeducedArgs.getArgument(parID, fPackOffset); ICPPTemplateArgument old= fDeducedArgs.getArgument(parID, fPackOffset);
if (old == null) { if (old == null) {
if (!deduce(parID, new CPPTemplateArgument(as, new CPPBasicType(ICPPBasicType.Kind.eInt, 0)))) { if (!deduce(parID, new CPPTemplateNonTypeArgument(as, new CPPBasicType(ICPPBasicType.Kind.eInt, 0)))) {
return false; return false;
} }
} else if (!as.equals(old.getNonTypeValue())) { } else if (!as.equals(old.getNonTypeValue())) {
@ -764,7 +762,7 @@ public class TemplateArgumentDeduction {
} }
if (a == null) if (a == null)
return false; return false;
return deduce(((ICPPTemplateParameter)p).getParameterID(), new CPPTemplateArgument(a)); return deduce(((ICPPTemplateParameter)p).getParameterID(), new CPPTemplateTypeArgument(a));
} else if (p instanceof ICPPTemplateInstance) { } else if (p instanceof ICPPTemplateInstance) {
if (!(a instanceof ICPPTemplateInstance)) if (!(a instanceof ICPPTemplateInstance))
return false; return false;
@ -792,7 +790,7 @@ public class TemplateArgumentDeduction {
if (current != null) { if (current != null) {
if (current.isNonTypeValue() || !current.getTypeValue().isSameType(aTemplate)) if (current.isNonTypeValue() || !current.getTypeValue().isSameType(aTemplate))
return false; return false;
} else if (!deduce(tparId, new CPPTemplateArgument(aTemplate))) { } else if (!deduce(tparId, new CPPTemplateTypeArgument(aTemplate))) {
return false; return false;
} }
} else if (!aTemplate.isSameType(pTemplate)) { } else if (!aTemplate.isSameType(pTemplate)) {

View file

@ -6,9 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.index; package org.eclipse.cdt.internal.core.index;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
@ -18,5 +17,4 @@ import org.eclipse.cdt.core.dom.ast.IType;
* @since 4.0 * @since 4.0
*/ */
public interface IIndexType extends IType { public interface IIndexType extends IType {
} }

View file

@ -233,7 +233,7 @@ public class CPPCompositesFactory extends AbstractCompositeFactory {
throw new CompositingNotImplementedError(); throw new CompositingNotImplementedError();
} }
private ICPPEvaluation getCompositeEvaluation(ICPPEvaluation eval) { public ICPPEvaluation getCompositeEvaluation(ICPPEvaluation eval) {
if (eval == null) if (eval == null)
return null; return null;
if (eval instanceof EvalBinary) { if (eval instanceof EvalBinary) {
@ -425,16 +425,13 @@ public class CPPCompositesFactory extends AbstractCompositeFactory {
public IValue getCompositeValue(IValue v) { public IValue getCompositeValue(IValue v) {
if (v == null) if (v == null)
return null; return null;
IBinding[] b= v.getUnknownBindings(); ICPPEvaluation eval = v.getEvaluation();
if (b.length == 0) if (eval == null)
return v; return v;
ICPPUnknownBinding[] b2= new ICPPUnknownBinding[b.length]; eval = getCompositeEvaluation(eval);
for (int i = 0; i < b2.length; i++) { return Value.fromInternalRepresentation(eval);
b2[i]= (ICPPUnknownBinding) getCompositeBinding((IIndexFragmentBinding) b[i]);
}
return Value.fromInternalRepresentation(v.getInternalExpression(), b2);
} }
private ICPPNamespace[] getNamespaces(IBinding rbinding) throws CoreException { private ICPPNamespace[] getNamespaces(IBinding rbinding) throws CoreException {

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Andrew Ferguson (Symbian) - Initial implementation * Andrew Ferguson (Symbian) - Initial implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.index.composite.cpp; package org.eclipse.cdt.internal.core.index.composite.cpp;
@ -43,8 +43,8 @@ class CompositeCPPClassScope extends CompositeScope implements ICPPClassScope {
public ICPPMethod[] getImplicitMethods() { public ICPPMethod[] getImplicitMethods() {
ICPPClassScope rscope = (ICPPClassScope) ((ICPPClassType)rbinding).getCompositeScope(); ICPPClassScope rscope = (ICPPClassScope) ((ICPPClassType)rbinding).getCompositeScope();
ICPPMethod[] result = rscope.getImplicitMethods(); ICPPMethod[] result = rscope.getImplicitMethods();
for(int i=0; i<result.length; i++) { for (int i= 0; i < result.length; i++) {
result[i] = (ICPPMethod) cf.getCompositeBinding((IIndexFragmentBinding)result[i]); result[i] = (ICPPMethod) cf.getCompositeBinding((IIndexFragmentBinding) result[i]);
} }
return result; return result;
} }
@ -53,15 +53,15 @@ class CompositeCPPClassScope extends CompositeScope implements ICPPClassScope {
public ICPPConstructor[] getConstructors() { public ICPPConstructor[] getConstructors() {
ICPPClassScope rscope = (ICPPClassScope) ((ICPPClassType)rbinding).getCompositeScope(); ICPPClassScope rscope = (ICPPClassScope) ((ICPPClassType)rbinding).getCompositeScope();
ICPPConstructor[] result = rscope.getConstructors(); ICPPConstructor[] result = rscope.getConstructors();
for(int i=0; i<result.length; i++) { for (int i= 0; i < result.length; i++) {
result[i] = (ICPPConstructor) cf.getCompositeBinding((IIndexFragmentBinding)result[i]); result[i] = (ICPPConstructor) cf.getCompositeBinding((IIndexFragmentBinding) result[i]);
} }
return result; return result;
} }
@Override @Override
public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet fileSet) { public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet fileSet) {
IBinding binding = ((ICPPClassType)rbinding).getCompositeScope().getBinding(name, resolve, fileSet); IBinding binding = ((ICPPClassType) rbinding).getCompositeScope().getBinding(name, resolve, fileSet);
return processUncertainBinding(binding); return processUncertainBinding(binding);
} }
@ -72,13 +72,13 @@ class CompositeCPPClassScope extends CompositeScope implements ICPPClassScope {
@Override @Override
public IBinding[] getBindings(ScopeLookupData lookup) { public IBinding[] getBindings(ScopeLookupData lookup) {
IBinding[] bindings = ((ICPPClassType)rbinding).getCompositeScope().getBindings(lookup); IBinding[] bindings = ((ICPPClassType) rbinding).getCompositeScope().getBindings(lookup);
return processUncertainBindings(bindings); return processUncertainBindings(bindings);
} }
@Override @Override
public IBinding[] find(String name) { public IBinding[] find(String name) {
IBinding[] preresult = ((ICPPClassType)rbinding).getCompositeScope().find(name); IBinding[] preresult = ((ICPPClassType) rbinding).getCompositeScope().find(name);
return processUncertainBindings(preresult); return processUncertainBindings(preresult);
} }

View file

@ -1,21 +1,24 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2007, 2010 Symbian Software Systems and others. * Copyright (c) 2007, 2012 Symbian Software Systems and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Andrew Ferguson (Symbian) - Initial implementation * Andrew Ferguson (Symbian) - Initial implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.index.composite.cpp; package org.eclipse.cdt.internal.core.index.composite.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.IASTNode; 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.IField;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
@ -29,6 +32,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassSpecialization.RecursionResolvingBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassSpecialization.RecursionResolvingBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope;
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.index.IIndexFragment; import org.eclipse.cdt.internal.core.index.IIndexFragment;
@ -37,11 +41,9 @@ import org.eclipse.cdt.internal.core.index.IIndexScope;
import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory;
public class CompositeCPPClassSpecialization extends CompositeCPPClassType implements ICPPClassSpecialization { public class CompositeCPPClassSpecialization extends CompositeCPPClassType implements ICPPClassSpecialization {
private ObjectMap specializationMap;
private ObjectMap specializationMap= null;
private final ThreadLocal<Set<IBinding>> fInProgress= new ThreadLocal<Set<IBinding>>(); private final ThreadLocal<Set<IBinding>> fInProgress= new ThreadLocal<Set<IBinding>>();
public CompositeCPPClassSpecialization(ICompositesFactory cf, ICPPClassType rbinding) { public CompositeCPPClassSpecialization(ICompositesFactory cf, ICPPClassType rbinding) {
super(cf, rbinding); super(cf, rbinding);
} }
@ -80,11 +82,11 @@ public class CompositeCPPClassSpecialization extends CompositeCPPClassType imple
specializationMap= (ObjectMap) cached; specializationMap= (ObjectMap) cached;
} else { } else {
final ObjectMap newMap= new ObjectMap(2); final ObjectMap newMap= new ObjectMap(2);
// in any fragment explicit specializations may be defined. // In any fragment explicit specializations may be defined.
IIndexFragmentBinding[] frags= cf.findEquivalentBindings(rbinding); IIndexFragmentBinding[] frags= cf.findEquivalentBindings(rbinding);
for (IIndexFragmentBinding fb : frags) { for (IIndexFragmentBinding fb : frags) {
if (fb instanceof ICPPClassType) { if (fb instanceof ICPPClassType) {
final ICPPClassType[] nested = ((ICPPClassType)fb).getNestedClasses(); final ICPPClassType[] nested = ClassTypeHelper.getNestedClasses((ICPPClassType) fb, point);
if (nested.length > 0) { if (nested.length > 0) {
for (ICPPClassType ct : nested) { for (ICPPClassType ct : nested) {
if (ct instanceof ICPPClassSpecialization && if (ct instanceof ICPPClassSpecialization &&
@ -130,56 +132,131 @@ public class CompositeCPPClassSpecialization extends CompositeCPPClassType imple
@Override @Override
public final ICPPBase[] getBases() { public final ICPPBase[] getBases() {
CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
return getBases(null);
}
@Override
public final ICPPBase[] getBases(IASTNode point) {
IScope scope= getCompositeScope(); IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) { if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getBases(); return ((ICPPClassSpecializationScope) scope).getBases(point);
} }
return super.getBases(); ICPPBase[] bases = ClassTypeHelper.getBases((ICPPClassType) rbinding, point);
return wrapBases(bases);
} }
@Override @Override
public final ICPPConstructor[] getConstructors() { public final ICPPConstructor[] getConstructors() {
CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
return getConstructors(null);
}
@Override
public final ICPPConstructor[] getConstructors(IASTNode point) {
IScope scope= getCompositeScope(); IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) { if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getConstructors(); return ((ICPPClassSpecializationScope) scope).getConstructors(point);
} }
return super.getConstructors(); ICPPConstructor[] result = ClassTypeHelper.getConstructors((ICPPClassType) rbinding, point);
return wrapBindings(result);
}
@Override
public ICPPMethod[] getMethods() {
CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
return getMethods(null);
}
@Override
public ICPPMethod[] getMethods(IASTNode point) {
return ClassTypeHelper.getMethods(this, point);
} }
@Override @Override
public final ICPPMethod[] getDeclaredMethods() { public final ICPPMethod[] getDeclaredMethods() {
CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
return getDeclaredMethods(null);
}
@Override
public final ICPPMethod[] getDeclaredMethods(IASTNode point) {
IScope scope= getCompositeScope(); IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) { if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getDeclaredMethods(); return ((ICPPClassSpecializationScope) scope).getDeclaredMethods(point);
} }
return super.getDeclaredMethods(); ICPPMethod[] result = ClassTypeHelper.getDeclaredMethods((ICPPClassType) rbinding, point);
return wrapBindings(result);
}
@Override
public final ICPPMethod[] getAllDeclaredMethods() {
CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
return getAllDeclaredMethods(null);
}
@Override
public final ICPPMethod[] getAllDeclaredMethods(IASTNode point) {
return ClassTypeHelper.getAllDeclaredMethods(this, point);
} }
@Override @Override
public final ICPPField[] getDeclaredFields() { public final ICPPField[] getDeclaredFields() {
CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
return getDeclaredFields(null);
}
@Override
public final ICPPField[] getDeclaredFields(IASTNode point) {
IScope scope= getCompositeScope(); IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) { if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getDeclaredFields(); return ((ICPPClassSpecializationScope) scope).getDeclaredFields(point);
} }
return super.getDeclaredFields(); ICPPField[] result = ClassTypeHelper.getDeclaredFields((ICPPClassType) rbinding, point);
return wrapBindings(result);
}
@Override
public IField[] getFields() {
CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
return getFields(null);
}
@Override
public final IField[] getFields(IASTNode point) {
return ClassTypeHelper.getFields(this, point);
} }
@Override @Override
public final IBinding[] getFriends() { public final IBinding[] getFriends() {
CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
return getFriends(null);
}
@Override
public final IBinding[] getFriends(IASTNode point) {
IScope scope= getCompositeScope(); IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) { if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getFriends(); return ((ICPPClassSpecializationScope) scope).getFriends(point);
} }
return super.getFriends(); IBinding[] result = ClassTypeHelper.getFriends((ICPPClassType) rbinding, point);
return wrapBindings(result);
} }
@Override @Override
public final ICPPClassType[] getNestedClasses() { public final ICPPClassType[] getNestedClasses() {
CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
return getNestedClasses(null);
}
@Override
public final ICPPClassType[] getNestedClasses(IASTNode point) {
IScope scope= getCompositeScope(); IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) { if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getNestedClasses(); return ((ICPPClassSpecializationScope) scope).getNestedClasses(point);
} }
return super.getNestedClasses(); ICPPClassType[] result = ClassTypeHelper.getNestedClasses((ICPPClassType) rbinding, point);
return wrapBindings(result);
} }
@Override @Override

View file

@ -8,11 +8,14 @@
* Contributors: * Contributors:
* Andrew Ferguson (Symbian) - Initial implementation * Andrew Ferguson (Symbian) - Initial implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.index.composite.cpp; package org.eclipse.cdt.internal.core.index.composite.cpp;
import org.eclipse.cdt.core.CCorePlugin;
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.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.ICPPClassSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
@ -67,8 +70,14 @@ public class CompositeCPPClassSpecializationScope extends CompositeScope impleme
@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) {
createDelegate(); createDelegate();
return fDelegate.getImplicitMethods(); return fDelegate.getImplicitMethods(point);
} }
@Override @Override
@ -97,37 +106,43 @@ public class CompositeCPPClassSpecializationScope extends CompositeScope impleme
@Override @Override
public ICPPConstructor[] getConstructors() { public ICPPConstructor[] getConstructors() {
createDelegate(); CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
return fDelegate.getConstructors(); return getConstructors(null);
} }
@Override @Override
public ICPPMethod[] getDeclaredMethods() { public ICPPConstructor[] getConstructors(IASTNode point) {
createDelegate(); createDelegate();
return fDelegate.getDeclaredMethods(); return fDelegate.getConstructors(point);
} }
@Override @Override
public ICPPBase[] getBases() { public ICPPMethod[] getDeclaredMethods(IASTNode point) {
createDelegate(); createDelegate();
return fDelegate.getBases(); return fDelegate.getDeclaredMethods(point);
} }
@Override @Override
public ICPPField[] getDeclaredFields() { public ICPPBase[] getBases(IASTNode point) {
createDelegate(); createDelegate();
return fDelegate.getDeclaredFields(); return fDelegate.getBases(point);
} }
@Override @Override
public IBinding[] getFriends() { public ICPPField[] getDeclaredFields(IASTNode point) {
createDelegate(); createDelegate();
return fDelegate.getFriends(); return fDelegate.getDeclaredFields(point);
} }
@Override @Override
public ICPPClassType[] getNestedClasses() { public IBinding[] getFriends(IASTNode point) {
createDelegate(); createDelegate();
return fDelegate.getNestedClasses(); return fDelegate.getFriends(point);
}
@Override
public ICPPClassType[] getNestedClasses(IASTNode point) {
createDelegate();
return fDelegate.getNestedClasses(point);
} }
} }

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.index.composite.cpp; package org.eclipse.cdt.internal.core.index.composite.cpp;

View file

@ -1,16 +1,19 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2007, 2010 Symbian Software Systems and others. * Copyright (c) 2007, 2012 Symbian Software Systems and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Andrew Ferguson (Symbian) - Initial implementation * Andrew Ferguson (Symbian) - Initial implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.index.composite.cpp; package org.eclipse.cdt.internal.core.index.composite.cpp;
import java.util.Arrays;
import org.eclipse.cdt.core.dom.IName; import org.eclipse.cdt.core.dom.IName;
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;
@ -42,8 +45,8 @@ class CompositeCPPClassType extends CompositeCPPBinding implements ICPPClassType
} }
@Override @Override
public final ICPPMethod[] getAllDeclaredMethods() { public ICPPMethod[] getAllDeclaredMethods() {
return ClassTypeHelper.getAllDeclaredMethods(this); return ClassTypeHelper.getAllDeclaredMethods(this, null);
} }
private class CPPBaseDelegate implements ICPPBase { private class CPPBaseDelegate implements ICPPBase {
@ -65,7 +68,7 @@ class CompositeCPPClassType extends CompositeCPPBinding implements ICPPClassType
if (baseClass != null) { if (baseClass != null) {
return baseClass; return baseClass;
} else { } else {
return cf.getCompositeBinding((IIndexFragmentBinding)base.getBaseClass()); return cf.getCompositeBinding((IIndexFragmentBinding) base.getBaseClass());
} }
} }
@ -101,68 +104,48 @@ class CompositeCPPClassType extends CompositeCPPBinding implements ICPPClassType
@Override @Override
public ICPPBase[] getBases() { public ICPPBase[] getBases() {
final ICPPBase[] preresult = ((ICPPClassType) rbinding).getBases(); ICPPBase[] bases = ((ICPPClassType) rbinding).getBases();
ICPPBase[] result = new ICPPBase[preresult.length]; return wrapBases(bases);
for (int i= 0; i < preresult.length; i++) {
result[i] = new CPPBaseDelegate(preresult[i]);
}
return result;
} }
@Override @Override
public ICPPConstructor[] getConstructors() { public ICPPConstructor[] getConstructors() {
ICPPConstructor[] result = ((ICPPClassType) rbinding).getConstructors(); ICPPConstructor[] result = ((ICPPClassType) rbinding).getConstructors();
for (int i= 0; i < result.length; i++) { return wrapBindings(result);
result[i] = (ICPPConstructor) cf.getCompositeBinding((IIndexFragmentBinding) result[i]);
}
return result;
} }
@Override @Override
public ICPPField[] getDeclaredFields() { public ICPPField[] getDeclaredFields() {
ICPPField[] result = ((ICPPClassType) rbinding).getDeclaredFields(); ICPPField[] result = ((ICPPClassType) rbinding).getDeclaredFields();
for (int i= 0; i < result.length; i++) { return wrapBindings(result);
result[i] = (ICPPField) cf.getCompositeBinding((IIndexFragmentBinding)result[i]);
}
return result;
} }
@Override @Override
public ICPPMethod[] getDeclaredMethods() { public ICPPMethod[] getDeclaredMethods() {
ICPPMethod[] result = ((ICPPClassType) rbinding).getDeclaredMethods(); ICPPMethod[] result = ((ICPPClassType) rbinding).getDeclaredMethods();
for (int i= 0; i < result.length; i++) { return wrapBindings(result);
result[i]= (ICPPMethod) cf.getCompositeBinding((IIndexFragmentBinding)result[i]);
}
return result;
} }
@Override @Override
public final IField[] getFields() { public IField[] getFields() {
return ClassTypeHelper.getFields(this); return ClassTypeHelper.getFields(this, null);
} }
@Override @Override
public IBinding[] getFriends() { public IBinding[] getFriends() {
IBinding[] preResult = ((ICPPClassType) rbinding).getFriends(); IBinding[] preResult = ((ICPPClassType) rbinding).getFriends();
IBinding[] result = new IBinding[preResult.length]; return wrapBindings(preResult);
for (int i= 0; i < preResult.length; i++) {
result[i] = cf.getCompositeBinding((IIndexFragmentBinding) preResult[i]);
}
return result;
} }
@Override @Override
public final ICPPMethod[] getMethods() { public ICPPMethod[] getMethods() {
return ClassTypeHelper.getMethods(this); return ClassTypeHelper.getMethods(this, null);
} }
@Override @Override
public ICPPClassType[] getNestedClasses() { public ICPPClassType[] getNestedClasses() {
ICPPClassType[] result = ((ICPPClassType) rbinding).getNestedClasses(); ICPPClassType[] result = ((ICPPClassType) rbinding).getNestedClasses();
for (int i= 0; i < result.length; i++) { return wrapBindings(result);
result[i] = (ICPPClassType) cf.getCompositeBinding((IIndexFragmentBinding) result[i]);
}
return result;
} }
@Override @Override
@ -184,4 +167,21 @@ class CompositeCPPClassType extends CompositeCPPBinding implements ICPPClassType
public boolean isAnonymous() { public boolean isAnonymous() {
return ((ICPPClassType) rbinding).isAnonymous(); return ((ICPPClassType) rbinding).isAnonymous();
} }
protected ICPPBase[] wrapBases(final ICPPBase[] bases) {
ICPPBase[] result = new ICPPBase[bases.length];
for (int i= 0; i < bases.length; i++) {
result[i] = new CPPBaseDelegate(bases[i]);
}
return result;
}
@SuppressWarnings("unchecked")
protected <T extends IBinding> T[] wrapBindings(T[] bindings) {
T[] result = Arrays.copyOf(bindings, bindings.length);
for (int i= 0; i < bindings.length; i++) {
result[i] = (T) cf.getCompositeBinding((IIndexFragmentBinding) bindings[i]);
}
return result;
}
} }

View file

@ -1,14 +1,15 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2007, 2011 Symbian Software Systems and others. * Copyright (c) 2007, 2012 Symbian Software Systems and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Andrew Ferguson (Symbian) - Initial implementation * Andrew Ferguson (Symbian) - Initial implementation
* Bryan Wilkinson (QNX) * Bryan Wilkinson (QNX)
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.index.composite.cpp; package org.eclipse.cdt.internal.core.index.composite.cpp;
@ -16,7 +17,6 @@ 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.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.cpp.ICPPClassTemplatePartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
@ -26,15 +26,18 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory;
/** /**
* For implementation re-use in the absence of multiple inheritance * For implementation re-use in the absence of multiple inheritance.
*/ */
public class TemplateInstanceUtil { public class TemplateInstanceUtil {
public static ICPPTemplateParameterMap getTemplateParameterMap(ICompositesFactory cf, ICPPTemplateInstance rbinding) { public static ICPPTemplateParameterMap getTemplateParameterMap(ICompositesFactory cf, ICPPTemplateInstance rbinding) {
ICPPTemplateParameterMap preresult= rbinding.getTemplateParameterMap(); ICPPTemplateParameterMap preresult= rbinding.getTemplateParameterMap();
Integer[] keys= preresult.getAllParameterPositions(); Integer[] keys= preresult.getAllParameterPositions();
@ -50,8 +53,8 @@ public class TemplateInstanceUtil {
result.put(key, convert(cf, pack)); result.put(key, convert(cf, pack));
} }
} }
} catch(DOMException de) { } catch (DOMException e) {
CCorePlugin.log(de); CCorePlugin.log(e);
} }
return result; return result;
} }
@ -90,22 +93,18 @@ public class TemplateInstanceUtil {
} }
static ICPPTemplateArgument convert(ICompositesFactory cf, ICPPTemplateArgument arg) throws DOMException { static ICPPTemplateArgument convert(ICompositesFactory cf, ICPPTemplateArgument arg) throws DOMException {
if (arg == null) if (arg instanceof CPPTemplateTypeArgument) {
return null; final IType typeValue = arg.getTypeValue();
if (arg.isNonTypeValue()) { IType t= cf.getCompositeType(typeValue);
final IType t= arg.getTypeOfNonTypeValue(); if (t != typeValue) {
final IType t2= cf.getCompositeType(t); return new CPPTemplateTypeArgument(t);
final IValue v= arg.getNonTypeValue(); }
final IValue v2= cf.getCompositeValue(v); } else if (arg instanceof CPPTemplateNonTypeArgument) {
if (t != t2 || v != v2) { ICPPEvaluation eval = ((CPPTemplateNonTypeArgument) arg).getEvaluation();
return new CPPTemplateArgument(v2, t2); ICPPEvaluation eval2 = ((CPPCompositesFactory) cf).getCompositeEvaluation(eval);
if (eval2 != eval) {
return new CPPTemplateNonTypeArgument(eval2);
} }
return arg;
}
final IType typeValue = arg.getTypeValue();
IType t= cf.getCompositeType(typeValue);
if (t != typeValue) {
return new CPPTemplateArgument(t);
} }
return arg; return arg;
} }
@ -113,8 +112,8 @@ public class TemplateInstanceUtil {
@Deprecated @Deprecated
public static ObjectMap getArgumentMap(ICompositesFactory cf, IIndexBinding rbinding) { public static ObjectMap getArgumentMap(ICompositesFactory cf, IIndexBinding rbinding) {
ICPPSpecialization specn= (ICPPSpecialization) rbinding; ICPPSpecialization specn= (ICPPSpecialization) rbinding;
IBinding specd= ((CPPCompositesFactory)cf).findOneBinding(specn.getSpecializedBinding()); IBinding specd= ((CPPCompositesFactory) cf).findOneBinding(specn.getSpecializedBinding());
if(specd == null) if (specd == null)
specd= specn.getSpecializedBinding(); specd= specn.getSpecializedBinding();
ObjectMap preresult= specn.getArgumentMap(); ObjectMap preresult= specn.getArgumentMap();
@ -122,14 +121,13 @@ public class TemplateInstanceUtil {
Object[] keys= preresult.keyArray(); Object[] keys= preresult.keyArray();
Object[] keysToAdapt= keys; Object[] keysToAdapt= keys;
if(specd instanceof ICPPTemplateDefinition) { if (specd instanceof ICPPTemplateDefinition) {
keysToAdapt= ((ICPPTemplateDefinition)specd).getTemplateParameters(); keysToAdapt= ((ICPPTemplateDefinition) specd).getTemplateParameters();
} }
for(int i = 0; i < keys.length && i < keysToAdapt.length; i++) { for (int i= 0; i < keys.length && i < keysToAdapt.length; i++) {
IType type= (IType) preresult.get(keys[i]); IType type= (IType) preresult.get(keys[i]);
result.put( result.put(
cf.getCompositeBinding((IIndexFragmentBinding)keysToAdapt[i]), cf.getCompositeBinding((IIndexFragmentBinding) keysToAdapt[i]), cf.getCompositeType(type));
cf.getCompositeType(type));
} }
return result; return result;
@ -144,15 +142,15 @@ public class TemplateInstanceUtil {
public static IType[] getArguments(ICompositesFactory cf, ICPPClassTemplatePartialSpecialization rbinding) { public static IType[] getArguments(ICompositesFactory cf, ICPPClassTemplatePartialSpecialization rbinding) {
try { try {
return getArguments(cf, rbinding.getArguments()); return getArguments(cf, rbinding.getArguments());
} catch(DOMException de) { } catch (DOMException e) {
CCorePlugin.log(de); CCorePlugin.log(e);
return IType.EMPTY_TYPE_ARRAY; return IType.EMPTY_TYPE_ARRAY;
} }
} }
@Deprecated @Deprecated
private static IType[] getArguments(ICompositesFactory cf, IType[] result) { private static IType[] getArguments(ICompositesFactory cf, IType[] result) {
for(int i=0; i<result.length; i++) { for (int i= 0; i < result.length; i++) {
result[i] = cf.getCompositeType(result[i]); result[i] = cf.getCompositeType(result[i]);
} }
return result; return result;

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009, 2010 Wind River Systems, Inc. and others. * Copyright (c) 2009, 2012 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.db; package org.eclipse.cdt.internal.core.pdom.db;
@ -16,11 +17,15 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.ISemanticProblem;
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.ICPPTemplateArgument;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableType; import org.eclipse.cdt.internal.core.dom.parser.ISerializableType;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
@ -93,7 +98,7 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
byte firstByte= fBuffer[fPos]; byte firstByte= fBuffer[fPos];
if (firstByte == BINDING_TYPE) { if (firstByte == BINDING_TYPE) {
fPos+= 2; fPos += 2;
long rec= getRecordPointer(); long rec= getRecordPointer();
return (IBinding) fLinkage.getNode(rec); return (IBinding) fLinkage.getNode(rec);
} else if (firstByte == NULL_TYPE || firstByte == UNSTORABLE_TYPE) { } else if (firstByte == NULL_TYPE || firstByte == UNSTORABLE_TYPE) {
@ -182,6 +187,27 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
return Value.unmarshal(this); return Value.unmarshal(this);
} }
@Override
public void marshalTemplateArgument(ICPPTemplateArgument arg) throws CoreException {
if (arg instanceof CPPTemplateNonTypeArgument) {
putByte(VALUE);
((CPPTemplateNonTypeArgument) arg).getEvaluation().marshal(this, true);
} else {
marshalType(arg.getTypeValue());
}
}
@Override
public ICPPTemplateArgument unmarshalTemplateArgument() throws CoreException {
int firstByte= getByte();
if (firstByte == VALUE) {
return new CPPTemplateNonTypeArgument((ICPPEvaluation) unmarshalEvaluation());
} else {
fPos--;
return new CPPTemplateTypeArgument(unmarshalType());
}
}
private void request(int i) { private void request(int i) {
if (fBuffer == null) { if (fBuffer == null) {
if (i <= Database.TYPE_SIZE) { if (i <= Database.TYPE_SIZE) {

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Markus Schorn - initial API and implementation * Markus Schorn - initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp; package org.eclipse.cdt.internal.core.pdom.dom.cpp;
@ -15,7 +15,8 @@ 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.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
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.CPPTemplateArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeArgument;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeArgument;
import org.eclipse.cdt.internal.core.pdom.db.Database; import org.eclipse.cdt.internal.core.pdom.db.Database;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
@ -36,17 +37,18 @@ public class PDOMCPPArgumentList {
public static long putArguments(PDOMNode parent, ICPPTemplateArgument[] templateArguments) throws CoreException { public static long putArguments(PDOMNode parent, ICPPTemplateArgument[] templateArguments) throws CoreException {
final PDOMLinkage linkage= parent.getLinkage(); final PDOMLinkage linkage= parent.getLinkage();
final Database db= linkage.getDB(); final Database db= linkage.getDB();
final short len= (short) Math.min(templateArguments.length, (Database.MAX_MALLOC_SIZE-2)/NODE_SIZE); final short len= (short) Math.min(templateArguments.length, (Database.MAX_MALLOC_SIZE - 2) / NODE_SIZE);
final long block= db.malloc(2+NODE_SIZE*len); final long block= db.malloc(2 + NODE_SIZE * len);
long p= block; long p= block;
db.putShort(p, len); p+=2; db.putShort(p, len);
for (int i=0; i<len; i++, p+=NODE_SIZE) { p += 2;
for (int i= 0; i < len; i++, p += NODE_SIZE) {
final ICPPTemplateArgument arg = templateArguments[i]; final ICPPTemplateArgument arg = templateArguments[i];
final boolean isNonType= arg.isNonTypeValue(); final boolean isNonType= arg.isNonTypeValue();
if (isNonType) { if (isNonType) {
linkage.storeType(p, arg.getTypeOfNonTypeValue()); linkage.storeType(p, arg.getTypeOfNonTypeValue());
linkage.storeValue(p+VALUE_OFFSET, arg.getNonTypeValue()); linkage.storeValue(p + VALUE_OFFSET, arg.getNonTypeValue());
} else { } else {
linkage.storeType(p, arg.getTypeValue()); linkage.storeType(p, arg.getTypeValue());
} }
@ -54,7 +56,6 @@ public class PDOMCPPArgumentList {
return block; return block;
} }
/** /**
* Restores an array of template arguments from the database. * Restores an array of template arguments from the database.
*/ */
@ -63,11 +64,11 @@ public class PDOMCPPArgumentList {
final Database db= linkage.getDB(); final Database db= linkage.getDB();
final short len= db.getShort(record); final short len= db.getShort(record);
Assert.isTrue(len >= 0 && len <= (Database.MAX_MALLOC_SIZE-2)/NODE_SIZE); Assert.isTrue(len >= 0 && len <= (Database.MAX_MALLOC_SIZE - 2) / NODE_SIZE);
long p= record+2; long p= record + 2;
for (int i=0; i<len; i++) { for (int i= 0; i < len; i++) {
linkage.storeType(p, null); linkage.storeType(p, null);
linkage.storeValue(p+VALUE_OFFSET, null); linkage.storeValue(p + VALUE_OFFSET, null);
p+= NODE_SIZE; p+= NODE_SIZE;
} }
db.free(record); db.free(record);
@ -81,25 +82,25 @@ public class PDOMCPPArgumentList {
final Database db= linkage.getDB(); final Database db= linkage.getDB();
final short len= db.getShort(rec); final short len= db.getShort(rec);
Assert.isTrue(len >= 0 && len <= (Database.MAX_MALLOC_SIZE-2)/NODE_SIZE); Assert.isTrue(len >= 0 && len <= (Database.MAX_MALLOC_SIZE - 2) / NODE_SIZE);
if (len == 0) { if (len == 0) {
return ICPPTemplateArgument.EMPTY_ARGUMENTS; return ICPPTemplateArgument.EMPTY_ARGUMENTS;
} }
rec+=2; rec += 2;
ICPPTemplateArgument[] result= new ICPPTemplateArgument[len]; ICPPTemplateArgument[] result= new ICPPTemplateArgument[len];
for (int i=0; i<len; i++) { for (int i= 0; i < len; i++) {
IType type= linkage.loadType(rec); IType type= linkage.loadType(rec);
if (type == null) { if (type == null) {
type= new ProblemType(ISemanticProblem.TYPE_NOT_PERSISTED); type= new ProblemType(ISemanticProblem.TYPE_NOT_PERSISTED);
} }
IValue val= linkage.loadValue(rec+VALUE_OFFSET); IValue val= linkage.loadValue(rec + VALUE_OFFSET);
if (val != null) { if (val != null) {
result[i]= new CPPTemplateArgument(val, type); result[i]= new CPPTemplateNonTypeArgument(val, type);
} else { } else {
result[i]= new CPPTemplateArgument(type); result[i]= new CPPTemplateTypeArgument(type);
} }
rec+= NODE_SIZE; rec += NODE_SIZE;
} }
return result; return result;
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2007, 2011 QNX Software Systems and others. * Copyright (c) 2007, 2012 QNX Software Systems and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -9,6 +9,7 @@
* QNX - Initial API and implementation * QNX - Initial API and implementation
* Andrew Ferguson (Symbian) * Andrew Ferguson (Symbian)
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp; package org.eclipse.cdt.internal.core.pdom.dom.cpp;
@ -54,18 +55,17 @@ import org.eclipse.core.runtime.CoreException;
*/ */
class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
ICPPClassSpecialization, IPDOMMemberOwner, IPDOMCPPClassType { ICPPClassSpecialization, IPDOMMemberOwner, IPDOMCPPClassType {
private static final int FIRST_BASE = PDOMCPPSpecialization.RECORD_SIZE + 0;
private static final int MEMBER_LIST = PDOMCPPSpecialization.RECORD_SIZE + 4;
private static final int FIRSTBASE = PDOMCPPSpecialization.RECORD_SIZE + 0;
private static final int MEMBERLIST = PDOMCPPSpecialization.RECORD_SIZE + 4;
/** /**
* The size in bytes of a PDOMCPPClassSpecialization record in the database. * The size in bytes of a PDOMCPPClassSpecialization record in the database.
*/ */
@SuppressWarnings("hiding") @SuppressWarnings("hiding")
protected static final int RECORD_SIZE = PDOMCPPSpecialization.RECORD_SIZE + 8; protected static final int RECORD_SIZE = PDOMCPPSpecialization.RECORD_SIZE + 8;
private volatile ICPPClassScope fScope; private volatile ICPPClassScope fScope;
private ObjectMap specializationMap= null; // Obtained from the synchronized PDOM cache private ObjectMap specializationMap; // Obtained from the synchronized PDOM cache
private final ThreadLocal<Set<IBinding>> fInProgress= new ThreadLocal<Set<IBinding>>(); private final ThreadLocal<Set<IBinding>> fInProgress= new ThreadLocal<Set<IBinding>>();
public PDOMCPPClassSpecialization(PDOMLinkage linkage, PDOMNode parent, ICPPClassType classType, public PDOMCPPClassSpecialization(PDOMLinkage linkage, PDOMNode parent, ICPPClassType classType,
@ -76,7 +76,7 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
public PDOMCPPClassSpecialization(PDOMLinkage linkage, long bindingRecord) { public PDOMCPPClassSpecialization(PDOMLinkage linkage, long bindingRecord) {
super(linkage, bindingRecord); super(linkage, bindingRecord);
} }
@Override @Override
protected int getRecordSize() { protected int getRecordSize() {
return RECORD_SIZE; return RECORD_SIZE;
@ -91,14 +91,14 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
public ICPPClassType getSpecializedBinding() { public ICPPClassType getSpecializedBinding() {
return (ICPPClassType) super.getSpecializedBinding(); return (ICPPClassType) super.getSpecializedBinding();
} }
@Override @Override
public IBinding specializeMember(IBinding original) { public IBinding specializeMember(IBinding original) {
return specializeMember(original, null); return specializeMember(original, null);
} }
@Override @Override
public IBinding specializeMember(IBinding original, IASTNode point) { public IBinding specializeMember(IBinding original, IASTNode point) {
if (specializationMap == null) { if (specializationMap == null) {
final Long key= record+PDOMCPPLinkage.CACHE_INSTANCE_SCOPE; final Long key= record+PDOMCPPLinkage.CACHE_INSTANCE_SCOPE;
Object cached= getPDOM().getCachedResult(key); Object cached= getPDOM().getCachedResult(key);
@ -124,14 +124,14 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
Set<IBinding> set; Set<IBinding> set;
synchronized (specializationMap) { synchronized (specializationMap) {
IBinding result= (IBinding) specializationMap.get(original); IBinding result= (IBinding) specializationMap.get(original);
if (result != null) if (result != null)
return result; return result;
set= fInProgress.get(); set= fInProgress.get();
if (set == null) { if (set == null) {
set= new HashSet<IBinding>(); set= new HashSet<IBinding>();
fInProgress.set(set); fInProgress.set(set);
} }
if (!set.add(original)) if (!set.add(original))
return new RecursionResolvingBinding(null, null); return new RecursionResolvingBinding(null, null);
} }
IBinding newSpec= CPPTemplates.createSpecialization(this, original, point); IBinding newSpec= CPPTemplates.createSpecialization(this, original, point);
@ -154,7 +154,7 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
if (hasOwnScope()) { if (hasOwnScope()) {
fScope= new PDOMCPPClassScope(this); fScope= new PDOMCPPClassScope(this);
return fScope; return fScope;
} }
} catch (CoreException e) { } catch (CoreException e) {
} }
fScope= new PDOMCPPClassSpecializationScope(this); fScope= new PDOMCPPClassSpecializationScope(this);
@ -167,22 +167,22 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
} }
public PDOMCPPBase getFirstBase() throws CoreException { public PDOMCPPBase getFirstBase() throws CoreException {
long rec = getDB().getRecPtr(record + FIRSTBASE); long rec = getDB().getRecPtr(record + FIRST_BASE);
return rec != 0 ? new PDOMCPPBase(getLinkage(), rec) : null; return rec != 0 ? new PDOMCPPBase(getLinkage(), rec) : null;
} }
private void setFirstBase(PDOMCPPBase base) throws CoreException { private void setFirstBase(PDOMCPPBase base) throws CoreException {
long rec = base != null ? base.getRecord() : 0; long rec = base != null ? base.getRecord() : 0;
getDB().putRecPtr(record + FIRSTBASE, rec); getDB().putRecPtr(record + FIRST_BASE, rec);
} }
public void addBase(PDOMCPPBase base) throws CoreException { public void addBase(PDOMCPPBase base) throws CoreException {
getPDOM().removeCachedResult(record+PDOMCPPLinkage.CACHE_BASES); getPDOM().removeCachedResult(record+PDOMCPPLinkage.CACHE_BASES);
PDOMCPPBase firstBase = getFirstBase(); PDOMCPPBase firstBase = getFirstBase();
base.setNextBase(firstBase); base.setNextBase(firstBase);
setFirstBase(base); setFirstBase(base);
} }
public void removeBase(PDOMName pdomName) throws CoreException { public void removeBase(PDOMName pdomName) throws CoreException {
getPDOM().removeCachedResult(record+PDOMCPPLinkage.CACHE_BASES); getPDOM().removeCachedResult(record+PDOMCPPLinkage.CACHE_BASES);
PDOMCPPBase base= getFirstBase(); PDOMCPPBase base= getFirstBase();
@ -205,25 +205,31 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
base.delete(); base.delete();
} }
} }
// implementation of class type
@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) {
IScope scope= getCompositeScope(); IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) { if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getBases(); return ((ICPPClassSpecializationScope) scope).getBases(point);
} }
// this is an explicit specialization // This is an explicit specialization
Long key= record + PDOMCPPLinkage.CACHE_BASES; Long key= record + PDOMCPPLinkage.CACHE_BASES;
ICPPBase[] bases= (ICPPBase[]) getPDOM().getCachedResult(key); ICPPBase[] bases= (ICPPBase[]) getPDOM().getCachedResult(key);
if (bases != null) if (bases != null)
return bases; return bases;
try { try {
List<PDOMCPPBase> list = new ArrayList<PDOMCPPBase>(); List<PDOMCPPBase> list = new ArrayList<PDOMCPPBase>();
for (PDOMCPPBase base = getFirstBase(); base != null; base = base.getNextBase()) for (PDOMCPPBase base = getFirstBase(); base != null; base = base.getNextBase()) {
list.add(base); list.add(base);
}
Collections.reverse(list); Collections.reverse(list);
bases = list.toArray(new ICPPBase[list.size()]); bases = list.toArray(new ICPPBase[list.size()]);
getPDOM().putCachedResult(key, bases); getPDOM().putCachedResult(key, bases);
@ -233,12 +239,18 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
} }
return ICPPBase.EMPTY_BASE_ARRAY; return ICPPBase.EMPTY_BASE_ARRAY;
} }
@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) {
IScope scope= getCompositeScope(); IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) { if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getConstructors(); return ((ICPPClassSpecializationScope) scope).getConstructors(point);
} }
try { try {
PDOMClassUtil.ConstructorCollector visitor= new PDOMClassUtil.ConstructorCollector(); PDOMClassUtil.ConstructorCollector visitor= new PDOMClassUtil.ConstructorCollector();
@ -252,9 +264,15 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
@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) {
IScope scope= getCompositeScope(); IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) { if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getDeclaredMethods(); return ((ICPPClassSpecializationScope) scope).getDeclaredMethods(point);
} }
try { try {
PDOMClassUtil.MethodCollector methods = new PDOMClassUtil.MethodCollector(false); PDOMClassUtil.MethodCollector methods = new PDOMClassUtil.MethodCollector(false);
@ -268,10 +286,16 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
@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) {
IScope scope= getCompositeScope(); IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) { if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getDeclaredFields(); return ((ICPPClassSpecializationScope) scope).getDeclaredFields(point);
} }
try { try {
PDOMClassUtil.FieldCollector visitor = new PDOMClassUtil.FieldCollector(); PDOMClassUtil.FieldCollector visitor = new PDOMClassUtil.FieldCollector();
PDOMCPPClassScope.acceptViaCache(this, visitor, false); PDOMCPPClassScope.acceptViaCache(this, visitor, false);
@ -281,13 +305,19 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
return ICPPField.EMPTY_CPPFIELD_ARRAY; return ICPPField.EMPTY_CPPFIELD_ARRAY;
} }
} }
@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) {
IScope scope= getCompositeScope(); IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) { if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getNestedClasses(); return ((ICPPClassSpecializationScope) scope).getNestedClasses(point);
} }
try { try {
PDOMClassUtil.NestedClassCollector visitor = new PDOMClassUtil.NestedClassCollector(); PDOMClassUtil.NestedClassCollector visitor = new PDOMClassUtil.NestedClassCollector();
PDOMCPPClassScope.acceptViaCache(this, visitor, false); PDOMCPPClassScope.acceptViaCache(this, visitor, false);
@ -300,25 +330,49 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
@Override @Override
public IBinding[] getFriends() { public IBinding[] getFriends() {
// not yet supported. 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) {
// Not yet supported.
return IBinding.EMPTY_BINDING_ARRAY; return IBinding.EMPTY_BINDING_ARRAY;
} }
@Override @Override
public ICPPMethod[] getMethods() { public ICPPMethod[] getMethods() {
return ClassTypeHelper.getMethods(this); CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
return getMethods(null);
}
@Override
public ICPPMethod[] getMethods(IASTNode point) {
return ClassTypeHelper.getMethods(this, point);
} }
@Override @Override
public ICPPMethod[] getAllDeclaredMethods() { public ICPPMethod[] getAllDeclaredMethods() {
return ClassTypeHelper.getAllDeclaredMethods(this); CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
return getAllDeclaredMethods(null);
} }
@Override
public ICPPMethod[] getAllDeclaredMethods(IASTNode point) {
return ClassTypeHelper.getAllDeclaredMethods(this, point);
}
@Override @Override
public IField[] getFields() { public IField[] getFields() {
return ClassTypeHelper.getFields(this); CCorePlugin.log(new Exception("Unsafe method call. Instantiation of dependent expressions may not work.")); //$NON-NLS-1$
return getFields(null);
} }
@Override
public IField[] getFields(IASTNode point) {
return ClassTypeHelper.getFields(this, point);
}
@Override @Override
public IField findField(String name) { public IField findField(String name) {
return ClassTypeHelper.findField(this, name); return ClassTypeHelper.findField(this, name);
@ -350,7 +404,7 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
return CPPClassSpecialization.isSameClassSpecialization(this, (ICPPClassSpecialization) type); return CPPClassSpecialization.isSameClassSpecialization(this, (ICPPClassSpecialization) type);
} }
@Override @Override
public Object clone() { public Object clone() {
try { try {
@ -362,13 +416,13 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
@Override @Override
public void addChild(PDOMNode member) throws CoreException { public void addChild(PDOMNode member) throws CoreException {
PDOMNodeLinkedList list = new PDOMNodeLinkedList(getLinkage(), record + MEMBERLIST); PDOMNodeLinkedList list = new PDOMNodeLinkedList(getLinkage(), record + MEMBER_LIST);
list.addMember(member); list.addMember(member);
} }
@Override @Override
public void acceptUncached(IPDOMVisitor visitor) throws CoreException { public void acceptUncached(IPDOMVisitor visitor) throws CoreException {
PDOMNodeLinkedList list = new PDOMNodeLinkedList(getLinkage(), record + MEMBERLIST); PDOMNodeLinkedList list = new PDOMNodeLinkedList(getLinkage(), record + MEMBER_LIST);
list.accept(visitor); list.accept(visitor);
} }
@ -376,7 +430,7 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
public void accept(IPDOMVisitor visitor) throws CoreException { public void accept(IPDOMVisitor visitor) throws CoreException {
PDOMCPPClassScope.acceptViaCache(this, visitor, false); PDOMCPPClassScope.acceptViaCache(this, visitor, false);
} }
@Override @Override
public boolean isAnonymous() { public boolean isAnonymous() {
return false; return false;

View file

@ -158,7 +158,7 @@ class PDOMCPPClassTemplateSpecialization extends PDOMCPPClassSpecialization
@Override @Override
public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() { public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() {
IASTNode point= null; // Instantiation of dependent expression may not work. IASTNode point= null; // Instantiation of dependent expressions may not work.
ICPPClassTemplate origTemplate= (ICPPClassTemplate) getSpecializedBinding(); ICPPClassTemplate origTemplate= (ICPPClassTemplate) getSpecializedBinding();
ICPPClassTemplatePartialSpecialization[] orig = origTemplate.getPartialSpecializations(); ICPPClassTemplatePartialSpecialization[] orig = origTemplate.getPartialSpecializations();
ICPPClassTemplatePartialSpecialization[] spec = new ICPPClassTemplatePartialSpecialization[orig.length]; ICPPClassTemplatePartialSpecialization[] spec = new ICPPClassTemplatePartialSpecialization[orig.length];

View file

@ -351,17 +351,17 @@ class PDOMCPPClassType extends PDOMCPPBinding implements IPDOMCPPClassType, IPDO
@Override @Override
public ICPPMethod[] getMethods() { public ICPPMethod[] getMethods() {
return ClassTypeHelper.getMethods(this); return ClassTypeHelper.getMethods(this, null);
} }
@Override @Override
public ICPPMethod[] getAllDeclaredMethods() { public ICPPMethod[] getAllDeclaredMethods() {
return ClassTypeHelper.getAllDeclaredMethods(this); return ClassTypeHelper.getAllDeclaredMethods(this, null);
} }
@Override @Override
public IField[] getFields() { public IField[] getFields() {
return ClassTypeHelper.getFields(this); return ClassTypeHelper.getFields(this, null);
} }
@Override @Override

View file

@ -13,6 +13,10 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp; package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
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.IASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
@ -63,6 +67,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable; import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.Util; import org.eclipse.cdt.internal.core.Util;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
@ -77,6 +82,7 @@ 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.CPPReferenceType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType;
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.ICPPUnknownBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownClassInstance;
@ -114,11 +120,6 @@ import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
/** /**
* Container for c++-entities. * Container for c++-entities.
*/ */
@ -252,7 +253,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
PDOMBinding pdomBinding = addBinding(binding, name); PDOMBinding pdomBinding = addBinding(binding, name);
if (pdomBinding instanceof PDOMCPPClassType || pdomBinding instanceof PDOMCPPClassSpecialization) { if (pdomBinding instanceof PDOMCPPClassType || pdomBinding instanceof PDOMCPPClassSpecialization) {
if (binding instanceof ICPPClassType && name.isDefinition()) { if (binding instanceof ICPPClassType && name.isDefinition()) {
addImplicitMethods(pdomBinding, (ICPPClassType) binding); addImplicitMethods(pdomBinding, (ICPPClassType) binding, name);
} }
} }
@ -299,7 +300,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
if (pdomBinding != null) { if (pdomBinding != null) {
getPDOM().putCachedResult(inputBinding, pdomBinding); getPDOM().putCachedResult(inputBinding, pdomBinding);
if (inputBinding instanceof CPPClosureType) { if (inputBinding instanceof CPPClosureType) {
addImplicitMethods(pdomBinding, (ICPPClassType) binding); addImplicitMethods(pdomBinding, (ICPPClassType) binding, fromName);
} }
} }
} catch (DOMException e) { } catch (DOMException e) {
@ -490,17 +491,14 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
return result; return result;
} }
private void addImplicitMethods(PDOMBinding type, ICPPClassType binding) throws CoreException { private void addImplicitMethods(PDOMBinding type, ICPPClassType binding, IASTNode point) throws CoreException {
try { try {
final long fileLocalRec= type.getLocalToFileRec(); final long fileLocalRec= type.getLocalToFileRec();
IScope scope = binding.getCompositeScope(); IScope scope = binding.getCompositeScope();
if (scope instanceof ICPPClassScope) { if (scope instanceof ICPPClassScope) {
List<ICPPMethod> old= new ArrayList<ICPPMethod>(); List<ICPPMethod> old= new ArrayList<ICPPMethod>();
if (type instanceof ICPPClassType) { if (type instanceof ICPPClassType) {
IScope oldScope = ((ICPPClassType)type).getCompositeScope(); ArrayUtil.addAll(old, ClassTypeHelper.getImplicitMethods((ICPPClassType) type, point));
if (oldScope instanceof ICPPClassScope) {
old.addAll(Arrays.asList(((ICPPClassScope) oldScope).getImplicitMethods()));
}
} }
ICPPMethod[] implicit= ((ICPPClassScope) scope).getImplicitMethods(); ICPPMethod[] implicit= ((ICPPClassScope) scope).getImplicitMethods();
for (ICPPMethod method : implicit) { for (ICPPMethod method : implicit) {
@ -1109,5 +1107,4 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
} }
throw new CoreException(CCorePlugin.createStatus("Cannot unmarshal an evaluation, first byte=" + firstByte)); //$NON-NLS-1$ throw new CoreException(CCorePlugin.createStatus("Cannot unmarshal an evaluation, first byte=" + firstByte)); //$NON-NLS-1$
} }
} }

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