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;
}
예제 #4
0
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);
    }
}
예제 #5
0
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;
}
예제 #7
0
 void setEnd(SourceLocation L) { Range.setEnd(L); }
예제 #8
0
 void setRange(SourceLocation B, SourceLocation E) {
   Range.setBegin(B); Range.setEnd(E);
 }
예제 #9
0
 void setRange(SourceLocation L) { Range.setBegin(L); Range.setEnd(L); }