diff options
| author | Tareq A. Siraj <tareq.a.sriaj@intel.com> | 2013-03-28 16:06:59 +0000 |
|---|---|---|
| committer | Tareq A. Siraj <tareq.a.sriaj@intel.com> | 2013-03-28 16:06:59 +0000 |
| commit | c2aa348dd0ab28df2974f9c94c750277d04a5e8a (patch) | |
| tree | 05fba4734d27de1d6f337fd23397c65131102cf1 /clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.cpp | |
| parent | 01186359798e9a95b474c05b1e2239ab03b082c0 (diff) | |
| download | bcm5719-llvm-c2aa348dd0ab28df2974f9c94c750277d04a5e8a.tar.gz bcm5719-llvm-c2aa348dd0ab28df2974f9c94c750277d04a5e8a.zip | |
Allow users to specify NULL like macros to be replaced
-use-nullptr only replaced macro named NULL and ignored any user defined
macros that behaved like NULL. This patch introduces -user-null-macros
command line option to let users specify their custom NULL like macros.
- Added a -user-null-macros command line option that takes a
comma-separated list of user-defined macros to be replaced when using
the -use-nullptr transform.
- Added documentation.
- Updated testcase to reflect current behavior.
- Whitespace fixes.
Reviewers: revane, klimek, gribozavr
llvm-svn: 178243
Diffstat (limited to 'clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.cpp')
| -rw-r--r-- | clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.cpp | 57 |
1 files changed, 46 insertions, 11 deletions
diff --git a/clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.cpp b/clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.cpp index f0ad46880aa..79b8b5fc1b4 100644 --- a/clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.cpp +++ b/clang-tools-extra/cpp11-migrate/UseNullptr/NullptrActions.cpp @@ -28,6 +28,13 @@ using namespace clang; namespace { +const char *NullMacroName = "NULL"; + +static llvm::cl::opt<std::string> UserNullMacroNames( + "user-null-macros", llvm::cl::desc("Comma-separated list of user-defined " + "macro names that behave like NULL"), + llvm::cl::init("")); + /// \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. @@ -41,6 +48,25 @@ bool ReplaceWithNullptr(tooling::Replacements &Replace, SourceManager &SM, return false; } +/// \brief Returns the name of the outermost macro. +/// +/// Given +/// \code +/// #define MY_NULL NULL +/// \endcode +/// If \p Loc points to NULL, this function will return the name MY_NULL. +llvm::StringRef GetOutermostMacroName( + SourceLocation Loc, const SourceManager &SM, const LangOptions &LO) { + assert(Loc.isMacroID()); + SourceLocation OutermostMacroLoc; + + while (Loc.isMacroID()) { + OutermostMacroLoc = Loc; + Loc = SM.getImmediateMacroCallerLoc(Loc); + } + + return clang::Lexer::getImmediateMacroName(OutermostMacroLoc, SM, LO); +} } /// \brief Looks for a sequences of 0 or more explicit casts with an implicit @@ -101,6 +127,16 @@ private: Expr *FirstSubExpr; }; +NullptrFixer::NullptrFixer(clang::tooling::Replacements &Replace, + unsigned &AcceptedChanges, RiskLevel) + : Replace(Replace), AcceptedChanges(AcceptedChanges) { + if (!UserNullMacroNames.empty()) { + llvm::StringRef S = UserNullMacroNames; + S.split(UserNullMacros, ","); + } + UserNullMacros.insert(UserNullMacros.begin(), llvm::StringRef(NullMacroName)); +} + void NullptrFixer::run(const ast_matchers::MatchFinder::MatchResult &Result) { SourceManager &SM = *Result.SourceManager; @@ -127,20 +163,19 @@ void NullptrFixer::run(const ast_matchers::MatchFinder::MatchResult &Result) { 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; + llvm::StringRef OutermostMacroName = + GetOutermostMacroName(StartLoc, SM, Result.Context->getLangOpts()); - SourceLocation MacroCallerStartLoc = - SM.getImmediateMacroCallerLoc(StartLoc); - SourceLocation MacroCallerEndLoc = SM.getImmediateMacroCallerLoc(EndLoc); + // Check to see if the user wants to replace the macro being expanded. + bool ReplaceNullMacro = + std::find(UserNullMacros.begin(), UserNullMacros.end(), + OutermostMacroName) != UserNullMacros.end(); - if (MacroCallerStartLoc.isFileID() && MacroCallerEndLoc.isFileID()) { - StartLoc = SM.getFileLoc(StartLoc); - EndLoc = SM.getFileLoc(EndLoc); - } else + if (!ReplaceNullMacro) return; + + StartLoc = SM.getFileLoc(StartLoc); + EndLoc = SM.getFileLoc(EndLoc); } AcceptedChanges += |

