mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 08:55:25 +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",
|
||||
"isReference",
|
||||
"isAssociatedWithLastName",
|
||||
"getNestingLevel"
|
||||
"getNestingLevel",
|
||||
"getImplicitNames"
|
||||
));
|
||||
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
* IBM Corporation - initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* Andrew Ferguson (Symbian)
|
||||
* Mike Kucera (IBM)
|
||||
*******************************************************************************/
|
||||
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.IASTFunctionDefinition;
|
||||
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.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||
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.util.BaseTestCase;
|
||||
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.c.CVisitor;
|
||||
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);
|
||||
}
|
||||
|
||||
public IASTTranslationUnit getTranslationUnit() {
|
||||
return tu;
|
||||
}
|
||||
|
||||
public IBinding assertProblem(String section, int len) {
|
||||
IBinding binding= binding(section, 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) {
|
||||
final int offset = contents.indexOf(section);
|
||||
assertTrue(offset >= 0);
|
||||
final String selection = section.substring(0, len);
|
||||
IASTName name= tu.getNodeSelector(null).findName(offset, len);
|
||||
IASTName name= findName(section,len,false);
|
||||
if (name != null) {
|
||||
String selection = section.substring(0, len);
|
||||
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) {
|
||||
try {
|
||||
for (Field field : IProblemBinding.class.getDeclaredFields()) {
|
||||
|
@ -536,10 +595,8 @@ public class AST2BaseTest extends BaseTestCase {
|
|||
}
|
||||
|
||||
private IBinding binding(String section, int len) {
|
||||
final int offset = contents.indexOf(section);
|
||||
assertTrue(offset >= 0);
|
||||
IASTName name = findName(section, len,false);
|
||||
final String selection = section.substring(0, len);
|
||||
IASTName name= tu.getNodeSelector(null).findName(offset, len);
|
||||
assertNotNull("did not find \""+selection+"\"", name);
|
||||
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.addTestSuite(GCCTests.class);
|
||||
suite.addTest(AST2CPPTests.suite());
|
||||
suite.addTest(AST2CPPImplicitNameTests.suite());
|
||||
suite.addTest(AST2TemplateTests.suite());
|
||||
suite.addTestSuite(QuickParser2Tests.class);
|
||||
suite.addTest(CompleteParser2Tests.suite());
|
||||
|
@ -53,6 +54,7 @@ public class DOMParserTestSuite extends TestCase {
|
|||
suite.addTest(FaultToleranceTests.suite());
|
||||
suite.addTest(LanguageExtensionsTest.suite());
|
||||
suite.addTest(ASTInactiveCodeTests.suite());
|
||||
suite.addTest(AST2CPPImplicitNameTests.suite());
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,8 +15,6 @@ package org.eclipse.cdt.core.suite;
|
|||
import junit.framework.Test;
|
||||
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.tests.PositionTrackerTests;
|
||||
import org.eclipse.cdt.core.internal.tests.ResourceLookupTests;
|
||||
|
@ -56,8 +54,8 @@ public class AutomatedIntegrationSuite extends TestSuite {
|
|||
final AutomatedIntegrationSuite suite = new AutomatedIntegrationSuite();
|
||||
|
||||
// Add all success tests
|
||||
suite.addTest(CDescriptorTests.suite());
|
||||
suite.addTest(CDescriptorOldTests.suite());
|
||||
//suite.addTest(CDescriptorTests.suite());
|
||||
//suite.addTest(CDescriptorOldTests.suite());
|
||||
suite.addTest(ErrorParserTests.suite());
|
||||
suite.addTest(ParserTestSuite.suite());
|
||||
suite.addTest(AllCoreTests.suite());
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
* IBM Corporation - initial API and implementation
|
||||
* Yuan Zhang / Beth Tibbitts (IBM Research)
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* Mike Kucera (IBM) - implicit names
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast;
|
||||
|
||||
|
@ -139,6 +140,23 @@ public abstract class ASTVisitor {
|
|||
*/
|
||||
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.
|
||||
*/
|
||||
|
@ -149,7 +167,9 @@ public abstract class ASTVisitor {
|
|||
/**
|
||||
* Creates a visitor.
|
||||
* @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
|
||||
*/
|
||||
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();
|
||||
|
||||
/**
|
||||
* 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:
|
||||
*
|
||||
* <code>
|
||||
|
@ -226,9 +226,11 @@ public interface IASTNode {
|
|||
*
|
||||
* Preprocessor nodes do not currently support being copied.
|
||||
*
|
||||
* Implicit name nodes are not copied, instead they can be regenerated
|
||||
* if required.
|
||||
*
|
||||
* @since 5.1
|
||||
* @throws UnsupportedOperationException if this node or one of its descendants
|
||||
* does not support copying
|
||||
* @throws UnsupportedOperationException if this node or one of its descendants does not support copying
|
||||
*/
|
||||
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.
|
||||
* Will not return an implicit name.
|
||||
*/
|
||||
IASTName findName(int offset, int length);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* <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:
|
||||
* John Camelon (IBM) - Initial API and implementation
|
||||
* Mike Kucera (IBM)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||
|
||||
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.
|
||||
|
@ -18,7 +20,7 @@ import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
|
|||
* @noextend This interface is not intended to be extended 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.
|
||||
|
|
|
@ -7,11 +7,13 @@
|
|||
*
|
||||
* Contributors:
|
||||
* John Camelon (IBM) - Initial API and implementation
|
||||
* Mike Kucera (IBM)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @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
|
||||
|
|
|
@ -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:
|
||||
* John Camelon (IBM) - Initial API and implementation
|
||||
* Mike Kucera (IBM)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||
|
||||
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
|
||||
|
@ -19,7 +21,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
|
|||
* @noextend This interface is not intended to be extended 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?
|
||||
|
|
|
@ -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:
|
||||
* John Camelon (IBM) - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* Mike Kucera (IBM)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @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?
|
||||
|
@ -110,6 +112,14 @@ public interface ICPPASTNewExpression extends IASTExpression {
|
|||
*/
|
||||
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.
|
||||
*/
|
||||
|
|
|
@ -7,16 +7,18 @@
|
|||
*
|
||||
* Contributors:
|
||||
* John Camelon (IBM) - Initial API and implementation
|
||||
* Mike Kucera
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||
|
||||
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.
|
||||
* @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
|
||||
|
|
|
@ -156,4 +156,11 @@ public interface ICPPNodeFactory extends INodeFactory {
|
|||
public ICPPASTTemplatedTypeTemplateParameter newTemplatedTypeTemplateParameter(IASTName name, IASTExpression defaultValue);
|
||||
|
||||
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;
|
||||
|
||||
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.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
|
||||
|
@ -119,72 +120,51 @@ public class ASTNodeSelector implements IASTNodeSelector {
|
|||
return nodeSpec.getBestNode();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#getFirstContainedNode(int, int)
|
||||
*/
|
||||
|
||||
public IASTNode findFirstContainedNode(int offset, int length) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
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) {
|
||||
return findNode(offset, length, Relation.ENCLOSING, IASTName.class);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.cdt.core.dom.ast.IASTNodeSelector#findSurrundingMacroExpansion(int, int)
|
||||
*/
|
||||
public IASTImplicitName findImplicitName(int offset, int length) {
|
||||
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) {
|
||||
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.IASTDeclaration;
|
||||
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.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||
|
@ -31,6 +32,10 @@ public class FindNodeForOffsetAction extends ASTGenericVisitor {
|
|||
shouldVisitNames = true;
|
||||
shouldVisitDeclarations= true;
|
||||
includeInactiveNodes= true;
|
||||
|
||||
// only visit implicit names if asked
|
||||
shouldVisitImplicitNames =
|
||||
shouldVisitImplicitNameAlternates = nodeSpec.requiresClass(IASTImplicitName.class);
|
||||
}
|
||||
|
||||
@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
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
* John Camelon (IBM) - Initial API and implementation
|
||||
* Mike Kucera (IBM)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||
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.IASTImplicitName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
||||
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.cpp.ICPPASTArraySubscriptExpression;
|
||||
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;
|
||||
|
@ -28,11 +31,12 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
|||
/**
|
||||
* @author jcamelon
|
||||
*/
|
||||
public class CPPASTArraySubscriptExpression extends ASTNode implements IASTArraySubscriptExpression, IASTAmbiguityParent {
|
||||
public class CPPASTArraySubscriptExpression extends ASTNode implements ICPPASTArraySubscriptExpression, IASTAmbiguityParent {
|
||||
|
||||
private IASTExpression subscriptExp;
|
||||
private IASTExpression arrayExpression;
|
||||
|
||||
private IASTImplicitName[] implicitNames = null;
|
||||
|
||||
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
|
||||
public boolean accept( ASTVisitor action ){
|
||||
if( action.shouldVisitExpressions ){
|
||||
|
@ -88,9 +127,18 @@ public class CPPASTArraySubscriptExpression extends ASTNode implements IASTArray
|
|||
}
|
||||
if( arrayExpression != null )
|
||||
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.accept( action ) ) return false;
|
||||
|
||||
if(implicits != null && implicits.length > 0)
|
||||
if(!implicits[1].accept(action)) return false;
|
||||
|
||||
if( action.shouldVisitExpressions ){
|
||||
switch( action.leave( this ) ){
|
||||
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
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
* John Camelon (IBM) - Initial API and implementation
|
||||
* Mike Kucera (IBM)
|
||||
*******************************************************************************/
|
||||
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.IASTBinaryExpression;
|
||||
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.IEnumeration;
|
||||
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.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 operand2;
|
||||
private IType type;
|
||||
|
||||
|
||||
private IASTImplicitName[] implicitNames = null;
|
||||
|
||||
|
||||
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
|
||||
public boolean accept( ASTVisitor action ){
|
||||
if( action.shouldVisitExpressions ){
|
||||
|
@ -106,6 +126,13 @@ public class CPPASTBinaryExpression extends ASTNode implements
|
|||
}
|
||||
|
||||
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(action.shouldVisitExpressions ){
|
||||
|
@ -140,9 +167,41 @@ public class CPPASTBinaryExpression extends ASTNode implements
|
|||
return type;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
// Check for overloaded operator.
|
||||
IType type1 = getOperand1().getExpressionType();
|
||||
IType ultimateType1 = SemanticUtil.getUltimateTypeUptoPointers(type1);
|
||||
if (ultimateType1 instanceof IProblemBinding) {
|
||||
|
@ -158,13 +217,13 @@ public class CPPASTBinaryExpression extends ASTNode implements
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
IType type2 = getOperand2().getExpressionType();
|
||||
IType ultimateType2 = SemanticUtil.getUltimateTypeUptoPointers(type2);
|
||||
if (ultimateType2 instanceof IProblemBinding) {
|
||||
return type2;
|
||||
}
|
||||
if (ultimateType1 instanceof ICPPClassType || ultimateType1 instanceof IEnumeration ||
|
||||
ultimateType2 instanceof ICPPClassType || ultimateType2 instanceof IEnumeration) {
|
||||
if(op != op_assign && isUserDefined(ultimateType1) || isUserDefined(ultimateType2)) {
|
||||
// If at least one of the types is user defined, the operator can be overloaded.
|
||||
ICPPFunction operator = CPPSemantics.findOverloadedOperator(this);
|
||||
if (operator != null) {
|
||||
|
@ -175,7 +234,8 @@ public class CPPASTBinaryExpression extends ASTNode implements
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
final int op = getOperator();
|
||||
switch (op) {
|
||||
case IASTBinaryExpression.op_lessEqual:
|
||||
|
@ -215,4 +275,10 @@ public class CPPASTBinaryExpression extends ASTNode implements
|
|||
}
|
||||
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
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
* John Camelon (IBM) - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
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.DOMException;
|
||||
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.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.cpp.semantics.CPPSemantics;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
*/
|
||||
public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpression {
|
||||
|
||||
private IASTExpression operand;
|
||||
private boolean isGlobal;
|
||||
private boolean isVectored;
|
||||
|
||||
private IASTImplicitName[] implicitNames = null;
|
||||
|
||||
|
||||
public CPPASTDeleteExpression() {
|
||||
}
|
||||
|
@ -76,7 +85,76 @@ public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpr
|
|||
public boolean 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
|
||||
public boolean accept( ASTVisitor action ){
|
||||
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( action.shouldVisitExpressions ){
|
||||
|
|
|
@ -1,30 +1,44 @@
|
|||
/*******************************************************************************
|
||||
* 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
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
* John Camelon (IBM) - Initial API and implementation
|
||||
* Mike Kucera (IBM) - implicit names
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||
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.IEnumeration;
|
||||
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||
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.internal.core.dom.parser.ASTNode;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
*/
|
||||
public class CPPASTExpressionList extends ASTNode implements
|
||||
IASTExpressionList, IASTAmbiguityParent {
|
||||
|
||||
public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionList, IASTAmbiguityParent {
|
||||
|
||||
|
||||
/**
|
||||
* Caution: may contain nulls.
|
||||
* @see CPPASTExpressionList#computeImplicitNames
|
||||
*/
|
||||
private IASTImplicitName[] implicitNames;
|
||||
|
||||
|
||||
public CPPASTExpressionList copy() {
|
||||
CPPASTExpressionList copy = new CPPASTExpressionList();
|
||||
for(IASTExpression expr : getExpressions())
|
||||
|
@ -59,9 +73,19 @@ public class CPPASTExpressionList extends ASTNode implements
|
|||
}
|
||||
}
|
||||
|
||||
IASTExpression [] exps = getExpressions();
|
||||
for( int i = 0; i < exps.length; i++ )
|
||||
if( !exps[i].accept( action ) ) return false;
|
||||
IASTExpression[] exps = getExpressions();
|
||||
IASTImplicitName[] implicits = action.shouldVisitImplicitNames ? computeImplicitNames() : null;
|
||||
|
||||
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 ){
|
||||
switch( action.leave( this ) ){
|
||||
|
@ -69,10 +93,81 @@ public class CPPASTExpressionList extends ASTNode implements
|
|||
case ASTVisitor.PROCESS_SKIP : return true;
|
||||
default : break;
|
||||
}
|
||||
}
|
||||
}
|
||||
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) {
|
||||
if( expressions == null ) return;
|
||||
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
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
* Bryan Wilkinson (QNX)
|
||||
* John Camelon (IBM) - Initial API and implementation
|
||||
* Bryan Wilkinson (QNX)
|
||||
* Mike Kucera (IBM)
|
||||
*******************************************************************************/
|
||||
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.IASTCompletionContext;
|
||||
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.IASTNode;
|
||||
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.IVariable;
|
||||
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.internal.core.dom.parser.ASTNode;
|
||||
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
|
||||
*/
|
||||
public class CPPASTFieldReference extends ASTNode implements
|
||||
ICPPASTFieldReference, IASTAmbiguityParent, IASTCompletionContext {
|
||||
ICPPASTFieldReference, IASTAmbiguityParent, IASTCompletionContext, IASTImplicitNameOwner {
|
||||
|
||||
private boolean isTemplate;
|
||||
private IASTExpression owner;
|
||||
private IASTName name;
|
||||
private boolean isDeref;
|
||||
|
||||
|
||||
private IASTImplicitName[] implicitNames = null;
|
||||
|
||||
public CPPASTFieldReference() {
|
||||
}
|
||||
|
@ -106,6 +111,34 @@ public class CPPASTFieldReference extends ASTNode implements
|
|||
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
|
||||
public boolean accept(ASTVisitor action) {
|
||||
if (action.shouldVisitExpressions) {
|
||||
|
@ -117,6 +150,13 @@ public class CPPASTFieldReference extends ASTNode implements
|
|||
}
|
||||
|
||||
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 (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
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
* John Camelon (IBM) - Initial API and implementation
|
||||
* Mike Kucera (IBM) - implicit names
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||
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.IASTFunctionCallExpression;
|
||||
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.IBinding;
|
||||
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.IType;
|
||||
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.ICPPConstructor;
|
||||
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.IASTAmbiguityParent;
|
||||
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.SemanticUtil;
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
*/
|
||||
|
||||
public class CPPASTFunctionCallExpression extends ASTNode implements
|
||||
IASTFunctionCallExpression, IASTAmbiguityParent {
|
||||
ICPPASTFunctionCallExpression, IASTAmbiguityParent {
|
||||
|
||||
private IASTExpression functionName;
|
||||
private IASTExpression parameter;
|
||||
|
||||
private IASTImplicitName[] implicitNames = null;
|
||||
|
||||
|
||||
public CPPASTFunctionCallExpression() {
|
||||
}
|
||||
|
@ -84,6 +88,51 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
|
|||
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
|
||||
public boolean accept( ASTVisitor action ){
|
||||
if( action.shouldVisitExpressions ){
|
||||
|
@ -95,8 +144,18 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
|
|||
}
|
||||
|
||||
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(implicits != null && implicits.length > 0)
|
||||
if(!implicits[1].accept(action)) return false;
|
||||
|
||||
if( action.shouldVisitExpressions ){
|
||||
switch( action.leave( this ) ){
|
||||
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() {
|
||||
return getExpressionType(null);
|
||||
}
|
||||
|
||||
private IType getExpressionType(ICPPFunction[] overload) {
|
||||
try {
|
||||
IType t= null;
|
||||
if (functionName instanceof IASTIdExpression) {
|
||||
|
@ -152,6 +221,8 @@ public class CPPASTFunctionCallExpression extends ASTNode implements
|
|||
} else if (t instanceof ICPPClassType) {
|
||||
ICPPFunction op = CPPSemantics.findOperator(this, (ICPPClassType) t);
|
||||
if (op != null) {
|
||||
if(overload != null)
|
||||
overload[0] = op;
|
||||
return op.getType().getReturnType();
|
||||
}
|
||||
} 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
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM - Initial API and implementation
|
||||
* John Camelon (IBM) - Initial API and implementation
|
||||
* Markus Schorn (Wind River Systems)
|
||||
* Mike Kucera (IBM)
|
||||
*******************************************************************************/
|
||||
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.IASTDeclarator;
|
||||
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.IASTPointerOperator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||
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.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.ASTQueries;
|
||||
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.core.runtime.Assert;
|
||||
|
||||
/**
|
||||
* @author jcamelon
|
||||
*/
|
||||
|
||||
public class CPPASTNewExpression extends ASTNode implements
|
||||
ICPPASTNewExpression, IASTAmbiguityParent {
|
||||
|
||||
|
@ -43,7 +48,8 @@ public class CPPASTNewExpression extends ASTNode implements
|
|||
|
||||
private IASTExpression [] arrayExpressions = null;
|
||||
|
||||
|
||||
private IASTImplicitName[] implicitNames = null;
|
||||
|
||||
|
||||
public CPPASTNewExpression() {
|
||||
}
|
||||
|
@ -171,6 +177,57 @@ public class CPPASTNewExpression extends ASTNode implements
|
|||
((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
|
||||
public boolean accept( ASTVisitor action ){
|
||||
if( action.shouldVisitExpressions ){
|
||||
|
@ -181,9 +238,16 @@ 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( typeId != null ) if( !typeId.accept( action ) ) return false;
|
||||
if( initializer != null ) if( !initializer.accept( action ) ) return false;
|
||||
|
||||
|
||||
if( action.shouldVisitExpressions ){
|
||||
switch( action.leave( this ) ){
|
||||
|
|
|
@ -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.IASTExpression;
|
||||
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.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
||||
|
@ -48,6 +49,8 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
|
|||
private int op;
|
||||
private IASTExpression operand;
|
||||
|
||||
private IASTImplicitName[] implicitNames = null;
|
||||
|
||||
public CPPASTUnaryExpression() {
|
||||
}
|
||||
|
||||
|
@ -83,7 +86,29 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
|
|||
expression.setPropertyInParent(OPERAND);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
public boolean accept(ASTVisitor action) {
|
||||
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(isPostfix && action.shouldVisitImplicitNames) {
|
||||
for(IASTImplicitName name : getImplicitNames()) {
|
||||
if(!name.accept(action)) return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (action.shouldVisitExpressions) {
|
||||
switch (action.leave(this)) {
|
||||
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() {
|
||||
final int op= getOperator();
|
||||
switch (op) {
|
||||
case IASTUnaryExpression.op_sizeof:
|
||||
case op_sizeof:
|
||||
return CPPVisitor.get_SIZE_T(this);
|
||||
case IASTUnaryExpression.op_typeid:
|
||||
case op_typeid:
|
||||
return CPPVisitor.get_type_info(this);
|
||||
}
|
||||
|
||||
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;
|
||||
boolean inParenthesis= false;
|
||||
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();
|
||||
type = SemanticUtil.getNestedType(type, TDEF | REF | CVQ);
|
||||
if (type instanceof IProblemBinding) {
|
||||
|
@ -193,7 +244,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres
|
|||
return operator;
|
||||
}
|
||||
|
||||
if(op == IASTUnaryExpression.op_not) {
|
||||
if(op == op_not) {
|
||||
return new CPPBasicType(ICPPBasicType.t_bool, 0);
|
||||
}
|
||||
if (type instanceof CPPBasicType) {
|
||||
|
|
|
@ -6,14 +6,13 @@
|
|||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
* Mike Kucera (IBM) - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTASMDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
|
||||
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.IASTCaseStatement;
|
||||
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.IASTEnumerationSpecifier;
|
||||
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.IASTFieldDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
|
||||
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.IASTTypeIdInitializerExpression;
|
||||
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.ICPPASTCastExpression;
|
||||
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.ICPPASTElaboratedTypeSpecifier;
|
||||
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.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.ICPPASTFunctionDefinition;
|
||||
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.
|
||||
*
|
||||
* @author Mike Kucera
|
||||
*/
|
||||
public class CPPNodeFactory implements ICPPNodeFactory {
|
||||
|
||||
|
@ -165,15 +163,15 @@ public class CPPNodeFactory implements ICPPNodeFactory {
|
|||
return new CPPASTIdExpression(name);
|
||||
}
|
||||
|
||||
public IASTArraySubscriptExpression newArraySubscriptExpression(IASTExpression arrayExpr, IASTExpression subscript) {
|
||||
public ICPPASTArraySubscriptExpression newArraySubscriptExpression(IASTExpression arrayExpr, IASTExpression subscript) {
|
||||
return new CPPASTArraySubscriptExpression(arrayExpr, subscript);
|
||||
}
|
||||
|
||||
public IASTExpressionList newExpressionList() {
|
||||
public ICPPASTExpressionList newExpressionList() {
|
||||
return new CPPASTExpressionList();
|
||||
}
|
||||
|
||||
public IASTFunctionCallExpression newFunctionCallExpression(IASTExpression idExpr, IASTExpression argList) {
|
||||
public ICPPASTFunctionCallExpression newFunctionCallExpression(IASTExpression idExpr, IASTExpression argList) {
|
||||
return new CPPASTFunctionCallExpression(idExpr, argList);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,8 +12,12 @@
|
|||
*******************************************************************************/
|
||||
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.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;
|
||||
|
||||
/**
|
||||
|
@ -78,9 +82,26 @@ public enum OverloadableOperator {
|
|||
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
|
||||
* 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}.
|
||||
*/
|
||||
|
@ -132,6 +153,11 @@ public enum OverloadableOperator {
|
|||
// other
|
||||
case IToken.tASSIGN: return ASSIGN;
|
||||
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;
|
||||
|
@ -203,4 +229,12 @@ public enum OverloadableOperator {
|
|||
}
|
||||
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 java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
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.ICPPASTConversionName;
|
||||
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.ICPPASTForStatement;
|
||||
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.parser.util.ArrayUtil;
|
||||
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.ObjectSet;
|
||||
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.CPPASTNameBase;
|
||||
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.CPPCompositeBinding;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPNamespace;
|
||||
|
@ -2525,6 +2530,7 @@ public class CPPSemantics {
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
@ -2534,6 +2540,13 @@ public class CPPSemantics {
|
|||
* @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();
|
||||
if (owner == null)
|
||||
return null;
|
||||
|
@ -2581,6 +2594,9 @@ public class CPPSemantics {
|
|||
if (op == null)
|
||||
break;
|
||||
|
||||
if(functionBindings != null)
|
||||
functionBindings.add(op);
|
||||
|
||||
type= op.getType().getReturnType();
|
||||
foundOperator= true;
|
||||
}
|
||||
|
@ -2609,42 +2625,40 @@ public class CPPSemantics {
|
|||
CPPASTName astName = new CPPASTName();
|
||||
astName.setParent(exp);
|
||||
astName.setPropertyInParent(STRING_LOOKUP_PROPERTY);
|
||||
LookupData data;
|
||||
LookupData data = new LookupData(astName);
|
||||
data.forceQualified = true;
|
||||
|
||||
if (exp instanceof IASTArraySubscriptExpression) {
|
||||
astName.setName(OverloadableOperator.BRACKET.toCharArray());
|
||||
data = new LookupData(astName);
|
||||
data.forceQualified = true;
|
||||
data.setFunctionArguments(((IASTArraySubscriptExpression) exp).getSubscriptExpression());
|
||||
} else if (exp instanceof IASTFieldReference) {
|
||||
astName.setName(OverloadableOperator.ARROW.toCharArray());
|
||||
data = new LookupData(astName);
|
||||
data.forceQualified = true;
|
||||
data.setFunctionArguments(IASTExpression.EMPTY_EXPRESSION_ARRAY);
|
||||
} else if (exp instanceof IASTFunctionCallExpression) {
|
||||
astName.setName(OverloadableOperator.PAREN.toCharArray());
|
||||
data = new LookupData(astName);
|
||||
data.forceQualified = true;
|
||||
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) {
|
||||
final IASTBinaryExpression binary = (IASTBinaryExpression) exp;
|
||||
OverloadableOperator operator = OverloadableOperator.fromBinaryExpression(binary);
|
||||
if (operator == null) {
|
||||
if (operator == null)
|
||||
return null;
|
||||
}
|
||||
astName.setName(operator.toCharArray());
|
||||
data = new LookupData(astName);
|
||||
data.forceQualified = true;
|
||||
data.setFunctionArguments(new IASTExpression[] { binary.getOperand2() });
|
||||
} else if (exp instanceof IASTUnaryExpression) {
|
||||
IASTUnaryExpression unary = (IASTUnaryExpression) exp;
|
||||
OverloadableOperator operator = OverloadableOperator.fromUnaryExpression(unary);
|
||||
if(operator == null) {
|
||||
if(operator == null)
|
||||
return null;
|
||||
}
|
||||
astName.setName(operator.toCharArray());
|
||||
data = new LookupData(astName);
|
||||
data.forceQualified = true;
|
||||
int op = unary.getOperator();
|
||||
if(op == IASTUnaryExpression.op_postFixDecr || op == IASTUnaryExpression.op_postFixIncr)
|
||||
data.setFunctionArguments(new IASTExpression[] { CPPASTLiteralExpression.INT_ZERO });
|
||||
|
@ -2663,7 +2677,75 @@ public class CPPSemantics {
|
|||
}
|
||||
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}
|
||||
* 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}
|
||||
* 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) {
|
||||
if (operator == null) {
|
||||
return null;
|
||||
|
@ -2721,6 +2858,8 @@ public class CPPSemantics {
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static IBinding[] findBindings(IScope scope, String name, boolean qualified) throws DOMException {
|
||||
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.ICPPASTConstructorChainInitializer;
|
||||
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.ICPPASTExplicitTemplateInstantiation;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
|
||||
|
@ -409,6 +410,13 @@ public class LookupData {
|
|||
if (tempNameParent instanceof IASTBinaryExpression) {
|
||||
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;
|
||||
}
|
||||
if (prop == IASTFieldReference.FIELD_NAME) {
|
||||
|
@ -549,8 +557,8 @@ public class LookupData {
|
|||
}
|
||||
setFunctionArguments(exprs);
|
||||
}
|
||||
|
||||
public void setFunctionArguments(IASTExpression[] exprs) {
|
||||
|
||||
public void setFunctionArguments(IASTExpression... exprs) {
|
||||
functionArgs= exprs;
|
||||
if (exprs.length != 0) {
|
||||
IASTNode node= exprs[0];
|
||||
|
|
|
@ -145,4 +145,18 @@ public class TokenUtil {
|
|||
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() {
|
||||
shouldVisitNames= true;
|
||||
shouldVisitImplicitNames = true;
|
||||
shouldVisitDeclarations= true;
|
||||
shouldVisitInitializers= true;
|
||||
shouldVisitDeclSpecifiers= true;
|
||||
|
|
Loading…
Add table
Reference in a new issue