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:
parent
69c84d4f05
commit
f413c21d03
2 changed files with 59 additions and 5 deletions
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue