Files
swift-mirror/lib/SIL/SILFunction.cpp
John McCall 5da6defa1f Clean up the linkage model and the computation of linkage.
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
2014-01-09 08:58:07 +00:00

104 lines
3.7 KiB
C++

//===--- SILFunction.cpp - Defines the SILFunction data structure ---------===//
//
// 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
//
//===----------------------------------------------------------------------===//
#include "swift/SIL/SILFunction.h"
#include "swift/SIL/SILModule.h"
// FIXME: For mapTypeInContext
#include "swift/AST/ArchetypeBuilder.h"
using namespace swift;
SILFunction *SILFunction::create(SILModule &M, SILLinkage linkage,
StringRef name,
CanSILFunctionType loweredType,
Optional<SILLocation> loc,
IsBare_t isBareSILFunction,
IsTransparent_t isTrans,
SILFunction *insertBefore,
SILDebugScope *debugScope,
DeclContext *DC) {
// Get a StringMapEntry for the function. As a sop to error cases,
// allow the name to have an empty string.
llvm::StringMapEntry<SILFunction*> *entry = nullptr;
if (!name.empty()) {
entry = &M.FunctionTable.GetOrCreateValue(name);
assert(!entry->getValue() && "function already exists");
name = entry->getKey();
}
auto fn = new (M) SILFunction(M, linkage, name, loweredType, loc,
isBareSILFunction, isTrans, insertBefore,
debugScope, DC);
if (entry) entry->setValue(fn);
return fn;
}
SILFunction::SILFunction(SILModule &Module, SILLinkage Linkage,
StringRef Name, CanSILFunctionType LoweredType,
Optional<SILLocation> Loc,
IsBare_t isBareSILFunction,
IsTransparent_t isTrans,
SILFunction *InsertBefore,
SILDebugScope *DebugScope,
DeclContext *DC)
: Module(Module),
Name(Name),
LoweredType(LoweredType),
// FIXME: Context params should be independent of the function type.
ContextGenericParams(LoweredType->getGenericParams()),
Location(Loc),
DeclCtx(DC),
DebugScope(DebugScope),
Bare(isBareSILFunction),
Transparent(isTrans),
Linkage(unsigned(Linkage)) {
if (InsertBefore)
Module.functions.insert(SILModule::iterator(InsertBefore), this);
else
Module.functions.push_back(this);
}
SILFunction::~SILFunction() {
assert(RefCount == 0 &&
"Function cannot be deleted while function_ref's still exist");
getModule().FunctionTable.erase(Name);
}
void SILFunction::setDeclContext(Decl *D) {
if (!D)
return;
switch (D->getKind()) {
// These four dual-inherit from DeclContext.
case DeclKind::Func: DeclCtx = cast<FuncDecl>(D); break;
case DeclKind::Constructor: DeclCtx = cast<ConstructorDecl>(D); break;
case DeclKind::Extension: DeclCtx = cast<ExtensionDecl>(D); break;
case DeclKind::Destructor: DeclCtx = cast<DestructorDecl>(D); break;
default:
DeclCtx = D->getDeclContext();
}
assert(DeclCtx);
}
void SILFunction::setDeclContext(Expr *E) {
DeclCtx = dyn_cast_or_null<AbstractClosureExpr>(E);
}
ASTContext &SILFunction::getASTContext() const {
return getModule().getASTContext();
}
Type SILFunction::mapTypeIntoContext(Type type) const {
return ArchetypeBuilder::mapTypeIntoContext(getContextGenericParams(),
type);
}