rnk created this revision.
rnk added a reviewer: rjmccall.

This provides no measurable build speedup, but it reinstates an
optimization from r112038 that was lost in r179618.  It requires moving
CapturedScopeInfo::Capture out to clang::sema, which might be too
general since we have plenty of other Capture records in BlockDecl and
other AST nodes.


https://reviews.llvm.org/D44221

Files:
  clang/include/clang/Sema/ScopeInfo.h
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Sema/SemaLambda.h
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaCoroutine.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/lib/Sema/SemaExpr.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaStmt.cpp

Index: clang/lib/Sema/SemaStmt.cpp
===================================================================
--- clang/lib/Sema/SemaStmt.cpp
+++ clang/lib/Sema/SemaStmt.cpp
@@ -4040,32 +4040,29 @@
   return RD;
 }
 
-static void buildCapturedStmtCaptureList(
-    SmallVectorImpl<CapturedStmt::Capture> &Captures,
-    SmallVectorImpl<Expr *> &CaptureInits,
-    ArrayRef<CapturingScopeInfo::Capture> Candidates) {
-
-  typedef ArrayRef<CapturingScopeInfo::Capture>::const_iterator CaptureIter;
-  for (CaptureIter Cap = Candidates.begin(); Cap != Candidates.end(); ++Cap) {
-
-    if (Cap->isThisCapture()) {
-      Captures.push_back(CapturedStmt::Capture(Cap->getLocation(),
+static void
+buildCapturedStmtCaptureList(SmallVectorImpl<CapturedStmt::Capture> &Captures,
+                             SmallVectorImpl<Expr *> &CaptureInits,
+                             ArrayRef<sema::Capture> Candidates) {
+  for (const sema::Capture &Cap : Candidates) {
+    if (Cap.isThisCapture()) {
+      Captures.push_back(CapturedStmt::Capture(Cap.getLocation(),
                                                CapturedStmt::VCK_This));
-      CaptureInits.push_back(Cap->getInitExpr());
+      CaptureInits.push_back(Cap.getInitExpr());
       continue;
-    } else if (Cap->isVLATypeCapture()) {
+    } else if (Cap.isVLATypeCapture()) {
       Captures.push_back(
-          CapturedStmt::Capture(Cap->getLocation(), CapturedStmt::VCK_VLAType));
+          CapturedStmt::Capture(Cap.getLocation(), CapturedStmt::VCK_VLAType));
       CaptureInits.push_back(nullptr);
       continue;
     }
 
-    Captures.push_back(CapturedStmt::Capture(Cap->getLocation(),
-                                             Cap->isReferenceCapture()
+    Captures.push_back(CapturedStmt::Capture(Cap.getLocation(),
+                                             Cap.isReferenceCapture()
                                                  ? CapturedStmt::VCK_ByRef
                                                  : CapturedStmt::VCK_ByCopy,
-                                             Cap->getVariable()));
-    CaptureInits.push_back(Cap->getInitExpr());
+                                             Cap.getVariable()));
+    CaptureInits.push_back(Cap.getInitExpr());
   }
 }
 
Index: clang/lib/Sema/SemaLambda.cpp
===================================================================
--- clang/lib/Sema/SemaLambda.cpp
+++ clang/lib/Sema/SemaLambda.cpp
@@ -1388,8 +1388,9 @@
   Class->addDecl(Conversion);
 }
 
-static ExprResult performLambdaVarCaptureInitialization(
-    Sema &S, const LambdaScopeInfo::Capture &Capture, FieldDecl *Field) {
+static ExprResult performLambdaVarCaptureInitialization(Sema &S,
+                                                        const Capture &Capture,
+                                                        FieldDecl *Field) {
   assert(Capture.isVariableCapture() && "not a variable capture");
 
   auto *Var = Capture.getVariable();
@@ -1443,7 +1444,7 @@
   llvm_unreachable("Unknown implicit capture style");
 }
 
-bool Sema::CaptureHasSideEffects(const LambdaScopeInfo::Capture &From) {
+bool Sema::CaptureHasSideEffects(const Capture &From) {
   if (!From.isVLATypeCapture()) {
     Expr *Init = From.getInitExpr();
     if (Init && Init->HasSideEffects(Context))
@@ -1468,7 +1469,7 @@
   return false;
 }
 
-void Sema::DiagnoseUnusedLambdaCapture(const LambdaScopeInfo::Capture &From) {
+void Sema::DiagnoseUnusedLambdaCapture(const Capture &From) {
   if (CaptureHasSideEffects(From))
     return;
 
@@ -1523,7 +1524,7 @@
     // Translate captures.
     auto CurField = Class->field_begin();
     for (unsigned I = 0, N = LSI->Captures.size(); I != N; ++I, ++CurField) {
-      const LambdaScopeInfo::Capture &From = LSI->Captures[I];
+      const Capture &From = LSI->Captures[I];
       assert(!From.isBlockCapture() && "Cannot capture __block variables");
       bool IsImplicit = I >= LSI->NumExplicitCaptures;
 
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -13045,7 +13045,7 @@
   // Set the captured variables on the block.
   // FIXME: Share capture structure between BlockDecl and CapturingScopeInfo!
   SmallVector<BlockDecl::Capture, 4> Captures;
-  for (CapturingScopeInfo::Capture &Cap : BSI->Captures) {
+  for (Capture &Cap : BSI->Captures) {
     if (Cap.isThisCapture())
       continue;
     BlockDecl::Capture NewCap(Cap.getVariable(), Cap.isBlockCapture(),
@@ -14144,7 +14144,7 @@
     // Similarly to mutable captures in lambda, all the OpenMP captures by copy
     // are mutable in the sense that user can change their value - they are
     // private instances of the captured declarations.
-    const CapturingScopeInfo::Capture &Cap = CSI->getCapture(Var);
+    const Capture &Cap = CSI->getCapture(Var);
     if (Cap.isCopyCapture() &&
         !(isa<LambdaScopeInfo>(CSI) && cast<LambdaScopeInfo>(CSI)->Mutable) &&
         !(isa<CapturedRegionScopeInfo>(CSI) &&
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -31,6 +31,7 @@
 #include "clang/Sema/Initialization.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
 #include "clang/Sema/SemaInternal.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringExtras.h"
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -6930,7 +6930,7 @@
 /// variable \p VD, or an invalid source location otherwise.
 static SourceLocation getCaptureLocation(const LambdaScopeInfo *LSI,
                                          const VarDecl *VD) {
-  for (const LambdaScopeInfo::Capture &Capture : LSI->Captures) {
+  for (const Capture &Capture : LSI->Captures) {
     if (Capture.isVariableCapture() && Capture.getVariable() == VD)
       return Capture.getLocation();
   }
Index: clang/lib/Sema/SemaCoroutine.cpp
===================================================================
--- clang/lib/Sema/SemaCoroutine.cpp
+++ clang/lib/Sema/SemaCoroutine.cpp
@@ -19,6 +19,7 @@
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/Initialization.h"
 #include "clang/Sema/Overload.h"
+#include "clang/Sema/ScopeInfo.h"
 #include "clang/Sema/SemaInternal.h"
 
 using namespace clang;
Index: clang/lib/Sema/Sema.cpp
===================================================================
--- clang/lib/Sema/Sema.cpp
+++ clang/lib/Sema/Sema.cpp
@@ -1426,6 +1426,18 @@
   return CurBSI;
 }
 
+FunctionScopeInfo *Sema::getEnclosingFunction() const {
+  if (FunctionScopes.empty())
+    return nullptr;
+
+  for (int e = FunctionScopes.size() - 1; e >= 0; --e) {
+    if (isa<sema::BlockScopeInfo>(FunctionScopes[e]))
+      continue;
+    return FunctionScopes[e];
+  }
+  return nullptr;
+}
+
 LambdaScopeInfo *Sema::getCurLambda(bool IgnoreNonLambdaCapturingScope) {
   if (FunctionScopes.empty())
     return nullptr;
Index: clang/include/clang/Sema/SemaLambda.h
===================================================================
--- clang/include/clang/Sema/SemaLambda.h
+++ clang/include/clang/Sema/SemaLambda.h
@@ -15,9 +15,13 @@
 
 #ifndef LLVM_CLANG_SEMA_SEMALAMBDA_H
 #define LLVM_CLANG_SEMA_SEMALAMBDA_H
+
 #include "clang/AST/ASTLambda.h"
-#include "clang/Sema/ScopeInfo.h"
+
 namespace clang {
+namespace sema {
+class FunctionScopeInfo;
+}
 class Sema;
 
 /// \brief Examines the FunctionScopeInfo stack to determine the nearest
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -30,7 +30,6 @@
 #include "clang/AST/TypeLoc.h"
 #include "clang/AST/TypeOrdering.h"
 #include "clang/Basic/ExpressionTraits.h"
-#include "clang/Basic/LangOptions.h"
 #include "clang/Basic/Module.h"
 #include "clang/Basic/OpenMPKinds.h"
 #include "clang/Basic/PragmaKinds.h"
@@ -45,7 +44,6 @@
 #include "clang/Sema/ObjCMethodList.h"
 #include "clang/Sema/Ownership.h"
 #include "clang/Sema/Scope.h"
-#include "clang/Sema/ScopeInfo.h"
 #include "clang/Sema/TypoCorrection.h"
 #include "clang/Sema/Weak.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -201,6 +199,7 @@
 namespace sema {
   class AccessedEntity;
   class BlockScopeInfo;
+  class Capture;
   class CapturedRegionScopeInfo;
   class CapturingScopeInfo;
   class CompoundScopeInfo;
@@ -1322,17 +1321,7 @@
     return FunctionScopes.back();
   }
 
-  sema::FunctionScopeInfo *getEnclosingFunction() const {
-    if (FunctionScopes.empty())
-      return nullptr;
-
-    for (int e = FunctionScopes.size()-1; e >= 0; --e) {
-      if (isa<sema::BlockScopeInfo>(FunctionScopes[e]))
-        continue;
-      return FunctionScopes[e];
-    }
-    return nullptr;
-  }
+  sema::FunctionScopeInfo *getEnclosingFunction() const;
 
   template <typename ExprT>
   void recordUseOfEvaluatedWeak(const ExprT *E, bool IsRead=true) {
@@ -5553,10 +5542,10 @@
                              Scope *CurScope);
 
   /// \brief Does copying/destroying the captured variable have side effects?
-  bool CaptureHasSideEffects(const sema::LambdaScopeInfo::Capture &From);
+  bool CaptureHasSideEffects(const sema::Capture &From);
 
   /// \brief Diagnose if an explicit lambda capture is unused.
-  void DiagnoseUnusedLambdaCapture(const sema::LambdaScopeInfo::Capture &From);
+  void DiagnoseUnusedLambdaCapture(const sema::Capture &From);
 
   /// \brief Complete a lambda-expression having processed and attached the
   /// lambda body.
Index: clang/include/clang/Sema/ScopeInfo.h
===================================================================
--- clang/include/clang/Sema/ScopeInfo.h
+++ clang/include/clang/Sema/ScopeInfo.h
@@ -469,144 +469,144 @@
   void Clear();
 };
 
-class CapturingScopeInfo : public FunctionScopeInfo {
-protected:
-  CapturingScopeInfo(const CapturingScopeInfo&) = default;
-
-public:
-  enum ImplicitCaptureStyle {
-    ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block,
-    ImpCap_CapturedRegion
+class Capture {
+  // There are three categories of capture: capturing 'this', capturing
+  // local variables, and C++1y initialized captures (which can have an
+  // arbitrary initializer, and don't really capture in the traditional
+  // sense at all).
+  //
+  // There are three ways to capture a local variable:
+  //  - capture by copy in the C++11 sense,
+  //  - capture by reference in the C++11 sense, and
+  //  - __block capture.
+  // Lambdas explicitly specify capture by copy or capture by reference.
+  // For blocks, __block capture applies to variables with that annotation,
+  // variables of reference type are captured by reference, and other
+  // variables are captured by copy.
+  enum CaptureKind {
+    Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_VLA
+  };
+  enum {
+    IsNestedCapture = 0x1,
+    IsThisCaptured = 0x2
   };
 
-  ImplicitCaptureStyle ImpCaptureStyle;
+  /// The variable being captured (if we are not capturing 'this') and whether
+  /// this is a nested capture, and whether we are capturing 'this'
+  llvm::PointerIntPair<VarDecl*, 2> VarAndNestedAndThis;
 
-  class Capture {
-    // There are three categories of capture: capturing 'this', capturing
-    // local variables, and C++1y initialized captures (which can have an
-    // arbitrary initializer, and don't really capture in the traditional
-    // sense at all).
-    //
-    // There are three ways to capture a local variable:
-    //  - capture by copy in the C++11 sense,
-    //  - capture by reference in the C++11 sense, and
-    //  - __block capture.
-    // Lambdas explicitly specify capture by copy or capture by reference.
-    // For blocks, __block capture applies to variables with that annotation,
-    // variables of reference type are captured by reference, and other
-    // variables are captured by copy.
-    enum CaptureKind {
-      Cap_ByCopy, Cap_ByRef, Cap_Block, Cap_VLA
-    };
-    enum {
-      IsNestedCapture = 0x1,
-      IsThisCaptured = 0x2
-    };
+  /// Expression to initialize a field of the given type, and the kind of
+  /// capture (if this is a capture and not an init-capture). The expression
+  /// is only required if we are capturing ByVal and the variable's type has
+  /// a non-trivial copy constructor.
+  llvm::PointerIntPair<void *, 2, CaptureKind> InitExprAndCaptureKind;
 
-    /// The variable being captured (if we are not capturing 'this') and whether
-    /// this is a nested capture, and whether we are capturing 'this'
-    llvm::PointerIntPair<VarDecl*, 2> VarAndNestedAndThis;
+  /// \brief The source location at which the first capture occurred.
+  SourceLocation Loc;
 
-    /// Expression to initialize a field of the given type, and the kind of
-    /// capture (if this is a capture and not an init-capture). The expression
-    /// is only required if we are capturing ByVal and the variable's type has
-    /// a non-trivial copy constructor.
-    llvm::PointerIntPair<void *, 2, CaptureKind> InitExprAndCaptureKind;
-    
-    /// \brief The source location at which the first capture occurred.
-    SourceLocation Loc;
+  /// \brief The location of the ellipsis that expands a parameter pack.
+  SourceLocation EllipsisLoc;
 
-    /// \brief The location of the ellipsis that expands a parameter pack.
-    SourceLocation EllipsisLoc;
+  /// \brief The type as it was captured, which is in effect the type of the
+  /// non-static data member that would hold the capture.
+  QualType CaptureType;
 
-    /// \brief The type as it was captured, which is in effect the type of the
-    /// non-static data member that would hold the capture.
-    QualType CaptureType;
+  /// \brief Whether an explicit capture has been odr-used in the body of the
+  /// lambda.
+  bool ODRUsed = false;
 
-    /// \brief Whether an explicit capture has been odr-used in the body of the
-    /// lambda.
-    bool ODRUsed = false;
+  /// \brief Whether an explicit capture has been non-odr-used in the body of
+  /// the lambda.
+  bool NonODRUsed = false;
 
-    /// \brief Whether an explicit capture has been non-odr-used in the body of
-    /// the lambda.
-    bool NonODRUsed = false;
+public:
+  Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested,
+          SourceLocation Loc, SourceLocation EllipsisLoc,
+          QualType CaptureType, Expr *Cpy)
+      : VarAndNestedAndThis(Var, IsNested ? IsNestedCapture : 0),
+        InitExprAndCaptureKind(
+            Cpy, !Var ? Cap_VLA : Block ? Cap_Block : ByRef ? Cap_ByRef
+                                                            : Cap_ByCopy),
+        Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType) {}
 
-  public:
-    Capture(VarDecl *Var, bool Block, bool ByRef, bool IsNested,
-            SourceLocation Loc, SourceLocation EllipsisLoc,
-            QualType CaptureType, Expr *Cpy)
-        : VarAndNestedAndThis(Var, IsNested ? IsNestedCapture : 0),
-          InitExprAndCaptureKind(
-              Cpy, !Var ? Cap_VLA : Block ? Cap_Block : ByRef ? Cap_ByRef
-                                                              : Cap_ByCopy),
-          Loc(Loc), EllipsisLoc(EllipsisLoc), CaptureType(CaptureType) {}
-
-    enum IsThisCapture { ThisCapture };
-    Capture(IsThisCapture, bool IsNested, SourceLocation Loc,
-            QualType CaptureType, Expr *Cpy, const bool ByCopy)
-        : VarAndNestedAndThis(
-              nullptr, (IsThisCaptured | (IsNested ? IsNestedCapture : 0))),
-          InitExprAndCaptureKind(Cpy, ByCopy ? Cap_ByCopy : Cap_ByRef),
-          Loc(Loc), CaptureType(CaptureType) {}
-
-    bool isThisCapture() const {
-      return VarAndNestedAndThis.getInt() & IsThisCaptured;
-    }
+  enum IsThisCapture { ThisCapture };
+  Capture(IsThisCapture, bool IsNested, SourceLocation Loc,
+          QualType CaptureType, Expr *Cpy, const bool ByCopy)
+      : VarAndNestedAndThis(
+            nullptr, (IsThisCaptured | (IsNested ? IsNestedCapture : 0))),
+        InitExprAndCaptureKind(Cpy, ByCopy ? Cap_ByCopy : Cap_ByRef),
+        Loc(Loc), CaptureType(CaptureType) {}
 
-    bool isVariableCapture() const {
-      return !isThisCapture() && !isVLATypeCapture();
-    }
+  bool isThisCapture() const {
+    return VarAndNestedAndThis.getInt() & IsThisCaptured;
+  }
 
-    bool isCopyCapture() const {
-      return InitExprAndCaptureKind.getInt() == Cap_ByCopy;
-    }
+  bool isVariableCapture() const {
+    return !isThisCapture() && !isVLATypeCapture();
+  }
 
-    bool isReferenceCapture() const {
-      return InitExprAndCaptureKind.getInt() == Cap_ByRef;
-    }
+  bool isCopyCapture() const {
+    return InitExprAndCaptureKind.getInt() == Cap_ByCopy;
+  }
 
-    bool isBlockCapture() const {
-      return InitExprAndCaptureKind.getInt() == Cap_Block;
-    }
+  bool isReferenceCapture() const {
+    return InitExprAndCaptureKind.getInt() == Cap_ByRef;
+  }
 
-    bool isVLATypeCapture() const {
-      return InitExprAndCaptureKind.getInt() == Cap_VLA;
-    }
+  bool isBlockCapture() const {
+    return InitExprAndCaptureKind.getInt() == Cap_Block;
+  }
 
-    bool isNested() const {
-      return VarAndNestedAndThis.getInt() & IsNestedCapture;
-    }
+  bool isVLATypeCapture() const {
+    return InitExprAndCaptureKind.getInt() == Cap_VLA;
+  }
 
-    bool isODRUsed() const { return ODRUsed; }
-    bool isNonODRUsed() const { return NonODRUsed; }
-    void markUsed(bool IsODRUse) { (IsODRUse ? ODRUsed : NonODRUsed) = true; }
+  bool isNested() const {
+    return VarAndNestedAndThis.getInt() & IsNestedCapture;
+  }
 
-    VarDecl *getVariable() const {
-      assert(isVariableCapture());
-      return VarAndNestedAndThis.getPointer();
-    }
-    
-    /// \brief Retrieve the location at which this variable was captured.
-    SourceLocation getLocation() const { return Loc; }
-    
-    /// \brief Retrieve the source location of the ellipsis, whose presence
-    /// indicates that the capture is a pack expansion.
-    SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
-    
-    /// \brief Retrieve the capture type for this capture, which is effectively
-    /// the type of the non-static data member in the lambda/block structure
-    /// that would store this capture.
-    QualType getCaptureType() const {
-      assert(!isThisCapture());
-      return CaptureType;
-    }
+  bool isODRUsed() const { return ODRUsed; }
+  bool isNonODRUsed() const { return NonODRUsed; }
+  void markUsed(bool IsODRUse) { (IsODRUse ? ODRUsed : NonODRUsed) = true; }
 
-    Expr *getInitExpr() const {
-      assert(!isVLATypeCapture() && "no init expression for type capture");
-      return static_cast<Expr *>(InitExprAndCaptureKind.getPointer());
-    }
+  VarDecl *getVariable() const {
+    assert(isVariableCapture());
+    return VarAndNestedAndThis.getPointer();
+  }
+
+  /// \brief Retrieve the location at which this variable was captured.
+  SourceLocation getLocation() const { return Loc; }
+
+  /// \brief Retrieve the source location of the ellipsis, whose presence
+  /// indicates that the capture is a pack expansion.
+  SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
+
+  /// \brief Retrieve the capture type for this capture, which is effectively
+  /// the type of the non-static data member in the lambda/block structure
+  /// that would store this capture.
+  QualType getCaptureType() const {
+    assert(!isThisCapture());
+    return CaptureType;
+  }
+
+  Expr *getInitExpr() const {
+    assert(!isVLATypeCapture() && "no init expression for type capture");
+    return static_cast<Expr *>(InitExprAndCaptureKind.getPointer());
+  }
+};
+
+class CapturingScopeInfo : public FunctionScopeInfo {
+protected:
+  CapturingScopeInfo(const CapturingScopeInfo&) = default;
+
+public:
+  enum ImplicitCaptureStyle {
+    ImpCap_None, ImpCap_LambdaByval, ImpCap_LambdaByref, ImpCap_Block,
+    ImpCap_CapturedRegion
   };
 
+  ImplicitCaptureStyle ImpCaptureStyle;
+
   CapturingScopeInfo(DiagnosticsEngine &Diag, ImplicitCaptureStyle Style)
       : FunctionScopeInfo(Diag), ImpCaptureStyle(Style) {}
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to