Commit Graph

64 Commits

Author SHA1 Message Date
David Majnemer 57417d0d97 Fix clang tests to be compliant with LLVM IR aliases
Comdat IR references were mistakenly printed for aliases when they
passed through the IR/AsmWriter code.

This makes clang's tests not check for the existance of these wrongly
printed comdat references.

llvm-svn: 212733
2014-07-10 16:26:19 +00:00
David Majnemer 611cdb9a63 CodeGen: Cleanup MS ABI RTTI LLVM IR
The MS ABI RTTI emission code would choose names for IR types like
%"MSRTTITypeDescriptor\02".  This name is undesirable because it
requires escaping; the underlying reason for this is that the name is
unprintable.  Fix this by naming it %rtti.TypeDescriptor2.

While here, stop trying to do lookups in the LLVM Module's type table.
Instead, store the IR types in MicrosoftCXXABI.  Lookups by name aren't
particularly fast.

llvm-svn: 212439
2014-07-07 08:09:15 +00:00
David Majnemer d905da4a5f MS ABI: Reference MSVC RTTI from the VFTable
The pointer for a class's RTTI data comes right before the VFTable but
has no name.  To be properly compatible with this, we do the following:
* Create a single GlobalVariable which holds the contents of the VFTable
  _and_ the pointer to the RTTI data.
* Create a GlobalAlias, with appropriate linkage/visibility, that points
  just after the RTTI data pointer.  This ensures that the VFTable
  symbol will always refer to VFTable data.
* Create a Comdat with a "Largest" SelectionKind and stick the private
  GlobalVariable in it.  By transitivity, the GlobalAlias will be a
  member of the Comdat group.  Using "Largest" ensures that foreign
  definitions without an RTTI data pointer will _not_ be chosen in the
  final linked image.

Whether or not we emit RTTI data depends on several things:
* The -fno-rtti flag implies that we should never not emit a pointer to
  RTTI data before the VFTable.
* __declspec(dllimport) brings in the VFTable from a remote DLL. Use an
  available_externally GlobalVariable to provide a local definition of
  the VFTable.  This means that we won't have any available_externally
  definitions of things like complete object locators.  This is
  acceptable because they are never directly referenced.

To my knowledge, this completes the implementation of MSVC RTTI code
generation.

Further semantic work should be done to properly support /GR-.

llvm-svn: 212125
2014-07-01 20:30:31 +00:00
Hans Wennborg 9bea9cc73b MS ABI: Propagate class-level DLL attributes to class template specialization bases (PR11170)
Consider the following code:

  template <typename T> class Base {};
  class __declspec(dllexport) class Derived : public Base<int> {}

When the base of an exported or imported class is a class template
specialization, MSVC will propagate the dll attribute to the base.
In the example code, Base<int> becomes a dllexported class.

This commit makes Clang do the proopagation when the base hasn't been
instantiated yet, and warns about it being unsupported otherwise.
This is different from MSVC, which allows changing a specialization
back and forth between dllimport and dllexport and seems to let the
last one win. Changing the dll attribute after instantiation would be
hard for us, and doesn't seem to come up in practice, so I think this
is a reasonable limitation to have.

MinGW doesn't do this kind of propagation.

Differential Revision: http://reviews.llvm.org/D4264

llvm-svn: 211725
2014-06-25 18:25:57 +00:00
Hans Wennborg 5e64528195 MS ABI: Ignore dll attributes on partial template specializations
llvm-svn: 211648
2014-06-24 23:57:13 +00:00
Hans Wennborg ef2272c49e Inherit dll attributes to static locals
This makes us handle static locals in exported/imported functions correctly.

Differential Revision: http://reviews.llvm.org/D4136

llvm-svn: 211173
2014-06-18 15:55:13 +00:00
Hans Wennborg dfcb7d6a97 Defer codegen of inline method definitions to the end of current top level declaration
We would previously fail to emit a definition of bar() for the following code:

  struct __declspec(dllexport) S {
    void foo() {
      t->bar();
    }
    struct T {
      void bar() {}
    };
    T *t;
  };

Note that foo() is an exported method, but bar() is not. However, foo() refers
to bar() so we need to emit its definition. We would previously fail to
realise that bar() is used.

By deferring the method definitions until the end of the top level declaration,
we can simply call EmitTopLevelDecl on them and rely on the usual mechanisms
to decide whether the method should be emitted or not.

Differential Revision: http://reviews.llvm.org/D4038

llvm-svn: 210356
2014-06-06 17:36:17 +00:00
Hans Wennborg da24e9cee3 Itanium ABI: Update getAddrOfVTable to set the DLL storage class for vtables
This corresponds to the same change for the MS ABI in r209908.

Differential Revision: http://reviews.llvm.org/D3993

llvm-svn: 210054
2014-06-02 23:13:03 +00:00
Hans Wennborg 853ae94660 Start adding support for dllimport/dllexport on classes (PR11170)
This implements the central part of support for dllimport/dllexport on
classes: allowing the attribute on class declarations, inheriting it
to class members, and forcing emission of exported members. It's based
on Nico Rieck's patch from http://reviews.llvm.org/D1099.

This patch doesn't propagate dllexport to bases that are template
specializations, which is an interesting problem. It also doesn't
look at the rules when redeclaring classes with different attributes,
I'd like to do that separately.

Differential Revision: http://reviews.llvm.org/D3877

llvm-svn: 209908
2014-05-30 16:59:42 +00:00
Nico Rieck 755a36f593 IRGen: Add more tests for dll attributes
llvm-svn: 209596
2014-05-25 10:34:16 +00:00
Hans Wennborg a926d84c4b Emit used/dllexport inline method definitions in nested classes (PR19743, PR11170)
The previous code that was supposed to handle this didn't work
since parsing of inline method definitions is delayed to the end
of the outer class definition. Thus, when HandleTagDeclDefinition()
got called for the inner class, the inline functions in that class
had not been parsed yet.

Richard suggested that the way to do this is by handling inline
method definitions through a new ASTConsumer callback.

I really wanted to call ASTContext::DeclMustBeEmitted() instead of
checking for attributes, but doing that causes us to compute linkage,
and then we fail with "error: unsupported: typedef changes linkage
of anonymous type, but linkage was already computed" on tests like
this: (from SemaCXX/undefined-internal.cpp) :-/

  namespace test7 {
    typedef struct {
      void bar();
      void foo() { bar(); }
    } A;
  }

Differential Revision: http://reviews.llvm.org/D3809

llvm-svn: 209549
2014-05-23 20:37:38 +00:00
Hans Wennborg 5161db61a9 test/CodeGenCXX/dllexport.cpp: -O2 and -disable-llvm-optzns aren't nedded
We only need them on the dllimport.cpp test to make sure that we emit code
for available_externaly functions, and don't inline the IR.

llvm-svn: 209145
2014-05-19 17:23:01 +00:00
Hans Wennborg 4e43fef3e5 test/CodeGenCXX/dllexport.cpp: we already correctly emit b() even when
it's not used, because CodeGenModule::EmitGlobal consults
ASTContext::DeclMustBeEmitted via CodeGenModule::MayDeferGeneration.

llvm-svn: 208936
2014-05-16 00:09:31 +00:00
Hans Wennborg b0f2f146bb Allow dllimport/dllexport on inline functions and adjust the linkage.
This is a step towards handling these attributes on classes (PR11170).

Differential Revision: http://reviews.llvm.org/D3772

llvm-svn: 208925
2014-05-15 22:07:49 +00:00