diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp | 2400 |
1 files changed, 1671 insertions, 729 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp index fd7cfeb6f0da..328ce7059631 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp @@ -15,6 +15,7 @@ #include "TypeLocBuilder.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/ASTLambda.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/CharUnits.h" #include "clang/AST/CommentDiagnostic.h" @@ -39,6 +40,7 @@ #include "clang/Sema/ParsedTemplate.h" #include "clang/Sema/Scope.h" #include "clang/Sema/ScopeInfo.h" +#include "clang/Sema/Template.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Triple.h" #include <algorithm> @@ -108,6 +110,7 @@ bool Sema::isSimpleTypeSpecifier(tok::TokenKind Kind) const { case tok::kw_char16_t: case tok::kw_char32_t: case tok::kw_typeof: + case tok::annot_decltype: case tok::kw_decltype: return getLangOpts().CPlusPlus; @@ -126,9 +129,6 @@ bool Sema::isSimpleTypeSpecifier(tok::TokenKind Kind) const { /// determine whether the name refers to a type. If so, returns an /// opaque pointer (actually a QualType) corresponding to that /// type. Otherwise, returns NULL. -/// -/// If name lookup results in an ambiguity, this routine will complain -/// and then return NULL. ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS, bool isClassName, bool HasTrailingDot, @@ -237,17 +237,9 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, IsCtorOrDtorName, WantNontrivialTypeSourceInfo); if (Ty) { - std::string CorrectedStr(Correction.getAsString(getLangOpts())); - std::string CorrectedQuotedStr( - Correction.getQuoted(getLangOpts())); - Diag(NameLoc, diag::err_unknown_type_or_class_name_suggest) - << Result.getLookupName() << CorrectedQuotedStr << isClassName - << FixItHint::CreateReplacement(SourceRange(NameLoc), - CorrectedStr); - if (NamedDecl *FirstDecl = Correction.getCorrectionDecl()) - Diag(FirstDecl->getLocation(), diag::note_previous_decl) - << CorrectedQuotedStr; - + diagnoseTypo(Correction, + PDiag(diag::err_unknown_type_or_class_name_suggest) + << Result.getLookupName() << isClassName); if (SS && NNS) SS->MakeTrivial(Context, NNS, SourceRange(NameLoc)); *CorrectedII = NewII; @@ -412,38 +404,33 @@ bool Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II, if (TypoCorrection Corrected = CorrectTypo(DeclarationNameInfo(II, IILoc), LookupOrdinaryName, S, SS, Validator)) { - std::string CorrectedStr(Corrected.getAsString(getLangOpts())); - std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOpts())); - if (Corrected.isKeyword()) { // We corrected to a keyword. - IdentifierInfo *NewII = Corrected.getCorrectionAsIdentifierInfo(); - if (!isSimpleTypeSpecifier(NewII->getTokenID())) - CorrectedQuotedStr = "the keyword " + CorrectedQuotedStr; - Diag(IILoc, diag::err_unknown_typename_suggest) - << II << CorrectedQuotedStr - << FixItHint::CreateReplacement(SourceRange(IILoc), CorrectedStr); - II = NewII; + diagnoseTypo(Corrected, PDiag(diag::err_unknown_typename_suggest) << II); + II = Corrected.getCorrectionAsIdentifierInfo(); } else { - NamedDecl *Result = Corrected.getCorrectionDecl(); // We found a similarly-named type or interface; suggest that. - if (!SS || !SS->isSet()) - Diag(IILoc, diag::err_unknown_typename_suggest) - << II << CorrectedQuotedStr - << FixItHint::CreateReplacement(SourceRange(IILoc), CorrectedStr); - else if (DeclContext *DC = computeDeclContext(*SS, false)) - Diag(IILoc, diag::err_unknown_nested_typename_suggest) - << II << DC << CorrectedQuotedStr << SS->getRange() - << FixItHint::CreateReplacement(Corrected.getCorrectionRange(), - CorrectedStr); - else + if (!SS || !SS->isSet()) { + diagnoseTypo(Corrected, + PDiag(diag::err_unknown_typename_suggest) << II); + } else if (DeclContext *DC = computeDeclContext(*SS, false)) { + std::string CorrectedStr(Corrected.getAsString(getLangOpts())); + bool DroppedSpecifier = Corrected.WillReplaceSpecifier() && + II->getName().equals(CorrectedStr); + diagnoseTypo(Corrected, + PDiag(diag::err_unknown_nested_typename_suggest) + << II << DC << DroppedSpecifier << SS->getRange()); + } else { llvm_unreachable("could not have corrected a typo here"); + } - Diag(Result->getLocation(), diag::note_previous_decl) - << CorrectedQuotedStr; - - SuggestedType = getTypeName(*Result->getIdentifier(), IILoc, S, SS, - false, false, ParsedType(), + CXXScopeSpec tmpSS; + if (Corrected.getCorrectionSpecifier()) + tmpSS.MakeTrivial(Context, Corrected.getCorrectionSpecifier(), + SourceRange(IILoc)); + SuggestedType = getTypeName(*Corrected.getCorrectionAsIdentifierInfo(), + IILoc, S, tmpSS.isSet() ? &tmpSS : SS, false, + false, ParsedType(), /*IsCtorOrDtorName=*/false, /*NonTrivialTypeSourceInfo=*/true); } @@ -460,7 +447,7 @@ bool Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II, if (isTemplateName(S, SS ? *SS : EmptySS, /*hasTemplateKeyword=*/false, Name, ParsedType(), true, TemplateResult, MemberOfUnknownSpecialization) == TNK_Type_template) { - TemplateName TplName = TemplateResult.getAsVal<TemplateName>(); + TemplateName TplName = TemplateResult.get(); Diag(IILoc, diag::err_template_missing_args) << TplName; if (TemplateDecl *TplDecl = TplName.getAsTemplateDecl()) { Diag(TplDecl->getLocation(), diag::note_template_decl_here) @@ -662,9 +649,7 @@ Corrected: &SS, *CCC)) { unsigned UnqualifiedDiag = diag::err_undeclared_var_use_suggest; unsigned QualifiedDiag = diag::err_no_member_suggest; - std::string CorrectedStr(Corrected.getAsString(getLangOpts())); - std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOpts())); - + NamedDecl *FirstDecl = Corrected.getCorrectionDecl(); NamedDecl *UnderlyingFirstDecl = FirstDecl? FirstDecl->getUnderlyingDecl() : 0; @@ -680,33 +665,30 @@ Corrected: QualifiedDiag = diag::err_unknown_nested_typename_suggest; } - if (SS.isEmpty()) - Diag(NameLoc, UnqualifiedDiag) - << Name << CorrectedQuotedStr - << FixItHint::CreateReplacement(NameLoc, CorrectedStr); - else // FIXME: is this even reachable? Test it. - Diag(NameLoc, QualifiedDiag) - << Name << computeDeclContext(SS, false) << CorrectedQuotedStr - << SS.getRange() - << FixItHint::CreateReplacement(Corrected.getCorrectionRange(), - CorrectedStr); + if (SS.isEmpty()) { + diagnoseTypo(Corrected, PDiag(UnqualifiedDiag) << Name); + } else {// FIXME: is this even reachable? Test it. + std::string CorrectedStr(Corrected.getAsString(getLangOpts())); + bool DroppedSpecifier = Corrected.WillReplaceSpecifier() && + Name->getName().equals(CorrectedStr); + diagnoseTypo(Corrected, PDiag(QualifiedDiag) + << Name << computeDeclContext(SS, false) + << DroppedSpecifier << SS.getRange()); + } // Update the name, so that the caller has the new name. Name = Corrected.getCorrectionAsIdentifierInfo(); - + // Typo correction corrected to a keyword. if (Corrected.isKeyword()) - return Corrected.getCorrectionAsIdentifierInfo(); + return Name; // Also update the LookupResult... // FIXME: This should probably go away at some point Result.clear(); Result.setLookupName(Corrected.getCorrection()); - if (FirstDecl) { + if (FirstDecl) Result.addDecl(FirstDecl); - Diag(FirstDecl->getLocation(), diag::note_previous_decl) - << CorrectedQuotedStr; - } // If we found an Objective-C instance variable, let // LookupInObjCMethod build the appropriate expression to @@ -789,6 +771,7 @@ Corrected: if (!Result.empty()) { bool IsFunctionTemplate; + bool IsVarTemplate; TemplateName Template; if (Result.end() - Result.begin() > 1) { IsFunctionTemplate = true; @@ -798,7 +781,8 @@ Corrected: TemplateDecl *TD = cast<TemplateDecl>((*Result.begin())->getUnderlyingDecl()); IsFunctionTemplate = isa<FunctionTemplateDecl>(TD); - + IsVarTemplate = isa<VarTemplateDecl>(TD); + if (SS.isSet() && !SS.isInvalid()) Template = Context.getQualifiedTemplateName(SS.getScopeRep(), /*TemplateKeyword=*/false, @@ -815,8 +799,9 @@ Corrected: return NameClassification::FunctionTemplate(Template); } - - return NameClassification::TypeTemplate(Template); + + return IsVarTemplate ? NameClassification::VarTemplate(Template) + : NameClassification::TypeTemplate(Template); } } @@ -858,18 +843,16 @@ Corrected: // Check for a tag type hidden by a non-type decl in a few cases where it // seems likely a type is wanted instead of the non-type that was found. - if (!getLangOpts().ObjC1) { - bool NextIsOp = NextToken.is(tok::amp) || NextToken.is(tok::star); - if ((NextToken.is(tok::identifier) || - (NextIsOp && FirstDecl->isFunctionOrFunctionTemplate())) && - isTagTypeWithMissingTag(*this, Result, S, SS, Name, NameLoc)) { - TypeDecl *Type = Result.getAsSingle<TypeDecl>(); - DiagnoseUseOfDecl(Type, NameLoc); - QualType T = Context.getTypeDeclType(Type); - if (SS.isNotEmpty()) - return buildNestedType(*this, SS, T, NameLoc); - return ParsedType::make(T); - } + bool NextIsOp = NextToken.is(tok::amp) || NextToken.is(tok::star); + if ((NextToken.is(tok::identifier) || + (NextIsOp && FirstDecl->isFunctionOrFunctionTemplate())) && + isTagTypeWithMissingTag(*this, Result, S, SS, Name, NameLoc)) { + TypeDecl *Type = Result.getAsSingle<TypeDecl>(); + DiagnoseUseOfDecl(Type, NameLoc); + QualType T = Context.getTypeDeclType(Type); + if (SS.isNotEmpty()) + return buildNestedType(*this, SS, T, NameLoc); + return ParsedType::make(T); } if (FirstDecl->isCXXClassMember()) @@ -887,7 +870,16 @@ DeclContext *Sema::getContainingDC(DeclContext *DC) { // Functions defined inline within classes aren't parsed until we've // finished parsing the top-level class, so the top-level class is // the context we'll need to return to. - if (isa<FunctionDecl>(DC)) { + // A Lambda call operator whose parent is a class must not be treated + // as an inline member function. A Lambda can be used legally + // either as an in-class member initializer or a default argument. These + // are parsed once the class has been marked complete and so the containing + // context would be the nested class (when the lambda is defined in one); + // If the class is not complete, then the lambda is being used in an + // ill-formed fashion (such as to specify the width of a bit-field, or + // in an array-bound) - in which case we still want to return the + // lexically containing DC (which could be a nested class). + if (isa<FunctionDecl>(DC) && !isLambdaCallOperator(DC)) { DC = DC->getLexicalParent(); // A function not defined within a class will always return to its @@ -962,7 +954,7 @@ void Sema::ExitDeclaratorContext(Scope *S) { // enforced by an assert in EnterDeclaratorContext. Scope *Ancestor = S->getParent(); while (!Ancestor->getEntity()) Ancestor = Ancestor->getParent(); - CurContext = (DeclContext*) Ancestor->getEntity(); + CurContext = Ancestor->getEntity(); // We don't need to do anything with the scope, which is going to // disappear. @@ -1032,8 +1024,7 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext) { // Move up the scope chain until we find the nearest enclosing // non-transparent context. The declaration will be introduced into this // scope. - while (S->getEntity() && - ((DeclContext *)S->getEntity())->isTransparentContext()) + while (S->getEntity() && S->getEntity()->isTransparentContext()) S = S->getParent(); // Add scoped declarations into their context, so that they can be @@ -1042,12 +1033,12 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext) { if (AddToContext) CurContext->addDecl(D); - // Out-of-line definitions shouldn't be pushed into scope in C++. - // Out-of-line variable and function definitions shouldn't even in C. - if ((getLangOpts().CPlusPlus || isa<VarDecl>(D) || isa<FunctionDecl>(D)) && - D->isOutOfLine() && + // Out-of-line definitions shouldn't be pushed into scope in C++, unless they + // are function-local declarations. + if (getLangOpts().CPlusPlus && D->isOutOfLine() && !D->getDeclContext()->getRedeclContext()->Equals( - D->getLexicalDeclContext()->getRedeclContext())) + D->getLexicalDeclContext()->getRedeclContext()) && + !D->getLexicalDeclContext()->isFunctionOrMethod()) return; // Template instantiations should also not be pushed into scope. @@ -1094,7 +1085,7 @@ void Sema::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) { TUScope->AddDecl(D); } -bool Sema::isDeclInScope(NamedDecl *&D, DeclContext *Ctx, Scope *S, +bool Sema::isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S, bool ExplicitInstantiationOrSpecialization) { return IdResolver.isDeclInScope(D, Ctx, S, ExplicitInstantiationOrSpecialization); @@ -1103,7 +1094,7 @@ bool Sema::isDeclInScope(NamedDecl *&D, DeclContext *Ctx, Scope *S, Scope *Sema::getScopeForDeclContext(Scope *S, DeclContext *DC) { DeclContext *TargetDC = DC->getPrimaryContext(); do { - if (DeclContext *ScopeDC = (DeclContext*) S->getEntity()) + if (DeclContext *ScopeDC = S->getEntity()) if (ScopeDC->getPrimaryContext() == TargetDC) return S; } while ((S = S->getParent())); @@ -1196,7 +1187,15 @@ bool Sema::mightHaveNonExternalLinkage(const DeclaratorDecl *D) { DC = DC->getParent(); } - return !D->hasExternalLinkage(); + return !D->isExternallyVisible(); +} + +// FIXME: This needs to be refactored; some other isInMainFile users want +// these semantics. +static bool isMainFileLoc(const Sema &S, SourceLocation Loc) { + if (S.TUKind != TU_Complete) + return false; + return S.SourceMgr.isInMainFile(Loc); } bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const { @@ -1218,12 +1217,9 @@ bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const { if (MD->isVirtual() || IsDisallowedCopyOrAssign(MD)) return false; } else { - // 'static inline' functions are used in headers; don't warn. - // Make sure we get the storage class from the canonical declaration, - // since otherwise we will get spurious warnings on specialized - // static template functions. - if (FD->getCanonicalDecl()->getStorageClass() == SC_Static && - FD->isInlineSpecified()) + // 'static inline' functions are defined in headers; don't warn. + if (FD->isInlineSpecified() && + !isMainFileLoc(*this, FD->getLocation())) return false; } @@ -1231,21 +1227,18 @@ bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const { Context.DeclMustBeEmitted(FD)) return false; } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { - // Don't warn on variables of const-qualified or reference type, since their - // values can be used even if though they're not odr-used, and because const - // qualified variables can appear in headers in contexts where they're not - // intended to be used. - // FIXME: Use more principled rules for these exemptions. - if (!VD->isFileVarDecl() || - VD->getType().isConstQualified() || - VD->getType()->isReferenceType() || - Context.DeclMustBeEmitted(VD)) + // Constants and utility variables are defined in headers with internal + // linkage; don't warn. (Unlike functions, there isn't a convenient marker + // like "inline".) + if (!isMainFileLoc(*this, VD->getLocation())) + return false; + + if (Context.DeclMustBeEmitted(VD)) return false; if (VD->isStaticDataMember() && VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) return false; - } else { return false; } @@ -1259,13 +1252,13 @@ void Sema::MarkUnusedFileScopedDecl(const DeclaratorDecl *D) { return; if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { - const FunctionDecl *First = FD->getFirstDeclaration(); + const FunctionDecl *First = FD->getFirstDecl(); if (FD != First && ShouldWarnIfUnusedFileScopedDecl(First)) return; // First should already be in the vector. } if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { - const VarDecl *First = VD->getFirstDeclaration(); + const VarDecl *First = VD->getFirstDecl(); if (VD != First && ShouldWarnIfUnusedFileScopedDecl(First)) return; // First should already be in the vector. } @@ -1312,7 +1305,7 @@ static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) { return false; if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Tag)) { - if (!RD->hasTrivialDestructor()) + if (!RD->hasTrivialDestructor() && !RD->hasAttr<WarnUnusedAttr>()) return false; if (const Expr *Init = VD->getInit()) { @@ -1322,7 +1315,7 @@ static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) { dyn_cast<CXXConstructExpr>(Init); if (Construct && !Construct->isElidable()) { CXXConstructorDecl *CD = Construct->getConstructor(); - if (!CD->isTrivial()) + if (!CD->isTrivial() && !RD->hasAttr<WarnUnusedAttr>()) return false; } } @@ -1402,6 +1395,7 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { // Remove this name from our lexical scope. IdResolver.RemoveDecl(D); } + DiagnoseUnusedBackingIvarInAccessor(S); } void Sema::ActOnStartFunctionDeclarator() { @@ -1440,13 +1434,8 @@ ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *&Id, if (TypoCorrection C = CorrectTypo(DeclarationNameInfo(Id, IdLoc), LookupOrdinaryName, TUScope, NULL, Validator)) { + diagnoseTypo(C, PDiag(diag::err_undef_interface_suggest) << Id); IDecl = C.getCorrectionDeclAs<ObjCInterfaceDecl>(); - Diag(IdLoc, diag::err_undef_interface_suggest) - << Id << IDecl->getDeclName() - << FixItHint::CreateReplacement(IdLoc, IDecl->getNameAsString()); - Diag(IDecl->getLocation(), diag::note_previous_decl) - << IDecl->getDeclName(); - Id = IDecl->getIdentifier(); } } @@ -1482,8 +1471,7 @@ ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *&Id, /// contain non-field names. Scope *Sema::getNonFieldDeclScope(Scope *S) { while (((S->getFlags() & Scope::DeclScope) == 0) || - (S->getEntity() && - ((DeclContext *)S->getEntity())->isTransparentContext()) || + (S->getEntity() && S->getEntity()->isTransparentContext()) || (S->isClassScope() && !getLangOpts().CPlusPlus)) S = S->getParent(); return S; @@ -1556,8 +1544,17 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, << Context.BuiltinInfo.GetName(BID); } + DeclContext *Parent = Context.getTranslationUnitDecl(); + if (getLangOpts().CPlusPlus) { + LinkageSpecDecl *CLinkageDecl = + LinkageSpecDecl::Create(Context, Parent, Loc, Loc, + LinkageSpecDecl::lang_c, false); + Parent->addDecl(CLinkageDecl); + Parent = CLinkageDecl; + } + FunctionDecl *New = FunctionDecl::Create(Context, - Context.getTranslationUnitDecl(), + Parent, Loc, Loc, II, R, /*TInfo=*/0, SC_Extern, false, @@ -1581,13 +1578,14 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, } AddKnownFunctionAttributes(New); + RegisterLocallyScopedExternCDecl(New, S); // TUScope is the translation-unit scope to insert this function into. // FIXME: This is hideous. We need to teach PushOnScopeChains to // relate Scopes to DeclContexts, and probably eliminate CurContext // entirely, but we're not there yet. DeclContext *SavedContext = CurContext; - CurContext = Context.getTranslationUnitDecl(); + CurContext = Parent; PushOnScopeChains(New, TUScope); CurContext = SavedContext; return New; @@ -1616,7 +1614,7 @@ static void filterNonConflictingPreviousDecls(ASTContext &context, if (!old->isHidden()) continue; - if (old->getLinkage() != ExternalLinkage) + if (!old->isExternallyVisible()) filter.erase(); } @@ -1730,10 +1728,12 @@ void Sema::MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls) { if (isIncompatibleTypedef(Old, New)) return; - // The types match. Link up the redeclaration chain if the old - // declaration was a typedef. - if (TypedefNameDecl *Typedef = dyn_cast<TypedefNameDecl>(Old)) - New->setPreviousDeclaration(Typedef); + // The types match. Link up the redeclaration chain and merge attributes if + // the old declaration was a typedef. + if (TypedefNameDecl *Typedef = dyn_cast<TypedefNameDecl>(Old)) { + New->setPreviousDecl(Typedef); + mergeDeclAttributes(New, Old); + } if (getLangOpts().MicrosoftExt) return; @@ -2014,11 +2014,15 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D, InheritableAttr *Attr, static const Decl *getDefinition(const Decl *D) { if (const TagDecl *TD = dyn_cast<TagDecl>(D)) return TD->getDefinition(); - if (const VarDecl *VD = dyn_cast<VarDecl>(D)) - return VD->getDefinition(); + if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { + const VarDecl *Def = VD->getDefinition(); + if (Def) + return Def; + return VD->getActingDefinition(); + } if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { const FunctionDecl* Def; - if (FD->hasBody(Def)) + if (FD->isDefined(Def)) return Def; } return NULL; @@ -2047,6 +2051,32 @@ static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) { AttrVec &NewAttributes = New->getAttrs(); for (unsigned I = 0, E = NewAttributes.size(); I != E;) { const Attr *NewAttribute = NewAttributes[I]; + + if (isa<AliasAttr>(NewAttribute)) { + if (FunctionDecl *FD = dyn_cast<FunctionDecl>(New)) + S.CheckForFunctionRedefinition(FD, cast<FunctionDecl>(Def)); + else { + VarDecl *VD = cast<VarDecl>(New); + unsigned Diag = cast<VarDecl>(Def)->isThisDeclarationADefinition() == + VarDecl::TentativeDefinition + ? diag::err_alias_after_tentative + : diag::err_redefinition; + S.Diag(VD->getLocation(), Diag) << VD->getDeclName(); + S.Diag(Def->getLocation(), diag::note_previous_definition); + VD->setInvalidDecl(); + } + ++I; + continue; + } + + if (const VarDecl *VD = dyn_cast<VarDecl>(Def)) { + // Tentative definitions are only interesting for the alias check above. + if (VD->isThisDeclarationADefinition() != VarDecl::Definition) { + ++I; + continue; + } + } + if (hasAttribute(Def, NewAttribute->getKind())) { ++I; continue; // regular attr merging will take care of validating this. @@ -2087,6 +2117,12 @@ static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) { /// mergeDeclAttributes - Copy attributes from the Old decl to the New one. void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old, AvailabilityMergeKind AMK) { + if (UsedAttr *OldAttr = Old->getMostRecentDecl()->getAttr<UsedAttr>()) { + UsedAttr *NewAttr = OldAttr->clone(Context); + NewAttr->setInherited(true); + New->addAttr(NewAttr); + } + if (!Old->hasAttrs() && !New->hasAttrs()) return; @@ -2124,6 +2160,10 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old, } } + // Already handled. + if (isa<UsedAttr>(*i)) + continue; + if (mergeDeclAttribute(*this, New, *i, Override)) foundAny = true; } @@ -2150,7 +2190,7 @@ static void mergeParamDeclAttributes(ParmVarDecl *newDecl, // Find the first declaration of the parameter. // FIXME: Should we build redeclaration chains for function parameters? const FunctionDecl *FirstFD = - cast<FunctionDecl>(oldDecl->getDeclContext())->getFirstDeclaration(); + cast<FunctionDecl>(oldDecl->getDeclContext())->getFirstDecl(); const ParmVarDecl *FirstVD = FirstFD->getParamDecl(oldDecl->getFunctionScopeIndex()); S.Diag(FirstVD->getLocation(), @@ -2226,17 +2266,11 @@ static bool canRedefineFunction(const FunctionDecl *FD, FD->getStorageClass() == SC_Extern); } -/// Is the given calling convention the ABI default for the given -/// declaration? -static bool isABIDefaultCC(Sema &S, CallingConv CC, FunctionDecl *D) { - CallingConv ABIDefaultCC; - if (isa<CXXMethodDecl>(D) && cast<CXXMethodDecl>(D)->isInstance()) { - ABIDefaultCC = S.Context.getDefaultCXXMethodCallConv(D->isVariadic()); - } else { - // Free C function or a static method. - ABIDefaultCC = (S.Context.getLangOpts().MRTD ? CC_X86StdCall : CC_C); - } - return ABIDefaultCC == CC; +const AttributedType *Sema::getCallingConvAttributedType(QualType T) const { + const AttributedType *AT = T->getAs<AttributedType>(); + while (AT && !AT->isCallingConv()) + AT = AT->getModifiedType()->getAs<AttributedType>(); + return AT; } template <typename T> @@ -2264,7 +2298,8 @@ 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 Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S, + bool MergeTypeWithOld) { // Verify the old decl was also a function. FunctionDecl *Old = 0; if (FunctionTemplateDecl *OldFunctionTemplate @@ -2297,6 +2332,10 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { 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; @@ -2307,16 +2346,13 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { else PrevDiag = diag::note_previous_declaration; - QualType OldQType = Context.getCanonicalType(Old->getType()); - QualType NewQType = Context.getCanonicalType(New->getType()); - // Don't complain about this if we're in GNU89 mode and the old function // is an extern inline function. // Don't complain about specializations. They are not supposed to have // storage classes. if (!isa<CXXMethodDecl>(New) && !isa<CXXMethodDecl>(Old) && New->getStorageClass() == SC_Static && - isExternalLinkage(Old->getLinkage()) && + Old->hasExternalFormalLinkage() && !New->getTemplateSpecializationInfo() && !canRedefineFunction(Old, getLangOpts())) { if (getLangOpts().MicrosoftExt) { @@ -2329,53 +2365,52 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { } } - // If a function is first declared with a calling convention, but is - // later declared or defined without one, the second decl assumes the - // calling convention of the first. + + // If a function is first declared with a calling convention, but is later + // declared or defined without one, all following decls assume the calling + // convention of the first. // // It's OK if a function is first declared without a calling convention, // but is later declared or defined with the default calling convention. // - // For the new decl, we have to look at the NON-canonical type to tell the - // difference between a function that really doesn't have a calling - // convention and one that is declared cdecl. That's because in - // canonicalization (see ASTContext.cpp), cdecl is canonicalized away - // because it is the default calling convention. + // To test if either decl has an explicit calling convention, we look for + // AttributedType sugar nodes on the type as written. If they are missing or + // were canonicalized away, we assume the calling convention was implicit. // // Note also that we DO NOT return at this point, because we still have // other tests to run. + QualType OldQType = Context.getCanonicalType(Old->getType()); + QualType NewQType = Context.getCanonicalType(New->getType()); const FunctionType *OldType = cast<FunctionType>(OldQType); - const FunctionType *NewType = New->getType()->getAs<FunctionType>(); + const FunctionType *NewType = cast<FunctionType>(NewQType); FunctionType::ExtInfo OldTypeInfo = OldType->getExtInfo(); FunctionType::ExtInfo NewTypeInfo = NewType->getExtInfo(); bool RequiresAdjustment = false; - if (OldTypeInfo.getCC() == NewTypeInfo.getCC()) { - // Fast path: nothing to do. - - // Inherit the CC from the previous declaration if it was specified - // there but not here. - } else if (NewTypeInfo.getCC() == CC_Default) { - NewTypeInfo = NewTypeInfo.withCallingConv(OldTypeInfo.getCC()); - RequiresAdjustment = true; - // Don't complain about mismatches when the default CC is - // effectively the same as the explict one. Only Old decl contains correct - // information about storage class of CXXMethod. - } else if (OldTypeInfo.getCC() == CC_Default && - isABIDefaultCC(*this, NewTypeInfo.getCC(), Old)) { - NewTypeInfo = NewTypeInfo.withCallingConv(OldTypeInfo.getCC()); - RequiresAdjustment = true; - - } else if (!Context.isSameCallConv(OldTypeInfo.getCC(), - NewTypeInfo.getCC())) { - // Calling conventions really aren't compatible, so complain. - Diag(New->getLocation(), diag::err_cconv_change) - << FunctionType::getNameForCallConv(NewTypeInfo.getCC()) - << (OldTypeInfo.getCC() == CC_Default) - << (OldTypeInfo.getCC() == CC_Default ? "" : - FunctionType::getNameForCallConv(OldTypeInfo.getCC())); - Diag(Old->getLocation(), diag::note_previous_declaration); - return true; + if (OldTypeInfo.getCC() != NewTypeInfo.getCC()) { + FunctionDecl *First = Old->getFirstDecl(); + const FunctionType *FT = + First->getType().getCanonicalType()->castAs<FunctionType>(); + FunctionType::ExtInfo FI = FT->getExtInfo(); + bool NewCCExplicit = getCallingConvAttributedType(New->getType()); + if (!NewCCExplicit) { + // Inherit the CC from the previous declaration if it was specified + // there but not here. + NewTypeInfo = NewTypeInfo.withCallingConv(OldTypeInfo.getCC()); + RequiresAdjustment = true; + } else { + // Calling conventions aren't compatible, so complain. + bool FirstCCExplicit = getCallingConvAttributedType(First->getType()); + Diag(New->getLocation(), diag::err_cconv_change) + << FunctionType::getNameForCallConv(NewTypeInfo.getCC()) + << !FirstCCExplicit + << (!FirstCCExplicit ? "" : + FunctionType::getNameForCallConv(FI.getCC())); + + // Put the note on the first decl, since it is the one that matters. + Diag(First->getLocation(), diag::note_previous_declaration); + return true; + } } // FIXME: diagnose the other way around? @@ -2412,9 +2447,11 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { } if (RequiresAdjustment) { - NewType = Context.adjustFunctionType(NewType, NewTypeInfo); - New->setType(QualType(NewType, 0)); + const FunctionType *AdjustedType = New->getType()->getAs<FunctionType>(); + AdjustedType = Context.adjustFunctionType(AdjustedType, NewTypeInfo); + New->setType(QualType(AdjustedType, 0)); NewQType = Context.getCanonicalType(New->getType()); + NewType = cast<FunctionType>(NewQType); } // If this redeclaration makes the function inline, we may need to add it to @@ -2441,7 +2478,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { // cannot be overloaded. // Go back to the type source info to compare the declared return types, - // per C++1y [dcl.type.auto]p??: + // per C++1y [dcl.type.auto]p13: // 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. @@ -2452,7 +2489,9 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { ? New->getTypeSourceInfo()->getType()->castAs<FunctionType>() : NewType)->getResultType(); QualType ResQT; - if (!Context.hasSameType(OldDeclaredReturnType, NewDeclaredReturnType)) { + if (!Context.hasSameType(OldDeclaredReturnType, NewDeclaredReturnType) && + !((NewQType->isDependentType() || OldQType->isDependentType()) && + New->isLocalExternDecl())) { if (NewDeclaredReturnType->isObjCObjectPointerType() && OldDeclaredReturnType->isObjCObjectPointerType()) ResQT = Context.mergeObjCGCQualifiers(NewQType, OldQType); @@ -2476,9 +2515,14 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { // defined, copy the deduced value from the old declaration. AutoType *OldAT = Old->getResultType()->getContainedAutoType(); if (OldAT && OldAT->isDeduced()) { - New->setType(SubstAutoType(New->getType(), OldAT->getDeducedType())); + New->setType( + SubstAutoType(New->getType(), + OldAT->isDependentType() ? Context.DependentTy + : OldAT->getDeducedType())); NewQType = Context.getCanonicalType( - SubstAutoType(NewQType, OldAT->getDeducedType())); + SubstAutoType(NewQType, + OldAT->isDependentType() ? Context.DependentTy + : OldAT->getDeducedType())); } } @@ -2501,7 +2545,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { // -- Member function declarations with the same name and the // same parameter types cannot be overloaded if any of them // is a static member function declaration. - if (OldMethod->isStatic() || NewMethod->isStatic()) { + if (OldMethod->isStatic() != NewMethod->isStatic()) { Diag(New->getLocation(), diag::err_ovl_static_nonstatic_member); Diag(Old->getLocation(), PrevDiag) << Old << Old->getType(); return true; @@ -2559,7 +2603,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { !Old->hasAttr<CXX11NoReturnAttr>()) { Diag(New->getAttr<CXX11NoReturnAttr>()->getLocation(), diag::err_noreturn_missing_on_first_decl); - Diag(Old->getFirstDeclaration()->getLocation(), + Diag(Old->getFirstDecl()->getLocation(), diag::note_noreturn_missing_first_decl); } @@ -2571,7 +2615,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { !Old->hasAttr<CarriesDependencyAttr>()) { Diag(New->getAttr<CarriesDependencyAttr>()->getLocation(), diag::err_carries_dependency_missing_on_first_decl) << 0/*Function*/; - Diag(Old->getFirstDeclaration()->getLocation(), + Diag(Old->getFirstDecl()->getLocation(), diag::note_carries_dependency_missing_first_decl) << 0/*Function*/; } @@ -2591,13 +2635,34 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { } if (haveIncompatibleLanguageLinkages(Old, New)) { - Diag(New->getLocation(), diag::err_different_language_linkage) << New; - Diag(Old->getLocation(), PrevDiag); - return true; + // As a special case, retain the language linkage from previous + // declarations of a friend function as an extension. + // + // This liberal interpretation of C++ [class.friend]p3 matches GCC/MSVC + // and is useful because there's otherwise no way to specify language + // linkage within class scope. + // + // 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); + } else { + Diag(New->getLocation(), diag::err_different_language_linkage) << New; + Diag(Old->getLocation(), PrevDiag); + return true; + } } if (OldQTypeForComparison == NewQType) - return MergeCompatibleFunctionDecls(New, Old, S); + return MergeCompatibleFunctionDecls(New, Old, S, MergeTypeWithOld); + + if ((NewQType->isDependentType() || OldQType->isDependentType()) && + New->isLocalExternDecl()) { + // It's OK if we couldn't merge types for a local function declaraton + // if either the old or new type is dependent. We'll merge the types + // when we instantiate the function. + return false; + } // Fall through for conflicting redeclarations and redefinitions. } @@ -2609,7 +2674,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { const FunctionType *OldFuncType = OldQType->getAs<FunctionType>(); const FunctionType *NewFuncType = NewQType->getAs<FunctionType>(); const FunctionProtoType *OldProto = 0; - if (isa<FunctionNoProtoType>(NewFuncType) && + 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. @@ -2642,7 +2707,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { New->setParams(Params); } - return MergeCompatibleFunctionDecls(New, Old, S); + return MergeCompatibleFunctionDecls(New, Old, S, MergeTypeWithOld); } // GNU C permits a K&R definition to follow a prototype declaration @@ -2700,9 +2765,10 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { diag::note_previous_declaration); } - New->setType(Context.getFunctionType(MergedReturn, ArgTypes, - OldProto->getExtProtoInfo())); - return MergeCompatibleFunctionDecls(New, Old, S); + if (MergeTypeWithOld) + New->setType(Context.getFunctionType(MergedReturn, ArgTypes, + OldProto->getExtProtoInfo())); + return MergeCompatibleFunctionDecls(New, Old, S, MergeTypeWithOld); } // Fall through to diagnose conflicting types. @@ -2730,7 +2796,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { // local declaration will produce a hard error; if it doesn't // remain visible, a single bogus local redeclaration (which is // actually only a warning) could break all the downstream code. - if (!New->getDeclContext()->isFunctionOrMethod()) + if (!New->getLexicalDeclContext()->isFunctionOrMethod()) New->getIdentifier()->setBuiltinID(Builtin::NotBuiltin); return false; @@ -2748,13 +2814,13 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { /// known to be compatible. /// /// This routine handles the merging of attributes and other -/// properties of function declarations form the old declaration to +/// properties of function declarations from the old declaration to /// the new declaration, once we know that New is in fact a /// redeclaration of Old. /// /// \returns false bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old, - Scope *S) { + Scope *S, bool MergeTypeWithOld) { // Merge the attributes mergeDeclAttributes(New, Old); @@ -2763,8 +2829,8 @@ bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old, New->setPure(); // Merge "used" flag. - if (Old->isUsed(false)) - New->setUsed(); + if (Old->getMostRecentDecl()->isUsed(false)) + New->setIsUsed(); // Merge attributes from the parameters. These can mismatch with K&R // declarations. @@ -2777,9 +2843,10 @@ bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old, return MergeCXXFunctionDecl(New, Old, S); // Merge the function types so the we get the composite types for the return - // and argument types. + // and argument types. Per C11 6.2.7/4, only update the type if the old decl + // was visible. QualType Merged = Context.mergeTypes(Old->getType(), New->getType()); - if (!Merged.isNull()) + if (!Merged.isNull() && MergeTypeWithOld) New->setType(Merged); return false; @@ -2813,7 +2880,8 @@ void Sema::mergeObjCMethodDecls(ObjCMethodDecl *newMethod, /// Declarations using the auto type specifier (C++ [decl.spec.auto]) call back /// to here in AddInitializerToDecl. We can't check them before the initializer /// is attached. -void Sema::MergeVarDeclTypes(VarDecl *New, VarDecl *Old, bool OldWasHidden) { +void Sema::MergeVarDeclTypes(VarDecl *New, VarDecl *Old, + bool MergeTypeWithOld) { if (New->isInvalidDecl() || Old->isInvalidDecl()) return; @@ -2839,21 +2907,48 @@ void Sema::MergeVarDeclTypes(VarDecl *New, VarDecl *Old, bool OldWasHidden) { NewArray->getElementType())) MergedT = New->getType(); } else if (Old->getType()->isArrayType() && - New->getType()->isIncompleteArrayType()) { + New->getType()->isIncompleteArrayType()) { const ArrayType *OldArray = Context.getAsArrayType(Old->getType()); const ArrayType *NewArray = Context.getAsArrayType(New->getType()); if (Context.hasSameType(OldArray->getElementType(), NewArray->getElementType())) MergedT = Old->getType(); - } else if (New->getType()->isObjCObjectPointerType() - && Old->getType()->isObjCObjectPointerType()) { - MergedT = Context.mergeObjCGCQualifiers(New->getType(), - Old->getType()); + } else if (New->getType()->isObjCObjectPointerType() && + Old->getType()->isObjCObjectPointerType()) { + MergedT = Context.mergeObjCGCQualifiers(New->getType(), + Old->getType()); } } else { + // C 6.2.7p2: + // All declarations that refer to the same object or function shall have + // compatible type. MergedT = Context.mergeTypes(New->getType(), Old->getType()); } if (MergedT.isNull()) { + // It's OK if we couldn't merge types if either type is dependent, for a + // block-scope variable. In other cases (static data members of class + // templates, variable templates, ...), we require the types to be + // equivalent. + // FIXME: The C++ standard doesn't say anything about this. + if ((New->getType()->isDependentType() || + Old->getType()->isDependentType()) && New->isLocalVarDecl()) { + // If the old type was dependent, we can't merge with it, so the new type + // becomes dependent for now. We'll reproduce the original type when we + // instantiate the TypeSourceInfo for the variable. + if (!New->getType()->isDependentType() && MergeTypeWithOld) + New->setType(Context.DependentTy); + return; + } + + // FIXME: Even if this merging succeeds, some other non-visible declaration + // of this variable might have an incompatible type. For instance: + // + // extern int arr[]; + // void f() { extern int arr[2]; } + // void g() { extern int arr[3]; } + // + // Neither C nor C++ requires a diagnostic for this, but we should still try + // to diagnose it. Diag(New->getLocation(), diag::err_redefinition_different_type) << New->getDeclName() << New->getType() << Old->getType(); Diag(Old->getLocation(), diag::note_previous_definition); @@ -2861,11 +2956,40 @@ void Sema::MergeVarDeclTypes(VarDecl *New, VarDecl *Old, bool OldWasHidden) { } // Don't actually update the type on the new declaration if the old - // declaration was a extern declaration in a different scope. - if (!OldWasHidden) + // declaration was an extern declaration in a different scope. + if (MergeTypeWithOld) New->setType(MergedT); } +static bool mergeTypeWithPrevious(Sema &S, VarDecl *NewVD, VarDecl *OldVD, + LookupResult &Previous) { + // C11 6.2.7p4: + // For an identifier with internal or external linkage declared + // in a scope in which a prior declaration of that identifier is + // visible, if the prior declaration specifies internal or + // external linkage, the type of the identifier at the later + // declaration becomes the composite type. + // + // If the variable isn't visible, we do not merge with its type. + if (Previous.isShadowed()) + return false; + + if (S.getLangOpts().CPlusPlus) { + // C++11 [dcl.array]p3: + // If there is a preceding declaration of the entity in the same + // scope in which the bound was specified, an omitted array bound + // is taken to be the same as in that earlier declaration. + return NewVD->isPreviousDeclInSameBlockScope() || + (!OldVD->getLexicalDeclContext()->isFunctionOrMethod() && + !NewVD->getLexicalDeclContext()->isFunctionOrMethod()); + } else { + // If the old declaration was function-local, don't merge with its + // type unless we're in the same function. + return !OldVD->getLexicalDeclContext()->isFunctionOrMethod() || + OldVD->getLexicalDeclContext() == NewVD->getLexicalDeclContext(); + } +} + /// MergeVarDecl - We just parsed a variable 'New' which has the same name /// and scope as a previous declaration 'Old'. Figure out how to resolve this /// situation, merging decls or emitting diagnostics as appropriate. @@ -2874,16 +2998,21 @@ void Sema::MergeVarDeclTypes(VarDecl *New, VarDecl *Old, bool OldWasHidden) { /// FinalizeDeclaratorGroup. Unfortunately, we can't analyze tentative /// definitions here, since the initializer hasn't been attached. /// -void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous, - bool PreviousWasHidden) { +void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { // If the new decl is already invalid, don't do any other checking. if (New->isInvalidDecl()) return; - // Verify the old decl was also a variable. + // Verify the old decl was also a variable or variable template. VarDecl *Old = 0; - if (!Previous.isSingleResult() || - !(Old = dyn_cast<VarDecl>(Previous.getFoundDecl()))) { + if (Previous.isSingleResult() && + (Old = dyn_cast<VarDecl>(Previous.getFoundDecl()))) { + if (New->getDescribedVarTemplate()) + Old = Old->getDescribedVarTemplate() ? Old : 0; + else + Old = Old->getDescribedVarTemplate() ? 0 : Old; + } + if (!Old) { Diag(New->getLocation(), diag::err_redefinition_different_kind) << New->getDeclName(); Diag(Previous.getRepresentativeDecl()->getLocation(), @@ -2918,14 +3047,15 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous, } // Merge the types. - MergeVarDeclTypes(New, Old, PreviousWasHidden); + MergeVarDeclTypes(New, Old, mergeTypeWithPrevious(*this, New, Old, Previous)); + if (New->isInvalidDecl()) return; // [dcl.stc]p8: Check if we have a non-static decl followed by a static. if (New->getStorageClass() == SC_Static && !New->isStaticDataMember() && - isExternalLinkage(Old->getLinkage())) { + Old->hasExternalFormalLinkage()) { Diag(New->getLocation(), diag::err_static_non_static) << New->getDeclName(); Diag(Old->getLocation(), diag::note_previous_definition); return New->setInvalidDecl(); @@ -2999,8 +3129,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous, if (getLangOpts().CPlusPlus && New->isThisDeclarationADefinition() == VarDecl::Definition && (Def = Old->getDefinition())) { - Diag(New->getLocation(), diag::err_redefinition) - << New->getDeclName(); + Diag(New->getLocation(), diag::err_redefinition) << New; Diag(Def->getLocation(), diag::note_previous_definition); New->setInvalidDecl(); return; @@ -3014,14 +3143,19 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous, } // Merge "used" flag. - if (Old->isUsed(false)) - New->setUsed(); + if (Old->getMostRecentDecl()->isUsed(false)) + New->setIsUsed(); // Keep a chain of previous declarations. - New->setPreviousDeclaration(Old); + New->setPreviousDecl(Old); // Inherit access appropriately. New->setAccess(Old->getAccess()); + + if (VarTemplateDecl *VTD = New->getDescribedVarTemplate()) { + if (New->isStaticDataMember() && New->isOutOfLine()) + VTD->setAccess(New->getAccess()); + } } /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with @@ -3031,6 +3165,30 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, return ParsedFreeStandingDeclSpec(S, AS, DS, MultiTemplateParamsArg()); } +static void HandleTagNumbering(Sema &S, const TagDecl *Tag) { + if (!S.Context.getLangOpts().CPlusPlus) + return; + + if (isa<CXXRecordDecl>(Tag->getParent())) { + // If this tag is the direct child of a class, number it if + // it is anonymous. + if (!Tag->getName().empty() || Tag->getTypedefNameForAnonDecl()) + return; + MangleNumberingContext &MCtx = + S.Context.getManglingNumberContext(Tag->getParent()); + S.Context.setManglingNumber(Tag, MCtx.getManglingNumber(Tag)); + return; + } + + // If this tag isn't a direct child of a class, number it if it is local. + Decl *ManglingContextDecl; + if (MangleNumberingContext *MCtx = + S.getCurrentMangleNumberContext(Tag->getDeclContext(), + ManglingContextDecl)) { + S.Context.setManglingNumber(Tag, MCtx->getManglingNumber(Tag)); + } +} + /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with /// no declarator (e.g. "struct foo;") is parsed. It also accepts template /// parameters to cope with template friend declarations. @@ -3060,7 +3218,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, } if (Tag) { - getASTContext().addUnnamedTag(Tag); + HandleTagNumbering(*this, Tag); Tag->setFreeStanding(); if (Tag->isInvalidDecl()) return Tag; @@ -3301,11 +3459,11 @@ static bool CheckAnonMemberRedeclaration(Sema &SemaRef, /// This routine is recursive, injecting the names of nested anonymous /// structs/unions into the owning context and scope as well. static bool InjectAnonymousStructOrUnionMembers(Sema &SemaRef, Scope *S, - DeclContext *Owner, - RecordDecl *AnonRecord, - AccessSpecifier AS, - SmallVector<NamedDecl*, 2> &Chaining, - bool MSAnonStruct) { + DeclContext *Owner, + RecordDecl *AnonRecord, + AccessSpecifier AS, + SmallVectorImpl<NamedDecl *> &Chaining, + bool MSAnonStruct) { unsigned diagKind = AnonRecord->isUnion() ? diag::err_anonymous_union_member_redecl : diag::err_anonymous_struct_member_redecl; @@ -3961,7 +4119,7 @@ bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC, DeclarationName Name, SourceLocation Loc) { DeclContext *Cur = CurContext; - while (isa<LinkageSpecDecl>(Cur)) + while (isa<LinkageSpecDecl>(Cur) || isa<CapturedDecl>(Cur)) Cur = Cur->getParent(); // C++ [dcl.meaning]p1: @@ -3999,6 +4157,9 @@ bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC, else if (isa<FunctionDecl>(Cur)) Diag(Loc, diag::err_invalid_declarator_in_function) << Name << SS.getRange(); + else if (isa<BlockDecl>(Cur)) + Diag(Loc, diag::err_invalid_declarator_in_block) + << Name << SS.getRange(); else Diag(Loc, diag::err_invalid_declarator_scope) << Name << cast<NamedDecl>(Cur) << cast<NamedDecl>(DC) << SS.getRange(); @@ -4071,7 +4232,7 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D, bool EnteringContext = !D.getDeclSpec().isFriendSpecified(); DC = computeDeclContext(D.getCXXScopeSpec(), EnteringContext); - if (!DC) { + if (!DC || isa<EnumDecl>(DC)) { // If we could not compute the declaration context, it's because the // declaration context is dependent but does not refer to a class, // class template, or class template partial specialization. Complain @@ -4132,26 +4293,31 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D, // See if this is a redefinition of a variable in the same scope. if (!D.getCXXScopeSpec().isSet()) { bool IsLinkageLookup = false; + bool CreateBuiltins = false; // If the declaration we're planning to build will be a function // or object with linkage, then look for another declaration with // linkage (C99 6.2.2p4-5 and C++ [basic.link]p6). + // + // If the declaration we're planning to build will be declared with + // external linkage in the translation unit, create any builtin with + // the same name. if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) /* Do nothing*/; - else if (R->isFunctionType()) { - if (CurContext->isFunctionOrMethod() || - D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_static) - IsLinkageLookup = true; - } else if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_extern) - IsLinkageLookup = true; - else if (CurContext->getRedeclContext()->isTranslationUnit() && - D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_static) + else if (CurContext->isFunctionOrMethod() && + (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_extern || + R->isFunctionType())) { IsLinkageLookup = true; + CreateBuiltins = + CurContext->getEnclosingNamespaceContext()->isTranslationUnit(); + } else if (CurContext->getRedeclContext()->isTranslationUnit() && + D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_static) + CreateBuiltins = true; if (IsLinkageLookup) Previous.clear(LookupRedeclarationWithLinkage); - LookupName(Previous, S, /* CreateBuiltins = */ IsLinkageLookup); + LookupName(Previous, S, CreateBuiltins); } else { // Something like "int foo::x;" LookupQualifiedName(Previous, DC); @@ -4223,8 +4389,8 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D, TemplateParamLists, AddToScope); } else { - New = ActOnVariableDeclarator(S, D, DC, TInfo, Previous, - TemplateParamLists); + New = ActOnVariableDeclarator(S, D, DC, TInfo, Previous, TemplateParamLists, + AddToScope); } if (New == 0) @@ -4233,8 +4399,15 @@ NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D, // If this has an identifier and is not an invalid redeclaration or // function template specialization, add it to the scope stack. if (New->getDeclName() && AddToScope && - !(D.isRedeclaration() && New->isInvalidDecl())) - PushOnScopeChains(New, S); + !(D.isRedeclaration() && New->isInvalidDecl())) { + // Only make a locally-scoped extern declaration visible if it is the first + // declaration of this entity. Qualified lookup for such an entity should + // only find this declaration if there is no visible declaration of it. + bool AddToContext = !D.isRedeclaration() || !New->isLocalExternDecl(); + PushOnScopeChains(New, S, AddToContext); + if (!AddToContext) + CurContext->addHiddenDecl(New); + } return New; } @@ -4356,21 +4529,26 @@ TryToFixInvalidVariablyModifiedTypeSourceInfo(TypeSourceInfo *TInfo, } /// \brief Register the given locally-scoped extern "C" declaration so -/// that it can be found later for redeclarations +/// that it can be found later for redeclarations. We include any extern "C" +/// declaration that is not visible in the translation unit here, not just +/// function-scope declarations. void -Sema::RegisterLocallyScopedExternCDecl(NamedDecl *ND, - const LookupResult &Previous, - Scope *S) { - assert(ND->getLexicalDeclContext()->isFunctionOrMethod() && - "Decl is not a locally-scoped decl!"); +Sema::RegisterLocallyScopedExternCDecl(NamedDecl *ND, Scope *S) { + if (!getLangOpts().CPlusPlus && + ND->getLexicalDeclContext()->getRedeclContext()->isTranslationUnit()) + // Don't need to track declarations in the TU in C. + return; + // Note that we have a locally-scoped external with this name. + // FIXME: There can be multiple such declarations if they are functions marked + // __attribute__((overloadable)) declared in function scope in C. LocallyScopedExternCDecls[ND->getDeclName()] = ND; } -llvm::DenseMap<DeclarationName, NamedDecl *>::iterator -Sema::findLocallyScopedExternCDecl(DeclarationName Name) { +NamedDecl *Sema::findLocallyScopedExternCDecl(DeclarationName Name) { if (ExternalSource) { // Load locally-scoped external decls from the external source. + // FIXME: This is inefficient. Maybe add a DeclContext for extern "C" decls? SmallVector<NamedDecl *, 4> Decls; ExternalSource->ReadLocallyScopedExternCDecls(Decls); for (unsigned I = 0, N = Decls.size(); I != N; ++I) { @@ -4380,8 +4558,9 @@ Sema::findLocallyScopedExternCDecl(DeclarationName Name) { LocallyScopedExternCDecls[Decls[I]->getDeclName()] = Decls[I]; } } - - return LocallyScopedExternCDecls.find(Name); + + NamedDecl *D = LocallyScopedExternCDecls.lookup(Name); + return D ? D->getMostRecentDecl() : 0; } /// \brief Diagnose function specifiers on a declaration of an identifier that @@ -4627,17 +4806,26 @@ bool Sema::inferObjCARCLifetime(ValueDecl *decl) { static void checkAttributesAfterMerging(Sema &S, NamedDecl &ND) { // 'weak' only applies to declarations with external linkage. if (WeakAttr *Attr = ND.getAttr<WeakAttr>()) { - if (ND.getLinkage() != ExternalLinkage) { + if (!ND.isExternallyVisible()) { S.Diag(Attr->getLocation(), diag::err_attribute_weak_static); ND.dropAttr<WeakAttr>(); } } if (WeakRefAttr *Attr = ND.getAttr<WeakRefAttr>()) { - if (ND.hasExternalLinkage()) { + if (ND.isExternallyVisible()) { S.Diag(Attr->getLocation(), diag::err_attribute_weakref_not_static); ND.dropAttr<WeakRefAttr>(); } } + + // 'selectany' only applies to externally visible varable declarations. + // It does not apply to functions. + if (SelectAnyAttr *Attr = ND.getAttr<SelectAnyAttr>()) { + if (isa<FunctionDecl>(ND) || !ND.isExternallyVisible()) { + S.Diag(Attr->getLocation(), diag::err_attribute_selectany_non_extern_data); + ND.dropAttr<SelectAnyAttr>(); + } + } } /// Given that we are within the definition of the given function, @@ -4672,6 +4860,32 @@ static bool isFunctionDefinitionDiscarded(Sema &S, FunctionDecl *FD) { return isC99Inline; } +/// Determine whether a variable is extern "C" prior to attaching +/// an initializer. We can't just call isExternC() here, because that +/// will also compute and cache whether the declaration is externally +/// visible, which might change when we attach the initializer. +/// +/// This can only be used if the declaration is known to not be a +/// redeclaration of an internal linkage declaration. +/// +/// For instance: +/// +/// auto x = []{}; +/// +/// Attaching the initializer here makes this declaration not externally +/// visible, because its type has internal linkage. +/// +/// FIXME: This is a hack. +template<typename T> +static bool isIncompleteDeclExternC(Sema &S, const T *D) { + if (S.getLangOpts().CPlusPlus) { + // In C++, the overloadable attribute negates the effects of extern "C". + if (!D->isInExternCContext() || D->template hasAttr<OverloadableAttr>()) + return false; + } + return D->isExternC(); +} + static bool shouldConsiderLinkage(const VarDecl *VD) { const DeclContext *DC = VD->getDeclContext()->getRedeclContext(); if (DC->isFunctionOrMethod()) @@ -4692,10 +4906,35 @@ static bool shouldConsiderLinkage(const FunctionDecl *FD) { llvm_unreachable("Unexpected context"); } -NamedDecl* +/// Adjust the \c DeclContext for a function or variable that might be a +/// function-local external declaration. +bool Sema::adjustContextForLocalExternDecl(DeclContext *&DC) { + if (!DC->isFunctionOrMethod()) + return false; + + // If this is a local extern function or variable declared within a function + // template, don't add it into the enclosing namespace scope until it is + // instantiated; it might have a dependent type right now. + if (DC->isDependentContext()) + return true; + + // C++11 [basic.link]p7: + // When a block scope declaration of an entity with linkage is not found to + // refer to some other declaration, then that entity is a member of the + // innermost enclosing namespace. + // + // Per C++11 [namespace.def]p6, the innermost enclosing namespace is a + // semantically-enclosing namespace, not a lexically-enclosing one. + while (!DC->isFileContext() && !isa<LinkageSpecDecl>(DC)) + DC = DC->getParent(); + return true; +} + +NamedDecl * Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, TypeSourceInfo *TInfo, LookupResult &Previous, - MultiTemplateParamsArg TemplateParamLists) { + MultiTemplateParamsArg TemplateParamLists, + bool &AddToScope) { QualType R = TInfo->getType(); DeclarationName Name = GetNameForDeclarator(D).getName(); @@ -4703,6 +4942,10 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, VarDecl::StorageClass SC = StorageClassSpecToVarDeclStorageClass(D.getDeclSpec()); + 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). @@ -4720,15 +4963,16 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, SC = SC_None; } - // C++11 [dcl.stc]p4: - // When thread_local is applied to a variable of block scope the - // storage-class-specifier static is implied if it does not appear - // explicitly. - // Core issue: 'static' is not implied if the variable is declared 'extern'. - if (SCSpec == DeclSpec::SCS_unspecified && - D.getDeclSpec().getThreadStorageClassSpec() == - DeclSpec::TSCS_thread_local && DC->isFunctionOrMethod()) - SC = SC_Static; + if (getLangOpts().CPlusPlus11 && SCSpec == DeclSpec::SCS_register && + !D.getAsmLabel() && !getSourceManager().isInSystemMacro( + D.getDeclSpec().getStorageClassSpecLoc())) { + // In C++11, the 'register' storage class specifier is deprecated. + // Suppress the warning in system macros, it's used in macros in some + // popular C system headers, such as in glibc's htonl() macro. + Diag(D.getDeclSpec().getStorageClassSpecLoc(), + diag::warn_deprecated_register) + << FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc()); + } IdentifierInfo *II = Name.getAsIdentifierInfo(); if (!II) { @@ -4743,7 +4987,6 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, // 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()) @@ -4753,7 +4996,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, D.setInvalidType(); } } - + if (getLangOpts().OpenCL) { // Set up the special work-group-local storage class for variables in the // OpenCL __local address space. @@ -4786,8 +5029,13 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, } } - bool isExplicitSpecialization = false; - VarDecl *NewVD; + bool IsExplicitSpecialization = false; + bool IsVariableTemplateSpecialization = false; + bool IsPartialSpecialization = false; + bool IsVariableTemplate = false; + VarTemplateDecl *PrevVarTemplate = 0; + VarDecl *NewVD = 0; + VarTemplateDecl *NewTemplate = 0; if (!getLangOpts().CPlusPlus) { NewVD = VarDecl::Create(Context, DC, D.getLocStart(), D.getIdentifierLoc(), II, @@ -4796,14 +5044,37 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (D.isInvalidType()) NewVD->setInvalidDecl(); } else { + bool Invalid = false; + if (DC->isRecord() && !CurContext->isRecord()) { // This is an out-of-line definition of a static data member. - if (SC == SC_Static) { + switch (SC) { + case SC_None: + break; + case SC_Static: Diag(D.getDeclSpec().getStorageClassSpecLoc(), diag::err_static_out_of_line) << FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc()); + break; + case SC_Auto: + case SC_Register: + case SC_Extern: + // [dcl.stc] p2: The auto or register specifiers shall be applied only + // to names of variables declared in a block or to function parameters. + // [dcl.stc] p6: The extern specifier cannot be used in the declaration + // of class members + + Diag(D.getDeclSpec().getStorageClassSpecLoc(), + diag::err_storage_class_for_static_member) + << FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc()); + break; + case SC_PrivateExtern: + llvm_unreachable("C storage class in c++!"); + case SC_OpenCLWorkGroupLocal: + llvm_unreachable("OpenCL storage class in c++!"); } - } + } + if (SC == SC_Static && CurContext->isRecord()) { if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC)) { if (RD->isLocalClass()) @@ -4826,28 +5097,21 @@ 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. - isExplicitSpecialization = false; - bool Invalid = false; - if (TemplateParameterList *TemplateParams - = MatchTemplateParametersToScopeSpecifier( - D.getDeclSpec().getLocStart(), - D.getIdentifierLoc(), - D.getCXXScopeSpec(), - TemplateParamLists.data(), - TemplateParamLists.size(), - /*never a friend*/ false, - isExplicitSpecialization, - Invalid)) { - if (TemplateParams->size() > 0) { - // There is no such thing as a variable template. - Diag(D.getIdentifierLoc(), diag::err_template_variable) - << II - << SourceRange(TemplateParams->getTemplateLoc(), - TemplateParams->getRAngleLoc()); - return 0; - } else { + TemplateParameterList *TemplateParams = + MatchTemplateParametersToScopeSpecifier( + D.getDeclSpec().getLocStart(), D.getIdentifierLoc(), + D.getCXXScopeSpec(), TemplateParamLists, + /*never a friend*/ false, IsExplicitSpecialization, Invalid); + if (TemplateParams) { + if (!TemplateParams->size() && + D.getName().getKind() != UnqualifiedId::IK_TemplateId) { // There is an extraneous 'template<>' for this variable. Complain // about it, but allow the declaration of the variable. Diag(TemplateParams->getTemplateLoc(), @@ -4855,24 +5119,148 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, << II << SourceRange(TemplateParams->getTemplateLoc(), TemplateParams->getRAngleLoc()); + } 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 + + 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; + } + + // 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; + } + } + } } + } 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; } - NewVD = VarDecl::Create(Context, DC, D.getLocStart(), - D.getIdentifierLoc(), II, - R, TInfo, SC); + 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, + IsPartialSpecialization); + if (Res.isInvalid()) + return 0; + NewVD = cast<VarDecl>(Res.get()); + AddToScope = false; + } else + NewVD = VarDecl::Create(Context, DC, D.getLocStart(), + D.getIdentifierLoc(), II, R, TInfo, SC); + + // If this is supposed to be a variable template, create it as such. + if (IsVariableTemplate) { + NewTemplate = + VarTemplateDecl::Create(Context, DC, D.getIdentifierLoc(), Name, + TemplateParams, NewVD, PrevVarTemplate); + NewVD->setDescribedVarTemplate(NewTemplate); + } // If this decl has an auto type in need of deduction, make a note of the // Decl so we can diagnose uses of it in its own initializer. if (D.getDeclSpec().containsPlaceholderType() && R->getContainedAutoType()) ParsingInitForAutoVars.insert(NewVD); - if (D.isInvalidType() || Invalid) + if (D.isInvalidType() || Invalid) { NewVD->setInvalidDecl(); + if (NewTemplate) + NewTemplate->setInvalidDecl(); + } SetNestedNameSpecifier(NewVD, D); - if (TemplateParamLists.size() > 0 && D.getCXXScopeSpec().isSet()) { + // FIXME: Do we need D.getCXXScopeSpec().isSet()? + if (TemplateParams && TemplateParamLists.size() > 1 && + (!IsVariableTemplateSpecialization || D.getCXXScopeSpec().isSet())) { + 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()); @@ -4885,13 +5273,29 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, // Set the lexical context. If the declarator has a C++ scope specifier, the // lexical context will be different from the semantic context. NewVD->setLexicalDeclContext(CurContext); + if (NewTemplate) + NewTemplate->setLexicalDeclContext(CurContext); + + if (IsLocalExternDecl) + NewVD->setLocalExternDecl(); if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec()) { - if (NewVD->hasLocalStorage()) - Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(), - diag::err_thread_non_global) - << DeclSpec::getSpecifierName(TSCS); - else if (!Context.getTargetInfo().isTLSSupported()) + if (NewVD->hasLocalStorage()) { + // C++11 [dcl.stc]p4: + // When thread_local is applied to a variable of block scope the + // storage-class-specifier static is implied if it does not appear + // explicitly. + // Core issue: 'static' is not implied if the variable is declared + // 'extern'. + if (SCSpec == DeclSpec::SCS_unspecified && + TSCS == DeclSpec::TSCS_thread_local && + DC->isFunctionOrMethod()) + NewVD->setTSCSpec(TSCS); + else + Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(), + diag::err_thread_non_global) + << DeclSpec::getSpecifierName(TSCS); + } else if (!Context.getTargetInfo().isTLSSupported()) Diag(D.getDeclSpec().getThreadStorageClassSpecLoc(), diag::err_thread_unsupported); else @@ -4918,7 +5322,12 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, } if (D.getDeclSpec().isModulePrivateSpecified()) { - if (isExplicitSpecialization) + if (IsVariableTemplateSpecialization) + Diag(NewVD->getLocation(), diag::err_module_private_specialization) + << (IsPartialSpecialization ? 1 : 0) + << FixItHint::CreateRemoval( + D.getDeclSpec().getModulePrivateSpecLoc()); + else if (IsExplicitSpecialization) Diag(NewVD->getLocation(), diag::err_module_private_specialization) << 2 << FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc()); @@ -4927,8 +5336,11 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, << 0 << NewVD->getDeclName() << SourceRange(D.getDeclSpec().getModulePrivateSpecLoc()) << FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc()); - else + else { NewVD->setModulePrivate(); + if (NewTemplate) + NewTemplate->setModulePrivate(); + } } // Handle attributes prior to checking for duplicates in MergeVarDecl @@ -4993,9 +5405,18 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, // 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, DC, S, shouldConsiderLinkage(NewVD), - isExplicitSpecialization); - + FilterLookupForScope( + Previous, OriginalDC, S, shouldConsiderLinkage(NewVD), + 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. + if (getLangOpts().CPlusPlus && + NewVD->isLocalVarDecl() && NewVD->hasExternalStorage()) + NewVD->setPreviousDeclInSameBlockScope( + Previous.isSingleResult() && !Previous.isShadowed() && + isDeclInScope(Previous.getFoundDecl(), OriginalDC, S, false)); + if (!getLangOpts().CPlusPlus) { D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous)); } else { @@ -5019,10 +5440,18 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, NewVD->setInvalidDecl(); } - D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous)); + 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)); + } // This is an explicit specialization of a static data member. Check it. - if (isExplicitSpecialization && !NewVD->isInvalidDecl() && + if (IsExplicitSpecialization && !NewVD->isInvalidDecl() && CheckMemberSpecialization(NewVD, Previous)) NewVD->setInvalidDecl(); } @@ -5030,11 +5459,30 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, ProcessPragmaWeak(S, NewVD); checkAttributesAfterMerging(*this, *NewVD); - // If this is a locally-scoped extern C variable, update the map of - // such variables. - if (CurContext->isFunctionOrMethod() && NewVD->isExternC() && - !NewVD->isInvalidDecl()) - RegisterLocallyScopedExternCDecl(NewVD, Previous, S); + // If this is the first declaration of an extern C variable, update + // the map of such variables. + if (NewVD->isFirstDecl() && !NewVD->isInvalidDecl() && + isIncompleteDeclExternC(*this, NewVD)) + RegisterLocallyScopedExternCDecl(NewVD, S); + + if (getLangOpts().CPlusPlus && NewVD->isStaticLocal()) { + Decl *ManglingContextDecl; + if (MangleNumberingContext *MCtx = + getCurrentMangleNumberContext(NewVD->getDeclContext(), + ManglingContextDecl)) { + Context.setManglingNumber(NewVD, MCtx->getManglingNumber(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 (NewTemplate) { + ActOnDocumentableDecl(NewTemplate); + return NewTemplate; + } return NewVD; } @@ -5134,30 +5582,121 @@ void Sema::CheckShadow(Scope *S, VarDecl *D) { CheckShadow(S, D, R); } +/// Check for conflict between this global or extern "C" declaration and +/// previous global or extern "C" declarations. This is only used in C++. template<typename T> -static bool mayConflictWithNonVisibleExternC(const T *ND) { - const DeclContext *DC = ND->getDeclContext(); - if (DC->getRedeclContext()->isTranslationUnit()) - return true; +static bool checkGlobalOrExternCConflict( + Sema &S, const T *ND, bool IsGlobal, LookupResult &Previous) { + assert(S.getLangOpts().CPlusPlus && "only C++ has extern \"C\""); + NamedDecl *Prev = S.findLocallyScopedExternCDecl(ND->getDeclName()); + + if (!Prev && IsGlobal && !isIncompleteDeclExternC(S, ND)) { + // The common case: this global doesn't conflict with any extern "C" + // declaration. + return false; + } - // We know that is the first decl we see, other than function local - // extern C ones. If this is C++ and the decl is not in a extern C context - // it cannot have C language linkage. Avoid calling isExternC in that case. - // We need to this because of code like - // - // namespace { struct bar {}; } - // auto foo = bar(); - // - // This code runs before the init of foo is set, and therefore before - // the type of foo is known. Not knowing the type we cannot know its linkage - // unless it is in an extern C block. - if (!ND->isInExternCContext()) { - const ASTContext &Context = ND->getASTContext(); - if (Context.getLangOpts().CPlusPlus) + if (Prev) { + if (!IsGlobal || isIncompleteDeclExternC(S, ND)) { + // Both the old and new declarations have C language linkage. This is a + // redeclaration. + Previous.clear(); + Previous.addDecl(Prev); + return true; + } + + // This is a global, non-extern "C" declaration, and there is a previous + // non-global extern "C" declaration. Diagnose if this is a variable + // declaration. + if (!isa<VarDecl>(ND)) return false; + } else { + // The declaration is extern "C". Check for any declaration in the + // translation unit which might conflict. + if (IsGlobal) { + // We have already performed the lookup into the translation unit. + IsGlobal = false; + for (LookupResult::iterator I = Previous.begin(), E = Previous.end(); + I != E; ++I) { + if (isa<VarDecl>(*I)) { + Prev = *I; + break; + } + } + } else { + DeclContext::lookup_result R = + S.Context.getTranslationUnitDecl()->lookup(ND->getDeclName()); + for (DeclContext::lookup_result::iterator I = R.begin(), E = R.end(); + I != E; ++I) { + if (isa<VarDecl>(*I)) { + Prev = *I; + break; + } + // FIXME: If we have any other entity with this name in global scope, + // the declaration is ill-formed, but that is a defect: it breaks the + // 'stat' hack, for instance. Only variables can have mangled name + // clashes with extern "C" declarations, so only they deserve a + // diagnostic. + } + } + + if (!Prev) + return false; + } + + // Use the first declaration's location to ensure we point at something which + // is lexically inside an extern "C" linkage-spec. + assert(Prev && "should have found a previous declaration to diagnose"); + if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Prev)) + Prev = FD->getFirstDecl(); + else + Prev = cast<VarDecl>(Prev)->getFirstDecl(); + + S.Diag(ND->getLocation(), diag::err_extern_c_global_conflict) + << IsGlobal << ND; + S.Diag(Prev->getLocation(), diag::note_extern_c_global_conflict) + << IsGlobal; + return false; +} + +/// Apply special rules for handling extern "C" declarations. Returns \c true +/// if we have found that this is a redeclaration of some prior entity. +/// +/// Per C++ [dcl.link]p6: +/// Two declarations [for a function or variable] with C language linkage +/// with the same name that appear in different scopes refer to the same +/// [entity]. An entity with C language linkage shall not be declared with +/// the same name as an entity in global scope. +template<typename T> +static bool checkForConflictWithNonVisibleExternC(Sema &S, const T *ND, + LookupResult &Previous) { + if (!S.getLangOpts().CPlusPlus) { + // In C, when declaring a global variable, look for a corresponding 'extern' + // variable declared in function scope. We don't need this in C++, because + // we find local extern decls in the surrounding file-scope DeclContext. + if (ND->getDeclContext()->getRedeclContext()->isTranslationUnit()) { + if (NamedDecl *Prev = S.findLocallyScopedExternCDecl(ND->getDeclName())) { + Previous.clear(); + Previous.addDecl(Prev); + return true; + } + } + return false; } - return ND->isExternC(); + // A declaration in the translation unit can conflict with an extern "C" + // declaration. + if (ND->getDeclContext()->getRedeclContext()->isTranslationUnit()) + return checkGlobalOrExternCConflict(S, ND, /*IsGlobal*/true, Previous); + + // An extern "C" declaration can conflict with a declaration in the + // translation unit or can be a redeclaration of an extern "C" declaration + // in another scope. + if (isIncompleteDeclExternC(S,ND)) + return checkGlobalOrExternCConflict(S, ND, /*IsGlobal*/false, Previous); + + // Neither global nor extern "C": nothing to do. + return false; } void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { @@ -5239,7 +5778,7 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { if (NewVD->isFileVarDecl()) Diag(NewVD->getLocation(), diag::err_vla_decl_in_file_scope) << SizeRange; - else if (NewVD->getStorageClass() == SC_Static) + else if (NewVD->isStaticLocal()) Diag(NewVD->getLocation(), diag::err_vla_decl_has_static_storage) << SizeRange; else @@ -5263,11 +5802,15 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { NewVD->setTypeSourceInfo(FixedTInfo); } - if (T->isVoidType() && NewVD->isThisDeclarationADefinition()) { - Diag(NewVD->getLocation(), diag::err_typecheck_decl_incomplete_type) - << T; - NewVD->setInvalidDecl(); - return; + if (T->isVoidType()) { + // C++98 [dcl.stc]p5: The extern specifier can be applied only to the names + // of objects and functions. + if (NewVD->isThisDeclarationADefinition() || getLangOpts().CPlusPlus) { + Diag(NewVD->getLocation(), diag::err_typecheck_decl_incomplete_type) + << T; + NewVD->setInvalidDecl(); + return; + } } if (!NewVD->hasLocalStorage() && NewVD->hasAttr<BlocksAttr>()) { @@ -5303,8 +5846,7 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) { /// Sets NewVD->isInvalidDecl() if an error was encountered. /// /// Returns true if the variable declaration is a redeclaration. -bool Sema::CheckVariableDeclaration(VarDecl *NewVD, - LookupResult &Previous) { +bool Sema::CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous) { CheckVariableDeclarationType(NewVD); // If the decl is already known invalid, don't check it. @@ -5313,44 +5855,15 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD, // If we did not find anything by this name, look for a non-visible // extern "C" declaration with the same name. - // - // Clang has a lot of problems with extern local declarations. - // The actual standards text here is: - // - // C++11 [basic.link]p6: - // The name of a function declared in block scope and the name - // of a variable declared by a block scope extern declaration - // have linkage. If there is a visible declaration of an entity - // with linkage having the same name and type, ignoring entities - // declared outside the innermost enclosing namespace scope, the - // block scope declaration declares that same entity and - // receives the linkage of the previous declaration. - // - // C11 6.2.7p4: - // For an identifier with internal or external linkage declared - // in a scope in which a prior declaration of that identifier is - // visible, if the prior declaration specifies internal or - // external linkage, the type of the identifier at the later - // declaration becomes the composite type. - // - // The most important point here is that we're not allowed to - // update our understanding of the type according to declarations - // not in scope. - bool PreviousWasHidden = false; - if (Previous.empty() && mayConflictWithNonVisibleExternC(NewVD)) { - llvm::DenseMap<DeclarationName, NamedDecl *>::iterator Pos - = findLocallyScopedExternCDecl(NewVD->getDeclName()); - if (Pos != LocallyScopedExternCDecls.end()) { - Previous.addDecl(Pos->second); - PreviousWasHidden = true; - } - } + if (Previous.empty() && + checkForConflictWithNonVisibleExternC(*this, NewVD, Previous)) + Previous.setShadowed(); // Filter out any non-conflicting previous declarations. filterNonConflictingPreviousDecls(Context, NewVD, Previous); if (!Previous.empty()) { - MergeVarDecl(NewVD, Previous, PreviousWasHidden); + MergeVarDecl(NewVD, Previous); return true; } return false; @@ -5524,24 +6037,27 @@ class DifferentNameValidatorCCC : public CorrectionCandidateCallback { /// /// Returns a NamedDecl iff typo correction was performed and substituting in /// the new declaration name does not cause new errors. -static NamedDecl* DiagnoseInvalidRedeclaration( +static NamedDecl *DiagnoseInvalidRedeclaration( Sema &SemaRef, LookupResult &Previous, FunctionDecl *NewFD, - ActOnFDArgs &ExtraArgs) { - NamedDecl *Result = NULL; + ActOnFDArgs &ExtraArgs, bool IsLocalFriend, Scope *S) { DeclarationName Name = NewFD->getDeclName(); DeclContext *NewDC = NewFD->getDeclContext(); - LookupResult Prev(SemaRef, Name, NewFD->getLocation(), - Sema::LookupOrdinaryName, Sema::ForRedeclaration); SmallVector<unsigned, 1> MismatchedParams; SmallVector<std::pair<FunctionDecl *, unsigned>, 1> NearMatches; TypoCorrection Correction; - bool isFriendDecl = (SemaRef.getLangOpts().CPlusPlus && - ExtraArgs.D.getDeclSpec().isFriendSpecified()); - unsigned DiagMsg = isFriendDecl ? diag::err_no_matching_local_friend - : diag::err_member_def_does_not_match; + bool IsDefinition = ExtraArgs.D.isFunctionDefinition(); + unsigned DiagMsg = IsLocalFriend ? diag::err_no_matching_local_friend + : diag::err_member_decl_does_not_match; + LookupResult Prev(SemaRef, Name, NewFD->getLocation(), + IsLocalFriend ? Sema::LookupLocalFriendName + : Sema::LookupOrdinaryName, + Sema::ForRedeclaration); NewFD->setInvalidDecl(); - SemaRef.LookupQualifiedName(Prev, NewDC); + if (IsLocalFriend) + SemaRef.LookupName(Prev, S); + else + SemaRef.LookupQualifiedName(Prev, NewDC); assert(!Prev.isAmbiguous() && "Cannot have an ambiguity in previous-declaration lookup"); CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD); @@ -5561,12 +6077,10 @@ static NamedDecl* DiagnoseInvalidRedeclaration( } } // If the qualified name lookup yielded nothing, try typo correction - } else if ((Correction = SemaRef.CorrectTypo(Prev.getLookupNameInfo(), - Prev.getLookupKind(), 0, 0, - Validator, NewDC))) { - // Trap errors. - Sema::SFINAETrap Trap(SemaRef); - + } else if ((Correction = SemaRef.CorrectTypo( + Prev.getLookupNameInfo(), Prev.getLookupKind(), S, + &ExtraArgs.D.getCXXScopeSpec(), Validator, + IsLocalFriend ? 0 : NewDC))) { // Set up everything for the call to ActOnFunctionDeclarator ExtraArgs.D.SetIdentifier(Correction.getCorrectionAsIdentifierInfo(), ExtraArgs.D.getIdentifierLoc()); @@ -5582,85 +6096,85 @@ static NamedDecl* DiagnoseInvalidRedeclaration( } } bool wasRedeclaration = ExtraArgs.D.isRedeclaration(); - // TODO: Refactor ActOnFunctionDeclarator so that we can call only the - // pieces need to verify the typo-corrected C++ declaraction and hopefully - // eliminate the need for the parameter pack ExtraArgs. - Result = SemaRef.ActOnFunctionDeclarator( - ExtraArgs.S, ExtraArgs.D, - Correction.getCorrectionDecl()->getDeclContext(), - NewFD->getTypeSourceInfo(), Previous, ExtraArgs.TemplateParamLists, - ExtraArgs.AddToScope); - if (Trap.hasErrorOccurred()) { - // Pretend the typo correction never occurred - ExtraArgs.D.SetIdentifier(Name.getAsIdentifierInfo(), - ExtraArgs.D.getIdentifierLoc()); - ExtraArgs.D.setRedeclaration(wasRedeclaration); - Previous.clear(); - Previous.setLookupName(Name); - Result = NULL; - } else { - for (LookupResult::iterator Func = Previous.begin(), - FuncEnd = Previous.end(); - Func != FuncEnd; ++Func) { - if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*Func)) - NearMatches.push_back(std::make_pair(FD, 0)); - } + + NamedDecl *Result; + // Retry building the function declaration with the new previous + // declarations, and with errors suppressed. + { + // Trap errors. + Sema::SFINAETrap Trap(SemaRef); + + // TODO: Refactor ActOnFunctionDeclarator so that we can call only the + // pieces need to verify the typo-corrected C++ declaration and hopefully + // eliminate the need for the parameter pack ExtraArgs. + Result = SemaRef.ActOnFunctionDeclarator( + ExtraArgs.S, ExtraArgs.D, + Correction.getCorrectionDecl()->getDeclContext(), + NewFD->getTypeSourceInfo(), Previous, ExtraArgs.TemplateParamLists, + ExtraArgs.AddToScope); + + if (Trap.hasErrorOccurred()) + Result = 0; + } + + if (Result) { + // Determine which correction we picked. + Decl *Canonical = Result->getCanonicalDecl(); + for (LookupResult::iterator I = Previous.begin(), E = Previous.end(); + I != E; ++I) + if ((*I)->getCanonicalDecl() == Canonical) + Correction.setCorrectionDecl(*I); + + SemaRef.diagnoseTypo( + Correction, + SemaRef.PDiag(IsLocalFriend + ? diag::err_no_matching_local_friend_suggest + : diag::err_member_decl_does_not_match_suggest) + << Name << NewDC << IsDefinition); + return Result; } - if (NearMatches.empty()) { - // Ignore the correction if it didn't yield any close FunctionDecl matches - Correction = TypoCorrection(); - } else { - DiagMsg = isFriendDecl ? diag::err_no_matching_local_friend_suggest - : diag::err_member_def_does_not_match_suggest; - } - } - - if (Correction) { - // FIXME: use Correction.getCorrectionRange() instead of computing the range - // here. This requires passing in the CXXScopeSpec to CorrectTypo which in - // turn causes the correction to fully qualify the name. If we fix - // CorrectTypo to minimally qualify then this change should be good. - SourceRange FixItLoc(NewFD->getLocation()); - CXXScopeSpec &SS = ExtraArgs.D.getCXXScopeSpec(); - if (Correction.getCorrectionSpecifier() && SS.isValid()) - FixItLoc.setBegin(SS.getBeginLoc()); - SemaRef.Diag(NewFD->getLocStart(), DiagMsg) - << Name << NewDC << Correction.getQuoted(SemaRef.getLangOpts()) - << FixItHint::CreateReplacement( - FixItLoc, Correction.getAsString(SemaRef.getLangOpts())); - } else { - SemaRef.Diag(NewFD->getLocation(), DiagMsg) - << Name << NewDC << NewFD->getLocation(); + + // Pretend the typo correction never occurred + ExtraArgs.D.SetIdentifier(Name.getAsIdentifierInfo(), + ExtraArgs.D.getIdentifierLoc()); + ExtraArgs.D.setRedeclaration(wasRedeclaration); + Previous.clear(); + Previous.setLookupName(Name); } + SemaRef.Diag(NewFD->getLocation(), DiagMsg) + << Name << NewDC << IsDefinition << NewFD->getLocation(); + bool NewFDisConst = false; if (CXXMethodDecl *NewMD = dyn_cast<CXXMethodDecl>(NewFD)) NewFDisConst = NewMD->isConst(); - for (SmallVector<std::pair<FunctionDecl *, unsigned>, 1>::iterator + for (SmallVectorImpl<std::pair<FunctionDecl *, unsigned> >::iterator NearMatch = NearMatches.begin(), NearMatchEnd = NearMatches.end(); NearMatch != NearMatchEnd; ++NearMatch) { FunctionDecl *FD = NearMatch->first; - bool FDisConst = false; - if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) - FDisConst = MD->isConst(); + CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD); + bool FDisConst = MD && MD->isConst(); + bool IsMember = MD || !IsLocalFriend; + // FIXME: These notes are poorly worded for the local friend case. if (unsigned Idx = NearMatch->second) { ParmVarDecl *FDParam = FD->getParamDecl(Idx-1); SourceLocation Loc = FDParam->getTypeSpecStartLoc(); if (Loc.isInvalid()) Loc = FD->getLocation(); - SemaRef.Diag(Loc, diag::note_member_def_close_param_match) - << Idx << FDParam->getType() << NewFD->getParamDecl(Idx-1)->getType(); - } else if (Correction) { - SemaRef.Diag(FD->getLocation(), diag::note_previous_decl) - << Correction.getQuoted(SemaRef.getLangOpts()); + SemaRef.Diag(Loc, IsMember ? diag::note_member_def_close_param_match + : diag::note_local_decl_close_param_match) + << Idx << FDParam->getType() + << NewFD->getParamDecl(Idx - 1)->getType(); } else if (FDisConst != NewFDisConst) { SemaRef.Diag(FD->getLocation(), diag::note_member_def_close_const_match) << NewFDisConst << FD->getSourceRange().getEnd(); } else - SemaRef.Diag(FD->getLocation(), diag::note_member_def_close_match); + SemaRef.Diag(FD->getLocation(), + IsMember ? diag::note_member_def_close_match + : diag::note_local_decl_close_match); } - return Result; + return 0; } static FunctionDecl::StorageClass getFunctionStorageClass(Sema &SemaRef, @@ -5778,6 +6292,15 @@ 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; @@ -5856,6 +6379,173 @@ void Sema::checkVoidParamDecl(ParmVarDecl *Param) { } } +enum OpenCLParamType { + ValidKernelParam, + PtrPtrKernelParam, + PtrKernelParam, + InvalidKernelParam, + RecordKernelParam +}; + +static OpenCLParamType getOpenCLKernelParameterType(QualType PT) { + if (PT->isPointerType()) { + QualType PointeeType = PT->getPointeeType(); + return PointeeType->isPointerType() ? PtrPtrKernelParam : PtrKernelParam; + } + + // TODO: Forbid the other integer types (size_t, ptrdiff_t...) when they can + // be used as builtin types. + + if (PT->isImageType()) + return PtrKernelParam; + + if (PT->isBooleanType()) + return InvalidKernelParam; + + if (PT->isEventT()) + return InvalidKernelParam; + + if (PT->isHalfType()) + return InvalidKernelParam; + + if (PT->isRecordType()) + return RecordKernelParam; + + return ValidKernelParam; +} + +static void checkIsValidOpenCLKernelParameter( + Sema &S, + Declarator &D, + ParmVarDecl *Param, + llvm::SmallPtrSet<const Type *, 16> &ValidTypes) { + QualType PT = Param->getType(); + + // Cache the valid types we encounter to avoid rechecking structs that are + // used again + if (ValidTypes.count(PT.getTypePtr())) + return; + + switch (getOpenCLKernelParameterType(PT)) { + case PtrPtrKernelParam: + // OpenCL v1.2 s6.9.a: + // A kernel function argument cannot be declared as a + // pointer to a pointer type. + S.Diag(Param->getLocation(), diag::err_opencl_ptrptr_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 + // uintptr_t or a struct and/or union that contain fields declared to be + // one of these built-in scalar types. + + case InvalidKernelParam: + // OpenCL v1.2 s6.8 n: + // A kernel function argument cannot be declared + // of event_t type. + S.Diag(Param->getLocation(), diag::err_bad_kernel_param_type) << PT; + D.setInvalidType(); + return; + + case PtrKernelParam: + case ValidKernelParam: + ValidTypes.insert(PT.getTypePtr()); + return; + + case RecordKernelParam: + break; + } + + // Track nested structs we will inspect + SmallVector<const Decl *, 4> VisitStack; + + // 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); + + const RecordDecl *PD = PT->castAs<RecordType>()->getDecl(); + VisitStack.push_back(PD); + + assert(VisitStack.back() && "First decl null?"); + + do { + const Decl *Next = VisitStack.pop_back_val(); + if (!Next) { + assert(!HistoryStack.empty()); + // Found a marker, we have gone up a level + if (const FieldDecl *Hist = HistoryStack.pop_back_val()) + ValidTypes.insert(Hist->getType().getTypePtr()); + + continue; + } + + // Adds everything except the original parameter declaration (which is not a + // field itself) to the history stack. + const RecordDecl *RD; + if (const FieldDecl *Field = dyn_cast<FieldDecl>(Next)) { + HistoryStack.push_back(Field); + RD = Field->getType()->castAs<RecordType>()->getDecl(); + } else { + RD = cast<RecordDecl>(Next); + } + + // Add a null marker so we know when we've gone back up a level + VisitStack.push_back((const Decl *) 0); + + for (RecordDecl::field_iterator I = RD->field_begin(), + E = RD->field_end(); I != E; ++I) { + const FieldDecl *FD = *I; + QualType QT = FD->getType(); + + if (ValidTypes.count(QT.getTypePtr())) + continue; + + OpenCLParamType ParamType = getOpenCLKernelParameterType(QT); + if (ParamType == ValidKernelParam) + continue; + + if (ParamType == RecordKernelParam) { + VisitStack.push_back(FD); + continue; + } + + // OpenCL v1.2 s6.9.p: + // 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) { + S.Diag(Param->getLocation(), + diag::err_record_with_pointers_kernel_param) + << PT->isUnionType() + << PT; + } else { + S.Diag(Param->getLocation(), diag::err_bad_kernel_param_type) << PT; + } + + S.Diag(PD->getLocation(), diag::note_within_field_of_type) + << PD->getDeclName(); + + // We have an error, now let's go back up through history and show where + // the offending field came from + for (ArrayRef<const FieldDecl *>::const_iterator I = HistoryStack.begin() + 1, + E = HistoryStack.end(); I != E; ++I) { + const FieldDecl *OuterField = *I; + S.Diag(OuterField->getLocation(), diag::note_within_field_of_type) + << OuterField->getType(); + } + + S.Diag(FD->getLocation(), diag::note_illegal_field_declared_here) + << QT->isPointerType() + << QT; + D.setInvalidType(); + return; + } + } while (!VisitStack.empty()); +} + NamedDecl* Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, TypeSourceInfo *TInfo, LookupResult &Previous, @@ -5875,25 +6565,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, diag::err_invalid_thread) << DeclSpec::getSpecifierName(TSCS); - // Do not allow returning a objc interface by-value. - if (R->getAs<FunctionType>()->getResultType()->isObjCObjectType()) { - Diag(D.getIdentifierLoc(), - diag::err_object_cannot_be_passed_returned_by_value) << 0 - << R->getAs<FunctionType>()->getResultType() - << FixItHint::CreateInsertion(D.getIdentifierLoc(), "*"); - - QualType T = R->getAs<FunctionType>()->getResultType(); - T = Context.getObjCObjectPointerType(T); - if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(R)) { - FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); - R = Context.getFunctionType(T, - ArrayRef<QualType>(FPT->arg_type_begin(), - FPT->getNumArgs()), - EPI); - } - else if (isa<FunctionNoProtoType>(R)) - R = Context.getFunctionNoProtoType(T); - } + if (D.isFirstDeclarationOfMember()) + adjustMemberFunctionCC(R, D.isStaticMember()); bool isFriend = false; FunctionTemplateDecl *FunctionTemplate = 0; @@ -5906,6 +6579,9 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, bool isVirtualOkay = false; + DeclContext *OriginalDC = DC; + bool IsLocalExternDecl = adjustContextForLocalExternDecl(DC); + FunctionDecl *NewFD = CreateNewFunctionDecl(*this, D, DC, R, TInfo, SC, isVirtualOkay); if (!NewFD) return 0; @@ -5913,6 +6589,14 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (OriginalLexicalContext && OriginalLexicalContext->isObjCContainer()) NewFD->setTopLevelDeclInObjCContainer(); + // Set the lexical context. If this is a function-scope declaration, or has a + // C++ scope specifier, or is the object of a friend declaration, the lexical + // context will be different from the semantic context. + NewFD->setLexicalDeclContext(CurContext); + + if (IsLocalExternDecl) + NewFD->setLocalExternDecl(); + if (getLangOpts().CPlusPlus) { bool isInline = D.getDeclSpec().isInlineSpecified(); bool isVirtual = D.getDeclSpec().isVirtualSpecified(); @@ -5940,25 +6624,15 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, isFunctionTemplateSpecialization = false; if (D.isInvalidType()) NewFD->setInvalidDecl(); - - // Set the lexical context. If the declarator has a C++ - // scope specifier, or is the object of a friend declaration, the - // lexical context will be different from the semantic context. - NewFD->setLexicalDeclContext(CurContext); - + // Match up the template parameter lists with the scope specifier, then // determine whether we have a template or a template specialization. bool Invalid = false; - if (TemplateParameterList *TemplateParams - = MatchTemplateParametersToScopeSpecifier( - D.getDeclSpec().getLocStart(), - D.getIdentifierLoc(), - D.getCXXScopeSpec(), - TemplateParamLists.data(), - TemplateParamLists.size(), - isFriend, - isExplicitSpecialization, - Invalid)) { + if (TemplateParameterList *TemplateParams = + MatchTemplateParametersToScopeSpecifier( + D.getDeclSpec().getLocStart(), D.getIdentifierLoc(), + D.getCXXScopeSpec(), TemplateParamLists, isFriend, + isExplicitSpecialization, Invalid)) { if (TemplateParams->size() > 0) { // This is a function template @@ -6072,6 +6746,24 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, Diag(D.getDeclSpec().getVirtualSpecLoc(), diag::err_auto_fn_virtual); } + if (getLangOpts().CPlusPlus1y && + (NewFD->isDependentContext() || + (isFriend && CurContext->isDependentContext())) && + NewFD->getResultType()->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 + // thing to do. + // FIXME: For a friend function, we have not marked the function as being + // 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(), + FPT->getExtProtoInfo())); + } + // C++ [dcl.fct.spec]p3: // The inline specifier shall not appear on a block scope function // declaration. @@ -6132,12 +6824,11 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, } if (isFriend) { - // For now, claim that the objects have no previous declaration. if (FunctionTemplate) { - FunctionTemplate->setObjectOfFriendDecl(false); + FunctionTemplate->setObjectOfFriendDecl(); FunctionTemplate->setAccess(AS_public); } - NewFD->setObjectOfFriendDecl(false); + NewFD->setObjectOfFriendDecl(); NewFD->setAccess(AS_public); } @@ -6188,17 +6879,15 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); EPI.ExceptionSpecType = EST_BasicNoexcept; NewFD->setType(Context.getFunctionType(FPT->getResultType(), - ArrayRef<QualType>(FPT->arg_type_begin(), - FPT->getNumArgs()), - EPI)); + FPT->getArgTypes(), EPI)); } } // Filter out previous declarations that don't match the scope. - FilterLookupForScope(Previous, DC, S, shouldConsiderLinkage(NewFD), + FilterLookupForScope(Previous, OriginalDC, S, shouldConsiderLinkage(NewFD), isExplicitSpecialization || isFunctionTemplateSpecialization); - + // Handle GNU asm-label extension (encoded as an attribute). if (Expr *E = (Expr*) D.getAsmLabel()) { // The parser guarantees this is a string. @@ -6282,10 +6971,6 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, ::new(Context) C11NoReturnAttr(D.getDeclSpec().getNoreturnSpecLoc(), Context)); - // Process the non-inheritable attributes on this declaration. - ProcessDeclAttributes(S, NewFD, D, - /*NonInheritable=*/true, /*Inheritable=*/false); - // Functions returning a variably modified type violate C99 6.7.5.2p2 // because all functions have linkage. if (!NewFD->isInvalidDecl() && @@ -6295,8 +6980,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, } // Handle attributes. - ProcessDeclAttributes(S, NewFD, D, - /*NonInheritable=*/false, /*Inheritable=*/true); + ProcessDeclAttributes(S, NewFD, D); QualType RetType = NewFD->getResultType(); const CXXRecordDecl *Ret = RetType->isRecordType() ? @@ -6304,7 +6988,9 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (!NewFD->isInvalidDecl() && !NewFD->hasAttr<WarnUnusedResultAttr>() && Ret && Ret->hasAttr<WarnUnusedResultAttr>()) { const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD); - if (!(MD && MD->getCorrespondingMethodInClass(Ret, true))) { + // 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)); } @@ -6313,19 +6999,36 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (!getLangOpts().CPlusPlus) { // Perform semantic checking on the function declaration. bool isExplicitSpecialization=false; - if (!NewFD->isInvalidDecl()) { - if (NewFD->isMain()) - CheckMain(NewFD, D.getDeclSpec()); + if (!NewFD->isInvalidDecl() && NewFD->isMain()) + CheckMain(NewFD, D.getDeclSpec()); + + if (!NewFD->isInvalidDecl() && NewFD->isMSVCRTEntryPoint()) + CheckMSVCRTEntryPoint(NewFD); + + if (!NewFD->isInvalidDecl()) D.setRedeclaration(CheckFunctionDeclaration(S, NewFD, Previous, isExplicitSpecialization)); - } - // Make graceful recovery from an invalid redeclaration. else if (!Previous.empty()) - D.setRedeclaration(true); + // Make graceful recovery from an invalid redeclaration. + D.setRedeclaration(true); assert((NewFD->isInvalidDecl() || !D.isRedeclaration() || Previous.getResultKind() != LookupResult::FoundOverloaded) && "previous declaration set still overloaded"); } else { + // C++11 [replacement.functions]p3: + // The program's definitions shall not be specified as inline. + // + // N.B. We diagnose declarations instead of definitions per LWG issue 2340. + // + // Suppress the diagnostic if the function is __attribute__((used)), since + // that forces an external definition to be emitted. + if (D.getDeclSpec().isInlineSpecified() && + NewFD->isReplaceableGlobalAllocationFunction() && + !NewFD->hasAttr<UsedAttr>()) + Diag(D.getDeclSpec().getInlineSpecLoc(), + diag::ext_operator_new_delete_declared_inline) + << NewFD->getDeclName(); + // If the declarator is a template-id, translate the parser's template // argument list into our AST format. if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) { @@ -6353,6 +7056,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // 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( @@ -6406,8 +7111,10 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // C++ [dcl.stc]p1: // A storage-class-specifier shall not be specified in an explicit // specialization (14.7.3) - if (SC != SC_None) { - if (SC != NewFD->getTemplateSpecializationInfo()->getTemplate()->getTemplatedDecl()->getStorageClass()) + FunctionTemplateSpecializationInfo *Info = + NewFD->getTemplateSpecializationInfo(); + if (Info && SC != SC_None) { + if (SC != Info->getTemplate()->getTemplatedDecl()->getStorageClass()) Diag(NewFD->getLocation(), diag::err_explicit_specialization_inconsistent_storage_class) << SC @@ -6428,17 +7135,20 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // Perform semantic checking on the function declaration. if (!isDependentClassScopeExplicitSpecialization) { + if (!NewFD->isInvalidDecl() && NewFD->isMain()) + CheckMain(NewFD, D.getDeclSpec()); + + 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->isMain()) - CheckMain(NewFD, D.getDeclSpec()); + } else D.setRedeclaration(CheckFunctionDeclaration(S, NewFD, Previous, isExplicitSpecialization)); - } } assert((NewFD->isInvalidDecl() || !D.isRedeclaration() || @@ -6456,8 +7166,6 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, NewFD->setAccess(Access); if (FunctionTemplate) FunctionTemplate->setAccess(Access); - - PrincipalDecl->setObjectOfFriendDecl(true); } if (NewFD->isOverloadedOperator() && !DC->isRecord() && @@ -6523,9 +7231,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // matches (e.g., those that differ only in cv-qualifiers and // whether the parameter types are references). - if (NamedDecl *Result = DiagnoseInvalidRedeclaration(*this, Previous, - NewFD, - ExtraArgs)) { + if (NamedDecl *Result = DiagnoseInvalidRedeclaration( + *this, Previous, NewFD, ExtraArgs, false, 0)) { AddToScope = ExtraArgs.AddToScope; return Result; } @@ -6534,9 +7241,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // Unqualified local friend declarations are required to resolve // to something. } else if (isFriend && cast<CXXRecordDecl>(CurContext)->isLocalClass()) { - if (NamedDecl *Result = DiagnoseInvalidRedeclaration(*this, Previous, - NewFD, - ExtraArgs)) { + if (NamedDecl *Result = DiagnoseInvalidRedeclaration( + *this, Previous, NewFD, ExtraArgs, true, S)) { AddToScope = ExtraArgs.AddToScope; return Result; } @@ -6570,7 +7276,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // Turn this into a variadic function with no parameters. const FunctionType *FT = NewFD->getType()->getAs<FunctionType>(); - FunctionProtoType::ExtProtoInfo EPI; + FunctionProtoType::ExtProtoInfo EPI( + Context.getDefaultCallingConvention(true, false)); EPI.Variadic = true; EPI.ExtInfo = FT->getExtInfo(); @@ -6580,18 +7287,18 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // If there's a #pragma GCC visibility in scope, and this isn't a class // member, set the visibility of this function. - if (!DC->isRecord() && NewFD->hasExternalLinkage()) + if (!DC->isRecord() && NewFD->isExternallyVisible()) AddPushedVisibilityAttribute(NewFD); // If there's a #pragma clang arc_cf_code_audited in scope, consider // marking the function. AddCFAuditedAttribute(NewFD); - // If this is a locally-scoped extern C function, update the - // map of such names. - if (CurContext->isFunctionOrMethod() && NewFD->isExternC() - && !NewFD->isInvalidDecl()) - RegisterLocallyScopedExternCDecl(NewFD, Previous, S); + // If this is the first declaration of an extern C variable, update + // the map of such variables. + if (NewFD->isFirstDecl() && !NewFD->isInvalidDecl() && + isIncompleteDeclExternC(*this, NewFD)) + RegisterLocallyScopedExternCDecl(NewFD, S); // Set this FunctionDecl's range up to the right paren. NewFD->setRangeEnd(D.getSourceRange().getEnd()); @@ -6618,27 +7325,12 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, diag::err_expected_kernel_void_return_type); 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; - QualType PT = Param->getType(); - - // OpenCL v1.2 s6.9.a: - // A kernel function argument cannot be declared as a - // pointer to a pointer type. - if (PT->isPointerType() && PT->getPointeeType()->isPointerType()) { - Diag(Param->getLocation(), diag::err_opencl_ptrptr_kernel_arg); - D.setInvalidType(); - } - - // OpenCL v1.2 s6.8 n: - // A kernel function argument cannot be declared - // of event_t type. - if (PT->isEventT()) { - Diag(Param->getLocation(), diag::err_event_t_kernel_arg); - D.setInvalidType(); - } + checkIsValidOpenCLKernelParameter(*this, D, Param, ValidTypes); } } @@ -6694,15 +7386,11 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, assert(!NewFD->getResultType()->isVariablyModifiedType() && "Variably modified return types are not handled here"); - // Check for a previous declaration of this name. - if (Previous.empty() && mayConflictWithNonVisibleExternC(NewFD)) { - // Since we did not find anything by this name, look for a non-visible - // extern "C" declaration with the same name. - llvm::DenseMap<DeclarationName, NamedDecl *>::iterator Pos - = findLocallyScopedExternCDecl(NewFD->getDeclName()); - if (Pos != LocallyScopedExternCDecls.end()) - Previous.addDecl(Pos->second); - } + // Determine whether the type of this function should be merged with + // a previous visible declaration. This never happens for functions in C++, + // and always happens in C if the previous declaration was visible. + bool MergeTypeWithPrevious = !getLangOpts().CPlusPlus && + !Previous.isShadowed(); // Filter out any non-conflicting previous declarations. filterNonConflictingPreviousDecls(Context, NewFD, Previous); @@ -6758,6 +7446,35 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, } } + // Check for a previous extern "C" declaration with this name. + if (!Redeclaration && + checkForConflictWithNonVisibleExternC(*this, NewFD, Previous)) { + filterNonConflictingPreviousDecls(Context, NewFD, Previous); + if (!Previous.empty()) { + // This is an extern "C" declaration with the same name as a previous + // declaration, and thus redeclares that entity... + Redeclaration = true; + OldDecl = Previous.getFoundDecl(); + MergeTypeWithPrevious = false; + + // ... except in the presence of __attribute__((overloadable)). + if (OldDecl->hasAttr<OverloadableAttr>()) { + if (!getLangOpts().CPlusPlus && !NewFD->hasAttr<OverloadableAttr>()) { + Diag(NewFD->getLocation(), diag::err_attribute_overloadable_missing) + << Redeclaration << NewFD; + Diag(Previous.getFoundDecl()->getLocation(), + diag::note_attribute_overloadable_prev_overload); + NewFD->addAttr(::new (Context) OverloadableAttr(SourceLocation(), + Context)); + } + if (IsOverload(NewFD, cast<FunctionDecl>(OldDecl), false)) { + Redeclaration = false; + OldDecl = 0; + } + } + } + } + // C++11 [dcl.constexpr]p8: // A constexpr specifier for a non-static member function that is not // a constructor declares that member function to be const. @@ -6781,9 +7498,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); EPI.TypeQuals |= Qualifiers::Const; MD->setType(Context.getFunctionType(FPT->getResultType(), - ArrayRef<QualType>(FPT->arg_type_begin(), - FPT->getNumArgs()), - EPI)); + FPT->getArgTypes(), 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. @@ -6802,7 +7517,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, if (Redeclaration) { // NewFD and OldDecl represent declarations that need to be // merged. - if (MergeFunctionDecl(NewFD, OldDecl, S)) { + if (MergeFunctionDecl(NewFD, OldDecl, S, MergeTypeWithPrevious)) { NewFD->setInvalidDecl(); return Redeclaration; } @@ -6850,7 +7565,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, // setNonKeyFunction needs to work with the original // declaration from the class definition, and isVirtual() is // just faster in that case, so map back to that now. - oldMethod = cast<CXXMethodDecl>(oldMethod->getFirstDeclaration()); + oldMethod = cast<CXXMethodDecl>(oldMethod->getFirstDecl()); if (oldMethod->isVirtual()) { Context.setNonKeyFunction(oldMethod); } @@ -6922,7 +7637,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, // during delayed parsing anyway. if (!CurContext->isRecord()) CheckCXXDefaultArguments(NewFD); - + // If this function declares a builtin function, check the type of this // declaration against the expected type for the builtin. if (unsigned BuiltinID = NewFD->getBuiltinID()) { @@ -6935,7 +7650,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, Context.BuiltinInfo.ForgetBuiltin(BuiltinID, Context.Idents); } } - + // If this function is declared as being extern "C", then check to see if // the function returns a UDT (class, struct, or union type) that is not C // compatible, and if it does, warn the user. @@ -6998,6 +7713,13 @@ void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) { FD->setConstexpr(false); } + if (getLangOpts().OpenCL) { + Diag(FD->getLocation(), diag::err_opencl_no_main) + << FD->hasAttr<OpenCLKernelAttr>(); + FD->setInvalidDecl(); + return; + } + QualType T = FD->getType(); assert(T->isFunctionType() && "function decl is not of function type"); const FunctionType* FT = T->castAs<FunctionType>(); @@ -7096,7 +7818,27 @@ void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) { } if (!FD->isInvalidDecl() && FD->getDescribedFunctionTemplate()) { - Diag(FD->getLocation(), diag::err_main_template_decl); + Diag(FD->getLocation(), diag::err_mainlike_template_decl) << FD->getName(); + FD->setInvalidDecl(); + } +} + +void Sema::CheckMSVCRTEntryPoint(FunctionDecl *FD) { + QualType T = FD->getType(); + assert(T->isFunctionType() && "function decl is not of function type"); + const FunctionType *FT = T->castAs<FunctionType>(); + + // 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()) + // 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(); FD->setInvalidDecl(); } } @@ -7313,7 +8055,6 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, RealDecl->setInvalidDecl(); return; } - ParenListExpr *CXXDirectInit = dyn_cast<ParenListExpr>(Init); // C++11 [decl.spec.auto]p6. Deduce the type which 'auto' stands in for. @@ -7326,14 +8067,17 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // It isn't possible to write this directly, but it is possible to // end up in this situation with "auto x(some_pack...);" Diag(CXXDirectInit->getLocStart(), - diag::err_auto_var_init_no_expression) + VDecl->isInitCapture() ? diag::err_init_capture_no_expression + : diag::err_auto_var_init_no_expression) << VDecl->getDeclName() << VDecl->getType() << VDecl->getSourceRange(); RealDecl->setInvalidDecl(); return; } else if (CXXDirectInit->getNumExprs() > 1) { Diag(CXXDirectInit->getExpr(1)->getLocStart(), - diag::err_auto_var_init_multiple_expressions) + VDecl->isInitCapture() + ? diag::err_init_capture_multiple_expressions + : diag::err_auto_var_init_multiple_expressions) << VDecl->getDeclName() << VDecl->getType() << VDecl->getSourceRange(); RealDecl->setInvalidDecl(); @@ -7385,8 +8129,11 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // If this is a redeclaration, check that the type we just deduced matches // the previously declared type. - if (VarDecl *Old = VDecl->getPreviousDecl()) - MergeVarDeclTypes(VDecl, Old, /*OldWasHidden*/ false); + if (VarDecl *Old = VDecl->getPreviousDecl()) { + // We never need to merge the type, because we cannot form an incomplete + // array of auto, nor deduce such a type. + MergeVarDeclTypes(VDecl, Old, /*MergeTypeWithPrevious*/false); + } // Check the deduced type is valid for a variable declaration. CheckVariableDeclarationType(VDecl); @@ -7576,9 +8323,20 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // C99 6.7.8p4: All the expressions in an initializer for an object that has // static storage duration shall be constant expressions or string literals. // C++ does not have this restriction. - if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl() && - VDecl->getStorageClass() == SC_Static) - CheckForConstantInitializer(Init, DclT); + if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl()) { + if (VDecl->getStorageClass() == SC_Static) + CheckForConstantInitializer(Init, DclT); + // C89 is stricter than C99 for non-static aggregate types. + // C89 6.5.7p3: All the expressions [...] in an initializer list + // for an object that has aggregate or union type shall be + // constant expressions. + else if (!getLangOpts().C99 && VDecl->getType()->isAggregateType() && + isa<InitListExpr>(Init) && + !Init->isConstantInitializer(Context, false)) + Diag(Init->getExprLoc(), + diag::ext_aggregate_init_not_constant) + << Init->getSourceRange(); + } } else if (VDecl->isStaticDataMember() && VDecl->getLexicalDeclContext()->isRecord()) { // This is an in-class initialization for a static data member, e.g., @@ -7679,7 +8437,8 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, if (VDecl->getStorageClass() == SC_Extern && (!getLangOpts().CPlusPlus || !(Context.getBaseElementType(VDecl->getType()).isConstQualified() || - VDecl->isExternC()))) + VDecl->isExternC())) && + !isTemplateInstantiation(VDecl->getTemplateSpecializationKind())) Diag(VDecl->getLocation(), diag::warn_extern_init); // C99 6.7.8p4. All file scoped initializers need to be constant. @@ -7817,7 +8576,7 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl, // declared with no linkage (C99 6.2.2p6), the type for the // object shall be complete. if (!Type->isDependentType() && Var->isLocalVarDecl() && - !Var->getLinkage() && !Var->isInvalidDecl() && + !Var->hasLinkage() && !Var->isInvalidDecl() && RequireCompleteType(Var->getLocation(), Type, diag::err_typecheck_decl_incomplete_type)) Var->setInvalidDecl(); @@ -7859,7 +8618,7 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl, // is accepted by gcc. Hence here we issue a warning instead of // an error and we do not invalidate the static declaration. // NOTE: to avoid multiple warnings, only check the first declaration. - if (Var->getPreviousDecl() == 0) + if (Var->isFirstDecl()) RequireCompleteType(Var->getLocation(), Type, diag::ext_typecheck_decl_incomplete_type); } @@ -8030,7 +8789,7 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { } if (var->isThisDeclarationADefinition() && - var->hasExternalLinkage() && + var->isExternallyVisible() && var->hasLinkage() && getDiagnostics().getDiagnosticLevel( diag::warn_missing_variable_declarations, var->getLocation())) { @@ -8091,10 +8850,16 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { if (IsGlobal && !var->isConstexpr() && getDiagnostics().getDiagnosticLevel(diag::warn_global_constructor, var->getLocation()) - != DiagnosticsEngine::Ignored && - !Init->isConstantInitializer(Context, baseType->isReferenceType())) - Diag(var->getLocation(), diag::warn_global_constructor) - << Init->getSourceRange(); + != DiagnosticsEngine::Ignored) { + // 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. + CXXRecordDecl *RD = baseType->getAsCXXRecordDecl(); + if (!(RD && !RD->hasTrivialDestructor()) && + !Init->isConstantInitializer(Context, baseType->isReferenceType())) + Diag(var->getLocation(), diag::warn_global_constructor) + << Init->getSourceRange(); + } if (var->isConstexpr()) { SmallVector<PartialDiagnosticAt, 8> Notes; @@ -8136,10 +8901,29 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) { if (!VD) return; + if (UsedAttr *Attr = VD->getAttr<UsedAttr>()) { + if (!Attr->isInherited() && !VD->isThisDeclarationADefinition()) { + Diag(Attr->getLocation(), diag::warn_attribute_ignored) << "used"; + VD->dropAttr<UsedAttr>(); + } + } + + if (!VD->isInvalidDecl() && + VD->isThisDeclarationADefinition() == VarDecl::TentativeDefinition) { + if (const VarDecl *Def = VD->getDefinition()) { + if (Def->hasAttr<AliasAttr>()) { + Diag(VD->getLocation(), diag::err_tentative_after_alias) + << VD->getDeclName(); + Diag(Def->getLocation(), diag::note_previous_definition); + VD->setInvalidDecl(); + } + } + } + const DeclContext *DC = VD->getDeclContext(); // If there's a #pragma GCC visibility in scope, and this isn't a class // member, set the visibility of this variable. - if (!DC->isRecord() && VD->hasExternalLinkage()) + if (!DC->isRecord() && VD->isExternallyVisible()) AddPushedVisibilityAttribute(VD); if (VD->isFileVarDecl()) @@ -8181,30 +8965,37 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) { } } -Sema::DeclGroupPtrTy -Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, - Decl **Group, unsigned NumDecls) { +Sema::DeclGroupPtrTy Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, + ArrayRef<Decl *> Group) { SmallVector<Decl*, 8> Decls; if (DS.isTypeSpecOwned()) Decls.push_back(DS.getRepAsDecl()); - for (unsigned i = 0; i != NumDecls; ++i) - if (Decl *D = Group[i]) + DeclaratorDecl *FirstDeclaratorInGroup = 0; + for (unsigned i = 0, e = Group.size(); i != e; ++i) + if (Decl *D = Group[i]) { + if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) + if (!FirstDeclaratorInGroup) + FirstDeclaratorInGroup = DD; Decls.push_back(D); + } - if (DeclSpec::isDeclRep(DS.getTypeSpecType())) - if (const TagDecl *Tag = dyn_cast_or_null<TagDecl>(DS.getRepAsDecl())) - getASTContext().addUnnamedTag(Tag); + if (DeclSpec::isDeclRep(DS.getTypeSpecType())) { + if (TagDecl *Tag = dyn_cast_or_null<TagDecl>(DS.getRepAsDecl())) { + HandleTagNumbering(*this, Tag); + if (!Tag->hasNameForLinkage() && !Tag->hasDeclaratorForAnonDecl()) + Tag->setDeclaratorForAnonDecl(FirstDeclaratorInGroup); + } + } - return BuildDeclaratorGroup(Decls.data(), Decls.size(), - DS.containsPlaceholderType()); + return BuildDeclaratorGroup(Decls, DS.containsPlaceholderType()); } /// BuildDeclaratorGroup - convert a list of declarations into a declaration /// group, performing any necessary semantic checking. Sema::DeclGroupPtrTy -Sema::BuildDeclaratorGroup(Decl **Group, unsigned NumDecls, +Sema::BuildDeclaratorGroup(llvm::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 @@ -8213,11 +9004,11 @@ Sema::BuildDeclaratorGroup(Decl **Group, unsigned NumDecls, // between the deduced type U and the deduced type which 'auto' stands for. // auto a = 0, b = { 1, 2, 3 }; // is legal because the deduced type U is 'int' in both cases. - if (TypeMayContainAuto && NumDecls > 1) { + if (TypeMayContainAuto && Group.size() > 1) { QualType Deduced; CanQualType DeducedCanon; VarDecl *DeducedDecl = 0; - for (unsigned i = 0; i != NumDecls; ++i) { + for (unsigned i = 0, e = Group.size(); i != e; ++i) { if (VarDecl *D = dyn_cast<VarDecl>(Group[i])) { AutoType *AT = D->getType()->getContainedAutoType(); // Don't reissue diagnostics when instantiating a template. @@ -8246,18 +9037,19 @@ Sema::BuildDeclaratorGroup(Decl **Group, unsigned NumDecls, } } - ActOnDocumentableDecls(Group, NumDecls); + ActOnDocumentableDecls(Group); - return DeclGroupPtrTy::make(DeclGroupRef::Create(Context, Group, NumDecls)); + return DeclGroupPtrTy::make( + DeclGroupRef::Create(Context, Group.data(), Group.size())); } void Sema::ActOnDocumentableDecl(Decl *D) { - ActOnDocumentableDecls(&D, 1); + ActOnDocumentableDecls(D); } -void Sema::ActOnDocumentableDecls(Decl **Group, unsigned NumDecls) { +void Sema::ActOnDocumentableDecls(ArrayRef<Decl *> Group) { // Don't parse the comment if Doxygen diagnostics are ignored. - if (NumDecls == 0 || !Group[0]) + if (Group.empty() || !Group[0]) return; if (Diags.getDiagnosticLevel(diag::warn_doc_param_not_found, @@ -8265,9 +9057,9 @@ void Sema::ActOnDocumentableDecls(Decl **Group, unsigned NumDecls) { == DiagnosticsEngine::Ignored) return; - if (NumDecls >= 2) { + if (Group.size() >= 2) { // This is a decl group. Normally it will contain only declarations - // procuded from declarator list. But in case we have any definitions or + // produced from declarator list. But in case we have any definitions or // additional declaration references: // 'typedef struct S {} S;' // 'typedef struct S *S;' @@ -8275,8 +9067,7 @@ void Sema::ActOnDocumentableDecls(Decl **Group, unsigned NumDecls) { // FinalizeDeclaratorGroup adds these as separate declarations. Decl *MaybeTagDecl = Group[0]; if (MaybeTagDecl && isa<TagDecl>(MaybeTagDecl)) { - Group++; - NumDecls--; + Group = Group.slice(1); } } @@ -8291,7 +9082,7 @@ void Sema::ActOnDocumentableDecls(Decl **Group, unsigned NumDecls) { // declaration, but also comments that *follow* the declaration -- thanks to // the lookahead in the lexer: we've consumed the semicolon and looked // ahead through comments. - for (unsigned i = 0; i != NumDecls; ++i) + for (unsigned i = 0, e = Group.size(); i != e; ++i) Context.getCommentForDecl(Group[i], &PP); } } @@ -8302,6 +9093,7 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { const DeclSpec &DS = D.getDeclSpec(); // Verify C99 6.7.5.3p2: The only SCS allowed is 'register'. + // C++03 [dcl.stc]p2 also permits 'auto'. VarDecl::StorageClass StorageClass = SC_None; if (DS.getStorageClassSpec() == DeclSpec::SCS_register) { @@ -8614,38 +9406,90 @@ static bool ShouldWarnAboutMissingPrototype(const FunctionDecl *FD, // Don't warn for OpenCL kernels. if (FD->hasAttr<OpenCLKernelAttr>()) return false; - + bool MissingPrototype = true; for (const FunctionDecl *Prev = FD->getPreviousDecl(); Prev; Prev = Prev->getPreviousDecl()) { // Ignore any declarations that occur in function or method // scope, because they aren't visible from the header. - if (Prev->getDeclContext()->isFunctionOrMethod()) + if (Prev->getLexicalDeclContext()->isFunctionOrMethod()) continue; - + MissingPrototype = !Prev->getType()->isFunctionProtoType(); if (FD->getNumParams() == 0) PossibleZeroParamPrototype = Prev; break; } - + return MissingPrototype; } -void Sema::CheckForFunctionRedefinition(FunctionDecl *FD) { +void +Sema::CheckForFunctionRedefinition(FunctionDecl *FD, + const FunctionDecl *EffectiveDefinition) { // Don't complain if we're in GNU89 mode and the previous definition // was an extern inline function. - const FunctionDecl *Definition; - if (FD->isDefined(Definition) && - !canRedefineFunction(Definition, getLangOpts())) { - if (getLangOpts().GNUMode && Definition->isInlineSpecified() && - Definition->getStorageClass() == SC_Extern) - Diag(FD->getLocation(), diag::err_redefinition_extern_inline) + const FunctionDecl *Definition = EffectiveDefinition; + if (!Definition) + if (!FD->isDefined(Definition)) + return; + + if (canRedefineFunction(Definition, getLangOpts())) + return; + + if (getLangOpts().GNUMode && Definition->isInlineSpecified() && + Definition->getStorageClass() == SC_Extern) + Diag(FD->getLocation(), diag::err_redefinition_extern_inline) << FD->getDeclName() << getLangOpts().CPlusPlus; - else - Diag(FD->getLocation(), diag::err_redefinition) << FD->getDeclName(); - Diag(Definition->getLocation(), diag::note_previous_definition); - FD->setInvalidDecl(); + else + Diag(FD->getLocation(), diag::err_redefinition) << FD->getDeclName(); + + Diag(Definition->getLocation(), diag::note_previous_definition); + FD->setInvalidDecl(); +} + + +static void RebuildLambdaScopeInfo(CXXMethodDecl *CallOperator, + Sema &S) { + CXXRecordDecl *const LambdaClass = CallOperator->getParent(); + + LambdaScopeInfo *LSI = S.PushLambdaScope(); + LSI->CallOperator = CallOperator; + LSI->Lambda = LambdaClass; + LSI->ReturnType = CallOperator->getResultType(); + const LambdaCaptureDefault LCD = LambdaClass->getLambdaCaptureDefault(); + + if (LCD == LCD_None) + LSI->ImpCaptureStyle = CapturingScopeInfo::ImpCap_None; + else if (LCD == LCD_ByCopy) + LSI->ImpCaptureStyle = CapturingScopeInfo::ImpCap_LambdaByval; + else if (LCD == LCD_ByRef) + LSI->ImpCaptureStyle = CapturingScopeInfo::ImpCap_LambdaByref; + DeclarationNameInfo DNI = CallOperator->getNameInfo(); + + LSI->IntroducerRange = DNI.getCXXOperatorNameRange(); + LSI->Mutable = !CallOperator->isConst(); + + // 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(); + if (VD->isInitCapture()) + S.CurrentInstantiationScope->InstantiatedLocal(VD, VD); + QualType CaptureType = VD->getType(); + 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); + } } } @@ -8661,9 +9505,24 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { FD = FunTmpl->getTemplatedDecl(); else FD = cast<FunctionDecl>(D); - - // Enter a new function scope - PushFunctionScope(); + // If we are instantiating a generic lambda call operator, push + // a LambdaScopeInfo onto the function stack. But use the information + // that's already been calculated (ActOnLambdaExpr) to prime the current + // LambdaScopeInfo. + // When the template operator is being specialized, the LambdaScopeInfo, + // has to be properly restored so that tryCaptureVariable doesn't try + // and capture any new variables. In addition when calculating potential + // captures during transformation of nested lambdas, it is necessary to + // have the LSI properly restored. + if (isGenericLambdaCallOperatorSpecialization(FD)) { + assert(ActiveTemplateInstantiations.size() && + "There should be an active template instantiation on the stack " + "when instantiating a generic lambda!"); + RebuildLambdaScopeInfo(cast<CXXMethodDecl>(D), *this); + } + else + // Enter a new function scope + PushFunctionScope(); // See if this is a redefinition. if (!FD->isLateTemplateParsed()) @@ -8695,17 +9554,19 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { const FunctionDecl *PossibleZeroParamPrototype = 0; if (ShouldWarnAboutMissingPrototype(FD, PossibleZeroParamPrototype)) { Diag(FD->getLocation(), diag::warn_missing_prototype) << FD; - + if (PossibleZeroParamPrototype) { - // We found a declaration that is not a prototype, + // We found a declaration that is not a prototype, // but that could be a zero-parameter prototype - TypeSourceInfo* TI = PossibleZeroParamPrototype->getTypeSourceInfo(); - TypeLoc TL = TI->getTypeLoc(); - if (FunctionNoProtoTypeLoc FTL = TL.getAs<FunctionNoProtoTypeLoc>()) - Diag(PossibleZeroParamPrototype->getLocation(), - diag::note_declaration_not_a_prototype) - << PossibleZeroParamPrototype - << FixItHint::CreateInsertion(FTL.getRParenLoc(), "void"); + if (TypeSourceInfo *TI = + PossibleZeroParamPrototype->getTypeSourceInfo()) { + TypeLoc TL = TI->getTypeLoc(); + if (FunctionNoProtoTypeLoc FTL = TL.getAs<FunctionNoProtoTypeLoc>()) + Diag(PossibleZeroParamPrototype->getLocation(), + diag::note_declaration_not_a_prototype) + << PossibleZeroParamPrototype + << FixItHint::CreateInsertion(FTL.getRParenLoc(), "void"); + } } } @@ -8732,8 +9593,10 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { // If we had any tags defined in the function prototype, // introduce them into the function scope. if (FnBodyScope) { - for (llvm::ArrayRef<NamedDecl*>::iterator I = FD->getDeclsInPrototypeScope().begin(), - E = FD->getDeclsInPrototypeScope().end(); I != E; ++I) { + for (ArrayRef<NamedDecl *>::iterator + I = FD->getDeclsInPrototypeScope().begin(), + E = FD->getDeclsInPrototypeScope().end(); + I != E; ++I) { NamedDecl *D = *I; // Some of these decls (like enums) may have been pinned to the translation unit @@ -8852,7 +9715,9 @@ 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. - return !FD->isConstexpr(); + // 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(); } Decl *Sema::ActOnSkippedFunctionBody(Decl *Decl) { @@ -8882,26 +9747,29 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, if (FD) { FD->setBody(Body); - if (getLangOpts().CPlusPlus1y && !FD->isInvalidDecl() && - !FD->isDependentContext()) { - if (FD->getResultType()->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>()) { - Diag(dcl->getLocation(), diag::err_auto_fn_no_return_but_not_auto) - << FD->getResultType(); - FD->setInvalidDecl(); - } - Context.adjustDeducedFunctionResultType(FD, Context.VoidTy); + if (getLangOpts().CPlusPlus1y && !FD->isInvalidDecl() && Body && + !FD->isDependentContext() && FD->getResultType()->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>()) { + Diag(dcl->getLocation(), diag::err_auto_fn_no_return_but_not_auto) + << FD->getResultType(); + FD->setInvalidDecl(); + } else { + // Substitute 'void' for the 'auto' in the type. + TypeLoc ResultType = FD->getTypeSourceInfo()->getTypeLoc(). + IgnoreParens().castAs<FunctionProtoTypeLoc>().getResultLoc(); + Context.adjustDeducedFunctionResultType( + FD, SubstAutoType(ResultType.getType(), Context.VoidTy)); } } // The only way to be included in UndefinedButUsed is if there is an // ODR use before the definition. Avoid the expensive map lookup if this // is the first declaration. - if (FD->getPreviousDecl() != 0 && FD->getPreviousDecl()->isUsed()) { - if (FD->getLinkage() != ExternalLinkage) + if (!FD->isFirstDecl() && FD->getPreviousDecl()->isUsed()) { + if (!FD->isExternallyVisible()) UndefinedButUsed.erase(FD); else if (FD->isInlined() && (LangOpts.CPlusPlus || !LangOpts.GNUInline) && @@ -8916,7 +9784,7 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, // MSVC permits the use of pure specifier (=0) on function definition, // defined at class scope, warn about this non standard construct. - if (getLangOpts().MicrosoftExt && FD->isPure()) + if (getLangOpts().MicrosoftExt && FD->isPure() && FD->isCanonicalDecl()) Diag(FD->getLocation(), diag::warn_pure_function_definition); if (!FD->isInvalidDecl()) { @@ -9014,7 +9882,6 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, PopDeclContext(); PopFunctionScopeInfo(ActivePolicy, dcl); - // 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. @@ -9049,12 +9916,10 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, // function, see whether there was a locally-scoped declaration of // this name as a function or variable. If so, use that // (non-visible) declaration, and complain about it. - llvm::DenseMap<DeclarationName, NamedDecl *>::iterator Pos - = findLocallyScopedExternCDecl(&II); - if (Pos != LocallyScopedExternCDecls.end()) { - Diag(Loc, diag::warn_use_out_of_scope_declaration) << Pos->second; - Diag(Pos->second->getLocation(), diag::note_previous_declaration); - return Pos->second; + if (NamedDecl *ExternCPrev = findLocallyScopedExternCDecl(&II)) { + Diag(Loc, diag::warn_use_out_of_scope_declaration) << ExternCPrev; + Diag(ExternCPrev->getLocation(), diag::note_previous_declaration); + return ExternCPrev; } // Extension in C99. Legal in C90, but warn about it. @@ -9073,19 +9938,9 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, TypoCorrection Corrected; DeclFilterCCC<FunctionDecl> Validator; if (S && (Corrected = CorrectTypo(DeclarationNameInfo(&II, Loc), - LookupOrdinaryName, S, 0, Validator))) { - std::string CorrectedStr = Corrected.getAsString(getLangOpts()); - std::string CorrectedQuotedStr = Corrected.getQuoted(getLangOpts()); - FunctionDecl *Func = Corrected.getCorrectionDeclAs<FunctionDecl>(); - - Diag(Loc, diag::note_function_suggestion) << CorrectedQuotedStr - << FixItHint::CreateReplacement(Loc, CorrectedStr); - - if (Func->getLocation().isValid() - && !II.getName().startswith("__builtin_")) - Diag(Func->getLocation(), diag::note_previous_decl) - << CorrectedQuotedStr; - } + LookupOrdinaryName, S, 0, Validator))) + diagnoseTypo(Corrected, PDiag(diag::note_function_suggestion), + /*ErrorRecovery*/false); } // Set a Declarator for the implicit definition: int foo(); @@ -9164,7 +10019,8 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { FD->getParamDecl(FormatIdx)->getType()->isObjCObjectPointerType()) fmt = "NSString"; FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context, - fmt, FormatIdx+1, + &Context.Idents.get(fmt), + FormatIdx+1, HasVAListArg ? 0 : FormatIdx+2)); } } @@ -9172,7 +10028,8 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { HasVAListArg)) { if (!FD->getAttr<FormatAttr>()) FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context, - "scanf", FormatIdx+1, + &Context.Idents.get("scanf"), + FormatIdx+1, HasVAListArg ? 0 : FormatIdx+2)); } @@ -9212,7 +10069,7 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { // target-specific builtins, perhaps? if (!FD->getAttr<FormatAttr>()) FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context, - "printf", 2, + &Context.Idents.get("printf"), 2, Name->isStr("vasprintf") ? 0 : 3)); } @@ -9246,7 +10103,7 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T, NewTD->setInvalidDecl(); return NewTD; } - + if (D.getDeclSpec().isModulePrivateSpecified()) { if (CurContext->isFunctionOrMethod()) Diag(NewTD->getLocation(), diag::err_module_private_local) @@ -9497,13 +10354,10 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // for non-C++ cases. if (TemplateParameterLists.size() > 0 || (SS.isNotEmpty() && TUK != TUK_Reference)) { - if (TemplateParameterList *TemplateParams - = MatchTemplateParametersToScopeSpecifier(KWLoc, NameLoc, SS, - TemplateParameterLists.data(), - TemplateParameterLists.size(), - TUK == TUK_Friend, - isExplicitSpecialization, - Invalid)) { + if (TemplateParameterList *TemplateParams = + MatchTemplateParametersToScopeSpecifier( + KWLoc, NameLoc, SS, TemplateParameterLists, TUK == TUK_Friend, + isExplicitSpecialization, Invalid)) { if (Kind == TTK_Enum) { Diag(KWLoc, diag::err_enum_template); return 0; @@ -9572,7 +10426,7 @@ 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'). @@ -9665,8 +10519,11 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, while (F.hasNext()) { NamedDecl *ND = F.next(); DeclContext *DC = ND->getDeclContext()->getRedeclContext(); - if (DC->isFileContext() && !EnclosingNS->Encloses(ND->getDeclContext())) + if (DC->isFileContext() && + !EnclosingNS->Encloses(ND->getDeclContext())) { F.erase(); + FriendSawTagOutsideEnclosingNamespace = true; + } } F.done(); } @@ -9757,8 +10614,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, (getLangOpts().CPlusPlus && S->isFunctionPrototypeScope()) || ((S->getFlags() & Scope::DeclScope) == 0) || - (S->getEntity() && - ((DeclContext *)S->getEntity())->isTransparentContext())) + (S->getEntity() && S->getEntity()->isTransparentContext())) S = S->getParent(); } else { assert(TUK == TUK_Friend); @@ -9865,6 +10721,16 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, return TUK == TUK_Declaration ? PrevTagDecl : 0; } + // C++11 [class.mem]p1: + // A member shall not be declared twice in the member-specification, + // except that a nested class or member class template can be declared + // and then later defined. + if (TUK == TUK_Declaration && PrevDecl->isCXXClassMember() && + S->isDeclScope(PrevDecl)) { + Diag(NameLoc, diag::ext_member_redeclared); + Diag(PrevTagDecl->getLocation(), diag::note_previous_declaration); + } + if (!Invalid) { // If this is a use, just return the declaration we found. @@ -10155,7 +11021,7 @@ CreateNewDecl: // declaration so we always pass true to setObjectOfFriendDecl to make // the tag name visible. if (TUK == TUK_Friend) - New->setObjectOfFriendDecl(/* PreviouslyDeclared = */ !Previous.empty() || + New->setObjectOfFriendDecl(!FriendSawTagOutsideEnclosingNamespace && getLangOpts().MicrosoftExt); // Set the access specifier. @@ -10239,6 +11105,7 @@ Decl *Sema::ActOnObjCContainerStartDefinition(Decl *IDecl) { void Sema::ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagD, SourceLocation FinalLoc, + bool IsFinalSpelledSealed, SourceLocation LBraceLoc) { AdjustDeclIfTemplate(TagD); CXXRecordDecl *Record = cast<CXXRecordDecl>(TagD); @@ -10249,8 +11116,9 @@ void Sema::ActOnStartCXXMemberDeclarations(Scope *S, Decl *TagD, return; if (FinalLoc.isValid()) - Record->addAttr(new (Context) FinalAttr(FinalLoc, Context)); - + Record->addAttr(new (Context) + FinalAttr(FinalLoc, Context, IsFinalSpelledSealed)); + // C++ [class]p2: // [...] The class-name is also inserted into the scope of the // class itself; this is known as the injected-class-name. For @@ -10337,8 +11205,8 @@ void Sema::ActOnTagDefinitionError(Scope *S, Decl *TagD) { // Note that FieldName may be null for anonymous bitfields. ExprResult Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName, - QualType FieldTy, Expr *BitWidth, - bool *ZeroWidth) { + QualType FieldTy, bool IsMsStruct, + Expr *BitWidth, bool *ZeroWidth) { // Default to true; that shouldn't confuse checks for emptiness if (ZeroWidth) *ZeroWidth = true; @@ -10387,7 +11255,7 @@ ExprResult Sema::VerifyBitField(SourceLocation FieldLoc, if (!FieldTy->isDependentType()) { uint64_t TypeSize = Context.getTypeSize(FieldTy); if (Value.getZExtValue() > TypeSize) { - if (!getLangOpts().CPlusPlus) { + if (!getLangOpts().CPlusPlus || IsMsStruct) { if (FieldName) return Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_size) << FieldName << (unsigned)Value.getZExtValue() @@ -10605,7 +11473,8 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, bool ZeroWidth = false; // If this is declared as a bit-field, check the bit-field. if (!InvalidDecl && BitWidth) { - BitWidth = VerifyBitField(Loc, II, T, BitWidth, &ZeroWidth).take(); + BitWidth = VerifyBitField(Loc, II, T, Record->isMsStruct(Context), BitWidth, + &ZeroWidth).take(); if (!BitWidth) { InvalidDecl = true; BitWidth = 0; @@ -10658,11 +11527,15 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, } // C++ [class.union]p1: If a union contains a member of reference type, - // the program is ill-formed. + // the program is ill-formed, except when compiling with MSVC extensions + // enabled. if (EltTy->isReferenceType()) { - Diag(NewFD->getLocation(), diag::err_union_member_of_reference_type) + Diag(NewFD->getLocation(), getLangOpts().MicrosoftExt ? + diag::ext_union_member_of_reference_type : + diag::err_union_member_of_reference_type) << NewFD->getDeclName() << EltTy; - NewFD->setInvalidDecl(); + if (!getLangOpts().MicrosoftExt) + NewFD->setInvalidDecl(); } } } @@ -10693,8 +11566,8 @@ bool Sema::CheckNontrivialField(FieldDecl *FD) { assert(FD); assert(getLangOpts().CPlusPlus && "valid check only for C++"); - if (FD->isInvalidDecl()) - return true; + if (FD->isInvalidDecl() || FD->getType()->isDependentType()) + return false; QualType EltTy = Context.getBaseElementType(FD->getType()); if (const RecordType *RT = EltTy->getAs<RecordType>()) { @@ -10782,7 +11655,7 @@ Decl *Sema::ActOnIvar(Scope *S, if (BitWidth) { // 6.7.2.1p3, 6.7.2.1p4 - BitWidth = VerifyBitField(Loc, II, T, BitWidth).take(); + BitWidth = VerifyBitField(Loc, II, T, /*IsMsStruct*/false, BitWidth).take(); if (!BitWidth) D.setInvalidType(); } else { @@ -10912,11 +11785,9 @@ void Sema::ActOnLastBitfield(SourceLocation DeclLoc, AllIvarDecls.push_back(Ivar); } -void Sema::ActOnFields(Scope* S, - SourceLocation RecLoc, Decl *EnclosingDecl, - llvm::ArrayRef<Decl *> Fields, - SourceLocation LBrac, SourceLocation RBrac, - AttributeList *Attr) { +void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, + ArrayRef<Decl *> Fields, SourceLocation LBrac, + SourceLocation RBrac, AttributeList *Attr) { assert(EnclosingDecl && "missing record or interface decl"); // If this is an Objective-C @implementation or category and we have @@ -10954,7 +11825,7 @@ void Sema::ActOnFields(Scope* S, SmallVector<FieldDecl*, 32> RecFields; bool ARCErrReported = false; - for (llvm::ArrayRef<Decl *>::iterator i = Fields.begin(), end = Fields.end(); + for (ArrayRef<Decl *>::iterator i = Fields.begin(), end = Fields.end(); i != end; ++i) { FieldDecl *FD = cast<FieldDecl>(*i); @@ -10999,34 +11870,38 @@ void Sema::ActOnFields(Scope* S, // Microsoft and g++ is more permissive regarding flexible array. // It will accept flexible array in union and also // as the sole element of a struct/class. - if (getLangOpts().MicrosoftExt) { - if (Record->isUnion()) - Diag(FD->getLocation(), diag::ext_flexible_array_union_ms) - << FD->getDeclName(); - else if (Fields.size() == 1) - Diag(FD->getLocation(), diag::ext_flexible_array_empty_aggregate_ms) - << FD->getDeclName() << Record->getTagKind(); - } else if (getLangOpts().CPlusPlus) { - if (Record->isUnion()) - Diag(FD->getLocation(), diag::ext_flexible_array_union_gnu) - << FD->getDeclName(); - else if (Fields.size() == 1) - Diag(FD->getLocation(), diag::ext_flexible_array_empty_aggregate_gnu) - << FD->getDeclName() << Record->getTagKind(); - } else if (!getLangOpts().C99) { + unsigned DiagID = 0; if (Record->isUnion()) - Diag(FD->getLocation(), diag::ext_flexible_array_union_gnu) - << FD->getDeclName(); - else + DiagID = getLangOpts().MicrosoftExt + ? diag::ext_flexible_array_union_ms + : getLangOpts().CPlusPlus + ? diag::ext_flexible_array_union_gnu + : diag::err_flexible_array_union; + else if (Fields.size() == 1) + DiagID = getLangOpts().MicrosoftExt + ? diag::ext_flexible_array_empty_aggregate_ms + : getLangOpts().CPlusPlus + ? diag::ext_flexible_array_empty_aggregate_gnu + : NumNamedMembers < 1 + ? diag::err_flexible_array_empty_aggregate + : 0; + + if (DiagID) + Diag(FD->getLocation(), DiagID) << FD->getDeclName() + << Record->getTagKind(); + // While the layout of types that contain virtual bases is not specified + // by the C++ standard, both the Itanium and Microsoft C++ ABIs place + // virtual bases after the derived members. This would make a flexible + // array member declared at the end of an object not adjacent to the end + // of the type. + if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Record)) + if (RD->getNumVBases() != 0) + Diag(FD->getLocation(), diag::err_flexible_array_virtual_base) + << FD->getDeclName() << Record->getTagKind(); + if (!getLangOpts().C99) Diag(FD->getLocation(), diag::ext_c99_flexible_array_member) << FD->getDeclName() << Record->getTagKind(); - } else if (NumNamedMembers < 1) { - Diag(FD->getLocation(), diag::err_flexible_array_empty_struct) - << FD->getDeclName(); - FD->setInvalidDecl(); - EnclosingDecl->setInvalidDecl(); - continue; - } + if (!FD->getType()->isDependentType() && !Context.getBaseElementType(FD->getType()).isPODType(Context)) { Diag(FD->getLocation(), diag::err_flexible_array_has_nonpod_type) @@ -11141,10 +12016,18 @@ void Sema::ActOnFields(Scope* S, I.setAccess((*I)->getAccess()); if (!CXXRecord->isDependentType()) { - // Adjust user-defined destructor exception spec. - if (getLangOpts().CPlusPlus11 && - CXXRecord->hasUserDeclaredDestructor()) - AdjustDestructorExceptionSpec(CXXRecord,CXXRecord->getDestructor()); + if (CXXRecord->hasUserDeclaredDestructor()) { + // Adjust user-defined destructor exception spec. + 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. AddImplicitlyDeclaredMembersToClass(CXXRecord); @@ -11197,6 +12080,59 @@ void Sema::ActOnFields(Scope* S, if (Record->hasAttrs()) CheckAlignasUnderalignment(Record); + + // 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. + bool CheckForZeroSize; + if (!getLangOpts().CPlusPlus) { + CheckForZeroSize = true; + } else { + // For C++ filter out types that cannot be referenced in C code. + CXXRecordDecl *CXXRecord = cast<CXXRecordDecl>(Record); + CheckForZeroSize = + CXXRecord->getLexicalDeclContext()->isExternCContext() && + !CXXRecord->isDependentType() && + CXXRecord->isCLike(); + } + if (CheckForZeroSize) { + bool ZeroSize = true; + bool IsEmpty = true; + unsigned NonBitFields = 0; + for (RecordDecl::field_iterator I = Record->field_begin(), + E = Record->field_end(); + (NonBitFields == 0 || ZeroSize) && I != E; ++I) { + IsEmpty = false; + if (I->isUnnamedBitfield()) { + if (I->getBitWidthValue(Context) > 0) + ZeroSize = false; + } else { + ++NonBitFields; + QualType FieldType = I->getType(); + if (FieldType->isIncompleteType() || + !Context.getTypeSizeInChars(FieldType).isZero()) + ZeroSize = false; + } + } + + // Empty structs are an extension in C (C99 6.7.2.1p7). They are + // allowed in C++, but warn if its declaration is inside + // extern "C" block. + if (ZeroSize) { + Diag(RecLoc, getLangOpts().CPlusPlus ? + diag::warn_zero_size_struct_union_in_extern_c : + diag::warn_zero_size_struct_union_compat) + << IsEmpty << Record->isUnion() << (NonBitFields > 1); + } + + // Structs without named members are extension in C (C99 6.7.2.1p7), + // but are accepted by GCC. + if (NonBitFields == 0 && !getLangOpts().CPlusPlus) { + Diag(RecLoc, IsEmpty ? diag::ext_empty_struct_union : + diag::ext_no_named_members_in_struct_union) + << Record->isUnion(); + } + } } else { ObjCIvarDecl **ClsFields = reinterpret_cast<ObjCIvarDecl**>(RecFields.data()); @@ -11991,6 +12927,12 @@ DeclResult Sema::ActOnModuleImport(SourceLocation AtLoc, return Import; } +void Sema::ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod) { + // FIXME: Should we synthesize an ImportDecl here? + PP.getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, DirectiveLoc, + /*Complain=*/true); +} + void Sema::createImplicitModuleImport(SourceLocation Loc, Module *Mod) { // Create the implicit import declaration. TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl(); |