summaryrefslogtreecommitdiff
path: root/lib/AsmParser
diff options
context:
space:
mode:
authorNico Rieck <nico.rieck@gmail.com>2014-01-14 11:55:03 +0000
committerNico Rieck <nico.rieck@gmail.com>2014-01-14 11:55:03 +0000
commitbce07a0c3bb907488e75bcabe0d7c6a8fb9c7132 (patch)
treee2d9d6de6bafcbf303219d701a015e3e78a0388a /lib/AsmParser
parent1b1321f0805d74481af18c1bdefd6ed7ef2b60e6 (diff)
downloadllvm-bce07a0c3bb907488e75bcabe0d7c6a8fb9c7132.tar.gz
llvm-bce07a0c3bb907488e75bcabe0d7c6a8fb9c7132.tar.bz2
llvm-bce07a0c3bb907488e75bcabe0d7c6a8fb9c7132.tar.xz
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@199204 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AsmParser')
-rw-r--r--lib/AsmParser/LLParser.cpp93
-rw-r--r--lib/AsmParser/LLParser.h7
2 files changed, 62 insertions, 38 deletions
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp
index a5b2aa586e..d4d6f7cee1 100644
--- a/lib/AsmParser/LLParser.cpp
+++ b/lib/AsmParser/LLParser.cpp
@@ -242,8 +242,8 @@ bool LLParser::ParseTopLevelEntities() {
// The Global variable production with no name can have many different
// optional leading prefixes, the production is:
- // GlobalVar ::= OptionalLinkage OptionalVisibility OptionalThreadLocal
- // OptionalAddrSpace OptionalUnNammedAddr
+ // GlobalVar ::= OptionalLinkage OptionalVisibility OptionalDLLStorageClass
+ // OptionalThreadLocal OptionalAddrSpace OptionalUnNammedAddr
// ('constant'|'global') ...
case lltok::kw_private: // OptionalLinkage
case lltok::kw_linker_private: // OptionalLinkage
@@ -254,24 +254,24 @@ bool LLParser::ParseTopLevelEntities() {
case lltok::kw_linkonce: // OptionalLinkage
case lltok::kw_linkonce_odr: // OptionalLinkage
case lltok::kw_appending: // OptionalLinkage
- case lltok::kw_dllexport: // OptionalLinkage
case lltok::kw_common: // OptionalLinkage
- case lltok::kw_dllimport: // OptionalLinkage
case lltok::kw_extern_weak: // OptionalLinkage
case lltok::kw_external: { // OptionalLinkage
- unsigned Linkage, Visibility;
+ unsigned Linkage, Visibility, DLLStorageClass;
if (ParseOptionalLinkage(Linkage) ||
ParseOptionalVisibility(Visibility) ||
- ParseGlobal("", SMLoc(), Linkage, true, Visibility))
+ ParseOptionalDLLStorageClass(DLLStorageClass) ||
+ ParseGlobal("", SMLoc(), Linkage, true, Visibility, DLLStorageClass))
return true;
break;
}
case lltok::kw_default: // OptionalVisibility
case lltok::kw_hidden: // OptionalVisibility
case lltok::kw_protected: { // OptionalVisibility
- unsigned Visibility;
+ unsigned Visibility, DLLStorageClass;
if (ParseOptionalVisibility(Visibility) ||
- ParseGlobal("", SMLoc(), 0, false, Visibility))
+ ParseOptionalDLLStorageClass(DLLStorageClass) ||
+ ParseGlobal("", SMLoc(), 0, false, Visibility, DLLStorageClass))
return true;
break;
}
@@ -280,7 +280,7 @@ bool LLParser::ParseTopLevelEntities() {
case lltok::kw_addrspace: // OptionalAddrSpace
case lltok::kw_constant: // GlobalType
case lltok::kw_global: // GlobalType
- if (ParseGlobal("", SMLoc(), 0, false, 0)) return true;
+ if (ParseGlobal("", SMLoc(), 0, false, 0, 0)) return true;
break;
case lltok::kw_attributes: if (ParseUnnamedAttrGrp()) return true; break;
@@ -446,9 +446,11 @@ bool LLParser::ParseGlobalType(bool &IsConstant) {
/// ParseUnnamedGlobal:
/// OptionalVisibility ALIAS ...
-/// OptionalLinkage OptionalVisibility ... -> global variable
+/// OptionalLinkage OptionalVisibility OptionalDLLStorageClass
+/// ... -> global variable
/// GlobalID '=' OptionalVisibility ALIAS ...
-/// GlobalID '=' OptionalLinkage OptionalVisibility ... -> global variable
+/// GlobalID '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass
+/// ... -> global variable
bool LLParser::ParseUnnamedGlobal() {
unsigned VarID = NumberedVals.size();
std::string Name;
@@ -466,19 +468,22 @@ bool LLParser::ParseUnnamedGlobal() {
}
bool HasLinkage;
- unsigned Linkage, Visibility;
+ unsigned Linkage, Visibility, DLLStorageClass;
if (ParseOptionalLinkage(Linkage, HasLinkage) ||
- ParseOptionalVisibility(Visibility))
+ ParseOptionalVisibility(Visibility) ||
+ ParseOptionalDLLStorageClass(DLLStorageClass))
return true;
if (HasLinkage || Lex.getKind() != lltok::kw_alias)
- return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility);
- return ParseAlias(Name, NameLoc, Visibility);
+ return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
+ DLLStorageClass);
+ return ParseAlias(Name, NameLoc, Visibility, DLLStorageClass);
}
/// ParseNamedGlobal:
/// GlobalVar '=' OptionalVisibility ALIAS ...
-/// GlobalVar '=' OptionalLinkage OptionalVisibility ... -> global variable
+/// GlobalVar '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass
+/// ... -> global variable
bool LLParser::ParseNamedGlobal() {
assert(Lex.getKind() == lltok::GlobalVar);
LocTy NameLoc = Lex.getLoc();
@@ -486,15 +491,17 @@ bool LLParser::ParseNamedGlobal() {
Lex.Lex();
bool HasLinkage;
- unsigned Linkage, Visibility;
+ unsigned Linkage, Visibility, DLLStorageClass;
if (ParseToken(lltok::equal, "expected '=' in global variable") ||
ParseOptionalLinkage(Linkage, HasLinkage) ||
- ParseOptionalVisibility(Visibility))
+ ParseOptionalVisibility(Visibility) ||
+ ParseOptionalDLLStorageClass(DLLStorageClass))
return true;
if (HasLinkage || Lex.getKind() != lltok::kw_alias)
- return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility);
- return ParseAlias(Name, NameLoc, Visibility);
+ return ParseGlobal(Name, NameLoc, Linkage, HasLinkage, Visibility,
+ DLLStorageClass);
+ return ParseAlias(Name, NameLoc, Visibility, DLLStorageClass);
}
// MDString:
@@ -615,16 +622,17 @@ bool LLParser::ParseStandaloneMetadata() {
}
/// ParseAlias:
-/// ::= GlobalVar '=' OptionalVisibility 'alias' OptionalLinkage Aliasee
+/// ::= GlobalVar '=' OptionalVisibility OptionalDLLStorageClass 'alias'
+/// OptionalLinkage Aliasee
/// Aliasee
/// ::= TypeAndValue
/// ::= 'bitcast' '(' TypeAndValue 'to' Type ')'
/// ::= 'getelementptr' 'inbounds'? '(' ... ')'
///
-/// Everything through visibility has already been parsed.
+/// Everything through DLL storage class has already been parsed.
///
bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc,
- unsigned Visibility) {
+ unsigned Visibility, unsigned DLLStorageClass) {
assert(Lex.getKind() == lltok::kw_alias);
Lex.Lex();
LocTy LinkageLoc = Lex.getLoc();
@@ -659,6 +667,7 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc,
(GlobalValue::LinkageTypes)Linkage, Name,
Aliasee);
GA->setVisibility((GlobalValue::VisibilityTypes)Visibility);
+ GA->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass);
// See if this value already exists in the symbol table. If so, it is either
// a redefinition or a definition of a forward reference.
@@ -691,18 +700,18 @@ bool LLParser::ParseAlias(const std::string &Name, LocTy NameLoc,
}
/// ParseGlobal
-/// ::= GlobalVar '=' OptionalLinkage OptionalVisibility OptionalThreadLocal
-/// OptionalAddrSpace OptionalUnNammedAddr
+/// ::= GlobalVar '=' OptionalLinkage OptionalVisibility OptionalDLLStorageClass
+/// OptionalThreadLocal OptionalAddrSpace OptionalUnNammedAddr
/// OptionalExternallyInitialized GlobalType Type Const
-/// ::= OptionalLinkage OptionalVisibility OptionalThreadLocal
-/// OptionalAddrSpace OptionalUnNammedAddr
+/// ::= OptionalLinkage OptionalVisibility OptionalDLLStorageClass
+/// OptionalThreadLocal OptionalAddrSpace OptionalUnNammedAddr
/// OptionalExternallyInitialized GlobalType Type Const
///
/// Everything through visibility has been parsed already.
///
bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
unsigned Linkage, bool HasLinkage,
- unsigned Visibility) {
+ unsigned Visibility, unsigned DLLStorageClass) {
unsigned AddrSpace;
bool IsConstant, UnnamedAddr, IsExternallyInitialized;
GlobalVariable::ThreadLocalMode TLM;
@@ -725,8 +734,7 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
// If the linkage is specified and is external, then no initializer is
// present.
Constant *Init = 0;
- if (!HasLinkage || (Linkage != GlobalValue::DLLImportLinkage &&
- Linkage != GlobalValue::ExternalWeakLinkage &&
+ if (!HasLinkage || (Linkage != GlobalValue::ExternalWeakLinkage &&
Linkage != GlobalValue::ExternalLinkage)) {
if (ParseGlobalValue(Ty, Init))
return true;
@@ -775,6 +783,7 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
GV->setConstant(IsConstant);
GV->setLinkage((GlobalValue::LinkageTypes)Linkage);
GV->setVisibility((GlobalValue::VisibilityTypes)Visibility);
+ GV->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass);
GV->setExternallyInitialized(IsExternallyInitialized);
GV->setThreadLocalMode(TLM);
GV->setUnnamedAddr(UnnamedAddr);
@@ -1277,9 +1286,7 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) {
/// ::= 'linkonce_odr'
/// ::= 'available_externally'
/// ::= 'appending'
-/// ::= 'dllexport'
/// ::= 'common'
-/// ::= 'dllimport'
/// ::= 'extern_weak'
/// ::= 'external'
bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage) {
@@ -1300,9 +1307,7 @@ bool LLParser::ParseOptionalLinkage(unsigned &Res, bool &HasLinkage) {
Res = GlobalValue::AvailableExternallyLinkage;
break;
case lltok::kw_appending: Res = GlobalValue::AppendingLinkage; break;
- case lltok::kw_dllexport: Res = GlobalValue::DLLExportLinkage; break;
case lltok::kw_common: Res = GlobalValue::CommonLinkage; break;
- case lltok::kw_dllimport: Res = GlobalValue::DLLImportLinkage; break;
case lltok::kw_extern_weak: Res = GlobalValue::ExternalWeakLinkage; break;
case lltok::kw_external: Res = GlobalValue::ExternalLinkage; break;
}
@@ -1328,6 +1333,21 @@ bool LLParser::ParseOptionalVisibility(unsigned &Res) {
return false;
}
+/// ParseOptionalDLLStorageClass
+/// ::= /*empty*/
+/// ::= 'dllimport'
+/// ::= 'dllexport'
+///
+bool LLParser::ParseOptionalDLLStorageClass(unsigned &Res) {
+ switch (Lex.getKind()) {
+ default: Res = GlobalValue::DefaultStorageClass; return false;
+ case lltok::kw_dllimport: Res = GlobalValue::DLLImportStorageClass; break;
+ case lltok::kw_dllexport: Res = GlobalValue::DLLExportStorageClass; break;
+ }
+ Lex.Lex();
+ return false;
+}
+
/// ParseOptionalCallingConv
/// ::= /*empty*/
/// ::= 'ccc'
@@ -2934,12 +2954,14 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
unsigned Linkage;
unsigned Visibility;
+ unsigned DLLStorageClass;
AttrBuilder RetAttrs;
CallingConv::ID CC;
Type *RetType = 0;
LocTy RetTypeLoc = Lex.getLoc();
if (ParseOptionalLinkage(Linkage) ||
ParseOptionalVisibility(Visibility) ||
+ ParseOptionalDLLStorageClass(DLLStorageClass) ||
ParseOptionalCallingConv(CC) ||
ParseOptionalReturnAttrs(RetAttrs) ||
ParseType(RetType, RetTypeLoc, true /*void allowed*/))
@@ -2949,7 +2971,6 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
switch ((GlobalValue::LinkageTypes)Linkage) {
case GlobalValue::ExternalLinkage:
break; // always ok.
- case GlobalValue::DLLImportLinkage:
case GlobalValue::ExternalWeakLinkage:
if (isDefine)
return Error(LinkageLoc, "invalid linkage for function definition");
@@ -2963,7 +2984,6 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
case GlobalValue::LinkOnceODRLinkage:
case GlobalValue::WeakAnyLinkage:
case GlobalValue::WeakODRLinkage:
- case GlobalValue::DLLExportLinkage:
if (!isDefine)
return Error(LinkageLoc, "invalid linkage for function declaration");
break;
@@ -3110,6 +3130,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
Fn->setLinkage((GlobalValue::LinkageTypes)Linkage);
Fn->setVisibility((GlobalValue::VisibilityTypes)Visibility);
+ Fn->setDLLStorageClass((GlobalValue::DLLStorageClassTypes)DLLStorageClass);
Fn->setCallingConv(CC);
Fn->setAttributes(PAL);
Fn->setUnnamedAddr(UnnamedAddr);
diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h
index ded776c398..c62979e6f2 100644
--- a/lib/AsmParser/LLParser.h
+++ b/lib/AsmParser/LLParser.h
@@ -204,6 +204,7 @@ namespace llvm {
bool HasLinkage; return ParseOptionalLinkage(Linkage, HasLinkage);
}
bool ParseOptionalVisibility(unsigned &Visibility);
+ bool ParseOptionalDLLStorageClass(unsigned &DLLStorageClass);
bool ParseOptionalCallingConv(CallingConv::ID &CC);
bool ParseOptionalAlignment(unsigned &Alignment);
bool ParseScopeAndOrdering(bool isAtomic, SynchronizationScope &Scope,
@@ -234,8 +235,10 @@ namespace llvm {
bool ParseUnnamedGlobal();
bool ParseNamedGlobal();
bool ParseGlobal(const std::string &Name, LocTy Loc, unsigned Linkage,
- bool HasLinkage, unsigned Visibility);
- bool ParseAlias(const std::string &Name, LocTy Loc, unsigned Visibility);
+ bool HasLinkage, unsigned Visibility,
+ unsigned DLLStorageClass);
+ bool ParseAlias(const std::string &Name, LocTy Loc, unsigned Visibility,
+ unsigned DLLStorageClass);
bool ParseStandaloneMetadata();
bool ParseNamedMetadata();
bool ParseMDString(MDString *&Result);