本文整理汇总了C++中SILLocation类的典型用法代码示例。如果您正苦于以下问题:C++ SILLocation类的具体用法?C++ SILLocation怎么用?C++ SILLocation使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了SILLocation类的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: isUserCode
/// \brief Check if this instruction corresponds to user-written code.
static bool isUserCode(const SILInstruction *I) {
SILLocation Loc = I->getLoc();
if (Loc.isAutoGenerated())
return false;
// Branch instructions are not user code. These could belong to the control
// flow statement we are folding (ex: while loop).
// Also, unreachable instructions are not user code, they are "expected" in
// unreachable blocks.
if ((isa<BranchInst>(I) || isa<UnreachableInst>(I)) &&
Loc.is<RegularLocation>())
return false;
// If the instruction corresponds to user-written return or some other
// statement, we know it corresponds to user code.
if (Loc.is<RegularLocation>() || Loc.is<ReturnLocation>()) {
if (auto *E = Loc.getAsASTNode<Expr>())
return !E->isImplicit();
if (auto *D = Loc.getAsASTNode<Decl>())
return !D->isImplicit();
if (auto *S = Loc.getAsASTNode<Decl>())
return !S->isImplicit();
if (auto *P = Loc.getAsASTNode<Decl>())
return !P->isImplicit();
return true;
}
return false;
}
开发者ID:pietbrauer,项目名称:swift,代码行数:29,代码来源:DiagnoseUnreachable.cpp
示例2: diagnoseMissingReturn
static void diagnoseMissingReturn(const UnreachableInst *UI,
ASTContext &Context) {
const SILBasicBlock *BB = UI->getParent();
const SILFunction *F = BB->getParent();
SILLocation FLoc = F->getLocation();
Type ResTy;
if (auto *FD = FLoc.getAsASTNode<FuncDecl>()) {
ResTy = FD->getResultType();
} else if (auto *CE = FLoc.getAsASTNode<ClosureExpr>()) {
ResTy = CE->getResultType();
} else {
llvm_unreachable("unhandled case in MissingReturn");
}
bool isNoReturn = F->getLoweredFunctionType()->isNoReturn();
// No action required if the function returns 'Void' or that the
// function is marked 'noreturn'.
if (ResTy->isVoid() || isNoReturn)
return;
SILLocation L = UI->getLoc();
assert(L && ResTy);
diagnose(Context,
L.getEndSourceLoc(),
diag::missing_return, ResTy,
FLoc.isASTNode<ClosureExpr>() ? 1 : 0);
}
开发者ID:pietbrauer,项目名称:swift,代码行数:30,代码来源:DataflowDiagnostics.cpp
示例3: SILLocation
SILFunction *MaterializeForSetEmitter::createCallback(SILFunction &F,
GeneratorFn generator) {
auto callbackType =
SGM.Types.getMaterializeForSetCallbackType(WitnessStorage,
GenericSig,
SelfInterfaceType,
CallbackRepresentation);
auto *genericEnv = GenericEnv;
if (GenericEnv && GenericEnv->getGenericSignature()->areAllParamsConcrete())
genericEnv = nullptr;
auto callback =
SGM.M.createFunction(Linkage, CallbackName, callbackType,
genericEnv, SILLocation(Witness),
IsBare, F.isTransparent(), F.isFragile(),
IsNotThunk,
/*ClassVisibility=*/SILFunction::NotRelevant,
/*InlineStrategy=*/InlineDefault,
/*EffectsKind=*/EffectsKind::Unspecified,
/*InsertBefore=*/&F);
callback->setDebugScope(new (SGM.M) SILDebugScope(Witness, callback));
PrettyStackTraceSILFunction X("silgen materializeForSet callback", callback);
{
SILGenFunction gen(SGM, *callback);
auto makeParam = [&](unsigned index) -> SILArgument * {
SILType type = gen.F.mapTypeIntoContext(
gen.getSILType(callbackType->getParameters()[index]));
return gen.F.begin()->createFunctionArgument(type);
};
// Add arguments for all the parameters.
auto valueBuffer = makeParam(0);
auto storageBuffer = makeParam(1);
auto self = makeParam(2);
(void) makeParam(3);
SILLocation loc = Witness;
loc.markAutoGenerated();
// Call the generator function we were provided.
{
LexicalScope scope(gen.Cleanups, gen, CleanupLocation::get(loc));
generator(gen, loc, valueBuffer, storageBuffer, self);
}
// Return void.
auto result = gen.emitEmptyTuple(loc);
gen.B.createReturn(loc, result);
}
callback->verify();
return callback;
}
开发者ID:bropiao,项目名称:swift,代码行数:57,代码来源:SILGenMaterializeForSet.cpp
示例4: SILDebugScope
SILFunction *MaterializeForSetEmitter::createCallback(SILFunction &F,
GeneratorFn generator) {
auto callbackType =
SGM.Types.getMaterializeForSetCallbackType(WitnessStorage,
GenericSig,
SelfInterfaceType);
auto callback =
SGM.M.getOrCreateFunction(Witness, CallbackName, Linkage,
callbackType, IsBare,
F.isTransparent(),
F.isFragile());
callback->setGenericEnvironment(GenericEnv);
callback->setDebugScope(new (SGM.M) SILDebugScope(Witness, callback));
PrettyStackTraceSILFunction X("silgen materializeForSet callback", callback);
{
SILGenFunction gen(SGM, *callback);
auto makeParam = [&](unsigned index) -> SILArgument* {
SILType type = gen.F.mapTypeIntoContext(
callbackType->getParameters()[index].getSILType());
return new (SGM.M) SILArgument(gen.F.begin(), type);
};
// Add arguments for all the parameters.
auto valueBuffer = makeParam(0);
auto storageBuffer = makeParam(1);
auto self = makeParam(2);
(void) makeParam(3);
SILLocation loc = Witness;
loc.markAutoGenerated();
// Call the generator function we were provided.
{
LexicalScope scope(gen.Cleanups, gen, CleanupLocation::get(loc));
generator(gen, loc, valueBuffer, storageBuffer, self);
}
// Return void.
auto result = gen.emitEmptyTuple(loc);
gen.B.createReturn(loc, result);
}
callback->verify();
return callback;
}
开发者ID:IngmarStein,项目名称:swift,代码行数:48,代码来源:SILGenMaterializeForSet.cpp
示例5: emitUnknownDiagnosticNotes
/// Given that this is an 'Unknown' value, emit diagnostic notes providing
/// context about what the problem is.
void SymbolicValue::emitUnknownDiagnosticNotes(SILLocation fallbackLoc) {
auto badInst = dyn_cast<SILInstruction>(getUnknownNode());
if (!badInst)
return;
bool emittedFirstNote = emitNoteDiagnostic(badInst, getUnknownReason(),
fallbackLoc);
auto sourceLoc = fallbackLoc.getSourceLoc();
auto &module = badInst->getModule();
if (sourceLoc.isInvalid()) {
diagnose(module.getASTContext(), sourceLoc, diag::constexpr_not_evaluable);
return;
}
for (auto &sourceLoc : llvm::reverse(getUnknownCallStack())) {
// Skip unknown sources.
if (!sourceLoc.isValid())
continue;
auto diag = emittedFirstNote ? diag::constexpr_called_from
: diag::constexpr_not_evaluable;
diagnose(module.getASTContext(), sourceLoc, diag);
emittedFirstNote = true;
}
}
开发者ID:phausler,项目名称:swift,代码行数:27,代码来源:SILConstants.cpp
示例6: get
CleanupLocation CleanupLocation::get(SILLocation L) {
if (Expr *E = L.getAsASTNode<Expr>())
return CleanupLocation(E, L.getSpecialFlags());
if (Stmt *S = L.getAsASTNode<Stmt>())
return CleanupLocation(S, L.getSpecialFlags());
if (Pattern *P = L.getAsASTNode<Pattern>())
return CleanupLocation(P, L.getSpecialFlags());
if (Decl *D = L.getAsASTNode<Decl>())
return CleanupLocation(D, L.getSpecialFlags());
if (L.isNull())
return CleanupLocation();
if (L.getAs<SILFileLocation>())
return CleanupLocation();
llvm_unreachable("Cannot construct Cleanup loc from the "
"given location.");
}
开发者ID:Ben-G,项目名称:swift,代码行数:16,代码来源:SILLocation.cpp
示例7: emitGlobalFunctionRef
SILValue SILGenFunction::emitGlobalFunctionRef(SILLocation loc,
SILDeclRef constant,
SILConstantInfo constantInfo) {
assert(constantInfo == getConstantInfo(constant));
// Builtins must be fully applied at the point of reference.
if (constant.hasDecl() &&
isa<BuiltinUnit>(constant.getDecl()->getDeclContext())) {
SGM.diagnose(loc.getSourceLoc(), diag::not_implemented,
"delayed application of builtin");
return SILUndef::get(constantInfo.getSILType(), SGM.M);
}
// If the constant is a thunk we haven't emitted yet, emit it.
if (!SGM.hasFunction(constant)) {
if (constant.isCurried) {
SGM.emitCurryThunk(constant);
} else if (constant.isForeignToNativeThunk()) {
SGM.emitForeignToNativeThunk(constant);
} else if (constant.isNativeToForeignThunk()) {
SGM.emitNativeToForeignThunk(constant);
} else if (constant.kind == SILDeclRef::Kind::EnumElement) {
SGM.emitEnumConstructor(cast<EnumElementDecl>(constant.getDecl()));
}
}
auto f = SGM.getFunction(constant, NotForDefinition);
assert(f->getLoweredFunctionType() == constantInfo.SILFnType);
return B.createFunctionRef(loc, f);
}
开发者ID:shingt,项目名称:swift,代码行数:30,代码来源:SILGenThunk.cpp
示例8: printSILLocationDescription
void swift::printSILLocationDescription(llvm::raw_ostream &out,
SILLocation loc,
ASTContext &Context) {
if (loc.isNull()) {
out << "<<invalid location>>";
} else if (loc.isSILFile()) {
printSourceLocDescription(out, loc.getSourceLoc(), Context);
} else if (auto decl = loc.getAsASTNode<Decl>()) {
printDeclDescription(out, decl, Context);
} else if (auto expr = loc.getAsASTNode<Expr>()) {
printExprDescription(out, expr, Context);
} else if (auto stmt = loc.getAsASTNode<Stmt>()) {
printStmtDescription(out, stmt, Context);
} else if (auto pattern = loc.castToASTNode<Pattern>()) {
printPatternDescription(out, pattern, Context);
}
}
开发者ID:apple,项目名称:swift,代码行数:17,代码来源:PrettyStackTrace.cpp
示例9: diagnoseReturn
static void diagnoseReturn(const SILInstruction *I, ASTContext &Context) {
auto *TI = dyn_cast<TermInst>(I);
if (!TI || !(isa<BranchInst>(TI) || isa<ReturnInst>(TI)))
return;
const SILBasicBlock *BB = TI->getParent();
const SILFunction *F = BB->getParent();
// Warn if we reach a return inside a noreturn function.
if (F->getLoweredFunctionType()->isNoReturn()) {
SILLocation L = TI->getLoc();
if (L.is<ReturnLocation>())
diagnose(Context, L.getSourceLoc(), diag::return_from_noreturn);
if (L.is<ImplicitReturnLocation>())
diagnose(Context, L.getSourceLoc(), diag::return_from_noreturn);
}
}
开发者ID:pietbrauer,项目名称:swift,代码行数:17,代码来源:DataflowDiagnostics.cpp
示例10: diagnoseMissingReturn
static void diagnoseMissingReturn(const UnreachableInst *UI,
ASTContext &Context) {
const SILBasicBlock *BB = UI->getParent();
const SILFunction *F = BB->getParent();
SILLocation FLoc = F->getLocation();
Type ResTy;
BraceStmt *BS;
if (auto *FD = FLoc.getAsASTNode<FuncDecl>()) {
ResTy = FD->getResultInterfaceType();
BS = FD->getBody(/*canSynthesize=*/false);
} else if (auto *CD = FLoc.getAsASTNode<ConstructorDecl>()) {
ResTy = CD->getResultInterfaceType();
BS = FD->getBody();
} else if (auto *CE = FLoc.getAsASTNode<ClosureExpr>()) {
ResTy = CE->getResultType();
BS = CE->getBody();
} else {
llvm_unreachable("unhandled case in MissingReturn");
}
SILLocation L = UI->getLoc();
assert(L && ResTy);
auto numElements = BS->getNumElements();
if (numElements > 0) {
auto element = BS->getElement(numElements - 1);
if (auto expr = element.dyn_cast<Expr *>()) {
if (expr->getType()->getCanonicalType() == ResTy->getCanonicalType()) {
Context.Diags.diagnose(
expr->getStartLoc(),
diag::missing_return_last_expr, ResTy,
FLoc.isASTNode<ClosureExpr>() ? 1 : 0)
.fixItInsert(expr->getStartLoc(), "return ");
return;
}
}
}
auto diagID = F->isNoReturnFunction() ? diag::missing_never_call
: diag::missing_return;
diagnose(Context,
L.getEndSourceLoc(),
diagID, ResTy,
FLoc.isASTNode<ClosureExpr>() ? 1 : 0);
}
开发者ID:gringoireDM,项目名称:swift,代码行数:45,代码来源:DataflowDiagnostics.cpp
示例11: getInlinedLocation
InlinedLocation InlinedLocation::getInlinedLocation(SILLocation L) {
if (Expr *E = L.getAsASTNode<Expr>())
return InlinedLocation(E, L.getSpecialFlags());
if (Stmt *S = L.getAsASTNode<Stmt>())
return InlinedLocation(S, L.getSpecialFlags());
if (Pattern *P = L.getAsASTNode<Pattern>())
return InlinedLocation(P, L.getSpecialFlags());
if (Decl *D = L.getAsASTNode<Decl>())
return InlinedLocation(D, L.getSpecialFlags());
if (L.hasSILFileSourceLoc())
return InlinedLocation(L.getSILFileSourceLoc(), L.getSpecialFlags());
if (L.isInTopLevel())
return InlinedLocation::getModuleLocation(L.getSpecialFlags());
if (L.isAutoGenerated()) {
InlinedLocation IL;
IL.markAutoGenerated();
return IL;
}
llvm_unreachable("Cannot construct Inlined loc from the given location.");
}
开发者ID:Ben-G,项目名称:swift,代码行数:23,代码来源:SILLocation.cpp
示例12: diagnoseUnreachable
static void diagnoseUnreachable(const SILInstruction *I,
ASTContext &Context) {
if (auto *UI = dyn_cast<UnreachableInst>(I)){
SILLocation L = UI->getLoc();
// Invalid location means that the instruction has been generated by SIL
// passes, such as DCE. FIXME: we might want to just introduce a separate
// instruction kind, instead of keeping this invariant.
//
// We also do not want to emit diagnostics for code that was
// transparently inlined. We should have already emitted these
// diagnostics when we process the callee function prior to
// inlining it.
if (!L.hasASTLocation() || L.is<MandatoryInlinedLocation>())
return;
// The most common case of getting an unreachable instruction is a
// missing return statement. In this case, we know that the instruction
// location will be the enclosing function.
if (L.isASTNode<AbstractFunctionDecl>() || L.isASTNode<ClosureExpr>()) {
diagnoseMissingReturn(UI, Context);
return;
}
// A non-exhaustive switch would also produce an unreachable instruction.
if (L.isASTNode<SwitchStmt>()) {
diagnose(Context, L.getEndSourceLoc(), diag::non_exhaustive_switch);
return;
}
if (auto *Guard = L.getAsASTNode<GuardStmt>()) {
diagnose(Context, Guard->getBody()->getEndLoc(),
diag::guard_body_must_not_fallthrough);
return;
}
}
}
开发者ID:pietbrauer,项目名称:swift,代码行数:37,代码来源:DataflowDiagnostics.cpp
示例13: emitGlobalFunctionRef
SILValue SILGenFunction::emitGlobalFunctionRef(SILLocation loc,
SILDeclRef constant,
SILConstantInfo constantInfo) {
assert(constantInfo == getConstantInfo(constant));
// Builtins must be fully applied at the point of reference.
if (constant.hasDecl() &&
isa<BuiltinUnit>(constant.getDecl()->getDeclContext())) {
SGM.diagnose(loc.getSourceLoc(), diag::not_implemented,
"delayed application of builtin");
return SILUndef::get(constantInfo.getSILType(), SGM.M);
}
// If the constant is a thunk we haven't emitted yet, emit it.
if (!SGM.hasFunction(constant)) {
if (constant.isCurried) {
auto vd = constant.getDecl();
// Reference the next uncurrying level of the function.
SILDeclRef next = SILDeclRef(vd, constant.kind,
SILDeclRef::ConstructAtBestResilienceExpansion,
constant.uncurryLevel + 1);
// If the function is fully uncurried and natively foreign, reference its
// foreign entry point.
if (!next.isCurried) {
if (requiresForeignToNativeThunk(vd))
next = next.asForeign();
}
// Preserve whether the curry thunks lead to a direct reference to the
// method implementation.
next = next.asDirectReference(constant.isDirectReference);
SGM.emitCurryThunk(vd, constant, next);
}
// Otherwise, if this is a calling convention thunk we haven't emitted yet,
// emit it.
else if (constant.isForeignToNativeThunk()) {
SGM.emitForeignToNativeThunk(constant);
} else if (constant.isNativeToForeignThunk()) {
SGM.emitNativeToForeignThunk(constant);
} else if (constant.kind == SILDeclRef::Kind::EnumElement) {
SGM.emitEnumConstructor(cast<EnumElementDecl>(constant.getDecl()));
}
}
auto f = SGM.getFunction(constant, NotForDefinition);
assert(f->getLoweredFunctionType() == constantInfo.SILFnType);
return B.createFunctionRef(loc, f);
}
开发者ID:Anandnitrate,项目名称:swift,代码行数:49,代码来源:SILGenFunction.cpp
示例14: MandatoryInlinedLocation
MandatoryInlinedLocation
MandatoryInlinedLocation::getMandatoryInlinedLocation(SILLocation L) {
if (Expr *E = L.getAsASTNode<Expr>())
return MandatoryInlinedLocation(E, L.getSpecialFlags());
if (Stmt *S = L.getAsASTNode<Stmt>())
return MandatoryInlinedLocation(S, L.getSpecialFlags());
if (Pattern *P = L.getAsASTNode<Pattern>())
return MandatoryInlinedLocation(P, L.getSpecialFlags());
if (Decl *D = L.getAsASTNode<Decl>())
return MandatoryInlinedLocation(D, L.getSpecialFlags());
if (L.isSILFile())
return MandatoryInlinedLocation(L.Loc.SILFileLoc, L.getSpecialFlags());
if (L.isInTopLevel())
return MandatoryInlinedLocation::getModuleLocation(L.getSpecialFlags());
llvm_unreachable("Cannot construct Inlined loc from the given location.");
}
开发者ID:007Indian,项目名称:swift,代码行数:19,代码来源:SILLocation.cpp
示例15: switch
/// Emit a check for whether a non-native function call produced an
/// error.
///
/// \c results should be left with only values that match the formal
/// direct results of the function.
void
SILGenFunction::emitForeignErrorCheck(SILLocation loc,
SmallVectorImpl<ManagedValue> &results,
ManagedValue errorSlot,
bool suppressErrorCheck,
const ForeignErrorConvention &foreignError) {
// All of this is autogenerated.
loc.markAutoGenerated();
switch (foreignError.getKind()) {
case ForeignErrorConvention::ZeroPreservedResult:
assert(results.size() == 1);
emitResultIsZeroErrorCheck(*this, loc, results[0], errorSlot,
suppressErrorCheck,
/*zeroIsError*/ true);
return;
case ForeignErrorConvention::ZeroResult:
assert(results.size() == 1);
emitResultIsZeroErrorCheck(*this, loc, results.pop_back_val(),
errorSlot, suppressErrorCheck,
/*zeroIsError*/ true);
return;
case ForeignErrorConvention::NonZeroResult:
assert(results.size() == 1);
emitResultIsZeroErrorCheck(*this, loc, results.pop_back_val(),
errorSlot, suppressErrorCheck,
/*zeroIsError*/ false);
return;
case ForeignErrorConvention::NilResult:
assert(results.size() == 1);
results[0] = emitResultIsNilErrorCheck(*this, loc, results[0], errorSlot,
suppressErrorCheck);
return;
case ForeignErrorConvention::NonNilError:
// Leave the direct results alone.
emitErrorIsNonNilErrorCheck(*this, loc, errorSlot, suppressErrorCheck);
return;
}
llvm_unreachable("bad foreign error convention kind");
}
开发者ID:AlexShiLucky,项目名称:swift,代码行数:45,代码来源:SILGenForeignError.cpp
示例16: emitSourceLocationArgs
static void emitSourceLocationArgs(SILGenFunction &gen,
SILLocation loc,
ManagedValue (&args)[4]) {
auto &ctx = gen.getASTContext();
auto sourceLoc = loc.getSourceLoc();
StringRef filename = "";
unsigned line = 0;
if (sourceLoc.isValid()) {
unsigned bufferID = ctx.SourceMgr.findBufferContainingLoc(sourceLoc);
filename = ctx.SourceMgr.getIdentifierForBuffer(bufferID);
line = ctx.SourceMgr.getLineAndColumn(sourceLoc).first;
}
bool isASCII = true;
for (unsigned char c : filename) {
if (c > 127) {
isASCII = false;
break;
}
}
auto wordTy = SILType::getBuiltinWordType(ctx);
auto i1Ty = SILType::getBuiltinIntegerType(1, ctx);
// File
SILValue literal = gen.B.createStringLiteral(loc, filename,
StringLiteralInst::Encoding::UTF8);
args[0] = ManagedValue::forUnmanaged(literal);
// File length
literal = gen.B.createIntegerLiteral(loc, wordTy, filename.size());
args[1] = ManagedValue::forUnmanaged(literal);
// File is ascii
literal = gen.B.createIntegerLiteral(loc, i1Ty, isASCII);
args[2] = ManagedValue::forUnmanaged(literal);
// Line
literal = gen.B.createIntegerLiteral(loc, wordTy, line);
args[3] = ManagedValue::forUnmanaged(literal);
}
开发者ID:mahzonghui,项目名称:swift,代码行数:39,代码来源:SILGenConvert.cpp
示例17: emitNoteDiagnostic
/// Emits an explanatory note if there is useful information to note or if there
/// is an interesting SourceLoc to point at.
/// Returns true if a diagnostic was emitted.
static bool emitNoteDiagnostic(SILInstruction *badInst, UnknownReason reason,
SILLocation fallbackLoc) {
auto loc = skipInternalLocations(badInst->getDebugLocation()).getLocation();
if (loc.isNull()) {
// If we have important clarifying information, make sure to emit it.
if (reason == UnknownReason::Default || fallbackLoc.isNull())
return false;
loc = fallbackLoc;
}
auto &ctx = badInst->getModule().getASTContext();
auto sourceLoc = loc.getSourceLoc();
switch (reason) {
case UnknownReason::Default:
diagnose(ctx, sourceLoc, diag::constexpr_unknown_reason_default)
.highlight(loc.getSourceRange());
break;
case UnknownReason::TooManyInstructions:
// TODO: Should pop up a level of the stack trace.
diagnose(ctx, sourceLoc, diag::constexpr_too_many_instructions,
ConstExprLimit)
.highlight(loc.getSourceRange());
break;
case UnknownReason::Loop:
diagnose(ctx, sourceLoc, diag::constexpr_loop)
.highlight(loc.getSourceRange());
break;
case UnknownReason::Overflow:
diagnose(ctx, sourceLoc, diag::constexpr_overflow)
.highlight(loc.getSourceRange());
break;
case UnknownReason::Trap:
diagnose(ctx, sourceLoc, diag::constexpr_trap)
.highlight(loc.getSourceRange());
break;
}
return true;
}
开发者ID:phausler,项目名称:swift,代码行数:41,代码来源:SILConstants.cpp
示例18: diagnoseUnreachableBlock
/// \brief Issue an "unreachable code" diagnostic if the blocks contains or
/// leads to another block that contains user code.
///
/// Note, we rely on SILLocation information to determine if SILInstructions
/// correspond to user code.
static bool diagnoseUnreachableBlock(const SILBasicBlock &B,
SILModule &M,
const SILBasicBlockSet &Reachable,
UnreachableUserCodeReportingState *State,
const SILBasicBlock *TopLevelB,
llvm::SmallPtrSetImpl<const SILBasicBlock*> &Visited){
if (Visited.count(&B))
return false;
Visited.insert(&B);
assert(State);
for (auto I = B.begin(), E = B.end(); I != E; ++I) {
SILLocation Loc = I->getLoc();
// If we've reached an implicit return, we have not found any user code and
// can stop searching for it.
if (Loc.is<ImplicitReturnLocation>() || Loc.isAutoGenerated())
return false;
// Check if the instruction corresponds to user-written code, also make
// sure we don't report an error twice for the same instruction.
if (isUserCode(&*I) && !State->BlocksWithErrors.count(&B)) {
// Emit the diagnostic.
auto BrInfoIter = State->MetaMap.find(TopLevelB);
assert(BrInfoIter != State->MetaMap.end());
auto BrInfo = BrInfoIter->second;
switch (BrInfo.Kind) {
case (UnreachableKind::FoldedBranch):
// Emit the diagnostic on the unreachable block and emit the
// note on the branch responsible for the unreachable code.
diagnose(M.getASTContext(), Loc.getSourceLoc(), diag::unreachable_code);
diagnose(M.getASTContext(), BrInfo.Loc.getSourceLoc(),
diag::unreachable_code_branch, BrInfo.CondIsAlwaysTrue);
break;
case (UnreachableKind::FoldedSwitchEnum): {
// If we are warning about a switch condition being a constant, the main
// emphasis should be on the condition (to ensure we have a single
// message per switch).
const SwitchStmt *SS = BrInfo.Loc.getAsASTNode<SwitchStmt>();
if (!SS)
break;
assert(SS);
const Expr *SE = SS->getSubjectExpr();
diagnose(M.getASTContext(), SE->getLoc(), diag::switch_on_a_constant);
diagnose(M.getASTContext(), Loc.getSourceLoc(),
diag::unreachable_code_note);
break;
}
case (UnreachableKind::NoreturnCall): {
// Specialcase when we are warning about unreachable code after a call
// to a noreturn function.
if (!BrInfo.Loc.isASTNode<ExplicitCastExpr>()) {
assert(BrInfo.Loc.isASTNode<ApplyExpr>());
diagnose(M.getASTContext(), Loc.getSourceLoc(),
diag::unreachable_code);
diagnose(M.getASTContext(), BrInfo.Loc.getSourceLoc(),
diag::call_to_noreturn_note);
}
break;
}
}
// Record that we've reported this unreachable block to avoid duplicates
// in the future.
State->BlocksWithErrors.insert(&B);
return true;
}
}
// This block could be empty if it's terminator has been folded.
if (B.empty())
return false;
// If we have not found user code in this block, inspect it's successors.
// Check if at least one of the successors contains user code.
for (auto I = B.succ_begin(), E = B.succ_end(); I != E; ++I) {
SILBasicBlock *SB = *I;
bool HasReachablePred = false;
for (auto PI = SB->pred_begin(), PE = SB->pred_end(); PI != PE; ++PI) {
if (Reachable.count(*PI))
HasReachablePred = true;
}
// If all of the predecessors of this successor are unreachable, check if
// it contains user code.
if (!HasReachablePred && diagnoseUnreachableBlock(*SB, M, Reachable,
State, TopLevelB, Visited))
return true;
}
return false;
}
开发者ID:pietbrauer,项目名称:swift,代码行数:100,代码来源:DiagnoseUnreachable.cpp
示例19: runOnFunctionRecursively
/// \brief Inlines all mandatory inlined functions into the body of a function,
/// first recursively inlining all mandatory apply instructions in those
/// functions into their bodies if necessary.
///
/// \param F the function to be processed
/// \param AI nullptr if this is being called from the top level; the relevant
/// ApplyInst requiring the recursive call when non-null
/// \param FullyInlinedSet the set of all functions already known to be fully
/// processed, to avoid processing them over again
/// \param SetFactory an instance of ImmutableFunctionSet::Factory
/// \param CurrentInliningSet the set of functions currently being inlined in
/// the current call stack of recursive calls
///
/// \returns true if successful, false if failed due to circular inlining.
static bool
runOnFunctionRecursively(SILFunction *F, FullApplySite AI,
SILModule::LinkingMode Mode,
DenseFunctionSet &FullyInlinedSet,
ImmutableFunctionSet::Factory &SetFactory,
ImmutableFunctionSet CurrentInliningSet,
ClassHierarchyAnalysis *CHA) {
// Avoid reprocessing functions needlessly.
if (FullyInlinedSet.count(F))
return true;
// Prevent attempt to circularly inline.
if (CurrentInliningSet.contains(F)) {
// This cannot happen on a top-level call, so AI should be non-null.
assert(AI && "Cannot have circular inline without apply");
SILLocation L = AI.getLoc();
assert(L && "Must have location for transparent inline apply");
diagnose(F->getModule().getASTContext(), L.getStartSourceLoc(),
diag::circular_transparent);
return false;
}
// Add to the current inlining set (immutably, so we only affect the set
// during this call and recursive subcalls).
CurrentInliningSet = SetFactory.add(CurrentInliningSet, F);
SmallVector<SILValue, 16> CaptureArgs;
SmallVector<SILValue, 32> FullArgs;
for (auto FI = F->begin(), FE = F->end(); FI != FE; ++FI) {
for (auto I = FI->begin(), E = FI->end(); I != E; ++I) {
FullApplySite InnerAI = FullApplySite::isa(&*I);
if (!InnerAI)
continue;
auto *ApplyBlock = InnerAI.getParent();
auto NewInstPair = tryDevirtualizeApply(InnerAI, CHA);
if (auto *NewInst = NewInstPair.first) {
replaceDeadApply(InnerAI, NewInst);
if (auto *II = dyn_cast<SILInstruction>(NewInst))
I = II->getIterator();
else
I = NewInst->getParentBlock()->begin();
auto NewAI = FullApplySite::isa(NewInstPair.second.getInstruction());
if (!NewAI)
continue;
InnerAI = NewAI;
}
SILLocation Loc = InnerAI.getLoc();
SILValue CalleeValue = InnerAI.getCallee();
bool IsThick;
PartialApplyInst *PAI;
SILFunction *CalleeFunction = getCalleeFunction(InnerAI, IsThick,
CaptureArgs, FullArgs,
PAI,
Mode);
if (!CalleeFunction ||
CalleeFunction->isTransparent() == IsNotTransparent)
continue;
if (F->isFragile() &&
!CalleeFunction->hasValidLinkageForFragileRef()) {
if (!CalleeFunction->hasValidLinkageForFragileInline()) {
llvm::errs() << "caller: " << F->getName() << "\n";
llvm::errs() << "callee: " << CalleeFunction->getName() << "\n";
llvm_unreachable("Should never be inlining a resilient function into "
"a fragile function");
}
continue;
}
// Then recursively process it first before trying to inline it.
if (!runOnFunctionRecursively(CalleeFunction, InnerAI, Mode,
FullyInlinedSet, SetFactory,
CurrentInliningSet, CHA)) {
// If we failed due to circular inlining, then emit some notes to
// trace back the failure if we have more information.
// FIXME: possibly it could be worth recovering and attempting other
// inlines within this same recursive call rather than simply
// propagating the failure.
if (AI) {
SILLocation L = AI.getLoc();
//.........这里部分代码省略.........
开发者ID:KoKumagai,项目名称:swift,代码行数:101,代码来源:MandatoryInlining.cpp
示例20: assert
void SILGenFunction::emitClassConstructorInitializer(ConstructorDecl *ctor) {
MagicFunctionName = SILGenModule::getMagicFunctionName(ctor);
assert(ctor->getBody() && "Class constructor without a body?");
// True if this constructor delegates to a peer constructor with self.init().
bool isDelegating = false;
if (!ctor->hasStubImplementation()) {
isDelegating = ctor->getDelegatingOrChainedInitKind(nullptr) ==
ConstructorDecl::BodyInitKind::Delegating;
}
// Set up the 'self' argument. If this class has a superclass, we set up
// self as a box. This allows "self reassignment" to happen in super init
// method chains, which is important for interoperating with Objective-C
// classes. We also use a box for delegating constructors, since the
// delegated-to initializer may also replace self.
//
// TODO: If we could require Objective-C classes to have an attribute to get
// this behavior, we could avoid runtime overhead here.
VarDecl *selfDecl = ctor->getImplicitSelfDecl();
auto *dc = ctor->getDeclContext();
auto selfClassDecl = dc->getAsClassOrClassExtensionContext();
bool NeedsBoxForSelf = isDelegating ||
(selfClassDecl->hasSuperclass() && !ctor->hasStubImplementation());
bool usesObjCAllocator = Lowering::usesObjCAllocator(selfClassDecl);
// If needed, mark 'self' as uninitialized so that DI knows to
// enforce its DI properties on stored properties.
MarkUninitializedInst::Kind MUKind;
if (isDelegating)
MUKind = MarkUninitializedInst::DelegatingSelf;
else if (selfClassDecl->requiresStoredPropertyInits() &&
usesObjCAllocator) {
// Stored properties will be initialized in a separate
// .cxx_construct method called by the Objective-C runtime.
assert(selfClassDecl->hasSuperclass() &&
"Cannot use ObjC allocation without a superclass");
MUKind = MarkUninitializedInst::DerivedSelfOnly;
} else if (selfClassDecl->hasSuperclass())
MUKind = MarkUninitializedInst::DerivedSelf;
else
MUKind = MarkUninitializedInst::RootSelf;
if (NeedsBoxForSelf) {
// Allocate the local variable for 'self'.
emitLocalVariableWithCleanup(selfDecl, false)->finishInitialization(*this);
auto &SelfVarLoc = VarLocs[selfDecl];
SelfVarLoc.value = B.createMarkUninitialized(selfDecl,
SelfVarLoc.value, MUKind);
}
// Emit the prolog for the non-self arguments.
// FIXME: Handle self along with the other body patterns.
emitProlog(ctor->getParameterList(1),
TupleType::getEmpty(F.getASTContext()), ctor, ctor->hasThrows());
SILType selfTy = getLoweredLoadableType(selfDecl->getType());
SILValue selfArg = new (SGM.M) SILArgument(F.begin(), selfTy, selfDecl);
if (!NeedsBoxForSelf) {
SILLocation PrologueLoc(selfDecl);
PrologueLoc.markAsPrologue();
B.createDebugValue(PrologueLoc, selfArg);
}
if (!ctor->hasStubImplementation()) {
assert(selfTy.hasReferenceSemantics() &&
"can't emit a value type ctor here");
if (NeedsBoxForSelf) {
SILLocation prologueLoc = RegularLocation(ctor);
prologueLoc.markAsPrologue();
B.createStore(prologueLoc, selfArg, VarLocs[selfDecl].value,
StoreOwnershipQualifier::Unqualified);
} else {
selfArg = B.createMarkUninitialized(selfDecl, selfArg, MUKind);
VarLocs[selfDecl] = VarLoc::get(selfArg);
enterDestroyCleanup(VarLocs[selfDecl].value);
}
}
// Prepare the end of initializer location.
SILLocation endOfInitLoc = RegularLocation(ctor);
endOfInitLoc.pointToEnd();
// Create a basic block to jump to for the implicit 'self' return.
// We won't emit the block until after we've emitted the body.
prepareEpilog(Type(), ctor->hasThrows(),
CleanupLocation::get(endOfInitLoc));
// If the constructor can fail, set up an alternative epilog for constructor
// failure.
SILBasicBlock *failureExitBB = nullptr;
SILArgument *failureExitArg = nullptr;
auto &resultLowering = getTypeLowering(ctor->getResultType());
if (ctor->getFailability() != OTK_None) {
SILBasicBlock *failureBB = createBasicBlock(FunctionSection::Postmatter);
//.........这里部分代码省略.........
开发者ID:mauruskuehne,项目名称:swift,代码行数:101,代码来源:SILGenConstructor.cpp
注:本文中的SILLocation类示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论