mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Tweak the AST representation and type-checking of default arguments to preserve a full ConcreteDeclRef with substitutions to the owner of the default arguments. In SILGen, emit default argument generators with the same genericity as the original function. Swift SVN r18760
157 lines
5.1 KiB
C++
157 lines
5.1 KiB
C++
//===--- ConcreteDeclRef.h - Reference to a concrete decl -------*- 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 ConcreteDeclRef class, which provides a reference to
|
|
// a declaration that is potentially specialized.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef SWIFT_AST_CONCRETEDECLREF_H
|
|
#define SWIFT_AST_CONCRETEDECLREF_H
|
|
|
|
#include "swift/Basic/LLVM.h"
|
|
#include "swift/AST/Substitution.h"
|
|
#include "llvm/ADT/ArrayRef.h"
|
|
#include "llvm/ADT/PointerUnion.h"
|
|
#include "llvm/Support/Compiler.h"
|
|
#include <cstring>
|
|
|
|
namespace swift {
|
|
|
|
class ASTContext;
|
|
class SourceManager;
|
|
class ValueDecl;
|
|
|
|
/// A reference to a concrete representation of a particular declaration,
|
|
/// providing substitutions for all type parameters of the original,
|
|
/// underlying declaration.
|
|
class ConcreteDeclRef {
|
|
/// A specialized declaration reference, which provides substitutions
|
|
/// that fully specialize a generic declaration.
|
|
class SpecializedDeclRef {
|
|
/// The declaration.
|
|
ValueDecl *TheDecl;
|
|
|
|
/// The number of substitutions, which are tail allocated.
|
|
unsigned NumSubstitutions;
|
|
|
|
SpecializedDeclRef(ValueDecl *decl, ArrayRef<Substitution> substitutions)
|
|
: TheDecl(decl), NumSubstitutions(substitutions.size())
|
|
{
|
|
std::memcpy(reinterpret_cast<Substitution *>(this + 1),
|
|
substitutions.data(),
|
|
sizeof(Substitution) * substitutions.size());
|
|
}
|
|
|
|
public:
|
|
/// Retrieve the generic declaration.
|
|
ValueDecl *getDecl() const { return TheDecl; }
|
|
|
|
/// Retrieve the substitutions.
|
|
ArrayRef<Substitution> getSubstitutions() const {
|
|
return llvm::makeArrayRef(reinterpret_cast<const Substitution *>(this+1),
|
|
NumSubstitutions);
|
|
}
|
|
|
|
/// Allocate a new specialized declaration reference.
|
|
static SpecializedDeclRef *create(ASTContext &ctx, ValueDecl *decl,
|
|
ArrayRef<Substitution> substitutions);
|
|
};
|
|
|
|
llvm::PointerUnion<ValueDecl *, SpecializedDeclRef *> Data;
|
|
|
|
friend class llvm::PointerLikeTypeTraits<ConcreteDeclRef>;
|
|
|
|
public:
|
|
/// Create an empty declaration reference.
|
|
ConcreteDeclRef() : Data() { }
|
|
|
|
/// Construct a reference to the given value.
|
|
ConcreteDeclRef(ValueDecl *decl) : Data(decl) { }
|
|
|
|
/// Construct a reference to the given value, specialized with the given
|
|
/// substitutions.
|
|
///
|
|
/// \param ctx The ASTContext in which to allocate the specialized
|
|
/// declaration reference.
|
|
///
|
|
/// \param decl The declaration to which this reference refers, which will
|
|
/// be specialized by applying the given substitutions.
|
|
///
|
|
/// \param substitutions The complete set of substitutions to apply to the
|
|
/// given declaration. This array will be copied into the ASTContext by the
|
|
/// constructor.
|
|
ConcreteDeclRef(ASTContext &ctx, ValueDecl *decl,
|
|
ArrayRef<Substitution> substitutions)
|
|
: Data(SpecializedDeclRef::create(ctx, decl, substitutions)) { }
|
|
|
|
/// Determine whether this declaration reference refers to anything.
|
|
explicit operator bool() const { return !Data.isNull(); }
|
|
|
|
/// Retrieve the declarations to which this reference refers.
|
|
ValueDecl *getDecl() const {
|
|
if (Data.is<ValueDecl *>())
|
|
return Data.get<ValueDecl *>();
|
|
|
|
return Data.get<SpecializedDeclRef *>()->getDecl();
|
|
}
|
|
|
|
/// Determine whether this reference specializes the declaration to which
|
|
/// it refers.
|
|
bool isSpecialized() const { return Data.is<SpecializedDeclRef *>(); }
|
|
|
|
/// For a specialized reference, return the set of substitutions applied to
|
|
/// the declaration reference.
|
|
ArrayRef<Substitution> getSubstitutions() const {
|
|
if (!isSpecialized())
|
|
return { };
|
|
|
|
return Data.get<SpecializedDeclRef *>()->getSubstitutions();
|
|
}
|
|
|
|
bool operator==(ConcreteDeclRef rhs) const {
|
|
return Data == rhs.Data;
|
|
}
|
|
|
|
/// Dump a debug representation of this reference.
|
|
void dump(raw_ostream &os);
|
|
void dump() LLVM_ATTRIBUTE_USED;
|
|
};
|
|
|
|
} // end namespace swift
|
|
|
|
namespace llvm {
|
|
template<> class PointerLikeTypeTraits<swift::ConcreteDeclRef> {
|
|
typedef llvm::PointerUnion<swift::ValueDecl *,
|
|
swift::ConcreteDeclRef::SpecializedDeclRef *>
|
|
DataPointer;
|
|
typedef PointerLikeTypeTraits<DataPointer> DataTraits;
|
|
|
|
public:
|
|
static inline void *
|
|
getAsVoidPointer(swift::ConcreteDeclRef ref) {
|
|
return ref.Data.getOpaqueValue();
|
|
}
|
|
|
|
static inline swift::ConcreteDeclRef getFromVoidPointer(void *ptr) {
|
|
swift::ConcreteDeclRef ref;
|
|
ref.Data = DataPointer::getFromOpaqueValue(ptr);
|
|
return ref;
|
|
}
|
|
|
|
enum {
|
|
NumLowBitsAvailable = DataTraits::NumLowBitsAvailable
|
|
};
|
|
};
|
|
} // end namespace llvm
|
|
|
|
#endif
|