@@ -82,33 +82,42 @@ const NamespaceDecl *getOuterNamespace(const NamespaceDecl *InnerNs,
82
82
return CurrentNs;
83
83
}
84
84
85
- // FIXME: get rid of this helper function if this is supported in clang-refactor
86
- // library.
87
- SourceLocation getStartOfNextLine (SourceLocation Loc, const SourceManager &SM,
88
- const LangOptions &LangOpts) {
85
+ static std::unique_ptr<Lexer>
86
+ getLexerStartingFromLoc (SourceLocation Loc, const SourceManager &SM,
87
+ const LangOptions &LangOpts) {
89
88
if (Loc.isMacroID () &&
90
89
!Lexer::isAtEndOfMacroExpansion (Loc, SM, LangOpts, &Loc))
91
- return SourceLocation () ;
90
+ return nullptr ;
92
91
// Break down the source location.
93
92
std::pair<FileID, unsigned > LocInfo = SM.getDecomposedLoc (Loc);
94
93
// Try to load the file buffer.
95
94
bool InvalidTemp = false ;
96
95
llvm::StringRef File = SM.getBufferData (LocInfo.first , &InvalidTemp);
97
96
if (InvalidTemp)
98
- return SourceLocation () ;
97
+ return nullptr ;
99
98
100
99
const char *TokBegin = File.data () + LocInfo.second ;
101
100
// Lex from the start of the given location.
102
- Lexer Lex (SM.getLocForStartOfFile (LocInfo.first ), LangOpts, File.begin (),
103
- TokBegin, File.end ());
101
+ return llvm::make_unique<Lexer>(SM.getLocForStartOfFile (LocInfo.first ),
102
+ LangOpts, File.begin (), TokBegin, File.end ());
103
+ }
104
104
105
+ // FIXME: get rid of this helper function if this is supported in clang-refactor
106
+ // library.
107
+ static SourceLocation getStartOfNextLine (SourceLocation Loc,
108
+ const SourceManager &SM,
109
+ const LangOptions &LangOpts) {
110
+ std::unique_ptr<Lexer> Lex = getLexerStartingFromLoc (Loc, SM, LangOpts);
111
+ if (!Lex.get ())
112
+ return SourceLocation ();
105
113
llvm::SmallVector<char , 16 > Line;
106
114
// FIXME: this is a bit hacky to get ReadToEndOfLine work.
107
- Lex. setParsingPreprocessorDirective (true );
108
- Lex. ReadToEndOfLine (&Line);
115
+ Lex-> setParsingPreprocessorDirective (true );
116
+ Lex-> ReadToEndOfLine (&Line);
109
117
auto End = Loc.getLocWithOffset (Line.size ());
110
- return SM.getLocForEndOfFile (LocInfo.first ) == End ? End
111
- : End.getLocWithOffset (1 );
118
+ return SM.getLocForEndOfFile (SM.getDecomposedLoc (Loc).first ) == End
119
+ ? End
120
+ : End.getLocWithOffset (1 );
112
121
}
113
122
114
123
// Returns `R` with new range that refers to code after `Replaces` being
@@ -365,6 +374,23 @@ void ChangeNamespaceTool::run(
365
374
}
366
375
}
367
376
377
+ static SourceLocation getLocAfterNamespaceLBrace (const NamespaceDecl *NsDecl,
378
+ const SourceManager &SM,
379
+ const LangOptions &LangOpts) {
380
+ std::unique_ptr<Lexer> Lex =
381
+ getLexerStartingFromLoc (NsDecl->getLocStart (), SM, LangOpts);
382
+ assert (Lex.get () &&
383
+ " Failed to create lexer from the beginning of namespace." );
384
+ if (!Lex.get ())
385
+ return SourceLocation ();
386
+ Token Tok;
387
+ while (!Lex->LexFromRawLexer (Tok) && Tok.isNot (tok::TokenKind::l_brace)) {
388
+ }
389
+ return Tok.isNot (tok::TokenKind::l_brace)
390
+ ? SourceLocation ()
391
+ : Tok.getEndLoc ().getLocWithOffset (1 );
392
+ }
393
+
368
394
// Stores information about a moved namespace in `MoveNamespaces` and leaves
369
395
// the actual movement to `onEndOfTranslationUnit()`.
370
396
void ChangeNamespaceTool::moveOldNamespace (
@@ -375,7 +401,9 @@ void ChangeNamespaceTool::moveOldNamespace(
375
401
return ;
376
402
377
403
// Get the range of the code in the old namespace.
378
- SourceLocation Start = NsDecl->decls_begin ()->getLocStart ();
404
+ SourceLocation Start = getLocAfterNamespaceLBrace (
405
+ NsDecl, *Result.SourceManager , Result.Context ->getLangOpts ());
406
+ assert (Start.isValid () && " Can't find l_brace for namespace." );
379
407
SourceLocation End = NsDecl->getRBraceLoc ().getLocWithOffset (-1 );
380
408
// Create a replacement that deletes the code in the old namespace merely for
381
409
// retrieving offset and length from it.
0 commit comments