|
@@ -0,0 +1,106 @@
|
|
|
+//===- FunctionTest.cpp - Function unit tests -----------------------------===//
|
|
|
+//
|
|
|
+// The LLVM Compiler Infrastructure
|
|
|
+//
|
|
|
+// This file is distributed under the University of Illinois Open Source
|
|
|
+// License. See LICENSE.TXT for details.
|
|
|
+//
|
|
|
+//===----------------------------------------------------------------------===//
|
|
|
+
|
|
|
+#include "llvm/IR/Function.h"
|
|
|
+#include "gtest/gtest.h"
|
|
|
+using namespace llvm;
|
|
|
+
|
|
|
+namespace {
|
|
|
+
|
|
|
+TEST(FunctionTest, hasLazyArguments) {
|
|
|
+ LLVMContext C;
|
|
|
+
|
|
|
+ Type *ArgTypes[] = {Type::getInt8Ty(C), Type::getInt32Ty(C)};
|
|
|
+ FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), ArgTypes, false);
|
|
|
+
|
|
|
+ // Functions start out with lazy arguments.
|
|
|
+ std::unique_ptr<Function> F(
|
|
|
+ Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
|
|
|
+ EXPECT_TRUE(F->hasLazyArguments());
|
|
|
+
|
|
|
+ // Checking for empty or size shouldn't force arguments to be instantiated.
|
|
|
+ EXPECT_FALSE(F->arg_empty());
|
|
|
+ EXPECT_TRUE(F->hasLazyArguments());
|
|
|
+ EXPECT_EQ(2u, F->arg_size());
|
|
|
+ EXPECT_TRUE(F->hasLazyArguments());
|
|
|
+
|
|
|
+ // The argument list should be populated at first access.
|
|
|
+ (void)F->arg_begin();
|
|
|
+ EXPECT_FALSE(F->hasLazyArguments());
|
|
|
+}
|
|
|
+
|
|
|
+TEST(FunctionTest, stealArgumentListFrom) {
|
|
|
+ LLVMContext C;
|
|
|
+
|
|
|
+ Type *ArgTypes[] = {Type::getInt8Ty(C), Type::getInt32Ty(C)};
|
|
|
+ FunctionType *FTy = FunctionType::get(Type::getVoidTy(C), ArgTypes, false);
|
|
|
+ std::unique_ptr<Function> F1(
|
|
|
+ Function::Create(FTy, GlobalValue::ExternalLinkage, "F1"));
|
|
|
+ std::unique_ptr<Function> F2(
|
|
|
+ Function::Create(FTy, GlobalValue::ExternalLinkage, "F1"));
|
|
|
+ EXPECT_TRUE(F1->hasLazyArguments());
|
|
|
+ EXPECT_TRUE(F2->hasLazyArguments());
|
|
|
+
|
|
|
+ // Steal arguments before they've been accessed. Nothing should change; both
|
|
|
+ // functions should still have lazy arguments.
|
|
|
+ //
|
|
|
+ // steal(empty); drop (empty)
|
|
|
+ F1->stealArgumentListFrom(*F2);
|
|
|
+ EXPECT_TRUE(F1->hasLazyArguments());
|
|
|
+ EXPECT_TRUE(F2->hasLazyArguments());
|
|
|
+
|
|
|
+ // Save arguments from F1 for later assertions. F1 won't have lazy arguments
|
|
|
+ // anymore.
|
|
|
+ SmallVector<Argument *, 4> Args;
|
|
|
+ for (Argument &A : F1->args())
|
|
|
+ Args.push_back(&A);
|
|
|
+ EXPECT_EQ(2u, Args.size());
|
|
|
+ EXPECT_FALSE(F1->hasLazyArguments());
|
|
|
+
|
|
|
+ // Steal arguments from F1 to F2. F1's arguments should be lazy again.
|
|
|
+ //
|
|
|
+ // steal(real); drop (empty)
|
|
|
+ F2->stealArgumentListFrom(*F1);
|
|
|
+ EXPECT_TRUE(F1->hasLazyArguments());
|
|
|
+ EXPECT_FALSE(F2->hasLazyArguments());
|
|
|
+ unsigned I = 0;
|
|
|
+ for (Argument &A : F2->args())
|
|
|
+ EXPECT_EQ(Args[I++], &A);
|
|
|
+ EXPECT_EQ(2u, I);
|
|
|
+
|
|
|
+ // Check that arguments in F1 don't have pointer equality with the saved ones.
|
|
|
+ // This also instantiates F1's arguments.
|
|
|
+ I = 0;
|
|
|
+ for (Argument &A : F1->args())
|
|
|
+ EXPECT_NE(Args[I++], &A);
|
|
|
+ EXPECT_EQ(2u, I);
|
|
|
+ EXPECT_FALSE(F1->hasLazyArguments());
|
|
|
+ EXPECT_FALSE(F2->hasLazyArguments());
|
|
|
+
|
|
|
+ // Steal back from F2. F2's arguments should be lazy again.
|
|
|
+ //
|
|
|
+ // steal(real); drop (real)
|
|
|
+ F1->stealArgumentListFrom(*F2);
|
|
|
+ EXPECT_FALSE(F1->hasLazyArguments());
|
|
|
+ EXPECT_TRUE(F2->hasLazyArguments());
|
|
|
+ I = 0;
|
|
|
+ for (Argument &A : F1->args())
|
|
|
+ EXPECT_EQ(Args[I++], &A);
|
|
|
+ EXPECT_EQ(2u, I);
|
|
|
+
|
|
|
+ // Steal from F2 a second time. Now both functions should have lazy
|
|
|
+ // arguments.
|
|
|
+ //
|
|
|
+ // steal(empty); drop (real)
|
|
|
+ F1->stealArgumentListFrom(*F2);
|
|
|
+ EXPECT_TRUE(F1->hasLazyArguments());
|
|
|
+ EXPECT_TRUE(F2->hasLazyArguments());
|
|
|
+}
|
|
|
+
|
|
|
+} // end namespace
|