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"
12using namespace llvm;
13
14namespace {
15
16TEST(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
38TEST(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