Skip to content

Delete DeclValidationRAII #27777

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 3 commits into from
Oct 18, 2019
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
62 changes: 1 addition & 61 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,17 +282,10 @@ bool conflicting(ASTContext &ctx,

/// Decl - Base class for all declarations in Swift.
class alignas(1 << DeclAlignInBits) Decl {
public:
enum class ValidationState {
Unchecked,
Checking,
Checked,
};

protected:
union { uint64_t OpaqueBits;

SWIFT_INLINE_BITFIELD_BASE(Decl, bitmax(NumDeclKindBits,8)+1+1+1+1+2+1,
SWIFT_INLINE_BITFIELD_BASE(Decl, bitmax(NumDeclKindBits,8)+1+1+1+1+1,
Kind : bitmax(NumDeclKindBits,8),

/// Whether this declaration is invalid.
Expand All @@ -307,9 +300,6 @@ class alignas(1 << DeclAlignInBits) Decl {
/// Use getClangNode() to retrieve the corresponding Clang AST.
FromClang : 1,

/// The validation state of this declaration.
ValidationState : 2,

/// Whether this declaration was added to the surrounding
/// DeclContext of an active #if config clause.
EscapedFromIfConfig : 1
Expand Down Expand Up @@ -689,7 +679,6 @@ class alignas(1 << DeclAlignInBits) Decl {
Bits.Decl.Invalid = false;
Bits.Decl.Implicit = false;
Bits.Decl.FromClang = false;
Bits.Decl.ValidationState = unsigned(ValidationState::Unchecked);
Bits.Decl.EscapedFromIfConfig = false;
}

Expand Down Expand Up @@ -830,37 +819,7 @@ class alignas(1 << DeclAlignInBits) Decl {
/// Mark this declaration as implicit.
void setImplicit(bool implicit = true) { Bits.Decl.Implicit = implicit; }

/// Get the validation state.
ValidationState getValidationState() const {
return ValidationState(Bits.Decl.ValidationState);
}

private:
friend class DeclValidationRAII;

/// Set the validation state.
void setValidationState(ValidationState VS) {
assert(VS > getValidationState() && "Validation is unidirectional");
Bits.Decl.ValidationState = unsigned(VS);
}

public:
/// Whether the declaration is in the middle of validation or not.
bool isBeingValidated() const {
switch (getValidationState()) {
case ValidationState::Unchecked:
case ValidationState::Checked:
return false;
case ValidationState::Checking:
return true;
}
llvm_unreachable("Unknown ValidationState");
}

bool hasValidationStarted() const {
return getValidationState() > ValidationState::Unchecked;
}

bool escapedFromIfConfig() const {
return Bits.Decl.EscapedFromIfConfig;
}
Expand Down Expand Up @@ -982,25 +941,6 @@ class alignas(1 << DeclAlignInBits) Decl {
}
};

/// Use RAII to track Decl validation progress and non-reentrancy.
class DeclValidationRAII {
Decl *D;

public:
DeclValidationRAII(const DeclValidationRAII &) = delete;
DeclValidationRAII(DeclValidationRAII &&) = delete;
void operator =(const DeclValidationRAII &) = delete;
void operator =(DeclValidationRAII &&) = delete;

DeclValidationRAII(Decl *decl) : D(decl) {
D->setValidationState(Decl::ValidationState::Checking);
}

~DeclValidationRAII() {
D->setValidationState(Decl::ValidationState::Checked);
}
};

/// Allocates memory for a Decl with the given \p baseSize. If necessary,
/// it includes additional space immediately preceding the Decl for a ClangNode.
/// \note \p baseSize does not need to include space for a ClangNode if
Expand Down
4 changes: 4 additions & 0 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -883,6 +883,8 @@ NOTE(found_this_precedence_group,none,
ERROR(unknown_precedence_group,none,
"unknown precedence group %0", (Identifier))
ERROR(precedence_group_cycle,none,
"cycle in '%select{lowerThan|higherThan}0' relation", (bool))
ERROR(higher_than_precedence_group_cycle,none,
"cycle in higherThan relation: %0", (StringRef))
ERROR(precedence_group_lower_within_module,none,
"precedence group cannot be given lower precedence than group in same"
Expand All @@ -892,6 +894,8 @@ ERROR(precedence_group_redeclared,none,
"precedence group redeclared", ())
NOTE(previous_precedence_group_decl,none,
"previous precedence group declaration here", ())
NOTE(circular_reference_through_precedence_group, none,
"through reference to precedence group %0 here", (Identifier))

//------------------------------------------------------------------------------
// MARK: Expression Type Checking Errors
Expand Down
50 changes: 0 additions & 50 deletions include/swift/AST/NameLookupRequests.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,56 +278,6 @@ class GenericParamListRequest :
void cacheResult(GenericParamList *value) const;
};

struct PrecedenceGroupDescriptor {
DeclContext *dc;
Identifier ident;
SourceLoc nameLoc;

SourceLoc getLoc() const;

friend llvm::hash_code hash_value(const PrecedenceGroupDescriptor &owner) {
return hash_combine(llvm::hash_value(owner.dc),
llvm::hash_value(owner.ident.getAsOpaquePointer()),
llvm::hash_value(owner.nameLoc.getOpaquePointerValue()));
}

friend bool operator==(const PrecedenceGroupDescriptor &lhs,
const PrecedenceGroupDescriptor &rhs) {
return lhs.dc == rhs.dc &&
lhs.ident == rhs.ident &&
lhs.nameLoc == rhs.nameLoc;
}

friend bool operator!=(const PrecedenceGroupDescriptor &lhs,
const PrecedenceGroupDescriptor &rhs) {
return !(lhs == rhs);
}
};

void simple_display(llvm::raw_ostream &out, const PrecedenceGroupDescriptor &d);

class LookupPrecedenceGroupRequest
: public SimpleRequest<LookupPrecedenceGroupRequest,
PrecedenceGroupDecl *(PrecedenceGroupDescriptor),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;

private:
friend SimpleRequest;

// Evaluation.
llvm::Expected<PrecedenceGroupDecl *>
evaluate(Evaluator &evaluator, PrecedenceGroupDescriptor descriptor) const;

public:
// Source location
SourceLoc getNearestLoc() const;

// Separate caching.
bool isCached() const { return true; }
};

/// Expand the given ASTScope. Requestified to detect recursion.
class ExpandASTScopeRequest
: public SimpleRequest<ExpandASTScopeRequest,
Expand Down
3 changes: 0 additions & 3 deletions include/swift/AST/NameLookupTypeIDZone.def
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@ SWIFT_REQUEST(NameLookup, InheritedDeclsReferencedRequest,
DirectlyReferencedTypeDecls(
llvm::PointerUnion<TypeDecl *, ExtensionDecl *>, unsigned),
Uncached, HasNearestLocation)
SWIFT_REQUEST(NameLookup, LookupPrecedenceGroupRequest,
PrecedenceGroupDecl *(DeclContext *, Identifier, SourceLoc),
Cached, NoLocationInfo)
SWIFT_REQUEST(NameLookup, SelfBoundsFromWhereClauseRequest,
SelfBounds(llvm::PointerUnion<TypeDecl *, ExtensionDecl *>),
Uncached, NoLocationInfo)
Expand Down
60 changes: 60 additions & 0 deletions include/swift/AST/TypeCheckRequests.h
Original file line number Diff line number Diff line change
Expand Up @@ -1448,6 +1448,66 @@ class InterfaceTypeRequest :
void cacheResult(Type value) const;
};

struct PrecedenceGroupDescriptor {
enum PathDirection : bool {
LowerThan = false,
HigherThan = true,
};
DeclContext *dc;
Identifier ident;
SourceLoc nameLoc;
// Exists for diagnostics. Does not contribute to the descriptor otherwise.
Optional<PathDirection> pathDirection;

SourceLoc getLoc() const;

friend llvm::hash_code hash_value(const PrecedenceGroupDescriptor &owner) {
return llvm::hash_combine(owner.dc,
owner.ident.getAsOpaquePointer(),
owner.nameLoc.getOpaquePointerValue());
}

friend bool operator==(const PrecedenceGroupDescriptor &lhs,
const PrecedenceGroupDescriptor &rhs) {
return lhs.dc == rhs.dc &&
lhs.ident == rhs.ident &&
lhs.nameLoc == rhs.nameLoc;
}

friend bool operator!=(const PrecedenceGroupDescriptor &lhs,
const PrecedenceGroupDescriptor &rhs) {
return !(lhs == rhs);
}
};

void simple_display(llvm::raw_ostream &out, const PrecedenceGroupDescriptor &d);

class LookupPrecedenceGroupRequest
: public SimpleRequest<LookupPrecedenceGroupRequest,
PrecedenceGroupDecl *(PrecedenceGroupDescriptor),
CacheKind::Cached> {
public:
using SimpleRequest::SimpleRequest;

private:
friend SimpleRequest;

// Evaluation.
llvm::Expected<PrecedenceGroupDecl *>
evaluate(Evaluator &evaluator, PrecedenceGroupDescriptor descriptor) const;

public:
// Cycle handling.
void diagnoseCycle(DiagnosticEngine &diags) const;
void noteCycleStep(DiagnosticEngine &diags) const;

// Source location
SourceLoc getNearestLoc() const;

// Separate caching.
bool isCached() const { return true; }
};

// Allow AnyValue to compare two Type values, even though Type doesn't
// support ==.
template<>
Expand Down
3 changes: 3 additions & 0 deletions include/swift/AST/TypeCheckerTypeIDZone.def
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ SWIFT_REQUEST(TypeChecker, IsSetterMutatingRequest, bool(AbstractStorageDecl *),
SeparatelyCached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, LazyStoragePropertyRequest, VarDecl *(VarDecl *),
Cached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, LookupPrecedenceGroupRequest,
PrecedenceGroupDecl *(DeclContext *, Identifier, SourceLoc),
Cached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, MangleLocalTypeDeclRequest,
std::string(const TypeDecl *), Cached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, NamingPatternRequest,
Expand Down
22 changes: 6 additions & 16 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2783,8 +2783,13 @@ bool ValueDecl::hasInterfaceType() const {
return !TypeAndAccess.getPointer().isNull();
}

static bool isComputingInterfaceType(const ValueDecl *VD) {
return VD->getASTContext().evaluator.hasActiveRequest(
InterfaceTypeRequest{const_cast<ValueDecl *>(VD)});
}

bool ValueDecl::isRecursiveValidation() const {
if (hasValidationStarted() && !hasInterfaceType())
if (isComputingInterfaceType(this) && !hasInterfaceType())
return true;

if (auto *vd = dyn_cast<VarDecl>(this))
Expand Down Expand Up @@ -7404,21 +7409,6 @@ PrecedenceGroupDecl::PrecedenceGroupDecl(DeclContext *dc,
lowerThan.size() * sizeof(Relation));
}

llvm::Expected<PrecedenceGroupDecl *> LookupPrecedenceGroupRequest::evaluate(
Evaluator &eval, PrecedenceGroupDescriptor descriptor) const {
auto *dc = descriptor.dc;
PrecedenceGroupDecl *group = nullptr;
if (auto sf = dc->getParentSourceFile()) {
bool cascading = dc->isCascadingContextForLookup(false);
group = sf->lookupPrecedenceGroup(descriptor.ident, cascading,
descriptor.nameLoc);
} else {
group = dc->getParentModule()->lookupPrecedenceGroup(descriptor.ident,
descriptor.nameLoc);
}
return group;
}

PrecedenceGroupDecl *InfixOperatorDecl::getPrecedenceGroup() const {
return evaluateOrDefault(
getASTContext().evaluator,
Expand Down
20 changes: 0 additions & 20 deletions lib/AST/NameLookupRequests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,26 +128,6 @@ void GenericParamListRequest::cacheResult(GenericParamList *params) const {
context->GenericParamsAndBit.setPointerAndInt(params, true);
}


//----------------------------------------------------------------------------//
// LookupPrecedenceGroupRequest computation.
//----------------------------------------------------------------------------//

SourceLoc LookupPrecedenceGroupRequest::getNearestLoc() const {
auto &desc = std::get<0>(getStorage());
return desc.getLoc();
}

SourceLoc PrecedenceGroupDescriptor::getLoc() const {
return nameLoc;
}

void swift::simple_display(llvm::raw_ostream &out,
const PrecedenceGroupDescriptor &desc) {
out << "precedence group " << desc.ident << " at ";
desc.nameLoc.print(out, desc.dc->getASTContext().SourceMgr);
}

// Define request evaluation functions for each of the name lookup requests.
static AbstractRequestFunction *nameLookupRequestFunctions[] = {
#define SWIFT_REQUEST(Zone, Name, Sig, Caching, LocOptions) \
Expand Down
34 changes: 34 additions & 0 deletions lib/AST/TypeCheckRequests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1026,3 +1026,37 @@ void InterfaceTypeRequest::cacheResult(Type type) const {
}
decl->TypeAndAccess.setPointer(type);
}

//----------------------------------------------------------------------------//
// LookupPrecedenceGroupRequest computation.
//----------------------------------------------------------------------------//

SourceLoc LookupPrecedenceGroupRequest::getNearestLoc() const {
auto &desc = std::get<0>(getStorage());
return desc.getLoc();
}

void LookupPrecedenceGroupRequest::diagnoseCycle(DiagnosticEngine &diags) const {
auto &desc = std::get<0>(getStorage());
if (auto pathDir = desc.pathDirection) {
diags.diagnose(desc.nameLoc, diag::precedence_group_cycle, (bool)*pathDir);
} else {
diags.diagnose(desc.nameLoc, diag::circular_reference);
}
}

void LookupPrecedenceGroupRequest::noteCycleStep(DiagnosticEngine &diag) const {
auto &desc = std::get<0>(getStorage());
diag.diagnose(desc.nameLoc,
diag::circular_reference_through_precedence_group, desc.ident);
}

SourceLoc PrecedenceGroupDescriptor::getLoc() const {
return nameLoc;
}

void swift::simple_display(llvm::raw_ostream &out,
const PrecedenceGroupDescriptor &desc) {
out << "precedence group " << desc.ident << " at ";
desc.nameLoc.print(out, desc.dc->getASTContext().SourceMgr);
}
Loading