From d69b51acc8971fa3799873961d1ce63b554b7bfb Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Thu, 27 Oct 2016 20:14:27 -0700 Subject: [PATCH] Bug 506668 - Name resolution problem with namespace alias in macro expansion Change-Id: I15a0198c588cbb0e044392f47367679bb90180a6 --- .../core/parser/tests/ast2/AST2CPPTests.java | 15 +++++++++++++-- .../parser/cpp/semantics/CPPSemantics.java | 19 +++++++++++++------ 2 files changed, 26 insertions(+), 8 deletions(-) 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 f457c863bc3..581a80d4a2a 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 @@ -30,8 +30,6 @@ import java.io.StringReader; import java.util.Arrays; import java.util.HashSet; -import junit.framework.TestSuite; - import org.eclipse.cdt.core.dom.IName; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.EScopeKind; @@ -157,6 +155,8 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.index.IndexCPPSignatureUtil; import org.eclipse.cdt.internal.core.parser.ParserException; +import junit.framework.TestSuite; + public class AST2CPPTests extends AST2TestBase { public AST2CPPTests() { @@ -3742,6 +3742,17 @@ public class AST2CPPTests extends AST2TestBase { assertTrue(alias.isGloballyQualified()); } + // namespace ns { struct A {}; } + // + // #define MACRO []() { namespace waldo = ::ns; waldo::A x; return x; }() + // + // void test() { + // MACRO; + // } + public void testNamespaceAliasInMacroExpansion_506668() throws Exception { + parseAndCheckBindings(); + } + // class A{}; // class B : public A { // B () : A() {} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index abdd2fcdc88..77fed825f64 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -1930,6 +1930,7 @@ public class CPPSemantics { } int pointOfDecl= -1; + boolean pointOfDeclIsEndOffset = false; if (obj instanceof ICPPInternalBinding) { ICPPInternalBinding cpp = (ICPPInternalBinding) obj; IASTNode[] n = cpp.getDeclarations(); @@ -1937,9 +1938,8 @@ public class CPPSemantics { nd = (ASTNode) n[0]; } ASTNode def = (ASTNode) cpp.getDefinition(); - if (def != null) { - if (nd == null || def.getOffset() < nd.getOffset()) - nd = def; + if (def != null && (nd == null || def.getOffset() < nd.getOffset())) { + nd = def; } if (nd == null) return true; @@ -1974,10 +1974,12 @@ public class CPPSemantics { // because function parameter declarations implement ICPPASTTemplateParameter too. boolean isTemplateParameter = dtor.getParent() instanceof ICPPASTTemplateParameter && dtor.getParent().getPropertyInParent() == ICPPASTTemplateDeclaration.PARAMETER; - if (init != null && !isTemplateParameter) + if (init != null && !isTemplateParameter) { pointOfDecl = ((ASTNode) init).getOffset() - 1; - else + } else { pointOfDecl = ((ASTNode) dtor).getOffset() + ((ASTNode) dtor).getLength(); + pointOfDeclIsEndOffset = true; + } } else if (prop == IASTEnumerator.ENUMERATOR_NAME) { // Point of declaration for an enumerator is immediately after it // enumerator-definition @@ -1988,17 +1990,20 @@ public class CPPSemantics { } else { pointOfDecl = nd.getOffset() + nd.getLength(); } + pointOfDeclIsEndOffset = true; } else if (prop == ICPPASTUsingDeclaration.NAME) { nd = (ASTNode) nd.getParent(); pointOfDecl = nd.getOffset(); } else if (prop == ICPPASTNamespaceAlias.ALIAS_NAME) { nd = (ASTNode) nd.getParent(); pointOfDecl = nd.getOffset() + nd.getLength(); + pointOfDeclIsEndOffset = true; } else if (prop == ICPPASTAliasDeclaration.ALIAS_NAME) { // [basic.scope.pdecl]/p3: The point of declaration of an alias or alias template // immediately follows the type-id to which the alias refers. ASTNode targetType = (ASTNode) ((ICPPASTAliasDeclaration) nd.getParent()).getMappingTypeId(); pointOfDecl = targetType.getOffset() + targetType.getLength(); + pointOfDeclIsEndOffset = true; } else if (prop == ICPPASTSimpleTypeTemplateParameter.PARAMETER_NAME || prop == ICPPASTTemplatedTypeTemplateParameter.PARAMETER_NAME) { // [basic.scope.pdecl]/p9: The point of declaration for a template parameter @@ -2008,11 +2013,13 @@ public class CPPSemantics { // case above. nd = (ASTNode) nd.getParent(); pointOfDecl = nd.getOffset() + nd.getLength(); + pointOfDeclIsEndOffset = true; } else { pointOfDecl = nd.getOffset() + nd.getLength(); + pointOfDeclIsEndOffset = true; } } - return (pointOfDecl < pointOfRef); + return pointOfDecl < pointOfRef || (pointOfDecl == pointOfRef && pointOfDeclIsEndOffset); } private static boolean acceptDeclaredAfter(ICPPInternalBinding cpp) {