summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2015-12-11 21:29:15 (GMT)
committerBrad King <brad.king@kitware.com>2015-12-14 16:44:22 (GMT)
commitf57109f31b94d0410e091a549a4aa0febc4140d6 (patch)
treee808c200077843a17e1873791cd3e9ac1f88beff /src
parentd10ec2e51efcff37b655404dd755e34b5e122cb1 (diff)
downloadCastXML-f57109f31b94d0410e091a549a4aa0febc4140d6.zip
CastXML-f57109f31b94d0410e091a549a4aa0febc4140d6.tar.gz
CastXML-f57109f31b94d0410e091a549a4aa0febc4140d6.tar.bz2
Output: Fix references to types whose declaration is invalid
We skip generating declarations that Clang has deemed invalid. Most callers of AddDeclDumpNode can check the return value and handle the lack of a valid decl. However, callers of AddDeclDumpNodeForType are generating references to types and expect to get a valid element to reference. We can get an invalid RecordDecl when it is a template instantation that fails (but does not otherwise produce a compilation error in Clang). References to types corresponding to the invalid RecordDecl must remain valid, so generate a Class/Struct/Union element anyway and simply leave out class members and bases.
Diffstat (limited to 'src')
-rw-r--r--src/Output.cxx17
1 files changed, 9 insertions, 8 deletions
diff --git a/src/Output.cxx b/src/Output.cxx
index 9796315..87fe512 100644
--- a/src/Output.cxx
+++ b/src/Output.cxx
@@ -234,7 +234,8 @@ class ASTVisitor: public ASTVisitorBase
}
/** Allocate a dump node for a Clang declaration. */
- DumpId AddDeclDumpNode(clang::Decl const* d, bool complete);
+ DumpId AddDeclDumpNode(clang::Decl const* d, bool complete,
+ bool forType = false);
DumpId AddDeclDumpNodeForType(clang::Decl const* d, bool complete,
DumpQual dq);
@@ -516,7 +517,7 @@ public:
//----------------------------------------------------------------------------
ASTVisitor::DumpId ASTVisitor::AddDeclDumpNode(clang::Decl const* d,
- bool complete) {
+ bool complete, bool forType) {
// Select the definition or canonical declaration.
d = d->getCanonicalDecl();
if(clang::RecordDecl const* rd = clang::dyn_cast<clang::RecordDecl>(d)) {
@@ -530,19 +531,19 @@ ASTVisitor::DumpId ASTVisitor::AddDeclDumpNode(clang::Decl const* d,
case clang::Decl::UsingShadow:
return this->AddDeclDumpNode(
static_cast<clang::UsingShadowDecl const*>(d)->getTargetDecl(),
- complete);
+ complete, forType);
case clang::Decl::LinkageSpec: {
clang::DeclContext const* dc =
static_cast<clang::LinkageSpecDecl const*>(d)->getDeclContext();
return this->AddDeclDumpNode(clang::Decl::castFromDeclContext(dc),
- complete);
+ complete, forType);
} break;
default:
break;
}
- // Skip invalid declarations.
- if(d->isInvalidDecl()) {
+ // Skip invalid declarations that are not needed for a type element.
+ if (d->isInvalidDecl() && !forType) {
return DumpId();
}
@@ -593,7 +594,7 @@ ASTVisitor::DumpId ASTVisitor::AddDeclDumpNodeForType(clang::Decl const* d,
bool complete,
DumpQual dq) {
// Get the id for the canonical decl.
- DumpId id = this->AddDeclDumpNode(d, complete);
+ DumpId id = this->AddDeclDumpNode(d, complete, true);
// If any qualifiers were collected through layers of desugaring
// then get the id of the qualified type referencing this decl.
@@ -1548,7 +1549,7 @@ void ASTVisitor::OutputRecordDecl(clang::RecordDecl const* d,
if(dx && dx->isAbstract()) {
this->OS << " abstract=\"1\"";
}
- if(dn->Complete) {
+ if (dn->Complete && !d->isInvalidDecl()) {
this->PrintMembersAttribute(d);
doBases = dx && dx->getNumBases();
if(doBases) {