1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-09-03 13:43:31 +02:00

Fix for 201204.

This commit is contained in:
Sergey Prigogin 2008-05-20 21:56:58 +00:00
parent 69ea8a3218
commit 17ed4692de
25 changed files with 652 additions and 568 deletions

View file

@ -1743,8 +1743,7 @@ public class AST2CPPTests extends AST2BaseTest {
def = (IASTFunctionDefinition) tu.getDeclarations()[2]; def = (IASTFunctionDefinition) tu.getDeclarations()[2];
expStatement = (IASTExpressionStatement) ((IASTCompoundStatement) def expStatement = (IASTExpressionStatement) ((IASTCompoundStatement) def
.getBody()).getStatements()[0]; .getBody()).getStatements()[0];
IASTUnaryExpression ue = (IASTUnaryExpression) expStatement IASTUnaryExpression ue = (IASTUnaryExpression) expStatement.getExpression();
.getExpression();
type = CPPVisitor.getExpressionType(ue); type = CPPVisitor.getExpressionType(ue);
assertTrue(type instanceof IQualifierType); assertTrue(type instanceof IQualifierType);
@ -1896,7 +1895,7 @@ public class AST2CPPTests extends AST2BaseTest {
IType t = pm.getType(); IType t = pm.getType();
assertNotNull(t); assertNotNull(t);
assertTrue(t instanceof ICPPPointerToMemberType); assertTrue(t instanceof ICPPPointerToMemberType);
ICPPClassType cls = ((ICPPPointerToMemberType) t).getMemberOfClass(); IType cls = ((ICPPPointerToMemberType) t).getMemberOfClass();
assertSame(S, cls); assertSame(S, cls);
assertTrue(((ICPPPointerToMemberType) t).getType() instanceof IBasicType); assertTrue(((ICPPPointerToMemberType) t).getType() instanceof IBasicType);
} }
@ -1937,9 +1936,8 @@ public class AST2CPPTests extends AST2BaseTest {
IType t = pm.getType(); IType t = pm.getType();
assertTrue(t instanceof ICPPPointerToMemberType); assertTrue(t instanceof ICPPPointerToMemberType);
IFunctionType ft = (IFunctionType) ((ICPPPointerToMemberType) t) IFunctionType ft = (IFunctionType) ((ICPPPointerToMemberType) t).getType();
.getType(); IType ST = ((ICPPPointerToMemberType) t).getMemberOfClass();
ICPPClassType ST = ((ICPPPointerToMemberType) t).getMemberOfClass();
assertTrue(ft.getReturnType() instanceof IPointerType); assertTrue(ft.getReturnType() instanceof IPointerType);
assertSame(ST, ((IPointerType) ft.getReturnType()).getType()); assertSame(ST, ((IPointerType) ft.getReturnType()).getType());

View file

@ -2009,14 +2009,14 @@ public class AST2TemplateTests extends AST2BaseTest {
assertTrue(col.getName(2).resolveBinding() instanceof ICPPSpecialization); assertTrue(col.getName(2).resolveBinding() instanceof ICPPSpecialization);
} }
// template<class T> // template<class T1>
// struct Closure { // struct Closure {
// Closure(T* obj, void (T::*method)()) {} // Closure(T1* obj1, void (T1::*method1)()) {}
// }; // };
// //
// template<class T> // template<class T2>
// Closure<T>* makeClosure(T* obj, void (T::*method)()) { // Closure<T2>* makeClosure(T2* obj2, void (T2::*method2)()) {
// return new Closure<T>(obj, method); // return new Closure<T2>(obj2, method2);
// } // }
// //
// struct A { // struct A {
@ -2025,7 +2025,7 @@ public class AST2TemplateTests extends AST2BaseTest {
// makeClosure(this, &A::m1); // makeClosure(this, &A::m1);
// } // }
// }; // };
public void _testBug201204() throws Exception { public void testBug201204() throws Exception {
BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), true); BindingAssertionHelper bh= new BindingAssertionHelper(getAboveComment(), true);
ICPPFunction fn= bh.assertNonProblem("makeClosure(this", 11, ICPPFunction.class); ICPPFunction fn= bh.assertNonProblem("makeClosure(this", 11, ICPPFunction.class);
} }

View file

@ -1400,7 +1400,7 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
try { try {
assertTrue(type instanceof ICPPPointerToMemberType); assertTrue(type instanceof ICPPPointerToMemberType);
ICPPPointerToMemberType ptmt = (ICPPPointerToMemberType) type; ICPPPointerToMemberType ptmt = (ICPPPointerToMemberType) type;
ICPPClassType classType = ptmt.getMemberOfClass(); ICPPClassType classType = (ICPPClassType) ptmt.getMemberOfClass();
assertQNEquals(cqn, classType); assertQNEquals(cqn, classType);
if(qn!=null) { if(qn!=null) {
assert(ptmt.getType() instanceof ICPPBinding); assert(ptmt.getType() instanceof ICPPBinding);

View file

@ -348,20 +348,17 @@ public class ASTTypeUtil {
} }
} }
try { if (((IPointerType) type).isConst()) {
if (((IPointerType) type).isConst()) { if (needSpace) {
if (needSpace) { result.append(SPACE); needSpace = false;
result.append(SPACE); needSpace = false;
}
result.append(Keywords.CONST); needSpace = true;
} }
if (((IPointerType) type).isVolatile()) { result.append(Keywords.CONST); needSpace = true;
if (needSpace) { }
result.append(SPACE); needSpace = false; if (((IPointerType) type).isVolatile()) {
} if (needSpace) {
result.append(Keywords.VOLATILE); needSpace = true; result.append(SPACE); needSpace = false;
} }
} catch (DOMException e) { result.append(Keywords.VOLATILE); needSpace = true;
} }
} else if (type instanceof IQualifierType) { } else if (type instanceof IQualifierType) {
if (type instanceof ICQualifierType) { if (type instanceof ICQualifierType) {

View file

@ -30,5 +30,5 @@ public interface IFunctionType extends IType {
* ISO C99 6.7.5.3, ISO C++98 8.3.4-3 * ISO C99 6.7.5.3, ISO C++98 8.3.4-3
* @throws DOMException * @throws DOMException
*/ */
public IType [] getParameterTypes() throws DOMException; public IType[] getParameterTypes() throws DOMException;
} }

View file

@ -28,11 +28,11 @@ public interface IPointerType extends IType {
* is this a const pointer * is this a const pointer
* @throws DOMException * @throws DOMException
*/ */
public boolean isConst() throws DOMException; public boolean isConst();
/** /**
* is this a volatile pointer * is this a volatile pointer
* @throws DOMException * @throws DOMException
*/ */
public boolean isVolatile() throws DOMException; public boolean isVolatile();
} }

View file

@ -1,13 +1,13 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005 IBM Corporation and others. * Copyright (c) 2005-2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM - Initial API and implementation * IBM - Initial API and implementation
* / * Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
/* /*
* Created on Apr 22, 2005 * Created on Apr 22, 2005
@ -15,20 +15,26 @@
package org.eclipse.cdt.core.dom.ast.cpp; package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IPointerType;
/** /**
* @author aniefer * @author aniefer
*
*/ */
public interface ICPPFunctionType extends IFunctionType { public interface ICPPFunctionType extends IFunctionType {
/** /**
* returns true for a constant method * Returns type of implicit <code>this</code>. parameter, or null, if the function
* is not a class method or a static method.
*/
public IPointerType getThisType();
/**
* Returns <code>true</code> for a constant method
*/ */
public boolean isConst(); public boolean isConst();
/** /**
* returns true for a volatile method * Returns <code>true</code> for a volatile method
*/ */
public boolean isVolatile(); public boolean isVolatile();
} }

View file

@ -7,6 +7,7 @@
* *
* Contributors: * Contributors:
* IBM Corporation - initial API and implementation * IBM Corporation - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
/* /*
@ -15,6 +16,7 @@
package org.eclipse.cdt.core.dom.ast.cpp; package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IType;
/** /**
* @author aniefer * @author aniefer
@ -22,8 +24,8 @@ import org.eclipse.cdt.core.dom.ast.IPointerType;
public interface ICPPPointerToMemberType extends IPointerType { public interface ICPPPointerToMemberType extends IPointerType {
/** /**
* Get the class to whose members this points to * Get the class to whose members this points to.
* * @return Either ICPPClassType or ICPPTeplateTypeParameter.
*/ */
public ICPPClassType getMemberOfClass(); public IType getMemberOfClass();
} }

View file

@ -50,11 +50,9 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBas
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
/** /**
* A utility that prints an AST to the console, useful for debugging purposes. * A utility that prints an AST to the console, useful for debugging purposes.
* *
*
* @author Mike Kucera * @author Mike Kucera
*/ */
@SuppressWarnings("nls") @SuppressWarnings("nls")
@ -70,39 +68,37 @@ public class ASTPrinter {
* to be called from a conditional breakpoint during debugging. * to be called from a conditional breakpoint during debugging.
*/ */
public static boolean print(IASTNode root, PrintStream out) { public static boolean print(IASTNode root, PrintStream out) {
if(root == null) { if (root == null) {
out.println("null"); out.println("null");
return false; return false;
} }
if(root instanceof IASTTranslationUnit) { if (root instanceof IASTTranslationUnit) {
IASTPreprocessorStatement[] preStats = ((IASTTranslationUnit)root).getAllPreprocessorStatements(); IASTPreprocessorStatement[] preStats = ((IASTTranslationUnit)root).getAllPreprocessorStatements();
if(preStats != null) { if (preStats != null) {
for(IASTPreprocessorStatement stat : preStats) for (IASTPreprocessorStatement stat : preStats)
print(out, 0, stat); print(out, 0, stat);
} }
} }
root.accept(new PrintVisitor(out)); root.accept(new PrintVisitor(out));
if(root instanceof IASTTranslationUnit) { if (root instanceof IASTTranslationUnit) {
IASTProblem[] problems = ((IASTTranslationUnit)root).getPreprocessorProblems(); IASTProblem[] problems = ((IASTTranslationUnit)root).getPreprocessorProblems();
if(problems != null) { if (problems != null) {
for(IASTProblem problem : problems) for (IASTProblem problem : problems)
print(out, 0, problem); print(out, 0, problem);
} }
IASTComment[] comments = ((IASTTranslationUnit)root).getComments(); IASTComment[] comments = ((IASTTranslationUnit)root).getComments();
if(comments != null) { if (comments != null) {
for(IASTComment comment : comments) for (IASTComment comment : comments)
print(out, 0, comment); print(out, 0, comment);
} }
} }
return false; return false;
} }
/** /**
* Prints the AST to stdout. * Prints the AST to stdout.
* *
@ -113,7 +109,6 @@ public class ASTPrinter {
return print(root, System.out); return print(root, System.out);
} }
/** /**
* Prints problem nodes in the AST to the given printstream. * Prints problem nodes in the AST to the given printstream.
* *
@ -121,17 +116,17 @@ public class ASTPrinter {
* to be called from a conditional breakpoint during debugging. * to be called from a conditional breakpoint during debugging.
*/ */
public static boolean printProblems(IASTNode root, PrintStream out) { public static boolean printProblems(IASTNode root, PrintStream out) {
if(root == null) { if (root == null) {
out.println("null"); out.println("null");
return false; return false;
} }
root.accept(new ProblemVisitor(out)); root.accept(new ProblemVisitor(out));
if(root instanceof IASTTranslationUnit) { if (root instanceof IASTTranslationUnit) {
IASTProblem[] problems = ((IASTTranslationUnit)root).getPreprocessorProblems(); IASTProblem[] problems = ((IASTTranslationUnit)root).getPreprocessorProblems();
if(problems != null) { if (problems != null) {
for(IASTProblem problem : problems) { for (IASTProblem problem : problems) {
print(out, 0, problem); print(out, 0, problem);
} }
} }
@ -140,7 +135,6 @@ public class ASTPrinter {
return false; return false;
} }
/** /**
* Prints problem nodes in the AST to stdout. * Prints problem nodes in the AST to stdout.
* *
@ -151,13 +145,11 @@ public class ASTPrinter {
return printProblems(root, System.out); return printProblems(root, System.out);
} }
private static void print(PrintStream out, int indentLevel, Object n) { private static void print(PrintStream out, int indentLevel, Object n) {
for(int i = 0; i < indentLevel; i++) for (int i = 0; i < indentLevel; i++)
out.print(" "); out.print(" ");
if(n == null) { if (n == null) {
out.println("NULL"); out.println("NULL");
return; return;
} }
@ -165,20 +157,20 @@ public class ASTPrinter {
String classname = n.getClass().getName(); String classname = n.getClass().getName();
out.print(classname); out.print(classname);
if(n instanceof ASTNode) { if (n instanceof ASTNode) {
ASTNode node = (ASTNode) n; ASTNode node = (ASTNode) n;
out.print(" (" + node.getOffset() + "," + node.getLength() + ") "); out.print(" (" + node.getOffset() + "," + node.getLength() + ") ");
if(node.getParent() == null && !(node instanceof IASTTranslationUnit)) { if (node.getParent() == null && !(node instanceof IASTTranslationUnit)) {
out.print("PARENT IS NULL "); out.print("PARENT IS NULL ");
} }
if(PRINT_PARENT_PROPERTIES) if (PRINT_PARENT_PROPERTIES)
out.print(node.getPropertyInParent()); out.print(node.getPropertyInParent());
} }
if(n instanceof ICArrayType) { if (n instanceof ICArrayType) {
ICArrayType at = (ICArrayType)n; ICArrayType at = (ICArrayType)n;
try { try {
if(at.isRestrict()) { if (at.isRestrict()) {
out.print(" restrict"); out.print(" restrict");
} }
} catch (DOMException e) { } catch (DOMException e) {
@ -186,64 +178,53 @@ public class ASTPrinter {
} }
} }
if(n instanceof IASTName) { if (n instanceof IASTName) {
out.print(" " + ((IASTName)n).toString()); out.print(" " + ((IASTName)n).toString());
} } else if (n instanceof ICASTPointer) {
else if(n instanceof ICASTPointer) {
ICASTPointer pointer = (ICASTPointer) n; ICASTPointer pointer = (ICASTPointer) n;
if(pointer.isConst()) if (pointer.isConst())
out.print(" const"); out.print(" const");
if(pointer.isVolatile()) if (pointer.isVolatile())
out.print(" volatile"); out.print(" volatile");
if(pointer.isRestrict()) if (pointer.isRestrict())
out.print(" restrict"); out.print(" restrict");
} } else if (n instanceof ICPointerType) {
else if(n instanceof ICPointerType) {
ICPointerType pointer = (ICPointerType)n; ICPointerType pointer = (ICPointerType)n;
try { if (pointer.isConst())
if(pointer.isConst()) out.print(" const");
out.print(" const"); if (pointer.isVolatile())
if(pointer.isVolatile()) out.print(" volatile");
out.print(" volatile"); if (pointer.isRestrict())
if(pointer.isRestrict()) out.print(" restrict");
out.print(" restrict");
} catch (DOMException e) {
e.printStackTrace();
}
out.println(); out.println();
try { try {
print(out, indentLevel, ((ITypeContainer)n).getType()); print(out, indentLevel, ((ITypeContainer)n).getType());
} catch(Exception e) {} } catch(Exception e) {}
} } else if (n instanceof ICASTArrayModifier) {
else if(n instanceof ICASTArrayModifier) { if (((ICASTArrayModifier)n).isRestrict()) {
if(((ICASTArrayModifier)n).isRestrict()) {
out.print(" restrict"); out.print(" restrict");
} }
} } else if (n instanceof IASTComment) {
else if(n instanceof IASTComment) {
out.print("'" + new String(((IASTComment)n).getComment()) + "'"); out.print("'" + new String(((IASTComment)n).getComment()) + "'");
} // } else if (n instanceof ICompositeType) {
// else if(n instanceof ICompositeType) {
// try { // try {
// IField[] fields = ((ICompositeType)n).getFields(); // IField[] fields = ((ICompositeType)n).getFields();
// if(fields == null || fields.length == 0) { // if (fields == null || fields.length == 0) {
// out.print(" no fields"); // out.print(" no fields");
// } // }
// for(IField field : fields) { // for (IField field : fields) {
// out.println(); // out.println();
// print(out, indentLevel + 1, field); // print(out, indentLevel + 1, field);
// } // }
// } catch (DOMException e) { // } catch (DOMException e) {
// e.printStackTrace(); // e.printStackTrace();
// } // }
// } } else if (n instanceof ITypeContainer) {
else if(n instanceof ITypeContainer) {
out.println(); out.println();
try { try {
print(out, indentLevel, ((ITypeContainer)n).getType()); print(out, indentLevel, ((ITypeContainer)n).getType());
} catch(Exception e) {} } catch(Exception e) {}
} } else if (n instanceof IVariable) {
else if(n instanceof IVariable) {
IVariable var = (IVariable) n; IVariable var = (IVariable) n;
IType t; IType t;
try { try {
@ -254,16 +235,13 @@ public class ASTPrinter {
//e.printStackTrace(); //e.printStackTrace();
} }
} } else if (n instanceof IProblemBinding) {
else if(n instanceof IProblemBinding) {
IProblemBinding problem = (IProblemBinding)n; IProblemBinding problem = (IProblemBinding)n;
out.print(problem.getMessage()); out.print(problem.getMessage());
} }
out.println(); out.println();
} }
private static class ProblemVisitor extends ASTVisitor { private static class ProblemVisitor extends ASTVisitor {
private PrintStream out; private PrintStream out;
@ -284,27 +262,26 @@ public class ASTPrinter {
@Override @Override
public int visit(IASTDeclaration declaration) { public int visit(IASTDeclaration declaration) {
if(declaration instanceof IASTProblemDeclaration) if (declaration instanceof IASTProblemDeclaration)
print(out, 0, declaration); print(out, 0, declaration);
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
@Override @Override
public int visit(IASTExpression expression) { public int visit(IASTExpression expression) {
if(expression instanceof IASTProblemExpression) if (expression instanceof IASTProblemExpression)
print(out, 0, expression); print(out, 0, expression);
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
@Override @Override
public int visit(IASTStatement statement) { public int visit(IASTStatement statement) {
if(statement instanceof IASTProblemStatement) if (statement instanceof IASTProblemStatement)
print(out, 0, statement); print(out, 0, statement);
return PROCESS_CONTINUE; return PROCESS_CONTINUE;
} }
} }
/** /**
* This visitor extends from CPPASTVisitor but you can still * This visitor extends from CPPASTVisitor but you can still
* apply it to a plain C AST and it will print everything * apply it to a plain C AST and it will print everything
@ -335,7 +312,6 @@ public class ASTPrinter {
shouldVisitTemplateParameters = true; shouldVisitTemplateParameters = true;
} }
private void print(IASTNode node) { private void print(IASTNode node) {
ASTPrinter.print(out, indentLevel, node); ASTPrinter.print(out, indentLevel, node);
} }
@ -366,7 +342,7 @@ public class ASTPrinter {
for (IASTPointerOperator pointer : pointers) { for (IASTPointerOperator pointer : pointers) {
print(pointer); print(pointer);
} }
if(declarator instanceof IASTArrayDeclarator) { if (declarator instanceof IASTArrayDeclarator) {
IASTArrayDeclarator decl = (IASTArrayDeclarator)declarator; IASTArrayDeclarator decl = (IASTArrayDeclarator)declarator;
org.eclipse.cdt.core.dom.ast.IASTArrayModifier[] modifiers = decl.getArrayModifiers(); org.eclipse.cdt.core.dom.ast.IASTArrayModifier[] modifiers = decl.getArrayModifiers();
for (IASTArrayModifier modifier : modifiers) { for (IASTArrayModifier modifier : modifiers) {
@ -407,7 +383,7 @@ public class ASTPrinter {
@Override @Override
public int visit(IASTName name) { public int visit(IASTName name) {
print(name); print(name);
if(RESOLVE_BINDINGS) { if (RESOLVE_BINDINGS) {
try { try {
IBinding binding = name.resolveBinding(); IBinding binding = name.resolveBinding();
print(binding); print(binding);
@ -475,7 +451,6 @@ public class ASTPrinter {
return super.visit(templateParameter); return super.visit(templateParameter);
} }
// @Override // @Override
// public int leave(ICASTDesignator designator) { // public int leave(ICASTDesignator designator) {
// indentLevel--; // indentLevel--;
@ -571,6 +546,5 @@ public class ASTPrinter {
indentLevel--; indentLevel--;
return super.leave(templateParameter); return super.leave(templateParameter);
} }
}
}
} }

View file

@ -11,6 +11,7 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
@ -360,4 +361,13 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition implements ICPPFu
public boolean isStatic( boolean resolveAll ) { public boolean isStatic( boolean resolveAll ) {
return hasStorageClass( IASTDeclSpecifier.sc_static ); return hasStorageClass( IASTDeclSpecifier.sc_static );
} }
@Override
public String toString() {
StringBuilder result = new StringBuilder();
result.append(getName());
IFunctionType t = getType();
result.append(t != null ? ASTTypeUtil.getParameterTypeString(t) : "()"); //$NON-NLS-1$
return result.toString();
}
} }

View file

@ -14,8 +14,10 @@
*/ */
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
@ -24,73 +26,74 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
* @author aniefer * @author aniefer
*/ */
public class CPPFunctionType implements ICPPFunctionType { public class CPPFunctionType implements ICPPFunctionType {
private IType[] parameters = null; private IType[] parameters;
private IType returnType = null; private IType returnType;
private boolean isConst = false; private IPointerType thisType;
private boolean isVolatile = false;
/** /**
* @param returnType * @param returnType
* @param types * @param types
*/ */
public CPPFunctionType( IType returnType, IType [] types ) { public CPPFunctionType(IType returnType, IType[] types) {
this.returnType = returnType; this.returnType = returnType;
this.parameters = types; this.parameters = types;
} }
public CPPFunctionType( IType returnType, IType [] types, boolean isConst, boolean isVolatile ) {
this.returnType = returnType;
this.parameters = types;
this.isConst = isConst;
this.isVolatile = isVolatile;
}
public boolean isSameType( IType o ){ public CPPFunctionType(IType returnType, IType[] types, IPointerType thisType) {
if( o instanceof ITypedef ) this.returnType = returnType;
return o.isSameType( this ); this.parameters = types;
if( o instanceof ICPPFunctionType ){ this.thisType = thisType;
}
public boolean isSameType(IType o) {
if (o instanceof ITypedef)
return o.isSameType(this);
if (o instanceof ICPPFunctionType) {
ICPPFunctionType ft = (ICPPFunctionType) o; ICPPFunctionType ft = (ICPPFunctionType) o;
IType [] fps; IType[] fps;
try { try {
fps = ft.getParameterTypes(); fps = ft.getParameterTypes();
} catch ( DOMException e ) { } catch (DOMException e) {
return false; return false;
} }
try { try {
//constructors & destructors have null return type //constructors & destructors have null return type
if( ( returnType == null ) ^ ( ft.getReturnType() == null ) ) if ((returnType == null) ^ (ft.getReturnType() == null))
return false; return false;
else if( returnType != null && ! returnType.isSameType( ft.getReturnType() ) ) else if (returnType != null && ! returnType.isSameType(ft.getReturnType()))
return false; return false;
} catch ( DOMException e1 ) { } catch (DOMException e1) {
return false; return false;
} }
try { try {
if( parameters.length == 1 && fps.length == 0 ){ if (parameters.length == 1 && fps.length == 0) {
if( !(parameters[0] instanceof IBasicType) || ((IBasicType)parameters[0]).getType() != IBasicType.t_void ) if (!(parameters[0] instanceof IBasicType) || ((IBasicType) parameters[0]).getType() != IBasicType.t_void)
return false; return false;
} else if( fps.length == 1 && parameters.length == 0 ){ } else if (fps.length == 1 && parameters.length == 0) {
if( !(fps[0] instanceof IBasicType) || ((IBasicType)fps[0]).getType() != IBasicType.t_void ) if (!(fps[0] instanceof IBasicType) || ((IBasicType) fps[0]).getType() != IBasicType.t_void)
return false; return false;
} else if( parameters.length != fps.length ){ } else if (parameters.length != fps.length) {
return false; return false;
} else { } else {
for( int i = 0; i < parameters.length; i++ ){ for (int i = 0; i < parameters.length; i++) {
if (parameters[i] == null || ! parameters[i].isSameType( fps[i] ) ) if (parameters[i] == null || ! parameters[i].isSameType(fps[i]))
return false; return false;
} }
} }
} catch (DOMException e ){ } catch (DOMException e) {
return false; return false;
} }
if( isConst != ft.isConst() || isVolatile != ft.isVolatile() ) if (isConst() != ft.isConst() || isVolatile() != ft.isVolatile()) {
return false; return false;
}
return true; return true;
} }
return false; return false;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IFunctionType#getReturnType() * @see org.eclipse.cdt.core.dom.ast.IFunctionType#getReturnType()
*/ */
@ -106,21 +109,33 @@ public class CPPFunctionType implements ICPPFunctionType {
} }
@Override @Override
public Object clone(){ public Object clone() {
IType t = null; IType t = null;
try { try {
t = (IType) super.clone(); t = (IType) super.clone();
} catch ( CloneNotSupportedException e ) { } catch (CloneNotSupportedException e) {
//not going to happen //not going to happen
} }
return t; return t;
} }
public boolean isConst() { /* (non-Javadoc)
return isConst; * @see org.eclipse.cdt.core.dom.ast.ICPPFunctionType#getThisType()
*/
public IPointerType getThisType() {
return thisType;
}
public final boolean isConst() {
return thisType != null && thisType.isConst();
} }
public boolean isVolatile() { public final boolean isVolatile() {
return isVolatile; return thisType != null && thisType.isVolatile();
}
@Override
public String toString() {
return ASTTypeUtil.getType(this);
} }
} }

View file

@ -1,13 +1,14 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2006 IBM Corporation and others. * Copyright (c) 2005, 2008 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM - Initial API and implementation * IBM - Initial API and implementation
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
/* /*
* Created on Feb 11, 2005 * Created on Feb 11, 2005
@ -28,10 +29,10 @@ import org.eclipse.cdt.internal.core.index.IIndexType;
/** /**
* @author aniefer * @author aniefer
*/ */
public class CPPPointerToMemberType extends CPPPointerType implements public class CPPPointerToMemberType extends CPPPointerType implements ICPPPointerToMemberType {
ICPPPointerToMemberType { private ICPPASTPointerToMember operator;
private ICPPASTPointerToMember operator = null; private IType classType; // Can be either ICPPClassType or ICPPTemplateTypeParameter
private ICPPClassType clsType = null;
/** /**
* @param type * @param type
* @param operator * @param operator
@ -41,49 +42,53 @@ public class CPPPointerToMemberType extends CPPPointerType implements
this.operator = operator; this.operator = operator;
} }
@Override public CPPPointerToMemberType(IType type, ICPPClassType thisType, boolean isConst, boolean isVolatile) {
public boolean isSameType( IType o ){ super(type, isConst, isVolatile);
if( o == this ) this.classType = thisType;
return true; }
if( o instanceof ITypedef || o instanceof IIndexType)
return o.isSameType( this );
if( !super.isSameType( o ) ) @Override
public boolean isSameType(IType o) {
if (o == this)
return true;
if (o instanceof ITypedef || o instanceof IIndexType)
return o.isSameType(this);
if (!super.isSameType(o))
return false; return false;
if( !( o instanceof CPPPointerToMemberType ) ) if (!(o instanceof CPPPointerToMemberType))
return false; return false;
CPPPointerToMemberType pt = (CPPPointerToMemberType) o; CPPPointerToMemberType pt = (CPPPointerToMemberType) o;
ICPPClassType cls = pt.getMemberOfClass(); IType cls = pt.getMemberOfClass();
if( cls != null ) if (cls != null)
return cls.isSameType( getMemberOfClass() ); return cls.isSameType(getMemberOfClass());
return false; return false;
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType#getMemberOfClass() * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType#getMemberOfClass()
*/ */
public ICPPClassType getMemberOfClass() { public IType getMemberOfClass() {
if( clsType == null ){ if (classType == null) {
ICPPASTPointerToMember pm = operator; ICPPASTPointerToMember pm = operator;
IASTName name = pm.getName(); IASTName name = pm.getName();
if( name instanceof ICPPASTQualifiedName ){ if (name instanceof ICPPASTQualifiedName) {
IASTName [] ns = ((ICPPASTQualifiedName)name).getNames(); IASTName[] ns = ((ICPPASTQualifiedName)name).getNames();
if( ns.length > 1 ) if (ns.length > 1)
name = ns[ ns.length - 2 ]; name = ns[ns.length - 2];
else else
name = ns[ ns.length - 1 ]; name = ns[ns.length - 1];
} }
IBinding binding = name.resolveBinding(); IBinding binding = name.resolveBinding();
if( binding instanceof ICPPClassType ){ if (binding instanceof IType) {
clsType = (ICPPClassType) binding; classType = (IType) binding;
} else { } else {
clsType = new CPPClassType.CPPClassTypeProblem( name, IProblemBinding.SEMANTIC_INVALID_TYPE, name.toCharArray() ); classType = new CPPClassType.CPPClassTypeProblem(name, IProblemBinding.SEMANTIC_INVALID_TYPE, name.toCharArray());
} }
} }
return clsType; return classType;
} }
} }

View file

@ -29,7 +29,6 @@ public class CPPPointerType implements IPointerType, ITypeContainer {
protected IType type = null; protected IType type = null;
private boolean isConst = false; private boolean isConst = false;
private boolean isVolatile = false; private boolean isVolatile = false;
public CPPPointerType(IType type, IASTPointer operator) { public CPPPointerType(IType type, IASTPointer operator) {
this.type = type; this.type = type;
@ -37,20 +36,19 @@ public class CPPPointerType implements IPointerType, ITypeContainer {
this.isVolatile = operator.isVolatile(); this.isVolatile = operator.isVolatile();
} }
public CPPPointerType(IType type, boolean isConst, boolean isVolatile) {
public CPPPointerType(IType type, boolean isConst, boolean isVolatile ) {
this.type = type; this.type = type;
this.isConst = isConst; this.isConst = isConst;
this.isVolatile = isVolatile; this.isVolatile = isVolatile;
} }
public CPPPointerType( IType type ){ public CPPPointerType(IType type) {
this.type = type; this.type = type;
} }
public IType stripQualifiers(){ public IType stripQualifiers() {
CPPPointerType result = this; CPPPointerType result = this;
if( isConst || isVolatile ){ if (isConst || isVolatile) {
result = (CPPPointerType) clone(); result = (CPPPointerType) clone();
result.isConst = false; result.isConst = false;
result.isVolatile = false; result.isVolatile = false;
@ -58,21 +56,21 @@ public class CPPPointerType implements IPointerType, ITypeContainer {
return result; return result;
} }
public boolean isSameType( IType o ){ public boolean isSameType(IType o) {
if( o == this ) if (o == this)
return true; return true;
if( o instanceof ITypedef || o instanceof IIndexType) if (o instanceof ITypedef || o instanceof IIndexType)
return o.isSameType( this ); return o.isSameType(this);
if( !( o instanceof CPPPointerType ) ) if (!(o instanceof CPPPointerType))
return false; return false;
if( type == null ) if (type == null)
return false; return false;
CPPPointerType pt = (CPPPointerType) o; CPPPointerType pt = (CPPPointerType) o;
if( isConst == pt.isConst && isVolatile == pt.isVolatile ) if (isConst == pt.isConst && isVolatile == pt.isVolatile)
return type.isSameType( pt.getType() ); return type.isSameType(pt.getType());
return false; return false;
} }
@ -80,7 +78,7 @@ public class CPPPointerType implements IPointerType, ITypeContainer {
return type; return type;
} }
public void setType( IType t ){ public void setType(IType t) {
type = t; type = t;
} }
@ -93,11 +91,11 @@ public class CPPPointerType implements IPointerType, ITypeContainer {
} }
@Override @Override
public Object clone(){ public Object clone() {
IType t = null; IType t = null;
try { try {
t = (IType) super.clone(); t = (IType) super.clone();
} catch ( CloneNotSupportedException e ) { } catch (CloneNotSupportedException e) {
//not going to happen //not going to happen
} }
return t; return t;

View file

@ -159,7 +159,7 @@ public class CPPSemantics {
public static final IType VOID_TYPE = new CPPBasicType(IBasicType.t_void, 0); public static final IType VOID_TYPE = new CPPBasicType(IBasicType.t_void, 0);
// Set to true for debugging. // Set to true for debugging.
public static boolean traceBindingResolution = false; public static boolean traceBindingResolution = true;
static protected IBinding resolveBinding(IASTName name) { static protected IBinding resolveBinding(IASTName name) {
if (traceBindingResolution) { if (traceBindingResolution) {
@ -489,10 +489,8 @@ public class CPPSemantics {
getAssociatedScopes(getUltimateType(element, true), namespaces, classes, tu); getAssociatedScopes(getUltimateType(element, true), namespaces, classes, tu);
} }
} else if (t instanceof ICPPPointerToMemberType) { } else if (t instanceof ICPPPointerToMemberType) {
IBinding binding = ((ICPPPointerToMemberType)t).getMemberOfClass(); IType binding = ((ICPPPointerToMemberType) t).getMemberOfClass();
if (binding instanceof IType) getAssociatedScopes(binding, namespaces, classes, tu);
getAssociatedScopes((IType)binding, namespaces, classes, tu);
getAssociatedScopes(getUltimateType(((ICPPPointerToMemberType)t).getType(), true), namespaces, classes, tu);
} }
return; return;
} }

View file

@ -106,6 +106,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethodInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethodSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethodSpecialization;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethodTemplateSpecialization; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethodTemplateSpecialization;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPParameter; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPParameter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateDefinition; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateDefinition;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTemplateParameter; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTemplateParameter;
@ -701,8 +702,7 @@ public class CPPTemplates {
} }
} catch (DOMException e) { } catch (DOMException e) {
} }
return new CPPFunctionType(ret, params, ((ICPPFunctionType) type).isConst(), return new CPPFunctionType(ret, params, ((ICPPFunctionType) type).getThisType());
((ICPPFunctionType) type).isVolatile());
} }
if (type instanceof ICPPTemplateParameter) { if (type instanceof ICPPTemplateParameter) {
@ -750,6 +750,16 @@ public class CPPTemplates {
try { try {
IType temp = ((ITypeContainer) type).getType(); IType temp = ((ITypeContainer) type).getType();
IType newType = instantiateType(temp, argMap, instantiationScope); IType newType = instantiateType(temp, argMap, instantiationScope);
if (type instanceof ICPPPointerToMemberType) {
ICPPPointerToMemberType ptm = (ICPPPointerToMemberType) type;
IType memberOfClass = ptm.getMemberOfClass();
IType newMemberOfClass = instantiateType(memberOfClass, argMap, instantiationScope);
if ((newType != temp || newMemberOfClass != memberOfClass) &&
newMemberOfClass instanceof ICPPClassType) {
return new CPPPointerToMemberType(newType, (ICPPClassType) newMemberOfClass,
ptm.isConst(), ptm.isVolatile());
}
}
if (newType != temp) { if (newType != temp) {
temp = (IType) type.clone(); temp = (IType) type.clone();
((ITypeContainer) temp).setType(newType); ((ITypeContainer) temp).setType(newType);
@ -1319,7 +1329,7 @@ public class CPPTemplates {
return false; return false;
p = ((ICPPPointerToMemberType) p).getType(); p = ((ICPPPointerToMemberType) p).getType();
p = ((ICPPPointerToMemberType) a).getType(); a = ((ICPPPointerToMemberType) a).getType();
} else if (p instanceof IPointerType) { } else if (p instanceof IPointerType) {
if (!(a instanceof IPointerType)) { if (!(a instanceof IPointerType)) {
return false; return false;
@ -1651,8 +1661,7 @@ public class CPPTemplates {
} }
//14.1s8 function to pointer and array to pointer conversions //14.1s8 function to pointer and array to pointer conversions
if (pType instanceof IFunctionType) if (pType instanceof IFunctionType) {
{
pType = new CPPPointerType(pType); pType = new CPPPointerType(pType);
} else if (pType instanceof IArrayType) { } else if (pType instanceof IArrayType) {
try { try {

View file

@ -124,6 +124,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
@ -1556,16 +1557,27 @@ public class CPPVisitor {
IASTName name = fnDtor.getName(); IASTName name = fnDtor.getName();
if (name instanceof ICPPASTQualifiedName) { if (name instanceof ICPPASTQualifiedName) {
IASTName[] ns = ((ICPPASTQualifiedName)name).getNames(); IASTName[] ns = ((ICPPASTQualifiedName) name).getNames();
name = ns[ns.length - 1]; name = ns[ns.length - 1];
} }
if (name instanceof ICPPASTConversionName) { if (name instanceof ICPPASTConversionName) {
returnType = createType(((ICPPASTConversionName)name).getTypeId()); returnType = createType(((ICPPASTConversionName) name).getTypeId());
} else { } else {
returnType = getPointerTypes(returnType, fnDtor); returnType = getPointerTypes(returnType, fnDtor);
} }
IType type = new CPPFunctionType(returnType, pTypes, fnDtor.isConst(), fnDtor.isVolatile()); IScope scope = fnDtor.getFunctionScope();
IType thisType = getThisType(scope);
if (thisType instanceof IPointerType) {
try {
IType classType = ((IPointerType) thisType).getType();
thisType = new CPPPointerType(classType, fnDtor.isConst(), fnDtor.isVolatile());
} catch (DOMException e) {
}
} else {
thisType = null;
}
IType type = new CPPFunctionType(returnType, pTypes, (IPointerType) thisType);
IASTDeclarator nested = fnDtor.getNestedDeclarator(); IASTDeclarator nested = fnDtor.getNestedDeclarator();
if (nested != null) { if (nested != null) {
return createType(type, nested); return createType(type, nested);
@ -1726,34 +1738,41 @@ public class CPPVisitor {
try { try {
IASTNode node = null; IASTNode node = null;
while (scope != null) { while (scope != null) {
if (scope instanceof ICPPBlockScope) { if (scope instanceof ICPPBlockScope || scope instanceof ICPPFunctionScope) {
node = ASTInternal.getPhysicalNodeOfScope(scope); node = ASTInternal.getPhysicalNodeOfScope(scope);
if (node instanceof IASTFunctionDeclarator)
break;
if (node.getParent() instanceof IASTFunctionDefinition) if (node.getParent() instanceof IASTFunctionDefinition)
break; break;
} }
scope = scope.getParent(); scope = scope.getParent();
} }
if (node != null && node.getParent() instanceof IASTFunctionDefinition) { if (node != null) {
IASTFunctionDefinition def = (IASTFunctionDefinition) node.getParent(); if (node.getParent() instanceof IASTFunctionDefinition) {
IASTName fName = def.getDeclarator().getName(); IASTFunctionDefinition def = (IASTFunctionDefinition) node.getParent();
if (fName instanceof ICPPASTQualifiedName) { node = def.getDeclarator();
IASTName[] ns = ((ICPPASTQualifiedName)fName).getNames();
fName = ns[ns.length - 1];
} }
IScope s = getContainingScope(fName); if (node instanceof IASTFunctionDeclarator) {
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) def.getDeclarator(); ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) node;
if (s instanceof ICPPTemplateScope) IASTName fName = dtor.getName();
s = getParentScope(s, fName.getTranslationUnit()); if (fName instanceof ICPPASTQualifiedName) {
if (s instanceof ICPPClassScope) { IASTName[] ns = ((ICPPASTQualifiedName)fName).getNames();
ICPPClassScope cScope = (ICPPClassScope) s; fName = ns[ns.length - 1];
IType type = cScope.getClassType(); }
if (type instanceof ICPPClassTemplate) { IScope s = getContainingScope(fName);
type = (IType) CPPTemplates.instantiateWithinClassTemplate((ICPPClassTemplate) type); if (s instanceof ICPPTemplateScope)
s = getParentScope(s, fName.getTranslationUnit());
if (s instanceof ICPPClassScope) {
ICPPClassScope cScope = (ICPPClassScope) s;
IType type = cScope.getClassType();
if (type instanceof ICPPClassTemplate) {
type = (IType) CPPTemplates.instantiateWithinClassTemplate((ICPPClassTemplate) type);
}
if (dtor.isConst() || dtor.isVolatile())
type = new CPPQualifierType(type, dtor.isConst(), dtor.isVolatile());
type = new CPPPointerType(type);
return type;
} }
if (dtor.isConst() || dtor.isVolatile())
type = new CPPQualifierType(type, dtor.isConst(), dtor.isVolatile());
type = new CPPPointerType(type);
return type;
} }
} }
} catch (DOMException e) { } catch (DOMException e) {
@ -1942,7 +1961,7 @@ public class CPPVisitor {
if (op == IASTUnaryExpression.op_star && type instanceof ICPPClassType) { if (op == IASTUnaryExpression.op_star && type instanceof ICPPClassType) {
try { try {
ICPPFunction operator= CPPSemantics.findOperator(expression, (ICPPClassType) type); ICPPFunction operator= CPPSemantics.findOperator(expression, (ICPPClassType) type);
if (operator!=null) { if (operator != null) {
return operator.getType().getReturnType(); return operator.getType().getReturnType();
} }
} catch(DOMException de) { } catch(DOMException de) {
@ -1951,19 +1970,34 @@ public class CPPVisitor {
} }
if (op == IASTUnaryExpression.op_star && (type instanceof IPointerType || type instanceof IArrayType)) { if (op == IASTUnaryExpression.op_star && (type instanceof IPointerType || type instanceof IArrayType)) {
try { try {
return ((ITypeContainer)type).getType(); return ((ITypeContainer) type).getType();
} catch (DOMException e) { } catch (DOMException e) {
return e.getProblem(); return e.getProblem();
} }
} else if (op == IASTUnaryExpression.op_amper) { } else if (op == IASTUnaryExpression.op_amper) {
if (type instanceof ICPPReferenceType) if (type instanceof ICPPReferenceType) {
try { try {
return new CPPPointerType(((ICPPReferenceType)type).getType()); type = ((ICPPReferenceType) type).getType();
} catch (DOMException e) { } catch (DOMException e) {
} }
}
if (type instanceof ICPPFunctionType) {
ICPPFunctionType functionType = (ICPPFunctionType) type;
IPointerType thisType = functionType.getThisType();
if (thisType != null) {
ICPPClassType classType;
try {
classType = (ICPPClassType) thisType.getType();
} catch (DOMException e) {
return e.getProblem();
}
return new CPPPointerToMemberType(type, classType,
thisType.isConst(), thisType.isVolatile());
}
}
return new CPPPointerType(type); return new CPPPointerType(type);
} else if (type instanceof CPPBasicType) { } else if (type instanceof CPPBasicType) {
((CPPBasicType)type).setValue(expression); ((CPPBasicType) type).setValue(expression);
} }
return type; return type;
} else if (expression instanceof ICPPASTFieldReference) { } else if (expression instanceof ICPPASTFieldReference) {

View file

@ -10,6 +10,7 @@
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Bryan Wilkinson (QNX) * Bryan Wilkinson (QNX)
* Andrew Ferguson (Symbian) * Andrew Ferguson (Symbian)
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
@ -65,7 +66,7 @@ public class Conversions {
public static Cost checkImplicitConversionSequence(boolean allowUDC, IASTExpression sourceExp, IType source, IType target, boolean isImpliedObject) throws DOMException { public static Cost checkImplicitConversionSequence(boolean allowUDC, IASTExpression sourceExp, IType source, IType target, boolean isImpliedObject) throws DOMException {
Cost cost; Cost cost;
if(!isImpliedObject && target instanceof ICPPReferenceType) { if (!isImpliedObject && target instanceof ICPPReferenceType) {
// [13.3.3.3.1] Reference binding // [13.3.3.3.1] Reference binding
IType cv1T1= ((ICPPReferenceType)target).getType(); IType cv1T1= ((ICPPReferenceType)target).getType();
cost= new Cost(source, cv1T1); cost= new Cost(source, cv1T1);
@ -74,7 +75,7 @@ public class Conversions {
boolean lvalue= sourceExp == null || !CPPVisitor.isRValue(sourceExp); boolean lvalue= sourceExp == null || !CPPVisitor.isRValue(sourceExp);
IType T2= source instanceof IQualifierType ? ((IQualifierType)source).getType() : source; IType T2= source instanceof IQualifierType ? ((IQualifierType)source).getType() : source;
if(lvalue && isReferenceCompatible(cv1T1, source)) { if (lvalue && isReferenceCompatible(cv1T1, source)) {
/* Direct reference binding */ /* Direct reference binding */
// [13.3.3.1.4] // [13.3.3.1.4]
@ -86,7 +87,7 @@ public class Conversions {
qualificationConversion(cost); qualificationConversion(cost);
derivedToBaseConversion(cost); derivedToBaseConversion(cost);
} else if(T2 instanceof ICPPClassType && allowUDC) { } else if (T2 instanceof ICPPClassType && allowUDC) {
/* /*
* or has a class type (i.e., T2 is a class type) and can be implicitly converted to * or has a class type (i.e., T2 is a class type) and can be implicitly converted to
* an lvalue of type "cv3 T3," where "cv1 T1" is reference-compatible with "cv3 T3" 92) * an lvalue of type "cv3 T3," where "cv1 T1" is reference-compatible with "cv3 T3" 92)
@ -97,15 +98,14 @@ public class Conversions {
Cost operatorCost= null; Cost operatorCost= null;
ICPPMethod conv= null; ICPPMethod conv= null;
boolean ambiguousConversionOperator= false; boolean ambiguousConversionOperator= false;
if( fcns.length > 0 && fcns[0] instanceof IProblemBinding == false ){ if (fcns.length > 0 && fcns[0] instanceof IProblemBinding == false) {
for (final ICPPMethod op : fcns) { for (final ICPPMethod op : fcns) {
Cost cost2 = checkStandardConversionSequence( op.getType().getReturnType(), target, false ); Cost cost2 = checkStandardConversionSequence(op.getType().getReturnType(), target, false);
if( cost2.rank != Cost.NO_MATCH_RANK ) { if (cost2.rank != Cost.NO_MATCH_RANK) {
if (operatorCost == null) { if (operatorCost == null) {
operatorCost= cost2; operatorCost= cost2;
conv= op; conv= op;
} } else {
else {
int cmp= operatorCost.compare(cost2); int cmp= operatorCost.compare(cost2);
if (cmp >= 0) { if (cmp >= 0) {
ambiguousConversionOperator= cmp == 0; ambiguousConversionOperator= cmp == 0;
@ -117,10 +117,10 @@ public class Conversions {
} }
} }
if(conv!= null && !ambiguousConversionOperator) { if (conv!= null && !ambiguousConversionOperator) {
IType newSource= conv.getType().getReturnType(); IType newSource= conv.getType().getReturnType();
boolean isNewSourceLValue= newSource instanceof ICPPReferenceType; boolean isNewSourceLValue= newSource instanceof ICPPReferenceType;
if(isNewSourceLValue && isReferenceCompatible(cv1T1, newSource)) { if (isNewSourceLValue && isReferenceCompatible(cv1T1, newSource)) {
cost= new Cost(cv1T1, newSource); cost= new Cost(cv1T1, newSource);
qualificationConversion(cost); qualificationConversion(cost);
derivedToBaseConversion(cost); derivedToBaseConversion(cost);
@ -130,18 +130,18 @@ public class Conversions {
/* Direct binding failed */ /* Direct binding failed */
if(cost.rank == Cost.NO_MATCH_RANK) { if (cost.rank == Cost.NO_MATCH_RANK) {
// 8.5.3-5 - Otherwise // 8.5.3-5 - Otherwise
boolean cv1isConst= false; boolean cv1isConst= false;
if(cv1T1 instanceof IQualifierType) { if (cv1T1 instanceof IQualifierType) {
cv1isConst= ((IQualifierType)cv1T1).isConst() && !((IQualifierType)cv1T1).isVolatile(); cv1isConst= ((IQualifierType)cv1T1).isConst() && !((IQualifierType)cv1T1).isVolatile();
} else if(cv1T1 instanceof IPointerType) { } else if (cv1T1 instanceof IPointerType) {
cv1isConst= ((IPointerType)cv1T1).isConst() && !((IPointerType)cv1T1).isVolatile(); cv1isConst= ((IPointerType)cv1T1).isConst() && !((IPointerType)cv1T1).isVolatile();
} }
if(cv1isConst) { if (cv1isConst) {
if(!lvalue && source instanceof ICPPClassType) { if (!lvalue && source instanceof ICPPClassType) {
cost= new Cost(source, target); cost= new Cost(source, target);
cost.rank= Cost.IDENTITY_RANK; cost.rank= Cost.IDENTITY_RANK;
} else { } else {
@ -152,22 +152,22 @@ public class Conversions {
// If T1 is reference-related to T2, cv1 must be the same cv-qualification as, or greater cvqualification // If T1 is reference-related to T2, cv1 must be the same cv-qualification as, or greater cvqualification
// than, cv2; otherwise, the program is ill-formed. [Example // than, cv2; otherwise, the program is ill-formed. [Example
boolean illformed= false; boolean illformed= false;
if(isReferenceRelated(cv1T1, source)) { if (isReferenceRelated(cv1T1, source)) {
Integer cmp= compareQualifications(cv1T1, source); Integer cmp= compareQualifications(cv1T1, source);
if(cmp == null || cmp < 0) { if (cmp == null || cmp < 0) {
illformed= true; illformed= true;
} }
} }
// we must do a non-reference initialization // we must do a non-reference initialization
if(!illformed) { if (!illformed) {
cost= checkStandardConversionSequence( source, cv1T1, isImpliedObject); cost= checkStandardConversionSequence(source, cv1T1, isImpliedObject);
// 12.3-4 At most one user-defined conversion is implicitly applied to // 12.3-4 At most one user-defined conversion is implicitly applied to
// a single value. (also prevents infinite loop) // a single value. (also prevents infinite loop)
if (allowUDC && (cost.rank == Cost.NO_MATCH_RANK || if (allowUDC && (cost.rank == Cost.NO_MATCH_RANK ||
cost.rank == Cost.FUZZY_TEMPLATE_PARAMETERS)) { cost.rank == Cost.FUZZY_TEMPLATE_PARAMETERS)) {
Cost temp = checkUserDefinedConversionSequence(source, cv1T1); Cost temp = checkUserDefinedConversionSequence(source, cv1T1);
if( temp != null ){ if (temp != null) {
cost = temp; cost = temp;
} }
} }
@ -178,11 +178,11 @@ public class Conversions {
} else { } else {
// Non-reference binding // Non-reference binding
cost= checkStandardConversionSequence( source, target, isImpliedObject); cost= checkStandardConversionSequence(source, target, isImpliedObject);
if (allowUDC && (cost.rank == Cost.NO_MATCH_RANK || if (allowUDC && (cost.rank == Cost.NO_MATCH_RANK ||
cost.rank == Cost.FUZZY_TEMPLATE_PARAMETERS)) { cost.rank == Cost.FUZZY_TEMPLATE_PARAMETERS)) {
Cost temp = checkUserDefinedConversionSequence(source, target); Cost temp = checkUserDefinedConversionSequence(source, target);
if( temp != null ){ if (temp != null) {
cost = temp; cost = temp;
} }
} }
@ -207,20 +207,20 @@ public class Conversions {
*/ */
private static final Integer compareQualifications(IType cv1, IType cv2) throws DOMException { private static final Integer compareQualifications(IType cv1, IType cv2) throws DOMException {
boolean cv1Const= false, cv2Const= false, cv1Volatile= false, cv2Volatile= false; boolean cv1Const= false, cv2Const= false, cv1Volatile= false, cv2Volatile= false;
if(cv1 instanceof IQualifierType) { if (cv1 instanceof IQualifierType) {
IQualifierType qt1= (IQualifierType) cv1; IQualifierType qt1= (IQualifierType) cv1;
cv1Const= qt1.isConst(); cv1Const= qt1.isConst();
cv1Volatile= qt1.isVolatile(); cv1Volatile= qt1.isVolatile();
} else if(cv1 instanceof IPointerType) { } else if (cv1 instanceof IPointerType) {
IPointerType pt1= (IPointerType) cv1; IPointerType pt1= (IPointerType) cv1;
cv1Const= pt1.isConst(); cv1Const= pt1.isConst();
cv1Volatile= pt1.isVolatile(); cv1Volatile= pt1.isVolatile();
} }
if(cv2 instanceof IQualifierType) { if (cv2 instanceof IQualifierType) {
IQualifierType qt2= (IQualifierType) cv2; IQualifierType qt2= (IQualifierType) cv2;
cv2Const= qt2.isConst(); cv2Const= qt2.isConst();
cv2Volatile= qt2.isVolatile(); cv2Volatile= qt2.isVolatile();
} else if(cv2 instanceof IPointerType) { } else if (cv2 instanceof IPointerType) {
IPointerType pt2= (IPointerType) cv2; IPointerType pt2= (IPointerType) cv2;
cv1Const= pt2.isConst(); cv1Const= pt2.isConst();
cv1Volatile= pt2.isVolatile(); cv1Volatile= pt2.isVolatile();
@ -228,11 +228,11 @@ public class Conversions {
int cmpConst= cv1Const ? (cv2Const ? 0 : 1) : (!cv2Const ? 0 : -1); int cmpConst= cv1Const ? (cv2Const ? 0 : 1) : (!cv2Const ? 0 : -1);
int cmpVolatile= cv1Volatile ? (cv2Volatile ? 0 : 1) : (!cv2Volatile ? 0 : -1); int cmpVolatile= cv1Volatile ? (cv2Volatile ? 0 : 1) : (!cv2Volatile ? 0 : -1);
if(cmpConst == cmpVolatile) { if (cmpConst == cmpVolatile) {
return cmpConst; return cmpConst;
} else if(cmpConst != 0 && cmpVolatile == 0) { } else if (cmpConst != 0 && cmpVolatile == 0) {
return cmpConst; return cmpConst;
} else if(cmpConst == 0 && cmpVolatile != 0) { } else if (cmpConst == 0 && cmpVolatile != 0) {
return cmpVolatile; return cmpVolatile;
} }
@ -254,7 +254,7 @@ public class Conversions {
// The way cv-qualification is currently modeled means // The way cv-qualification is currently modeled means
// we must cope with IPointerType objects separately. // we must cope with IPointerType objects separately.
if(t1 instanceof IPointerType && t2 instanceof IPointerType) { if (t1 instanceof IPointerType && t2 instanceof IPointerType) {
IType ptt1= ((IPointerType)t1).getType(); IType ptt1= ((IPointerType)t1).getType();
IType ptt2= ((IPointerType)t2).getType(); IType ptt2= ((IPointerType)t2).getType();
return ptt1 != null && ptt2 != null ? ptt1.isSameType(ptt2) : ptt1 == ptt2; return ptt1 != null && ptt2 != null ? ptt1.isSameType(ptt2) : ptt1 == ptt2;
@ -263,8 +263,8 @@ public class Conversions {
t1= t1 instanceof IQualifierType ? ((IQualifierType)t1).getType() : t1; t1= t1 instanceof IQualifierType ? ((IQualifierType)t1).getType() : t1;
t2= t2 instanceof IQualifierType ? ((IQualifierType)t2).getType() : t2; t2= t2 instanceof IQualifierType ? ((IQualifierType)t2).getType() : t2;
if(t1 instanceof ICPPClassType && t2 instanceof ICPPClassType) { if (t1 instanceof ICPPClassType && t2 instanceof ICPPClassType) {
return calculateInheritanceDepth(CPPSemantics.MAX_INHERITANCE_DEPTH, (ICPPClassType) t2, (ICPPClassType) t1) >= 0; return calculateInheritanceDepth(CPPSemantics.MAX_INHERITANCE_DEPTH, t2, t1) >= 0;
} }
return t1 != null && t2 != null ? t1.isSameType(t2) : t1 == t2; return t1 != null && t2 != null ? t1.isSameType(t2) : t1 == t2;
@ -280,7 +280,7 @@ public class Conversions {
* @throws DOMException * @throws DOMException
*/ */
private static final boolean isReferenceCompatible(IType cv1t1, IType cv2t2) throws DOMException { private static final boolean isReferenceCompatible(IType cv1t1, IType cv2t2) throws DOMException {
if(isReferenceRelated(cv1t1, cv2t2)) { if (isReferenceRelated(cv1t1, cv2t2)) {
Integer cmp= compareQualifications(cv1t1, cv2t2); Integer cmp= compareQualifications(cv1t1, cv2t2);
return cmp != null && cmp >= 0; return cmp != null && cmp >= 0;
} }
@ -295,10 +295,10 @@ public class Conversions {
* base conversion does not cause any costs. * base conversion does not cause any costs.
* @throws DOMException * @throws DOMException
*/ */
protected static final Cost checkStandardConversionSequence( IType source, IType target, boolean isImplicitThis) throws DOMException { protected static final Cost checkStandardConversionSequence(IType source, IType target, boolean isImplicitThis) throws DOMException {
Cost cost = lvalue_to_rvalue( source, target ); Cost cost = lvalue_to_rvalue(source, target);
if( cost.source == null || cost.target == null ){ if (cost.source == null || cost.target == null) {
return cost; return cost;
} }
@ -310,18 +310,18 @@ public class Conversions {
return cost; return cost;
} }
qualificationConversion( cost ); qualificationConversion(cost);
//if we can't convert the qualifications, then we can't do anything //if we can't convert the qualifications, then we can't do anything
if( cost.qualification == Cost.NO_MATCH_RANK ){ if (cost.qualification == Cost.NO_MATCH_RANK) {
return cost; return cost;
} }
//was the qualification conversion enough? //was the qualification conversion enough?
IType s = getUltimateType( cost.source, true ); IType s = getUltimateType(cost.source, true);
IType t = getUltimateType( cost.target, true ); IType t = getUltimateType(cost.target, true);
if( s == null || t == null ){ if (s == null || t == null) {
cost.rank = Cost.NO_MATCH_RANK; cost.rank = Cost.NO_MATCH_RANK;
return cost; return cost;
} }
@ -333,20 +333,20 @@ public class Conversions {
return cost; return cost;
} }
promotion( cost ); promotion(cost);
if( cost.promotion > 0 || cost.rank > -1 ){ if (cost.promotion > 0 || cost.rank > -1) {
return cost; return cost;
} }
conversion( cost ); conversion(cost);
if( cost.rank > -1 ) if (cost.rank > -1)
return cost; return cost;
derivedToBaseConversion( cost ); derivedToBaseConversion(cost);
if( cost.rank == -1 ){ if (cost.rank == -1) {
relaxTemplateParameters( cost ); relaxTemplateParameters(cost);
} }
return cost; return cost;
} }
@ -372,11 +372,11 @@ public class Conversions {
LookupData data= new LookupData(); LookupData data= new LookupData();
data.forUserDefinedConversion= true; data.forUserDefinedConversion= true;
data.functionParameters= new IType [] { source }; data.functionParameters= new IType [] { source };
IBinding binding = CPPSemantics.resolveFunction( data, constructors ); IBinding binding = CPPSemantics.resolveFunction(data, constructors);
if( binding instanceof ICPPConstructor ) { if (binding instanceof ICPPConstructor) {
ICPPConstructor constructor= (ICPPConstructor) binding; ICPPConstructor constructor= (ICPPConstructor) binding;
if(!constructor.isExplicit()){ if (!constructor.isExplicit()) {
constructorCost = checkStandardConversionSequence( t, target, false ); constructorCost = checkStandardConversionSequence(t, target, false);
if (constructorCost.rank == Cost.NO_MATCH_RANK) { if (constructorCost.rank == Cost.NO_MATCH_RANK) {
constructorCost= null; constructorCost= null;
} }
@ -392,7 +392,7 @@ public class Conversions {
if (ops.length > 0 && ops[0] instanceof IProblemBinding == false) { if (ops.length > 0 && ops[0] instanceof IProblemBinding == false) {
for (final ICPPMethod op : ops) { for (final ICPPMethod op : ops) {
Cost cost= checkStandardConversionSequence(op.getType().getReturnType(), target, false); Cost cost= checkStandardConversionSequence(op.getType().getReturnType(), target, false);
if( cost.rank != Cost.NO_MATCH_RANK ) { if (cost.rank != Cost.NO_MATCH_RANK) {
if (operatorCost == null) { if (operatorCost == null) {
operatorCost= cost; operatorCost= cost;
} }
@ -438,33 +438,33 @@ public class Conversions {
* <code>ancestorToFind</code>, returning -1 if no inheritance relationship is found. * <code>ancestorToFind</code>, returning -1 if no inheritance relationship is found.
* @param clazz the class to search upwards from * @param clazz the class to search upwards from
* @param ancestorToFind the class to find in the inheritance graph * @param ancestorToFind the class to find in the inheritance graph
* @return the number of edges in the inheritance graph, or -1 if the specifide classes have * @return the number of edges in the inheritance graph, or -1 if the specified classes have
* no inheritance relation * no inheritance relation
* @throws DOMException * @throws DOMException
*/ */
private static final int calculateInheritanceDepth(int maxdepth, ICPPClassType clazz, ICPPClassType ancestorToFind) throws DOMException { private static final int calculateInheritanceDepth(int maxdepth, IType type, IType ancestorToFind) throws DOMException {
if (clazz == ancestorToFind || clazz.isSameType(ancestorToFind)) { if (type == ancestorToFind || type.isSameType(ancestorToFind)) {
return 0; return 0;
} }
if (maxdepth>0) { if (maxdepth > 0 && type instanceof ICPPClassType && ancestorToFind instanceof ICPPClassType) {
ICPPClassType clazz = (ICPPClassType) type;
ICPPBase[] bases= clazz.getBases(); ICPPBase[] bases= clazz.getBases();
for (ICPPBase cppBase : bases) { for (ICPPBase cppBase : bases) {
IBinding base= cppBase.getBaseClass(); IBinding base= cppBase.getBaseClass();
if(base instanceof IType) { if (base instanceof IType) {
IType tbase= (IType) base; IType tbase= (IType) base;
if( tbase.isSameType(ancestorToFind) || if (tbase.isSameType(ancestorToFind) ||
(ancestorToFind instanceof ICPPSpecialization && /*allow some flexibility with templates*/ (ancestorToFind instanceof ICPPSpecialization && /*allow some flexibility with templates*/
((IType)((ICPPSpecialization)ancestorToFind).getSpecializedBinding()).isSameType(tbase) ) ) ((IType)((ICPPSpecialization)ancestorToFind).getSpecializedBinding()).isSameType(tbase))) {
{
return 1; return 1;
} }
tbase= getUltimateTypeViaTypedefs(tbase); tbase= getUltimateTypeViaTypedefs(tbase);
if(tbase instanceof ICPPClassType) { if (tbase instanceof ICPPClassType) {
int n= calculateInheritanceDepth(maxdepth-1, (ICPPClassType) tbase, ancestorToFind ); int n= calculateInheritanceDepth(maxdepth-1, tbase, ancestorToFind);
if(n>0) if (n > 0)
return n+1; return n + 1;
} }
} }
} }
@ -500,27 +500,24 @@ public class Conversions {
} }
//4.3 function to pointer conversion //4.3 function to pointer conversion
if( target instanceof IPointerType && ((IPointerType)target).getType() instanceof IFunctionType && if (target instanceof IPointerType && ((IPointerType)target).getType() instanceof IFunctionType &&
source instanceof IFunctionType ) source instanceof IFunctionType) {
{ source = new CPPPointerType(source);
source = new CPPPointerType( source ); } else if (target instanceof IPointerType && source instanceof IArrayType) {
} //4.2 Array-To-Pointer conversion
//4.2 Array-To-Pointer conversion source = new CPPPointerType(((IArrayType)source).getType());
else if( target instanceof IPointerType && source instanceof IArrayType ){
source = new CPPPointerType( ((IArrayType)source).getType() );
} }
//4.1 if T is a non-class type, the type of the rvalue is the cv-unqualified version of T //4.1 if T is a non-class type, the type of the rvalue is the cv-unqualified version of T
if( source instanceof IQualifierType ){ if (source instanceof IQualifierType) {
IType t = ((IQualifierType)source).getType(); IType t = ((IQualifierType)source).getType();
while( t instanceof ITypedef ) while (t instanceof ITypedef)
t = ((ITypedef)t).getType(); t = ((ITypedef)t).getType();
if( !(t instanceof ICPPClassType) ){ if (!(t instanceof ICPPClassType)) {
source = t; source = t;
} }
} else if( source instanceof IPointerType && } else if (source instanceof IPointerType &&
( ((IPointerType)source).isConst() || ((IPointerType)source).isVolatile() ) ) (((IPointerType)source).isConst() || ((IPointerType)source).isVolatile())) {
{
IType t= ((IPointerType) source).getType(); IType t= ((IPointerType) source).getType();
while (t instanceof ITypedef) while (t instanceof ITypedef)
t= ((ITypedef) t).getType(); t= ((ITypedef) t).getType();
@ -540,14 +537,14 @@ public class Conversions {
* @param cost * @param cost
* @throws DOMException * @throws DOMException
*/ */
private static final void qualificationConversion( Cost cost ) throws DOMException{ private static final void qualificationConversion(Cost cost) throws DOMException{
boolean canConvert = true; boolean canConvert = true;
int requiredConversion = Cost.IDENTITY_RANK; int requiredConversion = Cost.IDENTITY_RANK;
IType s = cost.source, t = cost.target; IType s = cost.source, t = cost.target;
boolean constInEveryCV2k = true; boolean constInEveryCV2k = true;
boolean firstPointer= true; boolean firstPointer= true;
while( true ){ while (true) {
s= getUltimateTypeViaTypedefs(s); s= getUltimateTypeViaTypedefs(s);
t= getUltimateTypeViaTypedefs(t); t= getUltimateTypeViaTypedefs(t);
final boolean sourceIsPointer= s instanceof IPointerType; final boolean sourceIsPointer= s instanceof IPointerType;
@ -556,8 +553,8 @@ public class Conversions {
if (!targetIsPointer) { if (!targetIsPointer) {
if (!sourceIsPointer) if (!sourceIsPointer)
break; break;
if(t instanceof ICPPBasicType) { if (t instanceof ICPPBasicType) {
if(((ICPPBasicType)t).getType() == ICPPBasicType.t_bool) { if (((ICPPBasicType)t).getType() == ICPPBasicType.t_bool) {
canConvert= true; canConvert= true;
requiredConversion = Cost.CONVERSION_RANK; requiredConversion = Cost.CONVERSION_RANK;
break; break;
@ -568,7 +565,7 @@ public class Conversions {
} else if (!sourceIsPointer) { } else if (!sourceIsPointer) {
canConvert = false; canConvert = false;
break; break;
} else if( s instanceof ICPPPointerToMemberType ^ t instanceof ICPPPointerToMemberType ){ } else if (s instanceof ICPPPointerToMemberType ^ t instanceof ICPPPointerToMemberType) {
canConvert = false; canConvert = false;
break; break;
} }
@ -578,15 +575,14 @@ public class Conversions {
IPointerType op2= (IPointerType) t; IPointerType op2= (IPointerType) t;
//if const is in cv1,j then const is in cv2,j. Similary for volatile //if const is in cv1,j then const is in cv2,j. Similary for volatile
if( ( op1.isConst() && !op2.isConst() ) || ( op1.isVolatile() && !op2.isVolatile() ) ) { if ((op1.isConst() && !op2.isConst()) || (op1.isVolatile() && !op2.isVolatile())) {
canConvert = false; canConvert = false;
requiredConversion = Cost.NO_MATCH_RANK; requiredConversion = Cost.NO_MATCH_RANK;
break; break;
} }
//if cv1,j and cv2,j are different then const is in every cv2,k for 0<k<j //if cv1,j and cv2,j are different then const is in every cv2,k for 0<k<j
if( !constInEveryCV2k && ( op1.isConst() != op2.isConst() || if (!constInEveryCV2k && (op1.isConst() != op2.isConst() ||
op1.isVolatile() != op2.isVolatile() ) ) op1.isVolatile() != op2.isVolatile())) {
{
canConvert = false; canConvert = false;
requiredConversion = Cost.NO_MATCH_RANK; requiredConversion = Cost.NO_MATCH_RANK;
break; break;
@ -597,27 +593,26 @@ public class Conversions {
firstPointer= false; firstPointer= false;
} }
if( s instanceof IQualifierType ^ t instanceof IQualifierType ){ if (s instanceof IQualifierType ^ t instanceof IQualifierType) {
if( t instanceof IQualifierType ){ if (t instanceof IQualifierType) {
if (!constInEveryCV2k) { if (!constInEveryCV2k) {
canConvert= false; canConvert= false;
requiredConversion= Cost.NO_MATCH_RANK; requiredConversion= Cost.NO_MATCH_RANK;
} } else {
else {
canConvert = true; canConvert = true;
requiredConversion = Cost.CONVERSION_RANK; requiredConversion = Cost.CONVERSION_RANK;
} }
} else { } else {
//4.2-2 a string literal can be converted to pointer to char //4.2-2 a string literal can be converted to pointer to char
if( t instanceof IBasicType && ((IBasicType)t).getType() == IBasicType.t_char && if (t instanceof IBasicType && ((IBasicType)t).getType() == IBasicType.t_char &&
s instanceof IQualifierType ) s instanceof IQualifierType)
{ {
IType qt = ((IQualifierType)s).getType(); IType qt = ((IQualifierType)s).getType();
if( qt instanceof IBasicType ){ if (qt instanceof IBasicType) {
IASTExpression val = ((IBasicType)qt).getValue(); IASTExpression val = ((IBasicType)qt).getValue();
canConvert = (val != null && canConvert = (val != null &&
val instanceof IASTLiteralExpression && val instanceof IASTLiteralExpression &&
((IASTLiteralExpression)val).getKind() == IASTLiteralExpression.lk_string_literal ); ((IASTLiteralExpression)val).getKind() == IASTLiteralExpression.lk_string_literal);
} else { } else {
canConvert = false; canConvert = false;
requiredConversion = Cost.NO_MATCH_RANK; requiredConversion = Cost.NO_MATCH_RANK;
@ -627,29 +622,28 @@ public class Conversions {
requiredConversion = Cost.NO_MATCH_RANK; requiredConversion = Cost.NO_MATCH_RANK;
} }
} }
} else if( s instanceof IQualifierType && t instanceof IQualifierType ){ } else if (s instanceof IQualifierType && t instanceof IQualifierType) {
IQualifierType qs = (IQualifierType) s, qt = (IQualifierType) t; IQualifierType qs = (IQualifierType) s, qt = (IQualifierType) t;
if( qs.isConst() == qt.isConst() && qs.isVolatile() == qt.isVolatile() ) { if (qs.isConst() == qt.isConst() && qs.isVolatile() == qt.isVolatile()) {
requiredConversion = Cost.IDENTITY_RANK; requiredConversion = Cost.IDENTITY_RANK;
} } else if ((qs.isConst() && !qt.isConst()) || (qs.isVolatile() && !qt.isVolatile()) || !constInEveryCV2k) {
else if( (qs.isConst() && !qt.isConst()) || (qs.isVolatile() && !qt.isVolatile()) || !constInEveryCV2k ) {
requiredConversion = Cost.NO_MATCH_RANK; requiredConversion = Cost.NO_MATCH_RANK;
canConvert= false; canConvert= false;
} } else {
else
requiredConversion = Cost.CONVERSION_RANK; requiredConversion = Cost.CONVERSION_RANK;
} else if( constInEveryCV2k && !canConvert ){ }
} else if (constInEveryCV2k && !canConvert) {
canConvert = true; canConvert = true;
requiredConversion = Cost.CONVERSION_RANK; requiredConversion = Cost.CONVERSION_RANK;
int i = 1; int i = 1;
for( IType type = s; canConvert == true && i == 1; type = t, i++ ){ for (IType type = s; canConvert == true && i == 1; type = t, i++) {
while( type instanceof ITypeContainer ){ while (type instanceof ITypeContainer) {
if( type instanceof IQualifierType ) if (type instanceof IQualifierType) {
canConvert = false; canConvert = false;
else if( type instanceof IPointerType ){ } else if (type instanceof IPointerType) {
canConvert = !((IPointerType)type).isConst() && !((IPointerType)type).isVolatile(); canConvert = !((IPointerType)type).isConst() && !((IPointerType)type).isVolatile();
} }
if( !canConvert ){ if (!canConvert) {
requiredConversion = Cost.NO_MATCH_RANK; requiredConversion = Cost.NO_MATCH_RANK;
break; break;
} }
@ -659,7 +653,7 @@ public class Conversions {
} }
cost.qualification = requiredConversion; cost.qualification = requiredConversion;
if( canConvert == true ){ if (canConvert == true) {
cost.rank = Cost.LVALUE_OR_QUALIFICATION_RANK; cost.rank = Cost.LVALUE_OR_QUALIFICATION_RANK;
} }
} }
@ -676,33 +670,31 @@ public class Conversions {
* 4.6 float can be promoted to double * 4.6 float can be promoted to double
* @throws DOMException * @throws DOMException
*/ */
private static final void promotion( Cost cost ) throws DOMException{ private static final void promotion(Cost cost) throws DOMException{
IType src = cost.source; IType src = cost.source;
IType trg = cost.target; IType trg = cost.target;
if( src.isSameType( trg ) ) if (src.isSameType(trg))
return; return;
if( src instanceof IBasicType && trg instanceof IBasicType ){ if (src instanceof IBasicType && trg instanceof IBasicType) {
int sType = ((IBasicType)src).getType(); int sType = ((IBasicType)src).getType();
int tType = ((IBasicType)trg).getType(); int tType = ((IBasicType)trg).getType();
if( ( tType == IBasicType.t_int && ( sType == IBasicType.t_int || //short, long , unsigned etc if ((tType == IBasicType.t_int && (sType == IBasicType.t_int || //short, long , unsigned etc
sType == IBasicType.t_char || sType == IBasicType.t_char ||
sType == ICPPBasicType.t_bool || sType == ICPPBasicType.t_bool ||
sType == ICPPBasicType.t_wchar_t || sType == ICPPBasicType.t_wchar_t ||
sType == IBasicType.t_unspecified ) ) || //treat unspecified as int sType == IBasicType.t_unspecified)) || //treat unspecified as int
( tType == IBasicType.t_double && sType == IBasicType.t_float ) ) (tType == IBasicType.t_double && sType == IBasicType.t_float)) {
{
cost.promotion = 1; cost.promotion = 1;
} }
} else if( src instanceof IEnumeration && trg instanceof IBasicType && } else if (src instanceof IEnumeration && trg instanceof IBasicType &&
( ((IBasicType)trg).getType() == IBasicType.t_int || (((IBasicType)trg).getType() == IBasicType.t_int ||
((IBasicType)trg).getType() == IBasicType.t_unspecified ) ) ((IBasicType)trg).getType() == IBasicType.t_unspecified)) {
{
cost.promotion = 1; cost.promotion = 1;
} }
cost.rank = (cost.promotion > 0 ) ? Cost.PROMOTION_RANK : Cost.NO_MATCH_RANK; cost.rank = (cost.promotion > 0) ? Cost.PROMOTION_RANK : Cost.NO_MATCH_RANK;
} }
/** /**
@ -714,7 +706,7 @@ public class Conversions {
* @param cost * @param cost
* @throws DOMException * @throws DOMException
*/ */
private static final void conversion( Cost cost ) throws DOMException{ private static final void conversion(Cost cost) throws DOMException{
final IType src = cost.source; final IType src = cost.source;
final IType trg = cost.target; final IType trg = cost.target;
@ -722,30 +714,29 @@ public class Conversions {
cost.detail = 0; cost.detail = 0;
IType[] sHolder= new IType[1], tHolder= new IType[1]; IType[] sHolder= new IType[1], tHolder= new IType[1];
IType s = getUltimateType( src, sHolder, true ); IType s = getUltimateType(src, sHolder, true);
IType t = getUltimateType( trg, tHolder, true ); IType t = getUltimateType(trg, tHolder, true);
IType sPrev= sHolder[0], tPrev= tHolder[0]; IType sPrev= sHolder[0], tPrev= tHolder[0];
if( src instanceof IBasicType && trg instanceof IPointerType ){ if (src instanceof IBasicType && trg instanceof IPointerType) {
//4.10-1 an integral constant expression of integer type that evaluates to 0 can be converted to a pointer type //4.10-1 an integral constant expression of integer type that evaluates to 0 can be converted to a pointer type
IASTExpression exp = ((IBasicType)src).getValue(); IASTExpression exp = ((IBasicType)src).getValue();
if( exp instanceof IASTLiteralExpression && if (exp instanceof IASTLiteralExpression &&
((IASTLiteralExpression)exp).getKind() == IASTLiteralExpression.lk_integer_constant ) ((IASTLiteralExpression)exp).getKind() == IASTLiteralExpression.lk_integer_constant) {
{
try { try {
String val = exp.toString().toLowerCase().replace('u', '0'); String val = exp.toString().toLowerCase().replace('u', '0');
val.replace( 'l', '0' ); val.replace('l', '0');
if( Integer.decode( val ).intValue() == 0 ){ if (Integer.decode(val).intValue() == 0) {
cost.rank = Cost.CONVERSION_RANK; cost.rank = Cost.CONVERSION_RANK;
cost.conversion = 1; cost.conversion = 1;
} }
} catch( NumberFormatException e ) { } catch(NumberFormatException e) {
} }
} }
} else if( sPrev instanceof IPointerType ){ } else if (sPrev instanceof IPointerType) {
//4.10-2 an rvalue of type "pointer to cv T", where T is an object type can be //4.10-2 an rvalue of type "pointer to cv T", where T is an object type can be
//converted to an rvalue of type "pointer to cv void" //converted to an rvalue of type "pointer to cv void"
if( tPrev instanceof IPointerType && t instanceof IBasicType && ((IBasicType)t).getType() == IBasicType.t_void ){ if (tPrev instanceof IPointerType && t instanceof IBasicType && ((IBasicType)t).getType() == IBasicType.t_void) {
cost.rank = Cost.CONVERSION_RANK; cost.rank = Cost.CONVERSION_RANK;
cost.conversion = 1; cost.conversion = 1;
cost.detail = 2; cost.detail = 2;
@ -753,29 +744,29 @@ public class Conversions {
} }
//4.10-3 An rvalue of type "pointer to cv D", where D is a class type can be converted //4.10-3 An rvalue of type "pointer to cv D", where D is a class type can be converted
//to an rvalue of type "pointer to cv B", where B is a base class of D. //to an rvalue of type "pointer to cv B", where B is a base class of D.
else if( s instanceof ICPPClassType && tPrev instanceof IPointerType && t instanceof ICPPClassType ){ else if (s instanceof ICPPClassType && tPrev instanceof IPointerType && t instanceof ICPPClassType) {
int depth= calculateInheritanceDepth(CPPSemantics.MAX_INHERITANCE_DEPTH, (ICPPClassType)s, (ICPPClassType) t ); int depth= calculateInheritanceDepth(CPPSemantics.MAX_INHERITANCE_DEPTH, s, t);
cost.rank= ( depth > -1 ) ? Cost.CONVERSION_RANK : Cost.NO_MATCH_RANK; cost.rank= (depth > -1) ? Cost.CONVERSION_RANK : Cost.NO_MATCH_RANK;
cost.conversion= ( depth > -1 ) ? depth : 0; cost.conversion= (depth > -1) ? depth : 0;
cost.detail= 1; cost.detail= 1;
return; return;
} }
// 4.12 if the target is a bool, we can still convert // 4.12 if the target is a bool, we can still convert
else if(!(trg instanceof IBasicType && ((IBasicType)trg).getType() == ICPPBasicType.t_bool)) { else if (!(trg instanceof IBasicType && ((IBasicType)trg).getType() == ICPPBasicType.t_bool)) {
return; return;
} }
} }
if( t instanceof IBasicType && s instanceof IBasicType || s instanceof IEnumeration ){ if (t instanceof IBasicType && s instanceof IBasicType || s instanceof IEnumeration) {
//4.7 An rvalue of an integer type can be converted to an rvalue of another integer type. //4.7 An rvalue of an integer type can be converted to an rvalue of another integer type.
//An rvalue of an enumeration type can be converted to an rvalue of an integer type. //An rvalue of an enumeration type can be converted to an rvalue of an integer type.
cost.rank = Cost.CONVERSION_RANK; cost.rank = Cost.CONVERSION_RANK;
cost.conversion = 1; cost.conversion = 1;
} else if( trg instanceof IBasicType && ((IBasicType)trg).getType() == ICPPBasicType.t_bool && s instanceof IPointerType ){ } else if (trg instanceof IBasicType && ((IBasicType)trg).getType() == ICPPBasicType.t_bool && s instanceof IPointerType) {
//4.12 pointer or pointer to member type can be converted to an rvalue of type bool //4.12 pointer or pointer to member type can be converted to an rvalue of type bool
cost.rank = Cost.CONVERSION_RANK; cost.rank = Cost.CONVERSION_RANK;
cost.conversion = 1; cost.conversion = 1;
} else if( s instanceof ICPPPointerToMemberType && t instanceof ICPPPointerToMemberType ){ } else if (s instanceof ICPPPointerToMemberType && t instanceof ICPPPointerToMemberType) {
//4.11-2 An rvalue of type "pointer to member of B of type cv T", where B is a class type, //4.11-2 An rvalue of type "pointer to member of B of type cv T", where B is a class type,
//can be converted to an rvalue of type "pointer to member of D of type cv T" where D is a //can be converted to an rvalue of type "pointer to member of D of type cv T" where D is a
//derived class of B //derived class of B
@ -783,10 +774,10 @@ public class Conversions {
ICPPPointerToMemberType tpm = (ICPPPointerToMemberType) t; ICPPPointerToMemberType tpm = (ICPPPointerToMemberType) t;
IType st = spm.getType(); IType st = spm.getType();
IType tt = tpm.getType(); IType tt = tpm.getType();
if( st != null && tt != null && st.isSameType( tt ) ){ if (st != null && tt != null && st.isSameType(tt)) {
int depth= calculateInheritanceDepth(CPPSemantics.MAX_INHERITANCE_DEPTH, tpm.getMemberOfClass(), spm.getMemberOfClass()); int depth= calculateInheritanceDepth(CPPSemantics.MAX_INHERITANCE_DEPTH, tpm.getMemberOfClass(), spm.getMemberOfClass());
cost.rank= ( depth > -1 ) ? Cost.CONVERSION_RANK : Cost.NO_MATCH_RANK; cost.rank= (depth > -1) ? Cost.CONVERSION_RANK : Cost.NO_MATCH_RANK;
cost.conversion= ( depth > -1 ) ? depth : 0; cost.conversion= (depth > -1) ? depth : 0;
cost.detail= 1; cost.detail= 1;
} }
} }
@ -802,7 +793,7 @@ public class Conversions {
IType t = getUltimateType(cost.target, true); IType t = getUltimateType(cost.target, true);
if (cost.targetHadReference && s instanceof ICPPClassType && t instanceof ICPPClassType) { if (cost.targetHadReference && s instanceof ICPPClassType && t instanceof ICPPClassType) {
int depth= calculateInheritanceDepth(CPPSemantics.MAX_INHERITANCE_DEPTH, (ICPPClassType) s, (ICPPClassType) t); int depth= calculateInheritanceDepth(CPPSemantics.MAX_INHERITANCE_DEPTH, s, t);
if (depth > -1) { if (depth > -1) {
cost.rank = Cost.DERIVED_TO_BASE_CONVERSION; cost.rank = Cost.DERIVED_TO_BASE_CONVERSION;
cost.conversion = depth; cost.conversion = depth;
@ -816,11 +807,11 @@ public class Conversions {
*/ */
private static final boolean isCompleteType(IType type) { private static final boolean isCompleteType(IType type) {
type= getUltimateType(type, false); type= getUltimateType(type, false);
if(type instanceof ICPPClassType) { if (type instanceof ICPPClassType) {
if(type instanceof ICPPInternalBinding) { if (type instanceof ICPPInternalBinding) {
return (((ICPPInternalBinding)type).getDefinition() != null ); return (((ICPPInternalBinding)type).getDefinition() != null);
} }
if(type instanceof IIndexFragmentBinding) { if (type instanceof IIndexFragmentBinding) {
try { try {
return ((IIndexFragmentBinding)type).hasDefinition(); return ((IIndexFragmentBinding)type).hasDefinition();
} catch(CoreException ce) { } catch(CoreException ce) {
@ -836,13 +827,12 @@ public class Conversions {
* Allows any very loose matching between template parameters. * Allows any very loose matching between template parameters.
* @param cost * @param cost
*/ */
private static final void relaxTemplateParameters( Cost cost ){ private static final void relaxTemplateParameters(Cost cost) {
IType s = getUltimateType( cost.source, false ); IType s = getUltimateType(cost.source, false);
IType t = getUltimateType( cost.target, false ); IType t = getUltimateType(cost.target, false);
if( (s instanceof ICPPTemplateTypeParameter && t instanceof ICPPTemplateTypeParameter) || if ((s instanceof ICPPTemplateTypeParameter && t instanceof ICPPTemplateTypeParameter) ||
(s instanceof ICPPTemplateTemplateParameter && t instanceof ICPPTemplateTemplateParameter ) ) (s instanceof ICPPTemplateTemplateParameter && t instanceof ICPPTemplateTemplateParameter)) {
{
cost.rank = Cost.FUZZY_TEMPLATE_PARAMETERS; cost.rank = Cost.FUZZY_TEMPLATE_PARAMETERS;
} }
} }

View file

@ -70,7 +70,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit;
class LookupData { class LookupData {
protected IASTName astName; protected IASTName astName;
protected CPPASTTranslationUnit tu; protected CPPASTTranslationUnit tu;
public Map<ICPPNamespaceScope, List<ICPPNamespaceScope>> usingDirectives= Collections.emptyMap(); public Map<ICPPNamespaceScope, List<ICPPNamespaceScope>> usingDirectives= Collections.emptyMap();
/* /*
* Used to ensure we don't visit things more than once * Used to ensure we don't visit things more than once
@ -95,320 +95,331 @@ class LookupData {
public boolean prefixLookup = false; public boolean prefixLookup = false;
public boolean typesOnly = false; public boolean typesOnly = false;
public boolean considerConstructors = false; public boolean considerConstructors = false;
public IBinding unknownBinding= null; public IBinding unknownBinding= null;
public Object foundItems = null; public Object foundItems = null;
public Object [] functionParameters; public Object[] functionParameters;
public IASTNode [] templateArguments; public IASTNode[] templateArguments;
public ProblemBinding problem; public ProblemBinding problem;
public LookupData( IASTName n ){ public LookupData(IASTName n) {
astName = n; astName = n;
tu= (CPPASTTranslationUnit) astName.getTranslationUnit(); tu= (CPPASTTranslationUnit) astName.getTranslationUnit();
typesOnly = typesOnly(); typesOnly = typesOnly();
considerConstructors = considerConstructors(); considerConstructors = considerConstructors();
checkWholeClassScope = checkWholeClassScope(); checkWholeClassScope = checkWholeClassScope();
} }
public LookupData(){
public LookupData() {
astName = null; astName = null;
} }
public final char [] name () {
if( astName != null ) public final char[] name () {
if (astName != null)
return astName.toCharArray(); return astName.toCharArray();
return CPPSemantics.EMPTY_NAME_ARRAY; return CPPSemantics.EMPTY_NAME_ARRAY;
} }
public boolean includeBlockItem( IASTNode item ){
if( astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY ) return true; public boolean includeBlockItem(IASTNode item) {
if( ( astName != null && astName.getParent() instanceof IASTIdExpression ) || if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return true;
item instanceof ICPPASTNamespaceDefinition || if ((astName != null && astName.getParent() instanceof IASTIdExpression) ||
(item instanceof IASTSimpleDeclaration && ((IASTSimpleDeclaration)item).getDeclSpecifier() instanceof IASTCompositeTypeSpecifier ) || item instanceof ICPPASTNamespaceDefinition ||
item instanceof ICPPASTTemplateDeclaration ) (item instanceof IASTSimpleDeclaration && ((IASTSimpleDeclaration)item).getDeclSpecifier() instanceof IASTCompositeTypeSpecifier) ||
{ item instanceof ICPPASTTemplateDeclaration) {
return true; return true;
} }
return false; return false;
} }
private boolean typesOnly(){
if( astName == null ) return false; private boolean typesOnly() {
if( astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY ) return false; if (astName == null) return false;
if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false;
IASTNode parent = astName.getParent(); IASTNode parent = astName.getParent();
if( parent instanceof ICPPASTBaseSpecifier || parent instanceof ICPPASTElaboratedTypeSpecifier || if (parent instanceof ICPPASTBaseSpecifier || parent instanceof ICPPASTElaboratedTypeSpecifier ||
parent instanceof ICPPASTCompositeTypeSpecifier ) parent instanceof ICPPASTCompositeTypeSpecifier)
return true; return true;
if( parent instanceof ICPPASTQualifiedName ){ if (parent instanceof ICPPASTQualifiedName) {
IASTName [] ns = ((ICPPASTQualifiedName)parent).getNames(); IASTName[] ns = ((ICPPASTQualifiedName)parent).getNames();
return ( astName != ns[ ns.length -1 ] ); return (astName != ns[ns.length -1]);
} }
return false; return false;
} }
public boolean forUsingDeclaration(){
if( astName == null ) return false; public boolean forUsingDeclaration() {
if( astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY ) return false; if (astName == null) return false;
if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false;
IASTNode p1 = astName.getParent(); IASTNode p1 = astName.getParent();
if( p1 instanceof ICPPASTUsingDeclaration ) if (p1 instanceof ICPPASTUsingDeclaration)
return true; return true;
if( p1 instanceof ICPPASTQualifiedName ){ if (p1 instanceof ICPPASTQualifiedName) {
IASTNode p2 = p1.getParent(); IASTNode p2 = p1.getParent();
if( p2 instanceof ICPPASTUsingDeclaration ){ if (p2 instanceof ICPPASTUsingDeclaration) {
IASTName [] ns = ((ICPPASTQualifiedName) p1 ).getNames(); IASTName[] ns = ((ICPPASTQualifiedName) p1).getNames();
return (ns[ ns.length - 1 ] == astName); return (ns[ns.length - 1] == astName);
} }
} }
return false; return false;
} }
public boolean forDefinition(){
if( astName == null ) return false; public boolean forDefinition() {
if( astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY ) return false; if (astName == null) return false;
if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false;
IASTName n = astName; IASTName n = astName;
if( n.getParent() instanceof ICPPASTTemplateId ) if (n.getParent() instanceof ICPPASTTemplateId)
n = (IASTName) n.getParent(); n = (IASTName) n.getParent();
IASTNode p1 = n.getParent(); IASTNode p1 = n.getParent();
if( p1 instanceof ICPPASTQualifiedName ){ if (p1 instanceof ICPPASTQualifiedName) {
IASTName [] ns = ((ICPPASTQualifiedName)p1).getNames(); IASTName[] ns = ((ICPPASTQualifiedName)p1).getNames();
if( ns[ns.length - 1] != n ) if (ns[ns.length - 1] != n)
return false; return false;
p1 = p1.getParent(); p1 = p1.getParent();
} }
IASTNode p2 = p1.getParent(); IASTNode p2 = p1.getParent();
if( p1 instanceof IASTDeclarator && p2 instanceof IASTSimpleDeclaration ){ if (p1 instanceof IASTDeclarator && p2 instanceof IASTSimpleDeclaration) {
return !( p2.getParent() instanceof ICPPASTExplicitTemplateInstantiation ); return !(p2.getParent() instanceof ICPPASTExplicitTemplateInstantiation);
} }
return ( p1 instanceof IASTDeclarator && p2 instanceof IASTFunctionDefinition); return (p1 instanceof IASTDeclarator && p2 instanceof IASTFunctionDefinition);
} }
public boolean forExplicitInstantiation(){ public boolean forExplicitInstantiation() {
if( astName == null ) return false; if (astName == null) return false;
if( astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY ) return false; if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false;
IASTName n = astName; IASTName n = astName;
if( n.getParent() instanceof ICPPASTTemplateId ) if (n.getParent() instanceof ICPPASTTemplateId)
n = (IASTName) n.getParent(); n = (IASTName) n.getParent();
IASTNode p1 = n.getParent(); IASTNode p1 = n.getParent();
if( p1 instanceof ICPPASTQualifiedName ){ if (p1 instanceof ICPPASTQualifiedName) {
IASTName [] ns = ((ICPPASTQualifiedName)p1).getNames(); IASTName[] ns = ((ICPPASTQualifiedName)p1).getNames();
if( ns[ns.length - 1] != n ) if (ns[ns.length - 1] != n)
return false; return false;
p1 = p1.getParent(); p1 = p1.getParent();
} }
IASTNode p2 = p1.getParent(); IASTNode p2 = p1.getParent();
if( p1 instanceof IASTDeclarator && p2 instanceof IASTSimpleDeclaration ){ if (p1 instanceof IASTDeclarator && p2 instanceof IASTSimpleDeclaration) {
return ( p2.getParent() instanceof ICPPASTExplicitTemplateInstantiation ); return (p2.getParent() instanceof ICPPASTExplicitTemplateInstantiation);
} }
return false; return false;
} }
private boolean considerConstructors(){ private boolean considerConstructors() {
if( astName == null ) return false; if (astName == null) return false;
if( astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY ) return false; if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false;
IASTNode p1 = astName.getParent(); IASTNode p1 = astName.getParent();
IASTNode p2 = p1.getParent(); IASTNode p2 = p1.getParent();
if( p1 instanceof ICPPASTConstructorChainInitializer ) if (p1 instanceof ICPPASTConstructorChainInitializer)
return true; return true;
if( p1 instanceof ICPPASTNamedTypeSpecifier && p2 instanceof IASTTypeId ) if (p1 instanceof ICPPASTNamedTypeSpecifier && p2 instanceof IASTTypeId) {
return p2.getParent() instanceof ICPPASTNewExpression; return p2.getParent() instanceof ICPPASTNewExpression;
else if( p1 instanceof ICPPASTQualifiedName ){ } else if (p1 instanceof ICPPASTQualifiedName) {
if( p2 instanceof ICPPASTFunctionDeclarator ){ if (p2 instanceof ICPPASTFunctionDeclarator) {
IASTName[] names = ((ICPPASTQualifiedName)p1).getNames(); IASTName[] names = ((ICPPASTQualifiedName)p1).getNames();
if( names.length >= 2 && names[ names.length - 1 ] == astName ) if (names.length >= 2 && names[names.length - 1] == astName)
return CPPVisitor.isConstructor( names[ names.length - 2 ], (IASTDeclarator) p2 ); return CPPVisitor.isConstructor(names[names.length - 2], (IASTDeclarator) p2);
} else if( p2 instanceof ICPPASTNamedTypeSpecifier ){ } else if (p2 instanceof ICPPASTNamedTypeSpecifier) {
IASTNode p3 = p2.getParent(); IASTNode p3 = p2.getParent();
return p3 instanceof IASTTypeId && p3.getParent() instanceof ICPPASTNewExpression; return p3 instanceof IASTTypeId && p3.getParent() instanceof ICPPASTNewExpression;
} else if( p2 instanceof IASTIdExpression ){ } else if (p2 instanceof IASTIdExpression) {
return p2.getParent() instanceof IASTFunctionCallExpression; return p2.getParent() instanceof IASTFunctionCallExpression;
} }
} else if( p1 instanceof IASTFunctionCallExpression || p2 instanceof IASTFunctionCallExpression ) } else if (p1 instanceof IASTFunctionCallExpression || p2 instanceof IASTFunctionCallExpression) {
return true; return true;
}
return false; return false;
} }
public boolean qualified(){
if( forceQualified ) return true; public boolean qualified() {
if( astName == null ) return false; if (forceQualified) return true;
if( astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY ) return false; if (astName == null) return false;
if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false;
IASTNode p1 = astName.getParent(); IASTNode p1 = astName.getParent();
if( p1 instanceof ICPPASTQualifiedName ){ if (p1 instanceof ICPPASTQualifiedName) {
final IASTName[] qnames = ((ICPPASTQualifiedName)p1).getNames(); final IASTName[] qnames = ((ICPPASTQualifiedName)p1).getNames();
return qnames.length == 1 || qnames[0] != astName; return qnames.length == 1 || qnames[0] != astName;
} }
return p1 instanceof ICPPASTFieldReference; return p1 instanceof ICPPASTFieldReference;
} }
public boolean functionCall(){
if( astName == null ) return false; public boolean functionCall() {
if( astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY ) return false; if (astName == null) return false;
if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false;
IASTNode p1 = astName.getParent(); IASTNode p1 = astName.getParent();
if( p1 instanceof ICPPASTQualifiedName ) if (p1 instanceof ICPPASTQualifiedName)
p1 = p1.getParent(); p1 = p1.getParent();
return ( p1 instanceof IASTIdExpression && p1.getPropertyInParent() == IASTFunctionCallExpression.FUNCTION_NAME ); return (p1 instanceof IASTIdExpression && p1.getPropertyInParent() == IASTFunctionCallExpression.FUNCTION_NAME);
} }
private boolean checkWholeClassScope() { private boolean checkWholeClassScope() {
if( astName == null ) return false; if (astName == null) return false;
if( astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY ) return true; if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return true;
IASTNode parent = astName.getParent(); IASTNode parent = astName.getParent();
while( parent != null && !(parent instanceof IASTFunctionDefinition) ){ while (parent != null && !(parent instanceof IASTFunctionDefinition)) {
parent = parent.getParent(); parent = parent.getParent();
} }
if( parent instanceof IASTFunctionDefinition ){ if (parent instanceof IASTFunctionDefinition) {
while( parent.getParent() instanceof ICPPASTTemplateDeclaration ) while (parent.getParent() instanceof ICPPASTTemplateDeclaration)
parent = parent.getParent(); parent = parent.getParent();
if( parent.getPropertyInParent() != IASTCompositeTypeSpecifier.MEMBER_DECLARATION ) if (parent.getPropertyInParent() != IASTCompositeTypeSpecifier.MEMBER_DECLARATION)
return false; return false;
ASTNodeProperty prop = astName.getPropertyInParent(); ASTNodeProperty prop = astName.getPropertyInParent();
if( prop == ICPPASTQualifiedName.SEGMENT_NAME ) if (prop == ICPPASTQualifiedName.SEGMENT_NAME)
prop = astName.getParent().getPropertyInParent(); prop = astName.getParent().getPropertyInParent();
if( prop == IASTIdExpression.ID_NAME || if (prop == IASTIdExpression.ID_NAME ||
prop == IASTFieldReference.FIELD_NAME || prop == IASTFieldReference.FIELD_NAME ||
prop == ICASTFieldDesignator.FIELD_NAME || prop == ICASTFieldDesignator.FIELD_NAME ||
prop == ICPPASTUsingDirective.QUALIFIED_NAME || prop == ICPPASTUsingDirective.QUALIFIED_NAME ||
prop == ICPPASTUsingDeclaration.NAME || prop == ICPPASTUsingDeclaration.NAME ||
prop == IASTFunctionCallExpression.FUNCTION_NAME || prop == IASTFunctionCallExpression.FUNCTION_NAME ||
prop == IASTNamedTypeSpecifier.NAME || prop == IASTNamedTypeSpecifier.NAME ||
prop == ICPPASTConstructorChainInitializer.MEMBER_ID ) prop == ICPPASTConstructorChainInitializer.MEMBER_ID) {
{
return true; return true;
} }
} }
return false; return false;
} }
public boolean hasResults(){ public boolean hasResults() {
if( foundItems == null ) if (foundItems == null)
return false; return false;
if( foundItems instanceof Object [] ) if (foundItems instanceof Object[])
return ((Object[])foundItems).length != 0; return ((Object[])foundItems).length != 0;
if( foundItems instanceof CharArrayObjectMap ) if (foundItems instanceof CharArrayObjectMap)
return ((CharArrayObjectMap)foundItems).size() != 0; return ((CharArrayObjectMap)foundItems).size() != 0;
return false; return false;
} }
/** /**
* an IType[] of function arguments, inluding the implied object argument * an IType[] of function arguments, including the implied object argument
*/ */
public IType getImpliedObjectArgument() { public IType getImpliedObjectArgument() {
IType implied = null; IType implied = null;
if( astName != null ){ if (astName != null) {
IASTName tempName = astName; IASTName tempName = astName;
while( tempName.getParent() instanceof IASTName ) while (tempName.getParent() instanceof IASTName)
tempName = (IASTName) tempName.getParent(); tempName = (IASTName) tempName.getParent();
ASTNodeProperty prop = tempName.getPropertyInParent(); ASTNodeProperty prop = tempName.getPropertyInParent();
if( (prop == CPPSemantics.STRING_LOOKUP_PROPERTY && tempName.getParent() instanceof ICPPASTUnaryExpression) ) { if ((prop == CPPSemantics.STRING_LOOKUP_PROPERTY && tempName.getParent() instanceof ICPPASTUnaryExpression)) {
ICPPASTUnaryExpression unaryExp = (ICPPASTUnaryExpression) tempName.getParent(); ICPPASTUnaryExpression unaryExp = (ICPPASTUnaryExpression) tempName.getParent();
IASTExpression oprd= unaryExp.getOperand(); IASTExpression oprd= unaryExp.getOperand();
return CPPVisitor.getExpressionType(oprd); return CPPVisitor.getExpressionType(oprd);
} else if( prop == IASTFieldReference.FIELD_NAME || } else if (prop == IASTFieldReference.FIELD_NAME ||
(prop == CPPSemantics.STRING_LOOKUP_PROPERTY && tempName.getParent() instanceof ICPPASTFieldReference) ) (prop == CPPSemantics.STRING_LOOKUP_PROPERTY && tempName.getParent() instanceof ICPPASTFieldReference)) {
{
ICPPASTFieldReference fieldRef = (ICPPASTFieldReference) tempName.getParent(); ICPPASTFieldReference fieldRef = (ICPPASTFieldReference) tempName.getParent();
implied = CPPVisitor.getExpressionType( fieldRef.getFieldOwner() ); implied = CPPVisitor.getExpressionType(fieldRef.getFieldOwner());
IType ultimateImplied= SemanticUtil.getUltimateTypeUptoPointers(implied); IType ultimateImplied= SemanticUtil.getUltimateTypeUptoPointers(implied);
if( prop != CPPSemantics.STRING_LOOKUP_PROPERTY && fieldRef.isPointerDereference() && ultimateImplied instanceof ICPPClassType) { if (prop != CPPSemantics.STRING_LOOKUP_PROPERTY && fieldRef.isPointerDereference() &&
ultimateImplied instanceof ICPPClassType) {
ICPPFunction operator= CPPSemantics.findOperator(fieldRef, (ICPPClassType) ultimateImplied); ICPPFunction operator= CPPSemantics.findOperator(fieldRef, (ICPPClassType) ultimateImplied);
try { try {
if(operator!=null) { if (operator!=null) {
implied= operator.getType().getReturnType(); implied= operator.getType().getReturnType();
} }
} catch(DOMException de) { } catch(DOMException de) {
return de.getProblem(); return de.getProblem();
} }
} else if( fieldRef.isPointerDereference() && implied instanceof IPointerType ){ } else if (fieldRef.isPointerDereference() && implied instanceof IPointerType) {
try { try {
implied = ((IPointerType)implied).getType(); implied = ((IPointerType)implied).getType();
} catch ( DOMException e ) { } catch (DOMException e) {
implied = e.getProblem(); implied = e.getProblem();
} }
} }
} else if( prop == IASTIdExpression.ID_NAME ){ } else if (prop == IASTIdExpression.ID_NAME) {
IScope scope = CPPVisitor.getContainingScope( tempName ); IScope scope = CPPVisitor.getContainingScope(tempName);
if( scope instanceof ICPPClassScope ){ if (scope instanceof ICPPClassScope) {
implied = ((ICPPClassScope)scope).getClassType(); implied = ((ICPPClassScope)scope).getClassType();
} else { } else {
implied = CPPVisitor.getThisType( scope ); implied = CPPVisitor.getThisType(scope);
if( implied instanceof IPointerType ){ if (implied instanceof IPointerType) {
try { try {
implied = ((IPointerType)implied).getType(); implied = ((IPointerType)implied).getType();
} catch ( DOMException e ) { } catch (DOMException e) {
implied = e.getProblem(); implied = e.getProblem();
} }
} }
} }
} else if( prop == CPPSemantics.STRING_LOOKUP_PROPERTY && tempName.getParent() instanceof IASTArraySubscriptExpression ){ } else if (prop == CPPSemantics.STRING_LOOKUP_PROPERTY && tempName.getParent() instanceof IASTArraySubscriptExpression) {
IASTExpression exp = ((IASTArraySubscriptExpression)tempName.getParent()).getArrayExpression(); IASTExpression exp = ((IASTArraySubscriptExpression)tempName.getParent()).getArrayExpression();
implied = CPPVisitor.getExpressionType( exp ); implied = CPPVisitor.getExpressionType(exp);
} }
} }
return implied; return implied;
} }
public boolean forFriendship() { public boolean forFriendship() {
if( astName == null ) if (astName == null)
return false; return false;
IASTNode node = astName.getParent(); IASTNode node = astName.getParent();
while( node instanceof IASTName ) while (node instanceof IASTName)
node = node.getParent(); node = node.getParent();
IASTDeclaration decl = null; IASTDeclaration decl = null;
IASTDeclarator dtor = null; IASTDeclarator dtor = null;
if( node instanceof ICPPASTDeclSpecifier && node.getParent() instanceof IASTDeclaration ){ if (node instanceof ICPPASTDeclSpecifier && node.getParent() instanceof IASTDeclaration) {
decl = (IASTDeclaration) node.getParent(); decl = (IASTDeclaration) node.getParent();
} else if( node instanceof IASTDeclarator ) { } else if (node instanceof IASTDeclarator) {
dtor = (IASTDeclarator) node; dtor = (IASTDeclarator) node;
while( dtor.getParent() instanceof IASTDeclarator ) while (dtor.getParent() instanceof IASTDeclarator)
dtor = (IASTDeclarator) dtor.getParent(); dtor = (IASTDeclarator) dtor.getParent();
if( !(dtor.getParent() instanceof IASTDeclaration) ) if (!(dtor.getParent() instanceof IASTDeclaration))
return false; return false;
decl = (IASTDeclaration) dtor.getParent(); decl = (IASTDeclaration) dtor.getParent();
} else { } else {
return false; return false;
} }
if( decl instanceof IASTSimpleDeclaration ){ if (decl instanceof IASTSimpleDeclaration) {
IASTSimpleDeclaration simple = (IASTSimpleDeclaration) decl; IASTSimpleDeclaration simple = (IASTSimpleDeclaration) decl;
if( ! ((ICPPASTDeclSpecifier)simple.getDeclSpecifier()).isFriend() ) if (!((ICPPASTDeclSpecifier)simple.getDeclSpecifier()).isFriend())
return false; return false;
if( dtor != null ) if (dtor != null)
return true; return true;
return simple.getDeclarators().length == 0; return simple.getDeclarators().length == 0;
} else if( decl instanceof IASTFunctionDefinition ){ } else if (decl instanceof IASTFunctionDefinition) {
IASTFunctionDefinition fnDef = (IASTFunctionDefinition) decl; IASTFunctionDefinition fnDef = (IASTFunctionDefinition) decl;
if( ! ((ICPPASTDeclSpecifier)fnDef.getDeclSpecifier()).isFriend() ) if (!((ICPPASTDeclSpecifier)fnDef.getDeclSpecifier()).isFriend())
return false; return false;
return ( dtor != null ); return (dtor != null);
} }
return false; return false;
} }
public boolean checkAssociatedScopes() { public boolean checkAssociatedScopes() {
if( astName == null || astName instanceof ICPPASTQualifiedName ) if (astName == null || astName instanceof ICPPASTQualifiedName)
return false; return false;
IASTNode parent = astName.getParent(); IASTNode parent = astName.getParent();
if( parent instanceof ICPPASTQualifiedName ){ if (parent instanceof ICPPASTQualifiedName) {
IASTName [] ns = ((ICPPASTQualifiedName)parent).getNames(); IASTName[] ns = ((ICPPASTQualifiedName)parent).getNames();
if( ns[ ns.length - 1] != astName ) if (ns[ns.length - 1] != astName)
return false; return false;
} }
return functionCall() && (associated.size() > 0); return functionCall() && (associated.size() > 0);
} }
public boolean checkClassContainingFriend() { public boolean checkClassContainingFriend() {
if( astName == null || astName instanceof ICPPASTQualifiedName ) if (astName == null || astName instanceof ICPPASTQualifiedName)
return false; return false;
IASTNode p = astName.getParent(); IASTNode p = astName.getParent();
ASTNodeProperty prop = null; ASTNodeProperty prop = null;
while( p != null ){ while (p != null) {
prop = p.getPropertyInParent(); prop = p.getPropertyInParent();
if( prop == ICPPASTTemplateId.TEMPLATE_ID_ARGUMENT || prop == IASTDeclarator.DECLARATOR_NAME ) if (prop == ICPPASTTemplateId.TEMPLATE_ID_ARGUMENT || prop == IASTDeclarator.DECLARATOR_NAME)
return false; return false;
if( p instanceof IASTDeclarator && !(((IASTDeclarator)p).getName() instanceof ICPPASTQualifiedName) ) if (p instanceof IASTDeclarator && !(((IASTDeclarator)p).getName() instanceof ICPPASTQualifiedName))
return false; return false;
if( p instanceof IASTDeclaration ){ if (p instanceof IASTDeclaration) {
if( prop == IASTCompositeTypeSpecifier.MEMBER_DECLARATION ){ if (prop == IASTCompositeTypeSpecifier.MEMBER_DECLARATION) {
if( p instanceof IASTSimpleDeclaration ){ if (p instanceof IASTSimpleDeclaration) {
ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) ((IASTSimpleDeclaration)p).getDeclSpecifier(); ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) ((IASTSimpleDeclaration)p).getDeclSpecifier();
return declSpec.isFriend(); return declSpec.isFriend();
} else if( p instanceof IASTFunctionDefinition ){ } else if (p instanceof IASTFunctionDefinition) {
ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) ((IASTFunctionDefinition)p).getDeclSpecifier(); ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) ((IASTFunctionDefinition)p).getDeclSpecifier();
return declSpec.isFriend(); return declSpec.isFriend();
} }
@ -420,9 +431,10 @@ class LookupData {
} }
return false; return false;
} }
public boolean preferTemplateFunctions() { public boolean preferTemplateFunctions() {
if( astName == null ) if (astName == null)
return false; return false;
return (astName instanceof ICPPASTTemplateId || astName.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME ); return (astName instanceof ICPPASTTemplateId || astName.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME);
} }
} }

View file

@ -240,8 +240,7 @@ public class SemanticUtil {
if (ret == r && params == ps) { if (ret == r && params == ps) {
return type; return type;
} }
return new CPPFunctionType(ret, params, ((ICPPFunctionType) type).isConst(), return new CPPFunctionType(ret, params, ((ICPPFunctionType) type).getThisType());
((ICPPFunctionType) type).isVolatile());
} }
if (type instanceof ITypeContainer) { if (type instanceof ITypeContainer) {

View file

@ -26,23 +26,27 @@ public class PointerTypeClone implements IPointerType, ITypeContainer, IIndexTyp
public PointerTypeClone(IPointerType pointer) { public PointerTypeClone(IPointerType pointer) {
this.delegate = pointer; this.delegate = pointer;
} }
public IType getType() throws DOMException { public IType getType() throws DOMException {
if (type == null) { if (type == null) {
return delegate.getType(); return delegate.getType();
} }
return type; return type;
} }
public boolean isConst() throws DOMException {
public boolean isConst() {
return delegate.isConst(); return delegate.isConst();
} }
public boolean isVolatile() throws DOMException {
public boolean isVolatile() {
return delegate.isVolatile(); return delegate.isVolatile();
} }
public boolean isSameType(IType type) { public boolean isSameType(IType type) {
if( type instanceof ITypedef ) if (type instanceof ITypedef)
return ((ITypedef)type).isSameType( this ); return ((ITypedef)type).isSameType(this);
if( !( type instanceof IPointerType )) if (!(type instanceof IPointerType))
return false; return false;
IPointerType rhs = (IPointerType) type; IPointerType rhs = (IPointerType) type;
@ -57,9 +61,11 @@ public class PointerTypeClone implements IPointerType, ITypeContainer, IIndexTyp
} }
return false; return false;
} }
public void setType(IType type) { public void setType(IType type) {
this.type = type; this.type = type;
} }
@Override @Override
public Object clone() { public Object clone() {
return new PointerTypeClone(this); return new PointerTypeClone(this);

View file

@ -21,17 +21,17 @@ public class CompositePointerType extends CompositeTypeContainer implements IPoi
super((ITypeContainer) pointerType, cf); super((ITypeContainer) pointerType, cf);
} }
public boolean isConst() throws DOMException { public boolean isConst() {
return ((IPointerType)type).isConst(); return ((IPointerType) type).isConst();
} }
public boolean isVolatile() throws DOMException { public boolean isVolatile() {
return ((IPointerType)type).isVolatile(); return ((IPointerType) type).isVolatile();
} }
@Override @Override
public boolean isSameType(IType other) { public boolean isSameType(IType other) {
return ((IPointerType)type).isSameType(other); return ((IPointerType) type).isSameType(other);
} }
@Override @Override

View file

@ -1,32 +1,38 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2007 Symbian Software Systems and others. * Copyright (c) 2007, 2008 Symbian Software Systems and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Andrew Ferguson (Symbian) - Initial implementation * Andrew Ferguson (Symbian) - Initial implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.index.composite.cpp; package org.eclipse.cdt.internal.core.index.composite.cpp;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.internal.core.index.composite.CompositeFunctionType; import org.eclipse.cdt.internal.core.index.composite.CompositeFunctionType;
import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory;
public class CompositeCPPFunctionType extends CompositeFunctionType implements ICPPFunctionType { public class CompositeCPPFunctionType extends CompositeFunctionType implements ICPPFunctionType {
public CompositeCPPFunctionType(ICPPFunctionType rtype, public CompositeCPPFunctionType(ICPPFunctionType rtype, ICompositesFactory cf) {
ICompositesFactory cf) {
super(rtype, cf); super(rtype, cf);
} }
public IPointerType getThisType() {
return ((ICPPFunctionType) type).getThisType();
}
public boolean isConst() { public boolean isConst() {
return ((ICPPFunctionType)type).isConst(); return ((ICPPFunctionType) type).isConst();
} }
public boolean isVolatile() { public boolean isVolatile() {
return ((ICPPFunctionType)type).isVolatile(); return ((ICPPFunctionType) type).isVolatile();
} }
@Override @Override

View file

@ -64,9 +64,9 @@ public class PDOMCFunctionType extends PDOMNode implements IIndexType, IFunction
PDOMNodeLinkedList list= new PDOMNodeLinkedList(pdom, record + TYPELIST, parent.getLinkageImpl(), true); PDOMNodeLinkedList list= new PDOMNodeLinkedList(pdom, record + TYPELIST, parent.getLinkageImpl(), true);
setReturnType(type.getReturnType()); setReturnType(type.getReturnType());
IType[] pt= type.getParameterTypes(); IType[] pt= type.getParameterTypes();
for(int i=0; i<pt.length; i++) { for (int i = 0; i < pt.length; i++) {
PDOMNode typeNode; PDOMNode typeNode;
if(pt[i]==null || pt[i] instanceof IProblemBinding) { if (pt[i] == null || pt[i] instanceof IProblemBinding) {
typeNode= null; typeNode= null;
} else { } else {
typeNode= linkage.addType(this, pt[i]); typeNode= linkage.addType(this, pt[i]);
@ -74,7 +74,6 @@ public class PDOMCFunctionType extends PDOMNode implements IIndexType, IFunction
list.addMember(typeNode); list.addMember(typeNode);
} }
} catch(DOMException de) { } catch(DOMException de) {
} }
} }

View file

@ -1,37 +1,41 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2007 Symbian Software Systems and others. * Copyright (c) 2007, 2008 Symbian Software Systems and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* Andrew Ferguson (Symbian) - Initial Implementation * Andrew Ferguson (Symbian) - Initial Implementation
* Sergey Prigogin (Google)
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp; package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.PDOM;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.cdt.internal.core.pdom.dom.c.PDOMCAnnotation;
import org.eclipse.cdt.internal.core.pdom.dom.c.PDOMCFunctionType; import org.eclipse.cdt.internal.core.pdom.dom.c.PDOMCFunctionType;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
public class PDOMCPPFunctionType extends PDOMCFunctionType implements ICPPFunctionType { public class PDOMCPPFunctionType extends PDOMCFunctionType implements ICPPFunctionType {
/** /**
* Offset for return type of this function (relative to * Offset for <code>this</code> type of this function (relative to
* the beginning of the record). * the beginning of the record).
*/ */
private static final int FLAGS= PDOMCFunctionType.RECORD_SIZE; private static final int THIS_TYPE= PDOMCFunctionType.RECORD_SIZE;
/** /**
* The size in bytes of a PDOMCFunctionType record in the database. * The size in bytes of a PDOMCFunctionType record in the database.
*/ */
@SuppressWarnings("hiding") @SuppressWarnings("hiding")
private static final int RECORD_SIZE= PDOMCFunctionType.RECORD_SIZE+ 4; private static final int RECORD_SIZE= PDOMCFunctionType.RECORD_SIZE + 4;
IPointerType thisType; // Cached value
protected PDOMCPPFunctionType(PDOM pdom, int offset) { protected PDOMCPPFunctionType(PDOM pdom, int offset) {
super(pdom, offset); super(pdom, offset);
@ -40,16 +44,36 @@ public class PDOMCPPFunctionType extends PDOMCFunctionType implements ICPPFuncti
protected PDOMCPPFunctionType(PDOM pdom, PDOMNode parent, ICPPFunctionType type) protected PDOMCPPFunctionType(PDOM pdom, PDOMNode parent, ICPPFunctionType type)
throws CoreException { throws CoreException {
super(pdom, parent, type); super(pdom, parent, type);
int modifiers= PDOMCAnnotation.encodeCVQualifiers(type); setThisType(type.getThisType());
pdom.getDB().putInt(getRecord()+FLAGS, modifiers);
} }
public boolean isConst() { private void setThisType(IPointerType type) throws CoreException {
return getBit(getInt(record + FLAGS), PDOMCAnnotation.CONST_OFFSET); PDOMNode typeNode = getLinkageImpl().addType(this, type);
if (typeNode != null) {
pdom.getDB().putInt(record + THIS_TYPE, typeNode.getRecord());
}
} }
public boolean isVolatile() { public IPointerType getThisType() {
return getBit(getInt(record + FLAGS), PDOMCAnnotation.VOLATILE_OFFSET); if (thisType == null) {
try {
PDOMNode node = getLinkageImpl().getNode(pdom.getDB().getInt(record + THIS_TYPE));
if (node instanceof IPointerType) {
thisType = (IPointerType) node;
}
} catch (CoreException e) {
CCorePlugin.log(e);
}
}
return thisType;
}
public final boolean isConst() {
return getThisType() != null && getThisType().isConst();
}
public final boolean isVolatile() {
return getThisType() != null && getThisType().isVolatile();
} }
@Override @Override
@ -59,11 +83,12 @@ public class PDOMCPPFunctionType extends PDOMCFunctionType implements ICPPFuncti
@Override @Override
public boolean isSameType(IType type) { public boolean isSameType(IType type) {
if(type instanceof ICPPFunctionType) { if (type instanceof ICPPFunctionType) {
if(super.isSameType(type)) { if (super.isSameType(type)) {
ICPPFunctionType ft= (ICPPFunctionType) type; ICPPFunctionType ft= (ICPPFunctionType) type;
if( isConst() != ft.isConst() || isVolatile() != ft.isVolatile() ) if (isConst() != ft.isConst() || isVolatile() != ft.isVolatile()) {
return false; return false;
}
return true; return true;
} }
} }

View file

@ -13,6 +13,7 @@
package org.eclipse.cdt.internal.core.pdom.dom.cpp; package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
@ -39,7 +40,7 @@ class PDOMCPPPointerToMemberType extends PDOMPointerType implements ICPPPointerT
Database db = pdom.getDB(); Database db = pdom.getDB();
// type // type
ICPPClassType ct = type.getMemberOfClass(); IType ct = type.getMemberOfClass();
int typeRec = 0; int typeRec = 0;
if (ct != null) { if (ct != null) {
PDOMNode targetTypeNode = getLinkageImpl().addType(this, ct); PDOMNode targetTypeNode = getLinkageImpl().addType(this, ct);
@ -81,8 +82,8 @@ class PDOMCPPPointerToMemberType extends PDOMPointerType implements ICPPPointerT
public PDOMCPPPointerToMemberTypeClone(ICPPPointerToMemberType pointer) { public PDOMCPPPointerToMemberTypeClone(ICPPPointerToMemberType pointer) {
super(pointer); super(pointer);
} }
public ICPPClassType getMemberOfClass() { public IType getMemberOfClass() {
return ((ICPPPointerToMemberType)delegate).getMemberOfClass(); return ((ICPPPointerToMemberType) delegate).getMemberOfClass();
} }
@Override @Override
public Object clone() { public Object clone() {