diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTDumper.cpp | 7 | ||||
-rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 5 | ||||
-rw-r--r-- | clang/lib/AST/Stmt.cpp | 58 | ||||
-rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderStmt.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterStmt.cpp | 8 |
6 files changed, 69 insertions, 23 deletions
diff --git a/clang/lib/AST/ASTDumper.cpp b/clang/lib/AST/ASTDumper.cpp index 99524e88937..e84814a96c0 100644 --- a/clang/lib/AST/ASTDumper.cpp +++ b/clang/lib/AST/ASTDumper.cpp @@ -513,6 +513,7 @@ namespace { void VisitAttributedStmt(const AttributedStmt *Node); void VisitIfStmt(const IfStmt *Node); void VisitSwitchStmt(const SwitchStmt *Node); + void VisitWhileStmt(const WhileStmt *Node); void VisitLabelStmt(const LabelStmt *Node); void VisitGotoStmt(const GotoStmt *Node); void VisitCXXCatchStmt(const CXXCatchStmt *Node); @@ -2041,6 +2042,12 @@ void ASTDumper::VisitSwitchStmt(const SwitchStmt *Node) { OS << " has_var"; } +void ASTDumper::VisitWhileStmt(const WhileStmt *Node) { + VisitStmt(Node); + if (Node->hasVarStorage()) + OS << " has_var"; +} + void ASTDumper::VisitLabelStmt(const LabelStmt *Node) { VisitStmt(Node); OS << " '" << Node->getName() << "'"; diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index b5f9472c9e3..f87f426336d 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -5864,9 +5864,8 @@ ExpectedStmt ASTNodeImporter::VisitWhileStmt(WhileStmt *S) { SourceLocation ToWhileLoc; std::tie(ToConditionVariable, ToCond, ToBody, ToWhileLoc) = *Imp; - return new (Importer.getToContext()) WhileStmt( - Importer.getToContext(), - ToConditionVariable, ToCond, ToBody, ToWhileLoc); + return WhileStmt::Create(Importer.getToContext(), ToConditionVariable, ToCond, + ToBody, ToWhileLoc); } ExpectedStmt ASTNodeImporter::VisitDoStmt(DoStmt *S) { diff --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp index 41a4a64f33f..81a2c50d769 100644 --- a/clang/lib/AST/Stmt.cpp +++ b/clang/lib/AST/Stmt.cpp @@ -978,32 +978,60 @@ void SwitchStmt::setConditionVariable(const ASTContext &Ctx, VarDecl *V) { DeclStmt(DeclGroupRef(V), VarRange.getBegin(), VarRange.getEnd()); } -WhileStmt::WhileStmt(const ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body, - SourceLocation WL) - : Stmt(WhileStmtClass) { - setConditionVariable(C, Var); - SubExprs[COND] = cond; - SubExprs[BODY] = body; - WhileStmtBits.WhileLoc = WL; +WhileStmt::WhileStmt(const ASTContext &Ctx, VarDecl *Var, Expr *Cond, + Stmt *Body, SourceLocation WL) + : Stmt(WhileStmtClass) { + bool HasVar = Var != nullptr; + WhileStmtBits.HasVar = HasVar; + + setCond(Cond); + setBody(Body); + if (HasVar) + setConditionVariable(Ctx, Var); + + setWhileLoc(WL); } -VarDecl *WhileStmt::getConditionVariable() const { - if (!SubExprs[VAR]) - return nullptr; +WhileStmt::WhileStmt(EmptyShell Empty, bool HasVar) + : Stmt(WhileStmtClass, Empty) { + WhileStmtBits.HasVar = HasVar; +} + +WhileStmt *WhileStmt::Create(const ASTContext &Ctx, VarDecl *Var, Expr *Cond, + Stmt *Body, SourceLocation WL) { + bool HasVar = Var != nullptr; + void *Mem = + Ctx.Allocate(totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasVar), + alignof(WhileStmt)); + return new (Mem) WhileStmt(Ctx, Var, Cond, Body, WL); +} - auto *DS = cast<DeclStmt>(SubExprs[VAR]); +WhileStmt *WhileStmt::CreateEmpty(const ASTContext &Ctx, bool HasVar) { + void *Mem = + Ctx.Allocate(totalSizeToAlloc<Stmt *>(NumMandatoryStmtPtr + HasVar), + alignof(WhileStmt)); + return new (Mem) WhileStmt(EmptyShell(), HasVar); +} + +VarDecl *WhileStmt::getConditionVariable() { + auto *DS = getConditionVariableDeclStmt(); + if (!DS) + return nullptr; return cast<VarDecl>(DS->getSingleDecl()); } -void WhileStmt::setConditionVariable(const ASTContext &C, VarDecl *V) { +void WhileStmt::setConditionVariable(const ASTContext &Ctx, VarDecl *V) { + assert(hasVarStorage() && + "This while statement has no storage for a condition variable!"); + if (!V) { - SubExprs[VAR] = nullptr; + getTrailingObjects<Stmt *>()[varOffset()] = nullptr; return; } SourceRange VarRange = V->getSourceRange(); - SubExprs[VAR] = new (C) DeclStmt(DeclGroupRef(V), VarRange.getBegin(), - VarRange.getEnd()); + getTrailingObjects<Stmt *>()[varOffset()] = new (Ctx) + DeclStmt(DeclGroupRef(V), VarRange.getBegin(), VarRange.getEnd()); } // IndirectGotoStmt diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 2018c874af5..5aff9c55738 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -1306,8 +1306,8 @@ StmtResult Sema::ActOnWhileStmt(SourceLocation WhileLoc, ConditionResult Cond, if (isa<NullStmt>(Body)) getCurCompoundScope().setHasEmptyLoopBodies(); - return new (Context) - WhileStmt(Context, CondVal.first, CondVal.second, Body, WhileLoc); + return WhileStmt::Create(Context, CondVal.first, CondVal.second, Body, + WhileLoc); } StmtResult diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 3c63fe1143d..8865ee335c5 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -270,10 +270,14 @@ void ASTStmtReader::VisitSwitchStmt(SwitchStmt *S) { void ASTStmtReader::VisitWhileStmt(WhileStmt *S) { VisitStmt(S); - S->setConditionVariable(Record.getContext(), ReadDeclAs<VarDecl>()); + + bool HasVar = Record.readInt(); S->setCond(Record.readSubExpr()); S->setBody(Record.readSubStmt()); + if (HasVar) + S->setConditionVariable(Record.getContext(), ReadDeclAs<VarDecl>()); + S->setWhileLoc(ReadSourceLocation()); } @@ -2325,7 +2329,9 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { break; case STMT_WHILE: - S = new (Context) WhileStmt(Empty); + S = WhileStmt::CreateEmpty( + Context, + /* HasVar=*/Record[ASTStmtReader::NumStmtFields + 0]); break; case STMT_DO: diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 396cc1c2d05..3d0297153d8 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -183,9 +183,15 @@ void ASTStmtWriter::VisitSwitchStmt(SwitchStmt *S) { void ASTStmtWriter::VisitWhileStmt(WhileStmt *S) { VisitStmt(S); - Record.AddDeclRef(S->getConditionVariable()); + + bool HasVar = S->getConditionVariableDeclStmt() != nullptr; + Record.push_back(HasVar); + Record.AddStmt(S->getCond()); Record.AddStmt(S->getBody()); + if (HasVar) + Record.AddDeclRef(S->getConditionVariable()); + Record.AddSourceLocation(S->getWhileLoc()); Code = serialization::STMT_WHILE; } |