diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -40,7 +40,6 @@ namespace llvm { struct fltSemantics; -class DataLayout; } namespace clang { @@ -205,7 +204,8 @@ unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth; unsigned short SimdDefaultAlign; - std::unique_ptr DataLayout; + std::string DataLayoutString; + const char *UserLabelPrefix; const char *MCountName; unsigned char RegParmMax, SSERegParmMax; TargetCXXABI TheCXXABI; @@ -238,7 +238,9 @@ // TargetInfo Constructor. Default initializes all fields. TargetInfo(const llvm::Triple &T); - void resetDataLayout(StringRef DL); + // UserLabelPrefix must match DL's getGlobalPrefix() when interpreted + // as a DataLayout object. + void resetDataLayout(StringRef DL, const char *UserLabelPrefix = ""); public: /// Construct a target for the given options. @@ -747,6 +749,12 @@ return PointerWidth; } + /// \brief Returns the default value of the __USER_LABEL_PREFIX__ macro, + /// which is the prefix given to user symbols by default. + /// + /// On most platforms this is "", but it is "_" on some. + const char *getUserLabelPrefix() const { return UserLabelPrefix; } + /// Returns the name of the mcount instrumentation function. const char *getMCountName() const { return MCountName; @@ -1096,9 +1104,9 @@ /// Returns the target ID if supported. virtual llvm::Optional getTargetID() const { return llvm::None; } - const llvm::DataLayout &getDataLayout() const { - assert(DataLayout && "Uninitialized DataLayout!"); - return *DataLayout; + const char *getDataLayoutString() const { + assert(!DataLayoutString.empty() && "Uninitialized DataLayout!"); + return DataLayoutString.c_str(); } struct GCCRegAlias { diff --git a/clang/include/clang/CodeGen/BackendUtil.h b/clang/include/clang/CodeGen/BackendUtil.h --- a/clang/include/clang/CodeGen/BackendUtil.h +++ b/clang/include/clang/CodeGen/BackendUtil.h @@ -39,8 +39,7 @@ void EmitBackendOutput(DiagnosticsEngine &Diags, const HeaderSearchOptions &, const CodeGenOptions &CGOpts, const TargetOptions &TOpts, const LangOptions &LOpts, - const llvm::DataLayout &TDesc, llvm::Module *M, - BackendAction Action, + StringRef TDesc, llvm::Module *M, BackendAction Action, std::unique_ptr OS); void EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts, diff --git a/clang/lib/AST/Mangle.cpp b/clang/lib/AST/Mangle.cpp --- a/clang/lib/AST/Mangle.cpp +++ b/clang/lib/AST/Mangle.cpp @@ -139,7 +139,9 @@ } void MangleContext::mangleName(GlobalDecl GD, raw_ostream &Out) { + const ASTContext &ASTContext = getASTContext(); const NamedDecl *D = cast(GD.getDecl()); + // Any decl can be declared with __asm("foo") on it, and this takes precedence // over all other naming in the .o file. if (const AsmLabelAttr *ALA = D->getAttr()) { @@ -157,9 +159,16 @@ // tricks normally used for producing aliases (PR9177). Fortunately the // llvm mangler on ELF is a nop, so we can just avoid adding the \01 // marker. + StringRef UserLabelPrefix = + getASTContext().getTargetInfo().getUserLabelPrefix(); +#ifndef NDEBUG char GlobalPrefix = - getASTContext().getTargetInfo().getDataLayout().getGlobalPrefix(); - if (GlobalPrefix) + llvm::DataLayout(getASTContext().getTargetInfo().getDataLayoutString()) + .getGlobalPrefix(); + assert((UserLabelPrefix.empty() && !GlobalPrefix) || + (UserLabelPrefix.size() == 1 && UserLabelPrefix[0] == GlobalPrefix)); +#endif + if (!UserLabelPrefix.empty()) Out << '\01'; // LLVM IR Marker for __asm("foo") Out << ALA->getLabel(); @@ -169,7 +178,6 @@ if (auto *GD = dyn_cast(D)) return mangleMSGuidDecl(GD, Out); - const ASTContext &ASTContext = getASTContext(); CCMangling CC = getCallingConvMangling(ASTContext, D); if (CC == CCM_WasmMainArgcArgv) { @@ -383,8 +391,8 @@ public: explicit Implementation(ASTContext &Ctx) - : MC(Ctx.createMangleContext()), DL(Ctx.getTargetInfo().getDataLayout()) { - } + : MC(Ctx.createMangleContext()), + DL(Ctx.getTargetInfo().getDataLayoutString()) {} bool writeName(const Decl *D, raw_ostream &OS) { // First apply frontend mangling. diff --git a/clang/lib/Basic/CMakeLists.txt b/clang/lib/Basic/CMakeLists.txt --- a/clang/lib/Basic/CMakeLists.txt +++ b/clang/lib/Basic/CMakeLists.txt @@ -1,5 +1,4 @@ set(LLVM_LINK_COMPONENTS - Core MC Support ) diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -17,7 +17,6 @@ #include "clang/Basic/LangOptions.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/IR/DataLayout.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TargetParser.h" #include @@ -114,6 +113,7 @@ LongDoubleFormat = &llvm::APFloat::IEEEdouble(); Float128Format = &llvm::APFloat::IEEEquad(); MCountName = "mcount"; + UserLabelPrefix = "_"; RegParmMax = 0; SSERegParmMax = 0; HasAlignMac68kSupport = false; @@ -149,8 +149,9 @@ // Out of line virtual dtor for TargetInfo. TargetInfo::~TargetInfo() {} -void TargetInfo::resetDataLayout(StringRef DL) { - DataLayout.reset(new llvm::DataLayout(DL)); +void TargetInfo::resetDataLayout(StringRef DL, const char *ULP) { + DataLayoutString = DL.str(); + UserLabelPrefix = ULP; } bool diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -745,9 +745,9 @@ void AArch64leTargetInfo::setDataLayout() { if (getTriple().isOSBinFormatMachO()) { if(getTriple().isArch32Bit()) - resetDataLayout("e-m:o-p:32:32-i64:64-i128:128-n32:64-S128"); + resetDataLayout("e-m:o-p:32:32-i64:64-i128:128-n32:64-S128", "_"); else - resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128"); + resetDataLayout("e-m:o-i64:64-i128:128-n32:64-S128", "_"); } else resetDataLayout("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"); } @@ -796,7 +796,8 @@ void WindowsARM64TargetInfo::setDataLayout() { resetDataLayout(Triple.isOSBinFormatMachO() ? "e-m:o-i64:64-i128:128-n32:64-S128" - : "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128"); + : "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128", + Triple.isOSBinFormatMachO() ? "_" : ""); } TargetInfo::BuiltinVaListKind diff --git a/clang/lib/Basic/Targets/AMDGPU.cpp b/clang/lib/Basic/Targets/AMDGPU.cpp --- a/clang/lib/Basic/Targets/AMDGPU.cpp +++ b/clang/lib/Basic/Targets/AMDGPU.cpp @@ -18,7 +18,6 @@ #include "clang/Basic/TargetBuiltins.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Frontend/OpenMP/OMPGridValues.h" -#include "llvm/IR/DataLayout.h" using namespace clang; using namespace clang::targets; @@ -329,7 +328,6 @@ llvm::AMDGPU::getArchAttrR600(GPUKind)) { resetDataLayout(isAMDGCN(getTriple()) ? DataLayoutStringAMDGCN : DataLayoutStringR600); - assert(DataLayout->getAllocaAddrSpace() == Private); GridValues = llvm::omp::AMDGPUGpuGridValues; setAddressSpaceMap(Triple.getOS() == llvm::Triple::Mesa3D || @@ -342,7 +340,7 @@ AllowAMDGPUUnsafeFPAtomics = Opts.AllowAMDGPUUnsafeFPAtomics; // Set pointer width and alignment for target address space 0. - PointerWidth = PointerAlign = DataLayout->getPointerSizeInBits(); + PointerWidth = PointerAlign = getPointerWidthV(Generic); if (getMaxPointerWidth() == 64) { LongWidth = LongAlign = 64; SizeType = UnsignedLong; diff --git a/clang/lib/Basic/Targets/ARM.cpp b/clang/lib/Basic/Targets/ARM.cpp --- a/clang/lib/Basic/Targets/ARM.cpp +++ b/clang/lib/Basic/Targets/ARM.cpp @@ -44,7 +44,8 @@ if (T.isOSBinFormatMachO()) { resetDataLayout(BigEndian ? "E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" - : "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"); + : "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", + "_"); } else if (T.isOSWindows()) { assert(!BigEndian && "Windows on ARM does not support big endian"); resetDataLayout("e" @@ -93,12 +94,13 @@ if (T.isOSBinFormatMachO() && IsAAPCS16) { assert(!BigEndian && "AAPCS16 does not support big-endian"); - resetDataLayout("e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128"); + resetDataLayout("e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128", "_"); } else if (T.isOSBinFormatMachO()) resetDataLayout( BigEndian ? "E-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32" - : "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"); + : "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32", + "_"); else resetDataLayout( BigEndian diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -468,7 +468,7 @@ BoolWidth = BoolAlign = 32; // XXX support -mone-byte-bool? PtrDiffType = SignedInt; // for http://llvm.org/bugs/show_bug.cgi?id=15726 LongLongAlign = 32; - resetDataLayout("E-m:o-p:32:32-f64:32:64-n32"); + resetDataLayout("E-m:o-p:32:32-f64:32:64-n32", "_"); } BuiltinVaListKind getBuiltinVaListKind() const override { @@ -482,7 +482,7 @@ DarwinPPC64TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : DarwinTargetInfo(Triple, Opts) { HasAlignMac68kSupport = true; - resetDataLayout("E-m:o-i64:64-n32:64"); + resetDataLayout("E-m:o-i64:64-n32:64", "_"); } }; diff --git a/clang/lib/Basic/Targets/X86.h b/clang/lib/Basic/Targets/X86.h --- a/clang/lib/Basic/Targets/X86.h +++ b/clang/lib/Basic/Targets/X86.h @@ -386,11 +386,13 @@ LongDoubleWidth = 96; LongDoubleAlign = 32; SuitableAlign = 128; - resetDataLayout(Triple.isOSBinFormatMachO() ? - "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-" - "f80:32-n8:16:32-S128" : - "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-" - "f80:32-n8:16:32-S128"); + resetDataLayout( + Triple.isOSBinFormatMachO() + ? "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-" + "f80:32-n8:16:32-S128" + : "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-" + "f80:32-n8:16:32-S128", + Triple.isOSBinFormatMachO() ? "_" : ""); SizeType = UnsignedInt; PtrDiffType = SignedInt; IntPtrType = SignedInt; @@ -494,7 +496,7 @@ SizeType = UnsignedLong; IntPtrType = SignedLong; resetDataLayout("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-" - "f80:128-n8:16:32-S128"); + "f80:128-n8:16:32-S128", "_"); HasAlignMac68kSupport = true; } @@ -522,7 +524,8 @@ resetDataLayout(IsWinCOFF ? "e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:" "64-i64:64-f80:32-n8:16:32-a:0:32-S32" : "e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:" - "64-i64:64-f80:32-n8:16:32-a:0:32-S32"); + "64-i64:64-f80:32-n8:16:32-a:0:32-S32", + IsWinCOFF ? "_" : ""); } }; @@ -571,7 +574,8 @@ this->WCharType = TargetInfo::UnsignedShort; DoubleAlign = LongLongAlign = 64; resetDataLayout("e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:" - "32-n8:16:32-a:0:32-S32"); + "32-n8:16:32-a:0:32-S32", + "_"); } void getTargetDefines(const LangOptions &Opts, @@ -866,7 +870,7 @@ if (T.isiOS()) UseSignedCharForObjCBool = false; resetDataLayout("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:" - "16:32:64-S128"); + "16:32:64-S128", "_"); } bool handleTargetFeatures(std::vector &Features, diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -1600,7 +1600,7 @@ const CodeGenOptions &CGOpts, const clang::TargetOptions &TOpts, const LangOptions &LOpts, - const llvm::DataLayout &TDesc, Module *M, + StringRef TDesc, Module *M, BackendAction Action, std::unique_ptr OS) { @@ -1654,11 +1654,11 @@ // DataLayout. if (AsmHelper.TM) { std::string DLDesc = M->getDataLayout().getStringRepresentation(); - if (DLDesc != TDesc.getStringRepresentation()) { + if (DLDesc != TDesc) { unsigned DiagID = Diags.getCustomDiagID( DiagnosticsEngine::Error, "backend data layout '%0' does not match " "expected target description '%1'"); - Diags.Report(DiagID) << DLDesc << TDesc.getStringRepresentation(); + Diags.Report(DiagID) << DLDesc << TDesc; } } } diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp --- a/clang/lib/CodeGen/CodeGenAction.cpp +++ b/clang/lib/CodeGen/CodeGenAction.cpp @@ -332,7 +332,7 @@ EmbedBitcode(getModule(), CodeGenOpts, llvm::MemoryBufferRef()); EmitBackendOutput(Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts, - LangOpts, C.getTargetInfo().getDataLayout(), + LangOpts, C.getTargetInfo().getDataLayoutString(), getModule(), Action, std::move(AsmOutStream)); Ctx.setDiagnosticHandler(std::move(OldDiagnosticHandler)); @@ -1105,7 +1105,7 @@ EmitBackendOutput(Diagnostics, CI.getHeaderSearchOpts(), CodeGenOpts, TargetOpts, CI.getLangOpts(), - CI.getTarget().getDataLayout(), TheModule.get(), BA, + CI.getTarget().getDataLayoutString(), TheModule.get(), BA, std::move(OS)); if (OptRecordFile) OptRecordFile->keep(); diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp --- a/clang/lib/CodeGen/ModuleBuilder.cpp +++ b/clang/lib/CodeGen/ModuleBuilder.cpp @@ -138,7 +138,7 @@ Ctx = &Context; M->setTargetTriple(Ctx->getTargetInfo().getTriple().getTriple()); - M->setDataLayout(Ctx->getTargetInfo().getDataLayout()); + M->setDataLayout(Ctx->getTargetInfo().getDataLayoutString()); const auto &SDKVersion = Ctx->getTargetInfo().getSDKVersion(); if (!SDKVersion.empty()) M->setSDKVersion(SDKVersion); diff --git a/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp b/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp --- a/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp +++ b/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp @@ -166,7 +166,7 @@ Ctx = &Context; VMContext.reset(new llvm::LLVMContext()); M.reset(new llvm::Module(MainFileName, *VMContext)); - M->setDataLayout(Ctx->getTargetInfo().getDataLayout()); + M->setDataLayout(Ctx->getTargetInfo().getDataLayoutString()); Builder.reset(new CodeGen::CodeGenModule( *Ctx, HeaderSearchOpts, PreprocessorOpts, CodeGenOpts, *M, Diags)); @@ -245,7 +245,7 @@ return; M->setTargetTriple(Ctx.getTargetInfo().getTriple().getTriple()); - M->setDataLayout(Ctx.getTargetInfo().getDataLayout()); + M->setDataLayout(Ctx.getTargetInfo().getDataLayoutString()); // PCH files don't have a signature field in the control block, // but LLVM detects DWO CUs by looking for a non-zero DWO id. @@ -295,7 +295,7 @@ llvm::SmallString<0> Buffer; clang::EmitBackendOutput( Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts, LangOpts, - Ctx.getTargetInfo().getDataLayout(), M.get(), + Ctx.getTargetInfo().getDataLayoutString(), M.get(), BackendAction::Backend_EmitLL, std::make_unique(Buffer)); llvm::dbgs() << Buffer; @@ -303,9 +303,9 @@ // Use the LLVM backend to emit the pch container. clang::EmitBackendOutput(Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts, - LangOpts, Ctx.getTargetInfo().getDataLayout(), - M.get(), BackendAction::Backend_EmitObj, - std::move(OS)); + LangOpts, + Ctx.getTargetInfo().getDataLayoutString(), M.get(), + BackendAction::Backend_EmitObj, std::move(OS)); // Free the memory for the temporary buffer. llvm::SmallVector Empty; diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -985,8 +985,7 @@ DefineFastIntType(64, true, TI, Builder); DefineFastIntType(64, false, TI, Builder); - char UserLabelPrefix[2] = {TI.getDataLayout().getGlobalPrefix(), 0}; - Builder.defineMacro("__USER_LABEL_PREFIX__", UserLabelPrefix); + Builder.defineMacro("__USER_LABEL_PREFIX__", TI.getUserLabelPrefix()); if (LangOpts.FastMath || LangOpts.FiniteMathOnly) Builder.defineMacro("__FINITE_MATH_ONLY__", "1"); diff --git a/clang/unittests/AST/DeclTest.cpp b/clang/unittests/AST/DeclTest.cpp --- a/clang/unittests/AST/DeclTest.cpp +++ b/clang/unittests/AST/DeclTest.cpp @@ -75,7 +75,7 @@ auto AST = tooling::buildASTFromCodeWithArgs(Code, {"-target", "i386-apple-darwin"}); ASTContext &Ctx = AST->getASTContext(); - assert(Ctx.getTargetInfo().getDataLayout().getGlobalPrefix() && + assert(Ctx.getTargetInfo().getUserLabelPrefix() == StringRef("_") && "Expected target to have a global prefix"); DiagnosticsEngine &Diags = AST->getDiagnostics(); @@ -118,7 +118,7 @@ auto AST = tooling::buildASTFromCodeWithArgs(Code, {"-target", "i386-apple-darwin"}); ASTContext &Ctx = AST->getASTContext(); - assert(Ctx.getTargetInfo().getDataLayout().getGlobalPrefix() && + assert(Ctx.getTargetInfo().getUserLabelPrefix() == StringRef("_") && "Expected target to have a global prefix"); DiagnosticsEngine &Diags = AST->getDiagnostics(); diff --git a/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn b/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn --- a/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/lib/Basic/BUILD.gn @@ -49,7 +49,6 @@ "//clang/include/clang/Sema:AttrParsedAttrKinds", "//clang/include/clang/Sema:AttrSpellingListIndex", "//llvm/include/llvm/Config:llvm-config", - "//llvm/lib/IR", "//llvm/lib/MC", "//llvm/lib/Support", ] diff --git a/llvm/utils/gn/secondary/clang/tools/clang-format/BUILD.gn b/llvm/utils/gn/secondary/clang/tools/clang-format/BUILD.gn --- a/llvm/utils/gn/secondary/clang/tools/clang-format/BUILD.gn +++ b/llvm/utils/gn/secondary/clang/tools/clang-format/BUILD.gn @@ -11,6 +11,7 @@ "//clang/lib/AST/", "//clang/lib/Frontend/", "//clang/lib/Sema/", + "//llvm/lib/IR", ] sources = [ "ClangFormat.cpp" ] }