Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java')
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java49
1 files changed, 44 insertions, 5 deletions
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