From db59f8081204b3fc45d17b4c9bc80c0520d4aa79 Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Fri, 13 Jan 2017 00:10:37 -0500 Subject: [PATCH] Bug 483824 - Inline namespace reopened without inline keyword Change-Id: I48a066e6572e92b4fee90a8faa532469ea3c12e2 --- .../index/tests/IndexCPPBindingResolutionTest.java | 14 ++++++++++++++ .../cdt/internal/core/dom/parser/cpp/CPPScope.java | 2 +- .../dom/parser/cpp/semantics/CPPSemantics.java | 10 +++++++++- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java index 8223d492c87..d6eaa10de5c 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java @@ -1758,6 +1758,20 @@ public class IndexCPPBindingResolutionTest extends IndexBindingResolutionTestBas assertEquals("void (char)", ASTTypeUtil.getType(ref.getType())); getBindingFromASTName("g(1)", 1); } + + // namespace std { + // inline namespace __cxx11 { } + // } + + // namespace std { + // namespace __cxx11 { + // class string {}; + // } + // void regex_match(string); // Type 'string' could not be resolved + // } + public void testInlineNamespaceReopenedWithoutInlineKeyword_483824() { + checkBindings(); + } // namespace ns { // void fun(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java index 0a63f033508..0152fb0b17a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java @@ -307,8 +307,8 @@ abstract public class CPPScope implements ICPPASTInternalScope { @Override public final void populateCache() { if (!isCached) { + isCached= true; // set to true before doing the work, to avoid recursion CPPSemantics.populateCache(this); - isCached= true; } } 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 14c71b4773c..f3f7cfc02ff 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 @@ -1600,7 +1600,15 @@ public class CPPSemantics { } else if (item instanceof ICPPASTNamespaceDefinition) { final ICPPASTNamespaceDefinition nsDef = (ICPPASTNamespaceDefinition) item; final boolean isUnnamed = nsDef.getName().getLookupKey().length == 0; - final boolean isInline = nsDef.isInline(); + boolean isInline = nsDef.isInline(); + // An inline namespace can be re-opened without repeating the inline keyword, + // so we need to consult the binding to check inlineness. + if (!isUnnamed && !isInline) { + IBinding nsBinding = nsDef.getName().resolveBinding(); + if (nsBinding instanceof ICPPNamespace) { + isInline = ((ICPPNamespace) nsBinding).isInline(); + } + } if (isUnnamed || isInline) { if (scope instanceof CPPNamespaceScope) { final CPPNamespaceScope nsscope = (CPPNamespaceScope) scope;