本文整理汇总了C++中SmallVector::pop_back方法的典型用法代码示例。如果您正苦于以下问题:C++ SmallVector::pop_back方法的具体用法?C++ SmallVector::pop_back怎么用?C++ SmallVector::pop_back使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类SmallVector
的用法示例。
在下文中一共展示了SmallVector::pop_back方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: while
AbstractFunctionDecl *SILDeclRef::getOverriddenWitnessTableEntry(
AbstractFunctionDecl *func) {
if (!isa<ProtocolDecl>(func->getDeclContext()))
return func;
AbstractFunctionDecl *bestOverridden = nullptr;
SmallVector<AbstractFunctionDecl *, 4> stack;
SmallPtrSet<AbstractFunctionDecl *, 4> visited;
stack.push_back(func);
visited.insert(func);
while (!stack.empty()) {
auto current = stack.back();
stack.pop_back();
auto overriddenDecls = current->getOverriddenDecls();
if (overriddenDecls.empty()) {
// This entry introduced a witness table entry. Determine whether it is
// better than the best entry we've seen thus far.
if (!bestOverridden ||
ProtocolDecl::compare(
cast<ProtocolDecl>(current->getDeclContext()),
cast<ProtocolDecl>(bestOverridden->getDeclContext()))
< 0) {
bestOverridden = cast<AbstractFunctionDecl>(current);
}
continue;
}
// Add overridden declarations to the stack.
for (auto overridden : overriddenDecls) {
auto overriddenFunc = cast<AbstractFunctionDecl>(overridden);
if (visited.insert(overriddenFunc).second)
stack.push_back(overriddenFunc);
}
}
return bestOverridden;
}
示例2: forallBases
bool CXXRecordDecl::forallBases(ForallBasesCallback *BaseMatches,
void *OpaqueData,
bool AllowShortCircuit) const {
SmallVector<const CXXRecordDecl*, 8> Queue;
const CXXRecordDecl *Record = this;
bool AllMatches = true;
while (true) {
for (CXXRecordDecl::base_class_const_iterator
I = Record->bases_begin(), E = Record->bases_end(); I != E; ++I) {
const RecordType *Ty = I->getType()->getAs<RecordType>();
if (!Ty) {
if (AllowShortCircuit) return false;
AllMatches = false;
continue;
}
CXXRecordDecl *Base =
cast_or_null<CXXRecordDecl>(Ty->getDecl()->getDefinition());
if (!Base) {
if (AllowShortCircuit) return false;
AllMatches = false;
continue;
}
Queue.push_back(Base);
if (!BaseMatches(Base, OpaqueData)) {
if (AllowShortCircuit) return false;
AllMatches = false;
continue;
}
}
if (Queue.empty()) break;
Record = Queue.back(); // not actually a queue.
Queue.pop_back();
}
return AllMatches;
}
示例3: MakeTrivial
void NestedNameSpecifierLocBuilder::MakeTrivial(ASTContext &Context,
NestedNameSpecifier *Qualifier,
SourceRange R) {
Representation = Qualifier;
// Construct bogus (but well-formed) source information for the
// nested-name-specifier.
BufferSize = 0;
SmallVector<NestedNameSpecifier *, 4> Stack;
for (NestedNameSpecifier *NNS = Qualifier; NNS; NNS = NNS->getPrefix())
Stack.push_back(NNS);
while (!Stack.empty()) {
NestedNameSpecifier *NNS = Stack.back();
Stack.pop_back();
switch (NNS->getKind()) {
case NestedNameSpecifier::Identifier:
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
SaveSourceLocation(R.getBegin(), Buffer, BufferSize, BufferCapacity);
break;
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate: {
TypeSourceInfo *TSInfo
= Context.getTrivialTypeSourceInfo(QualType(NNS->getAsType(), 0),
R.getBegin());
SavePointer(TSInfo->getTypeLoc().getOpaqueData(), Buffer, BufferSize,
BufferCapacity);
break;
}
case NestedNameSpecifier::Global:
break;
}
// Save the location of the '::'.
SaveSourceLocation(Stack.empty()? R.getEnd() : R.getBegin(),
Buffer, BufferSize, BufferCapacity);
}
}
示例4: constructScopeNest
/// constructScopeNest
void LexicalScopes::constructScopeNest(LexicalScope *Scope) {
assert(Scope && "Unable to calculate scope dominance graph!");
SmallVector<LexicalScope *, 4> WorkStack;
WorkStack.push_back(Scope);
unsigned Counter = 0;
while (!WorkStack.empty()) {
LexicalScope *WS = WorkStack.back();
const SmallVectorImpl<LexicalScope *> &Children = WS->getChildren();
bool visitedChildren = false;
for (auto &ChildScope : Children)
if (!ChildScope->getDFSOut()) {
WorkStack.push_back(ChildScope);
visitedChildren = true;
ChildScope->setDFSIn(++Counter);
break;
}
if (!visitedChildren) {
WorkStack.pop_back();
WS->setDFSOut(++Counter);
}
}
}
示例5: while
// Look through full copies and PHIs to get the set of non-copy MachineInstrs
// that can produce MI.
void A15SDOptimizer::elideCopiesAndPHIs(MachineInstr *MI,
SmallVectorImpl<MachineInstr*> &Outs) {
// Looking through PHIs may create loops so we need to track what
// instructions we have visited before.
std::set<MachineInstr *> Reached;
SmallVector<MachineInstr *, 8> Front;
Front.push_back(MI);
while (Front.size() != 0) {
MI = Front.back();
Front.pop_back();
// If we have already explored this MachineInstr, ignore it.
if (Reached.find(MI) != Reached.end())
continue;
Reached.insert(MI);
if (MI->isPHI()) {
for (unsigned I = 1, E = MI->getNumOperands(); I != E; I += 2) {
unsigned Reg = MI->getOperand(I).getReg();
if (!TRI->isVirtualRegister(Reg)) {
continue;
}
MachineInstr *NewMI = MRI->getVRegDef(Reg);
if (!NewMI)
continue;
Front.push_back(NewMI);
}
} else if (MI->isFullCopy()) {
if (!TRI->isVirtualRegister(MI->getOperand(1).getReg()))
continue;
MachineInstr *NewMI = MRI->getVRegDef(MI->getOperand(1).getReg());
if (!NewMI)
continue;
Front.push_back(NewMI);
} else {
DEBUG(dbgs() << "Found partial copy" << *MI <<"\n");
Outs.push_back(MI);
}
}
}
示例6: dumpNode
void ScheduleDAGSDNodes::dumpNode(const SUnit &SU) const {
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dumpNodeName(SU);
dbgs() << ": ";
if (!SU.getNode()) {
dbgs() << "PHYS REG COPY\n";
return;
}
SU.getNode()->dump(DAG);
dbgs() << "\n";
SmallVector<SDNode *, 4> GluedNodes;
for (SDNode *N = SU.getNode()->getGluedNode(); N; N = N->getGluedNode())
GluedNodes.push_back(N);
while (!GluedNodes.empty()) {
dbgs() << " ";
GluedNodes.back()->dump(DAG);
dbgs() << "\n";
GluedNodes.pop_back();
}
#endif
}
示例7: markUnavailable
void Module::markUnavailable(bool MissingRequirement) {
if (!IsAvailable)
return;
SmallVector<Module *, 2> Stack;
Stack.push_back(this);
while (!Stack.empty()) {
Module *Current = Stack.back();
Stack.pop_back();
if (!Current->IsAvailable)
continue;
Current->IsAvailable = false;
Current->IsMissingRequirement |= MissingRequirement;
for (submodule_iterator Sub = Current->submodule_begin(),
SubEnd = Current->submodule_end();
Sub != SubEnd; ++Sub) {
if ((*Sub)->IsAvailable)
Stack.push_back(*Sub);
}
}
}
示例8: IsValueIntLoadRecursive
static bool IsValueIntLoadRecursive(Value *V) {
SmallVector<Value*, 4> Worklist;
DenseSet<const Value *> VisitedValues;
Worklist.push_back(V);
VisitedValues.insert(V);
while (!Worklist.empty()) {
Value *CurValue = Worklist.back();
Worklist.pop_back();
if (!CanCheckValue(CurValue))
continue;
if (IsLoad(CurValue))
return true;
if (User *U = dyn_cast<User>(CurValue)) {
// Do not walk through call instructions. The call arguments are not
// necessarily directly related to the result, so it makes no sense to
// cross-check them.
//
// Alternatively we could check call return values as if they were loads
// expected to be datarando'd, but this may add false positives. Will
// just ignore calls for now.
if (isa<CallInst>(CurValue) ||
isa<InvokeInst>(CurValue)) {
continue;
}
for (Value *V : U->operands())
if (VisitedValues.insert(V).second)
Worklist.push_back(V);
}
}
return false;
}
示例9: Find
bool Find(const TypedValueRegion *R) {
QualType T = R->getValueType();
if (const RecordType *RT = T->getAsStructureType()) {
const RecordDecl *RD = RT->getDecl()->getDefinition();
assert(RD && "Referred record has no definition");
for (const auto *I : RD->fields()) {
const FieldRegion *FR = MrMgr.getFieldRegion(I, R);
FieldChain.push_back(I);
T = I->getType();
if (T->getAsStructureType()) {
if (Find(FR))
return true;
}
else {
const SVal &V = StoreMgr.getBinding(store, loc::MemRegionVal(FR));
if (V.isUndef())
return true;
}
FieldChain.pop_back();
}
}
return false;
}
示例10: RecursivelyDeleteTriviallyDeadInstructions
/// RecursivelyDeleteTriviallyDeadInstructions - If the specified value is a
/// trivially dead instruction, delete it. If that makes any of its operands
/// trivially dead, delete them too, recursively.
///
/// If DeadInst is specified, the vector is filled with the instructions that
/// are actually deleted.
void llvm::RecursivelyDeleteTriviallyDeadInstructions(Value *V,
SmallVectorImpl<Instruction*> *DeadInst) {
Instruction *I = dyn_cast<Instruction>(V);
if (!I || !I->use_empty() || !isInstructionTriviallyDead(I))
return;
SmallVector<Instruction*, 16> DeadInsts;
DeadInsts.push_back(I);
while (!DeadInsts.empty()) {
I = DeadInsts.back();
DeadInsts.pop_back();
// If the client wanted to know, tell it about deleted instructions.
if (DeadInst)
DeadInst->push_back(I);
// Null out all of the instruction's operands to see if any operand becomes
// dead as we go.
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
Value *OpV = I->getOperand(i);
I->setOperand(i, 0);
if (!OpV->use_empty()) continue;
// If the operand is an instruction that became dead as we nulled out the
// operand, and if it is 'trivially' dead, delete it in a future loop
// iteration.
if (Instruction *OpI = dyn_cast<Instruction>(OpV))
if (isInstructionTriviallyDead(OpI))
DeadInsts.push_back(OpI);
}
I->eraseFromParent();
}
}
示例11: runOnSCC
//.........这里部分代码省略.........
if (!Callee || Callee->isDeclaration()) continue;
// If this call site was obtained by inlining another function, verify
// that the include path for the function did not include the callee
// itself. If so, we'd be recursively inlining the same function,
// which would provide the same callsites, which would cause us to
// infinitely inline.
int InlineHistoryID = CallSites[CSi].second;
if (InlineHistoryID != -1 &&
InlineHistoryIncludes(Callee, InlineHistoryID, InlineHistory))
continue;
LLVMContext &CallerCtx = Caller->getContext();
// Get DebugLoc to report. CS will be invalid after Inliner.
DebugLoc DLoc = CS.getInstruction()->getDebugLoc();
// If the policy determines that we should inline this function,
// try to do so.
if (!shouldInline(CS)) {
emitOptimizationRemarkMissed(CallerCtx, DEBUG_TYPE, *Caller, DLoc,
Twine(Callee->getName() +
" will not be inlined into " +
Caller->getName()));
continue;
}
// Attempt to inline the function.
if (!InlineCallIfPossible(CS, InlineInfo, InlinedArrayAllocas,
InlineHistoryID, InsertLifetime)) {
emitOptimizationRemarkMissed(CallerCtx, DEBUG_TYPE, *Caller, DLoc,
Twine(Callee->getName() +
" will not be inlined into " +
Caller->getName()));
continue;
}
++NumInlined;
// Report the inline decision.
emitOptimizationRemark(
CallerCtx, DEBUG_TYPE, *Caller, DLoc,
Twine(Callee->getName() + " inlined into " + Caller->getName()));
// If inlining this function gave us any new call sites, throw them
// onto our worklist to process. They are useful inline candidates.
if (!InlineInfo.InlinedCalls.empty()) {
// Create a new inline history entry for this, so that we remember
// that these new callsites came about due to inlining Callee.
int NewHistoryID = InlineHistory.size();
InlineHistory.push_back(std::make_pair(Callee, InlineHistoryID));
for (unsigned i = 0, e = InlineInfo.InlinedCalls.size();
i != e; ++i) {
Value *Ptr = InlineInfo.InlinedCalls[i];
CallSites.push_back(std::make_pair(CallSite(Ptr), NewHistoryID));
}
}
}
// If we inlined or deleted the last possible call site to the function,
// delete the function body now.
if (Callee && Callee->use_empty() && Callee->hasLocalLinkage() &&
// TODO: Can remove if in SCC now.
!SCCFunctions.count(Callee) &&
// The function may be apparently dead, but if there are indirect
// callgraph references to the node, we cannot delete it yet, this
// could invalidate the CGSCC iterator.
CG[Callee]->getNumReferences() == 0) {
DEBUG(dbgs() << " -> Deleting dead function: "
<< Callee->getName() << "\n");
CallGraphNode *CalleeNode = CG[Callee];
// Remove any call graph edges from the callee to its callees.
CalleeNode->removeAllCalledFunctions();
// Removing the node for callee from the call graph and delete it.
delete CG.removeFunctionFromModule(CalleeNode);
++NumDeleted;
}
// Remove this call site from the list. If possible, use
// swap/pop_back for efficiency, but do not use it if doing so would
// move a call site to a function in this SCC before the
// 'FirstCallInSCC' barrier.
if (SCC.isSingular()) {
CallSites[CSi] = CallSites.back();
CallSites.pop_back();
} else {
CallSites.erase(CallSites.begin()+CSi);
}
--CSi;
Changed = true;
LocalChange = true;
}
} while (LocalChange);
return Changed;
}
示例12: lower
void WebAssemblyMCInstLower::lower(const MachineInstr *MI,
MCInst &OutMI) const {
OutMI.setOpcode(MI->getOpcode());
const MCInstrDesc &Desc = MI->getDesc();
for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) {
const MachineOperand &MO = MI->getOperand(I);
MCOperand MCOp;
switch (MO.getType()) {
default:
MI->print(errs());
llvm_unreachable("unknown operand type");
case MachineOperand::MO_MachineBasicBlock:
MI->print(errs());
llvm_unreachable("MachineBasicBlock operand should have been rewritten");
case MachineOperand::MO_Register: {
// Ignore all implicit register operands.
if (MO.isImplicit())
continue;
const WebAssemblyFunctionInfo &MFI =
*MI->getParent()->getParent()->getInfo<WebAssemblyFunctionInfo>();
unsigned WAReg = MFI.getWAReg(MO.getReg());
MCOp = MCOperand::createReg(WAReg);
break;
}
case MachineOperand::MO_Immediate:
if (I < Desc.NumOperands) {
const MCOperandInfo &Info = Desc.OpInfo[I];
if (Info.OperandType == WebAssembly::OPERAND_TYPEINDEX) {
MCSymbol *Sym = Printer.createTempSymbol("typeindex");
SmallVector<wasm::ValType, 4> Returns;
SmallVector<wasm::ValType, 4> Params;
const MachineRegisterInfo &MRI =
MI->getParent()->getParent()->getRegInfo();
for (const MachineOperand &MO : MI->defs())
Returns.push_back(getType(MRI.getRegClass(MO.getReg())));
for (const MachineOperand &MO : MI->explicit_uses())
if (MO.isReg())
Params.push_back(getType(MRI.getRegClass(MO.getReg())));
// call_indirect instructions have a callee operand at the end which
// doesn't count as a param.
if (WebAssembly::isCallIndirect(*MI))
Params.pop_back();
auto *WasmSym = cast<MCSymbolWasm>(Sym);
auto Signature = make_unique<wasm::WasmSignature>(std::move(Returns),
std::move(Params));
WasmSym->setSignature(Signature.get());
Printer.addSignature(std::move(Signature));
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_FUNCTION);
const MCExpr *Expr = MCSymbolRefExpr::create(
WasmSym, MCSymbolRefExpr::VK_WASM_TYPEINDEX, Ctx);
MCOp = MCOperand::createExpr(Expr);
break;
}
}
MCOp = MCOperand::createImm(MO.getImm());
break;
case MachineOperand::MO_FPImmediate: {
// TODO: MC converts all floating point immediate operands to double.
// This is fine for numeric values, but may cause NaNs to change bits.
const ConstantFP *Imm = MO.getFPImm();
if (Imm->getType()->isFloatTy())
MCOp = MCOperand::createFPImm(Imm->getValueAPF().convertToFloat());
else if (Imm->getType()->isDoubleTy())
MCOp = MCOperand::createFPImm(Imm->getValueAPF().convertToDouble());
else
llvm_unreachable("unknown floating point immediate type");
break;
}
case MachineOperand::MO_GlobalAddress:
MCOp = lowerSymbolOperand(MO, GetGlobalAddressSymbol(MO));
break;
case MachineOperand::MO_ExternalSymbol:
// The target flag indicates whether this is a symbol for a
// variable or a function.
assert(MO.getTargetFlags() == 0 &&
"WebAssembly uses only symbol flags on ExternalSymbols");
MCOp = lowerSymbolOperand(MO, GetExternalSymbolSymbol(MO));
break;
case MachineOperand::MO_MCSymbol:
// This is currently used only for LSDA symbols (GCC_except_table),
// because global addresses or other external symbols are handled above.
assert(MO.getTargetFlags() == 0 &&
"WebAssembly does not use target flags on MCSymbol");
MCOp = lowerSymbolOperand(MO, MO.getMCSymbol());
break;
}
OutMI.addOperand(MCOp);
}
if (!WasmKeepRegisters)
removeRegisterOperands(MI, OutMI);
}
示例13: Emitter
/// EmitSchedule - Emit the machine code in scheduled order. Return the new
/// InsertPos and MachineBasicBlock that contains this insertion
/// point. ScheduleDAGSDNodes holds a BB pointer for convenience, but this does
/// not necessarily refer to returned BB. The emitter may split blocks.
MachineBasicBlock *ScheduleDAGSDNodes::
EmitSchedule(MachineBasicBlock::iterator &InsertPos) {
InstrEmitter Emitter(BB, InsertPos);
DenseMap<SDValue, unsigned> VRBaseMap;
DenseMap<SUnit*, unsigned> CopyVRBaseMap;
SmallVector<std::pair<unsigned, MachineInstr*>, 32> Orders;
SmallSet<unsigned, 8> Seen;
bool HasDbg = DAG->hasDebugValues();
// If this is the first BB, emit byval parameter dbg_value's.
if (HasDbg && BB->getParent()->begin() == MachineFunction::iterator(BB)) {
SDDbgInfo::DbgIterator PDI = DAG->ByvalParmDbgBegin();
SDDbgInfo::DbgIterator PDE = DAG->ByvalParmDbgEnd();
for (; PDI != PDE; ++PDI) {
MachineInstr *DbgMI= Emitter.EmitDbgValue(*PDI, VRBaseMap);
if (DbgMI)
BB->insert(InsertPos, DbgMI);
}
}
for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
SUnit *SU = Sequence[i];
if (!SU) {
// Null SUnit* is a noop.
TII->insertNoop(*Emitter.getBlock(), InsertPos);
continue;
}
// For pre-regalloc scheduling, create instructions corresponding to the
// SDNode and any glued SDNodes and append them to the block.
if (!SU->getNode()) {
// Emit a copy.
EmitPhysRegCopy(SU, CopyVRBaseMap, InsertPos);
continue;
}
SmallVector<SDNode *, 4> GluedNodes;
for (SDNode *N = SU->getNode()->getGluedNode(); N;
N = N->getGluedNode())
GluedNodes.push_back(N);
while (!GluedNodes.empty()) {
SDNode *N = GluedNodes.back();
Emitter.EmitNode(GluedNodes.back(), SU->OrigNode != SU, SU->isCloned,
VRBaseMap);
// Remember the source order of the inserted instruction.
if (HasDbg)
ProcessSourceNode(N, DAG, Emitter, VRBaseMap, Orders, Seen);
GluedNodes.pop_back();
}
Emitter.EmitNode(SU->getNode(), SU->OrigNode != SU, SU->isCloned,
VRBaseMap);
// Remember the source order of the inserted instruction.
if (HasDbg)
ProcessSourceNode(SU->getNode(), DAG, Emitter, VRBaseMap, Orders,
Seen);
}
// Insert all the dbg_values which have not already been inserted in source
// order sequence.
if (HasDbg) {
MachineBasicBlock::iterator BBBegin = BB->getFirstNonPHI();
// Sort the source order instructions and use the order to insert debug
// values.
std::sort(Orders.begin(), Orders.end(), OrderSorter());
SDDbgInfo::DbgIterator DI = DAG->DbgBegin();
SDDbgInfo::DbgIterator DE = DAG->DbgEnd();
// Now emit the rest according to source order.
unsigned LastOrder = 0;
for (unsigned i = 0, e = Orders.size(); i != e && DI != DE; ++i) {
unsigned Order = Orders[i].first;
MachineInstr *MI = Orders[i].second;
// Insert all SDDbgValue's whose order(s) are before "Order".
if (!MI)
continue;
for (; DI != DE &&
(*DI)->getOrder() >= LastOrder && (*DI)->getOrder() < Order; ++DI) {
if ((*DI)->isInvalidated())
continue;
MachineInstr *DbgMI = Emitter.EmitDbgValue(*DI, VRBaseMap);
if (DbgMI) {
if (!LastOrder)
// Insert to start of the BB (after PHIs).
BB->insert(BBBegin, DbgMI);
else {
// Insert at the instruction, which may be in a different
// block, if the block was split by a custom inserter.
MachineBasicBlock::iterator Pos = MI;
MI->getParent()->insert(llvm::next(Pos), DbgMI);
}
}
}
LastOrder = Order;
}
// Add trailing DbgValue's before the terminator. FIXME: May want to add
//.........这里部分代码省略.........
示例14: HandlePathDiagnostic
void PathDiagnosticConsumer::HandlePathDiagnostic(PathDiagnostic *D) {
OwningPtr<PathDiagnostic> OwningD(D);
if (!D || D->path.empty())
return;
// We need to flatten the locations (convert Stmt* to locations) because
// the referenced statements may be freed by the time the diagnostics
// are emitted.
D->flattenLocations();
// If the PathDiagnosticConsumer does not support diagnostics that
// cross file boundaries, prune out such diagnostics now.
if (!supportsCrossFileDiagnostics()) {
// Verify that the entire path is from the same FileID.
FileID FID;
const SourceManager &SMgr = (*D->path.begin())->getLocation().getManager();
SmallVector<const PathPieces *, 5> WorkList;
WorkList.push_back(&D->path);
while (!WorkList.empty()) {
const PathPieces &path = *WorkList.back();
WorkList.pop_back();
for (PathPieces::const_iterator I = path.begin(), E = path.end();
I != E; ++I) {
const PathDiagnosticPiece *piece = I->getPtr();
FullSourceLoc L = piece->getLocation().asLocation().getExpansionLoc();
if (FID.isInvalid()) {
FID = SMgr.getFileID(L);
} else if (SMgr.getFileID(L) != FID)
return; // FIXME: Emit a warning?
// Check the source ranges.
ArrayRef<SourceRange> Ranges = piece->getRanges();
for (ArrayRef<SourceRange>::iterator I = Ranges.begin(),
E = Ranges.end(); I != E; ++I) {
SourceLocation L = SMgr.getExpansionLoc(I->getBegin());
if (!L.isFileID() || SMgr.getFileID(L) != FID)
return; // FIXME: Emit a warning?
L = SMgr.getExpansionLoc(I->getEnd());
if (!L.isFileID() || SMgr.getFileID(L) != FID)
return; // FIXME: Emit a warning?
}
if (const PathDiagnosticCallPiece *call =
dyn_cast<PathDiagnosticCallPiece>(piece)) {
WorkList.push_back(&call->path);
}
else if (const PathDiagnosticMacroPiece *macro =
dyn_cast<PathDiagnosticMacroPiece>(piece)) {
WorkList.push_back(¯o->subPieces);
}
}
}
if (FID.isInvalid())
return; // FIXME: Emit a warning?
}
// Profile the node to see if we already have something matching it
llvm::FoldingSetNodeID profile;
D->Profile(profile);
void *InsertPos = 0;
if (PathDiagnostic *orig = Diags.FindNodeOrInsertPos(profile, InsertPos)) {
// Keep the PathDiagnostic with the shorter path.
// Note, the enclosing routine is called in deterministic order, so the
// results will be consistent between runs (no reason to break ties if the
// size is the same).
const unsigned orig_size = orig->full_size();
const unsigned new_size = D->full_size();
if (orig_size <= new_size)
return;
assert(orig != D);
Diags.RemoveNode(orig);
delete orig;
}
Diags.InsertNode(OwningD.take());
}
示例15: lookupQualified
//.........这里部分代码省略.........
}
}
// Ignore stub implementations.
if (auto ctor = dyn_cast<ConstructorDecl>(decl)) {
if (ctor->hasStubImplementation())
return false;
}
// Check access.
if (!(options & NL_IgnoreAccessibility))
if (auto VD = dyn_cast<ValueDecl>(decl))
return VD->isAccessibleFrom(this);
return true;
};
ReferencedNameTracker *tracker = nullptr;
if (auto containingSourceFile = dyn_cast<SourceFile>(getModuleScopeContext()))
tracker = containingSourceFile->getReferencedNameTracker();
bool isLookupCascading;
if (tracker) {
if (auto maybeLookupCascade = checkLookupCascading())
isLookupCascading = maybeLookupCascade.getValue();
else
tracker = nullptr;
}
// Visit all of the nominal types we know about, discovering any others
// we need along the way.
while (!stack.empty()) {
auto current = stack.back();
stack.pop_back();
if (tracker)
tracker->addUsedMember({current, member.getBaseName()},isLookupCascading);
// Make sure we've resolved implicit constructors, if we need them.
if (member.getBaseName() == ctx.Id_init && typeResolver)
typeResolver->resolveImplicitConstructors(current);
// Look for results within the current nominal type and its extensions.
bool currentIsProtocol = isa<ProtocolDecl>(current);
for (auto decl : current->lookupDirect(member)) {
// If we're performing a type lookup, don't even attempt to validate
// the decl if its not a type.
if ((options & NL_OnlyTypes) && !isa<TypeDecl>(decl))
continue;
// Resolve the declaration signature when we find the
// declaration.
if (typeResolver && !decl->isBeingTypeChecked()) {
typeResolver->resolveDeclSignature(decl);
if (!decl->hasType())
continue;
}
if (isAcceptableDecl(current, decl))
decls.push_back(decl);
}
// If we're not supposed to visit our supertypes, we're done.
if ((options & NL_VisitSupertypes) == 0)
continue;