// Finds the location of the qualifying `const` token in the `FunctionDecl`'s
// return type. Returns `None` when the return type is not `const`-qualified or
// `const` does not appear in `Def`'s source like when the type is an alias or a
// macro.
static llvm::Optional<Token>
findConstToRemove(const FunctionDecl *Def,
                  const MatchFinder::MatchResult &Result) {
  if (!Def->getReturnType().isLocalConstQualified())
    return None;

  // Get the begin location for the function name, including any qualifiers
  // written in the source (for out-of-line declarations). A FunctionDecl's
  // "location" is the start of its name, so, when the name is unqualified, we
  // use `getLocation()`.
  SourceLocation NameBeginLoc = Def->getQualifier()
                                    ? Def->getQualifierLoc().getBeginLoc()
                                    : Def->getLocation();
  // Since either of the locs can be in a macro, use `makeFileCharRange` to be
  // sure that we have a consistent `CharSourceRange`, located entirely in the
  // source file.
  CharSourceRange FileRange = Lexer::makeFileCharRange(
      CharSourceRange::getCharRange(Def->getBeginLoc(), NameBeginLoc),
      *Result.SourceManager, Result.Context->getLangOpts());

  if (FileRange.isInvalid())
    return None;

  return utils::lexer::getConstQualifyingToken(FileRange, *Result.Context,
                                               *Result.SourceManager);
}
Example #2
0
static RawComment toRawComment(ASTContext &Context, CharSourceRange Range) {
  if (Range.isInvalid())
    return RawComment();

  auto &SourceMgr = Context.SourceMgr;
  unsigned BufferID = SourceMgr.findBufferContainingLoc(Range.getStart());
  unsigned Offset = SourceMgr.getLocOffsetInBuffer(Range.getStart(), BufferID);
  unsigned EndOffset = SourceMgr.getLocOffsetInBuffer(Range.getEnd(), BufferID);
  LangOptions FakeLangOpts;
  Lexer L(FakeLangOpts, SourceMgr, BufferID, nullptr, LexerMode::Swift,
          HashbangMode::Disallowed,
          CommentRetentionMode::ReturnAsTokens,
          TriviaRetentionMode::WithoutTrivia,
          Offset, EndOffset);
  SmallVector<SingleRawComment, 16> Comments;
  Token Tok;
  while (true) {
    L.lex(Tok);
    if (Tok.is(tok::eof))
      break;
    assert(Tok.is(tok::comment));
    addCommentToList(Comments, SingleRawComment(Tok.getRange(), SourceMgr));
  }
  RawComment Result;
  Result.Comments = Context.AllocateCopy(Comments);
  return Result;
}
Example #3
0
bool SourceManager::openVirtualFile(SourceLoc loc, StringRef name,
                                    int lineOffset) {
  CharSourceRange fullRange = getRangeForBuffer(findBufferContainingLoc(loc));
  SourceLoc end;

  auto nextRangeIter = VirtualFiles.upper_bound(loc.Value.getPointer());
  if (nextRangeIter != VirtualFiles.end() &&
      fullRange.contains(nextRangeIter->second.Range.getStart())) {
    const VirtualFile &existingFile = nextRangeIter->second;
    if (existingFile.Range.getStart() == loc) {
      assert(existingFile.Name == name);
      assert(existingFile.LineOffset == lineOffset);
      return false;
    }
    assert(!existingFile.Range.contains(loc) &&
           "must close current open file first");
    end = nextRangeIter->second.Range.getStart();
  } else {
    end = fullRange.getEnd();
  }

  CharSourceRange range = CharSourceRange(*this, loc, end);
  VirtualFiles[end.Value.getPointer()] = { range, name, lineOffset };
  CachedVFile = {nullptr, nullptr};
  return true;
}
Example #4
0
// Re-lex the tokens to get precise locations to insert 'override' and remove
// 'virtual'.
static SmallVector<Token, 16>
ParseTokens(CharSourceRange Range, const MatchFinder::MatchResult &Result) {
  const SourceManager &Sources = *Result.SourceManager;
  std::pair<FileID, unsigned> LocInfo =
      Sources.getDecomposedLoc(Range.getBegin());
  StringRef File = Sources.getBufferData(LocInfo.first);
  const char *TokenBegin = File.data() + LocInfo.second;
  Lexer RawLexer(Sources.getLocForStartOfFile(LocInfo.first),
                 Result.Context->getLangOpts(), File.begin(), TokenBegin,
                 File.end());
  SmallVector<Token, 16> Tokens;
  Token Tok;
  while (!RawLexer.LexFromRawLexer(Tok)) {
    if (Tok.is(tok::semi) || Tok.is(tok::l_brace))
      break;
    if (Sources.isBeforeInTranslationUnit(Range.getEnd(), Tok.getLocation()))
      break;
    if (Tok.is(tok::raw_identifier)) {
      IdentifierInfo &Info = Result.Context->Idents.get(StringRef(
          Sources.getCharacterData(Tok.getLocation()), Tok.getLength()));
      Tok.setIdentifierInfo(&Info);
      Tok.setKind(Info.getTokenID());
    }
    Tokens.push_back(Tok);
  }
  return Tokens;
}
Example #5
0
bool Commit::replaceWithInner(CharSourceRange range,
                              CharSourceRange replacementRange) {
  FileOffset OuterBegin;
  unsigned OuterLen;
  if (!canRemoveRange(range, OuterBegin, OuterLen)) {
    IsCommitable = false;
    return false;
  }

  FileOffset InnerBegin;
  unsigned InnerLen;
  if (!canRemoveRange(replacementRange, InnerBegin, InnerLen)) {
    IsCommitable = false;
    return false;
  }

  FileOffset OuterEnd = OuterBegin.getWithOffset(OuterLen);
  FileOffset InnerEnd = InnerBegin.getWithOffset(InnerLen);
  if (OuterBegin.getFID() != InnerBegin.getFID() ||
      InnerBegin < OuterBegin ||
      InnerBegin > OuterEnd ||
      InnerEnd > OuterEnd) {
    IsCommitable = false;
    return false;
  }

  addRemove(range.getBegin(),
            OuterBegin, InnerBegin.getOffset() - OuterBegin.getOffset());
  addRemove(replacementRange.getEnd(),
            InnerEnd, OuterEnd.getOffset() - InnerEnd.getOffset());
  return true;
}
static std::pair<unsigned, unsigned>
makeStandaloneRange(CharSourceRange Range, const SourceManager &SM,
                    const LangOptions &LangOpts) {
  CharSourceRange FileRange = Lexer::makeFileCharRange(Range, SM, LangOpts);
  unsigned Offset = SM.getFileOffset(FileRange.getBegin());
  unsigned EndOffset = SM.getFileOffset(FileRange.getEnd());
  return std::make_pair(Offset, EndOffset);
}
void SerializedDiagnosticConsumer::addRangeToRecord(CharSourceRange Range,
                                                    SourceManager &SM,
                                                    StringRef Filename,
                                                    RecordDataImpl &Record) {
  assert(Range.isValid());
  addLocToRecord(Range.getStart(), SM, Filename, Record);
  addLocToRecord(Range.getEnd(), SM, Filename, Record);
}
Example #8
0
static void EmitRange(raw_ostream& o, const SourceManager &SM,
                      const LangOptions &LangOpts,
                      CharSourceRange R, const FIDMap &FM,
                      unsigned indent) {
  Indent(o, indent) << "<array>\n";
  EmitLocation(o, SM, LangOpts, R.getBegin(), FM, indent+1);
  EmitLocation(o, SM, LangOpts, R.getEnd(), FM, indent+1, R.isTokenRange());
  Indent(o, indent) << "</array>\n";
}
Example #9
0
SingleRawComment::SingleRawComment(CharSourceRange Range,
                                   const SourceManager &SourceMgr)
    : Range(Range), RawText(SourceMgr.extractText(Range)),
      Kind(static_cast<unsigned>(getCommentKind(RawText))) {
  auto StartLineAndColumn = SourceMgr.getLineAndColumn(Range.getStart());
  StartLine = StartLineAndColumn.first;
  StartColumn = StartLineAndColumn.second;
  EndLine = SourceMgr.getLineNumber(Range.getEnd());
}
void MoveConstArgCheck::check(const MatchFinder::MatchResult &Result) {
  const auto *CallMove = Result.Nodes.getNodeAs<CallExpr>("call-move");
  const auto *ReceivingExpr = Result.Nodes.getNodeAs<Expr>("receiving-expr");
  const Expr *Arg = CallMove->getArg(0);
  SourceManager &SM = Result.Context->getSourceManager();

  CharSourceRange MoveRange =
      CharSourceRange::getCharRange(CallMove->getSourceRange());
  CharSourceRange FileMoveRange =
      Lexer::makeFileCharRange(MoveRange, SM, getLangOpts());
  if (!FileMoveRange.isValid())
    return;

  bool IsConstArg = Arg->getType().isConstQualified();
  bool IsTriviallyCopyable =
      Arg->getType().isTriviallyCopyableType(*Result.Context);

  if (IsConstArg || IsTriviallyCopyable) {
    if (const CXXRecordDecl *R = Arg->getType()->getAsCXXRecordDecl()) {
      // According to [expr.prim.lambda]p3, "whether the closure type is
      // trivially copyable" property can be changed by the implementation of
      // the language, so we shouldn't rely on it when issuing diagnostics.
      if (R->isLambda())
        return;
      // Don't warn when the type is not copyable.
      for (const auto *Ctor : R->ctors()) {
        if (Ctor->isCopyConstructor() && Ctor->isDeleted())
          return;
      }
    }

    if (!IsConstArg && IsTriviallyCopyable && !CheckTriviallyCopyableMove)
      return;

    bool IsVariable = isa<DeclRefExpr>(Arg);
    const auto *Var =
        IsVariable ? dyn_cast<DeclRefExpr>(Arg)->getDecl() : nullptr;
    auto Diag = diag(FileMoveRange.getBegin(),
                     "std::move of the %select{|const }0"
                     "%select{expression|variable %4}1 "
                     "%select{|of the trivially-copyable type %5 }2"
                     "has no effect; remove std::move()"
                     "%select{| or make the variable non-const}3")
                << IsConstArg << IsVariable << IsTriviallyCopyable
                << (IsConstArg && IsVariable && !IsTriviallyCopyable) << Var
                << Arg->getType();

    ReplaceCallWithArg(CallMove, Diag, SM, getLangOpts());
  } else if (ReceivingExpr) {
    auto Diag = diag(FileMoveRange.getBegin(),
                     "passing result of std::move() as a const reference "
                     "argument; no move will actually happen");

    ReplaceCallWithArg(CallMove, Diag, SM, getLangOpts());
  }
}
void RedundantVoidArgCheck::removeVoidArgumentTokens(
    const ast_matchers::MatchFinder::MatchResult &Result, SourceRange Range,
    StringRef GrammarLocation) {
  CharSourceRange CharRange =
      Lexer::makeFileCharRange(CharSourceRange::getTokenRange(Range),
                               *Result.SourceManager, getLangOpts());

  std::string DeclText =
      Lexer::getSourceText(CharRange, *Result.SourceManager, getLangOpts())
          .str();
  Lexer PrototypeLexer(CharRange.getBegin(), getLangOpts(), DeclText.data(),
                       DeclText.data(), DeclText.data() + DeclText.size());
  enum TokenState {
    NothingYet,
    SawLeftParen,
    SawVoid,
  };
  TokenState State = NothingYet;
  Token VoidToken;
  Token ProtoToken;
  std::string Diagnostic =
      ("redundant void argument list in " + GrammarLocation).str();

  while (!PrototypeLexer.LexFromRawLexer(ProtoToken)) {
    switch (State) {
    case NothingYet:
      if (ProtoToken.is(tok::TokenKind::l_paren)) {
        State = SawLeftParen;
      }
      break;
    case SawLeftParen:
      if (ProtoToken.is(tok::TokenKind::raw_identifier) &&
          ProtoToken.getRawIdentifier() == "void") {
        State = SawVoid;
        VoidToken = ProtoToken;
      } else if (ProtoToken.is(tok::TokenKind::l_paren)) {
        State = SawLeftParen;
      } else {
        State = NothingYet;
      }
      break;
    case SawVoid:
      State = NothingYet;
      if (ProtoToken.is(tok::TokenKind::r_paren)) {
        removeVoidToken(VoidToken, Diagnostic);
      } else if (ProtoToken.is(tok::TokenKind::l_paren)) {
        State = SawLeftParen;
      }
      break;
    }
  }

  if (State == SawVoid && ProtoToken.is(tok::TokenKind::r_paren)) {
    removeVoidToken(VoidToken, Diagnostic);
  }
}
Example #12
0
StringRef SourceManager::extractText(CharSourceRange Range,
                                     Optional<unsigned> BufferID) const {
  assert(Range.isValid() && "range should be valid");

  if (!BufferID)
    BufferID = findBufferContainingLoc(Range.getStart());
  StringRef Buffer = LLVMSourceMgr.getMemoryBuffer(*BufferID)->getBuffer();
  return Buffer.substr(getLocOffsetInBuffer(Range.getStart(), *BufferID),
                       Range.getByteLength());
}
static SourceLoc findEndOfLine(SourceManager &SM, SourceLoc loc,
                               unsigned bufferID) {
  CharSourceRange entireBuffer = SM.getRangeForBuffer(bufferID);
  CharSourceRange rangeFromLoc{SM, loc, entireBuffer.getEnd()};
  StringRef textFromLoc = SM.extractText(rangeFromLoc);
  size_t newlineOffset = textFromLoc.find_first_of({"\r\n\0", 3});
  if (newlineOffset == StringRef::npos)
    return entireBuffer.getEnd();
  return loc.getAdvancedLoc(newlineOffset);
}
Example #14
0
bool FileInstrumentation::redirectInclude(FileID includedFileID, llvm::StringRef newFilePath) {
	CharSourceRange includeDirectiveRange = utils::getIncludeDirectiveSourceRange(includedFileID, m_sourceFile.getSourceManager(), m_astContext.getLangOpts());

	if(includeDirectiveRange.isValid()) {
		m_rewriter.replace(includeDirectiveRange.getAsRange())
			<< "\"" << newFilePath << "\"";
		return true;
	}

	return false;
}
Example #15
0
// FIXME: This should go into the Lexer, but we need to figure out how
// to handle ranges for refactoring in general first - there is no obvious
// good way how to integrate this into the Lexer yet.
static int getRangeSize(SourceManager &Sources, const CharSourceRange &Range) {
  SourceLocation SpellingBegin = Sources.getSpellingLoc(Range.getBegin());
  SourceLocation SpellingEnd = Sources.getSpellingLoc(Range.getEnd());
  std::pair<FileID, unsigned> Start = Sources.getDecomposedLoc(SpellingBegin);
  std::pair<FileID, unsigned> End = Sources.getDecomposedLoc(SpellingEnd);
  if (Start.first != End.first) return -1;
  if (Range.isTokenRange())
    End.second += Lexer::MeasureTokenLength(SpellingEnd, Sources,
                                            LangOptions());
  return End.second - Start.second;
}
bool AffectedRangeManager::affectsCharSourceRange(
    const CharSourceRange &Range) {
  for (SmallVectorImpl<CharSourceRange>::const_iterator I = Ranges.begin(),
                                                        E = Ranges.end();
       I != E; ++I) {
    if (!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), I->getBegin()) &&
        !SourceMgr.isBeforeInTranslationUnit(I->getEnd(), Range.getBegin()))
      return true;
  }
  return false;
}
void SDiagsWriter::AddCharSourceRangeToRecord(CharSourceRange Range,
                                              RecordDataImpl &Record,
                                              const SourceManager &SM) {
  AddLocToRecord(Range.getBegin(), Record, &SM);
  unsigned TokSize = 0;
  if (Range.isTokenRange())
    TokSize = Lexer::MeasureTokenLength(Range.getEnd(),
                                        SM, *LangOpts);
  
  AddLocToRecord(Range.getEnd(), Record, &SM, TokSize);
}
Example #18
0
bool Commit::insertWrap(StringRef before, CharSourceRange range,
                        StringRef after) {
  bool commitableBefore = insert(range.getBegin(), before, /*afterToken=*/false,
                                 /*beforePreviousInsertions=*/true);
  bool commitableAfter;
  if (range.isTokenRange())
    commitableAfter = insertAfterToken(range.getEnd(), after);
  else
    commitableAfter = insert(range.getEnd(), after);

  return commitableBefore && commitableAfter;
}
Example #19
0
/// Check if all the locations in the range have the same macro argument
/// expansion, and that that expansion starts with ArgumentLoc.
static bool checkRangeForMacroArgExpansion(CharSourceRange Range,
                                           const SourceManager &SM,
                                           SourceLocation ArgumentLoc) {
  SourceLocation BegLoc = Range.getBegin(), EndLoc = Range.getEnd();
  while (BegLoc != EndLoc) {
    if (!checkLocForMacroArgExpansion(BegLoc, SM, ArgumentLoc))
      return false;
    BegLoc.getLocWithOffset(1);
  }

  return checkLocForMacroArgExpansion(BegLoc, SM, ArgumentLoc);
}
void ReplaceAutoPtrCheck::check(const MatchFinder::MatchResult &Result) {
  SourceManager &SM = *Result.SourceManager;
  if (const auto *E =
          Result.Nodes.getNodeAs<Expr>(AutoPtrOwnershipTransferId)) {
    CharSourceRange Range = Lexer::makeFileCharRange(
        CharSourceRange::getTokenRange(E->getSourceRange()), SM, LangOptions());

    if (Range.isInvalid())
      return;

    auto Diag = diag(Range.getBegin(), "use std::move to transfer ownership")
                << FixItHint::CreateInsertion(Range.getBegin(), "std::move(")
                << FixItHint::CreateInsertion(Range.getEnd(), ")");

    if (auto Fix =
            Inserter->CreateIncludeInsertion(SM.getMainFileID(), "utility",
                                             /*IsAngled=*/true))
      Diag << *Fix;

    return;
  }

  SourceLocation AutoPtrLoc;
  if (const auto *TL = Result.Nodes.getNodeAs<TypeLoc>(AutoPtrTokenId)) {
    //   std::auto_ptr<int> i;
    //        ^
    if (auto Loc = TL->getAs<TemplateSpecializationTypeLoc>())
      AutoPtrLoc = Loc.getTemplateNameLoc();
  } else if (const auto *D =
                 Result.Nodes.getNodeAs<UsingDecl>(AutoPtrTokenId)) {
    // using std::auto_ptr;
    //            ^
    AutoPtrLoc = D->getNameInfo().getBeginLoc();
  } else {
    llvm_unreachable("Bad Callback. No node provided.");
  }

  if (AutoPtrLoc.isMacroID())
    AutoPtrLoc = SM.getSpellingLoc(AutoPtrLoc);

  // Ensure that only the 'auto_ptr' token is replaced and not the template
  // aliases.
  if (StringRef(SM.getCharacterData(AutoPtrLoc), strlen("auto_ptr")) !=
      "auto_ptr")
    return;

  SourceLocation EndLoc =
      AutoPtrLoc.getLocWithOffset(strlen("auto_ptr") - 1);
  diag(AutoPtrLoc, "auto_ptr is deprecated, use unique_ptr instead")
      << FixItHint::CreateReplacement(SourceRange(AutoPtrLoc, EndLoc),
                                      "unique_ptr");
}
Example #21
0
/// Find the suitable set of lines to show to include a set of ranges.
static llvm::Optional<std::pair<unsigned, unsigned>>
findLinesForRange(const CharSourceRange &R, FileID FID,
                  const SourceManager &SM) {
  if (!R.isValid()) return None;

  SourceLocation Begin = R.getBegin();
  SourceLocation End = R.getEnd();
  if (SM.getFileID(Begin) != FID || SM.getFileID(End) != FID)
    return None;

  return std::make_pair(SM.getExpansionLineNumber(Begin),
                        SM.getExpansionLineNumber(End));
}
Example #22
0
void PreprocessingRecord::InclusionDirective(
    SourceLocation HashLoc,
    const clang::Token &IncludeTok,
    StringRef FileName,
    bool IsAngled,
    CharSourceRange FilenameRange,
    const FileEntry *File,
    StringRef SearchPath,
    StringRef RelativePath,
    const Module *Imported) {
  InclusionDirective::InclusionKind Kind = InclusionDirective::Include;
  
  switch (IncludeTok.getIdentifierInfo()->getPPKeywordID()) {
  case tok::pp_include: 
    Kind = InclusionDirective::Include; 
    break;
    
  case tok::pp_import: 
    Kind = InclusionDirective::Import; 
    break;

  case tok::pp_using: 
    Kind = InclusionDirective::Using;
    break;
    
  case tok::pp_include_next: 
    Kind = InclusionDirective::IncludeNext; 
    break;
    
  case tok::pp___include_macros: 
    Kind = InclusionDirective::IncludeMacros;
    break;
    
  default:
    llvm_unreachable("Unknown include directive kind");
  }

  SourceLocation EndLoc;
  if (!IsAngled) {
    EndLoc = FilenameRange.getBegin();
  } else {
    EndLoc = FilenameRange.getEnd();
    if (FilenameRange.isCharRange())
      EndLoc = EndLoc.getLocWithOffset(-1); // the InclusionDirective expects
                                            // a token range.
  }
  clang::InclusionDirective *ID
    = new (*this) clang::InclusionDirective(*this, Kind, FileName, !IsAngled, 
                                            File, SourceRange(HashLoc, EndLoc));
  addPreprocessedEntity(ID);
}
Example #23
0
void
Parser::diagnoseWhereClauseInGenericParamList(const GenericParamList *
                                              GenericParams) {
  if (GenericParams == nullptr || GenericParams->getWhereLoc().isInvalid())
    return;



  auto WhereRangeInsideBrackets = GenericParams->getWhereClauseSourceRange();

  // Move everything immediately following the last generic parameter
  // as written all the way to the right angle bracket (">")
  auto LastGenericParam = GenericParams->getParams().back();
  auto EndOfLastGenericParam =
      Lexer::getLocForEndOfToken(SourceMgr, LastGenericParam->getEndLoc());

  CharSourceRange RemoveWhereRange { SourceMgr,
    EndOfLastGenericParam,
    GenericParams->getRAngleLoc()
  };

  auto WhereCharRange =
    Lexer::getCharSourceRangeFromSourceRange(SourceMgr,
                                  GenericParams->getWhereClauseSourceRange());

  SmallString<64> Buffer;
  llvm::raw_svector_ostream WhereClauseText(Buffer);
  WhereClauseText << SourceMgr.extractText(Tok.is(tok::kw_where)
                                           ? WhereCharRange
                                           : RemoveWhereRange);

  // If, for some reason, there was a where clause in both locations, we're
  // adding to the list of requirements, so tack on a comma here before
  // inserting it at the head of the later where clause.
  if (Tok.is(tok::kw_where))
    WhereClauseText << ',';

  auto Diag = diagnose(WhereRangeInsideBrackets.Start,
                       diag::where_inside_brackets);

  Diag.fixItRemoveChars(RemoveWhereRange.getStart(),
                        RemoveWhereRange.getEnd());

  if (Tok.is(tok::kw_where)) {
    Diag.fixItReplace(Tok.getLoc(), WhereClauseText.str());
  } else {
    Diag.fixItInsert(Lexer::getLocForEndOfToken(SourceMgr, PreviousLoc),
                     WhereClauseText.str());
  }
}
Example #24
0
bool Commit::canRemoveRange(CharSourceRange range,
                            FileOffset &Offs, unsigned &Len) {
  const SourceManager &SM = SourceMgr;
  range = Lexer::makeFileCharRange(range, SM, LangOpts);
  if (range.isInvalid())
    return false;

  if (range.getBegin().isMacroID() || range.getEnd().isMacroID())
    return false;
  if (SM.isInSystemHeader(range.getBegin()) ||
      SM.isInSystemHeader(range.getEnd()))
    return false;

  if (PPRec && PPRec->rangeIntersectsConditionalDirective(range.getAsRange()))
    return false;

  std::pair<FileID, unsigned> beginInfo = SM.getDecomposedLoc(range.getBegin());
  std::pair<FileID, unsigned> endInfo = SM.getDecomposedLoc(range.getEnd());
  if (beginInfo.first != endInfo.first ||
      beginInfo.second > endInfo.second)
    return false;

  Offs = FileOffset(beginInfo.first, beginInfo.second);
  Len = endInfo.second - beginInfo.second;
  return true;
}
Example #25
0
bool
EditorAdapter::cacheReplacement(CharSourceRange Range, StringRef Text) const {
  if (!CacheEnabled)
    return false;
  unsigned SwiftBufferID, Offset;
  std::tie(SwiftBufferID, Offset) = getLocInfo(Range.getStart());
  Replacement R { Offset, Range.getByteLength(), Text };
  if (Replacements.count(R)) {
    return true;
  } else {
    Replacements.insert(R);
  }
  return false;
}
Example #26
0
bool Commit::replace(CharSourceRange range, StringRef text) {
  if (text.empty())
    return remove(range);

  FileOffset Offs;
  unsigned Len;
  if (!canInsert(range.getBegin(), Offs) || !canRemoveRange(range, Offs, Len)) {
    IsCommitable = false;
    return false;
  }

  addRemove(range.getBegin(), Offs, Len);
  addInsert(range.getBegin(), Offs, text, false);
  return true;
}
static void printUntilFirstDeclStarts(SourceFile &File, ASTPrinter &Printer) {
  if (!File.getBufferID().hasValue())
    return;
  auto BufferID = *File.getBufferID();

  auto &SM = File.getASTContext().SourceMgr;
  CharSourceRange TextRange = SM.getRangeForBuffer(BufferID);

  auto DeclStartLoc = getDeclStartPosition(File);
  if (DeclStartLoc.isValid()) {
    TextRange = CharSourceRange(SM, TextRange.getStart(), DeclStartLoc);
  }

  Printer << SM.extractText(TextRange, BufferID);
}
Example #28
0
bool Commit::insertFromRange(SourceLocation loc,
                             CharSourceRange range,
                             bool afterToken, bool beforePreviousInsertions) {
  FileOffset RangeOffs;
  unsigned RangeLen;
  if (!canRemoveRange(range, RangeOffs, RangeLen)) {
    IsCommitable = false;
    return false;
  }

  FileOffset Offs;
  if ((!afterToken && !canInsert(loc, Offs)) ||
      ( afterToken && !canInsertAfterToken(loc, Offs, loc))) {
    IsCommitable = false;
    return false;
  }

  if (PPRec &&
      PPRec->areInDifferentConditionalDirectiveRegion(loc, range.getBegin())) {
    IsCommitable = false;
    return false;
  }

  addInsertFromRange(loc, Offs, RangeOffs, RangeLen, beforePreviousInsertions);
  return true;
}
void ReplaceAutoPtrCheck::check(const MatchFinder::MatchResult &Result) {
  SourceManager &SM = *Result.SourceManager;
  if (const auto *E =
          Result.Nodes.getNodeAs<Expr>(AutoPtrOwnershipTransferId)) {
    CharSourceRange Range = Lexer::makeFileCharRange(
        CharSourceRange::getTokenRange(E->getSourceRange()), SM, LangOptions());

    if (Range.isInvalid())
      return;

    auto Diag = diag(Range.getBegin(), "use std::move to transfer ownership")
                << FixItHint::CreateInsertion(Range.getBegin(), "std::move(")
                << FixItHint::CreateInsertion(Range.getEnd(), ")");

    auto Insertion =
        Inserter->CreateIncludeInsertion(SM.getMainFileID(), "utility",
                                         /*IsAngled=*/true);
    if (Insertion.hasValue())
      Diag << Insertion.getValue();

    return;
  }

  SourceLocation IdentifierLoc;
  if (const auto *TL = Result.Nodes.getNodeAs<TypeLoc>(AutoPtrTokenId)) {
    IdentifierLoc = locateFromTypeLoc(TL, SM);
  } else if (const auto *D =
                 Result.Nodes.getNodeAs<UsingDecl>(AutoPtrTokenId)) {
    IdentifierLoc = locateFromUsingDecl(D, SM);
  } else {
    llvm_unreachable("Bad Callback. No node provided.");
  }

  if (IdentifierLoc.isMacroID())
    IdentifierLoc = SM.getSpellingLoc(IdentifierLoc);

  // Ensure that only the 'auto_ptr' token is replaced and not the template
  // aliases.
  if (!checkTokenIsAutoPtr(IdentifierLoc, SM, LangOptions()))
    return;

  SourceLocation EndLoc =
      IdentifierLoc.getLocWithOffset(strlen("auto_ptr") - 1);
  diag(IdentifierLoc, "auto_ptr is deprecated, use unique_ptr instead")
      << FixItHint::CreateReplacement(SourceRange(IdentifierLoc, EndLoc),
                                      "unique_ptr");
}
Example #30
0
bool SemaLocResolver::visitModuleReference(ModuleEntity Mod,
                                           CharSourceRange Range) {
  if (isDone())
    return false;
  if (Mod.isBuiltinModule())
    return true; // Ignore.
  return !tryResolve(Mod, Range.getStart());
}