summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.cpp
diff options
context:
space:
mode:
authorEdwin Vane <edwin.vane@intel.com>2013-03-19 18:47:03 +0000
committerEdwin Vane <edwin.vane@intel.com>2013-03-19 18:47:03 +0000
commitc383960be9ef8e9e761555cb66917c5d6c9595f0 (patch)
tree8ed3e47ff6378cc72a427d863dc31ce67852a3b6 /clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.cpp
parent0f1bc60d513e7bd6e6da5bb86a24c7bdcb822c96 (diff)
downloadbcm5719-llvm-c383960be9ef8e9e761555cb66917c5d6c9595f0.tar.gz
bcm5719-llvm-c383960be9ef8e9e761555cb66917c5d6c9595f0.zip
Don't replace macro usage if macro body has NULL
In case of macro body expansion, check to see if the macro is named NULL and don't replace inside the macro body. This fixes the case when NULL appears inside the macro body and the transform replaces the usage of the macro with nullptr. This is an easy fix for the problem for now and we should analyze the macro body to see if it expands to only NullToPointer in the future for a more robust solution that takes care of user defined macros that behaves like NULL. Other changes: - Moved complex macro tests to macros.cpp - Added new test cases. - Added checks to make sure that the macro bodies are not modified by the tool. Fixes: PR15396 Author: Tareq A Siraj <tareq.a.siraj@intel.com> llvm-svn: 177422
Diffstat (limited to 'clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.cpp')
-rw-r--r--clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.cpp31
1 files changed, 26 insertions, 5 deletions
diff --git a/clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.cpp b/clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.cpp
index 7fcd16e9e5e..f0ad46880aa 100644
--- a/clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.cpp
+++ b/clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.cpp
@@ -20,13 +20,15 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Lex/Lexer.h"
+
using namespace clang::ast_matchers;
using namespace clang::tooling;
using namespace clang;
namespace {
-/// \brief Replaces the provided range with the text "nullptr", but only if
+/// \brief Replaces the provided range with the text "nullptr", but only if
/// the start and end location are both in main file.
/// Returns true if and only if a replacement was made.
bool ReplaceWithNullptr(tooling::Replacements &Replace, SourceManager &SM,
@@ -114,13 +116,32 @@ void NullptrFixer::run(const ast_matchers::MatchFinder::MatchResult &Result) {
const CastExpr *Cast = Result.Nodes.getNodeAs<CastExpr>(ImplicitCastNode);
if (Cast) {
const Expr *E = Cast->IgnoreParenImpCasts();
-
SourceLocation StartLoc = E->getLocStart();
SourceLocation EndLoc = E->getLocEnd();
- // If the start/end location is a macro, get the expansion location.
- StartLoc = SM.getFileLoc(StartLoc);
- EndLoc = SM.getFileLoc(EndLoc);
+ // If the start/end location is a macro argument expansion, get the
+ // expansion location. If its a macro body expansion, check to see if its
+ // coming from a macro called NULL.
+ if (SM.isMacroArgExpansion(StartLoc) && SM.isMacroArgExpansion(EndLoc)) {
+ StartLoc = SM.getFileLoc(StartLoc);
+ EndLoc = SM.getFileLoc(EndLoc);
+ } else if (SM.isMacroBodyExpansion(StartLoc) &&
+ SM.isMacroBodyExpansion(EndLoc)) {
+ llvm::StringRef ImmediateMacroName = clang::Lexer::getImmediateMacroName(
+ StartLoc, SM, Result.Context->getLangOpts());
+ if (ImmediateMacroName != "NULL")
+ return;
+
+ SourceLocation MacroCallerStartLoc =
+ SM.getImmediateMacroCallerLoc(StartLoc);
+ SourceLocation MacroCallerEndLoc = SM.getImmediateMacroCallerLoc(EndLoc);
+
+ if (MacroCallerStartLoc.isFileID() && MacroCallerEndLoc.isFileID()) {
+ StartLoc = SM.getFileLoc(StartLoc);
+ EndLoc = SM.getFileLoc(EndLoc);
+ } else
+ return;
+ }
AcceptedChanges +=
ReplaceWithNullptr(Replace, SM, StartLoc, EndLoc) ? 1 : 0;
OpenPOWER on IntegriCloud