mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Fixes name-resolution with using-directives, related to bug 26110.
This commit is contained in:
parent
00091c99cb
commit
c754042629
13 changed files with 331 additions and 237 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(':');
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 () {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue