diff options
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 959 |
1 files changed, 559 insertions, 400 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index b92d76ad42049..23c99d45a78d4 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1735,12 +1735,13 @@ static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) { static void GenerateFixForUnusedDecl(const NamedDecl *D, ASTContext &Ctx, FixItHint &Hint) { if (isa<LabelDecl>(D)) { - SourceLocation AfterColon = Lexer::findLocationAfterToken(D->getLocEnd(), - tok::colon, Ctx.getSourceManager(), Ctx.getLangOpts(), true); + SourceLocation AfterColon = Lexer::findLocationAfterToken( + D->getEndLoc(), tok::colon, Ctx.getSourceManager(), Ctx.getLangOpts(), + true); if (AfterColon.isInvalid()) return; - Hint = FixItHint::CreateRemoval(CharSourceRange:: - getCharRange(D->getLocStart(), AfterColon)); + Hint = FixItHint::CreateRemoval( + CharSourceRange::getCharRange(D->getBeginLoc(), AfterColon)); } } @@ -2110,7 +2111,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New, // Allow multiple definitions for ObjC built-in typedefs. // FIXME: Verify the underlying types are equivalent! - if (getLangOpts().ObjC1) { + if (getLangOpts().ObjC) { const IdentifierInfo *TypeID = New->getIdentifier(); switch (TypeID->getLength()) { default: break; @@ -2474,14 +2475,9 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D, else if (const auto *OA = dyn_cast<OptimizeNoneAttr>(Attr)) NewAttr = S.mergeOptimizeNoneAttr(D, OA->getRange(), AttrSpellingListIndex); else if (const auto *InternalLinkageA = dyn_cast<InternalLinkageAttr>(Attr)) - NewAttr = S.mergeInternalLinkageAttr( - D, InternalLinkageA->getRange(), - &S.Context.Idents.get(InternalLinkageA->getSpelling()), - AttrSpellingListIndex); + NewAttr = S.mergeInternalLinkageAttr(D, *InternalLinkageA); else if (const auto *CommonA = dyn_cast<CommonAttr>(Attr)) - NewAttr = S.mergeCommonAttr(D, CommonA->getRange(), - &S.Context.Idents.get(CommonA->getSpelling()), - AttrSpellingListIndex); + NewAttr = S.mergeCommonAttr(D, *CommonA); else if (isa<AlignedAttr>(Attr)) // AlignedAttrs are handled separately, because we need to handle all // such attributes on a declaration at the same time. @@ -3249,20 +3245,15 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD, // Redeclarations or specializations of a function or function template // with a declared return type that uses a placeholder type shall also // use that placeholder, not a deduced type. - QualType OldDeclaredReturnType = - (Old->getTypeSourceInfo() - ? Old->getTypeSourceInfo()->getType()->castAs<FunctionType>() - : OldType)->getReturnType(); - QualType NewDeclaredReturnType = - (New->getTypeSourceInfo() - ? New->getTypeSourceInfo()->getType()->castAs<FunctionType>() - : NewType)->getReturnType(); + QualType OldDeclaredReturnType = Old->getDeclaredReturnType(); + QualType NewDeclaredReturnType = New->getDeclaredReturnType(); if (!Context.hasSameType(OldDeclaredReturnType, NewDeclaredReturnType) && - !((NewQType->isDependentType() || OldQType->isDependentType()) && - New->isLocalExternDecl())) { + canFullyTypeCheckRedeclaration(New, Old, NewDeclaredReturnType, + OldDeclaredReturnType)) { QualType ResQT; if (NewDeclaredReturnType->isObjCObjectPointerType() && OldDeclaredReturnType->isObjCObjectPointerType()) + // FIXME: This does the wrong thing for a deduced return type. ResQT = Context.mergeObjCGCQualifiers(NewQType, OldQType); if (ResQT.isNull()) { if (New->isCXXClassMember() && New->isOutOfLine()) @@ -3427,13 +3418,11 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD, if (OldQTypeForComparison == NewQType) return MergeCompatibleFunctionDecls(New, Old, S, MergeTypeWithOld); - if ((NewQType->isDependentType() || OldQType->isDependentType()) && - New->isLocalExternDecl()) { - // It's OK if we couldn't merge types for a local function declaraton - // if either the old or new type is dependent. We'll merge the types - // when we instantiate the function. + // If the types are imprecise (due to dependent constructs in friends or + // local extern declarations), it's OK if they differ. We'll check again + // during instantiation. + if (!canFullyTypeCheckRedeclaration(New, Old, NewQType, OldQType)) return false; - } // Fall through for conflicting redeclarations and redefinitions. } @@ -4356,8 +4345,8 @@ Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS, Record = UT->getDecl(); if (Record && getLangOpts().MicrosoftExt) { - Diag(DS.getLocStart(), diag::ext_ms_anonymous_record) - << Record->isUnion() << DS.getSourceRange(); + Diag(DS.getBeginLoc(), diag::ext_ms_anonymous_record) + << Record->isUnion() << DS.getSourceRange(); return BuildMicrosoftCAnonymousStruct(S, DS, Record); } @@ -4380,8 +4369,8 @@ Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS, if (!DS.isMissingDeclaratorOk()) { // Customize diagnostic for a typedef missing a name. if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) - Diag(DS.getLocStart(), diag::ext_typedef_without_a_name) - << DS.getSourceRange(); + Diag(DS.getBeginLoc(), diag::ext_typedef_without_a_name) + << DS.getSourceRange(); else DeclaresAnything = false; } @@ -4405,7 +4394,7 @@ Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS, if (!DeclaresAnything) { // In C, we allow this as a (popular) extension / bug. Don't bother // producing further diagnostics for redundant qualifiers after this. - Diag(DS.getLocStart(), diag::ext_no_declarators) << DS.getSourceRange(); + Diag(DS.getBeginLoc(), diag::ext_no_declarators) << DS.getSourceRange(); return TagD; } @@ -4815,14 +4804,11 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, // Create a declaration for this anonymous struct/union. NamedDecl *Anon = nullptr; if (RecordDecl *OwningClass = dyn_cast<RecordDecl>(Owner)) { - Anon = FieldDecl::Create(Context, OwningClass, - DS.getLocStart(), - Record->getLocation(), - /*IdentifierInfo=*/nullptr, - Context.getTypeDeclType(Record), - TInfo, - /*BitWidth=*/nullptr, /*Mutable=*/false, - /*InitStyle=*/ICIS_NoInit); + Anon = FieldDecl::Create( + Context, OwningClass, DS.getBeginLoc(), Record->getLocation(), + /*IdentifierInfo=*/nullptr, Context.getTypeDeclType(Record), TInfo, + /*BitWidth=*/nullptr, /*Mutable=*/false, + /*InitStyle=*/ICIS_NoInit); Anon->setAccess(AS); if (getLangOpts().CPlusPlus) FieldCollector->Add(cast<FieldDecl>(Anon)); @@ -4837,11 +4823,9 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, SC = SC_None; } - Anon = VarDecl::Create(Context, Owner, - DS.getLocStart(), + Anon = VarDecl::Create(Context, Owner, DS.getBeginLoc(), Record->getLocation(), /*IdentifierInfo=*/nullptr, - Context.getTypeDeclType(Record), - TInfo, SC); + Context.getTypeDeclType(Record), TInfo, SC); // Default-initialize the implicit variable. This initialization will be // trivial in almost all cases, except if a union member has an in-class @@ -4913,15 +4897,11 @@ Decl *Sema::BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS, QualType RecTy = Context.getTypeDeclType(Record); // Create a declaration for this anonymous struct. - NamedDecl *Anon = FieldDecl::Create(Context, - ParentDecl, - DS.getLocStart(), - DS.getLocStart(), - /*IdentifierInfo=*/nullptr, - RecTy, - TInfo, - /*BitWidth=*/nullptr, /*Mutable=*/false, - /*InitStyle=*/ICIS_NoInit); + NamedDecl *Anon = + FieldDecl::Create(Context, ParentDecl, DS.getBeginLoc(), DS.getBeginLoc(), + /*IdentifierInfo=*/nullptr, RecTy, TInfo, + /*BitWidth=*/nullptr, /*Mutable=*/false, + /*InitStyle=*/ICIS_NoInit); Anon->setImplicit(); // Add the anonymous struct object to the current context. @@ -4962,7 +4942,6 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) { case UnqualifiedIdKind::IK_ImplicitSelfParam: case UnqualifiedIdKind::IK_Identifier: NameInfo.setName(Name.Identifier); - NameInfo.setLoc(Name.StartLocation); return NameInfo; case UnqualifiedIdKind::IK_DeductionGuideName: { @@ -4989,14 +4968,12 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) { NameInfo.setName( Context.DeclarationNames.getCXXDeductionGuideName(Template)); - NameInfo.setLoc(Name.StartLocation); return NameInfo; } case UnqualifiedIdKind::IK_OperatorFunctionId: NameInfo.setName(Context.DeclarationNames.getCXXOperatorName( Name.OperatorFunctionId.Operator)); - NameInfo.setLoc(Name.StartLocation); NameInfo.getInfo().CXXOperatorName.BeginOpNameLoc = Name.OperatorFunctionId.SymbolLocations[0]; NameInfo.getInfo().CXXOperatorName.EndOpNameLoc @@ -5006,7 +4983,6 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) { case UnqualifiedIdKind::IK_LiteralOperatorId: NameInfo.setName(Context.DeclarationNames.getCXXLiteralOperatorName( Name.Identifier)); - NameInfo.setLoc(Name.StartLocation); NameInfo.setCXXLiteralOperatorNameLoc(Name.EndLocation); return NameInfo; @@ -5017,7 +4993,6 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) { return DeclarationNameInfo(); NameInfo.setName(Context.DeclarationNames.getCXXConversionFunctionName( Context.getCanonicalType(Ty))); - NameInfo.setLoc(Name.StartLocation); NameInfo.setNamedTypeInfo(TInfo); return NameInfo; } @@ -5029,7 +5004,6 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) { return DeclarationNameInfo(); NameInfo.setName(Context.DeclarationNames.getCXXConstructorName( Context.getCanonicalType(Ty))); - NameInfo.setLoc(Name.StartLocation); NameInfo.setNamedTypeInfo(TInfo); return NameInfo; } @@ -5051,7 +5025,6 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) { NameInfo.setName(Context.DeclarationNames.getCXXConstructorName( Context.getCanonicalType(CurClassType))); - NameInfo.setLoc(Name.StartLocation); // FIXME: should we retrieve TypeSourceInfo? NameInfo.setNamedTypeInfo(nullptr); return NameInfo; @@ -5064,7 +5037,6 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) { return DeclarationNameInfo(); NameInfo.setName(Context.DeclarationNames.getCXXDestructorName( Context.getCanonicalType(Ty))); - NameInfo.setLoc(Name.StartLocation); NameInfo.setNamedTypeInfo(TInfo); return NameInfo; } @@ -5349,9 +5321,8 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D, return ActOnDecompositionDeclarator(S, D, TemplateParamLists); } else if (!Name) { if (!D.isInvalidType()) // Reject this if we think it is valid. - Diag(D.getDeclSpec().getLocStart(), - diag::err_declarator_need_ident) - << D.getDeclSpec().getSourceRange() << D.getSourceRange(); + Diag(D.getDeclSpec().getBeginLoc(), diag::err_declarator_need_ident) + << D.getDeclSpec().getSourceRange() << D.getSourceRange(); return nullptr; } else if (DiagnoseUnexpandedParameterPack(NameInfo, UPPC_DeclarationType)) return nullptr; @@ -5542,15 +5513,8 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D, // If this has an identifier and is not a function template specialization, // add it to the scope stack. - if (New->getDeclName() && AddToScope) { - // Only make a locally-scoped extern declaration visible if it is the first - // declaration of this entity. Qualified lookup for such an entity should - // only find this declaration if there is no visible declaration of it. - bool AddToContext = !D.isRedeclaration() || !New->isLocalExternDecl(); - PushOnScopeChains(New, S, AddToContext); - if (!AddToContext) - CurContext->addHiddenDecl(New); - } + if (New->getDeclName() && AddToScope) + PushOnScopeChains(New, S); if (isInOpenMPDeclareTargetContext()) checkDeclIsAllowedInOpenMPTarget(nullptr, New); @@ -5604,11 +5568,13 @@ static QualType TryToFixInvalidVariablyModifiedType(QualType T, if (VLATy->getElementType()->isVariablyModifiedType()) return QualType(); - llvm::APSInt Res; + Expr::EvalResult Result; if (!VLATy->getSizeExpr() || - !VLATy->getSizeExpr()->EvaluateAsInt(Res, Context)) + !VLATy->getSizeExpr()->EvaluateAsInt(Result, Context)) return QualType(); + llvm::APSInt Res = Result.Val.getInt(); + // Check whether the array size is negative. if (Res.isSigned() && Res.isNegative()) { SizeIsNegative = true; @@ -5897,10 +5863,10 @@ isOutOfScopePreviousDeclaration(NamedDecl *PrevDecl, DeclContext *DC, return true; } -static void SetNestedNameSpecifier(DeclaratorDecl *DD, Declarator &D) { +static void SetNestedNameSpecifier(Sema &S, DeclaratorDecl *DD, Declarator &D) { CXXScopeSpec &SS = D.getCXXScopeSpec(); if (!SS.isSet()) return; - DD->setQualifierInfo(SS.getWithLocInContext(DD->getASTContext())); + DD->setQualifierInfo(SS.getWithLocInContext(S.Context)); } bool Sema::inferObjCARCLifetime(ValueDecl *decl) { @@ -6021,14 +5987,14 @@ static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) { // The [[lifetimebound]] attribute can be applied to the implicit object // parameter of a non-static member function (other than a ctor or dtor) // by applying it to the function type. - if (ATL.getAttrKind() == AttributedType::attr_lifetimebound) { + if (const auto *A = ATL.getAttrAs<LifetimeBoundAttr>()) { const auto *MD = dyn_cast<CXXMethodDecl>(FD); if (!MD || MD->isStatic()) { - S.Diag(ATL.getAttrNameLoc(), diag::err_lifetimebound_no_object_param) - << !MD << ATL.getLocalSourceRange(); + S.Diag(A->getLocation(), diag::err_lifetimebound_no_object_param) + << !MD << A->getRange(); } else if (isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD)) { - S.Diag(ATL.getAttrNameLoc(), diag::err_lifetimebound_ctor_dtor) - << isa<CXXDestructorDecl>(MD) << ATL.getLocalSourceRange(); + S.Diag(A->getLocation(), diag::err_lifetimebound_ctor_dtor) + << isa<CXXDestructorDecl>(MD) << A->getRange(); } } } @@ -6383,7 +6349,7 @@ NamedDecl *Sema::ActOnVariableDeclarator( // address space qualifiers. if (R->isEventT()) { if (R.getAddressSpace() != LangAS::opencl_private) { - Diag(D.getLocStart(), diag::err_event_t_addr_space_qual); + Diag(D.getBeginLoc(), diag::err_event_t_addr_space_qual); D.setInvalidType(); } } @@ -6457,9 +6423,8 @@ NamedDecl *Sema::ActOnVariableDeclarator( VarTemplateDecl *NewTemplate = nullptr; TemplateParameterList *TemplateParams = nullptr; if (!getLangOpts().CPlusPlus) { - NewVD = VarDecl::Create(Context, DC, D.getLocStart(), - D.getIdentifierLoc(), II, - R, TInfo, SC); + NewVD = VarDecl::Create(Context, DC, D.getBeginLoc(), D.getIdentifierLoc(), + II, R, TInfo, SC); if (R->getContainedDeducedType()) ParsingInitForAutoVars.insert(NewVD); @@ -6521,7 +6486,7 @@ NamedDecl *Sema::ActOnVariableDeclarator( // Match up the template parameter lists with the scope specifier, then // determine whether we have a template or a template specialization. TemplateParams = MatchTemplateParametersToScopeSpecifier( - D.getDeclSpec().getLocStart(), D.getIdentifierLoc(), + D.getDeclSpec().getBeginLoc(), D.getIdentifierLoc(), D.getCXXScopeSpec(), D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId ? D.getName().TemplateId @@ -6580,11 +6545,11 @@ NamedDecl *Sema::ActOnVariableDeclarator( NewVD = cast<VarDecl>(Res.get()); AddToScope = false; } else if (D.isDecompositionDeclarator()) { - NewVD = DecompositionDecl::Create(Context, DC, D.getLocStart(), + NewVD = DecompositionDecl::Create(Context, DC, D.getBeginLoc(), D.getIdentifierLoc(), R, TInfo, SC, Bindings); } else - NewVD = VarDecl::Create(Context, DC, D.getLocStart(), + NewVD = VarDecl::Create(Context, DC, D.getBeginLoc(), D.getIdentifierLoc(), II, R, TInfo, SC); // If this is supposed to be a variable template, create it as such. @@ -6606,7 +6571,7 @@ NamedDecl *Sema::ActOnVariableDeclarator( NewTemplate->setInvalidDecl(); } - SetNestedNameSpecifier(NewVD, D); + SetNestedNameSpecifier(*this, NewVD, D); // If we have any template parameter lists that don't directly belong to // the variable (matching the scope specifier), store them. @@ -6801,7 +6766,7 @@ NamedDecl *Sema::ActOnVariableDeclarator( } if (!R->isIntegralType(Context) && !R->isPointerType()) { - Diag(D.getLocStart(), diag::err_asm_bad_register_type); + Diag(D.getBeginLoc(), diag::err_asm_bad_register_type); NewVD->setInvalidDecl(true); } } @@ -6931,12 +6896,12 @@ NamedDecl *Sema::ActOnVariableDeclarator( // C++ [basic.start.main]p3 // A program that declares a variable main at global scope is ill-formed. if (getLangOpts().CPlusPlus) - Diag(D.getLocStart(), diag::err_main_global_variable); + Diag(D.getBeginLoc(), diag::err_main_global_variable); // In C, and external-linkage variable named main results in undefined // behavior. else if (NewVD->hasExternalFormalLinkage()) - Diag(D.getLocStart(), diag::warn_main_redefined); + Diag(D.getBeginLoc(), diag::warn_main_redefined); } if (D.isRedeclaration() && !Previous.empty()) { @@ -7382,19 +7347,23 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { return; } } - // OpenCL v1.2 s6.5 - All program scope variables must be declared in the + // OpenCL C v1.2 s6.5 - All program scope variables must be declared in the // __constant address space. - // OpenCL v2.0 s6.5.1 - Variables defined at program scope and static + // OpenCL C v2.0 s6.5.1 - Variables defined at program scope and static // variables inside a function can also be declared in the global // address space. + // OpenCL C++ v1.0 s2.5 inherits rule from OpenCL C v2.0 and allows local + // address space additionally. + // FIXME: Add local AS for OpenCL C++. if (NewVD->isFileVarDecl() || NewVD->isStaticLocal() || NewVD->hasExternalStorage()) { if (!T->isSamplerT() && !(T.getAddressSpace() == LangAS::opencl_constant || (T.getAddressSpace() == LangAS::opencl_global && - getLangOpts().OpenCLVersion == 200))) { + (getLangOpts().OpenCLVersion == 200 || + getLangOpts().OpenCLCPlusPlus)))) { int Scope = NewVD->isStaticLocal() | NewVD->hasExternalStorage() << 1; - if (getLangOpts().OpenCLVersion == 200) + if (getLangOpts().OpenCLVersion == 200 || getLangOpts().OpenCLCPlusPlus) Diag(NewVD->getLocation(), diag::err_opencl_global_invalid_addr_space) << Scope << "global or constant"; else @@ -7747,8 +7716,10 @@ static NamedDecl *DiagnoseInvalidRedeclaration( SmallVector<std::pair<FunctionDecl *, unsigned>, 1> NearMatches; TypoCorrection Correction; bool IsDefinition = ExtraArgs.D.isFunctionDefinition(); - unsigned DiagMsg = IsLocalFriend ? diag::err_no_matching_local_friend - : diag::err_member_decl_does_not_match; + unsigned DiagMsg = + IsLocalFriend ? diag::err_no_matching_local_friend : + NewFD->getFriendObjectKind() ? diag::err_qualified_friend_no_match : + diag::err_member_decl_does_not_match; LookupResult Prev(SemaRef, Name, NewFD->getLocation(), IsLocalFriend ? Sema::LookupLocalFriendName : Sema::LookupOrdinaryName, @@ -7938,10 +7909,8 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, (D.isFunctionDeclarator() && D.getFunctionTypeInfo().hasPrototype) || (!R->getAsAdjusted<FunctionType>() && R->isFunctionProtoType()); - NewFD = FunctionDecl::Create(SemaRef.Context, DC, - D.getLocStart(), NameInfo, R, - TInfo, SC, isInline, - HasPrototype, false); + NewFD = FunctionDecl::Create(SemaRef.Context, DC, D.getBeginLoc(), NameInfo, + R, TInfo, SC, isInline, HasPrototype, false); if (D.isInvalidType()) NewFD->setInvalidDecl(); @@ -7966,31 +7935,26 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, "Constructors can only be declared in a member context"); R = SemaRef.CheckConstructorDeclarator(D, R, SC); - return CXXConstructorDecl::Create(SemaRef.Context, cast<CXXRecordDecl>(DC), - D.getLocStart(), NameInfo, - R, TInfo, isExplicit, isInline, - /*isImplicitlyDeclared=*/false, - isConstexpr); + return CXXConstructorDecl::Create( + SemaRef.Context, cast<CXXRecordDecl>(DC), D.getBeginLoc(), NameInfo, R, + TInfo, isExplicit, isInline, + /*isImplicitlyDeclared=*/false, isConstexpr); } else if (Name.getNameKind() == DeclarationName::CXXDestructorName) { // This is a C++ destructor declaration. if (DC->isRecord()) { R = SemaRef.CheckDestructorDeclarator(D, R, SC); CXXRecordDecl *Record = cast<CXXRecordDecl>(DC); - CXXDestructorDecl *NewDD = CXXDestructorDecl::Create( - SemaRef.Context, Record, - D.getLocStart(), - NameInfo, R, TInfo, isInline, - /*isImplicitlyDeclared=*/false); - - // If the class is complete, then we now create the implicit exception - // specification. If the class is incomplete or dependent, we can't do - // it yet. - if (SemaRef.getLangOpts().CPlusPlus11 && !Record->isDependentType() && - Record->getDefinition() && !Record->isBeingDefined() && - R->getAs<FunctionProtoType>()->getExceptionSpecType() == EST_None) { - SemaRef.AdjustDestructorExceptionSpec(Record, NewDD); - } + CXXDestructorDecl *NewDD = + CXXDestructorDecl::Create(SemaRef.Context, Record, D.getBeginLoc(), + NameInfo, R, TInfo, isInline, + /*isImplicitlyDeclared=*/false); + + // If the destructor needs an implicit exception specification, set it + // now. FIXME: It'd be nice to be able to create the right type to start + // with, but the type needs to reference the destructor declaration. + if (SemaRef.getLangOpts().CPlusPlus11) + SemaRef.AdjustDestructorExceptionSpec(NewDD); IsVirtualOkay = true; return NewDD; @@ -8001,10 +7965,9 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, // Create a FunctionDecl to satisfy the function definition parsing // code path. - return FunctionDecl::Create(SemaRef.Context, DC, - D.getLocStart(), - D.getIdentifierLoc(), Name, R, TInfo, - SC, isInline, + return FunctionDecl::Create(SemaRef.Context, DC, D.getBeginLoc(), + D.getIdentifierLoc(), Name, R, TInfo, SC, + isInline, /*hasPrototype=*/true, isConstexpr); } @@ -8017,17 +7980,16 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, SemaRef.CheckConversionDeclarator(D, R, SC); IsVirtualOkay = true; - return CXXConversionDecl::Create(SemaRef.Context, cast<CXXRecordDecl>(DC), - D.getLocStart(), NameInfo, - R, TInfo, isInline, isExplicit, - isConstexpr, SourceLocation()); + return CXXConversionDecl::Create( + SemaRef.Context, cast<CXXRecordDecl>(DC), D.getBeginLoc(), NameInfo, 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(), + return CXXDeductionGuideDecl::Create(SemaRef.Context, DC, D.getBeginLoc(), isExplicit, NameInfo, R, TInfo, - D.getLocEnd()); + D.getEndLoc()); } 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. @@ -8042,11 +8004,9 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, } // This is a C++ method declaration. - CXXMethodDecl *Ret = CXXMethodDecl::Create(SemaRef.Context, - cast<CXXRecordDecl>(DC), - D.getLocStart(), NameInfo, R, - TInfo, SC, isInline, - isConstexpr, SourceLocation()); + CXXMethodDecl *Ret = CXXMethodDecl::Create( + SemaRef.Context, cast<CXXRecordDecl>(DC), D.getBeginLoc(), NameInfo, R, + TInfo, SC, isInline, isConstexpr, SourceLocation()); IsVirtualOkay = !Ret->isStatic(); return Ret; } else { @@ -8058,10 +8018,9 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, // Determine whether the function was written with a // prototype. This true when: // - we're in C++ (where every function has a prototype), - return FunctionDecl::Create(SemaRef.Context, DC, - D.getLocStart(), - NameInfo, R, TInfo, SC, isInline, - true/*HasPrototype*/, isConstexpr); + return FunctionDecl::Create(SemaRef.Context, DC, D.getBeginLoc(), NameInfo, + R, TInfo, SC, isInline, true /*HasPrototype*/, + isConstexpr); } } @@ -8137,7 +8096,7 @@ static OpenCLParamType getOpenCLKernelParameterType(Sema &S, QualType PT) { const Type *UnderlyingTy = PT->getPointeeOrArrayElementType(); // Call ourself to check an underlying type of an array. Since the // getPointeeOrArrayElementType returns an innermost type which is not an - // array, this recusive call only happens once. + // array, this recursive call only happens once. return getOpenCLKernelParameterType(S, QualType(UnderlyingTy, 0)); } @@ -8415,7 +8374,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, Diag(D.getDeclSpec().getVirtualSpecLoc(), diag::err_virtual_in_union); } - SetNestedNameSpecifier(NewFD, D); + SetNestedNameSpecifier(*this, NewFD, D); isMemberSpecialization = false; isFunctionTemplateSpecialization = false; if (D.isInvalidType()) @@ -8426,7 +8385,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, bool Invalid = false; if (TemplateParameterList *TemplateParams = MatchTemplateParametersToScopeSpecifier( - D.getDeclSpec().getLocStart(), D.getIdentifierLoc(), + D.getDeclSpec().getBeginLoc(), D.getIdentifierLoc(), D.getCXXScopeSpec(), D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId ? D.getName().TemplateId @@ -8496,8 +8455,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, << FixItHint::CreateInsertion(InsertLoc, "<>"); } } - } - else { + } else { // All template param lists were matched against the scope specifier: // this is NOT (an explicit specialization of) a template. if (TemplateParamLists.size() > 0) @@ -9067,10 +9025,14 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // selecting a friend based on a dependent factor. But there // are situations where these conditions don't apply and we // can actually do this check immediately. + // + // Unless the scope is dependent, it's always an error if qualified + // redeclaration lookup found nothing at all. Diagnose that now; + // nothing will diagnose that error later. if (isFriend && - (TemplateParamLists.size() || - D.getCXXScopeSpec().getScopeRep()->isDependent() || - CurContext->isDependentContext())) { + (D.getCXXScopeSpec().getScopeRep()->isDependent() || + (!Previous.empty() && (TemplateParamLists.size() || + CurContext->isDependentContext())))) { // ignore these } else { // The user tried to provide an out-of-line definition for a @@ -9336,6 +9298,39 @@ Attr *Sema::getImplicitCodeSegOrSectionAttrForFunction(const FunctionDecl *FD, } return nullptr; } + +/// Determines if we can perform a correct type check for \p D as a +/// redeclaration of \p PrevDecl. If not, we can generally still perform a +/// best-effort check. +/// +/// \param NewD The new declaration. +/// \param OldD The old declaration. +/// \param NewT The portion of the type of the new declaration to check. +/// \param OldT The portion of the type of the old declaration to check. +bool Sema::canFullyTypeCheckRedeclaration(ValueDecl *NewD, ValueDecl *OldD, + QualType NewT, QualType OldT) { + if (!NewD->getLexicalDeclContext()->isDependentContext()) + return true; + + // For dependently-typed local extern declarations and friends, we can't + // perform a correct type check in general until instantiation: + // + // int f(); + // template<typename T> void g() { T f(); } + // + // (valid if g() is only instantiated with T = int). + if (NewT->isDependentType() && + (NewD->isLocalExternDecl() || NewD->getFriendObjectKind())) + return false; + + // Similarly, if the previous declaration was a dependent local extern + // declaration, we don't really know its type yet. + if (OldT->isDependentType() && OldD->isLocalExternDecl()) + return false; + + return true; +} + /// Checks if the new declaration declared in dependent context must be /// put in the same redeclaration chain as the specified declaration. /// @@ -9346,36 +9341,32 @@ Attr *Sema::getImplicitCodeSegOrSectionAttrForFunction(const FunctionDecl *FD, /// belongs to. /// bool Sema::shouldLinkDependentDeclWithPrevious(Decl *D, Decl *PrevDecl) { - // Any declarations should be put into redeclaration chains except for - // friend declaration in a dependent context that names a function in - // namespace scope. + if (!D->getLexicalDeclContext()->isDependentContext()) + return true; + + // Don't chain dependent friend function definitions until instantiation, to + // permit cases like // - // This allows to compile code like: + // void func(); + // template<typename T> class C1 { friend void func() {} }; + // template<typename T> class C2 { friend void func() {} }; // - // void func(); - // template<typename T> class C1 { friend void func() { } }; - // template<typename T> class C2 { friend void func() { } }; + // ... which is valid if only one of C1 and C2 is ever instantiated. // - // This code snippet is a valid code unless both templates are instantiated. - return !(D->getLexicalDeclContext()->isDependentContext() && - D->getDeclContext()->isFileContext() && - D->getFriendObjectKind() != Decl::FOK_None); -} + // FIXME: This need only apply to function definitions. For now, we proxy + // this by checking for a file-scope function. We do not want this to apply + // to friend declarations nominating member functions, because that gets in + // the way of access checks. + if (D->getFriendObjectKind() && D->getDeclContext()->isFileContext()) + return false; -namespace MultiVersioning { -enum Type { None, Target, CPUSpecific, CPUDispatch}; -} // MultiVersionType - -static MultiVersioning::Type -getMultiVersionType(const FunctionDecl *FD) { - if (FD->hasAttr<TargetAttr>()) - return MultiVersioning::Target; - if (FD->hasAttr<CPUDispatchAttr>()) - return MultiVersioning::CPUDispatch; - if (FD->hasAttr<CPUSpecificAttr>()) - return MultiVersioning::CPUSpecific; - return MultiVersioning::None; + auto *VD = dyn_cast<ValueDecl>(D); + auto *PrevVD = dyn_cast<ValueDecl>(PrevDecl); + return !VD || !PrevVD || + canFullyTypeCheckRedeclaration(VD, PrevVD, VD->getType(), + PrevVD->getType()); } + /// Check the target attribute of the function for MultiVersion /// validity. /// @@ -9412,10 +9403,31 @@ static bool CheckMultiVersionValue(Sema &S, const FunctionDecl *FD) { return false; } +static bool HasNonMultiVersionAttributes(const FunctionDecl *FD, + MultiVersionKind MVType) { + for (const Attr *A : FD->attrs()) { + switch (A->getKind()) { + case attr::CPUDispatch: + case attr::CPUSpecific: + if (MVType != MultiVersionKind::CPUDispatch && + MVType != MultiVersionKind::CPUSpecific) + return true; + break; + case attr::Target: + if (MVType != MultiVersionKind::Target) + return true; + break; + default: + return true; + } + } + return false; +} + static bool CheckMultiVersionAdditionalRules(Sema &S, const FunctionDecl *OldFD, const FunctionDecl *NewFD, bool CausesMV, - MultiVersioning::Type MVType) { + MultiVersionKind MVType) { enum DoesntSupport { FuncTemplates = 0, VirtFuncs = 1, @@ -9436,8 +9448,8 @@ static bool CheckMultiVersionAdditionalRules(Sema &S, const FunctionDecl *OldFD, }; bool IsCPUSpecificCPUDispatchMVType = - MVType == MultiVersioning::CPUDispatch || - MVType == MultiVersioning::CPUSpecific; + MVType == MultiVersionKind::CPUDispatch || + MVType == MultiVersionKind::CPUSpecific; if (OldFD && !OldFD->getType()->getAs<FunctionProtoType>()) { S.Diag(OldFD->getLocation(), diag::err_multiversion_noproto); @@ -9457,15 +9469,14 @@ static bool CheckMultiVersionAdditionalRules(Sema &S, const FunctionDecl *OldFD, // For now, disallow all other attributes. These should be opt-in, but // an analysis of all of them is a future FIXME. - if (CausesMV && OldFD && - std::distance(OldFD->attr_begin(), OldFD->attr_end()) != 1) { + if (CausesMV && OldFD && HasNonMultiVersionAttributes(OldFD, MVType)) { S.Diag(OldFD->getLocation(), diag::err_multiversion_no_other_attrs) << IsCPUSpecificCPUDispatchMVType; S.Diag(NewFD->getLocation(), diag::note_multiversioning_caused_here); return true; } - if (std::distance(NewFD->attr_begin(), NewFD->attr_end()) != 1) + if (HasNonMultiVersionAttributes(NewFD, MVType)) return S.Diag(NewFD->getLocation(), diag::err_multiversion_no_other_attrs) << IsCPUSpecificCPUDispatchMVType; @@ -9498,8 +9509,8 @@ static bool CheckMultiVersionAdditionalRules(Sema &S, const FunctionDecl *OldFD, return S.Diag(NewFD->getLocation(), diag::err_multiversion_doesnt_support) << IsCPUSpecificCPUDispatchMVType << DefaultedFuncs; - if (NewFD->isConstexpr() && (MVType == MultiVersioning::CPUDispatch || - MVType == MultiVersioning::CPUSpecific)) + if (NewFD->isConstexpr() && (MVType == MultiVersionKind::CPUDispatch || + MVType == MultiVersionKind::CPUSpecific)) return S.Diag(NewFD->getLocation(), diag::err_multiversion_doesnt_support) << IsCPUSpecificCPUDispatchMVType << ConstexprFuncs; @@ -9563,19 +9574,19 @@ static bool CheckMultiVersionAdditionalRules(Sema &S, const FunctionDecl *OldFD, /// /// Returns true if there was an error, false otherwise. static bool CheckMultiVersionFirstFunction(Sema &S, FunctionDecl *FD, - MultiVersioning::Type MVType, + MultiVersionKind MVType, const TargetAttr *TA, const CPUDispatchAttr *CPUDisp, const CPUSpecificAttr *CPUSpec) { - assert(MVType != MultiVersioning::None && + assert(MVType != MultiVersionKind::None && "Function lacks multiversion attribute"); // Target only causes MV if it is default, otherwise this is a normal // function. - if (MVType == MultiVersioning::Target && !TA->isDefaultVersion()) + if (MVType == MultiVersionKind::Target && !TA->isDefaultVersion()) return false; - if (MVType == MultiVersioning::Target && CheckMultiVersionValue(S, FD)) { + if (MVType == MultiVersionKind::Target && CheckMultiVersionValue(S, FD)) { FD->setInvalidDecl(); return true; } @@ -9589,6 +9600,15 @@ static bool CheckMultiVersionFirstFunction(Sema &S, FunctionDecl *FD, return false; } +static bool PreviousDeclsHaveMultiVersionAttribute(const FunctionDecl *FD) { + for (const Decl *D = FD->getPreviousDecl(); D; D = D->getPreviousDecl()) { + if (D->getAsFunction()->getMultiVersionKind() != MultiVersionKind::None) + return true; + } + + return false; +} + static bool CheckTargetCausesMultiVersioning( Sema &S, FunctionDecl *OldFD, FunctionDecl *NewFD, const TargetAttr *NewTA, bool &Redeclaration, NamedDecl *&OldDecl, bool &MergeTypeWithPrevious, @@ -9596,11 +9616,12 @@ static bool CheckTargetCausesMultiVersioning( const auto *OldTA = OldFD->getAttr<TargetAttr>(); TargetAttr::ParsedTargetAttr NewParsed = NewTA->parse(); // Sort order doesn't matter, it just needs to be consistent. - llvm::sort(NewParsed.Features.begin(), NewParsed.Features.end()); + llvm::sort(NewParsed.Features); // If the old decl is NOT MultiVersioned yet, and we don't cause that // to change, this is a simple redeclaration. - if (!OldTA || OldTA->getFeaturesStr() == NewTA->getFeaturesStr()) + if (!NewTA->isDefaultVersion() && + (!OldTA || OldTA->getFeaturesStr() == NewTA->getFeaturesStr())) return false; // Otherwise, this decl causes MultiVersioning. @@ -9612,7 +9633,7 @@ static bool CheckTargetCausesMultiVersioning( } if (CheckMultiVersionAdditionalRules(S, OldFD, NewFD, true, - MultiVersioning::Target)) { + MultiVersionKind::Target)) { NewFD->setInvalidDecl(); return true; } @@ -9622,6 +9643,15 @@ static bool CheckTargetCausesMultiVersioning( return true; } + // If this is 'default', permit the forward declaration. + if (!OldFD->isMultiVersion() && !OldTA && NewTA->isDefaultVersion()) { + Redeclaration = true; + OldDecl = OldFD; + OldFD->setIsMultiVersion(); + NewFD->setIsMultiVersion(); + return false; + } + if (CheckMultiVersionValue(S, OldFD)) { S.Diag(NewFD->getLocation(), diag::note_multiversioning_caused_here); NewFD->setInvalidDecl(); @@ -9640,7 +9670,10 @@ static bool CheckTargetCausesMultiVersioning( for (const auto *FD : OldFD->redecls()) { const auto *CurTA = FD->getAttr<TargetAttr>(); - if (!CurTA || CurTA->isInherited()) { + // We allow forward declarations before ANY multiversioning attributes, but + // nothing after the fact. + if (PreviousDeclsHaveMultiVersionAttribute(FD) && + (!CurTA || CurTA->isInherited())) { S.Diag(FD->getLocation(), diag::err_multiversion_required_in_redecl) << 0; S.Diag(NewFD->getLocation(), diag::note_multiversioning_caused_here); @@ -9662,17 +9695,17 @@ static bool CheckTargetCausesMultiVersioning( /// multiversioned declaration collection. static bool CheckMultiVersionAdditionalDecl( Sema &S, FunctionDecl *OldFD, FunctionDecl *NewFD, - MultiVersioning::Type NewMVType, const TargetAttr *NewTA, + MultiVersionKind NewMVType, const TargetAttr *NewTA, const CPUDispatchAttr *NewCPUDisp, const CPUSpecificAttr *NewCPUSpec, bool &Redeclaration, NamedDecl *&OldDecl, bool &MergeTypeWithPrevious, LookupResult &Previous) { - MultiVersioning::Type OldMVType = getMultiVersionType(OldFD); + MultiVersionKind OldMVType = OldFD->getMultiVersionKind(); // Disallow mixing of multiversioning types. - if ((OldMVType == MultiVersioning::Target && - NewMVType != MultiVersioning::Target) || - (NewMVType == MultiVersioning::Target && - OldMVType != MultiVersioning::Target)) { + if ((OldMVType == MultiVersionKind::Target && + NewMVType != MultiVersionKind::Target) || + (NewMVType == MultiVersionKind::Target && + OldMVType != MultiVersionKind::Target)) { S.Diag(NewFD->getLocation(), diag::err_multiversion_types_mixed); S.Diag(OldFD->getLocation(), diag::note_previous_declaration); NewFD->setInvalidDecl(); @@ -9682,7 +9715,7 @@ static bool CheckMultiVersionAdditionalDecl( TargetAttr::ParsedTargetAttr NewParsed; if (NewTA) { NewParsed = NewTA->parse(); - llvm::sort(NewParsed.Features.begin(), NewParsed.Features.end()); + llvm::sort(NewParsed.Features); } bool UseMemberUsingDeclRules = @@ -9697,7 +9730,7 @@ static bool CheckMultiVersionAdditionalDecl( if (S.IsOverload(NewFD, CurFD, UseMemberUsingDeclRules)) continue; - if (NewMVType == MultiVersioning::Target) { + if (NewMVType == MultiVersionKind::Target) { const auto *CurTA = CurFD->getAttr<TargetAttr>(); if (CurTA->getFeaturesStr() == NewTA->getFeaturesStr()) { NewFD->setIsMultiVersion(); @@ -9720,7 +9753,7 @@ static bool CheckMultiVersionAdditionalDecl( // Handle CPUDispatch/CPUSpecific versions. // Only 1 CPUDispatch function is allowed, this will make it go through // the redeclaration errors. - if (NewMVType == MultiVersioning::CPUDispatch && + if (NewMVType == MultiVersionKind::CPUDispatch && CurFD->hasAttr<CPUDispatchAttr>()) { if (CurCPUDisp->cpus_size() == NewCPUDisp->cpus_size() && std::equal( @@ -9741,7 +9774,7 @@ static bool CheckMultiVersionAdditionalDecl( NewFD->setInvalidDecl(); return true; } - if (NewMVType == MultiVersioning::CPUSpecific && CurCPUSpec) { + if (NewMVType == MultiVersionKind::CPUSpecific && CurCPUSpec) { if (CurCPUSpec->cpus_size() == NewCPUSpec->cpus_size() && std::equal( @@ -9777,17 +9810,27 @@ static bool CheckMultiVersionAdditionalDecl( // Else, this is simply a non-redecl case. Checking the 'value' is only // necessary in the Target case, since The CPUSpecific/Dispatch cases are // handled in the attribute adding step. - if (NewMVType == MultiVersioning::Target && + if (NewMVType == MultiVersionKind::Target && CheckMultiVersionValue(S, NewFD)) { NewFD->setInvalidDecl(); return true; } - if (CheckMultiVersionAdditionalRules(S, OldFD, NewFD, false, NewMVType)) { + if (CheckMultiVersionAdditionalRules(S, OldFD, NewFD, + !OldFD->isMultiVersion(), NewMVType)) { NewFD->setInvalidDecl(); return true; } + // Permit forward declarations in the case where these two are compatible. + if (!OldFD->isMultiVersion()) { + OldFD->setIsMultiVersion(); + NewFD->setIsMultiVersion(); + Redeclaration = true; + OldDecl = OldFD; + return false; + } + NewFD->setIsMultiVersion(); Redeclaration = false; MergeTypeWithPrevious = false; @@ -9819,14 +9862,14 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, return true; } - MultiVersioning::Type MVType = getMultiVersionType(NewFD); + MultiVersionKind MVType = NewFD->getMultiVersionKind(); // Main isn't allowed to become a multiversion function, however it IS // permitted to have 'main' be marked with the 'target' optimization hint. if (NewFD->isMain()) { - if ((MVType == MultiVersioning::Target && NewTA->isDefaultVersion()) || - MVType == MultiVersioning::CPUDispatch || - MVType == MultiVersioning::CPUSpecific) { + if ((MVType == MultiVersionKind::Target && NewTA->isDefaultVersion()) || + MVType == MultiVersionKind::CPUDispatch || + MVType == MultiVersionKind::CPUSpecific) { S.Diag(NewFD->getLocation(), diag::err_multiversion_not_allowed_on_main); NewFD->setInvalidDecl(); return true; @@ -9839,7 +9882,7 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, NewFD->getDeclContext()->getRedeclContext()) { // If there's no previous declaration, AND this isn't attempting to cause // multiversioning, this isn't an error condition. - if (MVType == MultiVersioning::None) + if (MVType == MultiVersionKind::None) return false; return CheckMultiVersionFirstFunction(S, NewFD, MVType, NewTA, NewCPUDisp, NewCPUSpec); @@ -9847,29 +9890,21 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, FunctionDecl *OldFD = OldDecl->getAsFunction(); - if (!OldFD->isMultiVersion() && MVType == MultiVersioning::None) + if (!OldFD->isMultiVersion() && MVType == MultiVersionKind::None) return false; - if (OldFD->isMultiVersion() && MVType == MultiVersioning::None) { + if (OldFD->isMultiVersion() && MVType == MultiVersionKind::None) { S.Diag(NewFD->getLocation(), diag::err_multiversion_required_in_redecl) - << (getMultiVersionType(OldFD) != MultiVersioning::Target); + << (OldFD->getMultiVersionKind() != MultiVersionKind::Target); NewFD->setInvalidDecl(); return true; } // Handle the target potentially causes multiversioning case. - if (!OldFD->isMultiVersion() && MVType == MultiVersioning::Target) + if (!OldFD->isMultiVersion() && MVType == MultiVersionKind::Target) return CheckTargetCausesMultiVersioning(S, OldFD, NewFD, NewTA, Redeclaration, OldDecl, MergeTypeWithPrevious, Previous); - // Previous declarations lack CPUDispatch/CPUSpecific. - if (!OldFD->isMultiVersion()) { - S.Diag(OldFD->getLocation(), diag::err_multiversion_required_in_redecl) - << 1; - S.Diag(NewFD->getLocation(), diag::note_multiversioning_caused_here); - NewFD->setInvalidDecl(); - return true; - } // At this point, we have a multiversion function decl (in OldFD) AND an // appropriate attribute in the current function decl. Resolve that these are @@ -9982,7 +10017,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD); if (!getLangOpts().CPlusPlus14 && MD && MD->isConstexpr() && !MD->isStatic() && !isa<CXXConstructorDecl>(MD) && - (MD->getTypeQualifiers() & Qualifiers::Const) == 0) { + !MD->getTypeQualifiers().hasConst()) { CXXMethodDecl *OldMD = nullptr; if (OldDecl) OldMD = dyn_cast_or_null<CXXMethodDecl>(OldDecl->getAsFunction()); @@ -9990,7 +10025,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>(); FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); - EPI.TypeQuals |= Qualifiers::Const; + EPI.TypeQuals.addConst(); MD->setType(Context.getFunctionType(FPT->getReturnType(), FPT->getParamTypes(), EPI)); @@ -10022,11 +10057,17 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, if (FunctionTemplateDecl *OldTemplateDecl = dyn_cast<FunctionTemplateDecl>(OldDecl)) { auto *OldFD = OldTemplateDecl->getTemplatedDecl(); - NewFD->setPreviousDeclaration(OldFD); - adjustDeclContextForDeclaratorDecl(NewFD, OldFD); FunctionTemplateDecl *NewTemplateDecl = NewFD->getDescribedFunctionTemplate(); assert(NewTemplateDecl && "Template/non-template mismatch"); + + // The call to MergeFunctionDecl above may have created some state in + // NewTemplateDecl that needs to be merged with OldTemplateDecl before we + // can add it as a redeclaration. + NewTemplateDecl->mergePrevDecl(OldTemplateDecl); + + NewFD->setPreviousDeclaration(OldFD); + adjustDeclContextForDeclaratorDecl(NewFD, OldFD); if (NewFD->isCXXClassMember()) { NewFD->setAccess(OldTemplateDecl->getAccess()); NewTemplateDecl->setAccess(OldTemplateDecl->getAccess()); @@ -10116,7 +10157,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, // 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) + Diag(Guide->getBeginLoc(), diag::err_deduction_guide_specialized) << /*explicit specialization*/ 1; } @@ -10479,7 +10520,7 @@ namespace { Expr *Base = E; bool ReferenceField = false; - // Get the field memebers used. + // Get the field members used. while (MemberExpr *ME = dyn_cast<MemberExpr>(Base)) { FieldDecl *FD = dyn_cast<FieldDecl>(ME->getMemberDecl()); if (!FD) @@ -10719,11 +10760,10 @@ namespace { return; } - S.DiagRuntimeBehavior(DRE->getLocStart(), DRE, + S.DiagRuntimeBehavior(DRE->getBeginLoc(), DRE, S.PDiag(diag) - << DRE->getDecl() - << OrigDecl->getLocation() - << DRE->getSourceRange()); + << DRE->getDecl() << OrigDecl->getLocation() + << DRE->getSourceRange()); } }; @@ -10768,7 +10808,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl, DeclarationName Name, QualType Type, TypeSourceInfo *TSI, SourceRange Range, bool DirectInit, - Expr *Init) { + Expr *&Init) { bool IsInitCapture = !VDecl; assert((!VDecl || !VDecl->isInitCapture()) && "init captures are expected to be deduced prior to initialization"); @@ -10822,7 +10862,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl, if (DeduceInits.empty()) { // It isn't possible to write this directly, but it is possible to // end up in this situation with "auto x(some_pack...);" - Diag(Init->getLocStart(), IsInitCapture + Diag(Init->getBeginLoc(), IsInitCapture ? diag::err_init_capture_no_expression : diag::err_auto_var_init_no_expression) << VN << Type << Range; @@ -10830,7 +10870,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl, } if (DeduceInits.size() > 1) { - Diag(DeduceInits[1]->getLocStart(), + Diag(DeduceInits[1]->getBeginLoc(), IsInitCapture ? diag::err_init_capture_multiple_expressions : diag::err_auto_var_init_multiple_expressions) << VN << Type << Range; @@ -10839,7 +10879,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl, Expr *DeduceInit = DeduceInits[0]; if (DirectInit && isa<InitListExpr>(DeduceInit)) { - Diag(Init->getLocStart(), IsInitCapture + Diag(Init->getBeginLoc(), IsInitCapture ? diag::err_init_capture_paren_braces : diag::err_auto_var_init_paren_braces) << isa<InitListExpr>(Init) << VN << Type << Range; @@ -10884,7 +10924,8 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl, << (DeduceInit->getType().isNull() ? TSI->getType() : DeduceInit->getType()) << DeduceInit->getSourceRange(); - } + } else + Init = DeduceInit; // Warn if we deduced 'id'. 'auto' usually implies type-safety, but using // 'id' instead of a specific object type prevents most of our usual @@ -10901,7 +10942,7 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl, } bool Sema::DeduceVariableDeclarationType(VarDecl *VDecl, bool DirectInit, - Expr *Init) { + Expr *&Init) { QualType DeducedType = deduceVarTypeFromInitializer( VDecl, VDecl->getDeclName(), VDecl->getType(), VDecl->getTypeSourceInfo(), VDecl->getSourceRange(), DirectInit, Init); @@ -11144,7 +11185,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { if ((VDecl->getType().getObjCLifetime() == Qualifiers::OCL_Strong || VDecl->getType().isNonWeakInMRRWithObjCWeak(Context)) && !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, - Init->getLocStart())) + Init->getBeginLoc())) FSI->markSafeWeakUse(Init); } @@ -11159,9 +11200,9 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { // struct T { S a, b; } t = { Temp(), Temp() } // // we should destroy the first Temp before constructing the second. - ExprResult Result = ActOnFinishFullExpr(Init, VDecl->getLocation(), - false, - VDecl->isConstexpr()); + ExprResult Result = + ActOnFinishFullExpr(Init, VDecl->getLocation(), + /*DiscardedValue*/ false, VDecl->isConstexpr()); if (Result.isInvalid()) { VDecl->setInvalidDecl(); return; @@ -11276,9 +11317,9 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { Diag(VDecl->getLocation(), diag::ext_in_class_initializer_float_type_cxx11) << DclT << Init->getSourceRange(); - Diag(VDecl->getLocStart(), + Diag(VDecl->getBeginLoc(), diag::note_in_class_initializer_float_type_cxx11) - << FixItHint::CreateInsertion(VDecl->getLocStart(), "constexpr "); + << FixItHint::CreateInsertion(VDecl->getBeginLoc(), "constexpr "); } else { Diag(VDecl->getLocation(), diag::ext_in_class_initializer_float_type) << DclT << Init->getSourceRange(); @@ -11293,8 +11334,8 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { // Suggest adding 'constexpr' in C++11 for literal types. } else if (getLangOpts().CPlusPlus11 && DclT->isLiteralType(Context)) { Diag(VDecl->getLocation(), diag::err_in_class_initializer_literal_type) - << DclT << Init->getSourceRange() - << FixItHint::CreateInsertion(VDecl->getLocStart(), "constexpr "); + << DclT << Init->getSourceRange() + << FixItHint::CreateInsertion(VDecl->getBeginLoc(), "constexpr "); VDecl->setConstexpr(true); } else { @@ -11407,8 +11448,9 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) { return; } + Expr *TmpInit = nullptr; if (Type->isUndeducedType() && - DeduceVariableDeclarationType(Var, false, nullptr)) + DeduceVariableDeclarationType(Var, false, TmpInit)) return; // C++11 [class.static.data]p3: A static data member can be declared with @@ -11708,7 +11750,7 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { // In Objective-C, don't allow jumps past the implicit initialization of a // local retaining variable. - if (getLangOpts().ObjC1 && + if (getLangOpts().ObjC && var->hasLocalStorage()) { switch (var->getType().getObjCLifetime()) { case Qualifiers::OCL_None: @@ -11827,29 +11869,8 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { QualType type = var->getType(); if (type->isDependentType()) return; - // __block variables might require us to capture a copy-initializer. - if (var->hasAttr<BlocksAttr>()) { - // It's currently invalid to ever have a __block variable with an - // array type; should we diagnose that here? - - // Regardless, we don't want to ignore array nesting when - // constructing this copy. - if (type->isStructureOrClassType()) { - EnterExpressionEvaluationContext scope( - *this, ExpressionEvaluationContext::PotentiallyEvaluated); - SourceLocation poi = var->getLocation(); - Expr *varRef =new (Context) DeclRefExpr(var, false, type, VK_LValue, poi); - ExprResult result - = PerformMoveOrCopyInitialization( - InitializedEntity::InitializeBlock(poi, type, false), - var, var->getType(), varRef, /*AllowNRVO=*/true); - if (!result.isInvalid()) { - result = MaybeCreateExprWithCleanups(result); - Expr *init = result.getAs<Expr>(); - Context.setBlockVarCopyInits(var, init); - } - } - } + if (var->hasAttr<BlocksAttr>()) + getCurFunction()->addByrefBlockVar(var); Expr *Init = var->getInit(); bool IsGlobal = GlobalStorage && !var->isStaticLocal(); @@ -11940,6 +11961,49 @@ static bool hasDependentAlignment(VarDecl *VD) { return false; } +/// Check if VD needs to be dllexport/dllimport due to being in a +/// dllexport/import function. +void Sema::CheckStaticLocalForDllExport(VarDecl *VD) { + assert(VD->isStaticLocal()); + + auto *FD = dyn_cast_or_null<FunctionDecl>(VD->getParentFunctionOrMethod()); + + // Find outermost function when VD is in lambda function. + while (FD && !getDLLAttr(FD) && + !FD->hasAttr<DLLExportStaticLocalAttr>() && + !FD->hasAttr<DLLImportStaticLocalAttr>()) { + FD = dyn_cast_or_null<FunctionDecl>(FD->getParentFunctionOrMethod()); + } + + if (!FD) + return; + + // Static locals inherit dll attributes from their function. + if (Attr *A = getDLLAttr(FD)) { + auto *NewAttr = cast<InheritableAttr>(A->clone(getASTContext())); + NewAttr->setInherited(true); + VD->addAttr(NewAttr); + } else if (Attr *A = FD->getAttr<DLLExportStaticLocalAttr>()) { + auto *NewAttr = ::new (getASTContext()) DLLExportAttr(A->getRange(), + getASTContext(), + A->getSpellingListIndex()); + NewAttr->setInherited(true); + VD->addAttr(NewAttr); + + // Export this function to enforce exporting this static variable even + // if it is not used in this compilation unit. + if (!FD->hasAttr<DLLExportAttr>()) + FD->addAttr(NewAttr); + + } else if (Attr *A = FD->getAttr<DLLImportStaticLocalAttr>()) { + auto *NewAttr = ::new (getASTContext()) DLLImportAttr(A->getRange(), + getASTContext(), + A->getSpellingListIndex()); + NewAttr->setInherited(true); + VD->addAttr(NewAttr); + } +} + /// FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform /// any semantic actions necessary after any initializer has been attached. void Sema::FinalizeDeclaration(Decl *ThisDecl) { @@ -11993,14 +12057,9 @@ void Sema::FinalizeDeclaration(Decl *ThisDecl) { } if (VD->isStaticLocal()) { - if (FunctionDecl *FD = - dyn_cast_or_null<FunctionDecl>(VD->getParentFunctionOrMethod())) { - // Static locals inherit dll attributes from their function. - if (Attr *A = getDLLAttr(FD)) { - auto *NewAttr = cast<InheritableAttr>(A->clone(getASTContext())); - NewAttr->setInherited(true); - VD->addAttr(NewAttr); - } + CheckStaticLocalForDllExport(VD); + + if (dyn_cast_or_null<FunctionDecl>(VD->getParentFunctionOrMethod())) { // CUDA 8.0 E.3.9.4: Within the body of a __device__ or __global__ // function, only __shared__ variables or variables without any device // memory qualifiers may be declared with static storage class. @@ -12375,11 +12434,9 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { // Temporarily put parameter variables in the translation unit, not // the enclosing context. This prevents them from accidentally // looking like class members in C++. - ParmVarDecl *New = CheckParameter(Context.getTranslationUnitDecl(), - D.getLocStart(), - D.getIdentifierLoc(), II, - parmDeclType, TInfo, - SC); + ParmVarDecl *New = + CheckParameter(Context.getTranslationUnitDecl(), D.getBeginLoc(), + D.getIdentifierLoc(), II, parmDeclType, TInfo, SC); if (D.isInvalidType()) New->setInvalidDecl(); @@ -12508,7 +12565,7 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc, // passed by reference. if (T->isObjCObjectType()) { SourceLocation TypeEndLoc = - getLocForEndOfToken(TSInfo->getTypeLoc().getLocEnd()); + getLocForEndOfToken(TSInfo->getTypeLoc().getEndLoc()); Diag(NameLoc, diag::err_object_cannot_be_passed_returned_by_value) << 1 << T << FixItHint::CreateInsertion(TypeEndLoc, "*"); @@ -12682,6 +12739,29 @@ Sema::CheckForFunctionRedefinition(FunctionDecl *FD, } } } + + if (!Definition) + // Similar to friend functions a friend function template may be a + // definition and do not have a body if it is instantiated in a class + // template. + if (FunctionTemplateDecl *FTD = FD->getDescribedFunctionTemplate()) { + for (auto I : FTD->redecls()) { + auto D = cast<FunctionTemplateDecl>(I); + if (D != FTD) { + assert(!D->isThisDeclarationADefinition() && + "More than one definition in redeclaration chain"); + if (D->getFriendObjectKind() != Decl::FOK_None) + if (FunctionTemplateDecl *FT = + D->getInstantiatedFromMemberTemplate()) { + if (FT->isThisDeclarationADefinition()) { + Definition = D->getTemplatedDecl(); + break; + } + } + } + } + } + if (!Definition) return; @@ -12701,6 +12781,7 @@ Sema::CheckForFunctionRedefinition(FunctionDecl *FD, Definition->getDescribedFunctionTemplate() || Definition->getNumTemplateParameterLists())) { SkipBody->ShouldSkip = true; + SkipBody->Previous = const_cast<FunctionDecl*>(Definition); if (auto *TD = Definition->getDescribedFunctionTemplate()) makeMergedDefinitionVisible(TD); makeMergedDefinitionVisible(const_cast<FunctionDecl*>(Definition)); @@ -12772,6 +12853,7 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D, // Parsing the function declaration failed in some way. Push on a fake scope // anyway so we can try to parse the function body. PushFunctionScope(); + PushExpressionEvaluationContext(ExprEvalContexts.back().Context); return D; } @@ -12782,6 +12864,11 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D, else FD = cast<FunctionDecl>(D); + // Do not push if it is a lambda because one is already pushed when building + // the lambda in ActOnStartOfLambdaDefinition(). + if (!isLambdaCallOperator(FD)) + PushExpressionEvaluationContext(ExprEvalContexts.back().Context); + // 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; @@ -12990,6 +13077,21 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *D, Stmt *BodyArg) { return ActOnFinishFunctionBody(D, BodyArg, false); } +/// RAII object that pops an ExpressionEvaluationContext when exiting a function +/// body. +class ExitFunctionBodyRAII { +public: + ExitFunctionBodyRAII(Sema &S, bool IsLambda) : S(S), IsLambda(IsLambda) {} + ~ExitFunctionBodyRAII() { + if (!IsLambda) + S.PopExpressionEvaluationContext(); + } + +private: + Sema &S; + bool IsLambda = false; +}; + Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, bool IsInstantiation) { FunctionDecl *FD = dcl ? dcl->getAsFunction() : nullptr; @@ -13000,6 +13102,11 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, if (getLangOpts().CoroutinesTS && getCurFunction()->isCoroutine()) CheckCompletedCoroutineBody(FD, Body); + // Do not call PopExpressionEvaluationContext() if it is a lambda because one + // is already popped when finishing the lambda in BuildLambdaExpr(). This is + // meant to pop the context added in ActOnStartOfFunctionDef(). + ExitFunctionBodyRAII ExitRAII(*this, isLambdaCallOperator(FD)); + if (FD) { FD->setBody(Body); FD->setWillHaveBody(false); @@ -13054,7 +13161,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, if (!FD->isInvalidDecl()) { // Don't diagnose unused parameters of defaulted or deleted functions. - if (!FD->isDeleted() && !FD->isDefaulted()) + if (!FD->isDeleted() && !FD->isDefaulted() && !FD->hasSkippedBody()) DiagnoseUnusedParameters(FD->parameters()); DiagnoseSizeOfParametersAndReturnValue(FD->parameters(), FD->getReturnType(), FD); @@ -13116,7 +13223,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, if (FD->isMultiVersion() && FD->hasAttr<CPUDispatchAttr>() && Body) if (const auto *CmpndBody = dyn_cast<CompoundStmt>(Body)) if (!CmpndBody->body_empty()) - Diag(CmpndBody->body_front()->getLocStart(), + Diag(CmpndBody->body_front()->getBeginLoc(), diag::warn_dispatch_body_ignored); if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) { @@ -13149,7 +13256,8 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, assert(MD == getCurMethodDecl() && "Method parsing confused"); MD->setBody(Body); if (!MD->isInvalidDecl()) { - DiagnoseUnusedParameters(MD->parameters()); + if (!MD->hasSkippedBody()) + DiagnoseUnusedParameters(MD->parameters()); DiagnoseSizeOfParametersAndReturnValue(MD->parameters(), MD->getReturnType(), MD); @@ -13157,8 +13265,8 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, computeNRVO(Body, getCurFunction()); } if (getCurFunction()->ObjCShouldCallSuper) { - Diag(MD->getLocEnd(), diag::warn_objc_missing_super_call) - << MD->getSelector().getAsString(); + Diag(MD->getEndLoc(), diag::warn_objc_missing_super_call) + << MD->getSelector().getAsString(); getCurFunction()->ObjCShouldCallSuper = false; } if (getCurFunction()->ObjCWarnForNoDesignatedInitChain) { @@ -13267,7 +13375,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, if (RegisterVariables) continue; if (!isa<AsmStmt>(S) && !isa<NullStmt>(S)) { - Diag(S->getLocStart(), diag::err_non_asm_stmt_in_naked_function); + Diag(S->getBeginLoc(), diag::err_non_asm_stmt_in_naked_function); Diag(FD->getAttr<NakedAttr>()->getLocation(), diag::note_attribute); FD->setInvalidDecl(); break; @@ -13354,15 +13462,17 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, } // Extension in C99. Legal in C90, but warn about it. - // OpenCL v2.0 s6.9.u - Implicit function declaration is not supported. unsigned diag_id; if (II.getName().startswith("__builtin_")) diag_id = diag::warn_builtin_unknown; - else if (getLangOpts().C99 || getLangOpts().OpenCL) + // OpenCL v2.0 s6.9.u - Implicit function declaration is not supported. + else if (getLangOpts().OpenCL) + diag_id = diag::err_opencl_implicit_function_decl; + else if (getLangOpts().C99) diag_id = diag::ext_implicit_function_decl; else diag_id = diag::warn_implicit_function_decl; - Diag(Loc, diag_id) << &II << getLangOpts().OpenCL; + Diag(Loc, diag_id) << &II; // If we found a prior declaration of this function, don't bother building // another one. We've already pushed that one into scope, so there's nothing @@ -13400,12 +13510,8 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, /*NumParams=*/0, /*EllipsisLoc=*/NoLoc, /*RParenLoc=*/NoLoc, - /*TypeQuals=*/0, /*RefQualifierIsLvalueRef=*/true, /*RefQualifierLoc=*/NoLoc, - /*ConstQualifierLoc=*/NoLoc, - /*VolatileQualifierLoc=*/NoLoc, - /*RestrictQualifierLoc=*/NoLoc, /*MutableLoc=*/NoLoc, EST_None, /*ESpecRange=*/SourceRange(), /*Exceptions=*/nullptr, @@ -13573,11 +13679,9 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T, } // Scope manipulation handled by caller. - TypedefDecl *NewTD = TypedefDecl::Create(Context, CurContext, - D.getLocStart(), - D.getIdentifierLoc(), - D.getIdentifier(), - TInfo); + TypedefDecl *NewTD = + TypedefDecl::Create(Context, CurContext, D.getBeginLoc(), + D.getIdentifierLoc(), D.getIdentifier(), TInfo); // Bail out immediately if we have an invalid declaration. if (D.isInvalidType()) { @@ -13739,76 +13843,106 @@ bool Sema::isAcceptableTagRedeclaration(const TagDecl *Previous, // struct class-key shall be used to refer to a class (clause 9) // declared using the class or struct class-key. TagTypeKind OldTag = Previous->getTagKind(); - if (!isDefinition || !isClassCompatTagKind(NewTag)) - if (OldTag == NewTag) + if (OldTag != NewTag && + !(isClassCompatTagKind(OldTag) && isClassCompatTagKind(NewTag))) + return false; + + // Tags are compatible, but we might still want to warn on mismatched tags. + // Non-class tags can't be mismatched at this point. + if (!isClassCompatTagKind(NewTag)) + return true; + + // Declarations for which -Wmismatched-tags is disabled are entirely ignored + // by our warning analysis. We don't want to warn about mismatches with (eg) + // declarations in system headers that are designed to be specialized, but if + // a user asks us to warn, we should warn if their code contains mismatched + // declarations. + auto IsIgnoredLoc = [&](SourceLocation Loc) { + return getDiagnostics().isIgnored(diag::warn_struct_class_tag_mismatch, + Loc); + }; + if (IsIgnoredLoc(NewTagLoc)) + return true; + + auto IsIgnored = [&](const TagDecl *Tag) { + return IsIgnoredLoc(Tag->getLocation()); + }; + while (IsIgnored(Previous)) { + Previous = Previous->getPreviousDecl(); + if (!Previous) return true; + OldTag = Previous->getTagKind(); + } - if (isClassCompatTagKind(OldTag) && isClassCompatTagKind(NewTag)) { - // Warn about the struct/class tag mismatch. - bool isTemplate = false; - if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Previous)) - isTemplate = Record->getDescribedClassTemplate(); + bool isTemplate = false; + if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Previous)) + isTemplate = Record->getDescribedClassTemplate(); - if (inTemplateInstantiation()) { + if (inTemplateInstantiation()) { + if (OldTag != NewTag) { // 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) << getRedeclDiagFromTagKind(NewTag) << isTemplate << Name << getRedeclDiagFromTagKind(OldTag); + // FIXME: Note previous location? + } + return true; + } + + if (isDefinition) { + // On definitions, check all previous tags and issue a fix-it for each + // one that doesn't match the current tag. + if (Previous->getDefinition()) { + // Don't suggest fix-its for redefinitions. return true; } - if (isDefinition) { - // On definitions, check previous tags and issue a fix-it for each - // one that doesn't match the current tag. - if (Previous->getDefinition()) { - // Don't suggest fix-its for redefinitions. - return true; - } + bool previousMismatch = false; + for (const TagDecl *I : Previous->redecls()) { + if (I->getTagKind() != NewTag) { + // Ignore previous declarations for which the warning was disabled. + if (IsIgnored(I)) + continue; - bool previousMismatch = false; - for (auto I : Previous->redecls()) { - if (I->getTagKind() != NewTag) { - if (!previousMismatch) { - previousMismatch = true; - Diag(NewTagLoc, diag::warn_struct_class_previous_tag_mismatch) - << getRedeclDiagFromTagKind(NewTag) << isTemplate << Name - << getRedeclDiagFromTagKind(I->getTagKind()); - } - Diag(I->getInnerLocStart(), diag::note_struct_class_suggestion) - << getRedeclDiagFromTagKind(NewTag) - << FixItHint::CreateReplacement(I->getInnerLocStart(), - TypeWithKeyword::getTagTypeKindName(NewTag)); + if (!previousMismatch) { + previousMismatch = true; + Diag(NewTagLoc, diag::warn_struct_class_previous_tag_mismatch) + << getRedeclDiagFromTagKind(NewTag) << isTemplate << Name + << getRedeclDiagFromTagKind(I->getTagKind()); } + Diag(I->getInnerLocStart(), diag::note_struct_class_suggestion) + << getRedeclDiagFromTagKind(NewTag) + << FixItHint::CreateReplacement(I->getInnerLocStart(), + TypeWithKeyword::getTagTypeKindName(NewTag)); } - return true; - } - - // Check for a previous definition. If current tag and definition - // are same type, do nothing. If no definition, but disagree with - // with previous tag type, give a warning, but no fix-it. - const TagDecl *Redecl = Previous->getDefinition() ? - Previous->getDefinition() : Previous; - if (Redecl->getTagKind() == NewTag) { - return true; } + return true; + } + // Identify the prevailing tag kind: this is the kind of the definition (if + // there is a non-ignored definition), or otherwise the kind of the prior + // (non-ignored) declaration. + const TagDecl *PrevDef = Previous->getDefinition(); + if (PrevDef && IsIgnored(PrevDef)) + PrevDef = nullptr; + const TagDecl *Redecl = PrevDef ? PrevDef : Previous; + if (Redecl->getTagKind() != NewTag) { Diag(NewTagLoc, diag::warn_struct_class_tag_mismatch) << getRedeclDiagFromTagKind(NewTag) << isTemplate << Name << getRedeclDiagFromTagKind(OldTag); Diag(Redecl->getLocation(), diag::note_previous_use); // If there is a previous definition, suggest a fix-it. - if (Previous->getDefinition()) { - Diag(NewTagLoc, diag::note_struct_class_suggestion) - << getRedeclDiagFromTagKind(Redecl->getTagKind()) - << FixItHint::CreateReplacement(SourceRange(NewTagLoc), - TypeWithKeyword::getTagTypeKindName(Redecl->getTagKind())); + if (PrevDef) { + Diag(NewTagLoc, diag::note_struct_class_suggestion) + << getRedeclDiagFromTagKind(Redecl->getTagKind()) + << FixItHint::CreateReplacement(SourceRange(NewTagLoc), + TypeWithKeyword::getTagTypeKindName(Redecl->getTagKind())); } - - return true; } - return false; + + return true; } /// Add a minimal nested name specifier fixit hint to allow lookup of a tag name @@ -14031,7 +14165,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // many points during the parsing of a struct declaration (because // the #pragma tokens are effectively skipped over during the // parsing of the struct). - if (TUK == TUK_Definition) { + if (TUK == TUK_Definition && (!SkipBody || !SkipBody->ShouldSkip)) { AddAlignmentAttributesForRecord(RD); AddMsStructLayoutForRecord(RD); } @@ -14462,12 +14596,15 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // comparison. SkipBody->CheckSameAsPrevious = true; SkipBody->New = createTagFromNewDecl(); - SkipBody->Previous = Hidden; + SkipBody->Previous = Def; + return Def; } else { SkipBody->ShouldSkip = true; + SkipBody->Previous = Def; makeMergedDefinitionVisible(Hidden); + // Carry on and handle it like a normal definition. We'll + // skip starting the definitiion later. } - return Def; } else if (!IsExplicitSpecializationAfterInstantiation) { // A redeclaration in function prototype scope in C isn't // visible elsewhere, so merely issue a warning. @@ -14606,7 +14743,7 @@ CreateNewDecl: // If this is an undefined enum, warn. if (TUK != TUK_Definition && !Invalid) { TagDecl *Def; - if (IsFixed && (getLangOpts().CPlusPlus11 || getLangOpts().ObjC2) && + if (IsFixed && (getLangOpts().CPlusPlus11 || getLangOpts().ObjC) && cast<EnumDecl>(New)->isFixed()) { // C++0x: 7.2p2: opaque-enum-declaration. // Conflicts are diagnosed above. Do nothing. @@ -14696,7 +14833,7 @@ CreateNewDecl: // many points during the parsing of a struct declaration (because // the #pragma tokens are effectively skipped over during the // parsing of the struct). - if (TUK == TUK_Definition) { + if (TUK == TUK_Definition && (!SkipBody || !SkipBody->ShouldSkip)) { AddAlignmentAttributesForRecord(RD); AddMsStructLayoutForRecord(RD); } @@ -14758,7 +14895,7 @@ CreateNewDecl: if (PrevDecl) CheckRedeclarationModuleOwnership(New, PrevDecl); - if (TUK == TUK_Definition) + if (TUK == TUK_Definition && (!SkipBody || !SkipBody->ShouldSkip)) New->startDefinition(); ProcessDeclAttributeList(S, New, Attrs); @@ -14808,6 +14945,8 @@ CreateNewDecl: if (auto RD = dyn_cast<RecordDecl>(New)) RD->completeDefinition(); return nullptr; + } else if (SkipBody && SkipBody->ShouldSkip) { + return SkipBody->Previous; } else { return New; } @@ -14868,12 +15007,11 @@ void Sema::ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagD, // class itself; this is known as the injected-class-name. For // purposes of access checking, the injected-class-name is treated // as if it were a public member name. - CXXRecordDecl *InjectedClassName - = CXXRecordDecl::Create(Context, Record->getTagKind(), CurContext, - Record->getLocStart(), Record->getLocation(), - Record->getIdentifier(), - /*PrevDecl=*/nullptr, - /*DelayTypeCreation=*/true); + CXXRecordDecl *InjectedClassName = CXXRecordDecl::Create( + Context, Record->getTagKind(), CurContext, Record->getBeginLoc(), + Record->getLocation(), Record->getIdentifier(), + /*PrevDecl=*/nullptr, + /*DelayTypeCreation=*/true); Context.getTypeDeclType(InjectedClassName, Record); InjectedClassName->setImplicit(); InjectedClassName->setAccess(AS_public); @@ -15080,22 +15218,6 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record, } } - // TR 18037 does not allow fields to be declared with address spaces. - if (T.getQualifiers().hasAddressSpace() || - T->isDependentAddressSpaceType() || - T->getBaseElementTypeUnsafe()->isDependentAddressSpaceType()) { - Diag(Loc, diag::err_field_with_address_space); - D.setInvalidType(); - } - - // OpenCL v1.2 s6.9b,r & OpenCL v2.0 s6.12.5 - The following types cannot be - // used as structure or union field: image, sampler, event or block types. - if (LangOpts.OpenCL && (T->isEventT() || T->isImageType() || - T->isSamplerT() || T->isBlockPointerType())) { - Diag(Loc, diag::err_opencl_type_struct_or_union_field) << T; - D.setInvalidType(); - } - DiagnoseFunctionSpecifiers(D.getDeclSpec()); if (D.getDeclSpec().isInlineSpecified()) @@ -15140,7 +15262,7 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record, bool Mutable = (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_mutable); - SourceLocation TSSL = D.getLocStart(); + SourceLocation TSSL = D.getBeginLoc(); FieldDecl *NewFD = CheckFieldDecl(II, T, TInfo, Record, Loc, Mutable, BitWidth, InitStyle, TSSL, AS, PrevDecl, &D); @@ -15207,12 +15329,30 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, } } - // OpenCL v1.2 s6.9.c: bitfields are not supported. - if (BitWidth && getLangOpts().OpenCL) { - Diag(Loc, diag::err_opencl_bitfields); + // TR 18037 does not allow fields to be declared with address space + if (T.getQualifiers().hasAddressSpace() || T->isDependentAddressSpaceType() || + T->getBaseElementTypeUnsafe()->isDependentAddressSpaceType()) { + Diag(Loc, diag::err_field_with_address_space); + Record->setInvalidDecl(); InvalidDecl = true; } + if (LangOpts.OpenCL) { + // OpenCL v1.2 s6.9b,r & OpenCL v2.0 s6.12.5 - The following types cannot be + // used as structure or union field: image, sampler, event or block types. + if (T->isEventT() || T->isImageType() || T->isSamplerT() || + T->isBlockPointerType()) { + Diag(Loc, diag::err_opencl_type_struct_or_union_field) << T; + Record->setInvalidDecl(); + InvalidDecl = true; + } + // OpenCL v1.2 s6.9.c: bitfields are not supported. + if (BitWidth) { + Diag(Loc, diag::err_opencl_bitfields); + InvalidDecl = true; + } + } + // Anonymous bit-fields cannot be cv-qualified (CWG 2229). if (!InvalidDecl && getLangOpts().CPlusPlus && !II && BitWidth && T.hasQualifiers()) { @@ -15602,6 +15742,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, } RecordDecl *Record = dyn_cast<RecordDecl>(EnclosingDecl); + CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(EnclosingDecl); // Start counting up the number of named members; make sure to include // members of anonymous structs and unions in the total. @@ -15691,9 +15832,8 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, // virtual bases after the derived members. This would make a flexible // array member declared at the end of an object not adjacent to the end // of the type. - if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Record)) - if (RD->getNumVBases() != 0) - Diag(FD->getLocation(), diag::err_flexible_array_virtual_base) + if (CXXRecord && CXXRecord->getNumVBases() != 0) + Diag(FD->getLocation(), diag::err_flexible_array_virtual_base) << FD->getDeclName() << Record->getTagKind(); if (!getLangOpts().C99) Diag(FD->getLocation(), diag::ext_c99_flexible_array_member) @@ -15784,7 +15924,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, } ObjCFieldLifetimeErrReported = true; } - } else if (getLangOpts().ObjC1 && + } else if (getLangOpts().ObjC && getLangOpts().getGC() != LangOptions::NonGC && Record && !Record->hasObjectMember()) { if (FD->getType()->isObjCObjectPointerType() || @@ -15831,7 +15971,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, // Okay, we successfully defined 'Record'. if (Record) { bool Completed = false; - if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(Record)) { + if (CXXRecord) { if (!CXXRecord->isInvalidDecl()) { // Set access bits correctly on the directly-declared conversions. for (CXXRecordDecl::conversion_iterator @@ -15841,13 +15981,6 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, } if (!CXXRecord->isDependentType()) { - if (CXXRecord->hasUserDeclaredDestructor()) { - // Adjust user-defined destructor exception spec. - if (getLangOpts().CPlusPlus11) - AdjustDestructorExceptionSpec(CXXRecord, - CXXRecord->getDestructor()); - } - // Add any implicitly-declared members to this class. AddImplicitlyDeclaredMembersToClass(CXXRecord); @@ -15902,7 +16035,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, ProcessDeclAttributeList(S, Record, Attrs); // We may have deferred checking for a deleted destructor. Check now. - if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(Record)) { + if (CXXRecord) { auto *Dtor = CXXRecord->getDestructor(); if (Dtor && Dtor->isImplicit() && ShouldDeleteSpecialMember(Dtor, CXXDestructor)) { @@ -16289,8 +16422,10 @@ Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst, // Verify that there isn't already something declared with this name in this // scope. - NamedDecl *PrevDecl = LookupSingleName(S, Id, IdLoc, LookupOrdinaryName, - ForVisibleRedeclaration); + LookupResult R(*this, Id, IdLoc, LookupOrdinaryName, ForVisibleRedeclaration); + LookupName(R, S); + NamedDecl *PrevDecl = R.getAsSingle<NamedDecl>(); + if (PrevDecl && PrevDecl->isTemplateParameter()) { // Maybe we will complain about the shadowed template parameter. DiagnoseTemplateParameterShadow(IdLoc, PrevDecl); @@ -16313,6 +16448,11 @@ Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst, return nullptr; if (PrevDecl) { + if (!TheEnumDecl->isScoped() && isa<ValueDecl>(PrevDecl)) { + // Check for other kinds of shadowing not already handled. + CheckShadow(New, PrevDecl, R); + } + // When in C++, we may get a TagDecl with the same name; in this case the // enum constant will 'hide' the tag. assert((getLangOpts().CPlusPlus || !isa<TagDecl>(PrevDecl)) && @@ -16399,7 +16539,7 @@ static void CheckForDuplicateEnumValues(Sema &S, ArrayRef<Decl *> Elements, typedef SmallVector<std::unique_ptr<ECDVector>, 3> DuplicatesVector; typedef llvm::PointerUnion<EnumConstantDecl*, ECDVector*> DeclOrVector; - typedef llvm::DenseMap<int64_t, DeclOrVector> ValueToVectorMap; + typedef std::unordered_map<int64_t, DeclOrVector> ValueToVectorMap; // Use int64_t as a key to avoid needing special handling for DenseMap keys. auto EnumConstantToKey = [](const EnumConstantDecl *D) { @@ -16570,7 +16710,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, NumNegativeBits = std::max(NumNegativeBits, (unsigned)InitVal.getMinSignedBits()); - // Keep track of whether every enum element has type int (very commmon). + // Keep track of whether every enum element has type int (very common). if (AllElementsInt) AllElementsInt = ECD->getType() == Context.IntTy; } @@ -16776,7 +16916,7 @@ static void checkModuleImportContext(Sema &S, Module *M, switch (LSD->getLanguage()) { case LinkageSpecDecl::lang_c: if (ExternCLoc.isInvalid()) - ExternCLoc = LSD->getLocStart(); + ExternCLoc = LSD->getBeginLoc(); break; case LinkageSpecDecl::lang_cxx: break; @@ -16792,8 +16932,9 @@ static void checkModuleImportContext(Sema &S, Module *M, ? diag::ext_module_import_not_at_top_level_noop : diag::err_module_import_not_at_top_level_fatal) << M->getFullModuleName() << DC; - S.Diag(cast<Decl>(DC)->getLocStart(), - diag::note_module_import_not_at_top_level) << DC; + S.Diag(cast<Decl>(DC)->getBeginLoc(), + diag::note_module_import_not_at_top_level) + << DC; } else if (!M->IsExternC && ExternCLoc.isValid()) { S.Diag(ImportLoc, diag::ext_module_import_in_extern_c) << M->getFullModuleName(); @@ -16830,6 +16971,10 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDecl(SourceLocation StartLoc, case LangOptions::CMK_ModuleMap: Diag(ModuleLoc, diag::err_module_decl_in_module_map_module); return nullptr; + + case LangOptions::CMK_HeaderModule: + Diag(ModuleLoc, diag::err_module_decl_in_header_module); + return nullptr; } assert(ModuleScopes.size() == 1 && "expected to be at global module scope"); @@ -16898,7 +17043,8 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDecl(SourceLocation StartLoc, case ModuleDeclKind::Implementation: std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc( PP.getIdentifierInfo(ModuleName), Path[0].second); - Mod = getModuleLoader().loadModule(ModuleLoc, Path, Module::AllVisible, + Mod = getModuleLoader().loadModule(ModuleLoc, {ModuleNameLoc}, + Module::AllVisible, /*IsIncludeDirective=*/false); if (!Mod) { Diag(ModuleLoc, diag::err_module_not_defined) << ModuleName; @@ -16928,6 +17074,19 @@ Sema::DeclGroupPtrTy Sema::ActOnModuleDecl(SourceLocation StartLoc, DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc, SourceLocation ImportLoc, ModuleIdPath Path) { + // Flatten the module path for a Modules TS module name. + std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc; + if (getLangOpts().ModulesTS) { + std::string ModuleName; + for (auto &Piece : Path) { + if (!ModuleName.empty()) + ModuleName += "."; + ModuleName += Piece.first->getName(); + } + ModuleNameLoc = {PP.getIdentifierInfo(ModuleName), Path[0].second}; + Path = ModuleIdPath(ModuleNameLoc); + } + Module *Mod = getModuleLoader().loadModule(ImportLoc, Path, Module::AllVisible, /*IsIncludeDirective=*/false); |