diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp | 887 |
1 files changed, 610 insertions, 277 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp index c6af2ed..89f4b3a 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp @@ -128,45 +128,85 @@ bool Sema::isSimpleTypeSpecifier(tok::TokenKind Kind) const { return false; } +namespace { +enum class UnqualifiedTypeNameLookupResult { + NotFound, + FoundNonType, + FoundType +}; +} // namespace + +/// \brief 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. +static UnqualifiedTypeNameLookupResult +lookupUnqualifiedTypeNameInBase(Sema &S, const IdentifierInfo &II, + SourceLocation NameLoc, + const CXXRecordDecl *RD) { + if (!RD->hasDefinition()) + return UnqualifiedTypeNameLookupResult::NotFound; + // Look for type decls in base classes. + UnqualifiedTypeNameLookupResult FoundTypeDecl = + UnqualifiedTypeNameLookupResult::NotFound; + for (const auto &Base : RD->bases()) { + const CXXRecordDecl *BaseRD = nullptr; + if (auto *BaseTT = Base.getType()->getAs<TagType>()) + BaseRD = BaseTT->getAsCXXRecordDecl(); + else if (auto *TST = Base.getType()->getAs<TemplateSpecializationType>()) { + // Look for type decls in dependent base classes that have known primary + // templates. + if (!TST || !TST->isDependentType()) + continue; + auto *TD = TST->getTemplateName().getAsTemplateDecl(); + if (!TD) + continue; + auto *BasePrimaryTemplate = + dyn_cast_or_null<CXXRecordDecl>(TD->getTemplatedDecl()); + if (!BasePrimaryTemplate) + continue; + BaseRD = BasePrimaryTemplate; + } + if (BaseRD) { + for (NamedDecl *ND : BaseRD->lookup(&II)) { + if (!isa<TypeDecl>(ND)) + return UnqualifiedTypeNameLookupResult::FoundNonType; + FoundTypeDecl = UnqualifiedTypeNameLookupResult::FoundType; + } + if (FoundTypeDecl == UnqualifiedTypeNameLookupResult::NotFound) { + switch (lookupUnqualifiedTypeNameInBase(S, II, NameLoc, BaseRD)) { + case UnqualifiedTypeNameLookupResult::FoundNonType: + return UnqualifiedTypeNameLookupResult::FoundNonType; + case UnqualifiedTypeNameLookupResult::FoundType: + FoundTypeDecl = UnqualifiedTypeNameLookupResult::FoundType; + break; + case UnqualifiedTypeNameLookupResult::NotFound: + break; + } + } + } + } + + return FoundTypeDecl; +} + static ParsedType recoverFromTypeInKnownDependentBase(Sema &S, const IdentifierInfo &II, SourceLocation NameLoc) { - // Find the first parent class template context, if any. - // FIXME: Perform the lookup in all enclosing class templates. + // Lookup in the parent class template context, if any. const CXXRecordDecl *RD = nullptr; - for (DeclContext *DC = S.CurContext; DC; DC = DC->getParent()) { + UnqualifiedTypeNameLookupResult FoundTypeDecl = + UnqualifiedTypeNameLookupResult::NotFound; + for (DeclContext *DC = S.CurContext; + DC && FoundTypeDecl == UnqualifiedTypeNameLookupResult::NotFound; + DC = DC->getParent()) { + // Look for type decls in dependent base classes that have known primary + // templates. RD = dyn_cast<CXXRecordDecl>(DC); if (RD && RD->getDescribedClassTemplate()) - break; + FoundTypeDecl = lookupUnqualifiedTypeNameInBase(S, II, NameLoc, RD); } - if (!RD) - return ParsedType(); - - // Look for type decls in dependent base classes that have known primary - // templates. - bool FoundTypeDecl = false; - for (const auto &Base : RD->bases()) { - auto *TST = Base.getType()->getAs<TemplateSpecializationType>(); - if (!TST || !TST->isDependentType()) - continue; - auto *TD = TST->getTemplateName().getAsTemplateDecl(); - if (!TD) - continue; - auto *BasePrimaryTemplate = - dyn_cast_or_null<CXXRecordDecl>(TD->getTemplatedDecl()); - if (!BasePrimaryTemplate) - continue; - // FIXME: Allow lookup into non-dependent bases of dependent bases, possibly - // by calling or integrating with the main LookupQualifiedName mechanism. - for (NamedDecl *ND : BasePrimaryTemplate->lookup(&II)) { - if (FoundTypeDecl) - return ParsedType(); - FoundTypeDecl = isa<TypeDecl>(ND); - if (!FoundTypeDecl) - return ParsedType(); - } - } - if (!FoundTypeDecl) + if (FoundTypeDecl != UnqualifiedTypeNameLookupResult::FoundType) return ParsedType(); // We found some types in dependent base classes. Recover as if the user @@ -1708,7 +1748,7 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID, Loc, Loc, II, R, /*TInfo=*/nullptr, SC_Extern, false, - /*hasPrototype=*/true); + R->isFunctionProtoType()); New->setImplicit(); // Create Decl objects for each parameter, adding them to the @@ -1744,11 +1784,11 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned ID, /// should not consider because they are not permitted to conflict, e.g., /// because they come from hidden sub-modules and do not refer to the same /// entity. -static void filterNonConflictingPreviousDecls(ASTContext &context, +static void filterNonConflictingPreviousDecls(Sema &S, NamedDecl *decl, LookupResult &previous){ // This is only interesting when modules are enabled. - if (!context.getLangOpts().Modules) + if (!S.getLangOpts().Modules) return; // Empty sets are uninteresting. @@ -1760,7 +1800,7 @@ static void filterNonConflictingPreviousDecls(ASTContext &context, NamedDecl *old = filter.next(); // Non-hidden declarations are never ignored. - if (!old->isHidden()) + if (S.isVisible(old)) continue; if (!old->isExternallyVisible()) @@ -1774,11 +1814,11 @@ static void filterNonConflictingPreviousDecls(ASTContext &context, /// entity if their types are the same. /// FIXME: This is notionally doing the same thing as ASTReaderDecl's /// isSameEntity. -static void filterNonConflictingPreviousTypedefDecls(ASTContext &Context, +static void filterNonConflictingPreviousTypedefDecls(Sema &S, TypedefNameDecl *Decl, LookupResult &Previous) { // This is only interesting when modules are enabled. - if (!Context.getLangOpts().Modules) + if (!S.getLangOpts().Modules) return; // Empty sets are uninteresting. @@ -1790,16 +1830,23 @@ static void filterNonConflictingPreviousTypedefDecls(ASTContext &Context, NamedDecl *Old = Filter.next(); // Non-hidden declarations are never ignored. - if (!Old->isHidden()) + if (S.isVisible(Old)) continue; // Declarations of the same entity are not ignored, even if they have // different linkages. - if (auto *OldTD = dyn_cast<TypedefNameDecl>(Old)) - if (Context.hasSameType(OldTD->getUnderlyingType(), - Decl->getUnderlyingType())) + if (auto *OldTD = dyn_cast<TypedefNameDecl>(Old)) { + if (S.Context.hasSameType(OldTD->getUnderlyingType(), + Decl->getUnderlyingType())) continue; + // If both declarations give a tag declaration a typedef name for linkage + // purposes, then they declare the same entity. + if (OldTD->getAnonDeclWithTypedefName(/*AnyRedecl*/true) && + Decl->getAnonDeclWithTypedefName()) + continue; + } + if (!Old->isExternallyVisible()) Filter.erase(); } @@ -1909,6 +1956,27 @@ void Sema::MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls) { if (Old->isInvalidDecl()) return New->setInvalidDecl(); + if (auto *OldTD = dyn_cast<TypedefNameDecl>(Old)) { + auto *OldTag = OldTD->getAnonDeclWithTypedefName(/*AnyRedecl*/true); + auto *NewTag = New->getAnonDeclWithTypedefName(); + NamedDecl *Hidden = nullptr; + if (getLangOpts().CPlusPlus && OldTag && NewTag && + OldTag->getCanonicalDecl() != NewTag->getCanonicalDecl() && + !hasVisibleDefinition(OldTag, &Hidden)) { + // There is a definition of this tag, but it is not visible. Use it + // instead of our tag. + New->setTypeForDecl(OldTD->getTypeForDecl()); + if (OldTD->isModed()) + New->setModedTypeSourceInfo(OldTD->getTypeSourceInfo(), + OldTD->getUnderlyingType()); + else + New->setTypeSourceInfo(OldTD->getTypeSourceInfo()); + + // Make the old tag definition visible. + makeMergedDefinitionVisible(Hidden, NewTag->getLocation()); + } + } + // If the typedef types are not identical, reject them in all languages and // with any extensions enabled. if (isIncompatibleTypedef(Old, New)) @@ -1978,7 +2046,6 @@ void Sema::MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls) { Diag(New->getLocation(), diag::ext_redefinition_of_typedef) << New->getDeclName(); Diag(Old->getLocation(), diag::note_previous_definition); - return; } /// DeclhasAttr - returns true if decl Declaration already has the target @@ -2643,7 +2710,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD, // UndefinedButUsed. if (!Old->isInlined() && New->isInlined() && !New->hasAttr<GNUInlineAttr>() && - (getLangOpts().CPlusPlus || !getLangOpts().GNUInline) && + !getLangOpts().GNUInline && Old->isUsed(false) && !Old->isDefined() && !New->isThisDeclarationADefinition()) UndefinedButUsed.insert(std::make_pair(Old->getCanonicalDecl(), @@ -2761,6 +2828,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD, << New << New->getType(); } Diag(OldLocation, PrevDiag) << Old << Old->getType(); + return true; // Complain if this is an explicit declaration of a special // member that was initially declared implicitly. @@ -3336,14 +3404,23 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { } // C++ doesn't have tentative definitions, so go right ahead and check here. - const VarDecl *Def; + VarDecl *Def; if (getLangOpts().CPlusPlus && New->isThisDeclarationADefinition() == VarDecl::Definition && (Def = Old->getDefinition())) { - Diag(New->getLocation(), diag::err_redefinition) << New; - Diag(Def->getLocation(), diag::note_previous_definition); - New->setInvalidDecl(); - return; + NamedDecl *Hidden = nullptr; + if (!hasVisibleDefinition(Def, &Hidden) && + (New->getDescribedVarTemplate() || + New->getNumTemplateParameterLists() || + New->getDeclContext()->isDependentContext())) { + // The previous definition is hidden, and multiple definitions are + // permitted (in separate TUs). Form another definition of it. + } else { + Diag(New->getLocation(), diag::err_redefinition) << New; + Diag(Def->getLocation(), diag::note_previous_definition); + New->setInvalidDecl(); + return; + } } if (haveIncompatibleLanguageLinkages(Old, New)) { @@ -3375,8 +3452,20 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, return ParsedFreeStandingDeclSpec(S, AS, DS, MultiTemplateParamsArg()); } -static void HandleTagNumbering(Sema &S, const TagDecl *Tag, Scope *TagScope) { - if (!S.Context.getLangOpts().CPlusPlus) +// The MS ABI changed between VS2013 and VS2015 with regard to numbers used to +// disambiguate entities defined in different scopes. +// While the VS2015 ABI fixes potential miscompiles, it is also breaks +// compatibility. +// We will pick our mangling number depending on which version of MSVC is being +// targeted. +static unsigned getMSManglingNumber(const LangOptions &LO, Scope *S) { + return LO.isCompatibleWithMSVC(LangOptions::MSVC2015) + ? S->getMSCurManglingNumber() + : S->getMSLastManglingNumber(); +} + +void Sema::handleTagNumbering(const TagDecl *Tag, Scope *TagScope) { + if (!Context.getLangOpts().CPlusPlus) return; if (isa<CXXRecordDecl>(Tag->getParent())) { @@ -3385,21 +3474,62 @@ static void HandleTagNumbering(Sema &S, const TagDecl *Tag, Scope *TagScope) { if (!Tag->getName().empty() || Tag->getTypedefNameForAnonDecl()) return; MangleNumberingContext &MCtx = - S.Context.getManglingNumberContext(Tag->getParent()); - S.Context.setManglingNumber( - Tag, MCtx.getManglingNumber(Tag, TagScope->getMSLocalManglingNumber())); + Context.getManglingNumberContext(Tag->getParent()); + Context.setManglingNumber( + Tag, MCtx.getManglingNumber( + Tag, getMSManglingNumber(getLangOpts(), TagScope))); return; } // If this tag isn't a direct child of a class, number it if it is local. Decl *ManglingContextDecl; - if (MangleNumberingContext *MCtx = - S.getCurrentMangleNumberContext(Tag->getDeclContext(), - ManglingContextDecl)) { - S.Context.setManglingNumber( - Tag, - MCtx->getManglingNumber(Tag, TagScope->getMSLocalManglingNumber())); + if (MangleNumberingContext *MCtx = getCurrentMangleNumberContext( + Tag->getDeclContext(), ManglingContextDecl)) { + Context.setManglingNumber( + Tag, MCtx->getManglingNumber( + Tag, getMSManglingNumber(getLangOpts(), TagScope))); + } +} + +void Sema::setTagNameForLinkagePurposes(TagDecl *TagFromDeclSpec, + TypedefNameDecl *NewTD) { + // Do nothing if the tag is not anonymous or already has an + // associated typedef (from an earlier typedef in this decl group). + if (TagFromDeclSpec->getIdentifier()) + return; + if (TagFromDeclSpec->getTypedefNameForAnonDecl()) + return; + + // A well-formed anonymous tag must always be a TUK_Definition. + assert(TagFromDeclSpec->isThisDeclarationADefinition()); + + // The type must match the tag exactly; no qualifiers allowed. + if (!Context.hasSameType(NewTD->getUnderlyingType(), + Context.getTagDeclType(TagFromDeclSpec))) + return; + + // If we've already computed linkage for the anonymous tag, then + // adding a typedef name for the anonymous decl can change that + // linkage, which might be a serious problem. Diagnose this as + // unsupported and ignore the typedef name. TODO: we should + // pursue this as a language defect and establish a formal rule + // for how to handle it. + if (TagFromDeclSpec->hasLinkageBeenComputed()) { + Diag(NewTD->getLocation(), diag::err_typedef_changes_linkage); + + SourceLocation tagLoc = TagFromDeclSpec->getInnerLocStart(); + tagLoc = getLocForEndOfToken(tagLoc); + + llvm::SmallString<40> textToInsert; + textToInsert += ' '; + textToInsert += NewTD->getIdentifier()->getName(); + Diag(tagLoc, diag::note_typedef_changes_linkage) + << FixItHint::CreateInsertion(tagLoc, textToInsert); + return; } + + // Otherwise, set this is the anon-decl typedef for the tag. + TagFromDeclSpec->setTypedefNameForAnonDecl(NewTD); } /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with @@ -3431,7 +3561,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, } if (Tag) { - HandleTagNumbering(*this, Tag, S); + handleTagNumbering(Tag, S); Tag->setFreeStanding(); if (Tag->isInvalidDecl()) return Tag; @@ -3471,7 +3601,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, return ActOnFriendTypeDecl(S, DS, TemplateParams); } - CXXScopeSpec &SS = DS.getTypeSpecScope(); + const CXXScopeSpec &SS = DS.getTypeSpecScope(); bool IsExplicitSpecialization = !TemplateParams.empty() && TemplateParams.back()->size() == 0; if (Tag && SS.isNotEmpty() && !Tag->isCompleteDefinition() && @@ -3498,7 +3628,8 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DS.getStorageClassSpec() != DeclSpec::SCS_typedef) { if (getLangOpts().CPlusPlus || Record->getDeclContext()->isRecord()) - return BuildAnonymousStructOrUnion(S, DS, AS, Record, Context.getPrintingPolicy()); + return BuildAnonymousStructOrUnion(S, DS, AS, Record, + Context.getPrintingPolicy()); DeclaresAnything = false; } @@ -3726,8 +3857,7 @@ static bool InjectAnonymousStructOrUnionMembers(Sema &SemaRef, Scope *S, // anonymous union is declared. unsigned OldChainingSize = Chaining.size(); if (IndirectFieldDecl *IF = dyn_cast<IndirectFieldDecl>(VD)) - for (auto *PI : IF->chain()) - Chaining.push_back(PI); + Chaining.append(IF->chain_begin(), IF->chain_end()); else Chaining.push_back(VD); @@ -4054,10 +4184,11 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, if (VarDecl *NewVD = dyn_cast<VarDecl>(Anon)) { if (getLangOpts().CPlusPlus && NewVD->isStaticLocal()) { Decl *ManglingContextDecl; - if (MangleNumberingContext *MCtx = - getCurrentMangleNumberContext(NewVD->getDeclContext(), - ManglingContextDecl)) { - Context.setManglingNumber(NewVD, MCtx->getManglingNumber(NewVD, S->getMSLocalManglingNumber())); + if (MangleNumberingContext *MCtx = getCurrentMangleNumberContext( + NewVD->getDeclContext(), ManglingContextDecl)) { + Context.setManglingNumber( + NewVD, MCtx->getManglingNumber( + NewVD, getMSManglingNumber(getLangOpts(), S))); Context.setStaticLocalNumber(NewVD, MCtx->getStaticLocalNumber(NewVD)); } } @@ -4767,6 +4898,8 @@ static QualType TryToFixInvalidVariablyModifiedType(QualType T, static void FixInvalidVariablyModifiedTypeLoc(TypeLoc SrcTL, TypeLoc DstTL) { + SrcTL = SrcTL.getUnqualifiedLoc(); + DstTL = DstTL.getUnqualifiedLoc(); if (PointerTypeLoc SrcPTL = SrcTL.getAs<PointerTypeLoc>()) { PointerTypeLoc DstPTL = DstTL.castAs<PointerTypeLoc>(); FixInvalidVariablyModifiedTypeLoc(SrcPTL.getPointeeLoc(), @@ -4823,27 +4956,13 @@ Sema::RegisterLocallyScopedExternCDecl(NamedDecl *ND, Scope *S) { return; // Note that we have a locally-scoped external with this name. - // FIXME: There can be multiple such declarations if they are functions marked - // __attribute__((overloadable)) declared in function scope in C. - LocallyScopedExternCDecls[ND->getDeclName()] = ND; + Context.getExternCContextDecl()->makeDeclVisibleInContext(ND); } NamedDecl *Sema::findLocallyScopedExternCDecl(DeclarationName Name) { - if (ExternalSource) { - // Load locally-scoped external decls from the external source. - // FIXME: This is inefficient. Maybe add a DeclContext for extern "C" decls? - SmallVector<NamedDecl *, 4> Decls; - ExternalSource->ReadLocallyScopedExternCDecls(Decls); - for (unsigned I = 0, N = Decls.size(); I != N; ++I) { - llvm::DenseMap<DeclarationName, NamedDecl *>::iterator Pos - = LocallyScopedExternCDecls.find(Decls[I]->getDeclName()); - if (Pos == LocallyScopedExternCDecls.end()) - LocallyScopedExternCDecls[Decls[I]->getDeclName()] = Decls[I]; - } - } - - NamedDecl *D = LocallyScopedExternCDecls.lookup(Name); - return D ? D->getMostRecentDecl() : nullptr; + // FIXME: We can have multiple results via __attribute__((overloadable)). + auto Result = Context.getExternCContextDecl()->lookup(Name); + return Result.empty() ? nullptr : *Result.begin(); } /// \brief Diagnose function specifiers on a declaration of an identifier that @@ -4955,7 +5074,7 @@ Sema::ActOnTypedefNameDecl(Scope *S, DeclContext *DC, TypedefNameDecl *NewTD, // in an outer scope, it isn't the same thing. FilterLookupForScope(Previous, DC, S, /*ConsiderLinkage*/false, /*AllowInlineNamespace*/false); - filterNonConflictingPreviousTypedefDecls(Context, NewTD, Previous); + filterNonConflictingPreviousTypedefDecls(*this, NewTD, Previous); if (!Previous.empty()) { Redeclaration = true; MergeTypedefNameDecl(NewTD, Previous); @@ -5102,14 +5221,27 @@ static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) { if (ND.isExternallyVisible()) { S.Diag(Attr->getLocation(), diag::err_attribute_weakref_not_static); ND.dropAttr<WeakRefAttr>(); + ND.dropAttr<AliasAttr>(); } } - // 'selectany' only applies to externally visible varable declarations. + if (auto *VD = dyn_cast<VarDecl>(&ND)) { + if (VD->hasInit()) { + if (const auto *Attr = VD->getAttr<AliasAttr>()) { + assert(VD->isThisDeclarationADefinition() && + !VD->isExternallyVisible() && "Broken AliasAttr handled late!"); + S.Diag(Attr->getLocation(), diag::err_alias_is_definition) << VD; + VD->dropAttr<AliasAttr>(); + } + } + } + + // 'selectany' only applies to externally visible variable declarations. // It does not apply to functions. if (SelectAnyAttr *Attr = ND.getAttr<SelectAnyAttr>()) { if (isa<FunctionDecl>(ND) || !ND.isExternallyVisible()) { - S.Diag(Attr->getLocation(), diag::err_attribute_selectany_non_extern_data); + S.Diag(Attr->getLocation(), + diag::err_attribute_selectany_non_extern_data); ND.dropAttr<SelectAnyAttr>(); } } @@ -5565,8 +5697,9 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, } } } else { - assert(D.getName().getKind() != UnqualifiedId::IK_TemplateId && - "should have a 'template<>' for this decl"); + assert( + (Invalid || D.getName().getKind() != UnqualifiedId::IK_TemplateId) && + "should have a 'template<>' for this decl"); } if (IsVariableTemplateSpecialization) { @@ -5627,6 +5760,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (IsLocalExternDecl) NewVD->setLocalExternDecl(); + bool EmitTLSUnsupportedError = false; if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec()) { // C++11 [dcl.stc]p4: // When thread_local is applied to a variable of block scope the @@ -5641,10 +5775,20 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(), diag::err_thread_non_global) << DeclSpec::getSpecifierName(TSCS); - else if (!Context.getTargetInfo().isTLSSupported()) - Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(), - diag::err_thread_unsupported); - else + else if (!Context.getTargetInfo().isTLSSupported()) { + if (getLangOpts().CUDA) { + // Postpone error emission until we've collected attributes required to + // figure out whether it's a host or device variable and whether the + // error should be ignored. + EmitTLSUnsupportedError = true; + // We still need to mark the variable as TLS so it shows up in AST with + // proper storage class for other tools to use even if we're not going + // to emit any code for it. + NewVD->setTSCSpec(TSCS); + } else + Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(), + diag::err_thread_unsupported); + } else NewVD->setTSCSpec(TSCS); } @@ -5693,6 +5837,9 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, ProcessDeclAttributes(S, NewVD, D); if (getLangOpts().CUDA) { + if (EmitTLSUnsupportedError && DeclAttrsMatchCUDAMode(getLangOpts(), NewVD)) + Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(), + diag::err_thread_unsupported); // CUDA B.2.5: "__shared__ and __constant__ variables have implied static // storage [duration]." if (SC == SC_None && S->getFnParent() != nullptr && @@ -5845,11 +5992,11 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (getLangOpts().CPlusPlus && NewVD->isStaticLocal()) { Decl *ManglingContextDecl; - if (MangleNumberingContext *MCtx = - getCurrentMangleNumberContext(NewVD->getDeclContext(), - ManglingContextDecl)) { + if (MangleNumberingContext *MCtx = getCurrentMangleNumberContext( + NewVD->getDeclContext(), ManglingContextDecl)) { Context.setManglingNumber( - NewVD, MCtx->getManglingNumber(NewVD, S->getMSLocalManglingNumber())); + NewVD, MCtx->getManglingNumber( + NewVD, getMSManglingNumber(getLangOpts(), S))); Context.setStaticLocalNumber(NewVD, MCtx->getStaticLocalNumber(NewVD)); } } @@ -6243,7 +6390,7 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous) { Previous.setShadowed(); // Filter out any non-conflicting previous declarations. - filterNonConflictingPreviousDecls(Context, NewVD, Previous); + filterNonConflictingPreviousDecls(*this, NewVD, Previous); if (!Previous.empty()) { MergeVarDecl(NewVD, Previous); @@ -6898,8 +7045,10 @@ static void checkIsValidOpenCLKernelParameter( // We have an error, now let's go back up through history and show where // the offending field came from - for (ArrayRef<const FieldDecl *>::const_iterator I = HistoryStack.begin() + 1, - E = HistoryStack.end(); I != E; ++I) { + for (ArrayRef<const FieldDecl *>::const_iterator + I = HistoryStack.begin() + 1, + E = HistoryStack.end(); + I != E; ++I) { const FieldDecl *OuterField = *I; S.Diag(OuterField->getLocation(), diag::note_within_field_of_type) << OuterField->getType(); @@ -7010,12 +7159,12 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // Check that we can declare a template here. if (CheckTemplateDeclScope(S, TemplateParams)) - return nullptr; + NewFD->setInvalidDecl(); // A destructor cannot be a template. if (Name.getNameKind() == DeclarationName::CXXDestructorName) { Diag(NewFD->getLocation(), diag::err_destructor_template); - return nullptr; + NewFD->setInvalidDecl(); } // If we're adding a template to a dependent context, we may need to @@ -7347,7 +7496,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, NewFD->setInvalidDecl(); } - if (D.isFunctionDefinition() && CodeSegStack.CurrentValue && + // Apply an implicit SectionAttr if #pragma code_seg is active. + if (CodeSegStack.CurrentValue && D.isFunctionDefinition() && !NewFD->hasAttr<SectionAttr>()) { NewFD->addAttr( SectionAttr::CreateImplicit(Context, SectionAttr::Declspec_allocate, @@ -7363,23 +7513,10 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // Handle attributes. ProcessDeclAttributes(S, NewFD, D); - QualType RetType = NewFD->getReturnType(); - const CXXRecordDecl *Ret = RetType->isRecordType() ? - RetType->getAsCXXRecordDecl() : RetType->getPointeeCXXRecordDecl(); - if (!NewFD->isInvalidDecl() && !NewFD->hasAttr<WarnUnusedResultAttr>() && - Ret && Ret->hasAttr<WarnUnusedResultAttr>()) { - const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD); - // Attach WarnUnusedResult to functions returning types with that attribute. - // Don't apply the attribute to that type's own non-static member functions - // (to avoid warning on things like assignment operators) - if (!MD || MD->getParent() != Ret) - NewFD->addAttr(WarnUnusedResultAttr::CreateImplicit(Context)); - } - if (getLangOpts().OpenCL) { // OpenCL v1.1 s6.5: Using an address space qualifier in a function return // type declaration will generate a compilation error. - unsigned AddressSpace = RetType.getAddressSpace(); + unsigned AddressSpace = NewFD->getReturnType().getAddressSpace(); if (AddressSpace == LangAS::opencl_local || AddressSpace == LangAS::opencl_global || AddressSpace == LangAS::opencl_constant) { @@ -7402,7 +7539,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, D.setRedeclaration(CheckFunctionDeclaration(S, NewFD, Previous, isExplicitSpecialization)); else if (!Previous.empty()) - // Make graceful recovery from an invalid redeclaration. + // Recover gracefully from an invalid redeclaration. D.setRedeclaration(true); assert((NewFD->isInvalidDecl() || !D.isRedeclaration() || Previous.getResultKind() != LookupResult::FoundOverloaded) && @@ -7543,6 +7680,9 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (!NewFD->isInvalidDecl()) D.setRedeclaration(CheckFunctionDeclaration(S, NewFD, Previous, isExplicitSpecialization)); + else if (!Previous.empty()) + // Recover gracefully from an invalid redeclaration. + D.setRedeclaration(true); } assert((NewFD->isInvalidDecl() || !D.isRedeclaration() || @@ -7799,7 +7939,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, !Previous.isShadowed(); // Filter out any non-conflicting previous declarations. - filterNonConflictingPreviousDecls(Context, NewFD, Previous); + filterNonConflictingPreviousDecls(*this, NewFD, Previous); bool Redeclaration = false; NamedDecl *OldDecl = nullptr; @@ -7854,7 +7994,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, // Check for a previous extern "C" declaration with this name. if (!Redeclaration && checkForConflictWithNonVisibleExternC(*this, NewFD, Previous)) { - filterNonConflictingPreviousDecls(Context, NewFD, Previous); + filterNonConflictingPreviousDecls(*this, NewFD, Previous); if (!Previous.empty()) { // This is an extern "C" declaration with the same name as a previous // declaration, and thus redeclares that entity... @@ -7952,28 +8092,8 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, // This needs to happen first so that 'inline' propagates. NewFD->setPreviousDeclaration(cast<FunctionDecl>(OldDecl)); - if (isa<CXXMethodDecl>(NewFD)) { - // A valid redeclaration of a C++ method must be out-of-line, - // but (unfortunately) it's not necessarily a definition - // because of templates, which means that the previous - // declaration is not necessarily from the class definition. - - // For just setting the access, that doesn't matter. - CXXMethodDecl *oldMethod = cast<CXXMethodDecl>(OldDecl); - NewFD->setAccess(oldMethod->getAccess()); - - // Update the key-function state if necessary for this ABI. - if (NewFD->isInlined() && - !Context.getTargetInfo().getCXXABI().canKeyFunctionBeInline()) { - // setNonKeyFunction needs to work with the original - // declaration from the class definition, and isVirtual() is - // just faster in that case, so map back to that now. - oldMethod = cast<CXXMethodDecl>(oldMethod->getFirstDecl()); - if (oldMethod->isVirtual()) { - Context.setNonKeyFunction(oldMethod); - } - } - } + if (isa<CXXMethodDecl>(NewFD)) + NewFD->setAccess(OldDecl->getAccess()); } } @@ -8153,6 +8273,12 @@ void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) { bool HasExtraParameters = (nparams > 3); + if (FTP->isVariadic()) { + Diag(FD->getLocation(), diag::ext_variadic_main); + // FIXME: if we had information about the location of the ellipsis, we + // could add a FixIt hint to remove it as a parameter. + } + // Darwin passes an undocumented fourth argument of type char**. If // other platforms start sprouting these, the logic below will start // getting shifty. @@ -8543,8 +8669,13 @@ namespace { diag = diag::warn_uninit_self_reference_in_reference_init; } else if (cast<VarDecl>(OrigDecl)->isStaticLocal()) { diag = diag::warn_static_self_reference_in_init; - } else { + } else if (isa<TranslationUnitDecl>(OrigDecl->getDeclContext()) || + isa<NamespaceDecl>(OrigDecl->getDeclContext()) || + DRE->getDecl()->getType()->isRecordType()) { diag = diag::warn_uninit_self_reference_in_init; + } else { + // Local variables will be handled by the CFG analysis. + return; } S.DiagRuntimeBehavior(DRE->getLocStart(), DRE, @@ -8586,7 +8717,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // If there is no declaration, there was an error parsing it. Just ignore // the initializer. if (!RealDecl || RealDecl->isInvalidDecl()) { - CorrectDelayedTyposInExpr(Init); + CorrectDelayedTyposInExpr(Init, dyn_cast_or_null<VarDecl>(RealDecl)); return; } @@ -8617,6 +8748,21 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // C++11 [decl.spec.auto]p6. Deduce the type which 'auto' stands in for. if (TypeMayContainAuto && VDecl->getType()->isUndeducedType()) { + // Attempt typo correction early so that the type of the init expression can + // be deduced based on the chosen correction:if the original init contains a + // TypoExpr. + ExprResult Res = CorrectDelayedTyposInExpr(Init, VDecl); + if (!Res.isUsable()) { + RealDecl->setInvalidDecl(); + return; + } + + if (Res.get() != Init) { + Init = Res.get(); + if (CXXDirectInit) + CXXDirectInit = dyn_cast<ParenListExpr>(Init); + } + Expr *DeduceInit = Init; // Initializer could be a C++ direct-initializer. Deduction only works if it // contains exactly one expression. @@ -8746,16 +8892,24 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, VDecl->setInvalidDecl(); } - const VarDecl *Def; + VarDecl *Def; if ((Def = VDecl->getDefinition()) && Def != VDecl) { - Diag(VDecl->getLocation(), diag::err_redefinition) - << VDecl->getDeclName(); - Diag(Def->getLocation(), diag::note_previous_definition); - VDecl->setInvalidDecl(); - return; + NamedDecl *Hidden = nullptr; + if (!hasVisibleDefinition(Def, &Hidden) && + (VDecl->getDescribedVarTemplate() || + VDecl->getNumTemplateParameterLists() || + VDecl->getDeclContext()->isDependentContext())) { + // The previous definition is hidden, and multiple definitions are + // permitted (in separate TUs). Form another definition of it. + } else { + Diag(VDecl->getLocation(), diag::err_redefinition) + << VDecl->getDeclName(); + Diag(Def->getLocation(), diag::note_previous_definition); + VDecl->setInvalidDecl(); + return; + } } - const VarDecl *PrevInit = nullptr; if (getLangOpts().CPlusPlus) { // C++ [class.static.data]p4 // If a static data member is of const integral or const @@ -8769,10 +8923,12 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // We already performed a redefinition check above, but for static // data members we also need to check whether there was an in-class // declaration with an initializer. - if (VDecl->isStaticDataMember() && VDecl->getAnyInitializer(PrevInit)) { + if (VDecl->isStaticDataMember() && VDecl->getCanonicalDecl()->hasInit()) { Diag(Init->getExprLoc(), diag::err_static_data_member_reinitialization) << VDecl->getDeclName(); - Diag(PrevInit->getInit()->getExprLoc(), diag::note_previous_initializer) << 0; + Diag(VDecl->getCanonicalDecl()->getInit()->getExprLoc(), + diag::note_previous_initializer) + << 0; return; } @@ -8829,8 +8985,8 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // Try to correct any TypoExprs in the initialization arguments. for (size_t Idx = 0; Idx < Args.size(); ++Idx) { - ExprResult Res = - CorrectDelayedTyposInExpr(Args[Idx], [this, Entity, Kind](Expr *E) { + ExprResult Res = CorrectDelayedTyposInExpr( + Args[Idx], VDecl, [this, Entity, Kind](Expr *E) { InitializationSequence Init(*this, Entity, Kind, MultiExprArg(E)); return Init.Failed() ? ExprError() : E; }); @@ -9253,6 +9409,8 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl, Var->setInvalidDecl(); return; } + } else { + return; } // The variable can not have an abstract class type. @@ -9350,8 +9508,6 @@ void Sema::ActOnCXXForRangeDecl(Decl *D) { case SC_OpenCLWorkGroupLocal: llvm_unreachable("Unexpected storage class"); } - if (VD->isConstexpr()) - Error = 5; if (Error != -1) { Diag(VD->getOuterLocStart(), diag::err_for_range_storage_class) << VD->getDeclName() << Error; @@ -9453,7 +9609,9 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { } - if (var->isThisDeclarationADefinition() && + // Apply section attributes and pragmas to global variables. + bool GlobalStorage = var->hasGlobalStorage(); + if (GlobalStorage && var->isThisDeclarationADefinition() && ActiveTemplateInstantiations.empty()) { PragmaStack<StringLiteral *> *Stack = nullptr; int SectionFlags = ASTContext::PSF_Implicit | ASTContext::PSF_Read; @@ -9466,11 +9624,11 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { Stack = &DataSegStack; SectionFlags |= ASTContext::PSF_Write; } - if (!var->hasAttr<SectionAttr>() && Stack->CurrentValue) - var->addAttr( - SectionAttr::CreateImplicit(Context, SectionAttr::Declspec_allocate, - Stack->CurrentValue->getString(), - Stack->CurrentPragmaLocation)); + if (Stack->CurrentValue && !var->hasAttr<SectionAttr>()) { + var->addAttr(SectionAttr::CreateImplicit( + Context, SectionAttr::Declspec_allocate, + Stack->CurrentValue->getString(), Stack->CurrentPragmaLocation)); + } if (const SectionAttr *SA = var->getAttr<SectionAttr>()) if (UnifySection(SA->getName(), SectionFlags, var)) var->dropAttr<SectionAttr>(); @@ -9513,7 +9671,7 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { } Expr *Init = var->getInit(); - bool IsGlobal = var->hasGlobalStorage() && !var->isStaticLocal(); + bool IsGlobal = GlobalStorage && !var->isStaticLocal(); QualType baseType = Context.getBaseElementType(type); if (!var->getDeclContext()->isDependentContext() && @@ -9625,18 +9783,6 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) { } } - if (!VD->isInvalidDecl() && - VD->isThisDeclarationADefinition() == VarDecl::TentativeDefinition) { - if (const VarDecl *Def = VD->getDefinition()) { - if (Def->hasAttr<AliasAttr>()) { - Diag(VD->getLocation(), diag::err_tentative_after_alias) - << VD->getDeclName(); - Diag(Def->getLocation(), diag::note_previous_definition); - VD->setInvalidDecl(); - } - } - } - const DeclContext *DC = VD->getDeclContext(); // If there's a #pragma GCC visibility in scope, and this isn't a class // member, set the visibility of this variable. @@ -9699,7 +9845,7 @@ Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, if (DeclSpec::isDeclRep(DS.getTypeSpecType())) { if (TagDecl *Tag = dyn_cast_or_null<TagDecl>(DS.getRepAsDecl())) { - HandleTagNumbering(*this, Tag, S); + handleTagNumbering(Tag, S); if (!Tag->hasNameForLinkage() && !Tag->hasDeclaratorForAnonDecl()) Tag->setDeclaratorForAnonDecl(FirstDeclaratorInGroup); } @@ -9766,9 +9912,12 @@ void Sema::ActOnDocumentableDecl(Decl *D) { void Sema::ActOnDocumentableDecls(ArrayRef<Decl *> Group) { // Don't parse the comment if Doxygen diagnostics are ignored. if (Group.empty() || !Group[0]) - return; + return; - if (Diags.isIgnored(diag::warn_doc_param_not_found, Group[0]->getLocation())) + if (Diags.isIgnored(diag::warn_doc_param_not_found, + Group[0]->getLocation()) && + Diags.isIgnored(diag::warn_unknown_comment_command_name, + Group[0]->getLocation())) return; if (Group.size() >= 2) { @@ -10058,7 +10207,7 @@ void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D, << " int " << FTI.Params[i].Ident->getName() << ";\n"; Diag(FTI.Params[i].IdentLoc, diag::ext_param_not_declared) << FTI.Params[i].Ident - << FixItHint::CreateInsertion(LocAfterDecls, Code.str()); + << FixItHint::CreateInsertion(LocAfterDecls, Code); // Implicitly declare the argument as type 'int' for lack of a better // type. @@ -10127,6 +10276,10 @@ static bool ShouldWarnAboutMissingPrototype(const FunctionDecl *FD, if (FD->hasAttr<OpenCLKernelAttr>()) return false; + // Don't warn on explicitly deleted functions. + if (FD->isDeleted()) + return false; + bool MissingPrototype = true; for (const FunctionDecl *Prev = FD->getPreviousDecl(); Prev; Prev = Prev->getPreviousDecl()) { @@ -10157,6 +10310,18 @@ Sema::CheckForFunctionRedefinition(FunctionDecl *FD, if (canRedefineFunction(Definition, getLangOpts())) return; + // If we don't have a visible definition of the function, and it's inline or + // a template, it's OK to form another definition of it. + // + // FIXME: Should we skip the body of the function and use the old definition + // in this case? That may be necessary for functions that return local types + // through a deduced return type, or instantiate templates with local types. + if (!hasVisibleDefinition(Definition) && + (Definition->isInlineSpecified() || + Definition->getDescribedFunctionTemplate() || + Definition->getNumTemplateParameterLists())) + return; + if (getLangOpts().GNUMode && Definition->isInlineSpecified() && Definition->getStorageClass() == SC_Extern) Diag(FD->getLocation(), diag::err_redefinition_extern_inline) @@ -10269,30 +10434,6 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { diag::err_func_def_incomplete_result)) FD->setInvalidDecl(); - // GNU warning -Wmissing-prototypes: - // Warn if a global function is defined without a previous - // prototype declaration. This warning is issued even if the - // definition itself provides a prototype. The aim is to detect - // global functions that fail to be declared in header files. - const FunctionDecl *PossibleZeroParamPrototype = nullptr; - if (ShouldWarnAboutMissingPrototype(FD, PossibleZeroParamPrototype)) { - Diag(FD->getLocation(), diag::warn_missing_prototype) << FD; - - if (PossibleZeroParamPrototype) { - // We found a declaration that is not a prototype, - // but that could be a zero-parameter prototype - if (TypeSourceInfo *TI = - PossibleZeroParamPrototype->getTypeSourceInfo()) { - TypeLoc TL = TI->getTypeLoc(); - if (FunctionNoProtoTypeLoc FTL = TL.getAs<FunctionNoProtoTypeLoc>()) - Diag(PossibleZeroParamPrototype->getLocation(), - diag::note_declaration_not_a_prototype) - << PossibleZeroParamPrototype - << FixItHint::CreateInsertion(FTL.getRParenLoc(), "void"); - } - } - } - if (FnBodyScope) PushDeclContext(FnBodyScope, FD); @@ -10321,9 +10462,9 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { I != E; ++I) { NamedDecl *D = *I; - // Some of these decls (like enums) may have been pinned to the translation unit - // for lack of a real context earlier. If so, remove from the translation unit - // and reattach to the current context. + // Some of these decls (like enums) may have been pinned to the + // translation unit for lack of a real context earlier. If so, remove + // from the translation unit and reattach to the current context. if (D->getLexicalDeclContext() == Context.getTranslationUnitDecl()) { // Is the decl actually in the context? for (const auto *DI : Context.getTranslationUnitDecl()->decls()) { @@ -10468,6 +10609,23 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, Context.adjustDeducedFunctionResultType( FD, SubstAutoType(ResultType.getType(), Context.VoidTy)); } + } else if (getLangOpts().CPlusPlus11 && isLambdaCallOperator(FD)) { + auto *LSI = getCurLambda(); + if (LSI->HasImplicitReturnType) { + deduceClosureReturnType(*LSI); + + // C++11 [expr.prim.lambda]p4: + // [...] if there are no return statements in the compound-statement + // [the deduced type is] the type void + QualType RetType = + LSI->ReturnType.isNull() ? Context.VoidTy : LSI->ReturnType; + + // Update the return type to the deduced type. + const FunctionProtoType *Proto = + FD->getType()->getAs<FunctionProtoType>(); + FD->setType(Context.getFunctionType(RetType, Proto->getParamTypes(), + Proto->getExtProtoInfo())); + } } // The only way to be included in UndefinedButUsed is if there is an @@ -10477,7 +10635,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, if (!FD->isExternallyVisible()) UndefinedButUsed.erase(FD); else if (FD->isInlined() && - (LangOpts.CPlusPlus || !LangOpts.GNUInline) && + !LangOpts.GNUInline && (!FD->getPreviousDecl()->hasAttr<GNUInlineAttr>())) UndefinedButUsed.erase(FD); } @@ -10494,7 +10652,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, if (!FD->isInvalidDecl()) { // Don't diagnose unused parameters of defaulted or deleted functions. - if (Body) + if (!FD->isDeleted() && !FD->isDefaulted()) DiagnoseUnusedParameters(FD->param_begin(), FD->param_end()); DiagnoseSizeOfParametersAndReturnValue(FD->param_begin(), FD->param_end(), FD->getReturnType(), FD); @@ -10512,7 +10670,55 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, !FD->isDependentContext()) computeNRVO(Body, getCurFunction()); } - + + // GNU warning -Wmissing-prototypes: + // Warn if a global function is defined without a previous + // prototype declaration. This warning is issued even if the + // definition itself provides a prototype. The aim is to detect + // global functions that fail to be declared in header files. + const FunctionDecl *PossibleZeroParamPrototype = nullptr; + if (ShouldWarnAboutMissingPrototype(FD, PossibleZeroParamPrototype)) { + Diag(FD->getLocation(), diag::warn_missing_prototype) << FD; + + if (PossibleZeroParamPrototype) { + // We found a declaration that is not a prototype, + // but that could be a zero-parameter prototype + if (TypeSourceInfo *TI = + PossibleZeroParamPrototype->getTypeSourceInfo()) { + TypeLoc TL = TI->getTypeLoc(); + if (FunctionNoProtoTypeLoc FTL = TL.getAs<FunctionNoProtoTypeLoc>()) + Diag(PossibleZeroParamPrototype->getLocation(), + diag::note_declaration_not_a_prototype) + << PossibleZeroParamPrototype + << FixItHint::CreateInsertion(FTL.getRParenLoc(), "void"); + } + } + } + + if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) { + const CXXMethodDecl *KeyFunction; + if (MD->isOutOfLine() && (MD = MD->getCanonicalDecl()) && + MD->isVirtual() && + (KeyFunction = Context.getCurrentKeyFunction(MD->getParent())) && + MD == KeyFunction->getCanonicalDecl()) { + // Update the key-function state if necessary for this ABI. + if (FD->isInlined() && + !Context.getTargetInfo().getCXXABI().canKeyFunctionBeInline()) { + Context.setNonKeyFunction(MD); + + // If the newly-chosen key function is already defined, then we + // need to mark the vtable as used retroactively. + KeyFunction = Context.getCurrentKeyFunction(MD->getParent()); + const FunctionDecl *Definition; + if (KeyFunction && KeyFunction->isDefined(Definition)) + MarkVTableUsed(Definition->getLocation(), MD->getParent(), true); + } else { + // We just defined they key function; mark the vtable as used. + MarkVTableUsed(FD->getLocation(), MD->getParent(), true); + } + } + } + assert((FD == getCurFunctionDecl() || getCurLambda()->CallOperator == FD) && "Function parsing confused"); } else if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(dcl)) { @@ -10561,7 +10767,8 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, if (getCurFunction()->ObjCWarnForNoInitDelegation) { // Don't issue this warning for unavaialable inits. if (!MD->isUnavailable()) - Diag(MD->getLocation(), diag::warn_objc_secondary_init_missing_init_call); + Diag(MD->getLocation(), + diag::warn_objc_secondary_init_missing_init_call); getCurFunction()->ObjCWarnForNoInitDelegation = false; } } else { @@ -10573,7 +10780,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, "handled in the block above."); // Verify and clean out per-function state. - if (Body) { + if (Body && (!FD || !FD->isDefaulted())) { // C++ constructors that have function-try-blocks can't have return // statements in the handlers of that block. (C++ [except.handle]p14) // Verify this. @@ -10623,8 +10830,9 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, } } - assert(ExprCleanupObjects.size() == ExprEvalContexts.back().NumCleanupObjects - && "Leftover temporaries in function"); + assert(ExprCleanupObjects.size() == + ExprEvalContexts.back().NumCleanupObjects && + "Leftover temporaries in function"); assert(!ExprNeedsCleanups && "Unaccounted cleanups in function"); assert(MaybeODRUseExprs.empty() && "Leftover expressions for odr-use checking"); @@ -10888,44 +11096,10 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T, case TST_union: case TST_class: { TagDecl *tagFromDeclSpec = cast<TagDecl>(D.getDeclSpec().getRepAsDecl()); - - // Do nothing if the tag is not anonymous or already has an - // associated typedef (from an earlier typedef in this decl group). - if (tagFromDeclSpec->getIdentifier()) break; - if (tagFromDeclSpec->getTypedefNameForAnonDecl()) break; - - // A well-formed anonymous tag must always be a TUK_Definition. - assert(tagFromDeclSpec->isThisDeclarationADefinition()); - - // The type must match the tag exactly; no qualifiers allowed. - if (!Context.hasSameType(T, Context.getTagDeclType(tagFromDeclSpec))) - break; - - // If we've already computed linkage for the anonymous tag, then - // adding a typedef name for the anonymous decl can change that - // linkage, which might be a serious problem. Diagnose this as - // unsupported and ignore the typedef name. TODO: we should - // pursue this as a language defect and establish a formal rule - // for how to handle it. - if (tagFromDeclSpec->hasLinkageBeenComputed()) { - Diag(D.getIdentifierLoc(), diag::err_typedef_changes_linkage); - - SourceLocation tagLoc = D.getDeclSpec().getTypeSpecTypeLoc(); - tagLoc = getLocForEndOfToken(tagLoc); - - llvm::SmallString<40> textToInsert; - textToInsert += ' '; - textToInsert += D.getIdentifier()->getName(); - Diag(tagLoc, diag::note_typedef_changes_linkage) - << FixItHint::CreateInsertion(tagLoc, textToInsert); - break; - } - - // Otherwise, set this is the anon-decl typedef for the tag. - tagFromDeclSpec->setTypedefNameForAnonDecl(NewTD); + setTagNameForLinkagePurposes(tagFromDeclSpec, NewTD); break; } - + default: break; } @@ -11146,13 +11320,16 @@ static FixItHint createFriendTagNNSFixIt(Sema &SemaRef, NamedDecl *ND, Scope *S, return FixItHint::CreateInsertion(NameLoc, Insertion); } -/// ActOnTag - This is invoked when we see 'struct foo' or 'struct {'. In the +/// \brief 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. /// -/// IsTypeSpecifier is true if this is a type-specifier (or +/// \param IsTypeSpecifier \c true if this is a type-specifier (or /// trailing-type-specifier) other than one in an alias-declaration. +/// +/// \param SkipBody If non-null, will be set to indicate if the caller should +/// skip the definition of this tag and treat it as if it were a declaration. Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, @@ -11163,7 +11340,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation ScopedEnumKWLoc, bool ScopedEnumUsesClassTag, TypeResult UnderlyingType, - bool IsTypeSpecifier) { + bool IsTypeSpecifier, SkipBodyInfo *SkipBody) { // If this is not a definition, it must have a name. IdentifierInfo *OrigName = Name; assert((Name != nullptr || TUK == TUK_Definition) && @@ -11206,7 +11383,8 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, ModulePrivateLoc, /*FriendLoc*/SourceLocation(), TemplateParameterLists.size()-1, - TemplateParameterLists.data()); + TemplateParameterLists.data(), + SkipBody); return Result.get(); } else { // The "template<>" header is extraneous. @@ -11472,6 +11650,10 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, } } + // If we have a known previous declaration to use, then use it. + if (Previous.empty() && SkipBody && SkipBody->Previous) + Previous.addDecl(SkipBody->Previous); + if (!Previous.empty()) { NamedDecl *PrevDecl = Previous.getFoundDecl(); NamedDecl *DirectPrevDecl = @@ -11589,7 +11771,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // Diagnose attempts to redefine a tag. if (TUK == TUK_Definition) { - if (TagDecl *Def = PrevTagDecl->getDefinition()) { + if (NamedDecl *Def = PrevTagDecl->getDefinition()) { // If we're defining a specialization and the previous definition // is from an implicit instantiation, don't emit an error // here; we'll catch this in the general case below. @@ -11605,7 +11787,18 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, TSK_ExplicitSpecialization; } - if (!IsExplicitSpecializationAfterInstantiation) { + NamedDecl *Hidden = nullptr; + if (SkipBody && getLangOpts().CPlusPlus && + !hasVisibleDefinition(Def, &Hidden)) { + // There is a definition of this tag, but it is not visible. We + // explicitly make use of C++'s one definition rule here, and + // assume that this definition is identical to the hidden one + // we already have. Make the existing definition visible and + // use it in place of this one. + SkipBody->ShouldSkip = true; + makeMergedDefinitionVisible(Hidden, KWLoc); + return Def; + } else if (!IsExplicitSpecializationAfterInstantiation) { // A redeclaration in function prototype scope in C isn't // visible elsewhere, so merely issue a warning. if (!getLangOpts().CPlusPlus && S->containedInPrototypeScope()) @@ -12339,8 +12532,10 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, InvalidDecl = true; bool ZeroWidth = false; + if (InvalidDecl) + BitWidth = nullptr; // If this is declared as a bit-field, check the bit-field. - if (!InvalidDecl && BitWidth) { + if (BitWidth) { BitWidth = VerifyBitField(Loc, II, T, Record->isMsStruct(Context), BitWidth, &ZeroWidth).get(); if (!BitWidth) { @@ -12354,7 +12549,8 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, if (!InvalidDecl && Mutable) { unsigned DiagID = 0; if (T->isReferenceType()) - DiagID = diag::err_mutable_reference; + DiagID = getLangOpts().MSVCCompat ? diag::ext_mutable_reference + : diag::err_mutable_reference; else if (T.isConstQualified()) DiagID = diag::err_mutable_const; @@ -12363,8 +12559,10 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, if (D && D->getDeclSpec().getStorageClassSpecLoc().isValid()) ErrLoc = D->getDeclSpec().getStorageClassSpecLoc(); Diag(ErrLoc, DiagID); - Mutable = false; - InvalidDecl = true; + if (DiagID != diag::ext_mutable_reference) { + Mutable = false; + InvalidDecl = true; + } } } @@ -13286,6 +13484,29 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum, Val, EnumVal); } +Sema::SkipBodyInfo Sema::shouldSkipAnonEnumBody(Scope *S, IdentifierInfo *II, + SourceLocation IILoc) { + if (!getLangOpts().Modules || !getLangOpts().CPlusPlus) + return SkipBodyInfo(); + + // We have an anonymous enum definition. Look up the first enumerator to + // determine if we should merge the definition with an existing one and + // skip the body. + NamedDecl *PrevDecl = LookupSingleName(S, II, IILoc, LookupOrdinaryName, + ForRedeclaration); + auto *PrevECD = dyn_cast_or_null<EnumConstantDecl>(PrevDecl); + NamedDecl *Hidden; + if (PrevECD && + !hasVisibleDefinition(cast<NamedDecl>(PrevECD->getDeclContext()), + &Hidden)) { + SkipBodyInfo Skip; + Skip.ShouldSkip = true; + Skip.Previous = Hidden; + return Skip; + } + + return SkipBodyInfo(); +} Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst, SourceLocation IdLoc, IdentifierInfo *Id, @@ -13528,6 +13749,49 @@ static void CheckForDuplicateEnumValues(Sema &S, ArrayRef<Decl *> Elements, } } +bool +Sema::IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val, + bool AllowMask) const { + FlagEnumAttr *FEAttr = ED->getAttr<FlagEnumAttr>(); + assert(FEAttr && "looking for value in non-flag enum"); + + llvm::APInt FlagMask = ~FEAttr->getFlagBits(); + unsigned Width = FlagMask.getBitWidth(); + + // We will try a zero-extended value for the regular check first. + llvm::APInt ExtVal = Val.zextOrSelf(Width); + + // A value is in a flag enum if either its bits are a subset of the enum's + // flag bits (the first condition) or we are allowing masks and the same is + // true of its complement (the second condition). When masks are allowed, we + // allow the common idiom of ~(enum1 | enum2) to be a valid enum value. + // + // While it's true that any value could be used as a mask, the assumption is + // that a mask will have all of the insignificant bits set. Anything else is + // likely a logic error. + if (!(FlagMask & ExtVal)) + return true; + + if (AllowMask) { + // Try a one-extended value instead. This can happen if the enum is wider + // than the constant used, in C with extensions to allow for wider enums. + // The mask will still have the correct behaviour, so we give the user the + // benefit of the doubt. + // + // FIXME: This heuristic can cause weird results if the enum was extended + // to a larger type and is signed, because then bit-masks of smaller types + // that get extended will fall out of range (e.g. ~0x1u). We currently don't + // detect that case and will get a false positive for it. In most cases, + // though, it can be fixed by making it a signed type (e.g. ~0x1), so it may + // be fine just to accept this as a warning. + ExtVal |= llvm::APInt::getHighBitsSet(Width, Width - Val.getBitWidth()); + if (!(FlagMask & ~ExtVal)) + return true; + } + + return false; +} + void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, SourceLocation RBraceLoc, Decl *EnumDeclX, ArrayRef<Decl *> Elements, @@ -13613,10 +13877,8 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, BestPromotionType = Context.getPromotedIntegerType(BestType); else BestPromotionType = BestType; - // We don't need to set BestWidth, because BestType is going to be the type - // of the enumerators, but we do anyway because otherwise some compilers - // warn that it might be used uninitialized. - BestWidth = CharWidth; + + BestWidth = Context.getIntWidth(BestType); } else if (NumNegativeBits) { // If there is a negative value, figure out the smallest integer type (of @@ -13681,10 +13943,15 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, } } + FlagEnumAttr *FEAttr = Enum->getAttr<FlagEnumAttr>(); + if (FEAttr) + FEAttr->getFlagBits() = llvm::APInt(BestWidth, 0); + // Loop over all of the enumerator constants, changing their types to match - // the type of the enum if needed. - for (unsigned i = 0, e = Elements.size(); i != e; ++i) { - EnumConstantDecl *ECD = cast_or_null<EnumConstantDecl>(Elements[i]); + // the type of the enum if needed. If we have a flag type, we also prepare the + // FlagBits cache. + for (auto *D : Elements) { + auto *ECD = cast_or_null<EnumConstantDecl>(D); if (!ECD) continue; // Already issued a diagnostic. // Standard C says the enumerators have int type, but we allow, as an @@ -13714,7 +13981,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, // enum-specifier, each enumerator has the type of its // enumeration. ECD->setType(EnumType); - continue; + goto flagbits; } else { NewTy = BestType; NewWidth = BestWidth; @@ -13741,8 +14008,32 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, ECD->setType(EnumType); else ECD->setType(NewTy); + +flagbits: + // Check to see if we have a constant with exactly one bit set. Note that x + // & (x - 1) will be nonzero if and only if x has more than one bit set. + if (FEAttr) { + llvm::APInt ExtVal = InitVal.zextOrSelf(BestWidth); + if (ExtVal != 0 && !(ExtVal & (ExtVal - 1))) { + FEAttr->getFlagBits() |= ExtVal; + } + } } + if (FEAttr) { + for (Decl *D : Elements) { + EnumConstantDecl *ECD = cast_or_null<EnumConstantDecl>(D); + if (!ECD) continue; // Already issued a diagnostic. + + llvm::APSInt InitVal = ECD->getInitVal(); + if (InitVal != 0 && !IsValueInFlagEnum(Enum, InitVal, true)) + Diag(ECD->getLocation(), diag::warn_flag_enum_constant_out_of_range) + << ECD << Enum; + } + } + + + Enum->completeDefinition(BestType, BestPromotionType, NumPositiveBits, NumNegativeBits); @@ -13804,6 +14095,8 @@ DeclResult Sema::ActOnModuleImport(SourceLocation AtLoc, if (!Mod) return true; + VisibleModules.setVisible(Mod, ImportLoc); + checkModuleImportContext(*this, Mod, ImportLoc, CurContext); // FIXME: we should support importing a submodule within a different submodule @@ -13839,9 +14132,46 @@ DeclResult Sema::ActOnModuleImport(SourceLocation AtLoc, void Sema::ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod) { checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext); - // FIXME: Should we synthesize an ImportDecl here? - getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, DirectiveLoc, - /*Complain=*/true); + // Determine whether we're in the #include buffer for a module. The #includes + // in that buffer do not qualify as module imports; they're just an + // implementation detail of us building the module. + // + // FIXME: Should we even get ActOnModuleInclude calls for those? + bool IsInModuleIncludes = + TUKind == TU_Module && + getSourceManager().isWrittenInMainFile(DirectiveLoc); + + // If this module import was due to an inclusion directive, create an + // implicit import declaration to capture it in the AST. + if (!IsInModuleIncludes) { + TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl(); + ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU, + DirectiveLoc, Mod, + DirectiveLoc); + TU->addDecl(ImportD); + Consumer.HandleImplicitImportDecl(ImportD); + } + + getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, DirectiveLoc); + VisibleModules.setVisible(Mod, DirectiveLoc); +} + +void Sema::ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod) { + checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext); + + if (getLangOpts().ModulesLocalVisibility) + VisibleModulesStack.push_back(std::move(VisibleModules)); + VisibleModules.setVisible(Mod, DirectiveLoc); +} + +void Sema::ActOnModuleEnd(SourceLocation DirectiveLoc, Module *Mod) { + checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext); + + if (getLangOpts().ModulesLocalVisibility) { + VisibleModules = std::move(VisibleModulesStack.back()); + VisibleModulesStack.pop_back(); + VisibleModules.setVisible(Mod, DirectiveLoc); + } } void Sema::createImplicitModuleImportForErrorRecovery(SourceLocation Loc, @@ -13858,8 +14188,8 @@ void Sema::createImplicitModuleImportForErrorRecovery(SourceLocation Loc, Consumer.HandleImplicitImportDecl(ImportD); // Make the module visible. - getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, Loc, - /*Complain=*/false); + getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, Loc); + VisibleModules.setVisible(Mod, Loc); } void Sema::ActOnPragmaRedefineExtname(IdentifierInfo* Name, @@ -13917,7 +14247,10 @@ Decl *Sema::getObjCDeclContext() const { } AvailabilityResult Sema::getCurContextAvailability() const { - const Decl *D = cast<Decl>(getCurObjCLexicalContext()); + const Decl *D = cast_or_null<Decl>(getCurObjCLexicalContext()); + if (!D) + return AR_Available; + // If we are within an Objective-C method, we should consult // both the availability of the method as well as the // enclosing class. If the class is (say) deprecated, |