r360984 - [ELF] Implement Dependent Libraries Feature

2019-05-17 Thread Ben Dunbobbin via cfe-commits
Author: bd1976llvm
Date: Thu May 16 20:44:15 2019
New Revision: 360984

URL: http://llvm.org/viewvc/llvm-project?rev=360984&view=rev
Log:
[ELF] Implement Dependent Libraries Feature

This patch implements a limited form of autolinking primarily designed to allow
either the --dependent-library compiler option, or "comment lib" pragmas (
https://docs.microsoft.com/en-us/cpp/preprocessor/comment-c-cpp?view=vs-2017) in
C/C++ e.g. #pragma comment(lib, "foo"), to cause an ELF linker to automatically
add the specified library to the link when processing the input file generated
by the compiler.

Currently this extension is unique to LLVM and LLD. However, care has been taken
to design this feature so that it could be supported by other ELF linkers.

The design goals were to provide:

- A simple linking model for developers to reason about.
- The ability to to override autolinking from the linker command line.
- Source code compatibility, where possible, with "comment lib" pragmas in other
  environments (MSVC in particular).

Dependent library support is implemented differently for ELF platforms than on
the other platforms. Primarily this difference is that on ELF we pass the
dependent library specifiers directly to the linker without manipulating them.
This is in contrast to other platforms where they are mapped to a specific
linker option by the compiler. This difference is a result of the greater
variety of ELF linkers and the fact that ELF linkers tend to handle libraries in
a more complicated fashion than on other platforms. This forces us to defer
handling the specifiers to the linker.

In order to achieve a level of source code compatibility with other platforms
we have restricted this feature to work with libraries that meet the following
"reasonable" requirements:

1. There are no competing defined symbols in a given set of libraries, or
   if they exist, the program owner doesn't care which is linked to their
   program.
2. There may be circular dependencies between libraries.

The binary representation is a mergeable string section (SHF_MERGE,
SHF_STRINGS), called .deplibs, with custom type SHT_LLVM_DEPENDENT_LIBRARIES
(0x6fff4c04). The compiler forms this section by concatenating the arguments of
the "comment lib" pragmas and --dependent-library options in the order they are
encountered. Partial (-r, -Ur) links are handled by concatenating .deplibs
sections with the normal mergeable string section rules. As an example, #pragma
comment(lib, "foo") would result in:

.section ".deplibs","MS",@llvm_dependent_libraries,1
 .asciz "foo"

For LTO, equivalent information to the contents of a the .deplibs section can be
retrieved by the LLD for bitcode input files.

LLD processes the dependent library specifiers in the following way:

1. Dependent libraries which are found from the specifiers in .deplibs sections
   of relocatable object files are added when the linker decides to include that
   file (which could itself be in a library) in the link. Dependent libraries
   behave as if they were appended to the command line after all other options. 
As
   a consequence the set of dependent libraries are searched last to resolve
   symbols.
2. It is an error if a file cannot be found for a given specifier.
3. Any command line options in effect at the end of the command line parsing 
apply
   to the dependent libraries, e.g. --whole-archive.
4. The linker tries to add a library or relocatable object file from each of the
   strings in a .deplibs section by; first, handling the string as if it was
   specified on the command line; second, by looking for the string in each of 
the
   library search paths in turn; third, by looking for a lib.a or
   lib.so (depending on the current mode of the linker) in each of the
   library search paths.
5. A new command line option --no-dependent-libraries tells LLD to ignore the
   dependent libraries.

Rationale for the above points:

1. Adding the dependent libraries last makes the process simple to understand
   from a developers perspective. All linkers are able to implement this scheme.
2. Error-ing for libraries that are not found seems like better behavior than
   failing the link during symbol resolution.
3. It seems useful for the user to be able to apply command line options which
   will affect all of the dependent libraries. There is a potential problem of
   surprise for developers, who might not realize that these options would apply
   to these "invisible" input files; however, despite the potential for 
surprise,
   this is easy for developers to reason about and gives developers the control
   that they may require.
4. This algorithm takes into account all of the different ways that ELF linkers
   find input files. The different search methods are tried by the linker in 
most
   obvious to least obvious order.
5. I considered adding finer grained control over which dependent libraries were
   ignored (e.g. MSVC has /nodefaultlib:); however, I concluded t

[clang] 9d23b50 - [PS4] Enable relaxed relocations by default

2020-05-21 Thread Ben Dunbobbin via cfe-commits

Author: Ben Dunbobbin
Date: 2020-05-21T23:05:44+01:00
New Revision: 9d23b5025d5f6614a2b2b1b6fc19997f0fb69138

URL: 
https://github.com/llvm/llvm-project/commit/9d23b5025d5f6614a2b2b1b6fc19997f0fb69138
DIFF: 
https://github.com/llvm/llvm-project/commit/9d23b5025d5f6614a2b2b1b6fc19997f0fb69138.diff

LOG: [PS4] Enable relaxed relocations by default

PS4 supports these relocations types; so, we want to enable them by default.

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

Added: 
clang/test/Driver/ps4-relax-relocations.c

Modified: 
clang/lib/Driver/ToolChains/PS4CPU.h

Removed: 




diff  --git a/clang/lib/Driver/ToolChains/PS4CPU.h 
b/clang/lib/Driver/ToolChains/PS4CPU.h
index 27969bcf3726..6b1efd25f43a 100644
--- a/clang/lib/Driver/ToolChains/PS4CPU.h
+++ b/clang/lib/Driver/ToolChains/PS4CPU.h
@@ -100,6 +100,8 @@ class LLVM_LIBRARY_VISIBILITY PS4CPU : public Generic_ELF {
 return llvm::DenormalMode::getPreserveSign();
   }
 
+  bool useRelaxRelocations() const override { return true; }
+
 protected:
   Tool *buildAssembler() const override;
   Tool *buildLinker() const override;

diff  --git a/clang/test/Driver/ps4-relax-relocations.c 
b/clang/test/Driver/ps4-relax-relocations.c
new file mode 100644
index ..b22cd2e8d864
--- /dev/null
+++ b/clang/test/Driver/ps4-relax-relocations.c
@@ -0,0 +1,18 @@
+// REQUIRES: x86-registered-target
+
+// RUN: %clang -### -target x86_64-scei-ps4 %s -o - 2>&1 | \
+// RUN:   FileCheck %s
+// RUN: %clang -### -target x86_64-scei-ps4 -Wa,-mrelax-relocations=yes %s -o 
- 2>&1 | \
+// RUN:   FileCheck %s
+// RUN: %clang -### -target x86_64-scei-ps4 -Wa,-mrelax-relocations=no %s -o - 
2>&1 | \
+// RUN:   FileCheck -check-prefix=UNSET %s
+// RUN: %clang -### -x assembler -target x86_64-scei-ps4 %s -o - 2>&1 | \
+// RUN:   FileCheck %s
+// RUN: %clang -### -x assembler -target x86_64-scei-ps4 
-Wa,-mrelax-relocations=yes %s -o - 2>&1 | \
+// RUN:   FileCheck %s
+// RUN: %clang -### -x assembler -target x86_64-scei-ps4 
-Wa,-mrelax-relocations=no %s -o - 2>&1 | \
+// RUN:   FileCheck -check-prefix=UNSET %s
+
+// CHECK: "--mrelax-relocations"
+
+// UNSET-NOT: "--mrelax-relocations"



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 325e7e8 - [LLVM][LTO][LLD] Enable Profile Guided Layout (--call-graph-profile-sort) for FullLTO

2022-07-01 Thread Ben Dunbobbin via cfe-commits

Author: Ben Dunbobbin
Date: 2022-07-01T13:57:36+01:00
New Revision: 325e7e8b87423f83ba9fc53b9486ce67329d486c

URL: 
https://github.com/llvm/llvm-project/commit/325e7e8b87423f83ba9fc53b9486ce67329d486c
DIFF: 
https://github.com/llvm/llvm-project/commit/325e7e8b87423f83ba9fc53b9486ce67329d486c.diff

LOG: [LLVM][LTO][LLD] Enable Profile Guided Layout (--call-graph-profile-sort) 
for FullLTO

The CGProfilePass needs to be run during FullLTO compilation at link
time to emit the .llvm.call-graph-profile section to the compiled LTO
object file. Currently, it is being run only during the initial
LTO-prelink compilation stage (to produce the bitcode files to be
consumed by the linker) and so the section is not produced.

ThinLTO is not affected because:
- For ThinLTO-prelink compilation the CGProfilePass pass is not run
  because ThinLTO-prelink passes are added via
  buildThinLTOPreLinkDefaultPipeline. Normal and FullLTO-prelink
  passes are both added via buildPerModuleDefaultPipeline which uses
  the LTOPreLink parameter to customize its behavior for the
  FullLTO-prelink pass differences.
- ThinLTO backend compilation phase adds the CGProfilePass (see:
  buildModuleOptimizationPipeline).

Adjust when the pass is run so that the .llvm.call-graph-profile
section is produced correctly for FullLTO.

Fixes #56185 (https://github.com/llvm/llvm-project/issues/56185)

Added: 


Modified: 
clang/test/CodeGen/thinlto-distributed-newpm.ll
llvm/lib/Passes/PassBuilderPipelines.cpp
llvm/test/Other/new-pm-defaults.ll
llvm/test/Other/new-pm-lto-defaults.ll
llvm/test/Other/new-pm-thinlto-defaults.ll
llvm/test/Other/new-pm-thinlto-postlink-pgo-defaults.ll
llvm/test/Other/new-pm-thinlto-postlink-samplepgo-defaults.ll

Removed: 




diff  --git a/clang/test/CodeGen/thinlto-distributed-newpm.ll 
b/clang/test/CodeGen/thinlto-distributed-newpm.ll
index 6d42e9e744a89..463fc522c6a28 100644
--- a/clang/test/CodeGen/thinlto-distributed-newpm.ll
+++ b/clang/test/CodeGen/thinlto-distributed-newpm.ll
@@ -105,9 +105,9 @@
 ; CHECK-O: Running pass: InstSimplifyPass on main
 ; CHECK-O: Running pass: DivRemPairsPass on main
 ; CHECK-O: Running pass: SimplifyCFGPass on main
-; CHECK-O: Running pass: CGProfilePass
 ; CHECK-O: Running pass: GlobalDCEPass
 ; CHECK-O: Running pass: ConstantMergePass
+; CHECK-O: Running pass: CGProfilePass
 
 target datalayout = 
"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-grtev4-linux-gnu"

diff  --git a/llvm/lib/Passes/PassBuilderPipelines.cpp 
b/llvm/lib/Passes/PassBuilderPipelines.cpp
index 8e0f0cb3075bf..a5345172aae14 100644
--- a/llvm/lib/Passes/PassBuilderPipelines.cpp
+++ b/llvm/lib/Passes/PassBuilderPipelines.cpp
@@ -1278,9 +1278,6 @@ 
PassBuilder::buildModuleOptimizationPipeline(OptimizationLevel Level,
   if (PTO.MergeFunctions)
 MPM.addPass(MergeFunctionsPass());
 
-  if (PTO.CallGraphProfile)
-MPM.addPass(CGProfilePass());
-
   // Now we need to do some global optimization transforms.
   // FIXME: It would seem like these should come first in the optimization
   // pipeline and maybe be the bottom of the canonicalization pipeline? Weird
@@ -1288,6 +1285,9 @@ 
PassBuilder::buildModuleOptimizationPipeline(OptimizationLevel Level,
   MPM.addPass(GlobalDCEPass());
   MPM.addPass(ConstantMergePass());
 
+  if (PTO.CallGraphProfile && !LTOPreLink)
+MPM.addPass(CGProfilePass());
+
   // TODO: Relative look table converter pass caused an issue when full lto is
   // enabled. See https://reviews.llvm.org/D94355 for more details.
   // Until the issue fixed, disable this pass during pre-linking phase.
@@ -1748,6 +1748,9 @@ PassBuilder::buildLTODefaultPipeline(OptimizationLevel 
Level,
   if (PTO.MergeFunctions)
 MPM.addPass(MergeFunctionsPass());
 
+  if (PTO.CallGraphProfile)
+MPM.addPass(CGProfilePass());
+
   for (auto &C : FullLinkTimeOptimizationLastEPCallbacks)
 C(MPM, Level);
 

diff  --git a/llvm/test/Other/new-pm-defaults.ll 
b/llvm/test/Other/new-pm-defaults.ll
index 04b57fedc20f1..8dd82c4802830 100644
--- a/llvm/test/Other/new-pm-defaults.ll
+++ b/llvm/test/Other/new-pm-defaults.ll
@@ -265,9 +265,9 @@
 ; CHECK-IR-OUTLINER-NEXT: Running pass: IROutlinerPass
 ; CHECK-IR-OUTLINER-NEXT: Running analysis: IRSimilarityAnalysis
 ; CHECK-MERGE-FUNCS-NEXT: Running pass: MergeFunctionsPass
-; CHECK-O-NEXT: Running pass: CGProfilePass
 ; CHECK-O-NEXT: Running pass: GlobalDCEPass
 ; CHECK-O-NEXT: Running pass: ConstantMergePass
+; CHECK-DEFAULT-NEXT: Running pass: CGProfilePass
 ; CHECK-DEFAULT-NEXT: Running pass: RelLookupTableConverterPass
 ; CHECK-LTO-NOT: Running pass: RelLookupTableConverterPass
 ; CHECK-O-NEXT: Running pass: AnnotationRemarksPass on foo

diff  --git a/llvm/test/Other/new-pm-lto-defaults.ll 
b/llvm/test/Other/new-pm-lto-defaults.ll
index 2e826985fbb45..da66e71a5bf8d 100644
--- a/llvm/test/Other/new-pm-l

[clang] fd49ef1 - Removed a late added test-case from the tests for #74629

2024-01-19 Thread Ben Dunbobbin via cfe-commits

Author: Ben Dunbobbin
Date: 2024-01-20T01:35:06Z
New Revision: fd49ef1eb3de7eb2be5f7ddd469a005917cc1988

URL: 
https://github.com/llvm/llvm-project/commit/fd49ef1eb3de7eb2be5f7ddd469a005917cc1988
DIFF: 
https://github.com/llvm/llvm-project/commit/fd49ef1eb3de7eb2be5f7ddd469a005917cc1988.diff

LOG: Removed a late added test-case from the tests for #74629

This test-case was generating invalid IR and causing the test to fail.

Given that the reviewer initially accepted the change without this
test case I feel that it is appropriate to remove this test case,
to get the build to pass, and find a way to reimplement this test-case
in a later commit.

Added: 


Modified: 
clang/test/CodeGenCXX/visibility-dllstorageclass.cpp

Removed: 




diff  --git a/clang/test/CodeGenCXX/visibility-dllstorageclass.cpp 
b/clang/test/CodeGenCXX/visibility-dllstorageclass.cpp
index a44ff1316d94c5..3ea00bd4889923 100644
--- a/clang/test/CodeGenCXX/visibility-dllstorageclass.cpp
+++ b/clang/test/CodeGenCXX/visibility-dllstorageclass.cpp
@@ -43,17 +43,6 @@
 // RUN: -x c++  %s -S -emit-llvm -o - | \
 // RUN:   FileCheck %s --check-prefixes=ALL_KEEP
 
- Show that omitting -fvisibility-from-dllstorageclass causes the other 
options to be ignored.
-// RUN: %clang_cc1 -triple x86_64-unknown-windows-itanium -fdeclspec \
-// RUN: -fvisibility=hidden \
-// RUN: -fapply-global-visibility-to-externs \
-// RUN: -fvisibility-dllexport=protected \
-// RUN: -fvisibility-nodllstorageclass=protected \
-// RUN: -fvisibility-externs-dllimport=protected \
-// RUN: -fvisibility-externs-nodllstorageclass=protected \
-// RUN: -x c++  %s -S -emit-llvm -o - | \
-// RUN:   FileCheck %s --check-prefixes=ALL_KEEP
-
 // Local
 static void l() {}
 void use_locals(){l();}



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 7ad6010 - Fix - [Clang] Add the ability to map DLL storage class to visibility

2020-11-03 Thread Ben Dunbobbin via cfe-commits

Author: Ben Dunbobbin
Date: 2020-11-03T19:13:54Z
New Revision: 7ad6010f58eac498896e601857ff7eda84466064

URL: 
https://github.com/llvm/llvm-project/commit/7ad6010f58eac498896e601857ff7eda84466064
DIFF: 
https://github.com/llvm/llvm-project/commit/7ad6010f58eac498896e601857ff7eda84466064.diff

LOG: Fix - [Clang] Add the ability to map DLL storage class to visibility

415f7ee883 had a silly typo introduced when I inlined some
code into a loop from its own function.

Original commit message:

For PlayStation we offer source code compatibility with
Microsoft's dllimport/export annotations; however, our file
format is based on ELF.

To support this we translate from DLL storage class to ELF
visibility at the end of codegen in Clang.

Other toolchains have used similar strategies (e.g. see the
documentation for this ARM toolchain:

https://developer.arm.com/documentation/dui0530/i/migrating-from-rvct-v3-1-to-rvct-v4-0/changes-to-symbol-visibility-between-rvct-v3-1-and-rvct-v4-0)

This patch adds the ability to perform this translation. Options
are provided to support customizing the mapping behaviour.

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

Added: 


Modified: 
clang/lib/CodeGen/CodeGenModule.cpp
clang/test/CodeGenCXX/visibility-dllstorageclass.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 1efc39bc8fb1..24c067539f83 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -418,7 +418,7 @@ static void setVisibilityFromDLLStorageClass(const 
clang::LangOptions &LO,
 
   for (llvm::GlobalValue &GV : M.global_values()) {
 if (GV.hasAppendingLinkage() || GV.hasLocalLinkage())
-  return;
+  continue;
 
 if (GV.isDeclarationForLinker()) {
   GV.setVisibility(GV.getDLLStorageClass() ==
@@ -724,7 +724,7 @@ void CodeGenModule::Release() {
 
   EmitBackendOptionsMetadata(getCodeGenOpts());
 
-  // Set visibility from DLL export class
+  // Set visibility from DLL storage class
   // We do this at the end of LLVM IR generation; after any operation
   // that might affect the DLL storage class or the visibility, and
   // before anything that might act on these.

diff  --git a/clang/test/CodeGenCXX/visibility-dllstorageclass.cpp 
b/clang/test/CodeGenCXX/visibility-dllstorageclass.cpp
index f090ccb3b099..9003909f3ee0 100644
--- a/clang/test/CodeGenCXX/visibility-dllstorageclass.cpp
+++ b/clang/test/CodeGenCXX/visibility-dllstorageclass.cpp
@@ -19,11 +19,17 @@
 // RUN: -x c++  %s -S -emit-llvm -o - | \
 // RUN:   FileCheck %s --check-prefixes=EXPLICIT
 
+// Local
+static void l() {}
+void use_locals(){l();}
+// DEFAULT-DAG: define internal void @_ZL1lv()
+// EXPLICIT-DAG: define internal void @_ZL1lv()
+
 // Function
 void f() {}
 void __declspec(dllexport) exported_f() {}
 // DEFAULT-DAG: define hidden void @_Z1fv()
-// DEFAULT-DAG: define dso_local  void @_Z10exported_fv()
+// DEFAULT-DAG: define dso_local void @_Z10exported_fv()
 // EXPLICIT-DAG: define protected void @_Z1fv()
 // EXPLICIT-DAG: define hidden void @_Z10exported_fv()
 



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 4eb627e - first upstream review

2020-10-09 Thread Ben Dunbobbin via cfe-commits

Author: Ben Dunbobbin
Date: 2020-10-09T13:21:03+01:00
New Revision: 4eb627ed96e3f2f9f24aec8a0654ce5204874bb8

URL: 
https://github.com/llvm/llvm-project/commit/4eb627ed96e3f2f9f24aec8a0654ce5204874bb8
DIFF: 
https://github.com/llvm/llvm-project/commit/4eb627ed96e3f2f9f24aec8a0654ce5204874bb8.diff

LOG: first upstream review

Added: 


Modified: 
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaDeclAttr.cpp
clang/lib/Sema/SemaDeclCXX.cpp
clang/test/Sema/dllimport.c
clang/test/SemaCXX/dllexport.cpp
clang/test/SemaCXX/dllimport.cpp

Removed: 




diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index c92d906580eb..9a6682e837dd 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -6497,7 +6497,9 @@ static void checkDLLAttributeRedeclaration(Sema &S, 
NamedDecl *OldDecl,
   // special MSVC extension: in the last case, the declaration is treated as if
   // it were marked dllexport.
   bool IsInline = false, IsStaticDataMember = false, IsQualifiedFriend = false;
-  bool IsMicrosoft = S.Context.getTargetInfo().getCXXABI().isMicrosoft();
+  bool IsMicrosoft =
+  S.Context.getTargetInfo().getCXXABI().isMicrosoft() ||
+  S.Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment();
   if (const auto *VD = dyn_cast(NewDecl)) {
 // Ignore static data because out-of-line definitions are diagnosed
 // separately.

diff  --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index c07e5f792d14..0ccfb1504636 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -6731,14 +6731,16 @@ DLLExportAttr *Sema::mergeDLLExportAttr(Decl *D,
 
 static void handleDLLAttr(Sema &S, Decl *D, const ParsedAttr &A) {
   if (isa(D) &&
-  S.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+  (S.Context.getTargetInfo().getCXXABI().isMicrosoft() ||
+   S.Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment())) {
 S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored) << A;
 return;
   }
 
   if (const auto *FD = dyn_cast(D)) {
 if (FD->isInlined() && A.getKind() == ParsedAttr::AT_DLLImport &&
-!S.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+!(S.Context.getTargetInfo().getCXXABI().isMicrosoft() ||
+  
S.Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment())) {
   // MinGW doesn't allow dllimport on inline functions.
   S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored_on_inline)
   << A;
@@ -6747,7 +6749,8 @@ static void handleDLLAttr(Sema &S, Decl *D, const 
ParsedAttr &A) {
   }
 
   if (const auto *MD = dyn_cast(D)) {
-if (S.Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+if ((S.Context.getTargetInfo().getCXXABI().isMicrosoft() ||
+ S.Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment()) 
&&
 MD->getParent()->isLambda()) {
   S.Diag(A.getRange().getBegin(), diag::err_attribute_dll_lambda) << A;
   return;

diff  --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 1275fc0c95b5..138faa161c4e 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -6060,7 +6060,8 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl 
*Class) {
   Attr *ClassAttr = getDLLAttr(Class);
 
   // MSVC inherits DLL attributes to partial class template specializations.
-  if (Context.getTargetInfo().getCXXABI().isMicrosoft() && !ClassAttr) {
+  if ((Context.getTargetInfo().getCXXABI().isMicrosoft() || 
+   Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment()) && 
!ClassAttr) {
 if (auto *Spec = dyn_cast(Class)) {
   if (Attr *TemplateAttr =
   getDLLAttr(Spec->getSpecializedTemplate()->getTemplatedDecl())) {
@@ -6080,7 +6081,8 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl 
*Class) {
 return;
   }
 
-  if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+  if ((Context.getTargetInfo().getCXXABI().isMicrosoft() || 
+   Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment()) &&
   !ClassAttr->isInherited()) {
 // Diagnose dll attributes on members of class with dll attribute.
 for (Decl *Member : Class->decls()) {

diff  --git a/clang/test/Sema/dllimport.c b/clang/test/Sema/dllimport.c
index 988a8e33a7ef..66bd2703e648 100644
--- a/clang/test/Sema/dllimport.c
+++ b/clang/test/Sema/dllimport.c
@@ -1,8 +1,10 @@
-// RUN: %clang_cc1 -triple i686-win32 -fsyntax-only -fms-extensions 
-verify -std=c99 -DMS %s
-// RUN: %clang_cc1 -triple x86_64-win32   -fsyntax-only -fms-extensions 
-verify -std=c11 -DMS %s
-// RUN: %clang_cc1 -triple i686-mingw32   -fsyntax-only -fms-extensions 
-verify -std=c11 -DGNU %s
-// RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -fms-extensions 
-verify -std=c99 -DGNU %s
-// RUN: %clang_cc1 -triple aarch64-win32  -

[clang] a9f1bb9 - Revert "first upstream review"

2020-10-09 Thread Ben Dunbobbin via cfe-commits

Author: Ben Dunbobbin
Date: 2020-10-09T13:22:46+01:00
New Revision: a9f1bb92bfb1efc005b53bf9ea18ad5e902386fc

URL: 
https://github.com/llvm/llvm-project/commit/a9f1bb92bfb1efc005b53bf9ea18ad5e902386fc
DIFF: 
https://github.com/llvm/llvm-project/commit/a9f1bb92bfb1efc005b53bf9ea18ad5e902386fc.diff

LOG: Revert "first upstream review"

Pushed by accident :(

This reverts commit 4eb627ed96e3f2f9f24aec8a0654ce5204874bb8.

Added: 


Modified: 
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaDeclAttr.cpp
clang/lib/Sema/SemaDeclCXX.cpp
clang/test/Sema/dllimport.c
clang/test/SemaCXX/dllexport.cpp
clang/test/SemaCXX/dllimport.cpp

Removed: 




diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 9a6682e837dd..c92d906580eb 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -6497,9 +6497,7 @@ static void checkDLLAttributeRedeclaration(Sema &S, 
NamedDecl *OldDecl,
   // special MSVC extension: in the last case, the declaration is treated as if
   // it were marked dllexport.
   bool IsInline = false, IsStaticDataMember = false, IsQualifiedFriend = false;
-  bool IsMicrosoft =
-  S.Context.getTargetInfo().getCXXABI().isMicrosoft() ||
-  S.Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment();
+  bool IsMicrosoft = S.Context.getTargetInfo().getCXXABI().isMicrosoft();
   if (const auto *VD = dyn_cast(NewDecl)) {
 // Ignore static data because out-of-line definitions are diagnosed
 // separately.

diff  --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 0ccfb1504636..c07e5f792d14 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -6731,16 +6731,14 @@ DLLExportAttr *Sema::mergeDLLExportAttr(Decl *D,
 
 static void handleDLLAttr(Sema &S, Decl *D, const ParsedAttr &A) {
   if (isa(D) &&
-  (S.Context.getTargetInfo().getCXXABI().isMicrosoft() ||
-   S.Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment())) {
+  S.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
 S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored) << A;
 return;
   }
 
   if (const auto *FD = dyn_cast(D)) {
 if (FD->isInlined() && A.getKind() == ParsedAttr::AT_DLLImport &&
-!(S.Context.getTargetInfo().getCXXABI().isMicrosoft() ||
-  
S.Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment())) {
+!S.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
   // MinGW doesn't allow dllimport on inline functions.
   S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored_on_inline)
   << A;
@@ -6749,8 +6747,7 @@ static void handleDLLAttr(Sema &S, Decl *D, const 
ParsedAttr &A) {
   }
 
   if (const auto *MD = dyn_cast(D)) {
-if ((S.Context.getTargetInfo().getCXXABI().isMicrosoft() ||
- S.Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment()) 
&&
+if (S.Context.getTargetInfo().getCXXABI().isMicrosoft() &&
 MD->getParent()->isLambda()) {
   S.Diag(A.getRange().getBegin(), diag::err_attribute_dll_lambda) << A;
   return;

diff  --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 138faa161c4e..1275fc0c95b5 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -6060,8 +6060,7 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl 
*Class) {
   Attr *ClassAttr = getDLLAttr(Class);
 
   // MSVC inherits DLL attributes to partial class template specializations.
-  if ((Context.getTargetInfo().getCXXABI().isMicrosoft() || 
-   Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment()) && 
!ClassAttr) {
+  if (Context.getTargetInfo().getCXXABI().isMicrosoft() && !ClassAttr) {
 if (auto *Spec = dyn_cast(Class)) {
   if (Attr *TemplateAttr =
   getDLLAttr(Spec->getSpecializedTemplate()->getTemplatedDecl())) {
@@ -6081,8 +6080,7 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl 
*Class) {
 return;
   }
 
-  if ((Context.getTargetInfo().getCXXABI().isMicrosoft() || 
-   Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment()) &&
+  if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
   !ClassAttr->isInherited()) {
 // Diagnose dll attributes on members of class with dll attribute.
 for (Decl *Member : Class->decls()) {

diff  --git a/clang/test/Sema/dllimport.c b/clang/test/Sema/dllimport.c
index 66bd2703e648..988a8e33a7ef 100644
--- a/clang/test/Sema/dllimport.c
+++ b/clang/test/Sema/dllimport.c
@@ -1,10 +1,8 @@
-// RUN: %clang_cc1 -triple i686-win32 -fsyntax-only 
-fms-extensions -verify -std=c99 -DMS %s
-// RUN: %clang_cc1 -triple x86_64-win32   -fsyntax-only 
-fms-extensions -verify -std=c11 -DMS %s
-// RUN: %clang_cc1 -triple i686-mingw32   -fsyntax-only 
-fms-extensions -verify -std=c11 -DGNU %s
-// RUN: %clang_cc1 -trip

[clang] bb148ad - [windows-itanium] make dllimport/export handling closer to MS behavior

2020-10-09 Thread Ben Dunbobbin via cfe-commits

Author: Ben Dunbobbin
Date: 2020-10-09T13:24:07+01:00
New Revision: bb148ad426f8c7e6a6f968d54796f872685a00b2

URL: 
https://github.com/llvm/llvm-project/commit/bb148ad426f8c7e6a6f968d54796f872685a00b2
DIFF: 
https://github.com/llvm/llvm-project/commit/bb148ad426f8c7e6a6f968d54796f872685a00b2.diff

LOG: [windows-itanium] make dllimport/export handling closer to MS behavior

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

Added: 


Modified: 
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaDeclAttr.cpp
clang/lib/Sema/SemaDeclCXX.cpp
clang/test/Sema/dllimport.c
clang/test/SemaCXX/dllexport.cpp
clang/test/SemaCXX/dllimport.cpp

Removed: 




diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index c92d906580eb..9a6682e837dd 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -6497,7 +6497,9 @@ static void checkDLLAttributeRedeclaration(Sema &S, 
NamedDecl *OldDecl,
   // special MSVC extension: in the last case, the declaration is treated as if
   // it were marked dllexport.
   bool IsInline = false, IsStaticDataMember = false, IsQualifiedFriend = false;
-  bool IsMicrosoft = S.Context.getTargetInfo().getCXXABI().isMicrosoft();
+  bool IsMicrosoft =
+  S.Context.getTargetInfo().getCXXABI().isMicrosoft() ||
+  S.Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment();
   if (const auto *VD = dyn_cast(NewDecl)) {
 // Ignore static data because out-of-line definitions are diagnosed
 // separately.

diff  --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index c07e5f792d14..0ccfb1504636 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -6731,14 +6731,16 @@ DLLExportAttr *Sema::mergeDLLExportAttr(Decl *D,
 
 static void handleDLLAttr(Sema &S, Decl *D, const ParsedAttr &A) {
   if (isa(D) &&
-  S.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+  (S.Context.getTargetInfo().getCXXABI().isMicrosoft() ||
+   S.Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment())) {
 S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored) << A;
 return;
   }
 
   if (const auto *FD = dyn_cast(D)) {
 if (FD->isInlined() && A.getKind() == ParsedAttr::AT_DLLImport &&
-!S.Context.getTargetInfo().getCXXABI().isMicrosoft()) {
+!(S.Context.getTargetInfo().getCXXABI().isMicrosoft() ||
+  
S.Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment())) {
   // MinGW doesn't allow dllimport on inline functions.
   S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored_on_inline)
   << A;
@@ -6747,7 +6749,8 @@ static void handleDLLAttr(Sema &S, Decl *D, const 
ParsedAttr &A) {
   }
 
   if (const auto *MD = dyn_cast(D)) {
-if (S.Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+if ((S.Context.getTargetInfo().getCXXABI().isMicrosoft() ||
+ S.Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment()) 
&&
 MD->getParent()->isLambda()) {
   S.Diag(A.getRange().getBegin(), diag::err_attribute_dll_lambda) << A;
   return;

diff  --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 1275fc0c95b5..138faa161c4e 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -6060,7 +6060,8 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl 
*Class) {
   Attr *ClassAttr = getDLLAttr(Class);
 
   // MSVC inherits DLL attributes to partial class template specializations.
-  if (Context.getTargetInfo().getCXXABI().isMicrosoft() && !ClassAttr) {
+  if ((Context.getTargetInfo().getCXXABI().isMicrosoft() || 
+   Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment()) && 
!ClassAttr) {
 if (auto *Spec = dyn_cast(Class)) {
   if (Attr *TemplateAttr =
   getDLLAttr(Spec->getSpecializedTemplate()->getTemplatedDecl())) {
@@ -6080,7 +6081,8 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl 
*Class) {
 return;
   }
 
-  if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+  if ((Context.getTargetInfo().getCXXABI().isMicrosoft() || 
+   Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment()) &&
   !ClassAttr->isInherited()) {
 // Diagnose dll attributes on members of class with dll attribute.
 for (Decl *Member : Class->decls()) {

diff  --git a/clang/test/Sema/dllimport.c b/clang/test/Sema/dllimport.c
index 988a8e33a7ef..66bd2703e648 100644
--- a/clang/test/Sema/dllimport.c
+++ b/clang/test/Sema/dllimport.c
@@ -1,8 +1,10 @@
-// RUN: %clang_cc1 -triple i686-win32 -fsyntax-only -fms-extensions 
-verify -std=c99 -DMS %s
-// RUN: %clang_cc1 -triple x86_64-win32   -fsyntax-only -fms-extensions 
-verify -std=c11 -DMS %s
-// RUN: %clang_cc1 -triple i686-mingw32   -fsyntax-only -fms-extensions 
-verify -std=c11 -DGNU %s
-// RUN: %clang_cc1 -triple x86_64-ming

[clang] e42021d - [Clang][-fvisibility-from-dllstorageclass] Set DSO Locality from final visibility

2020-11-23 Thread Ben Dunbobbin via cfe-commits

Author: Ben Dunbobbin
Date: 2020-11-24T00:32:14Z
New Revision: e42021d5cc25a8dc7e3efac1e7007cc0c1a7b2bd

URL: 
https://github.com/llvm/llvm-project/commit/e42021d5cc25a8dc7e3efac1e7007cc0c1a7b2bd
DIFF: 
https://github.com/llvm/llvm-project/commit/e42021d5cc25a8dc7e3efac1e7007cc0c1a7b2bd.diff

LOG: [Clang][-fvisibility-from-dllstorageclass] Set DSO Locality from final 
visibility

Ensure that the DSO Locality of the globals in the IR is derived from
their final visibility when using -fvisibility-from-dllstorageclass.

To accomplish this we reset the DSO locality of globals (before
setting their visibility from their dllstorageclass) at the end of
IRGen in Clang. This removes any effects that visibility options or
annotations may have had on the DSO locality.

The resulting DSO locality of the globals will be pessimistic
w.r.t. to the normal compiler IRGen.

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

Added: 


Modified: 
clang/lib/CodeGen/CodeGenModule.cpp
clang/test/CodeGenCXX/visibility-dllstorageclass.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index f56b7374082f..6d0228e9e2e9 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -420,6 +420,13 @@ static void setVisibilityFromDLLStorageClass(const 
clang::LangOptions &LO,
 if (GV.hasAppendingLinkage() || GV.hasLocalLinkage())
   continue;
 
+// Reset DSO locality before setting the visibility. This removes
+// any effects that visibility options and annotations may have
+// had on the DSO locality. Setting the visibility will implicitly set
+// appropriate globals to DSO Local; however, this will be pessimistic
+// w.r.t. to the normal compiler IRGen.
+GV.setDSOLocal(false);
+
 if (GV.isDeclarationForLinker()) {
   GV.setVisibility(GV.getDLLStorageClass() ==
llvm::GlobalValue::DLLImportStorageClass

diff  --git a/clang/test/CodeGenCXX/visibility-dllstorageclass.cpp 
b/clang/test/CodeGenCXX/visibility-dllstorageclass.cpp
index 9003909f3ee0..c4dddcec2eb0 100644
--- a/clang/test/CodeGenCXX/visibility-dllstorageclass.cpp
+++ b/clang/test/CodeGenCXX/visibility-dllstorageclass.cpp
@@ -5,12 +5,14 @@
 
 // RUN: %clang_cc1 -triple x86_64-unknown-windows-itanium -fdeclspec \
 // RUN: -fvisibility hidden \
+// RUN: -fapply-global-visibility-to-externs \
 // RUN: -fvisibility-from-dllstorageclass \
 // RUN: -x c++ %s -S -emit-llvm -o - | \
-// RUN:   FileCheck %s --check-prefixes=DEFAULT
+// RUN:   FileCheck %s --check-prefixes=DEFAULTS
 
 // RUN: %clang_cc1 -triple x86_64-unknown-windows-itanium -fdeclspec \
 // RUN: -fvisibility hidden \
+// RUN: -fapply-global-visibility-to-externs \
 // RUN: -fvisibility-from-dllstorageclass \
 // RUN: -fvisibility-dllexport=hidden \
 // RUN: -fvisibility-nodllstorageclass=protected \
@@ -19,45 +21,78 @@
 // RUN: -x c++  %s -S -emit-llvm -o - | \
 // RUN:   FileCheck %s --check-prefixes=EXPLICIT
 
+// RUN: %clang_cc1 -triple x86_64-unknown-windows-itanium -fdeclspec \
+// RUN: -fvisibility hidden \
+// RUN: -fapply-global-visibility-to-externs \
+// RUN: -fvisibility-from-dllstorageclass \
+// RUN: -fvisibility-dllexport=default \
+// RUN: -fvisibility-nodllstorageclass=default \
+// RUN: -fvisibility-externs-dllimport=default \
+// RUN: -fvisibility-externs-nodllstorageclass=default \
+// RUN: -x c++  %s -S -emit-llvm -o - | \
+// RUN:   FileCheck %s --check-prefixes=ALL_DEFAULT
+
 // Local
 static void l() {}
 void use_locals(){l();}
-// DEFAULT-DAG: define internal void @_ZL1lv()
+// DEFAULTS-DAG: define internal void @_ZL1lv()
 // EXPLICIT-DAG: define internal void @_ZL1lv()
+// ALL_DEFAULT-DAG: define internal void @_ZL1lv()
 
 // Function
 void f() {}
 void __declspec(dllexport) exported_f() {}
-// DEFAULT-DAG: define hidden void @_Z1fv()
-// DEFAULT-DAG: define dso_local void @_Z10exported_fv()
+// DEFAULTS-DAG: define hidden void @_Z1fv()
+// DEFAULTS-DAG: define void @_Z10exported_fv()
 // EXPLICIT-DAG: define protected void @_Z1fv()
 // EXPLICIT-DAG: define hidden void @_Z10exported_fv()
+// ALL_DEFAULT-DAG: define void @_Z1fv()
+// ALL_DEFAULT-DAG: define void @_Z10exported_fv()
 
 // Variable
 int d = 123;
 __declspec(dllexport) int exported_d = 123;
-// DEFAULT-DAG: @d = hidden global
-// DEFAULT-DAG: @exported_d = dso_local global
+// DEFAULTS-DAG: @d = hidden global
+// DEFAULTS-DAG: @exported_d = global
 // EXPLICIT-DAG: @d = protected global
 // EXPLICIT-DAG: @exported_d = hidden global
+// ALL_DEFAULT-DAG: @d = global
+// ALL_DEFAULT-DAG: @exported_d = global
 
 // Alias
 extern "C" void aliased() {}
 void a() __attribute__((alias("aliased")));
 void __declspec(dllexport) a_exported() __attribute__((alias("aliased")));
-// DEFAULT-DAG: @_Z1av = hidden alias
-//

[clang] d5aaf60 - [windows-itanium] handle dllimport/export code paths separately and share with PS4

2020-11-30 Thread Ben Dunbobbin via cfe-commits

Author: Ben Dunbobbin
Date: 2020-11-30T14:36:39Z
New Revision: d5aaf6021476243de73f8eb8a7479a2288582225

URL: 
https://github.com/llvm/llvm-project/commit/d5aaf6021476243de73f8eb8a7479a2288582225
DIFF: 
https://github.com/llvm/llvm-project/commit/d5aaf6021476243de73f8eb8a7479a2288582225.diff

LOG: [windows-itanium] handle dllimport/export code paths separately and share 
with PS4

Similar to Windows Itanium, PS4 is also an Itanium C++ ABI variant
which shares the goal of semantic compatibility with Microsoft C++
code that uses dllimport/export.

This change introduces a new function to determine from the triple
if an environment aims for compatibility with MS C++ code w.r.t to
these attributes and guards the relevant code paths using that
function.

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

Added: 


Modified: 
clang/include/clang/Basic/TargetInfo.h
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaDeclAttr.cpp
clang/lib/Sema/SemaDeclCXX.cpp
clang/lib/Sema/SemaTemplate.cpp
clang/test/CodeGenCXX/dllexport-vtable-thunks.cpp
clang/test/CodeGenCXX/windows-implicit-dllexport-template-specialization.cpp
clang/test/CodeGenCXX/windows-itanium-dllexport.cpp
clang/test/Sema/dllimport.c
clang/test/SemaCXX/dllexport.cpp
clang/test/SemaCXX/dllimport.cpp

Removed: 




diff  --git a/clang/include/clang/Basic/TargetInfo.h 
b/clang/include/clang/Basic/TargetInfo.h
index 698964b94ee2..de91ca2ee82e 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1098,6 +1098,13 @@ class TargetInfo : public virtual 
TransferrableTargetInfo,
   /// either; the entire thing is pretty badly mangled.
   virtual bool hasProtectedVisibility() const { return true; }
 
+  /// Does this target aim for semantic compatibility with
+  /// Microsoft C++ code using dllimport/export attributes?
+  virtual bool shouldDLLImportComdatSymbols() const {
+return getTriple().isWindowsMSVCEnvironment() ||
+   getTriple().isWindowsItaniumEnvironment() || getTriple().isPS4CPU();
+  }
+
   /// An optional hook that targets can implement to perform semantic
   /// checking on attribute((section("foo"))) specifiers.
   ///

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index ce7475b0d5da..9c282a73e0ed 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -6510,9 +6510,7 @@ static void checkDLLAttributeRedeclaration(Sema &S, 
NamedDecl *OldDecl,
   // special MSVC extension: in the last case, the declaration is treated as if
   // it were marked dllexport.
   bool IsInline = false, IsStaticDataMember = false, IsQualifiedFriend = false;
-  bool IsMicrosoft =
-  S.Context.getTargetInfo().getCXXABI().isMicrosoft() ||
-  S.Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment();
+  bool IsMicrosoftABI  = 
S.Context.getTargetInfo().shouldDLLImportComdatSymbols();
   if (const auto *VD = dyn_cast(NewDecl)) {
 // Ignore static data because out-of-line definitions are diagnosed
 // separately.
@@ -6526,9 +6524,9 @@ static void checkDLLAttributeRedeclaration(Sema &S, 
NamedDecl *OldDecl,
   }
 
   if (OldImportAttr && !HasNewAttr &&
-  (!IsInline || (IsMicrosoft && IsTemplate)) && !IsStaticDataMember &&
+  (!IsInline || (IsMicrosoftABI && IsTemplate)) && !IsStaticDataMember &&
   !NewDecl->isLocalExternDecl() && !IsQualifiedFriend) {
-if (IsMicrosoft && IsDefinition) {
+if (IsMicrosoftABI && IsDefinition) {
   S.Diag(NewDecl->getLocation(),
  diag::warn_redeclaration_without_import_attribute)
   << NewDecl;
@@ -6545,7 +6543,7 @@ static void checkDLLAttributeRedeclaration(Sema &S, 
NamedDecl *OldDecl,
   OldDecl->dropAttr();
   NewDecl->dropAttr();
 }
-  } else if (IsInline && OldImportAttr && !IsMicrosoft) {
+  } else if (IsInline && OldImportAttr && !IsMicrosoftABI) {
 // In MinGW, seeing a function declared inline drops the dllimport
 // attribute.
 OldDecl->dropAttr();

diff  --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index a14c16229419..d31d18eac474 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -6791,16 +6791,14 @@ DLLExportAttr *Sema::mergeDLLExportAttr(Decl *D,
 
 static void handleDLLAttr(Sema &S, Decl *D, const ParsedAttr &A) {
   if (isa(D) &&
-  (S.Context.getTargetInfo().getCXXABI().isMicrosoft() ||
-   S.Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment())) {
+  (S.Context.getTargetInfo().shouldDLLImportComdatSymbols())) {
 S.Diag(A.getRange().getBegin(), diag::warn_attribute_ignored) << A;
 return;
   }
 
   if (const auto *FD = dyn_cast(D)) {
 if (FD->isInlined() && A.getKind() == ParsedAttr::AT_DLLImport &&
-!(S.Context.getTargetInfo().getCXXABI().isMicrosoft() ||
-  
S.Context.getTargetInfo().g

[clang] ff2e24a - [PS4] Support dllimport/export attributes

2020-11-02 Thread Ben Dunbobbin via cfe-commits

Author: Ben Dunbobbin
Date: 2020-11-02T14:25:34Z
New Revision: ff2e24a741e4cee903fa71ec5c8c1909a89f66a3

URL: 
https://github.com/llvm/llvm-project/commit/ff2e24a741e4cee903fa71ec5c8c1909a89f66a3
DIFF: 
https://github.com/llvm/llvm-project/commit/ff2e24a741e4cee903fa71ec5c8c1909a89f66a3.diff

LOG: [PS4] Support dllimport/export attributes

For PS4 development we support dllimport/export annotations in
source code. This patch enables the dllimport/export attributes
on PS4 by adding a new function to query the triple for whether
dllimport/export are used and using that function to decide
whether these attributes are supported. This replaces the current
method of checking if the target is Windows.

This means we can drop the use of "TargetArch" in the .td file
(which is an improvement as dllimport/export support isn't really
a function of the architecture).

I have included a simple codgen test to show that the attributes
are accepted and have an effect on codegen for PS4. I have also
enabled the DLLExportStaticLocal and DLLImportStaticLocal
attributes, which we support downstream. However, I am unable to
write a test for these attributes until other patches for PS4
dllimport/export handling land upstream. Whilst writing this
patch I noticed that, as these attributes are internal, they do
not need to be target specific (when these attributes are added
internally in Clang the target specific checks have already been
run); however, I think leaving them target specific is fine
because it isn't harmful and they "really are" target specific
even if that has no functional impact.

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

Added: 
clang/test/CodeGen/ps4-dllimport-dllexport.c

Modified: 
clang/include/clang/Basic/Attr.td
llvm/include/llvm/ADT/Triple.h

Removed: 




diff  --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 2b51a3ffcc6e..687c03f55841 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -368,8 +368,8 @@ def TargetRISCV : TargetArch<["riscv32", "riscv64"]>;
 def TargetX86 : TargetArch<["x86"]>;
 def TargetAnyX86 : TargetArch<["x86", "x86_64"]>;
 def TargetWebAssembly : TargetArch<["wasm32", "wasm64"]>;
-def TargetWindows : TargetArch<["x86", "x86_64", "arm", "thumb", "aarch64"]> {
-  let OSes = ["Win32"];
+def TargetHasDLLImportExport : TargetSpec {
+  let CustomCode = [{ Target.getTriple().hasDLLImportExport() }];
 }
 def TargetItaniumCXXABI : TargetSpec {
   let CustomCode = [{ Target.getCXXABI().isItaniumFamily() }];
@@ -3144,24 +3144,24 @@ def MSStruct : InheritableAttr {
   let SimpleHandler = 1;
 }
 
-def DLLExport : InheritableAttr, TargetSpecificAttr {
+def DLLExport : InheritableAttr, TargetSpecificAttr {
   let Spellings = [Declspec<"dllexport">, GCC<"dllexport">];
   let Subjects = SubjectList<[Function, Var, CXXRecord, ObjCInterface]>;
   let Documentation = [DLLExportDocs];
 }
 
-def DLLExportStaticLocal : InheritableAttr, TargetSpecificAttr {
+def DLLExportStaticLocal : InheritableAttr, 
TargetSpecificAttr {
   // This attribute is used internally only when -fno-dllexport-inlines is
-  // passed. This attribute is added to inline function of class having
-  // dllexport attribute. And if the function has static local variables, this
-  // attribute is used to whether the variables are exported or not. Also if
-  // function has local static variables, the function is dllexported too.
+  // passed. This attribute is added to inline functions of a class having the
+  // dllexport attribute. If the function has static local variables, this
+  // attribute is used to determine whether the variables are exported or not. 
If
+  // the function has local static variables, the function is dllexported too.
   let Spellings = [];
   let Subjects = SubjectList<[Function]>;
   let Documentation = [Undocumented];
 }
 
-def DLLImport : InheritableAttr, TargetSpecificAttr {
+def DLLImport : InheritableAttr, TargetSpecificAttr {
   let Spellings = [Declspec<"dllimport">, GCC<"dllimport">];
   let Subjects = SubjectList<[Function, Var, CXXRecord, ObjCInterface]>;
   let Documentation = [DLLImportDocs];
@@ -3177,11 +3177,11 @@ public:
   }];
 }
 
-def DLLImportStaticLocal : InheritableAttr, TargetSpecificAttr {
+def DLLImportStaticLocal : InheritableAttr, 
TargetSpecificAttr {
   // This attribute is used internally only when -fno-dllexport-inlines is
-  // passed. This attribute is added to inline function of class having
-  // dllimport attribute. And if the function has static local variables, this
-  // attribute is used to whether the variables are imported or not.
+  // passed. This attribute is added to inline functions of a class having the
+  // dllimport attribute. If the function has static local variables, this
+  // attribute is used to determine whether the variables are imported or not.
   let Spellings = [];
   le

[clang] 415f7ee - [Clang] Add the ability to map DLL storage class to visibility

2020-11-02 Thread Ben Dunbobbin via cfe-commits

Author: Ben Dunbobbin
Date: 2020-11-02T17:08:23Z
New Revision: 415f7ee8836944942d8beb70e982e95a312866a7

URL: 
https://github.com/llvm/llvm-project/commit/415f7ee8836944942d8beb70e982e95a312866a7
DIFF: 
https://github.com/llvm/llvm-project/commit/415f7ee8836944942d8beb70e982e95a312866a7.diff

LOG: [Clang] Add the ability to map DLL storage class to visibility

For PlayStation we offer source code compatibility with
Microsoft's dllimport/export annotations; however, our file
format is based on ELF.

To support this we translate from DLL storage class to ELF
visibility at the end of codegen in Clang.

Other toolchains have used similar strategies (e.g. see the
documentation for this ARM toolchain:

https://developer.arm.com/documentation/dui0530/i/migrating-from-rvct-v3-1-to-rvct-v4-0/changes-to-symbol-visibility-between-rvct-v3-1-and-rvct-v4-0)

This patch adds the ability to perform this translation. Options
are provided to support customizing the mapping behaviour.

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

Added: 
clang/test/CodeGenCXX/visibility-dllstorageclass.cpp
clang/test/Driver/ps4-visibility-dllstorageclass.c
clang/test/Driver/visibility-dllstorageclass.c

Modified: 
clang/include/clang/Basic/LangOptions.def
clang/include/clang/Driver/Options.td
clang/lib/CodeGen/CodeGenModule.cpp
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Driver/ToolChains/PS4CPU.cpp
clang/lib/Frontend/CompilerInvocation.cpp

Removed: 




diff  --git a/clang/include/clang/Basic/LangOptions.def 
b/clang/include/clang/Basic/LangOptions.def
index d711d66784a4..1d203f8489eb 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -307,6 +307,16 @@ ENUM_LANGOPT(TypeVisibilityMode, Visibility, 3, 
DefaultVisibility,
  "default visibility for types [-ftype-visibility]")
 LANGOPT(SetVisibilityForExternDecls, 1, 0,
 "apply global symbol visibility to external declarations without an 
explicit visibility")
+LANGOPT(VisibilityFromDLLStorageClass, 1, 0,
+"set the visiblity of globals from their DLL storage class 
[-fvisibility-from-dllstorageclass]")
+ENUM_LANGOPT(DLLExportVisibility, Visibility, 3, DefaultVisibility,
+ "visibility for functions and variables with dllexport 
annotations [-fvisibility-from-dllstorageclass]")
+ENUM_LANGOPT(NoDLLStorageClassVisibility, Visibility, 3, HiddenVisibility,
+ "visibility for functions and variables without an explicit DLL 
storage class [-fvisibility-from-dllstorageclass]")
+ENUM_LANGOPT(ExternDeclDLLImportVisibility, Visibility, 3, DefaultVisibility,
+ "visibility for external declarations with dllimport annotations 
[-fvisibility-from-dllstorageclass]")
+ENUM_LANGOPT(ExternDeclNoDLLStorageClassVisibility, Visibility, 3, 
HiddenVisibility,
+ "visibility for external declarations without an explicit DLL 
storage class [-fvisibility-from-dllstorageclass]")
 BENIGN_LANGOPT(SemanticInterposition, 1, 0, "semantic interposition")
 BENIGN_LANGOPT(ExplicitNoSemanticInterposition, 1, 0, "explicitly no semantic 
interposition")
 ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff,

diff  --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 057c2606c69d..33cfa72c0888 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1973,6 +1973,15 @@ def fno_var_tracking : Flag<["-"], "fno-var-tracking">, 
Group, Group,
   HelpText<"Generate verbose assembly output">;
 def dA : Flag<["-"], "dA">, Alias;
+defm visibility_from_dllstorageclass : 
OptInFFlag<"visibility-from-dllstorageclass", "Set the visiblity of symbols in 
the generated code from their DLL storage class">;
+def fvisibility_dllexport_EQ : Joined<["-"], "fvisibility-dllexport=">, 
Group, Flags<[CC1Option]>,
+  HelpText<"The visibility for dllexport defintions 
[-fvisibility-from-dllstorageclass]">, Values<"hidden,protected,default">;
+def fvisibility_nodllstorageclass_EQ : Joined<["-"], 
"fvisibility-nodllstorageclass=">, Group, Flags<[CC1Option]>,
+  HelpText<"The visibility for defintiions without an explicit DLL export 
class [-fvisibility-from-dllstorageclass]">, Values<"hidden,protected,default">;
+def fvisibility_externs_dllimport_EQ : Joined<["-"], 
"fvisibility-externs-dllimport=">, Group, Flags<[CC1Option]>,
+  HelpText<"The visibility for dllimport external declarations 
[-fvisibility-from-dllstorageclass]">, Values<"hidden,protected,default">;
+def fvisibility_externs_nodllstorageclass_EQ : Joined<["-"], 
"fvisibility-externs-nodllstorageclass=">, Group, Flags<[CC1Option]>,
+  HelpText<"The visibility for external declarations without an explicit DLL 
dllstorageclass [-fvisibility-from-dllstorageclass]">, 
Values<"hidden,protected,default">;
 def fvisibility_EQ : Joined<["-"], "fvisibilit

[clang] 5024d3a - Revert "[Clang] Add the ability to map DLL storage class to visibility"

2020-11-02 Thread Ben Dunbobbin via cfe-commits

Author: Ben Dunbobbin
Date: 2020-11-02T17:33:54Z
New Revision: 5024d3aa1855d4c17c7e875048d5ad20b8b2d8ce

URL: 
https://github.com/llvm/llvm-project/commit/5024d3aa1855d4c17c7e875048d5ad20b8b2d8ce
DIFF: 
https://github.com/llvm/llvm-project/commit/5024d3aa1855d4c17c7e875048d5ad20b8b2d8ce.diff

LOG: Revert "[Clang] Add the ability to map DLL storage class to visibility"

This reverts commit 415f7ee8836944942d8beb70e982e95a312866a7.

The added tests were failing on the build bots!

Added: 


Modified: 
clang/include/clang/Basic/LangOptions.def
clang/include/clang/Driver/Options.td
clang/lib/CodeGen/CodeGenModule.cpp
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Driver/ToolChains/PS4CPU.cpp
clang/lib/Frontend/CompilerInvocation.cpp

Removed: 
clang/test/CodeGenCXX/visibility-dllstorageclass.cpp
clang/test/Driver/ps4-visibility-dllstorageclass.c
clang/test/Driver/visibility-dllstorageclass.c



diff  --git a/clang/include/clang/Basic/LangOptions.def 
b/clang/include/clang/Basic/LangOptions.def
index 1d203f8489eb..d711d66784a4 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -307,16 +307,6 @@ ENUM_LANGOPT(TypeVisibilityMode, Visibility, 3, 
DefaultVisibility,
  "default visibility for types [-ftype-visibility]")
 LANGOPT(SetVisibilityForExternDecls, 1, 0,
 "apply global symbol visibility to external declarations without an 
explicit visibility")
-LANGOPT(VisibilityFromDLLStorageClass, 1, 0,
-"set the visiblity of globals from their DLL storage class 
[-fvisibility-from-dllstorageclass]")
-ENUM_LANGOPT(DLLExportVisibility, Visibility, 3, DefaultVisibility,
- "visibility for functions and variables with dllexport 
annotations [-fvisibility-from-dllstorageclass]")
-ENUM_LANGOPT(NoDLLStorageClassVisibility, Visibility, 3, HiddenVisibility,
- "visibility for functions and variables without an explicit DLL 
storage class [-fvisibility-from-dllstorageclass]")
-ENUM_LANGOPT(ExternDeclDLLImportVisibility, Visibility, 3, DefaultVisibility,
- "visibility for external declarations with dllimport annotations 
[-fvisibility-from-dllstorageclass]")
-ENUM_LANGOPT(ExternDeclNoDLLStorageClassVisibility, Visibility, 3, 
HiddenVisibility,
- "visibility for external declarations without an explicit DLL 
storage class [-fvisibility-from-dllstorageclass]")
 BENIGN_LANGOPT(SemanticInterposition, 1, 0, "semantic interposition")
 BENIGN_LANGOPT(ExplicitNoSemanticInterposition, 1, 0, "explicitly no semantic 
interposition")
 ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff,

diff  --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 33cfa72c0888..057c2606c69d 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1973,15 +1973,6 @@ def fno_var_tracking : Flag<["-"], "fno-var-tracking">, 
Group, Group,
   HelpText<"Generate verbose assembly output">;
 def dA : Flag<["-"], "dA">, Alias;
-defm visibility_from_dllstorageclass : 
OptInFFlag<"visibility-from-dllstorageclass", "Set the visiblity of symbols in 
the generated code from their DLL storage class">;
-def fvisibility_dllexport_EQ : Joined<["-"], "fvisibility-dllexport=">, 
Group, Flags<[CC1Option]>,
-  HelpText<"The visibility for dllexport defintions 
[-fvisibility-from-dllstorageclass]">, Values<"hidden,protected,default">;
-def fvisibility_nodllstorageclass_EQ : Joined<["-"], 
"fvisibility-nodllstorageclass=">, Group, Flags<[CC1Option]>,
-  HelpText<"The visibility for defintiions without an explicit DLL export 
class [-fvisibility-from-dllstorageclass]">, Values<"hidden,protected,default">;
-def fvisibility_externs_dllimport_EQ : Joined<["-"], 
"fvisibility-externs-dllimport=">, Group, Flags<[CC1Option]>,
-  HelpText<"The visibility for dllimport external declarations 
[-fvisibility-from-dllstorageclass]">, Values<"hidden,protected,default">;
-def fvisibility_externs_nodllstorageclass_EQ : Joined<["-"], 
"fvisibility-externs-nodllstorageclass=">, Group, Flags<[CC1Option]>,
-  HelpText<"The visibility for external declarations without an explicit DLL 
dllstorageclass [-fvisibility-from-dllstorageclass]">, 
Values<"hidden,protected,default">;
 def fvisibility_EQ : Joined<["-"], "fvisibility=">, Group,
   HelpText<"Set the default symbol visibility for all global declarations">, 
Values<"hidden,default">;
 def fvisibility_inlines_hidden : Flag<["-"], "fvisibility-inlines-hidden">, 
Group,

diff  --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 9512b350d9fd..66a3c57b9112 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -401,41 +401,6 @@ void InstrProfStats::reportDiagnostics(DiagnosticsEngine 
&Diags,
   }
 }
 
-static void setVisibilityFromDLLStorage

[clang] ae9231c - Reland - [Clang] Add the ability to map DLL storage class to visibility

2020-11-02 Thread Ben Dunbobbin via cfe-commits

Author: Ben Dunbobbin
Date: 2020-11-02T23:24:49Z
New Revision: ae9231ca2a8125ce75fff3ff2539126610aa2eeb

URL: 
https://github.com/llvm/llvm-project/commit/ae9231ca2a8125ce75fff3ff2539126610aa2eeb
DIFF: 
https://github.com/llvm/llvm-project/commit/ae9231ca2a8125ce75fff3ff2539126610aa2eeb.diff

LOG: Reland - [Clang] Add the ability to map DLL storage class to visibility

415f7ee883 had LIT test failures on any build where the clang executable
was not called "clang". I have adjusted the LIT CHECKs to remove the
binary name to fix this.

Original commit message:

For PlayStation we offer source code compatibility with
Microsoft's dllimport/export annotations; however, our file
format is based on ELF.

To support this we translate from DLL storage class to ELF
visibility at the end of codegen in Clang.

Other toolchains have used similar strategies (e.g. see the
documentation for this ARM toolchain:

https://developer.arm.com/documentation/dui0530/i/migrating-from-rvct-v3-1-to-rvct-v4-0/changes-to-symbol-visibility-between-rvct-v3-1-and-rvct-v4-0)

This patch adds the ability to perform this translation. Options
are provided to support customizing the mapping behaviour.

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

Added: 
clang/test/CodeGenCXX/visibility-dllstorageclass.cpp
clang/test/Driver/ps4-visibility-dllstorageclass.c
clang/test/Driver/visibility-dllstorageclass.c

Modified: 
clang/include/clang/Basic/LangOptions.def
clang/include/clang/Driver/Options.td
clang/lib/CodeGen/CodeGenModule.cpp
clang/lib/Driver/ToolChains/Clang.cpp
clang/lib/Driver/ToolChains/PS4CPU.cpp
clang/lib/Frontend/CompilerInvocation.cpp

Removed: 




diff  --git a/clang/include/clang/Basic/LangOptions.def 
b/clang/include/clang/Basic/LangOptions.def
index d711d66784a4..1d203f8489eb 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -307,6 +307,16 @@ ENUM_LANGOPT(TypeVisibilityMode, Visibility, 3, 
DefaultVisibility,
  "default visibility for types [-ftype-visibility]")
 LANGOPT(SetVisibilityForExternDecls, 1, 0,
 "apply global symbol visibility to external declarations without an 
explicit visibility")
+LANGOPT(VisibilityFromDLLStorageClass, 1, 0,
+"set the visiblity of globals from their DLL storage class 
[-fvisibility-from-dllstorageclass]")
+ENUM_LANGOPT(DLLExportVisibility, Visibility, 3, DefaultVisibility,
+ "visibility for functions and variables with dllexport 
annotations [-fvisibility-from-dllstorageclass]")
+ENUM_LANGOPT(NoDLLStorageClassVisibility, Visibility, 3, HiddenVisibility,
+ "visibility for functions and variables without an explicit DLL 
storage class [-fvisibility-from-dllstorageclass]")
+ENUM_LANGOPT(ExternDeclDLLImportVisibility, Visibility, 3, DefaultVisibility,
+ "visibility for external declarations with dllimport annotations 
[-fvisibility-from-dllstorageclass]")
+ENUM_LANGOPT(ExternDeclNoDLLStorageClassVisibility, Visibility, 3, 
HiddenVisibility,
+ "visibility for external declarations without an explicit DLL 
storage class [-fvisibility-from-dllstorageclass]")
 BENIGN_LANGOPT(SemanticInterposition, 1, 0, "semantic interposition")
 BENIGN_LANGOPT(ExplicitNoSemanticInterposition, 1, 0, "explicitly no semantic 
interposition")
 ENUM_LANGOPT(StackProtector, StackProtectorMode, 2, SSPOff,

diff  --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index 057c2606c69d..33cfa72c0888 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1973,6 +1973,15 @@ def fno_var_tracking : Flag<["-"], "fno-var-tracking">, 
Group, Group,
   HelpText<"Generate verbose assembly output">;
 def dA : Flag<["-"], "dA">, Alias;
+defm visibility_from_dllstorageclass : 
OptInFFlag<"visibility-from-dllstorageclass", "Set the visiblity of symbols in 
the generated code from their DLL storage class">;
+def fvisibility_dllexport_EQ : Joined<["-"], "fvisibility-dllexport=">, 
Group, Flags<[CC1Option]>,
+  HelpText<"The visibility for dllexport defintions 
[-fvisibility-from-dllstorageclass]">, Values<"hidden,protected,default">;
+def fvisibility_nodllstorageclass_EQ : Joined<["-"], 
"fvisibility-nodllstorageclass=">, Group, Flags<[CC1Option]>,
+  HelpText<"The visibility for defintiions without an explicit DLL export 
class [-fvisibility-from-dllstorageclass]">, Values<"hidden,protected,default">;
+def fvisibility_externs_dllimport_EQ : Joined<["-"], 
"fvisibility-externs-dllimport=">, Group, Flags<[CC1Option]>,
+  HelpText<"The visibility for dllimport external declarations 
[-fvisibility-from-dllstorageclass]">, Values<"hidden,protected,default">;
+def fvisibility_externs_nodllstorageclass_EQ : Joined<["-"], 
"fvisibility-externs-nodllstorageclass=">, Group, Flags<[CC1Option]>,
+  HelpText<"Th

[clang] 7eee2a2 - [IR] Don't allow DLL storage-class and local linkage

2022-09-29 Thread Ben Dunbobbin via cfe-commits

Author: Ben Dunbobbin
Date: 2022-09-30T00:26:01+01:00
New Revision: 7eee2a2d4401813cd485ae708e8cb0f94469e037

URL: 
https://github.com/llvm/llvm-project/commit/7eee2a2d4401813cd485ae708e8cb0f94469e037
DIFF: 
https://github.com/llvm/llvm-project/commit/7eee2a2d4401813cd485ae708e8cb0f94469e037.diff

LOG: [IR] Don't allow DLL storage-class and local linkage

Disallow this meaningless combination. Doing so simplifies analysis
of LLVM code w.r.t t DLL storage-class, and prevents mistakes with
DLL storage class.

- Change the assembler to reject DLL storage class on symbols with
  local linkage.
- Change the bitcode reader to clear the DLL Storage class when the
  linkage is local for auto-upgrading
- Update LangRef.

There is an existing restriction on non-default visibility and local
linkage which this is modelled on.

Differential Review: https://reviews.llvm.org/D134784

Added: 
llvm/test/Assembler/dll-storage-class-local-linkage.ll

Modified: 
clang/lib/CodeGen/CodeGenModule.cpp
llvm/docs/LangRef.rst
llvm/include/llvm/IR/GlobalValue.h
llvm/lib/AsmParser/LLParser.cpp
llvm/lib/Bitcode/Reader/BitcodeReader.cpp
llvm/test/Transforms/GlobalOpt/alias-used-section.ll

Removed: 




diff  --git a/clang/lib/CodeGen/CodeGenModule.cpp 
b/clang/lib/CodeGen/CodeGenModule.cpp
index 8feb673e9393a..92920dae8111a 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -6013,10 +6013,13 @@ ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary(
   getModule(), Type, Constant, Linkage, InitialValue, Name.c_str(),
   /*InsertBefore=*/nullptr, llvm::GlobalVariable::NotThreadLocal, 
TargetAS);
   if (emitter) emitter->finalize(GV);
-  setGVProperties(GV, VD);
-  if (GV->getDLLStorageClass() == llvm::GlobalVariable::DLLExportStorageClass)
-// The reference temporary should never be dllexport.
-GV->setDLLStorageClass(llvm::GlobalVariable::DefaultStorageClass);
+  // Don't assign dllimport or dllexport to local linkage globals.
+  if (!llvm::GlobalValue::isLocalLinkage(Linkage)) {
+setGVProperties(GV, VD);
+if (GV->getDLLStorageClass() == 
llvm::GlobalVariable::DLLExportStorageClass)
+  // The reference temporary should never be dllexport.
+  GV->setDLLStorageClass(llvm::GlobalVariable::DefaultStorageClass);
+  }
   GV->setAlignment(Align.getAsAlign());
   if (supportsCOMDAT() && GV->isWeakForLinker())
 GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));

diff  --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 5b66ac0f76a64..1778a0a14f3b5 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -522,6 +522,9 @@ DLL storage class:
 assembler and linker know it is externally referenced and must refrain from
 deleting the symbol.
 
+A symbol with ``internal`` or ``private`` linkage cannot have a DLL storage
+class.
+
 .. _tls_model:
 
 Thread Local Storage Models

diff  --git a/llvm/include/llvm/IR/GlobalValue.h 
b/llvm/include/llvm/IR/GlobalValue.h
index 63c5d1b5f5c79..db290923dcf0c 100644
--- a/llvm/include/llvm/IR/GlobalValue.h
+++ b/llvm/include/llvm/IR/GlobalValue.h
@@ -275,7 +275,11 @@ class GlobalValue : public Constant {
   bool hasDLLExportStorageClass() const {
 return DllStorageClass == DLLExportStorageClass;
   }
-  void setDLLStorageClass(DLLStorageClassTypes C) { DllStorageClass = C; }
+  void setDLLStorageClass(DLLStorageClassTypes C) {
+assert((!hasLocalLinkage() || C == DefaultStorageClass) &&
+   "local linkage requires DefaultStorageClass");
+DllStorageClass = C;
+  }
 
   bool hasSection() const { return !getSection().empty(); }
   StringRef getSection() const;
@@ -524,8 +528,10 @@ class GlobalValue : public Constant {
   }
 
   void setLinkage(LinkageTypes LT) {
-if (isLocalLinkage(LT))
+if (isLocalLinkage(LT)) {
   Visibility = DefaultVisibility;
+  DllStorageClass = DefaultStorageClass;
+}
 Linkage = LT;
 if (isImplicitDSOLocal())
   setDSOLocal(true);

diff  --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 23445f4a71b9d..1b072f8451a06 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -967,6 +967,10 @@ static bool isValidVisibilityForLinkage(unsigned V, 
unsigned L) {
   return !GlobalValue::isLocalLinkage((GlobalValue::LinkageTypes)L) ||
  (GlobalValue::VisibilityTypes)V == GlobalValue::DefaultVisibility;
 }
+static bool isValidDLLStorageClassForLinkage(unsigned S, unsigned L) {
+  return !GlobalValue::isLocalLinkage((GlobalValue::LinkageTypes)L) ||
+ (GlobalValue::DLLStorageClassTypes)S == 
GlobalValue::DefaultStorageClass;
+}
 
 // If there was an explicit dso_local, update GV. In the absence of an explicit
 // dso_local we keep the default value.
@@ -1020,6 +1024,10 @@ bool LLParser::parseAliasOrIFunc(const std::string 
&Name, LocTy NameLoc,
 return error

[clang] 437ccf5 - [windows-itanium] Propagate DLL storage class to Initialisation Guard Variables

2022-11-23 Thread Ben Dunbobbin via cfe-commits

Author: Ben Dunbobbin
Date: 2022-11-24T00:23:17Z
New Revision: 437ccf5af9c2aec915a68a164a95d506fbac2324

URL: 
https://github.com/llvm/llvm-project/commit/437ccf5af9c2aec915a68a164a95d506fbac2324
DIFF: 
https://github.com/llvm/llvm-project/commit/437ccf5af9c2aec915a68a164a95d506fbac2324.diff

LOG: [windows-itanium] Propagate DLL storage class to Initialisation Guard 
Variables

Initialisation Guard Variables should take their DLL storage class
from the guarded variable. Otherwise, there will be a link error if
the compiler inlines a reference to the guard variable into another
module but that guard variable is not exported from the defining
module.

This is required for platforms such as PlayStation and
windows-itanium, that are aiming for source compatibility with MSVC
w.r.t. dllimport/export annotations, given Clang's existing design
which allows for inlining of a dllimport function as long as all the
variables/functions referenced are also marked dllimport.

A similar change exists for the MSVC ABI:
https://reviews.llvm.org/D4136.

I have added a run test for windows-itanium for this issue to the
build recipe: https://reviews.llvm.org/D88124.

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

Added: 
clang/test/CodeGenCXX/windows-itanium-init-guard.cpp

Modified: 
clang/lib/CodeGen/ItaniumCXXABI.cpp

Removed: 




diff  --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp 
b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index 20aa9698dc564..224a019d2fd3a 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -2385,13 +2385,15 @@ void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction 
&CGF,
 }
 
 // Create the guard variable with a zero-initializer.
-// Just absorb linkage and visibility from the guarded variable.
+// Just absorb linkage, visibility and dll storage class  from the guarded
+// variable.
 guard = new llvm::GlobalVariable(CGM.getModule(), guardTy,
  false, var->getLinkage(),
  llvm::ConstantInt::get(guardTy, 0),
  guardName.str());
 guard->setDSOLocal(var->isDSOLocal());
 guard->setVisibility(var->getVisibility());
+guard->setDLLStorageClass(var->getDLLStorageClass());
 // If the variable is thread-local, so is its guard variable.
 guard->setThreadLocalMode(var->getThreadLocalMode());
 guard->setAlignment(guardAlignment.getAsAlign());

diff  --git a/clang/test/CodeGenCXX/windows-itanium-init-guard.cpp 
b/clang/test/CodeGenCXX/windows-itanium-init-guard.cpp
new file mode 100644
index 0..8bcfd272ae8f1
--- /dev/null
+++ b/clang/test/CodeGenCXX/windows-itanium-init-guard.cpp
@@ -0,0 +1,32 @@
+// Initialisation Guard Variables should take their DLL storage class from
+// the guarded variable. Otherwise, there will be a link error if the compiler
+// inlines a reference to the guard variable into another module but that
+// guard variable is not exported from the defining module.
+
+// RUN: %clang_cc1 -emit-llvm -triple i686-windows-itanium -fdeclspec %s -O1 
-disable-llvm-passes -o - -DAPI= | FileCheck %s --check-prefixes=NONE
+// RUN: %clang_cc1 -emit-llvm -triple i686-windows-itanium -fdeclspec %s -O1 
-disable-llvm-passes -o - -DAPI="__declspec(dllexport)" | FileCheck %s 
--check-prefixes=EXPORT
+// RUN: %clang_cc1 -emit-llvm -triple i686-windows-itanium -fdeclspec %s -O1 
-disable-llvm-passes -o - -DAPI="__declspec(dllimport)" | FileCheck %s 
--check-prefixes=IMPORT
+
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-scei-ps4 -fdeclspec %s -O1 
-disable-llvm-passes -o - -DAPI= | FileCheck %s --check-prefixes=NONE
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-scei-ps4 -fdeclspec %s -O1 
-disable-llvm-passes -o - -DAPI="__declspec(dllexport)" | FileCheck %s 
--check-prefixes=EXPORT
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-scei-ps4 -fdeclspec %s -O1 
-disable-llvm-passes -o - -DAPI="__declspec(dllimport)" | FileCheck %s 
--check-prefixes=IMPORT
+
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-scei-ps5 -fdeclspec %s -O1 
-disable-llvm-passes -o - -DAPI= | FileCheck %s --check-prefixes=NONE
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-scei-ps5 -fdeclspec %s -O1 
-disable-llvm-passes -o - -DAPI="__declspec(dllexport)" | FileCheck %s 
--check-prefixes=EXPORT
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-scei-ps5 -fdeclspec %s -O1 
-disable-llvm-passes -o - -DAPI="__declspec(dllimport)" | FileCheck %s 
--check-prefixes=IMPORT
+
+//NONE: @_ZZN3foo3GetEvE9Singleton = linkonce_odr {{(dso_local )?}}global
+//NONE: @_ZGVZN3foo3GetEvE9Singleton = linkonce_odr {{(dso_local )?}}global
+
+//EXPORT: @_ZZN3foo3GetEvE9Singleton = weak_odr {{(dso_local )?}}dllexport 
global
+//EXPORT: @_ZGVZN3foo3GetEvE9Singleton = weak_odr {{(dso_local )?}}dllexport 
global
+
+//IMPORT: @_ZZN3foo3GetEvE9Singleton = available_externally dllimport g

[clang] eae2d4b - [Windows Itanium][PS4] handle dllimport/export w.r.t vtables/rtti

2021-04-13 Thread Ben Dunbobbin via cfe-commits

Author: Ben Dunbobbin
Date: 2021-04-13T11:41:10+01:00
New Revision: eae2d4b8520c768291dcff2169b78486af324d17

URL: 
https://github.com/llvm/llvm-project/commit/eae2d4b8520c768291dcff2169b78486af324d17
DIFF: 
https://github.com/llvm/llvm-project/commit/eae2d4b8520c768291dcff2169b78486af324d17.diff

LOG: [Windows Itanium][PS4] handle dllimport/export w.r.t vtables/rtti

The existing Windows Itanium patches for dllimport/export
behaviour w.r.t vtables/rtti can't be adopted for PS4 due to
backwards compatibility reasons (see comments on
https://reviews.llvm.org/D90299).

This commit adds our PS4 scheme for this to Clang.

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

Added: 
clang/test/CodeGenCXX/ps4-dllstorage-vtable-rtti.cpp

Modified: 
clang/include/clang/Basic/TargetInfo.h
clang/lib/AST/RecordLayoutBuilder.cpp
clang/lib/CodeGen/ItaniumCXXABI.cpp

Removed: 




diff  --git a/clang/include/clang/Basic/TargetInfo.h 
b/clang/include/clang/Basic/TargetInfo.h
index 3ddb706dcf52..3bcaaceb63d8 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -1130,6 +1130,15 @@ class TargetInfo : public virtual 
TransferrableTargetInfo,
getTriple().isWindowsItaniumEnvironment() || getTriple().isPS4CPU();
   }
 
+  // Does this target have PS4 specific dllimport/export handling?
+  virtual bool hasPS4DLLImportExport() const {
+return getTriple().isPS4CPU() ||
+   // Windows Itanium support allows for testing the SCEI flavour of
+   // dllimport/export handling on a Windows system.
+   (getTriple().isWindowsItaniumEnvironment() &&
+getTriple().getVendor() == llvm::Triple::SCEI);
+  }
+
   /// An optional hook that targets can implement to perform semantic
   /// checking on attribute((section("foo"))) specifiers.
   ///

diff  --git a/clang/lib/AST/RecordLayoutBuilder.cpp 
b/clang/lib/AST/RecordLayoutBuilder.cpp
index eb9bfc20342f..8a25b5cbd84a 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -2293,7 +2293,8 @@ static const CXXMethodDecl *computeKeyFunction(ASTContext 
&Context,
 // If the key function is dllimport but the class isn't, then the class has
 // no key function. The DLL that exports the key function won't export the
 // vtable in this case.
-if (MD->hasAttr() && !RD->hasAttr())
+if (MD->hasAttr() && !RD->hasAttr() &&
+!Context.getTargetInfo().hasPS4DLLImportExport())
   return nullptr;
 
 // We found it.

diff  --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp 
b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index c10ee0446912..93500cb62359 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -1835,6 +1835,29 @@ ItaniumCXXABI::getVTableAddressPoint(BaseSubobject Base,
   /*InRangeIndex=*/1);
 }
 
+// Check whether all the non-inline virtual methods for the class have the
+// specified attribute.
+template 
+static bool CXXRecordAllNonInlineVirtualsHaveAttr(const CXXRecordDecl *RD) {
+  bool FoundNonInlineVirtualMethodWithAttr = false;
+  for (const auto *D : RD->noload_decls()) {
+if (const auto *FD = dyn_cast(D)) {
+  if (!FD->isVirtualAsWritten() || FD->isInlineSpecified() ||
+  FD->doesThisDeclarationHaveABody())
+continue;
+  if (!D->hasAttr())
+return false;
+  FoundNonInlineVirtualMethodWithAttr = true;
+}
+  }
+
+  // We didn't find any non-inline virtual methods missing the attribute.  We
+  // will return true when we found at least one non-inline virtual with the
+  // attribute.  (This lets our caller know that the attribute needs to be
+  // propagated up to the vtable.)
+  return FoundNonInlineVirtualMethodWithAttr;
+}
+
 llvm::Value *ItaniumCXXABI::getVTableAddressPointInStructorWithVTT(
 CodeGenFunction &CGF, const CXXRecordDecl *VTableClass, BaseSubobject Base,
 const CXXRecordDecl *NearestVBase) {
@@ -1891,6 +1914,24 @@ llvm::GlobalVariable 
*ItaniumCXXABI::getAddrOfVTable(const CXXRecordDecl *RD,
   getContext().toCharUnitsFromBits(PAlign).getQuantity());
   VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
 
+  // In MS C++ if you have a class with virtual functions in which you are 
using
+  // selective member import/export, then all virtual functions must be 
exported
+  // unless they are inline, otherwise a link error will result. To match this
+  // behavior, for such classes, we dllimport the vtable if it is defined
+  // externally and all the non-inline virtual methods are marked dllimport, 
and
+  // we dllexport the vtable if it is defined in this TU and all the non-inline
+  // virtual methods are marked dllexport.
+  if (CGM.getTarget().hasPS4DLLImportExport()) {
+if ((!RD->hasAttr()) && (!RD->hasAttr())) {
+  if (CGM.getVTables().isVTableExternal(RD)