summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-01-17 03:11:34 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-01-17 03:11:34 +0000
commit741081708eb7aa6ec02e348e1e2edfba8cb7d035 (patch)
treeae31ba53547393854609093df256c6e00a295ffa /clang/lib
parent2c6b449098dc0047f4697b2f822a7c7e56c32f43 (diff)
downloadbcm5719-llvm-741081708eb7aa6ec02e348e1e2edfba8cb7d035.tar.gz
bcm5719-llvm-741081708eb7aa6ec02e348e1e2edfba8cb7d035.zip
PR18477: Create a function scope representing the constructor call when
handling C++11 default initializers. Without this, other parts of Sema (such as lambda capture) would think the default initializer is part of the surrounding function scope. llvm-svn: 199453
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Parse/ParseCXXInlineMethods.cpp5
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp25
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp14
3 files changed, 28 insertions, 16 deletions
diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
index feff7fb724a..2fc705bc0fb 100644
--- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
@@ -528,10 +528,13 @@ void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) {
SourceLocation EqualLoc;
+ Actions.ActOnStartCXXInClassMemberInitializer();
+
ExprResult Init = ParseCXXMemberInitializer(MI.Field, /*IsFunction=*/false,
EqualLoc);
- Actions.ActOnCXXInClassMemberInitializer(MI.Field, EqualLoc, Init.release());
+ Actions.ActOnFinishCXXInClassMemberInitializer(MI.Field, EqualLoc,
+ Init.release());
// The next token should be our artificial terminating EOF token.
if (Tok.isNot(tok::eof)) {
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index c774f25241b..608f11ceff8 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -2343,13 +2343,24 @@ namespace {
}
} // namespace
-/// ActOnCXXInClassMemberInitializer - This is invoked after parsing an
-/// in-class initializer for a non-static C++ class member, and after
-/// instantiating an in-class initializer in a class template. Such actions
-/// are deferred until the class is complete.
-void
-Sema::ActOnCXXInClassMemberInitializer(Decl *D, SourceLocation InitLoc,
- Expr *InitExpr) {
+/// \brief Enter a new C++ default initializer scope. After calling this, the
+/// caller must call \ref ActOnFinishCXXInClassMemberInitializer, even if
+/// parsing or instantiating the initializer failed.
+void Sema::ActOnStartCXXInClassMemberInitializer() {
+ // Create a synthetic function scope to represent the call to the constructor
+ // that notionally surrounds a use of this initializer.
+ PushFunctionScope();
+}
+
+/// \brief This is invoked after parsing an in-class initializer for a
+/// non-static C++ class member, and after instantiating an in-class initializer
+/// in a class template. Such actions are deferred until the class is complete.
+void Sema::ActOnFinishCXXInClassMemberInitializer(Decl *D,
+ SourceLocation InitLoc,
+ Expr *InitExpr) {
+ // Pop the notional constructor scope we created earlier.
+ PopFunctionScopeInfo(0, D);
+
FieldDecl *FD = cast<FieldDecl>(D);
assert(FD->getInClassInitStyle() != ICIS_NoInit &&
"must set init style when field is created");
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 66203e6d5c5..2424e6fb84e 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2134,16 +2134,14 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
FieldDecl *NewField = FieldsWithMemberInitializers[I].second;
Expr *OldInit = OldField->getInClassInitializer();
+ ActOnStartCXXInClassMemberInitializer();
ExprResult NewInit = SubstInitializer(OldInit, TemplateArgs,
/*CXXDirectInit=*/false);
- if (NewInit.isInvalid())
- NewField->setInvalidDecl();
- else {
- Expr *Init = NewInit.take();
- assert(Init && "no-argument initializer in class");
- assert(!isa<ParenListExpr>(Init) && "call-style init in class");
- ActOnCXXInClassMemberInitializer(NewField, Init->getLocStart(), Init);
- }
+ Expr *Init = NewInit.take();
+ assert((!Init || !isa<ParenListExpr>(Init)) &&
+ "call-style init in class");
+ ActOnFinishCXXInClassMemberInitializer(NewField, Init->getLocStart(),
+ Init);
}
}
// Instantiate late parsed attributes, and attach them to their decls.
OpenPOWER on IntegriCloud