clang: lib/AST/ByteCode/State.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

15

16using namespace clang;

18

19State::~State() {}

20

22 unsigned ExtraNotes) {

23 return diag(Loc, DiagId, ExtraNotes, false);

24}

25

27 unsigned ExtraNotes) {

28 if (getEvalStatus().Diag)

29 return diag(E->getExprLoc(), DiagId, ExtraNotes, false);

30 setActiveDiagnostic(false);

32}

33

35 unsigned ExtraNotes) {

36 if (getEvalStatus().Diag)

37 return diag(SI.getLoc(), DiagId, ExtraNotes, false);

38 setActiveDiagnostic(false);

40}

41

43 unsigned ExtraNotes) {

44

45

46 if (!getEvalStatus().Diag || !getEvalStatus().Diag->empty()) {

47 setActiveDiagnostic(false);

49 }

50 return diag(Loc, DiagId, ExtraNotes, true);

51}

52

54 unsigned ExtraNotes) {

55 return CCEDiag(E->getExprLoc(), DiagId, ExtraNotes);

56}

57

59 unsigned ExtraNotes) {

60 return CCEDiag(SI.getLoc(), DiagId, ExtraNotes);

61}

62

64 if (!hasActiveDiagnostic())

67}

68

70 if (hasActiveDiagnostic()) {

71 getEvalStatus().Diag->insert(getEvalStatus().Diag->end(), Diags.begin(),

72 Diags.end());

73 }

74}

75

77 return getASTContext().getDiagnostics().Report(Loc, DiagId);

78}

79

80

83 getEvalStatus().Diag->push_back(std::make_pair(Loc, PD));

84 return getEvalStatus().Diag->back().second;

85}

86

88 unsigned ExtraNotes, bool IsCCEDiag) {

90 if (EvalStatus.Diag) {

91 if (hasPriorDiagnostic()) {

93 }

94

95 unsigned CallStackNotes = getCallStackDepth() - 1;

96 unsigned Limit =

97 getASTContext().getDiagnostics().getConstexprBacktraceLimit();

98 if (Limit)

99 CallStackNotes = std::min(CallStackNotes, Limit + 1);

100 if (checkingPotentialConstantExpression())

101 CallStackNotes = 0;

102

103 setActiveDiagnostic(true);

104 setFoldFailureDiagnostic(!IsCCEDiag);

105 EvalStatus.Diag->clear();

106 EvalStatus.Diag->reserve(1 + ExtraNotes + CallStackNotes);

107 addDiag(Loc, DiagId);

108 if (!checkingPotentialConstantExpression()) {

109 addCallStack(Limit);

110 }

112 }

113 setActiveDiagnostic(false);

115}

116

118 return getASTContext().getLangOpts();

119}

120

121void State::addCallStack(unsigned Limit) {

122

123 unsigned ActiveCalls = getCallStackDepth() - 1;

124 unsigned SkipStart = ActiveCalls, SkipEnd = SkipStart;

125 if (Limit && Limit < ActiveCalls) {

126 SkipStart = Limit / 2 + Limit % 2;

127 SkipEnd = ActiveCalls - Limit / 2;

128 }

129

130

131 unsigned CallIdx = 0;

132 const Frame *Top = getCurrentFrame();

133 const Frame *Bottom = getBottomFrame();

134 for (const Frame *F = Top; F != Bottom; F = F->getCaller(), ++CallIdx) {

135 SourceRange CallRange = F->getCallRange();

136

137

138 if (CallIdx >= SkipStart && CallIdx < SkipEnd) {

139 if (CallIdx == SkipStart) {

140

141 addDiag(CallRange.getBegin(), diag::note_constexpr_calls_suppressed)

142 << unsigned(ActiveCalls - Limit);

143 }

144 continue;

145 }

146

147

148

149 if (const auto *CD =

150 dyn_cast_if_present(F->getCallee());

151 CD && CD->isInheritingConstructor()) {

152 addDiag(CallRange.getBegin(),

153 diag::note_constexpr_inherited_ctor_call_here)

154 << CD->getParent();

155 continue;

156 }

157

159 llvm::raw_svector_ostream Out(Buffer);

160 F->describe(Out);

161 if (!Buffer.empty())

162 addDiag(CallRange.getBegin(), diag::note_constexpr_call_here)

163 << Out.str() << CallRange;

164 }

165}

Defines the clang::ASTContext interface.

static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)

Produce a diagnostic highlighting some portion of a literal.

Implements a partial diagnostic which may not be emitted.

A little helper class used to produce diagnostics.

This represents one expression.

SourceLocation getExprLoc() const LLVM_READONLY

getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

A partial diagnostic which we might know in advance that we are not going to emit.

Encodes a location in the source.

A trivial tuple used to represent a source range.

SourceLocation getBegin() const

Base class for stack frames, shared between VM and walker.

virtual Frame * getCaller() const =0

Returns a pointer to the caller frame.

Describes the statement/declaration an opcode was generated from.

SourceLocation getLoc() const

The JSON file list parser is used to communicate input to InstallAPI.

EvalStatus is a struct with detailed info about an evaluation in progress.

SmallVectorImpl< PartialDiagnosticAt > * Diag

Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...