forked from OSchip/llvm-project
Unify initializer-instantiation code for variable declarations and
base/member initializers. llvm-svn: 97560
This commit is contained in:
parent
350bb062b2
commit
b30f22b911
|
@ -202,6 +202,72 @@ static bool InstantiateInitializationArguments(Sema &SemaRef,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// \brief Instantiate an initializer, breaking it into separate
|
||||||
|
/// initialization arguments.
|
||||||
|
///
|
||||||
|
/// \param S The semantic analysis object.
|
||||||
|
///
|
||||||
|
/// \param Init The initializer to instantiate.
|
||||||
|
///
|
||||||
|
/// \param TemplateArgs Template arguments to be substituted into the
|
||||||
|
/// initializer.
|
||||||
|
///
|
||||||
|
/// \param NewArgs Will be filled in with the instantiation arguments.
|
||||||
|
///
|
||||||
|
/// \returns true if an error occurred, false otherwise
|
||||||
|
static bool InstantiateInitializer(Sema &S, Expr *Init,
|
||||||
|
const MultiLevelTemplateArgumentList &TemplateArgs,
|
||||||
|
SourceLocation &LParenLoc,
|
||||||
|
llvm::SmallVector<SourceLocation, 4> &CommaLocs,
|
||||||
|
ASTOwningVector<&ActionBase::DeleteExpr> &NewArgs,
|
||||||
|
SourceLocation &RParenLoc) {
|
||||||
|
NewArgs.clear();
|
||||||
|
LParenLoc = SourceLocation();
|
||||||
|
RParenLoc = SourceLocation();
|
||||||
|
|
||||||
|
if (!Init)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (CXXExprWithTemporaries *ExprTemp = dyn_cast<CXXExprWithTemporaries>(Init))
|
||||||
|
Init = ExprTemp->getSubExpr();
|
||||||
|
|
||||||
|
while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init))
|
||||||
|
Init = Binder->getSubExpr();
|
||||||
|
|
||||||
|
if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))
|
||||||
|
Init = ICE->getSubExprAsWritten();
|
||||||
|
|
||||||
|
if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
|
||||||
|
LParenLoc = ParenList->getLParenLoc();
|
||||||
|
RParenLoc = ParenList->getRParenLoc();
|
||||||
|
return InstantiateInitializationArguments(S, ParenList->getExprs(),
|
||||||
|
ParenList->getNumExprs(),
|
||||||
|
TemplateArgs, CommaLocs,
|
||||||
|
NewArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init)) {
|
||||||
|
if (InstantiateInitializationArguments(S,
|
||||||
|
Construct->getArgs(),
|
||||||
|
Construct->getNumArgs(),
|
||||||
|
TemplateArgs,
|
||||||
|
CommaLocs, NewArgs))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// FIXME: Fake locations!
|
||||||
|
LParenLoc = S.PP.getLocForEndOfToken(Init->getLocStart());
|
||||||
|
RParenLoc = CommaLocs.empty()? LParenLoc : CommaLocs.back();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Sema::OwningExprResult Result = S.SubstExpr(Init, TemplateArgs);
|
||||||
|
if (Result.isInvalid())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
NewArgs.push_back(Result.takeAs<Expr>());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
|
Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
|
||||||
// Do substitution on the type of the declaration
|
// Do substitution on the type of the declaration
|
||||||
TypeSourceInfo *DI = SemaRef.SubstType(D->getTypeSourceInfo(),
|
TypeSourceInfo *DI = SemaRef.SubstType(D->getTypeSourceInfo(),
|
||||||
|
@ -259,77 +325,33 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
|
||||||
else
|
else
|
||||||
SemaRef.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated);
|
SemaRef.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated);
|
||||||
|
|
||||||
// Extract the initializer, skipping through any temporary-binding
|
// Instantiate the initializer.
|
||||||
// expressions and look at the subexpression as it was written.
|
SourceLocation LParenLoc, RParenLoc;
|
||||||
Expr *DInit = D->getInit();
|
llvm::SmallVector<SourceLocation, 4> CommaLocs;
|
||||||
if (CXXExprWithTemporaries *ExprTemp
|
ASTOwningVector<&ActionBase::DeleteExpr> InitArgs(SemaRef);
|
||||||
= dyn_cast<CXXExprWithTemporaries>(DInit))
|
if (!InstantiateInitializer(SemaRef, D->getInit(), TemplateArgs, LParenLoc,
|
||||||
DInit = ExprTemp->getSubExpr();
|
CommaLocs, InitArgs, RParenLoc)) {
|
||||||
while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(DInit))
|
// Attach the initializer to the declaration.
|
||||||
DInit = Binder->getSubExpr();
|
if (D->hasCXXDirectInitializer()) {
|
||||||
if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(DInit))
|
|
||||||
DInit = ICE->getSubExprAsWritten();
|
|
||||||
|
|
||||||
if (ParenListExpr *PLE = dyn_cast<ParenListExpr>(DInit)) {
|
|
||||||
// The initializer is a parenthesized list of expressions that is
|
|
||||||
// type-dependent. Instantiate each of the expressions; we'll be
|
|
||||||
// performing direct initialization with them.
|
|
||||||
llvm::SmallVector<SourceLocation, 4> CommaLocs;
|
|
||||||
ASTOwningVector<&ActionBase::DeleteExpr> InitArgs(SemaRef);
|
|
||||||
if (!InstantiateInitializationArguments(SemaRef,
|
|
||||||
PLE->getExprs(),
|
|
||||||
PLE->getNumExprs(),
|
|
||||||
TemplateArgs,
|
|
||||||
CommaLocs, InitArgs)) {
|
|
||||||
// Add the direct initializer to the declaration.
|
// Add the direct initializer to the declaration.
|
||||||
SemaRef.AddCXXDirectInitializerToDecl(Sema::DeclPtrTy::make(Var),
|
SemaRef.AddCXXDirectInitializerToDecl(Sema::DeclPtrTy::make(Var),
|
||||||
PLE->getLParenLoc(),
|
LParenLoc,
|
||||||
move_arg(InitArgs),
|
move_arg(InitArgs),
|
||||||
CommaLocs.data(),
|
CommaLocs.data(),
|
||||||
PLE->getRParenLoc());
|
RParenLoc);
|
||||||
}
|
} else if (InitArgs.size() == 1) {
|
||||||
} else if (CXXConstructExpr *Construct =dyn_cast<CXXConstructExpr>(DInit)) {
|
Expr *Init = (Expr*)(InitArgs.take()[0]);
|
||||||
// The initializer resolved to a constructor. Instantiate the constructor
|
SemaRef.AddInitializerToDecl(Sema::DeclPtrTy::make(Var),
|
||||||
// arguments.
|
SemaRef.Owned(Init),
|
||||||
llvm::SmallVector<SourceLocation, 4> CommaLocs;
|
false);
|
||||||
ASTOwningVector<&ActionBase::DeleteExpr> InitArgs(SemaRef);
|
} else {
|
||||||
|
assert(InitArgs.size() == 0);
|
||||||
if (!InstantiateInitializationArguments(SemaRef,
|
SemaRef.ActOnUninitializedDecl(Sema::DeclPtrTy::make(Var), false);
|
||||||
Construct->getArgs(),
|
|
||||||
Construct->getNumArgs(),
|
|
||||||
TemplateArgs,
|
|
||||||
CommaLocs, InitArgs)) {
|
|
||||||
if (D->hasCXXDirectInitializer()) {
|
|
||||||
SourceLocation FakeLParenLoc =
|
|
||||||
SemaRef.PP.getLocForEndOfToken(D->getLocation());
|
|
||||||
SourceLocation FakeRParenLoc = CommaLocs.empty()? FakeLParenLoc
|
|
||||||
: CommaLocs.back();
|
|
||||||
SemaRef.AddCXXDirectInitializerToDecl(Sema::DeclPtrTy::make(Var),
|
|
||||||
FakeLParenLoc,
|
|
||||||
move_arg(InitArgs),
|
|
||||||
CommaLocs.data(),
|
|
||||||
FakeRParenLoc);
|
|
||||||
} else if (InitArgs.size() == 1) {
|
|
||||||
Expr *Init = (Expr*)(InitArgs.take()[0]);
|
|
||||||
SemaRef.AddInitializerToDecl(Sema::DeclPtrTy::make(Var),
|
|
||||||
SemaRef.Owned(Init),
|
|
||||||
false);
|
|
||||||
} else {
|
|
||||||
assert(InitArgs.size() == 0);
|
|
||||||
SemaRef.ActOnUninitializedDecl(Sema::DeclPtrTy::make(Var), false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
OwningExprResult Init
|
// FIXME: Not too happy about invalidating the declaration
|
||||||
= SemaRef.SubstExpr(D->getInit(), TemplateArgs);
|
// because of a bogus initializer.
|
||||||
|
Var->setInvalidDecl();
|
||||||
// FIXME: Not happy about invalidating decls just because of a bad
|
|
||||||
// initializer, unless it affects the type.
|
|
||||||
if (Init.isInvalid())
|
|
||||||
Var->setInvalidDecl();
|
|
||||||
else
|
|
||||||
SemaRef.AddInitializerToDecl(Sema::DeclPtrTy::make(Var), move(Init),
|
|
||||||
D->hasCXXDirectInitializer());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SemaRef.PopExpressionEvaluationContext();
|
SemaRef.PopExpressionEvaluationContext();
|
||||||
|
@ -1888,29 +1910,15 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New,
|
||||||
Inits != InitsEnd; ++Inits) {
|
Inits != InitsEnd; ++Inits) {
|
||||||
CXXBaseOrMemberInitializer *Init = *Inits;
|
CXXBaseOrMemberInitializer *Init = *Inits;
|
||||||
|
|
||||||
|
SourceLocation LParenLoc, RParenLoc;
|
||||||
ASTOwningVector<&ActionBase::DeleteExpr> NewArgs(*this);
|
ASTOwningVector<&ActionBase::DeleteExpr> NewArgs(*this);
|
||||||
llvm::SmallVector<SourceLocation, 4> CommaLocs;
|
llvm::SmallVector<SourceLocation, 4> CommaLocs;
|
||||||
|
|
||||||
// Instantiate all the arguments.
|
// Instantiate the initializer.
|
||||||
Expr *InitE = Init->getInit();
|
if (InstantiateInitializer(*this, Init->getInit(), TemplateArgs,
|
||||||
if (!InitE) {
|
LParenLoc, CommaLocs, NewArgs, RParenLoc)) {
|
||||||
// Nothing to instantiate;
|
AnyErrors = true;
|
||||||
} else if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(InitE)) {
|
continue;
|
||||||
if (InstantiateInitializationArguments(*this, ParenList->getExprs(),
|
|
||||||
ParenList->getNumExprs(),
|
|
||||||
TemplateArgs, CommaLocs,
|
|
||||||
NewArgs)) {
|
|
||||||
AnyErrors = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
OwningExprResult InitArg = SubstExpr(InitE, TemplateArgs);
|
|
||||||
if (InitArg.isInvalid()) {
|
|
||||||
AnyErrors = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
NewArgs.push_back(InitArg.release());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MemInitResult NewInit;
|
MemInitResult NewInit;
|
||||||
|
|
Loading…
Reference in New Issue