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
173 lines
5.3 KiB
C++
173 lines
5.3 KiB
C++
//===--- SILGlobalVariable.h - Defines SILGlobalVariable class --*- C++ -*-===//
|
|
//
|
|
// 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 defines the SILGlobalVariable class.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef SWIFT_SIL_SILGLOBALVARIABLE_H
|
|
#define SWIFT_SIL_SILGLOBALVARIABLE_H
|
|
|
|
#include <string>
|
|
#include "swift/SIL/SILLinkage.h"
|
|
#include "swift/SIL/SILLocation.h"
|
|
#include "swift/SIL/SILType.h"
|
|
#include "llvm/ADT/ilist_node.h"
|
|
#include "llvm/ADT/ilist.h"
|
|
|
|
namespace swift {
|
|
|
|
class ASTContext;
|
|
class SILModule;
|
|
|
|
/// A global variable that has been referenced in SIL.
|
|
class SILGlobalVariable
|
|
: public llvm::ilist_node<SILGlobalVariable>,
|
|
public SILAllocated<SILGlobalVariable>
|
|
{
|
|
private:
|
|
friend class SILBasicBlock;
|
|
friend class SILModule;
|
|
|
|
/// The SIL module that the global variable belongs to.
|
|
SILModule &Module;
|
|
|
|
/// The mangled name of the variable, which will be propagated to the
|
|
/// binary. A pointer into the module's lookup table.
|
|
StringRef Name;
|
|
|
|
/// The lowered type of the variable.
|
|
SILType LoweredType;
|
|
|
|
/// The SIL location of the variable, which provides a link back to the AST.
|
|
/// The variable only gets a location after it's been emitted.
|
|
Optional<SILLocation> Location;
|
|
|
|
/// The linkage of the global variable.
|
|
unsigned Linkage : NumSILLinkageBits;
|
|
|
|
SILGlobalVariable(SILModule &M, SILLinkage linkage,
|
|
StringRef mangledName, SILType loweredType,
|
|
Optional<SILLocation> loc);
|
|
|
|
public:
|
|
static SILGlobalVariable *create(SILModule &Module, SILLinkage Linkage,
|
|
StringRef MangledName, SILType LoweredType,
|
|
Optional<SILLocation> Loc = Nothing);
|
|
|
|
~SILGlobalVariable();
|
|
|
|
SILModule &getModule() const { return Module; }
|
|
|
|
SILType getLoweredType() const { return LoweredType; }
|
|
CanSILFunctionType getLoweredFunctionType() const {
|
|
return LoweredType.castTo<SILFunctionType>();
|
|
}
|
|
|
|
StringRef getName() const { return Name; }
|
|
|
|
/// True if this is a declaration of a variable defined in another module.
|
|
bool isExternalDeclaration() const {
|
|
return isAvailableExternally(getLinkage());
|
|
}
|
|
|
|
/// True if this is a definition of the variable.
|
|
bool isDefinition() const { return !isExternalDeclaration(); }
|
|
|
|
/// Get this function's linkage attribute.
|
|
SILLinkage getLinkage() const { return SILLinkage(Linkage); }
|
|
void setLinkage(SILLinkage linkage) { Linkage = unsigned(linkage); }
|
|
|
|
/// Initialize the source location of the function.
|
|
void setLocation(SILLocation L) { Location = L; }
|
|
|
|
/// Check if the function has a location.
|
|
/// FIXME: All functions should have locations, so this method should not be
|
|
/// necessary.
|
|
bool hasLocation() const {
|
|
return Location.hasValue();
|
|
}
|
|
|
|
/// Get the source location of the function.
|
|
SILLocation getLocation() const {
|
|
assert(Location.hasValue());
|
|
return Location.getValue();
|
|
}
|
|
|
|
//===--------------------------------------------------------------------===//
|
|
// Miscellaneous
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
/// verify - Run the IR verifier to make sure that the variable follows
|
|
/// invariants.
|
|
void verify() const;
|
|
|
|
/// Pretty-print the variable.
|
|
void dump(bool Verbose) const;
|
|
void dump() const { dump(false); }
|
|
|
|
/// Pretty-print the variable to the designated stream as a 'sil_global'
|
|
/// definition.
|
|
///
|
|
/// \param Verbose In verbose mode, print the SIL locations.
|
|
void print(raw_ostream &OS, bool Verbose = false) const;
|
|
|
|
/// Pretty-print the variable name using SIL syntax,
|
|
/// '@var_mangled_name'.
|
|
void printName(raw_ostream &OS) const;
|
|
|
|
ASTContext &getASTContext() const;
|
|
};
|
|
|
|
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
|
|
const SILGlobalVariable &F) {
|
|
F.print(OS);
|
|
return OS;
|
|
}
|
|
|
|
} // end swift namespace
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// ilist_traits for SILGLobalVariable
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
namespace llvm {
|
|
|
|
template <>
|
|
struct ilist_traits<::swift::SILGlobalVariable> :
|
|
public ilist_default_traits<::swift::SILGlobalVariable> {
|
|
typedef ::swift::SILGlobalVariable SILGlobalVariable;
|
|
|
|
private:
|
|
mutable ilist_half_node<SILGlobalVariable> Sentinel;
|
|
|
|
public:
|
|
SILGlobalVariable *createSentinel() const {
|
|
return static_cast<SILGlobalVariable*>(&Sentinel);
|
|
}
|
|
void destroySentinel(SILGlobalVariable *) const {}
|
|
|
|
SILGlobalVariable *provideInitialHead() const { return createSentinel(); }
|
|
SILGlobalVariable *ensureHead(SILGlobalVariable*) const {
|
|
return createSentinel();
|
|
}
|
|
static void noteHead(SILGlobalVariable*, SILGlobalVariable*) {}
|
|
static void deleteNode(SILGlobalVariable *V) {}
|
|
|
|
private:
|
|
void createNode(const SILGlobalVariable &);
|
|
};
|
|
|
|
} // end llvm namespace
|
|
|
|
#endif
|