diff options
author | Brad King <brad.king@kitware.com> | 2015-03-31 14:43:16 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2015-03-31 14:56:14 (GMT) |
commit | 4402138958fac4e9eae008d8987aa2f14278d272 (patch) | |
tree | 0ddb90a01f81686a678d21fd48e8d4eff74e446b | |
parent | c224a7968998ff627a2dcc3ab41f907c5f8541b0 (diff) | |
download | CastXML-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.cxx | 28 | ||||
-rw-r--r-- | test/CMakeLists.txt | 1 | ||||
-rw-r--r-- | test/expect/gccxml.c89.FunctionNoProto.xml.txt | 7 | ||||
-rw-r--r-- | test/input/FunctionNoProto.c | 1 |
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(); |