diff options
author | Eric Liu <ioeric@google.com> | 2016-12-14 17:01:52 +0000 |
---|---|---|
committer | Eric Liu <ioeric@google.com> | 2016-12-14 17:01:52 +0000 |
commit | 06ac39709152d6b2e56d9b5f264195b8f5e1b67a (patch) | |
tree | dd914e211621ed4b82b991c7806a54d8bad28e49 /clang-tools-extra/change-namespace | |
parent | 23b5b46d67ddbd089269792b2deaaf6e0da8a13e (diff) |
[change-namespace] don't crash when type reference is in function type parameter list.
Reviewers: hokein
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D27758
Diffstat (limited to 'clang-tools-extra/change-namespace')
-rw-r--r-- | clang-tools-extra/change-namespace/ChangeNamespace.cpp | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/clang-tools-extra/change-namespace/ChangeNamespace.cpp b/clang-tools-extra/change-namespace/ChangeNamespace.cpp index 4806f1ef123..b3588aaf689 100644 --- a/clang-tools-extra/change-namespace/ChangeNamespace.cpp +++ b/clang-tools-extra/change-namespace/ChangeNamespace.cpp @@ -172,6 +172,16 @@ tooling::Replacement createReplacement(SourceLocation Start, SourceLocation End, ReplacementText); } +void addReplacementOrDie( + SourceLocation Start, SourceLocation End, llvm::StringRef ReplacementText, + const SourceManager &SM, + std::map<std::string, tooling::Replacements> *FileToReplacements) { + const auto R = createReplacement(Start, End, ReplacementText, SM); + auto Err = (*FileToReplacements)[R.getFilePath()].add(R); + if (Err) + llvm_unreachable(llvm::toString(std::move(Err)).c_str()); +} + tooling::Replacement createInsertion(SourceLocation Loc, llvm::StringRef InsertText, const SourceManager &SM) { @@ -574,11 +584,8 @@ void ChangeNamespaceTool::moveClassForwardDeclaration( if (AfterSemi.isValid()) End = AfterSemi.getLocWithOffset(-1); // Delete the forward declaration from the code to be moved. - const auto Deletion = - createReplacement(Start, End, "", *Result.SourceManager); - auto Err = FileToReplacements[Deletion.getFilePath()].add(Deletion); - if (Err) - llvm_unreachable(llvm::toString(std::move(Err)).c_str()); + addReplacementOrDie(Start, End, "", *Result.SourceManager, + &FileToReplacements); llvm::StringRef Code = Lexer::getSourceText( CharSourceRange::getTokenRange( Result.SourceManager->getSpellingLoc(Start), @@ -608,6 +615,18 @@ void ChangeNamespaceTool::replaceQualifiedSymbolInDeclContext( const DeclContext *DeclCtx, SourceLocation Start, SourceLocation End, const NamedDecl *FromDecl) { const auto *NsDeclContext = DeclCtx->getEnclosingNamespaceContext(); + if (llvm::isa<TranslationUnitDecl>(NsDeclContext)) { + // This should not happen in usual unless the TypeLoc is in function type + // parameters, e.g `std::function<void(T)>`. In this case, DeclContext of + // `T` will be the translation unit. We simply use fully-qualified name + // here. + // Note that `FromDecl` must not be defined in the old namespace (according + // to `DeclMatcher`), so its fully-qualified name will not change after + // changing the namespace. + addReplacementOrDie(Start, End, FromDecl->getQualifiedNameAsString(), + *Result.SourceManager, &FileToReplacements); + return; + } const auto *NsDecl = llvm::cast<NamespaceDecl>(NsDeclContext); // Calculate the name of the `NsDecl` after it is moved to new namespace. std::string OldNs = NsDecl->getQualifiedNameAsString(); @@ -667,10 +686,8 @@ void ChangeNamespaceTool::replaceQualifiedSymbolInDeclContext( // NewNamespace is the global namespace. if (ReplaceName == FromDeclName && !NewNamespace.empty()) ReplaceName = "::" + ReplaceName; - auto R = createReplacement(Start, End, ReplaceName, *Result.SourceManager); - auto Err = FileToReplacements[R.getFilePath()].add(R); - if (Err) - llvm_unreachable(llvm::toString(std::move(Err)).c_str()); + addReplacementOrDie(Start, End, ReplaceName, *Result.SourceManager, + &FileToReplacements); } // Replace the [Start, End] of `Type` with the shortest qualified name when the @@ -731,11 +748,8 @@ void ChangeNamespaceTool::fixUsingShadowDecl( // FIXME: check if target_decl_name is in moved ns, which doesn't make much // sense. If this happens, we need to use name with the new namespace. // Use fully qualified name in UsingDecl for now. - auto R = createReplacement(Start, End, "using ::" + TargetDeclName, - *Result.SourceManager); - auto Err = FileToReplacements[R.getFilePath()].add(R); - if (Err) - llvm_unreachable(llvm::toString(std::move(Err)).c_str()); + addReplacementOrDie(Start, End, "using ::" + TargetDeclName, + *Result.SourceManager, &FileToReplacements); } void ChangeNamespaceTool::fixDeclRefExpr( |