LEFT | RIGHT |
1 //===--- RewriteScopedRefptr.cpp - Playground for the code rewriter ------------
---===// | 1 //===--- RewriteScopedRefptr.cpp - Playground for the code rewriter ------------
---===// |
2 // | 2 // |
3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 // | 9 // |
10 // Hacks and fun related to the code rewriter. | 10 // Hacks and fun related to the code rewriter. |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 if (RewrittenDecls.count(VD) > 0) | 232 if (RewrittenDecls.count(VD) > 0) |
233 continue; | 233 continue; |
234 | 234 |
235 // If variable has type scoped_refptr... | 235 // If variable has type scoped_refptr... |
236 if (!HasTypeScopedRefptr(VD->getType())) | 236 if (!HasTypeScopedRefptr(VD->getType())) |
237 continue; | 237 continue; |
238 | 238 |
239 // ..and the initializer is a raw ptr (`scoped_refptr<A> a = rawptr;`)... | 239 // ..and the initializer is a raw ptr (`scoped_refptr<A> a = rawptr;`)... |
240 if (Expr *Init = GetRawPtrInit(VD->getInit())) { | 240 if (Expr *Init = GetRawPtrInit(VD->getInit())) { |
241 // ...rewrite this to a constructor call (`scoped_refptr<A> a(rawptr);`). | 241 // ...rewrite this to a constructor call (`scoped_refptr<A> a(rawptr);`). |
242 SourceLocation DeclEnd = VD->getLocEnd(); | 242 SourceLocation DeclEnd = VD->getLocation(); |
243 SourceLocation Start = DeclEnd.getFileLocWithOffset( | 243 SourceLocation Start = DeclEnd.getFileLocWithOffset( |
244 Lexer::MeasureTokenLength(DeclEnd, *SM, LangOpts)); | 244 Lexer::MeasureTokenLength(DeclEnd, *SM, LangOpts)); |
245 SourceLocation End = Init->getLocStart(); | 245 SourceLocation End = Init->getLocStart(); |
246 CharSourceRange LeftRange( | 246 CharSourceRange LeftRange( |
247 SourceRange(Start, End), /*istokenrange=*/false); | 247 // FIXME: inst loc for start too? (required for macros for end) |
| 248 SourceRange(Start, SM->getInstantiationLoc(End)), |
| 249 /*istokenrange=*/false); |
248 int LeftLen = Rewrite.getRangeSize(LeftRange); | 250 int LeftLen = Rewrite.getRangeSize(LeftRange); |
249 // Can actually happen, if the initialization is a macro (` = NULL;`). | 251 if (LeftLen < 0) { |
| 252 // Could actually happen, if the initialization is a macro (` = NULL;`). |
| 253 // (before I added the getInstantiationLoc call) |
| 254 fprintf(stderr, "raw start:\n"); |
| 255 Start.dump(*SM); |
| 256 fprintf(stderr, "\nlocation:\n"); |
| 257 VD->getLocation().dump(*SM); |
| 258 fprintf(stderr, "\ntst loc:\n"); |
| 259 VD->getTypeSpecStartLoc().dump(*SM); |
| 260 fprintf(stderr, "\ninner loc:\n"); |
| 261 VD->getInnerLocStart().dump(*SM); |
| 262 fprintf(stderr, "\nraw end:\n"); |
| 263 End.dump(*SM); |
| 264 fprintf(stderr, "\nspel:\n"); |
| 265 SM->getSpellingLoc(End).dump(*SM); |
| 266 fprintf(stderr, "\ninst:\n"); |
| 267 SM->getInstantiationLoc(End).dump(*SM); |
| 268 fprintf(stderr, "\n"); |
| 269 } |
250 assert(LeftLen >= 0); | 270 assert(LeftLen >= 0); |
251 | 271 |
252 // Keep indentation on the new line for code like | 272 // Keep indentation on the new line for code like |
253 // scoped_refptr<A> = new A( | 273 // scoped_refptr<A> = new A( |
254 // param); | 274 // param); |
255 std::string spacing; | 275 std::string spacing; |
256 bool Invalid; | 276 bool Invalid; |
257 const char* Data = SM->getCharacterData(Start, &Invalid); | 277 const char* Data = SM->getCharacterData(Start, &Invalid); |
258 assert(!Invalid); | 278 assert(!Invalid); |
259 for (int i = 0; i < LeftLen; ++i) { | 279 for (int i = 0; i < LeftLen; ++i) { |
260 if (Data[i] == '\n') { | 280 if (Data[i] == '\n') { |
261 spacing = std::string(Data + i, LeftLen - i); | 281 spacing = std::string(Data + i, LeftLen - i); |
262 } | 282 } |
263 } | 283 } |
264 | 284 |
265 Rewrite.ReplaceText(Start, LeftLen, "(" + spacing); | 285 bool failed; |
266 | 286 failed = Rewrite.ReplaceText(Start, LeftLen, "(" + spacing); |
267 SourceLocation InitEnd = Init->getLocEnd(); | 287 assert(!failed); |
| 288 |
| 289 //SourceLocation InitEnd = Init->getLocEnd(); |
| 290 SourceLocation InitEnd = SM->getInstantiationLoc(Init->getLocEnd()); |
268 InitEnd = InitEnd.getFileLocWithOffset(Lexer::MeasureTokenLength(InitEnd,
*SM, LangOpts)); | 291 InitEnd = InitEnd.getFileLocWithOffset(Lexer::MeasureTokenLength(InitEnd,
*SM, LangOpts)); |
269 Rewrite.InsertText(InitEnd, ")"); | 292 failed = Rewrite.InsertText(InitEnd, ")"); |
| 293 assert(!failed); |
270 //fprintf(stderr, "inserted )\n"); | 294 //fprintf(stderr, "inserted )\n"); |
271 RewrittenDecls.insert(VD); | 295 RewrittenDecls.insert(VD); |
272 changed = true; | 296 changed = true; |
273 } | 297 } |
274 } | 298 } |
275 return changed; | 299 return changed; |
276 } | 300 } |
277 | 301 |
278 Stmt *RewriteScopedRefptr::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) { | 302 Stmt *RewriteScopedRefptr::RewriteFunctionBodyOrGlobalInitializer(Stmt *S) { |
279 // Try the special-case rewrite first; hope that the general case doesn't | 303 // Try the special-case rewrite first; hope that the general case doesn't |
(...skipping 25 matching lines...) Expand all Loading... |
305 if (!HasTypeScopedRefptr(C->getType())) return S; | 329 if (!HasTypeScopedRefptr(C->getType())) return S; |
306 if (C->getNumArgs() != 1) return S; | 330 if (C->getNumArgs() != 1) return S; |
307 Expr *Inner = C->getArg(0); | 331 Expr *Inner = C->getArg(0); |
308 if (HasTypeScopedRefptr(Inner->getType())) return S; | 332 if (HasTypeScopedRefptr(Inner->getType())) return S; |
309 assert(Inner->getType().getTypePtr()->isPointerType()); | 333 assert(Inner->getType().getTypePtr()->isPointerType()); |
310 | 334 |
311 if (RewrittenExprs.count(Inner) > 0) | 335 if (RewrittenExprs.count(Inner) > 0) |
312 return S; | 336 return S; |
313 | 337 |
314 // Looks like we want to add make_scoped_refptr calls. | 338 // Looks like we want to add make_scoped_refptr calls. |
315 Rewrite.InsertText( | 339 bool failed; |
316 Inner->getLocStart(), | 340 failed = Rewrite.InsertText( |
| 341 SM->getInstantiationLoc(Inner->getLocStart()), |
317 "make_scoped_refptr("); | 342 "make_scoped_refptr("); |
318 SourceLocation End = Inner->getLocEnd(); | 343 assert(!failed); |
| 344 // Need to convert to inst loc before measuring token length, else this |
| 345 // produces `make_scoped_refptr()NULL`. |
| 346 SourceLocation End = SM->getInstantiationLoc(Inner->getLocEnd()); |
319 End = End.getFileLocWithOffset( | 347 End = End.getFileLocWithOffset( |
320 Lexer::MeasureTokenLength(End, *SM, LangOpts)); | 348 Lexer::MeasureTokenLength(End, *SM, LangOpts)); |
321 Rewrite.InsertText( | 349 failed = Rewrite.InsertText( |
322 End, | 350 End, |
323 ")"); | 351 ")"); |
| 352 assert(!failed); |
324 | 353 |
325 RewrittenExprs.insert(Inner); | 354 RewrittenExprs.insert(Inner); |
326 } | 355 } |
327 | 356 |
328 // Return this stmt unmodified. | 357 // Return this stmt unmodified. |
329 return S; | 358 return S; |
330 } | 359 } |
331 | 360 |
332 /// HandleDeclInMainFile - This is called for each top-level decl defined in the | 361 /// HandleDeclInMainFile - This is called for each top-level decl defined in the |
333 /// main file of the input. | 362 /// main file of the input. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 ···· | 406 ···· |
378 // HACK: Ignore out file, overwrite input file | 407 // HACK: Ignore out file, overwrite input file |
379 FILE* f = fopen(InFileName.c_str(), "wb"); | 408 FILE* f = fopen(InFileName.c_str(), "wb"); |
380 assert(f); | 409 assert(f); |
381 fwrite(Result.data(), 1, Result.size(), f); | 410 fwrite(Result.data(), 1, Result.size(), f); |
382 fclose(f); | 411 fclose(f); |
383 } else { | 412 } else { |
384 llvm::errs() << "No changes\n"; | 413 llvm::errs() << "No changes\n"; |
385 } | 414 } |
386 } | 415 } |
LEFT | RIGHT |