|
22 | 22 | #include "clang/Basic/SourceManager.h"
|
23 | 23 | #include "clang/Basic/TargetInfo.h"
|
24 | 24 | #include "llvm/ADT/StringExtras.h"
|
| 25 | +#include "llvm/IR/DataLayout.h" |
25 | 26 | #include "llvm/IR/Mangler.h"
|
26 | 27 | #include "llvm/Support/ErrorHandling.h"
|
27 | 28 | #include "llvm/Support/raw_ostream.h"
|
@@ -283,183 +284,204 @@ void MangleContext::mangleObjCMethodName(const ObjCMethodDecl *MD,
|
283 | 284 | Out << OS.str().size() << OS.str();
|
284 | 285 | }
|
285 | 286 |
|
286 |
| -ASTNameGenerator::ASTNameGenerator(ASTContext &Ctx) |
287 |
| - : MC(Ctx.createMangleContext()), DL(Ctx.getTargetInfo().getDataLayout()) {} |
| 287 | +class ASTNameGenerator::Implementation { |
| 288 | + std::unique_ptr<MangleContext> MC; |
| 289 | + llvm::DataLayout DL; |
288 | 290 |
|
289 |
| -bool ASTNameGenerator::writeName(const Decl *D, raw_ostream &OS) { |
290 |
| - // First apply frontend mangling. |
291 |
| - SmallString<128> FrontendBuf; |
292 |
| - llvm::raw_svector_ostream FrontendBufOS(FrontendBuf); |
293 |
| - if (auto *FD = dyn_cast<FunctionDecl>(D)) { |
294 |
| - if (FD->isDependentContext()) |
295 |
| - return true; |
296 |
| - if (writeFuncOrVarName(FD, FrontendBufOS)) |
297 |
| - return true; |
298 |
| - } else if (auto *VD = dyn_cast<VarDecl>(D)) { |
299 |
| - if (writeFuncOrVarName(VD, FrontendBufOS)) |
| 291 | +public: |
| 292 | + explicit Implementation(ASTContext &Ctx) |
| 293 | + : MC(Ctx.createMangleContext()), DL(Ctx.getTargetInfo().getDataLayout()) { |
| 294 | + } |
| 295 | + |
| 296 | + bool writeName(const Decl *D, raw_ostream &OS) { |
| 297 | + // First apply frontend mangling. |
| 298 | + SmallString<128> FrontendBuf; |
| 299 | + llvm::raw_svector_ostream FrontendBufOS(FrontendBuf); |
| 300 | + if (auto *FD = dyn_cast<FunctionDecl>(D)) { |
| 301 | + if (FD->isDependentContext()) |
| 302 | + return true; |
| 303 | + if (writeFuncOrVarName(FD, FrontendBufOS)) |
| 304 | + return true; |
| 305 | + } else if (auto *VD = dyn_cast<VarDecl>(D)) { |
| 306 | + if (writeFuncOrVarName(VD, FrontendBufOS)) |
| 307 | + return true; |
| 308 | + } else if (auto *MD = dyn_cast<ObjCMethodDecl>(D)) { |
| 309 | + MC->mangleObjCMethodNameWithoutSize(MD, OS); |
| 310 | + return false; |
| 311 | + } else if (auto *ID = dyn_cast<ObjCInterfaceDecl>(D)) { |
| 312 | + writeObjCClassName(ID, FrontendBufOS); |
| 313 | + } else { |
300 | 314 | return true;
|
301 |
| - } else if (auto *MD = dyn_cast<ObjCMethodDecl>(D)) { |
302 |
| - MC->mangleObjCMethodNameWithoutSize(MD, OS); |
| 315 | + } |
| 316 | + |
| 317 | + // Now apply backend mangling. |
| 318 | + llvm::Mangler::getNameWithPrefix(OS, FrontendBufOS.str(), DL); |
303 | 319 | return false;
|
304 |
| - } else if (auto *ID = dyn_cast<ObjCInterfaceDecl>(D)) { |
305 |
| - writeObjCClassName(ID, FrontendBufOS); |
306 |
| - } else { |
307 |
| - return true; |
308 | 320 | }
|
309 | 321 |
|
310 |
| - // Now apply backend mangling. |
311 |
| - llvm::Mangler::getNameWithPrefix(OS, FrontendBufOS.str(), DL); |
312 |
| - return false; |
313 |
| -} |
314 |
| - |
315 |
| -std::string ASTNameGenerator::getName(const Decl *D) { |
316 |
| - std::string Name; |
317 |
| - { |
318 |
| - llvm::raw_string_ostream OS(Name); |
319 |
| - writeName(D, OS); |
| 322 | + std::string getName(const Decl *D) { |
| 323 | + std::string Name; |
| 324 | + { |
| 325 | + llvm::raw_string_ostream OS(Name); |
| 326 | + writeName(D, OS); |
| 327 | + } |
| 328 | + return Name; |
320 | 329 | }
|
321 |
| - return Name; |
322 |
| -} |
323 | 330 |
|
324 |
| -enum ObjCKind { |
325 |
| - ObjCClass, |
326 |
| - ObjCMetaclass, |
327 |
| -}; |
| 331 | + enum ObjCKind { |
| 332 | + ObjCClass, |
| 333 | + ObjCMetaclass, |
| 334 | + }; |
328 | 335 |
|
329 |
| -static StringRef getClassSymbolPrefix(ObjCKind Kind, |
330 |
| - const ASTContext &Context) { |
331 |
| - if (Context.getLangOpts().ObjCRuntime.isGNUFamily()) |
332 |
| - return Kind == ObjCMetaclass ? "_OBJC_METACLASS_" : "_OBJC_CLASS_"; |
333 |
| - return Kind == ObjCMetaclass ? "OBJC_METACLASS_$_" : "OBJC_CLASS_$_"; |
334 |
| -} |
| 336 | + static StringRef getClassSymbolPrefix(ObjCKind Kind, |
| 337 | + const ASTContext &Context) { |
| 338 | + if (Context.getLangOpts().ObjCRuntime.isGNUFamily()) |
| 339 | + return Kind == ObjCMetaclass ? "_OBJC_METACLASS_" : "_OBJC_CLASS_"; |
| 340 | + return Kind == ObjCMetaclass ? "OBJC_METACLASS_$_" : "OBJC_CLASS_$_"; |
| 341 | + } |
335 | 342 |
|
336 |
| -std::vector<std::string> |
337 |
| -ASTNameGenerator::getAllManglings(const ObjCContainerDecl *OCD) { |
338 |
| - StringRef ClassName; |
339 |
| - if (const auto *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) |
340 |
| - ClassName = OID->getObjCRuntimeNameAsString(); |
341 |
| - else if (const auto *OID = dyn_cast<ObjCImplementationDecl>(OCD)) |
342 |
| - ClassName = OID->getObjCRuntimeNameAsString(); |
343 |
| - |
344 |
| - if (ClassName.empty()) |
345 |
| - return {}; |
346 |
| - |
347 |
| - auto Mangle = [&](ObjCKind Kind, StringRef ClassName) -> std::string { |
348 |
| - SmallString<40> Mangled; |
349 |
| - auto Prefix = getClassSymbolPrefix(Kind, OCD->getASTContext()); |
350 |
| - llvm::Mangler::getNameWithPrefix(Mangled, Prefix + ClassName, DL); |
351 |
| - return Mangled.str(); |
352 |
| - }; |
| 343 | + std::vector<std::string> getAllManglings(const ObjCContainerDecl *OCD) { |
| 344 | + StringRef ClassName; |
| 345 | + if (const auto *OID = dyn_cast<ObjCInterfaceDecl>(OCD)) |
| 346 | + ClassName = OID->getObjCRuntimeNameAsString(); |
| 347 | + else if (const auto *OID = dyn_cast<ObjCImplementationDecl>(OCD)) |
| 348 | + ClassName = OID->getObjCRuntimeNameAsString(); |
| 349 | + |
| 350 | + if (ClassName.empty()) |
| 351 | + return {}; |
| 352 | + |
| 353 | + auto Mangle = [&](ObjCKind Kind, StringRef ClassName) -> std::string { |
| 354 | + SmallString<40> Mangled; |
| 355 | + auto Prefix = getClassSymbolPrefix(Kind, OCD->getASTContext()); |
| 356 | + llvm::Mangler::getNameWithPrefix(Mangled, Prefix + ClassName, DL); |
| 357 | + return Mangled.str(); |
| 358 | + }; |
| 359 | + |
| 360 | + return { |
| 361 | + Mangle(ObjCClass, ClassName), |
| 362 | + Mangle(ObjCMetaclass, ClassName), |
| 363 | + }; |
| 364 | + } |
353 | 365 |
|
354 |
| - return { |
355 |
| - Mangle(ObjCClass, ClassName), |
356 |
| - Mangle(ObjCMetaclass, ClassName), |
357 |
| - }; |
358 |
| -} |
| 366 | + std::vector<std::string> getAllManglings(const Decl *D) { |
| 367 | + if (const auto *OCD = dyn_cast<ObjCContainerDecl>(D)) |
| 368 | + return getAllManglings(OCD); |
359 | 369 |
|
360 |
| -std::vector<std::string> ASTNameGenerator::getAllManglings(const Decl *D) { |
361 |
| - if (const auto *OCD = dyn_cast<ObjCContainerDecl>(D)) |
362 |
| - return getAllManglings(OCD); |
| 370 | + if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D))) |
| 371 | + return {}; |
363 | 372 |
|
364 |
| - if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D))) |
365 |
| - return {}; |
| 373 | + const NamedDecl *ND = cast<NamedDecl>(D); |
366 | 374 |
|
367 |
| - const NamedDecl *ND = cast<NamedDecl>(D); |
| 375 | + ASTContext &Ctx = ND->getASTContext(); |
| 376 | + std::unique_ptr<MangleContext> M(Ctx.createMangleContext()); |
368 | 377 |
|
369 |
| - ASTContext &Ctx = ND->getASTContext(); |
370 |
| - std::unique_ptr<MangleContext> M(Ctx.createMangleContext()); |
| 378 | + std::vector<std::string> Manglings; |
371 | 379 |
|
372 |
| - std::vector<std::string> Manglings; |
| 380 | + auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) { |
| 381 | + auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false, |
| 382 | + /*IsCSSMethod=*/true); |
| 383 | + auto CC = MD->getType()->getAs<FunctionProtoType>()->getCallConv(); |
| 384 | + return CC == DefaultCC; |
| 385 | + }; |
373 | 386 |
|
374 |
| - auto hasDefaultCXXMethodCC = [](ASTContext &C, const CXXMethodDecl *MD) { |
375 |
| - auto DefaultCC = C.getDefaultCallingConvention(/*IsVariadic=*/false, |
376 |
| - /*IsCSSMethod=*/true); |
377 |
| - auto CC = MD->getType()->getAs<FunctionProtoType>()->getCallConv(); |
378 |
| - return CC == DefaultCC; |
379 |
| - }; |
| 387 | + if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) { |
| 388 | + Manglings.emplace_back(getMangledStructor(CD, Ctor_Base)); |
| 389 | + |
| 390 | + if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) |
| 391 | + if (!CD->getParent()->isAbstract()) |
| 392 | + Manglings.emplace_back(getMangledStructor(CD, Ctor_Complete)); |
380 | 393 |
|
381 |
| - if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) { |
382 |
| - Manglings.emplace_back(getMangledStructor(CD, Ctor_Base)); |
383 |
| - |
384 |
| - if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) |
385 |
| - if (!CD->getParent()->isAbstract()) |
386 |
| - Manglings.emplace_back(getMangledStructor(CD, Ctor_Complete)); |
387 |
| - |
388 |
| - if (Ctx.getTargetInfo().getCXXABI().isMicrosoft()) |
389 |
| - if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor()) |
390 |
| - if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0)) |
391 |
| - Manglings.emplace_back(getMangledStructor(CD, Ctor_DefaultClosure)); |
392 |
| - } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) { |
393 |
| - Manglings.emplace_back(getMangledStructor(DD, Dtor_Base)); |
394 |
| - if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) { |
395 |
| - Manglings.emplace_back(getMangledStructor(DD, Dtor_Complete)); |
396 |
| - if (DD->isVirtual()) |
397 |
| - Manglings.emplace_back(getMangledStructor(DD, Dtor_Deleting)); |
| 394 | + if (Ctx.getTargetInfo().getCXXABI().isMicrosoft()) |
| 395 | + if (CD->hasAttr<DLLExportAttr>() && CD->isDefaultConstructor()) |
| 396 | + if (!(hasDefaultCXXMethodCC(Ctx, CD) && CD->getNumParams() == 0)) |
| 397 | + Manglings.emplace_back(getMangledStructor(CD, Ctor_DefaultClosure)); |
| 398 | + } else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) { |
| 399 | + Manglings.emplace_back(getMangledStructor(DD, Dtor_Base)); |
| 400 | + if (Ctx.getTargetInfo().getCXXABI().isItaniumFamily()) { |
| 401 | + Manglings.emplace_back(getMangledStructor(DD, Dtor_Complete)); |
| 402 | + if (DD->isVirtual()) |
| 403 | + Manglings.emplace_back(getMangledStructor(DD, Dtor_Deleting)); |
| 404 | + } |
| 405 | + } else if (const auto *MD = dyn_cast_or_null<CXXMethodDecl>(ND)) { |
| 406 | + Manglings.emplace_back(getName(ND)); |
| 407 | + if (MD->isVirtual()) |
| 408 | + if (const auto *TIV = Ctx.getVTableContext()->getThunkInfo(MD)) |
| 409 | + for (const auto &T : *TIV) |
| 410 | + Manglings.emplace_back(getMangledThunk(MD, T)); |
398 | 411 | }
|
399 |
| - } else if (const auto *MD = dyn_cast_or_null<CXXMethodDecl>(ND)) { |
400 |
| - Manglings.emplace_back(getName(ND)); |
401 |
| - if (MD->isVirtual()) |
402 |
| - if (const auto *TIV = Ctx.getVTableContext()->getThunkInfo(MD)) |
403 |
| - for (const auto &T : *TIV) |
404 |
| - Manglings.emplace_back(getMangledThunk(MD, T)); |
| 412 | + |
| 413 | + return Manglings; |
405 | 414 | }
|
406 | 415 |
|
407 |
| - return Manglings; |
408 |
| -} |
| 416 | +private: |
| 417 | + bool writeFuncOrVarName(const NamedDecl *D, raw_ostream &OS) { |
| 418 | + if (MC->shouldMangleDeclName(D)) { |
| 419 | + if (const auto *CtorD = dyn_cast<CXXConstructorDecl>(D)) |
| 420 | + MC->mangleCXXCtor(CtorD, Ctor_Complete, OS); |
| 421 | + else if (const auto *DtorD = dyn_cast<CXXDestructorDecl>(D)) |
| 422 | + MC->mangleCXXDtor(DtorD, Dtor_Complete, OS); |
| 423 | + else |
| 424 | + MC->mangleName(D, OS); |
| 425 | + return false; |
| 426 | + } else { |
| 427 | + IdentifierInfo *II = D->getIdentifier(); |
| 428 | + if (!II) |
| 429 | + return true; |
| 430 | + OS << II->getName(); |
| 431 | + return false; |
| 432 | + } |
| 433 | + } |
409 | 434 |
|
410 |
| -bool ASTNameGenerator::writeFuncOrVarName(const NamedDecl *D, raw_ostream &OS) { |
411 |
| - if (MC->shouldMangleDeclName(D)) { |
412 |
| - if (const auto *CtorD = dyn_cast<CXXConstructorDecl>(D)) |
413 |
| - MC->mangleCXXCtor(CtorD, Ctor_Complete, OS); |
414 |
| - else if (const auto *DtorD = dyn_cast<CXXDestructorDecl>(D)) |
415 |
| - MC->mangleCXXDtor(DtorD, Dtor_Complete, OS); |
416 |
| - else |
417 |
| - MC->mangleName(D, OS); |
418 |
| - return false; |
419 |
| - } else { |
420 |
| - IdentifierInfo *II = D->getIdentifier(); |
421 |
| - if (!II) |
422 |
| - return true; |
423 |
| - OS << II->getName(); |
424 |
| - return false; |
| 435 | + void writeObjCClassName(const ObjCInterfaceDecl *D, raw_ostream &OS) { |
| 436 | + OS << getClassSymbolPrefix(ObjCClass, D->getASTContext()); |
| 437 | + OS << D->getObjCRuntimeNameAsString(); |
425 | 438 | }
|
426 |
| -} |
427 | 439 |
|
428 |
| -void ASTNameGenerator::writeObjCClassName(const ObjCInterfaceDecl *D, |
429 |
| - raw_ostream &OS) { |
430 |
| - OS << getClassSymbolPrefix(ObjCClass, D->getASTContext()); |
431 |
| - OS << D->getObjCRuntimeNameAsString(); |
432 |
| -} |
| 440 | + std::string getMangledStructor(const NamedDecl *ND, unsigned StructorType) { |
| 441 | + std::string FrontendBuf; |
| 442 | + llvm::raw_string_ostream FOS(FrontendBuf); |
| 443 | + |
| 444 | + if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) |
| 445 | + MC->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS); |
| 446 | + else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) |
| 447 | + MC->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS); |
433 | 448 |
|
434 |
| -std::string ASTNameGenerator::getMangledStructor(const NamedDecl *ND, |
435 |
| - unsigned StructorType) { |
436 |
| - std::string FrontendBuf; |
437 |
| - llvm::raw_string_ostream FOS(FrontendBuf); |
| 449 | + std::string BackendBuf; |
| 450 | + llvm::raw_string_ostream BOS(BackendBuf); |
438 | 451 |
|
439 |
| - if (const auto *CD = dyn_cast_or_null<CXXConstructorDecl>(ND)) |
440 |
| - MC->mangleCXXCtor(CD, static_cast<CXXCtorType>(StructorType), FOS); |
441 |
| - else if (const auto *DD = dyn_cast_or_null<CXXDestructorDecl>(ND)) |
442 |
| - MC->mangleCXXDtor(DD, static_cast<CXXDtorType>(StructorType), FOS); |
| 452 | + llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL); |
443 | 453 |
|
444 |
| - std::string BackendBuf; |
445 |
| - llvm::raw_string_ostream BOS(BackendBuf); |
| 454 | + return BOS.str(); |
| 455 | + } |
446 | 456 |
|
447 |
| - llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL); |
| 457 | + std::string getMangledThunk(const CXXMethodDecl *MD, const ThunkInfo &T) { |
| 458 | + std::string FrontendBuf; |
| 459 | + llvm::raw_string_ostream FOS(FrontendBuf); |
448 | 460 |
|
449 |
| - return BOS.str(); |
450 |
| -} |
| 461 | + MC->mangleThunk(MD, T, FOS); |
451 | 462 |
|
452 |
| -std::string ASTNameGenerator::getMangledThunk(const CXXMethodDecl *MD, |
453 |
| - const ThunkInfo &T) { |
454 |
| - std::string FrontendBuf; |
455 |
| - llvm::raw_string_ostream FOS(FrontendBuf); |
| 463 | + std::string BackendBuf; |
| 464 | + llvm::raw_string_ostream BOS(BackendBuf); |
456 | 465 |
|
457 |
| - MC->mangleThunk(MD, T, FOS); |
| 466 | + llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL); |
458 | 467 |
|
459 |
| - std::string BackendBuf; |
460 |
| - llvm::raw_string_ostream BOS(BackendBuf); |
| 468 | + return BOS.str(); |
| 469 | + } |
| 470 | +}; |
461 | 471 |
|
462 |
| - llvm::Mangler::getNameWithPrefix(BOS, FOS.str(), DL); |
| 472 | +ASTNameGenerator::ASTNameGenerator(ASTContext &Ctx) |
| 473 | + : Impl(llvm::make_unique<Implementation>(Ctx)) {} |
| 474 | + |
| 475 | +ASTNameGenerator::~ASTNameGenerator() {} |
463 | 476 |
|
464 |
| - return BOS.str(); |
| 477 | +bool ASTNameGenerator::writeName(const Decl *D, raw_ostream &OS) { |
| 478 | + return Impl->writeName(D, OS); |
| 479 | +} |
| 480 | + |
| 481 | +std::string ASTNameGenerator::getName(const Decl *D) { |
| 482 | + return Impl->getName(D); |
| 483 | +} |
| 484 | + |
| 485 | +std::vector<std::string> ASTNameGenerator::getAllManglings(const Decl *D) { |
| 486 | + return Impl->getAllManglings(D); |
465 | 487 | }
|
0 commit comments