diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/Decl.cpp | 16 | ||||
-rw-r--r-- | clang/lib/AST/Expr.cpp | 17 | ||||
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 13 | ||||
-rw-r--r-- | clang/lib/AST/StmtIterator.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Frontend/PCHReaderDecl.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 2 |
7 files changed, 47 insertions, 11 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 20fe39d0af5..6c620713f76 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -89,6 +89,15 @@ QualType ParmVarDecl::getOriginalType() const { return getType(); } +void VarDecl::setInit(ASTContext &C, Expr *I) { + if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>()) { + Eval->~EvaluatedStmt(); + C.Deallocate(Eval); + } + + Init = I; + } + bool VarDecl::isExternC(ASTContext &Context) const { if (!Context.getLangOptions().CPlusPlus) return (getDeclContext()->isTranslationUnit() && @@ -287,8 +296,13 @@ VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, void VarDecl::Destroy(ASTContext& C) { Expr *Init = getInit(); - if (Init) + if (Init) { Init->Destroy(C); + if (EvaluatedStmt *Eval = this->Init.dyn_cast<EvaluatedStmt *>()) { + Eval->~EvaluatedStmt(); + C.Deallocate(Eval); + } + } this->~VarDecl(); C.Deallocate((void *)this); } diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 6711faffe74..aca5efeb163 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1210,8 +1210,21 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) { // type initialized by an ICE can be used in ICEs. if (const VarDecl *Dcl = dyn_cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl())) { - if (const Expr *Init = Dcl->getInit()) - return CheckICE(Init, Ctx); + if (Dcl->isInitKnownICE()) { + // We have already checked whether this subexpression is an + // integral constant expression. + if (Dcl->isInitICE()) + return NoDiag(); + else + return ICEDiag(2, E->getLocStart()); + } + + if (const Expr *Init = Dcl->getInit()) { + ICEDiag Result = CheckICE(Init, Ctx); + // Cache the result of the ICE test. + Dcl->setInitKnownICE(Ctx, Result.Val == 0); + return Result; + } } } return ICEDiag(2, E->getLocStart()); diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 34b01879708..7651884aa60 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -700,8 +700,17 @@ bool IntExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) { // In C, they can also be folded, although they are not ICEs. if (E->getType().getCVRQualifiers() == QualType::Const) { if (const VarDecl *D = dyn_cast<VarDecl>(E->getDecl())) { - if (const Expr *Init = D->getInit()) - return Visit(const_cast<Expr*>(Init)); + if (APValue *V = D->getEvaluatedValue()) + return Success(V->getInt(), E); + if (const Expr *Init = D->getInit()) { + if (Visit(const_cast<Expr*>(Init))) { + // Cache the evaluated value in the variable declaration. + D->setEvaluatedValue(Info.Ctx, Result); + return true; + } + + return false; + } } } diff --git a/clang/lib/AST/StmtIterator.cpp b/clang/lib/AST/StmtIterator.cpp index 20024f513ff..5c22e28894f 100644 --- a/clang/lib/AST/StmtIterator.cpp +++ b/clang/lib/AST/StmtIterator.cpp @@ -140,14 +140,14 @@ Stmt*& StmtIteratorBase::GetDeclExpr() const { if (inDeclGroup()) { VarDecl* VD = cast<VarDecl>(*DGI); - return VD->Init; + return *VD->getInitAddress(); } assert (inDecl()); if (VarDecl* VD = dyn_cast<VarDecl>(decl)) { assert (VD->Init); - return VD->Init; + return *VD->getInitAddress(); } EnumConstantDecl* ECD = cast<EnumConstantDecl>(decl); diff --git a/clang/lib/Frontend/PCHReaderDecl.cpp b/clang/lib/Frontend/PCHReaderDecl.cpp index 7d4c6341932..adf0d1155e2 100644 --- a/clang/lib/Frontend/PCHReaderDecl.cpp +++ b/clang/lib/Frontend/PCHReaderDecl.cpp @@ -342,7 +342,7 @@ void PCHDeclReader::VisitVarDecl(VarDecl *VD) { cast_or_null<VarDecl>(Reader.GetDecl(Record[Idx++]))); VD->setTypeSpecStartLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); if (Record[Idx++]) - VD->setInit(Reader.ReadDeclExpr()); + VD->setInit(*Reader.getContext(), Reader.ReadDeclExpr()); } void PCHDeclReader::VisitImplicitParamDecl(ImplicitParamDecl *PD) { diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 22bdc7999bb..4149fa4c9a3 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2581,7 +2581,7 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) { // }; // Attach the initializer - VDecl->setInit(Init); + VDecl->setInit(Context, Init); // C++ [class.mem]p4: // A member-declarator can contain a constant-initializer only @@ -2644,7 +2644,7 @@ void Sema::AddInitializerToDecl(DeclPtrTy dcl, ExprArg init, bool DirectInit) { } // Attach the initializer to the decl. - VDecl->setInit(Init); + VDecl->setInit(Context, Init); // If the previous declaration of VDecl was a tentative definition, // remove it from the set of tentative definitions. diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index feb94569ed2..ebe34064d6d 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1776,7 +1776,7 @@ void Sema::InitializeVarWithConstructor(VarDecl *VD, Expr **Exprs, unsigned NumExprs) { Expr *Temp = CXXConstructExpr::Create(Context, VD, DeclInitType, Constructor, false, Exprs, NumExprs); - VD->setInit(Temp); + VD->setInit(Context, Temp); } /// AddCXXDirectInitializerToDecl - This action is called immediately after |