diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp | 2814 |
1 files changed, 1685 insertions, 1129 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp index 328ce70..bbe6930 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp @@ -25,12 +25,14 @@ #include "clang/AST/EvaluatedExprVisitor.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/StmtCXX.h" +#include "clang/Basic/Builtins.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" -#include "clang/Lex/HeaderSearch.h" // FIXME: Sema shouldn't depend on Lex -#include "clang/Lex/ModuleLoader.h" // FIXME: Sema shouldn't depend on Lex -#include "clang/Lex/Preprocessor.h" // FIXME: Sema shouldn't depend on Lex +#include "clang/Lex/HeaderSearch.h" // TODO: Sema shouldn't depend on Lex +#include "clang/Lex/Lexer.h" // TODO: Extract static functions to fix layering. +#include "clang/Lex/ModuleLoader.h" // TODO: Sema shouldn't depend on Lex +#include "clang/Lex/Preprocessor.h" // Included for isCodeCompletionEnabled() #include "clang/Parse/ParseDiagnostic.h" #include "clang/Sema/CXXFieldCollector.h" #include "clang/Sema/DeclSpec.h" @@ -62,24 +64,29 @@ namespace { class TypeNameValidatorCCC : public CorrectionCandidateCallback { public: - TypeNameValidatorCCC(bool AllowInvalid, bool WantClass=false) - : AllowInvalidDecl(AllowInvalid), WantClassName(WantClass) { + TypeNameValidatorCCC(bool AllowInvalid, bool WantClass=false, + bool AllowTemplates=false) + : AllowInvalidDecl(AllowInvalid), WantClassName(WantClass), + AllowClassTemplates(AllowTemplates) { WantExpressionKeywords = false; WantCXXNamedCasts = false; WantRemainingKeywords = false; } - virtual bool ValidateCandidate(const TypoCorrection &candidate) { - if (NamedDecl *ND = candidate.getCorrectionDecl()) - return (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND)) && - (AllowInvalidDecl || !ND->isInvalidDecl()); - else - return !WantClassName && candidate.isKeyword(); + bool ValidateCandidate(const TypoCorrection &candidate) override { + if (NamedDecl *ND = candidate.getCorrectionDecl()) { + bool IsType = isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND); + bool AllowedTemplate = AllowClassTemplates && isa<ClassTemplateDecl>(ND); + return (IsType || AllowedTemplate) && + (AllowInvalidDecl || !ND->isInvalidDecl()); + } + return !WantClassName && candidate.isKeyword(); } private: bool AllowInvalidDecl; bool WantClassName; + bool AllowClassTemplates; }; } @@ -121,6 +128,65 @@ bool Sema::isSimpleTypeSpecifier(tok::TokenKind Kind) const { return false; } +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. + const CXXRecordDecl *RD = nullptr; + for (DeclContext *DC = S.CurContext; DC; DC = DC->getParent()) { + RD = dyn_cast<CXXRecordDecl>(DC); + if (RD && RD->getDescribedClassTemplate()) + break; + } + 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 = cast<CXXRecordDecl>(TD->getTemplatedDecl()); + // 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) + return ParsedType(); + + // We found some types in dependent base classes. Recover as if the user + // wrote 'typename MyClass::II' instead of 'II'. We'll fully resolve the + // lookup during template instantiation. + S.Diag(NameLoc, diag::ext_found_via_dependent_bases_lookup) << &II; + + ASTContext &Context = S.Context; + auto *NNS = NestedNameSpecifier::Create(Context, nullptr, false, + cast<Type>(Context.getRecordType(RD))); + QualType T = Context.getDependentNameType(ETK_Typename, NNS, &II); + + CXXScopeSpec SS; + SS.MakeTrivial(Context, NNS, SourceRange(NameLoc)); + + TypeLocBuilder Builder; + DependentNameTypeLoc DepTL = Builder.push<DependentNameTypeLoc>(T); + DepTL.setNameLoc(NameLoc); + DepTL.setElaboratedKeywordLoc(SourceLocation()); + DepTL.setQualifierLoc(SS.getWithLocInContext(Context)); + return S.CreateParsedType(T, Builder.getTypeSourceInfo(Context, T)); +} + /// \brief If the identifier refers to a type name within this scope, /// return the declaration of that type. /// @@ -137,7 +203,7 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, bool WantNontrivialTypeSourceInfo, IdentifierInfo **CorrectedII) { // Determine where we will perform name lookup. - DeclContext *LookupCtx = 0; + DeclContext *LookupCtx = nullptr; if (ObjectTypePtr) { QualType ObjectType = ObjectTypePtr.get(); if (ObjectType->isRecordType()) @@ -165,11 +231,9 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, return ActOnTypenameType(S, SourceLocation(), *SS, II, NameLoc).get(); NestedNameSpecifierLoc QualifierLoc = SS->getWithLocInContext(Context); - QualType T = - CheckTypenameType(ETK_None, SourceLocation(), QualifierLoc, - II, NameLoc); - - return ParsedType::make(T); + QualType T = CheckTypenameType(ETK_None, SourceLocation(), QualifierLoc, + II, NameLoc); + return ParsedType::make(T); } return ParsedType(); @@ -204,16 +268,25 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, } else { // Perform unqualified name lookup. LookupName(Result, S); + + // For unqualified lookup in a class template in MSVC mode, look into + // dependent base classes where the primary class template is known. + if (Result.empty() && getLangOpts().MSVCCompat && (!SS || SS->isEmpty())) { + if (ParsedType TypeInBase = + recoverFromTypeInKnownDependentBase(*this, II, NameLoc)) + return TypeInBase; + } } - - NamedDecl *IIDecl = 0; + + NamedDecl *IIDecl = nullptr; switch (Result.getResultKind()) { case LookupResult::NotFound: case LookupResult::NotFoundInCurrentInstantiation: if (CorrectedII) { TypeNameValidatorCCC Validator(true, isClassName); TypoCorrection Correction = CorrectTypo(Result.getLookupNameInfo(), - Kind, S, SS, Validator); + Kind, S, SS, Validator, + CTK_ErrorRecovery); IdentifierInfo *NewII = Correction.getCorrectionAsIdentifierInfo(); TemplateTy Template; bool MemberOfUnknownSpecialization; @@ -303,8 +376,7 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, if (TypeDecl *TD = dyn_cast<TypeDecl>(IIDecl)) { DiagnoseUseOfDecl(IIDecl, NameLoc); - if (T.isNull()) - T = Context.getTypeDeclType(TD); + T = Context.getTypeDeclType(TD); // NOTE: avoid constructing an ElaboratedType(Loc) if this is a // constructor or destructor name (in such a case, the scope specifier @@ -338,6 +410,50 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, return ParsedType::make(T); } +// Builds a fake NNS for the given decl context. +static NestedNameSpecifier * +synthesizeCurrentNestedNameSpecifier(ASTContext &Context, DeclContext *DC) { + for (;; DC = DC->getLookupParent()) { + DC = DC->getPrimaryContext(); + auto *ND = dyn_cast<NamespaceDecl>(DC); + if (ND && !ND->isInline() && !ND->isAnonymousNamespace()) + return NestedNameSpecifier::Create(Context, nullptr, ND); + else if (auto *RD = dyn_cast<CXXRecordDecl>(DC)) + return NestedNameSpecifier::Create(Context, nullptr, RD->isTemplateDecl(), + RD->getTypeForDecl()); + else if (isa<TranslationUnitDecl>(DC)) + return NestedNameSpecifier::GlobalSpecifier(Context); + } + llvm_unreachable("something isn't in TU scope?"); +} + +ParsedType Sema::ActOnDelayedDefaultTemplateArg(const IdentifierInfo &II, + SourceLocation NameLoc) { + // Accepting an undeclared identifier as a default argument for a template + // type parameter is a Microsoft extension. + Diag(NameLoc, diag::ext_ms_delayed_template_argument) << &II; + + // Build a fake DependentNameType that will perform lookup into CurContext at + // instantiation time. The name specifier isn't dependent, so template + // instantiation won't transform it. It will retry the lookup, however. + NestedNameSpecifier *NNS = + synthesizeCurrentNestedNameSpecifier(Context, CurContext); + QualType T = Context.getDependentNameType(ETK_None, NNS, &II); + + // Build type location information. We synthesized the qualifier, so we have + // to build a fake NestedNameSpecifierLoc. + NestedNameSpecifierLocBuilder NNSLocBuilder; + NNSLocBuilder.MakeTrivial(Context, NNS, SourceRange(NameLoc)); + NestedNameSpecifierLoc QualifierLoc = NNSLocBuilder.getWithLocInContext(Context); + + TypeLocBuilder Builder; + DependentNameTypeLoc DepTL = Builder.push<DependentNameTypeLoc>(T); + DepTL.setNameLoc(NameLoc); + DepTL.setElaboratedKeywordLoc(SourceLocation()); + DepTL.setQualifierLoc(QualifierLoc); + return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T)); +} + /// isTagName() - This method is called *for error recovery purposes only* /// to determine if the specified name is a valid tag name ("struct foo"). If /// so, this returns the TST for the tag corresponding to it (TST_enum, @@ -381,29 +497,29 @@ bool Sema::isMicrosoftMissingTypename(const CXXScopeSpec *SS, Scope *S) { const Type *Ty = SS->getScopeRep()->getAsType(); CXXRecordDecl *RD = cast<CXXRecordDecl>(CurContext); - for (CXXRecordDecl::base_class_const_iterator Base = RD->bases_begin(), - BaseEnd = RD->bases_end(); Base != BaseEnd; ++Base) - if (Context.hasSameUnqualifiedType(QualType(Ty, 1), Base->getType())) + for (const auto &Base : RD->bases()) + if (Context.hasSameUnqualifiedType(QualType(Ty, 1), Base.getType())) return true; return S->isFunctionPrototypeScope(); } return CurContext->isFunctionOrMethod() || S->isFunctionPrototypeScope(); } -bool Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II, +void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II, SourceLocation IILoc, Scope *S, CXXScopeSpec *SS, - ParsedType &SuggestedType) { + ParsedType &SuggestedType, + bool AllowClassTemplates) { // We don't have anything to suggest (yet). SuggestedType = ParsedType(); // There may have been a typo in the name of the type. Look up typo // results, in case we have something that we can suggest. - TypeNameValidatorCCC Validator(false); + TypeNameValidatorCCC Validator(false, false, AllowClassTemplates); if (TypoCorrection Corrected = CorrectTypo(DeclarationNameInfo(II, IILoc), LookupOrdinaryName, S, SS, - Validator)) { + Validator, CTK_ErrorRecovery)) { if (Corrected.isKeyword()) { // We corrected to a keyword. diagnoseTypo(Corrected, PDiag(diag::err_unknown_typename_suggest) << II); @@ -434,7 +550,7 @@ bool Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II, /*IsCtorOrDtorName=*/false, /*NonTrivialTypeSourceInfo=*/true); } - return true; + return; } if (getLangOpts().CPlusPlus) { @@ -453,7 +569,7 @@ bool Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II, Diag(TplDecl->getLocation(), diag::note_template_decl_here) << TplDecl->getTemplateParameters()->getSourceRange(); } - return true; + return; } } @@ -467,11 +583,11 @@ bool Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II, << II << DC << SS->getRange(); else if (isDependentScopeSpecifier(*SS)) { unsigned DiagID = diag::err_typename_missing; - if (getLangOpts().MicrosoftMode && isMicrosoftMissingTypename(SS, S)) - DiagID = diag::warn_typename_missing; + if (getLangOpts().MSVCCompat && isMicrosoftMissingTypename(SS, S)) + DiagID = diag::ext_typename_missing; Diag(SS->getRange().getBegin(), DiagID) - << (NestedNameSpecifier *)SS->getScopeRep() << II->getName() + << SS->getScopeRep() << II->getName() << SourceRange(SS->getRange().getBegin(), IILoc) << FixItHint::CreateInsertion(SS->getRange().getBegin(), "typename "); SuggestedType = ActOnTypenameType(S, SourceLocation(), @@ -480,8 +596,6 @@ bool Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II, assert(SS && SS->isInvalid() && "Invalid scope specifier has already been diagnosed"); } - - return true; } /// \brief Determine whether the given result set contains either a type name @@ -508,35 +622,30 @@ static bool isTagTypeWithMissingTag(Sema &SemaRef, LookupResult &Result, LookupResult R(SemaRef, Name, NameLoc, Sema::LookupTagName); SemaRef.LookupParsedName(R, S, &SS); if (TagDecl *Tag = R.getAsSingle<TagDecl>()) { - const char *TagName = 0; - const char *FixItTagName = 0; + StringRef FixItTagName; switch (Tag->getTagKind()) { case TTK_Class: - TagName = "class"; FixItTagName = "class "; break; case TTK_Enum: - TagName = "enum"; FixItTagName = "enum "; break; case TTK_Struct: - TagName = "struct"; FixItTagName = "struct "; break; case TTK_Interface: - TagName = "__interface"; FixItTagName = "__interface "; break; case TTK_Union: - TagName = "union"; FixItTagName = "union "; break; } + StringRef TagName = FixItTagName.drop_back(); SemaRef.Diag(NameLoc, diag::err_use_of_tag_name_without_tag) << Name << TagName << SemaRef.getLangOpts().CPlusPlus << FixItHint::CreateInsertion(NameLoc, FixItTagName); @@ -579,16 +688,23 @@ Sema::NameClassification Sema::ClassifyName(Scope *S, CorrectionCandidateCallback *CCC) { DeclarationNameInfo NameInfo(Name, NameLoc); ObjCMethodDecl *CurMethod = getCurMethodDecl(); - + if (NextToken.is(tok::coloncolon)) { BuildCXXNestedNameSpecifier(S, *Name, NameLoc, NextToken.getLocation(), - QualType(), false, SS, 0, false); - + QualType(), false, SS, nullptr, false); } - + LookupResult Result(*this, Name, NameLoc, LookupOrdinaryName); LookupParsedName(Result, S, &SS, !CurMethod); - + + // For unqualified lookup in a class template in MSVC mode, look into + // dependent base classes where the primary class template is known. + if (Result.empty() && SS.isEmpty() && getLangOpts().MSVCCompat) { + if (ParsedType TypeInBase = + recoverFromTypeInKnownDependentBase(*this, *Name, NameLoc)) + return TypeInBase; + } + // Perform lookup for Objective-C instance variables (including automatically // synthesized instance variables), if we're in an Objective-C method. // FIXME: This lookup really, really needs to be folded in to the normal @@ -646,13 +762,14 @@ Corrected: SecondTry = true; if (TypoCorrection Corrected = CorrectTypo(Result.getLookupNameInfo(), Result.getLookupKind(), S, - &SS, *CCC)) { + &SS, *CCC, + CTK_ErrorRecovery)) { unsigned UnqualifiedDiag = diag::err_undeclared_var_use_suggest; unsigned QualifiedDiag = diag::err_no_member_suggest; NamedDecl *FirstDecl = Corrected.getCorrectionDecl(); NamedDecl *UnderlyingFirstDecl - = FirstDecl? FirstDecl->getUnderlyingDecl() : 0; + = FirstDecl? FirstDecl->getUnderlyingDecl() : nullptr; if (getLangOpts().CPlusPlus && NextToken.is(tok::less) && UnderlyingFirstDecl && isa<TemplateDecl>(UnderlyingFirstDecl)) { UnqualifiedDiag = diag::err_no_template_suggest; @@ -725,7 +842,7 @@ Corrected: // keyword here. return ActOnDependentIdExpression(SS, /*TemplateKWLoc=*/SourceLocation(), NameInfo, IsAddressOfOperand, - /*TemplateArgs=*/0); + /*TemplateArgs=*/nullptr); } case LookupResult::Found: @@ -817,8 +934,8 @@ Corrected: ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(FirstDecl); if (!Class) { // FIXME: It's unfortunate that we don't have a Type node for handling this. - if (ObjCCompatibleAliasDecl *Alias - = dyn_cast<ObjCCompatibleAliasDecl>(FirstDecl)) + if (ObjCCompatibleAliasDecl *Alias = + dyn_cast<ObjCCompatibleAliasDecl>(FirstDecl)) Class = Alias->getClassInterface(); } @@ -845,7 +962,8 @@ Corrected: // seems likely a type is wanted instead of the non-type that was found. bool NextIsOp = NextToken.is(tok::amp) || NextToken.is(tok::star); if ((NextToken.is(tok::identifier) || - (NextIsOp && FirstDecl->isFunctionOrFunctionTemplate())) && + (NextIsOp && + FirstDecl->getUnderlyingDecl()->isFunctionOrFunctionTemplate())) && isTagTypeWithMissingTag(*this, Result, S, SS, Name, NameLoc)) { TypeDecl *Type = Result.getAsSingle<TypeDecl>(); DiagnoseUseOfDecl(Type, NameLoc); @@ -856,7 +974,8 @@ Corrected: } if (FirstDecl->isCXXClassMember()) - return BuildPossibleImplicitMemberExpr(SS, SourceLocation(), Result, 0); + return BuildPossibleImplicitMemberExpr(SS, SourceLocation(), Result, + nullptr); bool ADL = UseArgumentDependentLookup(SS, Result, NextToken.is(tok::l_paren)); return BuildDeclarationNameExpr(SS, Result, ADL); @@ -962,12 +1081,9 @@ void Sema::ExitDeclaratorContext(Scope *S) { void Sema::ActOnReenterFunctionContext(Scope* S, Decl *D) { - FunctionDecl *FD = dyn_cast<FunctionDecl>(D); - if (FunctionTemplateDecl *TFD = dyn_cast_or_null<FunctionTemplateDecl>(D)) { - // We assume that the caller has already called - // ActOnReenterTemplateScope - FD = TFD->getTemplatedDecl(); - } + // We assume that the caller has already called + // ActOnReenterTemplateScope so getTemplatedDecl() works. + FunctionDecl *FD = D->getAsFunction(); if (!FD) return; @@ -1086,9 +1202,8 @@ void Sema::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) { } bool Sema::isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S, - bool ExplicitInstantiationOrSpecialization) { - return IdResolver.isDeclInScope(D, Ctx, S, - ExplicitInstantiationOrSpecialization); + bool AllowInlineNamespace) { + return IdResolver.isDeclInScope(D, Ctx, S, AllowInlineNamespace); } Scope *Sema::getScopeForDeclContext(Scope *S, DeclContext *DC) { @@ -1099,7 +1214,7 @@ Scope *Sema::getScopeForDeclContext(Scope *S, DeclContext *DC) { return S; } while ((S = S->getParent())); - return 0; + return nullptr; } static bool isOutOfScopePreviousDeclaration(NamedDecl *, @@ -1108,21 +1223,19 @@ static bool isOutOfScopePreviousDeclaration(NamedDecl *, /// Filters out lookup results that don't fall within the given scope /// as determined by isDeclInScope. -void Sema::FilterLookupForScope(LookupResult &R, - DeclContext *Ctx, Scope *S, +void Sema::FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S, bool ConsiderLinkage, - bool ExplicitInstantiationOrSpecialization) { + bool AllowInlineNamespace) { LookupResult::Filter F = R.makeFilter(); while (F.hasNext()) { NamedDecl *D = F.next(); - if (isDeclInScope(D, Ctx, S, ExplicitInstantiationOrSpecialization)) + if (isDeclInScope(D, Ctx, S, AllowInlineNamespace)) continue; - if (ConsiderLinkage && - isOutOfScopePreviousDeclaration(D, Ctx, Context)) + if (ConsiderLinkage && isOutOfScopePreviousDeclaration(D, Ctx, Context)) continue; - + F.erase(); } @@ -1173,8 +1286,8 @@ static bool IsDisallowedCopyOrAssign(const CXXMethodDecl *D) { // // When we see foo we don't know if after the typedef we will get 'A' or '*A' // for example. If 'A', foo will have external linkage. If we have '*A', -// foo will have no linkage. Since we can't know untill we get to the end -// of the typedef, this function finds out if D might have non external linkage. +// foo will have no linkage. Since we can't know until we get to the end +// of the typedef, this function finds out if D might have non-external linkage. // Callers should verify at the end of the TU if it D has external linkage or // not. bool Sema::mightHaveNonExternalLinkage(const DeclaratorDecl *D) { @@ -1204,7 +1317,8 @@ bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const { if (D->isInvalidDecl() || D->isUsed() || D->hasAttr<UnusedAttr>()) return false; - // Ignore class templates. + // Ignore all entities declared within templates, and out-of-line definitions + // of members of class templates. if (D->getDeclContext()->isDependentContext() || D->getLexicalDeclContext()->isDependentContext()) return false; @@ -1218,8 +1332,7 @@ bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const { return false; } else { // 'static inline' functions are defined in headers; don't warn. - if (FD->isInlineSpecified() && - !isMainFileLoc(*this, FD->getLocation())) + if (FD->isInlined() && !isMainFileLoc(*this, FD->getLocation())) return false; } @@ -1244,6 +1357,8 @@ bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const { } // Only warn for unused decls internal to the translation unit. + // FIXME: This seems like a bogus check; it suppresses -Wunused-function + // for inline functions defined in the main source file, for instance. return mightHaveNonExternalLinkage(D); } @@ -1271,7 +1386,8 @@ static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) { if (D->isInvalidDecl()) return false; - if (D->isReferenced() || D->isUsed() || D->hasAttr<UnusedAttr>()) + if (D->isReferenced() || D->isUsed() || D->hasAttr<UnusedAttr>() || + D->hasAttr<ObjCPreciseLifetimeAttr>()) return false; if (isa<LabelDecl>(D)) @@ -1309,7 +1425,8 @@ static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) { return false; if (const Expr *Init = VD->getInit()) { - if (const ExprWithCleanups *Cleanups = dyn_cast<ExprWithCleanups>(Init)) + if (const ExprWithCleanups *Cleanups = + dyn_cast<ExprWithCleanups>(Init)) Init = Cleanups->getSubExpr(); const CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init); @@ -1344,10 +1461,10 @@ static void GenerateFixForUnusedDecl(const NamedDecl *D, ASTContext &Ctx, /// DiagnoseUnusedDecl - Emit warnings about declarations that are not used /// unless they are marked attr(unused). void Sema::DiagnoseUnusedDecl(const NamedDecl *D) { - FixItHint Hint; if (!ShouldDiagnoseUnusedDecl(D)) return; + FixItHint Hint; GenerateFixForUnusedDecl(D, Context, Hint); unsigned DiagID; @@ -1365,18 +1482,18 @@ static void CheckPoppedLabel(LabelDecl *L, Sema &S) { // Verify that we have no forward references left. If so, there was a goto // or address of a label taken, but no definition of it. Label fwd // definitions are indicated with a null substmt. - if (L->getStmt() == 0) + if (L->getStmt() == nullptr) S.Diag(L->getLocation(), diag::err_undeclared_label_use) <<L->getDeclName(); } void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { + S->mergeNRVOIntoParent(); + if (S->decl_empty()) return; assert((S->getFlags() & (Scope::DeclScope | Scope::TemplateParamScope)) && "Scope shouldn't contain decls!"); - for (Scope::decl_iterator I = S->decl_begin(), E = S->decl_end(); - I != E; ++I) { - Decl *TmpD = (*I); + for (auto *TmpD : S->decls()) { assert(TmpD && "This decl didn't get pushed??"); assert(isa<NamedDecl>(TmpD) && "Decl isn't NamedDecl?"); @@ -1395,16 +1512,6 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { // Remove this name from our lexical scope. IdResolver.RemoveDecl(D); } - DiagnoseUnusedBackingIvarInAccessor(S); -} - -void Sema::ActOnStartFunctionDeclarator() { - ++InFunctionDeclarator; -} - -void Sema::ActOnEndFunctionDeclarator() { - assert(InFunctionDeclarator); - --InFunctionDeclarator; } /// \brief Look for an Objective-C class in the translation unit. @@ -1432,8 +1539,8 @@ ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *&Id, // find an Objective-C class name. DeclFilterCCC<ObjCInterfaceDecl> Validator; if (TypoCorrection C = CorrectTypo(DeclarationNameInfo(Id, IdLoc), - LookupOrdinaryName, TUScope, NULL, - Validator)) { + LookupOrdinaryName, TUScope, nullptr, + Validator, CTK_ErrorRecovery)) { diagnoseTypo(C, PDiag(diag::err_undef_interface_suggest) << Id); IDecl = C.getCorrectionDeclAs<ObjCInterfaceDecl>(); Id = IDecl->getIdentifier(); @@ -1495,6 +1602,20 @@ static void LookupPredefedObjCSuperType(Sema &ThisSema, Scope *S, Context.setObjCSuperType(Context.getTagDeclType(TD)); } +static StringRef getHeaderName(ASTContext::GetBuiltinTypeError Error) { + switch (Error) { + case ASTContext::GE_None: + return ""; + case ASTContext::GE_Missing_stdio: + return "stdio.h"; + case ASTContext::GE_Missing_setjmp: + return "setjmp.h"; + case ASTContext::GE_Missing_ucontext: + return "ucontext.h"; + } + llvm_unreachable("unhandled error kind"); +} + /// LazilyCreateBuiltin - The specified Builtin-ID was first used at /// file scope. lazily create a decl for it. ForRedeclaration is true /// if we're creating this built-in in anticipation of redeclaring the @@ -1508,28 +1629,12 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, ASTContext::GetBuiltinTypeError Error; QualType R = Context.GetBuiltinType(BID, Error); - switch (Error) { - case ASTContext::GE_None: - // Okay - break; - - case ASTContext::GE_Missing_stdio: + if (Error) { if (ForRedeclaration) - Diag(Loc, diag::warn_implicit_decl_requires_stdio) - << Context.BuiltinInfo.GetName(BID); - return 0; - - case ASTContext::GE_Missing_setjmp: - if (ForRedeclaration) - Diag(Loc, diag::warn_implicit_decl_requires_setjmp) - << Context.BuiltinInfo.GetName(BID); - return 0; - - case ASTContext::GE_Missing_ucontext: - if (ForRedeclaration) - Diag(Loc, diag::warn_implicit_decl_requires_ucontext) - << Context.BuiltinInfo.GetName(BID); - return 0; + Diag(Loc, diag::warn_implicit_decl_requires_sysheader) + << getHeaderName(Error) + << Context.BuiltinInfo.GetName(BID); + return nullptr; } if (!ForRedeclaration && Context.BuiltinInfo.isPredefinedLibFunction(BID)) { @@ -1537,11 +1642,10 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, << Context.BuiltinInfo.GetName(BID) << R; if (Context.BuiltinInfo.getHeaderName(BID) && - Diags.getDiagnosticLevel(diag::ext_implicit_lib_function_decl, Loc) - != DiagnosticsEngine::Ignored) - Diag(Loc, diag::note_please_include_header) - << Context.BuiltinInfo.getHeaderName(BID) - << Context.BuiltinInfo.GetName(BID); + !Diags.isIgnored(diag::ext_implicit_lib_function_decl, Loc)) + Diag(Loc, diag::note_include_header_or_declare) + << Context.BuiltinInfo.getHeaderName(BID) + << Context.BuiltinInfo.GetName(BID); } DeclContext *Parent = Context.getTranslationUnitDecl(); @@ -1549,13 +1653,14 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, LinkageSpecDecl *CLinkageDecl = LinkageSpecDecl::Create(Context, Parent, Loc, Loc, LinkageSpecDecl::lang_c, false); + CLinkageDecl->setImplicit(); Parent->addDecl(CLinkageDecl); Parent = CLinkageDecl; } FunctionDecl *New = FunctionDecl::Create(Context, Parent, - Loc, Loc, II, R, /*TInfo=*/0, + Loc, Loc, II, R, /*TInfo=*/nullptr, SC_Extern, false, /*hasPrototype=*/true); @@ -1565,12 +1670,11 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, // FunctionDecl. if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(R)) { SmallVector<ParmVarDecl*, 16> Params; - for (unsigned i = 0, e = FT->getNumArgs(); i != e; ++i) { + for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) { ParmVarDecl *parm = - ParmVarDecl::Create(Context, New, SourceLocation(), - SourceLocation(), 0, - FT->getArgType(i), /*TInfo=*/0, - SC_None, 0); + ParmVarDecl::Create(Context, New, SourceLocation(), SourceLocation(), + nullptr, FT->getParamType(i), /*TInfo=*/nullptr, + SC_None, nullptr); parm->setScopeInfo(0, i); Params.push_back(parm); } @@ -1789,7 +1893,7 @@ void Sema::MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls) { Context.getSourceManager().isInSystemHeader(New->getLocation()))) return; - Diag(New->getLocation(), diag::warn_redefinition_of_typedef) + Diag(New->getLocation(), diag::ext_redefinition_of_typedef) << New->getDeclName(); Diag(Old->getLocation(), diag::note_previous_definition); return; @@ -1797,46 +1901,19 @@ void Sema::MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls) { /// DeclhasAttr - returns true if decl Declaration already has the target /// attribute. -static bool -DeclHasAttr(const Decl *D, const Attr *A) { - // There can be multiple AvailabilityAttr in a Decl. Make sure we copy - // all of them. It is mergeAvailabilityAttr in SemaDeclAttr.cpp that is - // responsible for making sure they are consistent. - const AvailabilityAttr *AA = dyn_cast<AvailabilityAttr>(A); - if (AA) - return false; - - // The following thread safety attributes can also be duplicated. - switch (A->getKind()) { - case attr::ExclusiveLocksRequired: - case attr::SharedLocksRequired: - case attr::LocksExcluded: - case attr::ExclusiveLockFunction: - case attr::SharedLockFunction: - case attr::UnlockFunction: - case attr::ExclusiveTrylockFunction: - case attr::SharedTrylockFunction: - case attr::GuardedBy: - case attr::PtGuardedBy: - case attr::AcquiredBefore: - case attr::AcquiredAfter: - return false; - default: - ; - } - +static bool DeclHasAttr(const Decl *D, const Attr *A) { const OwnershipAttr *OA = dyn_cast<OwnershipAttr>(A); const AnnotateAttr *Ann = dyn_cast<AnnotateAttr>(A); - for (Decl::attr_iterator i = D->attr_begin(), e = D->attr_end(); i != e; ++i) - if ((*i)->getKind() == A->getKind()) { + for (const auto *i : D->attrs()) + if (i->getKind() == A->getKind()) { if (Ann) { - if (Ann->getAnnotation() == cast<AnnotateAttr>(*i)->getAnnotation()) + if (Ann->getAnnotation() == cast<AnnotateAttr>(i)->getAnnotation()) return true; continue; } // FIXME: Don't hardcode this check - if (OA && isa<OwnershipAttr>(*i)) - return OA->getOwnKind() == cast<OwnershipAttr>(*i)->getOwnKind(); + if (OA && isa<OwnershipAttr>(i)) + return OA->getOwnKind() == cast<OwnershipAttr>(i)->getOwnKind(); return true; } @@ -1858,12 +1935,10 @@ static bool isAttributeTargetADefinition(Decl *D) { static bool mergeAlignedAttrs(Sema &S, NamedDecl *New, Decl *Old) { // Look for alignas attributes on Old, and pick out whichever attribute // specifies the strictest alignment requirement. - AlignedAttr *OldAlignasAttr = 0; - AlignedAttr *OldStrictestAlignAttr = 0; + AlignedAttr *OldAlignasAttr = nullptr; + AlignedAttr *OldStrictestAlignAttr = nullptr; unsigned OldAlign = 0; - for (specific_attr_iterator<AlignedAttr> - I = Old->specific_attr_begin<AlignedAttr>(), - E = Old->specific_attr_end<AlignedAttr>(); I != E; ++I) { + for (auto *I : Old->specific_attrs<AlignedAttr>()) { // FIXME: We have no way of representing inherited dependent alignments // in a case like: // template<int A, int B> struct alignas(A) X; @@ -1874,26 +1949,24 @@ static bool mergeAlignedAttrs(Sema &S, NamedDecl *New, Decl *Old) { return false; if (I->isAlignas()) - OldAlignasAttr = *I; + OldAlignasAttr = I; unsigned Align = I->getAlignment(S.Context); if (Align > OldAlign) { OldAlign = Align; - OldStrictestAlignAttr = *I; + OldStrictestAlignAttr = I; } } // Look for alignas attributes on New. - AlignedAttr *NewAlignasAttr = 0; + AlignedAttr *NewAlignasAttr = nullptr; unsigned NewAlign = 0; - for (specific_attr_iterator<AlignedAttr> - I = New->specific_attr_begin<AlignedAttr>(), - E = New->specific_attr_end<AlignedAttr>(); I != E; ++I) { + for (auto *I : New->specific_attrs<AlignedAttr>()) { if (I->isAlignmentDependent()) return false; if (I->isAlignas()) - NewAlignasAttr = *I; + NewAlignasAttr = I; unsigned Align = I->getAlignment(S.Context); if (Align > NewAlign) @@ -1939,9 +2012,9 @@ static bool mergeAlignedAttrs(Sema &S, NamedDecl *New, Decl *Old) { // specifier, any other declaration of that object shall also // have no alignment specifier. S.Diag(New->getLocation(), diag::err_alignas_missing_on_definition) - << OldAlignasAttr->isC11(); + << OldAlignasAttr; S.Diag(OldAlignasAttr->getLocation(), diag::note_alignas_on_declaration) - << OldAlignasAttr->isC11(); + << OldAlignasAttr; } bool AnyAdded = false; @@ -1966,40 +2039,46 @@ static bool mergeAlignedAttrs(Sema &S, NamedDecl *New, Decl *Old) { return AnyAdded; } -static bool mergeDeclAttribute(Sema &S, NamedDecl *D, InheritableAttr *Attr, - bool Override) { - InheritableAttr *NewAttr = NULL; +static bool mergeDeclAttribute(Sema &S, NamedDecl *D, + const InheritableAttr *Attr, bool Override) { + InheritableAttr *NewAttr = nullptr; unsigned AttrSpellingListIndex = Attr->getSpellingListIndex(); - if (AvailabilityAttr *AA = dyn_cast<AvailabilityAttr>(Attr)) + if (const auto *AA = dyn_cast<AvailabilityAttr>(Attr)) NewAttr = S.mergeAvailabilityAttr(D, AA->getRange(), AA->getPlatform(), AA->getIntroduced(), AA->getDeprecated(), AA->getObsoleted(), AA->getUnavailable(), AA->getMessage(), Override, AttrSpellingListIndex); - else if (VisibilityAttr *VA = dyn_cast<VisibilityAttr>(Attr)) + else if (const auto *VA = dyn_cast<VisibilityAttr>(Attr)) NewAttr = S.mergeVisibilityAttr(D, VA->getRange(), VA->getVisibility(), AttrSpellingListIndex); - else if (TypeVisibilityAttr *VA = dyn_cast<TypeVisibilityAttr>(Attr)) + else if (const auto *VA = dyn_cast<TypeVisibilityAttr>(Attr)) NewAttr = S.mergeTypeVisibilityAttr(D, VA->getRange(), VA->getVisibility(), AttrSpellingListIndex); - else if (DLLImportAttr *ImportA = dyn_cast<DLLImportAttr>(Attr)) + else if (const auto *ImportA = dyn_cast<DLLImportAttr>(Attr)) NewAttr = S.mergeDLLImportAttr(D, ImportA->getRange(), AttrSpellingListIndex); - else if (DLLExportAttr *ExportA = dyn_cast<DLLExportAttr>(Attr)) + else if (const auto *ExportA = dyn_cast<DLLExportAttr>(Attr)) NewAttr = S.mergeDLLExportAttr(D, ExportA->getRange(), AttrSpellingListIndex); - else if (FormatAttr *FA = dyn_cast<FormatAttr>(Attr)) + else if (const auto *FA = dyn_cast<FormatAttr>(Attr)) NewAttr = S.mergeFormatAttr(D, FA->getRange(), FA->getType(), FA->getFormatIdx(), FA->getFirstArg(), AttrSpellingListIndex); - else if (SectionAttr *SA = dyn_cast<SectionAttr>(Attr)) + else if (const auto *SA = dyn_cast<SectionAttr>(Attr)) NewAttr = S.mergeSectionAttr(D, SA->getRange(), SA->getName(), AttrSpellingListIndex); + else if (const auto *IA = dyn_cast<MSInheritanceAttr>(Attr)) + NewAttr = S.mergeMSInheritanceAttr(D, IA->getRange(), IA->getBestCase(), + AttrSpellingListIndex, + IA->getSemanticSpelling()); else if (isa<AlignedAttr>(Attr)) // AlignedAttrs are handled separately, because we need to handle all // such attributes on a declaration at the same time. - NewAttr = 0; - else if (!DeclHasAttr(D, Attr)) + NewAttr = nullptr; + else if (isa<DeprecatedAttr>(Attr) && Override) + NewAttr = nullptr; + else if (Attr->duplicatesAllowed() || !DeclHasAttr(D, Attr)) NewAttr = cast<InheritableAttr>(Attr->clone(S.Context)); if (NewAttr) { @@ -2025,16 +2104,13 @@ static const Decl *getDefinition(const Decl *D) { if (FD->isDefined(Def)) return Def; } - return NULL; + return nullptr; } static bool hasAttribute(const Decl *D, attr::Kind Kind) { - for (Decl::attr_iterator I = D->attr_begin(), E = D->attr_end(); - I != E; ++I) { - Attr *Attribute = *I; + for (const auto *Attribute : D->attrs()) if (Attribute->getKind() == Kind) return true; - } return false; } @@ -2097,9 +2173,9 @@ static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) { // specifier, any other declaration of that object shall also // have no alignment specifier. S.Diag(Def->getLocation(), diag::err_alignas_missing_on_definition) - << AA->isC11(); + << AA; S.Diag(NewAttribute->getLocation(), diag::note_alignas_on_declaration) - << AA->isC11(); + << AA; NewAttributes.erase(NewAttributes.begin() + I); --E; continue; @@ -2138,15 +2214,12 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old, // we process them. if (!foundAny) New->setAttrs(AttrVec()); - for (specific_attr_iterator<InheritableAttr> - i = Old->specific_attr_begin<InheritableAttr>(), - e = Old->specific_attr_end<InheritableAttr>(); - i != e; ++i) { + for (auto *I : Old->specific_attrs<InheritableAttr>()) { bool Override = false; // Ignore deprecated/unavailable/availability attributes if requested. - if (isa<DeprecatedAttr>(*i) || - isa<UnavailableAttr>(*i) || - isa<AvailabilityAttr>(*i)) { + if (isa<DeprecatedAttr>(I) || + isa<UnavailableAttr>(I) || + isa<AvailabilityAttr>(I)) { switch (AMK) { case AMK_None: continue; @@ -2161,10 +2234,10 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old, } // Already handled. - if (isa<UsedAttr>(*i)) + if (isa<UsedAttr>(I)) continue; - if (mergeDeclAttribute(*this, New, *i, Override)) + if (mergeDeclAttribute(*this, New, I, Override)) foundAny = true; } @@ -2183,9 +2256,9 @@ static void mergeParamDeclAttributes(ParmVarDecl *newDecl, // The first declaration of a function shall specify the // carries_dependency attribute for its declarator-id if any declaration // of the function specifies the carries_dependency attribute. - if (newDecl->hasAttr<CarriesDependencyAttr>() && - !oldDecl->hasAttr<CarriesDependencyAttr>()) { - S.Diag(newDecl->getAttr<CarriesDependencyAttr>()->getLocation(), + const CarriesDependencyAttr *CDA = newDecl->getAttr<CarriesDependencyAttr>(); + if (CDA && !oldDecl->hasAttr<CarriesDependencyAttr>()) { + S.Diag(CDA->getLocation(), diag::err_carries_dependency_missing_on_first_decl) << 1/*Param*/; // Find the first declaration of the parameter. // FIXME: Should we build redeclaration chains for function parameters? @@ -2206,12 +2279,10 @@ static void mergeParamDeclAttributes(ParmVarDecl *newDecl, // done before we process them. if (!foundAny) newDecl->setAttrs(AttrVec()); - for (specific_attr_iterator<InheritableParamAttr> - i = oldDecl->specific_attr_begin<InheritableParamAttr>(), - e = oldDecl->specific_attr_end<InheritableParamAttr>(); i != e; ++i) { - if (!DeclHasAttr(newDecl, *i)) { + for (const auto *I : oldDecl->specific_attrs<InheritableParamAttr>()) { + if (!DeclHasAttr(newDecl, I)) { InheritableAttr *newAttr = - cast<InheritableParamAttr>((*i)->clone(S.Context)); + cast<InheritableParamAttr>(I->clone(S.Context)); newAttr->setInherited(true); newDecl->addAttr(newAttr); foundAny = true; @@ -2255,6 +2326,24 @@ Sema::CXXSpecialMember Sema::getSpecialMember(const CXXMethodDecl *MD) { return Sema::CXXInvalid; } +// Determine whether the previous declaration was a definition, implicit +// declaration, or a declaration. +template <typename T> +static std::pair<diag::kind, SourceLocation> +getNoteDiagForInvalidRedeclaration(const T *Old, const T *New) { + diag::kind PrevDiag; + SourceLocation OldLocation = Old->getLocation(); + if (Old->isThisDeclarationADefinition()) + PrevDiag = diag::note_previous_definition; + else if (Old->isImplicit()) { + PrevDiag = diag::note_previous_implicit_declaration; + if (OldLocation.isInvalid()) + OldLocation = New->getLocation(); + } else + PrevDiag = diag::note_previous_declaration; + return std::make_pair(PrevDiag, OldLocation); +} + /// canRedefineFunction - checks if a function can be redefined. Currently, /// only extern inline functions can be redefined, and even then only in /// GNU89 mode. @@ -2298,15 +2387,10 @@ static bool haveIncompatibleLanguageLinkages(const T *Old, const T *New) { /// merged with. /// /// Returns true if there was an error, false otherwise. -bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S, - bool MergeTypeWithOld) { +bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD, + Scope *S, bool MergeTypeWithOld) { // Verify the old decl was also a function. - FunctionDecl *Old = 0; - if (FunctionTemplateDecl *OldFunctionTemplate - = dyn_cast<FunctionTemplateDecl>(OldD)) - Old = OldFunctionTemplate->getTemplatedDecl(); - else - Old = dyn_cast<FunctionDecl>(OldD); + FunctionDecl *Old = OldD->getAsFunction(); if (!Old) { if (UsingShadowDecl *Shadow = dyn_cast<UsingShadowDecl>(OldD)) { if (New->getFriendObjectKind()) { @@ -2318,33 +2402,44 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S, return true; } - Diag(New->getLocation(), diag::err_using_decl_conflict_reverse); - Diag(Shadow->getTargetDecl()->getLocation(), - diag::note_using_decl_target); - Diag(Shadow->getUsingDecl()->getLocation(), - diag::note_using_decl) << 0; + // C++11 [namespace.udecl]p14: + // If a function declaration in namespace scope or block scope has the + // same name and the same parameter-type-list as a function introduced + // by a using-declaration, and the declarations do not declare the same + // function, the program is ill-formed. + + // Check whether the two declarations might declare the same function. + Old = dyn_cast<FunctionDecl>(Shadow->getTargetDecl()); + if (Old && + !Old->getDeclContext()->getRedeclContext()->Equals( + New->getDeclContext()->getRedeclContext()) && + !(Old->isExternC() && New->isExternC())) + Old = nullptr; + + if (!Old) { + Diag(New->getLocation(), diag::err_using_decl_conflict_reverse); + Diag(Shadow->getTargetDecl()->getLocation(), + diag::note_using_decl_target); + Diag(Shadow->getUsingDecl()->getLocation(), diag::note_using_decl) << 0; + return true; + } + OldD = Old; + } else { + Diag(New->getLocation(), diag::err_redefinition_different_kind) + << New->getDeclName(); + Diag(OldD->getLocation(), diag::note_previous_definition); return true; } - - Diag(New->getLocation(), diag::err_redefinition_different_kind) - << New->getDeclName(); - Diag(OldD->getLocation(), diag::note_previous_definition); - return true; } // If the old declaration is invalid, just give up here. if (Old->isInvalidDecl()) return true; - // Determine whether the previous declaration was a definition, - // implicit declaration, or a declaration. diag::kind PrevDiag; - if (Old->isThisDeclarationADefinition()) - PrevDiag = diag::note_previous_definition; - else if (Old->isImplicit()) - PrevDiag = diag::note_previous_implicit_declaration; - else - PrevDiag = diag::note_previous_declaration; + SourceLocation OldLocation; + std::tie(PrevDiag, OldLocation) = + getNoteDiagForInvalidRedeclaration(Old, New); // Don't complain about this if we're in GNU89 mode and the old function // is an extern inline function. @@ -2356,11 +2451,11 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S, !New->getTemplateSpecializationInfo() && !canRedefineFunction(Old, getLangOpts())) { if (getLangOpts().MicrosoftExt) { - Diag(New->getLocation(), diag::warn_static_non_static) << New; - Diag(Old->getLocation(), PrevDiag); + Diag(New->getLocation(), diag::ext_static_non_static) << New; + Diag(OldLocation, PrevDiag); } else { Diag(New->getLocation(), diag::err_static_non_static) << New; - Diag(Old->getLocation(), PrevDiag); + Diag(OldLocation, PrevDiag); return true; } } @@ -2426,7 +2521,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S, Diag(New->getLocation(), diag::err_regparm_mismatch) << NewType->getRegParmType() << OldType->getRegParmType(); - Diag(Old->getLocation(), diag::note_previous_declaration); + Diag(OldLocation, diag::note_previous_declaration); return true; } @@ -2438,7 +2533,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S, if (OldTypeInfo.getProducesResult() != NewTypeInfo.getProducesResult()) { if (NewTypeInfo.getProducesResult()) { Diag(New->getLocation(), diag::err_returns_retained_mismatch); - Diag(Old->getLocation(), diag::note_previous_declaration); + Diag(OldLocation, diag::note_previous_declaration); return true; } @@ -2482,12 +2577,14 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S, // Redeclarations or specializations of a function or function template // with a declared return type that uses a placeholder type shall also // use that placeholder, not a deduced type. - QualType OldDeclaredReturnType = (Old->getTypeSourceInfo() - ? Old->getTypeSourceInfo()->getType()->castAs<FunctionType>() - : OldType)->getResultType(); - QualType NewDeclaredReturnType = (New->getTypeSourceInfo() - ? New->getTypeSourceInfo()->getType()->castAs<FunctionType>() - : NewType)->getResultType(); + QualType OldDeclaredReturnType = + (Old->getTypeSourceInfo() + ? Old->getTypeSourceInfo()->getType()->castAs<FunctionType>() + : OldType)->getReturnType(); + QualType NewDeclaredReturnType = + (New->getTypeSourceInfo() + ? New->getTypeSourceInfo()->getType()->castAs<FunctionType>() + : NewType)->getReturnType(); QualType ResQT; if (!Context.hasSameType(OldDeclaredReturnType, NewDeclaredReturnType) && !((NewQType->isDependentType() || OldQType->isDependentType()) && @@ -2497,23 +2594,25 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S, ResQT = Context.mergeObjCGCQualifiers(NewQType, OldQType); if (ResQT.isNull()) { if (New->isCXXClassMember() && New->isOutOfLine()) - Diag(New->getLocation(), - diag::err_member_def_does_not_match_ret_type) << New; + Diag(New->getLocation(), diag::err_member_def_does_not_match_ret_type) + << New << New->getReturnTypeSourceRange(); else - Diag(New->getLocation(), diag::err_ovl_diff_return_type); - Diag(Old->getLocation(), PrevDiag) << Old << Old->getType(); + Diag(New->getLocation(), diag::err_ovl_diff_return_type) + << New->getReturnTypeSourceRange(); + Diag(OldLocation, PrevDiag) << Old << Old->getType() + << Old->getReturnTypeSourceRange(); return true; } else NewQType = ResQT; } - QualType OldReturnType = OldType->getResultType(); - QualType NewReturnType = cast<FunctionType>(NewQType)->getResultType(); + QualType OldReturnType = OldType->getReturnType(); + QualType NewReturnType = cast<FunctionType>(NewQType)->getReturnType(); if (OldReturnType != NewReturnType) { // If this function has a deduced return type and has already been // defined, copy the deduced value from the old declaration. - AutoType *OldAT = Old->getResultType()->getContainedAutoType(); + AutoType *OldAT = Old->getReturnType()->getContainedAutoType(); if (OldAT && OldAT->isDeduced()) { New->setType( SubstAutoType(New->getType(), @@ -2533,8 +2632,8 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S, NewMethod->setTrivial(OldMethod->isTrivial()); // MSVC allows explicit template specialization at class scope: - // 2 CXMethodDecls referring to the same function will be injected. - // We don't want a redeclartion error. + // 2 CXXMethodDecls referring to the same function will be injected. + // We don't want a redeclaration error. bool IsClassScopeExplicitSpecialization = OldMethod->isFunctionTemplateSpecialization() && NewMethod->isFunctionTemplateSpecialization(); @@ -2547,7 +2646,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S, // is a static member function declaration. if (OldMethod->isStatic() != NewMethod->isStatic()) { Diag(New->getLocation(), diag::err_ovl_static_nonstatic_member); - Diag(Old->getLocation(), PrevDiag) << Old << Old->getType(); + Diag(OldLocation, PrevDiag) << Old << Old->getType(); return true; } @@ -2571,7 +2670,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S, Diag(New->getLocation(), diag::err_member_redeclared_in_instantiation) << New << New->getType(); } - Diag(Old->getLocation(), PrevDiag) << Old << Old->getType(); + Diag(OldLocation, PrevDiag) << Old << Old->getType(); // Complain if this is an explicit declaration of a special // member that was initially declared implicitly. @@ -2599,10 +2698,9 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S, // The first declaration of a function shall specify the noreturn // attribute if any declaration of that function specifies the noreturn // attribute. - if (New->hasAttr<CXX11NoReturnAttr>() && - !Old->hasAttr<CXX11NoReturnAttr>()) { - Diag(New->getAttr<CXX11NoReturnAttr>()->getLocation(), - diag::err_noreturn_missing_on_first_decl); + const CXX11NoReturnAttr *NRA = New->getAttr<CXX11NoReturnAttr>(); + if (NRA && !Old->hasAttr<CXX11NoReturnAttr>()) { + Diag(NRA->getLocation(), diag::err_noreturn_missing_on_first_decl); Diag(Old->getFirstDecl()->getLocation(), diag::note_noreturn_missing_first_decl); } @@ -2611,9 +2709,9 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S, // The first declaration of a function shall specify the // carries_dependency attribute for its declarator-id if any declaration // of the function specifies the carries_dependency attribute. - if (New->hasAttr<CarriesDependencyAttr>() && - !Old->hasAttr<CarriesDependencyAttr>()) { - Diag(New->getAttr<CarriesDependencyAttr>()->getLocation(), + const CarriesDependencyAttr *CDA = New->getAttr<CarriesDependencyAttr>(); + if (CDA && !Old->hasAttr<CarriesDependencyAttr>()) { + Diag(CDA->getLocation(), diag::err_carries_dependency_missing_on_first_decl) << 0/*Function*/; Diag(Old->getFirstDecl()->getLocation(), diag::note_carries_dependency_missing_first_decl) << 0/*Function*/; @@ -2645,10 +2743,10 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S, // Check cautiously as the friend object kind isn't yet complete. if (New->getFriendObjectKind() != Decl::FOK_None) { Diag(New->getLocation(), diag::ext_retained_language_linkage) << New; - Diag(Old->getLocation(), PrevDiag); + Diag(OldLocation, PrevDiag); } else { Diag(New->getLocation(), diag::err_different_language_linkage) << New; - Diag(Old->getLocation(), PrevDiag); + Diag(OldLocation, PrevDiag); return true; } } @@ -2673,32 +2771,26 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S, Context.typesAreCompatible(OldQType, NewQType)) { const FunctionType *OldFuncType = OldQType->getAs<FunctionType>(); const FunctionType *NewFuncType = NewQType->getAs<FunctionType>(); - const FunctionProtoType *OldProto = 0; + const FunctionProtoType *OldProto = nullptr; if (MergeTypeWithOld && isa<FunctionNoProtoType>(NewFuncType) && (OldProto = dyn_cast<FunctionProtoType>(OldFuncType))) { // The old declaration provided a function prototype, but the // new declaration does not. Merge in the prototype. assert(!OldProto->hasExceptionSpec() && "Exception spec in C"); - SmallVector<QualType, 16> ParamTypes(OldProto->arg_type_begin(), - OldProto->arg_type_end()); - NewQType = Context.getFunctionType(NewFuncType->getResultType(), - ParamTypes, - OldProto->getExtProtoInfo()); + SmallVector<QualType, 16> ParamTypes(OldProto->param_types()); + NewQType = + Context.getFunctionType(NewFuncType->getReturnType(), ParamTypes, + OldProto->getExtProtoInfo()); New->setType(NewQType); New->setHasInheritedPrototype(); - // Synthesize a parameter for each argument type. + // Synthesize parameters with the same types. SmallVector<ParmVarDecl*, 16> Params; - for (FunctionProtoType::arg_type_iterator - ParamType = OldProto->arg_type_begin(), - ParamEnd = OldProto->arg_type_end(); - ParamType != ParamEnd; ++ParamType) { - ParmVarDecl *Param = ParmVarDecl::Create(Context, New, - SourceLocation(), - SourceLocation(), 0, - *ParamType, /*TInfo=*/0, - SC_None, - 0); + for (const auto &ParamType : OldProto->param_types()) { + ParmVarDecl *Param = ParmVarDecl::Create(Context, New, SourceLocation(), + SourceLocation(), nullptr, + ParamType, /*TInfo=*/nullptr, + SC_None, nullptr); Param->setScopeInfo(0, Params.size()); Param->setImplicit(); Params.push_back(Param); @@ -2733,21 +2825,21 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S, = New->getType()->getAs<FunctionProtoType>(); // Determine whether this is the GNU C extension. - QualType MergedReturn = Context.mergeTypes(OldProto->getResultType(), - NewProto->getResultType()); + QualType MergedReturn = Context.mergeTypes(OldProto->getReturnType(), + NewProto->getReturnType()); bool LooseCompatible = !MergedReturn.isNull(); for (unsigned Idx = 0, End = Old->getNumParams(); LooseCompatible && Idx != End; ++Idx) { ParmVarDecl *OldParm = Old->getParamDecl(Idx); ParmVarDecl *NewParm = New->getParamDecl(Idx); if (Context.typesAreCompatible(OldParm->getType(), - NewProto->getArgType(Idx))) { + NewProto->getParamType(Idx))) { ArgTypes.push_back(NewParm->getType()); } else if (Context.typesAreCompatible(OldParm->getType(), NewParm->getType(), /*CompareUnqualified=*/true)) { - GNUCompatibleParamWarning Warn - = { OldParm, NewParm, NewProto->getArgType(Idx) }; + GNUCompatibleParamWarning Warn = { OldParm, NewParm, + NewProto->getParamType(Idx) }; Warnings.push_back(Warn); ArgTypes.push_back(NewParm->getType()); } else @@ -2785,7 +2877,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S, // or 'printf', just warn about the incompatible redeclaration. if (Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) { Diag(New->getLocation(), diag::warn_redecl_library_builtin) << New; - Diag(Old->getLocation(), diag::note_previous_builtin_declaration) + Diag(OldLocation, diag::note_previous_builtin_declaration) << Old << Old->getType(); // If this is a global redeclaration, just forget hereafter @@ -2806,7 +2898,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S, } Diag(New->getLocation(), diag::err_conflicting_types) << New->getDeclName(); - Diag(Old->getLocation(), PrevDiag) << Old << Old->getType(); + Diag(OldLocation, PrevDiag) << Old << Old->getType(); return true; } @@ -3003,14 +3095,17 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { if (New->isInvalidDecl()) return; + VarTemplateDecl *NewTemplate = New->getDescribedVarTemplate(); + // Verify the old decl was also a variable or variable template. - VarDecl *Old = 0; - if (Previous.isSingleResult() && - (Old = dyn_cast<VarDecl>(Previous.getFoundDecl()))) { - if (New->getDescribedVarTemplate()) - Old = Old->getDescribedVarTemplate() ? Old : 0; - else - Old = Old->getDescribedVarTemplate() ? 0 : Old; + VarDecl *Old = nullptr; + VarTemplateDecl *OldTemplate = nullptr; + if (Previous.isSingleResult()) { + if (NewTemplate) { + OldTemplate = dyn_cast<VarTemplateDecl>(Previous.getFoundDecl()); + Old = OldTemplate ? OldTemplate->getTemplatedDecl() : nullptr; + } else + Old = dyn_cast<VarDecl>(Previous.getFoundDecl()); } if (!Old) { Diag(New->getLocation(), diag::err_redefinition_different_kind) @@ -3023,6 +3118,13 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { if (!shouldLinkPossiblyHiddenDecl(Old, New)) return; + // Ensure the template parameters are compatible. + if (NewTemplate && + !TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(), + OldTemplate->getTemplateParameters(), + /*Complain=*/true, TPL_TemplateMatch)) + return; + // C++ [class.mem]p1: // A member shall not be declared twice in the member-specification [...] // @@ -3037,9 +3139,9 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { mergeDeclAttributes(New, Old); // Warn if an already-declared variable is made a weak_import in a subsequent // declaration - if (New->getAttr<WeakImportAttr>() && + if (New->hasAttr<WeakImportAttr>() && Old->getStorageClass() == SC_None && - !Old->getAttr<WeakImportAttr>()) { + !Old->hasAttr<WeakImportAttr>()) { Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName(); Diag(Old->getLocation(), diag::note_previous_definition); // Remove weak_import attribute on new declaration. @@ -3052,13 +3154,25 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { if (New->isInvalidDecl()) return; + diag::kind PrevDiag; + SourceLocation OldLocation; + std::tie(PrevDiag, OldLocation) = + getNoteDiagForInvalidRedeclaration(Old, New); + // [dcl.stc]p8: Check if we have a non-static decl followed by a static. if (New->getStorageClass() == SC_Static && !New->isStaticDataMember() && Old->hasExternalFormalLinkage()) { - Diag(New->getLocation(), diag::err_static_non_static) << New->getDeclName(); - Diag(Old->getLocation(), diag::note_previous_definition); - return New->setInvalidDecl(); + if (getLangOpts().MicrosoftExt) { + Diag(New->getLocation(), diag::ext_static_non_static) + << New->getDeclName(); + Diag(OldLocation, PrevDiag); + } else { + Diag(New->getLocation(), diag::err_static_non_static) + << New->getDeclName(); + Diag(OldLocation, PrevDiag); + return New->setInvalidDecl(); + } } // C99 6.2.2p4: // For an identifier declared with the storage-class specifier @@ -3075,7 +3189,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { !New->isStaticDataMember() && Old->getCanonicalDecl()->getStorageClass() == SC_Static) { Diag(New->getLocation(), diag::err_non_static_static) << New->getDeclName(); - Diag(Old->getLocation(), diag::note_previous_definition); + Diag(OldLocation, PrevDiag); return New->setInvalidDecl(); } @@ -3083,13 +3197,13 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { if (New->hasExternalStorage() && !Old->hasLinkage() && Old->isLocalVarDecl()) { Diag(New->getLocation(), diag::err_extern_non_extern) << New->getDeclName(); - Diag(Old->getLocation(), diag::note_previous_definition); + Diag(OldLocation, PrevDiag); return New->setInvalidDecl(); } if (Old->hasLinkage() && New->isLocalVarDecl() && !New->hasExternalStorage()) { Diag(New->getLocation(), diag::err_non_extern_extern) << New->getDeclName(); - Diag(Old->getLocation(), diag::note_previous_definition); + Diag(OldLocation, PrevDiag); return New->setInvalidDecl(); } @@ -3102,17 +3216,17 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { !(Old->getLexicalDeclContext()->isRecord() && !New->getLexicalDeclContext()->isRecord())) { Diag(New->getLocation(), diag::err_redefinition) << New->getDeclName(); - Diag(Old->getLocation(), diag::note_previous_definition); + Diag(OldLocation, PrevDiag); return New->setInvalidDecl(); } if (New->getTLSKind() != Old->getTLSKind()) { if (!Old->getTLSKind()) { Diag(New->getLocation(), diag::err_thread_non_thread) << New->getDeclName(); - Diag(Old->getLocation(), diag::note_previous_declaration); + Diag(OldLocation, PrevDiag); } else if (!New->getTLSKind()) { Diag(New->getLocation(), diag::err_non_thread_thread) << New->getDeclName(); - Diag(Old->getLocation(), diag::note_previous_declaration); + Diag(OldLocation, PrevDiag); } else { // Do not allow redeclaration to change the variable between requiring // static and dynamic initialization. @@ -3120,7 +3234,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { // declaration to determine the kind. Do we need to be compatible here? Diag(New->getLocation(), diag::err_thread_thread_different_kind) << New->getDeclName() << (New->getTLSKind() == VarDecl::TLS_Dynamic); - Diag(Old->getLocation(), diag::note_previous_declaration); + Diag(OldLocation, PrevDiag); } } @@ -3137,7 +3251,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { if (haveIncompatibleLanguageLinkages(Old, New)) { Diag(New->getLocation(), diag::err_different_language_linkage) << New; - Diag(Old->getLocation(), diag::note_previous_definition); + Diag(OldLocation, PrevDiag); New->setInvalidDecl(); return; } @@ -3148,14 +3262,13 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { // Keep a chain of previous declarations. New->setPreviousDecl(Old); + if (NewTemplate) + NewTemplate->setPreviousDecl(OldTemplate); // Inherit access appropriately. New->setAccess(Old->getAccess()); - - if (VarTemplateDecl *VTD = New->getDescribedVarTemplate()) { - if (New->isStaticDataMember() && New->isOutOfLine()) - VTD->setAccess(New->getAccess()); - } + if (NewTemplate) + NewTemplate->setAccess(New->getAccess()); } /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with @@ -3165,7 +3278,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, return ParsedFreeStandingDeclSpec(S, AS, DS, MultiTemplateParamsArg()); } -static void HandleTagNumbering(Sema &S, const TagDecl *Tag) { +static void HandleTagNumbering(Sema &S, const TagDecl *Tag, Scope *TagScope) { if (!S.Context.getLangOpts().CPlusPlus) return; @@ -3176,7 +3289,8 @@ static void HandleTagNumbering(Sema &S, const TagDecl *Tag) { return; MangleNumberingContext &MCtx = S.Context.getManglingNumberContext(Tag->getParent()); - S.Context.setManglingNumber(Tag, MCtx.getManglingNumber(Tag)); + S.Context.setManglingNumber( + Tag, MCtx.getManglingNumber(Tag, TagScope->getMSLocalManglingNumber())); return; } @@ -3185,7 +3299,9 @@ static void HandleTagNumbering(Sema &S, const TagDecl *Tag) { if (MangleNumberingContext *MCtx = S.getCurrentMangleNumberContext(Tag->getDeclContext(), ManglingContextDecl)) { - S.Context.setManglingNumber(Tag, MCtx->getManglingNumber(Tag)); + S.Context.setManglingNumber( + Tag, + MCtx->getManglingNumber(Tag, TagScope->getMSLocalManglingNumber())); } } @@ -3196,8 +3312,8 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS, MultiTemplateParamsArg TemplateParams, bool IsExplicitInstantiation) { - Decl *TagD = 0; - TagDecl *Tag = 0; + Decl *TagD = nullptr; + TagDecl *Tag = nullptr; if (DS.getTypeSpecType() == DeclSpec::TST_class || DS.getTypeSpecType() == DeclSpec::TST_struct || DS.getTypeSpecType() == DeclSpec::TST_interface || @@ -3206,7 +3322,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, TagD = DS.getRepAsDecl(); if (!TagD) // We probably had an error - return 0; + return nullptr; // Note that the above type specs guarantee that the // type rep is a Decl, whereas in many of the others @@ -3218,7 +3334,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, } if (Tag) { - HandleTagNumbering(*this, Tag); + HandleTagNumbering(*this, Tag, S); Tag->setFreeStanding(); if (Tag->isInvalidDecl()) return Tag; @@ -3254,7 +3370,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, // If we're dealing with a decl but not a TagDecl, assume that // whatever routines created it handled the friendship aspect. if (TagD && !Tag) - return 0; + return nullptr; return ActOnFriendTypeDecl(S, DS, TemplateParams); } @@ -3273,7 +3389,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DS.getTypeSpecType() == DeclSpec::TST_interface ? 2 : DS.getTypeSpecType() == DeclSpec::TST_union ? 3 : 4) << SS.getRange(); - return 0; + return nullptr; } // Track whether this decl-specifier declares anything. @@ -3285,7 +3401,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DS.getStorageClassSpec() != DeclSpec::SCS_typedef) { if (getLangOpts().CPlusPlus || Record->getDeclContext()->isRecord()) - return BuildAnonymousStructOrUnion(S, DS, AS, Record); + return BuildAnonymousStructOrUnion(S, DS, AS, Record, Context.getPrintingPolicy()); DeclaresAnything = false; } @@ -3368,10 +3484,15 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, // Note that a linkage-specification sets a storage class, but // 'extern "C" struct foo;' is actually valid and not theoretically // useless. - if (DeclSpec::SCS SCS = DS.getStorageClassSpec()) - if (!DS.isExternInLinkageSpec() && SCS != DeclSpec::SCS_typedef) + if (DeclSpec::SCS SCS = DS.getStorageClassSpec()) { + if (SCS == DeclSpec::SCS_mutable) + // Since mutable is not a viable storage class specifier in C, there is + // no reason to treat it as an extension. Instead, diagnose as an error. + Diag(DS.getStorageClassSpecLoc(), diag::err_mutable_nonmember); + else if (!DS.isExternInLinkageSpec() && SCS != DeclSpec::SCS_typedef) Diag(DS.getStorageClassSpecLoc(), DiagID) << DeclSpec::getSpecifierName(SCS); + } if (DeclSpec::TSCS TSCS = DS.getThreadStorageClassSpec()) Diag(DS.getThreadStorageClassSpecLoc(), DiagID) @@ -3471,12 +3592,10 @@ static bool InjectAnonymousStructOrUnionMembers(Sema &SemaRef, Scope *S, bool Invalid = false; // Look every FieldDecl and IndirectFieldDecl with a name. - for (RecordDecl::decl_iterator D = AnonRecord->decls_begin(), - DEnd = AnonRecord->decls_end(); - D != DEnd; ++D) { - if ((isa<FieldDecl>(*D) || isa<IndirectFieldDecl>(*D)) && - cast<NamedDecl>(*D)->getDeclName()) { - ValueDecl *VD = cast<ValueDecl>(*D); + for (auto *D : AnonRecord->decls()) { + if ((isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D)) && + cast<NamedDecl>(D)->getDeclName()) { + ValueDecl *VD = cast<ValueDecl>(D); if (CheckAnonMemberRedeclaration(SemaRef, S, Owner, VD->getDeclName(), VD->getLocation(), diagKind)) { // C++ [class.union]p2: @@ -3492,9 +3611,8 @@ static bool InjectAnonymousStructOrUnionMembers(Sema &SemaRef, Scope *S, // anonymous union is declared. unsigned OldChainingSize = Chaining.size(); if (IndirectFieldDecl *IF = dyn_cast<IndirectFieldDecl>(VD)) - for (IndirectFieldDecl::chain_iterator PI = IF->chain_begin(), - PE = IF->chain_end(); PI != PE; ++PI) - Chaining.push_back(*PI); + for (auto *PI : IF->chain()) + Chaining.push_back(PI); else Chaining.push_back(VD); @@ -3549,13 +3667,45 @@ StorageClassSpecToVarDeclStorageClass(const DeclSpec &DS) { llvm_unreachable("unknown storage class specifier"); } +static SourceLocation findDefaultInitializer(const CXXRecordDecl *Record) { + assert(Record->hasInClassInitializer()); + + for (const auto *I : Record->decls()) { + const auto *FD = dyn_cast<FieldDecl>(I); + if (const auto *IFD = dyn_cast<IndirectFieldDecl>(I)) + FD = IFD->getAnonField(); + if (FD && FD->hasInClassInitializer()) + return FD->getLocation(); + } + + llvm_unreachable("couldn't find in-class initializer"); +} + +static void checkDuplicateDefaultInit(Sema &S, CXXRecordDecl *Parent, + SourceLocation DefaultInitLoc) { + if (!Parent->isUnion() || !Parent->hasInClassInitializer()) + return; + + S.Diag(DefaultInitLoc, diag::err_multiple_mem_union_initialization); + S.Diag(findDefaultInitializer(Parent), diag::note_previous_initializer) << 0; +} + +static void checkDuplicateDefaultInit(Sema &S, CXXRecordDecl *Parent, + CXXRecordDecl *AnonUnion) { + if (!Parent->isUnion() || !Parent->hasInClassInitializer()) + return; + + checkDuplicateDefaultInit(S, Parent, findDefaultInitializer(AnonUnion)); +} + /// BuildAnonymousStructOrUnion - Handle the declaration of an /// anonymous structure or union. Anonymous unions are a C++ feature /// (C++ [class.union]) and a C11 feature; anonymous structures /// are a C11 feature and GNU C++ extension. Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, - AccessSpecifier AS, - RecordDecl *Record) { + AccessSpecifier AS, + RecordDecl *Record, + const PrintingPolicy &Policy) { DeclContext *Owner = Record->getDeclContext(); // Diagnose whether this anonymous struct/union is an extension. @@ -3570,7 +3720,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, // structs/unions. bool Invalid = false; if (getLangOpts().CPlusPlus) { - const char* PrevSpec = 0; + const char *PrevSpec = nullptr; unsigned DiagID; if (Record->isUnion()) { // C++ [class.union]p6: @@ -3585,7 +3735,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, // Recover by adding 'static'. DS.SetStorageClassSpec(*this, DeclSpec::SCS_static, SourceLocation(), - PrevSpec, DiagID); + PrevSpec, DiagID, Policy); } // C++ [class.union]p6: // A storage class is not allowed in a declaration of an @@ -3599,7 +3749,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, // Recover by removing the storage specifier. DS.SetStorageClassSpec(*this, DeclSpec::SCS_unspecified, SourceLocation(), - PrevSpec, DiagID); + PrevSpec, DiagID, Context.getPrintingPolicy()); } } @@ -3632,10 +3782,8 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, // The member-specification of an anonymous union shall only // define non-static data members. [Note: nested types and // functions cannot be declared within an anonymous union. ] - for (DeclContext::decl_iterator Mem = Record->decls_begin(), - MemEnd = Record->decls_end(); - Mem != MemEnd; ++Mem) { - if (FieldDecl *FD = dyn_cast<FieldDecl>(*Mem)) { + for (auto *Mem : Record->decls()) { + if (auto *FD = dyn_cast<FieldDecl>(Mem)) { // C++ [class.union]p3: // An anonymous union shall not have private or protected // members (clause 11). @@ -3653,14 +3801,14 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, // array of such objects. if (CheckNontrivialField(FD)) Invalid = true; - } else if ((*Mem)->isImplicit()) { + } else if (Mem->isImplicit()) { // Any implicit members are fine. - } else if (isa<TagDecl>(*Mem) && (*Mem)->getDeclContext() != Record) { + } else if (isa<TagDecl>(Mem) && Mem->getDeclContext() != Record) { // This is a type that showed up in an // elaborated-type-specifier inside the anonymous struct or // union, but which actually declares a type outside of the // anonymous struct or union. It's okay. - } else if (RecordDecl *MemRecord = dyn_cast<RecordDecl>(*Mem)) { + } else if (auto *MemRecord = dyn_cast<RecordDecl>(Mem)) { if (!MemRecord->isAnonymousStructOrUnion() && MemRecord->getDeclName()) { // Visual C++ allows type definition in anonymous struct or union. @@ -3681,31 +3829,41 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, diag::ext_anonymous_record_with_anonymous_type) << (int)Record->isUnion(); } - } else if (isa<AccessSpecDecl>(*Mem)) { + } else if (isa<AccessSpecDecl>(Mem)) { // Any access specifier is fine. + } else if (isa<StaticAssertDecl>(Mem)) { + // In C++1z, static_assert declarations are also fine. } else { // We have something that isn't a non-static data // member. Complain about it. unsigned DK = diag::err_anonymous_record_bad_member; - if (isa<TypeDecl>(*Mem)) + if (isa<TypeDecl>(Mem)) DK = diag::err_anonymous_record_with_type; - else if (isa<FunctionDecl>(*Mem)) + else if (isa<FunctionDecl>(Mem)) DK = diag::err_anonymous_record_with_function; - else if (isa<VarDecl>(*Mem)) + else if (isa<VarDecl>(Mem)) DK = diag::err_anonymous_record_with_static; // Visual C++ allows type definition in anonymous struct or union. if (getLangOpts().MicrosoftExt && DK == diag::err_anonymous_record_with_type) - Diag((*Mem)->getLocation(), diag::ext_anonymous_record_with_type) + Diag(Mem->getLocation(), diag::ext_anonymous_record_with_type) << (int)Record->isUnion(); else { - Diag((*Mem)->getLocation(), DK) + Diag(Mem->getLocation(), DK) << (int)Record->isUnion(); Invalid = true; } } } + + // C++11 [class.union]p8 (DR1460): + // At most one variant member of a union may have a + // brace-or-equal-initializer. + if (cast<CXXRecordDecl>(Record)->hasInClassInitializer() && + Owner->isRecord()) + checkDuplicateDefaultInit(*this, cast<CXXRecordDecl>(Owner), + cast<CXXRecordDecl>(Record)); } if (!Record->isUnion() && !Owner->isRecord()) { @@ -3720,15 +3878,15 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, assert(TInfo && "couldn't build declarator info for anonymous struct/union"); // Create a declaration for this anonymous struct/union. - NamedDecl *Anon = 0; + NamedDecl *Anon = nullptr; if (RecordDecl *OwningClass = dyn_cast<RecordDecl>(Owner)) { Anon = FieldDecl::Create(Context, OwningClass, DS.getLocStart(), Record->getLocation(), - /*IdentifierInfo=*/0, + /*IdentifierInfo=*/nullptr, Context.getTypeDeclType(Record), TInfo, - /*BitWidth=*/0, /*Mutable=*/false, + /*BitWidth=*/nullptr, /*Mutable=*/false, /*InitStyle=*/ICIS_NoInit); Anon->setAccess(AS); if (getLangOpts().CPlusPlus) @@ -3746,7 +3904,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, Anon = VarDecl::Create(Context, Owner, DS.getLocStart(), - Record->getLocation(), /*IdentifierInfo=*/0, + Record->getLocation(), /*IdentifierInfo=*/nullptr, Context.getTypeDeclType(Record), TInfo, SC); @@ -3758,11 +3916,14 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, } Anon->setImplicit(); + // Mark this as an anonymous struct/union type. + Record->setAnonymousStructOrUnion(true); + // Add the anonymous struct/union object to the current // context. We'll be referencing this object when we refer to one of // its members. Owner->addDecl(Anon); - + // Inject the members of the anonymous struct/union into the owning // context and into the identifier resolver chain for name lookup // purposes. @@ -3773,13 +3934,17 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, Chain, false)) Invalid = true; - // Mark this as an anonymous struct/union type. Note that we do not - // do this until after we have already checked and injected the - // members of this anonymous struct/union type, because otherwise - // the members could be injected twice: once by DeclContext when it - // builds its lookup table, and once by - // InjectAnonymousStructOrUnionMembers. - Record->setAnonymousStructOrUnion(true); + 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())); + Context.setStaticLocalNumber(NewVD, MCtx->getStaticLocalNumber(NewVD)); + } + } + } if (Invalid) Anon->setInvalidDecl(); @@ -3813,14 +3978,14 @@ Decl *Sema::BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS, assert(TInfo && "couldn't build declarator info for anonymous struct"); // Create a declaration for this anonymous struct. - NamedDecl* Anon = FieldDecl::Create(Context, + NamedDecl *Anon = FieldDecl::Create(Context, cast<RecordDecl>(CurContext), DS.getLocStart(), DS.getLocStart(), - /*IdentifierInfo=*/0, + /*IdentifierInfo=*/nullptr, Context.getTypeDeclType(Record), TInfo, - /*BitWidth=*/0, /*Mutable=*/false, + /*BitWidth=*/nullptr, /*Mutable=*/false, /*InitStyle=*/ICIS_NoInit); Anon->setImplicit(); @@ -3922,7 +4087,7 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) { Context.getCanonicalType(CurClassType))); NameInfo.setLoc(Name.StartLocation); // FIXME: should we retrieve TypeSourceInfo? - NameInfo.setNamedTypeInfo(0); + NameInfo.setNamedTypeInfo(nullptr); return NameInfo; } @@ -4018,7 +4183,7 @@ static bool RebuildDeclaratorInCurrentInstantiation(Sema &S, Declarator &D, case DeclSpec::TST_underlyingType: case DeclSpec::TST_atomic: { // Grab the type from the parser. - TypeSourceInfo *TSI = 0; + TypeSourceInfo *TSI = nullptr; QualType T = S.GetTypeFromParser(DS.getRepAsType(), &TSI); if (T.isNull() || !T->isDependentType()) break; @@ -4117,33 +4282,31 @@ bool Sema::DiagnoseClassNameShadow(DeclContext *DC, /// \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) { DeclContext *Cur = CurContext; while (isa<LinkageSpecDecl>(Cur) || isa<CapturedDecl>(Cur)) Cur = Cur->getParent(); - - // C++ [dcl.meaning]p1: - // A declarator-id shall not be qualified except for the definition - // of a member function (9.3) or static data member (9.4) outside of - // its class, the definition or explicit instantiation of a function - // or variable member of a namespace outside of its namespace, or the - // definition of an explicit specialization outside of its namespace, - // or the declaration of a friend function that is a member of - // another class or namespace (11.3). [...] - - // The user provided a superfluous scope specifier that refers back to the - // class or namespaces in which the entity is already declared. + + // If the user provided a superfluous scope specifier that refers back to the + // class in which the entity is already declared, diagnose and ignore it. // // class X { // void X::f(); // }; + // + // Note, it was once ill-formed to give redundant qualification in all + // contexts, but that rule was removed by DR482. if (Cur->Equals(DC)) { - Diag(Loc, LangOpts.MicrosoftExt? diag::warn_member_extra_qualification - : diag::err_member_extra_qualification) - << Name << FixItHint::CreateRemoval(SS.getRange()); - SS.clear(); + if (Cur->isRecord()) { + Diag(Loc, LangOpts.MicrosoftExt ? diag::warn_member_extra_qualification + : diag::err_member_extra_qualification) + << Name << FixItHint::CreateRemoval(SS.getRange()); + SS.clear(); + } else { + Diag(Loc, diag::warn_namespace_member_extra_qualification) << Name; + } return false; - } + } // Check whether the qualifying scope encloses the scope of the original // declaration. @@ -4212,9 +4375,9 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D, Diag(D.getDeclSpec().getLocStart(), diag::err_declarator_need_ident) << D.getDeclSpec().getSourceRange() << D.getSourceRange(); - return 0; + return nullptr; } else if (DiagnoseUnexpandedParameterPack(NameInfo, UPPC_DeclarationType)) - return 0; + return nullptr; // The scope passed in may not be a decl scope. Zip up the scope tree until // we find one that is. @@ -4228,7 +4391,7 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D, else if (D.getCXXScopeSpec().isSet()) { if (DiagnoseUnexpandedParameterPack(D.getCXXScopeSpec(), UPPC_DeclarationQualifier)) - return 0; + return nullptr; bool EnteringContext = !D.getDeclSpec().isFriendSpecified(); DC = computeDeclContext(D.getCXXScopeSpec(), EnteringContext); @@ -4239,15 +4402,15 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D, // and return early, to avoid the coming semantic disaster. Diag(D.getIdentifierLoc(), diag::err_template_qualified_declarator_no_match) - << (NestedNameSpecifier*)D.getCXXScopeSpec().getScopeRep() + << D.getCXXScopeSpec().getScopeRep() << D.getCXXScopeSpec().getRange(); - return 0; + return nullptr; } bool IsDependentContext = DC->isDependentContext(); if (!IsDependentContext && RequireCompleteDeclContext(D.getCXXScopeSpec(), DC)) - return 0; + return nullptr; if (isa<CXXRecordDecl>(DC) && !cast<CXXRecordDecl>(DC)->hasDefinition()) { Diag(D.getIdentifierLoc(), @@ -4258,8 +4421,8 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D, if (diagnoseQualifiedDeclaration(D.getCXXScopeSpec(), DC, Name, D.getIdentifierLoc())) { if (DC->isRecord()) - return 0; - + return nullptr; + D.setInvalidType(); } } @@ -4278,8 +4441,8 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D, // If this is a typedef, we'll end up spewing multiple diagnostics. // Just return early; it's safer. if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) - return 0; - + return nullptr; + TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); QualType R = TInfo->getType(); @@ -4380,7 +4543,7 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D, if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) { if (TemplateParamLists.size()) { Diag(D.getIdentifierLoc(), diag::err_template_typedef); - return 0; + return nullptr; } New = ActOnTypedefDeclarator(S, D, DC, TInfo, Previous); @@ -4393,8 +4556,8 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D, AddToScope); } - if (New == 0) - return 0; + if (!New) + return nullptr; // If this has an identifier and is not an invalid redeclaration or // function template specialization, add it to the scope stack. @@ -4521,7 +4684,7 @@ TryToFixInvalidVariablyModifiedTypeSourceInfo(TypeSourceInfo *TInfo, = TryToFixInvalidVariablyModifiedType(TInfo->getType(), Context, SizeIsNegative, Oversized); if (FixedTy.isNull()) - return 0; + return nullptr; TypeSourceInfo *FixedTInfo = Context.getTrivialTypeSourceInfo(FixedTy); FixInvalidVariablyModifiedTypeLoc(TInfo->getTypeLoc(), FixedTInfo->getTypeLoc()); @@ -4560,7 +4723,7 @@ NamedDecl *Sema::findLocallyScopedExternCDecl(DeclarationName Name) { } NamedDecl *D = LocallyScopedExternCDecls.lookup(Name); - return D ? D->getMostRecentDecl() : 0; + return D ? D->getMostRecentDecl() : nullptr; } /// \brief Diagnose function specifiers on a declaration of an identifier that @@ -4607,11 +4770,11 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC, if (D.getName().Kind != UnqualifiedId::IK_Identifier) { Diag(D.getName().StartLocation, diag::err_typedef_not_identifier) << D.getName().getSourceRange(); - return 0; + return nullptr; } TypedefDecl *NewTD = ParseTypedefDecl(S, D, TInfo->getType(), TInfo); - if (!NewTD) return 0; + if (!NewTD) return nullptr; // Handle attributes prior to checking for duplicates in MergeVarDecl ProcessDeclAttributes(S, NewTD, D); @@ -4635,7 +4798,7 @@ Sema::CheckTypedefForVariablyModifiedType(Scope *S, TypedefNameDecl *NewTD) { if (T->isVariablyModifiedType()) { getCurFunction()->setHasBranchProtectedScope(); - if (S->getFnParent() == 0) { + if (S->getFnParent() == nullptr) { bool SizeIsNegative; llvm::APSInt Oversized; TypeSourceInfo *FixedTInfo = @@ -4670,8 +4833,8 @@ Sema::ActOnTypedefNameDecl(Scope *S, DeclContext *DC, TypedefNameDecl *NewTD, LookupResult &Previous, bool &Redeclaration) { // Merge the decl with the existing one if appropriate. If the decl is // in an outer scope, it isn't the same thing. - FilterLookupForScope(Previous, DC, S, /*ConsiderLinkage*/ false, - /*ExplicitInstantiationOrSpecialization=*/false); + FilterLookupForScope(Previous, DC, S, /*ConsiderLinkage*/false, + /*AllowInlineNamespace*/false); filterNonConflictingPreviousDecls(Context, NewTD, Previous); if (!Previous.empty()) { Redeclaration = true; @@ -4804,6 +4967,10 @@ bool Sema::inferObjCARCLifetime(ValueDecl *decl) { } static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) { + // Ensure that an auto decl is deduced otherwise the checks below might cache + // the wrong linkage. + assert(S.ParsingInitForAutoVars.count(&ND) == 0); + // 'weak' only applies to declarations with external linkage. if (WeakAttr *Attr = ND.getAttr<WeakAttr>()) { if (!ND.isExternallyVisible()) { @@ -4826,6 +4993,79 @@ static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) { ND.dropAttr<SelectAnyAttr>(); } } + + // dll attributes require external linkage. + if (const DLLImportAttr *Attr = ND.getAttr<DLLImportAttr>()) { + if (!ND.isExternallyVisible()) { + S.Diag(ND.getLocation(), diag::err_attribute_dll_not_extern) + << &ND << Attr; + ND.setInvalidDecl(); + } + } + if (const DLLExportAttr *Attr = ND.getAttr<DLLExportAttr>()) { + if (!ND.isExternallyVisible()) { + S.Diag(ND.getLocation(), diag::err_attribute_dll_not_extern) + << &ND << Attr; + ND.setInvalidDecl(); + } + } +} + +static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl, + NamedDecl *NewDecl, + bool IsSpecialization) { + if (TemplateDecl *OldTD = dyn_cast<TemplateDecl>(OldDecl)) + OldDecl = OldTD->getTemplatedDecl(); + if (TemplateDecl *NewTD = dyn_cast<TemplateDecl>(NewDecl)) + NewDecl = NewTD->getTemplatedDecl(); + + if (!OldDecl || !NewDecl) + return; + + const DLLImportAttr *OldImportAttr = OldDecl->getAttr<DLLImportAttr>(); + const DLLExportAttr *OldExportAttr = OldDecl->getAttr<DLLExportAttr>(); + const DLLImportAttr *NewImportAttr = NewDecl->getAttr<DLLImportAttr>(); + const DLLExportAttr *NewExportAttr = NewDecl->getAttr<DLLExportAttr>(); + + // dllimport and dllexport are inheritable attributes so we have to exclude + // inherited attribute instances. + bool HasNewAttr = (NewImportAttr && !NewImportAttr->isInherited()) || + (NewExportAttr && !NewExportAttr->isInherited()); + + // A redeclaration is not allowed to add a dllimport or dllexport attribute, + // the only exception being explicit specializations. + // Implicitly generated declarations are also excluded for now because there + // is no other way to switch these to use dllimport or dllexport. + bool AddsAttr = !(OldImportAttr || OldExportAttr) && HasNewAttr; + if (AddsAttr && !IsSpecialization && !OldDecl->isImplicit()) { + S.Diag(NewDecl->getLocation(), diag::err_attribute_dll_redeclaration) + << NewDecl + << (NewImportAttr ? (const Attr *)NewImportAttr : NewExportAttr); + S.Diag(OldDecl->getLocation(), diag::note_previous_declaration); + NewDecl->setInvalidDecl(); + return; + } + + // A redeclaration is not allowed to drop a dllimport attribute, the only + // exception being inline function definitions. + // NB: MSVC converts such a declaration to dllexport. + bool IsInline = false, IsStaticDataMember = false; + if (const auto *VD = dyn_cast<VarDecl>(NewDecl)) + // Ignore static data because out-of-line definitions are diagnosed + // separately. + IsStaticDataMember = VD->isStaticDataMember(); + else if (const auto *FD = dyn_cast<FunctionDecl>(NewDecl)) + IsInline = FD->isInlined(); + + if (OldImportAttr && !HasNewAttr && !IsInline && !IsStaticDataMember) { + S.Diag(NewDecl->getLocation(), + diag::warn_redeclaration_without_attribute_prev_attribute_ignored) + << NewDecl << OldImportAttr; + S.Diag(OldDecl->getLocation(), diag::note_previous_declaration); + S.Diag(OldImportAttr->getLocation(), diag::note_previous_attribute); + OldDecl->dropAttr<DLLImportAttr>(); + NewDecl->dropAttr<DLLImportAttr>(); + } } /// Given that we are within the definition of the given function, @@ -4851,7 +5091,8 @@ static bool isFunctionDefinitionDiscarded(Sema &S, FunctionDecl *FD) { FD->setLazyBody(1); #endif - bool isC99Inline = (S.Context.GetGVALinkageForFunction(FD) == GVA_C99Inline); + bool isC99Inline = + S.Context.GetGVALinkageForFunction(FD) == GVA_AvailableExternally; #ifndef NDEBUG FD->setLazyBody(0); @@ -4906,6 +5147,31 @@ 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) { + // Check decl attributes on the DeclSpec. + if (hasParsedAttr(S, PD.getDeclSpec().getAttributes().getList(), 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)) + return true; + } + + // Finally, check attributes on the decl itself. + return hasParsedAttr(S, PD.getAttributes(), Kind); +} + /// Adjust the \c DeclContext for a function or variable that might be a /// function-local external declaration. bool Sema::adjustContextForLocalExternDecl(DeclContext *&DC) { @@ -4942,16 +5208,36 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, VarDecl::StorageClass SC = StorageClassSpecToVarDeclStorageClass(D.getDeclSpec()); + // 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)) + SC = SC_Extern; + DeclContext *OriginalDC = DC; bool IsLocalExternDecl = SC == SC_Extern && adjustContextForLocalExternDecl(DC); - if (getLangOpts().OpenCL && !getOpenCLOptions().cl_khr_fp16) { - // OpenCL v1.2 s6.1.1.1: reject declaring variables of the half and - // half array type (unless the cl_khr_fp16 extension is enabled). - if (Context.getBaseElementType(R)->isHalfType()) { - Diag(D.getIdentifierLoc(), diag::err_opencl_half_declaration) << R; - D.setInvalidType(); + if (getLangOpts().OpenCL) { + // OpenCL v1.0 s6.8.a.3: Pointers to functions are not allowed. + QualType NR = R; + while (NR->isPointerType()) { + if (NR->isFunctionPointerType()) { + Diag(D.getIdentifierLoc(), diag::err_opencl_function_pointer_variable); + D.setInvalidType(); + break; + } + NR = NR->getPointeeType(); + } + + if (!getOpenCLOptions().cl_khr_fp16) { + // OpenCL v1.2 s6.1.1.1: reject declaring variables of the half and + // half array type (unless the cl_khr_fp16 extension is enabled). + if (Context.getBaseElementType(R)->isHalfType()) { + Diag(D.getIdentifierLoc(), diag::err_opencl_half_declaration) << R; + D.setInvalidType(); + } } } @@ -4978,21 +5264,17 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (!II) { Diag(D.getIdentifierLoc(), diag::err_bad_variable_name) << Name; - return 0; + return nullptr; } DiagnoseFunctionSpecifiers(D.getDeclSpec()); - if (!DC->isRecord() && S->getFnParent() == 0) { + if (!DC->isRecord() && S->getFnParent() == nullptr) { // C99 6.9p2: The storage-class specifiers auto and register shall not // appear in the declaration specifiers in an external declaration. - if (SC == SC_Auto || SC == SC_Register) { - // If this is a register variable with an asm label specified, then this - // is a GNU extension. - if (SC == SC_Register && D.getAsmLabel()) - Diag(D.getIdentifierLoc(), diag::err_unsupported_global_register); - else - Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_fscope); + // Global Register+Asm is a GNU extension we support. + if (SC == SC_Auto || (SC == SC_Register && !D.getAsmLabel())) { + Diag(D.getIdentifierLoc(), diag::err_typecheck_sclass_fscope); D.setInvalidType(); } } @@ -5017,7 +5299,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, // The event type cannot be used with the __local, __constant and __global // address space qualifiers. if (R->isEventT()) { - if (S->getParent() == 0) { + if (S->getParent() == nullptr) { Diag(D.getLocStart(), diag::err_event_t_global_var); D.setInvalidType(); } @@ -5033,9 +5315,9 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, bool IsVariableTemplateSpecialization = false; bool IsPartialSpecialization = false; bool IsVariableTemplate = false; - VarTemplateDecl *PrevVarTemplate = 0; - VarDecl *NewVD = 0; - VarTemplateDecl *NewTemplate = 0; + VarDecl *NewVD = nullptr; + VarTemplateDecl *NewTemplate = nullptr; + TemplateParameterList *TemplateParams = nullptr; if (!getLangOpts().CPlusPlus) { NewVD = VarDecl::Create(Context, DC, D.getLocStart(), D.getIdentifierLoc(), II, @@ -5097,18 +5379,17 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, } } - NamedDecl *PrevDecl = 0; - if (Previous.begin() != Previous.end()) - PrevDecl = (*Previous.begin())->getUnderlyingDecl(); - PrevVarTemplate = dyn_cast_or_null<VarTemplateDecl>(PrevDecl); - // Match up the template parameter lists with the scope specifier, then // determine whether we have a template or a template specialization. - TemplateParameterList *TemplateParams = - MatchTemplateParametersToScopeSpecifier( - D.getDeclSpec().getLocStart(), D.getIdentifierLoc(), - D.getCXXScopeSpec(), TemplateParamLists, - /*never a friend*/ false, IsExplicitSpecialization, Invalid); + TemplateParams = MatchTemplateParametersToScopeSpecifier( + D.getDeclSpec().getLocStart(), D.getIdentifierLoc(), + D.getCXXScopeSpec(), + D.getName().getKind() == UnqualifiedId::IK_TemplateId + ? D.getName().TemplateId + : nullptr, + TemplateParamLists, + /*never a friend*/ false, IsExplicitSpecialization, Invalid); + if (TemplateParams) { if (!TemplateParams->size() && D.getName().getKind() != UnqualifiedId::IK_TemplateId) { @@ -5119,113 +5400,43 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, << II << SourceRange(TemplateParams->getTemplateLoc(), TemplateParams->getRAngleLoc()); + TemplateParams = nullptr; } else { - // Only C++1y supports variable templates (N3651). - Diag(D.getIdentifierLoc(), - getLangOpts().CPlusPlus1y - ? diag::warn_cxx11_compat_variable_template - : diag::ext_variable_template); - if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) { // This is an explicit specialization or a partial specialization. - // Check that we can declare a specialization here - + // FIXME: Check that we can declare a specialization here. IsVariableTemplateSpecialization = true; IsPartialSpecialization = TemplateParams->size() > 0; - } else { // if (TemplateParams->size() > 0) // This is a template declaration. IsVariableTemplate = true; // Check that we can declare a template here. if (CheckTemplateDeclScope(S, TemplateParams)) - return 0; - - // If there is a previous declaration with the same name, check - // whether this is a valid redeclaration. - if (PrevDecl && !isDeclInScope(PrevDecl, DC, S)) - PrevDecl = PrevVarTemplate = 0; - - if (PrevVarTemplate) { - // Ensure that the template parameter lists are compatible. - if (!TemplateParameterListsAreEqual( - TemplateParams, PrevVarTemplate->getTemplateParameters(), - /*Complain=*/true, TPL_TemplateMatch)) - return 0; - } else if (PrevDecl && PrevDecl->isTemplateParameter()) { - // Maybe we will complain about the shadowed template parameter. - DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl); - - // Just pretend that we didn't see the previous declaration. - PrevDecl = 0; - } else if (PrevDecl) { - // C++ [temp]p5: - // ... a template name declared in namespace scope or in class - // scope shall be unique in that scope. - Diag(D.getIdentifierLoc(), diag::err_redefinition_different_kind) - << Name; - Diag(PrevDecl->getLocation(), diag::note_previous_definition); - return 0; - } + return nullptr; - // Check the template parameter list of this declaration, possibly - // merging in the template parameter list from the previous variable - // template declaration. - if (CheckTemplateParameterList( - TemplateParams, - PrevVarTemplate ? PrevVarTemplate->getTemplateParameters() - : 0, - (D.getCXXScopeSpec().isSet() && DC && DC->isRecord() && - DC->isDependentContext()) - ? TPC_ClassTemplateMember - : TPC_VarTemplate)) - Invalid = true; - - if (D.getCXXScopeSpec().isSet()) { - // If the name of the template was qualified, we must be defining - // the template out-of-line. - if (!D.getCXXScopeSpec().isInvalid() && !Invalid && - !PrevVarTemplate) { - Diag(D.getIdentifierLoc(), diag::err_member_decl_does_not_match) - << Name << DC << /*IsDefinition*/true - << D.getCXXScopeSpec().getRange(); - Invalid = true; - } - } + // Only C++1y supports variable templates (N3651). + Diag(D.getIdentifierLoc(), + getLangOpts().CPlusPlus1y + ? diag::warn_cxx11_compat_variable_template + : diag::ext_variable_template); } } - } else if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) { - TemplateIdAnnotation *TemplateId = D.getName().TemplateId; - - // We have encountered something that the user meant to be a - // specialization (because it has explicitly-specified template - // arguments) but that was not introduced with a "template<>" (or had - // too few of them). - // FIXME: Differentiate between attempts for explicit instantiations - // (starting with "template") and the rest. - Diag(D.getIdentifierLoc(), diag::err_template_spec_needs_header) - << SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc) - << FixItHint::CreateInsertion(D.getDeclSpec().getLocStart(), - "template<> "); - IsVariableTemplateSpecialization = true; + } else { + assert(D.getName().getKind() != UnqualifiedId::IK_TemplateId && + "should have a 'template<>' for this decl"); } if (IsVariableTemplateSpecialization) { - if (!PrevVarTemplate) { - Diag(D.getIdentifierLoc(), diag::err_var_spec_no_template) - << IsPartialSpecialization; - return 0; - } - SourceLocation TemplateKWLoc = TemplateParamLists.size() > 0 ? TemplateParamLists[0]->getTemplateLoc() : SourceLocation(); DeclResult Res = ActOnVarTemplateSpecialization( - S, PrevVarTemplate, D, TInfo, TemplateKWLoc, TemplateParams, SC, + S, D, TInfo, TemplateKWLoc, TemplateParams, SC, IsPartialSpecialization); if (Res.isInvalid()) - return 0; + return nullptr; NewVD = cast<VarDecl>(Res.get()); AddToScope = false; } else @@ -5236,7 +5447,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (IsVariableTemplate) { NewTemplate = VarTemplateDecl::Create(Context, DC, D.getIdentifierLoc(), Name, - TemplateParams, NewVD, PrevVarTemplate); + TemplateParams, NewVD); NewVD->setDescribedVarTemplate(NewTemplate); } @@ -5253,18 +5464,13 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, SetNestedNameSpecifier(NewVD, D); - // FIXME: Do we need D.getCXXScopeSpec().isSet()? - if (TemplateParams && TemplateParamLists.size() > 1 && - (!IsVariableTemplateSpecialization || D.getCXXScopeSpec().isSet())) { + // If we have any template parameter lists that don't directly belong to + // the variable (matching the scope specifier), store them. + unsigned VDTemplateParamLists = TemplateParams ? 1 : 0; + if (TemplateParamLists.size() > VDTemplateParamLists) NewVD->setTemplateParameterListsInfo( - Context, TemplateParamLists.size() - 1, TemplateParamLists.data()); - } else if (IsVariableTemplateSpecialization || - (!TemplateParams && TemplateParamLists.size() > 0 && - (D.getCXXScopeSpec().isSet()))) { - NewVD->setTemplateParameterListsInfo(Context, - TemplateParamLists.size(), - TemplateParamLists.data()); - } + Context, TemplateParamLists.size() - VDTemplateParamLists, + TemplateParamLists.data()); if (D.getDeclSpec().isConstexprSpecified()) NewVD->setConstexpr(true); @@ -5311,7 +5517,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, // that a local variable with thread storage duration still has to // be marked 'static'. Also note that it's possible to get these // semantics in C++ using __attribute__((gnu_inline)). - if (SC == SC_Static && S->getFnParent() != 0 && + if (SC == SC_Static && S->getFnParent() != nullptr && !NewVD->getType().isConstQualified()) { FunctionDecl *CurFD = getCurFunctionDecl(); if (CurFD && isFunctionDefinitionDiscarded(*this, CurFD)) { @@ -5346,19 +5552,23 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, // Handle attributes prior to checking for duplicates in MergeVarDecl ProcessDeclAttributes(S, NewVD, D); - if (NewVD->hasAttrs()) - CheckAlignasUnderalignment(NewVD); - if (getLangOpts().CUDA) { // CUDA B.2.5: "__shared__ and __constant__ variables have implied static // storage [duration]." - if (SC == SC_None && S->getFnParent() != 0 && + if (SC == SC_None && S->getFnParent() != nullptr && (NewVD->hasAttr<CUDASharedAttr>() || NewVD->hasAttr<CUDAConstantAttr>())) { NewVD->setStorageClass(SC_Static); } } + // Ensure that dllimport globals without explicit storage class are treated as + // extern. The storage class is set above using parsed attributes. Now we can + // check the VarDecl itself. + assert(!NewVD->hasAttr<DLLImportAttr>() || + NewVD->getAttr<DLLImportAttr>()->isInherited() || + NewVD->isStaticDataMember() || NewVD->getStorageClass() != SC_None); + // In auto-retain/release, infer strong retension for variables of // retainable type. if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(NewVD)) @@ -5369,13 +5579,14 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, // The parser guarantees this is a string. StringLiteral *SE = cast<StringLiteral>(E); StringRef Label = SE->getString(); - if (S->getFnParent() != 0) { + if (S->getFnParent() != nullptr) { switch (SC) { case SC_None: case SC_Auto: Diag(E->getExprLoc(), diag::warn_asm_label_on_auto_decl) << Label; break; case SC_Register: + // Local Named register if (!Context.getTargetInfo().isValidGCCRegisterName(Label)) Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label; break; @@ -5385,10 +5596,18 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, case SC_OpenCLWorkGroupLocal: break; } + } else if (SC == SC_Register) { + // Global Named register + if (!Context.getTargetInfo().isValidGCCRegisterName(Label)) + Diag(E->getExprLoc(), diag::err_asm_unknown_register_name) << Label; + if (!R->isIntegralType(Context) && !R->isPointerType()) { + Diag(D.getLocStart(), diag::err_asm_bad_register_type); + NewVD->setInvalidDecl(true); + } } NewVD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0), - Context, Label)); + Context, Label, 0)); } else if (!ExtnameUndeclaredIdentifiers.empty()) { llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I = ExtnameUndeclaredIdentifiers.find(NewVD->getIdentifier()); @@ -5399,15 +5618,16 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, } // Diagnose shadowed variables before filtering for scope. - if (!D.getCXXScopeSpec().isSet()) + if (D.getCXXScopeSpec().isEmpty()) CheckShadow(S, NewVD, Previous); // Don't consider existing declarations that are in a different // scope and are out-of-semantic-context declarations (if the new // declaration has linkage). - FilterLookupForScope( - Previous, OriginalDC, S, shouldConsiderLinkage(NewVD), - IsExplicitSpecialization || IsVariableTemplateSpecialization); + FilterLookupForScope(Previous, OriginalDC, S, shouldConsiderLinkage(NewVD), + D.getCXXScopeSpec().isNotEmpty() || + IsExplicitSpecialization || + IsVariableTemplateSpecialization); // Check whether the previous declaration is in the same block scope. This // affects whether we merge types with it, per C++11 [dcl.array]p3. @@ -5420,6 +5640,11 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (!getLangOpts().CPlusPlus) { D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous)); } else { + // If this is an explicit specialization of a static data member, check it. + if (IsExplicitSpecialization && !NewVD->isInvalidDecl() && + CheckMemberSpecialization(NewVD, Previous)) + NewVD->setInvalidDecl(); + // Merge the decl with the existing one if appropriate. if (!Previous.empty()) { if (Previous.isSingleResult() && @@ -5440,24 +5665,37 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, NewVD->setInvalidDecl(); } - if (!IsVariableTemplateSpecialization) { - if (PrevVarTemplate) { - LookupResult PrevDecl(*this, GetNameForDeclarator(D), - LookupOrdinaryName, ForRedeclaration); - PrevDecl.addDecl(PrevVarTemplate->getTemplatedDecl()); - D.setRedeclaration(CheckVariableDeclaration(NewVD, PrevDecl)); - } else - D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous)); - } + if (!IsVariableTemplateSpecialization) + D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous)); + + if (NewTemplate) { + VarTemplateDecl *PrevVarTemplate = + NewVD->getPreviousDecl() + ? NewVD->getPreviousDecl()->getDescribedVarTemplate() + : nullptr; + + // Check the template parameter list of this declaration, possibly + // merging in the template parameter list from the previous variable + // template declaration. + if (CheckTemplateParameterList( + TemplateParams, + PrevVarTemplate ? PrevVarTemplate->getTemplateParameters() + : nullptr, + (D.getCXXScopeSpec().isSet() && DC && DC->isRecord() && + DC->isDependentContext()) + ? TPC_ClassTemplateMember + : TPC_VarTemplate)) + NewVD->setInvalidDecl(); - // This is an explicit specialization of a static data member. Check it. - if (IsExplicitSpecialization && !NewVD->isInvalidDecl() && - CheckMemberSpecialization(NewVD, Previous)) - NewVD->setInvalidDecl(); + // If we are providing an explicit specialization of a static variable + // template, make a note of that. + if (PrevVarTemplate && + PrevVarTemplate->getInstantiatedFromMemberTemplate()) + PrevVarTemplate->setMemberSpecialization(); + } } ProcessPragmaWeak(S, NewVD); - checkAttributesAfterMerging(*this, *NewVD); // If this is the first declaration of an extern C variable, update // the map of such variables. @@ -5470,16 +5708,21 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (MangleNumberingContext *MCtx = getCurrentMangleNumberContext(NewVD->getDeclContext(), ManglingContextDecl)) { - Context.setManglingNumber(NewVD, MCtx->getManglingNumber(NewVD)); + Context.setManglingNumber( + NewVD, MCtx->getManglingNumber(NewVD, S->getMSLocalManglingNumber())); + Context.setStaticLocalNumber(NewVD, MCtx->getStaticLocalNumber(NewVD)); } } - // If we are providing an explicit specialization of a static variable - // template, make a note of that. - if (PrevVarTemplate && PrevVarTemplate->getInstantiatedFromMemberTemplate()) - PrevVarTemplate->setMemberSpecialization(); + if (D.isRedeclaration() && !Previous.empty()) { + checkDLLAttributeRedeclaration( + *this, dyn_cast<NamedDecl>(Previous.getRepresentativeDecl()), NewVD, + IsExplicitSpecialization); + } if (NewTemplate) { + if (NewVD->isInvalidDecl()) + NewTemplate->setInvalidDecl(); ActOnDocumentableDecl(NewTemplate); return NewTemplate; } @@ -5498,8 +5741,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, /// void Sema::CheckShadow(Scope *S, VarDecl *D, const LookupResult& R) { // Return if warning is ignored. - if (Diags.getDiagnosticLevel(diag::warn_decl_shadow, R.getNameLoc()) == - DiagnosticsEngine::Ignored) + if (Diags.isIgnored(diag::warn_decl_shadow, R.getNameLoc())) return; // Don't diagnose declarations at file scope. @@ -5526,11 +5768,9 @@ void Sema::CheckShadow(Scope *S, VarDecl *D, const LookupResult& R) { if (shadowedVar->isExternC()) { // For shadowing external vars, make sure that we point to the global // declaration, not a locally scoped extern declaration. - for (VarDecl::redecl_iterator - I = shadowedVar->redecls_begin(), E = shadowedVar->redecls_end(); - I != E; ++I) + for (auto I : shadowedVar->redecls()) if (I->isFileVarDecl()) { - ShadowedDecl = *I; + ShadowedDecl = I; break; } } @@ -5566,14 +5806,15 @@ void Sema::CheckShadow(Scope *S, VarDecl *D, const LookupResult& R) { DeclarationName Name = R.getLookupName(); // Emit warning and note. + if (getSourceManager().isInSystemMacro(R.getNameLoc())) + return; Diag(R.getNameLoc(), diag::warn_decl_shadow) << Name << Kind << OldDC; Diag(ShadowedDecl->getLocation(), diag::note_previous_declaration); } /// \brief Check -Wshadow without the advantage of a previous lookup. void Sema::CheckShadow(Scope *S, VarDecl *D) { - if (Diags.getDiagnosticLevel(diag::warn_decl_shadow, D->getLocation()) == - DiagnosticsEngine::Ignored) + if (Diags.isIgnored(diag::warn_decl_shadow, D->getLocation())) return; LookupResult R(*this, D->getDeclName(), D->getLocation(), @@ -5711,6 +5952,9 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { if (T->isUndeducedType()) return; + if (NewVD->hasAttrs()) + CheckAlignasUnderalignment(NewVD); + if (T->isObjCObjectType()) { Diag(NewVD->getLocation(), diag::err_statically_allocated_object) << FixItHint::CreateInsertion(NewVD->getLocation(), "*"); @@ -5769,7 +6013,7 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { TypeSourceInfo *FixedTInfo = TryToFixInvalidVariablyModifiedTypeSourceInfo(TInfo, Context, SizeIsNegative, Oversized); - if (FixedTInfo == 0 && T->isVariableArrayType()) { + if (!FixedTInfo && T->isVariableArrayType()) { const VariableArrayType *VAT = Context.getAsVariableArrayType(T); // FIXME: This won't give the correct result for // int a[10][n]; @@ -5788,7 +6032,7 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { return; } - if (FixedTInfo == 0) { + if (!FixedTInfo) { if (NewVD->isFileVarDecl()) Diag(NewVD->getLocation(), diag::err_vm_decl_in_file_scope); else @@ -5828,7 +6072,6 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { if (NewVD->isConstexpr() && !T->isDependentType() && RequireLiteralType(NewVD->getLocation(), T, diag::err_constexpr_var_non_literal)) { - // Can't perform this check until the type is deduced. NewVD->setInvalidDecl(); return; } @@ -5947,9 +6190,8 @@ bool Sema::AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD) { bool hasNonDeletedOverridenMethods = false; bool AddedAny = false; if (DC->lookupInBases(&FindOverriddenMethod, &Data, Paths)) { - for (CXXBasePaths::decl_iterator I = Paths.found_decls_begin(), - E = Paths.found_decls_end(); I != E; ++I) { - if (CXXMethodDecl *OldMD = dyn_cast<CXXMethodDecl>(*I)) { + for (auto *I : Paths.found_decls()) { + if (CXXMethodDecl *OldMD = dyn_cast<CXXMethodDecl>(I)) { MD->addOverriddenMethod(OldMD->getCanonicalDecl()); if (!CheckOverridingFunctionReturnType(MD, OldMD) && !CheckOverridingFunctionAttributes(MD, OldMD) && @@ -5993,9 +6235,9 @@ class DifferentNameValidatorCCC : public CorrectionCandidateCallback { DifferentNameValidatorCCC(ASTContext &Context, FunctionDecl *TypoFD, CXXRecordDecl *Parent) : Context(Context), OriginalFD(TypoFD), - ExpectedParent(Parent ? Parent->getCanonicalDecl() : 0) {} + ExpectedParent(Parent ? Parent->getCanonicalDecl() : nullptr) {} - virtual bool ValidateCandidate(const TypoCorrection &candidate) { + bool ValidateCandidate(const TypoCorrection &candidate) override { if (candidate.getEditDistance() == 0) return false; @@ -6062,7 +6304,7 @@ static NamedDecl *DiagnoseInvalidRedeclaration( "Cannot have an ambiguity in previous-declaration lookup"); CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD); DifferentNameValidatorCCC Validator(SemaRef.Context, NewFD, - MD ? MD->getParent() : 0); + MD ? MD->getParent() : nullptr); if (!Prev.empty()) { for (LookupResult::iterator Func = Prev.begin(), FuncEnd = Prev.end(); Func != FuncEnd; ++Func) { @@ -6080,7 +6322,7 @@ static NamedDecl *DiagnoseInvalidRedeclaration( } else if ((Correction = SemaRef.CorrectTypo( Prev.getLookupNameInfo(), Prev.getLookupKind(), S, &ExtraArgs.D.getCXXScopeSpec(), Validator, - IsLocalFriend ? 0 : NewDC))) { + Sema::CTK_ErrorRecovery, IsLocalFriend ? nullptr : NewDC))) { // Set up everything for the call to ActOnFunctionDeclarator ExtraArgs.D.SetIdentifier(Correction.getCorrectionAsIdentifierInfo(), ExtraArgs.D.getIdentifierLoc()); @@ -6114,7 +6356,7 @@ static NamedDecl *DiagnoseInvalidRedeclaration( ExtraArgs.AddToScope); if (Trap.hasErrorOccurred()) - Result = 0; + Result = nullptr; } if (Result) { @@ -6174,7 +6416,7 @@ static NamedDecl *DiagnoseInvalidRedeclaration( IsMember ? diag::note_member_def_close_match : diag::note_local_decl_close_match); } - return 0; + return nullptr; } static FunctionDecl::StorageClass getFunctionStorageClass(Sema &SemaRef, @@ -6221,7 +6463,7 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, DeclarationNameInfo NameInfo = SemaRef.GetNameForDeclarator(D); DeclarationName Name = NameInfo.getName(); - FunctionDecl *NewFD = 0; + FunctionDecl *NewFD = nullptr; bool isInline = D.getDeclSpec().isInlineSpecified(); if (!SemaRef.getLangOpts().CPlusPlus) { @@ -6254,10 +6496,9 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, // For record types, this is done by the AbstractClassUsageDiagnoser once // the class has been completely parsed. if (!DC->isRecord() && - SemaRef.RequireNonAbstractType(D.getIdentifierLoc(), - R->getAs<FunctionType>()->getResultType(), - diag::err_abstract_type_in_decl, - SemaRef.AbstractReturnType)) + SemaRef.RequireNonAbstractType( + D.getIdentifierLoc(), R->getAs<FunctionType>()->getReturnType(), + diag::err_abstract_type_in_decl, SemaRef.AbstractReturnType)) D.setInvalidType(); if (Name.getNameKind() == DeclarationName::CXXConstructorName) { @@ -6292,15 +6533,6 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, SemaRef.AdjustDestructorExceptionSpec(Record, NewDD); } - // The Microsoft ABI requires that we perform the destructor body - // checks (i.e. operator delete() lookup) at every declaration, as - // any translation unit may need to emit a deleting destructor. - if (SemaRef.Context.getTargetInfo().getCXXABI().isMicrosoft() && - !Record->isDependentType() && Record->getDefinition() && - !Record->isBeingDefined()) { - SemaRef.CheckDestructor(NewDD); - } - IsVirtualOkay = true; return NewDD; @@ -6321,7 +6553,7 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, if (!DC->isRecord()) { SemaRef.Diag(D.getIdentifierLoc(), diag::err_conv_function_not_member); - return 0; + return nullptr; } SemaRef.CheckConversionDeclarator(D, R, SC); @@ -6341,7 +6573,7 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, SemaRef.Diag(D.getIdentifierLoc(), diag::err_constructor_return_type) << SourceRange(D.getDeclSpec().getTypeSpecTypeLoc()) << SourceRange(D.getIdentifierLoc()); - return 0; + return nullptr; } // This is a C++ method declaration. @@ -6363,26 +6595,11 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, } } -void Sema::checkVoidParamDecl(ParmVarDecl *Param) { - // In C++, the empty parameter-type-list must be spelled "void"; a - // typedef of void is not permitted. - if (getLangOpts().CPlusPlus && - Param->getType().getUnqualifiedType() != Context.VoidTy) { - bool IsTypeAlias = false; - if (const TypedefType *TT = Param->getType()->getAs<TypedefType>()) - IsTypeAlias = isa<TypeAliasDecl>(TT->getDecl()); - else if (const TemplateSpecializationType *TST = - Param->getType()->getAs<TemplateSpecializationType>()) - IsTypeAlias = TST->isTypeAlias(); - Diag(Param->getLocation(), diag::err_param_typedef_of_void) - << IsTypeAlias; - } -} - enum OpenCLParamType { ValidKernelParam, PtrPtrKernelParam, PtrKernelParam, + PrivatePtrKernelParam, InvalidKernelParam, RecordKernelParam }; @@ -6390,7 +6607,10 @@ enum OpenCLParamType { static OpenCLParamType getOpenCLKernelParameterType(QualType PT) { if (PT->isPointerType()) { QualType PointeeType = PT->getPointeeType(); - return PointeeType->isPointerType() ? PtrPtrKernelParam : PtrKernelParam; + if (PointeeType->isPointerType()) + return PtrPtrKernelParam; + return PointeeType.getAddressSpace() == 0 ? PrivatePtrKernelParam + : PtrKernelParam; } // TODO: Forbid the other integer types (size_t, ptrdiff_t...) when they can @@ -6435,6 +6655,14 @@ static void checkIsValidOpenCLKernelParameter( D.setInvalidType(); return; + case PrivatePtrKernelParam: + // OpenCL v1.2 s6.9.a: + // A kernel function argument cannot be declared as a + // pointer to the private address space. + S.Diag(Param->getLocation(), diag::err_opencl_private_ptr_kernel_param); + D.setInvalidType(); + return; + // OpenCL v1.2 s6.9.k: // Arguments to kernel functions in a program cannot be declared with the // built-in scalar types bool, half, size_t, ptrdiff_t, intptr_t, and @@ -6464,7 +6692,7 @@ static void checkIsValidOpenCLKernelParameter( // Track where we are in the nested structs. Items will migrate from // VisitStack to HistoryStack as we do the DFS for bad field. SmallVector<const FieldDecl *, 4> HistoryStack; - HistoryStack.push_back((const FieldDecl *) 0); + HistoryStack.push_back(nullptr); const RecordDecl *PD = PT->castAs<RecordType>()->getDecl(); VisitStack.push_back(PD); @@ -6493,11 +6721,9 @@ static void checkIsValidOpenCLKernelParameter( } // Add a null marker so we know when we've gone back up a level - VisitStack.push_back((const Decl *) 0); + VisitStack.push_back(nullptr); - for (RecordDecl::field_iterator I = RD->field_begin(), - E = RD->field_end(); I != E; ++I) { - const FieldDecl *FD = *I; + for (const auto *FD : RD->fields()) { QualType QT = FD->getType(); if (ValidTypes.count(QT.getTypePtr())) @@ -6516,7 +6742,8 @@ static void checkIsValidOpenCLKernelParameter( // Arguments to kernel functions that are declared to be a struct or union // do not allow OpenCL objects to be passed as elements of the struct or // union. - if (ParamType == PtrKernelParam || ParamType == PtrPtrKernelParam) { + if (ParamType == PtrKernelParam || ParamType == PtrPtrKernelParam || + ParamType == PrivatePtrKernelParam) { S.Diag(Param->getLocation(), diag::err_record_with_pointers_kernel_param) << PT->isUnionType() @@ -6569,7 +6796,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, adjustMemberFunctionCC(R, D.isStaticMember()); bool isFriend = false; - FunctionTemplateDecl *FunctionTemplate = 0; + FunctionTemplateDecl *FunctionTemplate = nullptr; bool isExplicitSpecialization = false; bool isFunctionTemplateSpecialization = false; @@ -6584,7 +6811,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, FunctionDecl *NewFD = CreateNewFunctionDecl(*this, D, DC, R, TInfo, SC, isVirtualOkay); - if (!NewFD) return 0; + if (!NewFD) return nullptr; if (OriginalLexicalContext && OriginalLexicalContext->isObjCContainer()) NewFD->setTopLevelDeclInObjCContainer(); @@ -6631,19 +6858,23 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (TemplateParameterList *TemplateParams = MatchTemplateParametersToScopeSpecifier( D.getDeclSpec().getLocStart(), D.getIdentifierLoc(), - D.getCXXScopeSpec(), TemplateParamLists, isFriend, - isExplicitSpecialization, Invalid)) { + D.getCXXScopeSpec(), + D.getName().getKind() == UnqualifiedId::IK_TemplateId + ? D.getName().TemplateId + : nullptr, + TemplateParamLists, isFriend, isExplicitSpecialization, + Invalid)) { if (TemplateParams->size() > 0) { // This is a function template // Check that we can declare a template here. if (CheckTemplateDeclScope(S, TemplateParams)) - return 0; + return nullptr; // A destructor cannot be a template. if (Name.getNameKind() == DeclarationName::CXXDestructorName) { Diag(NewFD->getLocation(), diag::err_destructor_template); - return 0; + return nullptr; } // If we're adding a template to a dependent context, we may need to @@ -6673,9 +6904,10 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // This is a function template specialization. isFunctionTemplateSpecialization = true; // For source fidelity, store all the template param lists. - NewFD->setTemplateParameterListsInfo(Context, - TemplateParamLists.size(), - TemplateParamLists.data()); + if (TemplateParamLists.size() > 0) + NewFD->setTemplateParameterListsInfo(Context, + TemplateParamLists.size(), + TemplateParamLists.data()); // C++0x [temp.expl.spec]p20 forbids "template<> friend void foo(int);". if (isFriend) { @@ -6690,7 +6922,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, SourceLocation InsertLoc; if (D.getName().getKind() != UnqualifiedId::IK_TemplateId) { InsertLoc = D.getName().getSourceRange().getEnd(); - InsertLoc = PP.getLocForEndOfToken(InsertLoc); + InsertLoc = getLocForEndOfToken(InsertLoc); } Diag(D.getIdentifierLoc(), diag::err_template_spec_decl_friend) @@ -6742,14 +6974,14 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, } if (getLangOpts().CPlusPlus1y && - NewFD->getResultType()->isUndeducedType()) + NewFD->getReturnType()->isUndeducedType()) Diag(D.getDeclSpec().getVirtualSpecLoc(), diag::err_auto_fn_virtual); } if (getLangOpts().CPlusPlus1y && (NewFD->isDependentContext() || (isFriend && CurContext->isDependentContext())) && - NewFD->getResultType()->isUndeducedType()) { + NewFD->getReturnType()->isUndeducedType()) { // If the function template is referenced directly (for instance, as a // member of the current instantiation), pretend it has a dependent type. // This is not really justified by the standard, but is the only sane @@ -6758,9 +6990,9 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // a friend yet, so 'isDependentContext' on the FD doesn't work. const FunctionProtoType *FPT = NewFD->getType()->castAs<FunctionProtoType>(); - QualType Result = SubstAutoType(FPT->getResultType(), - Context.DependentTy); - NewFD->setType(Context.getFunctionType(Result, FPT->getArgTypes(), + QualType Result = + SubstAutoType(FPT->getReturnType(), Context.DependentTy); + NewFD->setType(Context.getFunctionType(Result, FPT->getParamTypes(), FPT->getExtProtoInfo())); } @@ -6833,6 +7065,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, } // If a function is defined as defaulted or deleted, mark it as such now. + // FIXME: Does this ever happen? ActOnStartOfFunctionDef forces the function + // definition kind to FDK_Definition. switch (D.getFunctionDefinitionKind()) { case FDK_Declaration: case FDK_Definition: @@ -6878,13 +7112,14 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, getLangOpts().CPlusPlus11 && FPT && !FPT->hasExceptionSpec()) { FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); EPI.ExceptionSpecType = EST_BasicNoexcept; - NewFD->setType(Context.getFunctionType(FPT->getResultType(), - FPT->getArgTypes(), EPI)); + NewFD->setType(Context.getFunctionType(FPT->getReturnType(), + FPT->getParamTypes(), EPI)); } } // Filter out previous declarations that don't match the scope. FilterLookupForScope(Previous, OriginalDC, S, shouldConsiderLinkage(NewFD), + D.getCXXScopeSpec().isNotEmpty() || isExplicitSpecialization || isFunctionTemplateSpecialization); @@ -6893,7 +7128,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // The parser guarantees this is a string. StringLiteral *SE = cast<StringLiteral>(E); NewFD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0), Context, - SE->getString())); + SE->getString(), 0)); } else if (!ExtnameUndeclaredIdentifiers.empty()) { llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I = ExtnameUndeclaredIdentifiers.find(NewFD->getIdentifier()); @@ -6914,14 +7149,9 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // single void argument. // We let through "const void" here because Sema::GetTypeForDeclarator // already checks for that case. - if (FTI.NumArgs == 1 && !FTI.isVariadic && FTI.ArgInfo[0].Ident == 0 && - FTI.ArgInfo[0].Param && - cast<ParmVarDecl>(FTI.ArgInfo[0].Param)->getType()->isVoidType()) { - // Empty arg list, don't push any params. - checkVoidParamDecl(cast<ParmVarDecl>(FTI.ArgInfo[0].Param)); - } else if (FTI.NumArgs > 0 && FTI.ArgInfo[0].Param != 0) { - for (unsigned i = 0, e = FTI.NumArgs; i != e; ++i) { - ParmVarDecl *Param = cast<ParmVarDecl>(FTI.ArgInfo[i].Param); + if (FTIHasNonVoidParameters(FTI) && FTI.Params[0].Param) { + for (unsigned i = 0, e = FTI.NumParams; i != e; ++i) { + ParmVarDecl *Param = cast<ParmVarDecl>(FTI.Params[i].Param); assert(Param->getDeclContext() != NewFD && "Was set before ?"); Param->setDeclContext(NewFD); Params.push_back(Param); @@ -6942,10 +7172,9 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // @endcode // Synthesize a parameter for each argument type. - for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(), - AE = FT->arg_type_end(); AI != AE; ++AI) { + for (const auto &AI : FT->param_types()) { ParmVarDecl *Param = - BuildParmVarDeclForTypedef(NewFD, D.getIdentifierLoc(), *AI); + BuildParmVarDeclForTypedef(NewFD, D.getIdentifierLoc(), AI); Param->setScopeInfo(0, Params.size()); Params.push_back(Param); } @@ -6969,30 +7198,53 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (D.getDeclSpec().isNoreturnSpecified()) NewFD->addAttr( ::new(Context) C11NoReturnAttr(D.getDeclSpec().getNoreturnSpecLoc(), - Context)); + Context, 0)); // Functions returning a variably modified type violate C99 6.7.5.2p2 // because all functions have linkage. if (!NewFD->isInvalidDecl() && - NewFD->getResultType()->isVariablyModifiedType()) { + NewFD->getReturnType()->isVariablyModifiedType()) { Diag(NewFD->getLocation(), diag::err_vm_func_decl); NewFD->setInvalidDecl(); } + if (D.isFunctionDefinition() && CodeSegStack.CurrentValue && + !NewFD->hasAttr<SectionAttr>()) { + NewFD->addAttr( + SectionAttr::CreateImplicit(Context, SectionAttr::Declspec_allocate, + CodeSegStack.CurrentValue->getString(), + CodeSegStack.CurrentPragmaLocation)); + if (UnifySection(CodeSegStack.CurrentValue->getString(), + PSF_Implicit | PSF_Execute | PSF_Read, NewFD)) + NewFD->dropAttr<SectionAttr>(); + } + // Handle attributes. ProcessDeclAttributes(S, NewFD, D); - QualType RetType = NewFD->getResultType(); + 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 the attribute to the new decl. Don't apply the attribute if it - // returns an instance of the class (e.g. assignment operators). - if (!MD || MD->getParent() != Ret) { - NewFD->addAttr(new (Context) WarnUnusedResultAttr(SourceRange(), - Context)); + // 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(); + if (AddressSpace == LangAS::opencl_local || + AddressSpace == LangAS::opencl_global || + AddressSpace == LangAS::opencl_constant) { + Diag(NewFD->getLocation(), + diag::err_opencl_return_value_with_address_space); + NewFD->setInvalidDecl(); } } @@ -7050,21 +7302,10 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, << SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc); HasExplicitTemplateArgs = false; - } else if (!isFunctionTemplateSpecialization && - !D.getDeclSpec().isFriendSpecified()) { - // We have encountered something that the user meant to be a - // specialization (because it has explicitly-specified template - // arguments) but that was not introduced with a "template<>" (or had - // too few of them). - // FIXME: Differentiate between attempts for explicit instantiations - // (starting with "template") and the rest. - Diag(D.getIdentifierLoc(), diag::err_template_spec_needs_header) - << SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc) - << FixItHint::CreateInsertion( - D.getDeclSpec().getLocStart(), - "template<> "); - isFunctionTemplateSpecialization = true; } else { + assert((isFunctionTemplateSpecialization || + D.getDeclSpec().isFriendSpecified()) && + "should have a 'template<>' for this decl"); // "friend void foo<>(int);" is an implicit specialization decl. isFunctionTemplateSpecialization = true; } @@ -7076,7 +7317,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // friend void foo<>(int); // Go ahead and fake up a template id. HasExplicitTemplateArgs = true; - TemplateArgs.setLAngleLoc(D.getIdentifierLoc()); + TemplateArgs.setLAngleLoc(D.getIdentifierLoc()); TemplateArgs.setRAngleLoc(D.getIdentifierLoc()); } @@ -7104,7 +7345,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, diag::err_function_specialization_in_class) << NewFD->getDeclName(); } else if (CheckFunctionTemplateSpecialization(NewFD, - (HasExplicitTemplateArgs ? &TemplateArgs : 0), + (HasExplicitTemplateArgs ? &TemplateArgs + : nullptr), Previous)) NewFD->setInvalidDecl(); @@ -7141,12 +7383,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (!NewFD->isInvalidDecl() && NewFD->isMSVCRTEntryPoint()) CheckMSVCRTEntryPoint(NewFD); - if (NewFD->isInvalidDecl()) { - // If this is a class member, mark the class invalid immediately. - // This avoids some consistency errors later. - if (CXXMethodDecl* methodDecl = dyn_cast<CXXMethodDecl>(NewFD)) - methodDecl->getParent()->setInvalidDecl(); - } else + if (!NewFD->isInvalidDecl()) D.setRedeclaration(CheckFunctionDeclaration(S, NewFD, Previous, isExplicitSpecialization)); } @@ -7178,7 +7415,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, FunctionTemplateDecl *PrevTemplate = FunctionTemplate->getPreviousDecl(); CheckTemplateParameterList(FunctionTemplate->getTemplateParameters(), - PrevTemplate ? PrevTemplate->getTemplateParameters() : 0, + PrevTemplate ? PrevTemplate->getTemplateParameters() + : nullptr, D.getDeclSpec().isFriendSpecified() ? (D.isFunctionDefinition() ? TPC_FriendFunctionTemplateDefinition @@ -7232,7 +7470,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // whether the parameter types are references). if (NamedDecl *Result = DiagnoseInvalidRedeclaration( - *this, Previous, NewFD, ExtraArgs, false, 0)) { + *this, Previous, NewFD, ExtraArgs, false, nullptr)) { AddToScope = ExtraArgs.AddToScope; return Result; } @@ -7248,11 +7486,12 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, } } - } else if (!D.isFunctionDefinition() && D.getCXXScopeSpec().isSet() && + } else if (!D.isFunctionDefinition() && + isa<CXXMethodDecl>(NewFD) && NewFD->isOutOfLine() && !isFriend && !isFunctionTemplateSpecialization && !isExplicitSpecialization) { // An out-of-line member function declaration must also be a - // definition (C++ [dcl.meaning]p1). + // definition (C++ [class.mfct]p2). // Note that this is not the case for explicit specializations of // function templates or member functions of class templates, per // C++ [temp.expl.spec]p2. We also allow these declarations as an @@ -7281,7 +7520,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, EPI.Variadic = true; EPI.ExtInfo = FT->getExtInfo(); - QualType R = Context.getFunctionType(FT->getResultType(), None, EPI); + QualType R = Context.getFunctionType(FT->getReturnType(), None, EPI); NewFD->setType(R); } @@ -7294,6 +7533,11 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // marking the function. AddCFAuditedAttribute(NewFD); + // If this is a function definition, check if we have to apply optnone due to + // a pragma. + if(D.isFunctionDefinition()) + AddRangeBasedOptnone(NewFD); + // If this is the first declaration of an extern C variable, update // the map of such variables. if (NewFD->isFirstDecl() && !NewFD->isInvalidDecl() && @@ -7303,6 +7547,12 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // Set this FunctionDecl's range up to the right paren. NewFD->setRangeEnd(D.getSourceRange().getEnd()); + if (D.isRedeclaration() && !Previous.empty()) { + checkDLLAttributeRedeclaration( + *this, dyn_cast<NamedDecl>(Previous.getRepresentativeDecl()), NewFD, + isExplicitSpecialization || isFunctionTemplateSpecialization); + } + if (getLangOpts().CPlusPlus) { if (FunctionTemplate) { if (NewFD->isInvalidDecl()) @@ -7320,18 +7570,17 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, } // OpenCL v1.2, s6.9 -- Kernels can only have return type void. - if (!NewFD->getResultType()->isVoidType()) { - Diag(D.getIdentifierLoc(), - diag::err_expected_kernel_void_return_type); + if (!NewFD->getReturnType()->isVoidType()) { + SourceRange RTRange = NewFD->getReturnTypeSourceRange(); + Diag(D.getIdentifierLoc(), diag::err_expected_kernel_void_return_type) + << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "void") + : FixItHint()); D.setInvalidType(); } llvm::SmallPtrSet<const Type *, 16> ValidTypes; - for (FunctionDecl::param_iterator PI = NewFD->param_begin(), - PE = NewFD->param_end(); PI != PE; ++PI) { - ParmVarDecl *Param = *PI; + for (auto Param : NewFD->params()) checkIsValidOpenCLKernelParameter(*this, D, Param, ValidTypes); - } } MarkUnusedFileScopedDecl(NewFD); @@ -7341,7 +7590,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (!NewFD->isInvalidDecl() && NewFD->getDeclContext()->getRedeclContext()->isTranslationUnit()) { if (II->isStr("cudaConfigureCall")) { - if (!R->getAs<FunctionType>()->getResultType()->isScalarType()) + if (!R->getAs<FunctionType>()->getReturnType()->isScalarType()) Diag(NewFD->getLocation(), diag::err_config_scalar_return); Context.setcudaConfigureCallDecl(NewFD); @@ -7383,8 +7632,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, LookupResult &Previous, bool IsExplicitSpecialization) { - assert(!NewFD->getResultType()->isVariablyModifiedType() - && "Variably modified return types are not handled here"); + assert(!NewFD->getReturnType()->isVariablyModifiedType() && + "Variably modified return types are not handled here"); // Determine whether the type of this function should be merged with // a previous visible declaration. This never happens for functions in C++, @@ -7396,7 +7645,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, filterNonConflictingPreviousDecls(Context, NewFD, Previous); bool Redeclaration = false; - NamedDecl *OldDecl = 0; + NamedDecl *OldDecl = nullptr; // Merge or overload the declaration with an existing declaration of // the same name, if appropriate. @@ -7432,7 +7681,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, // with that name must be marked "overloadable". Diag(NewFD->getLocation(), diag::err_attribute_overloadable_missing) << Redeclaration << NewFD; - NamedDecl *OverloadedDecl = 0; + NamedDecl *OverloadedDecl = nullptr; if (Redeclaration) OverloadedDecl = OldDecl; else if (!Previous.empty()) @@ -7440,8 +7689,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, if (OverloadedDecl) Diag(OverloadedDecl->getLocation(), diag::note_attribute_overloadable_prev_overload); - NewFD->addAttr(::new (Context) OverloadableAttr(SourceLocation(), - Context)); + NewFD->addAttr(OverloadableAttr::CreateImplicit(Context)); } } } @@ -7464,12 +7712,11 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, << Redeclaration << NewFD; Diag(Previous.getFoundDecl()->getLocation(), diag::note_attribute_overloadable_prev_overload); - NewFD->addAttr(::new (Context) OverloadableAttr(SourceLocation(), - Context)); + NewFD->addAttr(OverloadableAttr::CreateImplicit(Context)); } if (IsOverload(NewFD, cast<FunctionDecl>(OldDecl), false)) { Redeclaration = false; - OldDecl = 0; + OldDecl = nullptr; } } } @@ -7488,17 +7735,16 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, if (!getLangOpts().CPlusPlus1y && MD && MD->isConstexpr() && !MD->isStatic() && !isa<CXXConstructorDecl>(MD) && (MD->getTypeQualifiers() & Qualifiers::Const) == 0) { - CXXMethodDecl *OldMD = dyn_cast_or_null<CXXMethodDecl>(OldDecl); - if (FunctionTemplateDecl *OldTD = - dyn_cast_or_null<FunctionTemplateDecl>(OldDecl)) - OldMD = dyn_cast<CXXMethodDecl>(OldTD->getTemplatedDecl()); + CXXMethodDecl *OldMD = nullptr; + if (OldDecl) + OldMD = dyn_cast<CXXMethodDecl>(OldDecl->getAsFunction()); if (!OldMD || !OldMD->isStatic()) { const FunctionProtoType *FPT = MD->getType()->castAs<FunctionProtoType>(); FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); EPI.TypeQuals |= Qualifiers::Const; - MD->setType(Context.getFunctionType(FPT->getResultType(), - FPT->getArgTypes(), EPI)); + MD->setType(Context.getFunctionType(FPT->getReturnType(), + FPT->getParamTypes(), EPI)); // Warn that we did this, if we're not performing template instantiation. // In that case, we'll have warned already when the template was defined. @@ -7506,7 +7752,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, SourceLocation AddConstLoc; if (FunctionTypeLoc FTL = MD->getTypeSourceInfo()->getTypeLoc() .IgnoreParens().getAs<FunctionTypeLoc>()) - AddConstLoc = PP.getLocForEndOfToken(FTL.getRParenLoc()); + AddConstLoc = getLocForEndOfToken(FTL.getRParenLoc()); Diag(MD->getLocation(), diag::warn_cxx1y_compat_constexpr_not_const) << FixItHint::CreateInsertion(AddConstLoc, " const"); @@ -7656,7 +7902,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, // compatible, and if it does, warn the user. // But, issue any diagnostic on the first declaration only. if (NewFD->isExternC() && Previous.empty()) { - QualType R = NewFD->getResultType(); + QualType R = NewFD->getReturnType(); if (R->isIncompleteType() && !R->isVoidType()) Diag(NewFD->getLocation(), diag::warn_return_value_udt_incomplete) << NewFD << R; @@ -7668,26 +7914,10 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, return Redeclaration; } -static SourceRange getResultSourceRange(const FunctionDecl *FD) { - const TypeSourceInfo *TSI = FD->getTypeSourceInfo(); - if (!TSI) - return SourceRange(); - - TypeLoc TL = TSI->getTypeLoc(); - FunctionTypeLoc FunctionTL = TL.getAs<FunctionTypeLoc>(); - if (!FunctionTL) - return SourceRange(); - - TypeLoc ResultTL = FunctionTL.getResultLoc(); - if (ResultTL.getUnqualifiedLoc().getAs<BuiltinTypeLoc>()) - return ResultTL.getSourceRange(); - - return SourceRange(); -} - void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) { - // C++11 [basic.start.main]p3: A program that declares main to be inline, - // static or constexpr is ill-formed. + // C++11 [basic.start.main]p3: + // A program that [...] declares main to be inline, static or + // constexpr is ill-formed. // C11 6.7.4p4: In a hosted environment, no function specifier(s) shall // appear in a declaration of main. // static main is not an error under C99, but we should warn about it. @@ -7701,8 +7931,7 @@ void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) { << FixItHint::CreateRemoval(DS.getInlineSpecLoc()); if (DS.isNoreturnSpecified()) { SourceLocation NoreturnLoc = DS.getNoreturnSpecLoc(); - SourceRange NoreturnRange(NoreturnLoc, - PP.getLocForEndOfToken(NoreturnLoc)); + SourceRange NoreturnRange(NoreturnLoc, getLocForEndOfToken(NoreturnLoc)); Diag(NoreturnLoc, diag::ext_noreturn_main); Diag(NoreturnLoc, diag::note_main_remove_noreturn) << FixItHint::CreateRemoval(NoreturnRange); @@ -7724,41 +7953,44 @@ void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) { assert(T->isFunctionType() && "function decl is not of function type"); const FunctionType* FT = T->castAs<FunctionType>(); - // All the standards say that main() should should return 'int'. - if (Context.hasSameUnqualifiedType(FT->getResultType(), Context.IntTy)) { + if (getLangOpts().GNUMode && !getLangOpts().CPlusPlus) { + // In C with GNU extensions we allow main() to have non-integer return + // type, but we should warn about the extension, and we disable the + // implicit-return-zero rule. + + // GCC in C mode accepts qualified 'int'. + if (Context.hasSameUnqualifiedType(FT->getReturnType(), Context.IntTy)) + FD->setHasImplicitReturnZero(true); + else { + Diag(FD->getTypeSpecStartLoc(), diag::ext_main_returns_nonint); + SourceRange RTRange = FD->getReturnTypeSourceRange(); + if (RTRange.isValid()) + Diag(RTRange.getBegin(), diag::note_main_change_return_type) + << FixItHint::CreateReplacement(RTRange, "int"); + } + } else { // In C and C++, main magically returns 0 if you fall off the end; // set the flag which tells us that. // This is C++ [basic.start.main]p5 and C99 5.1.2.2.3. - FD->setHasImplicitReturnZero(true); - // In C with GNU extensions we allow main() to have non-integer return - // type, but we should warn about the extension, and we disable the - // implicit-return-zero rule. - } else if (getLangOpts().GNUMode && !getLangOpts().CPlusPlus) { - Diag(FD->getTypeSpecStartLoc(), diag::ext_main_returns_nonint); - - SourceRange ResultRange = getResultSourceRange(FD); - if (ResultRange.isValid()) - Diag(ResultRange.getBegin(), diag::note_main_change_return_type) - << FixItHint::CreateReplacement(ResultRange, "int"); - - // Otherwise, this is just a flat-out error. - } else { - SourceRange ResultRange = getResultSourceRange(FD); - if (ResultRange.isValid()) + // All the standards say that main() should return 'int'. + if (Context.hasSameType(FT->getReturnType(), Context.IntTy)) + FD->setHasImplicitReturnZero(true); + else { + // Otherwise, this is just a flat-out error. + SourceRange RTRange = FD->getReturnTypeSourceRange(); Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint) - << FixItHint::CreateReplacement(ResultRange, "int"); - else - Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint); - - FD->setInvalidDecl(true); + << (RTRange.isValid() ? FixItHint::CreateReplacement(RTRange, "int") + : FixItHint()); + FD->setInvalidDecl(true); + } } // Treat protoless main() as nullary. if (isa<FunctionNoProtoType>(FT)) return; const FunctionProtoType* FTP = cast<const FunctionProtoType>(FT); - unsigned nparams = FTP->getNumArgs(); + unsigned nparams = FTP->getNumParams(); assert(FD->getNumParams() == nparams); bool HasExtraParameters = (nparams > 3); @@ -7783,7 +8015,7 @@ void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) { QualType Expected[] = { Context.IntTy, CharPP, CharPP, CharPP }; for (unsigned i = 0; i < nparams; ++i) { - QualType AT = FTP->getArgType(i); + QualType AT = FTP->getParamType(i); bool mismatch = true; @@ -7818,7 +8050,7 @@ void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) { } if (!FD->isInvalidDecl() && FD->getDescribedFunctionTemplate()) { - Diag(FD->getLocation(), diag::err_mainlike_template_decl) << FD->getName(); + Diag(FD->getLocation(), diag::err_mainlike_template_decl) << FD; FD->setInvalidDecl(); } } @@ -7830,15 +8062,15 @@ void Sema::CheckMSVCRTEntryPoint(FunctionDecl *FD) { // Set an implicit return of 'zero' if the function can return some integral, // enumeration, pointer or nullptr type. - if (FT->getResultType()->isIntegralOrEnumerationType() || - FT->getResultType()->isAnyPointerType() || - FT->getResultType()->isNullPtrType()) + if (FT->getReturnType()->isIntegralOrEnumerationType() || + FT->getReturnType()->isAnyPointerType() || + FT->getReturnType()->isNullPtrType()) // DllMain is exempt because a return value of zero means it failed. if (FD->getName() != "DllMain") FD->setHasImplicitReturnZero(true); if (!FD->isInvalidDecl() && FD->getDescribedFunctionTemplate()) { - Diag(FD->getLocation(), diag::err_mainlike_template_decl) << FD->getName(); + Diag(FD->getLocation(), diag::err_mainlike_template_decl) << FD; FD->setInvalidDecl(); } } @@ -7852,10 +8084,11 @@ bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) { // "may accept other forms of constant expressions" exception. // (We never end up here for C++, so the constant expression // rules there don't matter.) - if (Init->isConstantInitializer(Context, false)) + const Expr *Culprit; + if (Init->isConstantInitializer(Context, false, &Culprit)) return false; - Diag(Init->getExprLoc(), diag::err_init_element_not_constant) - << Init->getSourceRange(); + Diag(Culprit->getExprLoc(), diag::err_init_element_not_constant) + << Culprit->getSourceRange(); return true; } @@ -8029,7 +8262,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit, bool TypeMayContainAuto) { // If there is no declaration, there was an error parsing it. Just ignore // the initializer. - if (RealDecl == 0 || RealDecl->isInvalidDecl()) + if (!RealDecl || RealDecl->isInvalidDecl()) return; if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(RealDecl)) { @@ -8084,6 +8317,11 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, return; } else { DeduceInit = CXXDirectInit->getExpr(0); + if (isa<InitListExpr>(DeduceInit)) + Diag(CXXDirectInit->getLocStart(), + diag::err_auto_var_init_paren_braces) + << VDecl->getDeclName() << VDecl->getType() + << VDecl->getSourceRange(); } } @@ -8096,7 +8334,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, VDecl->setInvalidDecl(); return; } - Init = Result.take(); + Init = Result.get(); DefaultedToAuto = true; } @@ -8141,6 +8379,13 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, return; } + // dllimport cannot be used on variable definitions. + if (VDecl->hasAttr<DLLImportAttr>() && !VDecl->isStaticDataMember()) { + Diag(VDecl->getLocation(), diag::err_attribute_dllimport_data_definition); + VDecl->setInvalidDecl(); + return; + } + if (VDecl->isLocalVarDecl() && VDecl->hasExternalStorage()) { // C99 6.7.8p5. C++ has no such restriction, but that is a defect. Diag(VDecl->getLocation(), diag::err_block_extern_cant_init); @@ -8176,8 +8421,8 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, VDecl->setInvalidDecl(); return; } - - const VarDecl* PrevInit = 0; + + const VarDecl *PrevInit = nullptr; if (getLangOpts().CPlusPlus) { // C++ [class.static.data]p4 // If a static data member is of const integral or const @@ -8192,9 +8437,9 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // data members we also need to check whether there was an in-class // declaration with an initializer. if (VDecl->isStaticDataMember() && VDecl->getAnyInitializer(PrevInit)) { - Diag(VDecl->getLocation(), diag::err_redefinition) - << VDecl->getDeclName(); - Diag(PrevInit->getLocation(), diag::note_previous_definition); + Diag(Init->getExprLoc(), diag::err_static_data_member_reinitialization) + << VDecl->getDeclName(); + Diag(PrevInit->getInit()->getExprLoc(), diag::note_previous_initializer) << 0; return; } @@ -8228,7 +8473,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, VDecl->setInvalidDecl(); return; } - Init = Result.take(); + Init = Result.get(); } // Perform the initialization. @@ -8256,7 +8501,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, return; } - Init = Result.takeAs<Expr>(); + Init = Result.getAs<Expr>(); } // Check for self-references within variable initializers. @@ -8287,13 +8532,10 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // 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) { - DiagnosticsEngine::Level Level = - Diags.getDiagnosticLevel(diag::warn_arc_repeated_use_of_weak, - Init->getLocStart()); - if (Level != DiagnosticsEngine::Ignored) + if (VDecl->getType().getObjCLifetime() == Qualifiers::OCL_Strong && + !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, + Init->getLocStart())) getCurFunction()->markSafeWeakUse(Init); - } } // The initialization is usually a full-expression. @@ -8314,7 +8556,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, VDecl->setInvalidDecl(); return; } - Init = Result.take(); + Init = Result.get(); // Attach the initializer to the decl. VDecl->setInit(Init); @@ -8324,6 +8566,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // static storage duration shall be constant expressions or string literals. // C++ does not have this restriction. if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl()) { + const Expr *Culprit; if (VDecl->getStorageClass() == SC_Static) CheckForConstantInitializer(Init, DclT); // C89 is stricter than C99 for non-static aggregate types. @@ -8332,10 +8575,10 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // constant expressions. else if (!getLangOpts().C99 && VDecl->getType()->isAggregateType() && isa<InitListExpr>(Init) && - !Init->isConstantInitializer(Context, false)) - Diag(Init->getExprLoc(), + !Init->isConstantInitializer(Context, false, &Culprit)) + Diag(Culprit->getExprLoc(), diag::ext_aggregate_init_not_constant) - << Init->getSourceRange(); + << Culprit->getSourceRange(); } } else if (VDecl->isStaticDataMember() && VDecl->getLexicalDeclContext()->isRecord()) { @@ -8444,19 +8687,6 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // C99 6.7.8p4. All file scoped initializers need to be constant. if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl()) CheckForConstantInitializer(Init, DclT); - else if (VDecl->getTLSKind() == VarDecl::TLS_Static && - !VDecl->isInvalidDecl() && !DclT->isDependentType() && - !Init->isValueDependent() && !VDecl->isConstexpr() && - !Init->isConstantInitializer( - Context, VDecl->getType()->isReferenceType())) { - // GNU C++98 edits for __thread, [basic.start.init]p4: - // An object of thread storage duration shall not require dynamic - // initialization. - // FIXME: Need strict checking here. - Diag(VDecl->getLocation(), diag::err_thread_dynamic_init); - if (getLangOpts().CPlusPlus11) - Diag(VDecl->getLocation(), diag::note_use_thread_local); - } } // We will represent direct-initialization similarly to copy-initialization: @@ -8512,7 +8742,7 @@ void Sema::ActOnInitializerError(Decl *D) { return; } - // Require an abstract type. + // Require a non-abstract type. if (RequireNonAbstractType(VD->getLocation(), Ty, diag::err_abstract_type_in_decl, AbstractVariableType)) { @@ -8527,7 +8757,7 @@ void Sema::ActOnInitializerError(Decl *D) { void Sema::ActOnUninitializedDecl(Decl *RealDecl, bool TypeMayContainAuto) { // If there is no declaration, there was an error parsing it. Just ignore it. - if (RealDecl == 0) + if (!RealDecl) return; if (VarDecl *Var = dyn_cast<VarDecl>(RealDecl)) { @@ -8558,6 +8788,16 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl, return; } + // OpenCL v1.1 s6.5.3: variables declared in the constant address space must + // be initialized. + if (!Var->isInvalidDecl() && + Var->getType().getAddressSpace() == LangAS::opencl_constant && + Var->getStorageClass() != SC_Extern && !Var->getInit()) { + Diag(Var->getLocation(), diag::err_opencl_constant_no_init); + Var->setInvalidDecl(); + return; + } + switch (Var->isThisDeclarationADefinition()) { case VarDecl::Definition: if (!Var->isStaticDataMember() || !Var->getAnyInitializer()) @@ -8657,11 +8897,13 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl, if (Var->isInvalidDecl()) return; - if (RequireCompleteType(Var->getLocation(), - Context.getBaseElementType(Type), - diag::err_typecheck_decl_incomplete_type)) { - Var->setInvalidDecl(); - return; + if (!Var->hasAttr<AliasAttr>()) { + if (RequireCompleteType(Var->getLocation(), + Context.getBaseElementType(Type), + diag::err_typecheck_decl_incomplete_type)) { + Var->setInvalidDecl(); + return; + } } // The variable can not have an abstract class type. @@ -8768,6 +9010,37 @@ void Sema::ActOnCXXForRangeDecl(Decl *D) { } } +StmtResult +Sema::ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc, + IdentifierInfo *Ident, + ParsedAttributes &Attrs, + SourceLocation AttrEnd) { + // C++1y [stmt.iter]p1: + // A range-based for statement of the form + // for ( for-range-identifier : for-range-initializer ) statement + // is equivalent to + // for ( auto&& for-range-identifier : for-range-initializer ) statement + DeclSpec DS(Attrs.getPool().getFactory()); + + const char *PrevSpec; + unsigned DiagID; + DS.SetTypeSpecType(DeclSpec::TST_auto, IdentLoc, PrevSpec, DiagID, + getPrintingPolicy()); + + Declarator D(DS, Declarator::ForContext); + D.SetIdentifier(Ident, IdentLoc); + D.takeAttributes(Attrs, AttrEnd); + + ParsedAttributes EmptyAttrs(Attrs.getPool().getFactory()); + D.AddTypeInfo(DeclaratorChunk::getReference(0, IdentLoc, /*lvalue*/false), + EmptyAttrs, IdentLoc); + Decl *Var = ActOnDeclarator(S, D); + cast<VarDecl>(Var)->setCXXForRangeDecl(true); + FinalizeDeclaration(Var); + return ActOnDeclStmt(FinalizeDeclaratorGroup(S, DS, Var), IdentLoc, + AttrEnd.isValid() ? AttrEnd : IdentLoc); +} + void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { if (var->isInvalidDecl()) return; @@ -8788,11 +9061,16 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { } } + // 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 + // class members because the linkage of an anonymous class can + // change if it's later given a typedef name. if (var->isThisDeclarationADefinition() && + var->getDeclContext()->getRedeclContext()->isFileContext() && var->isExternallyVisible() && var->hasLinkage() && - getDiagnostics().getDiagnosticLevel( - diag::warn_missing_variable_declarations, - var->getLocation())) { + !getDiagnostics().isIgnored(diag::warn_missing_variable_declarations, + var->getLocation())) { // Find a previous declaration that's not a definition. VarDecl *prev = var->getPreviousDecl(); while (prev && prev->isThisDeclarationADefinition()) @@ -8802,14 +9080,58 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { Diag(var->getLocation(), diag::warn_missing_variable_declarations) << var; } - if (var->getTLSKind() == VarDecl::TLS_Static && - var->getType().isDestructedType()) { - // GNU C++98 edits for __thread, [basic.start.term]p3: - // The type of an object with thread storage duration shall not - // have a non-trivial destructor. - Diag(var->getLocation(), diag::err_thread_nontrivial_dtor); - if (getLangOpts().CPlusPlus11) - Diag(var->getLocation(), diag::note_use_thread_local); + if (var->getTLSKind() == VarDecl::TLS_Static) { + const Expr *Culprit; + if (var->getType().isDestructedType()) { + // GNU C++98 edits for __thread, [basic.start.term]p3: + // The type of an object with thread storage duration shall not + // have a non-trivial destructor. + Diag(var->getLocation(), diag::err_thread_nontrivial_dtor); + if (getLangOpts().CPlusPlus11) + Diag(var->getLocation(), diag::note_use_thread_local); + } else if (getLangOpts().CPlusPlus && var->hasInit() && + !var->getInit()->isConstantInitializer( + Context, var->getType()->isReferenceType(), &Culprit)) { + // GNU C++98 edits for __thread, [basic.start.init]p4: + // An object of thread storage duration shall not require dynamic + // initialization. + // FIXME: Need strict checking here. + Diag(Culprit->getExprLoc(), diag::err_thread_dynamic_init) + << Culprit->getSourceRange(); + if (getLangOpts().CPlusPlus11) + Diag(var->getLocation(), diag::note_use_thread_local); + } + + } + + if (var->isThisDeclarationADefinition() && + ActiveTemplateInstantiations.empty()) { + PragmaStack<StringLiteral *> *Stack = nullptr; + int SectionFlags = PSF_Implicit | PSF_Read; + if (var->getType().isConstQualified()) + Stack = &ConstSegStack; + else if (!var->getInit()) { + Stack = &BSSSegStack; + SectionFlags |= PSF_Write; + } else { + Stack = &DataSegStack; + SectionFlags |= PSF_Write; + } + if (!var->hasAttr<SectionAttr>() && Stack->CurrentValue) + 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>(); + + // Apply the init_seg attribute if this has an initializer. If the + // initializer turns out to not be dynamic, we'll end up ignoring this + // attribute. + if (CurInitSeg && var->getInit()) + var->addAttr(InitSegAttr::CreateImplicit(Context, CurInitSeg->getString(), + CurInitSegLoc)); } // All the following checks are C++ only. @@ -8835,7 +9157,7 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { var, var->getType(), varRef, /*AllowNRVO=*/true); if (!result.isInvalid()) { result = MaybeCreateExprWithCleanups(result); - Expr *init = result.takeAs<Expr>(); + Expr *init = result.getAs<Expr>(); Context.setBlockVarCopyInits(var, init); } } @@ -8848,9 +9170,8 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { if (!var->getDeclContext()->isDependentContext() && Init && !Init->isValueDependent()) { if (IsGlobal && !var->isConstexpr() && - getDiagnostics().getDiagnosticLevel(diag::warn_global_constructor, - var->getLocation()) - != DiagnosticsEngine::Ignored) { + !getDiagnostics().isIgnored(diag::warn_global_constructor, + var->getLocation())) { // Warn about globals which don't have a constant initializer. Don't // warn about globals with a non-trivial destructor because we already // warned about them. @@ -8901,9 +9222,45 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) { if (!VD) return; + checkAttributesAfterMerging(*this, *VD); + + // Static locals inherit dll attributes from their function. + if (VD->isStaticLocal()) { + if (FunctionDecl *FD = + dyn_cast<FunctionDecl>(VD->getParentFunctionOrMethod())) { + if (Attr *A = getDLLAttr(FD)) { + auto *NewAttr = cast<InheritableAttr>(A->clone(getASTContext())); + NewAttr->setInherited(true); + VD->addAttr(NewAttr); + } + } + } + + // Imported static data members cannot be defined out-of-line. + if (const DLLImportAttr *IA = VD->getAttr<DLLImportAttr>()) { + if (VD->isStaticDataMember() && VD->isOutOfLine() && + VD->isThisDeclarationADefinition()) { + // We allow definitions of dllimport class template static data members + // with a warning. + CXXRecordDecl *Context = + cast<CXXRecordDecl>(VD->getFirstDecl()->getDeclContext()); + bool IsClassTemplateMember = + isa<ClassTemplatePartialSpecializationDecl>(Context) || + Context->getDescribedClassTemplate(); + + Diag(VD->getLocation(), + IsClassTemplateMember + ? diag::warn_attribute_dllimport_static_field_definition + : diag::err_attribute_dllimport_static_field_definition); + Diag(IA->getLocation(), diag::note_attribute); + if (!IsClassTemplateMember) + VD->setInvalidDecl(); + } + } + if (UsedAttr *Attr = VD->getAttr<UsedAttr>()) { if (!Attr->isInherited() && !VD->isThisDeclarationADefinition()) { - Diag(Attr->getLocation(), diag::warn_attribute_ignored) << "used"; + Diag(Attr->getLocation(), diag::warn_attribute_ignored) << Attr; VD->dropAttr<UsedAttr>(); } } @@ -8923,10 +9280,12 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) { 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. - if (!DC->isRecord() && VD->isExternallyVisible()) + if (DC->getRedeclContext()->isFileContext() && VD->isExternallyVisible()) AddPushedVisibilityAttribute(VD); - if (VD->isFileVarDecl()) + // FIXME: Warn on unused templates. + if (VD->isFileVarDecl() && !VD->getDescribedVarTemplate() && + !isa<VarTemplatePartialSpecializationDecl>(VD)) MarkUnusedFileScopedDecl(VD); // Now we have parsed the initializer and can update the table of magic @@ -8935,10 +9294,7 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) { !VD->getType()->isIntegralOrEnumerationType()) return; - for (specific_attr_iterator<TypeTagForDatatypeAttr> - I = ThisDecl->specific_attr_begin<TypeTagForDatatypeAttr>(), - E = ThisDecl->specific_attr_end<TypeTagForDatatypeAttr>(); - I != E; ++I) { + for (const auto *I : ThisDecl->specific_attrs<TypeTagForDatatypeAttr>()) { const Expr *MagicValueExpr = VD->getInit(); if (!MagicValueExpr) { continue; @@ -8972,7 +9328,7 @@ Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, if (DS.isTypeSpecOwned()) Decls.push_back(DS.getRepAsDecl()); - DeclaratorDecl *FirstDeclaratorInGroup = 0; + DeclaratorDecl *FirstDeclaratorInGroup = nullptr; for (unsigned i = 0, e = Group.size(); i != e; ++i) if (Decl *D = Group[i]) { if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) @@ -8983,7 +9339,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); + HandleTagNumbering(*this, Tag, S); if (!Tag->hasNameForLinkage() && !Tag->hasDeclaratorForAnonDecl()) Tag->setDeclaratorForAnonDecl(FirstDeclaratorInGroup); } @@ -8995,7 +9351,7 @@ Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, /// BuildDeclaratorGroup - convert a list of declarations into a declaration /// group, performing any necessary semantic checking. Sema::DeclGroupPtrTy -Sema::BuildDeclaratorGroup(llvm::MutableArrayRef<Decl *> Group, +Sema::BuildDeclaratorGroup(MutableArrayRef<Decl *> Group, bool TypeMayContainAuto) { // C++0x [dcl.spec.auto]p7: // If the type deduced for the template parameter U is not the same in each @@ -9007,7 +9363,7 @@ Sema::BuildDeclaratorGroup(llvm::MutableArrayRef<Decl *> Group, if (TypeMayContainAuto && Group.size() > 1) { QualType Deduced; CanQualType DeducedCanon; - VarDecl *DeducedDecl = 0; + VarDecl *DeducedDecl = nullptr; for (unsigned i = 0, e = Group.size(); i != e; ++i) { if (VarDecl *D = dyn_cast<VarDecl>(Group[i])) { AutoType *AT = D->getType()->getContainedAutoType(); @@ -9052,9 +9408,7 @@ void Sema::ActOnDocumentableDecls(ArrayRef<Decl *> Group) { if (Group.empty() || !Group[0]) return; - if (Diags.getDiagnosticLevel(diag::warn_doc_param_not_found, - Group[0]->getLocation()) - == DiagnosticsEngine::Ignored) + if (Diags.isIgnored(diag::warn_doc_param_not_found, Group[0]->getLocation())) return; if (Group.size() >= 2) { @@ -9133,12 +9487,12 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { } // Ensure we have a valid name - IdentifierInfo *II = 0; + IdentifierInfo *II = nullptr; if (D.hasName()) { II = D.getIdentifier(); if (!II) { Diag(D.getIdentifierLoc(), diag::err_bad_parameter_name) - << GetNameForDeclarator(D).getName().getAsString(); + << GetNameForDeclarator(D).getName(); D.setInvalidType(true); } } @@ -9154,14 +9508,14 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { // Maybe we will complain about the shadowed template parameter. DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl); // Just pretend that we didn't see the previous declaration. - PrevDecl = 0; + PrevDecl = nullptr; } else if (S->isDeclScope(PrevDecl)) { Diag(D.getIdentifierLoc(), diag::err_param_redefinition) << II; Diag(PrevDecl->getLocation(), diag::note_previous_declaration); // Recover by removing the name - II = 0; - D.SetIdentifier(0, D.getIdentifierLoc()); + II = nullptr; + D.SetIdentifier(nullptr, D.getIdentifierLoc()); D.setInvalidType(true); } } @@ -9211,9 +9565,9 @@ ParmVarDecl *Sema::BuildParmVarDeclForTypedef(DeclContext *DC, /* FIXME: setting StartLoc == Loc. Would it be worth to modify callers so as to provide proper source location for the unnamed parameters, embedding the parameter's type? */ - ParmVarDecl *Param = ParmVarDecl::Create(Context, DC, Loc, Loc, 0, + ParmVarDecl *Param = ParmVarDecl::Create(Context, DC, Loc, Loc, nullptr, T, Context.getTrivialTypeSourceInfo(T, Loc), - SC_None, 0); + SC_None, nullptr); Param->setImplicit(); return Param; } @@ -9293,7 +9647,7 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc, ParmVarDecl *New = ParmVarDecl::Create(Context, DC, StartLoc, NameLoc, Name, Context.getAdjustedParameterType(T), TSInfo, - StorageClass, 0); + StorageClass, nullptr); // Parameters can not be abstract class types. // For record types, this is done by the AbstractClassUsageDiagnoser once @@ -9319,8 +9673,12 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc, // Since all parameters have automatic store duration, they can not have // an address space. if (T.getAddressSpace() != 0) { - Diag(NameLoc, diag::err_arg_with_address_space); - New->setInvalidDecl(); + // OpenCL allows function arguments declared to be an array of a type + // to be qualified with an address space. + if (!(getLangOpts().OpenCL && T->isArrayType())) { + Diag(NameLoc, diag::err_arg_with_address_space); + New->setInvalidDecl(); + } } return New; @@ -9333,16 +9691,15 @@ void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D, // Verify 6.9.1p6: 'every identifier in the identifier list shall be declared' // for a K&R function. if (!FTI.hasPrototype) { - for (int i = FTI.NumArgs; i != 0; /* decrement in loop */) { + for (int i = FTI.NumParams; i != 0; /* decrement in loop */) { --i; - if (FTI.ArgInfo[i].Param == 0) { + if (FTI.Params[i].Param == nullptr) { SmallString<256> Code; - llvm::raw_svector_ostream(Code) << " int " - << FTI.ArgInfo[i].Ident->getName() - << ";\n"; - Diag(FTI.ArgInfo[i].IdentLoc, diag::ext_param_not_declared) - << FTI.ArgInfo[i].Ident - << FixItHint::CreateInsertion(LocAfterDecls, Code.str()); + llvm::raw_svector_ostream(Code) + << " 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()); // Implicitly declare the argument as type 'int' for lack of a better // type. @@ -9350,21 +9707,21 @@ void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D, DeclSpec DS(attrs); const char* PrevSpec; // unused unsigned DiagID; // unused - DS.SetTypeSpecType(DeclSpec::TST_int, FTI.ArgInfo[i].IdentLoc, - PrevSpec, DiagID); + DS.SetTypeSpecType(DeclSpec::TST_int, FTI.Params[i].IdentLoc, PrevSpec, + DiagID, Context.getPrintingPolicy()); // Use the identifier location for the type source range. - DS.SetRangeStart(FTI.ArgInfo[i].IdentLoc); - DS.SetRangeEnd(FTI.ArgInfo[i].IdentLoc); + DS.SetRangeStart(FTI.Params[i].IdentLoc); + DS.SetRangeEnd(FTI.Params[i].IdentLoc); Declarator ParamD(DS, Declarator::KNRTypeListContext); - ParamD.SetIdentifier(FTI.ArgInfo[i].Ident, FTI.ArgInfo[i].IdentLoc); - FTI.ArgInfo[i].Param = ActOnParamDeclarator(S, ParamD); + ParamD.SetIdentifier(FTI.Params[i].Ident, FTI.Params[i].IdentLoc); + FTI.Params[i].Param = ActOnParamDeclarator(S, ParamD); } } } } Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) { - assert(getCurFunctionDecl() == 0 && "Function parsing confused"); + assert(getCurFunctionDecl() == nullptr && "Function parsing confused"); assert(D.isFunctionDeclarator() && "Not a function declarator!"); Scope *ParentScope = FnBodyScope->getParent(); @@ -9373,6 +9730,10 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) { return ActOnStartOfFunctionDef(FnBodyScope, DP); } +void Sema::ActOnFinishInlineMethodDef(CXXMethodDecl *D) { + Consumer.HandleInlineMethodDefinition(D); +} + static bool ShouldWarnAboutMissingPrototype(const FunctionDecl *FD, const FunctionDecl*& PossibleZeroParamPrototype) { // Don't warn about invalid declarations. @@ -9456,7 +9817,7 @@ static void RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator, LambdaScopeInfo *LSI = S.PushLambdaScope(); LSI->CallOperator = CallOperator; LSI->Lambda = LambdaClass; - LSI->ReturnType = CallOperator->getResultType(); + LSI->ReturnType = CallOperator->getReturnType(); const LambdaCaptureDefault LCD = LambdaClass->getLambdaCaptureDefault(); if (LCD == LCD_None) @@ -9472,23 +9833,22 @@ static void RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator, // Add the captures to the LSI so they can be noted as already // captured within tryCaptureVar. - for (LambdaExpr::capture_iterator C = LambdaClass->captures_begin(), - CEnd = LambdaClass->captures_end(); C != CEnd; ++C) { - if (C->capturesVariable()) { - VarDecl *VD = C->getCapturedVar(); + for (const auto &C : LambdaClass->captures()) { + if (C.capturesVariable()) { + VarDecl *VD = C.getCapturedVar(); if (VD->isInitCapture()) S.CurrentInstantiationScope->InstantiatedLocal(VD, VD); QualType CaptureType = VD->getType(); - const bool ByRef = C->getCaptureKind() == LCK_ByRef; + const bool ByRef = C.getCaptureKind() == LCK_ByRef; LSI->addCapture(VD, /*IsBlock*/false, ByRef, - /*RefersToEnclosingLocal*/true, C->getLocation(), - /*EllipsisLoc*/C->isPackExpansion() - ? C->getEllipsisLoc() : SourceLocation(), - CaptureType, /*Expr*/ 0); - - } else if (C->capturesThis()) { - LSI->addThisCapture(/*Nested*/ false, C->getLocation(), - S.getCurrentThisType(), /*Expr*/ 0); + /*RefersToEnclosingLocal*/true, C.getLocation(), + /*EllipsisLoc*/C.isPackExpansion() + ? C.getEllipsisLoc() : SourceLocation(), + CaptureType, /*Expr*/ nullptr); + + } else if (C.capturesThis()) { + LSI->addThisCapture(/*Nested*/ false, C.getLocation(), + S.getCurrentThisType(), /*Expr*/ nullptr); } } } @@ -9499,7 +9859,7 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { if (!D) return D; - FunctionDecl *FD = 0; + FunctionDecl *FD = nullptr; if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D)) FD = FunTmpl->getTemplatedDecl(); @@ -9539,7 +9899,7 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { // The return type of a function definition must be complete // (C99 6.9.1p3, C++ [dcl.fct]p6). - QualType ResultType = FD->getResultType(); + QualType ResultType = FD->getReturnType(); if (!ResultType->isDependentType() && !ResultType->isVoidType() && !FD->isInvalidDecl() && RequireCompleteType(FD->getLocation(), ResultType, @@ -9551,7 +9911,7 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { // 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 = 0; + const FunctionDecl *PossibleZeroParamPrototype = nullptr; if (ShouldWarnAboutMissingPrototype(FD, PossibleZeroParamPrototype)) { Diag(FD->getLocation(), diag::warn_missing_prototype) << FD; @@ -9578,8 +9938,7 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { /*CheckParameterNames=*/true); // Introduce our parameters into the function scope - for (unsigned p = 0, NumParams = FD->getNumParams(); p < NumParams; ++p) { - ParmVarDecl *Param = FD->getParamDecl(p); + for (auto Param : FD->params()) { Param->setOwningFunction(FD); // If this has an identifier, add it to the scope stack. @@ -9604,9 +9963,8 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { // and reattach to the current context. if (D->getLexicalDeclContext() == Context.getTranslationUnitDecl()) { // Is the decl actually in the context? - for (DeclContext::decl_iterator DI = Context.getTranslationUnitDecl()->decls_begin(), - DE = Context.getTranslationUnitDecl()->decls_end(); DI != DE; ++DI) { - if (*DI == D) { + for (const auto *DI : Context.getTranslationUnitDecl()->decls()) { + if (DI == D) { Context.getTranslationUnitDecl()->removeDecl(D); break; } @@ -9621,10 +9979,9 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { // Similarly, dive into enums and fish their constants out, making them // accessible in this scope. - if (EnumDecl *ED = dyn_cast<EnumDecl>(D)) { - for (EnumDecl::enumerator_iterator EI = ED->enumerator_begin(), - EE = ED->enumerator_end(); EI != EE; ++EI) - PushOnScopeChains(*EI, FnBodyScope, /*AddToContext=*/false); + if (auto *ED = dyn_cast<EnumDecl>(D)) { + for (auto *EI : ED->enumerators()) + PushOnScopeChains(EI, FnBodyScope, /*AddToContext=*/false); } } } @@ -9633,35 +9990,22 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { if (const FunctionProtoType *FPT = FD->getType()->getAs<FunctionProtoType>()) ResolveExceptionSpec(D->getLocation(), FPT); - // Checking attributes of current function definition - // dllimport attribute. - DLLImportAttr *DA = FD->getAttr<DLLImportAttr>(); - if (DA && (!FD->getAttr<DLLExportAttr>())) { - // dllimport attribute cannot be directly applied to definition. - // Microsoft accepts dllimport for functions defined within class scope. - if (!DA->isInherited() && - !(LangOpts.MicrosoftExt && FD->getLexicalDeclContext()->isRecord())) { - Diag(FD->getLocation(), - diag::err_attribute_can_be_applied_only_to_symbol_declaration) - << "dllimport"; - FD->setInvalidDecl(); - return D; - } - - // Visual C++ appears to not think this is an issue, so only issue - // a warning when Microsoft extensions are disabled. - if (!LangOpts.MicrosoftExt) { - // If a symbol previously declared dllimport is later defined, the - // attribute is ignored in subsequent references, and a warning is - // emitted. - Diag(FD->getLocation(), - diag::warn_redeclaration_without_attribute_prev_attribute_ignored) - << FD->getName() << "dllimport"; - } + // dllimport cannot be applied to non-inline function definitions. + if (FD->hasAttr<DLLImportAttr>() && !FD->isInlined() && + !FD->isTemplateInstantiation()) { + assert(!FD->hasAttr<DLLExportAttr>()); + Diag(FD->getLocation(), diag::err_attribute_dllimport_function_definition); + FD->setInvalidDecl(); + return D; } // We want to attach documentation to original Decl (which might be // a function template). ActOnDocumentableDecl(D); + if (getCurLexicalContext()->isObjCContainer() && + getCurLexicalContext()->getDeclKind() != Decl::ObjCCategoryImpl && + getCurLexicalContext()->getDeclKind() != Decl::ObjCImplementation) + Diag(FD->getLocation(), diag::warn_function_def_in_objc_container); + return D; } @@ -9675,49 +10019,53 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { /// use the named return value optimization. /// /// This function applies a very simplistic algorithm for NRVO: if every return -/// statement in the function has the same NRVO candidate, that candidate is -/// the NRVO variable. -/// -/// FIXME: Employ a smarter algorithm that accounts for multiple return -/// statements and the lifetimes of the NRVO candidates. We should be able to -/// find a maximal set of NRVO variables. +/// statement in the scope of a variable has the same NRVO candidate, that +/// candidate is an NRVO variable. void Sema::computeNRVO(Stmt *Body, FunctionScopeInfo *Scope) { ReturnStmt **Returns = Scope->Returns.data(); - const VarDecl *NRVOCandidate = 0; for (unsigned I = 0, E = Scope->Returns.size(); I != E; ++I) { - if (!Returns[I]->getNRVOCandidate()) - return; - - if (!NRVOCandidate) - NRVOCandidate = Returns[I]->getNRVOCandidate(); - else if (NRVOCandidate != Returns[I]->getNRVOCandidate()) - return; + if (const VarDecl *NRVOCandidate = Returns[I]->getNRVOCandidate()) { + if (!NRVOCandidate->isNRVOVariable()) + Returns[I]->setNRVOCandidate(nullptr); + } } - - if (NRVOCandidate) - const_cast<VarDecl*>(NRVOCandidate)->setNRVOVariable(true); } -bool Sema::canSkipFunctionBody(Decl *D) { - if (!Consumer.shouldSkipFunctionBody(D)) +bool Sema::canDelayFunctionBody(const Declarator &D) { + // We can't delay parsing the body of a constexpr function template (yet). + if (D.getDeclSpec().isConstexprSpecified()) return false; - if (isa<ObjCMethodDecl>(D)) - return true; + // We can't delay parsing the body of a function template with a deduced + // return type (yet). + if (D.getDeclSpec().containsPlaceholderType()) { + // If the placeholder introduces a non-deduced trailing return type, + // we can still delay parsing it. + if (D.getNumTypeObjects()) { + const auto &Outer = D.getTypeObject(D.getNumTypeObjects() - 1); + if (Outer.Kind == DeclaratorChunk::Function && + Outer.Fun.hasTrailingReturnType()) { + QualType Ty = GetTypeFromParser(Outer.Fun.getTrailingReturnType()); + return Ty.isNull() || !Ty->isUndeducedType(); + } + } + return false; + } - FunctionDecl *FD = 0; - if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D)) - FD = FTD->getTemplatedDecl(); - else - FD = cast<FunctionDecl>(D); + return true; +} +bool Sema::canSkipFunctionBody(Decl *D) { // We cannot skip the body of a function (or function template) which is // constexpr, since we may need to evaluate its body in order to parse the // 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. - return !FD->isConstexpr() && !FD->getResultType()->isUndeducedType(); + if (const FunctionDecl *FD = D->getAsFunction()) + if (FD->isConstexpr() || FD->getReturnType()->isUndeducedType()) + return false; + return Consumer.shouldSkipFunctionBody(D); } Decl *Sema::ActOnSkippedFunctionBody(Decl *Decl) { @@ -9725,7 +10073,7 @@ Decl *Sema::ActOnSkippedFunctionBody(Decl *Decl) { FD->setHasSkippedBody(); else if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(Decl)) MD->setHasSkippedBody(); - return ActOnFinishFunctionBody(Decl, 0); + return ActOnFinishFunctionBody(Decl, nullptr); } Decl *Sema::ActOnFinishFunctionBody(Decl *D, Stmt *BodyArg) { @@ -9734,32 +10082,27 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *D, Stmt *BodyArg) { Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, bool IsInstantiation) { - FunctionDecl *FD = 0; - FunctionTemplateDecl *FunTmpl = dyn_cast_or_null<FunctionTemplateDecl>(dcl); - if (FunTmpl) - FD = FunTmpl->getTemplatedDecl(); - else - FD = dyn_cast_or_null<FunctionDecl>(dcl); + FunctionDecl *FD = dcl ? dcl->getAsFunction() : nullptr; sema::AnalysisBasedWarnings::Policy WP = AnalysisWarnings.getDefaultPolicy(); - sema::AnalysisBasedWarnings::Policy *ActivePolicy = 0; + sema::AnalysisBasedWarnings::Policy *ActivePolicy = nullptr; if (FD) { FD->setBody(Body); if (getLangOpts().CPlusPlus1y && !FD->isInvalidDecl() && Body && - !FD->isDependentContext() && FD->getResultType()->isUndeducedType()) { + !FD->isDependentContext() && FD->getReturnType()->isUndeducedType()) { // If the function has a deduced result type but contains no 'return' // statements, the result type as written must be exactly 'auto', and // the deduced result type is 'void'. - if (!FD->getResultType()->getAs<AutoType>()) { + if (!FD->getReturnType()->getAs<AutoType>()) { Diag(dcl->getLocation(), diag::err_auto_fn_no_return_but_not_auto) - << FD->getResultType(); + << FD->getReturnType(); FD->setInvalidDecl(); } else { // Substitute 'void' for the 'auto' in the type. TypeLoc ResultType = FD->getTypeSourceInfo()->getTypeLoc(). - IgnoreParens().castAs<FunctionProtoTypeLoc>().getResultLoc(); + IgnoreParens().castAs<FunctionProtoTypeLoc>().getReturnLoc(); Context.adjustDeducedFunctionResultType( FD, SubstAutoType(ResultType.getType(), Context.VoidTy)); } @@ -9783,15 +10126,17 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, WP.disableCheckFallThrough(); // MSVC permits the use of pure specifier (=0) on function definition, - // defined at class scope, warn about this non standard construct. + // defined at class scope, warn about this non-standard construct. if (getLangOpts().MicrosoftExt && FD->isPure() && FD->isCanonicalDecl()) - Diag(FD->getLocation(), diag::warn_pure_function_definition); + Diag(FD->getLocation(), diag::ext_pure_function_definition); if (!FD->isInvalidDecl()) { - DiagnoseUnusedParameters(FD->param_begin(), FD->param_end()); + // Don't diagnose unused parameters of defaulted or deleted functions. + if (Body) + DiagnoseUnusedParameters(FD->param_begin(), FD->param_end()); DiagnoseSizeOfParametersAndReturnValue(FD->param_begin(), FD->param_end(), - FD->getResultType(), FD); - + FD->getReturnType(), FD); + // If this is a constructor, we need a vtable. if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(FD)) MarkVTableUsed(FD->getLocation(), Constructor->getParent()); @@ -9799,7 +10144,7 @@ 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->getResultType()->isRecordType() && + if (getLangOpts().CPlusPlus && FD->getReturnType()->isRecordType() && !FD->isDependentContext()) computeNRVO(Body, getCurFunction()); } @@ -9812,8 +10157,8 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, if (!MD->isInvalidDecl()) { DiagnoseUnusedParameters(MD->param_begin(), MD->param_end()); DiagnoseSizeOfParametersAndReturnValue(MD->param_begin(), MD->param_end(), - MD->getResultType(), MD); - + MD->getReturnType(), MD); + if (Body) computeNRVO(Body, getCurFunction()); } @@ -9822,8 +10167,41 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, << MD->getSelector().getAsString(); getCurFunction()->ObjCShouldCallSuper = false; } + if (getCurFunction()->ObjCWarnForNoDesignatedInitChain) { + const ObjCMethodDecl *InitMethod = nullptr; + bool isDesignated = + MD->isDesignatedInitializerForTheInterface(&InitMethod); + assert(isDesignated && InitMethod); + (void)isDesignated; + + auto superIsNSObject = [&](const ObjCMethodDecl *MD) { + auto IFace = MD->getClassInterface(); + if (!IFace) + return false; + auto SuperD = IFace->getSuperClass(); + if (!SuperD) + return false; + return SuperD->getIdentifier() == + NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject); + }; + // Don't issue this warning for unavailable inits or direct subclasses + // of NSObject. + if (!MD->isUnavailable() && !superIsNSObject(MD)) { + Diag(MD->getLocation(), + diag::warn_objc_designated_init_missing_super_call); + Diag(InitMethod->getLocation(), + diag::note_objc_designated_init_marked_here); + } + getCurFunction()->ObjCWarnForNoDesignatedInitChain = false; + } + 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); + getCurFunction()->ObjCWarnForNoInitDelegation = false; + } } else { - return 0; + return nullptr; } assert(!getCurFunction()->ObjCShouldCallSuper && @@ -9840,8 +10218,6 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, // Verify that gotos and switch cases don't jump into scopes illegally. if (getCurFunction()->NeedsScopeChecking() && - !dcl->isInvalidDecl() && - !hasAnyUnrecoverableErrorsInThisFunction() && !PP.isCodeCompletionEnabled()) DiagnoseInvalidJumps(Body); @@ -9856,11 +10232,11 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, // If any errors have occurred, clear out any temporaries that may have // been leftover. This ensures that these temporaries won't be picked up for // deletion in some later function. - if (PP.getDiagnostics().hasErrorOccurred() || - PP.getDiagnostics().getSuppressAllDiagnostics()) { + if (getDiagnostics().hasErrorOccurred() || + getDiagnostics().getSuppressAllDiagnostics()) { DiscardCleanupsInEvaluationContext(); } - if (!PP.getDiagnostics().hasUncompilableErrorOccurred() && + if (!getDiagnostics().hasUncompilableErrorOccurred() && !isa<FunctionTemplateDecl>(dcl)) { // Since the body is valid, issue any analysis-based warnings that are // enabled. @@ -9938,7 +10314,8 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, TypoCorrection Corrected; DeclFilterCCC<FunctionDecl> Validator; if (S && (Corrected = CorrectTypo(DeclarationNameInfo(&II, Loc), - LookupOrdinaryName, S, 0, Validator))) + LookupOrdinaryName, S, nullptr, Validator, + CTK_NonError))) diagnoseTypo(Corrected, PDiag(diag::note_function_suggestion), /*ErrorRecovery*/false); } @@ -9948,16 +10325,17 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, AttributeFactory attrFactory; DeclSpec DS(attrFactory); unsigned DiagID; - bool Error = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, Dummy, DiagID); + bool Error = DS.SetTypeSpecType(DeclSpec::TST_int, Loc, Dummy, DiagID, + Context.getPrintingPolicy()); (void)Error; // Silence warning. assert(!Error && "Error setting up implicit decl!"); SourceLocation NoLoc; Declarator D(DS, Declarator::BlockContext); D.AddTypeInfo(DeclaratorChunk::getFunction(/*HasProto=*/false, /*IsAmbiguous=*/false, - /*RParenLoc=*/NoLoc, - /*ArgInfo=*/0, - /*NumArgs=*/0, + /*LParenLoc=*/NoLoc, + /*Params=*/nullptr, + /*NumParams=*/0, /*EllipsisLoc=*/NoLoc, /*RParenLoc=*/NoLoc, /*TypeQuals=*/0, @@ -9968,10 +10346,10 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, /*MutableLoc=*/NoLoc, EST_None, /*ESpecLoc=*/NoLoc, - /*Exceptions=*/0, - /*ExceptionRanges=*/0, + /*Exceptions=*/nullptr, + /*ExceptionRanges=*/nullptr, /*NumExceptions=*/0, - /*NoexceptExpr=*/0, + /*NoexceptExpr=*/nullptr, Loc, Loc, D), DS.getAttributes(), SourceLocation()); @@ -10012,25 +10390,27 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { unsigned FormatIdx; bool HasVAListArg; if (Context.BuiltinInfo.isPrintfLike(BuiltinID, FormatIdx, HasVAListArg)) { - if (!FD->getAttr<FormatAttr>()) { + if (!FD->hasAttr<FormatAttr>()) { const char *fmt = "printf"; unsigned int NumParams = FD->getNumParams(); if (FormatIdx < NumParams && // NumParams may be 0 (e.g. vfprintf) FD->getParamDecl(FormatIdx)->getType()->isObjCObjectPointerType()) fmt = "NSString"; - FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context, + FD->addAttr(FormatAttr::CreateImplicit(Context, &Context.Idents.get(fmt), FormatIdx+1, - HasVAListArg ? 0 : FormatIdx+2)); + HasVAListArg ? 0 : FormatIdx+2, + FD->getLocation())); } } if (Context.BuiltinInfo.isScanfLike(BuiltinID, FormatIdx, HasVAListArg)) { - if (!FD->getAttr<FormatAttr>()) - FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context, + if (!FD->hasAttr<FormatAttr>()) + FD->addAttr(FormatAttr::CreateImplicit(Context, &Context.Idents.get("scanf"), FormatIdx+1, - HasVAListArg ? 0 : FormatIdx+2)); + HasVAListArg ? 0 : FormatIdx+2, + FD->getLocation())); } // Mark const if we don't care about errno and that is the only @@ -10038,17 +10418,18 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { // IRgen to use LLVM intrinsics for such functions. if (!getLangOpts().MathErrno && Context.BuiltinInfo.isConstWithoutErrno(BuiltinID)) { - if (!FD->getAttr<ConstAttr>()) - FD->addAttr(::new (Context) ConstAttr(FD->getLocation(), Context)); + if (!FD->hasAttr<ConstAttr>()) + FD->addAttr(ConstAttr::CreateImplicit(Context, FD->getLocation())); } if (Context.BuiltinInfo.isReturnsTwice(BuiltinID) && - !FD->getAttr<ReturnsTwiceAttr>()) - FD->addAttr(::new (Context) ReturnsTwiceAttr(FD->getLocation(), Context)); - if (Context.BuiltinInfo.isNoThrow(BuiltinID) && !FD->getAttr<NoThrowAttr>()) - FD->addAttr(::new (Context) NoThrowAttr(FD->getLocation(), Context)); - if (Context.BuiltinInfo.isConst(BuiltinID) && !FD->getAttr<ConstAttr>()) - FD->addAttr(::new (Context) ConstAttr(FD->getLocation(), Context)); + !FD->hasAttr<ReturnsTwiceAttr>()) + FD->addAttr(ReturnsTwiceAttr::CreateImplicit(Context, + FD->getLocation())); + if (Context.BuiltinInfo.isNoThrow(BuiltinID) && !FD->hasAttr<NoThrowAttr>()) + FD->addAttr(NoThrowAttr::CreateImplicit(Context, FD->getLocation())); + if (Context.BuiltinInfo.isConst(BuiltinID) && !FD->hasAttr<ConstAttr>()) + FD->addAttr(ConstAttr::CreateImplicit(Context, FD->getLocation())); } IdentifierInfo *Name = FD->getIdentifier(); @@ -10067,17 +10448,19 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { if (Name->isStr("asprintf") || Name->isStr("vasprintf")) { // FIXME: asprintf and vasprintf aren't C99 functions. Should they be // target-specific builtins, perhaps? - if (!FD->getAttr<FormatAttr>()) - FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context, + if (!FD->hasAttr<FormatAttr>()) + FD->addAttr(FormatAttr::CreateImplicit(Context, &Context.Idents.get("printf"), 2, - Name->isStr("vasprintf") ? 0 : 3)); + Name->isStr("vasprintf") ? 0 : 3, + FD->getLocation())); } if (Name->isStr("__CFStringMakeConstantString")) { // We already have a __builtin___CFStringMakeConstantString, // but builds that use -fno-constant-cfstrings don't go through that. - if (!FD->getAttr<FormatArgAttr>()) - FD->addAttr(::new (Context) FormatArgAttr(FD->getLocation(), Context, 1)); + if (!FD->hasAttr<FormatArgAttr>()) + FD->addAttr(FormatArgAttr::CreateImplicit(Context, 1, + FD->getLocation())); } } @@ -10140,6 +10523,26 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T, 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); break; @@ -10179,7 +10582,7 @@ bool Sema::CheckEnumRedeclaration(SourceLocation EnumLoc, bool IsScoped, if (IsScoped != Prev->isScoped()) { Diag(EnumLoc, diag::err_enum_redeclare_scoped_mismatch) << Prev->isScoped(); - Diag(Prev->getLocation(), diag::note_previous_use); + Diag(Prev->getLocation(), diag::note_previous_declaration); return true; } @@ -10188,15 +10591,17 @@ bool Sema::CheckEnumRedeclaration(SourceLocation EnumLoc, bool IsScoped, !Prev->getIntegerType()->isDependentType() && !Context.hasSameUnqualifiedType(EnumUnderlyingTy, Prev->getIntegerType())) { + // TODO: Highlight the underlying type of the redeclaration. Diag(EnumLoc, diag::err_enum_redeclare_type_mismatch) << EnumUnderlyingTy << Prev->getIntegerType(); - Diag(Prev->getLocation(), diag::note_previous_use); + Diag(Prev->getLocation(), diag::note_previous_declaration) + << Prev->getIntegerTypeRange(); return true; } } else if (IsFixed != Prev->isFixed()) { Diag(EnumLoc, diag::err_enum_redeclare_fixed_mismatch) << Prev->isFixed(); - Diag(Prev->getLocation(), diag::note_previous_use); + Diag(Prev->getLocation(), diag::note_previous_declaration); return true; } @@ -10276,8 +10681,7 @@ bool Sema::isAcceptableTagRedeclaration(const TagDecl *Previous, } bool previousMismatch = false; - for (TagDecl::redecl_iterator I(Previous->redecls_begin()), - E(Previous->redecls_end()); I != E; ++I) { + for (auto I : Previous->redecls()) { if (I->getTagKind() != NewTag) { if (!previousMismatch) { previousMismatch = true; @@ -10308,7 +10712,7 @@ bool Sema::isAcceptableTagRedeclaration(const TagDecl *Previous, << getRedeclDiagFromTagKind(OldTag); Diag(Redecl->getLocation(), diag::note_previous_use); - // If there is a previous defintion, suggest a fix-it. + // If there is a previous definition, suggest a fix-it. if (Previous->getDefinition()) { Diag(NewTagLoc, diag::note_struct_class_suggestion) << getRedeclDiagFromTagKind(Redecl->getTagKind()) @@ -10321,10 +10725,56 @@ bool Sema::isAcceptableTagRedeclaration(const TagDecl *Previous, return false; } +/// Add a minimal nested name specifier fixit hint to allow lookup of a tag name +/// from an outer enclosing namespace or file scope inside a friend declaration. +/// This should provide the commented out code in the following snippet: +/// namespace N { +/// struct X; +/// namespace M { +/// struct Y { friend struct /*N::*/ X; }; +/// } +/// } +static FixItHint createFriendTagNNSFixIt(Sema &SemaRef, NamedDecl *ND, Scope *S, + SourceLocation NameLoc) { + // While the decl is in a namespace, do repeated lookup of that name and see + // if we get the same namespace back. If we do not, continue until + // translation unit scope, at which point we have a fully qualified NNS. + SmallVector<IdentifierInfo *, 4> Namespaces; + DeclContext *DC = ND->getDeclContext()->getRedeclContext(); + for (; !DC->isTranslationUnit(); DC = DC->getParent()) { + // This tag should be declared in a namespace, which can only be enclosed by + // other namespaces. Bail if there's an anonymous namespace in the chain. + NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(DC); + if (!Namespace || Namespace->isAnonymousNamespace()) + return FixItHint(); + IdentifierInfo *II = Namespace->getIdentifier(); + Namespaces.push_back(II); + NamedDecl *Lookup = SemaRef.LookupSingleName( + S, II, NameLoc, Sema::LookupNestedNameSpecifierName); + if (Lookup == Namespace) + break; + } + + // Once we have all the namespaces, reverse them to go outermost first, and + // build an NNS. + SmallString<64> Insertion; + llvm::raw_svector_ostream OS(Insertion); + if (DC->isTranslationUnit()) + OS << "::"; + std::reverse(Namespaces.begin(), Namespaces.end()); + for (auto *II : Namespaces) + OS << II->getName() << "::"; + OS.flush(); + return FixItHint::CreateInsertion(NameLoc, Insertion); +} + /// ActOnTag - 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 +/// trailing-type-specifier) other than one in an alias-declaration. Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, @@ -10334,10 +10784,11 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, bool &OwnedDecl, bool &IsDependent, SourceLocation ScopedEnumKWLoc, bool ScopedEnumUsesClassTag, - TypeResult UnderlyingType) { + TypeResult UnderlyingType, + bool IsTypeSpecifier) { // If this is not a definition, it must have a name. IdentifierInfo *OrigName = Name; - assert((Name != 0 || TUK == TUK_Definition) && + assert((Name != nullptr || TUK == TUK_Definition) && "Nameless record must be a definition!"); assert(TemplateParameterLists.size() == 0 || TUK != TUK_Reference); @@ -10356,11 +10807,11 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, (SS.isNotEmpty() && TUK != TUK_Reference)) { if (TemplateParameterList *TemplateParams = MatchTemplateParametersToScopeSpecifier( - KWLoc, NameLoc, SS, TemplateParameterLists, TUK == TUK_Friend, - isExplicitSpecialization, Invalid)) { + KWLoc, NameLoc, SS, nullptr, TemplateParameterLists, + TUK == TUK_Friend, isExplicitSpecialization, Invalid)) { if (Kind == TTK_Enum) { Diag(KWLoc, diag::err_enum_template); - return 0; + return nullptr; } if (TemplateParams->size() > 0) { @@ -10368,13 +10819,14 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // be a member of another template). if (Invalid) - return 0; + 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()); return Result.get(); @@ -10400,7 +10852,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, 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 = 0; + TypeSourceInfo *TI = nullptr; GetTypeFromParser(UnderlyingType.get(), &TI); EnumUnderlying = TI; @@ -10412,7 +10864,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, UPPC_FixedUnderlyingType)) EnumUnderlying = Context.IntTy.getTypePtr(); - } else if (getLangOpts().MicrosoftMode) + } else if (getLangOpts().MSVCCompat) // Microsoft enums are always of int type. EnumUnderlying = Context.IntTy.getTypePtr(); } @@ -10426,13 +10878,12 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, Redecl = NotForRedeclaration; LookupResult Previous(*this, Name, NameLoc, LookupTagName, Redecl); - bool FriendSawTagOutsideEnclosingNamespace = false; if (Name && SS.isNotEmpty()) { // We have a nested-name tag ('struct foo::bar'). // Check for invalid 'foo::'. if (SS.isInvalid()) { - Name = 0; + Name = nullptr; goto CreateNewDecl; } @@ -10442,26 +10893,26 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, DC = computeDeclContext(SS, false); if (!DC) { IsDependent = true; - return 0; + return nullptr; } } else { DC = computeDeclContext(SS, true); if (!DC) { Diag(SS.getRange().getBegin(), diag::err_dependent_nested_name_spec) << SS.getRange(); - return 0; + return nullptr; } } if (RequireCompleteDeclContext(SS, DC)) - return 0; + return nullptr; SearchDC = DC; // Look-up name inside 'foo::'. LookupQualifiedName(Previous, DC); if (Previous.isAmbiguous()) - return 0; + return nullptr; if (Previous.empty()) { // Name lookup did not find anything. However, if the @@ -10473,13 +10924,13 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, if (Previous.wasNotFoundInCurrentInstantiation() && (TUK == TUK_Reference || TUK == TUK_Friend)) { IsDependent = true; - return 0; + return nullptr; } // A tag 'foo::bar' must already exist. Diag(NameLoc, diag::err_not_tag_in_scope) << Kind << Name << DC << SS.getRange(); - Name = 0; + Name = nullptr; Invalid = true; goto CreateNewDecl; } @@ -10511,26 +10962,41 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // the entity has been previously declared shall not consider // any scopes outside the innermost enclosing namespace. // + // MSVC doesn't implement the above rule for types, so a friend tag + // declaration may be a redeclaration of a type declared in an enclosing + // scope. They do implement this rule for friend functions. + // // Does it matter that this should be by scope instead of by // semantic context? if (!Previous.empty() && TUK == TUK_Friend) { DeclContext *EnclosingNS = SearchDC->getEnclosingNamespaceContext(); LookupResult::Filter F = Previous.makeFilter(); + bool FriendSawTagOutsideEnclosingNamespace = false; while (F.hasNext()) { NamedDecl *ND = F.next(); DeclContext *DC = ND->getDeclContext()->getRedeclContext(); if (DC->isFileContext() && !EnclosingNS->Encloses(ND->getDeclContext())) { - F.erase(); - FriendSawTagOutsideEnclosingNamespace = true; + if (getLangOpts().MSVCCompat) + FriendSawTagOutsideEnclosingNamespace = true; + else + F.erase(); } } F.done(); + + // Diagnose this MSVC extension in the easy case where lookup would have + // unambiguously found something outside the enclosing namespace. + if (Previous.isSingleResult() && FriendSawTagOutsideEnclosingNamespace) { + NamedDecl *ND = Previous.getFoundDecl(); + Diag(NameLoc, diag::ext_friend_tag_redecl_outside_namespace) + << createFriendTagNNSFixIt(*this, ND, S, NameLoc); + } } - + // Note: there used to be some attempt at recovery here. if (Previous.isAmbiguous()) - return 0; + return nullptr; if (!getLangOpts().CPlusPlus && TUK != TUK_Reference) { // FIXME: This makes sure that we ignore the contexts associated @@ -10540,11 +11006,6 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, while (isa<RecordDecl>(SearchDC) || isa<EnumDecl>(SearchDC)) SearchDC = SearchDC->getParent(); } - } else if (S->isFunctionPrototypeScope()) { - // If this is an enum declaration in function prototype scope, set its - // initial context to the translation unit. - // FIXME: [citation needed] - SearchDC = Context.getTranslationUnitDecl(); } if (Previous.isSingleResult() && @@ -10634,7 +11095,9 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, } if (!Previous.empty()) { - NamedDecl *PrevDecl = (*Previous.begin())->getUnderlyingDecl(); + NamedDecl *PrevDecl = Previous.getFoundDecl(); + NamedDecl *DirectPrevDecl = + getLangOpts().MSVCCompat ? *Previous.begin() : PrevDecl; // It's okay to have a tag decl in the same scope as a typedef // which hides a tag decl in the same scope. Finding this @@ -10666,7 +11129,8 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // in the same scope (so that the definition/declaration completes or // rementions the tag), reuse the decl. if (TUK == TUK_Reference || TUK == TUK_Friend || - isDeclInScope(PrevDecl, SearchDC, S, isExplicitSpecialization)) { + isDeclInScope(DirectPrevDecl, SearchDC, S, + SS.isNotEmpty() || isExplicitSpecialization)) { // Make sure that this wasn't declared as an enum and now used as a // struct or something similar. if (!isAcceptableTagRedeclaration(PrevTagDecl, Kind, @@ -10688,7 +11152,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, Kind = PrevTagDecl->getTagKind(); else { // Recover by making this an anonymous redefinition. - Name = 0; + Name = nullptr; Previous.clear(); Invalid = true; } @@ -10709,7 +11173,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, QualType EnumUnderlyingTy; if (TypeSourceInfo *TI = EnumUnderlying.dyn_cast<TypeSourceInfo*>()) - EnumUnderlyingTy = TI->getType(); + EnumUnderlyingTy = TI->getType().getUnqualifiedType(); else if (const Type *T = EnumUnderlying.dyn_cast<const Type*>()) EnumUnderlyingTy = QualType(T, 0); @@ -10718,7 +11182,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, PrevEnum)) - return TUK == TUK_Declaration ? PrevTagDecl : 0; + return TUK == TUK_Declaration ? PrevTagDecl : nullptr; } // C++11 [class.mem]p1: @@ -10732,14 +11196,17 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, } if (!Invalid) { - // If this is a use, just return the declaration we found. + // If this is a use, just return the declaration we found, unless + // we have attributes. // FIXME: In the future, return a variant or some other clue // for the consumer of this Decl to know it doesn't own it. // For our current ASTs this shouldn't be a problem, but will // need to be changed with DeclGroups. - if ((TUK == TUK_Reference && (!PrevTagDecl->getFriendObjectKind() || - getLangOpts().MicrosoftExt)) || TUK == TUK_Friend) + if (!Attr && + ((TUK == TUK_Reference && + (!PrevTagDecl->getFriendObjectKind() || getLangOpts().MicrosoftExt)) + || TUK == TUK_Friend)) return PrevTagDecl; // Diagnose attempts to redefine a tag. @@ -10771,7 +11238,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // If this is a redefinition, recover by making this // struct be anonymous, which will make any later // references get the previous definition. - Name = 0; + Name = nullptr; Previous.clear(); Invalid = true; } @@ -10784,14 +11251,22 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, Diag(NameLoc, diag::err_nested_redefinition) << Name; Diag(PrevTagDecl->getLocation(), diag::note_previous_definition); - Name = 0; + Name = nullptr; Previous.clear(); Invalid = true; } } // Okay, this is definition of a previously declared or referenced - // tag PrevDecl. We're going to create a new Decl for it. + // tag. We're going to create a new Decl for it. + } + + // Okay, we're going to make a redeclaration. If this is some kind + // of reference, make sure we build the redeclaration in the same DC + // as the original, and ignore the current access specifier. + if (TUK == TUK_Friend || TUK == TUK_Reference) { + SearchDC = PrevTagDecl->getDeclContext(); + AS = AS_none; } } // If we get here we have (another) forward declaration or we @@ -10827,8 +11302,8 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, Invalid = true; // Otherwise, only diagnose if the declaration is in scope. - } else if (!isDeclInScope(PrevDecl, SearchDC, S, - isExplicitSpecialization)) { + } else if (!isDeclInScope(PrevDecl, SearchDC, S, + SS.isNotEmpty() || isExplicitSpecialization)) { // do nothing // Diagnose implicit declarations introduced by elaborated types. @@ -10857,7 +11332,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // issue an error and recover by making this tag be anonymous. Diag(NameLoc, diag::err_redefinition_different_kind) << Name; Diag(PrevDecl->getLocation(), diag::note_previous_definition); - Name = 0; + Name = nullptr; Invalid = true; } @@ -10869,7 +11344,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, CreateNewDecl: - TagDecl *PrevDecl = 0; + TagDecl *PrevDecl = nullptr; if (Previous.isSingleResult()) PrevDecl = cast<TagDecl>(Previous.getFoundDecl()); @@ -10904,7 +11379,7 @@ CreateNewDecl: Diag(Def->getLocation(), diag::note_previous_definition); } else { unsigned DiagID = diag::ext_forward_ref_enum; - if (getLangOpts().MicrosoftMode) + if (getLangOpts().MSVCCompat) DiagID = diag::ext_ms_forward_ref_enum; else if (getLangOpts().CPlusPlus) DiagID = diag::err_forward_ref_enum; @@ -10944,6 +11419,14 @@ CreateNewDecl: cast_or_null<RecordDecl>(PrevDecl)); } + // C++11 [dcl.type]p3: + // A type-specifier-seq shall not define a class or enumeration [...]. + if (getLangOpts().CPlusPlus && IsTypeSpecifier && TUK == TUK_Definition) { + Diag(New->getLocation(), diag::err_type_defined_in_type_specifier) + << Context.getTagDeclType(New); + Invalid = true; + } + // Maybe add qualifier info. if (SS.isNotEmpty()) { if (SS.isSet()) { @@ -10995,23 +11478,37 @@ CreateNewDecl: else if (!SearchDC->isFunctionOrMethod()) New->setModulePrivate(); } - + // If this is a specialization of a member class (of a class template), // check the specialization. if (isExplicitSpecialization && CheckMemberSpecialization(New, Previous)) Invalid = true; - + + // If we're declaring or defining a tag in function prototype scope in C, + // note that this type can only be used within the function and add it to + // the list of decls to inject into the function definition scope. + if ((Name || Kind == TTK_Enum) && + getNonFieldDeclScope(S)->isFunctionPrototypeScope()) { + if (getLangOpts().CPlusPlus) { + // C++ [dcl.fct]p6: + // Types shall not be defined in return or parameter types. + if (TUK == TUK_Definition && !IsTypeSpecifier) { + Diag(Loc, diag::err_type_defined_in_param_type) + << Name; + Invalid = true; + } + } else { + Diag(Loc, diag::warn_decl_in_param_list) << Context.getTagDeclType(New); + } + DeclsInPrototypeScope.push_back(New); + } + if (Invalid) New->setInvalidDecl(); if (Attr) ProcessDeclAttributeList(S, New, Attr); - // If we're declaring or defining a tag in function prototype scope - // in C, note that this type can only be used within the function. - if (Name && S->isFunctionPrototypeScope() && !getLangOpts().CPlusPlus) - Diag(Loc, diag::warn_decl_in_param_list) << Context.getTagDeclType(New); - // Set the lexical context. If the tag has a C++ scope specifier, the // lexical context will be different from the semantic context. New->setLexicalDeclContext(CurContext); @@ -11021,8 +11518,7 @@ CreateNewDecl: // declaration so we always pass true to setObjectOfFriendDecl to make // the tag name visible. if (TUK == TUK_Friend) - New->setObjectOfFriendDecl(!FriendSawTagOutsideEnclosingNamespace && - getLangOpts().MicrosoftExt); + New->setObjectOfFriendDecl(getLangOpts().MSVCCompat); // Set the access specifier. if (!Invalid && SearchDC->isRecord()) @@ -11060,12 +11556,6 @@ CreateNewDecl: II->isStr("FILE")) Context.setFILEDecl(New); - // If we were in function prototype scope (and not in C++ mode), add this - // tag to the list of decls to inject into the function definition scope. - if (S->isFunctionPrototypeScope() && !getLangOpts().CPlusPlus && - InFunctionDeclarator && Name) - DeclsInPrototypeScope.push_back(New); - if (PrevDecl) mergeDeclAttributes(New, PrevDecl); @@ -11076,7 +11566,7 @@ CreateNewDecl: OwnedDecl = true; // In C++, don't return an invalid declaration. We can't recover well from // the cases where we make the type anonymous. - return (Invalid && getLangOpts().CPlusPlus) ? 0 : New; + return (Invalid && getLangOpts().CPlusPlus) ? nullptr : New; } void Sema::ActOnTagStartDefinition(Scope *S, Decl *TagD) { @@ -11128,7 +11618,7 @@ void Sema::ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagD, = CXXRecordDecl::Create(Context, Record->getTagKind(), CurContext, Record->getLocStart(), Record->getLocation(), Record->getIdentifier(), - /*PrevDecl=*/0, + /*PrevDecl=*/nullptr, /*DelayTypeCreation=*/true); Context.getTypeDeclType(InjectedClassName, Record); InjectedClassName->setImplicit(); @@ -11181,7 +11671,7 @@ void Sema::ActOnObjCTemporaryExitContainerContext(DeclContext *DC) { void Sema::ActOnObjCReenterContainerContext(DeclContext *DC) { ActOnObjCContainerStartDefinition(cast<Decl>(DC)); - OriginalLexicalContext = 0; + OriginalLexicalContext = nullptr; } void Sema::ActOnTagDefinitionError(Scope *S, Decl *TagD) { @@ -11229,13 +11719,13 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc, // If the bit-width is type- or value-dependent, don't try to check // it now. if (BitWidth->isValueDependent() || BitWidth->isTypeDependent()) - return Owned(BitWidth); + return BitWidth; llvm::APSInt Value; ExprResult ICE = VerifyIntegerConstantExpression(BitWidth, &Value); if (ICE.isInvalid()) return ICE; - BitWidth = ICE.take(); + BitWidth = ICE.get(); if (Value != 0 && ZeroWidth) *ZeroWidth = false; @@ -11255,7 +11745,8 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc, if (!FieldTy->isDependentType()) { uint64_t TypeSize = Context.getTypeSize(FieldTy); if (Value.getZExtValue() > TypeSize) { - if (!getLangOpts().CPlusPlus || IsMsStruct) { + if (!getLangOpts().CPlusPlus || IsMsStruct || + Context.getTargetInfo().getCXXABI().isMicrosoft()) { if (FieldName) return Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_size) << FieldName << (unsigned)Value.getZExtValue() @@ -11275,7 +11766,7 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc, } } - return Owned(BitWidth); + return BitWidth; } /// ActOnField - Each field of a C struct/union is passed into this in order @@ -11333,7 +11824,7 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record, << DeclSpec::getSpecifierName(TSCS); // Check to see if this name was declared as a member previously - NamedDecl *PrevDecl = 0; + NamedDecl *PrevDecl = nullptr; LookupResult Previous(*this, II, Loc, LookupMemberName, ForRedeclaration); LookupName(Previous, S); switch (Previous.getResultKind()) { @@ -11357,11 +11848,11 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record, // Maybe we will complain about the shadowed template parameter. DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl); // Just pretend that we didn't see the previous declaration. - PrevDecl = 0; + PrevDecl = nullptr; } if (PrevDecl && !isDeclInScope(PrevDecl, Record, S)) - PrevDecl = 0; + PrevDecl = nullptr; bool Mutable = (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_mutable); @@ -11474,10 +11965,10 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, // If this is declared as a bit-field, check the bit-field. if (!InvalidDecl && BitWidth) { BitWidth = VerifyBitField(Loc, II, T, Record->isMsStruct(Context), BitWidth, - &ZeroWidth).take(); + &ZeroWidth).get(); if (!BitWidth) { InvalidDecl = true; - BitWidth = 0; + BitWidth = nullptr; ZeroWidth = false; } } @@ -11500,6 +11991,12 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, } } + // C++11 [class.union]p8 (DR1460): + // At most one variant member of a union may have a + // brace-or-equal-initializer. + if (InitStyle != ICIS_NoInit) + checkDuplicateDefaultInit(*this, cast<CXXRecordDecl>(Record), Loc); + FieldDecl *NewFD = FieldDecl::Create(Context, Record, TSSL, Loc, II, T, TInfo, BitWidth, Mutable, InitStyle); if (InvalidDecl) @@ -11603,8 +12100,9 @@ bool Sema::CheckNontrivialField(FieldDecl *FD) { SourceLocation Loc = FD->getLocation(); if (getSourceManager().isInSystemHeader(Loc)) { if (!FD->hasAttr<UnavailableAttr>()) - FD->addAttr(new (Context) UnavailableAttr(Loc, Context, - "this system field has retaining ownership")); + FD->addAttr(UnavailableAttr::CreateImplicit(Context, + "this system field has retaining ownership", + Loc)); return false; } } @@ -11655,7 +12153,7 @@ Decl *Sema::ActOnIvar(Scope *S, if (BitWidth) { // 6.7.2.1p3, 6.7.2.1p4 - BitWidth = VerifyBitField(Loc, II, T, /*IsMsStruct*/false, BitWidth).take(); + BitWidth = VerifyBitField(Loc, II, T, /*IsMsStruct*/false, BitWidth).get(); if (!BitWidth) D.setInvalidType(); } else { @@ -11682,7 +12180,7 @@ Decl *Sema::ActOnIvar(Scope *S, // Must set ivar's DeclContext to its enclosing interface. ObjCContainerDecl *EnclosingDecl = cast<ObjCContainerDecl>(CurContext); if (!EnclosingDecl || EnclosingDecl->isInvalidDecl()) - return 0; + return nullptr; ObjCContainerDecl *EnclosingContext; if (ObjCImplementationDecl *IMPDecl = dyn_cast<ObjCImplementationDecl>(EnclosingDecl)) { @@ -11698,7 +12196,7 @@ Decl *Sema::ActOnIvar(Scope *S, dyn_cast<ObjCCategoryDecl>(EnclosingDecl)) { if (LangOpts.ObjCRuntime.isFragile() || !CDecl->IsClassExtension()) { Diag(Loc, diag::err_misplaced_ivar) << CDecl->IsClassExtension(); - return 0; + return nullptr; } } EnclosingContext = EnclosingDecl; @@ -11776,7 +12274,7 @@ void Sema::ActOnLastBitfield(SourceLocation DeclLoc, Expr * BW = IntegerLiteral::Create(Context, Zero, Context.IntTy, DeclLoc); Ivar = ObjCIvarDecl::Create(Context, cast<ObjCContainerDecl>(CurContext), - DeclLoc, DeclLoc, 0, + DeclLoc, DeclLoc, nullptr, Context.CharTy, Context.getTrivialTypeSourceInfo(Context.CharTy, DeclLoc), @@ -11813,9 +12311,8 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, // members of anonymous structs and unions in the total. unsigned NumNamedMembers = 0; if (Record) { - for (RecordDecl::decl_iterator i = Record->decls_begin(), - e = Record->decls_end(); i != e; i++) { - if (IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(*i)) + for (const auto *I : Record->decls()) { + if (const auto *IFD = dyn_cast<IndirectFieldDecl>(I)) if (IFD->getDeclName()) ++NumNamedMembers; } @@ -11902,9 +12399,14 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, Diag(FD->getLocation(), diag::ext_c99_flexible_array_member) << FD->getDeclName() << Record->getTagKind(); - if (!FD->getType()->isDependentType() && - !Context.getBaseElementType(FD->getType()).isPODType(Context)) { - Diag(FD->getLocation(), diag::err_flexible_array_has_nonpod_type) + // If the element type has a non-trivial destructor, we would not + // implicitly destroy the elements, so disallow it for now. + // + // FIXME: GCC allows this. We should probably either implicitly delete + // the destructor of the containing class, or just allow this. + QualType BaseElem = Context.getBaseElementType(FD->getType()); + if (!BaseElem->isDependentType() && BaseElem.isDestructedType()) { + Diag(FD->getLocation(), diag::err_flexible_array_has_nontrivial_dtor) << FD->getDeclName() << FD->getType(); FD->setInvalidDecl(); EnclosingDecl->setInvalidDecl(); @@ -11972,8 +12474,9 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, SourceLocation loc = FD->getLocation(); if (getSourceManager().isInSystemHeader(loc)) { if (!FD->hasAttr<UnavailableAttr>()) { - FD->addAttr(new (Context) UnavailableAttr(loc, Context, - "this system field has retaining ownership")); + FD->addAttr(UnavailableAttr::CreateImplicit(Context, + "this system field has retaining ownership", + loc)); } } else { Diag(FD->getLocation(), diag::err_arc_objc_object_in_tag) @@ -12021,12 +12524,6 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, if (getLangOpts().CPlusPlus11) AdjustDestructorExceptionSpec(CXXRecord, CXXRecord->getDestructor()); - - // The Microsoft ABI requires that we perform the destructor body - // checks (i.e. operator delete() lookup) at every declaration, as - // any translation unit may need to emit a deleting destructor. - if (Context.getTargetInfo().getCXXABI().isMicrosoft()) - CheckDestructor(CXXRecord->getDestructor()); } // Add any implicitly-declared members to this class. @@ -12078,9 +12575,15 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, if (!Completed) Record->completeDefinition(); - if (Record->hasAttrs()) + if (Record->hasAttrs()) { CheckAlignasUnderalignment(Record); + if (const MSInheritanceAttr *IA = Record->getAttr<MSInheritanceAttr>()) + checkMSInheritanceAttrOnDefinition(cast<CXXRecordDecl>(Record), + IA->getRange(), IA->getBestCase(), + IA->getSemanticSpelling()); + } + // Check if the structure/union declaration is a type that can have zero // size in C. For C this is a language extension, for C++ it may cause // compatibility problems. @@ -12175,10 +12678,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, Diag(ClsIvar->getLocation(), diag::note_previous_definition); continue; } - for (ObjCInterfaceDecl::known_extensions_iterator - Ext = IDecl->known_extensions_begin(), - ExtEnd = IDecl->known_extensions_end(); - Ext != ExtEnd; ++Ext) { + for (const auto *Ext : IDecl->known_extensions()) { if (const ObjCIvarDecl *ClsExtIvar = Ext->getIvarDecl(ClsFields[i]->getIdentifier())) { Diag(ClsFields[i]->getLocation(), @@ -12251,10 +12751,10 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum, QualType EltTy; if (Val && DiagnoseUnexpandedParameterPack(Val, UPPC_EnumeratorValue)) - Val = 0; + Val = nullptr; if (Val) - Val = DefaultLvalueConversion(Val).take(); + Val = DefaultLvalueConversion(Val).get(); if (Val) { if (Enum->isDependentType() || Val->isTypeDependent()) @@ -12262,7 +12762,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum, else { SourceLocation ExpLoc; if (getLangOpts().CPlusPlus11 && Enum->isFixed() && - !getLangOpts().MicrosoftMode) { + !getLangOpts().MSVCCompat) { // C++11 [dcl.enum]p5: If the underlying type is fixed, [...] the // constant-expression in the enumerator-definition shall be a converted // constant expression of the underlying type. @@ -12271,12 +12771,12 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum, CheckConvertedConstantExpression(Val, EltTy, EnumVal, CCEK_Enumerator); if (Converted.isInvalid()) - Val = 0; + Val = nullptr; else - Val = Converted.take(); + Val = Converted.get(); } else if (!Val->isValueDependent() && !(Val = VerifyIntegerConstantExpression(Val, - &EnumVal).take())) { + &EnumVal).get())) { // C99 6.7.2.2p2: Make sure we have an integer constant expression. } else { if (Enum->isFixed()) { @@ -12287,13 +12787,13 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum, // we perform a non-narrowing conversion as part of converted constant // expression checking. if (!isRepresentableIntegerValue(Context, EnumVal, EltTy)) { - if (getLangOpts().MicrosoftMode) { + if (getLangOpts().MSVCCompat) { Diag(IdLoc, diag::ext_enumerator_too_large) << EltTy; - Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).take(); + Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).get(); } else Diag(IdLoc, diag::err_enumerator_too_large) << EltTy; } else - Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).take(); + Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).get(); } else if (getLangOpts().CPlusPlus) { // C++11 [dcl.enum]p5: // If the underlying type is not fixed, the type of each enumerator @@ -12314,7 +12814,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum, << (EnumVal.isUnsigned() || EnumVal.isNonNegative()); else if (!Context.hasSameType(Val->getType(), Context.IntTy)) { // Force the type of the expression to 'int'. - Val = ImpCastExprToType(Val, Context.IntTy, CK_IntegralCast).take(); + Val = ImpCastExprToType(Val, Context.IntTy, CK_IntegralCast).get(); } EltTy = Val->getType(); } @@ -12371,7 +12871,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum, << EnumVal.toString(10) << EltTy; else - Diag(IdLoc, diag::warn_enumerator_too_large) + Diag(IdLoc, diag::ext_enumerator_increment_too_large) << EnumVal.toString(10); } else { EltTy = T; @@ -12433,7 +12933,7 @@ Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst, // Maybe we will complain about the shadowed template parameter. DiagnoseTemplateParameterShadow(IdLoc, PrevDecl); // Just pretend that we didn't see the previous declaration. - PrevDecl = 0; + PrevDecl = nullptr; } if (PrevDecl) { @@ -12447,7 +12947,7 @@ Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst, else Diag(IdLoc, diag::err_redefinition) << Id; Diag(PrevDecl->getLocation(), diag::note_previous_definition); - return 0; + return nullptr; } } @@ -12549,9 +13049,7 @@ struct DenseMapInfoDupKey { static void CheckForDuplicateEnumValues(Sema &S, ArrayRef<Decl *> Elements, EnumDecl *Enum, QualType EnumType) { - if (S.Diags.getDiagnosticLevel(diag::warn_duplicate_enum_values, - Enum->getLocation()) == - DiagnosticsEngine::Ignored) + if (S.Diags.isIgnored(diag::warn_duplicate_enum_values, Enum->getLocation())) return; // Avoid anonymous enums if (!Enum->getIdentifier()) @@ -12729,7 +13227,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, // The C99 rule is modified by a gcc extension QualType BestPromotionType; - bool Packed = Enum->getAttr<PackedAttr>() ? true : false; + bool Packed = Enum->hasAttr<PackedAttr>(); // -fshort-enums is the equivalent to specifying the packed attribute on all // enum definitions. if (LangOpts.ShortEnums) @@ -12769,7 +13267,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, BestWidth = Context.getTargetInfo().getLongLongWidth(); if (NumNegativeBits > BestWidth || NumPositiveBits >= BestWidth) - Diag(Enum->getLocation(), diag::warn_enum_too_large); + Diag(Enum->getLocation(), diag::ext_enum_too_large); BestType = Context.LongLongTy; } } @@ -12860,7 +13358,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, ECD->setInitExpr(ImplicitCastExpr::Create(Context, NewTy, CK_IntegralCast, ECD->getInitExpr(), - /*base paths*/ 0, + /*base paths*/ nullptr, VK_RValue)); if (getLangOpts().CPlusPlus) // C++ [dcl.enum]p4: Following the closing brace of an @@ -12874,11 +13372,6 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, Enum->completeDefinition(BestType, BestPromotionType, NumPositiveBits, NumNegativeBits); - // If we're declaring a function, ensure this decl isn't forgotten about - - // it needs to go into the function scope. - if (InFunctionDeclarator) - DeclsInPrototypeScope.push_back(Enum); - CheckForDuplicateEnumValues(*this, Elements, Enum, EnumType); // Now that the enum type is defined, ensure it's not been underaligned. @@ -12898,15 +13391,54 @@ Decl *Sema::ActOnFileScopeAsmDecl(Expr *expr, return New; } +static void checkModuleImportContext(Sema &S, Module *M, + SourceLocation ImportLoc, + DeclContext *DC) { + if (auto *LSD = dyn_cast<LinkageSpecDecl>(DC)) { + switch (LSD->getLanguage()) { + case LinkageSpecDecl::lang_c: + if (!M->IsExternC) { + S.Diag(ImportLoc, diag::err_module_import_in_extern_c) + << M->getFullModuleName(); + S.Diag(LSD->getLocStart(), diag::note_module_import_in_extern_c); + return; + } + break; + case LinkageSpecDecl::lang_cxx: + break; + } + DC = LSD->getParent(); + } + + while (isa<LinkageSpecDecl>(DC)) + DC = DC->getParent(); + if (!isa<TranslationUnitDecl>(DC)) { + S.Diag(ImportLoc, diag::err_module_import_not_at_top_level) + << M->getFullModuleName() << DC; + S.Diag(cast<Decl>(DC)->getLocStart(), + diag::note_module_import_not_at_top_level) + << DC; + } +} + DeclResult Sema::ActOnModuleImport(SourceLocation AtLoc, SourceLocation ImportLoc, ModuleIdPath Path) { - Module *Mod = PP.getModuleLoader().loadModule(ImportLoc, Path, - Module::AllVisible, - /*IsIncludeDirective=*/false); + Module *Mod = + getModuleLoader().loadModule(ImportLoc, Path, Module::AllVisible, + /*IsIncludeDirective=*/false); if (!Mod) return true; - + + checkModuleImportContext(*this, Mod, ImportLoc, CurContext); + + // FIXME: we should support importing a submodule within a different submodule + // of the same top-level module. Until we do, make it an error rather than + // silently ignoring the import. + if (Mod->getTopLevelModuleName() == getLangOpts().CurrentModule) + Diag(ImportLoc, diag::err_module_self_import) + << Mod->getFullModuleName() << getLangOpts().CurrentModule; + SmallVector<SourceLocation, 2> IdentifierLocs; Module *ModCheck = Mod; for (unsigned I = 0, N = Path.size(); I != N; ++I) { @@ -12928,12 +13460,19 @@ DeclResult Sema::ActOnModuleImport(SourceLocation AtLoc, } void Sema::ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod) { + checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext); + // FIXME: Should we synthesize an ImportDecl here? - PP.getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, DirectiveLoc, - /*Complain=*/true); + getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, DirectiveLoc, + /*Complain=*/true); } -void Sema::createImplicitModuleImport(SourceLocation Loc, Module *Mod) { +void Sema::createImplicitModuleImportForErrorRecovery(SourceLocation Loc, + Module *Mod) { + // Bail if we're not allowed to implicitly import a module here. + if (isSFINAEContext() || !getLangOpts().ModulesErrorRecovery) + return; + // Create the implicit import declaration. TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl(); ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU, @@ -12942,8 +13481,8 @@ void Sema::createImplicitModuleImport(SourceLocation Loc, Module *Mod) { Consumer.HandleImplicitImportDecl(ImportD); // Make the module visible. - PP.getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, Loc, - /*Complain=*/false); + getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, Loc, + /*Complain=*/false); } void Sema::ActOnPragmaRedefineExtname(IdentifierInfo* Name, @@ -12953,8 +13492,8 @@ void Sema::ActOnPragmaRedefineExtname(IdentifierInfo* Name, SourceLocation AliasNameLoc) { Decl *PrevDecl = LookupSingleName(TUScope, Name, NameLoc, LookupOrdinaryName); - AsmLabelAttr *Attr = - ::new (Context) AsmLabelAttr(AliasNameLoc, Context, AliasName->getName()); + AsmLabelAttr *Attr = ::new (Context) AsmLabelAttr(AliasNameLoc, Context, + AliasName->getName(), 0); if (PrevDecl) PrevDecl->addAttr(Attr); @@ -12969,11 +13508,11 @@ void Sema::ActOnPragmaWeakID(IdentifierInfo* Name, Decl *PrevDecl = LookupSingleName(TUScope, Name, NameLoc, LookupOrdinaryName); if (PrevDecl) { - PrevDecl->addAttr(::new (Context) WeakAttr(PragmaLoc, Context)); + PrevDecl->addAttr(WeakAttr::CreateImplicit(Context, PragmaLoc)); } else { (void)WeakUndeclaredIdentifiers.insert( std::pair<IdentifierInfo*,WeakInfo> - (Name, WeakInfo((IdentifierInfo*)0, NameLoc))); + (Name, WeakInfo((IdentifierInfo*)nullptr, NameLoc))); } } @@ -13002,5 +13541,22 @@ Decl *Sema::getObjCDeclContext() const { AvailabilityResult Sema::getCurContextAvailability() const { const Decl *D = cast<Decl>(getCurObjCLexicalContext()); + // 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, + // the entire method is considered deprecated from the + // purpose of checking if the current context is deprecated. + if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { + AvailabilityResult R = MD->getAvailability(); + if (R != AR_Available) + return R; + D = MD->getClassInterface(); + } + // If we are within an Objective-c @implementation, it + // gets the same availability context as the @interface. + else if (const ObjCImplementationDecl *ID = + dyn_cast<ObjCImplementationDecl>(D)) { + D = ID->getClassInterface(); + } return D->getAvailability(); } |