summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2015-03-31 14:43:16 (GMT)
committerBrad King <brad.king@kitware.com>2015-03-31 14:56:14 (GMT)
commit4402138958fac4e9eae008d8987aa2f14278d272 (patch)
tree0ddb90a01f81686a678d21fd48e8d4eff74e446b
parentc224a7968998ff627a2dcc3ab41f907c5f8541b0 (diff)
downloadCastXML-4402138958fac4e9eae008d8987aa2f14278d272.zip
CastXML-4402138958fac4e9eae008d8987aa2f14278d272.tar.gz
CastXML-4402138958fac4e9eae008d8987aa2f14278d272.tar.bz2
Output: Handle function types with no prototype
A FunctionType may be either FunctionProtoType or FunctionNoProtoType. Check that runtime downcasts to FunctionProtoType succeed before using them. For FunctionNoProtoType we will simply output the type "int()", which is compatible with gccxml format (gccxml never lacked prototypes because it always operates in C++ mode). In CastXML we can encounter functions with no prototype in C++ modes when traversing Clang buildins. GitHub-Issue: 1
-rw-r--r--src/Output.cxx28
-rw-r--r--test/CMakeLists.txt1
-rw-r--r--test/expect/gccxml.c89.FunctionNoProto.xml.txt7
-rw-r--r--test/input/FunctionNoProto.c1
4 files changed, 24 insertions, 13 deletions
diff --git a/src/Output.cxx b/src/Output.cxx
index 8a387cb..c50a4b2 100644
--- a/src/Output.cxx
+++ b/src/Output.cxx
@@ -444,17 +444,18 @@ unsigned int ASTVisitor::AddDumpNode(clang::Decl const* d, bool complete) {
return 0;
}
- clang::FunctionProtoType const* fpt =
- fd->getType()->getAs<clang::FunctionProtoType>();
- if (fpt->getReturnType()->isRValueReferenceType()) {
- return 0;
- }
- for (clang::FunctionProtoType::param_type_iterator
- i = fpt->param_type_begin(), e = fpt->param_type_end();
- i != e; ++i) {
- if((*i)->isRValueReferenceType()) {
+ if (clang::FunctionProtoType const* fpt =
+ fd->getType()->getAs<clang::FunctionProtoType>()) {
+ if (fpt->getReturnType()->isRValueReferenceType()) {
return 0;
}
+ for (clang::FunctionProtoType::param_type_iterator
+ i = fpt->param_type_begin(), e = fpt->param_type_end();
+ i != e; ++i) {
+ if((*i)->isRValueReferenceType()) {
+ return 0;
+ }
+ }
}
}
}
@@ -1128,10 +1129,11 @@ void ASTVisitor::OutputFunctionHelper(clang::FunctionDecl const* d,
this->OS << " artificial=\"1\"";
}
- clang::QualType ft = d->getType();
- this->PrintFunctionTypeAttributes(ft->getAs<clang::FunctionProtoType>());
- this->PrintThrowsAttribute(
- ft->getAs<clang::FunctionProtoType>(), dn->Complete);
+ if (clang::FunctionProtoType const* fpt =
+ d->getType()->getAs<clang::FunctionProtoType>()) {
+ this->PrintFunctionTypeAttributes(fpt);
+ this->PrintThrowsAttribute(fpt, dn->Complete);
+ }
if(unsigned np = d->getNumParams()) {
this->OS << ">\n";
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index aa0a2fa..9006016 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -225,6 +225,7 @@ if(";${LLVM_TARGETS_TO_BUILD};" MATCHES ";X86;")
unset(castxml_test_gccxml_extra_arguments)
endif()
+castxml_test_gccxml_c(FunctionNoProto)
castxml_test_gccxml_c(FundamentalType)
castxml_test_gccxml_c(Typedef-called-class)
diff --git a/test/expect/gccxml.c89.FunctionNoProto.xml.txt b/test/expect/gccxml.c89.FunctionNoProto.xml.txt
new file mode 100644
index 0000000..d0df025
--- /dev/null
+++ b/test/expect/gccxml.c89.FunctionNoProto.xml.txt
@@ -0,0 +1,7 @@
+^<\?xml version="1.0"\?>
+<GCC_XML[^>]*>
+ <Function id="_1" name="start" returns="_2" context="_3" location="f1:1" file="f1" line="1"/>
+ <FundamentalType id="_2" name="int"/>
+ <Namespace id="_3" name="::"/>
+ <File id="f1" name=".*/test/input/FunctionNoProto.c"/>
+</GCC_XML>$
diff --git a/test/input/FunctionNoProto.c b/test/input/FunctionNoProto.c
new file mode 100644
index 0000000..2e1b401
--- /dev/null
+++ b/test/input/FunctionNoProto.c
@@ -0,0 +1 @@
+int start();