diff options
author | Tareq A. Siraj <tareq.a.sriaj@intel.com> | 2013-04-16 19:37:38 +0000 |
---|---|---|
committer | Tareq A. Siraj <tareq.a.sriaj@intel.com> | 2013-04-16 19:37:38 +0000 |
commit | 6afcf8875d4e447645cd7bf3733dd8e2eb8455dc (patch) | |
tree | 492ea5c7e442ea915d1f9feeafc8b24624942d96 /lib | |
parent | 596eea7cc26979c952a0b177d024787a99b299df (diff) |
Sema for Captured Statements
Add CapturedDecl to be the DeclContext for CapturedStmt, and perform semantic
analysis. Currently captures all variables by reference.
TODO: templates
Author: Ben Langmuir <ben.langmuir@intel.com>
Differential Revision: http://llvm-reviews.chandlerc.com/D433
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179618 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/Decl.cpp | 4 | ||||
-rw-r--r-- | lib/AST/DeclBase.cpp | 2 | ||||
-rw-r--r-- | lib/AST/Stmt.cpp | 16 | ||||
-rw-r--r-- | lib/AST/StmtPrinter.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGDecl.cpp | 1 | ||||
-rw-r--r-- | lib/Frontend/PrintPreprocessedOutput.cpp | 10 | ||||
-rw-r--r-- | lib/Parse/ParsePragma.cpp | 17 | ||||
-rw-r--r-- | lib/Sema/ScopeInfo.cpp | 1 | ||||
-rw-r--r-- | lib/Sema/Sema.cpp | 17 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 63 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 13 | ||||
-rw-r--r-- | lib/Sema/SemaLambda.cpp | 1 | ||||
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 111 | ||||
-rw-r--r-- | lib/Serialization/ASTCommon.cpp | 2 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 8 | ||||
-rw-r--r-- | lib/Serialization/ASTWriterDecl.cpp | 5 |
16 files changed, 256 insertions, 17 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 36044826e8..d572335fb3 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -3234,6 +3234,10 @@ MSPropertyDecl *MSPropertyDecl::CreateDeserialized(ASTContext &C, 0, 0); } +CapturedDecl *CapturedDecl::Create(ASTContext &C, DeclContext *DC) { + return new (C) CapturedDecl(DC); +} + EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD, SourceLocation L, IdentifierInfo *Id, QualType T, diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 3f23f3d855..402d83683a 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -553,6 +553,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case StaticAssert: case ObjCPropertyImpl: case Block: + case Captured: case TranslationUnit: case UsingDirective: @@ -839,6 +840,7 @@ DeclContext *DeclContext::getPrimaryContext() { case Decl::TranslationUnit: case Decl::LinkageSpec: case Decl::Block: + case Decl::Captured: // There is only one DeclContext for these entities. return this; diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp index e120c6a1f8..2a7b170222 100644 --- a/lib/AST/Stmt.cpp +++ b/lib/AST/Stmt.cpp @@ -1038,12 +1038,12 @@ CapturedStmt::Capture *CapturedStmt::getStoredCaptures() const { CapturedStmt::CapturedStmt(Stmt *S, ArrayRef<Capture> Captures, ArrayRef<Expr *> CaptureInits, - FunctionDecl *FD, + CapturedDecl *CD, RecordDecl *RD) : Stmt(CapturedStmtClass), NumCaptures(Captures.size()), - TheFuncDecl(FD), TheRecordDecl(RD) { + TheCapturedDecl(CD), TheRecordDecl(RD) { assert( S && "null captured statement"); - assert(FD && "null function declaration for captured statement"); + assert(CD && "null captured declaration for captured statement"); assert(RD && "null record declaration for captured statement"); // Copy initialization expressions. @@ -1061,14 +1061,14 @@ CapturedStmt::CapturedStmt(Stmt *S, ArrayRef<Capture> Captures, CapturedStmt::CapturedStmt(EmptyShell Empty, unsigned NumCaptures) : Stmt(CapturedStmtClass, Empty), NumCaptures(NumCaptures), - TheFuncDecl(0), TheRecordDecl(0) { + TheCapturedDecl(0), TheRecordDecl(0) { getStoredStmts()[NumCaptures] = 0; } CapturedStmt *CapturedStmt::Create(ASTContext &Context, Stmt *S, ArrayRef<Capture> Captures, ArrayRef<Expr *> CaptureInits, - FunctionDecl *FD, + CapturedDecl *CD, RecordDecl *RD) { // The layout is // @@ -1089,7 +1089,7 @@ CapturedStmt *CapturedStmt::Create(ASTContext &Context, Stmt *S, } void *Mem = Context.Allocate(Size); - return new (Mem) CapturedStmt(S, Captures, CaptureInits, FD, RD); + return new (Mem) CapturedStmt(S, Captures, CaptureInits, CD, RD); } CapturedStmt *CapturedStmt::CreateDeserialized(ASTContext &Context, @@ -1106,8 +1106,8 @@ CapturedStmt *CapturedStmt::CreateDeserialized(ASTContext &Context, } Stmt::child_range CapturedStmt::children() { - // Children are captured field initilizers and the statement being captured. - return child_range(getStoredStmts(), getStoredStmts() + NumCaptures + 1); + // Children are captured field initilizers. + return child_range(getStoredStmts(), getStoredStmts() + NumCaptures); } bool CapturedStmt::capturesVariable(const VarDecl *Var) const { diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp index 469c2846a6..1b2285c794 100644 --- a/lib/AST/StmtPrinter.cpp +++ b/lib/AST/StmtPrinter.cpp @@ -451,7 +451,7 @@ void StmtPrinter::VisitMSAsmStmt(MSAsmStmt *Node) { } void StmtPrinter::VisitCapturedStmt(CapturedStmt *Node) { - PrintStmt(Node->getCapturedStmt()); + PrintStmt(Node->getCapturedDecl()->getBody()); } void StmtPrinter::VisitObjCAtTryStmt(ObjCAtTryStmt *Node) { diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 15bb6a6e45..173ca6cb09 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -70,6 +70,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) { case Decl::Friend: case Decl::FriendTemplate: case Decl::Block: + case Decl::Captured: case Decl::ClassScopeFunctionSpecialization: llvm_unreachable("Declaration should not be in declstmts!"); case Decl::Function: // void X(); diff --git a/lib/Frontend/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp index 6734d7759b..7e1cae95d7 100644 --- a/lib/Frontend/PrintPreprocessedOutput.cpp +++ b/lib/Frontend/PrintPreprocessedOutput.cpp @@ -137,6 +137,7 @@ public: StringRef RelativePath, const Module *Imported); virtual void Ident(SourceLocation Loc, const std::string &str); + virtual void PragmaCaptured(SourceLocation Loc, StringRef Str); virtual void PragmaComment(SourceLocation Loc, const IdentifierInfo *Kind, const std::string &Str); virtual void PragmaMessage(SourceLocation Loc, StringRef Str); @@ -345,6 +346,15 @@ void PrintPPOutputPPCallbacks::Ident(SourceLocation Loc, const std::string &S) { EmittedTokensOnThisLine = true; } +void PrintPPOutputPPCallbacks::PragmaCaptured(SourceLocation Loc, + StringRef Str) { + startNewLineIfNeeded(); + MoveToLine(Loc); + OS << "#pragma captured"; + + setEmittedDirectiveOnThisLine(); +} + /// MacroDefined - This hook is called whenever a macro definition is seen. void PrintPPOutputPPCallbacks::MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) { diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp index 038636d108..96328e2fb6 100644 --- a/lib/Parse/ParsePragma.cpp +++ b/lib/Parse/ParsePragma.cpp @@ -15,6 +15,7 @@ #include "clang/Lex/Preprocessor.h" #include "clang/Parse/ParseDiagnostic.h" #include "clang/Parse/Parser.h" +#include "clang/Sema/Scope.h" using namespace clang; /// \brief Handle the annotation token produced for #pragma unused(...) @@ -132,7 +133,21 @@ StmtResult Parser::HandlePragmaCaptured() return StmtError(); } - return StmtEmpty(); + SourceLocation Loc = Tok.getLocation(); + + ParseScope CapturedRegionScope(this, Scope::FnScope | Scope::DeclScope); + Actions.ActOnCapturedRegionStart(Loc, getCurScope(), + sema::CapturedRegionScopeInfo::CR_Default); + + StmtResult R = ParseCompoundStatement(); + CapturedRegionScope.Exit(); + + if (R.isInvalid()) { + Actions.ActOnCapturedRegionError(); + return StmtError(); + } + + return Actions.ActOnCapturedRegionEnd(R.get()); } namespace { diff --git a/lib/Sema/ScopeInfo.cpp b/lib/Sema/ScopeInfo.cpp index 4d29a34a73..2f48bec123 100644 --- a/lib/Sema/ScopeInfo.cpp +++ b/lib/Sema/ScopeInfo.cpp @@ -187,3 +187,4 @@ void FunctionScopeInfo::markSafeWeakUse(const Expr *E) { FunctionScopeInfo::~FunctionScopeInfo() { } BlockScopeInfo::~BlockScopeInfo() { } LambdaScopeInfo::~LambdaScopeInfo() { } +CapturedRegionScopeInfo::~CapturedRegionScopeInfo() { } diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 6425f34ff5..203b689aa1 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -802,7 +802,7 @@ DeclContext *Sema::getFunctionLevelDeclContext() { DeclContext *DC = CurContext; while (true) { - if (isa<BlockDecl>(DC) || isa<EnumDecl>(DC)) { + if (isa<BlockDecl>(DC) || isa<EnumDecl>(DC) || isa<CapturedDecl>(DC)) { DC = DC->getParent(); } else if (isa<CXXMethodDecl>(DC) && cast<CXXMethodDecl>(DC)->getOverloadedOperator() == OO_Call && @@ -1314,3 +1314,18 @@ IdentifierInfo *Sema::getSuperIdentifier() const { Ident_super = &Context.Idents.get("super"); return Ident_super; } + +void Sema::PushCapturedRegionScope(Scope *S, CapturedDecl *CD, RecordDecl *RD, + CapturedRegionScopeInfo::CapturedRegionKind K) { + CapturingScopeInfo *CSI = new CapturedRegionScopeInfo(getDiagnostics(), + S, CD, RD, K); + CSI->ReturnType = Context.VoidTy; + FunctionScopes.push_back(CSI); +} + +CapturedRegionScopeInfo *Sema::getCurCapturedRegion() { + if (FunctionScopes.empty()) + return 0; + + return dyn_cast<CapturedRegionScopeInfo>(FunctionScopes.back()); +} diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index e96c5d40a3..cdfdc09e06 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -10851,6 +10851,34 @@ diagnoseUncapturableValueReference(Sema &S, SourceLocation loc, // capture. } +/// \brief Capture the given variable in the captured region. +static ExprResult captureInCapturedRegion(Sema &S, CapturedRegionScopeInfo *RSI, + VarDecl *Var, QualType FieldType, + QualType DeclRefType, + SourceLocation Loc, + bool RefersToEnclosingLocal) { + // The current implemention assumes that all variables are captured + // by references. Since there is no capture by copy, no expression evaluation + // will be needed. + // + RecordDecl *RD = RSI->TheRecordDecl; + + FieldDecl *Field + = FieldDecl::Create(S.Context, RD, Loc, Loc, 0, FieldType, + S.Context.getTrivialTypeSourceInfo(FieldType, Loc), + 0, false, ICIS_NoInit); + Field->setImplicit(true); + Field->setAccess(AS_private); + RD->addDecl(Field); + + Expr *Ref = new (S.Context) DeclRefExpr(Var, RefersToEnclosingLocal, + DeclRefType, VK_LValue, Loc); + Var->setReferenced(true); + Var->setUsed(true); + + return Ref; +} + /// \brief Capture the given variable in the given lambda expression. static ExprResult captureInLambda(Sema &S, LambdaScopeInfo *LSI, VarDecl *Var, QualType FieldType, @@ -10991,10 +11019,10 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc, bool Explicit = (Kind != TryCapture_Implicit); unsigned FunctionScopesIndex = FunctionScopes.size() - 1; do { - // Only block literals and lambda expressions can capture; other - // scopes don't work. + // Only block literals, captured statements, and lambda expressions can + // capture; other scopes don't work. DeclContext *ParentDC; - if (isa<BlockDecl>(DC)) + if (isa<BlockDecl>(DC) || isa<CapturedDecl>(DC)) ParentDC = DC->getParent(); else if (isa<CXXMethodDecl>(DC) && cast<CXXMethodDecl>(DC)->getOverloadedOperator() == OO_Call && @@ -11028,7 +11056,7 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc, } bool IsBlock = isa<BlockScopeInfo>(CSI); - bool IsLambda = !IsBlock; + bool IsLambda = isa<LambdaScopeInfo>(CSI); // Lambdas are not allowed to capture unnamed variables // (e.g. anonymous unions). @@ -11188,8 +11216,31 @@ bool Sema::tryCaptureVariable(VarDecl *Var, SourceLocation Loc, SourceLocation(), CaptureType, CopyExpr); Nested = true; continue; - } - + } + + if (CapturedRegionScopeInfo *RSI = dyn_cast<CapturedRegionScopeInfo>(CSI)) { + // By default, capture variables by reference. + bool ByRef = true; + // Using an LValue reference type is consistent with Lambdas (see below). + CaptureType = Context.getLValueReferenceType(DeclRefType); + + Expr *CopyExpr = 0; + if (BuildAndDiagnose) { + ExprResult Result = captureInCapturedRegion(*this, RSI, Var, + CaptureType, DeclRefType, + Loc, Nested); + if (!Result.isInvalid()) + CopyExpr = Result.take(); + } + + // Actually capture the variable. + if (BuildAndDiagnose) + CSI->addCapture(Var, /*isBlock*/false, ByRef, Nested, Loc, + SourceLocation(), CaptureType, CopyExpr); + Nested = true; + continue; + } + LambdaScopeInfo *LSI = cast<LambdaScopeInfo>(CSI); // Determine whether we are capturing by reference or by value. diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index cfc00502c4..89c1bc51c3 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -746,6 +746,7 @@ void Sema::CheckCXXThisCapture(SourceLocation Loc, bool Explicit) { if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByref || CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByval || CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_Block || + CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_CapturedRegion || Explicit) { // This closure can capture 'this'; continue looking upwards. NumClosures++; @@ -778,7 +779,19 @@ void Sema::CheckCXXThisCapture(SourceLocation Loc, bool Explicit) { Field->setAccess(AS_private); Lambda->addDecl(Field); ThisExpr = new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit=*/true); + } else if (CapturedRegionScopeInfo *RSI = + dyn_cast<CapturedRegionScopeInfo>(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); } + bool isNested = NumClosures > 1; CSI->addThisCapture(isNested, Loc, ThisTy, ThisExpr); } diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp index 53fa6dafdd..77e6bfd086 100644 --- a/lib/Sema/SemaLambda.cpp +++ b/lib/Sema/SemaLambda.cpp @@ -862,6 +862,7 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body, CaptureDefault = LCD_ByCopy; break; + case CapturingScopeInfo::ImpCap_CapturedRegion: case CapturingScopeInfo::ImpCap_LambdaByref: CaptureDefault = LCD_ByRef; break; diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index b3558a548b..88237b08b2 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -2403,6 +2403,10 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { Diag(ReturnLoc, diag::err_noreturn_block_has_return_expr); return StmtError(); } + } else if (CapturedRegionScopeInfo *CurRegion = + dyn_cast<CapturedRegionScopeInfo>(CurCap)) { + Diag(ReturnLoc, diag::err_return_in_captured_stmt) << CurRegion->getRegionName(); + return StmtError(); } else { LambdaScopeInfo *LSI = cast<LambdaScopeInfo>(CurCap); if (LSI->CallOperator->getType()->getAs<FunctionType>()->getNoReturnAttr()){ @@ -2914,3 +2918,110 @@ StmtResult Sema::ActOnMSDependentExistsStmt(SourceLocation KeywordLoc, GetNameFromUnqualifiedId(Name), Nested); } + +RecordDecl* +Sema::CreateCapturedStmtRecordDecl(CapturedDecl *&CD, SourceLocation Loc) +{ + DeclContext *DC = CurContext; + while (!(DC->isFunctionOrMethod() || DC->isRecord() || DC->isFileContext())) + DC = DC->getParent(); + + RecordDecl *RD = 0; + if (getLangOpts().CPlusPlus) + RD = CXXRecordDecl::Create(Context, TTK_Struct, DC, Loc, Loc, /*Id=*/0); + else + RD = RecordDecl::Create(Context, TTK_Struct, DC, Loc, Loc, /*Id=*/0); + + DC->addDecl(RD); + RD->setImplicit(); + RD->startDefinition(); + + CD = CapturedDecl::Create(Context, CurContext); + DC->addDecl(CD); + + 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(), + CapturedStmt::VCK_This)); + CaptureInits.push_back(Cap->getCopyExpr()); + continue; + } + + assert(Cap->isReferenceCapture() && + "non-reference capture not yet implemented"); + + Captures.push_back(CapturedStmt::Capture(Cap->getLocation(), + CapturedStmt::VCK_ByRef, + Cap->getVariable())); + CaptureInits.push_back(Cap->getCopyExpr()); + } +} + +void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, + CapturedRegionScopeInfo::CapturedRegionKind Kind) { + CapturedDecl *CD = 0; + RecordDecl *RD = CreateCapturedStmtRecordDecl(CD, Loc); + + // Enter the capturing scope for this captured region. + PushCapturedRegionScope(CurScope, CD, RD, Kind); + + if (CurScope) + PushDeclContext(CurScope, CD); + else + CurContext = CD; + + PushExpressionEvaluationContext(PotentiallyEvaluated); +} + +void Sema::ActOnCapturedRegionError(bool IsInstantiation) { + DiscardCleanupsInEvaluationContext(); + PopExpressionEvaluationContext(); + + if (!IsInstantiation) + PopDeclContext(); + + CapturedRegionScopeInfo *RSI = getCurCapturedRegion(); + RecordDecl *Record = RSI->TheRecordDecl; + Record->setInvalidDecl(); + + SmallVector<Decl*, 4> Fields; + for (RecordDecl::field_iterator I = Record->field_begin(), + E = Record->field_end(); I != E; ++I) + Fields.push_back(*I); + ActOnFields(/*Scope=*/0, Record->getLocation(), Record, Fields, + SourceLocation(), SourceLocation(), /*AttributeList=*/0); + + PopFunctionScopeInfo(); +} + +StmtResult Sema::ActOnCapturedRegionEnd(Stmt *S) { + CapturedRegionScopeInfo *RSI = getCurCapturedRegion(); + + SmallVector<CapturedStmt::Capture, 4> Captures; + SmallVector<Expr *, 4> CaptureInits; + buildCapturedStmtCaptureList(Captures, CaptureInits, RSI->Captures); + + CapturedDecl *CD = RSI->TheCapturedDecl; + RecordDecl *RD = RSI->TheRecordDecl; + + CapturedStmt *Res = CapturedStmt::Create(getASTContext(), S, Captures, + CaptureInits, CD, RD); + + CD->setBody(Res->getCapturedStmt()); + RD->completeDefinition(); + + PopDeclContext(); + PopFunctionScopeInfo(); + + return Owned(Res); +} diff --git a/lib/Serialization/ASTCommon.cpp b/lib/Serialization/ASTCommon.cpp index e8cc1553aa..24b268f36d 100644 --- a/lib/Serialization/ASTCommon.cpp +++ b/lib/Serialization/ASTCommon.cpp @@ -119,6 +119,7 @@ serialization::getDefinitiveDeclContext(const DeclContext *DC) { case Decl::CXXConversion: case Decl::ObjCMethod: case Decl::Block: + case Decl::Captured: // Objective C categories, category implementations, and class // implementations can only be defined in one place. case Decl::ObjCCategory: @@ -203,6 +204,7 @@ bool serialization::isRedeclarableDeclKind(unsigned Kind) { case Decl::FriendTemplate: case Decl::StaticAssert: case Decl::Block: + case Decl::Captured: case Decl::ClassScopeFunctionSpecialization: case Decl::Import: case Decl::OMPThreadPrivate: diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 02295d09be..949f593434 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -266,6 +266,7 @@ namespace clang { void VisitFriendTemplateDecl(FriendTemplateDecl *D); void VisitStaticAssertDecl(StaticAssertDecl *D); void VisitBlockDecl(BlockDecl *BD); + void VisitCapturedDecl(CapturedDecl *CD); void VisitEmptyDecl(EmptyDecl *D); std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC); @@ -994,6 +995,10 @@ void ASTDeclReader::VisitBlockDecl(BlockDecl *BD) { captures.end(), capturesCXXThis); } +void ASTDeclReader::VisitCapturedDecl(CapturedDecl *) { + llvm_unreachable("not implemented yet"); +} + void ASTDeclReader::VisitLinkageSpecDecl(LinkageSpecDecl *D) { VisitDecl(D); D->setLanguage((LinkageSpecDecl::LanguageIDs)Record[Idx++]); @@ -2146,6 +2151,9 @@ Decl *ASTReader::ReadDeclRecord(DeclID ID) { case DECL_MS_PROPERTY: D = MSPropertyDecl::CreateDeserialized(Context, ID); break; + case DECL_CAPTURED: + llvm_unreachable("not implemented yet"); + break; case DECL_CXX_BASE_SPECIFIERS: Error("attempt to read a C++ base-specifier record as a declaration"); return 0; diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index 7d21c584aa..b7ca623d7d 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/lib/Serialization/ASTWriterDecl.cpp @@ -103,6 +103,7 @@ namespace clang { void VisitFriendTemplateDecl(FriendTemplateDecl *D); void VisitStaticAssertDecl(StaticAssertDecl *D); void VisitBlockDecl(BlockDecl *D); + void VisitCapturedDecl(CapturedDecl *D); void VisitEmptyDecl(EmptyDecl *D); void VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset, @@ -824,6 +825,10 @@ void ASTDeclWriter::VisitBlockDecl(BlockDecl *D) { Code = serialization::DECL_BLOCK; } +void ASTDeclWriter::VisitCapturedDecl(CapturedDecl *) { + llvm_unreachable("not implemented yet"); +} + void ASTDeclWriter::VisitLinkageSpecDecl(LinkageSpecDecl *D) { VisitDecl(D); Record.push_back(D->getLanguage()); |