diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index c12c0f5d2c6..8bf3732feb7 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -2871,5 +2871,16 @@ public class AST2CPPTests extends AST2BaseTest { assertTrue( t instanceof IGPPPointerToMemberType ); assertTrue( ((IGPPPointerToMemberType) t).isRestrict() ); } + + public void testBug87705() throws Exception { + IASTTranslationUnit tu = parse( "class A { friend class B::C; };", ParserLanguage.CPP, true ); //$NON-NLS-1$ + CPPNameCollector col = new CPPNameCollector(); + tu.accept(col); + + IProblemBinding B = (IProblemBinding) col.getName(2).resolveBinding(); + assertEquals( B.getID(), IProblemBinding.SEMANTIC_NAME_NOT_FOUND ); + IProblemBinding C = (IProblemBinding) col.getName(3).resolveBinding(); + assertEquals( C.getID(), IProblemBinding.SEMANTIC_BAD_SCOPE ); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/DOMException.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/DOMException.java index 2d41ea2e3d7..1bb318c12cf 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/DOMException.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/DOMException.java @@ -31,7 +31,7 @@ public class DOMException extends Exception { * */ public DOMException( IProblemBinding problem ) { - super( problem != null ? problem.getMessage() : CPPSemantics.EMPTY_NAME ); + super( CPPSemantics.EMPTY_NAME ); problemBinding = problem; } @@ -43,4 +43,8 @@ public class DOMException extends Exception { public IProblemBinding getProblem(){ return problemBinding; } + + public String getMessage() { + return problemBinding.getMessage(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IProblemBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IProblemBinding.java index 60032ffc4bd..8ce3e0528fa 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IProblemBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IProblemBinding.java @@ -93,5 +93,10 @@ public interface IProblemBinding extends IBinding, IScope, IType { */ public static final int SEMANTIC_LABEL_STATEMENT_NOT_FOUND = 0x009; - public static final int LAST_PROBLEM = SEMANTIC_LABEL_STATEMENT_NOT_FOUND; + /** + * there was a problem creating the scope + */ + public static final int SEMANTIC_BAD_SCOPE = 0x00A; + + public static final int LAST_PROBLEM = SEMANTIC_BAD_SCOPE; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java index a22b7a2fbdc..2636f31daff 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java @@ -52,6 +52,7 @@ public class ProblemBinding implements IProblemBinding, IType, IScope { errorMessages[SEMANTIC_DEFINITION_NOT_FOUND - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.dom.definitionNotFound"); //$NON-NLS-1$ errorMessages[SEMANTIC_KNR_PARAMETER_DECLARATION_NOT_FOUND - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.dom.knrParameterDeclarationNotFound"); //$NON-NLS-1$ errorMessages[SEMANTIC_LABEL_STATEMENT_NOT_FOUND - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.dom.labelStatementNotFound"); //$NON-NLS-1$ + errorMessages[SEMANTIC_BAD_SCOPE - 1] = ParserMessages.getString("ASTProblemFactory.error.semantic.dom.badScope"); //$NON-NLS-1$ } /* (non-Javadoc) @@ -68,7 +69,7 @@ public class ProblemBinding implements IProblemBinding, IType, IScope { if (message != null) return message; - String msg = ( id >= 0 && id < LAST_PROBLEM ) ? errorMessages[ id - 1 ] : ""; //$NON-NLS-1$ + String msg = ( id >= 0 && id <= LAST_PROBLEM ) ? errorMessages[ id - 1 ] : ""; //$NON-NLS-1$ if (arg != null) { msg = MessageFormat.format(msg, new Object[] { new String(arg) }); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java index d6e4b4f9098..af0ac4e28db 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java @@ -127,9 +127,11 @@ public class CPPVisitor { { binding = CPPSemantics.resolveBinding( name ); if( binding instanceof IProblemBinding && parent instanceof ICPPASTQualifiedName ){ - //if( ((IProblemBinding)binding).getID() == IProblemBinding.SEMANTIC_NAME_NOT_FOUND ){ + IASTName [] ns = ((ICPPASTQualifiedName)parent).getNames(); + if( ns[ ns.length - 1 ] == name ) parent = parent.getParent(); - //} + else + return binding; } else { return binding; } @@ -233,12 +235,19 @@ public class CPPVisitor { IBinding binding = null; boolean mustBeSimple = true; boolean isFriend = false; + boolean qualified = false; + IASTName name = elabType.getName(); + if( name instanceof ICPPASTQualifiedName ){ + qualified = true; + IASTName [] ns = ((ICPPASTQualifiedName)name).getNames(); + name = ns[ ns.length - 1 ]; + } if( parent instanceof IASTSimpleDeclaration ){ IASTDeclarator [] dtors = ((IASTSimpleDeclaration)parent).getDeclarators(); ICPPASTDeclSpecifier declSpec = (ICPPASTDeclSpecifier) ((IASTSimpleDeclaration)parent).getDeclSpecifier(); isFriend = declSpec.isFriend() && dtors.length == 0; if( dtors.length > 0 || isFriend ){ - binding = CPPSemantics.resolveBinding( elabType.getName() ); + binding = CPPSemantics.resolveBinding( name ); mustBeSimple = !isFriend; } else { mustBeSimple = false; @@ -261,7 +270,7 @@ public class CPPVisitor { if( mustBeSimple && elabType.getName() instanceof ICPPASTQualifiedName ) return binding; - ICPPScope scope = (ICPPScope) getContainingScope( elabType ); + ICPPScope scope = (ICPPScope) getContainingScope( name ); if( mustBeSimple ){ //3.3.1-5 ... the identifier is declared in the smallest non-class non-function-prototype scope that contains @@ -273,7 +282,7 @@ public class CPPVisitor { } } } - if( scope instanceof ICPPClassScope && isFriend ){ + if( scope instanceof ICPPClassScope && isFriend && !qualified ){ try { while( scope instanceof ICPPClassScope ) scope = (ICPPScope) scope.getParent(); @@ -578,7 +587,7 @@ public class CPPVisitor { } else if( binding instanceof IProblemBinding ){ if( binding instanceof ICPPScope ) return (IScope) binding; - return new CPPScope.CPPScopeProblem( -1, names[i-1].toCharArray() ); + return new CPPScope.CPPScopeProblem( IProblemBinding.SEMANTIC_BAD_SCOPE, names[i-1].toCharArray() ); } } else if( ((ICPPASTQualifiedName)parent).isFullyQualified() ) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.properties b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.properties index 9c2bf825ae8..838f3eee153 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.properties +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserMessages.properties @@ -79,4 +79,5 @@ ASTProblemFactory.error.semantic.pst.recursiveTemplateInstantiation=Possible inf ASTProblemFactory.error.semantic.dom.definitionNotFound=A definition was not found for {0} ASTProblemFactory.error.semantic.dom.knrParameterDeclarationNotFound=A declaration was not found for the k&r parameter {0} -ASTProblemFactory.error.semantic.dom.labelStatementNotFound=A label statement was not found for the name {0} \ No newline at end of file +ASTProblemFactory.error.semantic.dom.labelStatementNotFound=A label statement was not found for the name {0} +ASTProblemFactory.error.semantic.dom.badScope=A scope could not be created to represent the name {0} \ No newline at end of file