summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2015-05-15 19:51:25 (GMT)
committerBrad King <brad.king@kitware.com>2015-05-15 19:51:25 (GMT)
commitd741c9e4e56ff43dc35603327f1a8d30c8bb167c (patch)
tree6b9cc06532204d3ff7c8b5fa751cbef4e976ec83
parent5587062f5f894d7b2d7a61679a495535db0a8924 (diff)
downloadCastXML-d741c9e4e56ff43dc35603327f1a8d30c8bb167c.zip
CastXML-d741c9e4e56ff43dc35603327f1a8d30c8bb167c.tar.gz
CastXML-d741c9e4e56ff43dc35603327f1a8d30c8bb167c.tar.bz2
Output: Place inline namespace members in containing namespace
An inline namespace affects the linkage of its members but for APIs the members are effectively in the containing namespace. Generate output as if they were really in the containing namespace and do not generate a Namespace element for an inline namespace. If --castxml-start names an inline namespace simply ignore it to avoid dumping a Namespace element for it. One can argue this is valid since the inline namespace should not normally be named in API usage. Set our printing policy to avoid showing the inline namespace component automatically. Note that expressions in the source code that hard-code the inline namespace name will still be preserved and show the inline namespace when printed (e.g. Variable init="" attribute expressions). Suggested-by: Michka Popoff <michkapopoff@gmail.com>
-rw-r--r--src/Output.cxx18
-rw-r--r--test/CMakeLists.txt3
-rw-r--r--test/expect/gccxml.any.Namespace-inline-start.xml.txt3
-rw-r--r--test/expect/gccxml.any.Namespace-inline-template.xml.txt9
-rw-r--r--test/expect/gccxml.any.Namespace-inline.xml.txt8
-rw-r--r--test/input/Namespace-inline-start.cxx2
-rw-r--r--test/input/Namespace-inline-template.cxx8
-rw-r--r--test/input/Namespace-inline.cxx9
8 files changed, 60 insertions, 0 deletions
diff --git a/src/Output.cxx b/src/Output.cxx
index d505b54..202ce63 100644
--- a/src/Output.cxx
+++ b/src/Output.cxx
@@ -493,6 +493,7 @@ public:
RequireComplete(true),
MangleContext(ctx.createMangleContext()),
PrintingPolicy(ctx.getPrintingPolicy()) {
+ this->PrintingPolicy.SuppressUnwrittenScope = true;
}
/** Visit declarations in the given translation unit.
@@ -792,6 +793,14 @@ void ASTVisitor::AddDeclContextMembers(clang::DeclContext const* dc,
static_cast<clang::LinkageSpecDecl const*>(d), emitted);
continue;
} break;
+ case clang::Decl::Namespace: {
+ clang::NamespaceDecl const* nd =
+ static_cast<clang::NamespaceDecl const*>(d);
+ if (nd->isInline()) {
+ this->AddDeclContextMembers(nd, emitted);
+ continue;
+ }
+ } break;
case clang::Decl::Using: {
continue;
} break;
@@ -821,6 +830,11 @@ void ASTVisitor::AddStartDecl(clang::Decl const* d)
this->AddFunctionTemplateDecl(
static_cast<clang::FunctionTemplateDecl const*>(d));
break;
+ case clang::Decl::Namespace: {
+ if (!static_cast<clang::NamespaceDecl const*>(d)->isInline()) {
+ this->AddDeclDumpNode(d, true);
+ }
+ } break;
case clang::Decl::Using: {
clang::UsingDecl const* ud = static_cast<clang::UsingDecl const*>(d);
for(clang::UsingDecl::shadow_iterator i = ud->shadow_begin(),
@@ -961,6 +975,10 @@ void ASTVisitor::OutputCvQualifiedType(DumpNode const* dn)
//----------------------------------------------------------------------------
ASTVisitor::DumpId ASTVisitor::GetContextIdRef(clang::DeclContext const* dc)
{
+ while (dc->isInlineNamespace()) {
+ dc = dc->getParent();
+ }
+
if(clang::Decl const* d = clang::dyn_cast<clang::Decl>(dc)) {
return this->AddDeclDumpNode(d, false);
} else {
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 12f3fe5..9240aff 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -195,6 +195,9 @@ castxml_test_gccxml(Namespace-Class-template-members)
castxml_test_gccxml(Namespace-Function-template-members)
castxml_test_gccxml(Namespace-empty)
castxml_test_gccxml(Namespace-extern-C-members)
+castxml_test_gccxml(Namespace-inline)
+castxml_test_gccxml(Namespace-inline-start)
+castxml_test_gccxml(Namespace-inline-template)
castxml_test_gccxml(Namespace-repeat)
castxml_test_gccxml(Namespace-repeat-start)
castxml_test_gccxml(OffsetType)
diff --git a/test/expect/gccxml.any.Namespace-inline-start.xml.txt b/test/expect/gccxml.any.Namespace-inline-start.xml.txt
new file mode 100644
index 0000000..73614a8
--- /dev/null
+++ b/test/expect/gccxml.any.Namespace-inline-start.xml.txt
@@ -0,0 +1,3 @@
+^<\?xml version="1.0"\?>
+<GCC_XML[^>]*>
+</GCC_XML>$
diff --git a/test/expect/gccxml.any.Namespace-inline-template.xml.txt b/test/expect/gccxml.any.Namespace-inline-template.xml.txt
new file mode 100644
index 0000000..fc966fb
--- /dev/null
+++ b/test/expect/gccxml.any.Namespace-inline-template.xml.txt
@@ -0,0 +1,9 @@
+^<\?xml version="1.0"\?>
+<GCC_XML[^>]*>
+ <Namespace id="_1" name="start" context="_2" members="_3 _4 _5"/>
+ <Struct id="_3" name="A" context="_1" location="f1:4" file="f1" line="4" incomplete="1"/>
+ <Struct id="_4" name="B&lt;start::A&gt;" context="_1" location="f1:6" file="f1" line="6" incomplete="1"/>
+ <Typedef id="_5" name="B_A" type="_4" context="_1" location="f1:7" file="f1" line="7"/>
+ <Namespace id="_2" name="::"/>
+ <File id="f1" name=".*/test/input/Namespace-inline-template.cxx"/>
+</GCC_XML>$
diff --git a/test/expect/gccxml.any.Namespace-inline.xml.txt b/test/expect/gccxml.any.Namespace-inline.xml.txt
new file mode 100644
index 0000000..f54e7a7
--- /dev/null
+++ b/test/expect/gccxml.any.Namespace-inline.xml.txt
@@ -0,0 +1,8 @@
+^<\?xml version="1.0"\?>
+<GCC_XML[^>]*>
+ <Namespace id="_1" name="start" context="_2" members="_3 _4"/>
+ <Struct id="_3" name="A" context="_1" location="f1:4" file="f1" line="4" incomplete="1"/>
+ <Struct id="_4" name="B" context="_1" location="f1:6" file="f1" line="6" incomplete="1"/>
+ <Namespace id="_2" name="::"/>
+ <File id="f1" name=".*/test/input/Namespace-inline.cxx"/>
+</GCC_XML>$
diff --git a/test/input/Namespace-inline-start.cxx b/test/input/Namespace-inline-start.cxx
new file mode 100644
index 0000000..35f05bc
--- /dev/null
+++ b/test/input/Namespace-inline-start.cxx
@@ -0,0 +1,2 @@
+#pragma clang diagnostic ignored "-Wc++11-extensions"
+inline namespace start {}
diff --git a/test/input/Namespace-inline-template.cxx b/test/input/Namespace-inline-template.cxx
new file mode 100644
index 0000000..fc38a46
--- /dev/null
+++ b/test/input/Namespace-inline-template.cxx
@@ -0,0 +1,8 @@
+#pragma clang diagnostic ignored "-Wc++11-extensions"
+namespace start {
+ inline namespace level1 {
+ struct A;
+ }
+ template <typename T> struct B;
+ typedef B<A> B_A;
+}
diff --git a/test/input/Namespace-inline.cxx b/test/input/Namespace-inline.cxx
new file mode 100644
index 0000000..9569ad3
--- /dev/null
+++ b/test/input/Namespace-inline.cxx
@@ -0,0 +1,9 @@
+#pragma clang diagnostic ignored "-Wc++11-extensions"
+namespace start {
+ inline namespace level1 {
+ struct A;
+ inline namespace level2 {
+ struct B;
+ }
+ }
+}