diff options
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 680 |
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. |