mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
In general, this forces SILGen and IRGen code that's grabbing a declaration to state whether it's doing so to define it. Change SIL serialization to serialize the linkage of functions and global variables, which means also serializing declarations. Change the deserializer to use this stored linkage, even when only deserializing a declaration, and to call a callback to inform the client that it has deserialized a new entity. Take advantage of that callback in the linking pass to alter the deserialized linkage as appropriate for the fact that we imported the declaration. This computation should really take advantage of the relationship between modules, but currently it does not. Swift SVN r12090
121 lines
3.8 KiB
C++
121 lines
3.8 KiB
C++
//===--- GenInit.cpp - IR Generation for Initialization -------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See http://swift.org/LICENSE.txt for license information
|
|
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file implements IR generation for the initialization of
|
|
// local and global variables.
|
|
//
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "swift/Basic/Optional.h"
|
|
#include "swift/AST/Pattern.h"
|
|
#include "swift/SIL/SILGlobalVariable.h"
|
|
#include "llvm/IR/GlobalVariable.h"
|
|
|
|
#include "ASTVisitor.h"
|
|
#include "Explosion.h"
|
|
#include "GenHeap.h"
|
|
#include "GenTuple.h"
|
|
#include "IRGenFunction.h"
|
|
#include "IRGenModule.h"
|
|
#include "FixedTypeInfo.h"
|
|
|
|
using namespace swift;
|
|
using namespace irgen;
|
|
|
|
/// Emit a global variable.
|
|
Address IRGenModule::emitSILGlobalVariable(SILGlobalVariable *var) {
|
|
auto &type = getTypeInfo(var->getLoweredType());
|
|
|
|
// If the variable is empty, don't actually emit it; just return undef.
|
|
if (type.isKnownEmpty()) {
|
|
return type.getUndefAddress();
|
|
}
|
|
|
|
/// Get the global variable.
|
|
Address addr = getAddrOfSILGlobalVariable(var, ForDefinition);
|
|
|
|
/// Add a zero initializer.
|
|
auto gvar = cast<llvm::GlobalVariable>(addr.getAddress());
|
|
gvar->setInitializer(llvm::Constant::getNullValue(type.getStorageType()));
|
|
|
|
return addr;
|
|
}
|
|
|
|
/// Emit a global variable.
|
|
///
|
|
/// FIXME: Combine into emitSILGlobalVariable.
|
|
Address IRGenModule::emitGlobalVariable(VarDecl *var,
|
|
const TypeInfo &type) {
|
|
// If the variable is empty, don't actually emit it; just return undef.
|
|
// FIXME: global destructors?
|
|
if (type.isKnownEmpty()) {
|
|
return type.getUndefAddress();
|
|
}
|
|
|
|
/// Get the global variable.
|
|
Address addr = getAddrOfGlobalVariable(var, ForDefinition);
|
|
|
|
// Add a zero-initializer.
|
|
llvm::GlobalVariable *gvar = cast<llvm::GlobalVariable>(addr.getAddress());
|
|
gvar->setInitializer(llvm::Constant::getNullValue(type.getStorageType()));
|
|
|
|
return addr;
|
|
}
|
|
|
|
ContainedAddress FixedTypeInfo::allocateStack(IRGenFunction &IGF,
|
|
const Twine &name) const {
|
|
// If the type is known to be empty, don't actually allocate anything.
|
|
if (isKnownEmpty()) {
|
|
auto addr = getUndefAddress();
|
|
return { addr, addr };
|
|
}
|
|
|
|
Address alloca =
|
|
IGF.createAlloca(getStorageType(), getFixedAlignment(), name);
|
|
// TODO: lifetime intrinsics?
|
|
|
|
return { alloca, alloca };
|
|
}
|
|
|
|
void FixedTypeInfo::deallocateStack(IRGenFunction &IGF, Address addr) const {
|
|
// TODO: lifetime intrinsics?
|
|
}
|
|
|
|
/// Allocate an object with fixed layout.
|
|
OwnedAddress FixedTypeInfo::allocateBox(IRGenFunction &IGF,
|
|
const Twine &name) const {
|
|
// If the type is known to be empty, don't actually allocate anything.
|
|
if (isKnownEmpty())
|
|
return OwnedAddress(getUndefAddress(), IGF.IGM.RefCountedNull);
|
|
|
|
// Lay out the type as a heap object.
|
|
HeapLayout layout(IGF.IGM, LayoutStrategy::Optimal, this);
|
|
assert(!layout.isKnownEmpty() && "non-empty type had empty layout?");
|
|
auto &elt = layout.getElements()[0];
|
|
|
|
// Allocate a new object.
|
|
// TODO: lifetime intrinsics?
|
|
llvm::Value *allocation = IGF.emitUnmanagedAlloc(layout, name + ".alloc");
|
|
|
|
// FIXME: provide non-fixed offsets
|
|
NonFixedOffsets offsets = Nothing;
|
|
|
|
// Cast and GEP down to the element.
|
|
Address rawAddr = layout.emitCastTo(IGF, allocation);
|
|
rawAddr = elt.project(IGF, rawAddr, offsets, name);
|
|
|
|
OwnedAddress addr(rawAddr, allocation);
|
|
return addr;
|
|
}
|
|
|