aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2012-01-20 01:26:23 +0000
committerEli Friedman <eli.friedman@gmail.com>2012-01-20 01:26:23 +0000
commitef331b783bb96a0f0e34afdb7ef46677dc4764cb (patch)
tree76961cf2e3a83c1dedb9490266157be929dd64b4 /lib/Sema/SemaExpr.cpp
parent2bf8fd84087231fd92dfdebe18895e01a6ae405c (diff)
Remove PotentiallyPotentiallyEvaluated, and replace it with a much simpler and less error-prone way of handling the relevant cases. Towards marking of whether a declaration is used more accurately.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148522 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r--lib/Sema/SemaExpr.cpp129
1 files changed, 43 insertions, 86 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 1bb4140bd0..0b0b825ed2 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -40,6 +40,7 @@
#include "clang/Sema/ParsedTemplate.h"
#include "clang/Sema/SemaFixItUtils.h"
#include "clang/Sema/Template.h"
+#include "TreeTransform.h"
using namespace clang;
using namespace sema;
@@ -1208,10 +1209,6 @@ diagnoseUncapturableValueReference(Sema &S, SourceLocation loc,
case Sema::PotentiallyEvaluated:
case Sema::PotentiallyEvaluatedIfUsed:
break;
-
- case Sema::PotentiallyPotentiallyEvaluated:
- // FIXME: delay these!
- break;
}
// Don't diagnose about capture if we're not actually in code right
@@ -9358,38 +9355,53 @@ bool Sema::VerifyIntegerConstantExpression(const Expr *E, llvm::APSInt *Result,
return false;
}
-void Sema::ExpressionEvaluationContextRecord::Destroy() {
- delete PotentiallyReferenced;
- delete SavedDiag;
- delete SavedRuntimeDiag;
- delete SavedDelayedDiag;
- PotentiallyReferenced = 0;
- SavedDiag = 0;
- SavedRuntimeDiag = 0;
- SavedDelayedDiag = 0;
-}
+namespace {
+ // Handle the case where we conclude a expression which we speculatively
+ // considered to be unevaluated is actually evaluated.
+ class TransformToPE : public TreeTransform<TransformToPE> {
+ typedef TreeTransform<TransformToPE> BaseTransform;
-void Sema::ExpressionEvaluationContextRecord::addDiagnostic(
- SourceLocation Loc, const PartialDiagnostic &PD) {
- if (!SavedDiag)
- SavedDiag = new PotentiallyEmittedDiagnostics;
- SavedDiag->push_back(std::make_pair(Loc, PD));
-}
+ public:
+ TransformToPE(Sema &SemaRef) : BaseTransform(SemaRef) { }
-void Sema::ExpressionEvaluationContextRecord::addRuntimeDiagnostic(
- const sema::PossiblyUnreachableDiag &PUD) {
- if (!SavedRuntimeDiag)
- SavedRuntimeDiag = new PotentiallyEmittedPossiblyUnreachableDiag;
- SavedRuntimeDiag->push_back(PUD);
-}
+ // Make sure we redo semantic analysis
+ bool AlwaysRebuild() { return true; }
-void Sema::ExpressionEvaluationContextRecord::addDelayedDiagnostic(
- const sema::DelayedDiagnostic &DD) {
- if (!SavedDelayedDiag)
- SavedDelayedDiag = new PotentiallyEmittedDelayedDiag;
- SavedDelayedDiag->push_back(DD);
+ // We need to special-case DeclRefExprs referring to FieldDecls which
+ // are not part of a member pointer formation; normal TreeTransforming
+ // doesn't catch this case because of the way we represent them in the AST.
+ // FIXME: This is a bit ugly; is it really the best way to handle this
+ // case?
+ //
+ // Error on DeclRefExprs referring to FieldDecls.
+ ExprResult TransformDeclRefExpr(DeclRefExpr *E) {
+ if (isa<FieldDecl>(E->getDecl()) &&
+ SemaRef.ExprEvalContexts.back().Context != Sema::Unevaluated)
+ return SemaRef.Diag(E->getLocation(),
+ diag::err_invalid_non_static_member_use)
+ << E->getDecl() << E->getSourceRange();
+
+ return BaseTransform::TransformDeclRefExpr(E);
+ }
+
+ // Exception: filter out member pointer formation
+ ExprResult TransformUnaryOperator(UnaryOperator *E) {
+ if (E->getOpcode() == UO_AddrOf && E->getType()->isMemberPointerType())
+ return E;
+
+ return BaseTransform::TransformUnaryOperator(E);
+ }
+
+ };
}
+ExprResult Sema::TranformToPotentiallyEvaluated(Expr *E) {
+ ExprEvalContexts.back().Context =
+ ExprEvalContexts[ExprEvalContexts.size()-2].Context;
+ if (ExprEvalContexts.back().Context == Unevaluated)
+ return E;
+ return TransformToPE(*this).TransformExpr(E);
+}
void
Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext) {
@@ -9405,46 +9417,6 @@ void Sema::PopExpressionEvaluationContext() {
ExpressionEvaluationContextRecord Rec = ExprEvalContexts.back();
ExprEvalContexts.pop_back();
- if (Rec.Context == PotentiallyPotentiallyEvaluated) {
- if (Rec.PotentiallyReferenced) {
- // 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).
- for (PotentiallyReferencedDecls::iterator
- I = Rec.PotentiallyReferenced->begin(),
- IEnd = Rec.PotentiallyReferenced->end();
- I != IEnd; ++I)
- MarkDeclarationReferenced(I->first, I->second);
- }
-
- if (Rec.SavedDiag) {
- // Emit any pending diagnostics.
- for (PotentiallyEmittedDiagnostics::iterator
- I = Rec.SavedDiag->begin(),
- IEnd = Rec.SavedDiag->end();
- I != IEnd; ++I)
- Diag(I->first, I->second);
- }
-
- if (Rec.SavedDelayedDiag) {
- // Emit any pending delayed diagnostics.
- for (PotentiallyEmittedDelayedDiag::iterator
- I = Rec.SavedDelayedDiag->begin(),
- IEnd = Rec.SavedDelayedDiag->end();
- I != IEnd; ++I)
- DelayedDiagnostics.add(*I);
- }
-
- if (Rec.SavedRuntimeDiag) {
- // Emit any pending runtime diagnostics.
- for (PotentiallyEmittedPossiblyUnreachableDiag::iterator
- I = Rec.SavedRuntimeDiag->begin(),
- IEnd = Rec.SavedRuntimeDiag->end();
- I != IEnd; ++I)
- FunctionScopes.back()->PossiblyUnreachableDiags.push_back(*I);
- }
- }
-
// When are coming out of an unevaluated context, clear out any
// temporaries that we may have created as part of the evaluation of
// the expression in that context: they aren't relevant because they
@@ -9458,9 +9430,6 @@ void Sema::PopExpressionEvaluationContext() {
} else {
ExprNeedsCleanups |= Rec.ParentNeedsCleanups;
}
-
- // Destroy the popped expression evaluation record.
- Rec.Destroy();
}
void Sema::DiscardCleanupsInEvaluationContext() {
@@ -9516,13 +9485,6 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
// "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.
- ExprEvalContexts.back().addReferencedDecl(Loc, D);
- return;
-
case PotentiallyEvaluatedIfUsed:
// Referenced declarations will only be used if the construct in the
// containing expression is used.
@@ -9806,11 +9768,6 @@ bool Sema::DiagRuntimeBehavior(SourceLocation Loc, const Stmt *Statement,
Diag(Loc, PD);
return true;
-
- case PotentiallyPotentiallyEvaluated:
- ExprEvalContexts.back().addRuntimeDiagnostic(
- sema::PossiblyUnreachableDiag(PD, Loc, Statement));
- break;
}
return false;