[PATCH] Full support for dllexport/dllimport attributes

Nico Rieck nico.rieck at gmail.com
Thu Jul 4 10:25:16 PDT 2013


This patch series implements full support for dllexport/dllimport attributes

- Adds support for class-wide export/import attributes (PR11170)
- Handles dllexport/dllimport on inline functions and templates

Fixes PR11170, PR13450



Implemented semantics:

1. dllexport and dllimport can be applied to functions, static data members and
   global variables. Both can also be applied to typedefs and enums (without
   effect) if -fms-extensions is specified, for all other cases the attributes
   are ignored and a warning is issued. It is an error to apply them to
   non-static data members.

2. dllexport requires a definition. The extern keyword can be used to force a
   declaration.

3. dllimport requires a declaration.

4. dllexport exposes the function or variable with its decorated name.
  a) For C++, this includes name mangling.
  b) For C or extern "C" functions, this includes platform-specific decoration 
     for the calling convention.

5. dllexport takes precedence over dllimport. If both are specified, dllimport
   is ignored and a warning is issued.

6. Classes
  a) When applied to a class, dllexport or dllimport affect all static and
     non-static member functions and all static data members, including all
     non-deleted special members.
  b) Everything that is accessible to the DLL's client according to C++ access
     rules is exported (including private data members referenced in inline
     functions).
  c) Members can be imported or exported selectively.
  d) Explicit dllexport/dllimport attributes on members of exported/imported
     classes are forbidden.
  e) Base classes of an exported class should be exported. Emits a warning
     otherwise. (-Wmissing-dllexport)
  f) Virtual tables and typeinfo follow the emission rules of the Itanium ABI,
     i.e. for an exported/imported dynamic class with key function, the needed
     globals are exported/imported. If there is no key function, they are
     emitted everywhere and are not exported/imported.

7. Inline functions
  a) dllexport can be applied to inline function definitions. The function is
     always instantiated and exported, presumed to be imported by another
     program.
  b) dllimport can be applied to inline function definitions. Such functions
     can be expanded, but never instantiated.

8. Templates
  a) If a class template is exported, explicit and implicit instantiations are
     also exported.
  b) Non-exported/imported class templates can be exported/imported by
     decorating an explicit instantiation.
  c) Base classes that are template specializations must be instantiated
     explicitly to export them.
  d) If a class is marked as dllexport, any specializations of class templates
     in the class hierarchy are implicitly marked as declspec(dllexport). This
     means that class templates are explicitly instantiated and the class's
     members must be defined.



Implementation notes:

Representing dllexport/dllimport as distinct linkage types prevents using them
on templates and inline functions.

Instead of introducing further mixed linkage types to include linkonce and
weak ODR, the old import/export linkage types are replaced with function
attributes (DLLExport, DLLImport) and an extension to global variables, similar
to how alignment is specified:

  @Exp = global i32 1, align 4, dllexport
  @Imp = external global i32, dllimport

Linkage for dllexported globals and functions is now equal to their linkage
without dllexport. All dllexported entities are decorated with UsedAttr to
ensure their emission. Imported globals and functions must be either
declarations, or definitions with AvailableExternallyLinkage.

In some cases a dllimport/dllexport attribute is ignored. If this happens on
a member of an exported/imported class, we need a way to drop the attribute.
During Sema, when checking such a class, every member is decorated with an
inherited attribute, which allows subsequent dropping. This requires a small
change (or possibly fix?) to table-gen so that the inherited status of an
attribute is preserved when instantiating template attributes.


Open questions/issues:

1. With two linkage types removed, should the bitcode mapping of linkage types
   to integers be adjusted to remove the "holes"?

2. Should aliases be exportable/importable? For now an alias is exported if
   the aliasee is exported.

3. Currently dynamic classes with key function cannot have individual virtual
   members exported as this leads to missing exports for typeinfo.

4. The CodeGen tests are extremely slow due to CHECK-DAG, and without CHECK-DAG
   the tests are very hard to understand because virtual/inline functions are
   emitted in a different order. Suggestions?


Please note: The uploaded patch is a combination of two git diffs. I prefixed
each one with the project-path from the SVN repo.


http://llvm-reviews.chandlerc.com/D1099

Files:
  llvm/trunk/include/llvm-c/Core.h
  llvm/trunk/include/llvm/IR/Attributes.h
  llvm/trunk/include/llvm/IR/GlobalValue.h
  llvm/trunk/include/llvm/IR/GlobalVariable.h
  llvm/trunk/lib/AsmParser/LLParser.cpp
  llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
  llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
  llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp
  llvm/trunk/lib/IR/AsmWriter.cpp
  llvm/trunk/lib/IR/Attributes.cpp
  llvm/trunk/lib/IR/Core.cpp
  llvm/trunk/lib/IR/Globals.cpp
  llvm/trunk/lib/IR/Verifier.cpp
  llvm/trunk/lib/Linker/LinkModules.cpp
  llvm/trunk/lib/Target/CppBackend/CPPBackend.cpp
  llvm/trunk/lib/Target/Mangler.cpp
  llvm/trunk/lib/Target/X86/X86AsmPrinter.cpp
  llvm/trunk/lib/Target/X86/X86FastISel.cpp
  llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
  llvm/trunk/lib/Target/X86/X86Subtarget.cpp
  llvm/trunk/lib/Target/XCore/XCoreAsmPrinter.cpp
  llvm/trunk/test/CodeGen/X86/dll-linkage.ll
  llvm/trunk/test/CodeGen/X86/dllexport.ll
  llvm/trunk/test/MC/COFF/linker-options.ll
  cfe/trunk/cfe/trunk/include/clang/AST/DeclCXX.h
  cfe/trunk/cfe/trunk/include/clang/Basic/DiagnosticGroups.td
  cfe/trunk/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
  cfe/trunk/cfe/trunk/lib/AST/ASTContext.cpp
  cfe/trunk/cfe/trunk/lib/AST/Decl.cpp
  cfe/trunk/cfe/trunk/lib/CodeGen/CGRTTI.cpp
  cfe/trunk/cfe/trunk/lib/CodeGen/CGVTT.cpp
  cfe/trunk/cfe/trunk/lib/CodeGen/CGVTables.cpp
  cfe/trunk/lib/CodeGen/CodeGenModule.cpp
  cfe/trunk/lib/CodeGen/CodeGenModule.h
  cfe/trunk/lib/Sema/SemaDecl.cpp
  cfe/trunk/lib/Sema/SemaDeclCXX.cpp
  cfe/trunk/lib/Sema/TargetAttributesSema.cpp
  cfe/trunk/test/CodeGen/dllimport-dllexport.c
  cfe/trunk/test/CodeGenCXX/dllexport-functions.cpp
  cfe/trunk/test/CodeGenCXX/dllexport-globals.cpp
  cfe/trunk/test/CodeGenCXX/dllexport-members.cpp
  cfe/trunk/test/CodeGenCXX/dllexport-records.cpp
  cfe/trunk/test/CodeGenCXX/dllexport-templates.cpp
  cfe/trunk/test/CodeGenCXX/dllimport-functions.cpp
  cfe/trunk/test/CodeGenCXX/dllimport-globals.cpp
  cfe/trunk/test/CodeGenCXX/dllimport-members.cpp
  cfe/trunk/test/CodeGenCXX/dllimport-records.cpp
  cfe/trunk/test/CodeGenCXX/dllimport-templates.cpp
  cfe/trunk/test/Rewriter/dllimport-typedef.c
  cfe/trunk/test/Rewriter/missing-dllimport.c
  cfe/trunk/test/Sema/dllexport.c
  cfe/trunk/test/Sema/dllimport-dllexport.c
  cfe/trunk/test/Sema/dllimport.c
  cfe/trunk/test/SemaCXX/MicrosoftExtensions.cpp
  cfe/trunk/test/SemaCXX/dllexport.cpp
  cfe/trunk/test/SemaCXX/dllimport.cpp
  cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1099.1.patch
Type: text/x-patch
Size: 234679 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130704/b70fe5e7/attachment.bin>


More information about the llvm-commits mailing list