1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +02:00

Bug 416278 - Indexer gets confused by a class in an anonymous namespace.

This commit is contained in:
Sergey Prigogin 2013-09-09 14:14:23 -07:00
parent 2690b106c5
commit 1c122ce5af
8 changed files with 147 additions and 29 deletions

View file

@ -85,8 +85,9 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase {
}
protected IASTName findName(String section, int len, boolean preferImplicitName) {
if (len == 0)
len= section.length();
if (len <= 0)
len += section.length();
for (int i = 0; i < strategy.getAstCount(); i++) {
IASTTranslationUnit ast = strategy.getAst(i);
final IASTNodeSelector nodeSelector = ast.getNodeSelector(null);
@ -128,10 +129,10 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase {
* @param clazz an expected class type or interface that the binding should extend/implement
* @return the associated name's binding
*/
protected <T> T getBindingFromASTName(String section, int len, Class<T> clazz, Class ... cs) {
if (len < 1) {
len= section.length()+len;
}
protected <T> T getBindingFromASTName(String section, int len, Class<T> clazz, Class... cs) {
if (len <= 0)
len += section.length();
IASTName name= findName(section, len);
assertNotNull("Name not found for \"" + section + "\"", name);
assertEquals(section.substring(0, len), name.getRawSignature());
@ -156,10 +157,10 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase {
* @param clazz an expected class type or interface that the binding should extend/implement
* @return the associated implicit name's binding
*/
protected <T> T getBindingFromImplicitASTName(String section, int len, Class<T> clazz, Class ... cs) {
if (len < 1) {
len= section.length()+len;
}
protected <T> T getBindingFromImplicitASTName(String section, int len, Class<T> clazz, Class... cs) {
if (len <= 0)
len += section.length();
IASTName name= findImplicitName(section, len);
assertNotNull("Name not found for \"" + section + "\"", name);
assertEquals(section.substring(0, len), name.getRawSignature());
@ -172,7 +173,7 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase {
}
/*
* @see IndexBindingResolutionTestBase#getBindingFromASTName(String, int, Class<T>, Class ...)
* @see IndexBindingResolutionTestBase#getBindingFromASTName(String, int, Class<T>, Class...)
*/
protected <T extends IBinding> T getBindingFromASTName(String section, int len) {
if (len <= 0)
@ -187,7 +188,15 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase {
assertFalse("Binding is a ProblemBinding for name \"" + name.getRawSignature() + "\"", IProblemBinding.class.isAssignableFrom(name.resolveBinding().getClass()));
return (T) binding;
}
protected <T extends IBinding> T getBindingFromFirstIdentifier(String section) {
return getBindingFromASTName(section, getIdentifierLength(section));
}
protected <T extends IBinding> T getBindingFromFirstIdentifier(String section, Class<T> clazz, Class... cs) {
return getBindingFromASTName(section, getIdentifierLength(section), clazz, cs);
}
/*
* @see IndexBindingResolutionTestBase#getBindingFromImplicitASTName(String, int, Class<T>, Class ...)
*/
@ -201,7 +210,8 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase {
IBinding binding = name.resolveBinding();
assertNotNull("No binding for " + name.getRawSignature(), binding);
assertFalse("Binding is a ProblemBinding for name \"" + name.getRawSignature() + "\"", IProblemBinding.class.isAssignableFrom(name.resolveBinding().getClass()));
assertFalse("Binding is a ProblemBinding for name \"" + name.getRawSignature() + "\"",
IProblemBinding.class.isAssignableFrom(name.resolveBinding().getClass()));
return (T) binding;
}
@ -218,10 +228,15 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase {
IBinding binding = name.resolveBinding();
assertNotNull("No binding for " + name.getRawSignature(), binding);
assertTrue("Binding is not a ProblemBinding for name \"" + name.getRawSignature() + "\"", IProblemBinding.class.isAssignableFrom(name.resolveBinding().getClass()));
assertTrue("Binding is not a ProblemBinding for name \"" + name.getRawSignature() + "\"",
IProblemBinding.class.isAssignableFrom(name.resolveBinding().getClass()));
return name.resolveBinding();
}
protected IBinding getProblemFromFirstIdentifier(String section) {
return getProblemFromASTName(section, getIdentifierLength(section));
}
protected static void assertQNEquals(String expectedQN, IBinding b) {
assertInstance(b, IBinding.class);
if (b instanceof ICPPBinding) {
@ -308,6 +323,13 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase {
}
}
protected int getIdentifierLength(String str) {
int i;
for (i = 0; i < str.length() && Character.isJavaIdentifierPart(str.charAt(i)); ++i) {
}
return i;
}
static protected class NameCollector extends ASTVisitor {
{
shouldVisitNames = true;
@ -773,4 +795,4 @@ public abstract class IndexBindingResolutionTestBase extends BaseTestCase {
assertNotNull(second);
assertTrue("Expected types to be the same, but first was: '" + first.toString() + "' and second was: '" + second + "'", first.isSameType(second));
}
}
}

View file

@ -1715,6 +1715,16 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
getBindingFromASTName("g(b)", 1, ICPPFunction.class);
}
// namespace {
// class A {};
// }
// A a;
public void testAnonymousNamespace() throws Exception {
getBindingFromFirstIdentifier("A", ICPPClassType.class);
}
// namespace ns {
// namespace {
// const char str[] = "";
@ -1735,6 +1745,6 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
//
// }
public void testAnonymousNamespaces_392577() throws Exception {
getBindingFromASTName("f(str)", 1, ICPPFunction.class);
getBindingFromFirstIdentifier("f(str)", ICPPFunction.class);
}
}

View file

@ -0,0 +1,59 @@
/*******************************************************************************
* Copyright (c) 2013 Google, 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:
* Sergey Prigogin (Google) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.index.tests;
import junit.framework.TestSuite;
/**
* Tests for header files included in multiple variants.
*
* The first line of each comment section preceding a test contains the name of the file
* to put the contents of the section to. To request the AST of a file, put an asterisk after
* the file name.
*/
public class IndexMultiFileTest extends IndexBindingResolutionTestBase {
public IndexMultiFileTest() {
setStrategy(new SinglePDOMTestNamedFilesStrategy(true));
}
public static TestSuite suite() {
return suite(IndexMultiFileTest.class);
}
// A.h
// template <typename T>
// struct A {
// void m(T p);
// };
// B.h
// struct B {};
// confuser.cpp
// #include "A.h"
//
// namespace {
// struct B {};
// }
// A<B*> z;
// test.cpp *
// #include "A.h"
// #include "B.h"
//
// void test(A<B*> a, B* b) {
// a.m(b);
// }
public void testAnonymousNamespace_416278() throws Exception {
checkBindings();
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2007 Wind River Systems, Inc. and others.
* Copyright (c) 2006, 2013 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
@ -7,6 +7,7 @@
*
* Contributors:
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.index.tests;
@ -31,6 +32,7 @@ public class IndexTests extends TestSuite {
suite.addTest(TeamSharedIndexTest.suite());
suite.addTest(IndexProviderManagerTest.suite());
suite.addTest(IndexMultiVariantHeaderTest.suite());
suite.addTest(IndexMultiFileTest.suite());
IndexCPPBindingResolutionBugs.addTests(suite);
IndexCPPBindingResolutionTest.addTests(suite);

View file

@ -17,6 +17,7 @@ import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.c.ICArrayType;
import org.eclipse.cdt.core.dom.ast.c.ICQualifierType;
@ -32,6 +33,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPQualifierType;
import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.parser.GCCKeywords;
import org.eclipse.cdt.core.parser.Keywords;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
@ -47,6 +50,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownMemberClassInstan
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeOfDependentExpression;
import org.eclipse.core.runtime.CoreException;
/**
* This is a utility class to help convert AST elements to Strings corresponding to
@ -735,6 +739,18 @@ public class ASTTypeUtil {
if (owner instanceof ICPPNamespace || owner instanceof IType) {
int pos= result.length();
appendCppName(owner, normalize, qualify, result);
if (binding instanceof IIndexBinding && owner instanceof ICPPNamespace && owner.getNameCharArray().length == 0) {
try {
IIndexFile file = ((IIndexBinding) binding).getLocalToFile();
if (file != null) {
result.append('{');
result.append(file.getLocation().getURI().toString());
result.append('}');
}
} catch (CoreException e) {
CCorePlugin.log(e);
}
}
if (result.length() > pos)
result.append("::"); //$NON-NLS-1$
}
@ -804,8 +820,10 @@ public class ASTTypeUtil {
int fnamestart= findFileNameStart(fname);
buf.append('{');
buf.append(fname, fnamestart, fname.length - fnamestart);
buf.append(':');
buf.append(loc.getNodeOffset());
if (!(binding instanceof ICPPNamespace)) {
buf.append(':');
buf.append(loc.getNodeOffset());
}
buf.append('}');
}
}

View file

@ -8,6 +8,7 @@
* Contributors:
* Markus Schorn - initial API and implementation
* Thomas Corbat (IFS)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom;
@ -39,6 +40,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.index.IIndexBinding;
@ -657,6 +659,8 @@ public class PDOMASTAdapter {
if (name != null) {
return new AnonymousCompositeType(name, (ICompositeType) binding);
}
} else if (binding instanceof ICPPNamespace) {
return binding;
} else if (binding instanceof ICPPTemplateParameter) {
return binding;
} else if (binding instanceof ICPPConstructor) {

View file

@ -864,15 +864,6 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
if (ib.isFileLocal()) {
return null;
}
} else {
// Skip anonymous namespaces.
while (owner instanceof ICPPNamespace) {
char[] name= owner.getNameCharArray();
if (name.length > 0) {
break;
}
owner= owner.getOwner();
}
}
if (owner == null)

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2011 QNX Software Systems and others.
* Copyright (c) 2006, 2013 QNX Software Systems 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
@ -11,6 +11,7 @@
* Andrew Ferguson (Symbian)
* Bryan Wilkinson (QNX)
* Jens Elmenthaler - http://bugs.eclipse.org/173458 (camel case completion)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
@ -30,6 +31,7 @@ import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.core.index.IndexFilter;
import org.eclipse.cdt.core.parser.Keywords;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
@ -135,6 +137,16 @@ class PDOMCPPNamespace extends PDOMCPPBinding
if (child instanceof PDOMCPPNamespace) {
((PDOMCPPNamespace) child).addToList(record + FIRST_NAMESPACE_CHILD_OFFSET);
}
if (hasName(CharArrayUtils.EMPTY_CHAR_ARRAY)) {
// The parent of the anonymous namespace adopts its children so that they could be
// found up there.
PDOMNode parent = getParentNode();
if (parent instanceof PDOMCPPNamespace) {
parent.addChild(child);
} else {
getLinkage().addChild(child);
}
}
}
public void addToList(final long listRecord) throws CoreException {