diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java index 28b9114e33c..a7ec8c4fddd 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexBugsTests.java @@ -29,6 +29,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.IEnumeration; +import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; @@ -468,4 +469,23 @@ public class IndexBugsTests extends BaseTestCase { fIndex.releaseReadLock(); } } + + // enum {e20070206}; + public void test156671() throws Exception { + waitForIndexer(); + String content= getContentsForTest(1)[0].toString(); + + IFile file= TestSourceReader.createFile(fCProject.getProject(), "test156671.cpp", content); + TestSourceReader.waitUntilFileIsIndexed(fIndex, file, INDEX_WAIT_TIME); + + fIndex.acquireReadLock(); + try { + IBinding[] bindings= fIndex.findBindings("e20070206".toCharArray(), IndexFilter.getFilter(ILinkage.CPP_LINKAGE_ID), NPM); + assertEquals(1, bindings.length); + assertTrue(bindings[0] instanceof IEnumerator); + } + finally { + fIndex.releaseReadLock(); + } + } } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ext/CElementHandle.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ext/CElementHandle.java index bd127b9382d..81976d17ca5 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ext/CElementHandle.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/ext/CElementHandle.java @@ -52,7 +52,14 @@ abstract class CElementHandle implements ICElementHandle, ISourceReference { public CElementHandle(ICElement parent, int type, String name) { fParent= parent; fType= type; - fName= name; + // anonymous types are assigned a name in the index, we + // undo this here + if (name.length() > 0 && name.charAt(0)=='{') { + fName= ""; //$NON-NLS-1$ + } + else { + fName= name; + } } public boolean equals(Object obj) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java index 37bb269c24c..e38e72410a4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTTranslationUnit.java @@ -13,7 +13,6 @@ package org.eclipse.cdt.core.dom.ast; import org.eclipse.cdt.core.dom.IName; import org.eclipse.cdt.core.index.IIndex; -import org.eclipse.cdt.core.model.ILanguage; import org.eclipse.cdt.core.parser.ParserLanguage; /** diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java index f3f23f6922f..8ea9c3a42b5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/index/IIndex.java @@ -241,7 +241,7 @@ public interface IIndex { * * This is fully equivalent to *
-	 * findBindings(new Pattern[]{pattern}, isFullyQualified, filter, monitor);
+	 * findBindings(new char[][]{name}, filter, monitor);
 	 * 
* @param names an array of names, which has to be matched by the qualified name of the bindings. * @param filter a filter that allows for skipping parts of the index @@ -249,7 +249,7 @@ public interface IIndex { * @return an array of bindings matching the pattern * @throws CoreException */ - public IIndexBinding[] findBindings(char[] names, IndexFilter filter, IProgressMonitor monitor) throws CoreException; + public IIndexBinding[] findBindings(char[] name, IndexFilter filter, IProgressMonitor monitor) throws CoreException; /** * Searches the given namespace for all bindings of a given name. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CEnumeration.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CEnumeration.java index bff0f339ae6..3591a48bc25 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CEnumeration.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CEnumeration.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2006 IBM Corporation and others. + * Copyright (c) 2004, 2007 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -37,7 +37,7 @@ import org.eclipse.core.runtime.PlatformObject; /** * @author aniefer */ -public class CEnumeration extends PlatformObject implements IEnumeration { +public class CEnumeration extends PlatformObject implements IEnumeration, ICInternalBinding { private IASTName [] declarations = null; private IASTName definition = null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitMethod.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitMethod.java index 99205a17daa..a4e745677fe 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitMethod.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPImplicitMethod.java @@ -115,22 +115,28 @@ public class CPPImplicitMethod extends CPPImplicitFunction implements ICPPMethod if( dtor instanceof ICPPASTFunctionDeclarator && CharArrayUtils.equals( name.toCharArray(), getNameCharArray() ) ) { - IFunctionType t = (IFunctionType) CPPVisitor.createType( dtor ); - IType [] ps = t.getParameterTypes(); + IType t0= CPPVisitor.createType( dtor ); boolean ok= false; - if( ps.length == params.length ){ - int idx = 0; - for( ; idx < ps.length && ps[idx] != null; idx++ ){ - if( !ps[idx].isSameType(params[idx]) ) - break; + if (t0 instanceof IFunctionType) { + IFunctionType t = (IFunctionType) t0; + IType [] ps = t.getParameterTypes(); + if( ps.length == params.length ){ + int idx = 0; + for( ; idx < ps.length && ps[idx] != null; idx++ ){ + if( !ps[idx].isSameType(params[idx]) ) + break; + } + ok= idx == ps.length; + } + else if (ps.length == 0) { + if (params.length == 1) { + IType t1= params[0]; + ok = (t1 instanceof IBasicType) && ((IBasicType) t1).getType() == IBasicType.t_void; + } } - ok= idx == ps.length; } - else if (ps.length == 0) { - if (params.length == 1) { - IType t1= params[0]; - ok = (t1 instanceof IBasicType) && ((IBasicType) t1).getType() == IBasicType.t_void; - } + else { + ok= false; } if (ok) { name.setBinding( this ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java index b97d067ccfd..0d88a35db76 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOMManager.java @@ -685,8 +685,8 @@ public class PDOMManager implements IPDOMManager, IWritableIndexManager, IListen monitor.beginTask(Messages.PDOMManager_JoinIndexerTask, 1000); long limit= System.currentTimeMillis()+waitMaxMillis; try { + int currentTicks= 0; while (true) { - int currentTicks= 0; if (monitor.isCanceled()) { return false; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java new file mode 100644 index 00000000000..56f3b9b92cd --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java @@ -0,0 +1,443 @@ +/******************************************************************************* + * Copyright (c) 2007 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.pdom.dom; + +import org.eclipse.cdt.core.dom.ILinkage; +import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; +import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTFileLocation; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.ICompositeType; +import org.eclipse.cdt.core.dom.ast.IEnumeration; +import org.eclipse.cdt.core.dom.ast.IEnumerator; +import org.eclipse.cdt.core.dom.ast.IField; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.internal.core.dom.parser.c.ICInternalBinding; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding; +import org.eclipse.core.runtime.CoreException; + +public class PDOMASTAdapter { + private static class AnonymousASTName implements IASTName { + private IASTName fDelegate; + private IASTFileLocation fLocation; + + public AnonymousASTName(IASTName name, final IASTFileLocation loc) { + fDelegate= name; + fLocation= new IASTFileLocation() { + public int getEndingLineNumber() { + return loc.getStartingLineNumber(); + } + public String getFileName() { + return loc.getFileName(); + } + + public int getStartingLineNumber() { + return loc.getStartingLineNumber(); + } + + public IASTFileLocation asFileLocation() { + return loc.asFileLocation(); + } + + public int getNodeLength() { + return 0; + } + + public int getNodeOffset() { + return loc.getNodeOffset(); + } + }; + } + + public boolean accept(ASTVisitor visitor) { + return fDelegate.accept(visitor); + } + + public boolean contains(IASTNode node) { + return fDelegate.contains(node); + } + + public IBinding getBinding() { + return fDelegate.getBinding(); + } + + public String getContainingFilename() { + return fDelegate.getContainingFilename(); + } + + public IASTFileLocation getFileLocation() { + return fLocation; + } + + public ILinkage getLinkage() { + return fDelegate.getLinkage(); + } + + public IASTNodeLocation[] getNodeLocations() { + return fDelegate.getNodeLocations(); + } + + public IASTNode getParent() { + return fDelegate.getParent(); + } + + public ASTNodeProperty getPropertyInParent() { + return fDelegate.getPropertyInParent(); + } + + public String getRawSignature() { + return fDelegate.getRawSignature(); + } + + public IASTTranslationUnit getTranslationUnit() { + return fDelegate.getTranslationUnit(); + } + + public boolean isDeclaration() { + return fDelegate.isDeclaration(); + } + + public boolean isDefinition() { + return fDelegate.isDefinition(); + } + + public boolean isReference() { + return fDelegate.isReference(); + } + + public IBinding resolveBinding() { + return fDelegate.resolveBinding(); + } + + public IBinding[] resolvePrefix() { + return fDelegate.resolvePrefix(); + } + + public void setBinding(IBinding binding) { + fDelegate.setBinding(binding); + } + + public void setParent(IASTNode node) { + fDelegate.setParent(node); + } + + public void setPropertyInParent(ASTNodeProperty property) { + fDelegate.setPropertyInParent(property); + } + + public char[] toCharArray() { + return fDelegate.toCharArray(); + } + } + + private static class AnonymousEnumeration implements IEnumeration { + private IEnumeration fDelegate; + private char[] fName; + + public AnonymousEnumeration(char[] name, IEnumeration delegate) { + fName= name; + fDelegate= delegate; + } + + public Object clone() { + throw new PDOMNotImplementedError(); + } + + public Object getAdapter(Class adapter) { + return fDelegate.getAdapter(adapter); + } + + public IEnumerator[] getEnumerators() throws DOMException { + return fDelegate.getEnumerators(); + } + + public ILinkage getLinkage() throws CoreException { + return fDelegate.getLinkage(); + } + + public String getName() { + return new String(fName); + } + + public char[] getNameCharArray() { + return fName; + } + + public IScope getScope() throws DOMException { + return fDelegate.getScope(); + } + + public boolean isSameType(IType type) { + return fDelegate.isSameType(type); + } + } + + private static class AnonymousCompositeType implements ICompositeType { + protected ICompositeType fDelegate; + private char[] fName; + + public AnonymousCompositeType(char[] name, ICompositeType delegate) { + fName= name; + fDelegate= delegate; + } + + public Object clone() { + throw new PDOMNotImplementedError(); + } + + public IField findField(String name) throws DOMException { + return fDelegate.findField(name); + } + + public Object getAdapter(Class adapter) { + return fDelegate.getAdapter(adapter); + } + + public IScope getCompositeScope() throws DOMException { + return fDelegate.getCompositeScope(); + } + + public IField[] getFields() throws DOMException { + return fDelegate.getFields(); + } + + public int getKey() throws DOMException { + return fDelegate.getKey(); + } + + public ILinkage getLinkage() throws CoreException { + return fDelegate.getLinkage(); + } + + public String getName() { + return new String(fName); + } + + public char[] getNameCharArray() { + return fName; + } + + public IScope getScope() throws DOMException { + return fDelegate.getScope(); + } + + public boolean isSameType(IType type) { + return fDelegate.isSameType(type); + } + } + + private static class AnonymousClassType implements ICPPClassType { + private ICPPClassType fDelegate; + private char[] fName; + + public AnonymousClassType(char[] name, ICPPClassType delegate) { + fName= name; + fDelegate= delegate; + } + + public Object clone() { + throw new PDOMNotImplementedError(); + } + + public String getName() { + return new String(fName); + } + + public char[] getNameCharArray() { + return fName; + } + + public IField findField(String name) throws DOMException { + return fDelegate.findField(name); + } + + public Object getAdapter(Class adapter) { + return fDelegate.getAdapter(adapter); + } + + public ICPPMethod[] getAllDeclaredMethods() throws DOMException { + return fDelegate.getAllDeclaredMethods(); + } + + public ICPPBase[] getBases() throws DOMException { + return fDelegate.getBases(); + } + + public IScope getCompositeScope() throws DOMException { + return fDelegate.getCompositeScope(); + } + + public ICPPConstructor[] getConstructors() throws DOMException { + return fDelegate.getConstructors(); + } + + public ICPPField[] getDeclaredFields() throws DOMException { + return fDelegate.getDeclaredFields(); + } + + public ICPPMethod[] getDeclaredMethods() throws DOMException { + return fDelegate.getDeclaredMethods(); + } + + public IField[] getFields() throws DOMException { + return fDelegate.getFields(); + } + + public IBinding[] getFriends() throws DOMException { + return fDelegate.getFriends(); + } + + public int getKey() throws DOMException { + return fDelegate.getKey(); + } + + public ILinkage getLinkage() throws CoreException { + return fDelegate.getLinkage(); + } + + public ICPPMethod[] getMethods() throws DOMException { + return fDelegate.getMethods(); + } + + public ICPPClassType[] getNestedClasses() throws DOMException { + return fDelegate.getNestedClasses(); + } + + public String[] getQualifiedName() throws DOMException { + return fDelegate.getQualifiedName(); + } + + public char[][] getQualifiedNameCharArray() throws DOMException { + return fDelegate.getQualifiedNameCharArray(); + } + + public IScope getScope() throws DOMException { + return fDelegate.getScope(); + } + + public boolean isGloballyQualified() throws DOMException { + return fDelegate.isGloballyQualified(); + } + + public boolean isSameType(IType type) { + return fDelegate.isSameType(type); + } + } + + + /** + * If the provided binding is anonymous, either an adapter is returned + * that computes a name for the binding, or null if that + * is not appropriate (e.g. binding is not a type). + * Otherwise, if the binding has a name it is returned unchanged. + */ + public static IBinding getAdapterIfAnonymous(IBinding binding) { + if (binding != null) { + char[] name= binding.getNameCharArray(); + if (name.length == 0) { + if (binding instanceof IEnumeration) { + name= createNameForAnonymous(binding); + if (name != null) { + return new AnonymousEnumeration(name, (IEnumeration) binding); + } + } + else if (binding instanceof ICPPClassType) { + name= createNameForAnonymous(binding); + if (name != null) { + return new AnonymousClassType(name, (ICPPClassType) binding); + } + } + else if (binding instanceof ICompositeType) { + name= createNameForAnonymous(binding); + if (name != null) { + return new AnonymousCompositeType(name, (ICompositeType) binding); + } + } + } + } + return binding; + } + + private static char[] createNameForAnonymous(IBinding binding) { + IASTNode node= null; + if (binding instanceof ICInternalBinding) { + node= ((ICInternalBinding) binding).getPhysicalNode(); + } + else if (binding instanceof ICPPInternalBinding) { + node= ((ICPPInternalBinding) binding).getDefinition(); + } + if (node != null) { + IASTFileLocation loc= node.getFileLocation(); + if (loc == null) { + node= node.getParent(); + if (node != null) { + loc= node.getFileLocation(); + } + } + if (loc != null) { + char[] fname= loc.getFileName().toCharArray(); + int fnamestart= findFileNameStart(fname); + StringBuffer buf= new StringBuffer(); + buf.append('{'); + buf.append(fname, fnamestart, fname.length-fnamestart); + buf.append(':'); + buf.append(loc.getNodeOffset()); + buf.append('}'); + return buf.toString().toCharArray(); + } + } + return null; + } + + private static int findFileNameStart(char[] fname) { + for (int i= fname.length-2; i>=0; i--) { + switch (fname[i]) { + case '/': + case '\\': + return i+1; + } + } + return 0; + } + + /** + * If the name is empty and has no file location, either an adapter + * that has a file location is returned, or null if that + * is not possible. + * Otherwise if the provided name is not empty, it is returned unchanged. + */ + public static IASTName getAdapterIfAnonymous(IASTName name) { + if (name.getFileLocation() == null) { + if (name.toCharArray().length == 0) { + IASTNode parent= name.getParent(); + if (parent != null) { + IASTFileLocation loc= parent.getFileLocation(); + if (loc != null) { + return new AnonymousASTName(name, loc); + } + } + } + } + return name; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java index fb50dac0b58..11b73604c4c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java @@ -40,6 +40,7 @@ import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.db.IBTreeComparator; import org.eclipse.cdt.internal.core.pdom.dom.FindBinding; import org.eclipse.cdt.internal.core.pdom.dom.IPDOMMemberOwner; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMASTAdapter; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode; @@ -83,10 +84,14 @@ class PDOMCLinkage extends PDOMLinkage { PDOMNode parent = getAdaptedParent(binding); if (parent == null) return null; + + // assign names to anonymous types. + binding= PDOMASTAdapter.getAdapterIfAnonymous(binding); - if (binding instanceof IParameter) + if (binding == null || binding instanceof IParameter) return null; // skip parameters - else if (binding instanceof IField) { // must be before IVariable + + if (binding instanceof IField) { // must be before IVariable if (parent instanceof IPDOMMemberOwner) pdomBinding = new PDOMCField(pdom, (IPDOMMemberOwner)parent, (IField) binding); } else if (binding instanceof IVariable) { @@ -130,7 +135,7 @@ class PDOMCLinkage extends PDOMLinkage { return null; char[] namechars = name.toCharArray(); - if (namechars == null || name.toCharArray().length == 0) + if (namechars == null) return null; IBinding binding = name.resolveBinding(); @@ -174,7 +179,13 @@ class PDOMCLinkage extends PDOMLinkage { } // so if the binding is from another pdom it has to be adapted. } - + else { + // assign names to anonymous types. + binding= PDOMASTAdapter.getAdapterIfAnonymous(binding); + if (binding == null) { + return null; + } + } PDOMNode parent = getAdaptedParent(binding); if (parent == this) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java index fec234ea1cd..b4e5a4ccbe4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java @@ -48,6 +48,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalFunction; import org.eclipse.cdt.internal.core.pdom.PDOM; import org.eclipse.cdt.internal.core.pdom.db.IBTreeComparator; import org.eclipse.cdt.internal.core.pdom.dom.IPDOMMemberOwner; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMASTAdapter; import org.eclipse.cdt.internal.core.pdom.dom.PDOMBinding; import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage; import org.eclipse.cdt.internal.core.pdom.dom.PDOMName; @@ -102,9 +103,9 @@ class PDOMCPPLinkage extends PDOMLinkage { // Check for null name char[] namechars = name.toCharArray(); - if (namechars == null || namechars.length == 0) + if (namechars == null) return null; - + IBinding binding = name.resolveBinding(); if (binding == null || binding instanceof IProblemBinding) { @@ -145,6 +146,12 @@ class PDOMCPPLinkage extends PDOMLinkage { private PDOMBinding addBinding(PDOMNode parent, IBinding binding) throws CoreException, DOMException { PDOMBinding pdomBinding= null; + // assign names to anonymous types. + binding= PDOMASTAdapter.getAdapterIfAnonymous(binding); + if (binding == null) { + return null; + } + if (binding instanceof ICPPField && parent instanceof PDOMCPPClassType) pdomBinding = new PDOMCPPField(pdom, (PDOMCPPClassType)parent, (ICPPField) binding); else if (binding instanceof ICPPVariable && !(binding.getScope() instanceof CPPBlockScope)) { @@ -254,6 +261,13 @@ class PDOMCPPLinkage extends PDOMLinkage { } // so if the binding is from another pdom it has to be adapted. } + else { + // assign names to anonymous types. + binding= PDOMASTAdapter.getAdapterIfAnonymous(binding); + if (binding == null) { + return null; + } + } PDOMNode parent = getAdaptedParent(binding); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java index 20d3059fb09..9d3549ce500 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 2007 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 @@ -45,6 +45,7 @@ import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.internal.core.index.IIndexFragmentFile; import org.eclipse.cdt.internal.core.index.IWritableIndex; +import org.eclipse.cdt.internal.core.pdom.dom.PDOMASTAdapter; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; @@ -463,7 +464,10 @@ public abstract class PDOMIndexerTask implements IPDOMIndexerTask { // names ast.accept(new IndexerASTVisitor() { public void visit(IASTName name, IASTName caller) { + // assign a location to anonymous types. + name= PDOMASTAdapter.getAdapterIfAnonymous(name); IASTFileLocation nameLoc = name.getFileLocation(); + if (nameLoc != null) { IIndexFileLocation location = findLocation(nameLoc.getFileName()); addToMap(symbolMap, 2, location, new IASTName[]{name, caller}); diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/BaseUITestCase.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/BaseUITestCase.java index e39b6afe35c..87b93aa9e46 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/BaseUITestCase.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/BaseUITestCase.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 2007 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 @@ -64,8 +64,13 @@ public class BaseUITestCase extends BaseTestCase { } protected void waitForIndexer(IIndex index, IFile file, int maxmillis) throws Exception { + boolean firstTime= true; long endTime= System.currentTimeMillis() + maxmillis; - do { + while (firstTime || System.currentTimeMillis() < endTime) { + if (!firstTime) + Thread.sleep(50); + firstTime= false; + index.acquireReadLock(); try { IIndexFile pfile= index.getFile(IndexLocationFactory.getWorkspaceIFL(file)); @@ -76,9 +81,7 @@ public class BaseUITestCase extends BaseTestCase { finally { index.releaseReadLock(); } - - Thread.sleep(50); - } while (System.currentTimeMillis() < endTime); + } throw new Exception("Indexer did not complete in time!"); } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/BasicCallHierarchyTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/BasicCallHierarchyTest.java index d7077171d7d..f65eaa921c7 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/BasicCallHierarchyTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/callhierarchy/BasicCallHierarchyTest.java @@ -132,11 +132,11 @@ public class BasicCallHierarchyTest extends CallHierarchyBaseTest { doTestEnumerator("enumerator.cpp", "testEnumerator"); } - public void _testAnonymousEnumeratorC_156671() throws Exception { + public void testAnonymousEnumeratorC_156671() throws Exception { doTestEnumerator("enumerator.c", "testAnonymousEnumerator"); } - public void _testAnonymousEnumeratorCpp_156671() throws Exception { + public void testAnonymousEnumeratorCpp_156671() throws Exception { doTestEnumerator("enumerator.cpp", "testAnonymousEnumerator"); } @@ -178,14 +178,6 @@ public class BasicCallHierarchyTest extends CallHierarchyBaseTest { checkTreeNode(tree, 0, "main()"); } - public void testStructMembersC() throws Exception { - doTestStructMembers("struct_member.c"); - } - - public void testStructMembersCpp() throws Exception { - doTestStructMembers("struct_member.cpp"); - } - // {testStructMembers} // struct s1 { // int mem1; @@ -215,19 +207,19 @@ public class BasicCallHierarchyTest extends CallHierarchyBaseTest { // i= vt2.mem2; //ref // i= vt3.mem3; //ref // }; - private void doTestStructMembers(String filename) throws Exception { + public void testStructMembersC() throws Exception { String content = readTaggedComment("testStructMembers"); - IFile file= createFile(getProject(), filename, content); + IFile file= createFile(getProject(), "struct_member.c", content); waitForIndexer(fIndex, file, 1000); IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); CEditor editor= (CEditor) IDE.openEditor(page, file); - + editor.selectAndReveal(content.indexOf("mem1"), 0); openCallHierarchy(editor); Tree tree = getCHTreeViewer().getTree(); checkTreeNode(tree, 0, "s1::mem1"); checkTreeNode(tree, 0, 0, "main()"); - + editor.selectAndReveal(content.indexOf("mem2"), 0); openCallHierarchy(editor); checkTreeNode(tree, 0, "s2::mem2"); @@ -236,78 +228,137 @@ public class BasicCallHierarchyTest extends CallHierarchyBaseTest { editor.selectAndReveal(content.indexOf("mem3"), 0); openCallHierarchy(editor); checkTreeNode(tree, 0, "(anon)::mem3"); - + editor.selectAndReveal(content.indexOf("mem4"), 0); openCallHierarchy(editor); checkTreeNode(tree, 0, "s4::mem4"); checkTreeNode(tree, 0, 0, "main()"); - + editor.selectAndReveal(content.indexOf("mem5"), 0); openCallHierarchy(editor); - checkTreeNode(tree, 0, "s4::(anon)::mem5"); - + checkTreeNode(tree, 0, "(anon)::mem5"); + editor.selectAndReveal(content.indexOf("mem1; //ref"), 0); openCallHierarchy(editor); checkTreeNode(tree, 0, "s1::mem1"); checkTreeNode(tree, 0, 0, "main()"); - + editor.selectAndReveal(content.indexOf("mem2; //ref"), 0); openCallHierarchy(editor); checkTreeNode(tree, 0, "s2::mem2"); checkTreeNode(tree, 0, 0, "main()"); - + editor.selectAndReveal(content.indexOf("mem4."), 0); openCallHierarchy(editor); checkTreeNode(tree, 0, "s4::mem4"); checkTreeNode(tree, 0, 0, "main()"); } - - public void _testAnonymousStructMembersC_156671() throws Exception { - doTestAnonymousStructMembers("anon_struct_member.c"); - } - public void _testAnonymousStructMembersCpp_156671() throws Exception { - doTestAnonymousStructMembers("anon_struct_member.cpp"); - } - - private void doTestAnonymousStructMembers(String filename) throws Exception { + public void testStructMembersCpp() throws Exception { String content = readTaggedComment("testStructMembers"); - IFile file= createFile(getProject(), filename, content); + IFile file= createFile(getProject(), "struct_member.cpp", content); waitForIndexer(fIndex, file, 1000); IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); CEditor editor= (CEditor) IDE.openEditor(page, file); - + + editor.selectAndReveal(content.indexOf("mem1"), 0); + openCallHierarchy(editor); + Tree tree = getCHTreeViewer().getTree(); + checkTreeNode(tree, 0, "s1::mem1"); + checkTreeNode(tree, 0, 0, "main()"); + + editor.selectAndReveal(content.indexOf("mem2"), 0); + openCallHierarchy(editor); + checkTreeNode(tree, 0, "s2::mem2"); + checkTreeNode(tree, 0, 0, "main()"); + + editor.selectAndReveal(content.indexOf("mem3"), 0); + openCallHierarchy(editor); + checkTreeNode(tree, 0, "(anon)::mem3"); + + editor.selectAndReveal(content.indexOf("mem4"), 0); + openCallHierarchy(editor); + checkTreeNode(tree, 0, "s4::mem4"); + checkTreeNode(tree, 0, 0, "main()"); + + editor.selectAndReveal(content.indexOf("mem5"), 0); + openCallHierarchy(editor); + checkTreeNode(tree, 0, "s4::(anon)::mem5"); + + editor.selectAndReveal(content.indexOf("mem1; //ref"), 0); + openCallHierarchy(editor); + checkTreeNode(tree, 0, "s1::mem1"); + checkTreeNode(tree, 0, 0, "main()"); + + editor.selectAndReveal(content.indexOf("mem2; //ref"), 0); + openCallHierarchy(editor); + checkTreeNode(tree, 0, "s2::mem2"); + checkTreeNode(tree, 0, 0, "main()"); + + editor.selectAndReveal(content.indexOf("mem4."), 0); + openCallHierarchy(editor); + checkTreeNode(tree, 0, "s4::mem4"); + checkTreeNode(tree, 0, 0, "main()"); + } + + public void testAnonymousStructMembersC_156671() throws Exception { + String content = readTaggedComment("testStructMembers"); + IFile file= createFile(getProject(), "anon_struct_member.c", content); + waitForIndexer(fIndex, file, 1000); + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + CEditor editor= (CEditor) IDE.openEditor(page, file); + editor.selectAndReveal(content.indexOf("mem3"), 0); openCallHierarchy(editor); Tree tree = getCHTreeViewer().getTree(); checkTreeNode(tree, 0, "(anon)::mem3"); checkTreeNode(tree, 0, 0, "main()"); - + editor.selectAndReveal(content.indexOf("mem5"), 0); openCallHierarchy(editor); - checkTreeNode(tree, 0, "s4::(anon)::mem5"); + checkTreeNode(tree, 0, "(anon)::mem5"); checkTreeNode(tree, 0, 0, "main()"); - + editor.selectAndReveal(content.indexOf("mem3; //ref"), 0); openCallHierarchy(editor); checkTreeNode(tree, 0, "(anon)::mem3"); checkTreeNode(tree, 0, 0, "main()"); - + + editor.selectAndReveal(content.indexOf("mem5; //ref"), 0); + openCallHierarchy(editor); + checkTreeNode(tree, 0, "(anon)::mem5"); + checkTreeNode(tree, 0, 0, "main()"); + } + + public void testAnonymousStructMembersCpp_156671() throws Exception { + String content = readTaggedComment("testStructMembers"); + IFile file= createFile(getProject(), "anon_struct_member.cpp", content); + waitForIndexer(fIndex, file, 1000); + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + CEditor editor= (CEditor) IDE.openEditor(page, file); + + editor.selectAndReveal(content.indexOf("mem3"), 0); + openCallHierarchy(editor); + Tree tree = getCHTreeViewer().getTree(); + checkTreeNode(tree, 0, "(anon)::mem3"); + checkTreeNode(tree, 0, 0, "main()"); + + editor.selectAndReveal(content.indexOf("mem5"), 0); + openCallHierarchy(editor); + checkTreeNode(tree, 0, "s4::(anon)::mem5"); + checkTreeNode(tree, 0, 0, "main()"); + + editor.selectAndReveal(content.indexOf("mem3; //ref"), 0); + openCallHierarchy(editor); + checkTreeNode(tree, 0, "(anon)::mem3"); + checkTreeNode(tree, 0, 0, "main()"); + editor.selectAndReveal(content.indexOf("mem5; //ref"), 0); openCallHierarchy(editor); checkTreeNode(tree, 0, "s4::(anon)::mem5"); checkTreeNode(tree, 0, 0, "main()"); } - - public void testUnionMembersC() throws Exception { - doTestUnionMembers("union_member.c"); - } - - public void testUnionMembersCpp() throws Exception { - doTestUnionMembers("union_member.cpp"); - } - // {testUnionMembers} // union u1 { // int mem1; @@ -342,19 +393,19 @@ public class BasicCallHierarchyTest extends CallHierarchyBaseTest { // i= vt2.mem2; //ref // i= vt3.mem3; //ref // }; - private void doTestUnionMembers(String filename) throws Exception { + public void testUnionMembersC() throws Exception { String content = readTaggedComment("testUnionMembers"); - IFile file= createFile(getProject(), filename, content); + IFile file= createFile(getProject(), "union_member.c", content); waitForIndexer(fIndex, file, 1000); IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); CEditor editor= (CEditor) IDE.openEditor(page, file); - + editor.selectAndReveal(content.indexOf("mem1"), 0); openCallHierarchy(editor); Tree tree = getCHTreeViewer().getTree(); checkTreeNode(tree, 0, "u1::mem1"); checkTreeNode(tree, 0, 0, "main()"); - + editor.selectAndReveal(content.indexOf("mem2"), 0); openCallHierarchy(editor); checkTreeNode(tree, 0, "u2::mem2"); @@ -363,63 +414,131 @@ public class BasicCallHierarchyTest extends CallHierarchyBaseTest { editor.selectAndReveal(content.indexOf("mem3"), 0); openCallHierarchy(editor); checkTreeNode(tree, 0, "(anon)::mem3"); - + editor.selectAndReveal(content.indexOf("mem4"), 0); openCallHierarchy(editor); checkTreeNode(tree, 0, "u4::mem4"); checkTreeNode(tree, 0, 0, "main()"); - + editor.selectAndReveal(content.indexOf("mem5"), 0); openCallHierarchy(editor); - checkTreeNode(tree, 0, "u4::(anon)::mem5"); - + checkTreeNode(tree, 0, "(anon)::mem5"); + editor.selectAndReveal(content.indexOf("mem1; //ref"), 0); openCallHierarchy(editor); checkTreeNode(tree, 0, "u1::mem1"); checkTreeNode(tree, 0, 0, "main()"); - + editor.selectAndReveal(content.indexOf("mem2; //ref"), 0); openCallHierarchy(editor); checkTreeNode(tree, 0, "u2::mem2"); checkTreeNode(tree, 0, 0, "main()"); - + + editor.selectAndReveal(content.indexOf("mem4."), 0); + openCallHierarchy(editor); + checkTreeNode(tree, 0, "u4::mem4"); + checkTreeNode(tree, 0, 0, "main()"); + } + + public void testUnionMembersCpp() throws Exception { + String content = readTaggedComment("testUnionMembers"); + IFile file= createFile(getProject(), "union_member.cpp", content); + waitForIndexer(fIndex, file, 1000); + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + CEditor editor= (CEditor) IDE.openEditor(page, file); + + editor.selectAndReveal(content.indexOf("mem1"), 0); + openCallHierarchy(editor); + Tree tree = getCHTreeViewer().getTree(); + checkTreeNode(tree, 0, "u1::mem1"); + checkTreeNode(tree, 0, 0, "main()"); + + editor.selectAndReveal(content.indexOf("mem2"), 0); + openCallHierarchy(editor); + checkTreeNode(tree, 0, "u2::mem2"); + checkTreeNode(tree, 0, 0, "main()"); + + editor.selectAndReveal(content.indexOf("mem3"), 0); + openCallHierarchy(editor); + checkTreeNode(tree, 0, "(anon)::mem3"); + + editor.selectAndReveal(content.indexOf("mem4"), 0); + openCallHierarchy(editor); + checkTreeNode(tree, 0, "u4::mem4"); + checkTreeNode(tree, 0, 0, "main()"); + + editor.selectAndReveal(content.indexOf("mem5"), 0); + openCallHierarchy(editor); + checkTreeNode(tree, 0, "u4::(anon)::mem5"); + + editor.selectAndReveal(content.indexOf("mem1; //ref"), 0); + openCallHierarchy(editor); + checkTreeNode(tree, 0, "u1::mem1"); + checkTreeNode(tree, 0, 0, "main()"); + + editor.selectAndReveal(content.indexOf("mem2; //ref"), 0); + openCallHierarchy(editor); + checkTreeNode(tree, 0, "u2::mem2"); + checkTreeNode(tree, 0, 0, "main()"); + editor.selectAndReveal(content.indexOf("mem4."), 0); openCallHierarchy(editor); checkTreeNode(tree, 0, "u4::mem4"); checkTreeNode(tree, 0, 0, "main()"); } - public void _testAnonymousUnionMembersC_156671() throws Exception { - doTestAnonymousUnionMembers("anon_union_member.c"); - } - - public void _testAnonymousUnionMembersCpp_156671() throws Exception { - doTestAnonymousUnionMembers("anon_union_member.cpp"); - } - - private void doTestAnonymousUnionMembers(String filename) throws Exception { + public void testAnonymousUnionMembersC_156671() throws Exception { String content = readTaggedComment("testUnionMembers"); - IFile file= createFile(getProject(), filename, content); + IFile file= createFile(getProject(), "anon_union_member.c", content); waitForIndexer(fIndex, file, 1000); IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); CEditor editor= (CEditor) IDE.openEditor(page, file); - + editor.selectAndReveal(content.indexOf("mem3"), 0); openCallHierarchy(editor); Tree tree = getCHTreeViewer().getTree(); checkTreeNode(tree, 0, "(anon)::mem3"); checkTreeNode(tree, 0, 0, "main()"); - + editor.selectAndReveal(content.indexOf("mem5"), 0); openCallHierarchy(editor); - checkTreeNode(tree, 0, "u4::(anon)::mem5"); + checkTreeNode(tree, 0, "(anon)::mem5"); checkTreeNode(tree, 0, 0, "main()"); - + editor.selectAndReveal(content.indexOf("mem3; //ref"), 0); openCallHierarchy(editor); checkTreeNode(tree, 0, "(anon)::mem3"); checkTreeNode(tree, 0, 0, "main()"); - + + editor.selectAndReveal(content.indexOf("mem5; //ref"), 0); + openCallHierarchy(editor); + checkTreeNode(tree, 0, "(anon)::mem5"); + checkTreeNode(tree, 0, 0, "main()"); + } + + public void testAnonymousUnionMembersCpp_156671() throws Exception { + String content = readTaggedComment("testUnionMembers"); + IFile file= createFile(getProject(), "anon_union_member.cpp", content); + waitForIndexer(fIndex, file, 1000); + IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); + CEditor editor= (CEditor) IDE.openEditor(page, file); + + editor.selectAndReveal(content.indexOf("mem3"), 0); + openCallHierarchy(editor); + Tree tree = getCHTreeViewer().getTree(); + checkTreeNode(tree, 0, "(anon)::mem3"); + checkTreeNode(tree, 0, 0, "main()"); + + editor.selectAndReveal(content.indexOf("mem5"), 0); + openCallHierarchy(editor); + checkTreeNode(tree, 0, "u4::(anon)::mem5"); + checkTreeNode(tree, 0, 0, "main()"); + + editor.selectAndReveal(content.indexOf("mem3; //ref"), 0); + openCallHierarchy(editor); + checkTreeNode(tree, 0, "(anon)::mem3"); + checkTreeNode(tree, 0, 0, "main()"); + editor.selectAndReveal(content.indexOf("mem5; //ref"), 0); openCallHierarchy(editor); checkTreeNode(tree, 0, "u4::(anon)::mem5"); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/CElementLabels.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/CElementLabels.java index 7864f386480..b69c5b1f5a6 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/CElementLabels.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/CElementLabels.java @@ -688,7 +688,8 @@ public class CElementLabels { break; } } - if (isQualifier) { + // types cannot be qualified in plain c + if (isQualifier && !isCLanguage(parent)) { int qflags= flags & ~MF_POST_FILE_QUALIFIED; getTypeLabel(parent, qflags, buf); buf.append("::"); //$NON-NLS-1$ @@ -731,6 +732,16 @@ public class CElementLabels { } } + private static boolean isCLanguage(ICElement elem) { + while (elem != null) { + elem= elem.getParent(); + if (elem instanceof ITranslationUnit) { + return ((ITranslationUnit) elem).isCLanguage(); + } + } + return false; + } + /** * Convert an ASTAccessVisibility into its string representation. *