From 3a2f91280a49f4747063f983dc6a3296bd9359d2 Mon Sep 17 00:00:00 2001 From: Ben Langmuir Date: Mon, 29 Apr 2013 13:32:41 +0000 Subject: [PATCH] Small CapturedStmt improvements Add a CapturedStmt.h similar to Lambda.h to reduce the typing required to get to the CapturedRegionKind enum. This also allows codegen to access this enum without including Sema/ScopeInfo.h. Also removes some duplicated code for capturing 'this' between CapturedStmt and Lambda. Differential Revision: http://llvm-reviews.chandlerc.com/D712 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@180710 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Stmt.h | 18 ++++++-------- include/clang/Basic/CapturedStmt.h | 23 ++++++++++++++++++ include/clang/Sema/ScopeInfo.h | 6 +---- include/clang/Sema/Sema.h | 4 +-- lib/Parse/ParsePragma.cpp | 3 +-- lib/Sema/Sema.cpp | 2 +- lib/Sema/SemaExprCXX.cpp | 39 +++++++++++++----------------- lib/Sema/SemaStmt.cpp | 2 +- 8 files changed, 53 insertions(+), 44 deletions(-) create mode 100644 include/clang/Basic/CapturedStmt.h diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 019e678620..1e5892fcf7 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -20,6 +20,7 @@ #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/PointerIntPair.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include @@ -1903,7 +1904,7 @@ public: /// \brief Describes the capture of either a variable or 'this'. class Capture { - VarDecl *Var; + llvm::PointerIntPair VarAndKind; SourceLocation Loc; public: @@ -1916,7 +1917,7 @@ public: /// \param Var The variable being captured, or null if capturing this. /// Capture(SourceLocation Loc, VariableCaptureKind Kind, VarDecl *Var = 0) - : Var(Var), Loc(Loc) { + : VarAndKind(Var, Kind), Loc(Loc) { switch (Kind) { case VCK_This: assert(Var == 0 && "'this' capture cannot have a variable!"); @@ -1928,29 +1929,24 @@ public: } /// \brief Determine the kind of capture. - VariableCaptureKind getCaptureKind() const { - if (capturesThis()) - return VCK_This; - - return VCK_ByRef; - } + VariableCaptureKind getCaptureKind() const { return VarAndKind.getInt(); } /// \brief Retrieve the source location at which the variable or 'this' was /// first used. SourceLocation getLocation() const { return Loc; } /// \brief Determine whether this capture handles the C++ 'this' pointer. - bool capturesThis() const { return Var == 0; } + bool capturesThis() const { return getCaptureKind() == VCK_This; } /// \brief Determine whether this capture handles a variable. - bool capturesVariable() const { return Var != 0; } + bool capturesVariable() const { return getCaptureKind() != VCK_This; } /// \brief Retrieve the declaration of the variable being captured. /// /// This operation is only valid if this capture does not capture 'this'. VarDecl *getCapturedVar() const { assert(!capturesThis() && "No variable available for 'this' capture"); - return Var; + return VarAndKind.getPointer(); } }; diff --git a/include/clang/Basic/CapturedStmt.h b/include/clang/Basic/CapturedStmt.h new file mode 100644 index 0000000000..484bbb1fee --- /dev/null +++ b/include/clang/Basic/CapturedStmt.h @@ -0,0 +1,23 @@ +//===--- CapturedStmt.h - Types for CapturedStmts ---------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + + +#ifndef LLVM_CLANG_BASIC_CAPTUREDSTMT_H +#define LLVM_CLANG_BASIC_CAPTUREDSTMT_H + +namespace clang { + +/// \brief The different kinds of captured statement. +enum CapturedRegionKind { + CR_Default +}; + +} // end namespace clang + +#endif // LLVM_CLANG_BASIC_CAPTUREDSTMT_H diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h index 103ce826ae..c8cc6964bd 100644 --- a/include/clang/Sema/ScopeInfo.h +++ b/include/clang/Sema/ScopeInfo.h @@ -16,6 +16,7 @@ #define LLVM_CLANG_SEMA_SCOPE_INFO_H #include "clang/AST/Type.h" +#include "clang/Basic/CapturedStmt.h" #include "clang/Basic/PartialDiagnostic.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" @@ -499,11 +500,6 @@ public: /// \brief Retains information about a captured region. class CapturedRegionScopeInfo: public CapturingScopeInfo { public: - - enum CapturedRegionKind { - CR_Default - }; - /// \brief The CapturedDecl for this statement. CapturedDecl *TheCapturedDecl; /// \brief The captured record type. diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index b1b7df2344..70a930ac7d 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -927,7 +927,7 @@ public: void PushLambdaScope(CXXRecordDecl *Lambda, CXXMethodDecl *CallOperator); void PushCapturedRegionScope(Scope *RegionScope, CapturedDecl *CD, RecordDecl *RD, - sema::CapturedRegionScopeInfo::CapturedRegionKind K); + CapturedRegionKind K); void PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP =0, const Decl *D = 0, const BlockExpr *blkExpr = 0); @@ -2782,7 +2782,7 @@ public: StmtResult ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope); void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, - sema::CapturedRegionScopeInfo::CapturedRegionKind Kind); + CapturedRegionKind Kind); StmtResult ActOnCapturedRegionEnd(Stmt *S); void ActOnCapturedRegionError(bool IsInstantiation = false); RecordDecl *CreateCapturedStmtRecordDecl(CapturedDecl *&CD, diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp index 96328e2fb6..0ecd11ec97 100644 --- a/lib/Parse/ParsePragma.cpp +++ b/lib/Parse/ParsePragma.cpp @@ -136,8 +136,7 @@ StmtResult Parser::HandlePragmaCaptured() SourceLocation Loc = Tok.getLocation(); ParseScope CapturedRegionScope(this, Scope::FnScope | Scope::DeclScope); - Actions.ActOnCapturedRegionStart(Loc, getCurScope(), - sema::CapturedRegionScopeInfo::CR_Default); + Actions.ActOnCapturedRegionStart(Loc, getCurScope(), CR_Default); StmtResult R = ParseCompoundStatement(); CapturedRegionScope.Exit(); diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 203b689aa1..38c58549cd 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -1316,7 +1316,7 @@ IdentifierInfo *Sema::getSuperIdentifier() const { } void Sema::PushCapturedRegionScope(Scope *S, CapturedDecl *CD, RecordDecl *RD, - CapturedRegionScopeInfo::CapturedRegionKind K) { + CapturedRegionKind K) { CapturingScopeInfo *CSI = new CapturedRegionScopeInfo(getDiagnostics(), S, CD, RD, K); CSI->ReturnType = Context.VoidTy; diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 65ad83d5fc..c05d29d7d4 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -728,6 +728,18 @@ Sema::CXXThisScopeRAII::~CXXThisScopeRAII() { } } +static Expr *captureThis(ASTContext &Context, RecordDecl *RD, + QualType ThisTy, SourceLocation Loc) { + FieldDecl *Field + = FieldDecl::Create(Context, RD, Loc, Loc, 0, ThisTy, + Context.getTrivialTypeSourceInfo(ThisTy, Loc), + 0, false, ICIS_NoInit); + Field->setImplicit(true); + Field->setAccess(AS_private); + RD->addDecl(Field); + return new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit*/true); +} + void Sema::CheckCXXThisCapture(SourceLocation Loc, bool Explicit) { // We don't need to capture this in an unevaluated context. if (ExprEvalContexts.back().Context == Unevaluated && !Explicit) @@ -768,29 +780,12 @@ void Sema::CheckCXXThisCapture(SourceLocation Loc, bool Explicit) { CapturingScopeInfo *CSI = cast(FunctionScopes[idx]); Expr *ThisExpr = 0; QualType ThisTy = getCurrentThisType(); - if (LambdaScopeInfo *LSI = dyn_cast(CSI)) { + if (LambdaScopeInfo *LSI = dyn_cast(CSI)) // For lambda expressions, build a field and an initializing expression. - CXXRecordDecl *Lambda = LSI->Lambda; - FieldDecl *Field - = FieldDecl::Create(Context, Lambda, Loc, Loc, 0, ThisTy, - Context.getTrivialTypeSourceInfo(ThisTy, Loc), - 0, false, ICIS_NoInit); - Field->setImplicit(true); - Field->setAccess(AS_private); - Lambda->addDecl(Field); - ThisExpr = new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit=*/true); - } else if (CapturedRegionScopeInfo *RSI = - dyn_cast(FunctionScopes[idx])) { - RecordDecl *RD = RSI->TheRecordDecl; - FieldDecl *Field - = FieldDecl::Create(Context, RD, Loc, Loc, 0, ThisTy, - Context.getTrivialTypeSourceInfo(ThisTy, Loc), - 0, false, ICIS_NoInit); - Field->setImplicit(true); - Field->setAccess(AS_private); - RD->addDecl(Field); - ThisExpr = new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit*/true); - } + ThisExpr = captureThis(Context, LSI->Lambda, ThisTy, Loc); + else if (CapturedRegionScopeInfo *RSI + = dyn_cast(FunctionScopes[idx])) + ThisExpr = captureThis(Context, RSI->TheRecordDecl, ThisTy, Loc); bool isNested = NumClosures > 1; CSI->addThisCapture(isNested, Loc, ThisTy, ThisExpr); diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 7286d166ca..4fc1818d32 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -2970,7 +2970,7 @@ static void buildCapturedStmtCaptureList( } void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, - CapturedRegionScopeInfo::CapturedRegionKind Kind) { + CapturedRegionKind Kind) { CapturedDecl *CD = 0; RecordDecl *RD = CreateCapturedStmtRecordDecl(CD, Loc); -- 2.40.0