Skip to main content
aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorNathan Ridge2018-01-22 05:56:56 +0000
committerNathan Ridge2018-01-25 22:32:58 +0000
commitf413c21d032e4428bda60528983493cbf45845b5 (patch)
tree11590ffc0f7b8397a6b4cd3a15cc1a606de2d5db /core
parent69c84d4f054f8291fcd674a4f8a19ccc61505f04 (diff)
downloadorg.eclipse.cdt-f413c21d032e4428bda60528983493cbf45845b5.tar.gz
org.eclipse.cdt-f413c21d032e4428bda60528983493cbf45845b5.tar.xz
org.eclipse.cdt-f413c21d032e4428bda60528983493cbf45845b5.zip
Bug 490359 - Add support for C++17 nested namespace definitions
Diffstat (limited to 'core')
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java15
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java49
2 files changed, 59 insertions, 5 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 9f78539d759..e7c1c2b670f 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
@@ -12632,4 +12632,19 @@ public class AST2CPPTests extends AST2CPPTestBase {
helper.assertVariableValue("waldo4", 0);
helper.assertVariableValue("waldo5", 0);
}
+
+ // namespace x {
+ // void foo();
+ // }
+ // namespace x::y {
+ // void bar() {
+ // foo();
+ // }
+ // }
+ // int main() {
+ // x::y::bar();
+ // }
+ public void testNestedNamespaceDefinition_490359() throws Exception {
+ parseAndCheckBindings();
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
index f35d19f3b5c..abc34b9f5da 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
@@ -2638,9 +2638,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
consume(IToken.t_namespace);
// optional name
- IASTName name = null;
+ ICPPASTName name = null;
if (LT(1) == IToken.tIDENTIFIER) {
- name = identifier();
+ name = qualifiedName();
endOffset= calculateEndOffset(name);
} else {
name = getNodeFactory().newName();
@@ -2650,16 +2650,55 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
List<IASTAttributeSpecifier> attributeSpecifiers = __attribute_decl_seq(true, false);
if (LT(1) == IToken.tLBRACE) {
- ICPPASTNamespaceDefinition ns = getNodeFactory().newNamespaceDefinition(name);
+ ICPPASTNamespaceDefinition outer = null;
+ ICPPASTNamespaceDefinition inner = null;
+ if (name instanceof ICPPASTQualifiedName) {
+ // Handle C++17 nested namespace definition.
+ ICPPASTNameSpecifier[] qualifier = ((ICPPASTQualifiedName) name).getQualifier();
+ for (ICPPASTNameSpecifier specifier : qualifier) {
+ if (!(specifier instanceof ICPPASTName)) {
+ // No decltype-specifiers in nested namespace definition.
+ throwBacktrack(specifier);
+ return null;
+ }
+ ICPPASTName segment = (ICPPASTName) specifier;
+ ICPPASTNamespaceDefinition ns = getNodeFactory().newNamespaceDefinition(segment);
+ if (outer == null || inner == null) { // second half of condition is just to avoid warning
+ outer = ns;
+ } else {
+ inner.addDeclaration(ns);
+ }
+ inner = ns;
+ }
+ }
+ IASTName lastName = name.getLastName();
+ ICPPASTNamespaceDefinition ns = getNodeFactory().newNamespaceDefinition(lastName);
+ if (outer == null || inner == null) { // second half of condition is just to avoid warning
+ outer = ns;
+ } else {
+ inner.addDeclaration(ns);
+ }
ns.setIsInline(isInline);
declarationListInBraces(ns, offset, DeclarationOptions.GLOBAL);
+ endOffset = getEndOffset();
+ if (ns != outer) {
+ // For a C++17 nested namespace definition, we need to set the offset/length of
+ // the enclosing namespace declaration nodes (declarationListInBraces() does it
+ // for the inner one).
+ for (IASTNode parent = ns.getParent(); parent != null; parent = parent.getParent()) {
+ setRange(parent, offset, endOffset);
+ if (parent == outer) {
+ break;
+ }
+ }
+ }
addAttributeSpecifiers(attributeSpecifiers, ns);
- return ns;
+ return outer;
}
if (LT(1) == IToken.tASSIGN) {
endOffset= consume().getEndOffset();
- if (name.toString() == null) {
+ if (name.toString() == null || name instanceof ICPPASTQualifiedName) {
throwBacktrack(offset, endOffset - offset);
return null;
}

Back to the top