bool EmptyStructToIntRewriteVisitor::VisitRecordTypeLoc(RecordTypeLoc RTLoc) { const RecordDecl *RD = RTLoc.getDecl(); if (RD->getCanonicalDecl() == ConsumerInstance->TheRecordDecl) { SourceLocation LocStart = RTLoc.getLocStart(); void *LocPtr = LocStart.getPtrEncoding(); if (ConsumerInstance->VisitedLocs.count(LocPtr)) return true; ConsumerInstance->VisitedLocs.insert(LocPtr); // handle a special case - // struct S1 { // struct { } S; // }; const IdentifierInfo *TypeId = RTLoc.getType().getBaseTypeIdentifier(); if (!TypeId) return true; ConsumerInstance->RewriteHelper->replaceRecordType(RTLoc, "int"); ConsumerInstance->Rewritten = true; } return true; }
bool RewriteUtils::replaceRecordType(RecordTypeLoc &RTLoc, const std::string &Name) { const IdentifierInfo *TypeId = RTLoc.getType().getBaseTypeIdentifier(); SourceLocation LocStart = RTLoc.getLocStart(); // Loc could be invalid, for example: // class AAA { }; // class BBB:AAA { // public: // BBB () { } // }; // In Clang's internal representation, BBB's Ctor is BBB() : AAA() {} // The implicit AAA() will be visited here // This is the only case where RTLoc is invalid, so the question is - // Is the guard below too strong? It is possible it could mask other // potential bugs? if (LocStart.isInvalid()) return true; return !(TheRewriter->ReplaceText(LocStart, TypeId->getLength(), Name)); }