|
11 | 11 | //===----------------------------------------------------------------------===//
|
12 | 12 |
|
13 | 13 | #include "CIRGenModule.h"
|
| 14 | +#include "CIRGenCXXABI.h" |
14 | 15 | #include "CIRGenConstantEmitter.h"
|
15 | 16 | #include "CIRGenFunction.h"
|
16 | 17 |
|
|
30 | 31 | using namespace clang;
|
31 | 32 | using namespace clang::CIRGen;
|
32 | 33 |
|
| 34 | +static CIRGenCXXABI *createCXXABI(CIRGenModule &cgm) { |
| 35 | + switch (cgm.getASTContext().getCXXABIKind()) { |
| 36 | + case TargetCXXABI::GenericItanium: |
| 37 | + case TargetCXXABI::GenericAArch64: |
| 38 | + case TargetCXXABI::AppleARM64: |
| 39 | + return CreateCIRGenItaniumCXXABI(cgm); |
| 40 | + |
| 41 | + case TargetCXXABI::Fuchsia: |
| 42 | + case TargetCXXABI::GenericARM: |
| 43 | + case TargetCXXABI::iOS: |
| 44 | + case TargetCXXABI::WatchOS: |
| 45 | + case TargetCXXABI::GenericMIPS: |
| 46 | + case TargetCXXABI::WebAssembly: |
| 47 | + case TargetCXXABI::XL: |
| 48 | + case TargetCXXABI::Microsoft: |
| 49 | + cgm.errorNYI("C++ ABI kind not yet implemented"); |
| 50 | + return nullptr; |
| 51 | + } |
| 52 | + |
| 53 | + llvm_unreachable("invalid C++ ABI kind"); |
| 54 | +} |
| 55 | + |
| 56 | +namespace clang::CIRGen { |
| 57 | +// TODO(cir): Implement target-specific CIRGenCXXABIs |
| 58 | +CIRGenCXXABI *CreateCIRGenItaniumCXXABI(CIRGenModule &cgm) { |
| 59 | + assert(!cir::MissingFeatures::targetSpecificCXXABI()); |
| 60 | + return new CIRGenCXXABI(cgm); |
| 61 | +} |
| 62 | +} // namespace clang::CIRGen |
| 63 | +CIRGenCXXABI::~CIRGenCXXABI() {} |
| 64 | + |
33 | 65 | CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
|
34 | 66 | clang::ASTContext &astContext,
|
35 | 67 | const clang::CodeGenOptions &cgo,
|
36 | 68 | DiagnosticsEngine &diags)
|
37 | 69 | : builder(mlirContext, *this), astContext(astContext),
|
38 | 70 | langOpts(astContext.getLangOpts()), codeGenOpts(cgo),
|
39 | 71 | theModule{mlir::ModuleOp::create(mlir::UnknownLoc::get(&mlirContext))},
|
40 |
| - diags(diags), target(astContext.getTargetInfo()), genTypes(*this) { |
| 72 | + diags(diags), target(astContext.getTargetInfo()), |
| 73 | + abi(createCXXABI(*this)), genTypes(*this) { |
41 | 74 |
|
42 | 75 | // Initialize cached types
|
43 | 76 | VoidTy = cir::VoidType::get(&getMLIRContext());
|
@@ -74,6 +107,8 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext,
|
74 | 107 | builder.getStringAttr(getTriple().str()));
|
75 | 108 | }
|
76 | 109 |
|
| 110 | +CIRGenModule::~CIRGenModule() = default; |
| 111 | + |
77 | 112 | CharUnits CIRGenModule::getNaturalTypeAlignment(QualType t,
|
78 | 113 | LValueBaseInfo *baseInfo) {
|
79 | 114 | assert(!cir::MissingFeatures::opTBAA());
|
@@ -301,9 +336,9 @@ CIRGenModule::getOrCreateCIRGlobal(const VarDecl *d, mlir::Type ty,
|
301 | 336 | if (!ty)
|
302 | 337 | ty = getTypes().convertTypeForMem(astTy);
|
303 | 338 |
|
304 |
| - assert(!cir::MissingFeatures::mangledNames()); |
305 |
| - return getOrCreateCIRGlobal(d->getIdentifier()->getName(), ty, |
306 |
| - astTy.getAddressSpace(), d, isForDefinition); |
| 339 | + StringRef mangledName = getMangledName(d); |
| 340 | + return getOrCreateCIRGlobal(mangledName, ty, astTy.getAddressSpace(), d, |
| 341 | + isForDefinition); |
307 | 342 | }
|
308 | 343 |
|
309 | 344 | /// Return the mlir::Value for the address of the given global variable. If
|
@@ -332,8 +367,9 @@ void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *vd,
|
332 | 367 | const QualType astTy = vd->getType();
|
333 | 368 | const mlir::Type type = convertType(vd->getType());
|
334 | 369 | if (clang::IdentifierInfo *identifier = vd->getIdentifier()) {
|
335 |
| - auto varOp = builder.create<cir::GlobalOp>(getLoc(vd->getSourceRange()), |
336 |
| - identifier->getName(), type); |
| 370 | + StringRef name = getMangledName(GlobalDecl(vd)); |
| 371 | + auto varOp = |
| 372 | + builder.create<cir::GlobalOp>(getLoc(vd->getSourceRange()), name, type); |
337 | 373 | // TODO(CIR): This code for processing initial values is a placeholder
|
338 | 374 | // until class ConstantEmitter is upstreamed and the code for processing
|
339 | 375 | // constant expressions is filled out. Only the most basic handling of
|
@@ -639,13 +675,80 @@ cir::FuncOp CIRGenModule::getAddrOfFunction(clang::GlobalDecl gd,
|
639 | 675 | funcType = convertType(fd->getType());
|
640 | 676 | }
|
641 | 677 |
|
642 |
| - assert(!cir::MissingFeatures::mangledNames()); |
643 |
| - cir::FuncOp func = getOrCreateCIRFunction( |
644 |
| - cast<NamedDecl>(gd.getDecl())->getIdentifier()->getName(), funcType, gd, |
645 |
| - forVTable, dontDefer, /*isThunk=*/false, isForDefinition); |
| 678 | + StringRef mangledName = getMangledName(gd); |
| 679 | + cir::FuncOp func = |
| 680 | + getOrCreateCIRFunction(mangledName, funcType, gd, forVTable, dontDefer, |
| 681 | + /*isThunk=*/false, isForDefinition); |
646 | 682 | return func;
|
647 | 683 | }
|
648 | 684 |
|
| 685 | +static std::string getMangledNameImpl(CIRGenModule &cgm, GlobalDecl gd, |
| 686 | + const NamedDecl *nd) { |
| 687 | + SmallString<256> buffer; |
| 688 | + |
| 689 | + llvm::raw_svector_ostream out(buffer); |
| 690 | + MangleContext &mc = cgm.getCXXABI().getMangleContext(); |
| 691 | + |
| 692 | + assert(!cir::MissingFeatures::moduleNameHash()); |
| 693 | + |
| 694 | + if (mc.shouldMangleDeclName(nd)) { |
| 695 | + mc.mangleName(gd.getWithDecl(nd), out); |
| 696 | + } else { |
| 697 | + IdentifierInfo *ii = nd->getIdentifier(); |
| 698 | + assert(ii && "Attempt to mangle unnamed decl."); |
| 699 | + |
| 700 | + const auto *fd = dyn_cast<FunctionDecl>(nd); |
| 701 | + if (fd && |
| 702 | + fd->getType()->castAs<FunctionType>()->getCallConv() == CC_X86RegCall) { |
| 703 | + cgm.errorNYI(nd->getSourceRange(), "getMangledName: X86RegCall"); |
| 704 | + } else if (fd && fd->hasAttr<CUDAGlobalAttr>() && |
| 705 | + gd.getKernelReferenceKind() == KernelReferenceKind::Stub) { |
| 706 | + cgm.errorNYI(nd->getSourceRange(), "getMangledName: CUDA device stub"); |
| 707 | + } |
| 708 | + out << ii->getName(); |
| 709 | + } |
| 710 | + |
| 711 | + // Check if the module name hash should be appended for internal linkage |
| 712 | + // symbols. This should come before multi-version target suffixes are |
| 713 | + // appendded. This is to keep the name and module hash suffix of the internal |
| 714 | + // linkage function together. The unique suffix should only be added when name |
| 715 | + // mangling is done to make sure that the final name can be properly |
| 716 | + // demangled. For example, for C functions without prototypes, name mangling |
| 717 | + // is not done and the unique suffix should not be appended then. |
| 718 | + assert(!cir::MissingFeatures::moduleNameHash()); |
| 719 | + |
| 720 | + if (const auto *fd = dyn_cast<FunctionDecl>(nd)) { |
| 721 | + if (fd->isMultiVersion()) { |
| 722 | + cgm.errorNYI(nd->getSourceRange(), |
| 723 | + "getMangledName: multi-version functions"); |
| 724 | + } |
| 725 | + } |
| 726 | + if (cgm.getLangOpts().GPURelocatableDeviceCode) { |
| 727 | + cgm.errorNYI(nd->getSourceRange(), |
| 728 | + "getMangledName: GPU relocatable device code"); |
| 729 | + } |
| 730 | + |
| 731 | + return std::string(out.str()); |
| 732 | +} |
| 733 | + |
| 734 | +StringRef CIRGenModule::getMangledName(GlobalDecl gd) { |
| 735 | + GlobalDecl canonicalGd = gd.getCanonicalDecl(); |
| 736 | + |
| 737 | + // Some ABIs don't have constructor variants. Make sure that base and complete |
| 738 | + // constructors get mangled the same. |
| 739 | + if (const auto *cd = dyn_cast<CXXConstructorDecl>(canonicalGd.getDecl())) { |
| 740 | + errorNYI(cd->getSourceRange(), "getMangledName: C++ constructor"); |
| 741 | + return cast<NamedDecl>(gd.getDecl())->getIdentifier()->getName(); |
| 742 | + } |
| 743 | + |
| 744 | + // Keep the first result in the case of a mangling collision. |
| 745 | + const auto *nd = cast<NamedDecl>(gd.getDecl()); |
| 746 | + std::string mangledName = getMangledNameImpl(*this, gd, nd); |
| 747 | + |
| 748 | + auto result = manglings.insert(std::make_pair(mangledName, gd)); |
| 749 | + return mangledDeclNames[canonicalGd] = result.first->first(); |
| 750 | +} |
| 751 | + |
649 | 752 | cir::FuncOp CIRGenModule::getOrCreateCIRFunction(
|
650 | 753 | StringRef mangledName, mlir::Type funcType, GlobalDecl gd, bool forVTable,
|
651 | 754 | bool dontDefer, bool isThunk, ForDefinition_t isForDefinition,
|
|
0 commit comments