From 96bafbccfdc0c3055d152db42de4780b5120c6e5 Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 6 Oct 2016 09:37:11 -0400 Subject: Output: Avoid assertion failure on a FunctionDecl with no identifier All C++98 function declarations have identifiers as names. Some C++11 function declarations, such as user defined literal operators, do not have identifiers. While we may implement support for these in a future non-gccxml output format, for now simply avoid an assertion failure by outputting such declarations as Unimplemented nodes. Issue: #76 --- src/Output.cxx | 8 ++++++-- test/CMakeLists.txt | 1 + test/expect/gccxml.any.CXXLiteral.xml.txt | 6 ++++++ test/expect/gccxml.c++98.CXXLiteral.result.txt | 1 + test/expect/gccxml.c++98.CXXLiteral.stderr.txt | 1 + test/expect/gccxml.c++98.CXXLiteral.xml.txt | 1 + test/input/CXXLiteral.cxx | 3 +++ 7 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 test/expect/gccxml.any.CXXLiteral.xml.txt create mode 100644 test/expect/gccxml.c++98.CXXLiteral.result.txt create mode 100644 test/expect/gccxml.c++98.CXXLiteral.stderr.txt create mode 100644 test/expect/gccxml.c++98.CXXLiteral.xml.txt create mode 100644 test/input/CXXLiteral.cxx diff --git a/src/Output.cxx b/src/Output.cxx index 1736397..f8b9c1f 100644 --- a/src/Output.cxx +++ b/src/Output.cxx @@ -1850,8 +1850,10 @@ void ASTVisitor::OutputFunctionDecl(clang::FunctionDecl const* d, if(d->isOverloadedOperator()) { this->OutputFunctionHelper(d, dn, "OperatorFunction", clang::getOperatorSpelling(d->getOverloadedOperator()), flags); + } else if (clang::IdentifierInfo const* ii = d->getIdentifier()) { + this->OutputFunctionHelper(d, dn, "Function", ii->getName().str(), flags); } else { - this->OutputFunctionHelper(d, dn, "Function", d->getName().str(), flags); + this->OutputUnimplementedDecl(d, dn); } } @@ -1881,8 +1883,10 @@ void ASTVisitor::OutputCXXMethodDecl(clang::CXXMethodDecl const* d, if(d->isOverloadedOperator()) { this->OutputFunctionHelper(d, dn, "OperatorMethod", clang::getOperatorSpelling(d->getOverloadedOperator()), flags); + } else if (clang::IdentifierInfo const* ii = d->getIdentifier()) { + this->OutputFunctionHelper(d, dn, "Method", ii->getName().str(), flags); } else { - this->OutputFunctionHelper(d, dn, "Method", d->getName().str(), flags); + this->OutputUnimplementedDecl(d, dn); } } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a039396..1bf4613 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -315,6 +315,7 @@ castxml_test_gccxml(Constructor-annotate) castxml_test_gccxml(Converter) castxml_test_gccxml(Converter-annotate) castxml_test_gccxml(CvQualifiedType) +castxml_test_gccxml(CXXLiteral) castxml_test_gccxml(Destructor) castxml_test_gccxml(Destructor-annotate) castxml_test_gccxml(Enumeration) diff --git a/test/expect/gccxml.any.CXXLiteral.xml.txt b/test/expect/gccxml.any.CXXLiteral.xml.txt new file mode 100644 index 0000000..7349496 --- /dev/null +++ b/test/expect/gccxml.any.CXXLiteral.xml.txt @@ -0,0 +1,6 @@ +^<\?xml version="1.0"\?> +]*> + + + +$ diff --git a/test/expect/gccxml.c++98.CXXLiteral.result.txt b/test/expect/gccxml.c++98.CXXLiteral.result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/test/expect/gccxml.c++98.CXXLiteral.result.txt @@ -0,0 +1 @@ +1 diff --git a/test/expect/gccxml.c++98.CXXLiteral.stderr.txt b/test/expect/gccxml.c++98.CXXLiteral.stderr.txt new file mode 100644 index 0000000..14fd5d6 --- /dev/null +++ b/test/expect/gccxml.c++98.CXXLiteral.stderr.txt @@ -0,0 +1 @@ +error: expected a type diff --git a/test/expect/gccxml.c++98.CXXLiteral.xml.txt b/test/expect/gccxml.c++98.CXXLiteral.xml.txt new file mode 100644 index 0000000..f276847 --- /dev/null +++ b/test/expect/gccxml.c++98.CXXLiteral.xml.txt @@ -0,0 +1 @@ +\(missing\) diff --git a/test/input/CXXLiteral.cxx b/test/input/CXXLiteral.cxx new file mode 100644 index 0000000..2d35460 --- /dev/null +++ b/test/input/CXXLiteral.cxx @@ -0,0 +1,3 @@ +namespace start { + unsigned long long operator "" _u(unsigned long long); +} -- cgit v0.12