diff options
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
| -rw-r--r-- | lib/Sema/SemaDecl.cpp | 1443 | 
1 files changed, 1070 insertions, 373 deletions
| diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index a1fc725f8df4..55542828f783 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -115,7 +115,7 @@ class TypeNameValidatorCCC : public CorrectionCandidateCallback {  } // end anonymous namespace -/// \brief Determine whether the token kind starts a simple-type-specifier. +/// Determine whether the token kind starts a simple-type-specifier.  bool Sema::isSimpleTypeSpecifier(tok::TokenKind Kind) const {    switch (Kind) {    // FIXME: Take into account the current language when deciding whether a @@ -148,6 +148,9 @@ bool Sema::isSimpleTypeSpecifier(tok::TokenKind Kind) const {    case tok::kw_decltype:      return getLangOpts().CPlusPlus; +  case tok::kw_char8_t: +    return getLangOpts().Char8; +    default:      break;    } @@ -163,7 +166,7 @@ enum class UnqualifiedTypeNameLookupResult {  };  } // end anonymous namespace -/// \brief Tries to perform unqualified lookup of the type decls in bases for +/// Tries to perform unqualified lookup of the type decls in bases for  /// dependent class.  /// \return \a NotFound if no any decls is found, \a FoundNotType if found not a  /// type decl, \a FoundType if only type decls are found. @@ -263,7 +266,7 @@ static ParsedType recoverFromTypeInKnownDependentBase(Sema &S,    return S.CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));  } -/// \brief If the identifier refers to a type name within this scope, +/// If the identifier refers to a type name within this scope,  /// return the declaration of that type.  ///  /// This routine performs ordinary name lookup of the identifier II @@ -724,13 +727,7 @@ void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,      if (isTemplateName(S, SS ? *SS : EmptySS, /*hasTemplateKeyword=*/false,                         Name, nullptr, true, TemplateResult,                         MemberOfUnknownSpecialization) == TNK_Type_template) { -      TemplateName TplName = TemplateResult.get(); -      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(); -      } +      diagnoseMissingTemplateArguments(TemplateResult.get(), IILoc);        return;      }    } @@ -763,7 +760,7 @@ void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,    }  } -/// \brief Determine whether the given result set contains either a type name +/// Determine whether the given result set contains either a type name  /// or  static bool isResultTypeOrTemplate(LookupResult &R, const Token &NextToken) {    bool CheckTemplate = R.getSema().getLangOpts().CPlusPlus && @@ -1318,7 +1315,7 @@ void Sema::ActOnExitFunctionContext() {    assert(CurContext && "Popped translation unit!");  } -/// \brief Determine whether we allow overloading of the function +/// Determine whether we allow overloading of the function  /// PrevDecl with another declaration.  ///  /// This routine determines whether overloading is possible, not @@ -1504,7 +1501,7 @@ static void RemoveUsingDecls(LookupResult &R) {    F.done();  } -/// \brief Check for this common pattern: +/// Check for this common pattern:  /// @code  /// class S {  ///   S(const S&); // DO NOT IMPLEMENT @@ -1519,9 +1516,7 @@ static bool IsDisallowedCopyOrAssign(const CXXMethodDecl *D) {    if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(D))      return CD->isCopyConstructor(); -  if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) -    return Method->isCopyAssignmentOperator(); -  return false; +  return D->isCopyAssignmentOperator();  }  // We need this to handle @@ -1843,7 +1838,7 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {    }  } -/// \brief Look for an Objective-C class in the translation unit. +/// Look for an Objective-C class in the translation unit.  ///  /// \param Id The name of the Objective-C class we're looking for. If  /// typo-correction fixes this name, the Id will be updated @@ -1913,7 +1908,7 @@ Scope *Sema::getNonFieldDeclScope(Scope *S) {    return S;  } -/// \brief Looks up the declaration of "struct objc_super" and +/// Looks up the declaration of "struct objc_super" and  /// saves it for later use in building builtin declaration of  /// objc_msgSendSuper and objc_msgSendSuper_stret. If no such  /// pre-existing declaration exists no action takes place. @@ -2457,6 +2452,9 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D,    else if (const auto *SA = dyn_cast<SectionAttr>(Attr))      NewAttr = S.mergeSectionAttr(D, SA->getRange(), SA->getName(),                                   AttrSpellingListIndex); +  else if (const auto *CSA = dyn_cast<CodeSegAttr>(Attr)) +    NewAttr = S.mergeCodeSegAttr(D, CSA->getRange(), CSA->getName(), +                                 AttrSpellingListIndex);    else if (const auto *IA = dyn_cast<MSInheritanceAttr>(Attr))      NewAttr = S.mergeMSInheritanceAttr(D, IA->getRange(), IA->getBestCase(),                                         AttrSpellingListIndex, @@ -2495,7 +2493,7 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D,    else if (const auto *UA = dyn_cast<UuidAttr>(Attr))      NewAttr = S.mergeUuidAttr(D, UA->getRange(), AttrSpellingListIndex,                                UA->getGuid()); -  else if (Attr->duplicatesAllowed() || !DeclHasAttr(D, Attr)) +  else if (Attr->shouldInheritEvenIfAlreadyPresent() || !DeclHasAttr(D, Attr))      NewAttr = cast<InheritableAttr>(Attr->clone(S.Context));    if (NewAttr) { @@ -2675,6 +2673,15 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old,      }    } +  // Redeclaration adds code-seg attribute. +  const auto *NewCSA = New->getAttr<CodeSegAttr>(); +  if (NewCSA && !Old->hasAttr<CodeSegAttr>() && +      !NewCSA->isImplicit() && isa<CXXMethodDecl>(New)) { +    Diag(New->getLocation(), diag::warn_mismatched_section) +         << 0 /*codeseg*/; +    Diag(Old->getLocation(), diag::note_previous_declaration); +  } +    if (!Old->hasAttrs())      return; @@ -2875,7 +2882,7 @@ static bool haveIncompatibleLanguageLinkages(const T *Old, const T *New) {  template<typename T> static bool isExternC(T *D) { return D->isExternC(); }  static bool isExternC(VarTemplateDecl *) { return false; } -/// \brief Check whether a redeclaration of an entity introduced by a +/// Check whether a redeclaration of an entity introduced by a  /// using-declaration is valid, given that we know it's not an overload  /// (nor a hidden tag declaration).  template<typename ExpectedDecl> @@ -2929,6 +2936,48 @@ static bool hasIdenticalPassObjectSizeAttrs(const FunctionDecl *A,    return std::equal(A->param_begin(), A->param_end(), B->param_begin(), AttrEq);  } +/// If necessary, adjust the semantic declaration context for a qualified +/// declaration to name the correct inline namespace within the qualifier. +static void adjustDeclContextForDeclaratorDecl(DeclaratorDecl *NewD, +                                               DeclaratorDecl *OldD) { +  // The only case where we need to update the DeclContext is when +  // redeclaration lookup for a qualified name finds a declaration +  // in an inline namespace within the context named by the qualifier: +  // +  //   inline namespace N { int f(); } +  //   int ::f(); // Sema DC needs adjusting from :: to N::. +  // +  // For unqualified declarations, the semantic context *can* change +  // along the redeclaration chain (for local extern declarations, +  // extern "C" declarations, and friend declarations in particular). +  if (!NewD->getQualifier()) +    return; + +  // NewD is probably already in the right context. +  auto *NamedDC = NewD->getDeclContext()->getRedeclContext(); +  auto *SemaDC = OldD->getDeclContext()->getRedeclContext(); +  if (NamedDC->Equals(SemaDC)) +    return; + +  assert((NamedDC->InEnclosingNamespaceSetOf(SemaDC) || +          NewD->isInvalidDecl() || OldD->isInvalidDecl()) && +         "unexpected context for redeclaration"); + +  auto *LexDC = NewD->getLexicalDeclContext(); +  auto FixSemaDC = [=](NamedDecl *D) { +    if (!D) +      return; +    D->setDeclContext(SemaDC); +    D->setLexicalDeclContext(LexDC); +  }; + +  FixSemaDC(NewD); +  if (auto *FD = dyn_cast<FunctionDecl>(NewD)) +    FixSemaDC(FD->getDescribedFunctionTemplate()); +  else if (auto *VD = dyn_cast<VarDecl>(NewD)) +    FixSemaDC(VD->getDescribedVarTemplate()); +} +  /// MergeFunctionDecl - We just parsed a function 'New' from  /// declarator D which has the same name and scope as a previous  /// declaration 'Old'.  Figure out how to resolve this situation, @@ -2971,6 +3020,14 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD,    if (Old->isInvalidDecl())      return true; +  // Disallow redeclaration of some builtins. +  if (!getASTContext().canBuiltinBeRedeclared(Old)) { +    Diag(New->getLocation(), diag::err_builtin_redeclare) << Old->getDeclName(); +    Diag(Old->getLocation(), diag::note_previous_builtin_declaration) +        << Old << Old->getType(); +    return true; +  } +    diag::kind PrevDiag;    SourceLocation OldLocation;    std::tie(PrevDiag, OldLocation) = @@ -3518,7 +3575,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD,    return true;  } -/// \brief Completes the merge of two function declarations that are +/// Completes the merge of two function declarations that are  /// known to be compatible.  ///  /// This routine handles the merging of attributes and other @@ -3581,6 +3638,8 @@ void Sema::mergeObjCMethodDecls(ObjCMethodDecl *newMethod,           ni = newMethod->param_begin(), ne = newMethod->param_end();         ni != ne && oi != oe; ++ni, ++oi)      mergeParamDeclAttributes(*ni, *oi, *this); + +  CheckObjCMethodOverride(newMethod, oldMethod);  }  static void diagnoseVarDeclTypeMismatch(Sema &S, VarDecl *New, VarDecl* Old) { @@ -3953,6 +4012,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {    New->setPreviousDecl(Old);    if (NewTemplate)      NewTemplate->setPreviousDecl(OldTemplate); +  adjustDeclContextForDeclaratorDecl(New, Old);    // Inherit access appropriately.    New->setAccess(Old->getAccess()); @@ -4014,7 +4074,8 @@ void Sema::notePreviousDefinition(const NamedDecl *Old, SourceLocation New) {    }    // Redefinition coming from different files or couldn't do better above. -  Diag(Old->getLocation(), diag::note_previous_definition); +  if (Old->getLocation().isValid()) +    Diag(Old->getLocation(), diag::note_previous_definition);  }  /// We've just determined that \p Old and \p New both appear to be definitions @@ -4398,10 +4459,9 @@ Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS,          TypeSpecType == DeclSpec::TST_interface ||          TypeSpecType == DeclSpec::TST_union ||          TypeSpecType == DeclSpec::TST_enum) { -      for (AttributeList* attrs = DS.getAttributes().getList(); attrs; -           attrs = attrs->getNext()) -        Diag(attrs->getLoc(), diag::warn_declspec_attribute_ignored) -            << attrs->getName() << GetDiagnosticTypeSpecifierID(TypeSpecType); +      for (const ParsedAttr &AL : DS.getAttributes()) +        Diag(AL.getLoc(), diag::warn_declspec_attribute_ignored) +            << AL.getName() << GetDiagnosticTypeSpecifierID(TypeSpecType);      }    } @@ -4593,12 +4653,14 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,      unsigned DiagID;      if (Record->isUnion()) {        // C++ [class.union]p6: +      // C++17 [class.union.anon]p2:        //   Anonymous unions declared in a named namespace or in the        //   global namespace shall be declared static. +      DeclContext *OwnerScope = Owner->getRedeclContext();        if (DS.getStorageClassSpec() != DeclSpec::SCS_static && -          (isa<TranslationUnitDecl>(Owner) || -           (isa<NamespaceDecl>(Owner) && -            cast<NamespaceDecl>(Owner)->getDeclName()))) { +          (OwnerScope->isTranslationUnit() || +           (OwnerScope->isNamespace() && +            !cast<NamespaceDecl>(OwnerScope)->isAnonymousNamespace()))) {          Diag(Record->getLocation(), diag::err_anonymous_union_not_static)            << FixItHint::CreateInsertion(Record->getLocation(), "static "); @@ -4746,7 +4808,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,    }    // Mock up a declarator. -  Declarator Dc(DS, Declarator::MemberContext); +  Declarator Dc(DS, DeclaratorContext::MemberContext);    TypeSourceInfo *TInfo = GetTypeForDeclarator(Dc, S);    assert(TInfo && "couldn't build declarator info for anonymous struct/union"); @@ -4843,7 +4905,7 @@ Decl *Sema::BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS,    assert(Record && "expected a record!");    // Mock up a declarator. -  Declarator Dc(DS, Declarator::TypeNameContext); +  Declarator Dc(DS, DeclaratorContext::TypeNameContext);    TypeSourceInfo *TInfo = GetTypeForDeclarator(Dc, S);    assert(TInfo && "couldn't build declarator info for anonymous struct"); @@ -4889,7 +4951,7 @@ DeclarationNameInfo Sema::GetNameForDeclarator(Declarator &D) {    return GetNameFromUnqualifiedId(D.getName());  } -/// \brief Retrieves the declaration name from a parsed unqualified-id. +/// Retrieves the declaration name from a parsed unqualified-id.  DeclarationNameInfo  Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {    DeclarationNameInfo NameInfo; @@ -4897,13 +4959,13 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {    switch (Name.getKind()) { -  case UnqualifiedId::IK_ImplicitSelfParam: -  case UnqualifiedId::IK_Identifier: +  case UnqualifiedIdKind::IK_ImplicitSelfParam: +  case UnqualifiedIdKind::IK_Identifier:      NameInfo.setName(Name.Identifier);      NameInfo.setLoc(Name.StartLocation);      return NameInfo; -  case UnqualifiedId::IK_DeductionGuideName: { +  case UnqualifiedIdKind::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 @@ -4931,7 +4993,7 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {      return NameInfo;    } -  case UnqualifiedId::IK_OperatorFunctionId: +  case UnqualifiedIdKind::IK_OperatorFunctionId:      NameInfo.setName(Context.DeclarationNames.getCXXOperatorName(                                             Name.OperatorFunctionId.Operator));      NameInfo.setLoc(Name.StartLocation); @@ -4941,14 +5003,14 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {        = Name.EndLocation.getRawEncoding();      return NameInfo; -  case UnqualifiedId::IK_LiteralOperatorId: +  case UnqualifiedIdKind::IK_LiteralOperatorId:      NameInfo.setName(Context.DeclarationNames.getCXXLiteralOperatorName(                                                             Name.Identifier));      NameInfo.setLoc(Name.StartLocation);      NameInfo.setCXXLiteralOperatorNameLoc(Name.EndLocation);      return NameInfo; -  case UnqualifiedId::IK_ConversionFunctionId: { +  case UnqualifiedIdKind::IK_ConversionFunctionId: {      TypeSourceInfo *TInfo;      QualType Ty = GetTypeFromParser(Name.ConversionFunctionId, &TInfo);      if (Ty.isNull()) @@ -4960,7 +5022,7 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {      return NameInfo;    } -  case UnqualifiedId::IK_ConstructorName: { +  case UnqualifiedIdKind::IK_ConstructorName: {      TypeSourceInfo *TInfo;      QualType Ty = GetTypeFromParser(Name.ConstructorName, &TInfo);      if (Ty.isNull()) @@ -4972,7 +5034,7 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {      return NameInfo;    } -  case UnqualifiedId::IK_ConstructorTemplateId: { +  case UnqualifiedIdKind::IK_ConstructorTemplateId: {      // In well-formed code, we can only have a constructor      // template-id that refers to the current context, so go there      // to find the actual type being constructed. @@ -4995,7 +5057,7 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {      return NameInfo;    } -  case UnqualifiedId::IK_DestructorName: { +  case UnqualifiedIdKind::IK_DestructorName: {      TypeSourceInfo *TInfo;      QualType Ty = GetTypeFromParser(Name.DestructorName, &TInfo);      if (Ty.isNull()) @@ -5007,7 +5069,7 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {      return NameInfo;    } -  case UnqualifiedId::IK_TemplateId: { +  case UnqualifiedIdKind::IK_TemplateId: {      TemplateName TName = Name.TemplateId->Template.get();      SourceLocation TNameLoc = Name.TemplateId->TemplateNameLoc;      return Context.getNameForTemplate(TName, TNameLoc); @@ -5176,7 +5238,7 @@ bool Sema::DiagnoseClassNameShadow(DeclContext *DC,    return false;  } -/// \brief Diagnose a declaration whose declarator-id has the given +/// Diagnose a declaration whose declarator-id has the given  /// nested-name-specifier.  ///  /// \param SS The nested-name-specifier of the declarator-id. @@ -5188,10 +5250,13 @@ bool Sema::DiagnoseClassNameShadow(DeclContext *DC,  ///  /// \param Loc The location of the name of the entity being declared.  /// +/// \param IsTemplateId Whether the name is a (simple-)template-id, and thus +/// we're declaring an explicit / partial specialization / instantiation. +///  /// \returns true if we cannot safely recover from this error, false otherwise.  bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,                                          DeclarationName Name, -                                        SourceLocation Loc) { +                                        SourceLocation Loc, bool IsTemplateId) {    DeclContext *Cur = CurContext;    while (isa<LinkageSpecDecl>(Cur) || isa<CapturedDecl>(Cur))      Cur = Cur->getParent(); @@ -5218,8 +5283,9 @@ bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,    }    // Check whether the qualifying scope encloses the scope of the original -  // declaration. -  if (!Cur->Encloses(DC)) { +  // declaration. For a template-id, we perform the checks in +  // CheckTemplateSpecializationScope. +  if (!Cur->Encloses(DC) && !IsTemplateId) {      if (Cur->isRecord())        Diag(Loc, diag::err_member_qualification)          << Name << SS.getRange(); @@ -5331,8 +5397,9 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D,        return nullptr;      }      if (!D.getDeclSpec().isFriendSpecified()) { -      if (diagnoseQualifiedDeclaration(D.getCXXScopeSpec(), DC, -                                      Name, D.getIdentifierLoc())) { +      if (diagnoseQualifiedDeclaration( +              D.getCXXScopeSpec(), DC, Name, D.getIdentifierLoc(), +              D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId)) {          if (DC->isRecord())            return nullptr; @@ -5609,7 +5676,7 @@ TryToFixInvalidVariablyModifiedTypeSourceInfo(TypeSourceInfo *TInfo,    return FixedTInfo;  } -/// \brief Register the given locally-scoped extern "C" declaration so +/// Register the given locally-scoped extern "C" declaration so  /// that it can be found later for redeclarations. We include any extern "C"  /// declaration that is not visible in the translation unit here, not just  /// function-scope declarations. @@ -5630,7 +5697,7 @@ NamedDecl *Sema::findLocallyScopedExternCDecl(DeclarationName Name) {    return Result.empty() ? nullptr : *Result.begin();  } -/// \brief Diagnose function specifiers on a declaration of an identifier that +/// Diagnose function specifiers on a declaration of an identifier that  /// does not identify a function.  void Sema::DiagnoseFunctionSpecifiers(const DeclSpec &DS) {    // FIXME: We should probably indicate the identifier in question to avoid @@ -5670,8 +5737,8 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,      Diag(D.getDeclSpec().getConstexprSpecLoc(), diag::err_invalid_constexpr)        << 1; -  if (D.getName().Kind != UnqualifiedId::IK_Identifier) { -    if (D.getName().Kind == UnqualifiedId::IK_DeductionGuideName) +  if (D.getName().Kind != UnqualifiedIdKind::IK_Identifier) { +    if (D.getName().Kind == UnqualifiedIdKind::IK_DeductionGuideName)        Diag(D.getName().StartLocation,             diag::err_deduction_guide_invalid_specifier)            << "typedef"; @@ -5704,7 +5771,7 @@ Sema::CheckTypedefForVariablyModifiedType(Scope *S, TypedefNameDecl *NewTD) {    TypeSourceInfo *TInfo = NewTD->getTypeSourceInfo();    QualType T = TInfo->getType();    if (T->isVariablyModifiedType()) { -    getCurFunction()->setHasBranchProtectedScope(); +    setFunctionHasBranchProtectedScope();      if (S->getFnParent() == nullptr) {        bool SizeIsNegative; @@ -5772,7 +5839,7 @@ Sema::ActOnTypedefNameDecl(Scope *S, DeclContext *DC, TypedefNameDecl *NewTD,    return NewTD;  } -/// \brief Determines whether the given declaration is an out-of-scope +/// Determines whether the given declaration is an out-of-scope  /// previous declaration.  ///  /// This routine should be invoked when name lookup has found a @@ -6148,29 +6215,21 @@ static bool shouldConsiderLinkage(const FunctionDecl *FD) {    llvm_unreachable("Unexpected context");  } -static bool hasParsedAttr(Scope *S, const AttributeList *AttrList, -                          AttributeList::Kind Kind) { -  for (const AttributeList *L = AttrList; L; L = L->getNext()) -    if (L->getKind() == Kind) -      return true; -  return false; -} -  static bool hasParsedAttr(Scope *S, const Declarator &PD, -                          AttributeList::Kind Kind) { +                          ParsedAttr::Kind Kind) {    // Check decl attributes on the DeclSpec. -  if (hasParsedAttr(S, PD.getDeclSpec().getAttributes().getList(), Kind)) +  if (PD.getDeclSpec().getAttributes().hasAttribute(Kind))      return true;    // Walk the declarator structure, checking decl attributes that were in a type    // position to the decl itself.    for (unsigned I = 0, E = PD.getNumTypeObjects(); I != E; ++I) { -    if (hasParsedAttr(S, PD.getTypeObject(I).getAttrs(), Kind)) +    if (PD.getTypeObject(I).getAttrs().hasAttribute(Kind))        return true;    }    // Finally, check attributes on the decl itself. -  return hasParsedAttr(S, PD.getAttributes(), Kind); +  return PD.getAttributes().hasAttribute(Kind);  }  /// Adjust the \c DeclContext for a function or variable that might be a @@ -6197,7 +6256,7 @@ bool Sema::adjustContextForLocalExternDecl(DeclContext *&DC) {    return true;  } -/// \brief Returns true if given declaration has external C language linkage. +/// Returns true if given declaration has external C language linkage.  static bool isDeclExternC(const Decl *D) {    if (const auto *FD = dyn_cast<FunctionDecl>(D))      return FD->isExternC(); @@ -6303,6 +6362,20 @@ NamedDecl *Sema::ActOnVariableDeclarator(          D.setInvalidType();        }      } + +    // OpenCL C++ 1.0 s2.9: the thread_local storage qualifier is not +    // supported.  OpenCL C does not support thread_local either, and +    // also reject all other thread storage class specifiers. +    DeclSpec::TSCS TSC = D.getDeclSpec().getThreadStorageClassSpec(); +    if (TSC != TSCS_unspecified) { +      bool IsCXX = getLangOpts().OpenCLCPlusPlus; +      Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(), +           diag::err_opencl_unknown_type_specifier) +          << IsCXX << getLangOpts().getOpenCLVersionTuple().getAsString() +          << DeclSpec::getSpecifierName(TSC) << 1; +      D.setInvalidType(); +      return nullptr; +    }    }    DeclSpec::SCS SCSpec = D.getDeclSpec().getStorageClassSpec(); @@ -6311,8 +6384,8 @@ NamedDecl *Sema::ActOnVariableDeclarator(    // dllimport globals without explicit storage class are treated as extern. We    // have to change the storage class this early to get the right DeclContext.    if (SC == SC_None && !DC->isRecord() && -      hasParsedAttr(S, D, AttributeList::AT_DLLImport) && -      !hasParsedAttr(S, D, AttributeList::AT_DLLExport)) +      hasParsedAttr(S, D, ParsedAttr::AT_DLLImport) && +      !hasParsedAttr(S, D, ParsedAttr::AT_DLLExport))      SC = SC_Extern;    DeclContext *OriginalDC = DC; @@ -6425,7 +6498,7 @@ NamedDecl *Sema::ActOnVariableDeclarator(      TemplateParams = MatchTemplateParametersToScopeSpecifier(          D.getDeclSpec().getLocStart(), D.getIdentifierLoc(),          D.getCXXScopeSpec(), -        D.getName().getKind() == UnqualifiedId::IK_TemplateId +        D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId              ? D.getName().TemplateId              : nullptr,          TemplateParamLists, @@ -6433,7 +6506,7 @@ NamedDecl *Sema::ActOnVariableDeclarator(      if (TemplateParams) {        if (!TemplateParams->size() && -          D.getName().getKind() != UnqualifiedId::IK_TemplateId) { +          D.getName().getKind() != UnqualifiedIdKind::IK_TemplateId) {          // There is an extraneous 'template<>' for this variable. Complain          // about it, but allow the declaration of the variable.          Diag(TemplateParams->getTemplateLoc(), @@ -6443,7 +6516,7 @@ NamedDecl *Sema::ActOnVariableDeclarator(                           TemplateParams->getRAngleLoc());          TemplateParams = nullptr;        } else { -        if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) { +        if (D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId) {            // This is an explicit specialization or a partial specialization.            // FIXME: Check that we can declare a specialization here.            IsVariableTemplateSpecialization = true; @@ -6464,9 +6537,9 @@ NamedDecl *Sema::ActOnVariableDeclarator(          }        }      } else { -      assert( -          (Invalid || D.getName().getKind() != UnqualifiedId::IK_TemplateId) && -          "should have a 'template<>' for this decl"); +      assert((Invalid || +              D.getName().getKind() != UnqualifiedIdKind::IK_TemplateId) && +             "should have a 'template<>' for this decl");      }      if (IsVariableTemplateSpecialization) { @@ -6842,9 +6915,9 @@ NamedDecl *Sema::ActOnVariableDeclarator(    }    if (D.isRedeclaration() && !Previous.empty()) { -    checkDLLAttributeRedeclaration( -        *this, dyn_cast<NamedDecl>(Previous.getRepresentativeDecl()), NewVD, -        IsMemberSpecialization, D.isFunctionDefinition()); +    NamedDecl *Prev = Previous.getRepresentativeDecl(); +    checkDLLAttributeRedeclaration(*this, Prev, NewVD, IsMemberSpecialization, +                                   D.isFunctionDefinition());    }    if (NewTemplate) { @@ -6887,7 +6960,7 @@ static ShadowedDeclKind computeShadowedDeclKind(const NamedDecl *ShadowedDecl,  /// variable \p VD, or an invalid source location otherwise.  static SourceLocation getCaptureLocation(const LambdaScopeInfo *LSI,                                           const VarDecl *VD) { -  for (const LambdaScopeInfo::Capture &Capture : LSI->Captures) { +  for (const Capture &Capture : LSI->Captures) {      if (Capture.isVariableCapture() && Capture.getVariable() == VD)        return Capture.getLocation();    } @@ -6904,7 +6977,7 @@ static bool shouldWarnIfShadowedDecl(const DiagnosticsEngine &Diags,    return !Diags.isIgnored(diag::warn_decl_shadow, R.getNameLoc());  } -/// \brief Return the declaration shadowed by the given variable \p D, or null +/// 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) { @@ -6921,14 +6994,14 @@ NamedDecl *Sema::getShadowedDeclaration(const VarDecl *D,               : nullptr;  } -/// \brief Return the declaration shadowed by the given typedef \p D, or null +/// 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; @@ -6936,7 +7009,7 @@ NamedDecl *Sema::getShadowedDeclaration(const TypedefNameDecl *D,    return isa<TypedefNameDecl>(ShadowedDecl) ? ShadowedDecl : nullptr;  } -/// \brief Diagnose variable or built-in function shadowing.  Implements +/// Diagnose variable or built-in function shadowing.  Implements  /// -Wshadow.  ///  /// This method is called whenever a VarDecl is added to a "useful" @@ -7067,7 +7140,7 @@ void Sema::DiagnoseShadowingLambdaDecls(const LambdaScopeInfo *LSI) {    }  } -/// \brief Check -Wshadow without the advantage of a previous lookup. +/// Check -Wshadow without the advantage of a previous lookup.  void Sema::CheckShadow(Scope *S, VarDecl *D) {    if (Diags.isIgnored(diag::warn_decl_shadow, D->getLocation()))      return; @@ -7225,8 +7298,7 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {    if (NewVD->isInvalidDecl())      return; -  TypeSourceInfo *TInfo = NewVD->getTypeSourceInfo(); -  QualType T = TInfo->getType(); +  QualType T = NewVD->getType();    // Defer checking an 'auto' type until its initializer is attached.    if (T->isUndeducedType()) @@ -7364,16 +7436,24 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {    bool isVM = T->isVariablyModifiedType();    if (isVM || NewVD->hasAttr<CleanupAttr>() ||        NewVD->hasAttr<BlocksAttr>()) -    getCurFunction()->setHasBranchProtectedScope(); +    setFunctionHasBranchProtectedScope();    if ((isVM && NewVD->hasLinkage()) ||        (T->isVariableArrayType() && NewVD->hasGlobalStorage())) {      bool SizeIsNegative;      llvm::APSInt Oversized; -    TypeSourceInfo *FixedTInfo = -      TryToFixInvalidVariablyModifiedTypeSourceInfo(TInfo, Context, -                                                    SizeIsNegative, Oversized); -    if (!FixedTInfo && T->isVariableArrayType()) { +    TypeSourceInfo *FixedTInfo = TryToFixInvalidVariablyModifiedTypeSourceInfo( +        NewVD->getTypeSourceInfo(), Context, SizeIsNegative, Oversized); +    QualType FixedT; +    if (FixedTInfo &&  T == NewVD->getTypeSourceInfo()->getType()) +      FixedT = FixedTInfo->getType(); +    else if (FixedTInfo) { +      // Type and type-as-written are canonically different. We need to fix up +      // both types separately. +      FixedT = TryToFixInvalidVariablyModifiedType(T, Context, SizeIsNegative, +                                                   Oversized); +    } +    if ((!FixedTInfo || FixedT.isNull()) && T->isVariableArrayType()) {        const VariableArrayType *VAT = Context.getAsVariableArrayType(T);        // FIXME: This won't give the correct result for        // int a[10][n]; @@ -7402,7 +7482,7 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {      }      Diag(NewVD->getLocation(), diag::warn_illegal_constant_array_size); -    NewVD->setType(FixedTInfo->getType()); +    NewVD->setType(FixedT);      NewVD->setTypeSourceInfo(FixedTInfo);    } @@ -7437,7 +7517,7 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {    }  } -/// \brief Perform semantic checking on a newly-created variable +/// Perform semantic checking on a newly-created variable  /// declaration.  ///  /// This routine performs all of the type-checking required for a @@ -7508,8 +7588,8 @@ struct FindOverriddenMethod {  enum OverrideErrorKind { OEK_All, OEK_NonDeleted, OEK_Deleted };  } // end anonymous namespace -/// \brief Report an error regarding overriding, along with any relevant -/// overriden methods. +/// Report an error regarding overriding, along with any relevant +/// overridden methods.  ///  /// \param DiagID the primary error to report.  /// \param MD the overriding method. @@ -7624,7 +7704,7 @@ void Sema::MarkTypoCorrectedFunctionDefinition(const NamedDecl *F) {    TypoCorrectedFunctionDefinitions.insert(F);  } -/// \brief Generate diagnostics for an invalid function redeclaration. +/// Generate diagnostics for an invalid function redeclaration.  ///  /// This routine handles generating the diagnostic messages for an invalid  /// function redeclaration, including finding possible similar declarations @@ -8176,7 +8256,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,                                bool &AddToScope) {    QualType R = TInfo->getType(); -  assert(R.getTypePtr()->isFunctionType()); +  assert(R->isFunctionType());    // TODO: consider using NameInfo for diagnostic.    DeclarationNameInfo NameInfo = GetNameForDeclarator(D); @@ -8261,7 +8341,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,              MatchTemplateParametersToScopeSpecifier(                  D.getDeclSpec().getLocStart(), D.getIdentifierLoc(),                  D.getCXXScopeSpec(), -                D.getName().getKind() == UnqualifiedId::IK_TemplateId +                D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId                      ? D.getName().TemplateId                      : nullptr,                  TemplateParamLists, isFriend, isMemberSpecialization, @@ -8318,7 +8398,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,            // and clearly the user wants a template specialization.  So            // we need to insert '<>' after the name.            SourceLocation InsertLoc; -          if (D.getName().getKind() != UnqualifiedId::IK_TemplateId) { +          if (D.getName().getKind() != UnqualifiedIdKind::IK_TemplateId) {              InsertLoc = D.getName().getSourceRange().getEnd();              InsertLoc = getLocForEndOfToken(InsertLoc);            } @@ -8655,6 +8735,15 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,        NewFD->dropAttr<SectionAttr>();    } +  // Apply an implicit CodeSegAttr from class declspec or +  // apply an implicit SectionAttr from #pragma code_seg if active. +  if (!NewFD->hasAttr<CodeSegAttr>()) { +    if (Attr *SAttr = getImplicitCodeSegOrSectionAttrForFunction(NewFD, +                                                                 D.isFunctionDefinition())) { +      NewFD->addAttr(SAttr); +    } +  } +    // Handle attributes.    ProcessDeclAttributes(S, NewFD, D); @@ -8719,7 +8808,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,      // If the declarator is a template-id, translate the parser's template      // argument list into our AST format. -    if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) { +    if (D.getName().getKind() == UnqualifiedIdKind::IK_TemplateId) {        TemplateIdAnnotation *TemplateId = D.getName().TemplateId;        TemplateArgs.setLAngleLoc(TemplateId->LAngleLoc);        TemplateArgs.setRAngleLoc(TemplateId->RAngleLoc); @@ -8785,10 +8874,6 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,        if (CurContext->isDependentContext() && CurContext->isRecord()            && !isFriend) {          isDependentClassScopeExplicitSpecialization = true; -        Diag(NewFD->getLocation(), getLangOpts().MicrosoftExt ? -          diag::ext_function_specialization_in_class : -          diag::err_function_specialization_in_class) -          << NewFD->getDeclName();        } else if (!NewFD->isInvalidDecl() &&                   CheckFunctionTemplateSpecialization(                       NewFD, (HasExplicitTemplateArgs ? &TemplateArgs : nullptr), @@ -8994,19 +9079,22 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,    NewFD->setRangeEnd(D.getSourceRange().getEnd());    if (D.isRedeclaration() && !Previous.empty()) { -    checkDLLAttributeRedeclaration( -        *this, dyn_cast<NamedDecl>(Previous.getRepresentativeDecl()), NewFD, -        isMemberSpecialization || isFunctionTemplateSpecialization, -        D.isFunctionDefinition()); +    NamedDecl *Prev = Previous.getRepresentativeDecl(); +    checkDLLAttributeRedeclaration(*this, Prev, NewFD, +                                   isMemberSpecialization || +                                       isFunctionTemplateSpecialization, +                                   D.isFunctionDefinition());    }    if (getLangOpts().CUDA) {      IdentifierInfo *II = NewFD->getIdentifier(); -    if (II && II->isStr("cudaConfigureCall") && !NewFD->isInvalidDecl() && +    if (II && +        II->isStr(getLangOpts().HIP ? "hipConfigureCall" +                                    : "cudaConfigureCall") && +        !NewFD->isInvalidDecl() &&          NewFD->getDeclContext()->getRedeclContext()->isTranslationUnit()) {        if (!R->getAs<FunctionType>()->getReturnType()->isScalarType())          Diag(NewFD->getLocation(), diag::err_config_scalar_return); -        Context.setcudaConfigureCallDecl(NewFD);      } @@ -9073,22 +9161,95 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,    }    // Here we have an function template explicit specialization at class scope. -  // The actually specialization will be postponed to template instatiation +  // The actual specialization will be postponed to template instatiation    // time via the ClassScopeFunctionSpecializationDecl node.    if (isDependentClassScopeExplicitSpecialization) {      ClassScopeFunctionSpecializationDecl *NewSpec =                           ClassScopeFunctionSpecializationDecl::Create( -                                Context, CurContext, SourceLocation(), +                                Context, CurContext, NewFD->getLocation(),                                  cast<CXXMethodDecl>(NewFD),                                  HasExplicitTemplateArgs, TemplateArgs);      CurContext->addDecl(NewSpec);      AddToScope = false;    } +  // Diagnose availability attributes. Availability cannot be used on functions +  // that are run during load/unload. +  if (const auto *attr = NewFD->getAttr<AvailabilityAttr>()) { +    if (NewFD->hasAttr<ConstructorAttr>()) { +      Diag(attr->getLocation(), diag::warn_availability_on_static_initializer) +          << 1; +      NewFD->dropAttr<AvailabilityAttr>(); +    } +    if (NewFD->hasAttr<DestructorAttr>()) { +      Diag(attr->getLocation(), diag::warn_availability_on_static_initializer) +          << 2; +      NewFD->dropAttr<AvailabilityAttr>(); +    } +  } +    return NewFD;  } -/// \brief Checks if the new declaration declared in dependent context must be +/// Return a CodeSegAttr from a containing class.  The Microsoft docs say +/// when __declspec(code_seg) "is applied to a class, all member functions of +/// the class and nested classes -- this includes compiler-generated special +/// member functions -- are put in the specified segment." +/// The actual behavior is a little more complicated. The Microsoft compiler +/// won't check outer classes if there is an active value from #pragma code_seg. +/// The CodeSeg is always applied from the direct parent but only from outer +/// classes when the #pragma code_seg stack is empty. See: +/// https://reviews.llvm.org/D22931, the Microsoft feedback page is no longer +/// available since MS has removed the page. +static Attr *getImplicitCodeSegAttrFromClass(Sema &S, const FunctionDecl *FD) { +  const auto *Method = dyn_cast<CXXMethodDecl>(FD); +  if (!Method) +    return nullptr; +  const CXXRecordDecl *Parent = Method->getParent(); +  if (const auto *SAttr = Parent->getAttr<CodeSegAttr>()) { +    Attr *NewAttr = SAttr->clone(S.getASTContext()); +    NewAttr->setImplicit(true); +    return NewAttr; +  } + +  // The Microsoft compiler won't check outer classes for the CodeSeg +  // when the #pragma code_seg stack is active. +  if (S.CodeSegStack.CurrentValue) +   return nullptr; + +  while ((Parent = dyn_cast<CXXRecordDecl>(Parent->getParent()))) { +    if (const auto *SAttr = Parent->getAttr<CodeSegAttr>()) { +      Attr *NewAttr = SAttr->clone(S.getASTContext()); +      NewAttr->setImplicit(true); +      return NewAttr; +    } +  } +  return nullptr; +} + +/// Returns an implicit CodeSegAttr if a __declspec(code_seg) is found on a +/// containing class. Otherwise it will return implicit SectionAttr if the +/// function is a definition and there is an active value on CodeSegStack +/// (from the current #pragma code-seg value). +/// +/// \param FD Function being declared. +/// \param IsDefinition Whether it is a definition or just a declarartion. +/// \returns A CodeSegAttr or SectionAttr to apply to the function or +///          nullptr if no attribute should be added. +Attr *Sema::getImplicitCodeSegOrSectionAttrForFunction(const FunctionDecl *FD, +                                                       bool IsDefinition) { +  if (Attr *A = getImplicitCodeSegAttrFromClass(*this, FD)) +    return A; +  if (!FD->hasAttr<SectionAttr>() && IsDefinition && +      CodeSegStack.CurrentValue) { +    return SectionAttr::CreateImplicit(getASTContext(), +                                       SectionAttr::Declspec_allocate, +                                       CodeSegStack.CurrentValue->getString(), +                                       CodeSegStack.CurrentPragmaLocation); +  } +  return nullptr; +} +/// Checks if the new declaration declared in dependent context must be  /// put in the same redeclaration chain as the specified declaration.  ///  /// \param D Declaration that is checked. @@ -9114,7 +9275,524 @@ bool Sema::shouldLinkDependentDeclWithPrevious(Decl *D, Decl *PrevDecl) {             D->getFriendObjectKind() != Decl::FOK_None);  } -/// \brief Perform semantic checking of a new function declaration. +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; +} +/// Check the target attribute of the function for MultiVersion +/// validity. +/// +/// Returns true if there was an error, false otherwise. +static bool CheckMultiVersionValue(Sema &S, const FunctionDecl *FD) { +  const auto *TA = FD->getAttr<TargetAttr>(); +  assert(TA && "MultiVersion Candidate requires a target attribute"); +  TargetAttr::ParsedTargetAttr ParseInfo = TA->parse(); +  const TargetInfo &TargetInfo = S.Context.getTargetInfo(); +  enum ErrType { Feature = 0, Architecture = 1 }; + +  if (!ParseInfo.Architecture.empty() && +      !TargetInfo.validateCpuIs(ParseInfo.Architecture)) { +    S.Diag(FD->getLocation(), diag::err_bad_multiversion_option) +        << Architecture << ParseInfo.Architecture; +    return true; +  } + +  for (const auto &Feat : ParseInfo.Features) { +    auto BareFeat = StringRef{Feat}.substr(1); +    if (Feat[0] == '-') { +      S.Diag(FD->getLocation(), diag::err_bad_multiversion_option) +          << Feature << ("no-" + BareFeat).str(); +      return true; +    } + +    if (!TargetInfo.validateCpuSupports(BareFeat) || +        !TargetInfo.isValidFeatureName(BareFeat)) { +      S.Diag(FD->getLocation(), diag::err_bad_multiversion_option) +          << Feature << BareFeat; +      return true; +    } +  } +  return false; +} + +static bool CheckMultiVersionAdditionalRules(Sema &S, const FunctionDecl *OldFD, +                                             const FunctionDecl *NewFD, +                                             bool CausesMV, +                                             MultiVersioning::Type MVType) { +  enum DoesntSupport { +    FuncTemplates = 0, +    VirtFuncs = 1, +    DeducedReturn = 2, +    Constructors = 3, +    Destructors = 4, +    DeletedFuncs = 5, +    DefaultedFuncs = 6, +    ConstexprFuncs = 7, +  }; +  enum Different { +    CallingConv = 0, +    ReturnType = 1, +    ConstexprSpec = 2, +    InlineSpec = 3, +    StorageClass = 4, +    Linkage = 5 +  }; + +  bool IsCPUSpecificCPUDispatchMVType = +      MVType == MultiVersioning::CPUDispatch || +      MVType == MultiVersioning::CPUSpecific; + +  if (OldFD && !OldFD->getType()->getAs<FunctionProtoType>()) { +    S.Diag(OldFD->getLocation(), diag::err_multiversion_noproto); +    S.Diag(NewFD->getLocation(), diag::note_multiversioning_caused_here); +    return true; +  } + +  if (!NewFD->getType()->getAs<FunctionProtoType>()) +    return S.Diag(NewFD->getLocation(), diag::err_multiversion_noproto); + +  if (!S.getASTContext().getTargetInfo().supportsMultiVersioning()) { +    S.Diag(NewFD->getLocation(), diag::err_multiversion_not_supported); +    if (OldFD) +      S.Diag(OldFD->getLocation(), diag::note_previous_declaration); +    return true; +  } + +  // 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) { +    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) +    return S.Diag(NewFD->getLocation(), diag::err_multiversion_no_other_attrs) +           << IsCPUSpecificCPUDispatchMVType; + +  if (NewFD->getTemplatedKind() == FunctionDecl::TK_FunctionTemplate) +    return S.Diag(NewFD->getLocation(), diag::err_multiversion_doesnt_support) +           << IsCPUSpecificCPUDispatchMVType << FuncTemplates; + +  if (const auto *NewCXXFD = dyn_cast<CXXMethodDecl>(NewFD)) { +    if (NewCXXFD->isVirtual()) +      return S.Diag(NewCXXFD->getLocation(), +                    diag::err_multiversion_doesnt_support) +             << IsCPUSpecificCPUDispatchMVType << VirtFuncs; + +    if (const auto *NewCXXCtor = dyn_cast<CXXConstructorDecl>(NewFD)) +      return S.Diag(NewCXXCtor->getLocation(), +                    diag::err_multiversion_doesnt_support) +             << IsCPUSpecificCPUDispatchMVType << Constructors; + +    if (const auto *NewCXXDtor = dyn_cast<CXXDestructorDecl>(NewFD)) +      return S.Diag(NewCXXDtor->getLocation(), +                    diag::err_multiversion_doesnt_support) +             << IsCPUSpecificCPUDispatchMVType << Destructors; +  } + +  if (NewFD->isDeleted()) +    return S.Diag(NewFD->getLocation(), diag::err_multiversion_doesnt_support) +           << IsCPUSpecificCPUDispatchMVType << DeletedFuncs; + +  if (NewFD->isDefaulted()) +    return S.Diag(NewFD->getLocation(), diag::err_multiversion_doesnt_support) +           << IsCPUSpecificCPUDispatchMVType << DefaultedFuncs; + +  if (NewFD->isConstexpr() && (MVType == MultiVersioning::CPUDispatch || +                               MVType == MultiVersioning::CPUSpecific)) +    return S.Diag(NewFD->getLocation(), diag::err_multiversion_doesnt_support) +           << IsCPUSpecificCPUDispatchMVType << ConstexprFuncs; + +  QualType NewQType = S.getASTContext().getCanonicalType(NewFD->getType()); +  const auto *NewType = cast<FunctionType>(NewQType); +  QualType NewReturnType = NewType->getReturnType(); + +  if (NewReturnType->isUndeducedType()) +    return S.Diag(NewFD->getLocation(), diag::err_multiversion_doesnt_support) +           << IsCPUSpecificCPUDispatchMVType << DeducedReturn; + +  // Only allow transition to MultiVersion if it hasn't been used. +  if (OldFD && CausesMV && OldFD->isUsed(false)) +    return S.Diag(NewFD->getLocation(), diag::err_multiversion_after_used); + +  // Ensure the return type is identical. +  if (OldFD) { +    QualType OldQType = S.getASTContext().getCanonicalType(OldFD->getType()); +    const auto *OldType = cast<FunctionType>(OldQType); +    FunctionType::ExtInfo OldTypeInfo = OldType->getExtInfo(); +    FunctionType::ExtInfo NewTypeInfo = NewType->getExtInfo(); + +    if (OldTypeInfo.getCC() != NewTypeInfo.getCC()) +      return S.Diag(NewFD->getLocation(), diag::err_multiversion_diff) +             << CallingConv; + +    QualType OldReturnType = OldType->getReturnType(); + +    if (OldReturnType != NewReturnType) +      return S.Diag(NewFD->getLocation(), diag::err_multiversion_diff) +             << ReturnType; + +    if (OldFD->isConstexpr() != NewFD->isConstexpr()) +      return S.Diag(NewFD->getLocation(), diag::err_multiversion_diff) +             << ConstexprSpec; + +    if (OldFD->isInlineSpecified() != NewFD->isInlineSpecified()) +      return S.Diag(NewFD->getLocation(), diag::err_multiversion_diff) +             << InlineSpec; + +    if (OldFD->getStorageClass() != NewFD->getStorageClass()) +      return S.Diag(NewFD->getLocation(), diag::err_multiversion_diff) +             << StorageClass; + +    if (OldFD->isExternC() != NewFD->isExternC()) +      return S.Diag(NewFD->getLocation(), diag::err_multiversion_diff) +             << Linkage; + +    if (S.CheckEquivalentExceptionSpec( +            OldFD->getType()->getAs<FunctionProtoType>(), OldFD->getLocation(), +            NewFD->getType()->getAs<FunctionProtoType>(), NewFD->getLocation())) +      return true; +  } +  return false; +} + +/// Check the validity of a multiversion function declaration that is the +/// first of its kind. Also sets the multiversion'ness' of the function itself. +/// +/// This sets NewFD->isInvalidDecl() to true if there was an error. +/// +/// Returns true if there was an error, false otherwise. +static bool CheckMultiVersionFirstFunction(Sema &S, FunctionDecl *FD, +                                           MultiVersioning::Type MVType, +                                           const TargetAttr *TA, +                                           const CPUDispatchAttr *CPUDisp, +                                           const CPUSpecificAttr *CPUSpec) { +  assert(MVType != MultiVersioning::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()) +    return false; + +  if (MVType == MultiVersioning::Target && CheckMultiVersionValue(S, FD)) { +    FD->setInvalidDecl(); +    return true; +  } + +  if (CheckMultiVersionAdditionalRules(S, nullptr, FD, true, MVType)) { +    FD->setInvalidDecl(); +    return true; +  } + +  FD->setIsMultiVersion(); +  return false; +} + +static bool CheckTargetCausesMultiVersioning( +    Sema &S, FunctionDecl *OldFD, FunctionDecl *NewFD, const TargetAttr *NewTA, +    bool &Redeclaration, NamedDecl *&OldDecl, bool &MergeTypeWithPrevious, +    LookupResult &Previous) { +  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()); + +  // 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()) +    return false; + +  // Otherwise, this decl causes MultiVersioning. +  if (!S.getASTContext().getTargetInfo().supportsMultiVersioning()) { +    S.Diag(NewFD->getLocation(), diag::err_multiversion_not_supported); +    S.Diag(OldFD->getLocation(), diag::note_previous_declaration); +    NewFD->setInvalidDecl(); +    return true; +  } + +  if (CheckMultiVersionAdditionalRules(S, OldFD, NewFD, true, +                                       MultiVersioning::Target)) { +    NewFD->setInvalidDecl(); +    return true; +  } + +  if (CheckMultiVersionValue(S, NewFD)) { +    NewFD->setInvalidDecl(); +    return true; +  } + +  if (CheckMultiVersionValue(S, OldFD)) { +    S.Diag(NewFD->getLocation(), diag::note_multiversioning_caused_here); +    NewFD->setInvalidDecl(); +    return true; +  } + +  TargetAttr::ParsedTargetAttr OldParsed = +      OldTA->parse(std::less<std::string>()); + +  if (OldParsed == NewParsed) { +    S.Diag(NewFD->getLocation(), diag::err_multiversion_duplicate); +    S.Diag(OldFD->getLocation(), diag::note_previous_declaration); +    NewFD->setInvalidDecl(); +    return true; +  } + +  for (const auto *FD : OldFD->redecls()) { +    const auto *CurTA = FD->getAttr<TargetAttr>(); +    if (!CurTA || CurTA->isInherited()) { +      S.Diag(FD->getLocation(), diag::err_multiversion_required_in_redecl) +          << 0; +      S.Diag(NewFD->getLocation(), diag::note_multiversioning_caused_here); +      NewFD->setInvalidDecl(); +      return true; +    } +  } + +  OldFD->setIsMultiVersion(); +  NewFD->setIsMultiVersion(); +  Redeclaration = false; +  MergeTypeWithPrevious = false; +  OldDecl = nullptr; +  Previous.clear(); +  return false; +} + +/// Check the validity of a new function declaration being added to an existing +/// multiversioned declaration collection. +static bool CheckMultiVersionAdditionalDecl( +    Sema &S, FunctionDecl *OldFD, FunctionDecl *NewFD, +    MultiVersioning::Type NewMVType, const TargetAttr *NewTA, +    const CPUDispatchAttr *NewCPUDisp, const CPUSpecificAttr *NewCPUSpec, +    bool &Redeclaration, NamedDecl *&OldDecl, bool &MergeTypeWithPrevious, +    LookupResult &Previous) { + +  MultiVersioning::Type OldMVType = getMultiVersionType(OldFD); +  // Disallow mixing of multiversioning types. +  if ((OldMVType == MultiVersioning::Target && +       NewMVType != MultiVersioning::Target) || +      (NewMVType == MultiVersioning::Target && +       OldMVType != MultiVersioning::Target)) { +    S.Diag(NewFD->getLocation(), diag::err_multiversion_types_mixed); +    S.Diag(OldFD->getLocation(), diag::note_previous_declaration); +    NewFD->setInvalidDecl(); +    return true; +  } + +  TargetAttr::ParsedTargetAttr NewParsed; +  if (NewTA) { +    NewParsed = NewTA->parse(); +    llvm::sort(NewParsed.Features.begin(), NewParsed.Features.end()); +  } + +  bool UseMemberUsingDeclRules = +      S.CurContext->isRecord() && !NewFD->getFriendObjectKind(); + +  // Next, check ALL non-overloads to see if this is a redeclaration of a +  // previous member of the MultiVersion set. +  for (NamedDecl *ND : Previous) { +    FunctionDecl *CurFD = ND->getAsFunction(); +    if (!CurFD) +      continue; +    if (S.IsOverload(NewFD, CurFD, UseMemberUsingDeclRules)) +      continue; + +    if (NewMVType == MultiVersioning::Target) { +      const auto *CurTA = CurFD->getAttr<TargetAttr>(); +      if (CurTA->getFeaturesStr() == NewTA->getFeaturesStr()) { +        NewFD->setIsMultiVersion(); +        Redeclaration = true; +        OldDecl = ND; +        return false; +      } + +      TargetAttr::ParsedTargetAttr CurParsed = +          CurTA->parse(std::less<std::string>()); +      if (CurParsed == NewParsed) { +        S.Diag(NewFD->getLocation(), diag::err_multiversion_duplicate); +        S.Diag(CurFD->getLocation(), diag::note_previous_declaration); +        NewFD->setInvalidDecl(); +        return true; +      } +    } else { +      const auto *CurCPUSpec = CurFD->getAttr<CPUSpecificAttr>(); +      const auto *CurCPUDisp = CurFD->getAttr<CPUDispatchAttr>(); +      // Handle CPUDispatch/CPUSpecific versions. +      // Only 1 CPUDispatch function is allowed, this will make it go through +      // the redeclaration errors. +      if (NewMVType == MultiVersioning::CPUDispatch && +          CurFD->hasAttr<CPUDispatchAttr>()) { +        if (CurCPUDisp->cpus_size() == NewCPUDisp->cpus_size() && +            std::equal( +                CurCPUDisp->cpus_begin(), CurCPUDisp->cpus_end(), +                NewCPUDisp->cpus_begin(), +                [](const IdentifierInfo *Cur, const IdentifierInfo *New) { +                  return Cur->getName() == New->getName(); +                })) { +          NewFD->setIsMultiVersion(); +          Redeclaration = true; +          OldDecl = ND; +          return false; +        } + +        // If the declarations don't match, this is an error condition. +        S.Diag(NewFD->getLocation(), diag::err_cpu_dispatch_mismatch); +        S.Diag(CurFD->getLocation(), diag::note_previous_declaration); +        NewFD->setInvalidDecl(); +        return true; +      } +      if (NewMVType == MultiVersioning::CPUSpecific && CurCPUSpec) { + +        if (CurCPUSpec->cpus_size() == NewCPUSpec->cpus_size() && +            std::equal( +                CurCPUSpec->cpus_begin(), CurCPUSpec->cpus_end(), +                NewCPUSpec->cpus_begin(), +                [](const IdentifierInfo *Cur, const IdentifierInfo *New) { +                  return Cur->getName() == New->getName(); +                })) { +          NewFD->setIsMultiVersion(); +          Redeclaration = true; +          OldDecl = ND; +          return false; +        } + +        // Only 1 version of CPUSpecific is allowed for each CPU. +        for (const IdentifierInfo *CurII : CurCPUSpec->cpus()) { +          for (const IdentifierInfo *NewII : NewCPUSpec->cpus()) { +            if (CurII == NewII) { +              S.Diag(NewFD->getLocation(), diag::err_cpu_specific_multiple_defs) +                  << NewII; +              S.Diag(CurFD->getLocation(), diag::note_previous_declaration); +              NewFD->setInvalidDecl(); +              return true; +            } +          } +        } +      } +      // If the two decls aren't the same MVType, there is no possible error +      // condition. +    } +  } + +  // 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 && +      CheckMultiVersionValue(S, NewFD)) { +    NewFD->setInvalidDecl(); +    return true; +  } + +  if (CheckMultiVersionAdditionalRules(S, OldFD, NewFD, false, NewMVType)) { +    NewFD->setInvalidDecl(); +    return true; +  } + +  NewFD->setIsMultiVersion(); +  Redeclaration = false; +  MergeTypeWithPrevious = false; +  OldDecl = nullptr; +  Previous.clear(); +  return false; +} + + +/// Check the validity of a mulitversion function declaration. +/// Also sets the multiversion'ness' of the function itself. +/// +/// This sets NewFD->isInvalidDecl() to true if there was an error. +/// +/// Returns true if there was an error, false otherwise. +static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, +                                      bool &Redeclaration, NamedDecl *&OldDecl, +                                      bool &MergeTypeWithPrevious, +                                      LookupResult &Previous) { +  const auto *NewTA = NewFD->getAttr<TargetAttr>(); +  const auto *NewCPUDisp = NewFD->getAttr<CPUDispatchAttr>(); +  const auto *NewCPUSpec = NewFD->getAttr<CPUSpecificAttr>(); + +  // Mixing Multiversioning types is prohibited. +  if ((NewTA && NewCPUDisp) || (NewTA && NewCPUSpec) || +      (NewCPUDisp && NewCPUSpec)) { +    S.Diag(NewFD->getLocation(), diag::err_multiversion_types_mixed); +    NewFD->setInvalidDecl(); +    return true; +  } + +  MultiVersioning::Type MVType = getMultiVersionType(NewFD); + +  // 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) { +      S.Diag(NewFD->getLocation(), diag::err_multiversion_not_allowed_on_main); +      NewFD->setInvalidDecl(); +      return true; +    } +    return false; +  } + +  if (!OldDecl || !OldDecl->getAsFunction() || +      OldDecl->getDeclContext()->getRedeclContext() != +          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) +      return false; +    return CheckMultiVersionFirstFunction(S, NewFD, MVType, NewTA, NewCPUDisp, +                                          NewCPUSpec); +  } + +  FunctionDecl *OldFD = OldDecl->getAsFunction(); + +  if (!OldFD->isMultiVersion() && MVType == MultiVersioning::None) +    return false; + +  if (OldFD->isMultiVersion() && MVType == MultiVersioning::None) { +    S.Diag(NewFD->getLocation(), diag::err_multiversion_required_in_redecl) +        << (getMultiVersionType(OldFD) != MultiVersioning::Target); +    NewFD->setInvalidDecl(); +    return true; +  } + +  // Handle the target potentially causes multiversioning case. +  if (!OldFD->isMultiVersion() && MVType == MultiVersioning::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 +  // still compatible with previous declarations. +  return CheckMultiVersionAdditionalDecl( +      S, OldFD, NewFD, MVType, NewTA, NewCPUDisp, NewCPUSpec, Redeclaration, +      OldDecl, MergeTypeWithPrevious, Previous); +} + +/// Perform semantic checking of a new function declaration.  ///  /// Performs semantic analysis of the new function declaration  /// NewFD. This routine performs all semantic checking that does not @@ -9201,6 +9879,10 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,      }    } +  if (CheckMultiVersionFunction(*this, NewFD, Redeclaration, OldDecl, +                                MergeTypeWithPrevious, Previous)) +    return Redeclaration; +    // C++11 [dcl.constexpr]p8:    //   A constexpr specifier for a non-static member function that is not    //   a constructor declares that member function to be const. @@ -9250,15 +9932,16 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,      Previous.clear();      Previous.addDecl(OldDecl); -    if (FunctionTemplateDecl *OldTemplateDecl -                                  = dyn_cast<FunctionTemplateDecl>(OldDecl)) { -      NewFD->setPreviousDeclaration(OldTemplateDecl->getTemplatedDecl()); +    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"); -      if (CXXMethodDecl *Method -            = dyn_cast<CXXMethodDecl>(NewTemplateDecl->getTemplatedDecl())) { -        Method->setAccess(OldTemplateDecl->getAccess()); +      if (NewFD->isCXXClassMember()) { +        NewFD->setAccess(OldTemplateDecl->getAccess());          NewTemplateDecl->setAccess(OldTemplateDecl->getAccess());        } @@ -9270,22 +9953,22 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,          assert(OldTemplateDecl->isMemberSpecialization());          // Explicit specializations of a member template do not inherit deleted          // status from the parent member template that they are specializing. -        if (OldTemplateDecl->getTemplatedDecl()->isDeleted()) { -          FunctionDecl *const OldTemplatedDecl = -              OldTemplateDecl->getTemplatedDecl(); +        if (OldFD->isDeleted()) {            // FIXME: This assert will not hold in the presence of modules. -          assert(OldTemplatedDecl->getCanonicalDecl() == OldTemplatedDecl); +          assert(OldFD->getCanonicalDecl() == OldFD);            // FIXME: We need an update record for this AST mutation. -          OldTemplatedDecl->setDeletedAsWritten(false); +          OldFD->setDeletedAsWritten(false);          }        }      } else {        if (shouldLinkDependentDeclWithPrevious(NewFD, OldDecl)) { +        auto *OldFD = cast<FunctionDecl>(OldDecl);          // This needs to happen first so that 'inline' propagates. -        NewFD->setPreviousDeclaration(cast<FunctionDecl>(OldDecl)); -        if (isa<CXXMethodDecl>(NewFD)) -          NewFD->setAccess(OldDecl->getAccess()); +        NewFD->setPreviousDeclaration(OldFD); +        adjustDeclContextForDeclaratorDecl(NewFD, OldFD); +        if (NewFD->isCXXClassMember()) +          NewFD->setAccess(OldFD->getAccess());        }      }    } else if (!getLangOpts().CPlusPlus && MayNeedOverloadableChecks && @@ -9440,7 +10123,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,          else if (auto *MPT = T->getAs<MemberPointerType>())            T = MPT->getPointeeType();          if (auto *FPT = T->getAs<FunctionProtoType>()) -          if (FPT->isNothrow(Context)) +          if (FPT->isNothrow())              return true;          return false;        }; @@ -9951,7 +10634,7 @@ namespace {        S.DiagRuntimeBehavior(DRE->getLocStart(), DRE,                              S.PDiag(diag) -                              << DRE->getNameInfo().getName() +                              << DRE->getDecl()                                << OrigDecl->getLocation()                                << DRE->getSourceRange());      } @@ -10011,12 +10694,22 @@ QualType Sema::deduceVarTypeFromInitializer(VarDecl *VDecl,    // 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(); + +    // Except for class argument deduction, and then for an initializing +    // declaration only, i.e. no static at class scope or extern. +    if (!isa<DeducedTemplateSpecializationType>(Deduced) || +        VDecl->hasExternalStorage() || +        VDecl->isStaticDataMember()) { +      Diag(VDecl->getLocation(), diag::err_auto_var_requires_init) +        << VDecl->getDeclName() << Type; +      return QualType(); +    }    } -  ArrayRef<Expr*> DeduceInits = Init; +  ArrayRef<Expr*> DeduceInits; +  if (Init) +    DeduceInits = Init; +    if (DirectInit) {      if (auto *PL = dyn_cast_or_null<ParenListExpr>(Init))        DeduceInits = PL->exprs(); @@ -10260,7 +10953,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {      }      if (VDecl->hasLocalStorage()) -      getCurFunction()->setHasBranchProtectedScope(); +      setFunctionHasBranchProtectedScope();      if (DiagnoseUnexpandedParameterPack(Init, UPPC_Initializer)) {        VDecl->setInvalidDecl(); @@ -10360,11 +11053,12 @@ 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 || -         VDecl->getType().isNonWeakInMRRWithObjCWeak(Context)) && -        !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, -                         Init->getLocStart())) -      getCurFunction()->markSafeWeakUse(Init); +    if (FunctionScopeInfo *FSI = getCurFunction()) +      if ((VDecl->getType().getObjCLifetime() == Qualifiers::OCL_Strong || +           VDecl->getType().isNonWeakInMRRWithObjCWeak(Context)) && +          !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, +                           Init->getLocStart())) +        FSI->markSafeWeakUse(Init);    }    // The initialization is usually a full-expression. @@ -10471,6 +11165,9 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {          ; // Nothing to check.        else if (Init->isIntegerConstantExpr(Context, &Loc))          ; // Ok, it's an ICE! +      else if (Init->getType()->isScopedEnumeralType() && +               Init->isCXX11ConstantExpr(Context)) +        ; // Ok, it is a scoped-enum constant expression.        else if (Init->isEvaluatable(Context)) {          // If we can constant fold the initializer through heroics, accept it,          // but report this as a use of an extension for -pedantic. @@ -10521,7 +11218,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {    } else if (VDecl->isFileVarDecl()) {      // In C, extern is typically used to avoid tentative definitions when      // declaring variables in headers, but adding an intializer makes it a -    // defintion. This is somewhat confusing, so GCC and Clang both warn on it. +    // definition. This is somewhat confusing, so GCC and Clang both warn on it.      // In C++, extern is often used to give implictly static const variables      // external linkage, so don't warn in that case. If selectany is present,      // this might be header code intended for C and C++ inclusion, so apply the @@ -10794,11 +11491,11 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) {        if (const RecordType *Record              = Context.getBaseElementType(Type)->getAs<RecordType>()) {          CXXRecordDecl *CXXRecord = cast<CXXRecordDecl>(Record->getDecl()); -        // Mark the function for further checking even if the looser rules of -        // C++11 do not require such checks, so that we can diagnose -        // incompatibilities with C++98. +        // Mark the function (if we're in one) for further checking even if the +        // looser rules of C++11 do not require such checks, so that we can +        // diagnose incompatibilities with C++98.          if (!CXXRecord->isPOD()) -          getCurFunction()->setHasBranchProtectedScope(); +          setFunctionHasBranchProtectedScope();        }      } @@ -10893,13 +11590,13 @@ Sema::ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc,    DS.SetTypeSpecType(DeclSpec::TST_auto, IdentLoc, PrevSpec, DiagID,                       getPrintingPolicy()); -  Declarator D(DS, Declarator::ForContext); +  Declarator D(DS, DeclaratorContext::ForContext);    D.SetIdentifier(Ident, IdentLoc);    D.takeAttributes(Attrs, AttrEnd);    ParsedAttributes EmptyAttrs(Attrs.getPool().getFactory()); -  D.AddTypeInfo(DeclaratorChunk::getReference(0, IdentLoc, /*lvalue*/false), -                EmptyAttrs, IdentLoc); +  D.AddTypeInfo(DeclaratorChunk::getReference(0, IdentLoc, /*lvalue*/ false), +                IdentLoc);    Decl *Var = ActOnDeclarator(S, D);    cast<VarDecl>(Var)->setCXXForRangeDecl(true);    FinalizeDeclaration(Var); @@ -10934,11 +11631,15 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {      case Qualifiers::OCL_Weak:      case Qualifiers::OCL_Strong: -      getCurFunction()->setHasBranchProtectedScope(); +      setFunctionHasBranchProtectedScope();        break;      }    } +  if (var->hasLocalStorage() && +      var->getType().isDestructedType() == QualType::DK_nontrivial_c_struct) +    setFunctionHasBranchProtectedScope(); +    // Warn about externally-visible variables being defined without a    // prior declaration.  We only want to do this for global    // declarations, but we also specifically need to avoid doing it for @@ -10947,6 +11648,8 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {    if (var->isThisDeclarationADefinition() &&        var->getDeclContext()->getRedeclContext()->isFileContext() &&        var->isExternallyVisible() && var->hasLinkage() && +      !var->isInline() && !var->getDescribedVarTemplate() && +      !isTemplateInstantiation(var->getTemplateSpecializationKind()) &&        !getDiagnostics().isIgnored(diag::warn_missing_variable_declarations,                                    var->getLocation())) {      // Find a previous declaration that's not a definition. @@ -11140,7 +11843,7 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) {      Context.addModuleInitializer(ModuleScopes.back().Module, var);  } -/// \brief Determines if a variable's alignment is dependent. +/// Determines if a variable's alignment is dependent.  static bool hasDependentAlignment(VarDecl *VD) {    if (VD->getType()->isDependentType())      return true; @@ -11227,58 +11930,8 @@ void Sema::FinalizeDeclaration(Decl *ThisDecl) {    // 7.5). We must also apply the same checks to all __shared__    // variables whether they are local or not. CUDA also allows    // constant initializers for __constant__ and __device__ variables. -  if (getLangOpts().CUDA) { -    const Expr *Init = VD->getInit(); -    if (Init && VD->hasGlobalStorage()) { -      if (VD->hasAttr<CUDADeviceAttr>() || VD->hasAttr<CUDAConstantAttr>() || -          VD->hasAttr<CUDASharedAttr>()) { -        assert(!VD->isStaticLocal() || VD->hasAttr<CUDASharedAttr>()); -        bool AllowedInit = false; -        if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(Init)) -          AllowedInit = -              isEmptyCudaConstructor(VD->getLocation(), CE->getConstructor()); -        // We'll allow constant initializers even if it's a non-empty -        // constructor according to CUDA rules. This deviates from NVCC, -        // but allows us to handle things like constexpr constructors. -        if (!AllowedInit && -            (VD->hasAttr<CUDADeviceAttr>() || VD->hasAttr<CUDAConstantAttr>())) -          AllowedInit = VD->getInit()->isConstantInitializer( -              Context, VD->getType()->isReferenceType()); - -        // Also make sure that destructor, if there is one, is empty. -        if (AllowedInit) -          if (CXXRecordDecl *RD = VD->getType()->getAsCXXRecordDecl()) -            AllowedInit = -                isEmptyCudaDestructor(VD->getLocation(), RD->getDestructor()); - -        if (!AllowedInit) { -          Diag(VD->getLocation(), VD->hasAttr<CUDASharedAttr>() -                                      ? diag::err_shared_var_init -                                      : diag::err_dynamic_var_init) -              << Init->getSourceRange(); -          VD->setInvalidDecl(); -        } -      } else { -        // This is a host-side global variable.  Check that the initializer is -        // callable from the host side. -        const FunctionDecl *InitFn = nullptr; -        if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(Init)) { -          InitFn = CE->getConstructor(); -        } else if (const CallExpr *CE = dyn_cast<CallExpr>(Init)) { -          InitFn = CE->getDirectCallee(); -        } -        if (InitFn) { -          CUDAFunctionTarget InitFnTarget = IdentifyCUDATarget(InitFn); -          if (InitFnTarget != CFT_Host && InitFnTarget != CFT_HostDevice) { -            Diag(VD->getLocation(), diag::err_ref_bad_target_global_initializer) -                << InitFnTarget << InitFn; -            Diag(InitFn->getLocation(), diag::note_previous_decl) << InitFn; -            VD->setInvalidDecl(); -          } -        } -      } -    } -  } +  if (getLangOpts().CUDA) +    checkAllowedCUDAInitializer(VD);    // Grab the dllimport or dllexport attribute off of the VarDecl.    const InheritableAttr *DLLAttr = getDLLAttr(VD); @@ -11657,7 +12310,7 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {    return New;  } -/// \brief Synthesizes a variable for a parameter arising from a +/// Synthesizes a variable for a parameter arising from a  /// typedef.  ParmVarDecl *Sema::BuildParmVarDeclForTypedef(DeclContext *DC,                                                SourceLocation Loc, @@ -11809,7 +12462,7 @@ void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D,          // Use the identifier location for the type source range.          DS.SetRangeStart(FTI.Params[i].IdentLoc);          DS.SetRangeEnd(FTI.Params[i].IdentLoc); -        Declarator ParamD(DS, Declarator::KNRTypeListContext); +        Declarator ParamD(DS, DeclaratorContext::KNRTypeListContext);          ParamD.SetIdentifier(FTI.Params[i].Ident, FTI.Params[i].IdentLoc);          FTI.Params[i].Param = ActOnParamDeclarator(S, ParamD);        } @@ -11894,9 +12547,45 @@ Sema::CheckForFunctionRedefinition(FunctionDecl *FD,                                     const FunctionDecl *EffectiveDefinition,                                     SkipBodyInfo *SkipBody) {    const FunctionDecl *Definition = EffectiveDefinition; +  if (!Definition && !FD->isDefined(Definition) && !FD->isCXXClassMember()) { +    // If this is a friend function defined in a class template, it does not +    // have a body until it is used, nevertheless it is a definition, see +    // [temp.inst]p2: +    // +    // ... for the purpose of determining whether an instantiated redeclaration +    // is valid according to [basic.def.odr] and [class.mem], a declaration that +    // corresponds to a definition in the template is considered to be a +    // definition. +    // +    // The following code must produce redefinition error: +    // +    //     template<typename T> struct C20 { friend void func_20() {} }; +    //     C20<int> c20i; +    //     void func_20() {} +    // +    for (auto I : FD->redecls()) { +      if (I != FD && !I->isInvalidDecl() && +          I->getFriendObjectKind() != Decl::FOK_None) { +        if (FunctionDecl *Original = I->getInstantiatedFromMemberFunction()) { +          if (FunctionDecl *OrigFD = FD->getInstantiatedFromMemberFunction()) { +            // A merged copy of the same function, instantiated as a member of +            // the same class, is OK. +            if (declaresSameEntity(OrigFD, Original) && +                declaresSameEntity(cast<Decl>(I->getLexicalDeclContext()), +                                   cast<Decl>(FD->getLexicalDeclContext()))) +              continue; +          } + +          if (Original->isThisDeclarationADefinition()) { +            Definition = I; +            break; +          } +        } +      } +    } +  }    if (!Definition) -    if (!FD->isDefined(Definition)) -      return; +    return;    if (canRedefineFunction(Definition, getLangOpts()))      return; @@ -11981,8 +12670,13 @@ static void RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator,  Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,                                      SkipBodyInfo *SkipBody) { -  if (!D) +  if (!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();      return D; +  } +    FunctionDecl *FD = nullptr;    if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D)) @@ -12119,7 +12813,7 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,    return D;  } -/// \brief Given the set of return statements within a function body, +/// Given the set of return statements within a function body,  /// compute the variables that are subject to the named return value  /// optimization.  /// @@ -12172,9 +12866,15 @@ bool Sema::canSkipFunctionBody(Decl *D) {    // rest of the file.    // We cannot skip the body of a function with an undeduced return type,    // because any callers of that function need to know the type. -  if (const FunctionDecl *FD = D->getAsFunction()) -    if (FD->isConstexpr() || FD->getReturnType()->isUndeducedType()) +  if (const FunctionDecl *FD = D->getAsFunction()) { +    if (FD->isConstexpr()) +      return false; +    // We can't simply call Type::isUndeducedType here, because inside template +    // auto can be deduced to a dependent type, which is not considered +    // "undeduced". +    if (FD->getReturnType()->getContainedDeducedType())        return false; +  }    return Consumer.shouldSkipFunctionBody(D);  } @@ -12270,8 +12970,8 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,        // Try to apply the named return value optimization. We have to check        // if we can do this here because lambdas keep return statements around        // to deduce an implicit return type. -      if (getLangOpts().CPlusPlus && FD->getReturnType()->isRecordType() && -          !FD->isDependentContext()) +      if (FD->getReturnType()->isRecordType() && +          (!getLangOpts().CPlusPlus || !FD->isDependentContext()))          computeNRVO(Body, getCurFunction());      } @@ -12314,6 +13014,13 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,        }      } +    // Warn on CPUDispatch with an actual 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::warn_dispatch_body_ignored); +      if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) {        const CXXMethodDecl *KeyFunction;        if (MD->isOutOfLine() && (MD = MD->getCanonicalDecl()) && @@ -12391,6 +13098,9 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,        getCurFunction()->ObjCWarnForNoInitDelegation = false;      }    } else { +    // Parsing the function declaration failed in some way. Pop the fake scope +    // we pushed on. +    PopFunctionScopeInfo(ActivePolicy, dcl);      return nullptr;    } @@ -12496,7 +13206,7 @@ void Sema::ActOnFinishDelayedAttribute(Scope *S, Decl *D,    // Always attach attributes to the underlying decl.    if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D))      D = TD->getTemplatedDecl(); -  ProcessDeclAttributeList(S, D, Attrs.getList()); +  ProcessDeclAttributeList(S, D, Attrs);    if (CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(D))      if (Method->isStatic()) @@ -12507,10 +13217,20 @@ void Sema::ActOnFinishDelayedAttribute(Scope *S, Decl *D,  /// call, forming a call to an implicitly defined function (per C99 6.5.1p2).  NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,                                            IdentifierInfo &II, Scope *S) { +  // Find the scope in which the identifier is injected and the corresponding +  // DeclContext. +  // FIXME: C89 does not say what happens if there is no enclosing block scope. +  // In that case, we inject the declaration into the translation unit scope +  // instead.    Scope *BlockScope = S;    while (!BlockScope->isCompoundStmtScope() && BlockScope->getParent())      BlockScope = BlockScope->getParent(); +  Scope *ContextScope = BlockScope; +  while (!ContextScope->getEntity()) +    ContextScope = ContextScope->getParent(); +  ContextRAII SavedContext(*this, ContextScope->getEntity()); +    // Before we produce a declaration for an implicitly defined    // function, see whether there was a locally-scoped declaration of    // this name as a function or variable. If so, use that @@ -12574,7 +13294,7 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,    (void)Error; // Silence warning.    assert(!Error && "Error setting up implicit decl!");    SourceLocation NoLoc; -  Declarator D(DS, Declarator::BlockContext); +  Declarator D(DS, DeclaratorContext::BlockContext);    D.AddTypeInfo(DeclaratorChunk::getFunction(/*HasProto=*/false,                                               /*IsAmbiguous=*/false,                                               /*LParenLoc=*/NoLoc, @@ -12588,18 +13308,16 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,                                               /*ConstQualifierLoc=*/NoLoc,                                               /*VolatileQualifierLoc=*/NoLoc,                                               /*RestrictQualifierLoc=*/NoLoc, -                                             /*MutableLoc=*/NoLoc, -                                             EST_None, +                                             /*MutableLoc=*/NoLoc, EST_None,                                               /*ESpecRange=*/SourceRange(),                                               /*Exceptions=*/nullptr,                                               /*ExceptionRanges=*/nullptr,                                               /*NumExceptions=*/0,                                               /*NoexceptExpr=*/nullptr,                                               /*ExceptionSpecTokens=*/nullptr, -                                             /*DeclsInPrototype=*/None, -                                             Loc, Loc, D), -                DS.getAttributes(), -                SourceLocation()); +                                             /*DeclsInPrototype=*/None, Loc, +                                             Loc, D), +                std::move(DS.getAttributes()), SourceLocation());    D.SetIdentifier(&II, Loc);    // Insert this function into the enclosing block scope. @@ -12611,7 +13329,7 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,    return FD;  } -/// \brief Adds any function attributes that we know a priori based on +/// Adds any function attributes that we know a priori based on  /// the declaration of this function.  ///  /// These attributes can apply both to implicitly-declared builtins @@ -12661,11 +13379,11 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {          Context.BuiltinInfo.isConstWithoutErrno(BuiltinID))        FD->addAttr(ConstAttr::CreateImplicit(Context, FD->getLocation())); -    // We make "fma" on GNU or Windows const because we know it does not set +    // We make "fma" on some platforms const because we know it does not set      // errno in those environments even though it could set errno based on the      // C standard.      const llvm::Triple &Trip = Context.getTargetInfo().getTriple(); -    if ((Trip.isGNUEnvironment() || Trip.isOSMSVCRT()) && +    if ((Trip.isGNUEnvironment() || Trip.isAndroid() || Trip.isOSMSVCRT()) &&          !FD->hasAttr<ConstAttr>()) {        switch (BuiltinID) {        case Builtin::BI__builtin_fma: @@ -12741,7 +13459,7 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {      // We already have a __builtin___CFStringMakeConstantString,      // but builds that use -fno-constant-cfstrings don't go through that.      if (!FD->hasAttr<FormatArgAttr>()) -      FD->addAttr(FormatArgAttr::CreateImplicit(Context, 1, +      FD->addAttr(FormatArgAttr::CreateImplicit(Context, ParamIdx(1, FD),                                                  FD->getLocation()));    }  } @@ -12803,7 +13521,7 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T,    return NewTD;  } -/// \brief Check that this is a valid underlying type for an enum declaration. +/// Check that this is a valid underlying type for an enum declaration.  bool Sema::CheckEnumUnderlyingType(TypeSourceInfo *TI) {    SourceLocation UnderlyingLoc = TI->getTypeLoc().getBeginLoc();    QualType T = TI->getType(); @@ -12821,11 +13539,9 @@ bool Sema::CheckEnumUnderlyingType(TypeSourceInfo *TI) {  /// Check whether this is a valid redeclaration of a previous enumeration.  /// \return true if the redeclaration was invalid. -bool Sema::CheckEnumRedeclaration( -    SourceLocation EnumLoc, bool IsScoped, QualType EnumUnderlyingTy, -    bool EnumUnderlyingIsImplicit, const EnumDecl *Prev) { -  bool IsFixed = !EnumUnderlyingTy.isNull(); - +bool Sema::CheckEnumRedeclaration(SourceLocation EnumLoc, bool IsScoped, +                                  QualType EnumUnderlyingTy, bool IsFixed, +                                  const EnumDecl *Prev) {    if (IsScoped != Prev->isScoped()) {      Diag(EnumLoc, diag::err_enum_redeclare_scoped_mismatch)        << Prev->isScoped(); @@ -12845,10 +13561,6 @@ bool Sema::CheckEnumRedeclaration(            << Prev->getIntegerTypeRange();        return true;      } -  } else if (IsFixed && !Prev->isFixed() && EnumUnderlyingIsImplicit) { -    ; -  } else if (!IsFixed && Prev->isFixed() && !Prev->getIntegerTypeSourceInfo()) { -    ;    } else if (IsFixed != Prev->isFixed()) {      Diag(EnumLoc, diag::err_enum_redeclare_fixed_mismatch)        << Prev->isFixed(); @@ -12859,7 +13571,7 @@ bool Sema::CheckEnumRedeclaration(    return false;  } -/// \brief Get diagnostic %select index for tag kind for +/// Get diagnostic %select index for tag kind for  /// redeclaration diagnostic message.  /// WARNING: Indexes apply to particular diagnostics only!  /// @@ -12873,7 +13585,7 @@ static unsigned getRedeclDiagFromTagKind(TagTypeKind Tag) {    }  } -/// \brief Determine if tag kind is a class-key compatible with +/// Determine if tag kind is a class-key compatible with  /// class for redeclaration (class, struct, or __interface).  ///  /// \returns true iff the tag kind is compatible. @@ -12907,7 +13619,7 @@ Sema::NonTagKind Sema::getNonTagTypeDeclKind(const Decl *PrevDecl,    llvm_unreachable("invalid TTK");  } -/// \brief Determine whether a tag with a given kind is acceptable +/// Determine whether a tag with a given kind is acceptable  /// as a redeclaration of the given tag declaration.  ///  /// \returns true if the new tag kind is acceptable, false otherwise. @@ -13043,8 +13755,8 @@ static FixItHint createFriendTagNNSFixIt(Sema &SemaRef, NamedDecl *ND, Scope *S,    return FixItHint::CreateInsertion(NameLoc, Insertion);  } -/// \brief Determine whether a tag originally declared in context \p OldDC can -/// be redeclared with an unqualfied name in \p NewDC (assuming name lookup +/// Determine whether a tag originally declared in context \p OldDC can +/// be redeclared with an unqualified name in \p NewDC (assuming name lookup  /// found a declaration in \p OldDC as a previous decl, perhaps through a  /// using-declaration).  static bool isAcceptableTagRedeclContext(Sema &S, DeclContext *OldDC, @@ -13064,7 +13776,7 @@ static bool isAcceptableTagRedeclContext(Sema &S, DeclContext *OldDC,    return false;  } -/// \brief This is invoked when we see 'struct foo' or 'struct {'.  In the +/// This is invoked when we see 'struct foo' or 'struct {'.  In the  /// former case, Name will be non-null.  In the later case, Name will be null.  /// TagSpec indicates what kind of tag this is. TUK indicates whether this is a  /// reference/declaration/definition of a tag. @@ -13077,13 +13789,12 @@ static bool isAcceptableTagRedeclContext(Sema &S, DeclContext *OldDC,  Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,                       SourceLocation KWLoc, CXXScopeSpec &SS,                       IdentifierInfo *Name, SourceLocation NameLoc, -                     AttributeList *Attr, AccessSpecifier AS, +                     const ParsedAttributesView &Attrs, AccessSpecifier AS,                       SourceLocation ModulePrivateLoc,                       MultiTemplateParamsArg TemplateParameterLists,                       bool &OwnedDecl, bool &IsDependent,                       SourceLocation ScopedEnumKWLoc, -                     bool ScopedEnumUsesClassTag, -                     TypeResult UnderlyingType, +                     bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,                       bool IsTypeSpecifier, bool IsTemplateParamOrArg,                       SkipBodyInfo *SkipBody) {    // If this is not a definition, it must have a name. @@ -13122,14 +13833,11 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,            return nullptr;          OwnedDecl = false; -        DeclResult Result = CheckClassTemplate(S, TagSpec, TUK, KWLoc, -                                               SS, Name, NameLoc, Attr, -                                               TemplateParams, AS, -                                               ModulePrivateLoc, -                                               /*FriendLoc*/SourceLocation(), -                                               TemplateParameterLists.size()-1, -                                               TemplateParameterLists.data(), -                                               SkipBody); +        DeclResult Result = CheckClassTemplate( +            S, TagSpec, TUK, KWLoc, SS, Name, NameLoc, Attrs, TemplateParams, +            AS, ModulePrivateLoc, +            /*FriendLoc*/ SourceLocation(), TemplateParameterLists.size() - 1, +            TemplateParameterLists.data(), SkipBody);          return Result.get();        } else {          // The "template<>" header is extraneous. @@ -13144,14 +13852,14 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,    // this early, because it's needed to detect if this is an incompatible    // redeclaration.    llvm::PointerUnion<const Type*, TypeSourceInfo*> EnumUnderlying; -  bool EnumUnderlyingIsImplicit = false; +  bool IsFixed = !UnderlyingType.isUnset() || ScopedEnum;    if (Kind == TTK_Enum) { -    if (UnderlyingType.isInvalid() || (!UnderlyingType.get() && ScopedEnum)) +    if (UnderlyingType.isInvalid() || (!UnderlyingType.get() && ScopedEnum)) {        // No underlying type explicitly specified, or we failed to parse the        // type, default to int.        EnumUnderlying = Context.IntTy.getTypePtr(); -    else if (UnderlyingType.get()) { +    } else if (UnderlyingType.get()) {        // C++0x 7.2p2: The type-specifier-seq of an enum-base shall name an        // integral type; any cv-qualification is ignored.        TypeSourceInfo *TI = nullptr; @@ -13167,11 +13875,12 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,          EnumUnderlying = Context.IntTy.getTypePtr();      } else if (Context.getTargetInfo().getCXXABI().isMicrosoft()) { -      if (getLangOpts().MSVCCompat || TUK == TUK_Definition) { -        // Microsoft enums are always of int type. +      // For MSVC ABI compatibility, unfixed enums must use an underlying type +      // of 'int'. However, if this is an unfixed forward declaration, don't set +      // the underlying type unless the user enables -fms-compatibility. This +      // makes unfixed forward declared enums incomplete and is more conforming. +      if (TUK == TUK_Definition || getLangOpts().MSVCCompat)          EnumUnderlying = Context.IntTy.getTypePtr(); -        EnumUnderlyingIsImplicit = true; -      }      }    } @@ -13197,8 +13906,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,      if (Kind == TTK_Enum) {        New = EnumDecl::Create(Context, SearchDC, KWLoc, Loc, Name, nullptr, -                             ScopedEnum, ScopedEnumUsesClassTag, -                             !EnumUnderlying.isNull()); +                             ScopedEnum, ScopedEnumUsesClassTag, IsFixed);        // If this is an undefined enum, bail.        if (TUK != TUK_Definition && !Invalid)          return nullptr; @@ -13577,7 +14285,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,            // in which case we want the caller to bail out.            if (CheckEnumRedeclaration(NameLoc.isValid() ? NameLoc : KWLoc,                                       ScopedEnum, EnumUnderlyingTy, -                                     EnumUnderlyingIsImplicit, PrevEnum)) +                                     IsFixed, PrevEnum))              return TUK == TUK_Declaration ? PrevTagDecl : nullptr;          } @@ -13595,7 +14303,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,            // If this is a use, just return the declaration we found, unless            // we have attributes.            if (TUK == TUK_Reference || TUK == TUK_Friend) { -            if (Attr) { +            if (!Attrs.empty()) {                // FIXME: Diagnose these attributes. For now, we create a new                // declaration to hold them.              } else if (TUK == TUK_Reference && @@ -13787,13 +14495,12 @@ CreateNewDecl:    // PrevDecl.    TagDecl *New; -  bool IsForwardReference = false;    if (Kind == TTK_Enum) {      // FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.:      // enum X { A, B, C } D;    D should chain to X.      New = EnumDecl::Create(Context, SearchDC, KWLoc, Loc, Name,                             cast_or_null<EnumDecl>(PrevDecl), ScopedEnum, -                           ScopedEnumUsesClassTag, !EnumUnderlying.isNull()); +                           ScopedEnumUsesClassTag, IsFixed);      if (isStdAlignValT && (!StdAlignValT || getStdAlignValT()->isImplicit()))        StdAlignValT = cast<EnumDecl>(New); @@ -13801,8 +14508,7 @@ CreateNewDecl:      // If this is an undefined enum, warn.      if (TUK != TUK_Definition && !Invalid) {        TagDecl *Def; -      if (!EnumUnderlyingIsImplicit && -          (getLangOpts().CPlusPlus11 || getLangOpts().ObjC2) && +      if (IsFixed && (getLangOpts().CPlusPlus11 || getLangOpts().ObjC2) &&            cast<EnumDecl>(New)->isFixed()) {          // C++0x: 7.2p2: opaque-enum-declaration.          // Conflicts are diagnosed above. Do nothing. @@ -13818,12 +14524,6 @@ CreateNewDecl:          else if (getLangOpts().CPlusPlus)            DiagID = diag::err_forward_ref_enum;          Diag(Loc, DiagID); - -        // If this is a forward-declared reference to an enumeration, make a -        // note of it; we won't actually be introducing the declaration into -        // the declaration context. -        if (TUK == TUK_Reference) -          IsForwardReference = true;        }      } @@ -13834,6 +14534,7 @@ CreateNewDecl:        else          ED->setIntegerType(QualType(EnumUnderlying.get<const Type*>(), 0));        ED->setPromotionType(ED->getIntegerType()); +      assert(ED->isComplete() && "enum with type should be complete");      }    } else {      // struct/union/class @@ -13872,13 +14573,10 @@ CreateNewDecl:    if (SS.isNotEmpty()) {      if (SS.isSet()) {        // If this is either a declaration or a definition, check the -      // nested-name-specifier against the current context. We don't do this -      // for explicit specializations, because they have similar checking -      // (with more specific diagnostics) in the call to -      // CheckMemberSpecialization, below. -      if (!isMemberSpecialization && -          (TUK == TUK_Definition || TUK == TUK_Declaration) && -          diagnoseQualifiedDeclaration(SS, DC, OrigName, Loc)) +      // nested-name-specifier against the current context. +      if ((TUK == TUK_Definition || TUK == TUK_Declaration) && +          diagnoseQualifiedDeclaration(SS, DC, OrigName, Loc, +                                       isMemberSpecialization))          Invalid = true;        New->setQualifierInfo(SS.getWithLocInContext(Context)); @@ -13965,8 +14663,7 @@ CreateNewDecl:    if (TUK == TUK_Definition)      New->startDefinition(); -  if (Attr) -    ProcessDeclAttributeList(S, New, Attr); +  ProcessDeclAttributeList(S, New, Attrs);    AddPragmaAttributes(S, New);    // If this has an identifier, add it to the scope stack. @@ -13983,9 +14680,7 @@ CreateNewDecl:          PushOnScopeChains(New, EnclosingScope, /* AddToContext = */ false);    } else if (Name) {      S = getNonFieldDeclScope(S); -    PushOnScopeChains(New, S, !IsForwardReference); -    if (IsForwardReference) -      SearchDC->makeDeclVisibleInContext(New); +    PushOnScopeChains(New, S, true);    } else {      CurContext->addDecl(New);    } @@ -14369,7 +15064,7 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record,    return NewFD;  } -/// \brief Build a new FieldDecl and check its well-formedness. +/// Build a new FieldDecl and check its well-formedness.  ///  /// This routine builds a new FieldDecl given the fields name, type,  /// record, etc. \p PrevDecl should refer to any previous declaration @@ -14420,6 +15115,13 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,      InvalidDecl = true;    } +  // Anonymous bit-fields cannot be cv-qualified (CWG 2229). +  if (!InvalidDecl && getLangOpts().CPlusPlus && !II && BitWidth && +      T.hasQualifiers()) { +    InvalidDecl = true; +    Diag(Loc, diag::err_anon_bitfield_qualifiers); +  } +    // C99 6.7.2.1p8: A member of a structure or union may have any type other    // than a variably modified type.    if (!InvalidDecl && T->isVariablyModifiedType()) { @@ -14752,7 +15454,7 @@ void Sema::ActOnLastBitfield(SourceLocation DeclLoc,    Decl *ivarDecl = AllIvarDecls[AllIvarDecls.size()-1];    ObjCIvarDecl *Ivar = cast<ObjCIvarDecl>(ivarDecl); -  if (!Ivar->isBitField() || Ivar->getBitWidthValue(Context) == 0) +  if (!Ivar->isBitField() || Ivar->isZeroLengthBitField(Context))      return;    ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(CurContext);    if (!ID) { @@ -14780,7 +15482,8 @@ void Sema::ActOnLastBitfield(SourceLocation DeclLoc,  void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,                         ArrayRef<Decl *> Fields, SourceLocation LBrac, -                       SourceLocation RBrac, AttributeList *Attr) { +                       SourceLocation RBrac, +                       const ParsedAttributesView &Attrs) {    assert(EnclosingDecl && "missing record or interface decl");    // If this is an Objective-C @implementation or category and we have @@ -14963,8 +15666,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,        QualType T = Context.getObjCObjectPointerType(FD->getType());        FD->setType(T);      } else if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() && -               Record && !ObjCFieldLifetimeErrReported && -               (!getLangOpts().CPlusPlus || Record->isUnion())) { +               Record && !ObjCFieldLifetimeErrReported && Record->isUnion()) {        // 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. @@ -15000,6 +15702,27 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,                 Record->setHasObjectMember(true);        }      } + +    if (Record && !getLangOpts().CPlusPlus && !FD->hasAttr<UnavailableAttr>()) { +      QualType FT = FD->getType(); +      if (FT.isNonTrivialToPrimitiveDefaultInitialize()) +        Record->setNonTrivialToPrimitiveDefaultInitialize(true); +      QualType::PrimitiveCopyKind PCK = FT.isNonTrivialToPrimitiveCopy(); +      if (PCK != QualType::PCK_Trivial && PCK != QualType::PCK_VolatileTrivial) +        Record->setNonTrivialToPrimitiveCopy(true); +      if (FT.isDestructedType()) { +        Record->setNonTrivialToPrimitiveDestroy(true); +        Record->setParamDestroyedInCallee(true); +      } + +      if (const auto *RT = FT->getAs<RecordType>()) { +        if (RT->getDecl()->getArgPassingRestrictions() == +            RecordDecl::APK_CanNeverPassInRegs) +          Record->setArgPassingRestrictions(RecordDecl::APK_CanNeverPassInRegs); +      } else if (FT.getQualifiers().getObjCLifetime() == Qualifiers::OCL_Weak) +        Record->setArgPassingRestrictions(RecordDecl::APK_CanNeverPassInRegs); +    } +      if (Record && FD->getType().isVolatileQualified())        Record->setHasVolatileMember(true);      // Keep track of the number of named members. @@ -15027,10 +15750,10 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,                                            CXXRecord->getDestructor());          } -        if (!CXXRecord->isInvalidDecl()) { -          // Add any implicitly-declared members to this class. -          AddImplicitlyDeclaredMembersToClass(CXXRecord); +        // Add any implicitly-declared members to this class. +        AddImplicitlyDeclaredMembersToClass(CXXRecord); +        if (!CXXRecord->isInvalidDecl()) {            // If we have virtual base classes, we may end up finding multiple            // final overriders for a given virtual function. Check for this            // problem now. @@ -15045,7 +15768,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,                                              SOEnd = M->second.end();                     SO != SOEnd; ++SO) {                  assert(SO->second.size() > 0 && -                       "Virtual function without overridding functions?"); +                       "Virtual function without overriding functions?");                  if (SO->second.size() == 1)                    continue; @@ -15077,6 +15800,9 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,      if (!Completed)        Record->completeDefinition(); +    // Handle attributes before checking the layout. +    ProcessDeclAttributeList(S, Record, Attrs); +      // We may have deferred checking for a deleted destructor. Check now.      if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(Record)) {        auto *Dtor = CXXRecord->getDestructor(); @@ -15119,7 +15845,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,             (NonBitFields == 0 || ZeroSize) && I != E; ++I) {          IsEmpty = false;          if (I->isUnnamedBitfield()) { -          if (I->getBitWidthValue(Context) > 0) +          if (!I->isZeroLengthBitField(Context))              ZeroSize = false;          } else {            ++NonBitFields; @@ -15207,12 +15933,9 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,        CDecl->setIvarRBraceLoc(RBrac);      }    } - -  if (Attr) -    ProcessDeclAttributeList(S, Record, Attr);  } -/// \brief Determine whether the given integral value is representable within +/// Determine whether the given integral value is representable within  /// the given type T.  static bool isRepresentableIntegerValue(ASTContext &Context,                                          llvm::APSInt &Value, @@ -15229,7 +15952,7 @@ static bool isRepresentableIntegerValue(ASTContext &Context,    return Value.getMinSignedBits() <= BitWidth;  } -// \brief Given an integral type, return the next larger integral type +// Given an integral type, return the next larger integral type  // (or a NULL type of no such type exists).  static QualType getNextLargerIntegralType(ASTContext &Context, QualType T) {    // FIXME: Int128/UInt128 support, which also needs to be introduced into @@ -15292,7 +16015,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum,                                                           &EnumVal).get())) {          // C99 6.7.2.2p2: Make sure we have an integer constant expression.        } else { -        if (Enum->isFixed()) { +        if (Enum->isComplete()) {            EltTy = Enum->getIntegerType();            // In Obj-C and Microsoft mode, require the enumeration value to be @@ -15456,7 +16179,7 @@ Sema::SkipBodyInfo Sema::shouldSkipAnonEnumBody(Scope *S, IdentifierInfo *II,  Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst,                                SourceLocation IdLoc, IdentifierInfo *Id, -                              AttributeList *Attr, +                              const ParsedAttributesView &Attrs,                                SourceLocation EqualLoc, Expr *Val) {    EnumDecl *TheEnumDecl = cast<EnumDecl>(theEnumDecl);    EnumConstantDecl *LastEnumConst = @@ -15507,7 +16230,7 @@ Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst,    }    // Process attributes. -  if (Attr) ProcessDeclAttributeList(S, New, Attr); +  ProcessDeclAttributeList(S, New, Attrs);    AddPragmaAttributes(S, New);    // Register this decl in the current scope stack. @@ -15559,39 +16282,10 @@ static bool ValidDuplicateEnum(EnumConstantDecl *ECD, EnumDecl *Enum) {    return false;  } -namespace { -struct DupKey { -  int64_t val; -  bool isTombstoneOrEmptyKey; -  DupKey(int64_t val, bool isTombstoneOrEmptyKey) -    : val(val), isTombstoneOrEmptyKey(isTombstoneOrEmptyKey) {} -}; - -static DupKey GetDupKey(const llvm::APSInt& Val) { -  return DupKey(Val.isSigned() ? Val.getSExtValue() : Val.getZExtValue(), -                false); -} - -struct DenseMapInfoDupKey { -  static DupKey getEmptyKey() { return DupKey(0, true); } -  static DupKey getTombstoneKey() { return DupKey(1, true); } -  static unsigned getHashValue(const DupKey Key) { -    return (unsigned)(Key.val * 37); -  } -  static bool isEqual(const DupKey& LHS, const DupKey& RHS) { -    return LHS.isTombstoneOrEmptyKey == RHS.isTombstoneOrEmptyKey && -           LHS.val == RHS.val; -  } -}; -} // end anonymous namespace -  // Emits a warning when an element is implicitly set a value that  // a previous element has already been set to.  static void CheckForDuplicateEnumValues(Sema &S, ArrayRef<Decl *> Elements, -                                        EnumDecl *Enum, -                                        QualType EnumType) { -  if (S.Diags.isIgnored(diag::warn_duplicate_enum_values, Enum->getLocation())) -    return; +                                        EnumDecl *Enum, QualType EnumType) {    // Avoid anonymous enums    if (!Enum->getIdentifier())      return; @@ -15600,20 +16294,28 @@ static void CheckForDuplicateEnumValues(Sema &S, ArrayRef<Decl *> Elements,    if (Enum->getNumPositiveBits() > 63 || Enum->getNumNegativeBits() > 64)      return; +  if (S.Diags.isIgnored(diag::warn_duplicate_enum_values, Enum->getLocation())) +    return; +    typedef SmallVector<EnumConstantDecl *, 3> ECDVector; -  typedef SmallVector<ECDVector *, 3> DuplicatesVector; +  typedef SmallVector<std::unique_ptr<ECDVector>, 3> DuplicatesVector;    typedef llvm::PointerUnion<EnumConstantDecl*, ECDVector*> DeclOrVector; -  typedef llvm::DenseMap<DupKey, DeclOrVector, DenseMapInfoDupKey> -          ValueToVectorMap; +  typedef llvm::DenseMap<int64_t, DeclOrVector> ValueToVectorMap; + +  // Use int64_t as a key to avoid needing special handling for DenseMap keys. +  auto EnumConstantToKey = [](const EnumConstantDecl *D) { +    llvm::APSInt Val = D->getInitVal(); +    return Val.isSigned() ? Val.getSExtValue() : Val.getZExtValue(); +  };    DuplicatesVector DupVector;    ValueToVectorMap EnumMap;    // Populate the EnumMap with all values represented by enum constants without -  // an initialier. -  for (unsigned i = 0, e = Elements.size(); i != e; ++i) { -    EnumConstantDecl *ECD = cast_or_null<EnumConstantDecl>(Elements[i]); +  // an initializer. +  for (auto *Element : Elements) { +    EnumConstantDecl *ECD = cast_or_null<EnumConstantDecl>(Element);      // Null EnumConstantDecl means a previous diagnostic has been emitted for      // this constant.  Skip this enum since it may be ill-formed. @@ -15621,45 +16323,45 @@ static void CheckForDuplicateEnumValues(Sema &S, ArrayRef<Decl *> Elements,        return;      } +    // Constants with initalizers are handled in the next loop.      if (ECD->getInitExpr())        continue; -    DupKey Key = GetDupKey(ECD->getInitVal()); -    DeclOrVector &Entry = EnumMap[Key]; - -    // First time encountering this value. -    if (Entry.isNull()) -      Entry = ECD; +    // Duplicate values are handled in the next loop. +    EnumMap.insert({EnumConstantToKey(ECD), ECD});    } +  if (EnumMap.size() == 0) +    return; +    // Create vectors for any values that has duplicates. -  for (unsigned i = 0, e = Elements.size(); i != e; ++i) { -    EnumConstantDecl *ECD = cast<EnumConstantDecl>(Elements[i]); +  for (auto *Element : Elements) { +    // The last loop returned if any constant was null. +    EnumConstantDecl *ECD = cast<EnumConstantDecl>(Element);      if (!ValidDuplicateEnum(ECD, Enum))        continue; -    DupKey Key = GetDupKey(ECD->getInitVal()); - -    DeclOrVector& Entry = EnumMap[Key]; -    if (Entry.isNull()) +    auto Iter = EnumMap.find(EnumConstantToKey(ECD)); +    if (Iter == EnumMap.end())        continue; +    DeclOrVector& Entry = Iter->second;      if (EnumConstantDecl *D = Entry.dyn_cast<EnumConstantDecl*>()) {        // Ensure constants are different.        if (D == ECD)          continue;        // Create new vector and push values onto it. -      ECDVector *Vec = new ECDVector(); +      auto Vec = llvm::make_unique<ECDVector>();        Vec->push_back(D);        Vec->push_back(ECD);        // Update entry to point to the duplicates vector. -      Entry = Vec; +      Entry = Vec.get();        // Store the vector somewhere we can consult later for quick emission of        // diagnostics. -      DupVector.push_back(Vec); +      DupVector.emplace_back(std::move(Vec));        continue;      } @@ -15672,26 +16374,21 @@ static void CheckForDuplicateEnumValues(Sema &S, ArrayRef<Decl *> Elements,    }    // Emit diagnostics. -  for (DuplicatesVector::iterator DupVectorIter = DupVector.begin(), -                                  DupVectorEnd = DupVector.end(); -       DupVectorIter != DupVectorEnd; ++DupVectorIter) { -    ECDVector *Vec = *DupVectorIter; +  for (const auto &Vec : DupVector) {      assert(Vec->size() > 1 && "ECDVector should have at least 2 elements.");      // Emit warning for one enum constant. -    ECDVector::iterator I = Vec->begin(); -    S.Diag((*I)->getLocation(), diag::warn_duplicate_enum_values) -      << (*I)->getName() << (*I)->getInitVal().toString(10) -      << (*I)->getSourceRange(); -    ++I; +    auto *FirstECD = Vec->front(); +    S.Diag(FirstECD->getLocation(), diag::warn_duplicate_enum_values) +      << FirstECD << FirstECD->getInitVal().toString(10) +      << FirstECD->getSourceRange();      // Emit one note for each of the remaining enum constants with      // the same value. -    for (ECDVector::iterator E = Vec->end(); I != E; ++I) -      S.Diag((*I)->getLocation(), diag::note_duplicate_element) -        << (*I)->getName() << (*I)->getInitVal().toString(10) -        << (*I)->getSourceRange(); -    delete Vec; +    for (auto *ECD : llvm::make_range(Vec->begin() + 1, Vec->end())) +      S.Diag(ECD->getLocation(), diag::note_duplicate_element) +        << ECD << ECD->getInitVal().toString(10) +        << ECD->getSourceRange();    }  } @@ -15725,14 +16422,12 @@ bool Sema::IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val,  }  void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, -                         Decl *EnumDeclX, -                         ArrayRef<Decl *> Elements, -                         Scope *S, AttributeList *Attr) { +                         Decl *EnumDeclX, ArrayRef<Decl *> Elements, Scope *S, +                         const ParsedAttributesView &Attrs) {    EnumDecl *Enum = cast<EnumDecl>(EnumDeclX);    QualType EnumType = Context.getTypeDeclType(Enum); -  if (Attr) -    ProcessDeclAttributeList(S, Enum, Attr); +  ProcessDeclAttributeList(S, Enum, Attrs);    if (Enum->isDependentType()) {      for (unsigned i = 0, e = Elements.size(); i != e; ++i) { @@ -15803,7 +16498,9 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange,    if (LangOpts.ShortEnums)      Packed = true; -  if (Enum->isFixed()) { +  // If the enum already has a type because it is fixed or dictated by the +  // target, promote that type instead of analyzing the enumerators. +  if (Enum->isComplete()) {      BestType = Enum->getIntegerType();      if (BestType->isPromotableIntegerType())        BestPromotionType = Context.getPromotedIntegerType(BestType); | 
