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:
parent
2690b106c5
commit
1c122ce5af
8 changed files with 147 additions and 29 deletions
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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('}');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Add table
Reference in a new issue