Distinguish betweeen simple names ("foo") and zero-argument compound names ("foo()").

This isn't actually used yet, but it's an important distinction.

Swift SVN r16326
This commit is contained in:
Doug Gregor
2014-04-14 20:05:34 +00:00
parent 75e5ae9e9b
commit 18bf604360
7 changed files with 44 additions and 24 deletions

View File

@@ -189,13 +189,17 @@ namespace swift {
/// A declaration name, which may comprise one or more identifier pieces. /// A declaration name, which may comprise one or more identifier pieces.
class DeclName { class DeclName {
friend class ASTContext; friend class ASTContext;
/// Represents a compound
struct alignas(Identifier*) CompoundDeclName : llvm::FoldingSetNode { struct alignas(Identifier*) CompoundDeclName : llvm::FoldingSetNode {
Identifier BaseName; Identifier BaseName;
size_t NumArgs; size_t NumArgs;
explicit CompoundDeclName(Identifier BaseName, size_t NumArgs) explicit CompoundDeclName(Identifier BaseName, size_t NumArgs)
: BaseName(BaseName), NumArgs(NumArgs) {} : BaseName(BaseName), NumArgs(NumArgs)
{
assert(NumArgs > 0 && "Should use NullaryName or Identifier");
}
ArrayRef<Identifier> getArgumentNames() const { ArrayRef<Identifier> getArgumentNames() const {
return {reinterpret_cast<const Identifier*>(this + 1), NumArgs}; return {reinterpret_cast<const Identifier*>(this + 1), NumArgs};
@@ -213,10 +217,14 @@ class DeclName {
Profile(id, BaseName, getArgumentNames()); Profile(id, BaseName, getArgumentNames());
} }
}; };
// Either a single identifier piece stored inline, or a reference to a // A single stored identifier, along with a bit stating whether it is is the
// compound declaration name. // base name for a zero-argument (nullary) compound name.
llvm::PointerUnion<Identifier, CompoundDeclName*> SimpleOrCompound; typedef llvm::PointerIntPair<Identifier, 1, bool> IdentifierAndNullary;
// Either a single identifier piece stored inline (with a bit to say whether
// it is simple or compound), or a reference to a compound declaration name.
llvm::PointerUnion<IdentifierAndNullary, CompoundDeclName*> SimpleOrCompound;
DeclName(void *Opaque) DeclName(void *Opaque)
: SimpleOrCompound(decltype(SimpleOrCompound)::getFromOpaqueValue(Opaque)) : SimpleOrCompound(decltype(SimpleOrCompound)::getFromOpaqueValue(Opaque))
@@ -224,14 +232,14 @@ class DeclName {
public: public:
/// Build a null name. /// Build a null name.
DeclName() : SimpleOrCompound(Identifier()) {} DeclName() : SimpleOrCompound(IdentifierAndNullary()) {}
/// Build a simple value name with one component. /// Build a simple value name with one component.
/*implicit*/ DeclName(Identifier simpleName) /*implicit*/ DeclName(Identifier simpleName)
: SimpleOrCompound(simpleName) {} : SimpleOrCompound(IdentifierAndNullary(simpleName, false)) {}
/// Build a compound value name given a base name and a set of argument names. /// Build a compound value name given a base name and a set of argument names.
DeclName(ASTContext &C, Identifier baseName, [[deprecated]] DeclName(ASTContext &C, Identifier baseName,
ArrayRef<Identifier> argumentNames); ArrayRef<Identifier> argumentNames);
/// Retrive the 'base' name, i.e., the name that follows the introducer, /// Retrive the 'base' name, i.e., the name that follows the introducer,
@@ -241,7 +249,7 @@ public:
if (auto compound = SimpleOrCompound.dyn_cast<CompoundDeclName*>()) if (auto compound = SimpleOrCompound.dyn_cast<CompoundDeclName*>())
return compound->BaseName; return compound->BaseName;
return SimpleOrCompound.get<Identifier>(); return SimpleOrCompound.get<IdentifierAndNullary>().getPointer();
} }
/// Retrieve the names of the arguments, if there are any. /// Retrieve the names of the arguments, if there are any.
@@ -255,12 +263,15 @@ public:
explicit operator bool() const { explicit operator bool() const {
if (SimpleOrCompound.dyn_cast<CompoundDeclName*>()) if (SimpleOrCompound.dyn_cast<CompoundDeclName*>())
return true; return true;
return SimpleOrCompound.get<Identifier>().get(); return !SimpleOrCompound.get<IdentifierAndNullary>().getPointer().empty();
} }
/// True if this is a simple one-component name. /// True if this is a simple one-component name.
bool isSimpleName() const { bool isSimpleName() const {
return !SimpleOrCompound.dyn_cast<CompoundDeclName*>(); if (SimpleOrCompound.dyn_cast<CompoundDeclName*>())
return false;
return !SimpleOrCompound.get<IdentifierAndNullary>().getInt();
} }
/// True if this name is a simple one-component name identical to the /// True if this name is a simple one-component name identical to the
@@ -313,7 +324,7 @@ public:
LLVM_ATTRIBUTE_DEPRECATED(void dump(), LLVM_ATTRIBUTE_DEPRECATED(void dump(),
"only for use within the debugger"); "only for use within the debugger");
}; };
} // end namespace swift } // end namespace swift
namespace llvm { namespace llvm {

View File

@@ -40,7 +40,7 @@ const uint16_t VERSION_MAJOR = 0;
/// Serialized module format minor version number. /// Serialized module format minor version number.
/// ///
/// When the format changes IN ANY WAY, this number should be incremented. /// When the format changes IN ANY WAY, this number should be incremented.
const uint16_t VERSION_MINOR = 55; const uint16_t VERSION_MINOR = 56;
using DeclID = Fixnum<31>; using DeclID = Fixnum<31>;
using DeclIDField = BCFixed<31>; using DeclIDField = BCFixed<31>;
@@ -701,6 +701,7 @@ namespace decls_block {
DeclIDField, // operator decl DeclIDField, // operator decl
DeclIDField, // overridden function DeclIDField, // overridden function
DeclIDField, // AccessorStorageDecl DeclIDField, // AccessorStorageDecl
BCFixed<1>, // name is compound?
BCArray<IdentifierIDField> // name components BCArray<IdentifierIDField> // name components
// The record is trailed by: // The record is trailed by:
// - its asmname, if any // - its asmname, if any

View File

@@ -2160,7 +2160,7 @@ void DeclName::CompoundDeclName::Profile(llvm::FoldingSetNodeID &id,
DeclName::DeclName(ASTContext &C, Identifier baseName, DeclName::DeclName(ASTContext &C, Identifier baseName,
ArrayRef<Identifier> argumentNames) { ArrayRef<Identifier> argumentNames) {
if (argumentNames.size() == 0) { if (argumentNames.size() == 0) {
SimpleOrCompound = baseName; SimpleOrCompound = IdentifierAndNullary(baseName, true);
return; return;
} }

View File

@@ -638,7 +638,7 @@ static DeclName mapSelectorName(ASTContext &ctx,
// Simple case. // Simple case.
if (!isInitializer || name.size() == 4) if (!isInitializer || name.size() == 4)
return ctx.getIdentifier(name); return DeclName(ctx, ctx.getIdentifier(name), { });
// This is an initializer with no parameters but a name that // This is an initializer with no parameters but a name that
// contains more than 'init', so synthesize an argument to capture // contains more than 'init', so synthesize an argument to capture

View File

@@ -743,11 +743,14 @@ Parser::parseFunctionSignature(Identifier SimpleName,
if (Tok.is(tok::l_paren)) { if (Tok.is(tok::l_paren)) {
Status = parseFunctionArguments(NamePieces, argPatterns, bodyPatterns, Status = parseFunctionArguments(NamePieces, argPatterns, bodyPatterns,
defaultArgs, HasSelectorStyleSignature); defaultArgs, HasSelectorStyleSignature);
// FIXME: Tying compound names to selector-style signatures is bogus.
FullName = DeclName(Context, NamePieces[0], if (HasSelectorStyleSignature)
llvm::makeArrayRef(NamePieces.begin() + 1, FullName = DeclName(Context, NamePieces[0],
NamePieces.end())); llvm::makeArrayRef(NamePieces.begin() + 1,
NamePieces.end()));
else
FullName = DeclName(NamePieces[0]);
if (bodyPatterns.empty()) { if (bodyPatterns.empty()) {
// If we didn't get anything, add a () pattern to avoid breaking // If we didn't get anything, add a () pattern to avoid breaking
// invariants. // invariants.

View File

@@ -1825,6 +1825,7 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
DeclID associatedDeclID; DeclID associatedDeclID;
DeclID overriddenID; DeclID overriddenID;
DeclID accessorStorageDeclID; DeclID accessorStorageDeclID;
bool hasCompoundName;
ArrayRef<uint64_t> nameIDs; ArrayRef<uint64_t> nameIDs;
decls_block::FuncLayout::readRecord(scratch, contextID, isImplicit, decls_block::FuncLayout::readRecord(scratch, contextID, isImplicit,
@@ -1836,7 +1837,7 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
numParamPatterns, signatureID, numParamPatterns, signatureID,
interfaceTypeID, associatedDeclID, interfaceTypeID, associatedDeclID,
overriddenID, accessorStorageDeclID, overriddenID, accessorStorageDeclID,
nameIDs); hasCompoundName, nameIDs);
// Resolve the name ids. // Resolve the name ids.
SmallVector<Identifier, 2> names; SmallVector<Identifier, 2> names;
@@ -1863,8 +1864,11 @@ Decl *ModuleFile::getDecl(DeclID DID, Optional<DeclContext *> ForcedContext) {
DeclName name; DeclName name;
if (!names.empty()) { if (!names.empty()) {
name = DeclName(ctx, names[0], if (hasCompoundName)
llvm::makeArrayRef(names.begin() + 1, names.end())); name = DeclName(ctx, names[0],
llvm::makeArrayRef(names.begin() + 1, names.end()));
else
name = DeclName(names[0]);
} }
auto fn = FuncDecl::createDeserialized( auto fn = FuncDecl::createDeserialized(
ctx, SourceLoc(), StaticSpelling.getValue(), SourceLoc(), name, ctx, SourceLoc(), StaticSpelling.getValue(), SourceLoc(), name,

View File

@@ -1700,6 +1700,7 @@ void Serializer::writeDecl(const Decl *D) {
addDeclRef(fn->getOperatorDecl()), addDeclRef(fn->getOperatorDecl()),
addDeclRef(fn->getOverriddenDecl()), addDeclRef(fn->getOverriddenDecl()),
addDeclRef(fn->getAccessorStorageDecl()), addDeclRef(fn->getAccessorStorageDecl()),
!fn->getFullName().isSimpleName(),
nameComponents); nameComponents);
writeGenericParams(fn->getGenericParams(), DeclTypeAbbrCodes); writeGenericParams(fn->getGenericParams(), DeclTypeAbbrCodes);