diff options
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 51 |
1 files changed, 47 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index d0cd23e8592..c005f103a30 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -5432,6 +5432,35 @@ bool Sema::VerifyIntegerConstantExpression(const Expr *E, llvm::APSInt *Result){ return false; } +Sema::ExpressionEvaluationContext +Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext) { + // Introduce a new set of potentially referenced declarations to the stack. + if (NewContext == PotentiallyPotentiallyEvaluated) + PotentiallyReferencedDeclStack.push_back(PotentiallyReferencedDecls()); + + std::swap(ExprEvalContext, NewContext); + return NewContext; +} + +void +Sema::PopExpressionEvaluationContext(ExpressionEvaluationContext OldContext, + ExpressionEvaluationContext NewContext) { + ExprEvalContext = NewContext; + + if (OldContext == PotentiallyPotentiallyEvaluated) { + // Mark any remaining declarations in the current position of the stack + // as "referenced". If they were not meant to be referenced, semantic + // analysis would have eliminated them (e.g., in ActOnCXXTypeId). + PotentiallyReferencedDecls RemainingDecls; + RemainingDecls.swap(PotentiallyReferencedDeclStack.back()); + PotentiallyReferencedDeclStack.pop_back(); + + for (PotentiallyReferencedDecls::iterator I = RemainingDecls.begin(), + IEnd = RemainingDecls.end(); + I != IEnd; ++I) + MarkDeclarationReferenced(I->first, I->second); + } +} /// \brief Note that the given declaration was referenced in the source code. /// @@ -5456,10 +5485,24 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) { if (CurContext->isDependentContext()) return; - // If we are in an unevaluated operand, don't mark any definitions as used. - if (InUnevaluatedOperand) - return; - + switch (ExprEvalContext) { + case Unevaluated: + // We are in an expression that is not potentially evaluated; do nothing. + return; + + case PotentiallyEvaluated: + // We are in a potentially-evaluated expression, so this declaration is + // "used"; handle this below. + break; + + case PotentiallyPotentiallyEvaluated: + // We are in an expression that may be potentially evaluated; queue this + // declaration reference until we know whether the expression is + // potentially evaluated. + PotentiallyReferencedDeclStack.back().push_back(std::make_pair(Loc, D)); + return; + } + // Note that this declaration has been used. if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) { if (Constructor->isImplicit() && Constructor->isDefaultConstructor()) { |