Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Schorn2008-02-08 13:51:56 +0000
committerMarkus Schorn2008-02-08 13:51:56 +0000
commitc754042629931ec6579327c2a449efee842850ce (patch)
tree1387ce6ae70abb72dcbe27820d226c42a5ee28de
parent00091c99cbc7b0bc051c3005da3cbc280878a876 (diff)
downloadorg.eclipse.cdt-c754042629931ec6579327c2a449efee842850ce.tar.gz
org.eclipse.cdt-c754042629931ec6579327c2a449efee842850ce.tar.xz
org.eclipse.cdt-c754042629931ec6579327c2a449efee842850ce.zip
Fixes name-resolution with using-directives, related to bug 26110.
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java22
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java2
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2SpecBaseTest.java48
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java17
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNamespaceScope.java27
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPUsingDirective.java22
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java56
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java2
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java22
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java258
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUsingDirective.java61
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPNamespaceScope.java11
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPNamespace.java20
13 files changed, 331 insertions, 237 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java
index cef6b11ad28..3acd1adf2eb 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2008 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
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2;
@@ -727,7 +728,8 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
buffer.append("// S is { Y::h(int), Z::h(double) } and overload\n"); //$NON-NLS-1$
buffer.append("// resolution chooses Z::h(double)\n"); //$NON-NLS-1$
buffer.append("}\n"); //$NON-NLS-1$
- parse(buffer.toString(), ParserLanguage.CPP, false, 0);
+ String[] problems= {"AB::x", "x", "AB::i", "i"};
+ parse(buffer.toString(), ParserLanguage.CPP, problems); // qualified names are counted double, so 4
}
/**
@@ -2386,7 +2388,9 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
buffer.append("A::i++; // A::unique::i\n"); //$NON-NLS-1$
buffer.append("j++; // A::unique::j\n"); //$NON-NLS-1$
buffer.append("}\n"); //$NON-NLS-1$
- parse(buffer.toString(), ParserLanguage.CPP, false, 0);
+
+ String[] problems= {"i"};
+ parse(buffer.toString(), ParserLanguage.CPP, problems);
}
/**
@@ -2999,7 +3003,8 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
buffer.append("void f4() {\n"); //$NON-NLS-1$
buffer.append("i = 5; // illformed; neither i is visible\n"); //$NON-NLS-1$
buffer.append("}\n"); //$NON-NLS-1$
- parse(buffer.toString(), ParserLanguage.CPP, false, 0);
+ String[] problems= {"i", "i"};
+ parse(buffer.toString(), ParserLanguage.CPP, problems);
}
/**
@@ -3032,7 +3037,8 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
buffer.append("using namespace N;\n"); //$NON-NLS-1$
buffer.append("i = 7; // error: both M::i and N::i are visible\n"); //$NON-NLS-1$
buffer.append("}\n"); //$NON-NLS-1$
- parse(buffer.toString(), ParserLanguage.CPP, true, 0);
+ String[] problems= {"i"};
+ parse(buffer.toString(), ParserLanguage.CPP, problems);
}
/**
@@ -3081,7 +3087,8 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
buffer.append("int n = j; // D::j hides B::j\n"); //$NON-NLS-1$
buffer.append("}\n"); //$NON-NLS-1$
buffer.append("}\n"); //$NON-NLS-1$
- parse(buffer.toString(), ParserLanguage.CPP, true, 0);
+ String[] problems= {"k"};
+ parse(buffer.toString(), ParserLanguage.CPP, problems);
}
/**
@@ -3140,7 +3147,8 @@ public class AST2CPPSpecTest extends AST2SpecBaseTest {
buffer.append("f(1); //error: ambiguous: D::f(int) or E::f(int)?\n"); //$NON-NLS-1$
buffer.append("f('a'); //OK: D::f(char)\n"); //$NON-NLS-1$
buffer.append("}\n"); //$NON-NLS-1$
- parse(buffer.toString(), ParserLanguage.CPP, false, 0);
+ String[] problems= {"d1", "f"};
+ parse(buffer.toString(), ParserLanguage.CPP, problems);
}
/**
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
index e40b800d5be..8e1c665a9d5 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
@@ -3398,7 +3398,7 @@ public class AST2CPPTests extends AST2BaseTest {
.getParent().getParent();
IScope scope = ((IASTCompoundStatement) def.getBody()).getScope();
IBinding[] bs = scope.find("f"); //$NON-NLS-1$
- assertEquals(bs.length, 3);
+ assertEquals(3, bs.length);
assertSame(bs[0], f);
assertSame(bs[1], f1);
assertSame(bs[2], f2);
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2SpecBaseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2SpecBaseTest.java
index b04d449de58..72e9748e532 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2SpecBaseTest.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2SpecBaseTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2008 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
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2;
@@ -64,20 +65,26 @@ public class AST2SpecBaseTest extends TestCase {
* @throws ParserException
*/
protected void parseCandCPP( String code, boolean checkBindings, int expectedProblemBindings ) throws ParserException {
- parse( code, ParserLanguage.C, false, true, checkBindings, expectedProblemBindings);
- parse( code, ParserLanguage.CPP, false, true, checkBindings, expectedProblemBindings );
+ parse( code, ParserLanguage.C, false, true, checkBindings, expectedProblemBindings, null);
+ parse( code, ParserLanguage.CPP, false, true, checkBindings, expectedProblemBindings, null );
}
protected IASTTranslationUnit parse( String code, ParserLanguage lang, boolean checkBindings, int expectedProblemBindings ) throws ParserException {
- return parse(code, lang, false, true, checkBindings, expectedProblemBindings );
+ return parse(code, lang, false, true, checkBindings, expectedProblemBindings, null );
}
+
+ protected IASTTranslationUnit parse(String code, ParserLanguage lang, String[] problems) throws ParserException {
+ return parse(code, lang, false, true, true, problems.length, problems );
+ }
+
- private IASTTranslationUnit parse( String code, ParserLanguage lang, boolean useGNUExtensions, boolean expectNoProblems, boolean checkBindings, int expectedProblemBindings ) throws ParserException {
+ private IASTTranslationUnit parse( String code, ParserLanguage lang, boolean useGNUExtensions, boolean expectNoProblems,
+ boolean checkBindings, int expectedProblemBindings, String[] problems ) throws ParserException {
// TODO beef this up with tests... i.e. run once with \n, and then run again with \r\n replacing \n ... etc
// TODO another example might be to replace all characters with corresponding trigraph/digraph tests...
CodeReader codeReader = new CodeReader(code.toCharArray());
- return parse(codeReader, lang, useGNUExtensions, expectNoProblems, checkBindings, expectedProblemBindings);
+ return parse(codeReader, lang, useGNUExtensions, expectNoProblems, checkBindings, expectedProblemBindings, problems);
}
// private IASTTranslationUnit parse( IFile filename, ParserLanguage lang, boolean useGNUExtensions, boolean expectNoProblems ) throws ParserException {
@@ -93,7 +100,8 @@ public class AST2SpecBaseTest extends TestCase {
// return parse(codeReader, lang, useGNUExtensions, expectNoProblems);
// }
- private IASTTranslationUnit parse(CodeReader codeReader, ParserLanguage lang, boolean useGNUExtensions, boolean expectNoProblems, boolean checkBindings, int expectedProblemBindings) throws ParserException {
+ private IASTTranslationUnit parse(CodeReader codeReader, ParserLanguage lang, boolean useGNUExtensions,
+ boolean expectNoProblems, boolean checkBindings, int expectedProblemBindings, String[] problems) throws ParserException {
ScannerInfo scannerInfo = new ScannerInfo();
IScanner scanner= AST2BaseTest.createScanner(codeReader, lang, ParserMode.COMPLETE_PARSE, scannerInfo, false);
@@ -129,13 +137,23 @@ public class AST2SpecBaseTest extends TestCase {
if ( lang == ParserLanguage.CPP ) {
CPPNameResolver res = new CPPNameResolver();
tu.accept( res );
- if (res.numProblemBindings != expectedProblemBindings )
- throw new ParserException("Expected " + expectedProblemBindings + " problems, encountered " + res.numProblemBindings ); //$NON-NLS-1$ //$NON-NLS-2$
+ if (res.problemBindings.size() != expectedProblemBindings )
+ throw new ParserException("Expected " + expectedProblemBindings + " problems, encountered " + res.problemBindings.size() ); //$NON-NLS-1$ //$NON-NLS-2$
+ if (problems != null) {
+ for (int i = 0; i < problems.length; i++) {
+ assertEquals(problems[i], res.problemBindings.get(i));
+ }
+ }
} else if (lang == ParserLanguage.C ) {
CNameResolver res = new CNameResolver();
tu.accept( res );
- if (res.numProblemBindings != expectedProblemBindings )
- throw new ParserException("Expected " + expectedProblemBindings + " problems, encountered " + res.numProblemBindings ); //$NON-NLS-1$ //$NON-NLS-2$
+ if (res.problemBindings.size() != expectedProblemBindings )
+ throw new ParserException("Expected " + expectedProblemBindings + " problems, encountered " + res.problemBindings.size() ); //$NON-NLS-1$ //$NON-NLS-2$
+ if (problems != null) {
+ for (int i = 0; i < problems.length; i++) {
+ assertEquals(problems[i], res.problemBindings.get(i));
+ }
+ }
}
}
@@ -168,14 +186,14 @@ public class AST2SpecBaseTest extends TestCase {
{
shouldVisitNames = true;
}
- public int numProblemBindings=0;
+ public ArrayList<String> problemBindings=new ArrayList<String>();
public int numNullBindings=0;
public List nameList = new ArrayList();
public int visit( IASTName name ){
nameList.add( name );
IBinding binding = name.resolveBinding();
if (binding instanceof IProblemBinding)
- numProblemBindings++;
+ problemBindings.add(name.toString());
if (binding == null)
numNullBindings++;
return PROCESS_CONTINUE;
@@ -192,14 +210,14 @@ public class AST2SpecBaseTest extends TestCase {
{
shouldVisitNames = true;
}
- public int numProblemBindings=0;
+ public ArrayList<String> problemBindings=new ArrayList<String>();
public int numNullBindings=0;
public List nameList = new ArrayList();
public int visit( IASTName name ){
nameList.add( name );
IBinding binding = name.resolveBinding();
if (binding instanceof IProblemBinding)
- numProblemBindings++;
+ problemBindings.add(name.toString());
if (binding == null)
numNullBindings++;
return PROCESS_CONTINUE;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java
index 71f8733a58c..853685f35c6 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2008 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
@@ -9,7 +9,6 @@
* Rational Software - initial implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
-
package org.eclipse.cdt.core.dom.ast;
import java.util.LinkedList;
@@ -69,7 +68,7 @@ public class ASTTypeUtil {
* @return the representation of the parameter type of an IFunctionType
*/
public static String getParameterTypeString(IFunctionType type) {
- StringBuffer result = new StringBuffer();
+ StringBuilder result = new StringBuilder();
String[] parms = getParameterTypeStringArray(type);
result.append(Keywords.cpLPAREN);
@@ -90,7 +89,7 @@ public class ASTTypeUtil {
* @return representation of the type array as a comma-separated list
*/
public static String getTypeListString(IType[] types) {
- StringBuffer result = new StringBuffer();
+ StringBuilder result = new StringBuilder();
for(int i=0; i<types.length; i++) {
if (types[i] != null) {
result.append(getTypeString(types[i]));
@@ -124,7 +123,7 @@ public class ASTTypeUtil {
}
private static String getTypeString(IType type) {
- StringBuffer result = new StringBuffer();
+ StringBuilder result = new StringBuilder();
boolean needSpace = false;
if (type instanceof IArrayType) {
@@ -311,7 +310,7 @@ public class ASTTypeUtil {
* @return the type representation of the IType
*/
public static String getType(IType type, boolean resolveTypedefs) {
- StringBuffer result = new StringBuffer();
+ StringBuilder result = new StringBuilder();
IType[] types = new IType[DEAULT_ITYPE_SIZE];
// push all of the types onto the stack
@@ -502,7 +501,7 @@ public class ASTTypeUtil {
private static String[] getQualifiedNameForAnonymous(ICPPBinding binding) throws DOMException {
- LinkedList result= new LinkedList();
+ LinkedList<String> result= new LinkedList<String>();
result.addFirst(getNameForAnonymous(binding));
ICPPScope scope = (ICPPScope) binding.getScope();
while( scope != null ){
@@ -530,7 +529,7 @@ public class ASTTypeUtil {
}
scope = (ICPPScope) scope.getParent();
}
- return (String[]) result.toArray(new String[result.size()]);
+ return result.toArray(new String[result.size()]);
}
private static String getNameForAnonymous(IBinding binding) {
@@ -570,7 +569,7 @@ public class ASTTypeUtil {
if (loc != null) {
char[] fname= loc.getFileName().toCharArray();
int fnamestart= findFileNameStart(fname);
- StringBuffer buf= new StringBuffer();
+ StringBuilder buf= new StringBuilder();
buf.append('{');
buf.append(fname, fnamestart, fname.length-fnamestart);
buf.append(':');
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNamespaceScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNamespaceScope.java
index 869735ae578..cf13df33ebf 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNamespaceScope.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPNamespaceScope.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * Copyright (c) 2004, 2008 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
@@ -7,36 +7,25 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
-/*
- * Created on Nov 29, 2004
- */
package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.DOMException;
-import org.eclipse.cdt.core.dom.ast.IASTNode;
/**
- * @author aniefer
+ * A namespace scope is either a block-scope or a namespace-scope or global scope.
*/
public interface ICPPNamespaceScope extends ICPPScope {
/**
- * Add an IASTNode that nominates another namespace to this scope Most
- * commonly, ICPPASTUsingDirectives, but in the case of unnamed namespaces,
- * it could be an ICPPASTNamespaceDefinition
- *
- * @param directive
+ * Add a directive that nominates another namespace to this scope.
*/
- public void addUsingDirective(IASTNode directive) throws DOMException;
+ public void addUsingDirective(ICPPUsingDirective usingDirective) throws DOMException;
/**
- * Get the IASTNodes that have been added to this scope to nominate other
- * namespaces during lookup. (ICPPASTUsingDirective or
- * ICPPASTNamespaceDefinition)
- *
- * @return
+ * Get the using directives that have been added to this scope to nominate other
+ * namespaces during lookup.
*/
- public IASTNode[] getUsingDirectives() throws DOMException;
-
+ public ICPPUsingDirective[] getUsingDirectives() throws DOMException;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPUsingDirective.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPUsingDirective.java
new file mode 100644
index 00000000000..febcbbfe7fb
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPUsingDirective.java
@@ -0,0 +1,22 @@
+package org.eclipse.cdt.core.dom.ast.cpp;
+
+import org.eclipse.cdt.core.dom.ast.DOMException;
+import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
+
+/**
+ * Interface to model using directives
+ * @since 5.0
+ */
+public interface ICPPUsingDirective {
+
+ /**
+ * Returns the scope of the namespace that is nominated by this
+ * directive.
+ */
+ ICPPNamespace getNamespace() throws DOMException;
+
+ /**
+ * Returns the point of declaration as global offset ({@link ASTNode#getOffset()}).
+ */
+ int getPointOfDeclaration();
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java
index b767e3aa6de..906e2d25d9c 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2008 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
@@ -57,6 +57,7 @@ import org.eclipse.cdt.core.dom.ast.IASTLabelStatement;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNullStatement;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
@@ -158,7 +159,8 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
BacktrackException {
if (LT(1) == IToken.tASSIGN) {
consume();
- return cInitializerClause(Collections.EMPTY_LIST);
+ final List<IASTNode> empty= Collections.emptyList();
+ return cInitializerClause(empty);
}
return null;
}
@@ -167,7 +169,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
* @param scope
* @return
*/
- protected IASTInitializer cInitializerClause(List designators)
+ protected IASTInitializer cInitializerClause(List<IASTNode> designators)
throws EndOfFileException, BacktrackException {
IToken la = LA(1);
int startingOffset = la.getOffset();
@@ -188,7 +190,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
int checkHashcode = LA(1).hashCode();
// required at least one initializer list
// get designator list
- List newDesignators = designatorList();
+ List<IASTNode> newDesignators = designatorList();
if (newDesignators.size() != 0)
if (LT(1) == IToken.tASSIGN)
consume();
@@ -269,10 +271,10 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
return new CASTInitializerExpression();
}
- protected List designatorList() throws EndOfFileException,
+ protected List<IASTNode> designatorList() throws EndOfFileException,
BacktrackException {
// designated initializers for C
- List designatorList = Collections.EMPTY_LIST;
+ List<IASTNode> designatorList= Collections.emptyList();
if (LT(1) == IToken.tDOT || LT(1) == IToken.tLBRACKET) {
while (LT(1) == IToken.tDOT || LT(1) == IToken.tLBRACKET) {
@@ -284,7 +286,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
IASTName n = createName(id);
designator.setName(n);
if (designatorList == Collections.EMPTY_LIST)
- designatorList = new ArrayList(DEFAULT_DESIGNATOR_LIST_SIZE);
+ designatorList = new ArrayList<IASTNode>(DEFAULT_DESIGNATOR_LIST_SIZE);
designatorList.add(designator);
} else if (LT(1) == IToken.tLBRACKET) {
IToken mark = consume();
@@ -296,7 +298,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
((ASTNode) designator).setOffsetAndLength(offset, lastOffset - offset);
designator.setSubscriptExpression(constantExpression);
if (designatorList == Collections.EMPTY_LIST)
- designatorList = new ArrayList(DEFAULT_DESIGNATOR_LIST_SIZE);
+ designatorList = new ArrayList<IASTNode>(DEFAULT_DESIGNATOR_LIST_SIZE);
designatorList.add(designator);
continue;
}
@@ -312,7 +314,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
designator.setRangeFloor(constantExpression1);
designator.setRangeCeiling(constantExpression2);
if (designatorList == Collections.EMPTY_LIST)
- designatorList = new ArrayList(DEFAULT_DESIGNATOR_LIST_SIZE);
+ designatorList = new ArrayList<IASTNode>(DEFAULT_DESIGNATOR_LIST_SIZE);
designatorList.add(designator);
}
} else if (supportGCCStyleDesignators
@@ -325,7 +327,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
IASTName n = createName(identifier);
designator.setName(n);
if (designatorList == Collections.EMPTY_LIST)
- designatorList = new ArrayList(DEFAULT_DESIGNATOR_LIST_SIZE);
+ designatorList = new ArrayList<IASTNode>(DEFAULT_DESIGNATOR_LIST_SIZE);
designatorList.add(designator);
}
}
@@ -346,7 +348,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
IASTName n = createName(identifier);
designator.setName(n);
if (designatorList == Collections.EMPTY_LIST)
- designatorList = new ArrayList(DEFAULT_DESIGNATOR_LIST_SIZE);
+ designatorList = new ArrayList<IASTNode>(DEFAULT_DESIGNATOR_LIST_SIZE);
designatorList.add(designator);
} else if (LT(1) == IToken.tLBRACKET) {
int startOffset = consume().getOffset();
@@ -359,7 +361,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
designator.setRangeFloor(constantExpression1);
designator.setRangeCeiling(constantExpression2);
if (designatorList == Collections.EMPTY_LIST)
- designatorList = new ArrayList(DEFAULT_DESIGNATOR_LIST_SIZE);
+ designatorList = new ArrayList<IASTNode>(DEFAULT_DESIGNATOR_LIST_SIZE);
designatorList.add(designator);
}
}
@@ -884,7 +886,8 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
if (t != null) {
consume(IToken.tRPAREN).getEndOffset();
if (LT(1) == IToken.tLBRACE) {
- IASTInitializer i = cInitializerClause(Collections.EMPTY_LIST);
+ final List<IASTNode> emptyList = Collections.emptyList();
+ IASTInitializer i = cInitializerClause(emptyList);
firstExpression = buildTypeIdInitializerExpression(t, i, offset, calculateEndOffset(i));
break;
}
@@ -1192,7 +1195,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
* @throws BacktrackException
* request a backtrack
*/
- protected void consumePointerOperators(List pointerOps)
+ protected void consumePointerOperators(List<IASTPointerOperator> pointerOps)
throws EndOfFileException, BacktrackException {
for (;;) {
// __attribute__ in-between pointers
@@ -1727,9 +1730,9 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
int startingOffset = la.getOffset();
int finalOffset = startingOffset;
la = null;
- List pointerOps = new ArrayList(DEFAULT_POINTEROPS_LIST_SIZE);
- List parameters = Collections.EMPTY_LIST;
- List arrayMods = Collections.EMPTY_LIST;
+ List<IASTPointerOperator> pointerOps = new ArrayList<IASTPointerOperator>(DEFAULT_POINTEROPS_LIST_SIZE);
+ List<IASTNode> parameters = Collections.emptyList();
+ List<IASTNode> arrayMods = Collections.emptyList();
boolean encounteredVarArgs = false;
IASTExpression bitField = null;
boolean isFunction = false;
@@ -1745,7 +1748,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
__attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers);
if (!pointerOps.isEmpty()) {
- finalOffset = calculateEndOffset((IASTPointerOperator) pointerOps
+ finalOffset = calculateEndOffset(pointerOps
.get(pointerOps.size() - 1));
}
@@ -1773,10 +1776,10 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
// count the number of K&R C parameters (0 K&R C parameters
// essentially means it's not K&R C)
- if( !knr )
+ if( !knr && supportKnRC)
numKnRCParms = countKnRCParms();
- if (supportKnRC && numKnRCParms > 0) { // KnR C parameters were found so
+ if (numKnRCParms > 0) { // KnR C parameters were found so
// handle the declarator accordingly
parmNames = new IASTName[numKnRCParms];
parmDeclarations = new IASTDeclaration[numKnRCParms];
@@ -1878,7 +1881,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
IASTParameterDeclaration pd = parameterDeclaration();
finalOffset = calculateEndOffset(pd);
if (parameters == Collections.EMPTY_LIST)
- parameters = new ArrayList(DEFAULT_PARAMETERS_LIST_SIZE);
+ parameters = new ArrayList<IASTNode>(DEFAULT_PARAMETERS_LIST_SIZE);
parameters.add(pd);
seenParameter = true;
}
@@ -1887,11 +1890,10 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
break;
case IToken.tLBRACKET:
if (arrayMods == Collections.EMPTY_LIST)
- arrayMods = new ArrayList(DEFAULT_POINTEROPS_LIST_SIZE);
+ arrayMods = new ArrayList<IASTNode>(DEFAULT_POINTEROPS_LIST_SIZE);
consumeArrayModifiers(arrayMods);
if (!arrayMods.isEmpty())
- finalOffset = calculateEndOffset((IASTArrayModifier) arrayMods
- .get(arrayMods.size() - 1));
+ finalOffset = calculateEndOffset(arrayMods.get(arrayMods.size() - 1));
continue;
case IToken.tCOLON:
consume();
@@ -1922,7 +1924,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
__attribute_decl_seq(supportAttributeSpecifiers, supportDeclspecSpecifiers);
IASTDeclarator d = null;
- if (numKnRCParms > 0) {
+ if (numKnRCParms > 0 && supportKnRC) {
ICASTKnRFunctionDeclarator functionDecltor = createKnRFunctionDeclarator();
parmDeclarations = (IASTDeclaration[]) ArrayUtil.removeNulls( IASTDeclaration.class, parmDeclarations );
for (int i = 0; i < parmDeclarations.length; ++i) {
@@ -1959,7 +1961,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
d = createDeclarator();
}
for (int i = 0; i < pointerOps.size(); ++i) {
- IASTPointerOperator po = (IASTPointerOperator) pointerOps.get(i);
+ IASTPointerOperator po = pointerOps.get(i);
d.addPointerOperator(po);
}
if (innerDecl != null) {
@@ -2021,7 +2023,7 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
return new CASTDeclarator();
}
- protected void consumeArrayModifiers(List arrayMods)
+ protected void consumeArrayModifiers(List<IASTNode> arrayMods)
throws EndOfFileException, BacktrackException {
while (LT(1) == IToken.tLBRACKET) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java
index 41d976295d2..de7ad22c899 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java
@@ -540,7 +540,7 @@ public class CPPASTTranslationUnit extends CPPASTNode implements ICPPASTTranslat
if (scope instanceof ICPPNamespaceScope) {
IScope result= fMappedScopes.get(scope);
if (result == null) {
- result= getScope().findNamespaecScope(scope);
+ result= getScope().findNamespaceScope(scope);
if (result == null) {
result= scope;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java
index f398ef9c90a..04f325ec8b4 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java
@@ -9,12 +9,10 @@
* IBM Corporation - initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
-/*
- * Created on Nov 29, 2004
- */
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.IName;
+import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IScope;
@@ -22,14 +20,16 @@ import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPSemantics.LookupData;
import org.eclipse.cdt.internal.core.index.IIndexScope;
/**
* @author aniefer
*/
public class CPPNamespaceScope extends CPPScope implements ICPPNamespaceScope{
- IASTNode[] usings = null;
+ ICPPUsingDirective[] usings = null;
public CPPNamespaceScope( IASTNode physicalNode ) {
super( physicalNode );
@@ -38,14 +38,18 @@ public class CPPNamespaceScope extends CPPScope implements ICPPNamespaceScope{
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope#getUsingDirectives()
*/
- public IASTNode[] getUsingDirectives() {
- return (IASTNode[]) ArrayUtil.trim( IASTNode.class, usings, true );
+ public ICPPUsingDirective[] getUsingDirectives() throws DOMException {
+ if (!isFullyCached()) {
+ LookupData ld= new LookupData();
+ CPPSemantics.lookupInScope(ld, this, null);
+ }
+ return (ICPPUsingDirective[]) ArrayUtil.trim( ICPPUsingDirective.class, usings, true );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope#addUsingDirective(org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective)
*/
- public void addUsingDirective(IASTNode directive) {
- usings = (IASTNode[]) ArrayUtil.append( IASTNode.class, usings, directive );
+ public void addUsingDirective(ICPPUsingDirective directive) {
+ usings = (ICPPUsingDirective[]) ArrayUtil.append( ICPPUsingDirective.class, usings, directive );
}
/* (non-Javadoc)
@@ -59,7 +63,7 @@ public class CPPNamespaceScope extends CPPScope implements ICPPNamespaceScope{
return null;
}
- public IScope findNamespaecScope(IIndexScope scope) {
+ public IScope findNamespaceScope(IIndexScope scope) {
final String[] qname= scope.getScopeBinding().getQualifiedName();
final IScope[] result= {null};
final CPPASTVisitor visitor= new CPPASTVisitor () {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java
index 83d15c99eb7..879b8aba254 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java
@@ -13,6 +13,14 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
@@ -90,6 +98,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
@@ -100,7 +109,6 @@ 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.ICPPMember;
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.ICPPNamespaceScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
@@ -115,15 +123,14 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
-import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.core.parser.util.ObjectSet;
-import org.eclipse.cdt.core.parser.util.ArrayUtil.ArrayWrapper;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
@@ -144,8 +151,9 @@ public class CPPSemantics {
static protected class LookupData
{
protected IASTName astName;
- public ObjectMap usingDirectives = ObjectMap.EMPTY_MAP;
- public ObjectSet visited = ObjectSet.EMPTY_SET; //used to ensure we don't visit things more than once
+ protected CPPASTTranslationUnit tu;
+ public Map<ICPPNamespaceScope, List<ICPPNamespaceScope>> usingDirectives= Collections.emptyMap();
+ public ObjectSet visited= new ObjectSet(1); //used to ensure we don't visit things more than once
public ObjectSet inheritanceChain; //used to detect circular inheritance
public ObjectSet associated = ObjectSet.EMPTY_SET;
@@ -167,6 +175,7 @@ public class CPPSemantics {
public LookupData( IASTName n ){
astName = n;
+ tu= (CPPASTTranslationUnit) astName.getTranslationUnit();
typesOnly = typesOnly();
considerConstructors = considerConstructors();
checkWholeClassScope = checkWholeClassScope();
@@ -292,7 +301,8 @@ public class CPPSemantics {
if( astName.getPropertyInParent() == STRING_LOOKUP_PROPERTY ) return false;
IASTNode p1 = astName.getParent();
if( p1 instanceof ICPPASTQualifiedName ){
- return ((ICPPASTQualifiedName)p1).getNames()[0] != astName;
+ final IASTName[] qnames = ((ICPPASTQualifiedName)p1).getNames();
+ return qnames.length == 1 || qnames[0] != astName;
}
return p1 instanceof ICPPASTFieldReference;
}
@@ -858,7 +868,7 @@ public class CPPSemantics {
IType p = ps[i];
p = getUltimateType( p, true );
try {
- getAssociatedScopes( p, namespaces, classes, (CPPASTTranslationUnit) data.astName.getTranslationUnit());
+ getAssociatedScopes( p, namespaces, classes, data.tu);
} catch ( DOMException e ) {
}
}
@@ -1011,9 +1021,8 @@ public class CPPSemantics {
IIndexFileSet fileSet= IIndexFileSet.EMPTY;
if (node != null) {
- final IASTTranslationUnit tu= node.getTranslationUnit();
- if (tu != null) {
- final IIndexFileSet fs= (IIndexFileSet) tu.getAdapter(IIndexFileSet.class);
+ if (data.tu != null) {
+ final IIndexFileSet fs= (IIndexFileSet) data.tu.getAdapter(IIndexFileSet.class);
if (fs != null) {
fileSet= fs;
}
@@ -1040,7 +1049,6 @@ public class CPPSemantics {
while( scope != null ){
IASTNode blockItem = CPPVisitor.getContainingBlockItem( node );
- ArrayWrapper directives = null;
if( !data.usingDirectivesOnly ){
if( ASTInternal.isFullyCached(scope) ){
if (!data.contentAssist && data.astName != null) {
@@ -1089,36 +1097,29 @@ public class CPPSemantics {
}
}
- if( (!data.hasResults() || data.contentAssist) && scope instanceof ICPPNamespaceScope ){
- directives = new ArrayWrapper();
- directives.array = ((ICPPNamespaceScope) scope).getUsingDirectives();
- if( directives.array != null ){
- for( int i = 0; i < directives.array.length; i++ ){
- if( !CPPSemantics.declaredBefore( directives.array[i], blockItem ) ){
- directives.array[i] = null;
- directives.array = ArrayUtil.trim( IASTNode.class, directives.array );
+ // store using-directives found in this block or namespace for later use.
+ if( (!data.hasResults() || !data.qualified() || data.contentAssist) && scope instanceof ICPPNamespaceScope ){
+ final ICPPNamespaceScope blockScope= (ICPPNamespaceScope) scope;
+ if (! (blockScope instanceof ICPPBlockScope)) {
+ data.visited.put(blockScope); // namespace has been searched.
+ }
+ ICPPUsingDirective[] uds= blockScope.getUsingDirectives();
+ if( uds != null && uds.length > 0) {
+ HashSet<ICPPNamespaceScope> handled= new HashSet<ICPPNamespaceScope>();
+ for( int i = 0; i < uds.length; i++ ){
+ final ICPPUsingDirective ud = uds[i];
+ if( CPPSemantics.declaredBefore( ud, blockItem ) ){
+ storeUsingDirective(data, blockScope, ud, handled);
}
}
}
}
}
-
- if( !data.ignoreUsingDirectives ) {
- data.visited.clear();
- if( data.contentAssist || !data.hasResults() ){
- Object[] transitives = lookupInNominated( data, scope, null );
-
- processDirectives( data, scope, transitives );
- if( directives != null && directives.array != null && directives.array.length != 0 )
- processDirectives( data, scope, directives.array );
-
- while( !data.usingDirectives.isEmpty() && data.usingDirectives.get( scope ) != null ){
- transitives = lookupInNominated( data, scope, transitives );
-
- if( !data.qualified() || ( data.contentAssist || !data.hasResults()) ){
- processDirectives( data, scope, transitives );
- }
- }
+
+ // lookup in nominated namespaces
+ if( !data.ignoreUsingDirectives && scope instanceof ICPPNamespaceScope && !(scope instanceof ICPPBlockScope)) {
+ if( !data.hasResults() || !data.qualified() || data.contentAssist) {
+ lookupInNominated(data, (ICPPNamespaceScope) scope);
}
}
@@ -1146,7 +1147,7 @@ public class CPPSemantics {
if( blockItem != null )
node = blockItem;
- ICPPScope parentScope = (ICPPScope) getParentScope(scope, (CPPASTTranslationUnit) node.getTranslationUnit());
+ ICPPScope parentScope = (ICPPScope) getParentScope(scope, data.tu);
if( parentScope instanceof ICPPTemplateScope ){
IASTNode parent = node.getParent();
while( parent != null && !(parent instanceof ICPPASTTemplateDeclaration) ){
@@ -1221,8 +1222,6 @@ public class CPPSemantics {
if( !bases[i].isVirtual() || !data.visited.containsKey( parent ) ){
if( bases[i].isVirtual() ){
- if( data.visited == ObjectSet.EMPTY_SET )
- data.visited = new ObjectSet(2);
data.visited.put( parent );
}
@@ -1313,8 +1312,6 @@ public class CPPSemantics {
if (b instanceof ICPPClassType) {
IScope bScope = ((ICPPClassType)b).getCompositeScope();
if( bases[i].isVirtual() ){
- if( data.visited == ObjectSet.EMPTY_SET )
- data.visited = new ObjectSet(2);
if (bScope != null)
data.visited.put(bScope);
} else if ( bScope != null ) {
@@ -1385,53 +1382,55 @@ public class CPPSemantics {
return false;
}
- static private void processDirectives( CPPSemantics.LookupData data, IScope scope, Object[] directives ) throws DOMException{
- if( directives == null || directives.length == 0 )
+ /**
+ * Stores the using directive with the scope where the members of the nominated namespace will appear.
+ * In case of an unqualified lookup the transitive directives are stored, also. This is important because
+ * the members nominated by a transitive directive can appear before those of the original directive.
+ */
+ static private void storeUsingDirective(CPPSemantics.LookupData data, ICPPNamespaceScope container,
+ ICPPUsingDirective directive, Set<ICPPNamespaceScope> handled) throws DOMException {
+ final ICPPNamespaceScope nominated= directive.getNamespace().getNamespaceScope();
+ if (nominated == null || data.visited.containsKey(nominated) || (handled != null && !handled.add(nominated))) {
return;
-
- ICPPScope enclosing = null;
- IScope temp = null;
-
- int size = directives.length;
- for( int i = 0; i < size && directives[i] != null; i++ ){
- Object d = directives[i];
- IBinding binding = null;
- if( d instanceof ICPPASTUsingDirective ){
- binding = ((ICPPASTUsingDirective)d).getQualifiedName().resolveBinding();
- } else if( d instanceof ICPPASTNamespaceDefinition ){
- binding = ((ICPPASTNamespaceDefinition)d).getName().resolveBinding();
- }
- if( binding instanceof ICPPNamespace ){
- temp = ((ICPPNamespace)binding).getNamespaceScope();
- } else
- continue;
-
- //namespace are searched at most once
- if( !data.visited.containsKey( temp ) ){
- enclosing = getClosestEnclosingScope( scope, temp, (CPPASTTranslationUnit) data.astName.getTranslationUnit());
-
- //data.usingDirectives is a map from enclosing scope to a IScope[]
- //of namespaces to consider when we reach that enclosing scope
- IScope [] scopes = (IScope[]) ( data.usingDirectives.isEmpty() ? null : data.usingDirectives.get( enclosing ) );
- scopes = (IScope[]) ArrayUtil.append( IScope.class, scopes, temp );
- if( data.usingDirectives == ObjectMap.EMPTY_MAP ){
- data.usingDirectives = new ObjectMap(2);
+ }
+ // 7.3.4.1 names appear at end of common enclosing scope of container and nominated scope.
+ final IScope appearsIn= getCommonEnclosingScope(nominated, container, data.tu);
+ if (appearsIn instanceof ICPPNamespaceScope) {
+ // store the directive with the scope where it has to be considered
+ List<ICPPNamespaceScope> listOfNominated= data.usingDirectives.get(appearsIn);
+ if (listOfNominated == null) {
+ listOfNominated= new ArrayList<ICPPNamespaceScope>(1);
+ if (data.usingDirectives.isEmpty()) {
+ data.usingDirectives= new HashMap<ICPPNamespaceScope, List<ICPPNamespaceScope>>();
}
- data.usingDirectives.put( enclosing, scopes );
+ data.usingDirectives.put((ICPPNamespaceScope) appearsIn, listOfNominated);
}
+ listOfNominated.add(nominated);
}
+ // in a non-qualified lookup the transitive directive have to be stored right away, they may overtake the
+ // container.
+ if (!data.qualified() || data.contentAssist) {
+ assert handled != null;
+ ICPPUsingDirective[] transitive= nominated.getUsingDirectives();
+ for (int i = 0; i < transitive.length; i++) {
+ storeUsingDirective(data, container, transitive[i], handled);
+ }
+ }
}
- static private ICPPScope getClosestEnclosingScope( IScope scope1, IScope scope2, CPPASTTranslationUnit tu) throws DOMException{
+ /**
+ * Computes the common enclosing scope of s1 and s2.
+ */
+ static private ICPPScope getCommonEnclosingScope(IScope s1, IScope s2, CPPASTTranslationUnit tu) throws DOMException {
ObjectSet set = new ObjectSet( 2 );
- IScope parent = scope1;
+ IScope parent= s1;
while( parent != null ){
set.put( parent );
- parent = getParentScope(parent, tu);
+ parent= getParentScope(parent, tu);
}
- parent = scope2;
- while( parent != null && !set.containsKey( parent ) ){
+ parent= s2;
+ while(parent != null && !set.containsKey( parent ) ){
parent = getParentScope(parent, tu);
}
return (ICPPScope) parent;
@@ -1520,12 +1519,19 @@ public class CPPSemantics {
if( item instanceof IASTDeclarationStatement )
item = ((IASTDeclarationStatement)item).getDeclaration();
- if( item instanceof ICPPASTUsingDirective ||
- (item instanceof ICPPASTNamespaceDefinition &&
- ((ICPPASTNamespaceDefinition)item).getName().toCharArray().length == 0) )
- {
- if( scope instanceof ICPPNamespaceScope )
- ((ICPPNamespaceScope)scope).addUsingDirective( item );
+ if( item instanceof ICPPASTUsingDirective ) {
+ if( scope instanceof ICPPNamespaceScope ) {
+ final ICPPNamespaceScope nsscope = (ICPPNamespaceScope)scope;
+ final ICPPASTUsingDirective usingDirective = (ICPPASTUsingDirective) item;
+ nsscope.addUsingDirective(new CPPUsingDirective(usingDirective));
+ }
+ } else if (item instanceof ICPPASTNamespaceDefinition &&
+ ((ICPPASTNamespaceDefinition)item).getName().toCharArray().length == 0) {
+ if( scope instanceof ICPPNamespaceScope ) {
+ final ICPPNamespaceScope nsscope = (ICPPNamespaceScope)scope;
+ final ICPPASTNamespaceDefinition nsdef= (ICPPASTNamespaceDefinition) item;
+ nsscope.addUsingDirective(new CPPUsingDirective(nsdef));
+ }
} else {
//possible is IASTName or IASTName[]
possible = collectResult( data, scope, item, (item == parent) );
@@ -1612,63 +1618,49 @@ public class CPPSemantics {
return found;
}
- static private Object[] lookupInNominated( CPPSemantics.LookupData data, ICPPScope scope, Object[] transitives ) throws DOMException{
- if( data.usingDirectives.isEmpty() )
- return transitives;
-
- ICPPScope temp = null;
-
- IScope [] directives = (IScope[]) data.usingDirectives.remove( scope );
- if( directives == null || directives.length == 0 ) {
- return transitives;
- }
- for( int i = 0; i < directives.length && directives[i] != null; i++ ){
- temp = (ICPPScope) directives[i];
- if( !data.visited.containsKey( temp ) ){
- if( data.visited == ObjectSet.EMPTY_SET ) {
- data.visited = new ObjectSet(2);
+ /**
+ * Perform lookup in nominated namespaces that appear in the given scope. For unqualified lookups the method assumes
+ * that transitive directives have been stored in the lookup-data. For qualified lookups the transitive directives
+ * are considered if the lookup of the original directive returns empty.
+ */
+ static private void lookupInNominated(CPPSemantics.LookupData data, ICPPNamespaceScope scope) throws DOMException{
+ List<ICPPNamespaceScope> allNominated= data.usingDirectives.remove(scope);
+ while (allNominated != null) {
+ for (ICPPNamespaceScope nominated : allNominated) {
+ if (data.visited.containsKey(nominated)) {
+ continue;
}
- data.visited.put( temp );
- ArrayWrapper usings = new ArrayWrapper();
-
+ data.visited.put(nominated);
+
boolean found = false;
- if( ASTInternal.isFullyCached(temp) ) {
- if ( !data.contentAssist ){
- IBinding binding = temp.getBinding( data.astName, true );
- if( binding != null &&
- ( CPPSemantics.declaredBefore( binding, data.astName ) ||
- (scope instanceof ICPPClassScope && data.checkWholeClassScope) ) )
- {
- mergeResults( data, binding, true );
- found = true;
- }
- } else {
- IBinding[] bindings = temp.getBindings( data.astName, true, data.prefixLookup );
- if (bindings != null && bindings.length > 0) {
- mergeResults( data, bindings, true );
- found = true;
- }
+ if (ASTInternal.isFullyCached(nominated)) {
+ IBinding[] bindings= nominated.getBindings(data.astName, true, data.prefixLookup);
+ if (bindings != null && bindings.length > 0) {
+ mergeResults( data, bindings, true );
+ found = true;
}
} else {
- IASTName [] f = lookupInScope( data, temp, null );
+ IASTName [] f = lookupInScope( data, nominated, null );
if( f != null ) {
mergeResults( data, f, true );
found = true;
}
}
- if( !found && temp instanceof ICPPNamespaceScope ){
- usings.array = ((ICPPNamespaceScope) temp).getUsingDirectives();
- }
-
- //only consider the transitive using directives if we are an unqualified
- //lookup, or we didn't find the name in decl
- if( usings.array != null && usings.array.length > 0 && (!data.qualified() || !found ) ){
- transitives = ArrayUtil.addAll( Object.class, transitives, usings.array );
+ // in the qualified lookup we have to nominate the transitive directives only when
+ // the lookup did not succeed. In the qualified case this is done earlier, when the directive
+ // is encountered.
+ if (!found && data.qualified() && !data.contentAssist) {
+ ICPPUsingDirective[] usings= nominated.getUsingDirectives();
+ for (int i = 0; i < usings.length; i++) {
+ ICPPUsingDirective using = usings[i];
+ storeUsingDirective(data, scope, using, null);
+ }
}
}
+ // retry with transitive directives that may have been nominated in a qualified lookup
+ allNominated= data.usingDirectives.remove(scope);
}
- return transitives;
}
static private Object collectResult( CPPSemantics.LookupData data, ICPPScope scope, IASTNode node, boolean checkAux ) throws DOMException{
@@ -1924,12 +1916,14 @@ public class CPPSemantics {
static public boolean declaredBefore( Object obj, IASTNode node ){
if( node == null ) return true;
if( node.getPropertyInParent() == STRING_LOOKUP_PROPERTY ) return true;
+ final int pointOfRef= ((ASTNode) node).getOffset();
ASTNode nd = null;
if( obj instanceof ICPPSpecialization ){
obj = ((ICPPSpecialization)obj).getSpecializedBinding();
}
+ int pointOfDecl= -1;
if( obj instanceof ICPPInternalBinding ){
ICPPInternalBinding cpp = (ICPPInternalBinding) obj;
IASTNode[] n = cpp.getDeclarations();
@@ -1945,10 +1939,11 @@ public class CPPSemantics {
return true;
} else if( obj instanceof ASTNode ){
nd = (ASTNode) obj;
+ } else if( obj instanceof ICPPUsingDirective) {
+ pointOfDecl= ((ICPPUsingDirective) obj).getPointOfDeclaration();
}
- if( nd != null ){
- int pointOfDecl = 0;
+ if( pointOfDecl < 0 && nd != null ){
ASTNodeProperty prop = nd.getPropertyInParent();
//point of declaration for a name is immediately after its complete declarator and before its initializer
if( prop == IASTDeclarator.DECLARATOR_NAME || nd instanceof IASTDeclarator ){
@@ -1978,11 +1973,8 @@ public class CPPSemantics {
pointOfDecl = nd.getOffset() + nd.getLength();
} else
pointOfDecl = nd.getOffset() + nd.getLength();
-
- return ( pointOfDecl < ((ASTNode)node).getOffset() );
-
}
- return true; // TODO - I changed this to true
+ return ( pointOfDecl < pointOfRef );
}
static private IBinding resolveAmbiguities( CPPSemantics.LookupData data, IASTName name ) throws DOMException {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUsingDirective.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUsingDirective.java
new file mode 100644
index 00000000000..7c41abe9df9
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUsingDirective.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.ast.DOMException;
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IBinding;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective;
+import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
+
+/**
+ * Represents a using-directive found in the AST.
+ */
+public class CPPUsingDirective implements ICPPUsingDirective {
+
+ private IASTName fNamespaceName;
+
+ /**
+ * Constructor for explicit using directives
+ */
+ public CPPUsingDirective(ICPPASTUsingDirective node) {
+ fNamespaceName= node.getQualifiedName();
+ }
+
+ /**
+ * Constructor for unnamed namespaces introducing an implicit using directive.
+ */
+ public CPPUsingDirective(ICPPASTNamespaceDefinition nsdef) {
+ fNamespaceName= nsdef.getName();
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective#getNamespaceScope()
+ */
+ public ICPPNamespace getNamespace() throws DOMException {
+ IBinding binding= fNamespaceName.resolveBinding();
+ if (binding instanceof ICPPNamespace) {
+ return (ICPPNamespace) binding;
+ }
+ return null;
+ }
+
+ /* (non-Javadoc)
+ * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective#getPointOfDeclaration()
+ */
+ public int getPointOfDeclaration() {
+ final ASTNode astNode = (ASTNode) fNamespaceName;
+ return astNode.getOffset() + astNode.getLength();
+ }
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPNamespaceScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPNamespaceScope.java
index 3441182570d..702e8455a64 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPNamespaceScope.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPNamespaceScope.java
@@ -6,18 +6,19 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * Andrew Ferguson (Symbian) - Initial implementation
+ * Andrew Ferguson (Symbian) - Initial implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.index.composite.cpp;
import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName;
-import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective;
import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
@@ -33,12 +34,12 @@ class CompositeCPPNamespaceScope extends CompositeScope implements ICPPNamespace
this.namespaces = namespaces;
}
- public void addUsingDirective(IASTNode directive) throws DOMException {
+ public void addUsingDirective(ICPPUsingDirective directive) throws DOMException {
fail();
}
- public IASTNode[] getUsingDirectives() throws DOMException {
- return new IASTNode[0]; // same behaviour as PDOMCPPNamespace
+ public ICPPUsingDirective[] getUsingDirectives() throws DOMException {
+ return new ICPPUsingDirective[0]; // same behavior as PDOMCPPNamespace
}
public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet fileSet)
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPNamespace.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPNamespace.java
index eb00dedbdfd..52b95eb6e88 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPNamespace.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPNamespace.java
@@ -6,12 +6,11 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * QNX - Initial API and implementation
- * Markus Schorn (Wind River Systems)
- * Andrew Ferguson (Symbian)
- * Bryan Wilkinson (QNX)
+ * QNX - Initial API and implementation
+ * Markus Schorn (Wind River Systems)
+ * Andrew Ferguson (Symbian)
+ * Bryan Wilkinson (QNX)
*******************************************************************************/
-
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import java.util.ArrayList;
@@ -21,12 +20,12 @@ import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName;
-import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective;
import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.core.index.IndexFilter;
@@ -106,9 +105,8 @@ class PDOMCPPNamespace extends PDOMCPPBinding
return this;
}
- public IASTNode[] getUsingDirectives() throws DOMException {
- // TODO
- return new IASTNode[0];
+ public ICPPUsingDirective[] getUsingDirectives() throws DOMException {
+ return new ICPPUsingDirective[0];
}
public IBinding[] find(String name) {
@@ -160,7 +158,7 @@ class PDOMCPPNamespace extends PDOMCPPBinding
if (result != null) {
return result;
}
- BindingCollector visitor = new BindingCollector(getLinkageImpl(), name, null, false, true);
+ BindingCollector visitor = new BindingCollector(getLinkageImpl(), name, IndexFilter.ALL_DECLARED_OR_IMPLICIT, false, true);
getIndex().accept(visitor);
result = visitor.getBindings();
pdom.putCachedResult(key, result);
@@ -195,7 +193,7 @@ class PDOMCPPNamespace extends PDOMCPPBinding
return result;
}
- public void addUsingDirective(IASTNode directive) throws DOMException {fail();}
+ public void addUsingDirective(ICPPUsingDirective directive) throws DOMException {fail();}
public IIndexBinding getScopeBinding() {
return this;

Back to the top