static FixItHint removeArgument(const CallExpr *Call, unsigned Index) { unsigned ArgCount = Call->getNumArgs(); const Expr *Arg = Call->getArg(Index); SourceRange RemovalRange = Arg->getSourceRange(); if (ArgCount == 1) return FixItHint::CreateRemoval(RemovalRange); if (Index == 0) RemovalRange.setEnd( Call->getArg(Index + 1)->getLocStart().getLocWithOffset(-1)); else RemovalRange.setBegin( Call->getArg(Index - 1)->getLocEnd().getLocWithOffset(1)); return FixItHint::CreateRemoval(RemovalRange); }
static FixItHint removeParameter(const FunctionDecl *Function, unsigned Index) { const ParmVarDecl *Param = Function->getParamDecl(Index); unsigned ParamCount = Function->getNumParams(); SourceRange RemovalRange = Param->getSourceRange(); if (ParamCount == 1) return FixItHint::CreateRemoval(RemovalRange); if (Index == 0) RemovalRange.setEnd( Function->getParamDecl(Index + 1)->getLocStart().getLocWithOffset(-1)); else RemovalRange.setBegin( Function->getParamDecl(Index - 1)->getLocEnd().getLocWithOffset(1)); return FixItHint::CreateRemoval(RemovalRange); }
std::vector<FixItHint> Qt4_QStringFromArray::fixitInsertFromLatin1(CXXConstructExpr *ctorExpr) { vector<FixItHint> fixits; SourceRange range; Expr *arg = *(ctorExpr->arg_begin()); range.setBegin(arg->getLocStart()); range.setEnd(Lexer::getLocForEndOfToken(FixItUtils::biggestSourceLocationInStmt(sm(), ctorExpr), 0, sm(), lo())); if (range.isInvalid()) { emitWarning(ctorExpr->getLocStart(), "Internal error"); return {}; } FixItUtils::insertParentMethodCall("QString::fromLatin1", range, fixits); return fixits; }
void RewriterASTConsumer::InclusionDirective(clang::SourceLocation HashLoc, const clang::Token& IncludeTok, clang::StringRef FileName, bool IsAngled, clang::CharSourceRange FilenameRange, const clang::FileEntry* File, clang::StringRef SearchPath, clang::StringRef RelativePath, const clang::Module* Imported) { if ("ParallelForEach.h" == FileName) { SourceManager& SM = TheGpuRewriter.getSourceMgr(); SourceRange Range; Range.setBegin(HashLoc); Range.setEnd(SM.getSpellingLoc(FilenameRange.getEnd())); TheGpuRewriter.RemoveText(Range); } }
ExtractionSemicolonPolicy ExtractionSemicolonPolicy::compute(const Stmt *S, SourceRange &ExtractedRange, const SourceManager &SM, const LangOptions &LangOpts) { auto neededInExtractedFunction = []() { return ExtractionSemicolonPolicy(true, false); }; auto neededInOriginalFunction = []() { return ExtractionSemicolonPolicy(false, true); }; /// The extracted expression should be terminated with a ';'. The call to /// the extracted function will replace this expression, so it won't need /// a terminating ';'. if (isa<Expr>(S)) return neededInExtractedFunction(); /// Some statements don't need to be terminated with ';'. The call to the /// extracted function will be a standalone statement, so it should be /// terminated with a ';'. bool NeedsSemi = isSemicolonRequiredAfter(S); if (!NeedsSemi) return neededInOriginalFunction(); /// Some statements might end at ';'. The extraction will move that ';', so /// the call to the extracted function should be terminated with a ';'. SourceLocation End = ExtractedRange.getEnd(); if (isSemicolonAtLocation(End, SM, LangOpts)) return neededInOriginalFunction(); /// Other statements should generally have a trailing ';'. We can try to find /// it and move it together it with the extracted code. Optional<Token> NextToken = Lexer::findNextToken(End, SM, LangOpts); if (NextToken && NextToken->is(tok::semi) && areOnSameLine(NextToken->getLocation(), End, SM)) { ExtractedRange.setEnd(NextToken->getLocation()); return neededInOriginalFunction(); } /// Otherwise insert semicolons in both places. return ExtractionSemicolonPolicy(true, true); }
std::vector<FixItHint> IncludeSorter::GetEdits() { if (SourceLocations.empty()) return {}; typedef std::map<int, std::pair<SourceRange, std::string>> FileLineToSourceEditMap; FileLineToSourceEditMap Edits; auto SourceLocationIterator = SourceLocations.begin(); auto SourceLocationIteratorEnd = SourceLocations.end(); // Compute the Edits that need to be done to each line to add, replace, or // delete inclusions. for (int IncludeKind = 0; IncludeKind < IK_InvalidInclude; ++IncludeKind) { std::sort(IncludeBucket[IncludeKind].begin(), IncludeBucket[IncludeKind].end()); for (const auto &IncludeEntry : IncludeBucket[IncludeKind]) { auto &Location = IncludeLocations[IncludeEntry]; SourceRangeVector::iterator LocationIterator = Location.begin(); SourceRangeVector::iterator LocationIteratorEnd = Location.end(); SourceRange FirstLocation = *LocationIterator; // If the first occurrence of a particular include is on the current // source line we are examining, leave it alone. if (FirstLocation == *SourceLocationIterator) ++LocationIterator; // Add the deletion Edits for any (remaining) instances of this inclusion, // and remove their Locations from the source Locations to be processed. for (; LocationIterator != LocationIteratorEnd; ++LocationIterator) { int LineNumber = SourceMgr->getSpellingLineNumber(LocationIterator->getBegin()); Edits[LineNumber] = std::make_pair(*LocationIterator, ""); SourceLocationIteratorEnd = std::remove(SourceLocationIterator, SourceLocationIteratorEnd, *LocationIterator); } if (FirstLocation == *SourceLocationIterator) { // Do nothing except move to the next source Location (Location of an // inclusion in the original, unchanged source file). ++SourceLocationIterator; continue; } // Add (or append to) the replacement text for this line in source file. int LineNumber = SourceMgr->getSpellingLineNumber(SourceLocationIterator->getBegin()); if (Edits.find(LineNumber) == Edits.end()) { Edits[LineNumber].first = SourceRange(SourceLocationIterator->getBegin()); } StringRef SourceText = Lexer::getSourceText( CharSourceRange::getCharRange(FirstLocation), *SourceMgr, *LangOpts); Edits[LineNumber].second.append(SourceText.data(), SourceText.size()); } // Clear the bucket. IncludeBucket[IncludeKind].clear(); } // Go through the single-line Edits and combine them into blocks of Edits. int CurrentEndLine = 0; SourceRange CurrentRange; std::string CurrentText; std::vector<FixItHint> Fixes; for (const auto &LineEdit : Edits) { // If the current edit is on the next line after the previous edit, add it // to the current block edit. if (LineEdit.first == CurrentEndLine + 1 && CurrentRange.getBegin() != CurrentRange.getEnd()) { SourceRange EditRange = LineEdit.second.first; if (EditRange.getBegin() != EditRange.getEnd()) { ++CurrentEndLine; CurrentRange.setEnd(EditRange.getEnd()); } CurrentText += LineEdit.second.second; // Otherwise report the current block edit and start a new block. } else { if (CurrentEndLine) { Fixes.push_back(CreateFixIt(CurrentRange, CurrentText)); } CurrentEndLine = LineEdit.first; CurrentRange = LineEdit.second.first; CurrentText = LineEdit.second.second; } } // Finally, report the current block edit if there is one. if (CurrentEndLine) { Fixes.push_back(CreateFixIt(CurrentRange, CurrentText)); } // Reset the remaining internal state. SourceLocations.clear(); IncludeLocations.clear(); return Fixes; }
void setEnd(SourceLocation L) { Range.setEnd(L); }
void setRange(SourceLocation B, SourceLocation E) { Range.setBegin(B); Range.setEnd(E); }
void setRange(SourceLocation L) { Range.setBegin(L); Range.setEnd(L); }