aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-04-16 16:02:28 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-04-16 16:02:28 +0000
commit7442d6faa2719e4e7d33a7021c406c5a4facd74d (patch)
treec72b9241553fc9966179aba84f90f17bfa9235c3 /lib/Sema/SemaDecl.cpp
parentb52119637f743680a99710ce5fdb6646da2772af (diff)
downloadsrc-7442d6faa2719e4e7d33a7021c406c5a4facd74d.tar.gz
src-7442d6faa2719e4e7d33a7021c406c5a4facd74d.zip
Vendor import of clang trunk r300422:vendor/clang/clang-trunk-r300422
Notes
Notes: svn path=/vendor/clang/dist/; revision=317019 svn path=/vendor/clang/clang-trunk-r300422/; revision=317020; tag=vendor/clang/clang-trunk-r300422
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r--lib/Sema/SemaDecl.cpp680
1 files changed, 423 insertions, 257 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index adcf2ee00e75..c6a0b0101d37 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -67,7 +67,7 @@ class TypeNameValidatorCCC : public CorrectionCandidateCallback {
TypeNameValidatorCCC(bool AllowInvalid, bool WantClass=false,
bool AllowTemplates=false)
: AllowInvalidDecl(AllowInvalid), WantClassName(WantClass),
- AllowClassTemplates(AllowTemplates) {
+ AllowTemplates(AllowTemplates) {
WantExpressionKeywords = false;
WantCXXNamedCasts = false;
WantRemainingKeywords = false;
@@ -76,7 +76,7 @@ class TypeNameValidatorCCC : public CorrectionCandidateCallback {
bool ValidateCandidate(const TypoCorrection &candidate) override {
if (NamedDecl *ND = candidate.getCorrectionDecl()) {
bool IsType = isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
- bool AllowedTemplate = AllowClassTemplates && isa<ClassTemplateDecl>(ND);
+ bool AllowedTemplate = AllowTemplates && getAsTypeTemplateDecl(ND);
return (IsType || AllowedTemplate) &&
(AllowInvalidDecl || !ND->isInvalidDecl());
}
@@ -86,7 +86,7 @@ class TypeNameValidatorCCC : public CorrectionCandidateCallback {
private:
bool AllowInvalidDecl;
bool WantClassName;
- bool AllowClassTemplates;
+ bool AllowTemplates;
};
} // end anonymous namespace
@@ -252,7 +252,13 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
ParsedType ObjectTypePtr,
bool IsCtorOrDtorName,
bool WantNontrivialTypeSourceInfo,
+ bool IsClassTemplateDeductionContext,
IdentifierInfo **CorrectedII) {
+ // FIXME: Consider allowing this outside C++1z mode as an extension.
+ bool AllowDeducedTemplate = IsClassTemplateDeductionContext &&
+ getLangOpts().CPlusPlus1z && !IsCtorOrDtorName &&
+ !isClassName && !HasTrailingDot;
+
// Determine where we will perform name lookup.
DeclContext *LookupCtx = nullptr;
if (ObjectTypePtr) {
@@ -334,10 +340,11 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
case LookupResult::NotFound:
case LookupResult::NotFoundInCurrentInstantiation:
if (CorrectedII) {
- TypoCorrection Correction = CorrectTypo(
- Result.getLookupNameInfo(), Kind, S, SS,
- llvm::make_unique<TypeNameValidatorCCC>(true, isClassName),
- CTK_ErrorRecovery);
+ TypoCorrection Correction =
+ CorrectTypo(Result.getLookupNameInfo(), Kind, S, SS,
+ llvm::make_unique<TypeNameValidatorCCC>(
+ true, isClassName, AllowDeducedTemplate),
+ CTK_ErrorRecovery);
IdentifierInfo *NewII = Correction.getCorrectionAsIdentifierInfo();
TemplateTy Template;
bool MemberOfUnknownSpecialization;
@@ -359,7 +366,8 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
ParsedType Ty = getTypeName(*NewII, NameLoc, S, NewSSPtr,
isClassName, HasTrailingDot, ObjectTypePtr,
IsCtorOrDtorName,
- WantNontrivialTypeSourceInfo);
+ WantNontrivialTypeSourceInfo,
+ IsClassTemplateDeductionContext);
if (Ty) {
diagnoseTypo(Correction,
PDiag(diag::err_unknown_type_or_class_name_suggest)
@@ -391,7 +399,8 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
// Look to see if we have a type anywhere in the list of results.
for (LookupResult::iterator Res = Result.begin(), ResEnd = Result.end();
Res != ResEnd; ++Res) {
- if (isa<TypeDecl>(*Res) || isa<ObjCInterfaceDecl>(*Res)) {
+ if (isa<TypeDecl>(*Res) || isa<ObjCInterfaceDecl>(*Res) ||
+ (AllowDeducedTemplate && getAsTypeTemplateDecl(*Res))) {
if (!IIDecl ||
(*Res)->getLocation().getRawEncoding() <
IIDecl->getLocation().getRawEncoding())
@@ -425,33 +434,29 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
QualType T;
if (TypeDecl *TD = dyn_cast<TypeDecl>(IIDecl)) {
+ // C++ [class.qual]p2: A lookup that would find the injected-class-name
+ // instead names the constructors of the class, except when naming a class.
+ // This is ill-formed when we're not actually forming a ctor or dtor name.
+ auto *LookupRD = dyn_cast_or_null<CXXRecordDecl>(LookupCtx);
+ auto *FoundRD = dyn_cast<CXXRecordDecl>(TD);
+ if (!isClassName && !IsCtorOrDtorName && LookupRD && FoundRD &&
+ FoundRD->isInjectedClassName() &&
+ declaresSameEntity(LookupRD, cast<Decl>(FoundRD->getParent())))
+ Diag(NameLoc, diag::err_out_of_line_qualified_id_type_names_constructor)
+ << &II << /*Type*/1;
+
DiagnoseUseOfDecl(IIDecl, NameLoc);
T = Context.getTypeDeclType(TD);
MarkAnyDeclReferenced(TD->getLocation(), TD, /*OdrUse=*/false);
-
- // NOTE: avoid constructing an ElaboratedType(Loc) if this is a
- // constructor or destructor name (in such a case, the scope specifier
- // will be attached to the enclosing Expr or Decl node).
- if (SS && SS->isNotEmpty() && !IsCtorOrDtorName) {
- if (WantNontrivialTypeSourceInfo) {
- // Construct a type with type-source information.
- TypeLocBuilder Builder;
- Builder.pushTypeSpec(T).setNameLoc(NameLoc);
-
- T = getElaboratedType(ETK_None, *SS, T);
- ElaboratedTypeLoc ElabTL = Builder.push<ElaboratedTypeLoc>(T);
- ElabTL.setElaboratedKeywordLoc(SourceLocation());
- ElabTL.setQualifierLoc(SS->getWithLocInContext(Context));
- return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
- } else {
- T = getElaboratedType(ETK_None, *SS, T);
- }
- }
} else if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(IIDecl)) {
(void)DiagnoseUseOfDecl(IDecl, NameLoc);
if (!HasTrailingDot)
T = Context.getObjCInterfaceType(IDecl);
+ } else if (AllowDeducedTemplate) {
+ if (auto *TD = getAsTypeTemplateDecl(IIDecl))
+ T = Context.getDeducedTemplateSpecializationType(TemplateName(TD),
+ QualType(), false);
}
if (T.isNull()) {
@@ -459,6 +464,27 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
Result.suppressDiagnostics();
return nullptr;
}
+
+ // NOTE: avoid constructing an ElaboratedType(Loc) if this is a
+ // constructor or destructor name (in such a case, the scope specifier
+ // will be attached to the enclosing Expr or Decl node).
+ if (SS && SS->isNotEmpty() && !IsCtorOrDtorName &&
+ !isa<ObjCInterfaceDecl>(IIDecl)) {
+ if (WantNontrivialTypeSourceInfo) {
+ // Construct a type with type-source information.
+ TypeLocBuilder Builder;
+ Builder.pushTypeSpec(T).setNameLoc(NameLoc);
+
+ T = getElaboratedType(ETK_None, *SS, T);
+ ElaboratedTypeLoc ElabTL = Builder.push<ElaboratedTypeLoc>(T);
+ ElabTL.setElaboratedKeywordLoc(SourceLocation());
+ ElabTL.setQualifierLoc(SS->getWithLocInContext(Context));
+ return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
+ } else {
+ T = getElaboratedType(ETK_None, *SS, T);
+ }
+ }
+
return ParsedType::make(T);
}
@@ -636,6 +662,7 @@ void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
if (Corrected.getCorrectionSpecifier())
tmpSS.MakeTrivial(Context, Corrected.getCorrectionSpecifier(),
SourceRange(IILoc));
+ // FIXME: Support class template argument deduction here.
SuggestedType =
getTypeName(*Corrected.getCorrectionAsIdentifierInfo(), IILoc, S,
tmpSS.isSet() ? &tmpSS : SS, false, false, nullptr,
@@ -656,7 +683,8 @@ void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
Name, nullptr, true, TemplateResult,
MemberOfUnknownSpecialization) == TNK_Type_template) {
TemplateName TplName = TemplateResult.get();
- Diag(IILoc, diag::err_template_missing_args) << TplName;
+ Diag(IILoc, diag::err_template_missing_args)
+ << (int)getTemplateNameKindForDiagnostics(TplName) << TplName;
if (TemplateDecl *TplDecl = TplName.getAsTemplateDecl()) {
Diag(TplDecl->getLocation(), diag::note_template_decl_here)
<< TplDecl->getTemplateParameters()->getSourceRange();
@@ -782,6 +810,13 @@ Sema::ClassifyName(Scope *S, CXXScopeSpec &SS, IdentifierInfo *&Name,
if (NextToken.is(tok::coloncolon)) {
NestedNameSpecInfo IdInfo(Name, NameLoc, NextToken.getLocation());
BuildCXXNestedNameSpecifier(S, IdInfo, false, SS, nullptr, false);
+ } else if (getLangOpts().CPlusPlus && SS.isSet() &&
+ isCurrentClassName(*Name, S, &SS)) {
+ // Per [class.qual]p2, this names the constructors of SS, not the
+ // injected-class-name. We don't have a classification for that.
+ // There's not much point caching this result, since the parser
+ // will reject it later.
+ return NameClassification::Unknown();
}
LookupResult Result(*this, Name, NameLoc, LookupOrdinaryName);
@@ -1072,6 +1107,24 @@ Corrected:
return BuildDeclarationNameExpr(SS, Result, ADL);
}
+Sema::TemplateNameKindForDiagnostics
+Sema::getTemplateNameKindForDiagnostics(TemplateName Name) {
+ auto *TD = Name.getAsTemplateDecl();
+ if (!TD)
+ return TemplateNameKindForDiagnostics::DependentTemplate;
+ if (isa<ClassTemplateDecl>(TD))
+ return TemplateNameKindForDiagnostics::ClassTemplate;
+ if (isa<FunctionTemplateDecl>(TD))
+ return TemplateNameKindForDiagnostics::FunctionTemplate;
+ if (isa<VarTemplateDecl>(TD))
+ return TemplateNameKindForDiagnostics::VarTemplate;
+ if (isa<TypeAliasTemplateDecl>(TD))
+ return TemplateNameKindForDiagnostics::AliasTemplate;
+ if (isa<TemplateTemplateParmDecl>(TD))
+ return TemplateNameKindForDiagnostics::TemplateTemplateParam;
+ return TemplateNameKindForDiagnostics::DependentTemplate;
+}
+
// Determines the context to return to after temporarily entering a
// context. This depends in an unnecessarily complicated way on the
// exact ordering of callbacks from the parser.
@@ -2101,7 +2154,9 @@ void Sema::MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
// -Wtypedef-redefinition. If either the original or the redefinition is
// in a system header, don't emit this for compatibility with GCC.
if (getDiagnostics().getSuppressSystemWarnings() &&
- (Context.getSourceManager().isInSystemHeader(Old->getLocation()) ||
+ // Some standard types are defined implicitly in Clang (e.g. OpenCL).
+ (Old->isImplicit() ||
+ Context.getSourceManager().isInSystemHeader(Old->getLocation()) ||
Context.getSourceManager().isInSystemHeader(New->getLocation())))
return;
@@ -3035,7 +3090,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD,
// [...] A member shall not be declared twice in the
// member-specification, except that a nested class or member
// class template can be declared and then later defined.
- if (ActiveTemplateInstantiations.empty()) {
+ if (!inTemplateInstantiation()) {
unsigned NewDiag;
if (isa<CXXConstructorDecl>(OldMethod))
NewDiag = diag::err_constructor_redeclared;
@@ -4622,6 +4677,34 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {
NameInfo.setLoc(Name.StartLocation);
return NameInfo;
+ case UnqualifiedId::IK_DeductionGuideName: {
+ // C++ [temp.deduct.guide]p3:
+ // The simple-template-id shall name a class template specialization.
+ // The template-name shall be the same identifier as the template-name
+ // of the simple-template-id.
+ // These together intend to imply that the template-name shall name a
+ // class template.
+ // FIXME: template<typename T> struct X {};
+ // template<typename T> using Y = X<T>;
+ // Y(int) -> Y<int>;
+ // satisfies these rules but does not name a class template.
+ TemplateName TN = Name.TemplateName.get().get();
+ auto *Template = TN.getAsTemplateDecl();
+ if (!Template || !isa<ClassTemplateDecl>(Template)) {
+ Diag(Name.StartLocation,
+ diag::err_deduction_guide_name_not_class_template)
+ << (int)getTemplateNameKindForDiagnostics(TN) << TN;
+ if (Template)
+ Diag(Template->getLocation(), diag::note_template_decl_here);
+ return DeclarationNameInfo();
+ }
+
+ NameInfo.setName(
+ Context.DeclarationNames.getCXXDeductionGuideName(Template));
+ NameInfo.setLoc(Name.StartLocation);
+ return NameInfo;
+ }
+
case UnqualifiedId::IK_OperatorFunctionId:
NameInfo.setName(Context.DeclarationNames.getCXXOperatorName(
Name.OperatorFunctionId.Operator));
@@ -5382,8 +5465,13 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
diag::err_concept_wrong_decl_kind);
if (D.getName().Kind != UnqualifiedId::IK_Identifier) {
- Diag(D.getName().StartLocation, diag::err_typedef_not_identifier)
- << D.getName().getSourceRange();
+ if (D.getName().Kind == UnqualifiedId::IK_DeductionGuideName)
+ Diag(D.getName().StartLocation,
+ diag::err_deduction_guide_invalid_specifier)
+ << "typedef";
+ else
+ Diag(D.getName().StartLocation, diag::err_typedef_not_identifier)
+ << D.getName().getSourceRange();
return nullptr;
}
@@ -5444,6 +5532,10 @@ Sema::CheckTypedefForVariablyModifiedType(Scope *S, TypedefNameDecl *NewTD) {
NamedDecl*
Sema::ActOnTypedefNameDecl(Scope *S, DeclContext *DC, TypedefNameDecl *NewTD,
LookupResult &Previous, bool &Redeclaration) {
+
+ // Find the shadowed declaration before filtering for scope.
+ NamedDecl *ShadowedDecl = getShadowedDeclaration(NewTD, Previous);
+
// Merge the decl with the existing one if appropriate. If the decl is
// in an outer scope, it isn't the same thing.
FilterLookupForScope(Previous, DC, S, /*ConsiderLinkage*/false,
@@ -5454,6 +5546,9 @@ Sema::ActOnTypedefNameDecl(Scope *S, DeclContext *DC, TypedefNameDecl *NewTD,
MergeTypedefNameDecl(S, NewTD, Previous);
}
+ if (ShadowedDecl && !Redeclaration)
+ CheckShadow(NewTD, ShadowedDecl, Previous);
+
// If this is the C FILE type, notify the AST context.
if (IdentifierInfo *II = NewTD->getIdentifier())
if (!NewTD->isInvalidDecl() &&
@@ -5649,13 +5744,17 @@ static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl,
if (OldDecl->isInvalidDecl())
return;
+ bool IsTemplate = false;
if (TemplateDecl *OldTD = dyn_cast<TemplateDecl>(OldDecl)) {
OldDecl = OldTD->getTemplatedDecl();
+ IsTemplate = true;
if (!IsSpecialization)
IsDefinition = false;
}
- if (TemplateDecl *NewTD = dyn_cast<TemplateDecl>(NewDecl))
+ if (TemplateDecl *NewTD = dyn_cast<TemplateDecl>(NewDecl)) {
NewDecl = NewTD->getTemplatedDecl();
+ IsTemplate = true;
+ }
if (!OldDecl || !NewDecl)
return;
@@ -5708,9 +5807,10 @@ static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl,
}
// A redeclaration is not allowed to drop a dllimport attribute, the only
- // exceptions being inline function definitions, local extern declarations,
- // qualified friend declarations or special MSVC extension: in the last case,
- // the declaration is treated as if it were marked dllexport.
+ // exceptions being inline function definitions (except for function
+ // templates), local extern declarations, qualified friend declarations or
+ // special MSVC extension: in the last case, the declaration is treated as if
+ // it were marked dllexport.
bool IsInline = false, IsStaticDataMember = false, IsQualifiedFriend = false;
bool IsMicrosoft = S.Context.getTargetInfo().getCXXABI().isMicrosoft();
if (const auto *VD = dyn_cast<VarDecl>(NewDecl)) {
@@ -5725,7 +5825,8 @@ static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl,
FD->getFriendObjectKind() == Decl::FOK_Declared;
}
- if (OldImportAttr && !HasNewAttr && !IsInline && !IsStaticDataMember &&
+ if (OldImportAttr && !HasNewAttr &&
+ (!IsInline || (IsMicrosoft && IsTemplate)) && !IsStaticDataMember &&
!NewDecl->isLocalExternDecl() && !IsQualifiedFriend) {
if (IsMicrosoft && IsDefinition) {
S.Diag(NewDecl->getLocation(),
@@ -5902,8 +6003,7 @@ NamedDecl *Sema::ActOnVariableDeclarator(
Name = II;
}
} else if (!II) {
- Diag(D.getIdentifierLoc(), diag::err_bad_variable_name)
- << Name;
+ Diag(D.getIdentifierLoc(), diag::err_bad_variable_name) << Name;
return nullptr;
}
@@ -6017,7 +6117,7 @@ NamedDecl *Sema::ActOnVariableDeclarator(
}
}
- bool IsExplicitSpecialization = false;
+ bool IsMemberSpecialization = false;
bool IsVariableTemplateSpecialization = false;
bool IsPartialSpecialization = false;
bool IsVariableTemplate = false;
@@ -6029,7 +6129,7 @@ NamedDecl *Sema::ActOnVariableDeclarator(
D.getIdentifierLoc(), II,
R, TInfo, SC);
- if (D.getDeclSpec().containsPlaceholderType() && R->getContainedAutoType())
+ if (R->getContainedDeducedType())
ParsingInitForAutoVars.insert(NewVD);
if (D.isInvalidType())
@@ -6095,7 +6195,7 @@ NamedDecl *Sema::ActOnVariableDeclarator(
? D.getName().TemplateId
: nullptr,
TemplateParamLists,
- /*never a friend*/ false, IsExplicitSpecialization, Invalid);
+ /*never a friend*/ false, IsMemberSpecialization, Invalid);
if (TemplateParams) {
if (!TemplateParams->size() &&
@@ -6165,7 +6265,7 @@ NamedDecl *Sema::ActOnVariableDeclarator(
// 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().containsPlaceholderType() && R->getContainedAutoType())
+ if (R->getContainedDeducedType())
ParsingInitForAutoVars.insert(NewVD);
if (D.isInvalidType() || Invalid) {
@@ -6321,7 +6421,7 @@ NamedDecl *Sema::ActOnVariableDeclarator(
<< (IsPartialSpecialization ? 1 : 0)
<< FixItHint::CreateRemoval(
D.getDeclSpec().getModulePrivateSpecLoc());
- else if (IsExplicitSpecialization)
+ else if (IsMemberSpecialization)
Diag(NewVD->getLocation(), diag::err_module_private_specialization)
<< 2
<< FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc());
@@ -6436,7 +6536,7 @@ NamedDecl *Sema::ActOnVariableDeclarator(
// declaration has linkage).
FilterLookupForScope(Previous, OriginalDC, S, shouldConsiderLinkage(NewVD),
D.getCXXScopeSpec().isNotEmpty() ||
- IsExplicitSpecialization ||
+ IsMemberSpecialization ||
IsVariableTemplateSpecialization);
// Check whether the previous declaration is in the same block scope. This
@@ -6451,7 +6551,7 @@ NamedDecl *Sema::ActOnVariableDeclarator(
D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous));
} else {
// If this is an explicit specialization of a static data member, check it.
- if (IsExplicitSpecialization && !NewVD->isInvalidDecl() &&
+ if (IsMemberSpecialization && !NewVD->isInvalidDecl() &&
CheckMemberSpecialization(NewVD, Previous))
NewVD->setInvalidDecl();
@@ -6566,7 +6666,7 @@ NamedDecl *Sema::ActOnVariableDeclarator(
if (D.isRedeclaration() && !Previous.empty()) {
checkDLLAttributeRedeclaration(
*this, dyn_cast<NamedDecl>(Previous.getRepresentativeDecl()), NewVD,
- IsExplicitSpecialization, D.isFunctionDefinition());
+ IsMemberSpecialization, D.isFunctionDefinition());
}
if (NewTemplate) {
@@ -6580,13 +6680,25 @@ NamedDecl *Sema::ActOnVariableDeclarator(
}
/// Enum describing the %select options in diag::warn_decl_shadow.
-enum ShadowedDeclKind { SDK_Local, SDK_Global, SDK_StaticMember, SDK_Field };
+enum ShadowedDeclKind {
+ SDK_Local,
+ SDK_Global,
+ SDK_StaticMember,
+ SDK_Field,
+ SDK_Typedef,
+ SDK_Using
+};
/// Determine what kind of declaration we're shadowing.
static ShadowedDeclKind computeShadowedDeclKind(const NamedDecl *ShadowedDecl,
const DeclContext *OldDC) {
- if (isa<RecordDecl>(OldDC))
+ if (isa<TypeAliasDecl>(ShadowedDecl))
+ return SDK_Using;
+ else if (isa<TypedefDecl>(ShadowedDecl))
+ return SDK_Typedef;
+ else if (isa<RecordDecl>(OldDC))
return isa<FieldDecl>(ShadowedDecl) ? SDK_Field : SDK_StaticMember;
+
return OldDC->isFileContext() ? SDK_Global : SDK_Local;
}
@@ -6601,28 +6713,48 @@ static SourceLocation getCaptureLocation(const LambdaScopeInfo *LSI,
return SourceLocation();
}
+static bool shouldWarnIfShadowedDecl(const DiagnosticsEngine &Diags,
+ const LookupResult &R) {
+ // Only diagnose if we're shadowing an unambiguous field or variable.
+ if (R.getResultKind() != LookupResult::Found)
+ return false;
+
+ // Return false if warning is ignored.
+ return !Diags.isIgnored(diag::warn_decl_shadow, R.getNameLoc());
+}
+
/// \brief Return the declaration shadowed by the given variable \p D, or null
/// if it doesn't shadow any declaration or shadowing warnings are disabled.
NamedDecl *Sema::getShadowedDeclaration(const VarDecl *D,
const LookupResult &R) {
- // Return if warning is ignored.
- if (Diags.isIgnored(diag::warn_decl_shadow, R.getNameLoc()))
+ if (!shouldWarnIfShadowedDecl(Diags, R))
return nullptr;
// Don't diagnose declarations at file scope.
if (D->hasGlobalStorage())
return nullptr;
- // Only diagnose if we're shadowing an unambiguous field or variable.
- if (R.getResultKind() != LookupResult::Found)
- return nullptr;
-
NamedDecl *ShadowedDecl = R.getFoundDecl();
return isa<VarDecl>(ShadowedDecl) || isa<FieldDecl>(ShadowedDecl)
? ShadowedDecl
: nullptr;
}
+/// \brief Return the declaration shadowed by the given typedef \p D, or null
+/// if it doesn't shadow any declaration or shadowing warnings are disabled.
+NamedDecl *Sema::getShadowedDeclaration(const TypedefNameDecl *D,
+ const LookupResult &R) {
+ // Don't warn if typedef declaration is part of a class
+ if (D->getDeclContext()->isRecord())
+ return nullptr;
+
+ if (!shouldWarnIfShadowedDecl(Diags, R))
+ return nullptr;
+
+ NamedDecl *ShadowedDecl = R.getFoundDecl();
+ return isa<TypedefNameDecl>(ShadowedDecl) ? ShadowedDecl : nullptr;
+}
+
/// \brief Diagnose variable or built-in function shadowing. Implements
/// -Wshadow.
///
@@ -6632,7 +6764,7 @@ NamedDecl *Sema::getShadowedDeclaration(const VarDecl *D,
/// \param ShadowedDecl the declaration that is shadowed by the given variable
/// \param R the lookup of the name
///
-void Sema::CheckShadow(VarDecl *D, NamedDecl *ShadowedDecl,
+void Sema::CheckShadow(NamedDecl *D, NamedDecl *ShadowedDecl,
const LookupResult &R) {
DeclContext *NewDC = D->getDeclContext();
@@ -6644,13 +6776,13 @@ void Sema::CheckShadow(VarDecl *D, NamedDecl *ShadowedDecl,
// Fields shadowed by constructor parameters are a special case. Usually
// the constructor initializes the field with the parameter.
- if (isa<CXXConstructorDecl>(NewDC) && isa<ParmVarDecl>(D)) {
- // Remember that this was shadowed so we can either warn about its
- // modification or its existence depending on warning settings.
- D = D->getCanonicalDecl();
- ShadowingDecls.insert({D, FD});
- return;
- }
+ if (isa<CXXConstructorDecl>(NewDC))
+ if (const auto PVD = dyn_cast<ParmVarDecl>(D)) {
+ // Remember that this was shadowed so we can either warn about its
+ // modification or its existence depending on warning settings.
+ ShadowingDecls.insert({PVD->getCanonicalDecl(), FD});
+ return;
+ }
}
if (VarDecl *shadowedVar = dyn_cast<VarDecl>(ShadowedDecl))
@@ -6668,7 +6800,8 @@ void Sema::CheckShadow(VarDecl *D, NamedDecl *ShadowedDecl,
unsigned WarningDiag = diag::warn_decl_shadow;
SourceLocation CaptureLoc;
- if (isa<VarDecl>(ShadowedDecl) && NewDC && isa<CXXMethodDecl>(NewDC)) {
+ if (isa<VarDecl>(D) && isa<VarDecl>(ShadowedDecl) && NewDC &&
+ isa<CXXMethodDecl>(NewDC)) {
if (const auto *RD = dyn_cast<CXXRecordDecl>(NewDC->getParent())) {
if (RD->isLambda() && OldDC->Encloses(NewDC->getLexicalParent())) {
if (RD->getLambdaCaptureDefault() == LCD_None) {
@@ -6682,7 +6815,8 @@ void Sema::CheckShadow(VarDecl *D, NamedDecl *ShadowedDecl,
// Remember that this was shadowed so we can avoid the warning if the
// shadowed decl isn't captured and the warning settings allow it.
cast<LambdaScopeInfo>(getCurFunction())
- ->ShadowingDecls.push_back({D, cast<VarDecl>(ShadowedDecl)});
+ ->ShadowingDecls.push_back(
+ {cast<VarDecl>(D), cast<VarDecl>(ShadowedDecl)});
return;
}
}
@@ -7430,6 +7564,7 @@ static StorageClass getFunctionStorageClass(Sema &SemaRef, Declarator &D) {
case DeclSpec::SCS_mutable:
SemaRef.Diag(D.getDeclSpec().getStorageClassSpecLoc(),
diag::err_typecheck_sclass_func);
+ D.getMutableDeclSpec().ClearStorageClassSpecs();
D.setInvalidType();
break;
case DeclSpec::SCS_unspecified: break;
@@ -7472,11 +7607,12 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
// Determine whether the function was written with a
// prototype. This true when:
// - there is a prototype in the declarator, or
- // - the type R of the function is some kind of typedef or other reference
- // to a type name (which eventually refers to a function type).
+ // - the type R of the function is some kind of typedef or other non-
+ // attributed reference to a type name (which eventually refers to a
+ // function type).
bool HasPrototype =
(D.isFunctionDeclarator() && D.getFunctionTypeInfo().hasPrototype) ||
- (!isa<FunctionType>(R.getTypePtr()) && R->isFunctionProtoType());
+ (!R->getAsAdjusted<FunctionType>() && R->isFunctionProtoType());
NewFD = FunctionDecl::Create(SemaRef.Context, DC,
D.getLocStart(), NameInfo, R,
@@ -7562,6 +7698,12 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
R, TInfo, isInline, isExplicit,
isConstexpr, SourceLocation());
+ } else if (Name.getNameKind() == DeclarationName::CXXDeductionGuideName) {
+ SemaRef.CheckDeductionGuideDeclarator(D, R, SC);
+
+ return CXXDeductionGuideDecl::Create(SemaRef.Context, DC, D.getLocStart(),
+ isExplicit, NameInfo, R, TInfo,
+ D.getLocEnd());
} else if (DC->isRecord()) {
// If the name of the function is the same as the name of the record,
// then this must be an invalid constructor that has a return type.
@@ -7835,7 +7977,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
bool isFriend = false;
FunctionTemplateDecl *FunctionTemplate = nullptr;
- bool isExplicitSpecialization = false;
+ bool isMemberSpecialization = false;
bool isFunctionTemplateSpecialization = false;
bool isDependentClassScopeExplicitSpecialization = false;
@@ -7891,7 +8033,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
}
SetNestedNameSpecifier(NewFD, D);
- isExplicitSpecialization = false;
+ isMemberSpecialization = false;
isFunctionTemplateSpecialization = false;
if (D.isInvalidType())
NewFD->setInvalidDecl();
@@ -7906,7 +8048,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
D.getName().getKind() == UnqualifiedId::IK_TemplateId
? D.getName().TemplateId
: nullptr,
- TemplateParamLists, isFriend, isExplicitSpecialization,
+ TemplateParamLists, isFriend, isMemberSpecialization,
Invalid)) {
if (TemplateParams->size() > 0) {
// This is a function template
@@ -8050,7 +8192,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// The explicit specifier shall be used only in the declaration of a
// constructor or conversion function within its class definition;
// see 12.3.1 and 12.3.2.
- if (isExplicit && !NewFD->isInvalidDecl()) {
+ if (isExplicit && !NewFD->isInvalidDecl() &&
+ !isa<CXXDeductionGuideDecl>(NewFD)) {
if (!CurContext->isRecord()) {
// 'explicit' was specified outside of the class.
Diag(D.getDeclSpec().getExplicitSpecLoc(),
@@ -8239,7 +8382,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// Filter out previous declarations that don't match the scope.
FilterLookupForScope(Previous, OriginalDC, S, shouldConsiderLinkage(NewFD),
D.getCXXScopeSpec().isNotEmpty() ||
- isExplicitSpecialization ||
+ isMemberSpecialization ||
isFunctionTemplateSpecialization);
// Handle GNU asm-label extension (encoded as an attribute).
@@ -8389,7 +8532,6 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
if (!getLangOpts().CPlusPlus) {
// Perform semantic checking on the function declaration.
- bool isExplicitSpecialization=false;
if (!NewFD->isInvalidDecl() && NewFD->isMain())
CheckMain(NewFD, D.getDeclSpec());
@@ -8398,7 +8540,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
if (!NewFD->isInvalidDecl())
D.setRedeclaration(CheckFunctionDeclaration(S, NewFD, Previous,
- isExplicitSpecialization));
+ isMemberSpecialization));
else if (!Previous.empty())
// Recover gracefully from an invalid redeclaration.
D.setRedeclaration(true);
@@ -8533,7 +8675,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
<< FixItHint::CreateRemoval(
D.getDeclSpec().getStorageClassSpecLoc());
}
- } else if (isExplicitSpecialization && isa<CXXMethodDecl>(NewFD)) {
+ } else if (isMemberSpecialization && isa<CXXMethodDecl>(NewFD)) {
if (CheckMemberSpecialization(NewFD, Previous))
NewFD->setInvalidDecl();
}
@@ -8548,7 +8690,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
if (!NewFD->isInvalidDecl())
D.setRedeclaration(CheckFunctionDeclaration(S, NewFD, Previous,
- isExplicitSpecialization));
+ isMemberSpecialization));
else if (!Previous.empty())
// Recover gracefully from an invalid redeclaration.
D.setRedeclaration(true);
@@ -8654,7 +8796,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
} else if (!D.isFunctionDefinition() &&
isa<CXXMethodDecl>(NewFD) && NewFD->isOutOfLine() &&
!isFriend && !isFunctionTemplateSpecialization &&
- !isExplicitSpecialization) {
+ !isMemberSpecialization) {
// An out-of-line member function declaration must also be a
// definition (C++ [class.mfct]p2).
// Note that this is not the case for explicit specializations of
@@ -8715,7 +8857,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
if (D.isRedeclaration() && !Previous.empty()) {
checkDLLAttributeRedeclaration(
*this, dyn_cast<NamedDecl>(Previous.getRepresentativeDecl()), NewFD,
- isExplicitSpecialization || isFunctionTemplateSpecialization,
+ isMemberSpecialization || isFunctionTemplateSpecialization,
D.isFunctionDefinition());
}
@@ -8840,15 +8982,16 @@ bool Sema::shouldLinkDependentDeclWithPrevious(Decl *D, Decl *PrevDecl) {
/// that have been instantiated via C++ template instantiation (called
/// via InstantiateDecl).
///
-/// \param IsExplicitSpecialization whether this new function declaration is
-/// an explicit specialization of the previous declaration.
+/// \param IsMemberSpecialization whether this new function declaration is
+/// a member specialization (that replaces any definition provided by the
+/// previous declaration).
///
/// This sets NewFD->isInvalidDecl() to true if there was an error.
///
/// \returns true if the function declaration is a redeclaration.
bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
LookupResult &Previous,
- bool IsExplicitSpecialization) {
+ bool IsMemberSpecialization) {
assert(!NewFD->getReturnType()->isVariablyModifiedType() &&
"Variably modified return types are not handled here");
@@ -8895,14 +9038,10 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
// with that name must be marked "overloadable".
Diag(NewFD->getLocation(), diag::err_attribute_overloadable_missing)
<< Redeclaration << NewFD;
- NamedDecl *OverloadedDecl = nullptr;
- if (Redeclaration)
- OverloadedDecl = OldDecl;
- else if (!Previous.empty())
- OverloadedDecl = Previous.getRepresentativeDecl();
- if (OverloadedDecl)
- Diag(OverloadedDecl->getLocation(),
- diag::note_attribute_overloadable_prev_overload);
+ NamedDecl *OverloadedDecl =
+ Redeclaration ? OldDecl : Previous.getRepresentativeDecl();
+ Diag(OverloadedDecl->getLocation(),
+ diag::note_attribute_overloadable_prev_overload);
NewFD->addAttr(OverloadableAttr::CreateImplicit(Context));
}
}
@@ -8961,7 +9100,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
// Warn that we did this, if we're not performing template instantiation.
// In that case, we'll have warned already when the template was defined.
- if (ActiveTemplateInstantiations.empty()) {
+ if (!inTemplateInstantiation()) {
SourceLocation AddConstLoc;
if (FunctionTypeLoc FTL = MD->getTypeSourceInfo()->getTypeLoc()
.IgnoreParens().getAs<FunctionTypeLoc>())
@@ -8998,7 +9137,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
// If this is an explicit specialization of a member that is a function
// template, mark it as a member specialization.
- if (IsExplicitSpecialization &&
+ if (IsMemberSpecialization &&
NewTemplateDecl->getInstantiatedFromMemberTemplate()) {
NewTemplateDecl->setMemberSpecialization();
assert(OldTemplateDecl->isMemberSpecialization());
@@ -9048,6 +9187,15 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
} else if (CXXConversionDecl *Conversion
= dyn_cast<CXXConversionDecl>(NewFD)) {
ActOnConversionDeclarator(Conversion);
+ } else if (auto *Guide = dyn_cast<CXXDeductionGuideDecl>(NewFD)) {
+ if (auto *TD = Guide->getDescribedFunctionTemplate())
+ CheckDeductionGuideTemplate(TD);
+
+ // A deduction guide is not on the list of entities that can be
+ // explicitly specialized.
+ if (Guide->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
+ Diag(Guide->getLocStart(), diag::err_deduction_guide_specialized)
+ << /*explicit specialization*/ 1;
}
// Find any virtual functions that this function overrides.
@@ -9395,7 +9543,7 @@ namespace {
InitFieldIndex.pop_back();
}
- // Returns true if MemberExpr is checked and no futher checking is needed.
+ // Returns true if MemberExpr is checked and no further checking is needed.
// Returns false if additional checking is required.
bool CheckInitListMemberExpr(MemberExpr *E, bool CheckReference) {
llvm::SmallVector<FieldDecl*, 4> Fields;
@@ -9703,11 +9851,36 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
VarDeclOrName VN{VDecl, Name};
- ArrayRef<Expr *> DeduceInits = Init;
+ DeducedType *Deduced = Type->getContainedDeducedType();
+ assert(Deduced && "deduceVarTypeFromInitializer for non-deduced type");
+
+ // C++11 [dcl.spec.auto]p3
+ if (!Init) {
+ assert(VDecl && "no init for init capture deduction?");
+ Diag(VDecl->getLocation(), diag::err_auto_var_requires_init)
+ << VDecl->getDeclName() << Type;
+ return QualType();
+ }
+
+ ArrayRef<Expr*> DeduceInits = Init;
if (DirectInit) {
- if (auto *PL = dyn_cast<ParenListExpr>(Init))
+ if (auto *PL = dyn_cast_or_null<ParenListExpr>(Init))
DeduceInits = PL->exprs();
- else if (auto *IL = dyn_cast<InitListExpr>(Init))
+ }
+
+ if (isa<DeducedTemplateSpecializationType>(Deduced)) {
+ assert(VDecl && "non-auto type for init capture deduction?");
+ InitializedEntity Entity = InitializedEntity::InitializeVariable(VDecl);
+ InitializationKind Kind = InitializationKind::CreateForInit(
+ VDecl->getLocation(), DirectInit, Init);
+ // FIXME: Initialization should not be taking a mutable list of inits.
+ SmallVector<Expr*, 8> InitsCopy(DeduceInits.begin(), DeduceInits.end());
+ return DeduceTemplateSpecializationFromInitializer(TSI, Entity, Kind,
+ InitsCopy);
+ }
+
+ if (DirectInit) {
+ if (auto *IL = dyn_cast<InitListExpr>(Init))
DeduceInits = IL->inits();
}
@@ -9784,8 +9957,8 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
// checks.
// We only want to warn outside of template instantiations, though:
// inside a template, the 'id' could have come from a parameter.
- if (ActiveTemplateInstantiations.empty() && !DefaultedAnyToId &&
- !IsInitCapture && !DeducedType.isNull() && DeducedType->isObjCIdType()) {
+ if (!inTemplateInstantiation() && !DefaultedAnyToId && !IsInitCapture &&
+ !DeducedType.isNull() && DeducedType->isObjCIdType()) {
SourceLocation Loc = TSI->getTypeLoc().getBeginLoc();
Diag(Loc, diag::warn_auto_var_is_id) << VN << Range;
}
@@ -9793,6 +9966,36 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,
return DeducedType;
}
+bool Sema::DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit,
+ Expr *Init) {
+ QualType DeducedType = deduceVarTypeFromInitializer(
+ VDecl, VDecl->getDeclName(), VDecl->getType(), VDecl->getTypeSourceInfo(),
+ VDecl->getSourceRange(), DirectInit, Init);
+ if (DeducedType.isNull()) {
+ VDecl->setInvalidDecl();
+ return true;
+ }
+
+ VDecl->setType(DeducedType);
+ assert(VDecl->isLinkageValid());
+
+ // In ARC, infer lifetime.
+ if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(VDecl))
+ VDecl->setInvalidDecl();
+
+ // If this is a redeclaration, check that the type we just deduced matches
+ // the previously declared type.
+ if (VarDecl *Old = VDecl->getPreviousDecl()) {
+ // We never need to merge the type, because we cannot form an incomplete
+ // array of auto, nor deduce such a type.
+ MergeVarDeclTypes(VDecl, Old, /*MergeTypeWithPrevious*/ false);
+ }
+
+ // Check the deduced type is valid for a variable declaration.
+ CheckVariableDeclarationType(VDecl);
+ return VDecl->isInvalidDecl();
+}
+
/// AddInitializerToDecl - Adds the initializer Init to the
/// declaration dcl. If DirectInit is true, this is C++ direct
/// initialization rather than copy initialization.
@@ -9832,32 +10035,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
}
Init = Res.get();
- QualType DeducedType = deduceVarTypeFromInitializer(
- VDecl, VDecl->getDeclName(), VDecl->getType(),
- VDecl->getTypeSourceInfo(), VDecl->getSourceRange(), DirectInit, Init);
- if (DeducedType.isNull()) {
- RealDecl->setInvalidDecl();
- return;
- }
-
- VDecl->setType(DeducedType);
- assert(VDecl->isLinkageValid());
-
- // In ARC, infer lifetime.
- if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(VDecl))
- VDecl->setInvalidDecl();
-
- // If this is a redeclaration, check that the type we just deduced matches
- // the previously declared type.
- if (VarDecl *Old = VDecl->getPreviousDecl()) {
- // We never need to merge the type, because we cannot form an incomplete
- // array of auto, nor deduce such a type.
- MergeVarDeclTypes(VDecl, Old, /*MergeTypeWithPrevious*/ false);
- }
-
- // Check the deduced type is valid for a variable declaration.
- CheckVariableDeclarationType(VDecl);
- if (VDecl->isInvalidDecl())
+ if (DeduceVariableDeclarationType(VDecl, DirectInit, Init))
return;
}
@@ -9963,28 +10141,9 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
// Perform the initialization.
ParenListExpr *CXXDirectInit = dyn_cast<ParenListExpr>(Init);
if (!VDecl->isInvalidDecl()) {
- // Handle errors like: int a({0})
- if (CXXDirectInit && CXXDirectInit->getNumExprs() == 1 &&
- !canInitializeWithParenthesizedList(VDecl->getType()))
- if (auto IList = dyn_cast<InitListExpr>(CXXDirectInit->getExpr(0))) {
- Diag(VDecl->getLocation(), diag::err_list_init_in_parens)
- << VDecl->getType() << CXXDirectInit->getSourceRange()
- << FixItHint::CreateRemoval(CXXDirectInit->getLocStart())
- << FixItHint::CreateRemoval(CXXDirectInit->getLocEnd());
- Init = IList;
- CXXDirectInit = nullptr;
- }
-
InitializedEntity Entity = InitializedEntity::InitializeVariable(VDecl);
- InitializationKind Kind =
- DirectInit
- ? CXXDirectInit
- ? InitializationKind::CreateDirect(VDecl->getLocation(),
- Init->getLocStart(),
- Init->getLocEnd())
- : InitializationKind::CreateDirectList(VDecl->getLocation())
- : InitializationKind::CreateCopy(VDecl->getLocation(),
- Init->getLocStart());
+ InitializationKind Kind = InitializationKind::CreateForInit(
+ VDecl->getLocation(), DirectInit, Init);
MultiExprArg Args = Init;
if (CXXDirectInit)
@@ -10047,7 +10206,8 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
// we do not warn to warn spuriously when 'x' and 'y' are on separate
// paths through the function. This should be revisited if
// -Wrepeated-use-of-weak is made flow-sensitive.
- if (VDecl->getType().getObjCLifetime() == Qualifiers::OCL_Strong &&
+ if ((VDecl->getType().getObjCLifetime() == Qualifiers::OCL_Strong ||
+ VDecl->getType().isNonWeakInMRRWithObjCWeak(Context)) &&
!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
Init->getLocStart()))
getCurFunction()->markSafeWeakUse(Init);
@@ -10111,7 +10271,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
// C++11 [class.static.data]p3:
// If a non-volatile non-inline const static data member is of integral
// or enumeration type, its declaration in the class definition can
- // specify a brace-or-equal-initializer in which every initalizer-clause
+ // specify a brace-or-equal-initializer in which every initializer-clause
// that is an assignment-expression is a constant expression. A static
// data member of literal type can be declared in the class definition
// with the constexpr specifier; if so, its declaration shall specify a
@@ -10281,18 +10441,6 @@ void Sema::ActOnInitializerError(Decl *D) {
// though.
}
-/// Checks if an object of the given type can be initialized with parenthesized
-/// init-list.
-///
-/// \param TargetType Type of object being initialized.
-///
-/// The function is used to detect wrong initializations, such as 'int({0})'.
-///
-bool Sema::canInitializeWithParenthesizedList(QualType TargetType) {
- return TargetType->isDependentType() || TargetType->isRecordType() ||
- TargetType->getContainedAutoType();
-}
-
void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
// If there is no declaration, there was an error parsing it. Just ignore it.
if (!RealDecl)
@@ -10308,13 +10456,9 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
return;
}
- // C++11 [dcl.spec.auto]p3
- if (Type->isUndeducedType()) {
- Diag(Var->getLocation(), diag::err_auto_var_requires_init)
- << Var->getDeclName() << Type;
- Var->setInvalidDecl();
+ if (Type->isUndeducedType() &&
+ DeduceVariableDeclarationType(Var, false, nullptr))
return;
- }
// C++11 [class.static.data]p3: A static data member can be declared with
// the constexpr specifier; if so, its declaration shall specify
@@ -10693,7 +10837,7 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
// Apply section attributes and pragmas to global variables.
bool GlobalStorage = var->hasGlobalStorage();
if (GlobalStorage && var->isThisDeclarationADefinition() &&
- ActiveTemplateInstantiations.empty()) {
+ !inTemplateInstantiation()) {
PragmaStack<StringLiteral *> *Stack = nullptr;
int SectionFlags = ASTContext::PSF_Implicit | ASTContext::PSF_Read;
if (var->getType().isConstQualified())
@@ -10745,7 +10889,8 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {
// Regardless, we don't want to ignore array nesting when
// constructing this copy.
if (type->isStructureOrClassType()) {
- EnterExpressionEvaluationContext scope(*this, PotentiallyEvaluated);
+ EnterExpressionEvaluationContext scope(
+ *this, ExpressionEvaluationContext::PotentiallyEvaluated);
SourceLocation poi = var->getLocation();
Expr *varRef =new (Context) DeclRefExpr(var, false, type, VK_LValue, poi);
ExprResult result
@@ -10865,7 +11010,8 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) {
if (unsigned MaxAlign = Context.getTargetInfo().getMaxTLSAlign()) {
// Protect the check so that it's not performed on dependent types and
// dependent alignments (we can't determine the alignment in that case).
- if (VD->getTLSKind() && !hasDependentAlignment(VD)) {
+ if (VD->getTLSKind() && !hasDependentAlignment(VD) &&
+ !VD->isInvalidDecl()) {
CharUnits MaxAlignChars = Context.toCharUnitsFromBits(MaxAlign);
if (Context.getDeclAlign(VD) > MaxAlignChars) {
Diag(VD->getLocation(), diag::err_tls_var_aligned_over_maximum)
@@ -11045,6 +11191,11 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) {
}
}
+static bool hasDeducedAuto(DeclaratorDecl *DD) {
+ auto *VD = dyn_cast<VarDecl>(DD);
+ return VD && !VD->getType()->hasAutoForTrailingReturnType();
+}
+
Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
ArrayRef<Decl *> Group) {
SmallVector<Decl*, 8> Decls;
@@ -11055,29 +11206,46 @@ Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS,
DeclaratorDecl *FirstDeclaratorInGroup = nullptr;
DecompositionDecl *FirstDecompDeclaratorInGroup = nullptr;
bool DiagnosedMultipleDecomps = false;
+ DeclaratorDecl *FirstNonDeducedAutoInGroup = nullptr;
+ bool DiagnosedNonDeducedAuto = false;
for (unsigned i = 0, e = Group.size(); i != e; ++i) {
if (Decl *D = Group[i]) {
- auto *DD = dyn_cast<DeclaratorDecl>(D);
- if (DD && !FirstDeclaratorInGroup)
- FirstDeclaratorInGroup = DD;
-
- auto *Decomp = dyn_cast<DecompositionDecl>(D);
- if (Decomp && !FirstDecompDeclaratorInGroup)
- FirstDecompDeclaratorInGroup = Decomp;
-
- // A decomposition declaration cannot be combined with any other
- // declaration in the same group.
- auto *OtherDD = FirstDeclaratorInGroup;
- if (OtherDD == FirstDecompDeclaratorInGroup)
- OtherDD = DD;
- if (OtherDD && FirstDecompDeclaratorInGroup &&
- OtherDD != FirstDecompDeclaratorInGroup &&
- !DiagnosedMultipleDecomps) {
- Diag(FirstDecompDeclaratorInGroup->getLocation(),
- diag::err_decomp_decl_not_alone)
- << OtherDD->getSourceRange();
- DiagnosedMultipleDecomps = true;
+ // For declarators, there are some additional syntactic-ish checks we need
+ // to perform.
+ if (auto *DD = dyn_cast<DeclaratorDecl>(D)) {
+ if (!FirstDeclaratorInGroup)
+ FirstDeclaratorInGroup = DD;
+ if (!FirstDecompDeclaratorInGroup)
+ FirstDecompDeclaratorInGroup = dyn_cast<DecompositionDecl>(D);
+ if (!FirstNonDeducedAutoInGroup && DS.hasAutoTypeSpec() &&
+ !hasDeducedAuto(DD))
+ FirstNonDeducedAutoInGroup = DD;
+
+ if (FirstDeclaratorInGroup != DD) {
+ // A decomposition declaration cannot be combined with any other
+ // declaration in the same group.
+ if (FirstDecompDeclaratorInGroup && !DiagnosedMultipleDecomps) {
+ Diag(FirstDecompDeclaratorInGroup->getLocation(),
+ diag::err_decomp_decl_not_alone)
+ << FirstDeclaratorInGroup->getSourceRange()
+ << DD->getSourceRange();
+ DiagnosedMultipleDecomps = true;
+ }
+
+ // A declarator that uses 'auto' in any way other than to declare a
+ // variable with a deduced type cannot be combined with any other
+ // declarator in the same group.
+ if (FirstNonDeducedAutoInGroup && !DiagnosedNonDeducedAuto) {
+ Diag(FirstNonDeducedAutoInGroup->getLocation(),
+ diag::err_auto_non_deduced_not_alone)
+ << FirstNonDeducedAutoInGroup->getType()
+ ->hasAutoForTrailingReturnType()
+ << FirstDeclaratorInGroup->getSourceRange()
+ << DD->getSourceRange();
+ DiagnosedNonDeducedAuto = true;
+ }
+ }
}
Decls.push_back(D);
@@ -11105,38 +11273,28 @@ Sema::BuildDeclaratorGroup(MutableArrayRef<Decl *> Group) {
// deduction, the program is ill-formed.
if (Group.size() > 1) {
QualType Deduced;
- CanQualType DeducedCanon;
VarDecl *DeducedDecl = nullptr;
for (unsigned i = 0, e = Group.size(); i != e; ++i) {
- if (VarDecl *D = dyn_cast<VarDecl>(Group[i])) {
- AutoType *AT = D->getType()->getContainedAutoType();
- // FIXME: DR1265: if we have a function pointer declaration, we can have
- // an 'auto' from a trailing return type. In that case, the return type
- // must match the various other uses of 'auto'.
- if (!AT)
- continue;
- // Don't reissue diagnostics when instantiating a template.
- if (D->isInvalidDecl())
- break;
- QualType U = AT->getDeducedType();
- if (!U.isNull()) {
- CanQualType UCanon = Context.getCanonicalType(U);
- if (Deduced.isNull()) {
- Deduced = U;
- DeducedCanon = UCanon;
- DeducedDecl = D;
- } else if (DeducedCanon != UCanon) {
- Diag(D->getTypeSourceInfo()->getTypeLoc().getBeginLoc(),
- diag::err_auto_different_deductions)
- << (unsigned)AT->getKeyword()
- << Deduced << DeducedDecl->getDeclName()
- << U << D->getDeclName()
- << DeducedDecl->getInit()->getSourceRange()
- << D->getInit()->getSourceRange();
- D->setInvalidDecl();
- break;
- }
- }
+ VarDecl *D = dyn_cast<VarDecl>(Group[i]);
+ if (!D || D->isInvalidDecl())
+ break;
+ DeducedType *DT = D->getType()->getContainedDeducedType();
+ if (!DT || DT->getDeducedType().isNull())
+ continue;
+ if (Deduced.isNull()) {
+ Deduced = DT->getDeducedType();
+ DeducedDecl = D;
+ } else if (!Context.hasSameType(DT->getDeducedType(), Deduced)) {
+ auto *AT = dyn_cast<AutoType>(DT);
+ Diag(D->getTypeSourceInfo()->getTypeLoc().getBeginLoc(),
+ diag::err_auto_different_deductions)
+ << (AT ? (unsigned)AT->getKeyword() : 3)
+ << Deduced << DeducedDecl->getDeclName()
+ << DT->getDeducedType() << D->getDeclName()
+ << DeducedDecl->getInit()->getSourceRange()
+ << D->getInit()->getSourceRange();
+ D->setInvalidDecl();
+ break;
}
}
}
@@ -11331,7 +11489,7 @@ ParmVarDecl *Sema::BuildParmVarDeclForTypedef(DeclContext *DC,
void Sema::DiagnoseUnusedParameters(ArrayRef<ParmVarDecl *> Parameters) {
// Don't diagnose unused-parameter errors in template instantiations; we
// will already have done so in the template itself.
- if (!ActiveTemplateInstantiations.empty())
+ if (inTemplateInstantiation())
return;
for (const ParmVarDecl *Parameter : Parameters) {
@@ -11549,8 +11707,6 @@ void
Sema::CheckForFunctionRedefinition(FunctionDecl *FD,
const FunctionDecl *EffectiveDefinition,
SkipBodyInfo *SkipBody) {
- // Don't complain if we're in GNU89 mode and the previous definition
- // was an extern inline function.
const FunctionDecl *Definition = EffectiveDefinition;
if (!Definition)
if (!FD->isDefined(Definition))
@@ -11635,9 +11791,6 @@ static void RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator,
Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
SkipBodyInfo *SkipBody) {
- // Clear the last template instantiation error context.
- LastTemplateInstantiationErrorContext = ActiveTemplateInstantiation();
-
if (!D)
return D;
FunctionDecl *FD = nullptr;
@@ -11647,6 +11800,18 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
else
FD = cast<FunctionDecl>(D);
+ // Check for defining attributes before the check for redefinition.
+ if (const auto *Attr = FD->getAttr<AliasAttr>()) {
+ Diag(Attr->getLocation(), diag::err_alias_is_definition) << FD << 0;
+ FD->dropAttr<AliasAttr>();
+ FD->setInvalidDecl();
+ }
+ if (const auto *Attr = FD->getAttr<IFuncAttr>()) {
+ Diag(Attr->getLocation(), diag::err_alias_is_definition) << FD << 1;
+ FD->dropAttr<IFuncAttr>();
+ FD->setInvalidDecl();
+ }
+
// See if this is a redefinition.
if (!FD->isLateTemplateParsed()) {
CheckForFunctionRedefinition(FD, nullptr, SkipBody);
@@ -11671,14 +11836,14 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
// captures during transformation of nested lambdas, it is necessary to
// have the LSI properly restored.
if (isGenericLambdaCallOperatorSpecialization(FD)) {
- assert(ActiveTemplateInstantiations.size() &&
- "There should be an active template instantiation on the stack "
- "when instantiating a generic lambda!");
+ assert(inTemplateInstantiation() &&
+ "There should be an active template instantiation on the stack "
+ "when instantiating a generic lambda!");
RebuildLambdaScopeInfo(cast<CXXMethodDecl>(D), *this);
- }
- else
+ } else {
// Enter a new function scope
PushFunctionScope();
+ }
// Builtin functions cannot be defined.
if (unsigned BuiltinID = FD->getBuiltinID()) {
@@ -11793,7 +11958,7 @@ bool Sema::canDelayFunctionBody(const Declarator &D) {
// We can't delay parsing the body of a function template with a deduced
// return type (yet).
- if (D.getDeclSpec().containsPlaceholderType()) {
+ if (D.getDeclSpec().hasAutoTypeSpec()) {
// If the placeholder introduces a non-deduced trailing return type,
// we can still delay parsing it.
if (D.getNumTypeObjects()) {
@@ -11841,7 +12006,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
sema::AnalysisBasedWarnings::Policy WP = AnalysisWarnings.getDefaultPolicy();
sema::AnalysisBasedWarnings::Policy *ActivePolicy = nullptr;
- if (getLangOpts().CoroutinesTS && !getCurFunction()->CoroutineStmts.empty())
+ if (getLangOpts().CoroutinesTS && getCurFunction()->CoroutinePromise)
CheckCompletedCoroutineBody(FD, Body);
if (FD) {
@@ -11962,7 +12127,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
!LangOpts.CPlusPlus) {
TypeSourceInfo *TI = FD->getTypeSourceInfo();
TypeLoc TL = TI->getTypeLoc();
- FunctionTypeLoc FTL = TL.castAs<FunctionTypeLoc>();
+ FunctionTypeLoc FTL = TL.getAsAdjusted<FunctionTypeLoc>();
Diag(FTL.getLParenLoc(), diag::warn_strict_prototypes) << 1;
}
}
@@ -12555,7 +12720,7 @@ bool Sema::isAcceptableTagRedeclaration(const TagDecl *Previous,
if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Previous))
isTemplate = Record->getDescribedClassTemplate();
- if (!ActiveTemplateInstantiations.empty()) {
+ if (inTemplateInstantiation()) {
// In a template instantiation, do not offer fix-its for tag mismatches
// since they usually mess up the template instead of fixing the problem.
Diag(NewTagLoc, diag::warn_struct_class_tag_mismatch)
@@ -12711,8 +12876,8 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
bool ScopedEnum = ScopedEnumKWLoc.isValid();
- // FIXME: Check explicit specializations more carefully.
- bool isExplicitSpecialization = false;
+ // FIXME: Check member specializations more carefully.
+ bool isMemberSpecialization = false;
bool Invalid = false;
// We only need to do this matching if we have template parameters
@@ -12723,7 +12888,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
if (TemplateParameterList *TemplateParams =
MatchTemplateParametersToScopeSpecifier(
KWLoc, NameLoc, SS, nullptr, TemplateParameterLists,
- TUK == TUK_Friend, isExplicitSpecialization, Invalid)) {
+ TUK == TUK_Friend, isMemberSpecialization, Invalid)) {
if (Kind == TTK_Enum) {
Diag(KWLoc, diag::err_enum_template);
return nullptr;
@@ -12750,7 +12915,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// The "template<>" header is extraneous.
Diag(TemplateParams->getTemplateLoc(), diag::err_template_tag_noparams)
<< TypeWithKeyword::getTagTypeKindName(Kind) << Name;
- isExplicitSpecialization = true;
+ isMemberSpecialization = true;
}
}
}
@@ -13070,7 +13235,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
if (auto *Shadow = dyn_cast<UsingShadowDecl>(DirectPrevDecl)) {
auto *OldTag = dyn_cast<TagDecl>(PrevDecl);
if (SS.isEmpty() && TUK != TUK_Reference && TUK != TUK_Friend &&
- isDeclInScope(Shadow, SearchDC, S, isExplicitSpecialization) &&
+ isDeclInScope(Shadow, SearchDC, S, isMemberSpecialization) &&
!(OldTag && isAcceptableTagRedeclContext(
*this, OldTag->getDeclContext(), SearchDC))) {
Diag(KWLoc, diag::err_using_decl_conflict_reverse);
@@ -13090,7 +13255,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// rementions the tag), reuse the decl.
if (TUK == TUK_Reference || TUK == TUK_Friend ||
isDeclInScope(DirectPrevDecl, SearchDC, S,
- SS.isNotEmpty() || isExplicitSpecialization)) {
+ SS.isNotEmpty() || isMemberSpecialization)) {
// Make sure that this wasn't declared as an enum and now used as a
// struct or something similar.
if (!isAcceptableTagRedeclaration(PrevTagDecl, Kind,
@@ -13195,7 +13360,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// is from an implicit instantiation, don't emit an error
// here; we'll catch this in the general case below.
bool IsExplicitSpecializationAfterInstantiation = false;
- if (isExplicitSpecialization) {
+ if (isMemberSpecialization) {
if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Def))
IsExplicitSpecializationAfterInstantiation =
RD->getTemplateSpecializationKind() !=
@@ -13289,7 +13454,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// Otherwise, only diagnose if the declaration is in scope.
} else if (!isDeclInScope(DirectPrevDecl, SearchDC, S,
- SS.isNotEmpty() || isExplicitSpecialization)) {
+ SS.isNotEmpty() || isMemberSpecialization)) {
// do nothing
// Diagnose implicit declarations introduced by elaborated types.
@@ -13421,7 +13586,7 @@ CreateNewDecl:
// for explicit specializations, because they have similar checking
// (with more specific diagnostics) in the call to
// CheckMemberSpecialization, below.
- if (!isExplicitSpecialization &&
+ if (!isMemberSpecialization &&
(TUK == TUK_Definition || TUK == TUK_Declaration) &&
diagnoseQualifiedDeclaration(SS, DC, OrigName, Loc))
Invalid = true;
@@ -13452,7 +13617,7 @@ CreateNewDecl:
}
if (ModulePrivateLoc.isValid()) {
- if (isExplicitSpecialization)
+ if (isMemberSpecialization)
Diag(New->getLocation(), diag::err_module_private_specialization)
<< 2
<< FixItHint::CreateRemoval(ModulePrivateLoc);
@@ -13465,7 +13630,7 @@ CreateNewDecl:
// If this is a specialization of a member class (of a class template),
// check the specialization.
- if (isExplicitSpecialization && CheckMemberSpecialization(New, Previous))
+ if (isMemberSpecialization && CheckMemberSpecialization(New, Previous))
Invalid = true;
// If we're declaring or defining a tag in function prototype scope in C,
@@ -13489,9 +13654,6 @@ CreateNewDecl:
if (Invalid)
New->setInvalidDecl();
- if (Attr)
- ProcessDeclAttributeList(S, New, Attr);
-
// Set the lexical context. If the tag has a C++ scope specifier, the
// lexical context will be different from the semantic context.
New->setLexicalDeclContext(CurContext);
@@ -13510,6 +13672,9 @@ CreateNewDecl:
if (TUK == TUK_Definition)
New->startDefinition();
+ if (Attr)
+ ProcessDeclAttributeList(S, New, Attr);
+
// If this has an identifier, add it to the scope stack.
if (TUK == TUK_Friend) {
// We might be replacing an existing declaration in the lookup tables;
@@ -13632,8 +13797,9 @@ void Sema::ActOnTagFinishDefinition(Scope *S, Decl *TagD,
RD->completeDefinition();
}
- if (isa<CXXRecordDecl>(Tag))
+ if (isa<CXXRecordDecl>(Tag)) {
FieldCollector->FinishClass();
+ }
// Exit this scope of this tag's definition.
PopDeclContext();
@@ -14340,7 +14506,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
// Verify that all the fields are okay.
SmallVector<FieldDecl*, 32> RecFields;
- bool ARCErrReported = false;
+ bool ObjCFieldLifetimeErrReported = false;
for (ArrayRef<Decl *>::iterator i = Fields.begin(), end = Fields.end();
i != end; ++i) {
FieldDecl *FD = cast<FieldDecl>(*i);
@@ -14475,16 +14641,16 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
<< FixItHint::CreateInsertion(FD->getLocation(), "*");
QualType T = Context.getObjCObjectPointerType(FD->getType());
FD->setType(T);
- } else if (getLangOpts().ObjCAutoRefCount && Record && !ARCErrReported &&
+ } else if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() &&
+ Record && !ObjCFieldLifetimeErrReported &&
(!getLangOpts().CPlusPlus || Record->isUnion())) {
- // It's an error in ARC if a field has lifetime.
+ // It's an error in ARC or Weak if a field has lifetime.
// We don't want to report this in a system header, though,
// so we just make the field unavailable.
// FIXME: that's really not sufficient; we need to make the type
// itself invalid to, say, initialize or copy.
QualType T = FD->getType();
- Qualifiers::ObjCLifetime lifetime = T.getObjCLifetime();
- if (lifetime && lifetime != Qualifiers::OCL_ExplicitNone) {
+ if (T.hasNonTrivialObjCLifetime()) {
SourceLocation loc = FD->getLocation();
if (getSourceManager().isInSystemHeader(loc)) {
if (!FD->hasAttr<UnavailableAttr>()) {
@@ -14495,7 +14661,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
Diag(FD->getLocation(), diag::err_arc_objc_object_in_tag)
<< T->isBlockPointerType() << Record->getTagKind();
}
- ARCErrReported = true;
+ ObjCFieldLifetimeErrReported = true;
}
} else if (getLangOpts().ObjC1 &&
getLangOpts().getGC() != LangOptions::NonGC &&
@@ -15207,7 +15373,7 @@ static void CheckForDuplicateEnumValues(Sema &S, ArrayRef<Decl *> Elements,
bool Sema::IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val,
bool AllowMask) const {
- assert(ED->hasAttr<FlagEnumAttr>() && "looking for value in non-flag enum");
+ assert(ED->isClosedFlag() && "looking for value in non-flag or open enum");
assert(ED->isCompleteDefinition() && "expected enum definition");
auto R = FlagBitsCache.insert(std::make_pair(ED, llvm::APInt()));
@@ -15452,7 +15618,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange,
CheckForDuplicateEnumValues(*this, Elements, Enum, EnumType);
- if (Enum->hasAttr<FlagEnumAttr>()) {
+ if (Enum->isClosedFlag()) {
for (Decl *D : Elements) {
EnumConstantDecl *ECD = cast_or_null<EnumConstantDecl>(D);
if (!ECD) continue; // Already issued a diagnostic.