Skip to content

Change the backing base name type of DeclName to DeclBaseName #8019

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 11, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 79 additions & 28 deletions include/swift/AST/Identifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ namespace llvm {
class PointerLikeTypeTraits<swift::Identifier> {
public:
static inline void *getAsVoidPointer(swift::Identifier I) {
return (void*)I.get();
return const_cast<void *>(I.getAsOpaquePointer());
}
static inline swift::Identifier getFromVoidPointer(void *P) {
return swift::Identifier::getFromOpaquePointer(P);
Expand All @@ -203,7 +203,54 @@ namespace llvm {
} // end namespace llvm

namespace swift {


/// Wrapper that may either be an Identifier or a special name
/// (e.g. for subscripts)
class DeclBaseName {
Identifier Ident;

public:
DeclBaseName(Identifier I) : Ident(I) {}

bool isSpecial() const { return false; }

/// Return the identifier backing the name. Assumes that the name is not
/// special.
Identifier getIdentifier() const {
assert(!isSpecial() && "Cannot retrieve identifier from special names");
return Ident;
}

bool empty() const { return !isSpecial() && getIdentifier().empty(); }

const void *getAsOpaquePointer() const { return Ident.get(); }

static DeclBaseName getFromOpaquePointer(void *P) {
return Identifier::getFromOpaquePointer(P);
}
};

} // end namespace swift

namespace llvm {

// A DeclBaseName is "pointer like".
template <typename T> class PointerLikeTypeTraits;
template <> class PointerLikeTypeTraits<swift::DeclBaseName> {
public:
static inline void *getAsVoidPointer(swift::DeclBaseName D) {
return const_cast<void *>(D.getAsOpaquePointer());
}
static inline swift::DeclBaseName getFromVoidPointer(void *P) {
return swift::DeclBaseName::getFromOpaquePointer(P);
}
enum { NumLowBitsAvailable = PointerLikeTypeTraits<swift::Identifier>::NumLowBitsAvailable };
};

} // end namespace llvm

namespace swift {

/// A declaration name, which may comprise one or more identifier pieces.
class DeclName {
friend class ASTContext;
Expand All @@ -214,12 +261,11 @@ class DeclName {
friend TrailingObjects;
friend class DeclName;

Identifier BaseName;
DeclBaseName BaseName;
size_t NumArgs;

explicit CompoundDeclName(Identifier BaseName, size_t NumArgs)
: BaseName(BaseName), NumArgs(NumArgs)
{

explicit CompoundDeclName(DeclBaseName BaseName, size_t NumArgs)
: BaseName(BaseName), NumArgs(NumArgs) {
assert(NumArgs > 0 && "Should use IdentifierAndCompound");
}

Expand All @@ -231,56 +277,61 @@ class DeclName {
}

/// Uniquing for the ASTContext.
static void Profile(llvm::FoldingSetNodeID &id,
Identifier baseName,
static void Profile(llvm::FoldingSetNodeID &id, DeclBaseName baseName,
ArrayRef<Identifier> argumentNames);

void Profile(llvm::FoldingSetNodeID &id) {
Profile(id, BaseName, getArgumentNames());
}
};

// A single stored identifier, along with a bit stating whether it is the
// base name for a zero-argument compound name.
typedef llvm::PointerIntPair<Identifier, 1, bool> IdentifierAndCompound;
typedef llvm::PointerIntPair<DeclBaseName, 1, bool> BaseNameAndCompound;

// 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<IdentifierAndCompound, CompoundDeclName*> SimpleOrCompound;
llvm::PointerUnion<BaseNameAndCompound, CompoundDeclName *> SimpleOrCompound;

DeclName(void *Opaque)
: SimpleOrCompound(decltype(SimpleOrCompound)::getFromOpaqueValue(Opaque))
{}

void initialize(ASTContext &C, Identifier baseName,
void initialize(ASTContext &C, DeclBaseName baseName,
ArrayRef<Identifier> argumentNames);

public:
/// Build a null name.
DeclName() : SimpleOrCompound(IdentifierAndCompound()) {}
DeclName() : SimpleOrCompound(BaseNameAndCompound()) {}

/// Build a simple value name with one component.
/*implicit*/ DeclName(DeclBaseName simpleName)
: SimpleOrCompound(BaseNameAndCompound(simpleName, false)) {}

/*implicit*/ DeclName(Identifier simpleName)
: SimpleOrCompound(IdentifierAndCompound(simpleName, false)) {}
: DeclName(DeclBaseName(simpleName)) {}

/// Build a compound value name given a base name and a set of argument names.
DeclName(ASTContext &C, Identifier baseName,
DeclName(ASTContext &C, DeclBaseName baseName,
ArrayRef<Identifier> argumentNames) {
initialize(C, baseName, argumentNames);
}

/// Build a compound value name given a base name and a set of argument names
/// extracted from a parameter list.
DeclName(ASTContext &C, Identifier baseName, ParameterList *paramList);
DeclName(ASTContext &C, DeclBaseName baseName, ParameterList *paramList);

/// Retrieve the 'base' name, i.e., the name that follows the introducer,
/// such as the 'foo' in 'func foo(x:Int, y:Int)' or the 'bar' in
/// 'var bar: Int'.
// TODO: Return DeclBaseName (remove two calls to getIdentifier)
Identifier getBaseName() const {
if (auto compound = SimpleOrCompound.dyn_cast<CompoundDeclName*>())
return compound->BaseName;

return SimpleOrCompound.get<IdentifierAndCompound>().getPointer();
return compound->BaseName.getIdentifier();

return SimpleOrCompound.get<BaseNameAndCompound>()
.getPointer()
.getIdentifier();
}

/// Retrieve the names of the arguments, if there are any.
Expand All @@ -294,23 +345,23 @@ class DeclName {
explicit operator bool() const {
if (SimpleOrCompound.dyn_cast<CompoundDeclName*>())
return true;
return !SimpleOrCompound.get<IdentifierAndCompound>().getPointer().empty();
return !SimpleOrCompound.get<BaseNameAndCompound>().getPointer().empty();
}

/// True if this is a simple one-component name.
bool isSimpleName() const {
if (SimpleOrCompound.dyn_cast<CompoundDeclName*>())
return false;

return !SimpleOrCompound.get<IdentifierAndCompound>().getInt();
return !SimpleOrCompound.get<BaseNameAndCompound>().getInt();
}

/// True if this is a compound name.
bool isCompoundName() const {
if (SimpleOrCompound.dyn_cast<CompoundDeclName*>())
return true;

return SimpleOrCompound.get<IdentifierAndCompound>().getInt();
return SimpleOrCompound.get<BaseNameAndCompound>().getInt();
}

/// True if this name is a simple one-component name identical to the
Expand Down
10 changes: 5 additions & 5 deletions lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3527,18 +3527,18 @@ GenericEnvironment *GenericEnvironment::getIncomplete(
}

void DeclName::CompoundDeclName::Profile(llvm::FoldingSetNodeID &id,
Identifier baseName,
DeclBaseName baseName,
ArrayRef<Identifier> argumentNames) {
id.AddPointer(baseName.get());
id.AddPointer(baseName.getAsOpaquePointer());
id.AddInteger(argumentNames.size());
for (auto arg : argumentNames)
id.AddPointer(arg.get());
}

void DeclName::initialize(ASTContext &C, Identifier baseName,
void DeclName::initialize(ASTContext &C, DeclBaseName baseName,
ArrayRef<Identifier> argumentNames) {
if (argumentNames.size() == 0) {
SimpleOrCompound = IdentifierAndCompound(baseName, true);
SimpleOrCompound = BaseNameAndCompound(baseName, true);
return;
}

Expand All @@ -3564,7 +3564,7 @@ void DeclName::initialize(ASTContext &C, Identifier baseName,

/// Build a compound value name given a base name and a set of argument names
/// extracted from a parameter list.
DeclName::DeclName(ASTContext &C, Identifier baseName,
DeclName::DeclName(ASTContext &C, DeclBaseName baseName,
ParameterList *paramList) {
SmallVector<Identifier, 4> names;

Expand Down