1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 02:06:01 +02:00

Bug 490359 - Add support for C++17 nested namespace definitions

Change-Id: I5f2550e607195335475427f6fced63bf97eaa718
This commit is contained in:
Nathan Ridge 2018-01-22 00:56:56 -05:00
parent 69c84d4f05
commit f413c21d03
2 changed files with 59 additions and 5 deletions

View file

@ -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();
}
}

View file

@ -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;
}