summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaExpr.cpp')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp51
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()) {
OpenPOWER on IntegriCloud