aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/Expr.h9
-rw-r--r--include/clang/AST/Stmt.h36
-rw-r--r--lib/AST/Stmt.cpp16
-rw-r--r--lib/Frontend/PCHReaderStmt.cpp4
-rw-r--r--lib/Sema/Sema.h8
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp3
-rw-r--r--lib/Sema/SemaTemplateInstantiateExpr.cpp31
7 files changed, 77 insertions, 30 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index fed58ba22b..d4b622ed04 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -67,6 +67,15 @@ protected:
explicit Expr(StmtClass SC, EmptyShell) : Stmt(SC) { }
public:
+ /// \brief Increases the reference count for this expression.
+ ///
+ /// Invoke the Retain() operation when this expression
+ /// is being shared by another owner.
+ Expr *Retain() {
+ Stmt::Retain();
+ return this;
+ }
+
QualType getType() const { return TR; }
void setType(QualType t) {
// In C++, the type of an expression is always adjusted so that it
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 239c6b5f43..5a4c93d695 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -105,7 +105,11 @@ public:
#include "clang/AST/StmtNodes.def"
};
private:
- const StmtClass sClass;
+ /// \brief The statement class.
+ const unsigned sClass : 8;
+
+ /// \brief The reference count for this statement.
+ unsigned RefCount : 24;
// Make vanilla 'new' and 'delete' illegal for Stmts.
protected:
@@ -151,7 +155,7 @@ protected:
void DestroyChildren(ASTContext& Ctx);
/// \brief Construct an empty statement.
- explicit Stmt(StmtClass SC, EmptyShell) : sClass(SC) {
+ explicit Stmt(StmtClass SC, EmptyShell) : sClass(SC), RefCount(1) {
if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
}
@@ -163,15 +167,27 @@ protected:
virtual void DoDestroy(ASTContext &Ctx);
public:
- Stmt(StmtClass SC) : sClass(SC) {
+ Stmt(StmtClass SC) : sClass(SC), RefCount(1) {
if (Stmt::CollectingStats()) Stmt::addStmtClass(SC);
}
virtual ~Stmt() {}
/// \brief Destroy the current statement and its children.
- void Destroy(ASTContext &Ctx) { DoDestroy(Ctx); }
+ void Destroy(ASTContext &Ctx) {
+ if (--RefCount == 0)
+ DoDestroy(Ctx);
+ }
- StmtClass getStmtClass() const { return sClass; }
+ /// \brief Increases the reference count for this statement.
+ ///
+ /// Invoke the Retain() operation when this statement or expression
+ /// is being shared by another owner.
+ Stmt *Retain() {
+ ++RefCount;
+ return this;
+ }
+
+ StmtClass getStmtClass() const { return (StmtClass)sClass; }
const char *getStmtClassName() const;
/// SourceLocation tokens are not useful in isolation - they are low level
@@ -643,6 +659,10 @@ class SwitchStmt : public Stmt {
// This points to a linked list of case and default statements.
SwitchCase *FirstCase;
SourceLocation SwitchLoc;
+
+protected:
+ virtual void DoDestroy(ASTContext &Ctx);
+
public:
SwitchStmt(Expr *cond) : Stmt(SwitchStmtClass), FirstCase(0) {
SubExprs[COND] = reinterpret_cast<Stmt*>(cond);
@@ -661,6 +681,11 @@ public:
Stmt *getBody() { return SubExprs[BODY]; }
void setBody(Stmt *S) { SubExprs[BODY] = S; }
SwitchCase *getSwitchCaseList() { return FirstCase; }
+
+ /// \brief Set the case list for this switch statement.
+ ///
+ /// The caller is responsible for incrementing the retain counts on
+ /// all of the SwitchCase statements in this list.
void setSwitchCaseList(SwitchCase *SC) { FirstCase = SC; }
SourceLocation getSwitchLoc() const { return SwitchLoc; }
@@ -672,6 +697,7 @@ public:
}
void addSwitchCase(SwitchCase *SC) {
assert(!SC->getNextSwitchCase() && "case/default already added to a switch");
+ SC->Retain();
SC->setNextSwitchCase(FirstCase);
FirstCase = SC;
}
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index 668f7ef57f..a0ef5a6428 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -43,7 +43,7 @@ static StmtClassNameTable &getStmtInfoTableEntry(Stmt::StmtClass E) {
}
const char *Stmt::getStmtClassName() const {
- return getStmtInfoTableEntry(sClass).Name;
+ return getStmtInfoTableEntry((StmtClass)sClass).Name;
}
void Stmt::DestroyChildren(ASTContext &C) {
@@ -104,6 +104,20 @@ BreakStmt* BreakStmt::Clone(ASTContext &C) const {
return new (C) BreakStmt(BreakLoc);
}
+void SwitchStmt::DoDestroy(ASTContext &Ctx) {
+ // Destroy the SwitchCase statements in this switch. In the normal
+ // case, this loop will merely decrement the reference counts from
+ // the Retain() calls in addSwitchCase();
+ SwitchCase *SC = FirstCase;
+ while (SC) {
+ SwitchCase *Next = SC->getNextSwitchCase();
+ SC->Destroy(Ctx);
+ SC = Next;
+ }
+
+ Stmt::DoDestroy(Ctx);
+}
+
void CompoundStmt::setStmts(ASTContext &C, Stmt **Stmts, unsigned NumStmts) {
if (this->Body)
C.Deallocate(Body);
diff --git a/lib/Frontend/PCHReaderStmt.cpp b/lib/Frontend/PCHReaderStmt.cpp
index 6b97e610f5..3040a52260 100644
--- a/lib/Frontend/PCHReaderStmt.cpp
+++ b/lib/Frontend/PCHReaderStmt.cpp
@@ -194,6 +194,10 @@ unsigned PCHStmtReader::VisitSwitchStmt(SwitchStmt *S) {
PrevSC->setNextSwitchCase(SC);
else
S->setSwitchCaseList(SC);
+
+ // Retain this SwitchCase, since SwitchStmt::addSwitchCase() would
+ // normally retain it (but we aren't calling addSwitchCase).
+ SC->Retain();
PrevSC = SC;
}
return 2;
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 6094e6dae0..295607b739 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -2821,14 +2821,6 @@ public:
NamedDecl *InstantiateCurrentDeclRef(NamedDecl *D);
- // Simple function for cloning expressions.
- template<typename T>
- OwningExprResult Clone(T *E) {
- assert(!E->isValueDependent() && !E->isTypeDependent() &&
- "expression is value or type dependent!");
- return Owned(E->Clone(Context));
- }
-
// Objective-C declarations.
virtual DeclPtrTy ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
IdentifierInfo *ClassName,
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 021a6ad2ab..1c98fca6af 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -222,7 +222,8 @@ Decl *TemplateDeclInstantiator::VisitStaticAssertDecl(StaticAssertDecl *D) {
if (InstantiatedAssertExpr.isInvalid())
return 0;
- OwningExprResult Message = SemaRef.Clone(D->getMessage());
+ OwningExprResult Message(SemaRef, D->getMessage());
+ D->getMessage()->Retain();
Decl *StaticAssert
= SemaRef.ActOnStaticAssertDeclaration(D->getLocation(),
move(InstantiatedAssertExpr),
diff --git a/lib/Sema/SemaTemplateInstantiateExpr.cpp b/lib/Sema/SemaTemplateInstantiateExpr.cpp
index 2e7ed1a632..1e97f5fcc4 100644
--- a/lib/Sema/SemaTemplateInstantiateExpr.cpp
+++ b/lib/Sema/SemaTemplateInstantiateExpr.cpp
@@ -57,53 +57,53 @@ Sema::OwningExprResult TemplateExprInstantiator::VisitExpr(Expr *E) {
Sema::OwningExprResult
TemplateExprInstantiator::VisitPredefinedExpr(PredefinedExpr *E) {
- return SemaRef.Clone(E);
+ return SemaRef.Owned(E->Retain());
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitIntegerLiteral(IntegerLiteral *E) {
- return SemaRef.Clone(E);
+ return SemaRef.Owned(E->Retain());
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitFloatingLiteral(FloatingLiteral *E) {
- return SemaRef.Clone(E);
+ return SemaRef.Owned(E->Retain());
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitStringLiteral(StringLiteral *E) {
- return SemaRef.Clone(E);
+ return SemaRef.Owned(E->Retain());
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitCharacterLiteral(CharacterLiteral *E) {
- return SemaRef.Clone(E);
+ return SemaRef.Owned(E->Retain());
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitImaginaryLiteral(ImaginaryLiteral *E) {
- return SemaRef.Clone(E);
+ return SemaRef.Owned(E->Retain());
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
- return SemaRef.Clone(E);
+ return SemaRef.Owned(E->Retain());
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitCXXNullPtrLiteralExpr(CXXNullPtrLiteralExpr *E) {
- return SemaRef.Clone(E);
+ return SemaRef.Owned(E->Retain());
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitGNUNullExpr(GNUNullExpr *E) {
- return SemaRef.Clone(E);
+ return SemaRef.Owned(E->Retain());
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitUnresolvedFunctionNameExpr(
UnresolvedFunctionNameExpr *E) {
- return SemaRef.Clone(E);
+ return SemaRef.Owned(E->Retain());
}
Sema::OwningExprResult
@@ -706,7 +706,8 @@ TemplateExprInstantiator::VisitImplicitValueInitExpr(
ImplicitValueInitExpr *E) {
assert(!E->isTypeDependent() && !E->isValueDependent() &&
"ImplicitValueInitExprs are never dependent");
- return SemaRef.Clone(E);
+ E->Retain();
+ return SemaRef.Owned(E);
}
Sema::OwningExprResult
@@ -1110,7 +1111,7 @@ TemplateExprInstantiator::VisitCXXFunctionalCastExpr(
Sema::OwningExprResult
TemplateExprInstantiator::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
- return SemaRef.Clone(E);
+ return SemaRef.Owned(E->Retain());
}
Sema::OwningExprResult
@@ -1289,7 +1290,7 @@ TemplateExprInstantiator::VisitCXXUnresolvedMemberExpr(
//----------------------------------------------------------------------------
Sema::OwningExprResult
TemplateExprInstantiator::VisitObjCStringLiteral(ObjCStringLiteral *E) {
- return SemaRef.Owned(E->Clone(SemaRef.Context));
+ return SemaRef.Owned(E->Retain());
}
Sema::OwningExprResult
@@ -1314,12 +1315,12 @@ TemplateExprInstantiator::VisitObjCMessageExpr(ObjCMessageExpr *E) {
Sema::OwningExprResult
TemplateExprInstantiator::VisitObjCSelectorExpr(ObjCSelectorExpr *E) {
- return SemaRef.Owned(E->Clone(SemaRef.Context));
+ return SemaRef.Owned(E->Retain());
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
- return SemaRef.Owned(E->Clone(SemaRef.Context));
+ return SemaRef.Owned(E->Retain());
}
Sema::OwningExprResult