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 "gtest/gtest.h"
12 using namespace llvm;
13
14 namespace {
15
TEST(FunctionTest,hasLazyArguments)16 TEST(FunctionTest, hasLazyArguments) {
17 LLVMContext C;
18
19 Type *ArgTypes[] = {Type::getInt8Ty(C), Type::getInt32Ty(C)};
20 FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), ArgTypes, false);
21
22 // Functions start out with lazy arguments.
23 std::unique_ptr<Function> F(
24 Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
25 EXPECT_TRUE(F->hasLazyArguments());
26
27 // Checking for empty or size shouldn't force arguments to be instantiated.
28 EXPECT_FALSE(F->arg_empty());
29 EXPECT_TRUE(F->hasLazyArguments());
30 EXPECT_EQ(2u, F->arg_size());
31 EXPECT_TRUE(F->hasLazyArguments());
32
33 // The argument list should be populated at first access.
34 (void)F->arg_begin();
35 EXPECT_FALSE(F->hasLazyArguments());
36 }
37
TEST(FunctionTest,stealArgumentListFrom)38 TEST(FunctionTest, stealArgumentListFrom) {
39 LLVMContext C;
40
41 Type *ArgTypes[] = {Type::getInt8Ty(C), Type::getInt32Ty(C)};
42 FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), ArgTypes, false);
43 std::unique_ptr<Function> F1(
44 Function::Create(FTy, GlobalValue::ExternalLinkage, "F1"));
45 std::unique_ptr<Function> F2(
46 Function::Create(FTy, GlobalValue::ExternalLinkage, "F1"));
47 EXPECT_TRUE(F1->hasLazyArguments());
48 EXPECT_TRUE(F2->hasLazyArguments());
49
50 // Steal arguments before they've been accessed. Nothing should change; both
51 // functions should still have lazy arguments.
52 //
53 // steal(empty); drop (empty)
54 F1->stealArgumentListFrom(*F2);
55 EXPECT_TRUE(F1->hasLazyArguments());
56 EXPECT_TRUE(F2->hasLazyArguments());
57
58 // Save arguments from F1 for later assertions. F1 won't have lazy arguments
59 // anymore.
60 SmallVector<Argument *, 4> Args;
61 for (Argument &A : F1->args())
62 Args.push_back(&A);
63 EXPECT_EQ(2u, Args.size());
64 EXPECT_FALSE(F1->hasLazyArguments());
65
66 // Steal arguments from F1 to F2. F1's arguments should be lazy again.
67 //
68 // steal(real); drop (empty)
69 F2->stealArgumentListFrom(*F1);
70 EXPECT_TRUE(F1->hasLazyArguments());
71 EXPECT_FALSE(F2->hasLazyArguments());
72 unsigned I = 0;
73 for (Argument &A : F2->args()) {
74 EXPECT_EQ(Args[I], &A);
75 I++;
76 }
77 EXPECT_EQ(2u, I);
78
79 // Check that arguments in F1 don't have pointer equality with the saved ones.
80 // This also instantiates F1's arguments.
81 I = 0;
82 for (Argument &A : F1->args()) {
83 EXPECT_NE(Args[I], &A);
84 I++;
85 }
86 EXPECT_EQ(2u, I);
87 EXPECT_FALSE(F1->hasLazyArguments());
88 EXPECT_FALSE(F2->hasLazyArguments());
89
90 // Steal back from F2. F2's arguments should be lazy again.
91 //
92 // steal(real); drop (real)
93 F1->stealArgumentListFrom(*F2);
94 EXPECT_FALSE(F1->hasLazyArguments());
95 EXPECT_TRUE(F2->hasLazyArguments());
96 I = 0;
97 for (Argument &A : F1->args()) {
98 EXPECT_EQ(Args[I], &A);
99 I++;
100 }
101 EXPECT_EQ(2u, I);
102
103 // Steal from F2 a second time. Now both functions should have lazy
104 // arguments.
105 //
106 // steal(empty); drop (real)
107 F1->stealArgumentListFrom(*F2);
108 EXPECT_TRUE(F1->hasLazyArguments());
109 EXPECT_TRUE(F2->hasLazyArguments());
110 }
111
112 } // end namespace
113