1
0
Fork 0
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:
Markus Schorn 2008-02-08 13:51:56 +00:00
parent 00091c99cb
commit c754042629
13 changed files with 331 additions and 237 deletions

View file

@ -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);
}
/**

View file

@ -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);

View file

@ -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;

View file

@ -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(':');

View file

@ -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;
}

View file

@ -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();
}

View file

@ -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) {

View file

@ -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;
}

View file

@ -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 () {

View file

@ -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 {

View file

@ -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();
}
}

View file

@ -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)

View file

@ -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;