diff options
author | Brad King <brad.king@kitware.com> | 2015-12-11 21:29:15 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2015-12-14 16:44:22 (GMT) |
commit | f57109f31b94d0410e091a549a4aa0febc4140d6 (patch) | |
tree | e808c200077843a17e1873791cd3e9ac1f88beff /src | |
parent | d10ec2e51efcff37b655404dd755e34b5e122cb1 (diff) | |
download | CastXML-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.cxx | 17 |
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) { |