aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ASTContext.cpp20
-rw-r--r--lib/Parse/ParseDecl.cpp2
-rw-r--r--lib/Parse/ParseExprCXX.cpp2
-rw-r--r--lib/Sema/Sema.cpp6
-rw-r--r--lib/Sema/SemaDecl.cpp27
-rw-r--r--lib/Sema/SemaDeclCXX.cpp4
-rw-r--r--lib/Sema/SemaExpr.cpp10
-rw-r--r--lib/Sema/SemaTemplateDeduction.cpp14
8 files changed, 53 insertions, 32 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 945dfb87f2..df92d11192 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -2683,12 +2683,22 @@ QualType ASTContext::getDecltypeType(Expr *e) const {
return QualType(dt, 0);
}
-/// getAutoType - Unlike many "get<Type>" functions, we don't unique
-/// AutoType AST's.
+/// getAutoType - We only unique auto types after they've been deduced.
QualType ASTContext::getAutoType(QualType DeducedType) const {
- AutoType *at = new (*this, TypeAlignment) AutoType(DeducedType);
- Types.push_back(at);
- return QualType(at, 0);
+ void *InsertPos = 0;
+ if (!DeducedType.isNull()) {
+ // Look in the folding set for an existing type.
+ llvm::FoldingSetNodeID ID;
+ AutoType::Profile(ID, DeducedType);
+ if (AutoType *AT = AutoTypes.FindNodeOrInsertPos(ID, InsertPos))
+ return QualType(AT, 0);
+ }
+
+ AutoType *AT = new (*this, TypeAlignment) AutoType(DeducedType);
+ Types.push_back(AT);
+ if (InsertPos)
+ AutoTypes.InsertNode(AT, InsertPos);
+ return QualType(AT, 0);
}
/// getTagDeclType - Return the unique reference to the type for the
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 5e3bfe77e7..37d152ed9d 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -667,6 +667,8 @@ Decl *Parser::ParseDeclarationAfterDeclarator(Declarator &D,
Actions.ActOnUninitializedDecl(ThisDecl, TypeContainsAuto);
}
+ Actions.FinalizeDeclaration(ThisDecl);
+
return ThisDecl;
}
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index e73578f23e..2fb9c0e5ae 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -836,6 +836,8 @@ bool Parser::ParseCXXCondition(ExprResult &ExprOut,
// FIXME: Build a reference to this declaration? Convert it to bool?
// (This is currently handled by Sema).
+
+ Actions.FinalizeDeclaration(DeclOut);
return false;
}
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 23a3c24804..78d49b7415 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -466,6 +466,12 @@ void Sema::ActOnEndOfTranslationUnit() {
checkUndefinedInternals(*this);
}
+ // Check we've noticed that we're no longer parsing the initializer for every
+ // variable. If we miss cases, then at best we have a performance issue and
+ // at worst a rejects-valid bug.
+ assert(ParsingInitForAutoVars.empty() &&
+ "Didn't unmark var as having its initializer parsed");
+
TUScope = 0;
}
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index dd30c1261e..3c62c18558 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -3026,11 +3026,11 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
NewVD = VarDecl::Create(Context, DC, D.getIdentifierLoc(),
II, R, TInfo, SC, SCAsWritten);
- // If this decl has an auto type in need of deduction, mark the VarDecl so
- // we can diagnose uses of it in its own initializer.
- if (D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto) {
- NewVD->setParsingAutoInit(R->getContainedAutoType());
- }
+ // If this decl has an auto type in need of deduction, make a note of the
+ // Decl so we can diagnose uses of it in its own initializer.
+ if (D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto &&
+ R->getContainedAutoType())
+ ParsingInitForAutoVars.insert(NewVD);
if (D.isInvalidType() || Invalid)
NewVD->setInvalidDecl();
@@ -4534,8 +4534,6 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
// C++0x [decl.spec.auto]p6. Deduce the type which 'auto' stands in for.
if (TypeMayContainAuto && VDecl->getType()->getContainedAutoType()) {
- VDecl->setParsingAutoInit(false);
-
QualType DeducedType;
if (!DeduceAutoType(VDecl->getType(), Init, DeducedType)) {
Diag(VDecl->getLocation(), diag::err_auto_var_deduction_failure)
@@ -4800,9 +4798,8 @@ void Sema::ActOnInitializerError(Decl *D) {
if (!VD) return;
// Auto types are meaningless if we can't make sense of the initializer.
- if (VD->isParsingAutoInit()) {
- VD->setParsingAutoInit(false);
- VD->setInvalidDecl();
+ if (ParsingInitForAutoVars.count(D)) {
+ D->setInvalidDecl();
return;
}
@@ -4840,8 +4837,6 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl,
// C++0x [dcl.spec.auto]p3
if (TypeMayContainAuto && Type->getContainedAutoType()) {
- Var->setParsingAutoInit(false);
-
Diag(Var->getLocation(), diag::err_auto_var_requires_init)
<< Var->getDeclName() << Type;
Var->setInvalidDecl();
@@ -5044,6 +5039,14 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
FinalizeVarWithDestructor(var, recordType);
}
+/// FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform
+/// any semantic actions necessary after any initializer has been attached.
+void
+Sema::FinalizeDeclaration(Decl *ThisDecl) {
+ // Note that we are no longer parsing the initializer for this declaration.
+ ParsingInitForAutoVars.erase(ThisDecl);
+}
+
Sema::DeclGroupPtrTy
Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
Decl **Group, unsigned NumDecls) {
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index e8abab8476..c12534645f 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -1078,6 +1078,8 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D,
if (Deleted) // FIXME: Source location is not very good.
SetDeclDeleted(Member, D.getSourceRange().getBegin());
+ FinalizeDeclaration(Member);
+
if (isInstField)
FieldCollector->Add(cast<FieldDecl>(Member));
return Member;
@@ -5972,8 +5974,6 @@ void Sema::AddCXXDirectInitializerToDecl(Decl *RealDecl,
// C++0x [decl.spec.auto]p6. Deduce the type which 'auto' stands in for.
if (TypeMayContainAuto && VDecl->getType()->getContainedAutoType()) {
- VDecl->setParsingAutoInit(false);
-
// FIXME: n3225 doesn't actually seem to indicate this is ill-formed
if (Exprs.size() > 1) {
Diag(Exprs.get()[1]->getSourceRange().getBegin(),
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index e7d167ed38..4ac3538764 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -76,12 +76,10 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc,
}
// See if this is an auto-typed variable whose initializer we are parsing.
- if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
- if (VD->isParsingAutoInit()) {
- Diag(Loc, diag::err_auto_variable_cannot_appear_in_own_initializer)
- << D->getDeclName();
- return true;
- }
+ if (ParsingInitForAutoVars.count(D)) {
+ Diag(Loc, diag::err_auto_variable_cannot_appear_in_own_initializer)
+ << D->getDeclName();
+ return true;
}
// See if the decl is deprecated.
diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp
index bd0a618283..139fafb346 100644
--- a/lib/Sema/SemaTemplateDeduction.cpp
+++ b/lib/Sema/SemaTemplateDeduction.cpp
@@ -3004,12 +3004,12 @@ Sema::DeduceAutoType(QualType Type, Expr *Init, QualType &Result) {
LocalInstantiationScope InstScope(*this);
// Build template<class TemplParam> void Func(FuncParam);
- NamedDecl *TemplParam
- = TemplateTypeParmDecl::Create(Context, 0, Loc, 0, 0, 0, false, false);
- TemplateParameterList *TemplateParams
- = TemplateParameterList::Create(Context, Loc, Loc, &TemplParam, 1, Loc);
-
QualType TemplArg = Context.getTemplateTypeParmType(0, 0, false);
+ TemplateTypeParmDecl TemplParam(0, Loc, 0, false, TemplArg, false);
+ NamedDecl *TemplParamPtr = &TemplParam;
+ FixedSizeTemplateParameterList<1> TemplateParams(Loc, Loc, &TemplParamPtr,
+ Loc);
+
QualType FuncParam =
SubstituteAutoTransform(*this, TemplArg).TransformType(Type);
@@ -3018,13 +3018,13 @@ Sema::DeduceAutoType(QualType Type, Expr *Init, QualType &Result) {
Deduced.resize(1);
QualType InitType = Init->getType();
unsigned TDF = 0;
- if (AdjustFunctionParmAndArgTypesForDeduction(*this, TemplateParams,
+ if (AdjustFunctionParmAndArgTypesForDeduction(*this, &TemplateParams,
FuncParam, InitType, Init,
TDF))
return false;
TemplateDeductionInfo Info(Context, Loc);
- if (::DeduceTemplateArguments(*this, TemplateParams,
+ if (::DeduceTemplateArguments(*this, &TemplateParams,
FuncParam, InitType, Info, Deduced,
TDF))
return false;