forked from OSchip/llvm-project
108 lines
3.4 KiB
C++
108 lines
3.4 KiB
C++
//===-- ReplaceAutoPtrActions.cpp --- std::auto_ptr replacement -----------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
///
|
|
/// \file
|
|
/// \brief This file contains the definition of the ASTMatcher callback for the
|
|
/// ReplaceAutoPtr transform.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "ReplaceAutoPtrActions.h"
|
|
#include "Core/Transform.h"
|
|
#include "ReplaceAutoPtrMatchers.h"
|
|
#include "clang/AST/ASTContext.h"
|
|
#include "clang/Lex/Lexer.h"
|
|
|
|
using namespace clang;
|
|
using namespace clang::tooling;
|
|
using namespace clang::ast_matchers;
|
|
|
|
namespace {
|
|
|
|
/// \brief Verifies that the token at \p BeginningOfToken is 'auto_ptr'.
|
|
bool checkTokenIsAutoPtr(clang::SourceLocation BeginningOfToken,
|
|
const clang::SourceManager &SM,
|
|
const clang::LangOptions &LangOptions) {
|
|
llvm::SmallVector<char, 8> Buffer;
|
|
bool Invalid = false;
|
|
llvm::StringRef Res =
|
|
Lexer::getSpelling(BeginningOfToken, Buffer, SM, LangOptions, &Invalid);
|
|
|
|
if (Invalid)
|
|
return false;
|
|
|
|
return Res == "auto_ptr";
|
|
}
|
|
|
|
} // end anonymous namespace
|
|
|
|
void AutoPtrReplacer::run(const MatchFinder::MatchResult &Result) {
|
|
SourceManager &SM = *Result.SourceManager;
|
|
SourceLocation IdentifierLoc;
|
|
|
|
if (const TypeLoc *TL = Result.Nodes.getNodeAs<TypeLoc>(AutoPtrTokenId)) {
|
|
IdentifierLoc = locateFromTypeLoc(*TL, SM);
|
|
} else {
|
|
const UsingDecl *D = Result.Nodes.getNodeAs<UsingDecl>(AutoPtrTokenId);
|
|
assert(D && "Bad Callback. No node provided.");
|
|
IdentifierLoc = locateFromUsingDecl(D, SM);
|
|
}
|
|
|
|
if (IdentifierLoc.isMacroID())
|
|
IdentifierLoc = SM.getSpellingLoc(IdentifierLoc);
|
|
|
|
if (!Owner.isFileModifiable(SM, IdentifierLoc))
|
|
return;
|
|
|
|
// make sure that only the 'auto_ptr' token is replaced and not the template
|
|
// aliases [temp.alias]
|
|
if (!checkTokenIsAutoPtr(IdentifierLoc, SM, LangOptions()))
|
|
return;
|
|
|
|
Owner.addReplacementForCurrentTU(
|
|
Replacement(SM, IdentifierLoc, strlen("auto_ptr"), "unique_ptr"));
|
|
++AcceptedChanges;
|
|
}
|
|
|
|
SourceLocation AutoPtrReplacer::locateFromTypeLoc(TypeLoc AutoPtrTypeLoc,
|
|
const SourceManager &SM) {
|
|
TemplateSpecializationTypeLoc TL =
|
|
AutoPtrTypeLoc.getAs<TemplateSpecializationTypeLoc>();
|
|
if (TL.isNull())
|
|
return SourceLocation();
|
|
|
|
return TL.getTemplateNameLoc();
|
|
}
|
|
|
|
SourceLocation
|
|
AutoPtrReplacer::locateFromUsingDecl(const UsingDecl *UsingAutoPtrDecl,
|
|
const SourceManager &SM) {
|
|
return UsingAutoPtrDecl->getNameInfo().getBeginLoc();
|
|
}
|
|
|
|
void OwnershipTransferFixer::run(const MatchFinder::MatchResult &Result) {
|
|
SourceManager &SM = *Result.SourceManager;
|
|
const Expr *E = Result.Nodes.getNodeAs<Expr>(AutoPtrOwnershipTransferId);
|
|
assert(E && "Bad Callback. No node provided.");
|
|
|
|
CharSourceRange Range = Lexer::makeFileCharRange(
|
|
CharSourceRange::getTokenRange(E->getSourceRange()), SM, LangOptions());
|
|
|
|
if (Range.isInvalid())
|
|
return;
|
|
|
|
if (!Owner.isFileModifiable(SM, Range.getBegin()))
|
|
return;
|
|
|
|
Owner.addReplacementForCurrentTU(
|
|
Replacement(SM, Range.getBegin(), 0, "std::move("));
|
|
Owner.addReplacementForCurrentTU(Replacement(SM, Range.getEnd(), 0, ")"));
|
|
AcceptedChanges += 2;
|
|
}
|