Decouple dllexport/dllimport from linkage

Representing dllexport/dllimport as distinct linkage types prevents using
these attributes 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 a new
separate visibility-like specifier:

  define available_externally dllimport void @f() {}
  @Var = dllexport global i32 1, align 4

Linkage for dllexported globals and functions is now equal to their linkage
without dllexport. Imported globals and functions must be either
declarations with external linkage, or definitions with
AvailableExternallyLinkage.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199218 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Nico Rieck
2014-01-14 15:22:47 +00:00
parent d05a6582da
commit 38f68c5a2e
27 changed files with 547 additions and 157 deletions

View File

@@ -131,6 +131,7 @@ namespace {
private:
void printLinkageType(GlobalValue::LinkageTypes LT);
void printVisibilityType(GlobalValue::VisibilityTypes VisTypes);
void printDLLStorageClassType(GlobalValue::DLLStorageClassTypes DSCType);
void printThreadLocalMode(GlobalVariable::ThreadLocalMode TLM);
void printCallingConv(CallingConv::ID cc);
void printEscapedString(const std::string& str);
@@ -300,10 +301,6 @@ void CppWriter::printLinkageType(GlobalValue::LinkageTypes LT) {
Out << "GlobalValue::AppendingLinkage"; break;
case GlobalValue::ExternalLinkage:
Out << "GlobalValue::ExternalLinkage"; break;
case GlobalValue::DLLImportLinkage:
Out << "GlobalValue::DLLImportLinkage"; break;
case GlobalValue::DLLExportLinkage:
Out << "GlobalValue::DLLExportLinkage"; break;
case GlobalValue::ExternalWeakLinkage:
Out << "GlobalValue::ExternalWeakLinkage"; break;
case GlobalValue::CommonLinkage:
@@ -325,6 +322,21 @@ void CppWriter::printVisibilityType(GlobalValue::VisibilityTypes VisType) {
}
}
void CppWriter::printDLLStorageClassType(
GlobalValue::DLLStorageClassTypes DSCType) {
switch (DSCType) {
case GlobalValue::DefaultStorageClass:
Out << "GlobalValue::DefaultStorageClass";
break;
case GlobalValue::DLLImportStorageClass:
Out << "GlobalValue::DLLImportStorageClass";
break;
case GlobalValue::DLLExportStorageClass:
Out << "GlobalValue::DLLExportStorageClass";
break;
}
}
void CppWriter::printThreadLocalMode(GlobalVariable::ThreadLocalMode TLM) {
switch (TLM) {
case GlobalVariable::NotThreadLocal:
@@ -1028,6 +1040,13 @@ void CppWriter::printVariableHead(const GlobalVariable *GV) {
Out << ");";
nl(Out);
}
if (GV->getDLLStorageClass() != GlobalValue::DefaultStorageClass) {
printCppName(GV);
Out << "->setDLLStorageClass(";
printDLLStorageClassType(GV->getDLLStorageClass());
Out << ");";
nl(Out);
}
if (GV->isThreadLocal()) {
printCppName(GV);
Out << "->setThreadLocalMode(";
@@ -1746,6 +1765,13 @@ void CppWriter::printFunctionHead(const Function* F) {
Out << ");";
nl(Out);
}
if (F->getDLLStorageClass() != GlobalValue::DefaultStorageClass) {
printCppName(F);
Out << "->setDLLStorageClass(";
printDLLStorageClassType(F->getDLLStorageClass());
Out << ");";
nl(Out);
}
if (F->hasGC()) {
printCppName(F);
Out << "->setGC(\"" << F->getGC() << "\");";