summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTDumper.cpp7
-rw-r--r--clang/lib/AST/ASTImporter.cpp5
-rw-r--r--clang/lib/AST/Stmt.cpp58
-rw-r--r--clang/lib/Sema/SemaStmt.cpp4
-rw-r--r--clang/lib/Serialization/ASTReaderStmt.cpp10
-rw-r--r--clang/lib/Serialization/ASTWriterStmt.cpp8
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;
}
OpenPOWER on IntegriCloud