diff options
author | dim <dim@FreeBSD.org> | 2013-04-08 18:45:10 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2013-04-08 18:45:10 +0000 |
commit | c72c57c9e9b69944e3e009cd5e209634839581d3 (patch) | |
tree | 4fc2f184c499d106f29a386c452b49e5197bf63d /lib/Sema/SemaDecl.cpp | |
parent | 5b20025c30d23d521e12c1f33ec8fa6b821952cd (diff) | |
download | FreeBSD-src-c72c57c9e9b69944e3e009cd5e209634839581d3.zip FreeBSD-src-c72c57c9e9b69944e3e009cd5e209634839581d3.tar.gz |
Vendor import of clang trunk r178860:
http://llvm.org/svn/llvm-project/cfe/trunk@178860
Diffstat (limited to 'lib/Sema/SemaDecl.cpp')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 2272 |
1 files changed, 1588 insertions, 684 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 0092d5d..adf3505 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -12,15 +12,11 @@ //===----------------------------------------------------------------------===// #include "clang/Sema/SemaInternal.h" -#include "clang/Sema/Initialization.h" -#include "clang/Sema/Lookup.h" -#include "clang/Sema/CXXFieldCollector.h" -#include "clang/Sema/Scope.h" -#include "clang/Sema/ScopeInfo.h" #include "TypeLocBuilder.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" #include "clang/AST/CXXInheritance.h" +#include "clang/AST/CharUnits.h" #include "clang/AST/CommentDiagnostic.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" @@ -28,18 +24,21 @@ #include "clang/AST/EvaluatedExprVisitor.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/StmtCXX.h" -#include "clang/AST/CharUnits.h" -#include "clang/Sema/DeclSpec.h" -#include "clang/Sema/ParsedTemplate.h" -#include "clang/Parse/ParseDiagnostic.h" #include "clang/Basic/PartialDiagnostic.h" -#include "clang/Sema/DelayedDiagnostic.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" -// FIXME: layering (ideally, Sema shouldn't be dependent on Lex API's) -#include "clang/Lex/Preprocessor.h" -#include "clang/Lex/HeaderSearch.h" -#include "clang/Lex/ModuleLoader.h" +#include "clang/Lex/HeaderSearch.h" // FIXME: Sema shouldn't depend on Lex +#include "clang/Lex/ModuleLoader.h" // FIXME: Sema shouldn't depend on Lex +#include "clang/Lex/Preprocessor.h" // FIXME: Sema shouldn't depend on Lex +#include "clang/Parse/ParseDiagnostic.h" +#include "clang/Sema/CXXFieldCollector.h" +#include "clang/Sema/DeclSpec.h" +#include "clang/Sema/DelayedDiagnostic.h" +#include "clang/Sema/Initialization.h" +#include "clang/Sema/Lookup.h" +#include "clang/Sema/ParsedTemplate.h" +#include "clang/Sema/Scope.h" +#include "clang/Sema/ScopeInfo.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Triple.h" #include <algorithm> @@ -677,9 +676,9 @@ Corrected: (isa<TypeDecl>(UnderlyingFirstDecl) || isa<ObjCInterfaceDecl>(UnderlyingFirstDecl) || isa<ObjCCompatibleAliasDecl>(UnderlyingFirstDecl))) { - UnqualifiedDiag = diag::err_unknown_typename_suggest; - QualifiedDiag = diag::err_unknown_nested_typename_suggest; - } + UnqualifiedDiag = diag::err_unknown_typename_suggest; + QualifiedDiag = diag::err_unknown_nested_typename_suggest; + } if (SS.isEmpty()) Diag(NameLoc, UnqualifiedDiag) @@ -1097,7 +1096,7 @@ void Sema::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) { bool Sema::isDeclInScope(NamedDecl *&D, DeclContext *Ctx, Scope *S, bool ExplicitInstantiationOrSpecialization) { - return IdResolver.isDeclInScope(D, Ctx, Context, S, + return IdResolver.isDeclInScope(D, Ctx, S, ExplicitInstantiationOrSpecialization); } @@ -1175,6 +1174,31 @@ static bool IsDisallowedCopyOrAssign(const CXXMethodDecl *D) { return false; } +// We need this to handle +// +// typedef struct { +// void *foo() { return 0; } +// } A; +// +// When we see foo we don't know if after the typedef we will get 'A' or '*A' +// for example. If 'A', foo will have external linkage. If we have '*A', +// foo will have no linkage. Since we can't know untill we get to the end +// of the typedef, this function finds out if D might have non external linkage. +// Callers should verify at the end of the TU if it D has external linkage or +// not. +bool Sema::mightHaveNonExternalLinkage(const DeclaratorDecl *D) { + const DeclContext *DC = D->getDeclContext(); + while (!DC->isTranslationUnit()) { + if (const RecordDecl *RD = dyn_cast<RecordDecl>(DC)){ + if (!RD->hasNameForLinkage()) + return true; + } + DC = DC->getParent(); + } + + return !D->hasExternalLinkage(); +} + bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const { assert(D); @@ -1224,10 +1248,7 @@ bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const { } // Only warn for unused decls internal to the translation unit. - if (D->getLinkage() == ExternalLinkage) - return false; - - return true; + return mightHaveNonExternalLinkage(D); } void Sema::MarkUnusedFileScopedDecl(const DeclaratorDecl *D) { @@ -1368,7 +1389,7 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { if (!D->getDeclName()) continue; // Diagnose unused variables in this scope. - if (!S->hasErrorOccurred()) + if (!S->hasUnrecoverableErrorOccurred()) DiagnoseUnusedDecl(D); // If this was a forward reference to a label, verify it was defined. @@ -1465,6 +1486,24 @@ Scope *Sema::getNonFieldDeclScope(Scope *S) { return S; } +/// \brief Looks up the declaration of "struct objc_super" and +/// saves it for later use in building builtin declaration of +/// objc_msgSendSuper and objc_msgSendSuper_stret. If no such +/// pre-existing declaration exists no action takes place. +static void LookupPredefedObjCSuperType(Sema &ThisSema, Scope *S, + IdentifierInfo *II) { + if (!II->isStr("objc_msgSendSuper")) + return; + ASTContext &Context = ThisSema.Context; + + LookupResult Result(ThisSema, &Context.Idents.get("objc_super"), + SourceLocation(), Sema::LookupTagName); + ThisSema.LookupName(Result, S); + if (Result.getResultKind() == LookupResult::Found) + if (const TagDecl *TD = Result.getAsSingle<TagDecl>()) + Context.setObjCSuperType(Context.getTagDeclType(TD)); +} + /// LazilyCreateBuiltin - The specified Builtin-ID was first used at /// file scope. lazily create a decl for it. ForRedeclaration is true /// if we're creating this built-in in anticipation of redeclaring the @@ -1472,6 +1511,8 @@ Scope *Sema::getNonFieldDeclScope(Scope *S) { NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, Scope *S, bool ForRedeclaration, SourceLocation Loc) { + LookupPredefedObjCSuperType(*this, S, II); + Builtin::ID BID = (Builtin::ID)bid; ASTContext::GetBuiltinTypeError Error; @@ -1516,7 +1557,7 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, Context.getTranslationUnitDecl(), Loc, Loc, II, R, /*TInfo=*/0, SC_Extern, - SC_None, false, + false, /*hasPrototype=*/true); New->setImplicit(); @@ -1529,7 +1570,7 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, ParmVarDecl::Create(Context, New, SourceLocation(), SourceLocation(), 0, FT->getArgType(i), /*TInfo=*/0, - SC_None, SC_None, 0); + SC_None, 0); parm->setScopeInfo(0, i); Params.push_back(parm); } @@ -1549,6 +1590,49 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, return New; } +/// \brief Filter out any previous declarations that the given declaration +/// should not consider because they are not permitted to conflict, e.g., +/// because they come from hidden sub-modules and do not refer to the same +/// entity. +static void filterNonConflictingPreviousDecls(ASTContext &context, + NamedDecl *decl, + LookupResult &previous){ + // This is only interesting when modules are enabled. + if (!context.getLangOpts().Modules) + return; + + // Empty sets are uninteresting. + if (previous.empty()) + return; + + LookupResult::Filter filter = previous.makeFilter(); + while (filter.hasNext()) { + NamedDecl *old = filter.next(); + + // Non-hidden declarations are never ignored. + if (!old->isHidden()) + continue; + + // If either has no-external linkage, ignore the old declaration. + // If this declaration would have external linkage if it were the first + // declaration of this name, then it may in fact be a redeclaration of + // some hidden declaration, so include those too. We don't need to worry + // about some previous visible declaration giving this declaration external + // linkage, because in that case, we'll mark this declaration as a redecl + // of the visible decl, and that decl will already be a redecl of the + // hidden declaration if that's appropriate. + // + // Don't cache this linkage computation, because it's not yet correct: we + // may later give this declaration a previous declaration which changes + // its linkage. + if (old->getLinkage() != ExternalLinkage || + !decl->hasExternalLinkageUncached()) + filter.erase(); + } + + filter.done(); +} + bool Sema::isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New) { QualType OldType; if (TypedefNameDecl *OldTypedef = dyn_cast<TypedefNameDecl>(Old)) @@ -1769,26 +1853,164 @@ DeclHasAttr(const Decl *D, const Attr *A) { return false; } -bool Sema::mergeDeclAttribute(Decl *D, InheritableAttr *Attr) { +static bool isAttributeTargetADefinition(Decl *D) { + if (VarDecl *VD = dyn_cast<VarDecl>(D)) + return VD->isThisDeclarationADefinition(); + if (TagDecl *TD = dyn_cast<TagDecl>(D)) + return TD->isCompleteDefinition() || TD->isBeingDefined(); + return true; +} + +/// Merge alignment attributes from \p Old to \p New, taking into account the +/// special semantics of C11's _Alignas specifier and C++11's alignas attribute. +/// +/// \return \c true if any attributes were added to \p New. +static bool mergeAlignedAttrs(Sema &S, NamedDecl *New, Decl *Old) { + // Look for alignas attributes on Old, and pick out whichever attribute + // specifies the strictest alignment requirement. + AlignedAttr *OldAlignasAttr = 0; + AlignedAttr *OldStrictestAlignAttr = 0; + unsigned OldAlign = 0; + for (specific_attr_iterator<AlignedAttr> + I = Old->specific_attr_begin<AlignedAttr>(), + E = Old->specific_attr_end<AlignedAttr>(); I != E; ++I) { + // FIXME: We have no way of representing inherited dependent alignments + // in a case like: + // template<int A, int B> struct alignas(A) X; + // template<int A, int B> struct alignas(B) X {}; + // For now, we just ignore any alignas attributes which are not on the + // definition in such a case. + if (I->isAlignmentDependent()) + return false; + + if (I->isAlignas()) + OldAlignasAttr = *I; + + unsigned Align = I->getAlignment(S.Context); + if (Align > OldAlign) { + OldAlign = Align; + OldStrictestAlignAttr = *I; + } + } + + // Look for alignas attributes on New. + AlignedAttr *NewAlignasAttr = 0; + unsigned NewAlign = 0; + for (specific_attr_iterator<AlignedAttr> + I = New->specific_attr_begin<AlignedAttr>(), + E = New->specific_attr_end<AlignedAttr>(); I != E; ++I) { + if (I->isAlignmentDependent()) + return false; + + if (I->isAlignas()) + NewAlignasAttr = *I; + + unsigned Align = I->getAlignment(S.Context); + if (Align > NewAlign) + NewAlign = Align; + } + + if (OldAlignasAttr && NewAlignasAttr && OldAlign != NewAlign) { + // Both declarations have 'alignas' attributes. We require them to match. + // C++11 [dcl.align]p6 and C11 6.7.5/7 both come close to saying this, but + // fall short. (If two declarations both have alignas, they must both match + // every definition, and so must match each other if there is a definition.) + + // If either declaration only contains 'alignas(0)' specifiers, then it + // specifies the natural alignment for the type. + if (OldAlign == 0 || NewAlign == 0) { + QualType Ty; + if (ValueDecl *VD = dyn_cast<ValueDecl>(New)) + Ty = VD->getType(); + else + Ty = S.Context.getTagDeclType(cast<TagDecl>(New)); + + if (OldAlign == 0) + OldAlign = S.Context.getTypeAlign(Ty); + if (NewAlign == 0) + NewAlign = S.Context.getTypeAlign(Ty); + } + + if (OldAlign != NewAlign) { + S.Diag(NewAlignasAttr->getLocation(), diag::err_alignas_mismatch) + << (unsigned)S.Context.toCharUnitsFromBits(OldAlign).getQuantity() + << (unsigned)S.Context.toCharUnitsFromBits(NewAlign).getQuantity(); + S.Diag(OldAlignasAttr->getLocation(), diag::note_previous_declaration); + } + } + + if (OldAlignasAttr && !NewAlignasAttr && isAttributeTargetADefinition(New)) { + // C++11 [dcl.align]p6: + // if any declaration of an entity has an alignment-specifier, + // every defining declaration of that entity shall specify an + // equivalent alignment. + // C11 6.7.5/7: + // If the definition of an object does not have an alignment + // specifier, any other declaration of that object shall also + // have no alignment specifier. + S.Diag(New->getLocation(), diag::err_alignas_missing_on_definition) + << OldAlignasAttr->isC11(); + S.Diag(OldAlignasAttr->getLocation(), diag::note_alignas_on_declaration) + << OldAlignasAttr->isC11(); + } + + bool AnyAdded = false; + + // Ensure we have an attribute representing the strictest alignment. + if (OldAlign > NewAlign) { + AlignedAttr *Clone = OldStrictestAlignAttr->clone(S.Context); + Clone->setInherited(true); + New->addAttr(Clone); + AnyAdded = true; + } + + // Ensure we have an alignas attribute if the old declaration had one. + if (OldAlignasAttr && !NewAlignasAttr && + !(AnyAdded && OldStrictestAlignAttr->isAlignas())) { + AlignedAttr *Clone = OldAlignasAttr->clone(S.Context); + Clone->setInherited(true); + New->addAttr(Clone); + AnyAdded = true; + } + + return AnyAdded; +} + +static bool mergeDeclAttribute(Sema &S, NamedDecl *D, InheritableAttr *Attr, + bool Override) { InheritableAttr *NewAttr = NULL; + unsigned AttrSpellingListIndex = Attr->getSpellingListIndex(); if (AvailabilityAttr *AA = dyn_cast<AvailabilityAttr>(Attr)) - NewAttr = mergeAvailabilityAttr(D, AA->getRange(), AA->getPlatform(), - AA->getIntroduced(), AA->getDeprecated(), - AA->getObsoleted(), AA->getUnavailable(), - AA->getMessage()); + NewAttr = S.mergeAvailabilityAttr(D, AA->getRange(), AA->getPlatform(), + AA->getIntroduced(), AA->getDeprecated(), + AA->getObsoleted(), AA->getUnavailable(), + AA->getMessage(), Override, + AttrSpellingListIndex); else if (VisibilityAttr *VA = dyn_cast<VisibilityAttr>(Attr)) - NewAttr = mergeVisibilityAttr(D, VA->getRange(), VA->getVisibility()); + NewAttr = S.mergeVisibilityAttr(D, VA->getRange(), VA->getVisibility(), + AttrSpellingListIndex); + else if (TypeVisibilityAttr *VA = dyn_cast<TypeVisibilityAttr>(Attr)) + NewAttr = S.mergeTypeVisibilityAttr(D, VA->getRange(), VA->getVisibility(), + AttrSpellingListIndex); else if (DLLImportAttr *ImportA = dyn_cast<DLLImportAttr>(Attr)) - NewAttr = mergeDLLImportAttr(D, ImportA->getRange()); + NewAttr = S.mergeDLLImportAttr(D, ImportA->getRange(), + AttrSpellingListIndex); else if (DLLExportAttr *ExportA = dyn_cast<DLLExportAttr>(Attr)) - NewAttr = mergeDLLExportAttr(D, ExportA->getRange()); + NewAttr = S.mergeDLLExportAttr(D, ExportA->getRange(), + AttrSpellingListIndex); else if (FormatAttr *FA = dyn_cast<FormatAttr>(Attr)) - NewAttr = mergeFormatAttr(D, FA->getRange(), FA->getType(), - FA->getFormatIdx(), FA->getFirstArg()); + NewAttr = S.mergeFormatAttr(D, FA->getRange(), FA->getType(), + FA->getFormatIdx(), FA->getFirstArg(), + AttrSpellingListIndex); else if (SectionAttr *SA = dyn_cast<SectionAttr>(Attr)) - NewAttr = mergeSectionAttr(D, SA->getRange(), SA->getName()); + NewAttr = S.mergeSectionAttr(D, SA->getRange(), SA->getName(), + AttrSpellingListIndex); + else if (isa<AlignedAttr>(Attr)) + // AlignedAttrs are handled separately, because we need to handle all + // such attributes on a declaration at the same time. + NewAttr = 0; else if (!DeclHasAttr(D, Attr)) - NewAttr = cast<InheritableAttr>(Attr->clone(Context)); + NewAttr = cast<InheritableAttr>(Attr->clone(S.Context)); if (NewAttr) { NewAttr->setInherited(true); @@ -1839,6 +2061,31 @@ static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) { ++I; continue; // regular attr merging will take care of validating this. } + + if (isa<C11NoReturnAttr>(NewAttribute)) { + // C's _Noreturn is allowed to be added to a function after it is defined. + ++I; + continue; + } else if (const AlignedAttr *AA = dyn_cast<AlignedAttr>(NewAttribute)) { + if (AA->isAlignas()) { + // C++11 [dcl.align]p6: + // if any declaration of an entity has an alignment-specifier, + // every defining declaration of that entity shall specify an + // equivalent alignment. + // C11 6.7.5/7: + // If the definition of an object does not have an alignment + // specifier, any other declaration of that object shall also + // have no alignment specifier. + S.Diag(Def->getLocation(), diag::err_alignas_missing_on_definition) + << AA->isC11(); + S.Diag(NewAttribute->getLocation(), diag::note_alignas_on_declaration) + << AA->isC11(); + NewAttributes.erase(NewAttributes.begin() + I); + --E; + continue; + } + } + S.Diag(NewAttribute->getLocation(), diag::warn_attribute_precede_definition); S.Diag(Def->getLocation(), diag::note_previous_definition); @@ -1848,8 +2095,11 @@ static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) { } /// mergeDeclAttributes - Copy attributes from the Old decl to the New one. -void Sema::mergeDeclAttributes(Decl *New, Decl *Old, - bool MergeDeprecation) { +void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old, + AvailabilityMergeKind AMK) { + if (!Old->hasAttrs() && !New->hasAttrs()) + return; + // attributes declared post-definition are currently ignored checkNewAttributesAfterDef(*this, New, Old); @@ -1866,17 +2116,31 @@ void Sema::mergeDeclAttributes(Decl *New, Decl *Old, i = Old->specific_attr_begin<InheritableAttr>(), e = Old->specific_attr_end<InheritableAttr>(); i != e; ++i) { + bool Override = false; // Ignore deprecated/unavailable/availability attributes if requested. - if (!MergeDeprecation && - (isa<DeprecatedAttr>(*i) || - isa<UnavailableAttr>(*i) || - isa<AvailabilityAttr>(*i))) - continue; + if (isa<DeprecatedAttr>(*i) || + isa<UnavailableAttr>(*i) || + isa<AvailabilityAttr>(*i)) { + switch (AMK) { + case AMK_None: + continue; - if (mergeDeclAttribute(New, *i)) + case AMK_Redeclaration: + break; + + case AMK_Override: + Override = true; + break; + } + } + + if (mergeDeclAttribute(*this, New, *i, Override)) foundAny = true; } + if (mergeAlignedAttrs(*this, New, Old)) + foundAny = true; + if (!foundAny) New->dropAttrs(); } @@ -1884,7 +2148,25 @@ void Sema::mergeDeclAttributes(Decl *New, Decl *Old, /// to the new one. static void mergeParamDeclAttributes(ParmVarDecl *newDecl, const ParmVarDecl *oldDecl, - ASTContext &C) { + Sema &S) { + // C++11 [dcl.attr.depend]p2: + // The first declaration of a function shall specify the + // carries_dependency attribute for its declarator-id if any declaration + // of the function specifies the carries_dependency attribute. + if (newDecl->hasAttr<CarriesDependencyAttr>() && + !oldDecl->hasAttr<CarriesDependencyAttr>()) { + S.Diag(newDecl->getAttr<CarriesDependencyAttr>()->getLocation(), + diag::err_carries_dependency_missing_on_first_decl) << 1/*Param*/; + // Find the first declaration of the parameter. + // FIXME: Should we build redeclaration chains for function parameters? + const FunctionDecl *FirstFD = + cast<FunctionDecl>(oldDecl->getDeclContext())->getFirstDeclaration(); + const ParmVarDecl *FirstVD = + FirstFD->getParamDecl(oldDecl->getFunctionScopeIndex()); + S.Diag(FirstVD->getLocation(), + diag::note_carries_dependency_missing_first_decl) << 1/*Param*/; + } + if (!oldDecl->hasAttrs()) return; @@ -1898,7 +2180,8 @@ static void mergeParamDeclAttributes(ParmVarDecl *newDecl, i = oldDecl->specific_attr_begin<InheritableParamAttr>(), e = oldDecl->specific_attr_end<InheritableParamAttr>(); i != e; ++i) { if (!DeclHasAttr(newDecl, *i)) { - InheritableAttr *newAttr = cast<InheritableParamAttr>((*i)->clone(C)); + InheritableAttr *newAttr = + cast<InheritableParamAttr>((*i)->clone(S.Context)); newAttr->setInherited(true); newDecl->addAttr(newAttr); foundAny = true; @@ -1966,6 +2249,22 @@ static bool isABIDefaultCC(Sema &S, CallingConv CC, FunctionDecl *D) { return ABIDefaultCC == CC; } +template <typename T> +static bool haveIncompatibleLanguageLinkages(const T *Old, const T *New) { + const DeclContext *DC = Old->getDeclContext(); + if (DC->isRecord()) + return false; + + LanguageLinkage OldLinkage = Old->getLanguageLinkage(); + if (OldLinkage == CXXLanguageLinkage && + New->getDeclContext()->isExternCContext()) + return true; + if (OldLinkage == CLanguageLinkage && + New->getDeclContext()->isExternCXXContext()) + return true; + return false; +} + /// MergeFunctionDecl - We just parsed a function 'New' from /// declarator D which has the same name and scope as a previous /// declaration 'Old'. Figure out how to resolve this situation, @@ -1987,6 +2286,15 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { Old = dyn_cast<FunctionDecl>(OldD); if (!Old) { if (UsingShadowDecl *Shadow = dyn_cast<UsingShadowDecl>(OldD)) { + if (New->getFriendObjectKind()) { + Diag(New->getLocation(), diag::err_using_decl_friend); + Diag(Shadow->getTargetDecl()->getLocation(), + diag::note_using_decl_target); + Diag(Shadow->getUsingDecl()->getLocation(), + diag::note_using_decl) << 0; + return true; + } + Diag(New->getLocation(), diag::err_using_decl_conflict_reverse); Diag(Shadow->getTargetDecl()->getLocation(), diag::note_using_decl_target); @@ -2016,9 +2324,12 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { // 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 && - Old->getStorageClass() != SC_Static && + isExternalLinkage(Old->getLinkage()) && + !New->getTemplateSpecializationInfo() && !canRedefineFunction(Old, getLangOpts())) { if (getLangOpts().MicrosoftExt) { Diag(New->getLocation(), diag::warn_static_non_static) << New; @@ -2060,9 +2371,10 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { RequiresAdjustment = true; // Don't complain about mismatches when the default CC is - // effectively the same as the explict one. + // 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(), New)) { + isABIDefaultCC(*this, NewTypeInfo.getCC(), Old)) { NewTypeInfo = NewTypeInfo.withCallingConv(OldTypeInfo.getCC()); RequiresAdjustment = true; @@ -2116,6 +2428,23 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { New->setType(QualType(NewType, 0)); NewQType = Context.getCanonicalType(New->getType()); } + + // If this redeclaration makes the function inline, we may need to add it to + // UndefinedButUsed. + if (!Old->isInlined() && New->isInlined() && + !New->hasAttr<GNUInlineAttr>() && + (getLangOpts().CPlusPlus || !getLangOpts().GNUInline) && + Old->isUsed(false) && + !Old->isDefined() && !New->isThisDeclarationADefinition()) + UndefinedButUsed.insert(std::make_pair(Old->getCanonicalDecl(), + SourceLocation())); + + // If this redeclaration makes it newly gnu_inline, we don't want to warn + // about it. + if (New->hasAttr<GNUInlineAttr>() && + Old->isInlined() && !Old->hasAttr<GNUInlineAttr>()) { + UndefinedButUsed.erase(Old->getCanonicalDecl()); + } if (getLangOpts().CPlusPlus) { // (C++98 13.1p2): @@ -2211,6 +2540,30 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { } } + // C++11 [dcl.attr.noreturn]p1: + // The first declaration of a function shall specify the noreturn + // attribute if any declaration of that function specifies the noreturn + // attribute. + if (New->hasAttr<CXX11NoReturnAttr>() && + !Old->hasAttr<CXX11NoReturnAttr>()) { + Diag(New->getAttr<CXX11NoReturnAttr>()->getLocation(), + diag::err_noreturn_missing_on_first_decl); + Diag(Old->getFirstDeclaration()->getLocation(), + diag::note_noreturn_missing_first_decl); + } + + // C++11 [dcl.attr.depend]p2: + // The first declaration of a function shall specify the + // carries_dependency attribute for its declarator-id if any declaration + // of the function specifies the carries_dependency attribute. + if (New->hasAttr<CarriesDependencyAttr>() && + !Old->hasAttr<CarriesDependencyAttr>()) { + Diag(New->getAttr<CarriesDependencyAttr>()->getLocation(), + diag::err_carries_dependency_missing_on_first_decl) << 0/*Function*/; + Diag(Old->getFirstDeclaration()->getLocation(), + diag::note_carries_dependency_missing_first_decl) << 0/*Function*/; + } + // (C++98 8.3.5p3): // All declarations for a function shall agree exactly in both the // return type and the parameter-type-list. @@ -2226,6 +2579,12 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { assert(OldQTypeForComparison.isCanonical()); } + if (haveIncompatibleLanguageLinkages(Old, New)) { + Diag(New->getLocation(), diag::err_different_language_linkage) << New; + Diag(Old->getLocation(), PrevDiag); + return true; + } + if (OldQTypeForComparison == NewQType) return MergeCompatibleFunctionDecls(New, Old, S); @@ -2247,7 +2606,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { SmallVector<QualType, 16> ParamTypes(OldProto->arg_type_begin(), OldProto->arg_type_end()); NewQType = Context.getFunctionType(NewFuncType->getResultType(), - ParamTypes.data(), ParamTypes.size(), + ParamTypes, OldProto->getExtProtoInfo()); New->setType(NewQType); New->setHasInheritedPrototype(); @@ -2262,7 +2621,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { SourceLocation(), SourceLocation(), 0, *ParamType, /*TInfo=*/0, - SC_None, SC_None, + SC_None, 0); Param->setScopeInfo(0, Params.size()); Param->setImplicit(); @@ -2330,8 +2689,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { diag::note_previous_declaration); } - New->setType(Context.getFunctionType(MergedReturn, &ArgTypes[0], - ArgTypes.size(), + New->setType(Context.getFunctionType(MergedReturn, ArgTypes, OldProto->getExtProtoInfo())); return MergeCompatibleFunctionDecls(New, Old, S); } @@ -2379,25 +2737,30 @@ bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old, // Merge the attributes mergeDeclAttributes(New, Old); - // Merge the storage class. - if (Old->getStorageClass() != SC_Extern && - Old->getStorageClass() != SC_None) - New->setStorageClass(Old->getStorageClass()); - // Merge "pure" flag. if (Old->isPure()) New->setPure(); + // Merge "used" flag. + if (Old->isUsed(false)) + New->setUsed(); + // Merge attributes from the parameters. These can mismatch with K&R // declarations. if (New->getNumParams() == Old->getNumParams()) for (unsigned i = 0, e = New->getNumParams(); i != e; ++i) mergeParamDeclAttributes(New->getParamDecl(i), Old->getParamDecl(i), - Context); + *this); if (getLangOpts().CPlusPlus) return MergeCXXFunctionDecl(New, Old, S); + // Merge the function types so the we get the composite types for the return + // and argument types. + QualType Merged = Context.mergeTypes(Old->getType(), New->getType()); + if (!Merged.isNull()) + New->setType(Merged); + return false; } @@ -2406,7 +2769,7 @@ void Sema::mergeObjCMethodDecls(ObjCMethodDecl *newMethod, ObjCMethodDecl *oldMethod) { // Merge the attributes, including deprecated/unavailable - mergeDeclAttributes(newMethod, oldMethod, /* mergeDeprecation */true); + mergeDeclAttributes(newMethod, oldMethod, AMK_Override); // Merge attributes from the parameters. ObjCMethodDecl::param_const_iterator oi = oldMethod->param_begin(), @@ -2414,9 +2777,9 @@ void Sema::mergeObjCMethodDecls(ObjCMethodDecl *newMethod, for (ObjCMethodDecl::param_iterator ni = newMethod->param_begin(), ne = newMethod->param_end(); ni != ne && oi != oe; ++ni, ++oi) - mergeParamDeclAttributes(*ni, *oi, Context); + mergeParamDeclAttributes(*ni, *oi, *this); - CheckObjCMethodOverride(newMethod, oldMethod, true); + CheckObjCMethodOverride(newMethod, oldMethod); } /// MergeVarDeclTypes - We parsed a variable 'New' which has the same name and @@ -2426,7 +2789,7 @@ 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) { +void Sema::MergeVarDeclTypes(VarDecl *New, VarDecl *Old, bool OldWasHidden) { if (New->isInvalidDecl() || Old->isInvalidDecl()) return; @@ -2447,19 +2810,17 @@ void Sema::MergeVarDeclTypes(VarDecl *New, VarDecl *Old) { // absence of a major array bound (8.3.4). else if (Old->getType()->isIncompleteArrayType() && New->getType()->isArrayType()) { - CanQual<ArrayType> OldArray - = Context.getCanonicalType(Old->getType())->getAs<ArrayType>(); - CanQual<ArrayType> NewArray - = Context.getCanonicalType(New->getType())->getAs<ArrayType>(); - if (OldArray->getElementType() == NewArray->getElementType()) + const ArrayType *OldArray = Context.getAsArrayType(Old->getType()); + const ArrayType *NewArray = Context.getAsArrayType(New->getType()); + if (Context.hasSameType(OldArray->getElementType(), + NewArray->getElementType())) MergedT = New->getType(); } else if (Old->getType()->isArrayType() && New->getType()->isIncompleteArrayType()) { - CanQual<ArrayType> OldArray - = Context.getCanonicalType(Old->getType())->getAs<ArrayType>(); - CanQual<ArrayType> NewArray - = Context.getCanonicalType(New->getType())->getAs<ArrayType>(); - if (OldArray->getElementType() == NewArray->getElementType()) + 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()) { @@ -2475,7 +2836,11 @@ void Sema::MergeVarDeclTypes(VarDecl *New, VarDecl *Old) { Diag(Old->getLocation(), diag::note_previous_definition); return New->setInvalidDecl(); } - New->setType(MergedT); + + // Don't actually update the type on the new declaration if the old + // declaration was a extern declaration in a different scope. + if (!OldWasHidden) + New->setType(MergedT); } /// MergeVarDecl - We just parsed a variable 'New' which has the same name @@ -2486,7 +2851,8 @@ void Sema::MergeVarDeclTypes(VarDecl *New, VarDecl *Old) { /// FinalizeDeclaratorGroup. Unfortunately, we can't analyze tentative /// definitions here, since the initializer hasn't been attached. /// -void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { +void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous, + bool PreviousWasHidden) { // If the new decl is already invalid, don't do any other checking. if (New->isInvalidDecl()) return; @@ -2526,13 +2892,14 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { } // Merge the types. - MergeVarDeclTypes(New, Old); + MergeVarDeclTypes(New, Old, PreviousWasHidden); if (New->isInvalidDecl()) return; - // C99 6.2.2p4: Check if we have a static decl followed by a non-static. + // [dcl.stc]p8: Check if we have a non-static decl followed by a static. if (New->getStorageClass() == SC_Static && - (Old->getStorageClass() == SC_None || Old->hasExternalStorage())) { + !New->isStaticDataMember() && + isExternalLinkage(Old->getLinkage())) { Diag(New->getLocation(), diag::err_static_non_static) << New->getDeclName(); Diag(Old->getLocation(), diag::note_previous_definition); return New->setInvalidDecl(); @@ -2548,8 +2915,9 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { // identifier has external linkage. if (New->hasExternalStorage() && Old->hasLinkage()) /* Okay */; - else if (New->getStorageClass() != SC_Static && - Old->getStorageClass() == SC_Static) { + else if (New->getCanonicalDecl()->getStorageClass() != SC_Static && + !New->isStaticDataMember() && + Old->getCanonicalDecl()->getStorageClass() == SC_Static) { Diag(New->getLocation(), diag::err_non_static_static) << New->getDeclName(); Diag(Old->getLocation(), diag::note_previous_definition); return New->setInvalidDecl(); @@ -2562,8 +2930,8 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { Diag(Old->getLocation(), diag::note_previous_definition); return New->setInvalidDecl(); } - if (Old->hasExternalStorage() && - !New->hasLinkage() && New->isLocalVarDecl()) { + if (Old->hasLinkage() && New->isLocalVarDecl() && + !New->hasExternalStorage()) { Diag(New->getLocation(), diag::err_non_extern_extern) << New->getDeclName(); Diag(Old->getLocation(), diag::note_previous_definition); return New->setInvalidDecl(); @@ -2601,17 +2969,17 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { New->setInvalidDecl(); return; } - // c99 6.2.2 P4. - // For an identifier declared with the storage-class specifier extern in a - // scope in which a prior declaration of that identifier is visible, if - // the prior declaration specifies internal or external linkage, the linkage - // of the identifier at the later declaration is the same as the linkage - // specified at the prior declaration. - // FIXME. revisit this code. - if (New->hasExternalStorage() && - Old->getLinkage() == InternalLinkage && - New->getDeclContext() == Old->getDeclContext()) - New->setStorageClass(Old->getStorageClass()); + + if (haveIncompatibleLanguageLinkages(Old, New)) { + Diag(New->getLocation(), diag::err_different_language_linkage) << New; + Diag(Old->getLocation(), diag::note_previous_definition); + New->setInvalidDecl(); + return; + } + + // Merge "used" flag. + if (Old->isUsed(false)) + New->setUsed(); // Keep a chain of previous declarations. New->setPreviousDeclaration(Old); @@ -2628,11 +2996,12 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, } /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with -/// no declarator (e.g. "struct foo;") is parsed. It also accopts template +/// no declarator (e.g. "struct foo;") is parsed. It also accepts template /// parameters to cope with template friend declarations. Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS, - MultiTemplateParamsArg TemplateParams) { + MultiTemplateParamsArg TemplateParams, + bool IsExplicitInstantiation) { Decl *TagD = 0; TagDecl *Tag = 0; if (DS.getTypeSpecType() == DeclSpec::TST_class || @@ -2655,6 +3024,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, } if (Tag) { + getASTContext().addUnnamedTag(Tag); Tag->setFreeStanding(); if (Tag->isInvalidDecl()) return Tag; @@ -2684,6 +3054,8 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, return TagD; } + DiagnoseFunctionSpecifiers(DS); + if (DS.isFriendSpecified()) { // If we're dealing with a decl but not a TagDecl, assume that // whatever routines created it handled the friendship aspect. @@ -2692,10 +3064,28 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, return ActOnFriendTypeDecl(S, DS, TemplateParams); } - // Track whether we warned about the fact that there aren't any - // declarators. - bool emittedWarning = false; - + CXXScopeSpec &SS = DS.getTypeSpecScope(); + bool IsExplicitSpecialization = + !TemplateParams.empty() && TemplateParams.back()->size() == 0; + if (Tag && SS.isNotEmpty() && !Tag->isCompleteDefinition() && + !IsExplicitInstantiation && !IsExplicitSpecialization) { + // Per C++ [dcl.type.elab]p1, a class declaration cannot have a + // nested-name-specifier unless it is an explicit instantiation + // or an explicit specialization. + // Per C++ [dcl.enum]p1, an opaque-enum-declaration can't either. + Diag(SS.getBeginLoc(), diag::err_standalone_class_nested_name_specifier) + << (DS.getTypeSpecType() == DeclSpec::TST_class ? 0 : + DS.getTypeSpecType() == DeclSpec::TST_struct ? 1 : + DS.getTypeSpecType() == DeclSpec::TST_interface ? 2 : + DS.getTypeSpecType() == DeclSpec::TST_union ? 3 : 4) + << SS.getRange(); + return 0; + } + + // Track whether this decl-specifier declares anything. + bool DeclaresAnything = true; + + // Handle anonymous struct definitions. if (RecordDecl *Record = dyn_cast_or_null<RecordDecl>(Tag)) { if (!Record->getDeclName() && Record->isCompleteDefinition() && DS.getStorageClassSpec() != DeclSpec::SCS_typedef) { @@ -2703,13 +3093,11 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, Record->getDeclContext()->isRecord()) return BuildAnonymousStructOrUnion(S, DS, AS, Record); - Diag(DS.getLocStart(), diag::ext_no_declarators) - << DS.getSourceRange(); - emittedWarning = true; + DeclaresAnything = false; } } - // Check for Microsoft C extension: anonymous struct. + // Check for Microsoft C extension: anonymous struct member. if (getLangOpts().MicrosoftExt && !getLangOpts().CPlusPlus && CurContext->isRecord() && DS.getStorageClassSpec() == DeclSpec::SCS_unspecified) { @@ -2726,70 +3114,82 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, return BuildMicrosoftCAnonymousStruct(S, DS, Record); } } - - if (getLangOpts().CPlusPlus && + + // Skip all the checks below if we have a type error. + if (DS.getTypeSpecType() == DeclSpec::TST_error || + (TagD && TagD->isInvalidDecl())) + return TagD; + + if (getLangOpts().CPlusPlus && DS.getStorageClassSpec() != DeclSpec::SCS_typedef) if (EnumDecl *Enum = dyn_cast_or_null<EnumDecl>(Tag)) if (Enum->enumerator_begin() == Enum->enumerator_end() && - !Enum->getIdentifier() && !Enum->isInvalidDecl()) { - Diag(Enum->getLocation(), diag::ext_no_declarators) - << DS.getSourceRange(); - emittedWarning = true; - } + !Enum->getIdentifier() && !Enum->isInvalidDecl()) + DeclaresAnything = false; - // Skip all the checks below if we have a type error. - if (DS.getTypeSpecType() == DeclSpec::TST_error) return TagD; - if (!DS.isMissingDeclaratorOk()) { - // Warn about typedefs of enums without names, since this is an - // extension in both Microsoft and GNU. - if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef && - Tag && isa<EnumDecl>(Tag)) { + // Customize diagnostic for a typedef missing a name. + if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) Diag(DS.getLocStart(), diag::ext_typedef_without_a_name) << DS.getSourceRange(); - return Tag; - } - - Diag(DS.getLocStart(), diag::ext_no_declarators) - << DS.getSourceRange(); - emittedWarning = true; + else + DeclaresAnything = false; } - // We're going to complain about a bunch of spurious specifiers; - // only do this if we're declaring a tag, because otherwise we - // should be getting diag::ext_no_declarators. - if (emittedWarning || (TagD && TagD->isInvalidDecl())) + if (DS.isModulePrivateSpecified() && + Tag && Tag->getDeclContext()->isFunctionOrMethod()) + Diag(DS.getModulePrivateSpecLoc(), diag::err_module_private_local_class) + << Tag->getTagKind() + << FixItHint::CreateRemoval(DS.getModulePrivateSpecLoc()); + + ActOnDocumentableDecl(TagD); + + // C 6.7/2: + // A declaration [...] shall declare at least a declarator [...], a tag, + // or the members of an enumeration. + // C++ [dcl.dcl]p3: + // [If there are no declarators], and except for the declaration of an + // unnamed bit-field, the decl-specifier-seq shall introduce one or more + // names into the program, or shall redeclare a name introduced by a + // previous declaration. + if (!DeclaresAnything) { + // In C, we allow this as a (popular) extension / bug. Don't bother + // producing further diagnostics for redundant qualifiers after this. + Diag(DS.getLocStart(), diag::ext_no_declarators) << DS.getSourceRange(); return TagD; + } + + // C++ [dcl.stc]p1: + // If a storage-class-specifier appears in a decl-specifier-seq, [...] the + // init-declarator-list of the declaration shall not be empty. + // C++ [dcl.fct.spec]p1: + // If a cv-qualifier appears in a decl-specifier-seq, the + // init-declarator-list of the declaration shall not be empty. + // + // Spurious qualifiers here appear to be valid in C. + unsigned DiagID = diag::warn_standalone_specifier; + if (getLangOpts().CPlusPlus) + DiagID = diag::ext_standalone_specifier; // Note that a linkage-specification sets a storage class, but // 'extern "C" struct foo;' is actually valid and not theoretically // useless. - if (DeclSpec::SCS scs = DS.getStorageClassSpec()) - if (!DS.isExternInLinkageSpec()) - Diag(DS.getStorageClassSpecLoc(), diag::warn_standalone_specifier) - << DeclSpec::getSpecifierName(scs); + if (DeclSpec::SCS SCS = DS.getStorageClassSpec()) + if (!DS.isExternInLinkageSpec() && SCS != DeclSpec::SCS_typedef) + Diag(DS.getStorageClassSpecLoc(), DiagID) + << DeclSpec::getSpecifierName(SCS); if (DS.isThreadSpecified()) - Diag(DS.getThreadSpecLoc(), diag::warn_standalone_specifier) << "__thread"; + Diag(DS.getThreadSpecLoc(), DiagID) << "__thread"; if (DS.getTypeQualifiers()) { if (DS.getTypeQualifiers() & DeclSpec::TQ_const) - Diag(DS.getConstSpecLoc(), diag::warn_standalone_specifier) << "const"; + Diag(DS.getConstSpecLoc(), DiagID) << "const"; if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile) - Diag(DS.getConstSpecLoc(), diag::warn_standalone_specifier) << "volatile"; + Diag(DS.getConstSpecLoc(), DiagID) << "volatile"; // Restrict is covered above. + if (DS.getTypeQualifiers() & DeclSpec::TQ_atomic) + Diag(DS.getAtomicSpecLoc(), DiagID) << "_Atomic"; } - if (DS.isInlineSpecified()) - Diag(DS.getInlineSpecLoc(), diag::warn_standalone_specifier) << "inline"; - if (DS.isVirtualSpecified()) - Diag(DS.getVirtualSpecLoc(), diag::warn_standalone_specifier) << "virtual"; - if (DS.isExplicitSpecified()) - Diag(DS.getExplicitSpecLoc(), diag::warn_standalone_specifier) <<"explicit"; - - if (DS.isModulePrivateSpecified() && - Tag && Tag->getDeclContext()->isFunctionOrMethod()) - Diag(DS.getModulePrivateSpecLoc(), diag::err_module_private_local_class) - << Tag->getTagKind() - << FixItHint::CreateRemoval(DS.getModulePrivateSpecLoc()); // Warn about ignored type attributes, for example: // __attribute__((aligned)) struct A; @@ -2814,8 +3214,6 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, } } - ActOnDocumentableDecl(TagD); - return TagD; } @@ -2950,25 +3348,6 @@ StorageClassSpecToVarDeclStorageClass(DeclSpec::SCS StorageClassSpec) { llvm_unreachable("unknown storage class specifier"); } -/// StorageClassSpecToFunctionDeclStorageClass - Maps a DeclSpec::SCS to -/// a StorageClass. Any error reporting is up to the caller: -/// illegal input values are mapped to SC_None. -static StorageClass -StorageClassSpecToFunctionDeclStorageClass(DeclSpec::SCS StorageClassSpec) { - switch (StorageClassSpec) { - case DeclSpec::SCS_unspecified: return SC_None; - case DeclSpec::SCS_extern: return SC_Extern; - case DeclSpec::SCS_static: return SC_Static; - case DeclSpec::SCS_private_extern: return SC_PrivateExtern; - // Illegal SCSs map to None: error reporting is up to the caller. - case DeclSpec::SCS_auto: // Fall through. - case DeclSpec::SCS_mutable: // Fall through. - case DeclSpec::SCS_register: // Fall through. - case DeclSpec::SCS_typedef: return SC_None; - } - llvm_unreachable("unknown storage class specifier"); -} - /// BuildAnonymousStructOrUnion - Handle the declaration of an /// anonymous structure or union. Anonymous unions are a C++ feature /// (C++ [class.union]) and a C11 feature; anonymous structures @@ -3027,18 +3406,23 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, if (DS.getTypeQualifiers()) { if (DS.getTypeQualifiers() & DeclSpec::TQ_const) Diag(DS.getConstSpecLoc(), diag::ext_anonymous_struct_union_qualified) - << Record->isUnion() << 0 + << Record->isUnion() << "const" << FixItHint::CreateRemoval(DS.getConstSpecLoc()); if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile) - Diag(DS.getVolatileSpecLoc(), + Diag(DS.getVolatileSpecLoc(), diag::ext_anonymous_struct_union_qualified) - << Record->isUnion() << 1 + << Record->isUnion() << "volatile" << FixItHint::CreateRemoval(DS.getVolatileSpecLoc()); if (DS.getTypeQualifiers() & DeclSpec::TQ_restrict) - Diag(DS.getRestrictSpecLoc(), + Diag(DS.getRestrictSpecLoc(), diag::ext_anonymous_struct_union_qualified) - << Record->isUnion() << 2 + << Record->isUnion() << "restrict" << FixItHint::CreateRemoval(DS.getRestrictSpecLoc()); + if (DS.getTypeQualifiers() & DeclSpec::TQ_atomic) + Diag(DS.getAtomicSpecLoc(), + diag::ext_anonymous_struct_union_qualified) + << Record->isUnion() << "_Atomic" + << FixItHint::CreateRemoval(DS.getAtomicSpecLoc()); DS.ClearTypeQualifiers(); } @@ -3088,6 +3472,13 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, << (int)Record->isUnion(); Invalid = true; } + } else { + // This is an anonymous type definition within another anonymous type. + // This is a popular extension, provided by Plan9, MSVC and GCC, but + // not part of standard C++. + Diag(MemRecord->getLocation(), + diag::ext_anonymous_record_with_anonymous_type) + << (int)Record->isUnion(); } } else if (isa<AccessSpecDecl>(*Mem)) { // Any access specifier is fine. @@ -3153,15 +3544,12 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, Invalid = true; SC = SC_None; } - SCSpec = DS.getStorageClassSpecAsWritten(); - VarDecl::StorageClass SCAsWritten - = StorageClassSpecToVarDeclStorageClass(SCSpec); Anon = VarDecl::Create(Context, Owner, DS.getLocStart(), Record->getLocation(), /*IdentifierInfo=*/0, Context.getTypeDeclType(Record), - TInfo, SC, SCAsWritten); + TInfo, SC); // Default-initialize the implicit variable. This initialization will be // trivial in almost all cases, except if a union member has an in-class @@ -3383,7 +3771,7 @@ static QualType getCoreType(QualType Ty) { static bool hasSimilarParameters(ASTContext &Context, FunctionDecl *Declaration, FunctionDecl *Definition, - llvm::SmallVectorImpl<unsigned> &Params) { + SmallVectorImpl<unsigned> &Params) { Params.clear(); if (Declaration->param_size() != Definition->param_size()) return false; @@ -3609,8 +3997,8 @@ bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC, return false; } -Decl *Sema::HandleDeclarator(Scope *S, Declarator &D, - MultiTemplateParamsArg TemplateParamLists) { +NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D, + MultiTemplateParamsArg TemplateParamLists) { // TODO: consider using NameInfo for diagnostic. DeclarationNameInfo NameInfo = GetNameForDeclarator(D); DeclarationName Name = NameInfo.getName(); @@ -3690,8 +4078,6 @@ Decl *Sema::HandleDeclarator(Scope *S, Declarator &D, if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) return 0; - NamedDecl *New; - TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); QualType R = TInfo->getType(); @@ -3776,6 +4162,13 @@ Decl *Sema::HandleDeclarator(Scope *S, Declarator &D, D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef) Previous.clear(); + // Check that there are no default arguments other than in the parameters + // of a function declaration (C++ only). + if (getLangOpts().CPlusPlus) + CheckExtraCXXDefaultArguments(D); + + NamedDecl *New; + bool AddToScope = true; if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) { if (TemplateParamLists.size()) { @@ -3877,29 +4270,29 @@ static QualType TryToFixInvalidVariablyModifiedType(QualType T, static void FixInvalidVariablyModifiedTypeLoc(TypeLoc SrcTL, TypeLoc DstTL) { - if (PointerTypeLoc* SrcPTL = dyn_cast<PointerTypeLoc>(&SrcTL)) { - PointerTypeLoc* DstPTL = cast<PointerTypeLoc>(&DstTL); - FixInvalidVariablyModifiedTypeLoc(SrcPTL->getPointeeLoc(), - DstPTL->getPointeeLoc()); - DstPTL->setStarLoc(SrcPTL->getStarLoc()); + if (PointerTypeLoc SrcPTL = SrcTL.getAs<PointerTypeLoc>()) { + PointerTypeLoc DstPTL = DstTL.castAs<PointerTypeLoc>(); + FixInvalidVariablyModifiedTypeLoc(SrcPTL.getPointeeLoc(), + DstPTL.getPointeeLoc()); + DstPTL.setStarLoc(SrcPTL.getStarLoc()); return; } - if (ParenTypeLoc* SrcPTL = dyn_cast<ParenTypeLoc>(&SrcTL)) { - ParenTypeLoc* DstPTL = cast<ParenTypeLoc>(&DstTL); - FixInvalidVariablyModifiedTypeLoc(SrcPTL->getInnerLoc(), - DstPTL->getInnerLoc()); - DstPTL->setLParenLoc(SrcPTL->getLParenLoc()); - DstPTL->setRParenLoc(SrcPTL->getRParenLoc()); + if (ParenTypeLoc SrcPTL = SrcTL.getAs<ParenTypeLoc>()) { + ParenTypeLoc DstPTL = DstTL.castAs<ParenTypeLoc>(); + FixInvalidVariablyModifiedTypeLoc(SrcPTL.getInnerLoc(), + DstPTL.getInnerLoc()); + DstPTL.setLParenLoc(SrcPTL.getLParenLoc()); + DstPTL.setRParenLoc(SrcPTL.getRParenLoc()); return; } - ArrayTypeLoc* SrcATL = cast<ArrayTypeLoc>(&SrcTL); - ArrayTypeLoc* DstATL = cast<ArrayTypeLoc>(&DstTL); - TypeLoc SrcElemTL = SrcATL->getElementLoc(); - TypeLoc DstElemTL = DstATL->getElementLoc(); + ArrayTypeLoc SrcATL = SrcTL.castAs<ArrayTypeLoc>(); + ArrayTypeLoc DstATL = DstTL.castAs<ArrayTypeLoc>(); + TypeLoc SrcElemTL = SrcATL.getElementLoc(); + TypeLoc DstElemTL = DstATL.getElementLoc(); DstElemTL.initializeFullCopy(SrcElemTL); - DstATL->setLBracketLoc(SrcATL->getLBracketLoc()); - DstATL->setSizeExpr(SrcATL->getSizeExpr()); - DstATL->setRBracketLoc(SrcATL->getRBracketLoc()); + DstATL.setLBracketLoc(SrcATL.getLBracketLoc()); + DstATL.setSizeExpr(SrcATL.getSizeExpr()); + DstATL.setRBracketLoc(SrcATL.getRBracketLoc()); } /// Helper method to turn variable array types into constant array @@ -3921,7 +4314,7 @@ TryToFixInvalidVariablyModifiedTypeSourceInfo(TypeSourceInfo *TInfo, return FixedTInfo; } -/// \brief Register the given locally-scoped external C declaration so +/// \brief Register the given locally-scoped extern "C" declaration so /// that it can be found later for redeclarations void Sema::RegisterLocallyScopedExternCDecl(NamedDecl *ND, @@ -3930,15 +4323,15 @@ Sema::RegisterLocallyScopedExternCDecl(NamedDecl *ND, assert(ND->getLexicalDeclContext()->isFunctionOrMethod() && "Decl is not a locally-scoped decl!"); // Note that we have a locally-scoped external with this name. - LocallyScopedExternalDecls[ND->getDeclName()] = ND; + LocallyScopedExternCDecls[ND->getDeclName()] = ND; if (!Previous.isSingleResult()) return; NamedDecl *PrevDecl = Previous.getFoundDecl(); - // If there was a previous declaration of this variable, it may be - // in our identifier chain. Update the identifier chain with the new + // If there was a previous declaration of this entity, it may be in + // our identifier chain. Update the identifier chain with the new // declaration. if (S && IdResolver.ReplaceDecl(PrevDecl, ND)) { // The previous declaration was found on the identifer resolver @@ -3962,38 +4355,42 @@ Sema::RegisterLocallyScopedExternCDecl(NamedDecl *ND, } llvm::DenseMap<DeclarationName, NamedDecl *>::iterator -Sema::findLocallyScopedExternalDecl(DeclarationName Name) { +Sema::findLocallyScopedExternCDecl(DeclarationName Name) { if (ExternalSource) { // Load locally-scoped external decls from the external source. SmallVector<NamedDecl *, 4> Decls; - ExternalSource->ReadLocallyScopedExternalDecls(Decls); + ExternalSource->ReadLocallyScopedExternCDecls(Decls); for (unsigned I = 0, N = Decls.size(); I != N; ++I) { llvm::DenseMap<DeclarationName, NamedDecl *>::iterator Pos - = LocallyScopedExternalDecls.find(Decls[I]->getDeclName()); - if (Pos == LocallyScopedExternalDecls.end()) - LocallyScopedExternalDecls[Decls[I]->getDeclName()] = Decls[I]; + = LocallyScopedExternCDecls.find(Decls[I]->getDeclName()); + if (Pos == LocallyScopedExternCDecls.end()) + LocallyScopedExternCDecls[Decls[I]->getDeclName()] = Decls[I]; } } - return LocallyScopedExternalDecls.find(Name); + return LocallyScopedExternCDecls.find(Name); } /// \brief Diagnose function specifiers on a declaration of an identifier that /// does not identify a function. -void Sema::DiagnoseFunctionSpecifiers(Declarator& D) { +void Sema::DiagnoseFunctionSpecifiers(const DeclSpec &DS) { // FIXME: We should probably indicate the identifier in question to avoid // confusion for constructs like "inline int a(), b;" - if (D.getDeclSpec().isInlineSpecified()) - Diag(D.getDeclSpec().getInlineSpecLoc(), + if (DS.isInlineSpecified()) + Diag(DS.getInlineSpecLoc(), diag::err_inline_non_function); - if (D.getDeclSpec().isVirtualSpecified()) - Diag(D.getDeclSpec().getVirtualSpecLoc(), + if (DS.isVirtualSpecified()) + Diag(DS.getVirtualSpecLoc(), diag::err_virtual_non_function); - if (D.getDeclSpec().isExplicitSpecified()) - Diag(D.getDeclSpec().getExplicitSpecLoc(), + if (DS.isExplicitSpecified()) + Diag(DS.getExplicitSpecLoc(), diag::err_explicit_non_function); + + if (DS.isNoreturnSpecified()) + Diag(DS.getNoreturnSpecLoc(), + diag::err_noreturn_non_function); } NamedDecl* @@ -4009,12 +4406,7 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC, Previous.clear(); } - if (getLangOpts().CPlusPlus) { - // Check that there are no default arguments (C++ only). - CheckExtraCXXDefaultArguments(D); - } - - DiagnoseFunctionSpecifiers(D); + DiagnoseFunctionSpecifiers(D.getDeclSpec()); if (D.getDeclSpec().isThreadSpecified()) Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_invalid_thread); @@ -4090,6 +4482,7 @@ Sema::ActOnTypedefNameDecl(Scope *S, DeclContext *DC, TypedefNameDecl *NewTD, // in an outer scope, it isn't the same thing. FilterLookupForScope(Previous, DC, S, /*ConsiderLinkage*/ false, /*ExplicitInstantiationOrSpecialization=*/false); + filterNonConflictingPreviousDecls(Context, NewTD, Previous); if (!Previous.empty()) { Redeclaration = true; MergeTypedefNameDecl(NewTD, Previous); @@ -4220,6 +4613,74 @@ bool Sema::inferObjCARCLifetime(ValueDecl *decl) { return false; } +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) { + S.Diag(Attr->getLocation(), diag::err_attribute_weak_static); + ND.dropAttr<WeakAttr>(); + } + } + if (WeakRefAttr *Attr = ND.getAttr<WeakRefAttr>()) { + if (ND.hasExternalLinkage()) { + S.Diag(Attr->getLocation(), diag::err_attribute_weakref_not_static); + ND.dropAttr<WeakRefAttr>(); + } + } +} + +/// Given that we are within the definition of the given function, +/// will that definition behave like C99's 'inline', where the +/// definition is discarded except for optimization purposes? +static bool isFunctionDefinitionDiscarded(Sema &S, FunctionDecl *FD) { + // Try to avoid calling GetGVALinkageForFunction. + + // All cases of this require the 'inline' keyword. + if (!FD->isInlined()) return false; + + // This is only possible in C++ with the gnu_inline attribute. + if (S.getLangOpts().CPlusPlus && !FD->hasAttr<GNUInlineAttr>()) + return false; + + // Okay, go ahead and call the relatively-more-expensive function. + +#ifndef NDEBUG + // AST quite reasonably asserts that it's working on a function + // definition. We don't really have a way to tell it that we're + // currently defining the function, so just lie to it in +Asserts + // builds. This is an awful hack. + FD->setLazyBody(1); +#endif + + bool isC99Inline = (S.Context.GetGVALinkageForFunction(FD) == GVA_C99Inline); + +#ifndef NDEBUG + FD->setLazyBody(0); +#endif + + return isC99Inline; +} + +static bool shouldConsiderLinkage(const VarDecl *VD) { + const DeclContext *DC = VD->getDeclContext()->getRedeclContext(); + if (DC->isFunctionOrMethod()) + return VD->hasExternalStorage(); + if (DC->isFileContext()) + return true; + if (DC->isRecord()) + return false; + llvm_unreachable("Unexpected context"); +} + +static bool shouldConsiderLinkage(const FunctionDecl *FD) { + const DeclContext *DC = FD->getDeclContext()->getRedeclContext(); + if (DC->isFileContext() || DC->isFunctionOrMethod()) + return true; + if (DC->isRecord()) + return false; + llvm_unreachable("Unexpected context"); +} + NamedDecl* Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, TypeSourceInfo *TInfo, LookupResult &Previous, @@ -4227,14 +4688,21 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, QualType R = TInfo->getType(); DeclarationName Name = GetNameForDeclarator(D).getName(); - // Check that there are no default arguments (C++ only). - if (getLangOpts().CPlusPlus) - CheckExtraCXXDefaultArguments(D); - DeclSpec::SCS SCSpec = D.getDeclSpec().getStorageClassSpec(); assert(SCSpec != DeclSpec::SCS_typedef && "Parser allowed 'typedef' as storage class VarDecl."); VarDecl::StorageClass SC = StorageClassSpecToVarDeclStorageClass(SCSpec); + + if (getLangOpts().OpenCL && !getOpenCLOptions().cl_khr_fp16) + { + // OpenCL v1.2 s6.1.1.1: reject declaring variables of the half and + // half array type (unless the cl_khr_fp16 extension is enabled). + if (Context.getBaseElementType(R)->isHalfType()) { + Diag(D.getIdentifierLoc(), diag::err_opencl_half_declaration) << R; + D.setInvalidType(); + } + } + if (SCSpec == DeclSpec::SCS_mutable) { // mutable can only appear on non-static class members, so it's always // an error here @@ -4242,9 +4710,6 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, D.setInvalidType(); SC = SC_None; } - SCSpec = D.getDeclSpec().getStorageClassSpecAsWritten(); - VarDecl::StorageClass SCAsWritten - = StorageClassSpecToVarDeclStorageClass(SCSpec); IdentifierInfo *II = Name.getAsIdentifierInfo(); if (!II) { @@ -4253,7 +4718,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, return 0; } - DiagnoseFunctionSpecifiers(D); + DiagnoseFunctionSpecifiers(D.getDeclSpec()); if (!DC->isRecord() && S->getFnParent() == 0) { // C99 6.9p2: The storage-class specifiers auto and register shall not @@ -4273,8 +4738,33 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (getLangOpts().OpenCL) { // Set up the special work-group-local storage class for variables in the // OpenCL __local address space. - if (R.getAddressSpace() == LangAS::opencl_local) + if (R.getAddressSpace() == LangAS::opencl_local) { SC = SC_OpenCLWorkGroupLocal; + } + + // OpenCL v1.2 s6.9.b p4: + // The sampler type cannot be used with the __local and __global address + // space qualifiers. + if (R->isSamplerT() && (R.getAddressSpace() == LangAS::opencl_local || + R.getAddressSpace() == LangAS::opencl_global)) { + Diag(D.getIdentifierLoc(), diag::err_wrong_sampler_addressspace); + } + + // OpenCL 1.2 spec, p6.9 r: + // The event type cannot be used to declare a program scope variable. + // The event type cannot be used with the __local, __constant and __global + // address space qualifiers. + if (R->isEventT()) { + if (S->getParent() == 0) { + Diag(D.getLocStart(), diag::err_event_t_global_var); + D.setInvalidType(); + } + + if (R.getAddressSpace()) { + Diag(D.getLocStart(), diag::err_event_t_addr_space_qual); + D.setInvalidType(); + } + } } bool isExplicitSpecialization = false; @@ -4282,7 +4772,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (!getLangOpts().CPlusPlus) { NewVD = VarDecl::Create(Context, DC, D.getLocStart(), D.getIdentifierLoc(), II, - R, TInfo, SC, SCAsWritten); + R, TInfo, SC); if (D.isInvalidType()) NewVD->setInvalidDecl(); @@ -4293,8 +4783,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, Diag(D.getDeclSpec().getStorageClassSpecLoc(), diag::err_static_out_of_line) << FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc()); - } else if (SC == SC_None) - SC = SC_Static; + } } if (SC == SC_Static && CurContext->isRecord()) { if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC)) { @@ -4307,7 +4796,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, // the program is ill-formed. C++11 drops this restriction. if (RD->isUnion()) Diag(D.getIdentifierLoc(), - getLangOpts().CPlusPlus0x + getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_static_data_member_in_union : diag::ext_static_data_member_in_union) << Name; // We conservatively disallow static data members in anonymous structs. @@ -4352,7 +4841,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, NewVD = VarDecl::Create(Context, DC, D.getLocStart(), D.getIdentifierLoc(), II, - R, TInfo, SC, SCAsWritten); + R, TInfo, SC); // 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. @@ -4388,6 +4877,25 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, NewVD->setThreadSpecified(true); } + // C99 6.7.4p3 + // An inline definition of a function with external linkage shall + // not contain a definition of a modifiable object with static or + // thread storage duration... + // We only apply this when the function is required to be defined + // elsewhere, i.e. when the function is not 'extern inline'. Note + // that a local variable with thread storage duration still has to + // be marked 'static'. Also note that it's possible to get these + // semantics in C++ using __attribute__((gnu_inline)). + if (SC == SC_Static && S->getFnParent() != 0 && + !NewVD->getType().isConstQualified()) { + FunctionDecl *CurFD = getCurFunctionDecl(); + if (CurFD && isFunctionDefinitionDiscarded(*this, CurFD)) { + Diag(D.getDeclSpec().getStorageClassSpecLoc(), + diag::warn_static_local_in_extern_inline); + MaybeSuggestAddingStaticToDecl(CurFD); + } + } + if (D.getDeclSpec().isModulePrivateSpecified()) { if (isExplicitSpecialization) Diag(NewVD->getLocation(), diag::err_module_private_specialization) @@ -4405,12 +4913,17 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, // Handle attributes prior to checking for duplicates in MergeVarDecl ProcessDeclAttributes(S, NewVD, D); + if (NewVD->hasAttrs()) + CheckAlignasUnderalignment(NewVD); + if (getLangOpts().CUDA) { // CUDA B.2.5: "__shared__ and __constant__ variables have implied static // storage [duration]." if (SC == SC_None && S->getFnParent() != 0 && - (NewVD->hasAttr<CUDASharedAttr>() || NewVD->hasAttr<CUDAConstantAttr>())) + (NewVD->hasAttr<CUDASharedAttr>() || + NewVD->hasAttr<CUDAConstantAttr>())) { NewVD->setStorageClass(SC_Static); + } } // In auto-retain/release, infer strong retension for variables of @@ -4459,7 +4972,7 @@ 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, NewVD->hasLinkage(), + FilterLookupForScope(Previous, DC, S, shouldConsiderLinkage(NewVD), isExplicitSpecialization); if (!getLangOpts().CPlusPlus) { @@ -4493,19 +5006,15 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, NewVD->setInvalidDecl(); } + 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 there's a #pragma GCC visibility in scope, and this isn't a class - // member, set the visibility of this variable. - if (NewVD->getLinkage() == ExternalLinkage && !DC->isRecord()) - AddPushedVisibilityAttribute(NewVD); - - MarkUnusedFileScopedDecl(NewVD); - return NewVD; } @@ -4604,6 +5113,32 @@ void Sema::CheckShadow(Scope *S, VarDecl *D) { CheckShadow(S, D, R); } +template<typename T> +static bool mayConflictWithNonVisibleExternC(const T *ND) { + const DeclContext *DC = ND->getDeclContext(); + if (DC->getRedeclContext()->isTranslationUnit()) + return true; + + // 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 (!DC->isExternCContext()) { + const ASTContext &Context = ND->getASTContext(); + if (Context.getLangOpts().CPlusPlus) + return false; + } + + return ND->isExternC(); +} + /// \brief Perform semantic checking on a newly-created variable /// declaration. /// @@ -4706,16 +5241,44 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD, NewVD->setTypeSourceInfo(FixedTInfo); } - if (Previous.empty() && NewVD->isExternC()) { - // Since we did not find anything by this name and we're declaring - // an extern "C" variable, look for a non-visible extern "C" - // declaration with the same name. + // 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 - = findLocallyScopedExternalDecl(NewVD->getDeclName()); - if (Pos != LocallyScopedExternalDecls.end()) + = findLocallyScopedExternCDecl(NewVD->getDeclName()); + if (Pos != LocallyScopedExternCDecls.end()) { Previous.addDecl(Pos->second); + PreviousWasHidden = true; + } } + // Filter out any non-conflicting previous declarations. + filterNonConflictingPreviousDecls(Context, NewVD, Previous); + if (T->isVoidType() && !NewVD->hasExternalStorage()) { Diag(NewVD->getLocation(), diag::err_typecheck_decl_incomplete_type) << T; @@ -4743,7 +5306,7 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD, } if (!Previous.empty()) { - MergeVarDecl(NewVD, Previous); + MergeVarDecl(NewVD, Previous, PreviousWasHidden); return true; } return false; @@ -4778,9 +5341,9 @@ static bool FindOverriddenMethod(const CXXBaseSpecifier *Specifier, } for (Path.Decls = BaseRecord->lookup(Name); - Path.Decls.first != Path.Decls.second; - ++Path.Decls.first) { - NamedDecl *D = *Path.Decls.first; + !Path.Decls.empty(); + Path.Decls = Path.Decls.slice(1)) { + NamedDecl *D = Path.Decls.front(); if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { if (MD->isVirtual() && !Data->S->IsOverload(Data->Method, MD, false)) return true; @@ -4832,6 +5395,7 @@ bool Sema::AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD) { if (CXXMethodDecl *OldMD = dyn_cast<CXXMethodDecl>(*I)) { MD->addOverriddenMethod(OldMD->getCanonicalDecl()); if (!CheckOverridingFunctionReturnType(MD, OldMD) && + !CheckOverridingFunctionAttributes(MD, OldMD) && !CheckOverridingFunctionExceptionSpec(MD, OldMD) && !CheckIfOverriddenFunctionIsMarkedFinal(MD, OldMD)) { hasDeletedOverridenMethods |= OldMD->isDeleted(); @@ -4878,7 +5442,7 @@ class DifferentNameValidatorCCC : public CorrectionCandidateCallback { if (candidate.getEditDistance() == 0) return false; - llvm::SmallVector<unsigned, 1> MismatchedParams; + SmallVector<unsigned, 1> MismatchedParams; for (TypoCorrection::const_decl_iterator CDecl = candidate.begin(), CDeclEnd = candidate.end(); CDecl != CDeclEnd; ++CDecl) { @@ -4924,8 +5488,8 @@ static NamedDecl* DiagnoseInvalidRedeclaration( DeclContext *NewDC = NewFD->getDeclContext(); LookupResult Prev(SemaRef, Name, NewFD->getLocation(), Sema::LookupOrdinaryName, Sema::ForRedeclaration); - llvm::SmallVector<unsigned, 1> MismatchedParams; - llvm::SmallVector<std::pair<FunctionDecl*, unsigned>, 1> NearMatches; + SmallVector<unsigned, 1> MismatchedParams; + SmallVector<std::pair<FunctionDecl *, unsigned>, 1> NearMatches; TypoCorrection Correction; bool isFriendDecl = (SemaRef.getLangOpts().CPlusPlus && ExtraArgs.D.getDeclSpec().isFriendSpecified()); @@ -5029,7 +5593,7 @@ static NamedDecl* DiagnoseInvalidRedeclaration( if (CXXMethodDecl *NewMD = dyn_cast<CXXMethodDecl>(NewFD)) NewFDisConst = NewMD->isConst(); - for (llvm::SmallVector<std::pair<FunctionDecl*, unsigned>, 1>::iterator + for (SmallVector<std::pair<FunctionDecl *, unsigned>, 1>::iterator NearMatch = NearMatches.begin(), NearMatchEnd = NearMatches.end(); NearMatch != NearMatchEnd; ++NearMatch) { FunctionDecl *FD = NearMatch->first; @@ -5098,9 +5662,6 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, FunctionDecl *NewFD = 0; bool isInline = D.getDeclSpec().isInlineSpecified(); - DeclSpec::SCS SCSpec = D.getDeclSpec().getStorageClassSpecAsWritten(); - FunctionDecl::StorageClass SCAsWritten - = StorageClassSpecToFunctionDeclStorageClass(SCSpec); if (!SemaRef.getLangOpts().CPlusPlus) { // Determine whether the function was written with a @@ -5114,8 +5675,8 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, NewFD = FunctionDecl::Create(SemaRef.Context, DC, D.getLocStart(), NameInfo, R, - TInfo, SC, SCAsWritten, isInline, - HasPrototype); + TInfo, SC, isInline, + HasPrototype, false); if (D.isInvalidType()) NewFD->setInvalidDecl(); @@ -5164,7 +5725,7 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, // If the class is complete, then we now create the implicit exception // specification. If the class is incomplete or dependent, we can't do // it yet. - if (SemaRef.getLangOpts().CPlusPlus0x && !Record->isDependentType() && + if (SemaRef.getLangOpts().CPlusPlus11 && !Record->isDependentType() && Record->getDefinition() && !Record->isBeingDefined() && R->getAs<FunctionProtoType>()->getExceptionSpecType() == EST_None) { SemaRef.AdjustDestructorExceptionSpec(Record, NewDD); @@ -5182,7 +5743,7 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, return FunctionDecl::Create(SemaRef.Context, DC, D.getLocStart(), D.getIdentifierLoc(), Name, R, TInfo, - SC, SCAsWritten, isInline, + SC, isInline, /*hasPrototype=*/true, isConstexpr); } @@ -5213,36 +5774,21 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, return 0; } - bool isStatic = SC == SC_Static; - - // [class.free]p1: - // Any allocation function for a class T is a static member - // (even if not explicitly declared static). - if (Name.getCXXOverloadedOperator() == OO_New || - Name.getCXXOverloadedOperator() == OO_Array_New) - isStatic = true; - - // [class.free]p6 Any deallocation function for a class X is a static member - // (even if not explicitly declared static). - if (Name.getCXXOverloadedOperator() == OO_Delete || - Name.getCXXOverloadedOperator() == OO_Array_Delete) - isStatic = true; - - IsVirtualOkay = !isStatic; - // This is a C++ method declaration. - return CXXMethodDecl::Create(SemaRef.Context, cast<CXXRecordDecl>(DC), - D.getLocStart(), NameInfo, R, - TInfo, isStatic, SCAsWritten, isInline, - isConstexpr, SourceLocation()); - + CXXMethodDecl *Ret = CXXMethodDecl::Create(SemaRef.Context, + cast<CXXRecordDecl>(DC), + D.getLocStart(), NameInfo, R, + TInfo, SC, isInline, + isConstexpr, SourceLocation()); + IsVirtualOkay = !Ret->isStatic(); + return Ret; } else { // Determine whether the function was written with a // prototype. This true when: // - we're in C++ (where every function has a prototype), return FunctionDecl::Create(SemaRef.Context, DC, D.getLocStart(), - NameInfo, R, TInfo, SC, SCAsWritten, isInline, + NameInfo, R, TInfo, SC, isInline, true/*HasPrototype*/, isConstexpr); } } @@ -5291,8 +5837,10 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, T = Context.getObjCObjectPointerType(T); if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(R)) { FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); - R = Context.getFunctionType(T, FPT->arg_type_begin(), - FPT->getNumArgs(), EPI); + R = Context.getFunctionType(T, + ArrayRef<QualType>(FPT->arg_type_begin(), + FPT->getNumArgs()), + EPI); } else if (isa<FunctionNoProtoType>(R)) R = Context.getFunctionNoProtoType(T); @@ -5504,11 +6052,11 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, } if (isConstexpr) { - // C++0x [dcl.constexpr]p2: constexpr functions and constexpr constructors + // C++11 [dcl.constexpr]p2: constexpr functions and constexpr constructors // are implicitly inline. NewFD->setImplicitlyInline(); - // C++0x [dcl.constexpr]p3: functions declared constexpr are required to + // C++11 [dcl.constexpr]p3: functions declared constexpr are required to // be either constructors or to return a literal type. Therefore, // destructors cannot be declared constexpr. if (isa<CXXDestructorDecl>(NewFD)) @@ -5583,17 +6131,18 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, const FunctionProtoType *FPT = R->getAs<FunctionProtoType>(); if ((Name.getCXXOverloadedOperator() == OO_Delete || Name.getCXXOverloadedOperator() == OO_Array_Delete) && - getLangOpts().CPlusPlus0x && FPT && !FPT->hasExceptionSpec()) { + getLangOpts().CPlusPlus11 && FPT && !FPT->hasExceptionSpec()) { FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); EPI.ExceptionSpecType = EST_BasicNoexcept; NewFD->setType(Context.getFunctionType(FPT->getResultType(), - FPT->arg_type_begin(), - FPT->getNumArgs(), EPI)); + ArrayRef<QualType>(FPT->arg_type_begin(), + FPT->getNumArgs()), + EPI)); } } // Filter out previous declarations that don't match the scope. - FilterLookupForScope(Previous, DC, S, NewFD->hasLinkage(), + FilterLookupForScope(Previous, DC, S, shouldConsiderLinkage(NewFD), isExplicitSpecialization || isFunctionTemplateSpecialization); @@ -5675,6 +6224,11 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, NewFD->setDeclsInPrototypeScope(DeclsInPrototypeScope); DeclsInPrototypeScope.clear(); + if (D.getDeclSpec().isNoreturnSpecified()) + NewFD->addAttr( + ::new(Context) C11NoReturnAttr(D.getDeclSpec().getNoreturnSpecLoc(), + Context)); + // Process the non-inheritable attributes on this declaration. ProcessDeclAttributes(S, NewFD, D, /*NonInheritable=*/true, /*Inheritable=*/false); @@ -5691,6 +6245,18 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, ProcessDeclAttributes(S, NewFD, D, /*NonInheritable=*/false, /*Inheritable=*/true); + QualType RetType = NewFD->getResultType(); + const CXXRecordDecl *Ret = RetType->isRecordType() ? + RetType->getAsCXXRecordDecl() : RetType->getPointeeCXXRecordDecl(); + if (!NewFD->isInvalidDecl() && !NewFD->hasAttr<WarnUnusedResultAttr>() && + Ret && Ret->hasAttr<WarnUnusedResultAttr>()) { + const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD); + if (!(MD && MD->getCorrespondingMethodInClass(Ret, true))) { + NewFD->addAttr(new (Context) WarnUnusedResultAttr(SourceRange(), + Context)); + } + } + if (!getLangOpts().CPlusPlus) { // Perform semantic checking on the function declaration. bool isExplicitSpecialization=false; @@ -5788,7 +6354,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // A storage-class-specifier shall not be specified in an explicit // specialization (14.7.3) if (SC != SC_None) { - if (SC != NewFD->getStorageClass()) + if (SC != NewFD->getTemplateSpecializationInfo()->getTemplate()->getTemplatedDecl()->getStorageClass()) Diag(NewFD->getLocation(), diag::err_explicit_specialization_inconsistent_storage_class) << SC @@ -5938,6 +6504,9 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, } } + ProcessPragmaWeak(S, NewFD); + checkAttributesAfterMerging(*this, *NewFD); + AddKnownFunctionAttributes(NewFD); if (NewFD->hasAttr<OverloadableAttr>() && @@ -5952,13 +6521,15 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, EPI.Variadic = true; EPI.ExtInfo = FT->getExtInfo(); - QualType R = Context.getFunctionType(FT->getResultType(), 0, 0, EPI); + QualType R = Context.getFunctionType(FT->getResultType(), + ArrayRef<QualType>(), + EPI); NewFD->setType(R); } // If there's a #pragma GCC visibility in scope, and this isn't a class // member, set the visibility of this function. - if (NewFD->getLinkage() == ExternalLinkage && !DC->isRecord()) + if (!DC->isRecord() && NewFD->hasExternalLinkage()) AddPushedVisibilityAttribute(NewFD); // If there's a #pragma clang arc_cf_code_audited in scope, consider @@ -5982,12 +6553,42 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, } } - // OpenCL v1.2 s6.8 static is invalid for kernel functions. - if ((getLangOpts().OpenCLVersion >= 120) - && NewFD->hasAttr<OpenCLKernelAttr>() - && (SC == SC_Static)) { - Diag(D.getIdentifierLoc(), diag::err_static_kernel); - D.setInvalidType(); + if (NewFD->hasAttr<OpenCLKernelAttr>()) { + // OpenCL v1.2 s6.8 static is invalid for kernel functions. + if ((getLangOpts().OpenCLVersion >= 120) + && (SC == SC_Static)) { + Diag(D.getIdentifierLoc(), diag::err_static_kernel); + D.setInvalidType(); + } + + // OpenCL v1.2, s6.9 -- Kernels can only have return type void. + if (!NewFD->getResultType()->isVoidType()) { + Diag(D.getIdentifierLoc(), + diag::err_expected_kernel_void_return_type); + D.setInvalidType(); + } + + 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(); + } + } } MarkUnusedFileScopedDecl(NewFD); @@ -6043,17 +6644,20 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, && "Variably modified return types are not handled here"); // Check for a previous declaration of this name. - if (Previous.empty() && NewFD->isExternC()) { - // Since we did not find anything by this name and we're declaring - // an extern "C" function, look for a non-visible extern "C" - // declaration with the same 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 - = findLocallyScopedExternalDecl(NewFD->getDeclName()); - if (Pos != LocallyScopedExternalDecls.end()) + = findLocallyScopedExternCDecl(NewFD->getDeclName()); + if (Pos != LocallyScopedExternCDecls.end()) Previous.addDecl(Pos->second); } + // Filter out any non-conflicting previous declarations. + filterNonConflictingPreviousDecls(Context, NewFD, Previous); + bool Redeclaration = false; + NamedDecl *OldDecl = 0; // Merge or overload the declaration with an existing declaration of // the same name, if appropriate. @@ -6062,8 +6666,6 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, // a declaration that requires merging. If it's an overload, // there's no more work to do here; we'll just add the new // function to the scope. - - NamedDecl *OldDecl = 0; if (!AllowOverloadingOfFunction(Previous, Context)) { Redeclaration = true; OldDecl = Previous.getFoundDecl(); @@ -6100,42 +6702,90 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, Context)); } } + } - if (Redeclaration) { - // NewFD and OldDecl represent declarations that need to be - // merged. - if (MergeFunctionDecl(NewFD, OldDecl, S)) { - NewFD->setInvalidDecl(); - return Redeclaration; - } + // C++11 [dcl.constexpr]p8: + // A constexpr specifier for a non-static member function that is not + // a constructor declares that member function to be const. + // + // This needs to be delayed until we know whether this is an out-of-line + // definition of a static member function. + CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD); + if (MD && MD->isConstexpr() && !MD->isStatic() && + !isa<CXXConstructorDecl>(MD) && + (MD->getTypeQualifiers() & Qualifiers::Const) == 0) { + CXXMethodDecl *OldMD = dyn_cast_or_null<CXXMethodDecl>(OldDecl); + if (FunctionTemplateDecl *OldTD = + dyn_cast_or_null<FunctionTemplateDecl>(OldDecl)) + OldMD = dyn_cast<CXXMethodDecl>(OldTD->getTemplatedDecl()); + if (!OldMD || !OldMD->isStatic()) { + const FunctionProtoType *FPT = + MD->getType()->castAs<FunctionProtoType>(); + FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); + EPI.TypeQuals |= Qualifiers::Const; + MD->setType(Context.getFunctionType(FPT->getResultType(), + ArrayRef<QualType>(FPT->arg_type_begin(), + FPT->getNumArgs()), + EPI)); + } + } - Previous.clear(); - Previous.addDecl(OldDecl); - - if (FunctionTemplateDecl *OldTemplateDecl - = dyn_cast<FunctionTemplateDecl>(OldDecl)) { - NewFD->setPreviousDeclaration(OldTemplateDecl->getTemplatedDecl()); - FunctionTemplateDecl *NewTemplateDecl - = NewFD->getDescribedFunctionTemplate(); - assert(NewTemplateDecl && "Template/non-template mismatch"); - if (CXXMethodDecl *Method - = dyn_cast<CXXMethodDecl>(NewTemplateDecl->getTemplatedDecl())) { - Method->setAccess(OldTemplateDecl->getAccess()); - NewTemplateDecl->setAccess(OldTemplateDecl->getAccess()); - } - - // If this is an explicit specialization of a member that is a function - // template, mark it as a member specialization. - if (IsExplicitSpecialization && - NewTemplateDecl->getInstantiatedFromMemberTemplate()) { - NewTemplateDecl->setMemberSpecialization(); - assert(OldTemplateDecl->isMemberSpecialization()); + if (Redeclaration) { + // NewFD and OldDecl represent declarations that need to be + // merged. + if (MergeFunctionDecl(NewFD, OldDecl, S)) { + NewFD->setInvalidDecl(); + return Redeclaration; + } + + Previous.clear(); + Previous.addDecl(OldDecl); + + if (FunctionTemplateDecl *OldTemplateDecl + = dyn_cast<FunctionTemplateDecl>(OldDecl)) { + NewFD->setPreviousDeclaration(OldTemplateDecl->getTemplatedDecl()); + FunctionTemplateDecl *NewTemplateDecl + = NewFD->getDescribedFunctionTemplate(); + assert(NewTemplateDecl && "Template/non-template mismatch"); + if (CXXMethodDecl *Method + = dyn_cast<CXXMethodDecl>(NewTemplateDecl->getTemplatedDecl())) { + Method->setAccess(OldTemplateDecl->getAccess()); + NewTemplateDecl->setAccess(OldTemplateDecl->getAccess()); + } + + // If this is an explicit specialization of a member that is a function + // template, mark it as a member specialization. + if (IsExplicitSpecialization && + NewTemplateDecl->getInstantiatedFromMemberTemplate()) { + NewTemplateDecl->setMemberSpecialization(); + assert(OldTemplateDecl->isMemberSpecialization()); + } + + } else { + // This needs to happen first so that 'inline' propagates. + NewFD->setPreviousDeclaration(cast<FunctionDecl>(OldDecl)); + + if (isa<CXXMethodDecl>(NewFD)) { + // A valid redeclaration of a C++ method must be out-of-line, + // but (unfortunately) it's not necessarily a definition + // because of templates, which means that the previous + // declaration is not necessarily from the class definition. + + // For just setting the access, that doesn't matter. + CXXMethodDecl *oldMethod = cast<CXXMethodDecl>(OldDecl); + NewFD->setAccess(oldMethod->getAccess()); + + // Update the key-function state if necessary for this ABI. + if (NewFD->isInlined() && + !Context.getTargetInfo().getCXXABI().canKeyFunctionBeInline()) { + // setNonKeyFunction needs to work with the original + // declaration from the class definition, and isVirtual() is + // just faster in that case, so map back to that now. + oldMethod = cast<CXXMethodDecl>(oldMethod->getFirstDeclaration()); + if (oldMethod->isVirtual()) { + Context.setNonKeyFunction(oldMethod); + } } - - } else { - if (isa<CXXMethodDecl>(NewFD)) // Set access for out-of-line definitions - NewFD->setAccess(OldDecl->getAccess()); - NewFD->setPreviousDeclaration(cast<FunctionDecl>(OldDecl)); } } } @@ -6208,6 +6858,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, // declaration against the expected type for the builtin. if (unsigned BuiltinID = NewFD->getBuiltinID()) { ASTContext::GetBuiltinTypeError Error; + LookupPredefedObjCSuperType(*this, S, NewFD->getIdentifier()); QualType T = Context.GetBuiltinType(BuiltinID, Error); if (!T.isNull() && !Context.hasSameType(T, NewFD->getType())) { // The type of this function differs from the type of the builtin, @@ -6219,7 +6870,8 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, // 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. - if (NewFD->isExternC()) { + // But, issue any diagnostic on the first declaration only. + if (NewFD->isExternC() && Previous.empty()) { QualType R = NewFD->getResultType(); if (R->isIncompleteType() && !R->isVoidType()) Diag(NewFD->getLocation(), diag::warn_return_value_udt_incomplete) @@ -6232,12 +6884,30 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, return Redeclaration; } +static SourceRange getResultSourceRange(const FunctionDecl *FD) { + const TypeSourceInfo *TSI = FD->getTypeSourceInfo(); + if (!TSI) + return SourceRange(); + + TypeLoc TL = TSI->getTypeLoc(); + FunctionTypeLoc FunctionTL = TL.getAs<FunctionTypeLoc>(); + if (!FunctionTL) + return SourceRange(); + + TypeLoc ResultTL = FunctionTL.getResultLoc(); + if (ResultTL.getUnqualifiedLoc().getAs<BuiltinTypeLoc>()) + return ResultTL.getSourceRange(); + + return SourceRange(); +} + void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) { // C++11 [basic.start.main]p3: A program that declares main to be inline, // static or constexpr is ill-formed. - // C99 6.7.4p4: In a hosted environment, the inline function specifier - // shall not appear in a declaration of main. + // C11 6.7.4p4: In a hosted environment, no function specifier(s) shall + // appear in a declaration of main. // static main is not an error under C99, but we should warn about it. + // We accept _Noreturn main as an extension. if (FD->getStorageClass() == SC_Static) Diag(DS.getStorageClassSpecLoc(), getLangOpts().CPlusPlus ? diag::err_static_main : diag::warn_static_main) @@ -6245,6 +6915,14 @@ void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) { if (FD->isInlineSpecified()) Diag(DS.getInlineSpecLoc(), diag::err_inline_main) << FixItHint::CreateRemoval(DS.getInlineSpecLoc()); + if (DS.isNoreturnSpecified()) { + SourceLocation NoreturnLoc = DS.getNoreturnSpecLoc(); + SourceRange NoreturnRange(NoreturnLoc, + PP.getLocForEndOfToken(NoreturnLoc)); + Diag(NoreturnLoc, diag::ext_noreturn_main); + Diag(NoreturnLoc, diag::note_main_remove_noreturn) + << FixItHint::CreateRemoval(NoreturnRange); + } if (FD->isConstexpr()) { Diag(DS.getConstexprSpecLoc(), diag::err_constexpr_main) << FixItHint::CreateRemoval(DS.getConstexprSpecLoc()); @@ -6268,9 +6946,20 @@ void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) { } else if (getLangOpts().GNUMode && !getLangOpts().CPlusPlus) { Diag(FD->getTypeSpecStartLoc(), diag::ext_main_returns_nonint); + SourceRange ResultRange = getResultSourceRange(FD); + if (ResultRange.isValid()) + Diag(ResultRange.getBegin(), diag::note_main_change_return_type) + << FixItHint::CreateReplacement(ResultRange, "int"); + // Otherwise, this is just a flat-out error. } else { - Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint); + SourceRange ResultRange = getResultSourceRange(FD); + if (ResultRange.isValid()) + Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint) + << FixItHint::CreateReplacement(ResultRange, "int"); + else + Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint); + FD->setInvalidDecl(true); } @@ -6319,7 +7008,8 @@ void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) { const PointerType* PT; if ((PT = qs.strip(AT)->getAs<PointerType>()) && (PT = qs.strip(PT->getPointeeType())->getAs<PointerType>()) && - (QualType(qs.strip(PT->getPointeeType()), 0) == Context.CharTy)) { + Context.hasSameType(QualType(qs.strip(PT->getPointeeType()), 0), + Context.CharTy)) { qs.removeConst(); mismatch = !qs.empty(); } @@ -6457,6 +7147,14 @@ namespace { Visit(Base); } + void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) { + if (E->getNumArgs() > 0) + if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->getArg(0))) + HandleDeclRefExpr(DRE); + + Inherited::VisitCXXOperatorCallExpr(E); + } + void VisitUnaryOperator(UnaryOperator *E) { // For POD record types, addresses of its own members are well-defined. if (E->getOpcode() == UO_AddrOf && isRecordType && @@ -6471,11 +7169,17 @@ namespace { void VisitObjCMessageExpr(ObjCMessageExpr *E) { return; } void HandleDeclRefExpr(DeclRefExpr *DRE) { - Decl* ReferenceDecl = DRE->getDecl(); + Decl* ReferenceDecl = DRE->getDecl(); if (OrigDecl != ReferenceDecl) return; - unsigned diag = isReferenceType - ? diag::warn_uninit_self_reference_in_reference_init - : diag::warn_uninit_self_reference_in_init; + unsigned diag; + if (isReferenceType) { + diag = diag::warn_uninit_self_reference_in_reference_init; + } else if (cast<VarDecl>(OrigDecl)->isStaticLocal()) { + diag = diag::warn_static_self_reference_in_init; + } else { + diag = diag::warn_uninit_self_reference_in_init; + } + S.DiagRuntimeBehavior(DRE->getLocStart(), DRE, S.PDiag(diag) << DRE->getNameInfo().getName() @@ -6572,6 +7276,20 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, DeduceInit = CXXDirectInit->getExpr(0); } } + + // Expressions default to 'id' when we're in a debugger. + bool DefaultedToAuto = false; + if (getLangOpts().DebuggerCastResultToId && + Init->getType() == Context.UnknownAnyTy) { + ExprResult Result = forceUnknownAnyToType(Init, Context.getObjCIdType()); + if (Result.isInvalid()) { + VDecl->setInvalidDecl(); + return; + } + Init = Result.take(); + DefaultedToAuto = true; + } + TypeSourceInfo *DeducedType = 0; if (DeduceAutoType(VDecl->getTypeSourceInfo(), DeduceInit, DeducedType) == DAR_Failed) @@ -6582,8 +7300,8 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, } VDecl->setTypeSourceInfo(DeducedType); VDecl->setType(DeducedType->getType()); - VDecl->ClearLinkageCache(); - + assert(VDecl->isLinkageValid()); + // In ARC, infer lifetime. if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(VDecl)) VDecl->setInvalidDecl(); @@ -6592,7 +7310,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // 'id' instead of a specific object type prevents most of our usual checks. // We only want to warn outside of template instantiations, though: // inside a template, the 'id' could have come from a parameter. - if (ActiveTemplateInstantiations.empty() && + if (ActiveTemplateInstantiations.empty() && !DefaultedToAuto && DeducedType->getType()->isObjCIdType()) { SourceLocation Loc = DeducedType->getTypeLoc().getBeginLoc(); Diag(Loc, diag::warn_auto_var_is_id) @@ -6602,7 +7320,7 @@ 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); + MergeVarDeclTypes(VDecl, Old, /*OldWasHidden*/ false); } if (VDecl->isLocalVarDecl() && VDecl->hasExternalStorage()) { @@ -6683,17 +7401,17 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // CheckInitializerTypes may change it. QualType DclT = VDecl->getType(), SavT = DclT; - // Top-level message sends default to 'id' when we're in a debugger - // and we are assigning it to a variable of 'id' type. - if (getLangOpts().DebuggerCastResultToId && DclT->isObjCIdType()) - if (Init->getType() == Context.UnknownAnyTy && isa<ObjCMessageExpr>(Init)) { - ExprResult Result = forceUnknownAnyToType(Init, Context.getObjCIdType()); - if (Result.isInvalid()) { - VDecl->setInvalidDecl(); - return; - } - Init = Result.take(); + // Expressions default to 'id' when we're in a debugger + // and we are assigning it to a variable of Objective-C pointer type. + if (getLangOpts().DebuggerCastResultToId && DclT->isObjCObjectPointerType() && + Init->getType() == Context.UnknownAnyTy) { + ExprResult Result = forceUnknownAnyToType(Init, Context.getObjCIdType()); + if (Result.isInvalid()) { + VDecl->setInvalidDecl(); + return; } + Init = Result.take(); + } // Perform the initialization. if (!VDecl->isInvalidDecl()) { @@ -6740,9 +7458,6 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, if (!VDecl->isInvalidDecl() && (DclT != SavT)) VDecl->setType(DclT); - // Check any implicit conversions within the expression. - CheckImplicitConversions(Init, VDecl->getLocation()); - if (!VDecl->isInvalidDecl()) { checkUnsafeAssigns(VDecl->getLocation(), VDecl->getType(), Init); @@ -6765,7 +7480,26 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, } } - Init = MaybeCreateExprWithCleanups(Init); + // The initialization is usually a full-expression. + // + // FIXME: If this is a braced initialization of an aggregate, it is not + // an expression, and each individual field initializer is a separate + // full-expression. For instance, in: + // + // struct Temp { ~Temp(); }; + // struct S { S(Temp); }; + // struct T { S a, b; } t = { Temp(), Temp() } + // + // we should destroy the first Temp before constructing the second. + ExprResult Result = ActOnFinishFullExpr(Init, VDecl->getLocation(), + false, + VDecl->isConstexpr()); + if (Result.isInvalid()) { + VDecl->setInvalidDecl(); + return; + } + Init = Result.take(); + // Attach the initializer to the decl. VDecl->setInit(Init); @@ -6817,7 +7551,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, } else if (DclT->isIntegralOrEnumerationType()) { // Check whether the expression is a constant expression. SourceLocation Loc; - if (getLangOpts().CPlusPlus0x && DclT.isVolatileQualified()) + if (getLangOpts().CPlusPlus11 && DclT.isVolatileQualified()) // In C++11, a non-constexpr const static data member with an // in-class initializer cannot be volatile. Diag(VDecl->getLocation(), diag::err_in_class_initializer_volatile); @@ -6840,21 +7574,28 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // We allow foldable floating-point constants as an extension. } else if (DclT->isFloatingType()) { // also permits complex, which is ok - Diag(VDecl->getLocation(), diag::ext_in_class_initializer_float_type) - << DclT << Init->getSourceRange(); - if (getLangOpts().CPlusPlus0x) + // In C++98, this is a GNU extension. In C++11, it is not, but we support + // it anyway and provide a fixit to add the 'constexpr'. + if (getLangOpts().CPlusPlus11) { Diag(VDecl->getLocation(), - diag::note_in_class_initializer_float_type_constexpr) - << FixItHint::CreateInsertion(VDecl->getLocStart(), "constexpr "); + diag::ext_in_class_initializer_float_type_cxx11) + << DclT << Init->getSourceRange(); + Diag(VDecl->getLocStart(), + diag::note_in_class_initializer_float_type_cxx11) + << FixItHint::CreateInsertion(VDecl->getLocStart(), "constexpr "); + } else { + Diag(VDecl->getLocation(), diag::ext_in_class_initializer_float_type) + << DclT << Init->getSourceRange(); - if (!Init->isValueDependent() && !Init->isEvaluatable(Context)) { - Diag(Init->getExprLoc(), diag::err_in_class_initializer_non_constant) - << Init->getSourceRange(); - VDecl->setInvalidDecl(); + if (!Init->isValueDependent() && !Init->isEvaluatable(Context)) { + Diag(Init->getExprLoc(), diag::err_in_class_initializer_non_constant) + << Init->getSourceRange(); + VDecl->setInvalidDecl(); + } } // Suggest adding 'constexpr' in C++11 for literal types. - } else if (getLangOpts().CPlusPlus0x && DclT->isLiteralType()) { + } else if (getLangOpts().CPlusPlus11 && DclT->isLiteralType()) { Diag(VDecl->getLocation(), diag::err_in_class_initializer_literal_type) << DclT << Init->getSourceRange() << FixItHint::CreateInsertion(VDecl->getLocStart(), "constexpr "); @@ -6866,9 +7607,10 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, VDecl->setInvalidDecl(); } } else if (VDecl->isFileVarDecl()) { - if (VDecl->getStorageClassAsWritten() == SC_Extern && + if (VDecl->getStorageClass() == SC_Extern && (!getLangOpts().CPlusPlus || - !Context.getBaseElementType(VDecl->getType()).isConstQualified())) + !(Context.getBaseElementType(VDecl->getType()).isConstQualified() || + VDecl->isExternC()))) Diag(VDecl->getLocation(), diag::warn_extern_init); // C99 6.7.8p4. All file scoped initializers need to be constant. @@ -7155,7 +7897,7 @@ void Sema::ActOnCXXForRangeDecl(Decl *D) { // for-range-declaration cannot be given a storage class specifier. int Error = -1; - switch (VD->getStorageClassAsWritten()) { + switch (VD->getStorageClass()) { case SC_None: break; case SC_Extern: @@ -7206,7 +7948,10 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { } if (var->isThisDeclarationADefinition() && - var->getLinkage() == ExternalLinkage) { + var->hasExternalLinkage() && + getDiagnostics().getDiagnosticLevel( + diag::warn_missing_variable_declarations, + var->getLocation())) { // Find a previous declaration that's not a definition. VarDecl *prev = var->getPreviousDecl(); while (prev && prev->isThisDeclarationADefinition()) @@ -7230,12 +7975,13 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { // Regardless, we don't want to ignore array nesting when // constructing this copy. if (type->isStructureOrClassType()) { + EnterExpressionEvaluationContext scope(*this, PotentiallyEvaluated); SourceLocation poi = var->getLocation(); Expr *varRef =new (Context) DeclRefExpr(var, false, type, VK_LValue, poi); - ExprResult result = - PerformCopyInitialization( - InitializedEntity::InitializeBlock(poi, type, false), - poi, Owned(varRef)); + ExprResult result + = PerformMoveOrCopyInitialization( + InitializedEntity::InitializeBlock(poi, type, false), + var, var->getType(), varRef, /*AllowNRVO=*/true); if (!result.isInvalid()) { result = MaybeCreateExprWithCleanups(result); Expr *init = result.takeAs<Expr>(); @@ -7259,7 +8005,7 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { << Init->getSourceRange(); if (var->isConstexpr()) { - llvm::SmallVector<PartialDiagnosticAt, 8> Notes; + SmallVector<PartialDiagnosticAt, 8> Notes; if (!var->evaluateValue(Notes) || !var->isInitICE()) { SourceLocation DiagLoc = var->getLocation(); // If the note doesn't add any useful information other than a source @@ -7294,40 +8040,52 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) { // Note that we are no longer parsing the initializer for this declaration. ParsingInitForAutoVars.erase(ThisDecl); + VarDecl *VD = dyn_cast_or_null<VarDecl>(ThisDecl); + if (!VD) + return; + + 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()) + AddPushedVisibilityAttribute(VD); + + if (VD->isFileVarDecl()) + MarkUnusedFileScopedDecl(VD); + // Now we have parsed the initializer and can update the table of magic // tag values. - if (ThisDecl && ThisDecl->hasAttr<TypeTagForDatatypeAttr>()) { - const VarDecl *VD = dyn_cast<VarDecl>(ThisDecl); - if (VD && VD->getType()->isIntegralOrEnumerationType()) { - for (specific_attr_iterator<TypeTagForDatatypeAttr> - I = ThisDecl->specific_attr_begin<TypeTagForDatatypeAttr>(), - E = ThisDecl->specific_attr_end<TypeTagForDatatypeAttr>(); - I != E; ++I) { - const Expr *MagicValueExpr = VD->getInit(); - if (!MagicValueExpr) { - continue; - } - llvm::APSInt MagicValueInt; - if (!MagicValueExpr->isIntegerConstantExpr(MagicValueInt, Context)) { - Diag(I->getRange().getBegin(), - diag::err_type_tag_for_datatype_not_ice) - << LangOpts.CPlusPlus << MagicValueExpr->getSourceRange(); - continue; - } - if (MagicValueInt.getActiveBits() > 64) { - Diag(I->getRange().getBegin(), - diag::err_type_tag_for_datatype_too_large) - << LangOpts.CPlusPlus << MagicValueExpr->getSourceRange(); - continue; - } - uint64_t MagicValue = MagicValueInt.getZExtValue(); - RegisterTypeTagForDatatype(I->getArgumentKind(), - MagicValue, - I->getMatchingCType(), - I->getLayoutCompatible(), - I->getMustBeNull()); - } + if (!VD->hasAttr<TypeTagForDatatypeAttr>() || + !VD->getType()->isIntegralOrEnumerationType()) + return; + + for (specific_attr_iterator<TypeTagForDatatypeAttr> + I = ThisDecl->specific_attr_begin<TypeTagForDatatypeAttr>(), + E = ThisDecl->specific_attr_end<TypeTagForDatatypeAttr>(); + I != E; ++I) { + const Expr *MagicValueExpr = VD->getInit(); + if (!MagicValueExpr) { + continue; + } + llvm::APSInt MagicValueInt; + if (!MagicValueExpr->isIntegerConstantExpr(MagicValueInt, Context)) { + Diag(I->getRange().getBegin(), + diag::err_type_tag_for_datatype_not_ice) + << LangOpts.CPlusPlus << MagicValueExpr->getSourceRange(); + continue; + } + if (MagicValueInt.getActiveBits() > 64) { + Diag(I->getRange().getBegin(), + diag::err_type_tag_for_datatype_too_large) + << LangOpts.CPlusPlus << MagicValueExpr->getSourceRange(); + continue; } + uint64_t MagicValue = MagicValueInt.getZExtValue(); + RegisterTypeTagForDatatype(I->getArgumentKind(), + MagicValue, + I->getMatchingCType(), + I->getLayoutCompatible(), + I->getMustBeNull()); } } @@ -7343,6 +8101,10 @@ Sema::FinalizeDeclaratorGroup(Scope *S, const DeclSpec &DS, if (Decl *D = Group[i]) Decls.push_back(D); + if (DeclSpec::isDeclRep(DS.getTypeSpecType())) + if (const TagDecl *Tag = dyn_cast_or_null<TagDecl>(DS.getRepAsDecl())) + getASTContext().addUnnamedTag(Tag); + return BuildDeclaratorGroup(Decls.data(), Decls.size(), DS.getTypeSpecType() == DeclSpec::TST_auto); } @@ -7449,14 +8211,11 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { // 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; - VarDecl::StorageClass StorageClassAsWritten = SC_None; if (DS.getStorageClassSpec() == DeclSpec::SCS_register) { StorageClass = SC_Register; - StorageClassAsWritten = SC_Register; } else if (getLangOpts().CPlusPlus && DS.getStorageClassSpec() == DeclSpec::SCS_auto) { StorageClass = SC_Auto; - StorageClassAsWritten = SC_Auto; } else if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified) { Diag(DS.getStorageClassSpecLoc(), diag::err_invalid_storage_class_in_func_decl); @@ -7469,7 +8228,7 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { Diag(D.getDeclSpec().getConstexprSpecLoc(), diag::err_invalid_constexpr) << 0; - DiagnoseFunctionSpecifiers(D); + DiagnoseFunctionSpecifiers(D.getDeclSpec()); TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); QualType parmDeclType = TInfo->getType(); @@ -7529,7 +8288,7 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { D.getLocStart(), D.getIdentifierLoc(), II, parmDeclType, TInfo, - StorageClass, StorageClassAsWritten); + StorageClass); if (D.isInvalidType()) New->setInvalidDecl(); @@ -7568,7 +8327,7 @@ ParmVarDecl *Sema::BuildParmVarDeclForTypedef(DeclContext *DC, location for the unnamed parameters, embedding the parameter's type? */ ParmVarDecl *Param = ParmVarDecl::Create(Context, DC, Loc, Loc, 0, T, Context.getTrivialTypeSourceInfo(T, Loc), - SC_None, SC_None, 0); + SC_None, 0); Param->setImplicit(); return Param; } @@ -7621,8 +8380,7 @@ void Sema::DiagnoseSizeOfParametersAndReturnValue(ParmVarDecl * const *Param, ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc, SourceLocation NameLoc, IdentifierInfo *Name, QualType T, TypeSourceInfo *TSInfo, - VarDecl::StorageClass StorageClass, - VarDecl::StorageClass StorageClassAsWritten) { + VarDecl::StorageClass StorageClass) { // In ARC, infer a lifetime qualifier for appropriate parameter types. if (getLangOpts().ObjCAutoRefCount && T.getObjCLifetime() == Qualifiers::OCL_None && @@ -7649,8 +8407,7 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc, ParmVarDecl *New = ParmVarDecl::Create(Context, DC, StartLoc, NameLoc, Name, Context.getAdjustedParameterType(T), TSInfo, - StorageClass, StorageClassAsWritten, - 0); + StorageClass, 0); // Parameters can not be abstract class types. // For record types, this is done by the AbstractClassUsageDiagnoser once @@ -7730,7 +8487,8 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) { return ActOnStartOfFunctionDef(FnBodyScope, DP); } -static bool ShouldWarnAboutMissingPrototype(const FunctionDecl *FD) { +static bool ShouldWarnAboutMissingPrototype(const FunctionDecl *FD, + const FunctionDecl*& PossibleZeroParamPrototype) { // Don't warn about invalid declarations. if (FD->isInvalidDecl()) return false; @@ -7772,6 +8530,8 @@ static bool ShouldWarnAboutMissingPrototype(const FunctionDecl *FD) { continue; MissingPrototype = !Prev->getType()->isFunctionProtoType(); + if (FD->getNumParams() == 0) + PossibleZeroParamPrototype = Prev; break; } @@ -7837,8 +8597,22 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { // prototype declaration. This warning is issued even if the // definition itself provides a prototype. The aim is to detect // global functions that fail to be declared in header files. - if (ShouldWarnAboutMissingPrototype(FD)) + 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, + // 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 (FnBodyScope) PushDeclContext(FnBodyScope, FD); @@ -7913,7 +8687,7 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { diag::err_attribute_can_be_applied_only_to_symbol_declaration) << "dllimport"; FD->setInvalidDecl(); - return FD; + return D; } // Visual C++ appears to not think this is an issue, so only issue @@ -7930,7 +8704,7 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { // We want to attach documentation to original Decl (which might be // a function template). ActOnDocumentableDecl(D); - return FD; + return D; } /// \brief Given the set of return statements within a function body, @@ -7967,6 +8741,33 @@ void Sema::computeNRVO(Stmt *Body, FunctionScopeInfo *Scope) { const_cast<VarDecl*>(NRVOCandidate)->setNRVOVariable(true); } +bool Sema::canSkipFunctionBody(Decl *D) { + if (!Consumer.shouldSkipFunctionBody(D)) + return false; + + if (isa<ObjCMethodDecl>(D)) + return true; + + FunctionDecl *FD = 0; + if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(D)) + FD = FTD->getTemplatedDecl(); + else + FD = cast<FunctionDecl>(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(); +} + +Decl *Sema::ActOnSkippedFunctionBody(Decl *Decl) { + if (FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(Decl)) + FD->setHasSkippedBody(); + else if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(Decl)) + MD->setHasSkippedBody(); + return ActOnFinishFunctionBody(Decl, 0); +} + Decl *Sema::ActOnFinishFunctionBody(Decl *D, Stmt *BodyArg) { return ActOnFinishFunctionBody(D, BodyArg, false); } @@ -7986,6 +8787,18 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, if (FD) { FD->setBody(Body); + // 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) + UndefinedButUsed.erase(FD); + else if (FD->isInlined() && + (LangOpts.CPlusPlus || !LangOpts.GNUInline) && + (!FD->getPreviousDecl()->hasAttr<GNUInlineAttr>())) + UndefinedButUsed.erase(FD); + } + // If the function implicitly returns zero (like 'main') or is naked, // don't complain about missing return statements. if (FD->hasImplicitReturnZero() || FD->hasAttr<NakedAttr>()) @@ -8068,7 +8881,9 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, if (PP.getDiagnostics().hasErrorOccurred() || PP.getDiagnostics().getSuppressAllDiagnostics()) { DiscardCleanupsInEvaluationContext(); - } else if (!isa<FunctionTemplateDecl>(dcl)) { + } + if (!PP.getDiagnostics().hasUncompilableErrorOccurred() && + !isa<FunctionTemplateDecl>(dcl)) { // Since the body is valid, issue any analysis-based warnings that are // enabled. ActivePolicy = &WP; @@ -8125,8 +8940,8 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, // this name as a function or variable. If so, use that // (non-visible) declaration, and complain about it. llvm::DenseMap<DeclarationName, NamedDecl *>::iterator Pos - = findLocallyScopedExternalDecl(&II); - if (Pos != LocallyScopedExternalDecls.end()) { + = 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; @@ -8202,7 +9017,7 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, DeclContext *PrevDC = CurContext; CurContext = Context.getTranslationUnitDecl(); - FunctionDecl *FD = dyn_cast<FunctionDecl>(ActOnDeclarator(TUScope, D)); + FunctionDecl *FD = cast<FunctionDecl>(ActOnDeclarator(TUScope, D)); FD->setImplicit(); CurContext = PrevDC; @@ -8376,9 +9191,13 @@ bool Sema::CheckEnumUnderlyingType(TypeSourceInfo *TI) { SourceLocation UnderlyingLoc = TI->getTypeLoc().getBeginLoc(); QualType T = TI->getType(); - if (T->isDependentType() || T->isIntegralType(Context)) + if (T->isDependentType()) return false; + if (const BuiltinType *BT = T->getAs<BuiltinType>()) + if (BT->isInteger()) + return false; + Diag(UnderlyingLoc, diag::err_enum_invalid_underlying) << T; return true; } @@ -8575,6 +9394,11 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, TUK == TUK_Friend, isExplicitSpecialization, Invalid)) { + if (Kind == TTK_Enum) { + Diag(KWLoc, diag::err_enum_template); + return 0; + } + if (TemplateParams->size() > 0) { // This is a declaration or definition of a class template (which may // be a member of another template). @@ -8703,6 +9527,8 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // shouldn't be diagnosing. LookupName(Previous, S); + // When declaring or defining a tag, ignore ambiguities introduced + // by types using'ed into this scope. if (Previous.isAmbiguous() && (TUK == TUK_Definition || TUK == TUK_Declaration)) { LookupResult::Filter F = Previous.makeFilter(); @@ -8713,6 +9539,27 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, } F.done(); } + + // C++11 [namespace.memdef]p3: + // If the name in a friend declaration is neither qualified nor + // a template-id and the declaration is a function or an + // elaborated-type-specifier, the lookup to determine whether + // the entity has been previously declared shall not consider + // any scopes outside the innermost enclosing namespace. + // + // Does it matter that this should be by scope instead of by + // semantic context? + if (!Previous.empty() && TUK == TUK_Friend) { + DeclContext *EnclosingNS = SearchDC->getEnclosingNamespaceContext(); + LookupResult::Filter F = Previous.makeFilter(); + while (F.hasNext()) { + NamedDecl *ND = F.next(); + DeclContext *DC = ND->getDeclContext()->getRedeclContext(); + if (DC->isFileContext() && !EnclosingNS->Encloses(ND->getDeclContext())) + F.erase(); + } + F.done(); + } // Note: there used to be some attempt at recovery here. if (Previous.isAmbiguous()) @@ -9070,7 +9917,8 @@ CreateNewDecl: // If this is an undefined enum, warn. if (TUK != TUK_Definition && !Invalid) { TagDecl *Def; - if (getLangOpts().CPlusPlus0x && cast<EnumDecl>(New)->isFixed()) { + if ((getLangOpts().CPlusPlus11 || getLangOpts().ObjC2) && + cast<EnumDecl>(New)->isFixed()) { // C++0x: 7.2p2: opaque-enum-declaration. // Conflicts are diagnosed above. Do nothing. } @@ -9250,7 +10098,9 @@ CreateNewDecl: AddPushedVisibilityAttribute(New); OwnedDecl = true; - return New; + // In C++, don't return an invalid declaration. We can't recover well from + // the cases where we make the type anonymous. + return (Invalid && getLangOpts().CPlusPlus) ? 0 : New; } void Sema::ActOnTagStartDefinition(Scope *S, Decl *TagD) { @@ -9330,7 +10180,11 @@ void Sema::ActOnTagFinishDefinition(Scope *S, Decl *TagD, // Exit this scope of this tag's definition. PopDeclContext(); - + + if (getCurLexicalContext()->isObjCContainer() && + Tag->getDeclContext()->isFileContext()) + Tag->setTopLevelDeclInObjCContainer(); + // Notify the consumer that we've defined a tag. Consumer.HandleTagDeclDefinition(Tag); } @@ -9479,14 +10333,24 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record, } } - DiagnoseFunctionSpecifiers(D); + // TR 18037 does not allow fields to be declared with address spaces. + if (T.getQualifiers().hasAddressSpace()) { + Diag(Loc, diag::err_field_with_address_space); + D.setInvalidType(); + } + + // OpenCL 1.2 spec, s6.9 r: + // The event type cannot be used to declare a structure or union field. + if (LangOpts.OpenCL && T->isEventT()) { + Diag(Loc, diag::err_event_t_struct_field); + D.setInvalidType(); + } + + DiagnoseFunctionSpecifiers(D.getDeclSpec()); if (D.getDeclSpec().isThreadSpecified()) Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_invalid_thread); - if (D.getDeclSpec().isConstexprSpecified()) - Diag(D.getDeclSpec().getConstexprSpecLoc(), diag::err_invalid_constexpr) - << 2; - + // Check to see if this name was declared as a member previously NamedDecl *PrevDecl = 0; LookupResult Previous(*this, II, Loc, LookupMemberName, ForRedeclaration); @@ -9587,6 +10451,12 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, } } + // OpenCL v1.2 s6.9.c: bitfields are not supported. + if (BitWidth && getLangOpts().OpenCL) { + Diag(Loc, diag::err_opencl_bitfields); + InvalidDecl = true; + } + // C99 6.7.2.1p8: A member of a structure or union may have any type other // than a variably modified type. if (!InvalidDecl && T->isVariablyModifiedType()) { @@ -9686,10 +10556,14 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, // FIXME: We need to pass in the attributes given an AST // representation, not a parser representation. - if (D) + if (D) { // FIXME: What to pass instead of TUScope? ProcessDeclAttributes(TUScope, NewFD, *D); + if (NewFD->hasAttrs()) + CheckAlignasUnderalignment(NewFD); + } + // In auto-retain/release, infer strong retension for fields of // retainable type. if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(NewFD)) @@ -9711,24 +10585,29 @@ bool Sema::CheckNontrivialField(FieldDecl *FD) { QualType EltTy = Context.getBaseElementType(FD->getType()); if (const RecordType *RT = EltTy->getAs<RecordType>()) { - CXXRecordDecl* RDecl = cast<CXXRecordDecl>(RT->getDecl()); + CXXRecordDecl *RDecl = cast<CXXRecordDecl>(RT->getDecl()); if (RDecl->getDefinition()) { // We check for copy constructors before constructors // because otherwise we'll never get complaints about // copy constructors. CXXSpecialMember member = CXXInvalid; - if (!RDecl->hasTrivialCopyConstructor()) + // We're required to check for any non-trivial constructors. Since the + // implicit default constructor is suppressed if there are any + // user-declared constructors, we just need to check that there is a + // trivial default constructor and a trivial copy constructor. (We don't + // worry about move constructors here, since this is a C++98 check.) + if (RDecl->hasNonTrivialCopyConstructor()) member = CXXCopyConstructor; else if (!RDecl->hasTrivialDefaultConstructor()) member = CXXDefaultConstructor; - else if (!RDecl->hasTrivialCopyAssignment()) + else if (RDecl->hasNonTrivialCopyAssignment()) member = CXXCopyAssignment; - else if (!RDecl->hasTrivialDestructor()) + else if (RDecl->hasNonTrivialDestructor()) member = CXXDestructor; if (member != CXXInvalid) { - if (!getLangOpts().CPlusPlus0x && + if (!getLangOpts().CPlusPlus11 && getLangOpts().ObjCAutoRefCount && RDecl->hasObjectMember()) { // Objective-C++ ARC: it is an error to have a non-trivial field of // a union. However, system headers in Objective-C programs @@ -9744,192 +10623,17 @@ bool Sema::CheckNontrivialField(FieldDecl *FD) { } } - Diag(FD->getLocation(), getLangOpts().CPlusPlus0x ? + Diag(FD->getLocation(), getLangOpts().CPlusPlus11 ? diag::warn_cxx98_compat_nontrivial_union_or_anon_struct_member : diag::err_illegal_union_or_anon_struct_member) << (int)FD->getParent()->isUnion() << FD->getDeclName() << member; - DiagnoseNontrivial(RT, member); - return !getLangOpts().CPlusPlus0x; - } - } - } - - return false; -} - -/// If the given constructor is user-declared, produce a diagnostic explaining -/// that it makes the class non-trivial. -static bool diagnoseNonTrivialUserDeclaredCtor(Sema &S, QualType QT, - CXXConstructorDecl *CD, - Sema::CXXSpecialMember CSM) { - if (CD->isImplicit()) - return false; - - SourceLocation CtorLoc = CD->getLocation(); - S.Diag(CtorLoc, diag::note_nontrivial_user_defined) << QT << CSM; - return true; -} - -/// DiagnoseNontrivial - Given that a class has a non-trivial -/// special member, figure out why. -void Sema::DiagnoseNontrivial(const RecordType* T, CXXSpecialMember member) { - QualType QT(T, 0U); - CXXRecordDecl* RD = cast<CXXRecordDecl>(T->getDecl()); - - // Check whether the member was user-declared. - switch (member) { - case CXXInvalid: - break; - - case CXXDefaultConstructor: - if (RD->hasUserDeclaredConstructor()) { - typedef CXXRecordDecl::ctor_iterator ctor_iter; - for (ctor_iter CI = RD->ctor_begin(), CE = RD->ctor_end(); CI != CE; ++CI) - if (diagnoseNonTrivialUserDeclaredCtor(*this, QT, *CI, member)) - return; - - // No user-delcared constructors; look for constructor templates. - typedef CXXRecordDecl::specific_decl_iterator<FunctionTemplateDecl> - tmpl_iter; - for (tmpl_iter TI(RD->decls_begin()), TE(RD->decls_end()); - TI != TE; ++TI) { - CXXConstructorDecl *CD = - dyn_cast<CXXConstructorDecl>(TI->getTemplatedDecl()); - if (CD && diagnoseNonTrivialUserDeclaredCtor(*this, QT, CD, member)) - return; - } - } - break; - - case CXXCopyConstructor: - if (RD->hasUserDeclaredCopyConstructor()) { - SourceLocation CtorLoc = - RD->getCopyConstructor(0)->getLocation(); - Diag(CtorLoc, diag::note_nontrivial_user_defined) << QT << member; - return; - } - break; - - case CXXMoveConstructor: - if (RD->hasUserDeclaredMoveConstructor()) { - SourceLocation CtorLoc = RD->getMoveConstructor()->getLocation(); - Diag(CtorLoc, diag::note_nontrivial_user_defined) << QT << member; - return; - } - break; - - case CXXCopyAssignment: - if (RD->hasUserDeclaredCopyAssignment()) { - SourceLocation AssignLoc = - RD->getCopyAssignmentOperator(0)->getLocation(); - Diag(AssignLoc, diag::note_nontrivial_user_defined) << QT << member; - return; - } - break; - - case CXXMoveAssignment: - if (RD->hasUserDeclaredMoveAssignment()) { - SourceLocation AssignLoc = RD->getMoveAssignmentOperator()->getLocation(); - Diag(AssignLoc, diag::note_nontrivial_user_defined) << QT << member; - return; - } - break; - - case CXXDestructor: - if (RD->hasUserDeclaredDestructor()) { - SourceLocation DtorLoc = LookupDestructor(RD)->getLocation(); - Diag(DtorLoc, diag::note_nontrivial_user_defined) << QT << member; - return; - } - break; - } - - typedef CXXRecordDecl::base_class_iterator base_iter; - - // Virtual bases and members inhibit trivial copying/construction, - // but not trivial destruction. - if (member != CXXDestructor) { - // Check for virtual bases. vbases includes indirect virtual bases, - // so we just iterate through the direct bases. - for (base_iter bi = RD->bases_begin(), be = RD->bases_end(); bi != be; ++bi) - if (bi->isVirtual()) { - SourceLocation BaseLoc = bi->getLocStart(); - Diag(BaseLoc, diag::note_nontrivial_has_virtual) << QT << 1; - return; - } - - // Check for virtual methods. - typedef CXXRecordDecl::method_iterator meth_iter; - for (meth_iter mi = RD->method_begin(), me = RD->method_end(); mi != me; - ++mi) { - if (mi->isVirtual()) { - SourceLocation MLoc = mi->getLocStart(); - Diag(MLoc, diag::note_nontrivial_has_virtual) << QT << 0; - return; - } - } - } - - bool (CXXRecordDecl::*hasTrivial)() const; - switch (member) { - case CXXDefaultConstructor: - hasTrivial = &CXXRecordDecl::hasTrivialDefaultConstructor; break; - case CXXCopyConstructor: - hasTrivial = &CXXRecordDecl::hasTrivialCopyConstructor; break; - case CXXCopyAssignment: - hasTrivial = &CXXRecordDecl::hasTrivialCopyAssignment; break; - case CXXDestructor: - hasTrivial = &CXXRecordDecl::hasTrivialDestructor; break; - default: - llvm_unreachable("unexpected special member"); - } - - // Check for nontrivial bases (and recurse). - for (base_iter bi = RD->bases_begin(), be = RD->bases_end(); bi != be; ++bi) { - const RecordType *BaseRT = bi->getType()->getAs<RecordType>(); - assert(BaseRT && "Don't know how to handle dependent bases"); - CXXRecordDecl *BaseRecTy = cast<CXXRecordDecl>(BaseRT->getDecl()); - if (!(BaseRecTy->*hasTrivial)()) { - SourceLocation BaseLoc = bi->getLocStart(); - Diag(BaseLoc, diag::note_nontrivial_has_nontrivial) << QT << 1 << member; - DiagnoseNontrivial(BaseRT, member); - return; - } - } - - // Check for nontrivial members (and recurse). - typedef RecordDecl::field_iterator field_iter; - for (field_iter fi = RD->field_begin(), fe = RD->field_end(); fi != fe; - ++fi) { - QualType EltTy = Context.getBaseElementType(fi->getType()); - if (const RecordType *EltRT = EltTy->getAs<RecordType>()) { - CXXRecordDecl* EltRD = cast<CXXRecordDecl>(EltRT->getDecl()); - - if (!(EltRD->*hasTrivial)()) { - SourceLocation FLoc = fi->getLocation(); - Diag(FLoc, diag::note_nontrivial_has_nontrivial) << QT << 0 << member; - DiagnoseNontrivial(EltRT, member); - return; - } - } - - if (EltTy->isObjCLifetimeType()) { - switch (EltTy.getObjCLifetime()) { - case Qualifiers::OCL_None: - case Qualifiers::OCL_ExplicitNone: - break; - - case Qualifiers::OCL_Autoreleasing: - case Qualifiers::OCL_Weak: - case Qualifiers::OCL_Strong: - Diag(fi->getLocation(), diag::note_nontrivial_objc_ownership) - << QT << EltTy.getObjCLifetime(); - return; + DiagnoseNontrivial(RDecl, member); + return !getLangOpts().CPlusPlus11; } } } - llvm_unreachable("found no explanation for non-trivial member"); + return false; } /// TranslateIvarVisibility - Translate visibility from a token ID to an @@ -10058,8 +10762,8 @@ Decl *Sema::ActOnIvar(Scope *S, } /// ActOnLastBitfield - This routine handles synthesized bitfields rules for -/// class and class extensions. For every class @interface and class -/// extension @interface, if the last ivar is a bitfield of any type, +/// class and class extensions. For every class \@interface and class +/// extension \@interface, if the last ivar is a bitfield of any type, /// then add an implicit `char :0` ivar to the end of that interface. void Sema::ActOnLastBitfield(SourceLocation DeclLoc, SmallVectorImpl<Decl *> &AllIvarDecls) { @@ -10259,52 +10963,54 @@ void Sema::ActOnFields(Scope* S, } if (Record && FDTTy->getDecl()->hasObjectMember()) Record->setHasObjectMember(true); + if (Record && FDTTy->getDecl()->hasVolatileMember()) + Record->setHasVolatileMember(true); } else if (FDTy->isObjCObjectType()) { /// A field cannot be an Objective-c object Diag(FD->getLocation(), diag::err_statically_allocated_object) << FixItHint::CreateInsertion(FD->getLocation(), "*"); QualType T = Context.getObjCObjectPointerType(FD->getType()); FD->setType(T); - } else if (!getLangOpts().CPlusPlus) { - if (getLangOpts().ObjCAutoRefCount && Record && !ARCErrReported) { - // It's an error in ARC if a field has lifetime. - // We don't want to report this in a system header, though, - // so we just make the field unavailable. - // FIXME: that's really not sufficient; we need to make the type - // itself invalid to, say, initialize or copy. - QualType T = FD->getType(); - Qualifiers::ObjCLifetime lifetime = T.getObjCLifetime(); - if (lifetime && lifetime != Qualifiers::OCL_ExplicitNone) { - SourceLocation loc = FD->getLocation(); - if (getSourceManager().isInSystemHeader(loc)) { - if (!FD->hasAttr<UnavailableAttr>()) { - FD->addAttr(new (Context) UnavailableAttr(loc, Context, - "this system field has retaining ownership")); - } - } else { - Diag(FD->getLocation(), diag::err_arc_objc_object_in_struct) - << T->isBlockPointerType(); + } else if (getLangOpts().ObjCAutoRefCount && Record && !ARCErrReported && + (!getLangOpts().CPlusPlus || Record->isUnion())) { + // It's an error in ARC if a field has lifetime. + // We don't want to report this in a system header, though, + // so we just make the field unavailable. + // FIXME: that's really not sufficient; we need to make the type + // itself invalid to, say, initialize or copy. + QualType T = FD->getType(); + Qualifiers::ObjCLifetime lifetime = T.getObjCLifetime(); + if (lifetime && lifetime != Qualifiers::OCL_ExplicitNone) { + SourceLocation loc = FD->getLocation(); + if (getSourceManager().isInSystemHeader(loc)) { + if (!FD->hasAttr<UnavailableAttr>()) { + FD->addAttr(new (Context) UnavailableAttr(loc, Context, + "this system field has retaining ownership")); } - ARCErrReported = true; + } else { + Diag(FD->getLocation(), diag::err_arc_objc_object_in_tag) + << T->isBlockPointerType() << Record->getTagKind(); } + ARCErrReported = true; } - else if (getLangOpts().ObjC1 && + } else if (getLangOpts().ObjC1 && getLangOpts().getGC() != LangOptions::NonGC && Record && !Record->hasObjectMember()) { - if (FD->getType()->isObjCObjectPointerType() || - FD->getType().isObjCGCStrong()) + if (FD->getType()->isObjCObjectPointerType() || + FD->getType().isObjCGCStrong()) + Record->setHasObjectMember(true); + else if (Context.getAsArrayType(FD->getType())) { + QualType BaseType = Context.getBaseElementType(FD->getType()); + if (BaseType->isRecordType() && + BaseType->getAs<RecordType>()->getDecl()->hasObjectMember()) Record->setHasObjectMember(true); - else if (Context.getAsArrayType(FD->getType())) { - QualType BaseType = Context.getBaseElementType(FD->getType()); - if (BaseType->isRecordType() && - BaseType->getAs<RecordType>()->getDecl()->hasObjectMember()) - Record->setHasObjectMember(true); - else if (BaseType->isObjCObjectPointerType() || - BaseType.isObjCGCStrong()) - Record->setHasObjectMember(true); - } + else if (BaseType->isObjCObjectPointerType() || + BaseType.isObjCGCStrong()) + Record->setHasObjectMember(true); } } + if (Record && FD->getType().isVolatileQualified()) + Record->setHasVolatileMember(true); // Keep track of the number of named members. if (FD->getIdentifier()) ++NumNamedMembers; @@ -10316,14 +11022,14 @@ void Sema::ActOnFields(Scope* S, if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(Record)) { if (!CXXRecord->isInvalidDecl()) { // Set access bits correctly on the directly-declared conversions. - UnresolvedSetImpl *Convs = CXXRecord->getConversionFunctions(); - for (UnresolvedSetIterator I = Convs->begin(), E = Convs->end(); - I != E; ++I) - Convs->setAccess(I, (*I)->getAccess()); + for (CXXRecordDecl::conversion_iterator + I = CXXRecord->conversion_begin(), + E = CXXRecord->conversion_end(); I != E; ++I) + I.setAccess((*I)->getAccess()); if (!CXXRecord->isDependentType()) { // Adjust user-defined destructor exception spec. - if (getLangOpts().CPlusPlus0x && + if (getLangOpts().CPlusPlus11 && CXXRecord->hasUserDeclaredDestructor()) AdjustDestructorExceptionSpec(CXXRecord,CXXRecord->getDestructor()); @@ -10376,6 +11082,8 @@ void Sema::ActOnFields(Scope* S, if (!Completed) Record->completeDefinition(); + if (Record->hasAttrs()) + CheckAlignasUnderalignment(Record); } else { ObjCIvarDecl **ClsFields = reinterpret_cast<ObjCIvarDecl**>(RecFields.data()); @@ -10418,11 +11126,12 @@ void Sema::ActOnFields(Scope* S, Diag(ClsIvar->getLocation(), diag::note_previous_definition); continue; } - for (const ObjCCategoryDecl *ClsExtDecl = - IDecl->getFirstClassExtension(); - ClsExtDecl; ClsExtDecl = ClsExtDecl->getNextClassExtension()) { - if (const ObjCIvarDecl *ClsExtIvar = - ClsExtDecl->getIvarDecl(ClsFields[i]->getIdentifier())) { + for (ObjCInterfaceDecl::known_extensions_iterator + Ext = IDecl->known_extensions_begin(), + ExtEnd = IDecl->known_extensions_end(); + Ext != ExtEnd; ++Ext) { + if (const ObjCIvarDecl *ClsExtIvar + = Ext->getIvarDecl(ClsFields[i]->getIdentifier())) { Diag(ClsFields[i]->getLocation(), diag::err_duplicate_ivar_declaration); Diag(ClsExtIvar->getLocation(), diag::note_previous_definition); @@ -10503,7 +11212,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum, EltTy = Context.DependentTy; else { SourceLocation ExpLoc; - if (getLangOpts().CPlusPlus0x && Enum->isFixed() && + if (getLangOpts().CPlusPlus11 && Enum->isFixed() && !getLangOpts().MicrosoftMode) { // C++11 [dcl.enum]p5: If the underlying type is fixed, [...] the // constant-expression in the enumerator-definition shall be a converted @@ -10722,6 +11431,182 @@ Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst, return New; } +// Returns true when the enum initial expression does not trigger the +// duplicate enum warning. A few common cases are exempted as follows: +// Element2 = Element1 +// Element2 = Element1 + 1 +// Element2 = Element1 - 1 +// Where Element2 and Element1 are from the same enum. +static bool ValidDuplicateEnum(EnumConstantDecl *ECD, EnumDecl *Enum) { + Expr *InitExpr = ECD->getInitExpr(); + if (!InitExpr) + return true; + InitExpr = InitExpr->IgnoreImpCasts(); + + if (BinaryOperator *BO = dyn_cast<BinaryOperator>(InitExpr)) { + if (!BO->isAdditiveOp()) + return true; + IntegerLiteral *IL = dyn_cast<IntegerLiteral>(BO->getRHS()); + if (!IL) + return true; + if (IL->getValue() != 1) + return true; + + InitExpr = BO->getLHS(); + } + + // This checks if the elements are from the same enum. + DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(InitExpr); + if (!DRE) + return true; + + EnumConstantDecl *EnumConstant = dyn_cast<EnumConstantDecl>(DRE->getDecl()); + if (!EnumConstant) + return true; + + if (cast<EnumDecl>(TagDecl::castFromDeclContext(ECD->getDeclContext())) != + Enum) + return true; + + return false; +} + +struct DupKey { + int64_t val; + bool isTombstoneOrEmptyKey; + DupKey(int64_t val, bool isTombstoneOrEmptyKey) + : val(val), isTombstoneOrEmptyKey(isTombstoneOrEmptyKey) {} +}; + +static DupKey GetDupKey(const llvm::APSInt& Val) { + return DupKey(Val.isSigned() ? Val.getSExtValue() : Val.getZExtValue(), + false); +} + +struct DenseMapInfoDupKey { + static DupKey getEmptyKey() { return DupKey(0, true); } + static DupKey getTombstoneKey() { return DupKey(1, true); } + static unsigned getHashValue(const DupKey Key) { + return (unsigned)(Key.val * 37); + } + static bool isEqual(const DupKey& LHS, const DupKey& RHS) { + return LHS.isTombstoneOrEmptyKey == RHS.isTombstoneOrEmptyKey && + LHS.val == RHS.val; + } +}; + +// Emits a warning when an element is implicitly set a value that +// a previous element has already been set to. +static void CheckForDuplicateEnumValues(Sema &S, Decl **Elements, + unsigned NumElements, EnumDecl *Enum, + QualType EnumType) { + if (S.Diags.getDiagnosticLevel(diag::warn_duplicate_enum_values, + Enum->getLocation()) == + DiagnosticsEngine::Ignored) + return; + // Avoid anonymous enums + if (!Enum->getIdentifier()) + return; + + // Only check for small enums. + if (Enum->getNumPositiveBits() > 63 || Enum->getNumNegativeBits() > 64) + return; + + typedef SmallVector<EnumConstantDecl *, 3> ECDVector; + typedef SmallVector<ECDVector *, 3> DuplicatesVector; + + typedef llvm::PointerUnion<EnumConstantDecl*, ECDVector*> DeclOrVector; + typedef llvm::DenseMap<DupKey, DeclOrVector, DenseMapInfoDupKey> + ValueToVectorMap; + + DuplicatesVector DupVector; + ValueToVectorMap EnumMap; + + // Populate the EnumMap with all values represented by enum constants without + // an initialier. + for (unsigned i = 0; i < NumElements; ++i) { + EnumConstantDecl *ECD = cast<EnumConstantDecl>(Elements[i]); + + // Null EnumConstantDecl means a previous diagnostic has been emitted for + // this constant. Skip this enum since it may be ill-formed. + if (!ECD) { + return; + } + + if (ECD->getInitExpr()) + continue; + + DupKey Key = GetDupKey(ECD->getInitVal()); + DeclOrVector &Entry = EnumMap[Key]; + + // First time encountering this value. + if (Entry.isNull()) + Entry = ECD; + } + + // Create vectors for any values that has duplicates. + for (unsigned i = 0; i < NumElements; ++i) { + EnumConstantDecl *ECD = cast<EnumConstantDecl>(Elements[i]); + if (!ValidDuplicateEnum(ECD, Enum)) + continue; + + DupKey Key = GetDupKey(ECD->getInitVal()); + + DeclOrVector& Entry = EnumMap[Key]; + if (Entry.isNull()) + continue; + + if (EnumConstantDecl *D = Entry.dyn_cast<EnumConstantDecl*>()) { + // Ensure constants are different. + if (D == ECD) + continue; + + // Create new vector and push values onto it. + ECDVector *Vec = new ECDVector(); + Vec->push_back(D); + Vec->push_back(ECD); + + // Update entry to point to the duplicates vector. + Entry = Vec; + + // Store the vector somewhere we can consult later for quick emission of + // diagnostics. + DupVector.push_back(Vec); + continue; + } + + ECDVector *Vec = Entry.get<ECDVector*>(); + // Make sure constants are not added more than once. + if (*Vec->begin() == ECD) + continue; + + Vec->push_back(ECD); + } + + // Emit diagnostics. + for (DuplicatesVector::iterator DupVectorIter = DupVector.begin(), + DupVectorEnd = DupVector.end(); + DupVectorIter != DupVectorEnd; ++DupVectorIter) { + ECDVector *Vec = *DupVectorIter; + assert(Vec->size() > 1 && "ECDVector should have at least 2 elements."); + + // Emit warning for one enum constant. + ECDVector::iterator I = Vec->begin(); + S.Diag((*I)->getLocation(), diag::warn_duplicate_enum_values) + << (*I)->getName() << (*I)->getInitVal().toString(10) + << (*I)->getSourceRange(); + ++I; + + // Emit one note for each of the remaining enum constants with + // the same value. + for (ECDVector::iterator E = Vec->end(); I != E; ++I) + S.Diag((*I)->getLocation(), diag::note_duplicate_element) + << (*I)->getName() << (*I)->getInitVal().toString(10) + << (*I)->getSourceRange(); + delete Vec; + } +} + void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, SourceLocation RBraceLoc, Decl *EnumDeclX, Decl **Elements, unsigned NumElements, @@ -10944,6 +11829,12 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, // it needs to go into the function scope. if (InFunctionDeclarator) DeclsInPrototypeScope.push_back(Enum); + + CheckForDuplicateEnumValues(*this, Elements, NumElements, Enum, EnumType); + + // Now that the enum type is defined, ensure it's not been underaligned. + if (Enum->hasAttrs()) + CheckAlignasUnderalignment(Enum); } Decl *Sema::ActOnFileScopeAsmDecl(Expr *expr, @@ -10967,7 +11858,7 @@ DeclResult Sema::ActOnModuleImport(SourceLocation AtLoc, if (!Mod) return true; - llvm::SmallVector<SourceLocation, 2> IdentifierLocs; + SmallVector<SourceLocation, 2> IdentifierLocs; Module *ModCheck = Mod; for (unsigned I = 0, N = Path.size(); I != N; ++I) { // If we've run out of module parents, just drop the remaining identifiers. @@ -10987,6 +11878,19 @@ DeclResult Sema::ActOnModuleImport(SourceLocation AtLoc, return Import; } +void Sema::createImplicitModuleImport(SourceLocation Loc, Module *Mod) { + // Create the implicit import declaration. + TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl(); + ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU, + Loc, Mod, Loc); + TU->addDecl(ImportD); + Consumer.HandleImplicitImportDecl(ImportD); + + // Make the module visible. + PP.getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, Loc, + /*Complain=*/false); +} + void Sema::ActOnPragmaRedefineExtname(IdentifierInfo* Name, IdentifierInfo* AliasName, SourceLocation PragmaLoc, |