summaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2016-08-16 15:26:17 (GMT)
committerBrad King <brad.king@kitware.com>2016-08-16 15:43:46 (GMT)
commita583b278626bfd7d5930a462ebda5caa5906461a (patch)
treee4737d7647c5769cbb812de5cd22bf8cf7180b37 /test
parentd5934bd08651dbda95a65ccadcc5f39637d7bc59 (diff)
downloadCastXML-a583b278626bfd7d5930a462ebda5caa5906461a.zip
CastXML-a583b278626bfd7d5930a462ebda5caa5906461a.tar.gz
CastXML-a583b278626bfd7d5930a462ebda5caa5906461a.tar.bz2
Output: Desugar typedefs whose context is a template
In the code template <typename> struct A { struct B { typedef int intermediate_type; typedef intermediate_type type; }; }; Clang represents `A<int>::B::type` as a typedef whose type is sugared to `A<>::B::intermediate_type` where `A<>::B` is a non-template whose context is an uninstantiated template `A<>` even though the original typedef's context `A<int>::B` is a non-template whose context is an instaniated template `A<int>`. Since CastXML's gccxml output format does not support uninstantiated templates we cannot represent the context of `intermediate_type` so we must desugar it instead. Otherwise we end up with an `Unimplemented` node or even a crash in Clang because we perform operations meant for non-templates on the template context. We previously did this for typedefs that appear directly in template contexts, but not for those whose contexts are nominally non-template but contained in a template context. Fix the logic to loop through all nested contexts to perform this check. Closes: #70
Diffstat (limited to 'test')
-rw-r--r--test/CMakeLists.txt1
-rw-r--r--test/expect/gccxml.any.Class-template-member-nontemplate-Typedef.xml.txt10
-rw-r--r--test/input/Class-template-member-nontemplate-Typedef.cxx7
3 files changed, 18 insertions, 0 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 51da580..a039396 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -305,6 +305,7 @@ castxml_test_gccxml(Class-template-Method-return-const)
castxml_test_gccxml(Class-template-bases)
castxml_test_gccxml(Class-template-constructor-template)
castxml_test_gccxml(Class-template-friends)
+castxml_test_gccxml(Class-template-member-nontemplate-Typedef)
castxml_test_gccxml(Class-template-member-Typedef)
castxml_test_gccxml(Class-template-member-Typedef-const)
castxml_test_gccxml(Class-template-member-template)
diff --git a/test/expect/gccxml.any.Class-template-member-nontemplate-Typedef.xml.txt b/test/expect/gccxml.any.Class-template-member-nontemplate-Typedef.xml.txt
new file mode 100644
index 0000000..693ac8d
--- /dev/null
+++ b/test/expect/gccxml.any.Class-template-member-nontemplate-Typedef.xml.txt
@@ -0,0 +1,10 @@
+^<\?xml version="1.0"\?>
+<GCC_XML[^>]*>
+ <Typedef id="_1" name="start" type="_2" context="_3" location="f1:7" file="f1" line="7"/>
+ <Typedef id="_2" name="type" type="_4" context="_5" access="public" location="f1:4" file="f1" line="4"/>
+ <FundamentalType id="_4" name="int" size="[0-9]+" align="[0-9]+"/>
+ <Namespace id="_3" name="::"/>
+ <Struct id="_5" name="B" context="_6" access="public" location="f1:2" file="f1" line="2" size="[0-9]+" align="[0-9]+"/>
+ <Struct id="_6" name="A&lt;int&gt;" context="_3" location="f1:1" file="f1" line="1" size="[0-9]+" align="[0-9]+"/>
+ <File id="f1" name=".*/test/input/Class-template-member-nontemplate-Typedef.cxx"/>
+</GCC_XML>$
diff --git a/test/input/Class-template-member-nontemplate-Typedef.cxx b/test/input/Class-template-member-nontemplate-Typedef.cxx
new file mode 100644
index 0000000..91ffab3
--- /dev/null
+++ b/test/input/Class-template-member-nontemplate-Typedef.cxx
@@ -0,0 +1,7 @@
+template <typename> struct A {
+ struct B {
+ typedef int intermediate_type;
+ typedef intermediate_type type;
+ };
+};
+typedef A<int>::B::type start;