// This function skips type specifiers bool RewriteUtils::getDeclGroupStrAndRemove(DeclGroupRef DGR, std::string &Str) { if (DGR.isSingleDecl()) { Decl *D = DGR.getSingleDecl(); VarDecl *VD = dyn_cast<VarDecl>(D); TransAssert(VD && "Bad VarDecl!"); // We need to get the outermost TypeLocEnd instead of the StartLoc of // a var name, because we need to handle the case below: // int *x; // int *y; // If we rely on the StartLoc of a var name, then we will make bad // transformation like: // int *x, y; SourceLocation TypeLocEnd = getVarDeclTypeLocEnd(VD); SourceRange VarRange = VD->getSourceRange(); SourceLocation LocEnd = getEndLocationUntil(VarRange, ';'); getStringBetweenLocs(Str, TypeLocEnd, LocEnd); SourceLocation StartLoc = VarRange.getBegin(); SourceLocation NewEndLoc = getLocationAfterSkiping(LocEnd, ';'); return !(TheRewriter->RemoveText(SourceRange(StartLoc, NewEndLoc))); } TransAssert(DGR.getDeclGroup().size() > 1); DeclGroupRef::iterator I = DGR.begin(); DeclGroupRef::iterator E = DGR.end(); --E; Decl *FirstD = (*I); VarDecl *FirstVD = dyn_cast<VarDecl>(FirstD); Decl *LastD = (*E); VarDecl *LastVD = dyn_cast<VarDecl>(LastD); TransAssert(FirstVD && "Bad First VarDecl!"); TransAssert(LastVD && "Bad First VarDecl!"); SourceLocation TypeLocEnd = getVarDeclTypeLocEnd(FirstVD); SourceRange LastVarRange = LastVD->getSourceRange(); SourceLocation LastEndLoc = getEndLocationUntil(LastVarRange, ';'); getStringBetweenLocs(Str, TypeLocEnd, LastEndLoc); SourceLocation StartLoc = FirstVD->getLocStart(); SourceLocation NewLastEndLoc = getLocationAfterSkiping(LastEndLoc, ';'); return !(TheRewriter->RemoveText(SourceRange(StartLoc, NewLastEndLoc))); }
bool RewriteUtils::removeVarDecl(const VarDecl *VD, DeclGroupRef DGR) { SourceRange VarRange = VD->getSourceRange(); if (DGR.isSingleDecl()) { SourceLocation StartLoc = VarRange.getBegin(); SourceLocation EndLoc = getEndLocationUntil(VarRange, ';'); // in case the previous EndLoc is invalid, for example, // VarRange could have bad EndLoc value if (EndLoc.isInvalid()) EndLoc = getLocationUntil(StartLoc, ';'); return !(TheRewriter->RemoveText(SourceRange(StartLoc, EndLoc))); } DeclGroupRef::const_iterator I = DGR.begin(); const VarDecl *FirstVD = dyn_cast<VarDecl>(*I); // dyn_cast (*I) to VarDecl could fail, because it could be a struct decl, // e.g., struct S1 { int f1; } s2 = {1}, where FirstDecl is // struct S1 {int f1;}. We need to skip it if (!FirstVD) { // handle the case where we could have implicit declaration of RecordDecl // e.g., // struct S0 *s; // ...; // in this case, struct S0 is implicitly declared if ( RecordDecl *RD = dyn_cast<RecordDecl>(*I) ) { if (!RD->getDefinition() && DGR.getDeclGroup().size() == 2) { SourceLocation StartLoc = VarRange.getBegin(); SourceLocation EndLoc = getEndLocationUntil(VarRange, ';'); return !(TheRewriter->RemoveText(SourceRange(StartLoc, EndLoc))); } } ++I; TransAssert((I != DGR.end()) && "Bad Decl!"); FirstVD = dyn_cast<VarDecl>(*I); TransAssert(FirstVD && "Invalid Var Decl!"); if (VD == FirstVD) { SourceLocation StartLoc = VD->getLocation(); SourceLocation EndLoc = getEndLocationUntil(VarRange, ','); return !(TheRewriter->RemoveText(SourceRange(StartLoc, EndLoc))); } } else if (VD == FirstVD) { SourceLocation StartLoc = getVarDeclTypeLocEnd(VD); SourceLocation EndLoc = getEndLocationUntil(VarRange, ','); return !(TheRewriter->RemoveText(SourceRange(StartLoc, EndLoc))); } const VarDecl *PrevVD = FirstVD; const VarDecl *CurrVD = NULL; ++I; DeclGroupRef::const_iterator E = DGR.end(); for (; I != E; ++I) { CurrVD = dyn_cast<VarDecl>(*I); TransAssert(CurrVD && "Not a valid VarDecl!"); if (VD == CurrVD) break; PrevVD = CurrVD; } TransAssert((VD == CurrVD) && "Cannot find VD!"); SourceLocation VarEndLoc = VarRange.getEnd(); SourceRange PrevDeclRange = PrevVD->getSourceRange(); SourceLocation PrevDeclEndLoc = getEndLocationUntil(PrevDeclRange, ','); return !(TheRewriter->RemoveText(SourceRange(PrevDeclEndLoc, VarEndLoc))); }