diff --git a/include/swift/AST/CaptureInfo.h b/include/swift/AST/CaptureInfo.h index d60af9c679861..8e52cd0dfb47f 100644 --- a/include/swift/AST/CaptureInfo.h +++ b/include/swift/AST/CaptureInfo.h @@ -18,8 +18,13 @@ #include "llvm/ADT/PointerIntPair.h" #include +namespace swift { +class CapturedValue; +} + namespace llvm { class raw_ostream; +template <> struct DenseMapInfo; } namespace swift { @@ -30,7 +35,12 @@ class FuncDecl; /// that indicate how it is captured. class CapturedValue { llvm::PointerIntPair Value; + + explicit CapturedValue(llvm::PointerIntPair V) : Value(V) {} + public: + friend struct llvm::DenseMapInfo; + enum { /// IsDirect is set when a VarDecl with storage *and* accessors is captured /// by its storage address. This happens in the accessors for the VarDecl. @@ -64,7 +74,36 @@ class CapturedValue { } }; +} // end swift namespace +namespace llvm { + +template <> struct DenseMapInfo { + using CapturedValue = swift::CapturedValue; + + using PtrIntPairDenseMapInfo = + DenseMapInfo>; + + static inline swift::CapturedValue getEmptyKey() { + return CapturedValue{PtrIntPairDenseMapInfo::getEmptyKey()}; + } + + static inline CapturedValue getTombstoneKey() { + return CapturedValue{PtrIntPairDenseMapInfo::getTombstoneKey()}; + } + + static unsigned getHashValue(const CapturedValue &Val) { + return PtrIntPairDenseMapInfo::getHashValue(Val.Value); + } + + static bool isEqual(const CapturedValue &LHS, const CapturedValue &RHS) { + return PtrIntPairDenseMapInfo::isEqual(LHS.Value, RHS.Value); + } +}; + +} // end llvm namespace + +namespace swift { /// \brief Stores information about captured variables. class CaptureInfo { diff --git a/include/swift/AST/ModuleLoader.h b/include/swift/AST/ModuleLoader.h index ae3e62490c95f..3eb675d6b57a8 100644 --- a/include/swift/AST/ModuleLoader.h +++ b/include/swift/AST/ModuleLoader.h @@ -34,7 +34,8 @@ enum class KnownProtocolKind : uint8_t; /// Records dependencies on files outside of the current module. class DependencyTracker { - llvm::SetVector> paths; + llvm::SetVector, + llvm::SmallSet> paths; public: /// Adds a file as a dependency. diff --git a/lib/AST/LookupVisibleDecls.cpp b/lib/AST/LookupVisibleDecls.cpp index a85177bf080af..3f8b4906a7acc 100644 --- a/lib/AST/LookupVisibleDecls.cpp +++ b/lib/AST/LookupVisibleDecls.cpp @@ -519,6 +519,7 @@ static void lookupVisibleMemberDeclsImpl( } namespace { + struct FoundDeclTy { ValueDecl *D; DeclVisibilityKind Reason; @@ -535,6 +536,33 @@ struct FoundDeclTy { } }; +} // end anonymous namespace + +namespace llvm { + +template <> struct DenseMapInfo { + static inline FoundDeclTy getEmptyKey() { + return FoundDeclTy{nullptr, DeclVisibilityKind::LocalVariable}; + } + + static inline FoundDeclTy getTombstoneKey() { + return FoundDeclTy{reinterpret_cast(0x1), + DeclVisibilityKind::LocalVariable}; + } + + static unsigned getHashValue(const FoundDeclTy &Val) { + return llvm::hash_combine(unsigned(Val.Reason), Val.D); + } + + static bool isEqual(const FoundDeclTy &LHS, const FoundDeclTy &RHS) { + return LHS == RHS; + } +}; + +} // end llvm namespace + +namespace { + /// Similar to swift::conflicting, but lenient about protocol extensions which /// don't affect code completion's concept of overloading. static bool relaxedConflicting(const OverloadSignature &sig1, diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index c8dbc0e1b6a76..f04d91433cdfe 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -296,6 +296,9 @@ getNormalInvocationArguments(std::vector &invocationArgStrs, // Enable modules. "-fmodules", + // Enable implicit module maps + "-fimplicit-module-maps", + // Don't emit LLVM IR. "-fsyntax-only", @@ -512,6 +515,10 @@ ClangImporter::create(ASTContext &ctx, std::vector invocationArgStrs; + // Clang expects this to be like an actual command line. So we need to pass in + // "clang" for argv[0] + invocationArgStrs.push_back("clang"); + switch (importerOpts.Mode) { case ClangImporterOptions::Modes::Normal: getNormalInvocationArguments(invocationArgStrs, ctx, importerOpts); diff --git a/lib/IRGen/GenClangDecl.cpp b/lib/IRGen/GenClangDecl.cpp index ecb6eaf0e16a5..2f930f7a60e81 100644 --- a/lib/IRGen/GenClangDecl.cpp +++ b/lib/IRGen/GenClangDecl.cpp @@ -13,7 +13,7 @@ #include "IRGenModule.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclGroup.h" -#include "clang/AST/DataRecursiveASTVisitor.h" +#include "clang/AST/RecursiveASTVisitor.h" #include "clang/CodeGen/ModuleBuilder.h" #include "llvm/ADT/SmallPtrSet.h" @@ -22,7 +22,7 @@ using namespace irgen; namespace { class ClangDeclRefFinder - : public clang::DataRecursiveASTVisitor { + : public clang::RecursiveASTVisitor { std::function callback; public: template diff --git a/lib/IRGen/IRGenSIL.cpp b/lib/IRGen/IRGenSIL.cpp index abb358fdc884d..aafca5fedcca7 100644 --- a/lib/IRGen/IRGenSIL.cpp +++ b/lib/IRGen/IRGenSIL.cpp @@ -1306,13 +1306,13 @@ void IRGenSILFunction::emitSILFunction() { // Map the entry bb. LoweredBBs[&*CurSILFn->begin()] = LoweredBB(&*CurFn->begin(), {}); // Create LLVM basic blocks for the other bbs. - for (SILBasicBlock *bb = CurSILFn->begin()->getNextNode(); - bb != CurSILFn->end(); bb = bb->getNextNode()) { + for (auto bi = std::next(CurSILFn->begin()), be = CurSILFn->end(); bi != be; + ++bi) { // FIXME: Use the SIL basic block's name. llvm::BasicBlock *llBB = llvm::BasicBlock::Create(IGM.getLLVMContext()); - auto phis = emitPHINodesForBBArgs(*this, bb, llBB); + auto phis = emitPHINodesForBBArgs(*this, &*bi, llBB); CurFn->getBasicBlockList().push_back(llBB); - LoweredBBs[bb] = LoweredBB(llBB, std::move(phis)); + LoweredBBs[&*bi] = LoweredBB(llBB, std::move(phis)); } auto entry = LoweredBBs.begin(); @@ -3311,18 +3311,21 @@ static bool tryDeferFixedSizeBufferInitialization(IRGenSILFunction &IGF, // if the alloc_stack is dominated by copy_addrs into it on all paths. // For now, check only that the copy_addr is the first use within the same // block. - const SILInstruction *inst = allocInst; - while ((inst = inst->getNextNode()) && !isa(inst)) { - // Does this instruction use the allocation? - for (auto &operand : inst->getAllOperands()) - if (operand.get() == addressValue) - goto is_use; - - continue; - - is_use: + for (auto ii = std::next(allocInst->getIterator()), + ie = std::prev(allocInst->getParent()->end()); + ii != ie; ++ii) { + auto *inst = &*ii; + + // Does this instruction use the allocation? If not, continue. + auto Ops = inst->getAllOperands(); + if (std::none_of(Ops.begin(), Ops.end(), + [&addressValue](const Operand &Op) { + return Op.get() == addressValue; + })) + continue; + // Is this a copy? - auto copy = dyn_cast(inst); + auto *copy = dyn_cast(inst); if (!copy) return false; diff --git a/lib/SIL/Dominance.cpp b/lib/SIL/Dominance.cpp index 907b928f0dc6d..e33af6b10188e 100644 --- a/lib/SIL/Dominance.cpp +++ b/lib/SIL/Dominance.cpp @@ -40,10 +40,13 @@ bool DominanceInfo::properlyDominates(SILInstruction *a, SILInstruction *b) { // Otherwise, they're in the same block, and we just need to check // whether B comes after A. This is a non-strict computation. - SILInstruction *f = &*aBlock->begin(); - while (b != f) { - b = b->getPrevNode(); - if (a == b) return true; + auto aIter = a->getIterator(); + auto bIter = b->getIterator(); + auto fIter = aBlock->begin(); + while (bIter != fIter) { + --bIter; + if (aIter == bIter) + return true; } return false; diff --git a/lib/SILGen/SILGenStmt.cpp b/lib/SILGen/SILGenStmt.cpp index bfbb04575a3a3..0d196e4a14544 100644 --- a/lib/SILGen/SILGenStmt.cpp +++ b/lib/SILGen/SILGenStmt.cpp @@ -53,7 +53,8 @@ SILBasicBlock *SILGenFunction::createBasicBlock(FunctionSection section) { // The end of the ordinary section is just the end of the function // unless postmatter blocks exist. SILBasicBlock *afterBB = - (StartOfPostmatter ? StartOfPostmatter->getPrevNode() : nullptr); + (StartOfPostmatter ? &*std::prev(StartOfPostmatter->getIterator()) + : nullptr); return new (F.getModule()) SILBasicBlock(&F, afterBB); } @@ -73,7 +74,7 @@ void SILGenFunction::eraseBasicBlock(SILBasicBlock *block) { assert(block->pred_empty() && "erasing block with predecessors"); assert(block->empty() && "erasing block with content"); if (block == StartOfPostmatter) { - StartOfPostmatter = block->getNextNode(); + StartOfPostmatter = &*std::next(block->getIterator()); } block->eraseFromParent(); } diff --git a/lib/SILPasses/EarlySIL/DefiniteInitialization.cpp b/lib/SILPasses/EarlySIL/DefiniteInitialization.cpp index d67143af19118..c18bbf29d6856 100644 --- a/lib/SILPasses/EarlySIL/DefiniteInitialization.cpp +++ b/lib/SILPasses/EarlySIL/DefiniteInitialization.cpp @@ -1825,7 +1825,7 @@ SILValue LifetimeChecker::handleConditionalInitAssign() { } // Before the memory allocation, store zero in the control variable. - B.setInsertionPoint(TheMemory.MemoryInst->getNextNode()); + B.setInsertionPoint(&*std::next(TheMemory.MemoryInst->getIterator())); SILValue ControlVariableAddr = SILValue(ControlVariableBox, 1); auto Zero = B.createIntegerLiteral(Loc, IVType, 0); B.createStore(Loc, Zero, ControlVariableAddr); diff --git a/lib/SILPasses/IPO/CapturePromotion.cpp b/lib/SILPasses/IPO/CapturePromotion.cpp index a3bb0741375fb..54cd7f79658f4 100644 --- a/lib/SILPasses/IPO/CapturePromotion.cpp +++ b/lib/SILPasses/IPO/CapturePromotion.cpp @@ -778,10 +778,12 @@ examineAllocBoxInst(AllocBoxInst *ABI, ReachabilityInfo &RI, // Helper lambda function to determine if instruction b is strictly after // instruction a, assuming both are in the same basic block. auto isAfter = [](SILInstruction *a, SILInstruction *b) { - SILInstruction *f = &*b->getParent()->begin(); - while (b != f) { - b = b->getPrevNode(); - if (a == b) + auto fIter = b->getParent()->begin(); + auto bIter = b->getIterator(); + auto aIter = a->getIterator(); + while (bIter != fIter) { + --bIter; + if (aIter == bIter) return true; } return false; diff --git a/lib/SILPasses/Scalar/DeadStoreElimination.cpp b/lib/SILPasses/Scalar/DeadStoreElimination.cpp index a363ad4a21a5c..d38f6bf702d70 100644 --- a/lib/SILPasses/Scalar/DeadStoreElimination.cpp +++ b/lib/SILPasses/Scalar/DeadStoreElimination.cpp @@ -881,7 +881,7 @@ void DSEContext::run() { for (SILBasicBlock &BB : *F) { // Create the stores that are alive. for (auto &I : getBBLocState(&BB)->LiveStores) { - SILInstruction *IT = cast(I.first)->getNextNode(); + auto *IT = &*std::next(cast(I.first)->getIterator()); SILBuilderWithScope Builder(IT); Builder.createStore(I.first.getLoc().getValue(), I.second, I.first); } diff --git a/lib/SILPasses/Scalar/SimplifyCFG.cpp b/lib/SILPasses/Scalar/SimplifyCFG.cpp index a24c278f723fa..62964d0a9aff6 100644 --- a/lib/SILPasses/Scalar/SimplifyCFG.cpp +++ b/lib/SILPasses/Scalar/SimplifyCFG.cpp @@ -3013,7 +3013,7 @@ bool simplifySwitchEnumToSelectEnum(SILBasicBlock *BB, unsigned ArgNum, // Do not replace the bbarg SmallVector Args; Args.push_back(SelectInst); - B.setInsertionPoint(SelectInst->getNextNode()); + B.setInsertionPoint(&*std::next(SelectInst->getIterator())); B.createBranch(SEI->getLoc(), BB, Args); // Remove switch_enum instruction SEI->getParent()->getTerminator()->eraseFromParent();