diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp | 2332 |
1 files changed, 1461 insertions, 871 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp index d90a821..8b314b5 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaDecl.cpp @@ -18,7 +18,6 @@ #include "clang/Sema/Scope.h" #include "clang/Sema/ScopeInfo.h" #include "TypeLocBuilder.h" -#include "clang/AST/APValue.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" #include "clang/AST/CXXInheritance.h" @@ -40,6 +39,7 @@ #include "clang/Lex/Preprocessor.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/ModuleLoader.h" +#include "llvm/ADT/SmallString.h" #include "llvm/ADT/Triple.h" #include <algorithm> #include <cstring> @@ -56,6 +56,30 @@ Sema::DeclGroupPtrTy Sema::ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType) { return DeclGroupPtrTy::make(DeclGroupRef(Ptr)); } +namespace { + +class TypeNameValidatorCCC : public CorrectionCandidateCallback { + public: + TypeNameValidatorCCC(bool AllowInvalid) : AllowInvalidDecl(AllowInvalid) { + WantExpressionKeywords = false; + WantCXXNamedCasts = false; + WantRemainingKeywords = false; + } + + virtual bool ValidateCandidate(const TypoCorrection &candidate) { + if (NamedDecl *ND = candidate.getCorrectionDecl()) + return (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND)) && + (AllowInvalidDecl || !ND->isInvalidDecl()); + else + return candidate.isKeyword(); + } + + private: + bool AllowInvalidDecl; +}; + +} + /// \brief If the identifier refers to a type name within this scope, /// return the declaration of that type. /// @@ -71,6 +95,7 @@ ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS, bool isClassName, bool HasTrailingDot, ParsedType ObjectTypePtr, + bool IsCtorOrDtorName, bool WantNontrivialTypeSourceInfo, IdentifierInfo **CorrectedII) { // Determine where we will perform name lookup. @@ -93,7 +118,7 @@ ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc, // // We therefore do not perform any name lookup if the result would // refer to a member of an unknown specialization. - if (!isClassName) + if (!isClassName && !IsCtorOrDtorName) return ParsedType(); // We know from the grammar that this name refers to a type, @@ -148,9 +173,9 @@ ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc, case LookupResult::NotFound: case LookupResult::NotFoundInCurrentInstantiation: if (CorrectedII) { + TypeNameValidatorCCC Validator(true); TypoCorrection Correction = CorrectTypo(Result.getLookupNameInfo(), - Kind, S, SS, 0, false, - Sema::CTC_Type); + Kind, S, SS, Validator); IdentifierInfo *NewII = Correction.getCorrectionAsIdentifierInfo(); TemplateTy Template; bool MemberOfUnknownSpecialization; @@ -166,16 +191,17 @@ ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc, // Ignore a correction to a template type as the to-be-corrected // identifier is not a template (typo correction for template names // is handled elsewhere). - !(getLangOptions().CPlusPlus && NewSSPtr && + !(getLangOpts().CPlusPlus && NewSSPtr && isTemplateName(S, *NewSSPtr, false, TemplateName, ParsedType(), false, Template, MemberOfUnknownSpecialization))) { ParsedType Ty = getTypeName(*NewII, NameLoc, S, NewSSPtr, isClassName, HasTrailingDot, ObjectTypePtr, + IsCtorOrDtorName, WantNontrivialTypeSourceInfo); if (Ty) { - std::string CorrectedStr(Correction.getAsString(getLangOptions())); + std::string CorrectedStr(Correction.getAsString(getLangOpts())); std::string CorrectedQuotedStr( - Correction.getQuoted(getLangOptions())); + Correction.getQuoted(getLangOpts())); Diag(NameLoc, diag::err_unknown_typename_suggest) << Result.getLookupName() << CorrectedQuotedStr << FixItHint::CreateReplacement(SourceRange(NameLoc), @@ -249,8 +275,11 @@ ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc, if (T.isNull()) T = Context.getTypeDeclType(TD); - - if (SS && SS->isNotEmpty()) { + + // NOTE: avoid constructing an ElaboratedType(Loc) if this is a + // constructor or destructor name (in such a case, the scope specifier + // will be attached to the enclosing Expr or Decl node). + if (SS && SS->isNotEmpty() && !IsCtorOrDtorName) { if (WantNontrivialTypeSourceInfo) { // Construct a type with type-source information. TypeLocBuilder Builder; @@ -258,7 +287,7 @@ ParsedType Sema::getTypeName(IdentifierInfo &II, SourceLocation NameLoc, T = getElaboratedType(ETK_None, *SS, T); ElaboratedTypeLoc ElabTL = Builder.push<ElaboratedTypeLoc>(T); - ElabTL.setKeywordLoc(SourceLocation()); + ElabTL.setElaboratedKeywordLoc(SourceLocation()); ElabTL.setQualifierLoc(SS->getWithLocInContext(Context)); return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T)); } else { @@ -292,7 +321,6 @@ DeclSpec::TST Sema::isTagName(IdentifierInfo &II, Scope *S) { if (R.getResultKind() == LookupResult::Found) if (const TagDecl *TD = R.getAsSingle<TagDecl>()) { switch (TD->getTagKind()) { - default: return DeclSpec::TST_unspecified; case TTK_Struct: return DeclSpec::TST_struct; case TTK_Union: return DeclSpec::TST_union; case TTK_Class: return DeclSpec::TST_class; @@ -341,46 +369,44 @@ bool Sema::DiagnoseUnknownTypeName(const IdentifierInfo &II, // There may have been a typo in the name of the type. Look up typo // results, in case we have something that we can suggest. + TypeNameValidatorCCC Validator(false); if (TypoCorrection Corrected = CorrectTypo(DeclarationNameInfo(&II, IILoc), - LookupOrdinaryName, S, SS, NULL, - false, CTC_Type)) { - std::string CorrectedStr(Corrected.getAsString(getLangOptions())); - std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOptions())); + LookupOrdinaryName, S, SS, + Validator)) { + std::string CorrectedStr(Corrected.getAsString(getLangOpts())); + std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOpts())); if (Corrected.isKeyword()) { // We corrected to a keyword. // FIXME: Actually recover with the keyword we suggest, and emit a fix-it. Diag(IILoc, diag::err_unknown_typename_suggest) << &II << CorrectedQuotedStr; - return true; } else { NamedDecl *Result = Corrected.getCorrectionDecl(); - if ((isa<TypeDecl>(Result) || isa<ObjCInterfaceDecl>(Result)) && - !Result->isInvalidDecl()) { - // We found a similarly-named type or interface; suggest that. - if (!SS || !SS->isSet()) - Diag(IILoc, diag::err_unknown_typename_suggest) - << &II << CorrectedQuotedStr - << FixItHint::CreateReplacement(SourceRange(IILoc), CorrectedStr); - else if (DeclContext *DC = computeDeclContext(*SS, false)) - Diag(IILoc, diag::err_unknown_nested_typename_suggest) - << &II << DC << CorrectedQuotedStr << SS->getRange() - << FixItHint::CreateReplacement(SourceRange(IILoc), CorrectedStr); - else - llvm_unreachable("could not have corrected a typo here"); + // We found a similarly-named type or interface; suggest that. + if (!SS || !SS->isSet()) + Diag(IILoc, diag::err_unknown_typename_suggest) + << &II << CorrectedQuotedStr + << FixItHint::CreateReplacement(SourceRange(IILoc), CorrectedStr); + else if (DeclContext *DC = computeDeclContext(*SS, false)) + Diag(IILoc, diag::err_unknown_nested_typename_suggest) + << &II << DC << CorrectedQuotedStr << SS->getRange() + << FixItHint::CreateReplacement(SourceRange(IILoc), CorrectedStr); + else + llvm_unreachable("could not have corrected a typo here"); - Diag(Result->getLocation(), diag::note_previous_decl) - << CorrectedQuotedStr; - - SuggestedType = getTypeName(*Result->getIdentifier(), IILoc, S, SS, - false, false, ParsedType(), - /*NonTrivialTypeSourceInfo=*/true); - return true; - } + Diag(Result->getLocation(), diag::note_previous_decl) + << CorrectedQuotedStr; + + SuggestedType = getTypeName(*Result->getIdentifier(), IILoc, S, SS, + false, false, ParsedType(), + /*IsCtorOrDtorName=*/false, + /*NonTrivialTypeSourceInfo=*/true); } + return true; } - if (getLangOptions().CPlusPlus) { + if (getLangOpts().CPlusPlus) { // See if II is a class template that the user forgot to pass arguments to. UnqualifiedId Name; Name.setIdentifier(&II, IILoc); @@ -410,14 +436,15 @@ bool Sema::DiagnoseUnknownTypeName(const IdentifierInfo &II, << &II << DC << SS->getRange(); else if (isDependentScopeSpecifier(*SS)) { unsigned DiagID = diag::err_typename_missing; - if (getLangOptions().MicrosoftMode && isMicrosoftMissingTypename(SS, S)) + if (getLangOpts().MicrosoftMode && isMicrosoftMissingTypename(SS, S)) DiagID = diag::warn_typename_missing; Diag(SS->getRange().getBegin(), DiagID) << (NestedNameSpecifier *)SS->getScopeRep() << II.getName() << SourceRange(SS->getRange().getBegin(), IILoc) << FixItHint::CreateInsertion(SS->getRange().getBegin(), "typename "); - SuggestedType = ActOnTypenameType(S, SourceLocation(), *SS, II, IILoc).get(); + SuggestedType = ActOnTypenameType(S, SourceLocation(), *SS, II, IILoc) + .get(); } else { assert(SS && SS->isInvalid() && "Invalid scope specifier has already been diagnosed"); @@ -429,7 +456,7 @@ bool Sema::DiagnoseUnknownTypeName(const IdentifierInfo &II, /// \brief Determine whether the given result set contains either a type name /// or static bool isResultTypeOrTemplate(LookupResult &R, const Token &NextToken) { - bool CheckTemplate = R.getSema().getLangOptions().CPlusPlus && + bool CheckTemplate = R.getSema().getLangOpts().CPlusPlus && NextToken.is(tok::less); for (LookupResult::iterator I = R.begin(), IEnd = R.end(); I != IEnd; ++I) { @@ -481,7 +508,7 @@ Corrected: if (!SS.isSet() && NextToken.is(tok::l_paren)) { // In C++, this is an ADL-only call. // FIXME: Reference? - if (getLangOptions().CPlusPlus) + if (getLangOpts().CPlusPlus) return BuildDeclarationNameExpr(SS, Result, /*ADL=*/true); // C90 6.3.2.2: @@ -506,7 +533,7 @@ Corrected: // In C, we first see whether there is a tag type by the same name, in // which case it's likely that the user just forget to write "enum", // "struct", or "union". - if (!getLangOptions().CPlusPlus && !SecondTry) { + if (!getLangOpts().CPlusPlus && !SecondTry) { Result.clear(LookupTagName); LookupParsedName(Result, S, &SS); if (TagDecl *Tag = Result.getAsSingle<TagDecl>()) { @@ -535,7 +562,7 @@ Corrected: } Diag(NameLoc, diag::err_use_of_tag_name_without_tag) - << Name << TagName << getLangOptions().CPlusPlus + << Name << TagName << getLangOpts().CPlusPlus << FixItHint::CreateInsertion(NameLoc, FixItTagName); break; } @@ -547,17 +574,19 @@ Corrected: // close to this name. if (!SecondTry) { SecondTry = true; + CorrectionCandidateCallback DefaultValidator; if (TypoCorrection Corrected = CorrectTypo(Result.getLookupNameInfo(), - Result.getLookupKind(), S, &SS)) { + Result.getLookupKind(), S, + &SS, DefaultValidator)) { unsigned UnqualifiedDiag = diag::err_undeclared_var_use_suggest; unsigned QualifiedDiag = diag::err_no_member_suggest; - std::string CorrectedStr(Corrected.getAsString(getLangOptions())); - std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOptions())); + std::string CorrectedStr(Corrected.getAsString(getLangOpts())); + std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOpts())); NamedDecl *FirstDecl = Corrected.getCorrectionDecl(); NamedDecl *UnderlyingFirstDecl = FirstDecl? FirstDecl->getUnderlyingDecl() : 0; - if (getLangOptions().CPlusPlus && NextToken.is(tok::less) && + if (getLangOpts().CPlusPlus && NextToken.is(tok::less) && UnderlyingFirstDecl && isa<TemplateDecl>(UnderlyingFirstDecl)) { UnqualifiedDiag = diag::err_no_template_suggest; QualifiedDiag = diag::err_no_member_template_suggest; @@ -582,19 +611,19 @@ Corrected: // Update the name, so that the caller has the new name. Name = Corrected.getCorrectionAsIdentifierInfo(); + // Typo correction corrected to a keyword. + if (Corrected.isKeyword()) + return Corrected.getCorrectionAsIdentifierInfo(); + // Also update the LookupResult... // FIXME: This should probably go away at some point Result.clear(); Result.setLookupName(Corrected.getCorrection()); - if (FirstDecl) Result.addDecl(FirstDecl); - - // Typo correction corrected to a keyword. - if (Corrected.isKeyword()) - return Corrected.getCorrectionAsIdentifierInfo(); - - if (FirstDecl) + if (FirstDecl) { + Result.addDecl(FirstDecl); Diag(FirstDecl->getLocation(), diag::note_previous_decl) << CorrectedQuotedStr; + } // If we found an Objective-C instance variable, let // LookupInObjCMethod build the appropriate expression to @@ -614,7 +643,7 @@ Corrected: Result.suppressDiagnostics(); return NameClassification::Unknown(); - case LookupResult::NotFoundInCurrentInstantiation: + case LookupResult::NotFoundInCurrentInstantiation: { // We performed name lookup into the current instantiation, and there were // dependent bases, so we treat this result the same way as any other // dependent nested-name-specifier. @@ -629,7 +658,9 @@ Corrected: // perform some heroics to see if we actually have a // template-argument-list, which would indicate a missing 'template' // keyword here. - return BuildDependentDeclRefExpr(SS, NameInfo, /*TemplateArgs=*/0); + return BuildDependentDeclRefExpr(SS, /*TemplateKWLoc=*/SourceLocation(), + NameInfo, /*TemplateArgs=*/0); + } case LookupResult::Found: case LookupResult::FoundOverloaded: @@ -637,7 +668,7 @@ Corrected: break; case LookupResult::Ambiguous: - if (getLangOptions().CPlusPlus && NextToken.is(tok::less) && + if (getLangOpts().CPlusPlus && NextToken.is(tok::less) && hasAnyAcceptableTemplateNames(Result)) { // C++ [temp.local]p3: // A lookup that finds an injected-class-name (10.2) can result in an @@ -661,7 +692,7 @@ Corrected: return NameClassification::Error(); } - if (getLangOptions().CPlusPlus && NextToken.is(tok::less) && + if (getLangOpts().CPlusPlus && NextToken.is(tok::less) && (IsFilteredTemplateName || hasAnyAcceptableTemplateNames(Result))) { // C++ [temp.names]p3: // After name lookup (3.4) finds that a name is a template-name or that @@ -735,7 +766,7 @@ Corrected: } if (!Result.empty() && (*Result.begin())->isCXXClassMember()) - return BuildPossibleImplicitMemberExpr(SS, Result, 0); + return BuildPossibleImplicitMemberExpr(SS, SourceLocation(), Result, 0); bool ADL = UseArgumentDependentLookup(SS, Result, NextToken.is(tok::l_paren)); return BuildDeclarationNameExpr(SS, Result, ADL); @@ -841,7 +872,13 @@ void Sema::ActOnReenterFunctionContext(Scope* S, Decl *D) { if (!FD) return; - PushDeclContext(S, FD); + // Same implementation as PushDeclContext, but enters the context + // from the lexical parent, rather than the top-level class. + assert(CurContext == FD->getLexicalParent() && + "The next DeclContext should be lexically contained in the current one."); + CurContext = FD; + S->setEntity(CurContext); + for (unsigned P = 0, NumParams = FD->getNumParams(); P < NumParams; ++P) { ParmVarDecl *Param = FD->getParamDecl(P); // If the parameter has an identifier, then add it to the scope @@ -853,6 +890,15 @@ void Sema::ActOnReenterFunctionContext(Scope* S, Decl *D) { } +void Sema::ActOnExitFunctionContext() { + // Same implementation as PopDeclContext, but returns to the lexical parent, + // rather than the top-level class. + assert(CurContext && "DeclContext imbalance!"); + CurContext = CurContext->getLexicalParent(); + assert(CurContext && "Popped translation unit!"); +} + + /// \brief Determine whether we allow overloading of the function /// PrevDecl with another declaration. /// @@ -864,7 +910,7 @@ void Sema::ActOnReenterFunctionContext(Scope* S, Decl *D) { /// attribute. static bool AllowOverloadingOfFunction(LookupResult &Previous, ASTContext &Context) { - if (Context.getLangOptions().CPlusPlus) + if (Context.getLangOpts().CPlusPlus) return true; if (Previous.getResultKind() == LookupResult::FoundOverloaded) @@ -891,7 +937,7 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext) { // Out-of-line definitions shouldn't be pushed into scope in C++. // Out-of-line variable and function definitions shouldn't even in C. - if ((getLangOptions().CPlusPlus || isa<VarDecl>(D) || isa<FunctionDecl>(D)) && + if ((getLangOpts().CPlusPlus || isa<VarDecl>(D) || isa<FunctionDecl>(D)) && D->isOutOfLine() && !D->getDeclContext()->getRedeclContext()->Equals( D->getLexicalDeclContext()->getRedeclContext())) @@ -936,6 +982,11 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext) { } } +void Sema::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) { + if (IdResolver.tryAddTopLevelDecl(D, Name) && TUScope) + TUScope->AddDecl(D); +} + bool Sema::isDeclInScope(NamedDecl *&D, DeclContext *Ctx, Scope *S, bool ExplicitInstantiationOrSpecialization) { return IdResolver.isDeclInScope(D, Ctx, Context, S, @@ -1089,7 +1140,7 @@ static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) { if (D->isInvalidDecl()) return false; - if (D->isUsed() || D->hasAttr<UnusedAttr>()) + if (D->isReferenced() || D->isUsed() || D->hasAttr<UnusedAttr>()) return false; if (isa<LabelDecl>(D)) @@ -1101,7 +1152,7 @@ static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) { return false; // Types of valid local variables should be complete, so this should succeed. - if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) { + if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { // White-list anything with an __attribute__((unused)) type. QualType Ty = VD->getType(); @@ -1123,11 +1174,18 @@ static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) { return false; if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Tag)) { - // FIXME: Checking for the presence of a user-declared constructor - // isn't completely accurate; we'd prefer to check that the initializer - // has no side effects. - if (RD->hasUserDeclaredConstructor() || !RD->hasTrivialDestructor()) + if (!RD->hasTrivialDestructor()) return false; + + if (const Expr *Init = VD->getInit()) { + const CXXConstructExpr *Construct = + dyn_cast<CXXConstructExpr>(Init); + if (Construct && !Construct->isElidable()) { + CXXConstructorDecl *CD = Construct->getConstructor(); + if (!CD->isTrivial()) + return false; + } + } } } @@ -1141,7 +1199,7 @@ static void GenerateFixForUnusedDecl(const NamedDecl *D, ASTContext &Ctx, FixItHint &Hint) { if (isa<LabelDecl>(D)) { SourceLocation AfterColon = Lexer::findLocationAfterToken(D->getLocEnd(), - tok::colon, Ctx.getSourceManager(), Ctx.getLangOptions(), true); + tok::colon, Ctx.getSourceManager(), Ctx.getLangOpts(), true); if (AfterColon.isInvalid()) return; Hint = FixItHint::CreateRemoval(CharSourceRange:: @@ -1206,6 +1264,15 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { } } +void Sema::ActOnStartFunctionDeclarator() { + ++InFunctionDeclarator; +} + +void Sema::ActOnEndFunctionDeclarator() { + assert(InFunctionDeclarator); + --InFunctionDeclarator; +} + /// \brief Look for an Objective-C class in the translation unit. /// /// \param Id The name of the Objective-C class we're looking for. If @@ -1229,10 +1296,11 @@ ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *&Id, if (!IDecl && DoTypoCorrection) { // Perform typo correction at the given location, but only if we // find an Objective-C class name. - TypoCorrection C; - if ((C = CorrectTypo(DeclarationNameInfo(Id, IdLoc), LookupOrdinaryName, - TUScope, NULL, NULL, false, CTC_NoKeywords)) && - (IDecl = C.getCorrectionDeclAs<ObjCInterfaceDecl>())) { + DeclFilterCCC<ObjCInterfaceDecl> Validator; + if (TypoCorrection C = CorrectTypo(DeclarationNameInfo(Id, IdLoc), + LookupOrdinaryName, TUScope, NULL, + Validator)) { + IDecl = C.getCorrectionDeclAs<ObjCInterfaceDecl>(); Diag(IdLoc, diag::err_undef_interface_suggest) << Id << IDecl->getDeclName() << FixItHint::CreateReplacement(IdLoc, IDecl->getNameAsString()); @@ -1242,8 +1310,11 @@ ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *&Id, Id = IDecl->getIdentifier(); } } - - return dyn_cast_or_null<ObjCInterfaceDecl>(IDecl); + ObjCInterfaceDecl *Def = dyn_cast_or_null<ObjCInterfaceDecl>(IDecl); + // This routine must always return a class definition, if any. + if (Def && Def->getDefinition()) + Def = Def->getDefinition(); + return Def; } /// getNonFieldDeclScope - Retrieves the innermost scope, starting @@ -1273,7 +1344,7 @@ Scope *Sema::getNonFieldDeclScope(Scope *S) { while (((S->getFlags() & Scope::DeclScope) == 0) || (S->getEntity() && ((DeclContext *)S->getEntity())->isTransparentContext()) || - (S->isClassScope() && !getLangOptions().CPlusPlus)) + (S->isClassScope() && !getLangOpts().CPlusPlus)) S = S->getParent(); return S; } @@ -1362,6 +1433,40 @@ NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, return New; } +bool Sema::isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New) { + QualType OldType; + if (TypedefNameDecl *OldTypedef = dyn_cast<TypedefNameDecl>(Old)) + OldType = OldTypedef->getUnderlyingType(); + else + OldType = Context.getTypeDeclType(Old); + QualType NewType = New->getUnderlyingType(); + + if (NewType->isVariablyModifiedType()) { + // Must not redefine a typedef with a variably-modified type. + int Kind = isa<TypeAliasDecl>(Old) ? 1 : 0; + Diag(New->getLocation(), diag::err_redefinition_variably_modified_typedef) + << Kind << NewType; + if (Old->getLocation().isValid()) + Diag(Old->getLocation(), diag::note_previous_definition); + New->setInvalidDecl(); + return true; + } + + if (OldType != NewType && + !OldType->isDependentType() && + !NewType->isDependentType() && + !Context.hasSameType(OldType, NewType)) { + int Kind = isa<TypeAliasDecl>(Old) ? 1 : 0; + Diag(New->getLocation(), diag::err_redefinition_different_typedef) + << Kind << NewType << OldType; + if (Old->getLocation().isValid()) + Diag(Old->getLocation(), diag::note_previous_definition); + New->setInvalidDecl(); + return true; + } + return false; +} + /// MergeTypedefNameDecl - We just parsed a typedef 'New' which has the /// same name and scope as a previous declaration 'Old'. Figure out /// how to resolve this situation, merging decls or emitting @@ -1374,7 +1479,7 @@ void Sema::MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls) { // Allow multiple definitions for ObjC built-in typedefs. // FIXME: Verify the underlying types are equivalent! - if (getLangOptions().ObjC1) { + if (getLangOpts().ObjC1) { const IdentifierInfo *TypeID = New->getIdentifier(); switch (TypeID->getLength()) { default: break; @@ -1420,46 +1525,20 @@ void Sema::MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls) { if (Old->isInvalidDecl()) return New->setInvalidDecl(); - // Determine the "old" type we'll use for checking and diagnostics. - QualType OldType; - if (TypedefNameDecl *OldTypedef = dyn_cast<TypedefNameDecl>(Old)) - OldType = OldTypedef->getUnderlyingType(); - else - OldType = Context.getTypeDeclType(Old); - // If the typedef types are not identical, reject them in all languages and // with any extensions enabled. - - if (OldType != New->getUnderlyingType() && - Context.getCanonicalType(OldType) != - Context.getCanonicalType(New->getUnderlyingType())) { - int Kind = 0; - if (isa<TypeAliasDecl>(Old)) - Kind = 1; - Diag(New->getLocation(), diag::err_redefinition_different_typedef) - << Kind << New->getUnderlyingType() << OldType; - if (Old->getLocation().isValid()) - Diag(Old->getLocation(), diag::note_previous_definition); - return New->setInvalidDecl(); - } + if (isIncompatibleTypedef(Old, New)) + return; // The types match. Link up the redeclaration chain if the old // declaration was a typedef. - // FIXME: this is a potential source of weirdness if the type - // spellings don't match exactly. if (TypedefNameDecl *Typedef = dyn_cast<TypedefNameDecl>(Old)) New->setPreviousDeclaration(Typedef); - // __module_private__ is propagated to later declarations. - if (Old->isModulePrivate()) - New->setModulePrivate(); - else if (New->isModulePrivate()) - diagnoseModulePrivateRedeclaration(New, Old); - - if (getLangOptions().MicrosoftExt) + if (getLangOpts().MicrosoftExt) return; - if (getLangOptions().CPlusPlus) { + if (getLangOpts().CPlusPlus) { // C++ [dcl.typedef]p2: // In a given non-class scope, a typedef specifier can be used to // redefine the name of any type declared in that scope to refer @@ -1497,6 +1576,10 @@ void Sema::MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls) { return New->setInvalidDecl(); } + // Modules always permit redefinition of typedefs, as does C11. + if (getLangOpts().Modules || getLangOpts().C11) + return; + // If we have a redefinition of a typedef in C, emit a warning. This warning // is normally mapped to an error, but can be controlled with // -Wtypedef-redefinition. If either the original or the redefinition is @@ -1535,36 +1618,37 @@ DeclHasAttr(const Decl *D, const Attr *A) { } /// mergeDeclAttributes - Copy attributes from the Old decl to the New one. -static void mergeDeclAttributes(Decl *newDecl, const Decl *oldDecl, - ASTContext &C, bool mergeDeprecation = true) { - if (!oldDecl->hasAttrs()) +void Sema::mergeDeclAttributes(Decl *New, Decl *Old, + bool MergeDeprecation) { + if (!Old->hasAttrs()) return; - bool foundAny = newDecl->hasAttrs(); + bool foundAny = New->hasAttrs(); // Ensure that any moving of objects within the allocated map is done before // we process them. - if (!foundAny) newDecl->setAttrs(AttrVec()); + if (!foundAny) New->setAttrs(AttrVec()); for (specific_attr_iterator<InheritableAttr> - i = oldDecl->specific_attr_begin<InheritableAttr>(), - e = oldDecl->specific_attr_end<InheritableAttr>(); i != e; ++i) { + i = Old->specific_attr_begin<InheritableAttr>(), + e = Old->specific_attr_end<InheritableAttr>(); + i != e; ++i) { // Ignore deprecated/unavailable/availability attributes if requested. - if (!mergeDeprecation && + if (!MergeDeprecation && (isa<DeprecatedAttr>(*i) || isa<UnavailableAttr>(*i) || isa<AvailabilityAttr>(*i))) continue; - if (!DeclHasAttr(newDecl, *i)) { - InheritableAttr *newAttr = cast<InheritableAttr>((*i)->clone(C)); + if (!DeclHasAttr(New, *i)) { + InheritableAttr *newAttr = cast<InheritableAttr>((*i)->clone(Context)); newAttr->setInherited(true); - newDecl->addAttr(newAttr); + New->addAttr(newAttr); foundAny = true; } } - if (!foundAny) newDecl->dropAttrs(); + if (!foundAny) New->dropAttrs(); } /// mergeParamDeclAttributes - Copy attributes from the old parameter @@ -1651,7 +1735,7 @@ static bool canRedefineFunction(const FunctionDecl *FD, /// merged with. /// /// Returns true if there was an error, false otherwise. -bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) { +bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD, Scope *S) { // Verify the old decl was also a function. FunctionDecl *Old = 0; if (FunctionTemplateDecl *OldFunctionTemplate @@ -1693,8 +1777,8 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) { if (!isa<CXXMethodDecl>(New) && !isa<CXXMethodDecl>(Old) && New->getStorageClass() == SC_Static && Old->getStorageClass() != SC_Static && - !canRedefineFunction(Old, getLangOptions())) { - if (getLangOptions().MicrosoftExt) { + !canRedefineFunction(Old, getLangOpts())) { + if (getLangOpts().MicrosoftExt) { Diag(New->getLocation(), diag::warn_static_non_static) << New; Diag(Old->getLocation(), PrevDiag); } else { @@ -1776,7 +1860,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) { NewQType = Context.getCanonicalType(New->getType()); } - if (getLangOptions().CPlusPlus) { + if (getLangOpts().CPlusPlus) { // (C++98 13.1p2): // Certain function declarations cannot be overloaded: // -- Function declarations that differ only in the return type @@ -1881,14 +1965,14 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) { } if (OldQTypeForComparison == NewQType) - return MergeCompatibleFunctionDecls(New, Old); + return MergeCompatibleFunctionDecls(New, Old, S); // Fall through for conflicting redeclarations and redefinitions. } // C: Function types need to be compatible, not identical. This handles // duplicate function decls like "void f(int); void f(enum X);" properly. - if (!getLangOptions().CPlusPlus && + if (!getLangOpts().CPlusPlus && Context.typesAreCompatible(OldQType, NewQType)) { const FunctionType *OldFuncType = OldQType->getAs<FunctionType>(); const FunctionType *NewFuncType = NewQType->getAs<FunctionType>(); @@ -1926,7 +2010,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) { New->setParams(Params); } - return MergeCompatibleFunctionDecls(New, Old); + return MergeCompatibleFunctionDecls(New, Old, S); } // GNU C permits a K&R definition to follow a prototype declaration @@ -1940,7 +2024,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) { // the K&R definition becomes variadic. This is sort of an edge case, but // it's legal per the standard depending on how you read C99 6.7.5.3p15 and // C99 6.9.1p8. - if (!getLangOptions().CPlusPlus && + if (!getLangOpts().CPlusPlus && Old->hasPrototype() && !New->hasPrototype() && New->getType()->getAs<FunctionProtoType>() && Old->getNumParams() == New->getNumParams()) { @@ -1987,7 +2071,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) { New->setType(Context.getFunctionType(MergedReturn, &ArgTypes[0], ArgTypes.size(), OldProto->getExtProtoInfo())); - return MergeCompatibleFunctionDecls(New, Old); + return MergeCompatibleFunctionDecls(New, Old, S); } // Fall through to diagnose conflicting types. @@ -2028,9 +2112,10 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) { /// redeclaration of Old. /// /// \returns false -bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old) { +bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old, + Scope *S) { // Merge the attributes - mergeDeclAttributes(New, Old, Context); + mergeDeclAttributes(New, Old); // Merge the storage class. if (Old->getStorageClass() != SC_Extern && @@ -2041,12 +2126,6 @@ bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old) { if (Old->isPure()) New->setPure(); - // __module_private__ is propagated to later declarations. - if (Old->isModulePrivate()) - New->setModulePrivate(); - else if (New->isModulePrivate()) - diagnoseModulePrivateRedeclaration(New, Old); - // Merge attributes from the parameters. These can mismatch with K&R // declarations. if (New->getNumParams() == Old->getNumParams()) @@ -2054,21 +2133,21 @@ bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old) { mergeParamDeclAttributes(New->getParamDecl(i), Old->getParamDecl(i), Context); - if (getLangOptions().CPlusPlus) - return MergeCXXFunctionDecl(New, Old); + if (getLangOpts().CPlusPlus) + return MergeCXXFunctionDecl(New, Old, S); return false; } void Sema::mergeObjCMethodDecls(ObjCMethodDecl *newMethod, - const ObjCMethodDecl *oldMethod) { + ObjCMethodDecl *oldMethod) { // We don't want to merge unavailable and deprecated attributes // except from interface to implementation. bool mergeDeprecation = isa<ObjCImplDecl>(newMethod->getDeclContext()); // Merge the attributes. - mergeDeclAttributes(newMethod, oldMethod, Context, mergeDeprecation); + mergeDeclAttributes(newMethod, oldMethod, mergeDeprecation); // Merge attributes from the parameters. ObjCMethodDecl::param_const_iterator oi = oldMethod->param_begin(); @@ -2085,15 +2164,14 @@ void Sema::mergeObjCMethodDecls(ObjCMethodDecl *newMethod, /// emitting diagnostics as appropriate. /// /// Declarations using the auto type specifier (C++ [decl.spec.auto]) call back -/// to here in AddInitializerToDecl and AddCXXDirectInitializerToDecl. We can't -/// check them before the initializer is attached. -/// +/// to here in AddInitializerToDecl. We can't check them before the initializer +/// is attached. void Sema::MergeVarDeclTypes(VarDecl *New, VarDecl *Old) { if (New->isInvalidDecl() || Old->isInvalidDecl()) return; QualType MergedT; - if (getLangOptions().CPlusPlus) { + if (getLangOpts().CPlusPlus) { AutoType *AT = New->getType()->getContainedAutoType(); if (AT && !AT->isDeduced()) { // We don't know what the new type is until the initializer is attached. @@ -2175,8 +2253,9 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { New->setInvalidDecl(); } - mergeDeclAttributes(New, Old, Context); - // Warn if an already-declared variable is made a weak_import in a subsequent declaration + mergeDeclAttributes(New, Old); + // Warn if an already-declared variable is made a weak_import in a subsequent + // declaration if (New->getAttr<WeakImportAttr>() && Old->getStorageClass() == SC_None && !Old->getAttr<WeakImportAttr>()) { @@ -2230,12 +2309,6 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { return New->setInvalidDecl(); } - // __module_private__ is propagated to later declarations. - if (Old->isModulePrivate()) - New->setModulePrivate(); - else if (New->isModulePrivate()) - diagnoseModulePrivateRedeclaration(New, Old); - // Variables with external linkage are analyzed in FinalizeDeclaratorGroup. // FIXME: The test for external storage here seems wrong? We still @@ -2259,7 +2332,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { // C++ doesn't have tentative definitions, so go right ahead and check here. const VarDecl *Def; - if (getLangOptions().CPlusPlus && + if (getLangOpts().CPlusPlus && New->isThisDeclarationADefinition() == VarDecl::Definition && (Def = Old->getDefinition())) { Diag(New->getLocation(), diag::err_redefinition) @@ -2315,11 +2388,17 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, // Note that the above type specs guarantee that the // type rep is a Decl, whereas in many of the others // it's a Type. - Tag = dyn_cast<TagDecl>(TagD); + if (isa<TagDecl>(TagD)) + Tag = cast<TagDecl>(TagD); + else if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(TagD)) + Tag = CTD->getTemplatedDecl(); } - if (Tag) + if (Tag) { Tag->setFreeStanding(); + if (Tag->isInvalidDecl()) + return Tag; + } if (unsigned TypeQuals = DS.getTypeQualifiers()) { // Enforce C99 6.7.3p2: "Types other than pointer types derived from object @@ -2357,22 +2436,20 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, bool emittedWarning = false; if (RecordDecl *Record = dyn_cast_or_null<RecordDecl>(Tag)) { - ProcessDeclAttributeList(S, Record, DS.getAttributes().getList()); - if (!Record->getDeclName() && Record->isCompleteDefinition() && DS.getStorageClassSpec() != DeclSpec::SCS_typedef) { - if (getLangOptions().CPlusPlus || + if (getLangOpts().CPlusPlus || Record->getDeclContext()->isRecord()) return BuildAnonymousStructOrUnion(S, DS, AS, Record); - Diag(DS.getSourceRange().getBegin(), diag::ext_no_declarators) + Diag(DS.getLocStart(), diag::ext_no_declarators) << DS.getSourceRange(); emittedWarning = true; } } // Check for Microsoft C extension: anonymous struct. - if (getLangOptions().MicrosoftExt && !getLangOptions().CPlusPlus && + if (getLangOpts().MicrosoftExt && !getLangOpts().CPlusPlus && CurContext->isRecord() && DS.getStorageClassSpec() == DeclSpec::SCS_unspecified) { // Handle 2 kinds of anonymous struct: @@ -2383,13 +2460,13 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, if ((Record && Record->getDeclName() && !Record->isCompleteDefinition()) || (DS.getTypeSpecType() == DeclSpec::TST_typename && DS.getRepAsType().get()->isStructureType())) { - Diag(DS.getSourceRange().getBegin(), diag::ext_ms_anonymous_struct) + Diag(DS.getLocStart(), diag::ext_ms_anonymous_struct) << DS.getSourceRange(); return BuildMicrosoftCAnonymousStruct(S, DS, Record); } } - if (getLangOptions().CPlusPlus && + if (getLangOpts().CPlusPlus && DS.getStorageClassSpec() != DeclSpec::SCS_typedef) if (EnumDecl *Enum = dyn_cast_or_null<EnumDecl>(Tag)) if (Enum->enumerator_begin() == Enum->enumerator_end() && @@ -2407,12 +2484,12 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, // extension in both Microsoft and GNU. if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef && Tag && isa<EnumDecl>(Tag)) { - Diag(DS.getSourceRange().getBegin(), diag::ext_typedef_without_a_name) + Diag(DS.getLocStart(), diag::ext_typedef_without_a_name) << DS.getSourceRange(); return Tag; } - Diag(DS.getSourceRange().getBegin(), diag::ext_no_declarators) + Diag(DS.getLocStart(), diag::ext_no_declarators) << DS.getSourceRange(); emittedWarning = true; } @@ -2453,28 +2530,29 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, << Tag->getTagKind() << FixItHint::CreateRemoval(DS.getModulePrivateSpecLoc()); - // FIXME: Warn on useless attributes - - return TagD; -} - -/// ActOnVlaStmt - This rouine if finds a vla expression in a decl spec. -/// builds a statement for it and returns it so it is evaluated. -StmtResult Sema::ActOnVlaStmt(const DeclSpec &DS) { - StmtResult R; - if (DS.getTypeSpecType() == DeclSpec::TST_typeofExpr) { - Expr *Exp = DS.getRepAsExpr(); - QualType Ty = Exp->getType(); - if (Ty->isPointerType()) { - do - Ty = Ty->getAs<PointerType>()->getPointeeType(); - while (Ty->isPointerType()); - } - if (Ty->isVariableArrayType()) { - R = ActOnExprStmt(MakeFullExpr(Exp)); + // Warn about ignored type attributes, for example: + // __attribute__((aligned)) struct A; + // Attributes should be placed after tag to apply to type declaration. + if (!DS.getAttributes().empty()) { + DeclSpec::TST TypeSpecType = DS.getTypeSpecType(); + if (TypeSpecType == DeclSpec::TST_class || + TypeSpecType == DeclSpec::TST_struct || + TypeSpecType == DeclSpec::TST_union || + TypeSpecType == DeclSpec::TST_enum) { + AttributeList* attrs = DS.getAttributes().getList(); + while (attrs) { + Diag(attrs->getScopeLoc(), + diag::warn_declspec_attribute_ignored) + << attrs->getName() + << (TypeSpecType == DeclSpec::TST_class ? 0 : + TypeSpecType == DeclSpec::TST_struct ? 1 : + TypeSpecType == DeclSpec::TST_union ? 2 : 3); + attrs = attrs->getNext(); + } } } - return R; + + return TagD; } /// We are trying to inject an anonymous member into the given scope; @@ -2629,51 +2707,56 @@ StorageClassSpecToFunctionDeclStorageClass(DeclSpec::SCS StorageClassSpec) { /// BuildAnonymousStructOrUnion - Handle the declaration of an /// anonymous structure or union. Anonymous unions are a C++ feature -/// (C++ [class.union]) and a GNU C extension; anonymous structures -/// are a GNU C and GNU C++ extension. +/// (C++ [class.union]) and a C11 feature; anonymous structures +/// are a C11 feature and GNU C++ extension. Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, AccessSpecifier AS, RecordDecl *Record) { DeclContext *Owner = Record->getDeclContext(); // Diagnose whether this anonymous struct/union is an extension. - if (Record->isUnion() && !getLangOptions().CPlusPlus) + if (Record->isUnion() && !getLangOpts().CPlusPlus && !getLangOpts().C11) Diag(Record->getLocation(), diag::ext_anonymous_union); - else if (!Record->isUnion()) - Diag(Record->getLocation(), diag::ext_anonymous_struct); + else if (!Record->isUnion() && getLangOpts().CPlusPlus) + Diag(Record->getLocation(), diag::ext_gnu_anonymous_struct); + else if (!Record->isUnion() && !getLangOpts().C11) + Diag(Record->getLocation(), diag::ext_c11_anonymous_struct); // C and C++ require different kinds of checks for anonymous // structs/unions. bool Invalid = false; - if (getLangOptions().CPlusPlus) { + if (getLangOpts().CPlusPlus) { const char* PrevSpec = 0; unsigned DiagID; - // C++ [class.union]p3: - // Anonymous unions declared in a named namespace or in the - // global namespace shall be declared static. - if (DS.getStorageClassSpec() != DeclSpec::SCS_static && - (isa<TranslationUnitDecl>(Owner) || - (isa<NamespaceDecl>(Owner) && - cast<NamespaceDecl>(Owner)->getDeclName()))) { - Diag(Record->getLocation(), diag::err_anonymous_union_not_static); - Invalid = true; - - // Recover by adding 'static'. - DS.SetStorageClassSpec(*this, DeclSpec::SCS_static, SourceLocation(), - PrevSpec, DiagID); - } - // C++ [class.union]p3: - // A storage class is not allowed in a declaration of an - // anonymous union in a class scope. - else if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified && - isa<RecordDecl>(Owner)) { - Diag(DS.getStorageClassSpecLoc(), - diag::err_anonymous_union_with_storage_spec); - Invalid = true; - - // Recover by removing the storage specifier. - DS.SetStorageClassSpec(*this, DeclSpec::SCS_unspecified, SourceLocation(), - PrevSpec, DiagID); + if (Record->isUnion()) { + // C++ [class.union]p6: + // Anonymous unions declared in a named namespace or in the + // global namespace shall be declared static. + if (DS.getStorageClassSpec() != DeclSpec::SCS_static && + (isa<TranslationUnitDecl>(Owner) || + (isa<NamespaceDecl>(Owner) && + cast<NamespaceDecl>(Owner)->getDeclName()))) { + Diag(Record->getLocation(), diag::err_anonymous_union_not_static) + << FixItHint::CreateInsertion(Record->getLocation(), "static "); + + // Recover by adding 'static'. + DS.SetStorageClassSpec(*this, DeclSpec::SCS_static, SourceLocation(), + PrevSpec, DiagID); + } + // C++ [class.union]p6: + // A storage class is not allowed in a declaration of an + // anonymous union in a class scope. + else if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified && + isa<RecordDecl>(Owner)) { + Diag(DS.getStorageClassSpecLoc(), + diag::err_anonymous_union_with_storage_spec) + << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc()); + + // Recover by removing the storage specifier. + DS.SetStorageClassSpec(*this, DeclSpec::SCS_unspecified, + SourceLocation(), + PrevSpec, DiagID); + } } // Ignore const/volatile/restrict qualifiers. @@ -2683,11 +2766,13 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, << Record->isUnion() << 0 << FixItHint::CreateRemoval(DS.getConstSpecLoc()); if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile) - Diag(DS.getVolatileSpecLoc(), diag::ext_anonymous_struct_union_qualified) + Diag(DS.getVolatileSpecLoc(), + diag::ext_anonymous_struct_union_qualified) << Record->isUnion() << 1 << FixItHint::CreateRemoval(DS.getVolatileSpecLoc()); if (DS.getTypeQualifiers() & DeclSpec::TQ_restrict) - Diag(DS.getRestrictSpecLoc(), diag::ext_anonymous_struct_union_qualified) + Diag(DS.getRestrictSpecLoc(), + diag::ext_anonymous_struct_union_qualified) << Record->isUnion() << 2 << FixItHint::CreateRemoval(DS.getRestrictSpecLoc()); @@ -2717,7 +2802,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, // copy constructor, a non-trivial destructor, or a non-trivial copy // assignment operator cannot be a member of a union, nor can an // array of such objects. - if (!getLangOptions().CPlusPlus0x && CheckNontrivialField(FD)) + if (CheckNontrivialField(FD)) Invalid = true; } else if ((*Mem)->isImplicit()) { // Any implicit members are fine. @@ -2730,7 +2815,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, if (!MemRecord->isAnonymousStructOrUnion() && MemRecord->getDeclName()) { // Visual C++ allows type definition in anonymous struct or union. - if (getLangOptions().MicrosoftExt) + if (getLangOpts().MicrosoftExt) Diag(MemRecord->getLocation(), diag::ext_anonymous_record_with_type) << (int)Record->isUnion(); else { @@ -2754,7 +2839,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, DK = diag::err_anonymous_record_with_static; // Visual C++ allows type definition in anonymous struct or union. - if (getLangOptions().MicrosoftExt && + if (getLangOpts().MicrosoftExt && DK == diag::err_anonymous_record_with_type) Diag((*Mem)->getLocation(), diag::ext_anonymous_record_with_type) << (int)Record->isUnion(); @@ -2769,7 +2854,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, if (!Record->isUnion() && !Owner->isRecord()) { Diag(Record->getLocation(), diag::err_anonymous_struct_not_member) - << (int)getLangOptions().CPlusPlus; + << (int)getLangOpts().CPlusPlus; Invalid = true; } @@ -2782,7 +2867,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, NamedDecl *Anon = 0; if (RecordDecl *OwningClass = dyn_cast<RecordDecl>(Owner)) { Anon = FieldDecl::Create(Context, OwningClass, - DS.getSourceRange().getBegin(), + DS.getLocStart(), Record->getLocation(), /*IdentifierInfo=*/0, Context.getTypeDeclType(Record), @@ -2790,7 +2875,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, /*BitWidth=*/0, /*Mutable=*/false, /*HasInit=*/false); Anon->setAccess(AS); - if (getLangOptions().CPlusPlus) + if (getLangOpts().CPlusPlus) FieldCollector->Add(cast<FieldDecl>(Anon)); } else { DeclSpec::SCS SCSpec = DS.getStorageClassSpec(); @@ -2809,7 +2894,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, = StorageClassSpecToVarDeclStorageClass(SCSpec); Anon = VarDecl::Create(Context, Owner, - DS.getSourceRange().getBegin(), + DS.getLocStart(), Record->getLocation(), /*IdentifierInfo=*/0, Context.getTypeDeclType(Record), TInfo, SC, SCAsWritten); @@ -2879,8 +2964,8 @@ Decl *Sema::BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS, // Create a declaration for this anonymous struct. NamedDecl* Anon = FieldDecl::Create(Context, cast<RecordDecl>(CurContext), - DS.getSourceRange().getBegin(), - DS.getSourceRange().getBegin(), + DS.getLocStart(), + DS.getLocStart(), /*IdentifierInfo=*/0, Context.getTypeDeclType(Record), TInfo, @@ -2897,9 +2982,10 @@ Decl *Sema::BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS, SmallVector<NamedDecl*, 2> Chain; Chain.push_back(Anon); - if (InjectAnonymousStructOrUnionMembers(*this, S, CurContext, - Record->getDefinition(), - AS_none, Chain, true)) + RecordDecl *RecordDef = Record->getDefinition(); + if (!RecordDef || InjectAnonymousStructOrUnionMembers(*this, S, CurContext, + RecordDef, AS_none, + Chain, true)) Anon->setInvalidDecl(); return Anon; @@ -3135,8 +3221,14 @@ static bool RebuildDeclaratorInCurrentInstantiation(Sema &S, Declarator &D, } Decl *Sema::ActOnDeclarator(Scope *S, Declarator &D) { - D.setFunctionDefinition(false); - return HandleDeclarator(S, D, MultiTemplateParamsArg(*this)); + D.setFunctionDefinitionKind(FDK_Declaration); + Decl *Dcl = HandleDeclarator(S, D, MultiTemplateParamsArg(*this)); + + if (OriginalLexicalContext && OriginalLexicalContext->isObjCContainer() && + Dcl->getDeclContext()->isFileContext()) + Dcl->setTopLevelDeclInObjCContainer(); + + return Dcl; } /// DiagnoseClassNameShadow - Implement C++ [class.mem]p13: @@ -3158,7 +3250,100 @@ bool Sema::DiagnoseClassNameShadow(DeclContext *DC, return false; } + +/// \brief Diagnose a declaration whose declarator-id has the given +/// nested-name-specifier. +/// +/// \param SS The nested-name-specifier of the declarator-id. +/// +/// \param DC The declaration context to which the nested-name-specifier +/// resolves. +/// +/// \param Name The name of the entity being declared. +/// +/// \param Loc The location of the name of the entity being declared. +/// +/// \returns true if we cannot safely recover from this error, false otherwise. +bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC, + DeclarationName Name, + SourceLocation Loc) { + DeclContext *Cur = CurContext; + while (isa<LinkageSpecDecl>(Cur)) + Cur = Cur->getParent(); + // C++ [dcl.meaning]p1: + // A declarator-id shall not be qualified except for the definition + // of a member function (9.3) or static data member (9.4) outside of + // its class, the definition or explicit instantiation of a function + // or variable member of a namespace outside of its namespace, or the + // definition of an explicit specialization outside of its namespace, + // or the declaration of a friend function that is a member of + // another class or namespace (11.3). [...] + + // The user provided a superfluous scope specifier that refers back to the + // class or namespaces in which the entity is already declared. + // + // class X { + // void X::f(); + // }; + if (Cur->Equals(DC)) { + Diag(Loc, diag::warn_member_extra_qualification) + << Name << FixItHint::CreateRemoval(SS.getRange()); + SS.clear(); + return false; + } + + // Check whether the qualifying scope encloses the scope of the original + // declaration. + if (!Cur->Encloses(DC)) { + if (Cur->isRecord()) + Diag(Loc, diag::err_member_qualification) + << Name << SS.getRange(); + else if (isa<TranslationUnitDecl>(DC)) + Diag(Loc, diag::err_invalid_declarator_global_scope) + << Name << SS.getRange(); + else if (isa<FunctionDecl>(Cur)) + Diag(Loc, diag::err_invalid_declarator_in_function) + << Name << SS.getRange(); + else + Diag(Loc, diag::err_invalid_declarator_scope) + << Name << cast<NamedDecl>(Cur) << cast<NamedDecl>(DC) << SS.getRange(); + + return true; + } + + if (Cur->isRecord()) { + // Cannot qualify members within a class. + Diag(Loc, diag::err_member_qualification) + << Name << SS.getRange(); + SS.clear(); + + // C++ constructors and destructors with incorrect scopes can break + // our AST invariants by having the wrong underlying types. If + // that's the case, then drop this declaration entirely. + if ((Name.getNameKind() == DeclarationName::CXXConstructorName || + Name.getNameKind() == DeclarationName::CXXDestructorName) && + !Context.hasSameType(Name.getCXXNameType(), + Context.getTypeDeclType(cast<CXXRecordDecl>(Cur)))) + return true; + + return false; + } + + // C++11 [dcl.meaning]p1: + // [...] "The nested-name-specifier of the qualified declarator-id shall + // not begin with a decltype-specifer" + NestedNameSpecifierLoc SpecLoc(SS.getScopeRep(), SS.location_data()); + while (SpecLoc.getPrefix()) + SpecLoc = SpecLoc.getPrefix(); + if (dyn_cast_or_null<DecltypeType>( + SpecLoc.getNestedNameSpecifier()->getAsType())) + Diag(Loc, diag::err_decltype_in_declarator) + << SpecLoc.getTypeLoc().getSourceRange(); + + return false; +} + Decl *Sema::HandleDeclarator(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists) { // TODO: consider using NameInfo for diagnostic. @@ -3169,7 +3354,7 @@ Decl *Sema::HandleDeclarator(Scope *S, Declarator &D, // one, the ParsedFreeStandingDeclSpec action should be used. if (!Name) { if (!D.isInvalidType()) // Reject this if we think it is valid. - Diag(D.getDeclSpec().getSourceRange().getBegin(), + Diag(D.getDeclSpec().getLocStart(), diag::err_declarator_need_ident) << D.getDeclSpec().getSourceRange() << D.getSourceRange(); return 0; @@ -3209,29 +3394,18 @@ Decl *Sema::HandleDeclarator(Scope *S, Declarator &D, RequireCompleteDeclContext(D.getCXXScopeSpec(), DC)) return 0; - if (isa<CXXRecordDecl>(DC)) { - if (!cast<CXXRecordDecl>(DC)->hasDefinition()) { - Diag(D.getIdentifierLoc(), - diag::err_member_def_undefined_record) - << Name << DC << D.getCXXScopeSpec().getRange(); - D.setInvalidType(); - } else if (isa<CXXRecordDecl>(CurContext) && - !D.getDeclSpec().isFriendSpecified()) { - // The user provided a superfluous scope specifier inside a class - // definition: - // - // class X { - // void X::f(); - // }; - if (CurContext->Equals(DC)) - Diag(D.getIdentifierLoc(), diag::warn_member_extra_qualification) - << Name << FixItHint::CreateRemoval(D.getCXXScopeSpec().getRange()); - else - Diag(D.getIdentifierLoc(), diag::err_member_qualification) - << Name << D.getCXXScopeSpec().getRange(); + if (isa<CXXRecordDecl>(DC) && !cast<CXXRecordDecl>(DC)->hasDefinition()) { + Diag(D.getIdentifierLoc(), + diag::err_member_def_undefined_record) + << Name << DC << D.getCXXScopeSpec().getRange(); + D.setInvalidType(); + } else if (!D.getDeclSpec().isFriendSpecified()) { + if (diagnoseQualifiedDeclaration(D.getCXXScopeSpec(), DC, + Name, D.getIdentifierLoc())) { + if (DC->isRecord()) + return 0; - // Pretend that this qualifier was not here. - D.getCXXScopeSpec().clear(); + D.setInvalidType(); } } @@ -3289,21 +3463,16 @@ Decl *Sema::HandleDeclarator(Scope *S, Declarator &D, } else { // Something like "int foo::x;" LookupQualifiedName(Previous, DC); - // Don't consider using declarations as previous declarations for - // out-of-line members. - RemoveUsingDecls(Previous); - - // C++ 7.3.1.2p2: - // Members (including explicit specializations of templates) of a named - // namespace can also be defined outside that namespace by explicit - // qualification of the name being defined, provided that the entity being - // defined was already declared in the namespace and the definition appears - // after the point of declaration in a namespace that encloses the - // declarations namespace. + // C++ [dcl.meaning]p1: + // When the declarator-id is qualified, the declaration shall refer to a + // previously declared member of the class or namespace to which the + // qualifier refers (or, in the case of a namespace, of an element of the + // inline namespace set of that namespace (7.3.1)) or to a specialization + // thereof; [...] // - // Note that we only check the context at this point. We don't yet - // have enough information to make sure that PrevDecl is actually - // the declaration we want to match. For example, given: + // Note that we already checked the context above, and that we do not have + // enough information to make sure that Previous contains the declaration + // we want to match. For example, given: // // class X { // void f(); @@ -3312,40 +3481,23 @@ Decl *Sema::HandleDeclarator(Scope *S, Declarator &D, // // void X::f(int) { } // ill-formed // - // In this case, PrevDecl will point to the overload set + // In this case, Previous will point to the overload set // containing the two f's declared in X, but neither of them // matches. - - // First check whether we named the global scope. - if (isa<TranslationUnitDecl>(DC)) { - Diag(D.getIdentifierLoc(), diag::err_invalid_declarator_global_scope) - << Name << D.getCXXScopeSpec().getRange(); - } else { - DeclContext *Cur = CurContext; - while (isa<LinkageSpecDecl>(Cur)) - Cur = Cur->getParent(); - if (!Cur->Encloses(DC)) { - // The qualifying scope doesn't enclose the original declaration. - // Emit diagnostic based on current scope. - SourceLocation L = D.getIdentifierLoc(); - SourceRange R = D.getCXXScopeSpec().getRange(); - if (isa<FunctionDecl>(Cur)) - Diag(L, diag::err_invalid_declarator_in_function) << Name << R; - else - Diag(L, diag::err_invalid_declarator_scope) - << Name << cast<NamedDecl>(DC) << R; - D.setInvalidType(); - } - } + + // C++ [dcl.meaning]p1: + // [...] the member shall not merely have been introduced by a + // using-declaration in the scope of the class or namespace nominated by + // the nested-name-specifier of the declarator-id. + RemoveUsingDecls(Previous); } if (Previous.isSingleResult() && Previous.getFoundDecl()->isTemplateParameter()) { // Maybe we will complain about the shadowed template parameter. if (!D.isInvalidType()) - if (DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), - Previous.getFoundDecl())) - D.setInvalidType(); + DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), + Previous.getFoundDecl()); // Just pretend that we didn't see the previous declaration. Previous.clear(); @@ -3434,14 +3586,12 @@ static QualType TryToFixInvalidVariablyModifiedType(QualType T, if (VLATy->getElementType()->isVariablyModifiedType()) return QualType(); - Expr::EvalResult EvalResult; + llvm::APSInt Res; if (!VLATy->getSizeExpr() || - !VLATy->getSizeExpr()->Evaluate(EvalResult, Context) || - !EvalResult.Val.isInt()) + !VLATy->getSizeExpr()->EvaluateAsInt(Res, Context)) return QualType(); // Check whether the array size is negative. - llvm::APSInt &Res = EvalResult.Val.getInt(); if (Res.isSigned() && Res.isNegative()) { SizeIsNegative = true; return QualType(); @@ -3548,7 +3698,7 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC, Previous.clear(); } - if (getLangOptions().CPlusPlus) { + if (getLangOpts().CPlusPlus) { // Check that there are no default arguments (C++ only). CheckExtraCXXDefaultArguments(D); } @@ -3606,7 +3756,8 @@ Sema::CheckTypedefForVariablyModifiedType(Scope *S, TypedefNameDecl *NewTD) { else if (T->isVariableArrayType()) Diag(NewTD->getLocation(), diag::err_vla_decl_in_file_scope); else if (Oversized.getBoolValue()) - Diag(NewTD->getLocation(), diag::err_array_too_large) << Oversized.toString(10); + Diag(NewTD->getLocation(), diag::err_array_too_large) + << Oversized.toString(10); else Diag(NewTD->getLocation(), diag::err_vm_decl_in_file_scope); NewTD->setInvalidDecl(); @@ -3677,7 +3828,7 @@ isOutOfScopePreviousDeclaration(NamedDecl *PrevDecl, DeclContext *DC, if (!PrevDecl->hasLinkage()) return false; - if (Context.getLangOptions().CPlusPlus) { + if (Context.getLangOpts().CPlusPlus) { // C++ [basic.link]p6: // If there is a visible declaration of an entity with linkage // having the same name and type, ignoring entities declared @@ -3766,7 +3917,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, DeclarationName Name = GetNameForDeclarator(D).getName(); // Check that there are no default arguments (C++ only). - if (getLangOptions().CPlusPlus) + if (getLangOpts().CPlusPlus) CheckExtraCXXDefaultArguments(D); DeclSpec::SCS SCSpec = D.getDeclSpec().getStorageClassSpec(); @@ -3808,7 +3959,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, } } - if (getLangOptions().OpenCL) { + 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) @@ -3817,8 +3968,8 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, bool isExplicitSpecialization = false; VarDecl *NewVD; - if (!getLangOptions().CPlusPlus) { - NewVD = VarDecl::Create(Context, DC, D.getSourceRange().getBegin(), + if (!getLangOpts().CPlusPlus) { + NewVD = VarDecl::Create(Context, DC, D.getLocStart(), D.getIdentifierLoc(), II, R, TInfo, SC, SCAsWritten); @@ -3834,20 +3985,24 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, } else if (SC == SC_None) SC = SC_Static; } - if (SC == SC_Static) { + if (SC == SC_Static && CurContext->isRecord()) { if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC)) { if (RD->isLocalClass()) Diag(D.getIdentifierLoc(), diag::err_static_data_member_not_allowed_in_local_class) << Name << RD->getDeclName(); - // C++ [class.union]p1: If a union contains a static data member, - // the program is ill-formed. - // - // We also disallow static data members in anonymous structs. - if (CurContext->isRecord() && (RD->isUnion() || !RD->getDeclName())) + // C++98 [class.union]p1: If a union contains a static data member, + // the program is ill-formed. C++11 drops this restriction. + if (RD->isUnion()) + Diag(D.getIdentifierLoc(), + getLangOpts().CPlusPlus0x + ? 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. + else if (!RD->getDeclName()) Diag(D.getIdentifierLoc(), - diag::err_static_data_member_not_allowed_in_union_or_anon_struct) + diag::err_static_data_member_not_allowed_in_anon_struct) << Name << RD->isUnion(); } } @@ -3858,7 +4013,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, bool Invalid = false; if (TemplateParameterList *TemplateParams = MatchTemplateParametersToScopeSpecifier( - D.getDeclSpec().getSourceRange().getBegin(), + D.getDeclSpec().getLocStart(), D.getIdentifierLoc(), D.getCXXScopeSpec(), TemplateParamLists.get(), @@ -3884,7 +4039,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, } } - NewVD = VarDecl::Create(Context, DC, D.getSourceRange().getBegin(), + NewVD = VarDecl::Create(Context, DC, D.getLocStart(), D.getIdentifierLoc(), II, R, TInfo, SC, SCAsWritten); @@ -3905,38 +4060,8 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, TemplateParamLists.release()); } - if (D.getDeclSpec().isConstexprSpecified()) { - // FIXME: once we know whether there's an initializer, apply this to - // static data members too. - if (!NewVD->isStaticDataMember() && - !NewVD->isThisDeclarationADefinition()) { - // 'constexpr' is redundant and ill-formed on a non-defining declaration - // of a variable. Suggest replacing it with 'const' if appropriate. - SourceLocation ConstexprLoc = D.getDeclSpec().getConstexprSpecLoc(); - SourceRange ConstexprRange(ConstexprLoc, ConstexprLoc); - // If the declarator is complex, we need to move the keyword to the - // innermost chunk as we switch it from 'constexpr' to 'const'. - int Kind = DeclaratorChunk::Paren; - for (unsigned I = 0, E = D.getNumTypeObjects(); I != E; ++I) { - Kind = D.getTypeObject(I).Kind; - if (Kind != DeclaratorChunk::Paren) - break; - } - if ((D.getDeclSpec().getTypeQualifiers() & DeclSpec::TQ_const) || - Kind == DeclaratorChunk::Reference) - Diag(ConstexprLoc, diag::err_invalid_constexpr_var_decl) - << FixItHint::CreateRemoval(ConstexprRange); - else if (Kind == DeclaratorChunk::Paren) - Diag(ConstexprLoc, diag::err_invalid_constexpr_var_decl) - << FixItHint::CreateReplacement(ConstexprRange, "const"); - else - Diag(ConstexprLoc, diag::err_invalid_constexpr_var_decl) - << FixItHint::CreateRemoval(ConstexprRange) - << FixItHint::CreateInsertion(D.getIdentifierLoc(), "const "); - } else { - NewVD->setConstexpr(true); - } - } + if (D.getDeclSpec().isConstexprSpecified()) + NewVD->setConstexpr(true); } // Set the lexical context. If the declarator has a C++ scope specifier, the @@ -3971,7 +4096,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, // In auto-retain/release, infer strong retension for variables of // retainable type. - if (getLangOptions().ObjCAutoRefCount && inferObjCARCLifetime(NewVD)) + if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(NewVD)) NewVD->setInvalidDecl(); // Handle GNU asm-label extension (encoded as an attribute). @@ -3999,6 +4124,13 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, NewVD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0), Context, Label)); + } else if (!ExtnameUndeclaredIdentifiers.empty()) { + llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I = + ExtnameUndeclaredIdentifiers.find(NewVD->getIdentifier()); + if (I != ExtnameUndeclaredIdentifiers.end()) { + NewVD->addAttr(I->second); + ExtnameUndeclaredIdentifiers.erase(I); + } } // Diagnose shadowed variables before filtering for scope. @@ -4011,7 +4143,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, FilterLookupForScope(Previous, DC, S, NewVD->hasLinkage(), isExplicitSpecialization); - if (!getLangOptions().CPlusPlus) { + if (!getLangOpts().CPlusPlus) { D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous)); } else { // Merge the decl with the existing one if appropriate. @@ -4204,7 +4336,7 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD, if (NewVD->hasLocalStorage() && T.isObjCGCWeak() && !NewVD->hasAttr<BlocksAttr>()) { - if (getLangOptions().getGC() != LangOptions::NonGC) + if (getLangOpts().getGC() != LangOptions::NonGC) Diag(NewVD->getLocation(), diag::warn_gc_attribute_weak_on_local); else Diag(NewVD->getLocation(), diag::warn_attribute_weak_on_local); @@ -4284,20 +4416,9 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD, return false; } - // Function pointers and references cannot have qualified function type, only - // function pointer-to-members can do that. - QualType Pointee; - unsigned PtrOrRef = 0; - if (const PointerType *Ptr = T->getAs<PointerType>()) - Pointee = Ptr->getPointeeType(); - else if (const ReferenceType *Ref = T->getAs<ReferenceType>()) { - Pointee = Ref->getPointeeType(); - PtrOrRef = 1; - } - if (!Pointee.isNull() && Pointee->isFunctionProtoType() && - Pointee->getAs<FunctionProtoType>()->getTypeQuals() != 0) { - Diag(NewVD->getLocation(), diag::err_invalid_qualified_function_pointer) - << PtrOrRef; + if (NewVD->isConstexpr() && !T->isDependentType() && + RequireLiteralType(NewVD->getLocation(), T, + PDiag(diag::err_constexpr_var_non_literal))) { NewVD->setInvalidDecl(); return false; } @@ -4387,6 +4508,33 @@ namespace { }; } +namespace { + +// Callback to only accept typo corrections that have a non-zero edit distance. +// Also only accept corrections that have the same parent decl. +class DifferentNameValidatorCCC : public CorrectionCandidateCallback { + public: + DifferentNameValidatorCCC(CXXRecordDecl *Parent) + : ExpectedParent(Parent ? Parent->getCanonicalDecl() : 0) {} + + virtual bool ValidateCandidate(const TypoCorrection &candidate) { + if (candidate.getEditDistance() == 0) + return false; + + if (CXXMethodDecl *MD = candidate.getCorrectionDeclAs<CXXMethodDecl>()) { + CXXRecordDecl *Parent = MD->getParent(); + return Parent && Parent->getCanonicalDecl() == ExpectedParent; + } + + return !ExpectedParent; + } + + private: + CXXRecordDecl *ExpectedParent; +}; + +} + /// \brief Generate diagnostics for an invalid function redeclaration. /// /// This routine handles generating the diagnostic messages for an invalid @@ -4407,7 +4555,7 @@ static NamedDecl* DiagnoseInvalidRedeclaration( llvm::SmallVector<unsigned, 1> MismatchedParams; llvm::SmallVector<std::pair<FunctionDecl*, unsigned>, 1> NearMatches; TypoCorrection Correction; - bool isFriendDecl = (SemaRef.getLangOptions().CPlusPlus && + bool isFriendDecl = (SemaRef.getLangOpts().CPlusPlus && ExtraArgs.D.getDeclSpec().isFriendSpecified()); unsigned DiagMsg = isFriendDecl ? diag::err_no_matching_local_friend : diag::err_member_def_does_not_match; @@ -4416,6 +4564,8 @@ static NamedDecl* DiagnoseInvalidRedeclaration( SemaRef.LookupQualifiedName(Prev, NewDC); assert(!Prev.isAmbiguous() && "Cannot have an ambiguity in previous-declaration lookup"); + CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD); + DifferentNameValidatorCCC Validator(MD ? MD->getParent() : 0); if (!Prev.empty()) { for (LookupResult::iterator Func = Prev.begin(), FuncEnd = Prev.end(); Func != FuncEnd; ++Func) { @@ -4431,8 +4581,8 @@ static NamedDecl* DiagnoseInvalidRedeclaration( } // If the qualified name lookup yielded nothing, try typo correction } else if ((Correction = SemaRef.CorrectTypo(Prev.getLookupNameInfo(), - Prev.getLookupKind(), 0, 0, NewDC)) && - Correction.getCorrection() != Name) { + Prev.getLookupKind(), 0, 0, + Validator, NewDC))) { // Trap errors. Sema::SFINAETrap Trap(SemaRef); @@ -4454,12 +4604,11 @@ static NamedDecl* DiagnoseInvalidRedeclaration( // TODO: Refactor ActOnFunctionDeclarator so that we can call only the // pieces need to verify the typo-corrected C++ declaraction and hopefully // eliminate the need for the parameter pack ExtraArgs. - Result = SemaRef.ActOnFunctionDeclarator(ExtraArgs.S, ExtraArgs.D, - NewFD->getDeclContext(), - NewFD->getTypeSourceInfo(), - Previous, - ExtraArgs.TemplateParamLists, - ExtraArgs.AddToScope); + Result = SemaRef.ActOnFunctionDeclarator( + ExtraArgs.S, ExtraArgs.D, + Correction.getCorrectionDecl()->getDeclContext(), + NewFD->getTypeSourceInfo(), Previous, ExtraArgs.TemplateParamLists, + ExtraArgs.AddToScope); if (Trap.hasErrorOccurred()) { // Pretend the typo correction never occurred ExtraArgs.D.SetIdentifier(Name.getAsIdentifierInfo(), @@ -4487,10 +4636,10 @@ static NamedDecl* DiagnoseInvalidRedeclaration( if (Correction) SemaRef.Diag(NewFD->getLocation(), DiagMsg) - << Name << NewDC << Correction.getQuoted(SemaRef.getLangOptions()) + << Name << NewDC << Correction.getQuoted(SemaRef.getLangOpts()) << FixItHint::CreateReplacement( NewFD->getLocation(), - Correction.getAsString(SemaRef.getLangOptions())); + Correction.getAsString(SemaRef.getLangOpts())); else SemaRef.Diag(NewFD->getLocation(), DiagMsg) << Name << NewDC << NewFD->getLocation(); @@ -4509,12 +4658,13 @@ static NamedDecl* DiagnoseInvalidRedeclaration( if (unsigned Idx = NearMatch->second) { ParmVarDecl *FDParam = FD->getParamDecl(Idx-1); - SemaRef.Diag(FDParam->getTypeSpecStartLoc(), - diag::note_member_def_close_param_match) + SourceLocation Loc = FDParam->getTypeSpecStartLoc(); + if (Loc.isInvalid()) Loc = FD->getLocation(); + SemaRef.Diag(Loc, diag::note_member_def_close_param_match) << Idx << FDParam->getType() << NewFD->getParamDecl(Idx-1)->getType(); } else if (Correction) { SemaRef.Diag(FD->getLocation(), diag::note_previous_decl) - << Correction.getQuoted(SemaRef.getLangOptions()); + << Correction.getQuoted(SemaRef.getLangOpts()); } else if (FDisConst != NewFDisConst) { SemaRef.Diag(FD->getLocation(), diag::note_member_def_close_const_match) << NewFDisConst << FD->getSourceRange().getEnd(); @@ -4524,7 +4674,8 @@ static NamedDecl* DiagnoseInvalidRedeclaration( return Result; } -static FunctionDecl::StorageClass getFunctionStorageClass(Sema &SemaRef, Declarator &D) { +static FunctionDecl::StorageClass getFunctionStorageClass(Sema &SemaRef, + Declarator &D) { switch (D.getDeclSpec().getStorageClassSpec()) { default: llvm_unreachable("Unknown storage class!"); case DeclSpec::SCS_auto: @@ -4570,7 +4721,7 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, FunctionDecl::StorageClass SCAsWritten = StorageClassSpecToFunctionDeclStorageClass(SCSpec); - if (!SemaRef.getLangOptions().CPlusPlus) { + if (!SemaRef.getLangOpts().CPlusPlus) { // Determine whether the function was written with a // prototype. This true when: // - there is a prototype in the declarator, or @@ -4580,8 +4731,9 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, (D.isFunctionDeclarator() && D.getFunctionTypeInfo().hasPrototype) || (!isa<FunctionType>(R.getTypePtr()) && R->isFunctionProtoType()); - NewFD = FunctionDecl::Create(SemaRef.Context, DC, D.getSourceRange().getBegin(), - NameInfo, R, TInfo, SC, SCAsWritten, isInline, + NewFD = FunctionDecl::Create(SemaRef.Context, DC, + D.getLocStart(), NameInfo, R, + TInfo, SC, SCAsWritten, isInline, HasPrototype); if (D.isInvalidType()) NewFD->setInvalidDecl(); @@ -4612,7 +4764,7 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, R = SemaRef.CheckConstructorDeclarator(D, R, SC); return CXXConstructorDecl::Create(SemaRef.Context, cast<CXXRecordDecl>(DC), - D.getSourceRange().getBegin(), NameInfo, + D.getLocStart(), NameInfo, R, TInfo, isExplicit, isInline, /*isImplicitlyDeclared=*/false, isConstexpr); @@ -4624,14 +4776,14 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, CXXRecordDecl *Record = cast<CXXRecordDecl>(DC); CXXDestructorDecl *NewDD = CXXDestructorDecl::Create( SemaRef.Context, Record, - D.getSourceRange().getBegin(), + D.getLocStart(), NameInfo, R, TInfo, isInline, /*isImplicitlyDeclared=*/false); // 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.getLangOptions().CPlusPlus0x && !Record->isDependentType() && + if (SemaRef.getLangOpts().CPlusPlus0x && !Record->isDependentType() && Record->getDefinition() && !Record->isBeingDefined() && R->getAs<FunctionProtoType>()->getExceptionSpecType() == EST_None) { SemaRef.AdjustDestructorExceptionSpec(Record, NewDD); @@ -4647,7 +4799,7 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, // Create a FunctionDecl to satisfy the function definition parsing // code path. return FunctionDecl::Create(SemaRef.Context, DC, - D.getSourceRange().getBegin(), + D.getLocStart(), D.getIdentifierLoc(), Name, R, TInfo, SC, SCAsWritten, isInline, /*hasPrototype=*/true, isConstexpr); @@ -4663,7 +4815,7 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, SemaRef.CheckConversionDeclarator(D, R, SC); IsVirtualOkay = true; return CXXConversionDecl::Create(SemaRef.Context, cast<CXXRecordDecl>(DC), - D.getSourceRange().getBegin(), NameInfo, + D.getLocStart(), NameInfo, R, TInfo, isInline, isExplicit, isConstexpr, SourceLocation()); @@ -4699,7 +4851,7 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, // This is a C++ method declaration. return CXXMethodDecl::Create(SemaRef.Context, cast<CXXRecordDecl>(DC), - D.getSourceRange().getBegin(), NameInfo, R, + D.getLocStart(), NameInfo, R, TInfo, isStatic, SCAsWritten, isInline, isConstexpr, SourceLocation()); @@ -4708,7 +4860,7 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D, // prototype. This true when: // - we're in C++ (where every function has a prototype), return FunctionDecl::Create(SemaRef.Context, DC, - D.getSourceRange().getBegin(), + D.getLocStart(), NameInfo, R, TInfo, SC, SCAsWritten, isInline, true/*HasPrototype*/, isConstexpr); } @@ -4760,7 +4912,10 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, isVirtualOkay); if (!NewFD) return 0; - if (getLangOptions().CPlusPlus) { + if (OriginalLexicalContext && OriginalLexicalContext->isObjCContainer()) + NewFD->setTopLevelDeclInObjCContainer(); + + if (getLangOpts().CPlusPlus) { bool isInline = D.getDeclSpec().isInlineSpecified(); bool isVirtual = D.getDeclSpec().isVirtualSpecified(); bool isExplicit = D.getDeclSpec().isExplicitSpecified(); @@ -4783,13 +4938,13 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // scope specifier, or is the object of a friend declaration, the // lexical context will be different from the semantic context. NewFD->setLexicalDeclContext(CurContext); - + // Match up the template parameter lists with the scope specifier, then // determine whether we have a template or a template specialization. bool Invalid = false; if (TemplateParameterList *TemplateParams = MatchTemplateParametersToScopeSpecifier( - D.getDeclSpec().getSourceRange().getBegin(), + D.getDeclSpec().getLocStart(), D.getIdentifierLoc(), D.getCXXScopeSpec(), TemplateParamLists.get(), @@ -4811,7 +4966,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, } // If we're adding a template to a dependent context, we may need to - // rebuilding some of the types used within the template parameter list, + // rebuilding some of the types used within the template parameter list, // now that we know what the current instantiation is. if (DC->isDependentContext()) { ContextRAII SavedContext(*this, DC); @@ -4880,6 +5035,56 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, FunctionTemplate->setInvalidDecl(); } + // If we see "T var();" at block scope, where T is a class type, it is + // probably an attempt to initialize a variable, not a function declaration. + // We don't catch this case earlier, since there is no ambiguity here. + if (!FunctionTemplate && D.getFunctionDefinitionKind() == FDK_Declaration && + CurContext->isFunctionOrMethod() && + D.getNumTypeObjects() == 1 && D.isFunctionDeclarator() && + D.getDeclSpec().getStorageClassSpecAsWritten() + == DeclSpec::SCS_unspecified) { + QualType T = R->getAs<FunctionType>()->getResultType(); + DeclaratorChunk &C = D.getTypeObject(0); + if (!T->isVoidType() && C.Fun.NumArgs == 0 && !C.Fun.isVariadic && + !C.Fun.TrailingReturnType && + C.Fun.getExceptionSpecType() == EST_None) { + SourceRange ParenRange(C.Loc, C.EndLoc); + Diag(C.Loc, diag::warn_empty_parens_are_function_decl) << ParenRange; + + // If the declaration looks like: + // T var1, + // f(); + // and name lookup finds a function named 'f', then the ',' was + // probably intended to be a ';'. + if (!D.isFirstDeclarator() && D.getIdentifier()) { + FullSourceLoc Comma(D.getCommaLoc(), SourceMgr); + FullSourceLoc Name(D.getIdentifierLoc(), SourceMgr); + if (Comma.getFileID() != Name.getFileID() || + Comma.getSpellingLineNumber() != Name.getSpellingLineNumber()) { + LookupResult Result(*this, D.getIdentifier(), SourceLocation(), + LookupOrdinaryName); + if (LookupName(Result, S)) + Diag(D.getCommaLoc(), diag::note_empty_parens_function_call) + << FixItHint::CreateReplacement(D.getCommaLoc(), ";") << NewFD; + } + } + const CXXRecordDecl *RD = T->getAsCXXRecordDecl(); + // Empty parens mean value-initialization, and no parens mean default + // initialization. These are equivalent if the default constructor is + // user-provided, or if zero-initialization is a no-op. + if (RD && RD->hasDefinition() && + (RD->isEmpty() || RD->hasUserProvidedDefaultConstructor())) + Diag(C.Loc, diag::note_empty_parens_default_ctor) + << FixItHint::CreateRemoval(ParenRange); + else if (const char *Init = getFixItZeroInitializerForType(T)) + Diag(C.Loc, diag::note_empty_parens_zero_initialize) + << FixItHint::CreateReplacement(ParenRange, Init); + else if (LangOpts.CPlusPlus0x) + Diag(C.Loc, diag::note_empty_parens_zero_initialize) + << FixItHint::CreateReplacement(ParenRange, "{}"); + } + } + // C++ [dcl.fct.spec]p5: // The virtual specifier shall only be used in declarations of // nonstatic class member functions that appear within a @@ -4907,7 +5112,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, } // C++ [dcl.fct.spec]p3: - // The inline specifier shall not appear on a block scope function declaration. + // The inline specifier shall not appear on a block scope function + // declaration. if (isInline && !NewFD->isInvalidDecl()) { if (CurContext->isFunctionOrMethod()) { // 'inline' is not allowed on block scope function declaration. @@ -4919,8 +5125,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // C++ [dcl.fct.spec]p6: // The explicit specifier shall be used only in the declaration of a - // constructor or conversion function within its class definition; see 12.3.1 - // and 12.3.2. + // constructor or conversion function within its class definition; + // see 12.3.1 and 12.3.2. if (isExplicit && !NewFD->isInvalidDecl()) { if (!CurContext->isRecord()) { // 'explicit' was specified outside of the class. @@ -4974,10 +5180,26 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, NewFD->setAccess(AS_public); } + // If a function is defined as defaulted or deleted, mark it as such now. + switch (D.getFunctionDefinitionKind()) { + case FDK_Declaration: + case FDK_Definition: + break; + + case FDK_Defaulted: + NewFD->setDefaulted(); + break; + + case FDK_Deleted: + NewFD->setDeletedAsWritten(); + break; + } + if (isa<CXXMethodDecl>(NewFD) && DC == CurContext && D.isFunctionDefinition()) { - // A method is implicitly inline if it's defined in its class - // definition. + // C++ [class.mfct]p2: + // A member function may be defined (8.4) in its class definition, in + // which case it is an inline member function (7.1.2) NewFD->setImplicitlyInline(); } @@ -5007,6 +5229,13 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, StringLiteral *SE = cast<StringLiteral>(E); NewFD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0), Context, SE->getString())); + } else if (!ExtnameUndeclaredIdentifiers.empty()) { + llvm::DenseMap<IdentifierInfo*,AsmLabelAttr*>::iterator I = + ExtnameUndeclaredIdentifiers.find(NewFD->getIdentifier()); + if (I != ExtnameUndeclaredIdentifiers.end()) { + NewFD->addAttr(I->second); + ExtnameUndeclaredIdentifiers.erase(I); + } } // Copy the parameter declarations from the declarator D to the function @@ -5028,7 +5257,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // In C++, the empty parameter-type-list must be spelled "void"; a // typedef of void is not permitted. - if (getLangOptions().CPlusPlus && + if (getLangOpts().CPlusPlus && Param->getType().getUnqualifiedType() != Context.VoidTy) { bool IsTypeAlias = false; if (const TypedefType *TT = Param->getType()->getAs<TypedefType>()) @@ -5077,25 +5306,35 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // Finally, we know we have the right number of parameters, install them. NewFD->setParams(Params); + // Find all anonymous symbols defined during the declaration of this function + // and add to NewFD. This lets us track decls such 'enum Y' in: + // + // void f(enum Y {AA} x) {} + // + // which would otherwise incorrectly end up in the translation unit scope. + NewFD->setDeclsInPrototypeScope(DeclsInPrototypeScope); + DeclsInPrototypeScope.clear(); + // Process the non-inheritable attributes on this declaration. ProcessDeclAttributes(S, NewFD, D, /*NonInheritable=*/true, /*Inheritable=*/false); - if (!getLangOptions().CPlusPlus) { + // Functions returning a variably modified type violate C99 6.7.5.2p2 + // because all functions have linkage. + if (!NewFD->isInvalidDecl() && + NewFD->getResultType()->isVariablyModifiedType()) { + Diag(NewFD->getLocation(), diag::err_vm_func_decl); + NewFD->setInvalidDecl(); + } + + if (!getLangOpts().CPlusPlus) { // Perform semantic checking on the function declaration. bool isExplicitSpecialization=false; if (!NewFD->isInvalidDecl()) { - if (NewFD->getResultType()->isVariablyModifiedType()) { - // Functions returning a variably modified type violate C99 6.7.5.2p2 - // because all functions have linkage. - Diag(NewFD->getLocation(), diag::err_vm_func_decl); - NewFD->setInvalidDecl(); - } else { - if (NewFD->isMain()) - CheckMain(NewFD, D.getDeclSpec()); - D.setRedeclaration(CheckFunctionDeclaration(S, NewFD, Previous, - isExplicitSpecialization)); - } + if (NewFD->isMain()) + CheckMain(NewFD, D.getDeclSpec()); + D.setRedeclaration(CheckFunctionDeclaration(S, NewFD, Previous, + isExplicitSpecialization)); } assert((NewFD->isInvalidDecl() || !D.isRedeclaration() || Previous.getResultKind() != LookupResult::FoundOverloaded) && @@ -5135,8 +5374,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, Diag(D.getIdentifierLoc(), diag::err_template_spec_needs_header) << SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc) << FixItHint::CreateInsertion( - D.getDeclSpec().getSourceRange().getBegin(), - "template<> "); + D.getDeclSpec().getLocStart(), + "template<> "); isFunctionTemplateSpecialization = true; } else { // "friend void foo<>(int);" is an implicit specialization decl. @@ -5173,7 +5412,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (CurContext->isDependentContext() && CurContext->isRecord() && !isFriend) { isDependentClassScopeExplicitSpecialization = true; - Diag(NewFD->getLocation(), getLangOptions().MicrosoftExt ? + Diag(NewFD->getLocation(), getLangOpts().MicrosoftExt ? diag::ext_function_specialization_in_class : diag::err_function_specialization_in_class) << NewFD->getDeclName(); @@ -5224,10 +5463,6 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, Previous.getResultKind() != LookupResult::FoundOverloaded) && "previous declaration set still overloaded"); - if (NewFD->isConstexpr() && !NewFD->isInvalidDecl() && - !CheckConstexprFunctionDecl(NewFD, CCK_Declaration)) - NewFD->setInvalidDecl(); - NamedDecl *PrincipalDecl = (FunctionTemplate ? cast<NamedDecl>(FunctionTemplate) : NewFD); @@ -5235,7 +5470,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (isFriend && D.isRedeclaration()) { AccessSpecifier Access = AS_public; if (!NewFD->isInvalidDecl()) - Access = NewFD->getPreviousDeclaration()->getAccess(); + Access = NewFD->getPreviousDecl()->getAccess(); NewFD->setAccess(Access); if (FunctionTemplate) FunctionTemplate->setAccess(Access); @@ -5250,9 +5485,10 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // If we have a function template, check the template parameter // list. This will check and merge default template arguments. if (FunctionTemplate) { - FunctionTemplateDecl *PrevTemplate = FunctionTemplate->getPreviousDeclaration(); + FunctionTemplateDecl *PrevTemplate = + FunctionTemplate->getPreviousDecl(); CheckTemplateParameterList(FunctionTemplate->getTemplateParameters(), - PrevTemplate? PrevTemplate->getTemplateParameters() : 0, + PrevTemplate ? PrevTemplate->getTemplateParameters() : 0, D.getDeclSpec().isFriendSpecified() ? (D.isFunctionDefinition() ? TPC_FriendFunctionTemplateDefinition @@ -5331,8 +5567,9 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // definition (C++ [dcl.meaning]p1). // Note that this is not the case for explicit specializations of // function templates or member functions of class templates, per - // C++ [temp.expl.spec]p2. We also allow these declarations as an extension - // for compatibility with old SWIG code which likes to generate them. + // C++ [temp.expl.spec]p2. We also allow these declarations as an + // extension for compatibility with old SWIG code which likes to + // generate them. Diag(NewFD->getLocation(), diag::ext_out_of_line_declaration) << D.getCXXScopeSpec().getRange(); } @@ -5393,7 +5630,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // Set this FunctionDecl's range up to the right paren. NewFD->setRangeEnd(D.getSourceRange().getEnd()); - if (getLangOptions().CPlusPlus) { + if (getLangOpts().CPlusPlus) { if (FunctionTemplate) { if (NewFD->isInvalidDecl()) FunctionTemplate->setInvalidDecl(); @@ -5403,7 +5640,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, MarkUnusedFileScopedDecl(NewFD); - if (getLangOptions().CUDA) + if (getLangOpts().CUDA) if (IdentifierInfo *II = NewFD->getIdentifier()) if (!NewFD->isInvalidDecl() && NewFD->getDeclContext()->getRedeclContext()->isTranslationUnit()) { @@ -5493,7 +5730,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, break; } - if (!getLangOptions().CPlusPlus && !NewFD->hasAttr<OverloadableAttr>()) { + if (!getLangOpts().CPlusPlus && !NewFD->hasAttr<OverloadableAttr>()) { // If a function name is overloadable in C, then every function // with that name must be marked "overloadable". Diag(NewFD->getLocation(), diag::err_attribute_overloadable_missing) @@ -5514,7 +5751,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, if (Redeclaration) { // NewFD and OldDecl represent declarations that need to be // merged. - if (MergeFunctionDecl(NewFD, OldDecl)) { + if (MergeFunctionDecl(NewFD, OldDecl, S)) { NewFD->setInvalidDecl(); return Redeclaration; } @@ -5524,7 +5761,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, if (FunctionTemplateDecl *OldTemplateDecl = dyn_cast<FunctionTemplateDecl>(OldDecl)) { - NewFD->setPreviousDeclaration(OldTemplateDecl->getTemplatedDecl()); + NewFD->setPreviousDeclaration(OldTemplateDecl->getTemplatedDecl()); FunctionTemplateDecl *NewTemplateDecl = NewFD->getDescribedFunctionTemplate(); assert(NewTemplateDecl && "Template/non-template mismatch"); @@ -5542,9 +5779,6 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, assert(OldTemplateDecl->isMemberSpecialization()); } - if (OldTemplateDecl->isModulePrivate()) - NewTemplateDecl->setModulePrivate(); - } else { if (isa<CXXMethodDecl>(NewFD)) // Set access for out-of-line definitions NewFD->setAccess(OldDecl->getAccess()); @@ -5554,7 +5788,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, } // Semantic checking for this function declaration (in isolation). - if (getLangOptions().CPlusPlus) { + if (getLangOpts().CPlusPlus) { // C++-specific checks. if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(NewFD)) { CheckConstructor(Constructor); @@ -5633,29 +5867,59 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, Context.BuiltinInfo.ForgetBuiltin(BuiltinID, Context.Idents); } } + + // If this function is declared as being extern "C", then check to see if + // the function returns a UDT (class, struct, or union type) that is not C + // compatible, and if it does, warn the user. + if (NewFD->isExternC()) { + QualType R = NewFD->getResultType(); + if (!R.isPODType(Context) && + !R->isVoidType()) + Diag( NewFD->getLocation(), diag::warn_return_value_udt ) + << NewFD << R; + } } return Redeclaration; } void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) { - // C++ [basic.start.main]p3: A program that declares main to be inline - // or static is ill-formed. + // 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. // static main is not an error under C99, but we should warn about it. if (FD->getStorageClass() == SC_Static) - Diag(DS.getStorageClassSpecLoc(), getLangOptions().CPlusPlus + Diag(DS.getStorageClassSpecLoc(), getLangOpts().CPlusPlus ? diag::err_static_main : diag::warn_static_main) << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc()); if (FD->isInlineSpecified()) Diag(DS.getInlineSpecLoc(), diag::err_inline_main) << FixItHint::CreateRemoval(DS.getInlineSpecLoc()); + if (FD->isConstexpr()) { + Diag(DS.getConstexprSpecLoc(), diag::err_constexpr_main) + << FixItHint::CreateRemoval(DS.getConstexprSpecLoc()); + FD->setConstexpr(false); + } QualType T = FD->getType(); assert(T->isFunctionType() && "function decl is not of function type"); - const FunctionType* FT = T->getAs<FunctionType>(); - - if (!Context.hasSameUnqualifiedType(FT->getResultType(), Context.IntTy)) { + const FunctionType* FT = T->castAs<FunctionType>(); + + // All the standards say that main() should should return 'int'. + if (Context.hasSameUnqualifiedType(FT->getResultType(), Context.IntTy)) { + // In C and C++, main magically returns 0 if you fall off the end; + // set the flag which tells us that. + // This is C++ [basic.start.main]p5 and C99 5.1.2.2.3. + FD->setHasImplicitReturnZero(true); + + // In C with GNU extensions we allow main() to have non-integer return + // type, but we should warn about the extension, and we disable the + // implicit-return-zero rule. + } else if (getLangOpts().GNUMode && !getLangOpts().CPlusPlus) { + Diag(FD->getTypeSpecStartLoc(), diag::ext_main_returns_nonint); + + // Otherwise, this is just a flat-out error. + } else { Diag(FD->getTypeSpecStartLoc(), diag::err_main_returns_nonint); FD->setInvalidDecl(true); } @@ -5786,7 +6050,8 @@ namespace { void VisitMemberExpr(MemberExpr *E) { if (E->getType()->canDecayToPointerType()) return; - if (isa<FieldDecl>(E->getMemberDecl())) + ValueDecl *VD = E->getMemberDecl(); + if (isa<FieldDecl>(VD) || isa<CXXMethodDecl>(VD)) if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->getBase()->IgnoreParenImpCasts())) { HandleDeclRefExpr(DRE); @@ -5844,17 +6109,6 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, if (RealDecl == 0 || RealDecl->isInvalidDecl()) return; - // Check for self-references within variable initializers. - if (VarDecl *vd = dyn_cast<VarDecl>(RealDecl)) { - // Variables declared within a function/method body are handled - // by a dataflow analysis. - if (!vd->hasLocalStorage() && !vd->isStaticLocal()) - CheckSelfReference(RealDecl, Init); - } - else { - CheckSelfReference(RealDecl, Init); - } - if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(RealDecl)) { // With declarators parsed the way they are, the parser cannot // distinguish between a normal initializer and a pure-specifier. @@ -5879,48 +6133,88 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, return; } - // C++0x [decl.spec.auto]p6. Deduce the type which 'auto' stands in for. + // Check for self-references within variable initializers. + // Variables declared within a function/method body are handled + // by a dataflow analysis. + if (!VDecl->hasLocalStorage() && !VDecl->isStaticLocal()) + CheckSelfReference(RealDecl, Init); + + ParenListExpr *CXXDirectInit = dyn_cast<ParenListExpr>(Init); + + // C++11 [decl.spec.auto]p6. Deduce the type which 'auto' stands in for. if (TypeMayContainAuto && VDecl->getType()->getContainedAutoType()) { + Expr *DeduceInit = Init; + // Initializer could be a C++ direct-initializer. Deduction only works if it + // contains exactly one expression. + if (CXXDirectInit) { + if (CXXDirectInit->getNumExprs() == 0) { + // It isn't possible to write this directly, but it is possible to + // end up in this situation with "auto x(some_pack...);" + Diag(CXXDirectInit->getLocStart(), + diag::err_auto_var_init_no_expression) + << VDecl->getDeclName() << VDecl->getType() + << VDecl->getSourceRange(); + RealDecl->setInvalidDecl(); + return; + } else if (CXXDirectInit->getNumExprs() > 1) { + Diag(CXXDirectInit->getExpr(1)->getLocStart(), + diag::err_auto_var_init_multiple_expressions) + << VDecl->getDeclName() << VDecl->getType() + << VDecl->getSourceRange(); + RealDecl->setInvalidDecl(); + return; + } else { + DeduceInit = CXXDirectInit->getExpr(0); + } + } TypeSourceInfo *DeducedType = 0; - if (!DeduceAutoType(VDecl->getTypeSourceInfo(), Init, DeducedType)) - Diag(VDecl->getLocation(), diag::err_auto_var_deduction_failure) - << VDecl->getDeclName() << VDecl->getType() << Init->getType() - << Init->getSourceRange(); + if (DeduceAutoType(VDecl->getTypeSourceInfo(), DeduceInit, DeducedType) == + DAR_Failed) + DiagnoseAutoDeductionFailure(VDecl, DeduceInit); if (!DeducedType) { RealDecl->setInvalidDecl(); return; } VDecl->setTypeSourceInfo(DeducedType); VDecl->setType(DeducedType->getType()); - + VDecl->ClearLinkageCache(); + // In ARC, infer lifetime. - if (getLangOptions().ObjCAutoRefCount && inferObjCARCLifetime(VDecl)) + if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(VDecl)) VDecl->setInvalidDecl(); // If this is a redeclaration, check that the type we just deduced matches // the previously declared type. - if (VarDecl *Old = VDecl->getPreviousDeclaration()) + if (VarDecl *Old = VDecl->getPreviousDecl()) MergeVarDeclTypes(VDecl, Old); } - - // A definition must end up with a complete type, which means it must be - // complete with the restriction that an array type might be completed by the - // initializer; note that later code assumes this restriction. - QualType BaseDeclType = VDecl->getType(); - if (const ArrayType *Array = Context.getAsIncompleteArrayType(BaseDeclType)) - BaseDeclType = Array->getElementType(); - if (RequireCompleteType(VDecl->getLocation(), BaseDeclType, - diag::err_typecheck_decl_incomplete_type)) { - RealDecl->setInvalidDecl(); + if (VDecl->isLocalVarDecl() && VDecl->hasExternalStorage()) { + // C99 6.7.8p5. C++ has no such restriction, but that is a defect. + Diag(VDecl->getLocation(), diag::err_block_extern_cant_init); + VDecl->setInvalidDecl(); return; } - // The variable can not have an abstract class type. - if (RequireNonAbstractType(VDecl->getLocation(), VDecl->getType(), - diag::err_abstract_type_in_decl, - AbstractVariableType)) - VDecl->setInvalidDecl(); + if (!VDecl->getType()->isDependentType()) { + // A definition must end up with a complete type, which means it must be + // complete with the restriction that an array type might be completed by + // the initializer; note that later code assumes this restriction. + QualType BaseDeclType = VDecl->getType(); + if (const ArrayType *Array = Context.getAsIncompleteArrayType(BaseDeclType)) + BaseDeclType = Array->getElementType(); + if (RequireCompleteType(VDecl->getLocation(), BaseDeclType, + diag::err_typecheck_decl_incomplete_type)) { + RealDecl->setInvalidDecl(); + return; + } + + // The variable can not have an abstract class type. + if (RequireNonAbstractType(VDecl->getLocation(), VDecl->getType(), + diag::err_abstract_type_in_decl, + AbstractVariableType)) + VDecl->setInvalidDecl(); + } const VarDecl *Def; if ((Def = VDecl->getDefinition()) && Def != VDecl) { @@ -5932,7 +6226,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, } const VarDecl* PrevInit = 0; - if (getLangOptions().CPlusPlus) { + if (getLangOpts().CPlusPlus) { // C++ [class.static.data]p4 // If a static data member is of const integral or const // enumeration type, its declaration in the class definition can @@ -5946,7 +6240,8 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // data members we also need to check whether there was an in-class // declaration with an initializer. if (VDecl->isStaticDataMember() && VDecl->getAnyInitializer(PrevInit)) { - Diag(VDecl->getLocation(), diag::err_redefinition) << VDecl->getDeclName(); + Diag(VDecl->getLocation(), diag::err_redefinition) + << VDecl->getDeclName(); Diag(PrevInit->getLocation(), diag::note_previous_definition); return; } @@ -5968,44 +6263,77 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, return; } - // Capture the variable that is being initialized and the style of - // initialization. - InitializedEntity Entity = InitializedEntity::InitializeVariable(VDecl); - - // FIXME: Poor source location information. - InitializationKind Kind - = DirectInit? InitializationKind::CreateDirect(VDecl->getLocation(), - Init->getLocStart(), - Init->getLocEnd()) - : InitializationKind::CreateCopy(VDecl->getLocation(), - Init->getLocStart()); - // Get the decls type and save a reference for later, since // CheckInitializerTypes may change it. QualType DclT = VDecl->getType(), SavT = DclT; - if (VDecl->isLocalVarDecl()) { - if (VDecl->hasExternalStorage()) { // C99 6.7.8p5 - Diag(VDecl->getLocation(), diag::err_block_extern_cant_init); - VDecl->setInvalidDecl(); - } else if (!VDecl->isInvalidDecl()) { - InitializationSequence InitSeq(*this, Entity, Kind, &Init, 1); - ExprResult Result = InitSeq.Perform(*this, Entity, Kind, - MultiExprArg(*this, &Init, 1), - &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(); + } - Init = Result.takeAs<Expr>(); - - // C++ 3.6.2p2, allow dynamic initialization of static initializers. - // Don't check invalid declarations to avoid emitting useless diagnostics. - if (!getLangOptions().CPlusPlus && !VDecl->isInvalidDecl()) { - if (VDecl->getStorageClass() == SC_Static) // C99 6.7.8p4. - CheckForConstantInitializer(Init, DclT); - } + // Perform the initialization. + if (!VDecl->isInvalidDecl()) { + InitializedEntity Entity = InitializedEntity::InitializeVariable(VDecl); + InitializationKind Kind + = DirectInit ? + CXXDirectInit ? InitializationKind::CreateDirect(VDecl->getLocation(), + Init->getLocStart(), + Init->getLocEnd()) + : InitializationKind::CreateDirectList( + VDecl->getLocation()) + : InitializationKind::CreateCopy(VDecl->getLocation(), + Init->getLocStart()); + + Expr **Args = &Init; + unsigned NumArgs = 1; + if (CXXDirectInit) { + Args = CXXDirectInit->getExprs(); + NumArgs = CXXDirectInit->getNumExprs(); + } + InitializationSequence InitSeq(*this, Entity, Kind, Args, NumArgs); + ExprResult Result = InitSeq.Perform(*this, Entity, Kind, + MultiExprArg(*this, Args,NumArgs), + &DclT); + if (Result.isInvalid()) { + VDecl->setInvalidDecl(); + return; } + + Init = Result.takeAs<Expr>(); + } + + // If the type changed, it means we had an incomplete type that was + // completed by the initializer. For example: + // int ary[] = { 1, 3, 5 }; + // "ary" transitions from an IncompleteArrayType to a ConstantArrayType. + 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); + + Init = MaybeCreateExprWithCleanups(Init); + // Attach the initializer to the decl. + VDecl->setInit(Init); + + if (VDecl->isLocalVarDecl()) { + // C99 6.7.8p4: All the expressions in an initializer for an object that has + // static storage duration shall be constant expressions or string literals. + // C++ does not have this restriction. + if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl() && + VDecl->getStorageClass() == SC_Static) + CheckForConstantInitializer(Init, DclT); } else if (VDecl->isStaticDataMember() && VDecl->getLexicalDeclContext()->isRecord()) { // This is an in-class initialization for a static data member, e.g., @@ -6014,26 +6342,12 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // static const int value = 17; // }; - // Try to perform the initialization regardless. - if (!VDecl->isInvalidDecl()) { - InitializationSequence InitSeq(*this, Entity, Kind, &Init, 1); - ExprResult Result = InitSeq.Perform(*this, Entity, Kind, - MultiExprArg(*this, &Init, 1), - &DclT); - if (Result.isInvalid()) { - VDecl->setInvalidDecl(); - return; - } - - Init = Result.takeAs<Expr>(); - } - // C++ [class.mem]p4: // A member-declarator can contain a constant-initializer only // if it declares a static member (9.4) of const integral or // const enumeration type, see 9.4.2. // - // C++0x [class.static.data]p3: + // C++11 [class.static.data]p3: // If a non-volatile const static data member is of integral or // enumeration type, its declaration in the class definition can // specify a brace-or-equal-initializer in which every initalizer-clause @@ -6042,28 +6356,27 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, // with the constexpr specifier; if so, its declaration shall specify a // brace-or-equal-initializer in which every initializer-clause that is // an assignment-expression is a constant expression. - QualType T = VDecl->getType(); // Do nothing on dependent types. - if (T->isDependentType()) { + if (DclT->isDependentType()) { // Allow any 'static constexpr' members, whether or not they are of literal - // type. We separately check that the initializer is a constant expression, - // which implicitly requires the member to be of literal type. + // type. We separately check that every constexpr variable is of literal + // type. } else if (VDecl->isConstexpr()) { // Require constness. - } else if (!T.isConstQualified()) { + } else if (!DclT.isConstQualified()) { Diag(VDecl->getLocation(), diag::err_in_class_initializer_non_const) << Init->getSourceRange(); VDecl->setInvalidDecl(); // We allow integer constant expressions in all cases. - } else if (T->isIntegralOrEnumerationType()) { + } else if (DclT->isIntegralOrEnumerationType()) { // Check whether the expression is a constant expression. SourceLocation Loc; - if (getLangOptions().CPlusPlus0x && T.isVolatileQualified()) - // In C++0x, a non-constexpr const static data member with an + if (getLangOpts().CPlusPlus0x && 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); else if (Init->isValueDependent()) @@ -6083,88 +6396,65 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, VDecl->setInvalidDecl(); } - // We allow floating-point constants as an extension. - } else if (T->isFloatingType()) { // also permits complex, which is ok + // 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) - << T << Init->getSourceRange(); - if (getLangOptions().CPlusPlus0x) + << DclT << Init->getSourceRange(); + if (getLangOpts().CPlusPlus0x) Diag(VDecl->getLocation(), diag::note_in_class_initializer_float_type_constexpr) << FixItHint::CreateInsertion(VDecl->getLocStart(), "constexpr "); - if (!Init->isValueDependent() && - !Init->isConstantInitializer(Context, false)) { + 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++0x for literal types. - } else if (getLangOptions().CPlusPlus0x && T->isLiteralType()) { + // Suggest adding 'constexpr' in C++11 for literal types. + } else if (getLangOpts().CPlusPlus0x && DclT->isLiteralType()) { Diag(VDecl->getLocation(), diag::err_in_class_initializer_literal_type) - << T << Init->getSourceRange() + << DclT << Init->getSourceRange() << FixItHint::CreateInsertion(VDecl->getLocStart(), "constexpr "); VDecl->setConstexpr(true); } else { Diag(VDecl->getLocation(), diag::err_in_class_initializer_bad_type) - << T << Init->getSourceRange(); + << DclT << Init->getSourceRange(); VDecl->setInvalidDecl(); } } else if (VDecl->isFileVarDecl()) { - if (VDecl->getStorageClassAsWritten() == SC_Extern && - (!getLangOptions().CPlusPlus || + if (VDecl->getStorageClassAsWritten() == SC_Extern && + (!getLangOpts().CPlusPlus || !Context.getBaseElementType(VDecl->getType()).isConstQualified())) Diag(VDecl->getLocation(), diag::warn_extern_init); - if (!VDecl->isInvalidDecl()) { - InitializationSequence InitSeq(*this, Entity, Kind, &Init, 1); - ExprResult Result = InitSeq.Perform(*this, Entity, Kind, - MultiExprArg(*this, &Init, 1), - &DclT); - if (Result.isInvalid()) { - VDecl->setInvalidDecl(); - return; - } - Init = Result.takeAs<Expr>(); - } - - // C++ 3.6.2p2, allow dynamic initialization of static initializers. - // Don't check invalid declarations to avoid emitting useless diagnostics. - if (!getLangOptions().CPlusPlus && !VDecl->isInvalidDecl()) { - // C99 6.7.8p4. All file scoped initializers need to be constant. + // C99 6.7.8p4. All file scoped initializers need to be constant. + if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl()) CheckForConstantInitializer(Init, DclT); - } - } - // If the type changed, it means we had an incomplete type that was - // completed by the initializer. For example: - // int ary[] = { 1, 3, 5 }; - // "ary" transitions from a VariableArrayType to a ConstantArrayType. - if (!VDecl->isInvalidDecl() && (DclT != SavT)) { - VDecl->setType(DclT); - Init->setType(DclT); } - - // Check any implicit conversions within the expression. - CheckImplicitConversions(Init, VDecl->getLocation()); - - if (!VDecl->isInvalidDecl()) - checkUnsafeAssigns(VDecl->getLocation(), VDecl->getType(), Init); - if (VDecl->isConstexpr() && !VDecl->isInvalidDecl() && - !VDecl->getType()->isDependentType() && - !Init->isTypeDependent() && !Init->isValueDependent() && - !Init->isConstantInitializer(Context, - VDecl->getType()->isReferenceType())) { - // FIXME: Improve this diagnostic to explain why the initializer is not - // a constant expression. - Diag(VDecl->getLocation(), diag::err_constexpr_var_requires_const_init) - << VDecl << Init->getSourceRange(); + // We will represent direct-initialization similarly to copy-initialization: + // int x(1); -as-> int x = 1; + // ClassType x(a,b,c); -as-> ClassType x = ClassType(a,b,c); + // + // Clients that want to distinguish between the two forms, can check for + // direct initializer using VarDecl::getInitStyle(). + // A major benefit is that clients that don't particularly care about which + // exactly form was it (like the CodeGen) can handle both cases without + // special case code. + + // C++ 8.5p11: + // The form of initialization (using parentheses or '=') is generally + // insignificant, but does matter when the entity being initialized has a + // class type. + if (CXXDirectInit) { + assert(DirectInit && "Call-style initializer must be direct init."); + VDecl->setInitStyle(VarDecl::CallInit); + } else if (DirectInit) { + // This must be list-initialization. No other way is direct-initialization. + VDecl->setInitStyle(VarDecl::ListInit); } - - Init = MaybeCreateExprWithCleanups(Init); - // Attach the initializer to the decl. - VDecl->setInit(Init); CheckCompleteVariableDeclaration(VDecl); } @@ -6218,7 +6508,7 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl, if (VarDecl *Var = dyn_cast<VarDecl>(RealDecl)) { QualType Type = Var->getType(); - // C++0x [dcl.spec.auto]p3 + // C++11 [dcl.spec.auto]p3 if (TypeMayContainAuto && Type->getContainedAutoType()) { Diag(Var->getLocation(), diag::err_auto_var_requires_init) << Var->getDeclName() << Type; @@ -6226,17 +6516,19 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl, return; } - // C++0x [dcl.constexpr]p9: An object or reference declared constexpr must - // have an initializer. - // C++0x [class.static.data]p3: A static data member can be declared with + // C++11 [class.static.data]p3: A static data member can be declared with // the constexpr specifier; if so, its declaration shall specify // a brace-or-equal-initializer. - // - // A static data member's definition may inherit an initializer from an - // in-class declaration. - if (Var->isConstexpr() && !Var->getAnyInitializer()) { - Diag(Var->getLocation(), diag::err_constexpr_var_requires_init) - << Var->getDeclName(); + // C++11 [dcl.constexpr]p1: The constexpr specifier shall be applied only to + // the definition of a variable [...] or the declaration of a static data + // member. + if (Var->isConstexpr() && !Var->isThisDeclarationADefinition()) { + if (Var->isStaticDataMember()) + Diag(Var->getLocation(), + diag::err_constexpr_static_mem_var_requires_init) + << Var->getDeclName(); + else + Diag(Var->getLocation(), diag::err_invalid_constexpr_var_decl); Var->setInvalidDecl(); return; } @@ -6295,7 +6587,7 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl, // is accepted by gcc. Hence here we issue a warning instead of // an error and we do not invalidate the static declaration. // NOTE: to avoid multiple warnings, only check the first declaration. - if (Var->getPreviousDeclaration() == 0) + if (Var->getPreviousDecl() == 0) RequireCompleteType(Var->getLocation(), Type, diag::ext_typecheck_decl_incomplete_type); } @@ -6352,21 +6644,21 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl, // Check for jumps past the implicit initializer. C++0x // clarifies that this applies to a "variable with automatic // storage duration", not a "local variable". - // C++0x [stmt.dcl]p3 + // C++11 [stmt.dcl]p3 // A program that jumps from a point where a variable with automatic // storage duration is not in scope to a point where it is in scope is // ill-formed unless the variable has scalar type, class type with a // trivial default constructor and a trivial destructor, a cv-qualified // version of one of these types, or an array of one of the preceding // types and is declared without an initializer. - if (getLangOptions().CPlusPlus && Var->hasLocalStorage()) { + if (getLangOpts().CPlusPlus && Var->hasLocalStorage()) { if (const RecordType *Record = Context.getBaseElementType(Type)->getAs<RecordType>()) { CXXRecordDecl *CXXRecord = cast<CXXRecordDecl>(Record->getDecl()); - if ((!getLangOptions().CPlusPlus0x && !CXXRecord->isPOD()) || - (getLangOptions().CPlusPlus0x && - (!CXXRecord->hasTrivialDefaultConstructor() || - !CXXRecord->hasTrivialDestructor()))) + // Mark the function for further checking even if the looser rules of + // C++11 do not require such checks, so that we can diagnose + // incompatibilities with C++98. + if (!CXXRecord->isPOD()) getCurFunction()->setHasBranchProtectedScope(); } } @@ -6394,8 +6686,11 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl, MultiExprArg(*this, 0, 0)); if (Init.isInvalid()) Var->setInvalidDecl(); - else if (Init.get()) + else if (Init.get()) { Var->setInit(MaybeCreateExprWithCleanups(Init.get())); + // This is important for template substitution. + Var->setInitStyle(VarDecl::CallInit); + } CheckCompleteVariableDeclaration(Var); } @@ -6448,7 +6743,7 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { // In ARC, don't allow jumps past the implicit initialization of a // local retaining variable. - if (getLangOptions().ObjCAutoRefCount && + if (getLangOpts().ObjCAutoRefCount && var->hasLocalStorage()) { switch (var->getType().getObjCLifetime()) { case Qualifiers::OCL_None: @@ -6464,7 +6759,7 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { } // All the following checks are C++ only. - if (!getLangOptions().CPlusPlus) return; + if (!getLangOpts().CPlusPlus) return; QualType baseType = Context.getBaseElementType(var->getType()); if (baseType->isDependentType()) return; @@ -6480,7 +6775,7 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { if (type->isStructureOrClassType()) { SourceLocation poi = var->getLocation(); - Expr *varRef = new (Context) DeclRefExpr(var, type, VK_LValue, poi); + Expr *varRef =new (Context) DeclRefExpr(var, false, type, VK_LValue, poi); ExprResult result = PerformCopyInitialization( InitializedEntity::InitializeBlock(poi, type, false), @@ -6493,15 +6788,41 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { } } - // Check for global constructors. - if (!var->getDeclContext()->isDependentContext() && - var->hasGlobalStorage() && - !var->isStaticLocal() && - var->getInit() && - !var->getInit()->isConstantInitializer(Context, - baseType->isReferenceType())) - Diag(var->getLocation(), diag::warn_global_constructor) - << var->getInit()->getSourceRange(); + Expr *Init = var->getInit(); + bool IsGlobal = var->hasGlobalStorage() && !var->isStaticLocal(); + + if (!var->getDeclContext()->isDependentContext() && Init) { + if (IsGlobal && !var->isConstexpr() && + getDiagnostics().getDiagnosticLevel(diag::warn_global_constructor, + var->getLocation()) + != DiagnosticsEngine::Ignored && + !Init->isConstantInitializer(Context, baseType->isReferenceType())) + Diag(var->getLocation(), diag::warn_global_constructor) + << Init->getSourceRange(); + + if (var->isConstexpr()) { + llvm::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 + // location, fold it into the primary diagnostic. + if (Notes.size() == 1 && Notes[0].second.getDiagID() == + diag::note_invalid_subexpr_in_const_expr) { + DiagLoc = Notes[0].first; + Notes.clear(); + } + Diag(DiagLoc, diag::err_constexpr_var_requires_const_init) + << var << Init->getSourceRange(); + for (unsigned I = 0, N = Notes.size(); I != N; ++I) + Diag(Notes[I].first, Notes[I].second); + } + } else if (var->isUsableInConstantExpressions(Context)) { + // Check whether the initializer of a const variable of integral or + // enumeration type is an ICE now, since we can't tell whether it was + // initialized by a constant expression if we check later. + var->checkInitIsICE(); + } + } // Require the destructor. if (const RecordType *recordType = baseType->getAs<RecordType>()) @@ -6586,11 +6907,16 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { const DeclSpec &DS = D.getDeclSpec(); // Verify C99 6.7.5.3p2: The only SCS allowed is 'register'. + // C++03 [dcl.stc]p2 also permits 'auto'. VarDecl::StorageClass StorageClass = SC_None; 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); @@ -6608,7 +6934,7 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); QualType parmDeclType = TInfo->getType(); - if (getLangOptions().CPlusPlus) { + if (getLangOpts().CPlusPlus) { // Check that there are no default arguments inside the type of this // parameter. CheckExtraCXXDefaultArguments(D); @@ -6660,7 +6986,7 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { // the enclosing context. This prevents them from accidentally // looking like class members in C++. ParmVarDecl *New = CheckParameter(Context.getTranslationUnitDecl(), - D.getSourceRange().getBegin(), + D.getLocStart(), D.getIdentifierLoc(), II, parmDeclType, TInfo, StorageClass, StorageClassAsWritten); @@ -6715,7 +7041,7 @@ void Sema::DiagnoseUnusedParameters(ParmVarDecl * const *Param, return; for (; Param != ParamEnd; ++Param) { - if (!(*Param)->isUsed() && (*Param)->getDeclName() && + if (!(*Param)->isReferenced() && (*Param)->getDeclName() && !(*Param)->hasAttr<UnusedAttr>()) { Diag((*Param)->getLocation(), diag::warn_unused_parameter) << (*Param)->getDeclName(); @@ -6732,7 +7058,7 @@ void Sema::DiagnoseSizeOfParametersAndReturnValue(ParmVarDecl * const *Param, // Warn if the return value is pass-by-value and larger than the specified // threshold. - if (ReturnTy.isPODType(Context)) { + if (!ReturnTy->isDependentType() && ReturnTy.isPODType(Context)) { unsigned Size = Context.getTypeSizeInChars(ReturnTy).getQuantity(); if (Size > LangOpts.NumLargeByValueCopy) Diag(D->getLocation(), diag::warn_return_value_size) @@ -6743,7 +7069,7 @@ void Sema::DiagnoseSizeOfParametersAndReturnValue(ParmVarDecl * const *Param, // threshold. for (; Param != ParamEnd; ++Param) { QualType T = (*Param)->getType(); - if (!T.isPODType(Context)) + if (T->isDependentType() || !T.isPODType(Context)) continue; unsigned Size = Context.getTypeSizeInChars(T).getQuantity(); if (Size > LangOpts.NumLargeByValueCopy) @@ -6758,7 +7084,7 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc, VarDecl::StorageClass StorageClass, VarDecl::StorageClass StorageClassAsWritten) { // In ARC, infer a lifetime qualifier for appropriate parameter types. - if (getLangOptions().ObjCAutoRefCount && + if (getLangOpts().ObjCAutoRefCount && T.getObjCLifetime() == Qualifiers::OCL_None && T->isObjCLifetimeType()) { @@ -6826,7 +7152,7 @@ void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D, for (int i = FTI.NumArgs; i != 0; /* decrement in loop */) { --i; if (FTI.ArgInfo[i].Param == 0) { - llvm::SmallString<256> Code; + SmallString<256> Code; llvm::raw_svector_ostream(Code) << " int " << FTI.ArgInfo[i].Ident->getName() << ";\n"; @@ -6856,7 +7182,7 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, assert(D.isFunctionDeclarator() && "Not a function declarator!"); Scope *ParentScope = FnBodyScope->getParent(); - D.setFunctionDefinition(true); + D.setFunctionDefinitionKind(FDK_Definition); Decl *DP = HandleDeclarator(ParentScope, D, MultiTemplateParamsArg(*this)); return ActOnStartOfFunctionDef(FnBodyScope, DP); @@ -6892,8 +7218,8 @@ static bool ShouldWarnAboutMissingPrototype(const FunctionDecl *FD) { return false; bool MissingPrototype = true; - for (const FunctionDecl *Prev = FD->getPreviousDeclaration(); - Prev; Prev = Prev->getPreviousDeclaration()) { + for (const FunctionDecl *Prev = FD->getPreviousDecl(); + Prev; Prev = Prev->getPreviousDecl()) { // Ignore any declarations that occur in function or method // scope, because they aren't visible from the header. if (Prev->getDeclContext()->isFunctionOrMethod()) @@ -6911,11 +7237,11 @@ void Sema::CheckForFunctionRedefinition(FunctionDecl *FD) { // was an extern inline function. const FunctionDecl *Definition; if (FD->isDefined(Definition) && - !canRedefineFunction(Definition, getLangOptions())) { - if (getLangOptions().GNUMode && Definition->isInlineSpecified() && + !canRedefineFunction(Definition, getLangOpts())) { + if (getLangOpts().GNUMode && Definition->isInlineSpecified() && Definition->getStorageClass() == SC_Extern) Diag(FD->getLocation(), diag::err_redefinition_extern_inline) - << FD->getDeclName() << getLangOptions().CPlusPlus; + << FD->getDeclName() << getLangOpts().CPlusPlus; else Diag(FD->getLocation(), diag::err_redefinition) << FD->getDeclName(); Diag(Definition->getLocation(), diag::note_previous_definition); @@ -6987,6 +7313,43 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D) { } } + // If we had any tags defined in the function prototype, + // introduce them into the function scope. + if (FnBodyScope) { + for (llvm::ArrayRef<NamedDecl*>::iterator I = FD->getDeclsInPrototypeScope().begin(), + E = FD->getDeclsInPrototypeScope().end(); I != E; ++I) { + NamedDecl *D = *I; + + // Some of these decls (like enums) may have been pinned to the translation unit + // for lack of a real context earlier. If so, remove from the translation unit + // and reattach to the current context. + if (D->getLexicalDeclContext() == Context.getTranslationUnitDecl()) { + // Is the decl actually in the context? + for (DeclContext::decl_iterator DI = Context.getTranslationUnitDecl()->decls_begin(), + DE = Context.getTranslationUnitDecl()->decls_end(); DI != DE; ++DI) { + if (*DI == D) { + Context.getTranslationUnitDecl()->removeDecl(D); + break; + } + } + // Either way, reassign the lexical decl context to our FunctionDecl. + D->setLexicalDeclContext(CurContext); + } + + // If the decl has a non-null name, make accessible in the current scope. + if (!D->getName().empty()) + PushOnScopeChains(D, FnBodyScope, /*AddToContext=*/false); + + // Similarly, dive into enums and fish their constants out, making them + // accessible in this scope. + if (EnumDecl *ED = dyn_cast<EnumDecl>(D)) { + for (EnumDecl::enumerator_iterator EI = ED->enumerator_begin(), + EE = ED->enumerator_end(); EI != EE; ++EI) + PushOnScopeChains(*EI, FnBodyScope, /*AddToContext=*/false); + } + } + } + // Checking attributes of current function definition // dllimport attribute. DLLImportAttr *DA = FD->getAttr<DLLImportAttr>(); @@ -7068,20 +7431,15 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, if (FD) { FD->setBody(Body); - if (FD->isMain()) { - // C and C++ allow for main to automagically return 0. - // Implements C++ [basic.start.main]p5 and C99 5.1.2.2.3. - FD->setHasImplicitReturnZero(true); - WP.disableCheckFallThrough(); - } else if (FD->hasAttr<NakedAttr>()) { - // If the function is marked 'naked', don't complain about missing return - // statements. + + // If the function implicitly returns zero (like 'main') or is naked, + // don't complain about missing return statements. + if (FD->hasImplicitReturnZero() || FD->hasAttr<NakedAttr>()) WP.disableCheckFallThrough(); - } // MSVC permits the use of pure specifier (=0) on function definition, // defined at class scope, warn about this non standard construct. - if (getLangOptions().MicrosoftExt && FD->isPure()) + if (getLangOpts().MicrosoftExt && FD->isPure()) Diag(FD->getLocation(), diag::warn_pure_function_definition); if (!FD->isInvalidDecl()) { @@ -7096,7 +7454,8 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, computeNRVO(Body, getCurFunction()); } - assert(FD == getCurFunctionDecl() && "Function parsing confused"); + assert((FD == getCurFunctionDecl() || getCurLambda()->CallOperator == FD) && + "Function parsing confused"); } else if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(dcl)) { assert(MD == getCurMethodDecl() && "Method parsing confused"); MD->setBody(Body); @@ -7154,33 +7513,34 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, // deletion in some later function. if (PP.getDiagnostics().hasErrorOccurred() || PP.getDiagnostics().getSuppressAllDiagnostics()) { - ExprTemporaries.clear(); - ExprNeedsCleanups = false; + DiscardCleanupsInEvaluationContext(); } else if (!isa<FunctionTemplateDecl>(dcl)) { // Since the body is valid, issue any analysis-based warnings that are // enabled. ActivePolicy = &WP; } - if (FD && FD->isConstexpr() && !FD->isInvalidDecl() && - !CheckConstexprFunctionBody(FD, Body)) + if (!IsInstantiation && FD && FD->isConstexpr() && !FD->isInvalidDecl() && + (!CheckConstexprFunctionDecl(FD) || + !CheckConstexprFunctionBody(FD, Body))) FD->setInvalidDecl(); - assert(ExprTemporaries.empty() && "Leftover temporaries in function"); + assert(ExprCleanupObjects.empty() && "Leftover temporaries in function"); assert(!ExprNeedsCleanups && "Unaccounted cleanups in function"); + assert(MaybeODRUseExprs.empty() && + "Leftover expressions for odr-use checking"); } if (!IsInstantiation) PopDeclContext(); - PopFunctionOrBlockScope(ActivePolicy, dcl); + PopFunctionScopeInfo(ActivePolicy, dcl); // If any errors have occurred, clear out any temporaries that may have // been leftover. This ensures that these temporaries won't be picked up for // deletion in some later function. if (getDiagnostics().hasErrorOccurred()) { - ExprTemporaries.clear(); - ExprNeedsCleanups = false; + DiscardCleanupsInEvaluationContext(); } return dcl; @@ -7191,6 +7551,9 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, /// relevant Decl. void Sema::ActOnFinishDelayedAttribute(Scope *S, Decl *D, ParsedAttributes &Attrs) { + // Always attach attributes to the underlying decl. + if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) + D = TD->getTemplatedDecl(); ProcessDeclAttributeList(S, D, Attrs.getList()); } @@ -7212,12 +7575,35 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, } // Extension in C99. Legal in C90, but warn about it. + unsigned diag_id; if (II.getName().startswith("__builtin_")) - Diag(Loc, diag::warn_builtin_unknown) << &II; - else if (getLangOptions().C99) - Diag(Loc, diag::ext_implicit_function_decl) << &II; + diag_id = diag::warn_builtin_unknown; + else if (getLangOpts().C99) + diag_id = diag::ext_implicit_function_decl; else - Diag(Loc, diag::warn_implicit_function_decl) << &II; + diag_id = diag::warn_implicit_function_decl; + Diag(Loc, diag_id) << &II; + + // Because typo correction is expensive, only do it if the implicit + // function declaration is going to be treated as an error. + if (Diags.getDiagnosticLevel(diag_id, Loc) >= DiagnosticsEngine::Error) { + TypoCorrection Corrected; + DeclFilterCCC<FunctionDecl> Validator; + if (S && (Corrected = CorrectTypo(DeclarationNameInfo(&II, Loc), + LookupOrdinaryName, S, 0, Validator))) { + std::string CorrectedStr = Corrected.getAsString(getLangOpts()); + std::string CorrectedQuotedStr = Corrected.getQuoted(getLangOpts()); + FunctionDecl *Func = Corrected.getCorrectionDeclAs<FunctionDecl>(); + + Diag(Loc, diag::note_function_suggestion) << CorrectedQuotedStr + << FixItHint::CreateReplacement(Loc, CorrectedStr); + + if (Func->getLocation().isValid() + && !II.getName().startswith("__builtin_")) + Diag(Func->getLocation(), diag::note_previous_decl) + << CorrectedQuotedStr; + } + } // Set a Declarator for the implicit definition: int foo(); const char *Dummy; @@ -7230,6 +7616,7 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, Declarator D(DS, Declarator::BlockContext); D.AddTypeInfo(DeclaratorChunk::getFunction(false, false, SourceLocation(), 0, 0, 0, true, SourceLocation(), + SourceLocation(), SourceLocation(), SourceLocation(), EST_None, SourceLocation(), 0, 0, 0, 0, Loc, Loc, D), @@ -7272,10 +7659,16 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { unsigned FormatIdx; bool HasVAListArg; if (Context.BuiltinInfo.isPrintfLike(BuiltinID, FormatIdx, HasVAListArg)) { - if (!FD->getAttr<FormatAttr>()) + if (!FD->getAttr<FormatAttr>()) { + const char *fmt = "printf"; + unsigned int NumParams = FD->getNumParams(); + if (FormatIdx < NumParams && // NumParams may be 0 (e.g. vfprintf) + FD->getParamDecl(FormatIdx)->getType()->isObjCObjectPointerType()) + fmt = "NSString"; FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context, - "printf", FormatIdx+1, + fmt, FormatIdx+1, HasVAListArg ? 0 : FormatIdx+2)); + } } if (Context.BuiltinInfo.isScanfLike(BuiltinID, FormatIdx, HasVAListArg)) { @@ -7288,7 +7681,7 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { // Mark const if we don't care about errno and that is the only // thing preventing the function from being const. This allows // IRgen to use LLVM intrinsics for such functions. - if (!getLangOptions().MathErrno && + if (!getLangOpts().MathErrno && Context.BuiltinInfo.isConstWithoutErrno(BuiltinID)) { if (!FD->getAttr<ConstAttr>()) FD->addAttr(::new (Context) ConstAttr(FD->getLocation(), Context)); @@ -7306,7 +7699,7 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { IdentifierInfo *Name = FD->getIdentifier(); if (!Name) return; - if ((!getLangOptions().CPlusPlus && + if ((!getLangOpts().CPlusPlus && FD->getDeclContext()->isTranslationUnit()) || (isa<LinkageSpecDecl>(FD->getDeclContext()) && cast<LinkageSpecDecl>(FD->getDeclContext())->getLanguage() == @@ -7316,16 +7709,7 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) { } else return; - if (Name->isStr("NSLog") || Name->isStr("NSLogv")) { - // FIXME: NSLog and NSLogv should be target specific - if (const FormatAttr *Format = FD->getAttr<FormatAttr>()) { - // FIXME: We known better than our headers. - const_cast<FormatAttr *>(Format)->setType(Context, "printf"); - } else - FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context, - "printf", 1, - Name->isStr("NSLogv") ? 0 : 2)); - } else if (Name->isStr("asprintf") || Name->isStr("vasprintf")) { + if (Name->isStr("asprintf") || Name->isStr("vasprintf")) { // FIXME: asprintf and vasprintf aren't C99 functions. Should they be // target-specific builtins, perhaps? if (!FD->getAttr<FormatAttr>()) @@ -7347,7 +7731,7 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T, // Scope manipulation handled by caller. TypedefDecl *NewTD = TypedefDecl::Create(Context, CurContext, - D.getSourceRange().getBegin(), + D.getLocStart(), D.getIdentifierLoc(), D.getIdentifier(), TInfo); @@ -7406,6 +7790,52 @@ TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D, QualType T, } +/// \brief Check that this is a valid underlying type for an enum declaration. +bool Sema::CheckEnumUnderlyingType(TypeSourceInfo *TI) { + SourceLocation UnderlyingLoc = TI->getTypeLoc().getBeginLoc(); + QualType T = TI->getType(); + + if (T->isDependentType() || T->isIntegralType(Context)) + return false; + + Diag(UnderlyingLoc, diag::err_enum_invalid_underlying) << T; + return true; +} + +/// Check whether this is a valid redeclaration of a previous enumeration. +/// \return true if the redeclaration was invalid. +bool Sema::CheckEnumRedeclaration(SourceLocation EnumLoc, bool IsScoped, + QualType EnumUnderlyingTy, + const EnumDecl *Prev) { + bool IsFixed = !EnumUnderlyingTy.isNull(); + + if (IsScoped != Prev->isScoped()) { + Diag(EnumLoc, diag::err_enum_redeclare_scoped_mismatch) + << Prev->isScoped(); + Diag(Prev->getLocation(), diag::note_previous_use); + return true; + } + + if (IsFixed && Prev->isFixed()) { + if (!EnumUnderlyingTy->isDependentType() && + !Prev->getIntegerType()->isDependentType() && + !Context.hasSameUnqualifiedType(EnumUnderlyingTy, + Prev->getIntegerType())) { + Diag(EnumLoc, diag::err_enum_redeclare_type_mismatch) + << EnumUnderlyingTy << Prev->getIntegerType(); + Diag(Prev->getLocation(), diag::note_previous_use); + return true; + } + } else if (IsFixed != Prev->isFixed()) { + Diag(EnumLoc, diag::err_enum_redeclare_fixed_mismatch) + << Prev->isFixed(); + Diag(Prev->getLocation(), diag::note_previous_use); + return true; + } + + return false; +} + /// \brief Determine whether a tag with a given kind is acceptable /// as a redeclaration of the given tag declaration. /// @@ -7512,15 +7942,18 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation ModulePrivateLoc, MultiTemplateParamsArg TemplateParameterLists, bool &OwnedDecl, bool &IsDependent, - bool ScopedEnum, bool ScopedEnumUsesClassTag, + SourceLocation ScopedEnumKWLoc, + bool ScopedEnumUsesClassTag, TypeResult UnderlyingType) { // If this is not a definition, it must have a name. + IdentifierInfo *OrigName = Name; assert((Name != 0 || TUK == TUK_Definition) && "Nameless record must be a definition!"); assert(TemplateParameterLists.size() == 0 || TUK != TUK_Reference); OwnedDecl = false; TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec); + bool ScopedEnum = ScopedEnumKWLoc.isValid(); // FIXME: Check explicit specializations more carefully. bool isExplicitSpecialization = false; @@ -7576,23 +8009,18 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // C++0x 7.2p2: The type-specifier-seq of an enum-base shall name an // integral type; any cv-qualification is ignored. TypeSourceInfo *TI = 0; - QualType T = GetTypeFromParser(UnderlyingType.get(), &TI); + GetTypeFromParser(UnderlyingType.get(), &TI); EnumUnderlying = TI; - SourceLocation UnderlyingLoc = TI->getTypeLoc().getBeginLoc(); - - if (!T->isDependentType() && !T->isIntegralType(Context)) { - Diag(UnderlyingLoc, diag::err_enum_invalid_underlying) - << T; + if (CheckEnumUnderlyingType(TI)) // Recover by falling back to int. EnumUnderlying = Context.IntTy.getTypePtr(); - } - if (DiagnoseUnexpandedParameterPack(UnderlyingLoc, TI, + if (DiagnoseUnexpandedParameterPack(TI->getTypeLoc().getBeginLoc(), TI, UPPC_FixedUnderlyingType)) EnumUnderlying = Context.IntTy.getTypePtr(); - } else if (getLangOptions().MicrosoftExt) + } else if (getLangOpts().MicrosoftMode) // Microsoft enums are always of int type. EnumUnderlying = Context.IntTy.getTypePtr(); } @@ -7686,7 +8114,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, if (Previous.isAmbiguous()) return 0; - if (!getLangOptions().CPlusPlus && TUK != TUK_Reference) { + if (!getLangOpts().CPlusPlus && TUK != TUK_Reference) { // FIXME: This makes sure that we ignore the contexts associated // with C structs, unions, and enums when looking for a matching // tag declaration or definition. See the similar lookup tweak @@ -7697,6 +8125,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, } else if (S->isFunctionPrototypeScope()) { // If this is an enum declaration in function prototype scope, set its // initial context to the translation unit. + // FIXME: [citation needed] SearchDC = Context.getTranslationUnitDecl(); } @@ -7708,7 +8137,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, Previous.clear(); } - if (getLangOptions().CPlusPlus && Name && DC && StdNamespace && + if (getLangOpts().CPlusPlus && Name && DC && StdNamespace && DC->Equals(getStdNamespace()) && Name->isStr("bad_alloc")) { // This is a declaration of or a reference to "std::bad_alloc". isStdBadAlloc = true; @@ -7759,12 +8188,12 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // Find the context where we'll be declaring the tag. // FIXME: We would like to maintain the current DeclContext as the // lexical context, - while (SearchDC->isRecord() || SearchDC->isTransparentContext()) + while (!SearchDC->isFileContext() && !SearchDC->isFunctionOrMethod()) SearchDC = SearchDC->getParent(); // Find the scope where we'll be declaring the tag. while (S->isClassScope() || - (getLangOptions().CPlusPlus && + (getLangOpts().CPlusPlus && S->isFunctionPrototypeScope()) || ((S->getFlags() & Scope::DeclScope) == 0) || (S->getEntity() && @@ -7781,7 +8210,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // In C++, we need to do a redeclaration lookup to properly // diagnose some problems. - if (getLangOptions().CPlusPlus) { + if (getLangOpts().CPlusPlus) { Previous.setRedeclarationKind(ForRedeclaration); LookupQualifiedName(Previous, SearchDC); } @@ -7799,7 +8228,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // technically forbidden by the current standard but which is // okay according to the likely resolution of an open issue; // see http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#407 - if (getLangOptions().CPlusPlus) { + if (getLangOpts().CPlusPlus) { if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(PrevDecl)) { if (const TagType *TT = TD->getUnderlyingType()->getAs<TagType>()) { TagDecl *Tag = TT->getDecl(); @@ -7851,36 +8280,28 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, if (Kind == TTK_Enum && PrevTagDecl->getTagKind() == TTK_Enum) { const EnumDecl *PrevEnum = cast<EnumDecl>(PrevTagDecl); - // All conflicts with previous declarations are recovered by - // returning the previous declaration. - if (ScopedEnum != PrevEnum->isScoped()) { - Diag(KWLoc, diag::err_enum_redeclare_scoped_mismatch) - << PrevEnum->isScoped(); - Diag(PrevTagDecl->getLocation(), diag::note_previous_use); - return PrevTagDecl; - } - else if (EnumUnderlying && PrevEnum->isFixed()) { - QualType T; - if (TypeSourceInfo *TI = EnumUnderlying.dyn_cast<TypeSourceInfo*>()) - T = TI->getType(); - else - T = QualType(EnumUnderlying.get<const Type*>(), 0); - - if (!Context.hasSameUnqualifiedType(T, PrevEnum->getIntegerType())) { - Diag(NameLoc.isValid() ? NameLoc : KWLoc, - diag::err_enum_redeclare_type_mismatch) - << T - << PrevEnum->getIntegerType(); - Diag(PrevTagDecl->getLocation(), diag::note_previous_use); - return PrevTagDecl; - } - } - else if (!EnumUnderlying.isNull() != PrevEnum->isFixed()) { - Diag(KWLoc, diag::err_enum_redeclare_fixed_mismatch) - << PrevEnum->isFixed(); - Diag(PrevTagDecl->getLocation(), diag::note_previous_use); + // If this is an elaborated-type-specifier for a scoped enumeration, + // the 'class' keyword is not necessary and not permitted. + if (TUK == TUK_Reference || TUK == TUK_Friend) { + if (ScopedEnum) + Diag(ScopedEnumKWLoc, diag::err_enum_class_reference) + << PrevEnum->isScoped() + << FixItHint::CreateRemoval(ScopedEnumKWLoc); return PrevTagDecl; } + + QualType EnumUnderlyingTy; + if (TypeSourceInfo *TI = EnumUnderlying.dyn_cast<TypeSourceInfo*>()) + EnumUnderlyingTy = TI->getType(); + else if (const Type *T = EnumUnderlying.dyn_cast<const Type*>()) + EnumUnderlyingTy = QualType(T, 0); + + // All conflicts with previous declarations are recovered by + // returning the previous declaration, unless this is a definition, + // in which case we want the caller to bail out. + if (CheckEnumRedeclaration(NameLoc.isValid() ? NameLoc : KWLoc, + ScopedEnum, EnumUnderlyingTy, PrevEnum)) + return TUK == TUK_Declaration ? PrevTagDecl : 0; } if (!Invalid) { @@ -7891,7 +8312,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // For our current ASTs this shouldn't be a problem, but will // need to be changed with DeclGroups. if ((TUK == TUK_Reference && (!PrevTagDecl->getFriendObjectKind() || - getLangOptions().MicrosoftExt)) || TUK == TUK_Friend) + getLangOpts().MicrosoftExt)) || TUK == TUK_Friend) return PrevTagDecl; // Diagnose attempts to redefine a tag. @@ -7900,11 +8321,25 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // If we're defining a specialization and the previous definition // is from an implicit instantiation, don't emit an error // here; we'll catch this in the general case below. - if (!isExplicitSpecialization || - !isa<CXXRecordDecl>(Def) || - cast<CXXRecordDecl>(Def)->getTemplateSpecializationKind() - == TSK_ExplicitSpecialization) { - Diag(NameLoc, diag::err_redefinition) << Name; + bool IsExplicitSpecializationAfterInstantiation = false; + if (isExplicitSpecialization) { + if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Def)) + IsExplicitSpecializationAfterInstantiation = + RD->getTemplateSpecializationKind() != + TSK_ExplicitSpecialization; + else if (EnumDecl *ED = dyn_cast<EnumDecl>(Def)) + IsExplicitSpecializationAfterInstantiation = + ED->getTemplateSpecializationKind() != + TSK_ExplicitSpecialization; + } + + if (!IsExplicitSpecializationAfterInstantiation) { + // A redeclaration in function prototype scope in C isn't + // visible elsewhere, so merely issue a warning. + if (!getLangOpts().CPlusPlus && S->containedInPrototypeScope()) + Diag(NameLoc, diag::warn_redefinition_in_param_list) << Name; + else + Diag(NameLoc, diag::err_redefinition) << Name; Diag(Def->getLocation(), diag::note_previous_definition); // If this is a redefinition, recover by making this // struct be anonymous, which will make any later @@ -7951,8 +8386,6 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // lookup. This is only actually possible in C++, where a few // things like templates still live in the tag namespace. } else { - assert(getLangOptions().CPlusPlus); - // Use a better diagnostic if an elaborated-type-specifier // found the wrong kind of type on the first // (non-redeclaration) lookup. @@ -8033,7 +8466,7 @@ CreateNewDecl: // If this is an undefined enum, warn. if (TUK != TUK_Definition && !Invalid) { TagDecl *Def; - if (getLangOptions().CPlusPlus0x && cast<EnumDecl>(New)->isFixed()) { + if (getLangOpts().CPlusPlus0x && cast<EnumDecl>(New)->isFixed()) { // C++0x: 7.2p2: opaque-enum-declaration. // Conflicts are diagnosed above. Do nothing. } @@ -8043,9 +8476,9 @@ CreateNewDecl: Diag(Def->getLocation(), diag::note_previous_definition); } else { unsigned DiagID = diag::ext_forward_ref_enum; - if (getLangOptions().MicrosoftExt) + if (getLangOpts().MicrosoftMode) DiagID = diag::ext_ms_forward_ref_enum; - else if (getLangOptions().CPlusPlus) + else if (getLangOpts().CPlusPlus) DiagID = diag::err_forward_ref_enum; Diag(Loc, DiagID); @@ -8071,7 +8504,7 @@ CreateNewDecl: // FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.: // struct X { int A; } D; D should chain to X. - if (getLangOptions().CPlusPlus) { + if (getLangOpts().CPlusPlus) { // FIXME: Look for a way to use RecordDecl for simple structs. New = CXXRecordDecl::Create(Context, Kind, SearchDC, KWLoc, Loc, Name, cast_or_null<CXXRecordDecl>(PrevDecl)); @@ -8086,6 +8519,16 @@ CreateNewDecl: // Maybe add qualifier info. if (SS.isNotEmpty()) { if (SS.isSet()) { + // If this is either a declaration or a definition, check the + // nested-name-specifier against the current context. We don't do this + // for explicit specializations, because they have similar checking + // (with more specific diagnostics) in the call to + // CheckMemberSpecialization, below. + if (!isExplicitSpecialization && + (TUK == TUK_Definition || TUK == TUK_Declaration) && + diagnoseQualifiedDeclaration(SS, DC, OrigName, NameLoc)) + Invalid = true; + New->setQualifierInfo(SS.getWithLocInContext(Context)); if (TemplateParameterLists.size() > 0) { New->setTemplateParameterListsInfo(Context, @@ -8112,19 +8555,14 @@ CreateNewDecl: AddMsStructLayoutForRecord(RD); } - if (PrevDecl && PrevDecl->isModulePrivate()) - New->setModulePrivate(); - else if (ModulePrivateLoc.isValid()) { + if (ModulePrivateLoc.isValid()) { if (isExplicitSpecialization) Diag(New->getLocation(), diag::err_module_private_specialization) << 2 << FixItHint::CreateRemoval(ModulePrivateLoc); - else if (PrevDecl && !PrevDecl->isModulePrivate()) - diagnoseModulePrivateRedeclaration(New, PrevDecl, ModulePrivateLoc); // __module_private__ does not apply to local classes. However, we only // diagnose this as an error when the declaration specifiers are // freestanding. Here, we just ignore the __module_private__. - // foobar else if (!SearchDC->isFunctionOrMethod()) New->setModulePrivate(); } @@ -8133,7 +8571,7 @@ CreateNewDecl: // check the specialization. if (isExplicitSpecialization && CheckMemberSpecialization(New, Previous)) Invalid = true; - + if (Invalid) New->setInvalidDecl(); @@ -8142,7 +8580,7 @@ CreateNewDecl: // If we're declaring or defining a tag in function prototype scope // in C, note that this type can only be used within the function. - if (Name && S->isFunctionPrototypeScope() && !getLangOptions().CPlusPlus) + if (Name && S->isFunctionPrototypeScope() && !getLangOpts().CPlusPlus) Diag(Loc, diag::warn_decl_in_param_list) << Context.getTagDeclType(New); // Set the lexical context. If the tag has a C++ scope specifier, the @@ -8155,7 +8593,7 @@ CreateNewDecl: // the tag name visible. if (TUK == TUK_Friend) New->setObjectOfFriendDecl(/* PreviouslyDeclared = */ !Previous.empty() || - getLangOptions().MicrosoftExt); + getLangOpts().MicrosoftExt); // Set the access specifier. if (!Invalid && SearchDC->isRecord()) @@ -8172,7 +8610,7 @@ CreateNewDecl: New->setAccess(PrevDecl->getAccess()); DeclContext *DC = New->getDeclContext()->getRedeclContext(); - DC->makeDeclVisibleInContext(New, /* Recoverable = */ false); + DC->makeDeclVisibleInContext(New); if (Name) // can be null along some error paths if (Scope *EnclosingScope = getScopeForDeclContext(S, DC)) PushOnScopeChains(New, EnclosingScope, /* AddToContext = */ false); @@ -8180,7 +8618,7 @@ CreateNewDecl: S = getNonFieldDeclScope(S); PushOnScopeChains(New, S, !IsForwardReference); if (IsForwardReference) - SearchDC->makeDeclVisibleInContext(New, /* Recoverable = */ false); + SearchDC->makeDeclVisibleInContext(New); } else { CurContext->addDecl(New); @@ -8193,6 +8631,12 @@ CreateNewDecl: II->isStr("FILE")) Context.setFILEDecl(New); + // If we were in function prototype scope (and not in C++ mode), add this + // tag to the list of decls to inject into the function definition scope. + if (S->isFunctionPrototypeScope() && !getLangOpts().CPlusPlus && + InFunctionDeclarator && Name) + DeclsInPrototypeScope.push_back(New); + OwnedDecl = true; return New; } @@ -8256,6 +8700,13 @@ void Sema::ActOnTagFinishDefinition(Scope *S, Decl *TagD, TagDecl *Tag = cast<TagDecl>(TagD); Tag->setRBraceLoc(RBraceLoc); + // Make sure we "complete" the definition even it is invalid. + if (Tag->isBeingDefined()) { + assert(Tag->isInvalidDecl() && "We should already have completed it"); + if (RecordDecl *RD = dyn_cast<RecordDecl>(Tag)) + RD->completeDefinition(); + } + if (isa<CXXRecordDecl>(Tag)) FieldCollector->FinishClass(); @@ -8271,13 +8722,14 @@ void Sema::ActOnObjCContainerFinishDefinition() { PopDeclContext(); } -void Sema::ActOnObjCTemporaryExitContainerContext() { - OriginalLexicalContext = CurContext; +void Sema::ActOnObjCTemporaryExitContainerContext(DeclContext *DC) { + assert(DC == CurContext && "Mismatch of container contexts"); + OriginalLexicalContext = DC; ActOnObjCContainerFinishDefinition(); } -void Sema::ActOnObjCReenterContainerContext() { - ActOnObjCContainerStartDefinition(cast<Decl>(OriginalLexicalContext)); +void Sema::ActOnObjCReenterContainerContext(DeclContext *DC) { + ActOnObjCContainerStartDefinition(cast<Decl>(DC)); OriginalLexicalContext = 0; } @@ -8286,6 +8738,12 @@ void Sema::ActOnTagDefinitionError(Scope *S, Decl *TagD) { TagDecl *Tag = cast<TagDecl>(TagD); Tag->setInvalidDecl(); + // Make sure we "complete" the definition even it is invalid. + if (Tag->isBeingDefined()) { + if (RecordDecl *RD = dyn_cast<RecordDecl>(Tag)) + RD->completeDefinition(); + } + // We're undoing ActOnTagStartDefinition here, not // ActOnStartCXXMemberDeclarations, so we don't have to mess with // the FieldCollector. @@ -8294,9 +8752,10 @@ void Sema::ActOnTagDefinitionError(Scope *S, Decl *TagD) { } // Note that FieldName may be null for anonymous bitfields. -bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName, - QualType FieldTy, const Expr *BitWidth, - bool *ZeroWidth) { +ExprResult Sema::VerifyBitField(SourceLocation FieldLoc, + IdentifierInfo *FieldName, + QualType FieldTy, Expr *BitWidth, + bool *ZeroWidth) { // Default to true; that shouldn't confuse checks for emptiness if (ZeroWidth) *ZeroWidth = true; @@ -8306,7 +8765,7 @@ bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName, if (!FieldTy->isDependentType() && !FieldTy->isIntegralOrEnumerationType()) { // Handle incomplete types with specific error. if (RequireCompleteType(FieldLoc, FieldTy, diag::err_field_incomplete)) - return true; + return ExprError(); if (FieldName) return Diag(FieldLoc, diag::err_not_integral_type_bitfield) << FieldName << FieldTy << BitWidth->getSourceRange(); @@ -8314,16 +8773,18 @@ bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName, << FieldTy << BitWidth->getSourceRange(); } else if (DiagnoseUnexpandedParameterPack(const_cast<Expr *>(BitWidth), UPPC_BitFieldWidth)) - return true; + return ExprError(); // If the bit-width is type- or value-dependent, don't try to check // it now. if (BitWidth->isValueDependent() || BitWidth->isTypeDependent()) - return false; + return Owned(BitWidth); llvm::APSInt Value; - if (VerifyIntegerConstantExpression(BitWidth, &Value)) - return true; + ExprResult ICE = VerifyIntegerConstantExpression(BitWidth, &Value); + if (ICE.isInvalid()) + return ICE; + BitWidth = ICE.take(); if (Value != 0 && ZeroWidth) *ZeroWidth = false; @@ -8343,7 +8804,7 @@ bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName, if (!FieldTy->isDependentType()) { uint64_t TypeSize = Context.getTypeSize(FieldTy); if (Value.getZExtValue() > TypeSize) { - if (!getLangOptions().CPlusPlus) { + if (!getLangOpts().CPlusPlus) { if (FieldName) return Diag(FieldLoc, diag::err_bitfield_width_exceeds_type_size) << FieldName << (unsigned)Value.getZExtValue() @@ -8363,7 +8824,7 @@ bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName, } } - return false; + return Owned(BitWidth); } /// ActOnField - Each field of a C struct/union is passed into this in order @@ -8388,7 +8849,7 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record, TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); QualType T = TInfo->getType(); - if (getLangOptions().CPlusPlus) { + if (getLangOpts().CPlusPlus) { CheckExtraCXXDefaultArguments(D); if (DiagnoseUnexpandedParameterPack(D.getIdentifierLoc(), TInfo, @@ -8408,15 +8869,25 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record, << 2; // Check to see if this name was declared as a member previously + NamedDecl *PrevDecl = 0; LookupResult Previous(*this, II, Loc, LookupMemberName, ForRedeclaration); LookupName(Previous, S); - assert((Previous.empty() || Previous.isOverloadedResult() || - Previous.isSingleResult()) - && "Lookup of member name should be either overloaded, single or null"); - - // If the name is overloaded then get any declaration else get the single result - NamedDecl *PrevDecl = Previous.isOverloadedResult() ? - Previous.getRepresentativeDecl() : Previous.getAsSingle<NamedDecl>(); + switch (Previous.getResultKind()) { + case LookupResult::Found: + case LookupResult::FoundUnresolvedValue: + PrevDecl = Previous.getAsSingle<NamedDecl>(); + break; + + case LookupResult::FoundOverloaded: + PrevDecl = Previous.getRepresentativeDecl(); + break; + + case LookupResult::NotFound: + case LookupResult::NotFoundInCurrentInstantiation: + case LookupResult::Ambiguous: + break; + } + Previous.suppressDiagnostics(); if (PrevDecl && PrevDecl->isTemplateParameter()) { // Maybe we will complain about the shadowed template parameter. @@ -8430,7 +8901,7 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record, bool Mutable = (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_mutable); - SourceLocation TSSL = D.getSourceRange().getBegin(); + SourceLocation TSSL = D.getLocStart(); FieldDecl *NewFD = CheckFieldDecl(II, T, TInfo, Record, Loc, Mutable, BitWidth, HasInit, TSSL, AS, PrevDecl, &D); @@ -8481,11 +8952,19 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, } QualType EltTy = Context.getBaseElementType(T); - if (!EltTy->isDependentType() && - RequireCompleteType(Loc, EltTy, diag::err_field_incomplete)) { - // Fields of incomplete type force their record to be invalid. - Record->setInvalidDecl(); - InvalidDecl = true; + if (!EltTy->isDependentType()) { + if (RequireCompleteType(Loc, EltTy, diag::err_field_incomplete)) { + // Fields of incomplete type force their record to be invalid. + Record->setInvalidDecl(); + InvalidDecl = true; + } else { + NamedDecl *Def; + EltTy->isIncompleteType(&Def); + if (Def && Def->isInvalidDecl()) { + Record->setInvalidDecl(); + InvalidDecl = true; + } + } } // C99 6.7.2.1p8: A member of a structure or union may have any type other @@ -8519,11 +8998,13 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, bool ZeroWidth = false; // If this is declared as a bit-field, check the bit-field. - if (!InvalidDecl && BitWidth && - VerifyBitField(Loc, II, T, BitWidth, &ZeroWidth)) { - InvalidDecl = true; - BitWidth = 0; - ZeroWidth = false; + if (!InvalidDecl && BitWidth) { + BitWidth = VerifyBitField(Loc, II, T, BitWidth, &ZeroWidth).take(); + if (!BitWidth) { + InvalidDecl = true; + BitWidth = 0; + ZeroWidth = false; + } } // Check that 'mutable' is consistent with the type of the declaration. @@ -8555,7 +9036,7 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, NewFD->setInvalidDecl(); } - if (!InvalidDecl && getLangOptions().CPlusPlus) { + if (!InvalidDecl && getLangOpts().CPlusPlus) { if (Record->isUnion()) { if (const RecordType *RT = EltTy->getAs<RecordType>()) { CXXRecordDecl* RDecl = cast<CXXRecordDecl>(RT->getDecl()); @@ -8565,7 +9046,7 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, // destructor, or a non-trivial copy assignment operator // cannot be a member of a union, nor can an array of such // objects. - if (!getLangOptions().CPlusPlus0x && CheckNontrivialField(NewFD)) + if (CheckNontrivialField(NewFD)) NewFD->setInvalidDecl(); } } @@ -8588,7 +9069,7 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, // In auto-retain/release, infer strong retension for fields of // retainable type. - if (getLangOptions().ObjCAutoRefCount && inferObjCARCLifetime(NewFD)) + if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(NewFD)) NewFD->setInvalidDecl(); if (T.isObjCGCWeak()) @@ -8600,7 +9081,7 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, bool Sema::CheckNontrivialField(FieldDecl *FD) { assert(FD); - assert(getLangOptions().CPlusPlus && "valid check only for C++"); + assert(getLangOpts().CPlusPlus && "valid check only for C++"); if (FD->isInvalidDecl()) return true; @@ -8624,7 +9105,8 @@ bool Sema::CheckNontrivialField(FieldDecl *FD) { member = CXXDestructor; if (member != CXXInvalid) { - if (getLangOptions().ObjCAutoRefCount && RDecl->hasObjectMember()) { + if (!getLangOpts().CPlusPlus0x && + 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 // occasionally have Objective-C lifetime objects within unions, @@ -8638,11 +9120,13 @@ bool Sema::CheckNontrivialField(FieldDecl *FD) { return false; } } - - Diag(FD->getLocation(), diag::err_illegal_union_or_anon_struct_member) - << (int)FD->getParent()->isUnion() << FD->getDeclName() << member; + + Diag(FD->getLocation(), getLangOpts().CPlusPlus0x ? + 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 true; + return !getLangOpts().CPlusPlus0x; } } } @@ -8650,6 +9134,19 @@ bool Sema::CheckNontrivialField(FieldDecl *FD) { return false; } +/// If the given constructor is user-provided, produce a diagnostic explaining +/// that it makes the class non-trivial. +static bool DiagnoseNontrivialUserProvidedCtor(Sema &S, QualType QT, + CXXConstructorDecl *CD, + Sema::CXXSpecialMember CSM) { + if (!CD->isUserProvided()) + 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) { @@ -8664,17 +9161,20 @@ void Sema::DiagnoseNontrivial(const RecordType* T, CXXSpecialMember member) { 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){ - const FunctionDecl *body = 0; - ci->hasBody(body); - if (!body || !cast<CXXConstructorDecl>(body)->isImplicitlyDefined()) { - SourceLocation CtorLoc = ci->getLocation(); - Diag(CtorLoc, diag::note_nontrivial_user_defined) << QT << member; + for (ctor_iter CI = RD->ctor_begin(), CE = RD->ctor_end(); CI != CE; ++CI) + if (DiagnoseNontrivialUserProvidedCtor(*this, QT, *CI, member)) return; - } - } - llvm_unreachable("found no user-declared constructors"); + // No user-provided 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 && DiagnoseNontrivialUserProvidedCtor(*this, QT, CD, member)) + return; + } } break; @@ -8699,7 +9199,7 @@ void Sema::DiagnoseNontrivial(const RecordType* T, CXXSpecialMember member) { if (RD->hasUserDeclaredCopyAssignment()) { // FIXME: this should use the location of the copy // assignment, not the type. - SourceLocation TyLoc = RD->getSourceRange().getBegin(); + SourceLocation TyLoc = RD->getLocStart(); Diag(TyLoc, diag::note_nontrivial_user_defined) << QT << member; return; } @@ -8731,7 +9231,7 @@ void Sema::DiagnoseNontrivial(const RecordType* T, CXXSpecialMember member) { // 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->getSourceRange().getBegin(); + SourceLocation BaseLoc = bi->getLocStart(); Diag(BaseLoc, diag::note_nontrivial_has_virtual) << QT << 1; return; } @@ -8741,7 +9241,7 @@ void Sema::DiagnoseNontrivial(const RecordType* T, CXXSpecialMember member) { for (meth_iter mi = RD->method_begin(), me = RD->method_end(); mi != me; ++mi) { if (mi->isVirtual()) { - SourceLocation MLoc = mi->getSourceRange().getBegin(); + SourceLocation MLoc = mi->getLocStart(); Diag(MLoc, diag::note_nontrivial_has_virtual) << QT << 0; return; } @@ -8768,7 +9268,7 @@ void Sema::DiagnoseNontrivial(const RecordType* T, CXXSpecialMember member) { assert(BaseRT && "Don't know how to handle dependent bases"); CXXRecordDecl *BaseRecTy = cast<CXXRecordDecl>(BaseRT->getDecl()); if (!(BaseRecTy->*hasTrivial)()) { - SourceLocation BaseLoc = bi->getSourceRange().getBegin(); + SourceLocation BaseLoc = bi->getLocStart(); Diag(BaseLoc, diag::note_nontrivial_has_nontrivial) << QT << 1 << member; DiagnoseNontrivial(BaseRT, member); return; @@ -8843,10 +9343,9 @@ Decl *Sema::ActOnIvar(Scope *S, if (BitWidth) { // 6.7.2.1p3, 6.7.2.1p4 - if (VerifyBitField(Loc, II, T, BitWidth)) { + BitWidth = VerifyBitField(Loc, II, T, BitWidth).take(); + if (!BitWidth) D.setInvalidType(); - BitWidth = 0; - } } else { // Not a bitfield. @@ -8870,6 +9369,8 @@ Decl *Sema::ActOnIvar(Scope *S, : ObjCIvarDecl::None; // Must set ivar's DeclContext to its enclosing interface. ObjCContainerDecl *EnclosingDecl = cast<ObjCContainerDecl>(CurContext); + if (!EnclosingDecl || EnclosingDecl->isInvalidDecl()) + return 0; ObjCContainerDecl *EnclosingContext; if (ObjCImplementationDecl *IMPDecl = dyn_cast<ObjCImplementationDecl>(EnclosingDecl)) { @@ -8914,7 +9415,7 @@ Decl *Sema::ActOnIvar(Scope *S, NewID->setInvalidDecl(); // In ARC, infer 'retaining' for ivars of retainable type. - if (getLangOptions().ObjCAutoRefCount && inferObjCARCLifetime(NewID)) + if (getLangOpts().ObjCAutoRefCount && inferObjCARCLifetime(NewID)) NewID->setInvalidDecl(); if (D.getDeclSpec().isModulePrivateSpecified()) @@ -8980,11 +9481,23 @@ void Sema::ActOnFields(Scope* S, if (EnclosingDecl->isInvalidDecl()) return; - // Verify that all the fields are okay. + RecordDecl *Record = dyn_cast<RecordDecl>(EnclosingDecl); + + // Start counting up the number of named members; make sure to include + // members of anonymous structs and unions in the total. unsigned NumNamedMembers = 0; + if (Record) { + for (RecordDecl::decl_iterator i = Record->decls_begin(), + e = Record->decls_end(); i != e; i++) { + if (IndirectFieldDecl *IFD = dyn_cast<IndirectFieldDecl>(*i)) + if (IFD->getDeclName()) + ++NumNamedMembers; + } + } + + // Verify that all the fields are okay. SmallVector<FieldDecl*, 32> RecFields; - RecordDecl *Record = dyn_cast<RecordDecl>(EnclosingDecl); bool ARCErrReported = false; for (llvm::ArrayRef<Decl *>::iterator i = Fields.begin(), end = Fields.end(); i != end; ++i) { @@ -9024,27 +9537,34 @@ void Sema::ActOnFields(Scope* S, continue; } else if (FDTy->isIncompleteArrayType() && Record && ((i + 1 == Fields.end() && !Record->isUnion()) || - ((getLangOptions().MicrosoftExt || - getLangOptions().CPlusPlus) && + ((getLangOpts().MicrosoftExt || + getLangOpts().CPlusPlus) && (i + 1 == Fields.end() || Record->isUnion())))) { // Flexible array member. // Microsoft and g++ is more permissive regarding flexible array. // It will accept flexible array in union and also // as the sole element of a struct/class. - if (getLangOptions().MicrosoftExt) { + if (getLangOpts().MicrosoftExt) { if (Record->isUnion()) Diag(FD->getLocation(), diag::ext_flexible_array_union_ms) << FD->getDeclName(); else if (Fields.size() == 1) Diag(FD->getLocation(), diag::ext_flexible_array_empty_aggregate_ms) << FD->getDeclName() << Record->getTagKind(); - } else if (getLangOptions().CPlusPlus) { + } else if (getLangOpts().CPlusPlus) { if (Record->isUnion()) Diag(FD->getLocation(), diag::ext_flexible_array_union_gnu) << FD->getDeclName(); else if (Fields.size() == 1) Diag(FD->getLocation(), diag::ext_flexible_array_empty_aggregate_gnu) << FD->getDeclName() << Record->getTagKind(); + } else if (!getLangOpts().C99) { + if (Record->isUnion()) + Diag(FD->getLocation(), diag::ext_flexible_array_union_gnu) + << FD->getDeclName(); + else + Diag(FD->getLocation(), diag::ext_c99_flexible_array_member) + << FD->getDeclName() << Record->getTagKind(); } else if (NumNamedMembers < 1) { Diag(FD->getLocation(), diag::err_flexible_array_empty_struct) << FD->getDeclName(); @@ -9101,8 +9621,8 @@ void Sema::ActOnFields(Scope* S, QualType T = Context.getObjCObjectPointerType(FD->getType()); FD->setType(T); } - else if (!getLangOptions().CPlusPlus) { - if (getLangOptions().ObjCAutoRefCount && Record && !ARCErrReported) { + 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. @@ -9118,13 +9638,14 @@ void Sema::ActOnFields(Scope* S, "this system field has retaining ownership")); } } else { - Diag(FD->getLocation(), diag::err_arc_objc_object_in_struct); + Diag(FD->getLocation(), diag::err_arc_objc_object_in_struct) + << T->isBlockPointerType(); } ARCErrReported = true; } } - else if (getLangOptions().ObjC1 && - getLangOptions().getGC() != LangOptions::NonGC && + else if (getLangOpts().ObjC1 && + getLangOpts().getGC() != LangOptions::NonGC && Record && !Record->hasObjectMember()) { if (FD->getType()->isObjCObjectPointerType() || FD->getType().isObjCGCStrong()) @@ -9168,7 +9689,7 @@ void Sema::ActOnFields(Scope* S, // non-POD because of the presence of an Objective-C pointer member. // If so, objects of this type cannot be shared between code compiled // with instant objects and code compiled with manual retain/release. - if (getLangOptions().ObjCAutoRefCount && + if (getLangOpts().ObjCAutoRefCount && CXXRecord->hasObjectMember() && CXXRecord->getLinkage() == ExternalLinkage) { if (CXXRecord->isPOD()) { @@ -9194,7 +9715,7 @@ void Sema::ActOnFields(Scope* S, } // Adjust user-defined destructor exception spec. - if (getLangOptions().CPlusPlus0x && + if (getLangOpts().CPlusPlus0x && CXXRecord->hasUserDeclaredDestructor()) AdjustDestructorExceptionSpec(CXXRecord,CXXRecord->getDestructor()); @@ -9266,7 +9787,7 @@ void Sema::ActOnFields(Scope* S, ObjCIvarDecl **ClsFields = reinterpret_cast<ObjCIvarDecl**>(RecFields.data()); if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(EnclosingDecl)) { - ID->setLocEnd(RBrac); + ID->setEndOfDefinitionLoc(RBrac); // Add ivar's to class's DeclContext. for (unsigned i = 0, e = RecFields.size(); i != e; ++i) { ClsFields[i]->setLexicalDeclContext(ID); @@ -9284,6 +9805,8 @@ void Sema::ActOnFields(Scope* S, // Only it is in implementation's lexical context. ClsFields[I]->setLexicalDeclContext(IMPDecl); CheckImplementationIvars(IMPDecl, ClsFields, RecFields.size(), RBrac); + IMPDecl->setIvarLBraceLoc(LBrac); + IMPDecl->setIvarRBraceLoc(RBrac); } else if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(EnclosingDecl)) { // case of ivars in class extension; all other cases have been @@ -9291,10 +9814,34 @@ void Sema::ActOnFields(Scope* S, // FIXME. Class extension does not have a LocEnd field. // CDecl->setLocEnd(RBrac); // Add ivar's to class extension's DeclContext. + // Diagnose redeclaration of private ivars. + ObjCInterfaceDecl *IDecl = CDecl->getClassInterface(); for (unsigned i = 0, e = RecFields.size(); i != e; ++i) { + if (IDecl) { + if (const ObjCIvarDecl *ClsIvar = + IDecl->getIvarDecl(ClsFields[i]->getIdentifier())) { + Diag(ClsFields[i]->getLocation(), + diag::err_duplicate_ivar_declaration); + 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())) { + Diag(ClsFields[i]->getLocation(), + diag::err_duplicate_ivar_declaration); + Diag(ClsExtIvar->getLocation(), diag::note_previous_definition); + continue; + } + } + } ClsFields[i]->setLexicalDeclContext(CDecl); CDecl->addDecl(ClsFields[i]); } + CDecl->setIvarLBraceLoc(LBrac); + CDecl->setIvarRBraceLoc(RBrac); } } @@ -9360,56 +9907,70 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum, if (Val && DiagnoseUnexpandedParameterPack(Val, UPPC_EnumeratorValue)) Val = 0; + if (Val) + Val = DefaultLvalueConversion(Val).take(); + if (Val) { if (Enum->isDependentType() || Val->isTypeDependent()) EltTy = Context.DependentTy; else { - // C99 6.7.2.2p2: Make sure we have an integer constant expression. SourceLocation ExpLoc; - if (!Val->isValueDependent() && - VerifyIntegerConstantExpression(Val, &EnumVal)) { - Val = 0; - } else { - if (!getLangOptions().CPlusPlus) { - // C99 6.7.2.2p2: - // The expression that defines the value of an enumeration constant - // shall be an integer constant expression that has a value - // representable as an int. - - // Complain if the value is not representable in an int. - if (!isRepresentableIntegerValue(Context, EnumVal, Context.IntTy)) - Diag(IdLoc, diag::ext_enum_value_not_int) - << EnumVal.toString(10) << Val->getSourceRange() - << (EnumVal.isUnsigned() || EnumVal.isNonNegative()); - else if (!Context.hasSameType(Val->getType(), Context.IntTy)) { - // Force the type of the expression to 'int'. - Val = ImpCastExprToType(Val, Context.IntTy, CK_IntegralCast).take(); - } - } - + if (getLangOpts().CPlusPlus0x && 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 + // constant expression of the underlying type. + EltTy = Enum->getIntegerType(); + ExprResult Converted = + CheckConvertedConstantExpression(Val, EltTy, EnumVal, + CCEK_Enumerator); + if (Converted.isInvalid()) + Val = 0; + else + Val = Converted.take(); + } else if (!Val->isValueDependent() && + !(Val = VerifyIntegerConstantExpression(Val, + &EnumVal).take())) { + // C99 6.7.2.2p2: Make sure we have an integer constant expression. + } else { if (Enum->isFixed()) { EltTy = Enum->getIntegerType(); - // C++0x [dcl.enum]p5: - // ... if the initializing value of an enumerator cannot be - // represented by the underlying type, the program is ill-formed. + // In Obj-C and Microsoft mode, require the enumeration value to be + // representable in the underlying type of the enumeration. In C++11, + // we perform a non-narrowing conversion as part of converted constant + // expression checking. if (!isRepresentableIntegerValue(Context, EnumVal, EltTy)) { - if (getLangOptions().MicrosoftExt) { + if (getLangOpts().MicrosoftMode) { Diag(IdLoc, diag::ext_enumerator_too_large) << EltTy; Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).take(); - } else - Diag(IdLoc, diag::err_enumerator_too_large) - << EltTy; + } else + Diag(IdLoc, diag::err_enumerator_too_large) << EltTy; } else Val = ImpCastExprToType(Val, EltTy, CK_IntegralCast).take(); - } - else { - // C++0x [dcl.enum]p5: + } else if (getLangOpts().CPlusPlus) { + // C++11 [dcl.enum]p5: // If the underlying type is not fixed, the type of each enumerator // is the type of its initializing value: // - If an initializer is specified for an enumerator, the // initializing value has the same type as the expression. EltTy = Val->getType(); + } else { + // C99 6.7.2.2p2: + // The expression that defines the value of an enumeration constant + // shall be an integer constant expression that has a value + // representable as an int. + + // Complain if the value is not representable in an int. + if (!isRepresentableIntegerValue(Context, EnumVal, Context.IntTy)) + Diag(IdLoc, diag::ext_enum_value_not_int) + << EnumVal.toString(10) << Val->getSourceRange() + << (EnumVal.isUnsigned() || EnumVal.isNonNegative()); + else if (!Context.hasSameType(Val->getType(), Context.IntTy)) { + // Force the type of the expression to 'int'. + Val = ImpCastExprToType(Val, Context.IntTy, CK_IntegralCast).take(); + } + EltTy = Val->getType(); } } } @@ -9483,9 +10044,9 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum, // an int (C99 6.7.2.2p2). However, we support GCC's extension that // permits enumerator values that are representable in some larger // integral type. - if (!getLangOptions().CPlusPlus && !T.isNull()) + if (!getLangOpts().CPlusPlus && !T.isNull()) Diag(IdLoc, diag::warn_enum_value_overflow); - } else if (!getLangOptions().CPlusPlus && + } else if (!getLangOpts().CPlusPlus && !isRepresentableIntegerValue(Context, EnumVal, EltTy)) { // Enforce C99 6.7.2.2p2 even when we compute the next value. Diag(IdLoc, diag::ext_enum_value_not_int) @@ -9497,7 +10058,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum, if (!EltTy->isDependentType()) { // Make the enumerator value match the signedness and size of the // enumerator's type. - EnumVal = EnumVal.zextOrTrunc(Context.getIntWidth(EltTy)); + EnumVal = EnumVal.extOrTrunc(Context.getIntWidth(EltTy)); EnumVal.setIsSigned(EltTy->isSignedIntegerOrEnumerationType()); } @@ -9509,11 +10070,10 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum, Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst, SourceLocation IdLoc, IdentifierInfo *Id, AttributeList *Attr, - SourceLocation EqualLoc, Expr *val) { + SourceLocation EqualLoc, Expr *Val) { EnumDecl *TheEnumDecl = cast<EnumDecl>(theEnumDecl); EnumConstantDecl *LastEnumConst = cast_or_null<EnumConstantDecl>(lastEnumConst); - Expr *Val = static_cast<Expr*>(val); // The scope passed in may not be a decl scope. Zip up the scope tree until // we find one that is. @@ -9533,7 +10093,7 @@ Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst, if (PrevDecl) { // When in C++, we may get a TagDecl with the same name; in this case the // enum constant will 'hide' the tag. - assert((getLangOptions().CPlusPlus || !isa<TagDecl>(PrevDecl)) && + assert((getLangOpts().CPlusPlus || !isa<TagDecl>(PrevDecl)) && "Received TagDecl when not in C++!"); if (!isa<TagDecl>(PrevDecl) && isDeclInScope(PrevDecl, CurContext, S)) { if (isa<EnumConstantDecl>(PrevDecl)) @@ -9651,7 +10211,11 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, Packed = true; if (Enum->isFixed()) { - BestType = BestPromotionType = Enum->getIntegerType(); + BestType = Enum->getIntegerType(); + if (BestType->isPromotableIntegerType()) + BestPromotionType = Context.getPromotedIntegerType(BestType); + else + BestPromotionType = BestType; // We don't need to set BestWidth, because BestType is going to be the type // of the enumerators, but we do anyway because otherwise some compilers // warn that it might be used uninitialized. @@ -9701,13 +10265,13 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, BestType = Context.UnsignedIntTy; BestWidth = IntWidth; BestPromotionType - = (NumPositiveBits == BestWidth || !getLangOptions().CPlusPlus) + = (NumPositiveBits == BestWidth || !getLangOpts().CPlusPlus) ? Context.UnsignedIntTy : Context.IntTy; } else if (NumPositiveBits <= (BestWidth = Context.getTargetInfo().getLongWidth())) { BestType = Context.UnsignedLongTy; BestPromotionType - = (NumPositiveBits == BestWidth || !getLangOptions().CPlusPlus) + = (NumPositiveBits == BestWidth || !getLangOpts().CPlusPlus) ? Context.UnsignedLongTy : Context.LongTy; } else { BestWidth = Context.getTargetInfo().getLongLongWidth(); @@ -9715,7 +10279,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, "How could an initializer get larger than ULL?"); BestType = Context.UnsignedLongLongTy; BestPromotionType - = (NumPositiveBits == BestWidth || !getLangOptions().CPlusPlus) + = (NumPositiveBits == BestWidth || !getLangOpts().CPlusPlus) ? Context.UnsignedLongLongTy : Context.LongLongTy; } } @@ -9740,14 +10304,15 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, QualType NewTy; unsigned NewWidth; bool NewSign; - if (!getLangOptions().CPlusPlus && + if (!getLangOpts().CPlusPlus && + !Enum->isFixed() && isRepresentableIntegerValue(Context, InitVal, Context.IntTy)) { NewTy = Context.IntTy; NewWidth = IntWidth; NewSign = true; } else if (ECD->getType() == BestType) { // Already the right type! - if (getLangOptions().CPlusPlus) + if (getLangOpts().CPlusPlus) // C++ [dcl.enum]p4: Following the closing brace of an // enum-specifier, each enumerator has the type of its // enumeration. @@ -9772,7 +10337,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, ECD->getInitExpr(), /*base paths*/ 0, VK_RValue)); - if (getLangOptions().CPlusPlus) + if (getLangOpts().CPlusPlus) // C++ [dcl.enum]p4: Following the closing brace of an // enum-specifier, each enumerator has the type of its // enumeration. @@ -9783,6 +10348,12 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, Enum->completeDefinition(BestType, BestPromotionType, NumPositiveBits, NumNegativeBits); + + // If we're declaring a function, ensure this decl isn't forgotten about - + // it needs to go into the function scope. + if (InFunctionDeclarator) + DeclsInPrototypeScope.push_back(Enum); + } Decl *Sema::ActOnFileScopeAsmDecl(Expr *expr, @@ -9797,31 +10368,50 @@ Decl *Sema::ActOnFileScopeAsmDecl(Expr *expr, return New; } -DeclResult Sema::ActOnModuleImport(SourceLocation ImportLoc, - IdentifierInfo &ModuleName, - SourceLocation ModuleNameLoc) { - ModuleKey Module = PP.getModuleLoader().loadModule(ImportLoc, - ModuleName, ModuleNameLoc); - if (!Module) +DeclResult Sema::ActOnModuleImport(SourceLocation AtLoc, + SourceLocation ImportLoc, + ModuleIdPath Path) { + Module *Mod = PP.getModuleLoader().loadModule(ImportLoc, Path, + Module::AllVisible, + /*IsIncludeDirective=*/false); + if (!Mod) return true; - // FIXME: Actually create a declaration to describe the module import. - (void)Module; - return DeclResult((Decl *)0); + llvm::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. + // We need the length to be consistent. + if (!ModCheck) + break; + ModCheck = ModCheck->Parent; + + IdentifierLocs.push_back(Path[I].second); + } + + ImportDecl *Import = ImportDecl::Create(Context, + Context.getTranslationUnitDecl(), + AtLoc.isValid()? AtLoc : ImportLoc, + Mod, IdentifierLocs); + Context.getTranslationUnitDecl()->addDecl(Import); + return Import; } -void -Sema::diagnoseModulePrivateRedeclaration(NamedDecl *New, NamedDecl *Old, - SourceLocation ModulePrivateKeyword) { - assert(!Old->isModulePrivate() && "Old is module-private!"); - - Diag(New->getLocation(), diag::err_module_private_follows_public) - << New->getDeclName() << SourceRange(ModulePrivateKeyword); - Diag(Old->getLocation(), diag::note_previous_declaration) - << Old->getDeclName(); - - // Drop the __module_private__ from the new declaration, since it's invalid. - New->setModulePrivate(false); +void Sema::ActOnPragmaRedefineExtname(IdentifierInfo* Name, + IdentifierInfo* AliasName, + SourceLocation PragmaLoc, + SourceLocation NameLoc, + SourceLocation AliasNameLoc) { + Decl *PrevDecl = LookupSingleName(TUScope, Name, NameLoc, + LookupOrdinaryName); + AsmLabelAttr *Attr = + ::new (Context) AsmLabelAttr(AliasNameLoc, Context, AliasName->getName()); + + if (PrevDecl) + PrevDecl->addAttr(Attr); + else + (void)ExtnameUndeclaredIdentifiers.insert( + std::pair<IdentifierInfo*,AsmLabelAttr*>(Name, Attr)); } void Sema::ActOnPragmaWeakID(IdentifierInfo* Name, |