Skip to content

Commit

Permalink
CodeGenModule: Always output wchar_size, check LLVM assumptions.
Browse files Browse the repository at this point in the history
llvm::TargetLibraryInfo needs to know the size of wchar_t to work on
functions like `wcslen`. This patch changes clang to always emit the
wchar_size module flag (it would only do so for ARM previously).
This also adds an `assert()` to ensure the LLVM defaults based on the
target triple are in sync with clang.

Differential Revision: https://reviews.llvm.org/D32982

llvm-svn: 303463
  • Loading branch information
MatzeB committed May 19, 2017
1 parent 5934882 commit bf4a869
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 6 deletions.
19 changes: 13 additions & 6 deletions clang/lib/CodeGen/CodeGenModule.cpp
Expand Up @@ -45,6 +45,7 @@
#include "clang/Frontend/CodeGenOptions.h"
#include "clang/Sema/SemaDiagnostic.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/DataLayout.h"
Expand Down Expand Up @@ -465,18 +466,24 @@ void CodeGenModule::Release() {
getModule().addModuleFlag(llvm::Module::Warning, "Debug Info Version",
llvm::DEBUG_METADATA_VERSION);

// Width of wchar_t in bytes
uint64_t WCharWidth =
Context.getTypeSizeInChars(Context.getWideCharType()).getQuantity();
assert(LangOpts.ShortWChar ||
llvm::TargetLibraryInfoImpl::getTargetWCharSize(Target.getTriple()) ==
Target.getWCharWidth() / 8 &&
"LLVM wchar_t size out of sync");

// We need to record the widths of enums and wchar_t, so that we can generate
// the correct build attributes in the ARM backend.
// the correct build attributes in the ARM backend. wchar_size is also used by
// TargetLibraryInfo.
getModule().addModuleFlag(llvm::Module::Error, "wchar_size", WCharWidth);

llvm::Triple::ArchType Arch = Context.getTargetInfo().getTriple().getArch();
if ( Arch == llvm::Triple::arm
|| Arch == llvm::Triple::armeb
|| Arch == llvm::Triple::thumb
|| Arch == llvm::Triple::thumbeb) {
// Width of wchar_t in bytes
uint64_t WCharWidth =
Context.getTypeSizeInChars(Context.getWideCharType()).getQuantity();
getModule().addModuleFlag(llvm::Module::Error, "wchar_size", WCharWidth);

// The minimum width of an enum in bytes
uint64_t EnumWidth = Context.getLangOpts().ShortEnums ? 1 : 4;
getModule().addModuleFlag(llvm::Module::Error, "min_enum_size", EnumWidth);
Expand Down
8 changes: 8 additions & 0 deletions clang/test/CodeGen/wchar-size.c
@@ -0,0 +1,8 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s -check-prefix=LONG-WCHAR
// RUN: %clang_cc1 -triple x86_64-unknown-windows-msvc -emit-llvm -o - %s | FileCheck %s -check-prefix=SHORT-WCHAR
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -o - -fshort-wchar %s | FileCheck %s -check-prefix=SHORT-WCHAR
// Note: -fno-short-wchar implies the target default is used; so there is no
// need to test this separately here.

// LONG-WCHAR: !{{[0-9]+}} = !{i32 {{[0-9]+}}, !"wchar_size", i32 4}
// SHORT-WCHAR: !{{[0-9]+}} = !{i32 {{[0-9]+}}, !"wchar_size", i32 2}

0 comments on commit bf4a869

Please sign in to comment.