mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-29 20:05:35 +02:00
bug 265375 - implicit names API and support for overloaded operator references
This commit is contained in:
parent
39de0e3a61
commit
5fcb227983
36 changed files with 1640 additions and 138 deletions
|
@ -50,7 +50,8 @@ public class ASTComparer extends Assert {
|
||||||
"isDefinition",
|
"isDefinition",
|
||||||
"isReference",
|
"isReference",
|
||||||
"isAssociatedWithLastName",
|
"isAssociatedWithLastName",
|
||||||
"getNestingLevel"
|
"getNestingLevel",
|
||||||
|
"getImplicitNames"
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
* IBM Corporation - initial API and implementation
|
* IBM Corporation - initial API and implementation
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
* Andrew Ferguson (Symbian)
|
* Andrew Ferguson (Symbian)
|
||||||
|
* Mike Kucera (IBM)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.parser.tests.ast2;
|
package org.eclipse.cdt.core.parser.tests.ast2;
|
||||||
|
|
||||||
|
@ -35,8 +36,11 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
||||||
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.IASTNodeSelector;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
|
@ -76,6 +80,7 @@ import org.eclipse.cdt.core.parser.tests.scanner.FileCodeReaderFactory;
|
||||||
import org.eclipse.cdt.core.testplugin.CTestPlugin;
|
import org.eclipse.cdt.core.testplugin.CTestPlugin;
|
||||||
import org.eclipse.cdt.core.testplugin.util.BaseTestCase;
|
import org.eclipse.cdt.core.testplugin.util.BaseTestCase;
|
||||||
import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
|
import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser;
|
import org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor;
|
import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.c.GNUCSourceParser;
|
import org.eclipse.cdt.internal.core.dom.parser.c.GNUCSourceParser;
|
||||||
|
@ -477,6 +482,10 @@ public class AST2BaseTest extends BaseTestCase {
|
||||||
this.tu= parse(contents, isCPP ? ParserLanguage.CPP : ParserLanguage.C, true, false);
|
this.tu= parse(contents, isCPP ? ParserLanguage.CPP : ParserLanguage.C, true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IASTTranslationUnit getTranslationUnit() {
|
||||||
|
return tu;
|
||||||
|
}
|
||||||
|
|
||||||
public IBinding assertProblem(String section, int len) {
|
public IBinding assertProblem(String section, int len) {
|
||||||
IBinding binding= binding(section, len);
|
IBinding binding= binding(section, len);
|
||||||
assertTrue("Non-ProblemBinding for name: " + section.substring(0, len),
|
assertTrue("Non-ProblemBinding for name: " + section.substring(0, len),
|
||||||
|
@ -497,15 +506,65 @@ public class AST2BaseTest extends BaseTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void assertNoName(String section, int len) {
|
public void assertNoName(String section, int len) {
|
||||||
final int offset = contents.indexOf(section);
|
IASTName name= findName(section,len,false);
|
||||||
assertTrue(offset >= 0);
|
|
||||||
final String selection = section.substring(0, len);
|
|
||||||
IASTName name= tu.getNodeSelector(null).findName(offset, len);
|
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
|
String selection = section.substring(0, len);
|
||||||
fail("Found unexpected \""+selection+"\": " + name.resolveBinding());
|
fail("Found unexpected \""+selection+"\": " + name.resolveBinding());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asserts that there is exactly one name at the given location and that
|
||||||
|
* it resolves to the given type of binding.
|
||||||
|
*/
|
||||||
|
public IASTImplicitName assertImplicitName(String section, int len, Class<?> bindingClass) {
|
||||||
|
IASTName name = findName(section,len,true);
|
||||||
|
final String selection = section.substring(0, len);
|
||||||
|
assertNotNull("did not find \""+selection+"\"", name);
|
||||||
|
|
||||||
|
assertInstance(name, IASTImplicitName.class);
|
||||||
|
IASTImplicitNameOwner owner = (IASTImplicitNameOwner) name.getParent();
|
||||||
|
IASTImplicitName[] implicits = owner.getImplicitNames();
|
||||||
|
assertNotNull(implicits);
|
||||||
|
|
||||||
|
if(implicits.length > 1) {
|
||||||
|
boolean found = false;
|
||||||
|
for(IASTImplicitName n : implicits) {
|
||||||
|
if(((ASTNode)n).getOffset() == ((ASTNode)name).getOffset()) {
|
||||||
|
assertFalse(found);
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertTrue(found);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(selection, name.getRawSignature());
|
||||||
|
IBinding binding = name.resolveBinding();
|
||||||
|
assertNotNull(binding);
|
||||||
|
assertInstance(binding, bindingClass);
|
||||||
|
return (IASTImplicitName) name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void assertNoImplicitName(String section, int len) {
|
||||||
|
IASTName name = findName(section,len,true);
|
||||||
|
final String selection = section.substring(0, len);
|
||||||
|
assertNull("found name \""+selection+"\"", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IASTImplicitName[] getImplicitNames(String section, int len) {
|
||||||
|
IASTName name = findName(section,len,true);
|
||||||
|
IASTImplicitNameOwner owner = (IASTImplicitNameOwner) name.getParent();
|
||||||
|
IASTImplicitName[] implicits = owner.getImplicitNames();
|
||||||
|
return implicits;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IASTName findName(String section, int len, boolean implicit) {
|
||||||
|
final int offset = contents.indexOf(section);
|
||||||
|
assertTrue(offset >= 0);
|
||||||
|
IASTNodeSelector selector = tu.getNodeSelector(null);
|
||||||
|
return implicit ? selector.findImplicitName(offset, len) : selector.findName(offset, len);
|
||||||
|
}
|
||||||
|
|
||||||
private String renderProblemID(int i) {
|
private String renderProblemID(int i) {
|
||||||
try {
|
try {
|
||||||
for (Field field : IProblemBinding.class.getDeclaredFields()) {
|
for (Field field : IProblemBinding.class.getDeclaredFields()) {
|
||||||
|
@ -536,10 +595,8 @@ public class AST2BaseTest extends BaseTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
private IBinding binding(String section, int len) {
|
private IBinding binding(String section, int len) {
|
||||||
final int offset = contents.indexOf(section);
|
IASTName name = findName(section, len,false);
|
||||||
assertTrue(offset >= 0);
|
|
||||||
final String selection = section.substring(0, len);
|
final String selection = section.substring(0, len);
|
||||||
IASTName name= tu.getNodeSelector(null).findName(offset, len);
|
|
||||||
assertNotNull("did not find \""+selection+"\"", name);
|
assertNotNull("did not find \""+selection+"\"", name);
|
||||||
assertEquals(selection, name.getRawSignature());
|
assertEquals(selection, name.getRawSignature());
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,385 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2009 IBM Corporation and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Mike Kucera (IBM)
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.core.parser.tests.ast2;
|
||||||
|
|
||||||
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||||
|
import org.eclipse.cdt.core.parser.ParserLanguage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class AST2CPPImplicitNameTests extends AST2BaseTest {
|
||||||
|
|
||||||
|
public AST2CPPImplicitNameTests() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public AST2CPPImplicitNameTests(String name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TestSuite suite() {
|
||||||
|
return suite(AST2CPPImplicitNameTests.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IASTImplicitName[] getImplicitNames(IASTTranslationUnit tu, String contents, String section, int len) {
|
||||||
|
final int offset = contents.indexOf(section);
|
||||||
|
assertTrue(offset >= 0);
|
||||||
|
IASTNodeSelector selector = tu.getNodeSelector(null);
|
||||||
|
IASTImplicitName firstImplicit = selector.findImplicitName(offset, len);
|
||||||
|
IASTImplicitNameOwner owner = (IASTImplicitNameOwner) firstImplicit.getParent();
|
||||||
|
IASTImplicitName[] implicits = owner.getImplicitNames();
|
||||||
|
return implicits;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// class point {
|
||||||
|
// int x,y;
|
||||||
|
// public:
|
||||||
|
// point operator+(point);
|
||||||
|
// point operator-(point);
|
||||||
|
// point operator-();
|
||||||
|
// point operator+=(int);
|
||||||
|
// };
|
||||||
|
// point operator*(point,point);
|
||||||
|
// point operator/(point,point);
|
||||||
|
//
|
||||||
|
// point test(point p) {
|
||||||
|
// p += 5;
|
||||||
|
// p + p - p * p / p;
|
||||||
|
// p << 6;
|
||||||
|
// -p;
|
||||||
|
// +p;
|
||||||
|
// }
|
||||||
|
public void testBinaryExpressions() throws Exception {
|
||||||
|
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
ba.assertImplicitName("+= 5", 2, ICPPMethod.class);
|
||||||
|
ba.assertImplicitName("+ p", 1, ICPPMethod.class);
|
||||||
|
ba.assertImplicitName("- p", 1, ICPPMethod.class);
|
||||||
|
ba.assertImplicitName("* p", 1, ICPPFunction.class);
|
||||||
|
ba.assertImplicitName("/ p", 1, ICPPFunction.class);
|
||||||
|
ba.assertNoImplicitName("<< 6", 2);
|
||||||
|
ba.assertImplicitName("-p;", 1, ICPPMethod.class);
|
||||||
|
ba.assertNoImplicitName("+p;", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//struct X {};
|
||||||
|
//
|
||||||
|
//template <class T> class auto_ptr {
|
||||||
|
// T* ptr;
|
||||||
|
//public:
|
||||||
|
// explicit auto_ptr(T* p = 0) : ptr(p) {}
|
||||||
|
// T& operator*() {return *ptr;}
|
||||||
|
//};
|
||||||
|
//
|
||||||
|
//void test() {
|
||||||
|
// auto_ptr<X> x(new X());
|
||||||
|
// *x; //1
|
||||||
|
// int *y;
|
||||||
|
// *y; //2
|
||||||
|
//}
|
||||||
|
public void testPointerDereference() throws Exception {
|
||||||
|
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
ba.assertImplicitName("*x;", 1, ICPPFunction.class);
|
||||||
|
ba.assertNoImplicitName("*y; //2", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// struct X {};
|
||||||
|
// struct Y {
|
||||||
|
// X x;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// X* operator&(X);
|
||||||
|
// X* operator&(Y);
|
||||||
|
//
|
||||||
|
// void test(X x, Y y) {
|
||||||
|
// X (Y::*px1) = &Y::x; // not the overloaded operator
|
||||||
|
// X *px2 = &y; // overloaded
|
||||||
|
// }
|
||||||
|
public void testPointerToMember() throws Exception {
|
||||||
|
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
ba.assertNoImplicitName("&Y::x;", 1);
|
||||||
|
ba.assertImplicitName("&y;", 1, ICPPFunction.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// class A {
|
||||||
|
// public:
|
||||||
|
// void doA() {}
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// class FirstLevelProxy {
|
||||||
|
// public:
|
||||||
|
// A* operator->() {A *a = new A(); return a;} // leaky
|
||||||
|
// void doFLP() {}
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// class SecondLevelProxy {
|
||||||
|
// public:
|
||||||
|
// FirstLevelProxy operator->() {FirstLevelProxy p; return p;}
|
||||||
|
// void doSLP() {}
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// int main(int argc, char **argv) {
|
||||||
|
// SecondLevelProxy p2;
|
||||||
|
// p2->doA();
|
||||||
|
// }
|
||||||
|
public void testArrowOperator() throws Exception {
|
||||||
|
String contents = getAboveComment();
|
||||||
|
IASTTranslationUnit tu = parse(contents, ParserLanguage.CPP);
|
||||||
|
CPPNameCollector col = new CPPNameCollector();
|
||||||
|
tu.accept(col);
|
||||||
|
|
||||||
|
IASTImplicitName[] implicits = getImplicitNames(tu, contents, "->doA();", 2);
|
||||||
|
|
||||||
|
assertNotNull(implicits);
|
||||||
|
assertEquals(2, implicits.length);
|
||||||
|
|
||||||
|
assertSame(implicits[1].getBinding(), col.getName(4).resolveBinding());
|
||||||
|
assertSame(implicits[0].getBinding(), col.getName(12).resolveBinding());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// struct A {
|
||||||
|
// int x;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// struct B {
|
||||||
|
// A& operator++(); // prefix
|
||||||
|
// };
|
||||||
|
// A operator++(B, int); // postfix
|
||||||
|
//
|
||||||
|
// void test(B p1, B p2) {
|
||||||
|
// (p1++).x; //1
|
||||||
|
// (++p1).x; //2
|
||||||
|
// }
|
||||||
|
public void testUnaryPrefixAndPostfix() throws Exception {
|
||||||
|
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
ba.assertImplicitName("++).x; //1", 2, ICPPFunction.class);
|
||||||
|
ba.assertImplicitName("++p1).x; //2", 2, ICPPMethod.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// struct A {};
|
||||||
|
// struct B {};
|
||||||
|
// struct C {};
|
||||||
|
// struct D {};
|
||||||
|
//
|
||||||
|
// C operator,(A,B);
|
||||||
|
// D operator,(C,C);
|
||||||
|
//
|
||||||
|
// int test(A a, B b, C c, D d) {
|
||||||
|
// // should be treated like (((a , b) , c) , d)
|
||||||
|
// a , b , c , d; // expr
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// int main(int argc, char **argv) {
|
||||||
|
// A a;
|
||||||
|
// B b;
|
||||||
|
// C c;
|
||||||
|
// D d;
|
||||||
|
// test(a , b , c , d); // func
|
||||||
|
// }
|
||||||
|
public void _testCommaOperator() throws Exception {
|
||||||
|
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
// expression lists are used in function calls but they should not resolve to the comma operator
|
||||||
|
ba.assertNoImplicitName(", b , c , d); // func", 1);
|
||||||
|
ba.assertNoImplicitName(", c , d); // func", 1);
|
||||||
|
ba.assertNoImplicitName(", d); // func", 1);
|
||||||
|
|
||||||
|
IASTImplicitName opAB = ba.assertImplicitName(", b , c , d; // expr", 1, ICPPFunction.class);
|
||||||
|
IASTImplicitName opCC = ba.assertImplicitName(", c , d; // expr", 1, ICPPFunction.class);
|
||||||
|
ba.assertNoImplicitName(", d; // expr", 1);
|
||||||
|
|
||||||
|
IASTTranslationUnit tu = ba.getTranslationUnit();
|
||||||
|
CPPNameCollector col = new CPPNameCollector();
|
||||||
|
tu.accept(col);
|
||||||
|
|
||||||
|
assertSame(opAB.resolveBinding(), col.getName(5).resolveBinding());
|
||||||
|
assertSame(opCC.resolveBinding(), col.getName(9).resolveBinding());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// struct X {
|
||||||
|
// int operator()(bool);
|
||||||
|
// int operator()();
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// int test(X x) {
|
||||||
|
// bool b = true;
|
||||||
|
// x(b); // 1
|
||||||
|
// x(); // 2
|
||||||
|
// }
|
||||||
|
public void testFunctionCallOperator() throws Exception {
|
||||||
|
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
|
||||||
|
IASTImplicitName n1 = ba.assertImplicitName("(b); // 1", 1, ICPPMethod.class);
|
||||||
|
IASTImplicitName n2 = ba.assertImplicitName("); // 1", 1, ICPPMethod.class);
|
||||||
|
assertSame(n1.resolveBinding(), n2.resolveBinding());
|
||||||
|
assertFalse(n1.isAlternate());
|
||||||
|
assertTrue(n2.isAlternate());
|
||||||
|
// there should be no overlap
|
||||||
|
ba.assertNoImplicitName("b); // 1", 1);
|
||||||
|
|
||||||
|
n1 = ba.assertImplicitName("(); // 2", 1, ICPPMethod.class);
|
||||||
|
n2 = ba.assertImplicitName("); // 2", 1, ICPPMethod.class);
|
||||||
|
assertSame(n1.resolveBinding(), n2.resolveBinding());
|
||||||
|
assertFalse(n1.isAlternate());
|
||||||
|
assertTrue(n2.isAlternate());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// struct A {};
|
||||||
|
// struct B {};
|
||||||
|
//
|
||||||
|
// // error operator= must be a non-static member function
|
||||||
|
// A& operator=(const B&, const A&);
|
||||||
|
//
|
||||||
|
// int main(int argc, char **argv) {
|
||||||
|
// A a;
|
||||||
|
// B b;
|
||||||
|
// b = a; // should not resolve
|
||||||
|
// }
|
||||||
|
public void testCopyAssignmentOperator() throws Exception {
|
||||||
|
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
ba.assertNoImplicitName("= a;", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// struct A {
|
||||||
|
// const char& operator[](int pos) const;
|
||||||
|
// char& operator[](int pos);
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// void func(const char& c);
|
||||||
|
// void func(char& c);
|
||||||
|
//
|
||||||
|
// void test(const A& x, A& y) {
|
||||||
|
// int q;
|
||||||
|
// func(x[0]); //1
|
||||||
|
// func(y[q]); //2
|
||||||
|
// }
|
||||||
|
public void testArraySubscript() throws Exception {
|
||||||
|
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
IASTImplicitName n1 = ba.assertImplicitName("[0]); //1", 1, ICPPMethod.class);
|
||||||
|
ba.assertNoImplicitName("0]); //1", 1);
|
||||||
|
IASTImplicitName n2 = ba.assertImplicitName("]); //1", 1, ICPPMethod.class);
|
||||||
|
assertSame(n1.resolveBinding(), n2.resolveBinding());
|
||||||
|
assertFalse(n1.isAlternate());
|
||||||
|
assertTrue(n2.isAlternate());
|
||||||
|
|
||||||
|
n1 = ba.assertImplicitName("[q]); //2", 1, ICPPMethod.class);
|
||||||
|
ba.assertNoImplicitName("q]); //2", 1);
|
||||||
|
n2 = ba.assertImplicitName("]); //2", 1, ICPPMethod.class);
|
||||||
|
assertSame(n1.resolveBinding(), n2.resolveBinding());
|
||||||
|
assertFalse(n1.isAlternate());
|
||||||
|
assertTrue(n2.isAlternate());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// struct X {
|
||||||
|
// ~X();
|
||||||
|
// void operator delete();
|
||||||
|
// void operator delete[]();
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// int test(X* x) {
|
||||||
|
// delete x;
|
||||||
|
// X* xs = new X[5];
|
||||||
|
// delete[] x;
|
||||||
|
// }
|
||||||
|
public void testDelete() throws Exception {
|
||||||
|
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
IASTImplicitName[] names = ba.getImplicitNames("delete x;", 6);
|
||||||
|
assertEquals(2, names.length);
|
||||||
|
IASTImplicitName destructor = names[0];
|
||||||
|
IASTImplicitName delete = names[1];
|
||||||
|
|
||||||
|
IASTTranslationUnit tu = ba.getTranslationUnit();
|
||||||
|
CPPNameCollector col = new CPPNameCollector();
|
||||||
|
tu.accept(col);
|
||||||
|
|
||||||
|
assertSame(col.getName(1).resolveBinding(), destructor.resolveBinding());
|
||||||
|
assertSame(col.getName(2).resolveBinding(), delete.resolveBinding());
|
||||||
|
|
||||||
|
names = ba.getImplicitNames("delete[] x;", 6);
|
||||||
|
assertEquals(1, names.length);
|
||||||
|
assertSame(col.getName(3).resolveBinding(), names[0].resolveBinding());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// struct X {}
|
||||||
|
// int test(X *x) {
|
||||||
|
// X* xs = new X[5];
|
||||||
|
// delete[] x;
|
||||||
|
// }
|
||||||
|
public void _testImplicitNewAndDelete() throws Exception {
|
||||||
|
BindingAssertionHelper ba = new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
ba.assertNoImplicitName("new X", 3);
|
||||||
|
ba.assertNoImplicitName("delete[]", 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// typedef long unsigned int size_t
|
||||||
|
// struct nothrow_t {};
|
||||||
|
// extern const nothrow_t nothrow;
|
||||||
|
// void *operator new(size_t, const nothrow_t&);
|
||||||
|
// void *operator new[](size_t, const nothrow_t&);
|
||||||
|
// void *operator new[](size_t, int, int);
|
||||||
|
// struct X {};
|
||||||
|
//
|
||||||
|
// int test() {
|
||||||
|
// X *fp = new (nothrow) X;
|
||||||
|
// int* p = new (nothrow) int[5];
|
||||||
|
// int* p2 = new (5,6) int[5];
|
||||||
|
// }
|
||||||
|
public void testNew() throws Exception {
|
||||||
|
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
IASTImplicitName n1 = ba.assertImplicitName("new (nothrow) X", 3, ICPPFunction.class);
|
||||||
|
IASTImplicitName n2 = ba.assertImplicitName("new (nothrow) int", 3, ICPPFunction.class);
|
||||||
|
IASTImplicitName n3 = ba.assertImplicitName("new (5,6) int", 3, ICPPFunction.class);
|
||||||
|
|
||||||
|
IASTTranslationUnit tu = ba.getTranslationUnit();
|
||||||
|
CPPNameCollector col = new CPPNameCollector();
|
||||||
|
tu.accept(col);
|
||||||
|
|
||||||
|
assertSame(col.getName(4).resolveBinding(), n1.resolveBinding());
|
||||||
|
assertSame(col.getName(9).resolveBinding(), n2.resolveBinding());
|
||||||
|
assertSame(col.getName(14).resolveBinding(), n3.resolveBinding());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// int test() {
|
||||||
|
// throw;
|
||||||
|
// }
|
||||||
|
public void testEmptyThrow() throws Exception {
|
||||||
|
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
|
||||||
|
ba.assertNoImplicitName("throw;", 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -27,6 +27,7 @@ public class DOMParserTestSuite extends TestCase {
|
||||||
suite.addTest(AST2Tests.suite());
|
suite.addTest(AST2Tests.suite());
|
||||||
suite.addTestSuite(GCCTests.class);
|
suite.addTestSuite(GCCTests.class);
|
||||||
suite.addTest(AST2CPPTests.suite());
|
suite.addTest(AST2CPPTests.suite());
|
||||||
|
suite.addTest(AST2CPPImplicitNameTests.suite());
|
||||||
suite.addTest(AST2TemplateTests.suite());
|
suite.addTest(AST2TemplateTests.suite());
|
||||||
suite.addTestSuite(QuickParser2Tests.class);
|
suite.addTestSuite(QuickParser2Tests.class);
|
||||||
suite.addTest(CompleteParser2Tests.suite());
|
suite.addTest(CompleteParser2Tests.suite());
|
||||||
|
@ -53,6 +54,7 @@ public class DOMParserTestSuite extends TestCase {
|
||||||
suite.addTest(FaultToleranceTests.suite());
|
suite.addTest(FaultToleranceTests.suite());
|
||||||
suite.addTest(LanguageExtensionsTest.suite());
|
suite.addTest(LanguageExtensionsTest.suite());
|
||||||
suite.addTest(ASTInactiveCodeTests.suite());
|
suite.addTest(ASTInactiveCodeTests.suite());
|
||||||
|
suite.addTest(AST2CPPImplicitNameTests.suite());
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,6 @@ package org.eclipse.cdt.core.suite;
|
||||||
import junit.framework.Test;
|
import junit.framework.Test;
|
||||||
import junit.framework.TestSuite;
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.cdescriptor.tests.CDescriptorTests;
|
|
||||||
import org.eclipse.cdt.core.cdescriptor.tests.CDescriptorOldTests;
|
|
||||||
import org.eclipse.cdt.core.internal.errorparsers.tests.ErrorParserTests;
|
import org.eclipse.cdt.core.internal.errorparsers.tests.ErrorParserTests;
|
||||||
import org.eclipse.cdt.core.internal.tests.PositionTrackerTests;
|
import org.eclipse.cdt.core.internal.tests.PositionTrackerTests;
|
||||||
import org.eclipse.cdt.core.internal.tests.ResourceLookupTests;
|
import org.eclipse.cdt.core.internal.tests.ResourceLookupTests;
|
||||||
|
@ -56,8 +54,8 @@ public class AutomatedIntegrationSuite extends TestSuite {
|
||||||
final AutomatedIntegrationSuite suite = new AutomatedIntegrationSuite();
|
final AutomatedIntegrationSuite suite = new AutomatedIntegrationSuite();
|
||||||
|
|
||||||
// Add all success tests
|
// Add all success tests
|
||||||
suite.addTest(CDescriptorTests.suite());
|
//suite.addTest(CDescriptorTests.suite());
|
||||||
suite.addTest(CDescriptorOldTests.suite());
|
//suite.addTest(CDescriptorOldTests.suite());
|
||||||
suite.addTest(ErrorParserTests.suite());
|
suite.addTest(ErrorParserTests.suite());
|
||||||
suite.addTest(ParserTestSuite.suite());
|
suite.addTest(ParserTestSuite.suite());
|
||||||
suite.addTest(AllCoreTests.suite());
|
suite.addTest(AllCoreTests.suite());
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
* IBM Corporation - initial API and implementation
|
* IBM Corporation - initial API and implementation
|
||||||
* Yuan Zhang / Beth Tibbitts (IBM Research)
|
* Yuan Zhang / Beth Tibbitts (IBM Research)
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
|
* Mike Kucera (IBM) - implicit names
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.dom.ast;
|
package org.eclipse.cdt.core.dom.ast;
|
||||||
|
|
||||||
|
@ -139,6 +140,23 @@ public abstract class ASTVisitor {
|
||||||
*/
|
*/
|
||||||
public boolean shouldVisitAmbiguousNodes = false;
|
public boolean shouldVisitAmbiguousNodes = false;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implicit names are created to allow implicit bindings to be resolved,
|
||||||
|
* normally they are not visited, set this flag to true to visit them.
|
||||||
|
* @since 5.1
|
||||||
|
*/
|
||||||
|
public boolean shouldVisitImplicitNames = false;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sometimes more than one implicit name is created for a binding,
|
||||||
|
* set this flag to true to visit more than one name for an implicit binding.
|
||||||
|
* @since 5.1
|
||||||
|
*/
|
||||||
|
public boolean shouldVisitImplicitNameAlternates = false;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a visitor that does not visit any kind of node per default.
|
* Creates a visitor that does not visit any kind of node per default.
|
||||||
*/
|
*/
|
||||||
|
@ -149,7 +167,9 @@ public abstract class ASTVisitor {
|
||||||
/**
|
/**
|
||||||
* Creates a visitor.
|
* Creates a visitor.
|
||||||
* @param visitNodes whether visitor is setup to visit all nodes per default, except
|
* @param visitNodes whether visitor is setup to visit all nodes per default, except
|
||||||
* ambiguous nodes ({@link #shouldVisitAmbiguousNodes}) and inactive nodes ({@link #includeInactiveNodes}).
|
* ambiguous nodes ({@link #shouldVisitAmbiguousNodes}),
|
||||||
|
* inactive nodes ({@link #includeInactiveNodes}),
|
||||||
|
* and implicit names (@link {@link #shouldVisitImplicitNames}).
|
||||||
* @since 5.1
|
* @since 5.1
|
||||||
*/
|
*/
|
||||||
public ASTVisitor(boolean visitNodes) {
|
public ASTVisitor(boolean visitNodes) {
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2009 IBM Corporation and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Mike Kucera (IBM) - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.core.dom.ast;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An implicit name is used to resolve uses of implicit bindings, such as overloaded operators.
|
||||||
|
*
|
||||||
|
* Implicit names are not generated unless they resolve to something.
|
||||||
|
*
|
||||||
|
* @see ASTVisitor#shouldVisitImplicitNames
|
||||||
|
* @since 5.1
|
||||||
|
*/
|
||||||
|
public interface IASTImplicitName extends IASTName {
|
||||||
|
|
||||||
|
public static final IASTImplicitName[] EMPTY_NAME_ARRAY = {};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* Redeclared with strengthened postcondition.
|
||||||
|
*
|
||||||
|
* Will not return null or a problem binding.
|
||||||
|
* Implicit names are not generated unless they resolve to something.
|
||||||
|
*/
|
||||||
|
public IBinding resolveBinding();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this node is an alternate.
|
||||||
|
*
|
||||||
|
* Sometimes more than one implicit name is generated for the same binding
|
||||||
|
* but with different offsets, when this happens the additional names
|
||||||
|
* generated are considered alternates.
|
||||||
|
*
|
||||||
|
* @see ASTVisitor#shouldVisitImplicitNameAlternates
|
||||||
|
*/
|
||||||
|
public boolean isAlternate();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convenience method that returns true if this
|
||||||
|
* name represents an overloaded operator.
|
||||||
|
*/
|
||||||
|
public boolean isOperator();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is not supported on implicit names.
|
||||||
|
*
|
||||||
|
* Implicit names are not copied when an AST is copied,
|
||||||
|
* instead the implicit names are regenerated when needed.
|
||||||
|
*
|
||||||
|
* @throws UnsupportedOperationException always
|
||||||
|
*/
|
||||||
|
IASTName copy() throws UnsupportedOperationException;
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2009 IBM Corporation and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Mike Kucera (IBM) - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.core.dom.ast;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An implicit name generated on demand.
|
||||||
|
* @since 5.1
|
||||||
|
*/
|
||||||
|
public interface IASTImplicitNameOwner extends IASTNode {
|
||||||
|
|
||||||
|
public static final ASTNodeProperty IMPLICIT_NAME =
|
||||||
|
new ASTNodeProperty("ICPPASTImplicitNameOwner.IMPLICIT_NAME"); //$NON-NLS-1$
|
||||||
|
|
||||||
|
|
||||||
|
public IASTImplicitName[] getImplicitNames();
|
||||||
|
|
||||||
|
}
|
|
@ -215,7 +215,7 @@ public interface IASTNode {
|
||||||
public boolean isActive();
|
public boolean isActive();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a copy of the tree rooted at this node.
|
* Returns a mutable copy of the tree rooted at this node.
|
||||||
* The following postconditions hold:
|
* The following postconditions hold:
|
||||||
*
|
*
|
||||||
* <code>
|
* <code>
|
||||||
|
@ -226,9 +226,11 @@ public interface IASTNode {
|
||||||
*
|
*
|
||||||
* Preprocessor nodes do not currently support being copied.
|
* Preprocessor nodes do not currently support being copied.
|
||||||
*
|
*
|
||||||
|
* Implicit name nodes are not copied, instead they can be regenerated
|
||||||
|
* if required.
|
||||||
|
*
|
||||||
* @since 5.1
|
* @since 5.1
|
||||||
* @throws UnsupportedOperationException if this node or one of its descendants
|
* @throws UnsupportedOperationException if this node or one of its descendants does not support copying
|
||||||
* does not support copying
|
|
||||||
*/
|
*/
|
||||||
public IASTNode copy();
|
public IASTNode copy();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,19 +23,42 @@ public interface IASTNodeSelector {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name for the exact given range, or <code>null</code> if there is no such node.
|
* Returns the name for the exact given range, or <code>null</code> if there is no such node.
|
||||||
|
* Will not return an implicit name.
|
||||||
*/
|
*/
|
||||||
IASTName findName(int offset, int length);
|
IASTName findName(int offset, int length);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the smallest name enclosing the given range, or <code>null</code> if there is no such node.
|
* Returns the smallest name enclosing the given range, or <code>null</code> if there is no such node.
|
||||||
|
* Will not return an implicit name.
|
||||||
*/
|
*/
|
||||||
IASTName findEnclosingName(int offset, int length);
|
IASTName findEnclosingName(int offset, int length);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the first name contained in the given range, or <code>null</code> if there is no such node.
|
* Returns the first name contained in the given range, or <code>null</code> if there is no such node.
|
||||||
|
* Will not return an implicit name.
|
||||||
*/
|
*/
|
||||||
IASTName findFirstContainedName(int offset, int length);
|
IASTName findFirstContainedName(int offset, int length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the implicit name for the exact given range, or <code>null</code> if there is no such node.
|
||||||
|
*
|
||||||
|
* Note that there can be more than one implicit name in the same location.
|
||||||
|
* The implicit name's parent can be used to get all the names at the location.
|
||||||
|
*
|
||||||
|
* @since 5.1
|
||||||
|
*/
|
||||||
|
IASTImplicitName findImplicitName(int offset, int length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the first implicit name enclosing the given range.
|
||||||
|
*
|
||||||
|
* Note that there can be more than one implicit name in the same location.
|
||||||
|
* The implicit name's parent can be used to get all the names at the location.
|
||||||
|
*
|
||||||
|
* @since 5.1
|
||||||
|
*/
|
||||||
|
IASTImplicitName findEnclosingImplicitName(int offset, int length);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the node for the exact given range, or <code>null</code> if there is no such node.
|
* Returns the node for the exact given range, or <code>null</code> if there is no such node.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2009 IBM Corporation and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Mike Kucera (IBM) - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 5.1
|
||||||
|
*/
|
||||||
|
public interface ICPPASTArraySubscriptExpression extends IASTArraySubscriptExpression, IASTImplicitNameOwner {
|
||||||
|
|
||||||
|
public ICPPASTArraySubscriptExpression copy();
|
||||||
|
}
|
|
@ -7,10 +7,12 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* John Camelon (IBM) - Initial API and implementation
|
* John Camelon (IBM) - Initial API and implementation
|
||||||
|
* Mike Kucera (IBM)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* C++ adds a few more binary expressions over C.
|
* C++ adds a few more binary expressions over C.
|
||||||
|
@ -18,7 +20,7 @@ import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
|
||||||
* @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.
|
||||||
*/
|
*/
|
||||||
public interface ICPPASTBinaryExpression extends IASTBinaryExpression {
|
public interface ICPPASTBinaryExpression extends IASTBinaryExpression, IASTImplicitNameOwner {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>op_pmdot</code> pointer-to-member field dereference.
|
* <code>op_pmdot</code> pointer-to-member field dereference.
|
||||||
|
|
|
@ -7,11 +7,13 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* John Camelon (IBM) - Initial API and implementation
|
* John Camelon (IBM) - Initial API and implementation
|
||||||
|
* Mike Kucera (IBM)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface represents a delete expression. delete [] operand;
|
* This interface represents a delete expression. delete [] operand;
|
||||||
|
@ -19,7 +21,7 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
* @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.
|
||||||
*/
|
*/
|
||||||
public interface ICPPASTDeleteExpression extends IASTExpression {
|
public interface ICPPASTDeleteExpression extends IASTExpression, IASTImplicitNameOwner {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>OPERAND</code> is the expression representing the pointer being
|
* <code>OPERAND</code> is the expression representing the pointer being
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2009 IBM Corporation and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Mike Kucera (IBM) - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 5.1
|
||||||
|
*/
|
||||||
|
public interface ICPPASTExpressionList extends IASTExpressionList, IASTImplicitNameOwner {
|
||||||
|
|
||||||
|
public ICPPASTExpressionList copy();
|
||||||
|
}
|
|
@ -7,10 +7,12 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* John Camelon (IBM) - Initial API and implementation
|
* John Camelon (IBM) - Initial API and implementation
|
||||||
|
* Mike Kucera (IBM)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
|
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Certain field references in C++ require the use the keyword template to
|
* Certain field references in C++ require the use the keyword template to
|
||||||
|
@ -19,7 +21,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
|
||||||
* @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.
|
||||||
*/
|
*/
|
||||||
public interface ICPPASTFieldReference extends IASTFieldReference {
|
public interface ICPPASTFieldReference extends IASTFieldReference, IASTImplicitNameOwner {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Was template keyword used?
|
* Was template keyword used?
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2009 IBM Corporation and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Mike Kucera (IBM) - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 5.1
|
||||||
|
*/
|
||||||
|
public interface ICPPASTFunctionCallExpression extends IASTFunctionCallExpression, IASTImplicitNameOwner {
|
||||||
|
|
||||||
|
ICPPASTFunctionCallExpression copy();
|
||||||
|
}
|
|
@ -8,12 +8,14 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* John Camelon (IBM) - Initial API and implementation
|
* John Camelon (IBM) - Initial API and implementation
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
|
* Mike Kucera (IBM)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface represents a new expression.
|
* This interface represents a new expression.
|
||||||
|
@ -21,7 +23,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||||
* @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.
|
||||||
*/
|
*/
|
||||||
public interface ICPPASTNewExpression extends IASTExpression {
|
public interface ICPPASTNewExpression extends IASTExpression, IASTImplicitNameOwner {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is this a ::new expression?
|
* Is this a ::new expression?
|
||||||
|
@ -110,6 +112,14 @@ public interface ICPPASTNewExpression extends IASTExpression {
|
||||||
*/
|
*/
|
||||||
public void setIsNewTypeId(boolean value);
|
public void setIsNewTypeId(boolean value);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this expression is allocating an array.
|
||||||
|
* @since 5.1
|
||||||
|
*/
|
||||||
|
public boolean isArrayAllocation();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expressions that go inside array brackets.
|
* Expressions that go inside array brackets.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -7,16 +7,18 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* John Camelon (IBM) - Initial API and implementation
|
* John Camelon (IBM) - Initial API and implementation
|
||||||
|
* Mike Kucera
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @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.
|
||||||
*/
|
*/
|
||||||
public interface ICPPASTUnaryExpression extends IASTUnaryExpression {
|
public interface ICPPASTUnaryExpression extends IASTUnaryExpression, IASTImplicitNameOwner {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>op_throw</code> throw exp
|
* <code>op_throw</code> throw exp
|
||||||
|
|
|
@ -156,4 +156,11 @@ public interface ICPPNodeFactory extends INodeFactory {
|
||||||
public ICPPASTTemplatedTypeTemplateParameter newTemplatedTypeTemplateParameter(IASTName name, IASTExpression defaultValue);
|
public ICPPASTTemplatedTypeTemplateParameter newTemplatedTypeTemplateParameter(IASTName name, IASTExpression defaultValue);
|
||||||
|
|
||||||
public IASTProblemTypeId newProblemTypeId(IASTProblem problem);
|
public IASTProblemTypeId newProblemTypeId(IASTProblem problem);
|
||||||
|
|
||||||
|
public ICPPASTExpressionList newExpressionList();
|
||||||
|
|
||||||
|
public ICPPASTArraySubscriptExpression newArraySubscriptExpression(IASTExpression arrayExpr, IASTExpression subscript);
|
||||||
|
|
||||||
|
public ICPPASTFunctionCallExpression newFunctionCallExpression(IASTExpression idExpr, IASTExpression argList);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
package org.eclipse.cdt.internal.core.dom.parser;
|
package org.eclipse.cdt.internal.core.dom.parser;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||||
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.IASTNodeSelector;
|
import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
|
||||||
|
@ -119,72 +120,51 @@ public class ASTNodeSelector implements IASTNodeSelector {
|
||||||
return nodeSpec.getBestNode();
|
return nodeSpec.getBestNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getFirstContainedNode(int, int)
|
|
||||||
*/
|
|
||||||
public IASTNode findFirstContainedNode(int offset, int length) {
|
public IASTNode findFirstContainedNode(int offset, int length) {
|
||||||
return findNode(offset, length, Relation.FIRST_CONTAINED, IASTNode.class);
|
return findNode(offset, length, Relation.FIRST_CONTAINED, IASTNode.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getNode(int, int)
|
|
||||||
*/
|
|
||||||
public IASTNode findNode(int offset, int length) {
|
public IASTNode findNode(int offset, int length) {
|
||||||
return findNode(offset, length, Relation.EXACT_MATCH, IASTNode.class);
|
return findNode(offset, length, Relation.EXACT_MATCH, IASTNode.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getSurroundingNode(int, int)
|
|
||||||
*/
|
|
||||||
public IASTNode findEnclosingNode(int offset, int length) {
|
public IASTNode findEnclosingNode(int offset, int length) {
|
||||||
return findNode(offset, length, Relation.ENCLOSING, IASTNode.class);
|
return findNode(offset, length, Relation.ENCLOSING, IASTNode.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getFirstContainedNode(int, int)
|
|
||||||
*/
|
|
||||||
public IASTNode findFirstContainedNodeInExpansion(int offset, int length) {
|
public IASTNode findFirstContainedNodeInExpansion(int offset, int length) {
|
||||||
return findNode(offset, length, Relation.FIRST_CONTAINED, IASTNode.class, true);
|
return findNode(offset, length, Relation.FIRST_CONTAINED, IASTNode.class, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getNode(int, int)
|
|
||||||
*/
|
|
||||||
public IASTNode findNodeInExpansion(int offset, int length) {
|
public IASTNode findNodeInExpansion(int offset, int length) {
|
||||||
return findNode(offset, length, Relation.EXACT_MATCH, IASTNode.class, true);
|
return findNode(offset, length, Relation.EXACT_MATCH, IASTNode.class, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getSurroundingNode(int, int)
|
|
||||||
*/
|
|
||||||
public IASTNode findEnclosingNodeInExpansion(int offset, int length) {
|
public IASTNode findEnclosingNodeInExpansion(int offset, int length) {
|
||||||
return findNode(offset, length, Relation.ENCLOSING, IASTNode.class, true);
|
return findNode(offset, length, Relation.ENCLOSING, IASTNode.class, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getFirstContainedNode(int, int)
|
|
||||||
*/
|
|
||||||
public IASTName findFirstContainedName(int offset, int length) {
|
public IASTName findFirstContainedName(int offset, int length) {
|
||||||
return findNode(offset, length, Relation.FIRST_CONTAINED, IASTName.class);
|
return findNode(offset, length, Relation.FIRST_CONTAINED, IASTName.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getNode(int, int)
|
|
||||||
*/
|
|
||||||
public IASTName findName(int offset, int length) {
|
public IASTName findName(int offset, int length) {
|
||||||
return findNode(offset, length, Relation.EXACT_MATCH, IASTName.class);
|
return findNode(offset, length, Relation.EXACT_MATCH, IASTName.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getSurroundingNode(int, int)
|
|
||||||
*/
|
|
||||||
public IASTName findEnclosingName(int offset, int length) {
|
public IASTName findEnclosingName(int offset, int length) {
|
||||||
return findNode(offset, length, Relation.ENCLOSING, IASTName.class);
|
return findNode(offset, length, Relation.ENCLOSING, IASTName.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
public IASTImplicitName findImplicitName(int offset, int length) {
|
||||||
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#findSurrundingMacroExpansion(int, int)
|
return findNode(offset, length, Relation.EXACT_MATCH, IASTImplicitName.class);
|
||||||
*/
|
}
|
||||||
|
|
||||||
|
public IASTImplicitName findEnclosingImplicitName(int offset, int length) {
|
||||||
|
return findNode(offset, length, Relation.ENCLOSING, IASTImplicitName.class);
|
||||||
|
}
|
||||||
|
|
||||||
public IASTPreprocessorMacroExpansion findEnclosingMacroExpansion(int offset, int length) {
|
public IASTPreprocessorMacroExpansion findEnclosingMacroExpansion(int offset, int length) {
|
||||||
return findNode(offset, length, Relation.ENCLOSING, IASTPreprocessorMacroExpansion.class);
|
return findNode(offset, length, Relation.ENCLOSING, IASTPreprocessorMacroExpansion.class);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.core.dom.parser;
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTGenericVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTGenericVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||||
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.IASTPointerOperator;
|
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||||
|
@ -31,6 +32,10 @@ public class FindNodeForOffsetAction extends ASTGenericVisitor {
|
||||||
shouldVisitNames = true;
|
shouldVisitNames = true;
|
||||||
shouldVisitDeclarations= true;
|
shouldVisitDeclarations= true;
|
||||||
includeInactiveNodes= true;
|
includeInactiveNodes= true;
|
||||||
|
|
||||||
|
// only visit implicit names if asked
|
||||||
|
shouldVisitImplicitNames =
|
||||||
|
shouldVisitImplicitNameAlternates = nodeSpec.requiresClass(IASTImplicitName.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,23 +1,26 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2004, 2008 IBM Corporation and others.
|
* Copyright (c) 2004, 2009 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
|
* John Camelon (IBM) - Initial API and implementation
|
||||||
|
* Mike Kucera (IBM)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
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.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;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTArraySubscriptExpression;
|
||||||
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.internal.core.dom.parser.ASTNode;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
|
@ -28,11 +31,12 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||||
/**
|
/**
|
||||||
* @author jcamelon
|
* @author jcamelon
|
||||||
*/
|
*/
|
||||||
public class CPPASTArraySubscriptExpression extends ASTNode implements IASTArraySubscriptExpression, IASTAmbiguityParent {
|
public class CPPASTArraySubscriptExpression extends ASTNode implements ICPPASTArraySubscriptExpression, IASTAmbiguityParent {
|
||||||
|
|
||||||
private IASTExpression subscriptExp;
|
private IASTExpression subscriptExp;
|
||||||
private IASTExpression arrayExpression;
|
private IASTExpression arrayExpression;
|
||||||
|
|
||||||
|
private IASTImplicitName[] implicitNames = null;
|
||||||
|
|
||||||
public CPPASTArraySubscriptExpression() {
|
public CPPASTArraySubscriptExpression() {
|
||||||
}
|
}
|
||||||
|
@ -77,6 +81,41 @@ public class CPPASTArraySubscriptExpression extends ASTNode implements IASTArray
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IASTImplicitName[] getImplicitNames() {
|
||||||
|
if(implicitNames == null) {
|
||||||
|
ICPPFunction overload = getOverload();
|
||||||
|
if(overload == null)
|
||||||
|
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||||
|
|
||||||
|
// create separate implicit names for the two brackets
|
||||||
|
CPPASTImplicitName n1 = new CPPASTImplicitName(OverloadableOperator.BRACKET, this);
|
||||||
|
n1.setBinding(overload);
|
||||||
|
n1.computeOperatorOffsets(arrayExpression, true);
|
||||||
|
|
||||||
|
CPPASTImplicitName n2 = new CPPASTImplicitName(OverloadableOperator.BRACKET, this);
|
||||||
|
n2.setBinding(overload);
|
||||||
|
n2.computeOperatorOffsets(subscriptExp, true);
|
||||||
|
n2.setAlternate(true);
|
||||||
|
|
||||||
|
implicitNames = new IASTImplicitName[] { n1, n2 };
|
||||||
|
}
|
||||||
|
|
||||||
|
return implicitNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ICPPFunction getOverload() {
|
||||||
|
IType type1 = arrayExpression.getExpressionType();
|
||||||
|
IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
|
||||||
|
if (ultimateType1 instanceof IProblemBinding) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (ultimateType1 instanceof ICPPClassType) {
|
||||||
|
return CPPSemantics.findOperator(this, (ICPPClassType) ultimateType1);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept( ASTVisitor action ){
|
public boolean accept( ASTVisitor action ){
|
||||||
if( action.shouldVisitExpressions ){
|
if( action.shouldVisitExpressions ){
|
||||||
|
@ -88,9 +127,18 @@ public class CPPASTArraySubscriptExpression extends ASTNode implements IASTArray
|
||||||
}
|
}
|
||||||
if( arrayExpression != null )
|
if( arrayExpression != null )
|
||||||
if( !arrayExpression.accept( action ) ) return false;
|
if( !arrayExpression.accept( action ) ) return false;
|
||||||
|
|
||||||
|
IASTImplicitName[] implicits = action.shouldVisitImplicitNames ? getImplicitNames() : null;
|
||||||
|
|
||||||
|
if(implicits != null && implicits.length > 0)
|
||||||
|
if(!implicits[0].accept(action)) return false;
|
||||||
|
|
||||||
if( subscriptExp != null )
|
if( subscriptExp != null )
|
||||||
if( !subscriptExp.accept( action ) ) return false;
|
if( !subscriptExp.accept( action ) ) return false;
|
||||||
|
|
||||||
|
if(implicits != null && implicits.length > 0)
|
||||||
|
if(!implicits[1].accept(action)) return false;
|
||||||
|
|
||||||
if( action.shouldVisitExpressions ){
|
if( action.shouldVisitExpressions ){
|
||||||
switch( action.leave( this ) ){
|
switch( action.leave( this ) ){
|
||||||
case ASTVisitor.PROCESS_ABORT : return false;
|
case ASTVisitor.PROCESS_ABORT : return false;
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2004, 2008 IBM Corporation and others.
|
* Copyright (c) 2004, 2009 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
|
* John Camelon (IBM) - Initial API and implementation
|
||||||
|
* Mike Kucera (IBM)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
|
@ -14,6 +15,7 @@ import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
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;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IEnumeration;
|
import org.eclipse.cdt.core.dom.ast.IEnumeration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||||
|
@ -31,17 +33,17 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author jcamelon
|
|
||||||
*/
|
|
||||||
public class CPPASTBinaryExpression extends ASTNode implements
|
|
||||||
ICPPASTBinaryExpression, IASTAmbiguityParent {
|
|
||||||
|
|
||||||
private int op;
|
public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpression, IASTAmbiguityParent {
|
||||||
|
|
||||||
|
private int op;
|
||||||
private IASTExpression operand1;
|
private IASTExpression operand1;
|
||||||
private IASTExpression operand2;
|
private IASTExpression operand2;
|
||||||
private IType type;
|
private IType type;
|
||||||
|
|
||||||
|
private IASTImplicitName[] implicitNames = null;
|
||||||
|
|
||||||
|
|
||||||
public CPPASTBinaryExpression() {
|
public CPPASTBinaryExpression() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,6 +97,24 @@ public class CPPASTBinaryExpression extends ASTNode implements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IASTImplicitName[] getImplicitNames() {
|
||||||
|
if(implicitNames == null) {
|
||||||
|
ICPPFunction overload = getOverload();
|
||||||
|
if(overload == null)
|
||||||
|
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||||
|
|
||||||
|
CPPASTImplicitName operatorName = new CPPASTImplicitName(overload.getNameCharArray(), this);
|
||||||
|
operatorName.setBinding(overload);
|
||||||
|
operatorName.setOperator(true);
|
||||||
|
operatorName.computeOperatorOffsets(operand1, true);
|
||||||
|
implicitNames = new IASTImplicitName[] { operatorName };
|
||||||
|
}
|
||||||
|
|
||||||
|
return implicitNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept( ASTVisitor action ){
|
public boolean accept( ASTVisitor action ){
|
||||||
if( action.shouldVisitExpressions ){
|
if( action.shouldVisitExpressions ){
|
||||||
|
@ -106,6 +126,13 @@ public class CPPASTBinaryExpression extends ASTNode implements
|
||||||
}
|
}
|
||||||
|
|
||||||
if( operand1 != null ) if( !operand1.accept( action ) ) return false;
|
if( operand1 != null ) if( !operand1.accept( action ) ) return false;
|
||||||
|
|
||||||
|
if(action.shouldVisitImplicitNames) {
|
||||||
|
for(IASTImplicitName name : getImplicitNames()) {
|
||||||
|
if(!name.accept(action)) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( operand2 != null ) if( !operand2.accept( action ) ) return false;
|
if( operand2 != null ) if( !operand2.accept( action ) ) return false;
|
||||||
|
|
||||||
if(action.shouldVisitExpressions ){
|
if(action.shouldVisitExpressions ){
|
||||||
|
@ -140,9 +167,41 @@ public class CPPASTBinaryExpression extends ASTNode implements
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IType createExpressionType() {
|
|
||||||
|
|
||||||
// Check for overloaded operator.
|
|
||||||
|
/**
|
||||||
|
* Returns the operator function that is invoked or null
|
||||||
|
* if it is actually a built-in operator.
|
||||||
|
*/
|
||||||
|
public ICPPFunction getOverload() {
|
||||||
|
// try to find a method
|
||||||
|
IType type1 = getOperand1().getExpressionType();
|
||||||
|
IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
|
||||||
|
if (ultimateType1 instanceof IProblemBinding) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (ultimateType1 instanceof ICPPClassType) {
|
||||||
|
ICPPFunction operator = CPPSemantics.findOperator(this, (ICPPClassType) ultimateType1);
|
||||||
|
if (operator != null)
|
||||||
|
return operator;
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to find a function
|
||||||
|
if(op != op_assign) {
|
||||||
|
IType type2 = getOperand2().getExpressionType();
|
||||||
|
IType ultimateType2 = SemanticUtil.getUltimateTypeUptoPointers(type2);
|
||||||
|
if (ultimateType2 instanceof IProblemBinding)
|
||||||
|
return null;
|
||||||
|
if (isUserDefined(ultimateType1) || isUserDefined(ultimateType2))
|
||||||
|
return CPPSemantics.findOverloadedOperator(this);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private IType createExpressionType() {
|
||||||
|
// Check for overloaded operator.
|
||||||
IType type1 = getOperand1().getExpressionType();
|
IType type1 = getOperand1().getExpressionType();
|
||||||
IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
|
IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
|
||||||
if (ultimateType1 instanceof IProblemBinding) {
|
if (ultimateType1 instanceof IProblemBinding) {
|
||||||
|
@ -158,13 +217,13 @@ public class CPPASTBinaryExpression extends ASTNode implements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IType type2 = getOperand2().getExpressionType();
|
IType type2 = getOperand2().getExpressionType();
|
||||||
IType ultimateType2 = SemanticUtil.getUltimateTypeUptoPointers(type2);
|
IType ultimateType2 = SemanticUtil.getUltimateTypeUptoPointers(type2);
|
||||||
if (ultimateType2 instanceof IProblemBinding) {
|
if (ultimateType2 instanceof IProblemBinding) {
|
||||||
return type2;
|
return type2;
|
||||||
}
|
}
|
||||||
if (ultimateType1 instanceof ICPPClassType || ultimateType1 instanceof IEnumeration ||
|
if(op != op_assign && isUserDefined(ultimateType1) || isUserDefined(ultimateType2)) {
|
||||||
ultimateType2 instanceof ICPPClassType || ultimateType2 instanceof IEnumeration) {
|
|
||||||
// If at least one of the types is user defined, the operator can be overloaded.
|
// If at least one of the types is user defined, the operator can be overloaded.
|
||||||
ICPPFunction operator = CPPSemantics.findOverloadedOperator(this);
|
ICPPFunction operator = CPPSemantics.findOverloadedOperator(this);
|
||||||
if (operator != null) {
|
if (operator != null) {
|
||||||
|
@ -176,6 +235,7 @@ public class CPPASTBinaryExpression extends ASTNode implements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
final int op = getOperator();
|
final int op = getOperator();
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case IASTBinaryExpression.op_lessEqual:
|
case IASTBinaryExpression.op_lessEqual:
|
||||||
|
@ -215,4 +275,10 @@ public class CPPASTBinaryExpression extends ASTNode implements
|
||||||
}
|
}
|
||||||
return type1;
|
return type1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static boolean isUserDefined(IType type) {
|
||||||
|
return type instanceof ICPPClassType || type instanceof IEnumeration;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +1,40 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2004, 2008 IBM Corporation and others.
|
* Copyright (c) 2004, 2009 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
|
* John Camelon (IBM) - Initial API and implementation
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
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.IASTExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||||
|
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.cpp.ICPPASTDeleteExpression;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author jcamelon
|
|
||||||
*/
|
|
||||||
public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpression {
|
public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpression {
|
||||||
|
|
||||||
private IASTExpression operand;
|
private IASTExpression operand;
|
||||||
private boolean isGlobal;
|
private boolean isGlobal;
|
||||||
private boolean isVectored;
|
private boolean isVectored;
|
||||||
|
|
||||||
|
private IASTImplicitName[] implicitNames = null;
|
||||||
|
|
||||||
|
|
||||||
public CPPASTDeleteExpression() {
|
public CPPASTDeleteExpression() {
|
||||||
}
|
}
|
||||||
|
@ -77,6 +86,75 @@ public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpr
|
||||||
return isVectored;
|
return isVectored;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to resolve both the destructor and the operator delete.
|
||||||
|
*/
|
||||||
|
public IASTImplicitName[] getImplicitNames() {
|
||||||
|
if(implicitNames == null) {
|
||||||
|
ICPPClassType nestedType = getNestedClassType();
|
||||||
|
if(nestedType == null)
|
||||||
|
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||||
|
|
||||||
|
List<IASTImplicitName> names = new ArrayList<IASTImplicitName>();
|
||||||
|
|
||||||
|
if(!isVectored) {
|
||||||
|
ICPPFunction destructor = CPPSemantics.findDestructor(this, nestedType);
|
||||||
|
if(destructor != null) {
|
||||||
|
CPPASTImplicitName destructorName = new CPPASTImplicitName(destructor.getNameCharArray(), this);
|
||||||
|
destructorName.setBinding(destructor);
|
||||||
|
destructorName.computeOperatorOffsets(operand, false);
|
||||||
|
names.add(destructorName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!isGlobal) {
|
||||||
|
ICPPFunction deleteOperator = findOperatorFunction(nestedType);
|
||||||
|
if(deleteOperator != null) {
|
||||||
|
CPPASTImplicitName deleteName = new CPPASTImplicitName(deleteOperator.getNameCharArray(), this);
|
||||||
|
deleteName.setOperator(true);
|
||||||
|
deleteName.setBinding(deleteOperator);
|
||||||
|
deleteName.computeOperatorOffsets(operand, false);
|
||||||
|
names.add(deleteName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(names.isEmpty())
|
||||||
|
implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||||
|
else
|
||||||
|
implicitNames = names.toArray(new IASTImplicitName[names.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return implicitNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private ICPPClassType getNestedClassType() {
|
||||||
|
IType type1 = operand.getExpressionType();
|
||||||
|
IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
|
||||||
|
if(ultimateType1 instanceof IPointerType) {
|
||||||
|
try {
|
||||||
|
IType classType = ((IPointerType)ultimateType1).getType();
|
||||||
|
if(classType instanceof ICPPClassType)
|
||||||
|
return (ICPPClassType) classType;
|
||||||
|
} catch (DOMException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO this code is repeated in too many places
|
||||||
|
private ICPPFunction findOperatorFunction(IType type) {
|
||||||
|
if(type instanceof ICPPClassType) {
|
||||||
|
ICPPFunction operator = CPPSemantics.findOperator(this, (ICPPClassType) type);
|
||||||
|
if(operator != null)
|
||||||
|
return operator;
|
||||||
|
return CPPSemantics.findOverloadedOperator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept( ASTVisitor action ){
|
public boolean accept( ASTVisitor action ){
|
||||||
if( action.shouldVisitExpressions ){
|
if( action.shouldVisitExpressions ){
|
||||||
|
@ -87,6 +165,12 @@ public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(action.shouldVisitImplicitNames) {
|
||||||
|
for(IASTImplicitName name : getImplicitNames()) {
|
||||||
|
if(!name.accept(action)) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( operand != null ) if( !operand.accept( action ) ) return false;
|
if( operand != null ) if( !operand.accept( action ) ) return false;
|
||||||
|
|
||||||
if( action.shouldVisitExpressions ){
|
if( action.shouldVisitExpressions ){
|
||||||
|
|
|
@ -1,29 +1,43 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2004, 2008 IBM Corporation and others.
|
* Copyright (c) 2004, 2009 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
|
* John Camelon (IBM) - Initial API and implementation
|
||||||
|
* Mike Kucera (IBM) - implicit names
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
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.ASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IEnumeration;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpressionList;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||||
|
|
||||||
|
|
||||||
|
public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionList, IASTAmbiguityParent {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caution: may contain nulls.
|
||||||
|
* @see CPPASTExpressionList#computeImplicitNames
|
||||||
|
*/
|
||||||
|
private IASTImplicitName[] implicitNames;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author jcamelon
|
|
||||||
*/
|
|
||||||
public class CPPASTExpressionList extends ASTNode implements
|
|
||||||
IASTExpressionList, IASTAmbiguityParent {
|
|
||||||
|
|
||||||
public CPPASTExpressionList copy() {
|
public CPPASTExpressionList copy() {
|
||||||
CPPASTExpressionList copy = new CPPASTExpressionList();
|
CPPASTExpressionList copy = new CPPASTExpressionList();
|
||||||
|
@ -59,9 +73,19 @@ public class CPPASTExpressionList extends ASTNode implements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IASTExpression [] exps = getExpressions();
|
IASTExpression[] exps = getExpressions();
|
||||||
for( int i = 0; i < exps.length; i++ )
|
IASTImplicitName[] implicits = action.shouldVisitImplicitNames ? computeImplicitNames() : null;
|
||||||
if( !exps[i].accept( action ) ) return false;
|
|
||||||
|
for(int i = 0, n = exps.length; i < n; i++) {
|
||||||
|
if(!exps[i].accept(action)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(i < n-1 && implicits != null && implicits[i] != null) {
|
||||||
|
if(!implicits[i].accept(action)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( action.shouldVisitExpressions ){
|
if( action.shouldVisitExpressions ){
|
||||||
switch( action.leave( this ) ){
|
switch( action.leave( this ) ){
|
||||||
|
@ -73,6 +97,77 @@ public class CPPASTExpressionList extends ASTNode implements
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of implicit names where each element of the array
|
||||||
|
* represents a comma between the expression in the same index and the
|
||||||
|
* next expression. This array contains null elements as placeholders
|
||||||
|
* for commas that do not resolve to overloaded operators.
|
||||||
|
*/
|
||||||
|
private IASTImplicitName[] computeImplicitNames() {
|
||||||
|
if(implicitNames == null) {
|
||||||
|
IASTExpression[] exprs = getExpressions(); // has to be at least two
|
||||||
|
if(exprs.length < 2)
|
||||||
|
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||||
|
|
||||||
|
implicitNames = new IASTImplicitName[exprs.length-1];
|
||||||
|
|
||||||
|
if(getPropertyInParent() == IASTFunctionCallExpression.PARAMETERS)
|
||||||
|
return implicitNames;
|
||||||
|
|
||||||
|
for(int i = 0, n = exprs.length-1; i < n; i++) {
|
||||||
|
ICPPFunction overload = getOverload(i);
|
||||||
|
if(overload != null) {
|
||||||
|
CPPASTImplicitName operatorName = new CPPASTImplicitName(OverloadableOperator.COMMA, this);
|
||||||
|
operatorName.setBinding(overload);
|
||||||
|
operatorName.computeOperatorOffsets(exprs[i], true);
|
||||||
|
implicitNames[i] = operatorName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return implicitNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public IASTImplicitName[] getImplicitNames() {
|
||||||
|
return (IASTImplicitName[])ArrayUtil.removeNulls(IASTImplicitName.class, computeImplicitNames());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param index the index of the first argument
|
||||||
|
*/
|
||||||
|
private ICPPFunction getOverload(int index) {
|
||||||
|
// try to find a method
|
||||||
|
IASTExpression[] exprs = getExpressions();
|
||||||
|
|
||||||
|
IType type1 = exprs[index].getExpressionType();
|
||||||
|
IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
|
||||||
|
if (ultimateType1 instanceof IProblemBinding) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (ultimateType1 instanceof ICPPClassType) {
|
||||||
|
ICPPFunction operator = CPPSemantics.findOperatorComma(this, index, (ICPPClassType) ultimateType1);
|
||||||
|
if (operator != null)
|
||||||
|
return operator;
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to find a function
|
||||||
|
IType type2 = exprs[index+1].getExpressionType();
|
||||||
|
IType ultimateType2 = SemanticUtil.getUltimateTypeUptoPointers(type2);
|
||||||
|
if (ultimateType2 instanceof IProblemBinding)
|
||||||
|
return null;
|
||||||
|
if (isUserDefined(ultimateType1) || isUserDefined(ultimateType2))
|
||||||
|
return CPPSemantics.findOverloadedOperator(this, index);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isUserDefined(IType type) {
|
||||||
|
return type instanceof ICPPClassType || type instanceof IEnumeration;
|
||||||
|
}
|
||||||
|
|
||||||
public void replace(IASTNode child, IASTNode other) {
|
public void replace(IASTNode child, IASTNode other) {
|
||||||
if( expressions == null ) return;
|
if( expressions == null ) return;
|
||||||
for (int i = 0; i < expressions.length; ++i) {
|
for (int i = 0; i < expressions.length; ++i) {
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2004, 2008 IBM Corporation and others.
|
* Copyright (c) 2004, 2009 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
|
* John Camelon (IBM) - Initial API and implementation
|
||||||
* Bryan Wilkinson (QNX)
|
* Bryan Wilkinson (QNX)
|
||||||
|
* Mike Kucera (IBM)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
|
@ -18,6 +19,8 @@ import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTCompletionContext;
|
import org.eclipse.cdt.core.dom.ast.IASTCompletionContext;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
||||||
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.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
|
@ -27,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IVariable;
|
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
||||||
|
@ -36,13 +40,14 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
||||||
* @author jcamelon
|
* @author jcamelon
|
||||||
*/
|
*/
|
||||||
public class CPPASTFieldReference extends ASTNode implements
|
public class CPPASTFieldReference extends ASTNode implements
|
||||||
ICPPASTFieldReference, IASTAmbiguityParent, IASTCompletionContext {
|
ICPPASTFieldReference, IASTAmbiguityParent, IASTCompletionContext, IASTImplicitNameOwner {
|
||||||
|
|
||||||
private boolean isTemplate;
|
private boolean isTemplate;
|
||||||
private IASTExpression owner;
|
private IASTExpression owner;
|
||||||
private IASTName name;
|
private IASTName name;
|
||||||
private boolean isDeref;
|
private boolean isDeref;
|
||||||
|
|
||||||
|
private IASTImplicitName[] implicitNames = null;
|
||||||
|
|
||||||
public CPPASTFieldReference() {
|
public CPPASTFieldReference() {
|
||||||
}
|
}
|
||||||
|
@ -106,6 +111,34 @@ public class CPPASTFieldReference extends ASTNode implements
|
||||||
isDeref = value;
|
isDeref = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IASTImplicitName[] getImplicitNames() {
|
||||||
|
if(implicitNames == null) {
|
||||||
|
if(!isDeref)
|
||||||
|
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||||
|
|
||||||
|
// collect the function bindings
|
||||||
|
List<ICPPFunction> functionBindings = new ArrayList<ICPPFunction>();
|
||||||
|
try {
|
||||||
|
CPPSemantics.getChainedMemberAccessOperatorReturnType(this, functionBindings);
|
||||||
|
} catch (DOMException e) {
|
||||||
|
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||||
|
}
|
||||||
|
if(functionBindings.isEmpty())
|
||||||
|
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||||
|
|
||||||
|
// create a name to wrap each binding
|
||||||
|
implicitNames = new IASTImplicitName[functionBindings.size()];
|
||||||
|
for(int i = 0, n = functionBindings.size(); i < n; i++) {
|
||||||
|
CPPASTImplicitName operatorName = new CPPASTImplicitName(OverloadableOperator.ARROW, this);
|
||||||
|
operatorName.setBinding(functionBindings.get(i));
|
||||||
|
operatorName.computeOperatorOffsets(owner, true);
|
||||||
|
implicitNames[i] = operatorName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return implicitNames;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(ASTVisitor action) {
|
public boolean accept(ASTVisitor action) {
|
||||||
if (action.shouldVisitExpressions) {
|
if (action.shouldVisitExpressions) {
|
||||||
|
@ -117,6 +150,13 @@ public class CPPASTFieldReference extends ASTNode implements
|
||||||
}
|
}
|
||||||
|
|
||||||
if (owner != null && !owner.accept(action)) return false;
|
if (owner != null && !owner.accept(action)) return false;
|
||||||
|
|
||||||
|
if(action.shouldVisitImplicitNames) {
|
||||||
|
for(IASTImplicitName name : getImplicitNames()) {
|
||||||
|
if(!name.accept(action)) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (name != null && !name.accept(action)) return false;
|
if (name != null && !name.accept(action)) return false;
|
||||||
|
|
||||||
if (action.shouldVisitExpressions) {
|
if (action.shouldVisitExpressions) {
|
||||||
|
|
|
@ -1,20 +1,22 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2004, 2008 IBM Corporation and others.
|
* Copyright (c) 2004, 2009 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
|
* John Camelon (IBM) - Initial API and implementation
|
||||||
|
* Mike Kucera (IBM) - implicit names
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
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.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;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.ExpansionOverlapsBoundaryException;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||||
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.IFunction;
|
import org.eclipse.cdt.core.dom.ast.IFunction;
|
||||||
|
@ -23,24 +25,26 @@ import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IVariable;
|
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionCallExpression;
|
||||||
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.ICPPFunction;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
|
import org.eclipse.cdt.core.parser.IToken;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
|
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
|
||||||
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;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author jcamelon
|
|
||||||
*/
|
|
||||||
public class CPPASTFunctionCallExpression extends ASTNode implements
|
public class CPPASTFunctionCallExpression extends ASTNode implements
|
||||||
IASTFunctionCallExpression, IASTAmbiguityParent {
|
ICPPASTFunctionCallExpression, IASTAmbiguityParent {
|
||||||
|
|
||||||
private IASTExpression functionName;
|
private IASTExpression functionName;
|
||||||
private IASTExpression parameter;
|
private IASTExpression parameter;
|
||||||
|
|
||||||
|
private IASTImplicitName[] implicitNames = null;
|
||||||
|
|
||||||
|
|
||||||
public CPPASTFunctionCallExpression() {
|
public CPPASTFunctionCallExpression() {
|
||||||
}
|
}
|
||||||
|
@ -84,6 +88,51 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
|
||||||
return parameter;
|
return parameter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public IASTImplicitName[] getImplicitNames() {
|
||||||
|
if(implicitNames == null) {
|
||||||
|
ICPPFunction overload = getOperator();
|
||||||
|
if(overload == null)
|
||||||
|
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||||
|
|
||||||
|
// create separate implicit names for the two brackets
|
||||||
|
CPPASTImplicitName n1 = new CPPASTImplicitName(OverloadableOperator.PAREN, this);
|
||||||
|
n1.setBinding(overload);
|
||||||
|
|
||||||
|
CPPASTImplicitName n2 = new CPPASTImplicitName(OverloadableOperator.PAREN, this);
|
||||||
|
n2.setBinding(overload);
|
||||||
|
n2.setAlternate(true);
|
||||||
|
|
||||||
|
if(parameter == null) {
|
||||||
|
int idEndOffset = ((ASTNode)functionName).getOffset() + ((ASTNode)functionName).getLength();
|
||||||
|
try {
|
||||||
|
IToken lparen = functionName.getTrailingSyntax();
|
||||||
|
IToken rparen = lparen.getNext();
|
||||||
|
|
||||||
|
if(lparen.getType() == IToken.tLPAREN)
|
||||||
|
n1.setOffsetAndLength(idEndOffset + lparen.getOffset(), 1);
|
||||||
|
else
|
||||||
|
n1.setOffsetAndLength(idEndOffset + lparen.getEndOffset(), 0);
|
||||||
|
|
||||||
|
if(rparen.getType() == IToken.tRPAREN)
|
||||||
|
n2.setOffsetAndLength(idEndOffset + rparen.getOffset(), 1);
|
||||||
|
else
|
||||||
|
n2.setOffsetAndLength(idEndOffset + rparen.getEndOffset(), 0);
|
||||||
|
} catch(ExpansionOverlapsBoundaryException e) {
|
||||||
|
n1.setOffsetAndLength(idEndOffset, 0);
|
||||||
|
n2.setOffsetAndLength(idEndOffset, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
n1.computeOperatorOffsets(functionName, true);
|
||||||
|
n2.computeOperatorOffsets(parameter, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
implicitNames = new IASTImplicitName[] { n1, n2 };
|
||||||
|
}
|
||||||
|
return implicitNames;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept( ASTVisitor action ){
|
public boolean accept( ASTVisitor action ){
|
||||||
if( action.shouldVisitExpressions ){
|
if( action.shouldVisitExpressions ){
|
||||||
|
@ -95,8 +144,18 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
|
||||||
}
|
}
|
||||||
|
|
||||||
if( functionName != null ) if( !functionName.accept( action ) ) return false;
|
if( functionName != null ) if( !functionName.accept( action ) ) return false;
|
||||||
|
|
||||||
|
|
||||||
|
IASTImplicitName[] implicits = action.shouldVisitImplicitNames ? getImplicitNames() : null;
|
||||||
|
|
||||||
|
if(implicits != null && implicits.length > 0)
|
||||||
|
if(!implicits[0].accept(action)) return false;
|
||||||
|
|
||||||
if( parameter != null ) if( !parameter.accept( action ) ) return false;
|
if( parameter != null ) if( !parameter.accept( action ) ) return false;
|
||||||
|
|
||||||
|
if(implicits != null && implicits.length > 0)
|
||||||
|
if(!implicits[1].accept(action)) return false;
|
||||||
|
|
||||||
if( action.shouldVisitExpressions ){
|
if( action.shouldVisitExpressions ){
|
||||||
switch( action.leave( this ) ){
|
switch( action.leave( this ) ){
|
||||||
case ASTVisitor.PROCESS_ABORT : return false;
|
case ASTVisitor.PROCESS_ABORT : return false;
|
||||||
|
@ -122,7 +181,17 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ICPPFunction getOperator() {
|
||||||
|
ICPPFunction[] overload = new ICPPFunction[] {null};
|
||||||
|
getExpressionType(overload);
|
||||||
|
return overload[0];
|
||||||
|
}
|
||||||
|
|
||||||
public IType getExpressionType() {
|
public IType getExpressionType() {
|
||||||
|
return getExpressionType(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IType getExpressionType(ICPPFunction[] overload) {
|
||||||
try {
|
try {
|
||||||
IType t= null;
|
IType t= null;
|
||||||
if (functionName instanceof IASTIdExpression) {
|
if (functionName instanceof IASTIdExpression) {
|
||||||
|
@ -152,6 +221,8 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
|
||||||
} else if (t instanceof ICPPClassType) {
|
} else if (t instanceof ICPPClassType) {
|
||||||
ICPPFunction op = CPPSemantics.findOperator(this, (ICPPClassType) t);
|
ICPPFunction op = CPPSemantics.findOperator(this, (ICPPClassType) t);
|
||||||
if (op != null) {
|
if (op != null) {
|
||||||
|
if(overload != null)
|
||||||
|
overload[0] = op;
|
||||||
return op.getType().getReturnType();
|
return op.getType().getReturnType();
|
||||||
}
|
}
|
||||||
} else if (t instanceof IPointerType) {
|
} else if (t instanceof IPointerType) {
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2009 IBM Corporation and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Mike Kucera (IBM) - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.ExpansionOverlapsBoundaryException;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
|
import org.eclipse.cdt.core.parser.IToken;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
|
|
||||||
|
|
||||||
|
public class CPPASTImplicitName extends CPPASTName implements IASTImplicitName {
|
||||||
|
|
||||||
|
private boolean alternate = false;
|
||||||
|
private boolean isOperator = false;
|
||||||
|
|
||||||
|
|
||||||
|
public CPPASTImplicitName(char[] name, IASTNode parent) {
|
||||||
|
super(name);
|
||||||
|
setParent(parent);
|
||||||
|
setPropertyInParent(IASTImplicitNameOwner.IMPLICIT_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CPPASTImplicitName(OverloadableOperator op, IASTNode parent) {
|
||||||
|
this(op.toCharArray(), parent);
|
||||||
|
isOperator = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CPPASTImplicitName copy() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isAlternate() {
|
||||||
|
return alternate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAlternate(boolean alternate) {
|
||||||
|
this.alternate = alternate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean accept(ASTVisitor action) {
|
||||||
|
if((!alternate && action.shouldVisitImplicitNames) ||
|
||||||
|
(alternate && action.shouldVisitImplicitNameAlternates)) {
|
||||||
|
|
||||||
|
switch (action.visit(this)) {
|
||||||
|
case ASTVisitor.PROCESS_ABORT: return false;
|
||||||
|
case ASTVisitor.PROCESS_SKIP: return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (action.leave(this)) {
|
||||||
|
case ASTVisitor.PROCESS_ABORT: return false;
|
||||||
|
case ASTVisitor.PROCESS_SKIP: return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDeclaration() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDefinition() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReference() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility method for setting offsets using operator syntax.
|
||||||
|
*
|
||||||
|
* @param trailing true for trailing syntax, false for leading syntax
|
||||||
|
*/
|
||||||
|
public void computeOperatorOffsets(IASTNode relativeNode, boolean trailing) {
|
||||||
|
if(relativeNode == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
IToken first;
|
||||||
|
try {
|
||||||
|
first = trailing ? relativeNode.getTrailingSyntax() : relativeNode.getLeadingSyntax();
|
||||||
|
|
||||||
|
int offset = ((ASTNode)relativeNode).getOffset() + first.getOffset();
|
||||||
|
if(trailing)
|
||||||
|
offset += ((ASTNode)relativeNode).getLength();
|
||||||
|
|
||||||
|
OverloadableOperator oo = OverloadableOperator.valueOf(first);
|
||||||
|
if((first.getNext() == null && oo != null) ||
|
||||||
|
Arrays.equals(first.getCharImage(), "delete".toCharArray()) || //$NON-NLS-1$
|
||||||
|
Arrays.equals(first.getCharImage(), "new".toCharArray())) { //$NON-NLS-1$
|
||||||
|
int length = first.getLength();
|
||||||
|
setOffsetAndLength(offset, length);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setOffsetAndLength(offset, 0);
|
||||||
|
}
|
||||||
|
} catch (ExpansionOverlapsBoundaryException e) {
|
||||||
|
ASTNode parent = (ASTNode) getParent();
|
||||||
|
setOffsetAndLength(parent.getOffset() + parent.getLength(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setOperator(boolean isOperator) {
|
||||||
|
this.isOperator = isOperator;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOperator() {
|
||||||
|
return isOperator;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -1,13 +1,14 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2004, 2008 IBM Corporation and others.
|
* Copyright (c) 2004, 2009 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
|
* John Camelon (IBM) - Initial API and implementation
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
|
* Mike Kucera (IBM)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
|
@ -17,21 +18,25 @@ import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
|
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||||
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
||||||
|
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.cpp.ICPPASTNewExpression;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||||
|
import org.eclipse.cdt.core.parser.IProblem;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||||
import org.eclipse.core.runtime.Assert;
|
import org.eclipse.core.runtime.Assert;
|
||||||
|
|
||||||
/**
|
|
||||||
* @author jcamelon
|
|
||||||
*/
|
|
||||||
public class CPPASTNewExpression extends ASTNode implements
|
public class CPPASTNewExpression extends ASTNode implements
|
||||||
ICPPASTNewExpression, IASTAmbiguityParent {
|
ICPPASTNewExpression, IASTAmbiguityParent {
|
||||||
|
|
||||||
|
@ -43,6 +48,7 @@ public class CPPASTNewExpression extends ASTNode implements
|
||||||
|
|
||||||
private IASTExpression [] arrayExpressions = null;
|
private IASTExpression [] arrayExpressions = null;
|
||||||
|
|
||||||
|
private IASTImplicitName[] implicitNames = null;
|
||||||
|
|
||||||
|
|
||||||
public CPPASTNewExpression() {
|
public CPPASTNewExpression() {
|
||||||
|
@ -171,6 +177,57 @@ public class CPPASTNewExpression extends ASTNode implements
|
||||||
((IASTArrayDeclarator) dtor).addArrayModifier(mod);
|
((IASTArrayDeclarator) dtor).addArrayModifier(mod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public IASTImplicitName[] getImplicitNames() {
|
||||||
|
if(implicitNames == null) {
|
||||||
|
IType type = getExpressionType();
|
||||||
|
if(type instanceof IProblem)
|
||||||
|
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||||
|
|
||||||
|
try {
|
||||||
|
type = ((IPointerType)type).getType();
|
||||||
|
} catch (DOMException e) {
|
||||||
|
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
ICPPFunction operatorFunction = findOperatorFunction(type);
|
||||||
|
if(operatorFunction == null) {
|
||||||
|
implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
CPPASTImplicitName operatorName = new CPPASTImplicitName(operatorFunction.getNameCharArray(), this);
|
||||||
|
operatorName.setOperator(true);
|
||||||
|
operatorName.setBinding(operatorFunction);
|
||||||
|
operatorName.setOffsetAndLength(getOffset(), 3);
|
||||||
|
implicitNames = new IASTImplicitName[] { operatorName };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return implicitNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO this code is repeated in too many places
|
||||||
|
private ICPPFunction findOperatorFunction(IType type) {
|
||||||
|
if(type instanceof ICPPClassType) {
|
||||||
|
ICPPFunction operator = CPPSemantics.findOperator(this, (ICPPClassType) type);
|
||||||
|
if(operator != null)
|
||||||
|
return operator;
|
||||||
|
}
|
||||||
|
return CPPSemantics.findOverloadedOperator(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this expression is allocating an array.
|
||||||
|
* @since 5.1
|
||||||
|
*/
|
||||||
|
public boolean isArrayAllocation() {
|
||||||
|
IType t = CPPVisitor.createType(getTypeId());
|
||||||
|
return t instanceof IArrayType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept( ASTVisitor action ){
|
public boolean accept( ASTVisitor action ){
|
||||||
if( action.shouldVisitExpressions ){
|
if( action.shouldVisitExpressions ){
|
||||||
|
@ -181,10 +238,17 @@ public class CPPASTNewExpression extends ASTNode implements
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(action.shouldVisitImplicitNames) {
|
||||||
|
for(IASTImplicitName name : getImplicitNames()) {
|
||||||
|
if(!name.accept(action)) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( placement != null ) if( !placement.accept( action ) ) return false;
|
if( placement != null ) if( !placement.accept( action ) ) return false;
|
||||||
if( typeId != null ) if( !typeId.accept( action ) ) return false;
|
if( typeId != null ) if( !typeId.accept( action ) ) return false;
|
||||||
if( initializer != null ) if( !initializer.accept( action ) ) return false;
|
if( initializer != null ) if( !initializer.accept( action ) ) return false;
|
||||||
|
|
||||||
|
|
||||||
if( action.shouldVisitExpressions ){
|
if( action.shouldVisitExpressions ){
|
||||||
switch( action.leave( this ) ){
|
switch( action.leave( this ) ){
|
||||||
case ASTVisitor.PROCESS_ABORT : return false;
|
case ASTVisitor.PROCESS_ABORT : return false;
|
||||||
|
|
|
@ -18,6 +18,7 @@ import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
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.IASTIdExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTImplicitName;
|
||||||
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.IASTUnaryExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
||||||
|
@ -48,6 +49,8 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
|
||||||
private int op;
|
private int op;
|
||||||
private IASTExpression operand;
|
private IASTExpression operand;
|
||||||
|
|
||||||
|
private IASTImplicitName[] implicitNames = null;
|
||||||
|
|
||||||
public CPPASTUnaryExpression() {
|
public CPPASTUnaryExpression() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,6 +87,28 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isPostfixOperator() {
|
||||||
|
return op == op_postFixDecr || op == op_postFixIncr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public IASTImplicitName[] getImplicitNames() {
|
||||||
|
if(implicitNames == null) {
|
||||||
|
ICPPFunction overload = getOverload();
|
||||||
|
if(overload == null)
|
||||||
|
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||||
|
|
||||||
|
CPPASTImplicitName operatorName = new CPPASTImplicitName(overload.getNameCharArray(), this);
|
||||||
|
operatorName.setOperator(true);
|
||||||
|
operatorName.setBinding(overload);
|
||||||
|
operatorName.computeOperatorOffsets(operand, isPostfixOperator());
|
||||||
|
implicitNames = new IASTImplicitName[] { operatorName };
|
||||||
|
}
|
||||||
|
|
||||||
|
return implicitNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(ASTVisitor action) {
|
public boolean accept(ASTVisitor action) {
|
||||||
if (action.shouldVisitExpressions) {
|
if (action.shouldVisitExpressions) {
|
||||||
|
@ -94,8 +119,22 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final boolean isPostfix = isPostfixOperator();
|
||||||
|
|
||||||
|
if(!isPostfix && action.shouldVisitImplicitNames) {
|
||||||
|
for(IASTImplicitName name : getImplicitNames()) {
|
||||||
|
if(!name.accept(action)) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (operand != null && !operand.accept(action)) return false;
|
if (operand != null && !operand.accept(action)) return false;
|
||||||
|
|
||||||
|
if(isPostfix && action.shouldVisitImplicitNames) {
|
||||||
|
for(IASTImplicitName name : getImplicitNames()) {
|
||||||
|
if(!name.accept(action)) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (action.shouldVisitExpressions) {
|
if (action.shouldVisitExpressions) {
|
||||||
switch (action.leave(this)) {
|
switch (action.leave(this)) {
|
||||||
case ASTVisitor.PROCESS_ABORT: return false;
|
case ASTVisitor.PROCESS_ABORT: return false;
|
||||||
|
@ -114,18 +153,30 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ICPPFunction getOverload() {
|
||||||
|
if(operand == null)
|
||||||
|
return null;
|
||||||
|
if(getExpressionType() instanceof CPPPointerToMemberType) // then it must be the builtin &
|
||||||
|
return null;
|
||||||
|
IType type = operand.getExpressionType();
|
||||||
|
type = SemanticUtil.getNestedType(type, TDEF | REF);
|
||||||
|
return findOperatorFunction(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public IType getExpressionType() {
|
public IType getExpressionType() {
|
||||||
final int op= getOperator();
|
final int op= getOperator();
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case IASTUnaryExpression.op_sizeof:
|
case op_sizeof:
|
||||||
return CPPVisitor.get_SIZE_T(this);
|
return CPPVisitor.get_SIZE_T(this);
|
||||||
case IASTUnaryExpression.op_typeid:
|
case op_typeid:
|
||||||
return CPPVisitor.get_type_info(this);
|
return CPPVisitor.get_type_info(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
final IASTExpression operand = getOperand();
|
final IASTExpression operand = getOperand();
|
||||||
|
|
||||||
if (op == IASTUnaryExpression.op_amper) { // check for pointer to member
|
if (op == op_amper) { // check for pointer to member
|
||||||
IASTNode child= operand;
|
IASTNode child= operand;
|
||||||
boolean inParenthesis= false;
|
boolean inParenthesis= false;
|
||||||
while (child instanceof IASTUnaryExpression && ((IASTUnaryExpression) child).getOperator() == IASTUnaryExpression.op_bracketedPrimary) {
|
while (child instanceof IASTUnaryExpression && ((IASTUnaryExpression) child).getOperator() == IASTUnaryExpression.op_bracketedPrimary) {
|
||||||
|
@ -164,7 +215,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (op == IASTUnaryExpression.op_star) {
|
if (op == op_star) {
|
||||||
IType type= operand.getExpressionType();
|
IType type= operand.getExpressionType();
|
||||||
type = SemanticUtil.getNestedType(type, TDEF | REF | CVQ);
|
type = SemanticUtil.getNestedType(type, TDEF | REF | CVQ);
|
||||||
if (type instanceof IProblemBinding) {
|
if (type instanceof IProblemBinding) {
|
||||||
|
@ -193,7 +244,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
|
||||||
return operator;
|
return operator;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(op == IASTUnaryExpression.op_not) {
|
if(op == op_not) {
|
||||||
return new CPPBasicType(ICPPBasicType.t_bool, 0);
|
return new CPPBasicType(ICPPBasicType.t_bool, 0);
|
||||||
}
|
}
|
||||||
if (type instanceof CPPBasicType) {
|
if (type instanceof CPPBasicType) {
|
||||||
|
|
|
@ -6,14 +6,13 @@
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* IBM Corporation - initial API and implementation
|
* Mike Kucera (IBM) - initial API and implementation
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
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.IASTASMDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTASMDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
|
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTBreakStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTBreakStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTCaseStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTCaseStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
||||||
|
@ -27,10 +26,8 @@ import org.eclipse.cdt.core.dom.ast.IASTDefaultStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDoStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTDoStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
||||||
|
@ -52,6 +49,7 @@ import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTTypeIdInitializerExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTTypeIdInitializerExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
|
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTArraySubscriptExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
|
||||||
|
@ -62,8 +60,10 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpressionList;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionCallExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||||
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.ICPPASTFunctionWithTryBlock;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionWithTryBlock;
|
||||||
|
@ -107,8 +107,6 @@ import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTSimpleDeclSpecifier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract factory implementation that creates C++ AST nodes.
|
* Abstract factory implementation that creates C++ AST nodes.
|
||||||
*
|
|
||||||
* @author Mike Kucera
|
|
||||||
*/
|
*/
|
||||||
public class CPPNodeFactory implements ICPPNodeFactory {
|
public class CPPNodeFactory implements ICPPNodeFactory {
|
||||||
|
|
||||||
|
@ -165,15 +163,15 @@ public class CPPNodeFactory implements ICPPNodeFactory {
|
||||||
return new CPPASTIdExpression(name);
|
return new CPPASTIdExpression(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IASTArraySubscriptExpression newArraySubscriptExpression(IASTExpression arrayExpr, IASTExpression subscript) {
|
public ICPPASTArraySubscriptExpression newArraySubscriptExpression(IASTExpression arrayExpr, IASTExpression subscript) {
|
||||||
return new CPPASTArraySubscriptExpression(arrayExpr, subscript);
|
return new CPPASTArraySubscriptExpression(arrayExpr, subscript);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IASTExpressionList newExpressionList() {
|
public ICPPASTExpressionList newExpressionList() {
|
||||||
return new CPPASTExpressionList();
|
return new CPPASTExpressionList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IASTFunctionCallExpression newFunctionCallExpression(IASTExpression idExpr, IASTExpression argList) {
|
public ICPPASTFunctionCallExpression newFunctionCallExpression(IASTExpression idExpr, IASTExpression argList) {
|
||||||
return new CPPASTFunctionCallExpression(idExpr, argList);
|
return new CPPASTFunctionCallExpression(idExpr, argList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,8 +12,12 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
|
||||||
import org.eclipse.cdt.core.parser.IToken;
|
import org.eclipse.cdt.core.parser.IToken;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,9 +82,26 @@ public enum OverloadableOperator {
|
||||||
return rep;
|
return rep;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the given name equals 'operator new'
|
||||||
|
* or 'operator new[]'.
|
||||||
|
*/
|
||||||
|
public static boolean isNew(char[] name) {
|
||||||
|
return Arrays.equals(name, NEW.rep) || Arrays.equals(name, NEW_ARRAY.rep);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the given name equals 'operator delete'
|
||||||
|
* or 'operator delete[]'.
|
||||||
|
*/
|
||||||
|
public static boolean isDelete(char[] name) {
|
||||||
|
return Arrays.equals(name, DELETE.rep) || Arrays.equals(name, DELETE_ARRAY.rep);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the OverloadableOperator constant that corresponds to
|
* Returns the OverloadableOperator constant that corresponds to
|
||||||
* the given token. Only works for operators that consist of one token.
|
* the given token. Does not work for new[] and delete[] operators.
|
||||||
*
|
*
|
||||||
* @throws NullPointerException if {@code token} is {@code null}.
|
* @throws NullPointerException if {@code token} is {@code null}.
|
||||||
*/
|
*/
|
||||||
|
@ -132,6 +153,11 @@ public enum OverloadableOperator {
|
||||||
// other
|
// other
|
||||||
case IToken.tASSIGN: return ASSIGN;
|
case IToken.tASSIGN: return ASSIGN;
|
||||||
case IToken.tCOMMA: return COMMA;
|
case IToken.tCOMMA: return COMMA;
|
||||||
|
|
||||||
|
case IToken.tLBRACKET: return BRACKET;
|
||||||
|
case IToken.tRBRACKET: return BRACKET;
|
||||||
|
case IToken.tLPAREN: return PAREN;
|
||||||
|
case IToken.tRPAREN: return PAREN;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -203,4 +229,12 @@ public enum OverloadableOperator {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static OverloadableOperator fromDeleteExpression(ICPPASTDeleteExpression expression) {
|
||||||
|
return expression.isVectored() ? DELETE_ARRAY : DELETE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static OverloadableOperator fromNewExpression(ICPPASTNewExpression expression) {
|
||||||
|
return expression.isArrayAllocation() ? NEW_ARRAY : NEW;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ 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.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -82,6 +83,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpressionList;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||||
|
@ -135,6 +138,7 @@ import org.eclipse.cdt.core.index.IIndexBinding;
|
||||||
import org.eclipse.cdt.core.index.IIndexFileSet;
|
import org.eclipse.cdt.core.index.IIndexFileSet;
|
||||||
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.core.parser.util.CharArrayUtils;
|
||||||
import org.eclipse.cdt.core.parser.util.DebugUtil;
|
import org.eclipse.cdt.core.parser.util.DebugUtil;
|
||||||
import org.eclipse.cdt.core.parser.util.ObjectSet;
|
import org.eclipse.cdt.core.parser.util.ObjectSet;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
|
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
|
||||||
|
@ -149,6 +153,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTLiteralExpression;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit;
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTypeIdExpression;
|
||||||
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.CPPCompositeBinding;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPCompositeBinding;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPNamespace;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPNamespace;
|
||||||
|
@ -2525,6 +2530,7 @@ public class CPPSemantics {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For a pointer dereference expression e1->e2, return the type that e1 ultimately evaluates to
|
* For a pointer dereference expression e1->e2, return the type that e1 ultimately evaluates to
|
||||||
* when chaining overloaded class member access operators <code>operator->()</code> calls.
|
* when chaining overloaded class member access operators <code>operator->()</code> calls.
|
||||||
|
@ -2534,6 +2540,13 @@ public class CPPSemantics {
|
||||||
* @throws DOMException
|
* @throws DOMException
|
||||||
*/
|
*/
|
||||||
public static IType getChainedMemberAccessOperatorReturnType(ICPPASTFieldReference fieldReference) throws DOMException {
|
public static IType getChainedMemberAccessOperatorReturnType(ICPPASTFieldReference fieldReference) throws DOMException {
|
||||||
|
return getChainedMemberAccessOperatorReturnType(fieldReference, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Also collections the funciton bindings if requested.
|
||||||
|
*/
|
||||||
|
public static IType getChainedMemberAccessOperatorReturnType(ICPPASTFieldReference fieldReference, Collection<ICPPFunction> functionBindings) throws DOMException {
|
||||||
IASTExpression owner = fieldReference.getFieldOwner();
|
IASTExpression owner = fieldReference.getFieldOwner();
|
||||||
if (owner == null)
|
if (owner == null)
|
||||||
return null;
|
return null;
|
||||||
|
@ -2581,6 +2594,9 @@ public class CPPSemantics {
|
||||||
if (op == null)
|
if (op == null)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
if(functionBindings != null)
|
||||||
|
functionBindings.add(op);
|
||||||
|
|
||||||
type= op.getType().getReturnType();
|
type= op.getType().getReturnType();
|
||||||
foundOperator= true;
|
foundOperator= true;
|
||||||
}
|
}
|
||||||
|
@ -2609,42 +2625,40 @@ public class CPPSemantics {
|
||||||
CPPASTName astName = new CPPASTName();
|
CPPASTName astName = new CPPASTName();
|
||||||
astName.setParent(exp);
|
astName.setParent(exp);
|
||||||
astName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
|
astName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
|
||||||
LookupData data;
|
LookupData data = new LookupData(astName);
|
||||||
|
data.forceQualified = true;
|
||||||
|
|
||||||
if (exp instanceof IASTArraySubscriptExpression) {
|
if (exp instanceof IASTArraySubscriptExpression) {
|
||||||
astName.setName(OverloadableOperator.BRACKET.toCharArray());
|
astName.setName(OverloadableOperator.BRACKET.toCharArray());
|
||||||
data = new LookupData(astName);
|
|
||||||
data.forceQualified = true;
|
|
||||||
data.setFunctionArguments(((IASTArraySubscriptExpression) exp).getSubscriptExpression());
|
data.setFunctionArguments(((IASTArraySubscriptExpression) exp).getSubscriptExpression());
|
||||||
} else if (exp instanceof IASTFieldReference) {
|
} else if (exp instanceof IASTFieldReference) {
|
||||||
astName.setName(OverloadableOperator.ARROW.toCharArray());
|
astName.setName(OverloadableOperator.ARROW.toCharArray());
|
||||||
data = new LookupData(astName);
|
|
||||||
data.forceQualified = true;
|
|
||||||
data.setFunctionArguments(IASTExpression.EMPTY_EXPRESSION_ARRAY);
|
data.setFunctionArguments(IASTExpression.EMPTY_EXPRESSION_ARRAY);
|
||||||
} else if (exp instanceof IASTFunctionCallExpression) {
|
} else if (exp instanceof IASTFunctionCallExpression) {
|
||||||
astName.setName(OverloadableOperator.PAREN.toCharArray());
|
astName.setName(OverloadableOperator.PAREN.toCharArray());
|
||||||
data = new LookupData(astName);
|
|
||||||
data.forceQualified = true;
|
|
||||||
data.setFunctionArguments(((IASTFunctionCallExpression) exp).getParameterExpression());
|
data.setFunctionArguments(((IASTFunctionCallExpression) exp).getParameterExpression());
|
||||||
|
} else if (exp instanceof ICPPASTDeleteExpression) {
|
||||||
|
OverloadableOperator oo = OverloadableOperator.fromDeleteExpression((ICPPASTDeleteExpression)exp);
|
||||||
|
astName.setName(oo.toCharArray());
|
||||||
|
data.setFunctionArguments(IASTExpression.EMPTY_EXPRESSION_ARRAY);
|
||||||
|
} else if (exp instanceof ICPPASTNewExpression) {
|
||||||
|
ICPPASTNewExpression newExpression = (ICPPASTNewExpression) exp;
|
||||||
|
OverloadableOperator operator = OverloadableOperator.fromNewExpression(newExpression);
|
||||||
|
astName.setName(operator.toCharArray());
|
||||||
|
data.setFunctionArguments(newExpression.getNewPlacement());
|
||||||
} else if (exp instanceof IASTBinaryExpression) {
|
} else if (exp instanceof IASTBinaryExpression) {
|
||||||
final IASTBinaryExpression binary = (IASTBinaryExpression) exp;
|
final IASTBinaryExpression binary = (IASTBinaryExpression) exp;
|
||||||
OverloadableOperator operator = OverloadableOperator.fromBinaryExpression(binary);
|
OverloadableOperator operator = OverloadableOperator.fromBinaryExpression(binary);
|
||||||
if (operator == null) {
|
if (operator == null)
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
astName.setName(operator.toCharArray());
|
astName.setName(operator.toCharArray());
|
||||||
data = new LookupData(astName);
|
|
||||||
data.forceQualified = true;
|
|
||||||
data.setFunctionArguments(new IASTExpression[] { binary.getOperand2() });
|
data.setFunctionArguments(new IASTExpression[] { binary.getOperand2() });
|
||||||
} else if (exp instanceof IASTUnaryExpression) {
|
} else if (exp instanceof IASTUnaryExpression) {
|
||||||
IASTUnaryExpression unary = (IASTUnaryExpression) exp;
|
IASTUnaryExpression unary = (IASTUnaryExpression) exp;
|
||||||
OverloadableOperator operator = OverloadableOperator.fromUnaryExpression(unary);
|
OverloadableOperator operator = OverloadableOperator.fromUnaryExpression(unary);
|
||||||
if(operator == null) {
|
if(operator == null)
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
astName.setName(operator.toCharArray());
|
astName.setName(operator.toCharArray());
|
||||||
data = new LookupData(astName);
|
|
||||||
data.forceQualified = true;
|
|
||||||
int op = unary.getOperator();
|
int op = unary.getOperator();
|
||||||
if(op == IASTUnaryExpression.op_postFixDecr || op == IASTUnaryExpression.op_postFixIncr)
|
if(op == IASTUnaryExpression.op_postFixDecr || op == IASTUnaryExpression.op_postFixIncr)
|
||||||
data.setFunctionArguments(new IASTExpression[] { CPPASTLiteralExpression.INT_ZERO });
|
data.setFunctionArguments(new IASTExpression[] { CPPASTLiteralExpression.INT_ZERO });
|
||||||
|
@ -2664,6 +2678,74 @@ public class CPPSemantics {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param expressionList
|
||||||
|
* @param index the index of the first parameter
|
||||||
|
*/
|
||||||
|
public static ICPPFunction findOperatorComma(ICPPASTExpressionList expressionList, int index, ICPPClassType cls) {
|
||||||
|
IScope scope = null;
|
||||||
|
try {
|
||||||
|
scope = cls.getCompositeScope();
|
||||||
|
} catch (DOMException e1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (scope == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
CPPASTName astName = new CPPASTName();
|
||||||
|
astName.setParent(expressionList);
|
||||||
|
astName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
|
||||||
|
astName.setName(OverloadableOperator.COMMA.toCharArray());
|
||||||
|
|
||||||
|
LookupData data = new LookupData(astName);
|
||||||
|
data.forceQualified = true;
|
||||||
|
IASTExpression[] exprs = expressionList.getExpressions();
|
||||||
|
data.setFunctionArguments(new IASTExpression[] { exprs[index], exprs[index+1] });
|
||||||
|
|
||||||
|
try {
|
||||||
|
lookup(data, scope);
|
||||||
|
IBinding binding = resolveAmbiguities(data, astName);
|
||||||
|
if (binding instanceof ICPPFunction)
|
||||||
|
return (ICPPFunction) binding;
|
||||||
|
} catch (DOMException e) {
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static ICPPFunction findDestructor(ICPPASTDeleteExpression expr, ICPPClassType cls) {
|
||||||
|
IScope scope = null;
|
||||||
|
try {
|
||||||
|
scope = cls.getCompositeScope();
|
||||||
|
} catch (DOMException e1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (scope == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
CPPASTName astName = new CPPASTName();
|
||||||
|
astName.setParent(expr);
|
||||||
|
astName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
|
||||||
|
astName.setName(CharArrayUtils.concat("~".toCharArray(), cls.getNameCharArray())); //$NON-NLS-1$
|
||||||
|
|
||||||
|
LookupData data = new LookupData(astName);
|
||||||
|
data.forceQualified = true;
|
||||||
|
data.setFunctionArguments(IASTExpression.EMPTY_EXPRESSION_ARRAY);
|
||||||
|
|
||||||
|
try {
|
||||||
|
lookup(data, scope);
|
||||||
|
IBinding binding = resolveAmbiguities(data, astName);
|
||||||
|
if (binding instanceof ICPPFunction)
|
||||||
|
return (ICPPFunction) binding;
|
||||||
|
} catch (DOMException e) {
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the overloaded operator corresponding to a binary expression, or {@code null}
|
* Returns the overloaded operator corresponding to a binary expression, or {@code null}
|
||||||
* if no such operator is found.
|
* if no such operator is found.
|
||||||
|
@ -2677,6 +2759,19 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the overloaded operator corresponding to a binary expression, or {@code null}
|
||||||
|
* if no such operator is found.
|
||||||
|
* @param exp a binary expression
|
||||||
|
* @return the overloaded operator, or {@code null}.
|
||||||
|
*/
|
||||||
|
public static ICPPFunction findOverloadedOperator(ICPPASTDeleteExpression exp) {
|
||||||
|
OverloadableOperator operator = OverloadableOperator.fromDeleteExpression(exp);
|
||||||
|
IASTExpression[] args = { exp.getOperand() };
|
||||||
|
return findOverloadedOperator(exp, operator, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the overloaded operator corresponding to a unary expression, or {@code null}
|
* Returns the overloaded operator corresponding to a unary expression, or {@code null}
|
||||||
* if no such operator is found.
|
* if no such operator is found.
|
||||||
|
@ -2695,6 +2790,48 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the overloaded operator corresponding to a comma in an expression list,
|
||||||
|
* or {@code null} if no such operator is found.
|
||||||
|
* @param index the index of the left argument to the comma operator
|
||||||
|
* @throws IndexOutOfBoundsException if index is invalid
|
||||||
|
*/
|
||||||
|
public static ICPPFunction findOverloadedOperator(ICPPASTExpressionList exp, int index) {
|
||||||
|
OverloadableOperator operator = OverloadableOperator.COMMA;
|
||||||
|
IASTExpression[] exprs = exp.getExpressions();
|
||||||
|
IASTExpression[] args = { exprs[index], exprs[index+1] };
|
||||||
|
return findOverloadedOperator(exp, operator, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the overloaded operator corresponding to a comma in an expression list,
|
||||||
|
* or {@code null} if no such operator is found.
|
||||||
|
* @throws IndexOutOfBoundsException if index is invalid
|
||||||
|
*/
|
||||||
|
public static ICPPFunction findOverloadedOperator(ICPPASTNewExpression exp) {
|
||||||
|
OverloadableOperator operator = OverloadableOperator.fromNewExpression(exp);
|
||||||
|
|
||||||
|
IASTTypeId typeId = exp.getTypeId().copy();
|
||||||
|
IASTExpression sizeExpression = new CPPASTTypeIdExpression(IASTTypeIdExpression.op_sizeof, typeId);
|
||||||
|
sizeExpression.setParent(exp);
|
||||||
|
|
||||||
|
IASTExpression placement = exp.getNewPlacement();
|
||||||
|
|
||||||
|
List<IASTExpression> args = new ArrayList<IASTExpression>();
|
||||||
|
args.add(sizeExpression);
|
||||||
|
|
||||||
|
if(placement instanceof IASTExpressionList) {
|
||||||
|
for(IASTExpression p : ((IASTExpressionList)placement).getExpressions())
|
||||||
|
args.add(p);
|
||||||
|
}
|
||||||
|
else if(placement != null) {
|
||||||
|
args.add(placement);
|
||||||
|
}
|
||||||
|
|
||||||
|
return findOverloadedOperator(exp, operator, args.toArray(new IASTExpression[args.size()]));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static ICPPFunction findOverloadedOperator(IASTExpression exp, OverloadableOperator operator, IASTExpression[] args) {
|
private static ICPPFunction findOverloadedOperator(IASTExpression exp, OverloadableOperator operator, IASTExpression[] args) {
|
||||||
if (operator == null) {
|
if (operator == null) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -2721,6 +2858,8 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static IBinding[] findBindings(IScope scope, String name, boolean qualified) throws DOMException {
|
public static IBinding[] findBindings(IScope scope, String name, boolean qualified) throws DOMException {
|
||||||
return findBindings(scope, name.toCharArray(), qualified, null);
|
return findBindings(scope, name.toCharArray(), qualified, null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ import org.eclipse.cdt.core.dom.ast.c.ICASTFieldDesignator;
|
||||||
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.ICPPASTConstructorChainInitializer;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
|
||||||
|
@ -409,6 +410,13 @@ public class LookupData {
|
||||||
if (tempNameParent instanceof IASTBinaryExpression) {
|
if (tempNameParent instanceof IASTBinaryExpression) {
|
||||||
return ((IASTBinaryExpression) tempNameParent).getOperand1().getExpressionType();
|
return ((IASTBinaryExpression) tempNameParent).getOperand1().getExpressionType();
|
||||||
}
|
}
|
||||||
|
if (tempNameParent instanceof ICPPASTDeleteExpression) {
|
||||||
|
IType implied = ((ICPPASTDeleteExpression) tempNameParent).getOperand().getExpressionType();
|
||||||
|
if(implied instanceof IPointerType) {
|
||||||
|
return ((IPointerType)implied).getType();
|
||||||
|
}
|
||||||
|
return implied;
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (prop == IASTFieldReference.FIELD_NAME) {
|
if (prop == IASTFieldReference.FIELD_NAME) {
|
||||||
|
@ -550,7 +558,7 @@ public class LookupData {
|
||||||
setFunctionArguments(exprs);
|
setFunctionArguments(exprs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFunctionArguments(IASTExpression[] exprs) {
|
public void setFunctionArguments(IASTExpression... exprs) {
|
||||||
functionArgs= exprs;
|
functionArgs= exprs;
|
||||||
if (exprs.length != 0) {
|
if (exprs.length != 0) {
|
||||||
IASTNode node= exprs[0];
|
IASTNode node= exprs[0];
|
||||||
|
|
|
@ -145,4 +145,18 @@ public class TokenUtil {
|
||||||
return CharArrayUtils.EMPTY;
|
return CharArrayUtils.EMPTY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the last token in the given token list.
|
||||||
|
* @throws NullPointerException if the argument is null
|
||||||
|
*/
|
||||||
|
public static IToken getLast(IToken tokenList) {
|
||||||
|
IToken last;
|
||||||
|
do {
|
||||||
|
last = tokenList;
|
||||||
|
} while((tokenList = tokenList.getNext()) != null);
|
||||||
|
return last;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,7 @@ abstract public class IndexerASTVisitor extends ASTVisitor {
|
||||||
|
|
||||||
public IndexerASTVisitor() {
|
public IndexerASTVisitor() {
|
||||||
shouldVisitNames= true;
|
shouldVisitNames= true;
|
||||||
|
shouldVisitImplicitNames = true;
|
||||||
shouldVisitDeclarations= true;
|
shouldVisitDeclarations= true;
|
||||||
shouldVisitInitializers= true;
|
shouldVisitInitializers= true;
|
||||||
shouldVisitDeclSpecifiers= true;
|
shouldVisitDeclSpecifiers= true;
|
||||||
|
|
Loading…
Add table
Reference in a new issue