Index: clang/lib/AST/ExprConstant.cpp =================================================================== --- clang/lib/AST/ExprConstant.cpp +++ clang/lib/AST/ExprConstant.cpp @@ -551,8 +551,8 @@ /// Temporaries - Temporary lvalues materialized within this stack frame. MapTy Temporaries; - /// CallLoc - The location of the call expression for this call. - SourceLocation CallLoc; + /// CallRange - The source range of the call expression for this call. + SourceRange CallRange; /// Index - The call index of this call. unsigned Index; @@ -586,7 +586,7 @@ llvm::DenseMap LambdaCaptureFields; FieldDecl *LambdaThisCaptureField = nullptr; - CallStackFrame(EvalInfo &Info, SourceLocation CallLoc, + CallStackFrame(EvalInfo &Info, SourceRange CallRange, const FunctionDecl *Callee, const LValue *This, const Expr *CallExpr, CallRef Arguments); ~CallStackFrame(); @@ -630,7 +630,7 @@ void describe(llvm::raw_ostream &OS) const override; Frame *getCaller() const override { return Caller; } - SourceLocation getCallLocation() const override { return CallLoc; } + SourceRange getCallRange() const override { return CallRange; } const FunctionDecl *getCallee() const override { return Callee; } bool isStdFunction() const { @@ -1468,11 +1468,11 @@ setInvalid(); } -CallStackFrame::CallStackFrame(EvalInfo &Info, SourceLocation CallLoc, +CallStackFrame::CallStackFrame(EvalInfo &Info, SourceRange CallRange, const FunctionDecl *Callee, const LValue *This, const Expr *CallExpr, CallRef Call) : Info(Info), Caller(Info.CurrentCall), Callee(Callee), This(This), - CallExpr(CallExpr), Arguments(Call), CallLoc(CallLoc), + CallExpr(CallExpr), Arguments(Call), CallRange(CallRange), Index(Info.NextCallIndex++) { Info.CurrentCall = this; ++Info.CallStackDepth; @@ -6237,7 +6237,7 @@ if (!Info.CheckCallLimit(CallLoc)) return false; - CallStackFrame Frame(Info, CallLoc, Callee, This, E, Call); + CallStackFrame Frame(Info, E->getSourceRange(), Callee, This, E, Call); // For a trivial copy or move assignment, perform an APValue copy. This is // essential for unions, where the operations performed by the assignment @@ -6302,7 +6302,7 @@ Info, ObjectUnderConstruction{This.getLValueBase(), This.Designator.Entries}, RD->getNumBases()); - CallStackFrame Frame(Info, CallLoc, Definition, &This, E, Call); + CallStackFrame Frame(Info, E->getSourceRange(), Definition, &This, E, Call); // FIXME: Creating an APValue just to hold a nonexistent return value is // wasteful. @@ -12149,8 +12149,9 @@ Callee->getIdentifier()->isStr("is_constant_evaluated")))) { // FIXME: Find a better way to avoid duplicated diagnostics. if (Info.EvalStatus.Diag) - Info.report((Info.CallStackDepth == 1) ? E->getExprLoc() - : Info.CurrentCall->CallLoc, + Info.report((Info.CallStackDepth == 1) + ? E->getExprLoc() + : Info.CurrentCall->getCallRange().getBegin(), diag::warn_is_constant_evaluated_always_true_constexpr) << (Info.CallStackDepth == 1 ? "__builtin_is_constant_evaluated" : "std::is_constant_evaluated"); Index: clang/lib/AST/Interp/Frame.h =================================================================== --- clang/lib/AST/Interp/Frame.h +++ clang/lib/AST/Interp/Frame.h @@ -33,7 +33,7 @@ virtual Frame *getCaller() const = 0; /// Returns the location of the call site. - virtual SourceLocation getCallLocation() const = 0; + virtual SourceRange getCallRange() const = 0; /// Returns the called function's declaration. virtual const FunctionDecl *getCallee() const = 0; Index: clang/lib/AST/Interp/InterpFrame.h =================================================================== --- clang/lib/AST/Interp/InterpFrame.h +++ clang/lib/AST/Interp/InterpFrame.h @@ -56,7 +56,7 @@ Frame *getCaller() const override; /// Returns the location of the call to the frame. - SourceLocation getCallLocation() const override; + SourceRange getCallRange() const override; /// Returns the caller. const FunctionDecl *getCallee() const override; Index: clang/lib/AST/Interp/InterpFrame.cpp =================================================================== --- clang/lib/AST/Interp/InterpFrame.cpp +++ clang/lib/AST/Interp/InterpFrame.cpp @@ -176,10 +176,10 @@ return S.getSplitFrame(); } -SourceLocation InterpFrame::getCallLocation() const { +SourceRange InterpFrame::getCallRange() const { if (!Caller->Func) - return S.getLocation(nullptr, {}); - return S.getLocation(Caller->Func, RetPC - sizeof(uintptr_t)); + return S.getRange(nullptr, {}); + return S.getRange(Caller->Func, RetPC - sizeof(uintptr_t)); } const FunctionDecl *InterpFrame::getCallee() const { Index: clang/lib/AST/Interp/State.cpp =================================================================== --- clang/lib/AST/Interp/State.cpp +++ clang/lib/AST/Interp/State.cpp @@ -129,13 +129,13 @@ const Frame *Top = getCurrentFrame(); const Frame *Bottom = getBottomFrame(); for (const Frame *F = Top; F != Bottom; F = F->getCaller(), ++CallIdx) { - SourceLocation CallLocation = F->getCallLocation(); + SourceRange CallRange = F->getCallRange(); // Skip this call? if (CallIdx >= SkipStart && CallIdx < SkipEnd) { if (CallIdx == SkipStart) { // Note that we're skipping calls. - addDiag(CallLocation, diag::note_constexpr_calls_suppressed) + addDiag(CallRange.getBegin(), diag::note_constexpr_calls_suppressed) << unsigned(ActiveCalls - Limit); } continue; @@ -146,7 +146,8 @@ if (const auto *CD = dyn_cast_if_present(F->getCallee()); CD && CD->isInheritingConstructor()) { - addDiag(CallLocation, diag::note_constexpr_inherited_ctor_call_here) + addDiag(CallRange.getBegin(), + diag::note_constexpr_inherited_ctor_call_here) << CD->getParent(); continue; } @@ -154,6 +155,7 @@ SmallString<128> Buffer; llvm::raw_svector_ostream Out(Buffer); F->describe(Out); - addDiag(CallLocation, diag::note_constexpr_call_here) << Out.str(); + addDiag(CallRange.getBegin(), diag::note_constexpr_call_here) + << Out.str() << CallRange; } } Index: clang/test/Misc/constexpr-source-ranges.cpp =================================================================== --- clang/test/Misc/constexpr-source-ranges.cpp +++ clang/test/Misc/constexpr-source-ranges.cpp @@ -13,3 +13,13 @@ constexpr const int *P = &I; constexpr long L = (long)P; // CHECK: constexpr-source-ranges.cpp:14:20:{14:20-14:27} + + +constexpr int div(bool a, bool b) { + return 1 / (int)b; +} +constexpr int ints(int a, int b, int c, int d) { + return 1; +} +static_assert(ints(1, div(true, false), 2, div(false, true)) == 1, ""); +// CHECK: constexpr-source-ranges.cpp:24:23:{24:23-24:39}