[cfe-commits] r73899 - in /cfe/trunk: include/clang/Parse/Action.h include/clang/Parse/Parser.h lib/Parse/ParseExpr.cpp lib/Parse/ParseExprCXX.cpp lib/Parse/ParseTemplate.cpp lib/Sema/Sema.cpp lib/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Sema/SemaTemplateInstantiateExpr.cpp lib/Sema/SemaTemplateInstantiateStmt.cpp

Douglas Gregor dgregor at apple.com
Mon Jun 22 13:57:12 PDT 2009


Author: dgregor
Date: Mon Jun 22 15:57:11 2009
New Revision: 73899

URL: http://llvm.org/viewvc/llvm-project?rev=73899&view=rev
Log:
Rework the way we track which declarations are "used" during
compilation, and (hopefully) introduce RAII objects for changing the
"potentially evaluated" state at all of the necessary places within
Sema and Parser. Other changes:

  - Set the unevaluated/potentially-evaluated context appropriately
    during template instantiation.
  - We now recognize three different states while parsing or
    instantiating expressions: unevaluated, potentially evaluated, and
    potentially potentially evaluated (for C++'s typeid).
  - When we're in a potentially potentially-evaluated context, queue
    up MarkDeclarationReferenced calls in a stack. For C++ typeid
    expressions that are potentially evaluated, we will play back
    these MarkDeclarationReferenced calls when we exit the
    corresponding potentially potentially-evaluated context.
  - Non-type template arguments are now parsed as constant
    expressions, so they are not potentially-evaluated.


Modified:
    cfe/trunk/include/clang/Parse/Action.h
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/ParseExpr.cpp
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Parse/ParseTemplate.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateStmt.cpp

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=73899&r1=73898&r2=73899&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Mon Jun 22 15:57:11 2009
@@ -637,18 +637,50 @@
   // Expression Parsing Callbacks.
   //===--------------------------------------------------------------------===//
 
-  /// \brief Notifies the action when the parser is processing an unevaluated
-  /// operand.
+  /// \brief Describes how the expressions currently being parsed are
+  /// evaluated at run-time, if at all.
+  enum ExpressionEvaluationContext {
+    /// \brief The current expression and its subexpressions occur within an
+    /// unevaluated operand (C++0x [expr]p8), such as a constant expression
+    /// or the subexpression of \c sizeof, where the type or the value of the
+    /// expression may be significant but no code will be generated to evaluate 
+    /// the value of the expression at run time.
+    Unevaluated,
+    
+    /// \brief The current expression is potentially evaluated at run time, 
+    /// which means that code may be generated to evaluate the value of the 
+    /// expression at run time.
+    PotentiallyEvaluated,
+    
+    /// \brief The current expression may be potentially evaluated or it may
+    /// be unevaluated, but it is impossible to tell from the lexical context.
+    /// This evaluation context is used primary for the operand of the C++
+    /// \c typeid expression, whose argument is potentially evaluated only when
+    /// it is an lvalue of polymorphic class type (C++ [basic.def.odr]p2).
+    PotentiallyPotentiallyEvaluated
+  };
+  
+  /// \brief The parser is entering a new expression evaluation context.
   ///
-  /// \param UnevaluatedOperand true to indicate that the parser is processing
-  /// an unevaluated operand, or false otherwise.
+  /// \param NewContext is the new expression evaluation context.
   ///
-  /// \returns whether the the action module was previously in an unevaluated
-  /// operand.
-  virtual bool setUnevaluatedOperand(bool UnevaluatedOperand) { 
-    return false;
+  /// \returns the previous expression evaluation context.
+  virtual ExpressionEvaluationContext 
+  PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext) {
+    return PotentiallyEvaluated;
   }
   
+  /// \brief The parser is existing an expression evaluation context.
+  ///
+  /// \param OldContext the expression evaluation context that the parser is
+  /// leaving.
+  ///
+  /// \param NewContext the expression evaluation context that the parser is
+  /// returning to.
+  virtual void 
+  PopExpressionEvaluationContext(ExpressionEvaluationContext OldContext,
+                                 ExpressionEvaluationContext NewContext) { }
+  
   // Primary Expressions.
 
   /// \brief Retrieve the source range that corresponds to the given
@@ -1891,6 +1923,29 @@
   virtual void print(llvm::raw_ostream &OS) const;
 };  
   
+/// \brief RAII object that enters a new expression evaluation context.
+class EnterExpressionEvaluationContext {    
+  /// \brief The action object.
+  Action &Actions;
+  
+  /// \brief The previous expression evaluation context.
+  Action::ExpressionEvaluationContext PrevContext;
+
+  /// \brief The current expression evaluation context.
+  Action::ExpressionEvaluationContext CurContext;
+
+public:
+  EnterExpressionEvaluationContext(Action &Actions,
+                              Action::ExpressionEvaluationContext NewContext) 
+    : Actions(Actions), CurContext(NewContext) { 
+      PrevContext = Actions.PushExpressionEvaluationContext(NewContext);
+  }
+    
+  ~EnterExpressionEvaluationContext() {
+    Actions.PopExpressionEvaluationContext(CurContext, PrevContext);
+  }
+};
+  
 }  // end namespace clang
 
 #endif

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=73899&r1=73898&r2=73899&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Mon Jun 22 15:57:11 2009
@@ -104,24 +104,6 @@
       GreaterThanIsOperator = OldGreaterThanIsOperator;
     }
   };
-
-  /// \brief RAII object that enters an unevaluated operand.
-  class EnterUnevaluatedOperand {    
-    /// \brief The action object.
-    Action &Actions;
-    
-    /// \brief Whether we were previously within an unevaluated operand.
-    bool PreviouslyInUnevaluatedOperand;
-    
-  public:
-    explicit EnterUnevaluatedOperand(Action &Actions) : Actions(Actions) { 
-      PreviouslyInUnevaluatedOperand = Actions.setUnevaluatedOperand(true);
-    }
-    
-    ~EnterUnevaluatedOperand() {
-      Actions.setUnevaluatedOperand(PreviouslyInUnevaluatedOperand);
-    }
-  };
   
 public:
   Parser(Preprocessor &PP, Action &Actions);

Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=73899&r1=73898&r2=73899&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Mon Jun 22 15:57:11 2009
@@ -279,7 +279,8 @@
   // C++ [basic.def.odr]p2:
   //   An expression is potentially evaluated unless it appears where an 
   //   integral constant expression is required (see 5.19) [...].
-  EnterUnevaluatedOperand Unevaluated(Actions);
+  EnterExpressionEvaluationContext Unevaluated(Actions,
+                                               Action::Unevaluated);
   
   OwningExprResult LHS(ParseCastExpression(false));
   if (LHS.isInvalid()) return move(LHS);
@@ -983,7 +984,8 @@
     //
     // The GNU typeof and alignof extensions also behave as unevaluated
     // operands.
-    EnterUnevaluatedOperand Unevaluated(Actions);
+    EnterExpressionEvaluationContext Unevaluated(Actions,
+                                                 Action::Unevaluated);
     Operand = ParseCastExpression(true/*isUnaryExpression*/);
   } else {
     // If it starts with a '(', we know that it is either a parenthesized
@@ -999,7 +1001,8 @@
     //
     // The GNU typeof and alignof extensions also behave as unevaluated
     // operands.
-    EnterUnevaluatedOperand Unevaluated(Actions);
+    EnterExpressionEvaluationContext Unevaluated(Actions,
+                                                 Action::Unevaluated);
     Operand = ParseParenExpression(ExprType, true/*stopIfCastExpr*/,
                                    CastTy, RParenLoc);
     CastRange = SourceRange(LParenLoc, RParenLoc);

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=73899&r1=73898&r2=73899&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Mon Jun 22 15:57:11 2009
@@ -384,10 +384,9 @@
     //
     // Note that we can't tell whether the expression is an lvalue of a 
     // polymorphic class type until after we've parsed the expression, so
-    // we treat the expression as an unevaluated operand and let semantic
-    // analysis cope with case where the expression is not an unevaluated
-    // operand.
-    EnterUnevaluatedOperand Unevaluated(Actions);
+    // we the expression is potentially potentially evaluated.
+    EnterExpressionEvaluationContext Unevaluated(Actions,
+                                       Action::PotentiallyPotentiallyEvaluated);
     Result = ParseExpression();
 
     // Match the ')'.

Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=73899&r1=73898&r2=73899&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Mon Jun 22 15:57:11 2009
@@ -750,7 +750,7 @@
 /// ParseTemplateArgument - Parse a C++ template argument (C++ [temp.names]).
 ///
 ///       template-argument: [C++ 14.2]
-///         assignment-expression
+///         constant-expression
 ///         type-id
 ///         id-expression
 void *Parser::ParseTemplateArgument(bool &ArgIsType) {
@@ -768,7 +768,7 @@
     return TypeArg.get();
   }
 
-  OwningExprResult ExprArg = ParseAssignmentExpression();
+  OwningExprResult ExprArg = ParseConstantExpression();
   if (ExprArg.isInvalid() || !ExprArg.get())
     return 0;
 

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=73899&r1=73898&r2=73899&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Mon Jun 22 15:57:11 2009
@@ -182,7 +182,7 @@
     Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()), 
     ExternalSource(0), CurContext(0), PreDeclaratorDC(0),
     CurBlock(0), PackContext(0), IdResolver(pp.getLangOptions()),
-    GlobalNewDeleteDeclared(false), InUnevaluatedOperand(false),
+    GlobalNewDeleteDeclared(false), ExprEvalContext(PotentiallyEvaluated),
     CompleteTranslationUnit(CompleteTranslationUnit),
     NumSFINAEErrors(0), CurrentInstantiationScope(0) {
   

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=73899&r1=73898&r2=73899&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Jun 22 15:57:11 2009
@@ -29,6 +29,7 @@
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/OwningPtr.h"
+#include <list>
 #include <string>
 #include <vector>
 
@@ -247,11 +248,18 @@
   /// have been declared.
   bool GlobalNewDeleteDeclared;
 
-  /// A flag that indicates when we are processing an unevaluated operand
-  /// (C++0x [expr]). C99 has the same notion of declarations being
-  /// "used" and C++03 has the notion of "potentially evaluated", but we
-  /// adopt the C++0x terminology since it is most precise.
-  bool InUnevaluatedOperand;
+  /// The current expression evaluation context.
+  ExpressionEvaluationContext ExprEvalContext;
+  
+  typedef std::vector<std::pair<SourceLocation, Decl *> > 
+    PotentiallyReferencedDecls;
+  
+  /// A stack of declarations, each element of which is a set of declarations
+  /// that will be marked as referenced if the corresponding potentially
+  /// potentially evaluated expression is potentially evaluated. Each element
+  /// in the stack corresponds to a PotentiallyPotentiallyEvaluated expression
+  /// evaluation context.
+  std::list<PotentiallyReferencedDecls> PotentiallyReferencedDeclStack;
   
   /// \brief Whether the code handled by Sema should be considered a
   /// complete translation unit or not.
@@ -1334,12 +1342,13 @@
   void DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc,
                              Expr **Args, unsigned NumArgs);
 
-  virtual bool setUnevaluatedOperand(bool UnevaluatedOperand) { 
-    bool Result = InUnevaluatedOperand;
-    InUnevaluatedOperand = UnevaluatedOperand;
-    return Result;
-  }
-
+  virtual ExpressionEvaluationContext 
+  PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext);
+  
+  virtual void 
+  PopExpressionEvaluationContext(ExpressionEvaluationContext OldContext,
+                                 ExpressionEvaluationContext NewContext);
+  
   void MarkDeclarationReferenced(SourceLocation Loc, Decl *D);
   
   // Primary Expressions.

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=73899&r1=73898&r2=73899&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Jun 22 15:57:11 2009
@@ -5432,6 +5432,35 @@
   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 @@
   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()) {

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=73899&r1=73898&r2=73899&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon Jun 22 15:57:11 2009
@@ -71,6 +71,31 @@
 
   QualType TypeInfoType = Context.getTypeDeclType(TypeInfoRecordDecl);
 
+  if (!isType) {
+    // C++0x [expr.typeid]p3:
+    //   When typeid is applied to an expression other than an lvalue of a 
+    //   polymorphic class type [...] [the] expression is an unevaluated 
+    //   operand.
+    
+    // FIXME: if the type of the expression is a class type, the class
+    // shall be completely defined.
+    bool isUnevaluatedOperand = true;
+    Expr *E = static_cast<Expr *>(TyOrExpr);
+    if (E && !E->isTypeDependent() && E->isLvalue(Context) == Expr::LV_Valid) {
+      QualType T = E->getType();
+      if (const RecordType *RecordT = T->getAsRecordType()) {
+        CXXRecordDecl *RecordD = cast<CXXRecordDecl>(RecordT->getDecl());
+        if (RecordD->isPolymorphic())
+          isUnevaluatedOperand = false;
+      }
+    }
+    
+    // If this is an unevaluated operand, clear out the set of declaration
+    // references we have been computing.
+    if (isUnevaluatedOperand)
+      PotentiallyReferencedDeclStack.back().clear();
+  }
+  
   return Owned(new (Context) CXXTypeidExpr(isType, TyOrExpr,
                                            TypeInfoType.withConst(),
                                            SourceRange(OpLoc, RParenLoc)));

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=73899&r1=73898&r2=73899&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Mon Jun 22 15:57:11 2009
@@ -420,6 +420,7 @@
   }
   
   // Instantiate the size expression
+  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
   Sema::OwningExprResult InstantiatedArraySize = 
     SemaRef.InstantiateExpr(ArraySize, TemplateArgs);
   if (InstantiatedArraySize.isInvalid())
@@ -443,6 +444,10 @@
       return QualType();
   }
 
+  // The expression in a dependent-sized extended vector type is not
+  // potentially evaluated.
+  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+
   // Instantiate the size expression.
   const Expr *SizeExpr = T->getSizeExpr();
   Sema::OwningExprResult InstantiatedArraySize = 
@@ -520,6 +525,9 @@
 QualType 
 TemplateTypeInstantiator::InstantiateTypeOfExprType(const TypeOfExprType *T,
                                                     unsigned Quals) const {
+  // The expression in a typeof is not potentially evaluated.
+  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+  
   Sema::OwningExprResult E 
     = SemaRef.InstantiateExpr(T->getUnderlyingExpr(), TemplateArgs);
   if (E.isInvalid())
@@ -1175,6 +1183,9 @@
     return Arg;
 
   case TemplateArgument::Expression: {
+    // Template argument expressions are not potentially evaluated.
+    EnterExpressionEvaluationContext Unevaluated(*this, Action::Unevaluated);
+
     Sema::OwningExprResult E = InstantiateExpr(Arg.getAsExpr(), TemplateArgs);
     if (E.isInvalid())
       return TemplateArgument();

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=73899&r1=73898&r2=73899&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon Jun 22 15:57:11 2009
@@ -163,6 +163,9 @@
   if (Invalid)
     BitWidth = 0;
   else if (BitWidth) {
+    // The bit-width expression is not potentially evaluated.
+    EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+    
     OwningExprResult InstantiatedBitWidth
       = SemaRef.InstantiateExpr(BitWidth, TemplateArgs);
     if (InstantiatedBitWidth.isInvalid()) {
@@ -192,6 +195,9 @@
 Decl *TemplateDeclInstantiator::VisitStaticAssertDecl(StaticAssertDecl *D) {
   Expr *AssertExpr = D->getAssertExpr();
       
+  // The expression in a static assertion is not potentially evaluated.
+  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+  
   OwningExprResult InstantiatedAssertExpr
     = SemaRef.InstantiateExpr(AssertExpr, TemplateArgs);
   if (InstantiatedAssertExpr.isInvalid())
@@ -222,8 +228,13 @@
        EC != ECEnd; ++EC) {
     // The specified value for the enumerator.
     OwningExprResult Value = SemaRef.Owned((Expr *)0);
-    if (Expr *UninstValue = EC->getInitExpr())
+    if (Expr *UninstValue = EC->getInitExpr()) {
+      // The enumerator's value expression is not potentially evaluated.
+      EnterExpressionEvaluationContext Unevaluated(SemaRef, 
+                                                   Action::Unevaluated);
+      
       Value = SemaRef.InstantiateExpr(UninstValue, TemplateArgs);
+    }
 
     // Drop the initial value and continue.
     bool isInvalid = false;

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp?rev=73899&r1=73898&r2=73899&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateExpr.cpp Mon Jun 22 15:57:11 2009
@@ -714,9 +714,17 @@
                                            E->getSourceRange());
   } 
 
-  Sema::OwningExprResult Arg = Visit(E->getArgumentExpr());
-  if (Arg.isInvalid())
-    return SemaRef.ExprError();
+  Sema::OwningExprResult Arg(SemaRef);
+  {   
+    // C++0x [expr.sizeof]p1:
+    //   The operand is either an expression, which is an unevaluated operand
+    //   [...]
+    EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+    
+    Arg = Visit(E->getArgumentExpr());
+    if (Arg.isInvalid())
+      return SemaRef.ExprError();
+  }
 
   Sema::OwningExprResult Result
     = SemaRef.CreateSizeOfAlignOfExpr((Expr *)Arg.get(), E->getOperatorLoc(),
@@ -949,6 +957,12 @@
                                   E->getSourceRange().getEnd());
   }
 
+  // We don't know whether the expression is potentially evaluated until
+  // after we perform semantic analysis, so the expression is potentially
+  // potentially evaluated.
+  EnterExpressionEvaluationContext Unevaluated(SemaRef, 
+                                     Action::PotentiallyPotentiallyEvaluated);
+
   OwningExprResult Operand = Visit(E->getExprOperand());
   if (Operand.isInvalid())
     return SemaRef.ExprError();

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateStmt.cpp?rev=73899&r1=73898&r2=73899&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateStmt.cpp Mon Jun 22 15:57:11 2009
@@ -145,6 +145,9 @@
 }
 
 Sema::OwningStmtResult TemplateStmtInstantiator::VisitCaseStmt(CaseStmt *S) {
+  // The case value expressions are not potentially evaluated.
+  EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+
   // Instantiate left-hand case value.
   OwningExprResult LHS = SemaRef.InstantiateExpr(S->getLHS(), TemplateArgs);
   if (LHS.isInvalid())





More information about the cfe-commits mailing list