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

Function declared by use of a typedef, bug 86495.

This commit is contained in:
Markus Schorn 2009-11-03 15:15:50 +00:00
parent 1b08bd261f
commit 29e5a63132
22 changed files with 593 additions and 422 deletions

View file

@ -100,6 +100,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.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
@ -7625,5 +7626,34 @@ public class AST2CPPTests extends AST2BaseTest {
parseAndCheckBindings(code, ParserLanguage.CPP); parseAndCheckBindings(code, ParserLanguage.CPP);
} }
// typedef int F(int);
// template<typename T> F functionTemplate;
// class C {
// F method;
// friend F friendFunction;
// template<typename T> F methodTemplate;
// };
public void testFunctionDeclViaTypedef_86495() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP);
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
ICPPFunctionTemplate template= bh.assertNonProblem("functionTemplate", 16);
assertNotNull(template.getType());
assertEquals(1, template.getParameters().length);
ICPPMethod method= bh.assertNonProblem("method", 6);
assertNotNull(method.getType());
assertEquals(1, method.getParameters().length);
ICPPFunction friendFunction= bh.assertNonProblem("friendFunction", 14);
assertNotNull(friendFunction.getType());
assertEquals(1, friendFunction.getParameters().length);
ICPPMethod methodTemplate= bh.assertNonProblem("methodTemplate", 14);
assertTrue(methodTemplate instanceof ICPPFunctionTemplate);
assertNotNull(methodTemplate.getType());
assertEquals(1, methodTemplate.getParameters().length);
}
} }

View file

@ -7029,19 +7029,16 @@ public class AST2Tests extends AST2BaseTest {
assertEquals("const int *", ASTTypeUtil.getType(f.getParameters()[0].getType())); assertEquals("const int *", ASTTypeUtil.getType(f.getParameters()[0].getType()));
} }
// typedef int f(); // typedef int f(int);
// f ff; // f ff;
// int ff() { return 0;}
public void testFunctionDeclViaTypedef_86495() throws Exception { public void testFunctionDeclViaTypedef_86495() throws Exception {
final String code = getAboveComment(); final String code = getAboveComment();
// for(ParserLanguage lang : ParserLanguage.values()) { for(ParserLanguage lang : ParserLanguage.values()) {
// IASTTranslationUnit tu = parseAndCheckBindings(code, lang); IASTTranslationUnit tu = parseAndCheckBindings(code, lang);
IASTTranslationUnit tu = parseAndCheckBindings(code, ParserLanguage.C);
IASTSimpleDeclaration decl= getDeclaration(tu, 1); IASTSimpleDeclaration decl= getDeclaration(tu, 1);
IASTFunctionDefinition def= getDeclaration(tu, 2); IFunction ff= (IFunction) decl.getDeclarators()[0].getName().resolveBinding();
IBinding ffDecl= decl.getDeclarators()[0].getName().resolveBinding(); assertNotNull(ff.getType());
IBinding ffDef= def.getDeclarator().getName().resolveBinding(); assertEquals(1, ff.getParameters().length);
assertSame(ffDecl, ffDef); }
// }
} }
} }

View file

@ -464,7 +464,43 @@ public abstract class ArrayUtil {
return array; return array;
} }
/**
* Inserts the obj at the beginning of the array, shifting the whole thing one index
* Assumes that array contains nulls at the end, only.
* array must not be <code>null</code>.
* @since 5.2
*/
public static <T> T[] prepend(T[] array, T obj) {
assert array != null;
if (obj == null)
return array;
if (array.length == 0) {
array = newArray(array, DEFAULT_LENGTH);
array[0] = obj;
return array;
}
int i = findFirstNull(array);
if (i >= 0) {
System.arraycopy(array, 0, array, 1, i);
array[0] = obj;
} else {
T[] temp = newArray(array, array.length*2);
System.arraycopy(array, 0, temp, 1, array.length);
temp[0] = obj;
array = temp;
}
return array;
}
@SuppressWarnings("unchecked")
private static <T> T[] newArray(T[] array, int newLen) {
return (T[]) Array.newInstance(array.getClass().getComponentType(), newLen);
}
/** /**
* Removes first occurrence of element in array and moves objects behind up front. * Removes first occurrence of element in array and moves objects behind up front.
* @since 4.0 * @since 4.0

View file

@ -13,7 +13,6 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser; package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
@ -21,15 +20,13 @@ import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
import org.eclipse.cdt.core.dom.parser.IBuiltinBindingsProvider; import org.eclipse.cdt.core.dom.parser.IBuiltinBindingsProvider;
import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.cdt.internal.core.dom.parser.c.CBasicType; import org.eclipse.cdt.internal.core.dom.parser.c.CBasicType;
import org.eclipse.cdt.internal.core.dom.parser.c.CBuiltinParameter;
import org.eclipse.cdt.internal.core.dom.parser.c.CBuiltinVariable; import org.eclipse.cdt.internal.core.dom.parser.c.CBuiltinVariable;
import org.eclipse.cdt.internal.core.dom.parser.c.CFunctionType; import org.eclipse.cdt.internal.core.dom.parser.c.CFunctionType;
import org.eclipse.cdt.internal.core.dom.parser.c.CImplicitFunction; import org.eclipse.cdt.internal.core.dom.parser.c.CImplicitFunction;
@ -37,6 +34,7 @@ import org.eclipse.cdt.internal.core.dom.parser.c.CImplicitTypedef;
import org.eclipse.cdt.internal.core.dom.parser.c.CPointerType; import org.eclipse.cdt.internal.core.dom.parser.c.CPointerType;
import org.eclipse.cdt.internal.core.dom.parser.c.CQualifierType; import org.eclipse.cdt.internal.core.dom.parser.c.CQualifierType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBuiltinParameter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBuiltinVariable; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBuiltinVariable;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitFunction; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitFunction;
@ -44,7 +42,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitTypedef;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPQualifierType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPQualifierType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPPointerType; import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPPointerType;
import org.eclipse.core.runtime.PlatformObject;
/** /**
* This is the IBuiltinBindingsProvider used to implement the "Other" built-in GCC symbols defined: * This is the IBuiltinBindingsProvider used to implement the "Other" built-in GCC symbols defined:
@ -2972,167 +2969,4 @@ public class GCCBuiltinSymbolProvider implements IBuiltinBindingsProvider {
initialize(); initialize();
return (IBinding[]) ArrayUtil.trim(IBinding.class, bindings); return (IBinding[]) ArrayUtil.trim(IBinding.class, bindings);
} }
public static class CBuiltinParameter extends PlatformObject implements IParameter {
private static final String BLANK_STRING = ""; //$NON-NLS-1$
private IType type= null;
public CBuiltinParameter(IType type) {
this.type = type;
}
public IType getType() {
return type;
}
/**
* Returns false
*/
public boolean isStatic() {
return false;
}
/**
* Returns false
*/
public boolean isExtern() {
return false;
}
/**
* Returns false
*/
public boolean isAuto() {
return false;
}
/**
* Returns false
*/
public boolean isRegister() {
return false;
}
public String getName() {
return BLANK_STRING;
}
public char[] getNameCharArray() {
return BLANK_STRING.toCharArray();
}
/**
* Returns false
*/
public IScope getScope() {
return null;
}
public ILinkage getLinkage() {
return Linkage.C_LINKAGE;
}
public IBinding getOwner() {
return null;
}
public IValue getInitialValue() {
return null;
}
}
static public class CPPBuiltinParameter extends PlatformObject implements ICPPParameter {
private static final String BLANK_STRING = ""; //$NON-NLS-1$
private IType type= null;
public CPPBuiltinParameter(IType type) {
this.type = type;
}
public IType getType() {
return type;
}
/**
* Returns false
*/
public boolean isStatic() {
return false;
}
/**
* Returns false
*/
public boolean isExtern() {
return false;
}
public boolean isExternC() {
return false;
}
/**
* Returns false
*/
public boolean isAuto() {
return false;
}
/**
* Returns false
*/
public boolean isRegister() {
return false;
}
public String getName() {
return BLANK_STRING;
}
public char[] getNameCharArray() {
return BLANK_STRING.toCharArray();
}
/**
* Returns false
*/
public IScope getScope() {
return null;
}
public boolean hasDefaultValue() {
return false;
}
/**
* Returns false
*/
public boolean isMutable() {
return false;
}
public String[] getQualifiedName() {
return new String[0];
}
public char[][] getQualifiedNameCharArray() {
return new char[0][];
}
public boolean isGloballyQualified() {
return false;
}
public ILinkage getLinkage() {
return Linkage.CPP_LINKAGE;
}
public IBinding getOwner() {
return null;
}
public IValue getInitialValue() {
return null;
}
}
} }

View file

@ -0,0 +1,89 @@
/*******************************************************************************
* Copyright (c) 2009 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.core.runtime.PlatformObject;
public class CBuiltinParameter extends PlatformObject implements IParameter {
public static IParameter[] createParameterList(IFunctionType ft) {
if (ft == null) {
return IParameter.EMPTY_PARAMETER_ARRAY;
}
assert !(ft instanceof ICPPFunctionType);
IType[] ptypes= ft.getParameterTypes();
IParameter[] result= new IParameter[ptypes.length];
for (int i = 0; i < result.length; i++) {
result[i]= new CBuiltinParameter(ptypes[i]);
}
return result;
}
private IType type= null;
public CBuiltinParameter(IType type) {
this.type = type;
}
public IType getType() {
return type;
}
public boolean isStatic() {
return false;
}
public boolean isExtern() {
return false;
}
public boolean isAuto() {
return false;
}
public boolean isRegister() {
return false;
}
public String getName() {
return ""; //$NON-NLS-1$
}
public char[] getNameCharArray() {
return CharArrayUtils.EMPTY;
}
public IScope getScope() {
return null;
}
public ILinkage getLinkage() {
return Linkage.C_LINKAGE;
}
public IBinding getOwner() {
return null;
}
public IValue getInitialValue() {
return null;
}
}

View file

@ -1,33 +1,32 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others. * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html * http://www.eclipse.org/legal/epl-v10.html
* *
* Contributors: * Contributors:
* IBM Corporation - initial API and implementation * Andrew Niefer (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/ *******************************************************************************/
/*
* Created on Jan 26, 2005
*/
package org.eclipse.cdt.internal.core.dom.parser.c; package org.eclipse.cdt.internal.core.dom.parser.c;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.c.ICExternalBinding; import org.eclipse.cdt.core.dom.ast.c.ICExternalBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
/** /**
* @author aniefer * Models functions used without declarations.
*/ */
public class CExternalFunction extends CFunction implements ICExternalBinding { public class CExternalFunction extends CFunction implements ICExternalBinding {
private IASTName name = null; private static final IType VOID_TYPE = new CBasicType(Kind.eVoid, 0);
private IASTName name = null;
private IASTTranslationUnit tu = null; private IASTTranslationUnit tu = null;
public CExternalFunction( IASTTranslationUnit tu, IASTName name ) { public CExternalFunction( IASTTranslationUnit tu, IASTName name ) {
@ -39,14 +38,19 @@ public class CExternalFunction extends CFunction implements ICExternalBinding {
@Override @Override
public IFunctionType getType() { public IFunctionType getType() {
IFunctionType t = super.getType(); IFunctionType t = super.getType();
if( t == null ) { if (t == null) {
type = new CPPFunctionType( CPPSemantics.VOID_TYPE, IType.EMPTY_TYPE_ARRAY ); type = new CFunctionType(VOID_TYPE, IType.EMPTY_TYPE_ARRAY);
} }
return type; return type;
} }
@Override @Override
public IParameter[] getParameters() {
return IParameter.EMPTY_PARAMETER_ARRAY;
}
@Override
protected IASTTranslationUnit getTranslationUnit() { protected IASTTranslationUnit getTranslationUnit() {
return tu; return tu;
} }

View file

@ -157,7 +157,7 @@ public class CFunction extends PlatformObject implements IFunction, ICInternalFu
return getParameters(); return getParameters();
} }
return IParameter.EMPTY_PARAMETER_ARRAY; return CBuiltinParameter.createParameterList(getType());
} }
/* (non-Javadoc) /* (non-Javadoc)

View file

@ -30,7 +30,6 @@ import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit; import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.GCCBuiltinSymbolProvider.CPPBuiltinParameter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.index.IIndexScope; import org.eclipse.cdt.internal.core.index.IIndexScope;
import org.eclipse.cdt.internal.core.parser.scanner.IncludeFileContent; import org.eclipse.cdt.internal.core.parser.scanner.IncludeFileContent;

View file

@ -0,0 +1,111 @@
/*******************************************************************************
* Copyright (c) 2009 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IParameter;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.core.runtime.PlatformObject;
public class CPPBuiltinParameter extends PlatformObject implements ICPPParameter {
public static IParameter[] createParameterList(ICPPFunctionType ft) {
if (ft == null) {
return IParameter.EMPTY_PARAMETER_ARRAY;
}
IType[] ptypes= ft.getParameterTypes();
IParameter[] result= new IParameter[ptypes.length];
for (int i = 0; i < result.length; i++) {
result[i]= new CPPBuiltinParameter(ptypes[i]);
}
return result;
}
private IType type= null;
public CPPBuiltinParameter(IType type) {
this.type = type;
}
public IType getType() {
return type;
}
public boolean isStatic() {
return false;
}
public boolean isExtern() {
return false;
}
public boolean isExternC() {
return false;
}
public boolean isAuto() {
return false;
}
public boolean isRegister() {
return false;
}
public String getName() {
return ""; //$NON-NLS-1$
}
public char[] getNameCharArray() {
return CharArrayUtils.EMPTY;
}
public IScope getScope() {
return null;
}
public boolean hasDefaultValue() {
return false;
}
public boolean isMutable() {
return false;
}
public String[] getQualifiedName() {
return new String[0];
}
public char[][] getQualifiedNameCharArray() {
return new char[0][];
}
public boolean isGloballyQualified() {
return false;
}
public ILinkage getLinkage() {
return Linkage.CPP_LINKAGE;
}
public IBinding getOwner() {
return null;
}
public IValue getInitialValue() {
return null;
}
}

View file

@ -11,6 +11,9 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType;
import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
@ -106,7 +109,7 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
} }
} }
protected ICPPASTFunctionDeclarator[] declarations; protected IASTDeclarator[] declarations;
protected ICPPASTFunctionDeclarator definition; protected ICPPASTFunctionDeclarator definition;
protected ICPPFunctionType type = null; protected ICPPFunctionType type = null;
@ -114,13 +117,16 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
private static final int RESOLUTION_IN_PROGRESS = 1 << 1; private static final int RESOLUTION_IN_PROGRESS = 1 << 1;
private int bits = 0; private int bits = 0;
public CPPFunction(ICPPASTFunctionDeclarator declarator) { public CPPFunction(IASTDeclarator declarator) {
if (declarator != null) { if (declarator != null) {
IASTNode parent = ASTQueries.findOutermostDeclarator(declarator).getParent(); IASTNode parent = ASTQueries.findOutermostDeclarator(declarator).getParent();
if (parent instanceof IASTFunctionDefinition) if (parent instanceof IASTFunctionDefinition) {
definition = declarator; if (declarator instanceof ICPPASTFunctionDeclarator) {
else definition = (ICPPASTFunctionDeclarator) declarator;
declarations = new ICPPASTFunctionDeclarator[] { declarator }; }
} else {
declarations = new IASTDeclarator[] { declarator };
}
IASTName name= getASTName(); IASTName name= getASTName();
name.setBinding(this); name.setBinding(this);
@ -149,64 +155,65 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
if (tu != null) { if (tu != null) {
CPPVisitor.getDeclarations(tu, this); CPPVisitor.getDeclarations(tu, this);
} }
declarations = (ICPPASTFunctionDeclarator[]) ArrayUtil.trim(ICPPASTFunctionDeclarator.class, declarations = (IASTDeclarator[]) ArrayUtil.trim(IASTDeclarator.class, declarations);
declarations);
bits |= FULLY_RESOLVED; bits |= FULLY_RESOLVED;
bits &= ~RESOLUTION_IN_PROGRESS; bits &= ~RESOLUTION_IN_PROGRESS;
} }
} }
public IASTNode[] getDeclarations() { public IASTDeclarator[] getDeclarations() {
return declarations; return declarations;
} }
public IASTNode getDefinition() { public ICPPASTFunctionDeclarator getDefinition() {
return definition; return definition;
} }
public final void addDefinition(IASTNode node) { public final void addDefinition(IASTNode node) {
ICPPASTFunctionDeclarator dtor = extractFunctionDtor(node); IASTDeclarator dtor = extractRelevantDtor(node);
if (dtor != null) { if (dtor instanceof ICPPASTFunctionDeclarator) {
updateFunctionParameterBindings(dtor); ICPPASTFunctionDeclarator fdtor= (ICPPASTFunctionDeclarator) dtor;
definition = dtor; updateFunctionParameterBindings(fdtor);
definition = fdtor;
} }
} }
public final void addDeclaration(IASTNode node) { public final void addDeclaration(IASTNode node) {
ICPPASTFunctionDeclarator dtor = extractFunctionDtor(node); IASTDeclarator dtor = extractRelevantDtor(node);
if (dtor != null) { if (dtor == null) {
updateFunctionParameterBindings(dtor); return;
}
if (declarations == null) {
declarations = new ICPPASTFunctionDeclarator[] { dtor }; // function could be declared via a typedef
return; if (dtor instanceof ICPPASTFunctionDeclarator) {
} updateFunctionParameterBindings((ICPPASTFunctionDeclarator) dtor);
}
if (declarations == null || declarations.length == 0) {
declarations = new IASTDeclarator[] { dtor };
} else {
// Keep the lowest offset declaration in [0] // Keep the lowest offset declaration in [0]
if (declarations.length > 0 && ((ASTNode)node).getOffset() < ((ASTNode)declarations[0]).getOffset()) { if (((ASTNode)node).getOffset() < ((ASTNode)declarations[0]).getOffset()) {
declarations = (ICPPASTFunctionDeclarator[]) ArrayUtil.prepend(ICPPASTFunctionDeclarator.class, declarations = ArrayUtil.prepend(declarations, dtor);
declarations, dtor);
} else { } else {
declarations = (ICPPASTFunctionDeclarator[]) ArrayUtil.append(ICPPASTFunctionDeclarator.class, declarations = ArrayUtil.append(declarations, dtor);
declarations, dtor);
} }
} }
} }
private ICPPASTFunctionDeclarator extractFunctionDtor(IASTNode node) { private IASTDeclarator extractRelevantDtor(IASTNode node) {
while (node instanceof IASTName) while (node instanceof IASTName)
node = node.getParent(); node = node.getParent();
if (node instanceof IASTDeclarator == false) if (!(node instanceof IASTDeclarator))
return null; return null;
node= ASTQueries.findTypeRelevantDeclarator((IASTDeclarator) node); return ASTQueries.findTypeRelevantDeclarator((IASTDeclarator) node);
if (node instanceof ICPPASTFunctionDeclarator == false)
return null;
return (ICPPASTFunctionDeclarator) node;
} }
public IParameter[] getParameters() { public IParameter[] getParameters() {
IASTStandardFunctionDeclarator dtor = getPreferredDtor(); IASTStandardFunctionDeclarator dtor = getPreferredDtor();
if (dtor == null) {
return CPPBuiltinParameter.createParameterList(getType());
}
IASTParameterDeclaration[] params = dtor.getParameters(); IASTParameterDeclaration[] params = dtor.getParameters();
int size = params.length; int size = params.length;
IParameter[] result = new IParameter[size]; IParameter[] result = new IParameter[size];
@ -232,7 +239,14 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
return definition.getFunctionScope(); return definition.getFunctionScope();
} }
return declarations[0].getFunctionScope(); for (IASTDeclarator dtor : declarations) {
if (dtor instanceof ICPPASTFunctionDeclarator) {
return ((ICPPASTFunctionDeclarator) dtor).getFunctionScope();
}
}
// function declaration via typedef
return null;
} }
public String getName() { public String getName() {
@ -281,8 +295,11 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
} }
public ICPPFunctionType getType() { public ICPPFunctionType getType() {
if (type == null) if (type == null) {
type = (ICPPFunctionType) CPPVisitor.createType((definition != null) ? definition : declarations[0]); final IType t = getNestedType(CPPVisitor.createType((definition != null) ? definition : declarations[0]), TDEF);
if (t instanceof ICPPFunctionType)
type = (ICPPFunctionType) t;
}
return type; return type;
} }
@ -297,9 +314,14 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
if (tdecl == null) if (tdecl == null)
continue; continue;
} else { } else {
tdecl= declarations[i]; final IASTDeclarator dtor= declarations[i];
if (tdecl == null) if (!(dtor instanceof ICPPASTFunctionDeclarator)) {
break; if (dtor == null) {
break;
}
continue;
}
tdecl= (ICPPASTFunctionDeclarator) dtor;
} }
IASTParameterDeclaration[] params = tdecl.getParameters(); IASTParameterDeclaration[] params = tdecl.getParameters();
@ -327,9 +349,14 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
if (tdecl == null) if (tdecl == null)
continue; continue;
} else { } else {
tdecl= declarations[i]; final IASTDeclarator dtor= declarations[i];
if (tdecl == null) if (!(dtor instanceof ICPPASTFunctionDeclarator)) {
break; if (dtor == null) {
break;
}
continue;
}
tdecl= (ICPPASTFunctionDeclarator) dtor;
} }
IASTParameterDeclaration[] params = tdecl.getParameters(); IASTParameterDeclaration[] params = tdecl.getParameters();
@ -405,7 +432,7 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
} }
static public boolean hasStorageClass(ICPPInternalFunction function, int storage) { static public boolean hasStorageClass(ICPPInternalFunction function, int storage) {
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) function.getDefinition(); IASTDeclarator dtor = (IASTDeclarator) function.getDefinition();
IASTNode[] ds = function.getDeclarations(); IASTNode[] ds = function.getDeclarations();
int i = -1; int i = -1;
@ -426,7 +453,7 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
} }
} }
if (ds != null && ++i < ds.length) { if (ds != null && ++i < ds.length) {
dtor = (ICPPASTFunctionDeclarator) ds[i]; dtor = (IASTDeclarator) ds[i];
} else { } else {
break; break;
} }
@ -439,8 +466,8 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
} }
public boolean isInline() throws DOMException { public boolean isInline() throws DOMException {
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) getDefinition(); IASTDeclarator dtor = getDefinition();
ICPPASTFunctionDeclarator[] ds = (ICPPASTFunctionDeclarator[]) getDeclarations(); IASTDeclarator[] ds = getDeclarations();
int i = -1; int i = -1;
do { do {
if (dtor != null) { if (dtor != null) {
@ -534,15 +561,15 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
} }
protected ICPPASTFunctionDeclarator getPreferredDtor() { protected ICPPASTFunctionDeclarator getPreferredDtor() {
ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) getDefinition(); ICPPASTFunctionDeclarator dtor = getDefinition();
if (dtor != null) if (dtor != null)
return dtor; return dtor;
ICPPASTFunctionDeclarator[] dtors = (ICPPASTFunctionDeclarator[]) getDeclarations(); IASTDeclarator[] dtors = getDeclarations();
if (dtors != null) { if (dtors != null) {
for (ICPPASTFunctionDeclarator declarator : dtors) { for (IASTDeclarator declarator : dtors) {
if (declarator != null) if (declarator instanceof ICPPASTFunctionDeclarator)
return declarator; return (ICPPASTFunctionDeclarator) declarator;
} }
} }
return null; return null;

View file

@ -19,6 +19,7 @@ import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.EScopeKind; import org.eclipse.cdt.core.dom.ast.EScopeKind;
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
@ -27,7 +28,6 @@ import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ILabel; import org.eclipse.cdt.core.dom.ast.ILabel;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionScope;
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
@ -89,8 +89,8 @@ public class CPPFunctionScope extends CPPScope implements ICPPFunctionScope {
} }
IBinding[] additional = super.find(name); IBinding[] additional = super.find(name);
for (int i = 0; i < additional.length; i++) { for (IBinding element : additional) {
bindings.add(additional[i]); bindings.add(element);
} }
return bindings.toArray(new IBinding[bindings.size()]); return bindings.toArray(new IBinding[bindings.size()]);
@ -125,8 +125,8 @@ public class CPPFunctionScope extends CPPScope implements ICPPFunctionScope {
@Override @Override
public IName getScopeName() { public IName getScopeName() {
IASTNode node = getPhysicalNode(); IASTNode node = getPhysicalNode();
if (node instanceof ICPPASTFunctionDeclarator) { if (node instanceof IASTDeclarator) {
return ((ICPPASTFunctionDeclarator)node).getName(); return ((IASTDeclarator)node).getName();
} }
return null; return null;
} }

View file

@ -11,6 +11,9 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
@ -113,29 +116,45 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
public void addDefinition(IASTNode node) { public void addDefinition(IASTNode node) {
if (!(node instanceof IASTName)) if (!(node instanceof IASTName))
return; return;
ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(node); IASTDeclarator fdecl= getDeclaratorByName(node);
if (fdecl == null) if (fdecl instanceof ICPPASTFunctionDeclarator) {
return; updateFunctionParameterBindings((ICPPASTFunctionDeclarator) fdecl);
super.addDefinition(node);
updateFunctionParameterBindings(fdecl); }
super.addDefinition(node);
} }
@Override @Override
public void addDeclaration(IASTNode node) { public void addDeclaration(IASTNode node) {
if (!(node instanceof IASTName)) if (!(node instanceof IASTName))
return; return;
ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(node); IASTDeclarator fdecl= getDeclaratorByName(node);
if (fdecl == null) if (fdecl == null)
return; return;
updateFunctionParameterBindings(fdecl); if (fdecl instanceof ICPPASTFunctionDeclarator)
updateFunctionParameterBindings((ICPPASTFunctionDeclarator) fdecl);
super.addDeclaration(node); super.addDeclaration(node);
} }
private ICPPASTFunctionDeclarator getFirstFunctionDtor() {
IASTDeclarator dtor= getDeclaratorByName(getDefinition());
if (dtor instanceof ICPPASTFunctionDeclarator)
return (ICPPASTFunctionDeclarator) dtor;
IASTNode[] decls = getDeclarations();
if (decls != null) {
for (IASTNode decl : decls) {
dtor= getDeclaratorByName(decl);
if (dtor instanceof ICPPASTFunctionDeclarator)
return (ICPPASTFunctionDeclarator) dtor;
}
}
return null;
}
public IParameter[] getParameters() { public IParameter[] getParameters() {
IASTName name = getTemplateName(); ICPPASTFunctionDeclarator fdecl= getFirstFunctionDtor();
ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(name);
if (fdecl != null) { if (fdecl != null) {
IASTParameterDeclaration[] params = fdecl.getParameters(); IASTParameterDeclaration[] params = fdecl.getParameters();
int size = params.length; int size = params.length;
@ -155,7 +174,7 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
} }
return result; return result;
} }
return null; return CPPBuiltinParameter.createParameterList(getType());
} }
public IScope getFunctionScope() { public IScope getFunctionScope() {
@ -169,7 +188,7 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
while(parent.getParent() instanceof IASTDeclarator) while(parent.getParent() instanceof IASTDeclarator)
parent = parent.getParent(); parent = parent.getParent();
IType temp = CPPVisitor.createType((IASTDeclarator)parent); IType temp = getNestedType(CPPVisitor.createType((IASTDeclarator)parent), TDEF);
if (temp instanceof ICPPFunctionType) if (temp instanceof ICPPFunctionType)
type = (ICPPFunctionType) temp; type = (ICPPFunctionType) temp;
} }
@ -210,7 +229,7 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
final IASTNode[] decls= getDeclarations(); final IASTNode[] decls= getDeclarations();
int tdeclLen= decls == null ? 0 : decls.length; int tdeclLen= decls == null ? 0 : decls.length;
for (int i= -1; i < tdeclLen; i++) { for (int i= -1; i < tdeclLen; i++) {
ICPPASTFunctionDeclarator tdecl; IASTDeclarator tdecl;
if (i == -1) { if (i == -1) {
tdecl= getDeclaratorByName(getDefinition()); tdecl= getDeclaratorByName(getDefinition());
if (tdecl == null) if (tdecl == null)
@ -223,10 +242,12 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
break; break;
} }
IASTParameterDeclaration[] params = tdecl.getParameters(); if (tdecl instanceof ICPPASTFunctionDeclarator) {
if (pos < params.length) { IASTParameterDeclaration[] params = ((ICPPASTFunctionDeclarator) tdecl).getParameters();
final IASTName oName = getParamName(params[pos]); if (pos < params.length) {
return oName.resolvePreBinding(); final IASTName oName = getParamName(params[pos]);
return oName.resolvePreBinding();
}
} }
} }
return param; return param;
@ -239,7 +260,7 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
final IASTNode[] decls= getDeclarations(); final IASTNode[] decls= getDeclarations();
int tdeclLen= decls == null ? 0 : decls.length; int tdeclLen= decls == null ? 0 : decls.length;
for (int i= -1; i < tdeclLen && k < updateParams.length; i++) { for (int i= -1; i < tdeclLen && k < updateParams.length; i++) {
ICPPASTFunctionDeclarator tdecl; IASTDeclarator tdecl;
if (i == -1) { if (i == -1) {
tdecl= getDeclaratorByName(getDefinition()); tdecl= getDeclaratorByName(getDefinition());
if (tdecl == null) if (tdecl == null)
@ -252,14 +273,16 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
break; break;
} }
IASTParameterDeclaration[] params = tdecl.getParameters(); if (tdecl instanceof ICPPASTFunctionDeclarator) {
int end= Math.min(params.length, updateParams.length); IASTParameterDeclaration[] params = ((ICPPASTFunctionDeclarator) tdecl).getParameters();
for (; k < end; k++) { int end= Math.min(params.length, updateParams.length);
final IASTName oName = getParamName(params[k]); for (; k < end; k++) {
IBinding b= oName.resolvePreBinding(); final IASTName oName = getParamName(params[k]);
IASTName n = getParamName(updateParams[k]); IBinding b= oName.resolvePreBinding();
n.setBinding(b); IASTName n = getParamName(updateParams[k]);
ASTInternal.addDeclaration(b, n); n.setBinding(b);
ASTInternal.addDeclaration(b, n);
}
} }
} }
} }
@ -332,28 +355,19 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
} }
public boolean takesVarArgs() { public boolean takesVarArgs() {
ICPPASTFunctionDeclarator fdecl= getDeclaratorByName(getDefinition()); ICPPASTFunctionDeclarator fdecl= getFirstFunctionDtor();
if (fdecl == null) {
IASTName[] ns = (IASTName[]) getDeclarations();
if (ns != null && ns.length > 0) {
for (int i = 0; i < ns.length && fdecl == null; i++) {
IASTName name = ns[i];
fdecl= getDeclaratorByName(name);
}
}
}
if (fdecl != null) { if (fdecl != null) {
return fdecl.takesVarArgs(); return fdecl.takesVarArgs();
} }
return false; return false;
} }
private ICPPASTFunctionDeclarator getDeclaratorByName(IASTNode node) { private IASTDeclarator getDeclaratorByName(IASTNode node) {
// skip qualified names and nested declarators. // skip qualified names and nested declarators.
while (node != null) { while (node != null) {
node= node.getParent(); node= node.getParent();
if (node instanceof ICPPASTFunctionDeclarator) { if (node instanceof IASTDeclarator) {
return ((ICPPASTFunctionDeclarator) node); return ASTQueries.findTypeRelevantDeclarator((IASTDeclarator) node);
} }
} }
return null; return null;
@ -373,7 +387,7 @@ public class CPPFunctionTemplate extends CPPTemplateDefinition
} }
public IType[] getExceptionSpecification() throws DOMException { public IType[] getExceptionSpecification() throws DOMException {
ICPPASTFunctionDeclarator declarator = getDeclaratorByName(getDefinition()); ICPPASTFunctionDeclarator declarator = getFirstFunctionDtor();
if (declarator != null) { if (declarator != null) {
IASTTypeId[] astTypeIds = declarator.getExceptionSpecification(); IASTTypeId[] astTypeIds = declarator.getExceptionSpecification();
if (astTypeIds.equals(ICPPASTFunctionDeclarator.NO_EXCEPTION_SPECIFICATION)) { if (astTypeIds.equals(ICPPASTFunctionDeclarator.NO_EXCEPTION_SPECIFICATION)) {

View file

@ -86,7 +86,7 @@ public class CPPImplicitMethod extends CPPImplicitFunction implements ICPPMethod
public IASTDeclaration getPrimaryDeclaration() throws DOMException { public IASTDeclaration getPrimaryDeclaration() throws DOMException {
// first check if we already know it // first check if we already know it
if (declarations != null) { if (declarations != null) {
for (ICPPASTFunctionDeclarator dtor : declarations) { for (IASTDeclarator dtor : declarations) {
if (dtor == null) if (dtor == null)
break; break;

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others. * Copyright (c) 2004, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -32,71 +32,65 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
/** /**
* The binding for a method. * The binding for a method.
*/ */
public class CPPMethod extends CPPFunction implements ICPPMethod { public class CPPMethod extends CPPFunction implements ICPPMethod {
public static class CPPMethodProblem extends CPPFunctionProblem implements ICPPMethod { public static class CPPMethodProblem extends CPPFunctionProblem implements ICPPMethod {
/** public CPPMethodProblem(IASTNode node, int id, char[] arg) {
* @param id super(node, id, arg);
* @param arg }
*/
public CPPMethodProblem( IASTNode node, int id, char[] arg ) {
super( node, id, arg );
}
public int getVisibility() throws DOMException { public int getVisibility() throws DOMException {
throw new DOMException( this ); throw new DOMException(this);
} }
public ICPPClassType getClassOwner() throws DOMException { public ICPPClassType getClassOwner() throws DOMException {
throw new DOMException( this ); throw new DOMException(this);
} }
@Override public boolean isVirtual() throws DOMException {
public boolean isStatic() throws DOMException { throw new DOMException(this);
throw new DOMException( this ); }
} public boolean isPureVirtual() throws DOMException {
public boolean isVirtual() throws DOMException { throw new DOMException(this);
throw new DOMException( this ); }
}
public boolean isPureVirtual() throws DOMException {
throw new DOMException( this );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod#isDestructor()
*/
public boolean isDestructor() { public boolean isDestructor() {
char[] name = getNameCharArray(); char[] name = getNameCharArray();
if (name.length > 1 && name[0] == '~') if (name.length > 1 && name[0] == '~')
return true; return true;
return false; return false;
} }
public boolean isImplicit() { public boolean isImplicit() {
return false; return false;
} }
} }
public CPPMethod( ICPPASTFunctionDeclarator declarator ){ public CPPMethod(IASTDeclarator declarator) {
super( declarator ); super(declarator);
} }
public IASTDeclaration getPrimaryDeclaration() throws DOMException{ public IASTDeclaration getPrimaryDeclaration() throws DOMException{
//first check if we already know it //first check if we already know it
if( declarations != null ){ if (declarations != null) {
for (IASTDeclarator dtor : declarations) { for (IASTDeclarator dtor : declarations) {
if (dtor == null) { if (dtor == null) {
break; break;
} }
dtor= CPPVisitor.findOutermostDeclarator(dtor); dtor = ASTQueries.findOutermostDeclarator(dtor);
IASTDeclaration decl = (IASTDeclaration) dtor.getParent(); IASTDeclaration decl = (IASTDeclaration) dtor.getParent();
if( decl.getParent() instanceof ICPPASTCompositeTypeSpecifier ) if (decl.getParent() instanceof ICPPASTCompositeTypeSpecifier)
return decl; return decl;
} }
} }
if (definition != null) {
IASTDeclarator dtor = ASTQueries.findOutermostDeclarator(definition);
IASTDeclaration decl = (IASTDeclaration) dtor.getParent();
if (decl.getParent() instanceof ICPPASTCompositeTypeSpecifier)
return decl;
}
final char[] myName = getASTName().getLookupKey(); final char[] myName = getASTName().getLookupKey();
ICPPClassScope scope = (ICPPClassScope) getScope(); ICPPClassScope scope = (ICPPClassScope) getScope();
@ -107,14 +101,14 @@ public class CPPMethod extends CPPFunction implements ICPPMethod {
if (member instanceof IASTSimpleDeclaration) { if (member instanceof IASTSimpleDeclaration) {
IASTDeclarator[] dtors = ((IASTSimpleDeclaration) member).getDeclarators(); IASTDeclarator[] dtors = ((IASTSimpleDeclaration) member).getDeclarators();
for (IASTDeclarator dtor : dtors) { for (IASTDeclarator dtor : dtors) {
IASTName name = CPPVisitor.findInnermostDeclarator(dtor).getName(); IASTName name = ASTQueries.findInnermostDeclarator(dtor).getName();
if (CharArrayUtils.equals(name.getLookupKey(), myName) && name.resolveBinding() == this) { if (CharArrayUtils.equals(name.getLookupKey(), myName) && name.resolveBinding() == this) {
return member; return member;
} }
} }
} else if (member instanceof IASTFunctionDefinition) { } else if (member instanceof IASTFunctionDefinition) {
final IASTFunctionDeclarator declarator = ((IASTFunctionDefinition) member).getDeclarator(); final IASTFunctionDeclarator declarator = ((IASTFunctionDefinition) member).getDeclarator();
IASTName name = CPPVisitor.findInnermostDeclarator(declarator).getName(); IASTName name = ASTQueries.findInnermostDeclarator(declarator).getName();
if (CharArrayUtils.equals(name.getLookupKey(), myName) && name.resolveBinding() == this) { if (CharArrayUtils.equals(name.getLookupKey(), myName) && name.resolveBinding() == this) {
return member; return member;
} }
@ -163,7 +157,7 @@ public class CPPMethod extends CPPFunction implements ICPPMethod {
@Override @Override
protected IASTName getASTName() { protected IASTName getASTName() {
IASTDeclarator dtor= (declarations != null && declarations.length > 0) ? declarations[0] : definition; IASTDeclarator dtor= (declarations != null && declarations.length > 0) ? declarations[0] : definition;
dtor= CPPVisitor.findInnermostDeclarator(dtor); dtor= ASTQueries.findInnermostDeclarator(dtor);
IASTName name= dtor.getName(); IASTName name= dtor.getName();
if (name instanceof ICPPASTQualifiedName) { if (name instanceof ICPPASTQualifiedName) {
IASTName[] ns = ((ICPPASTQualifiedName)name).getNames(); IASTName[] ns = ((ICPPASTQualifiedName)name).getNames();
@ -247,10 +241,10 @@ public class CPPMethod extends CPPFunction implements ICPPMethod {
if (dtor == null) if (dtor == null)
break; break;
dtor = CPPVisitor.findOutermostDeclarator(dtor); dtor = ASTQueries.findOutermostDeclarator(dtor);
IASTDeclaration decl = (IASTDeclaration) dtor.getParent(); IASTDeclaration decl = (IASTDeclaration) dtor.getParent();
if (decl.getParent() instanceof ICPPASTCompositeTypeSpecifier) { if (decl.getParent() instanceof ICPPASTCompositeTypeSpecifier) {
dtor= CPPVisitor.findTypeRelevantDeclarator(dtor); dtor= ASTQueries.findTypeRelevantDeclarator(dtor);
if (dtor instanceof ICPPASTFunctionDeclarator) { if (dtor instanceof ICPPASTFunctionDeclarator) {
return ((ICPPASTFunctionDeclarator) dtor).isPureVirtual(); return ((ICPPASTFunctionDeclarator) dtor).isPureVirtual();
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2005, 2008 IBM Corporation and others. * Copyright (c) 2005, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -53,6 +53,15 @@ public class CPPMethodTemplate extends CPPFunctionTemplate implements ICPPMethod
return decl; return decl;
} }
} }
if (definition != null) {
IASTNode parent = definition.getParent();
while (!(parent instanceof IASTDeclaration) && parent != null)
parent = parent.getParent();
IASTDeclaration decl = (IASTDeclaration) parent;
if (decl != null && decl.getParent() instanceof ICPPASTCompositeTypeSpecifier)
return decl;
}
final char[] myName = getTemplateName().getLookupKey(); final char[] myName = getTemplateName().getLookupKey();
IScope scope = getScope(); IScope scope = getScope();

View file

@ -153,7 +153,6 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousDeclarator; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousDeclarator;
import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope; import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.GCCBuiltinSymbolProvider.CPPBuiltinParameter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFieldReference; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFieldReference;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTLiteralExpression; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTLiteralExpression;
@ -163,6 +162,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTypeIdExpression; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTypeIdExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTUnaryExpression; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTUnaryExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBuiltinParameter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPCompositeBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPCompositeBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitFunction; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitFunction;

View file

@ -13,6 +13,7 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateType; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateTypeUptoPointers; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateTypeUptoPointers;
@ -509,11 +510,7 @@ public class CPPVisitor extends ASTQueries {
IASTNode parent = findOutermostDeclarator(declarator).getParent(); IASTNode parent = findOutermostDeclarator(declarator).getParent();
declarator= findInnermostDeclarator(declarator); declarator= findInnermostDeclarator(declarator);
IASTFunctionDeclarator funcDeclarator= null;
final IASTDeclarator typeRelevantDtor= findTypeRelevantDeclarator(declarator); final IASTDeclarator typeRelevantDtor= findTypeRelevantDeclarator(declarator);
if (typeRelevantDtor instanceof IASTFunctionDeclarator) {
funcDeclarator= (IASTFunctionDeclarator) typeRelevantDtor;
}
IASTName name= declarator.getName(); IASTName name= declarator.getName();
if (name instanceof ICPPASTQualifiedName) { if (name instanceof ICPPASTQualifiedName) {
@ -606,29 +603,65 @@ public class CPPVisitor extends ASTQueries {
return e.getProblem(); return e.getProblem();
} }
IASTSimpleDeclaration simpleDecl = (parent instanceof IASTSimpleDeclaration) ? boolean isFunction= false;
(IASTSimpleDeclaration) parent : null; if (parent instanceof ICPPASTFunctionDefinition) {
if (simpleDecl != null && isFunction= true;
simpleDecl.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef) { } else if (parent instanceof IASTSimpleDeclaration) {
if (binding instanceof ICPPInternalBinding && binding instanceof ITypedef && name.isActive()) { IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration) parent;
IType t1 = ((ITypedef) binding).getType(); if (simpleDecl.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef) {
IType t2 = createType(declarator); // typedef declaration
if (t1 != null && t2 != null && t1.isSameType(t2)) { if (binding instanceof ICPPInternalBinding && binding instanceof ITypedef && name.isActive()) {
ASTInternal.addDeclaration(binding, name); IType t1 = ((ITypedef) binding).getType();
return binding; IType t2 = createType(declarator);
} if (t1 != null && t2 != null && t1.isSameType(t2)) {
return new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_REDECLARATION); ASTInternal.addDeclaration(binding, name);
} return binding;
// if we don't resolve the target type first, we get a problem binding in case the typedef }
// redeclares the target type, otherwise it is safer to defer the resolution of the target type. return new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_REDECLARATION);
IType targetType= createType(declarator); }
CPPTypedef td= new CPPTypedef(name); // if we don't resolve the target type first, we get a problem binding in case the typedef
td.setType(targetType); // redeclares the target type, otherwise it is safer to defer the resolution of the target type.
binding = td; IType targetType= createType(declarator);
} else if (funcDeclarator != null) { CPPTypedef td= new CPPTypedef(name);
td.setType(targetType);
binding = td;
} else if (typeRelevantDtor instanceof IASTFunctionDeclarator) {
// function declaration
isFunction= true;
} else {
// looks like a variable declaration
IType t1 = createType(declarator);
if (SemanticUtil.getNestedType(t1, TDEF) instanceof IFunctionType) {
// function declaration with typedef
isFunction= true;
} else {
// variable declaration
IType t2= null;
if (binding != null && binding instanceof IVariable && !(binding instanceof IIndexBinding)) {
try {
t2 = ((IVariable) binding).getType();
} catch (DOMException e1) {
}
}
if (t1 != null && t2 != null) {
if (t1.isSameType(t2) || isCompatibleArray(t1, t2) != null) {
ASTInternal.addDeclaration(binding, name);
} else {
binding = new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_REDECLARATION);
}
} else if (simpleDecl.getParent() instanceof ICPPASTCompositeTypeSpecifier) {
binding = new CPPField(name);
} else {
binding = new CPPVariable(name);
}
}
}
}
if (isFunction) {
if (binding instanceof ICPPInternalBinding && binding instanceof IFunction && name.isActive()) { if (binding instanceof ICPPInternalBinding && binding instanceof IFunction && name.isActive()) {
IFunction function = (IFunction) binding; IFunction function = (IFunction) binding;
if (CPPSemantics.isSameFunction(function, funcDeclarator)) { if (CPPSemantics.isSameFunction(function, typeRelevantDtor)) {
binding= CPPSemantics.checkDeclSpecifier(binding, name, parent); binding= CPPSemantics.checkDeclSpecifier(binding, name, parent);
if (binding instanceof IProblemBinding) if (binding instanceof IProblemBinding)
return binding; return binding;
@ -652,40 +685,20 @@ public class CPPVisitor extends ASTQueries {
} }
if (scope instanceof ICPPClassScope) { if (scope instanceof ICPPClassScope) {
if (isConstructor(scope, funcDeclarator)) { if (isConstructor(scope, typeRelevantDtor)) {
binding = template ? (ICPPConstructor) new CPPConstructorTemplate(name) binding = template ? (ICPPConstructor) new CPPConstructorTemplate(name)
: new CPPConstructor((ICPPASTFunctionDeclarator) funcDeclarator); : new CPPConstructor((ICPPASTFunctionDeclarator) typeRelevantDtor);
} else { } else {
binding = template ? (ICPPMethod) new CPPMethodTemplate(name) binding = template ? (ICPPMethod) new CPPMethodTemplate(name)
: new CPPMethod((ICPPASTFunctionDeclarator) funcDeclarator); : new CPPMethod(typeRelevantDtor);
} }
} else { } else {
binding = template ? (ICPPFunction) new CPPFunctionTemplate(name) binding = template ? (ICPPFunction) new CPPFunctionTemplate(name)
: new CPPFunction((ICPPASTFunctionDeclarator) funcDeclarator); : new CPPFunction(typeRelevantDtor);
} }
binding= CPPSemantics.checkDeclSpecifier(binding, name, parent); binding= CPPSemantics.checkDeclSpecifier(binding, name, parent);
} else if (simpleDecl != null) { }
IType t1 = null, t2 = null;
if (binding != null && binding instanceof IVariable && !(binding instanceof IIndexBinding)) {
t1 = createType(declarator);
try {
t2 = ((IVariable) binding).getType();
} catch (DOMException e1) {
}
}
if (t1 != null && t2 != null) {
if (t1.isSameType(t2) || isCompatibleArray(t1, t2) != null) {
ASTInternal.addDeclaration(binding, name);
} else {
binding = new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_REDECLARATION);
}
} else if (simpleDecl.getParent() instanceof ICPPASTCompositeTypeSpecifier) {
binding = new CPPField(name);
} else {
binding = new CPPVariable(name);
}
}
return binding; return binding;
} }
@ -712,8 +725,8 @@ public class CPPVisitor extends ASTQueries {
} }
public static boolean isConstructor(IASTName parentName, IASTDeclarator declarator) { public static boolean isConstructor(IASTName parentName, IASTDeclarator declarator) {
if (declarator == null || !(declarator instanceof IASTFunctionDeclarator)) if (declarator == null || !(declarator instanceof IASTFunctionDeclarator))
return false; return false;
IASTName name = findInnermostDeclarator(declarator).getName(); IASTName name = findInnermostDeclarator(declarator).getName();
if (!CharArrayUtils.equals(name.getLookupKey(), parentName.getLookupKey())) if (!CharArrayUtils.equals(name.getLookupKey(), parentName.getLookupKey()))

View file

@ -557,6 +557,8 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
} }
} catch (Exception e) { } catch (Exception e) {
swallowError(path, e); swallowError(path, e);
} catch (Error e) {
swallowError(path, e);
} }
} }
fFilesUpFront.clear(); fFilesUpFront.clear();
@ -701,12 +703,8 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
th= e; th= e;
} catch (StackOverflowError e) { } catch (StackOverflowError e) {
th= e; th= e;
} catch (Error e) { } catch (AssertionError e) {
try { th= e;
swallowError(path, e);
} catch (Throwable ignore) {
}
throw e;
} }
if (th != null) { if (th != null) {
swallowError(path, th); swallowError(path, th);
@ -807,23 +805,25 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
*/ */
if (e instanceof CoreException) { if (e instanceof CoreException) {
s=((CoreException)e).getStatus(); s=((CoreException)e).getStatus();
if (s != null && s.getCode() == CCorePlugin.STATUS_PDOM_TOO_LARGE) { if (s.getCode() == CCorePlugin.STATUS_PDOM_TOO_LARGE) {
if (CCorePlugin.PLUGIN_ID.equals(s.getPlugin())) if (CCorePlugin.PLUGIN_ID.equals(s.getPlugin()))
throw (CoreException) e; throw (CoreException) e;
} }
}
if (e instanceof CoreException) { // mask errors in order to avoid dialog from platform
s= ((CoreException) e).getStatus();
Throwable exception = s.getException(); Throwable exception = s.getException();
if (exception instanceof OutOfMemoryError || exception instanceof StackOverflowError) { if (exception != null) {
// mask errors in order to avoid dialog from platform Throwable masked= getMaskedException(exception);
e= new InvocationTargetException(exception); if (masked != exception) {
exception= null; e= exception;
} exception= null;
}
}
if (exception == null) { if (exception == null) {
s= new Status(s.getSeverity(), s.getPlugin(), s.getCode(), s.getMessage(), e); s= new Status(s.getSeverity(), s.getPlugin(), s.getCode(), s.getMessage(), e);
} }
} else { } else {
e= getMaskedException(e);
s= createStatus(getMessage(MessageKind.errorWhileParsing, file), e); s= createStatus(getMessage(MessageKind.errorWhileParsing, file), e);
} }
logError(s); logError(s);
@ -832,9 +832,13 @@ public abstract class AbstractIndexerTask extends PDOMWriter {
} }
} }
/** private Throwable getMaskedException(Throwable e) {
* @param s if (e instanceof OutOfMemoryError || e instanceof StackOverflowError || e instanceof AssertionError) {
*/ return new InvocationTargetException(e);
}
return e;
}
protected void logError(IStatus s) { protected void logError(IStatus s) {
CCorePlugin.log(s); CCorePlugin.log(s);
} }

View file

@ -212,6 +212,8 @@ abstract public class PDOMWriter {
th= e; th= e;
} catch (StackOverflowError e) { } catch (StackOverflowError e) {
th= e; th= e;
} catch (AssertionError e) {
th= e;
} finally { } finally {
index.releaseWriteLock(readlockCount, flushIndex); index.releaseWriteLock(readlockCount, flushIndex);
} }

View file

@ -101,7 +101,11 @@ class PDOMCFunction extends PDOMBinding implements IFunction {
} }
IFunctionType oldType= getType(); IFunctionType oldType= getType();
setType(linkage, newType); if (oldType != null && oldType.isSameType(newType)) {
oldType= null;
} else {
setType(linkage, newType);
}
PDOMCParameter oldParams= getFirstParameter(); PDOMCParameter oldParams= getFirstParameter();
setParameters(newParams); setParameters(newParams);
if (oldType != null) { if (oldType != null) {

View file

@ -122,11 +122,15 @@ class PDOMCPPFunction extends PDOMCPPBinding implements ICPPFunction, IPDOMOverl
IFunctionType oldType= getType(); IFunctionType oldType= getType();
PDOMCPPParameter oldParams= getFirstParameter(); PDOMCPPParameter oldParams= getFirstParameter();
PDOMCPPFunctionType pft= setType(newType); if (oldType instanceof PDOMCPPFunctionType && oldType.isSameType(newType)) {
setParameters(pft, newParams); setParameters((PDOMCPPFunctionType) oldType, newParams);
if (oldType != null) { } else {
linkage.deleteType(oldType, record); PDOMCPPFunctionType pft= setType(newType);
} setParameters(pft, newParams);
if (oldType != null) {
linkage.deleteType(oldType, record);
}
}
if (oldParams != null) { if (oldParams != null) {
oldParams.delete(linkage); oldParams.delete(linkage);
} }

View file

@ -67,11 +67,11 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.ui.CUIPlugin; import org.eclipse.cdt.ui.CUIPlugin;
import org.eclipse.cdt.ui.text.ICPartitions; import org.eclipse.cdt.ui.text.ICPartitions;
import org.eclipse.cdt.internal.core.dom.parser.GCCBuiltinSymbolProvider.CBuiltinParameter; import org.eclipse.cdt.internal.core.dom.parser.c.CBuiltinParameter;
import org.eclipse.cdt.internal.core.dom.parser.GCCBuiltinSymbolProvider.CPPBuiltinParameter;
import org.eclipse.cdt.internal.core.dom.parser.c.CBuiltinVariable; import org.eclipse.cdt.internal.core.dom.parser.c.CBuiltinVariable;
import org.eclipse.cdt.internal.core.dom.parser.c.CImplicitFunction; import org.eclipse.cdt.internal.core.dom.parser.c.CImplicitFunction;
import org.eclipse.cdt.internal.core.dom.parser.c.CImplicitTypedef; import org.eclipse.cdt.internal.core.dom.parser.c.CImplicitTypedef;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBuiltinParameter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBuiltinVariable; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBuiltinVariable;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitFunction; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitMethod; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitMethod;