Allow unnamed_addr on declarations.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@123529 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Rafael Espindola 2011-01-15 08:15:00 +00:00
parent 6ccb5ef1b5
commit ba7c38c36a
10 changed files with 40 additions and 82 deletions

View File

@ -716,9 +716,6 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
return true;
}
if (!Init && UnnamedAddr)
return Error(UnnamedAddrLoc, "only definitions can have unnamed_addr");
if (Ty->isFunctionTy() || Ty->isLabelTy())
return Error(TyLoc, "invalid type for global variable");
@ -2687,9 +2684,6 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
ParseType(RetType, RetTypeLoc, true /*void allowed*/))
return true;
if (!isDefine && UnnamedAddr)
return Error(UnnamedAddrLoc, "only definitions can have unnamed_addr");
// Verify that the linkage is ok.
switch ((GlobalValue::LinkageTypes)Linkage) {
case GlobalValue::ExternalLinkage:

View File

@ -352,8 +352,6 @@ static void CopyGVAttributes(GlobalValue *DestGV, const GlobalValue *SrcGV) {
unsigned Alignment = std::max(DestGV->getAlignment(), SrcGV->getAlignment());
DestGV->copyAttributesFrom(SrcGV);
DestGV->setAlignment(Alignment);
if (SrcGV->hasUnnamedAddr())
DestGV->setUnnamedAddr(true);
}
/// GetLinkageResult - This analyzes the two global values and determines what
@ -521,6 +519,8 @@ static bool LinkGlobals(Module *Dest, const Module *Src,
continue;
}
bool HasUnnamedAddr = SGV->hasUnnamedAddr() && DGV->hasUnnamedAddr();
// If the visibilities of the symbols disagree and the destination is a
// prototype, take the visibility of its input.
if (DGV->isDeclaration())
@ -565,6 +565,9 @@ static bool LinkGlobals(Module *Dest, const Module *Src,
DGV->getName(), 0, false,
SGV->getType()->getAddressSpace());
// Set the unnamed_addr.
NewDGV->setUnnamedAddr(HasUnnamedAddr);
// Propagate alignment, section, and visibility info.
CopyGVAttributes(NewDGV, SGV);
DGV->replaceAllUsesWith(ConstantExpr::getBitCast(NewDGV,
@ -609,8 +612,9 @@ static bool LinkGlobals(Module *Dest, const Module *Src,
"': symbol multiple defined");
}
// Set calculated linkage
// Set calculated linkage and unnamed_addr
DGV->setLinkage(NewLinkage);
DGV->setUnnamedAddr(HasUnnamedAddr);
// Make sure to remember this mapping...
ValueMap[SGV] = ConstantExpr::getBitCast(DGV, SGV->getType());

View File

@ -469,8 +469,6 @@ void Verifier::visitGlobalVariable(GlobalVariable &GV) {
Assert1(GV.hasExternalLinkage() || GV.hasDLLImportLinkage() ||
GV.hasExternalWeakLinkage(),
"invalid linkage type for global declaration", &GV);
Assert1(!GV.hasUnnamedAddr(), "only definitions can have unnamed_addr",
&GV);
}
visitGlobalValue(GV);
@ -727,7 +725,6 @@ void Verifier::visitFunction(Function &F) {
Assert1(F.hasExternalLinkage() || F.hasDLLImportLinkage() ||
F.hasExternalWeakLinkage(),
"invalid linkage type for function declaration", &F);
Assert1(!F.hasUnnamedAddr(), "only definitions can have unnamed_addr", &F);
} else {
// Verify that this function (which has a body) is not named "llvm.*". It
// is not legal to define intrinsics.

View File

@ -1,8 +0,0 @@
; RUN: not llvm-as %s -o /dev/null 2>%t
; RUN: FileCheck -input-file=%t %s
declare unnamed_addr i32 @zed()
// CHECK: error: only definitions can have unnamed_addr
// CHECK: declare unnamed_addr i32 @zed()
// CHECK: ^

View File

@ -1,8 +0,0 @@
; RUN: not llvm-as %s -o /dev/null 2>%t
; RUN: FileCheck -input-file=%t %s
@foo = external unnamed_addr global i8*
// CHECK: error: only definitions can have unnamed_addr
// CHECK: @foo = external unnamed_addr global i8*
// CHECK: ^

View File

@ -1,11 +1,27 @@
; RUN: llvm-link %s %p/unnamed-addr1-b.ll -S -o - | FileCheck %s
; RUN: llvm-link %s %p/unnamed-addr1-b.ll -S -o - | sort | FileCheck %s
@foo = external global i32
; Only in this file
@a = common global i32 0
; CHECK: @a = common global i32 0
@b = common unnamed_addr global i32 0
; CHECK: @b = common unnamed_addr global i32 0
define i32 @bar() {
entry:
%tmp = load i32* @foo, align 4
ret i32 %tmp
}
; Other file has unnamed_addr definition
@c = common unnamed_addr global i32 0
; CHECK: @c = common unnamed_addr global i32 0
@d = external global i32
; CHECK: @d = global i32 42
@e = external unnamed_addr global i32
; CHECK: @e = unnamed_addr global i32 42
@f = weak global i32 42
; CHECK: @f = global i32 42
; CHECK: @foo = common unnamed_addr global i32 0, align 4
; Other file has non-unnamed_addr definition
@g = common unnamed_addr global i32 0
; CHECK: @g = common global i32 0
@h = external global i32
; CHECK: @h = global i32 42
@i = external unnamed_addr global i32
; CHECK: @i = global i32 42
@j = weak global i32 42
; CHECK: @j = global i32 42

View File

@ -1,4 +1,12 @@
; This file is for use with unnamed-addr1-a.ll
; RUN: true
@foo = common unnamed_addr global i32 0, align 4
@c = common unnamed_addr global i32 42
@d = unnamed_addr global i32 42
@e = unnamed_addr global i32 42
@f = unnamed_addr global i32 42
@g = common global i32 42
@h = global i32 42
@i = global i32 42
@j = global i32 42

View File

@ -1,11 +0,0 @@
; RUN: llvm-link %s %p/unnamed-addr2-b.ll -S -o - | FileCheck %s
define i32 @bar() {
entry:
%call = tail call i32 @foo()
ret i32 %call
}
declare i32 @foo()
; CHECK: define unnamed_addr i32 @foo()

View File

@ -1,7 +0,0 @@
; This file is for use with unnamed-addr2-a.ll
; RUN: true
define unnamed_addr i32 @foo() {
entry:
ret i32 42
}

View File

@ -60,32 +60,5 @@ TEST(VerifierTest, AliasUnnamedAddr) {
EXPECT_TRUE(verifyModule(M, ReturnStatusAction, &Error));
EXPECT_TRUE(StringRef(Error).startswith("Alias cannot have unnamed_addr"));
}
TEST(VerifierTest, ExternalUnnamedAddr) {
LLVMContext &C = getGlobalContext();
Module M("M", C);
const Type *Ty = Type::getInt8Ty(C);
GlobalVariable *GV = new GlobalVariable(M, Ty, true,
GlobalValue::ExternalLinkage,
NULL, "foo");
GV->setUnnamedAddr(true);
std::string Error;
EXPECT_TRUE(verifyModule(M, ReturnStatusAction, &Error));
EXPECT_TRUE(StringRef(Error)
.startswith("only definitions can have unnamed_addr"));
}
TEST(VerifierTest, DeclarationUnnamedAddr) {
LLVMContext &C = getGlobalContext();
Module M("M", C);
FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), /*isVarArg=*/false);
Function *F = Function::Create(FTy, GlobalValue::ExternalLinkage,
"foo", &M);
F->setUnnamedAddr(true);
std::string Error;
EXPECT_TRUE(verifyModule(M, ReturnStatusAction, &Error));
EXPECT_TRUE(StringRef(Error)
.startswith("only definitions can have unnamed_addr"));
}
}
}