1 //===- FunctionTest.cpp - Function unit tests -----------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "llvm/IR/Function.h"
11 #include "llvm/IR/Module.h"
12 #include "gtest/gtest.h"
13 using namespace llvm;
14
15 namespace {
16
TEST(FunctionTest,hasLazyArguments)17 TEST(FunctionTest, hasLazyArguments) {
18 LLVMContext C;
19
20 Type *ArgTypes[] = {Type::getInt8Ty(C), Type::getInt32Ty(C)};
21 FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), ArgTypes, false);
22
23 // Functions start out with lazy arguments.
24 std::unique_ptr<Function> F(
25 Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
26 EXPECT_TRUE(F->hasLazyArguments());
27
28 // Checking for empty or size shouldn't force arguments to be instantiated.
29 EXPECT_FALSE(F->arg_empty());
30 EXPECT_TRUE(F->hasLazyArguments());
31 EXPECT_EQ(2u, F->arg_size());
32 EXPECT_TRUE(F->hasLazyArguments());
33
34 // The argument list should be populated at first access.
35 (void)F->arg_begin();
36 EXPECT_FALSE(F->hasLazyArguments());
37 }
38
TEST(FunctionTest,stealArgumentListFrom)39 TEST(FunctionTest, stealArgumentListFrom) {
40 LLVMContext C;
41
42 Type *ArgTypes[] = {Type::getInt8Ty(C), Type::getInt32Ty(C)};
43 FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), ArgTypes, false);
44 std::unique_ptr<Function> F1(
45 Function::Create(FTy, GlobalValue::ExternalLinkage, "F1"));
46 std::unique_ptr<Function> F2(
47 Function::Create(FTy, GlobalValue::ExternalLinkage, "F1"));
48 EXPECT_TRUE(F1->hasLazyArguments());
49 EXPECT_TRUE(F2->hasLazyArguments());
50
51 // Steal arguments before they've been accessed. Nothing should change; both
52 // functions should still have lazy arguments.
53 //
54 // steal(empty); drop (empty)
55 F1->stealArgumentListFrom(*F2);
56 EXPECT_TRUE(F1->hasLazyArguments());
57 EXPECT_TRUE(F2->hasLazyArguments());
58
59 // Save arguments from F1 for later assertions. F1 won't have lazy arguments
60 // anymore.
61 SmallVector<Argument *, 4> Args;
62 for (Argument &A : F1->args())
63 Args.push_back(&A);
64 EXPECT_EQ(2u, Args.size());
65 EXPECT_FALSE(F1->hasLazyArguments());
66
67 // Steal arguments from F1 to F2. F1's arguments should be lazy again.
68 //
69 // steal(real); drop (empty)
70 F2->stealArgumentListFrom(*F1);
71 EXPECT_TRUE(F1->hasLazyArguments());
72 EXPECT_FALSE(F2->hasLazyArguments());
73 unsigned I = 0;
74 for (Argument &A : F2->args()) {
75 EXPECT_EQ(Args[I], &A);
76 I++;
77 }
78 EXPECT_EQ(2u, I);
79
80 // Check that arguments in F1 don't have pointer equality with the saved ones.
81 // This also instantiates F1's arguments.
82 I = 0;
83 for (Argument &A : F1->args()) {
84 EXPECT_NE(Args[I], &A);
85 I++;
86 }
87 EXPECT_EQ(2u, I);
88 EXPECT_FALSE(F1->hasLazyArguments());
89 EXPECT_FALSE(F2->hasLazyArguments());
90
91 // Steal back from F2. F2's arguments should be lazy again.
92 //
93 // steal(real); drop (real)
94 F1->stealArgumentListFrom(*F2);
95 EXPECT_FALSE(F1->hasLazyArguments());
96 EXPECT_TRUE(F2->hasLazyArguments());
97 I = 0;
98 for (Argument &A : F1->args()) {
99 EXPECT_EQ(Args[I], &A);
100 I++;
101 }
102 EXPECT_EQ(2u, I);
103
104 // Steal from F2 a second time. Now both functions should have lazy
105 // arguments.
106 //
107 // steal(empty); drop (real)
108 F1->stealArgumentListFrom(*F2);
109 EXPECT_TRUE(F1->hasLazyArguments());
110 EXPECT_TRUE(F2->hasLazyArguments());
111 }
112
113 // Test setting and removing section information
TEST(FunctionTest,setSection)114 TEST(FunctionTest, setSection) {
115 LLVMContext C;
116 Module M("test", C);
117
118 llvm::Function *F =
119 Function::Create(llvm::FunctionType::get(llvm::Type::getVoidTy(C), false),
120 llvm::GlobalValue::ExternalLinkage, "F", &M);
121
122 F->setSection(".text.test");
123 EXPECT_TRUE(F->getSection() == ".text.test");
124 EXPECT_TRUE(F->hasSection());
125 F->setSection("");
126 EXPECT_FALSE(F->hasSection());
127 F->setSection(".text.test");
128 F->setSection(".text.test2");
129 EXPECT_TRUE(F->getSection() == ".text.test2");
130 EXPECT_TRUE(F->hasSection());
131 }
132
133 } // end namespace
134