| //===--- SemaDecl.cpp - Semantic Analysis for Declarations ----------------===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file implements semantic analysis for declarations. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "clang/Sema/SemaInternal.h" |
| #include "TypeLocBuilder.h" |
| #include "clang/AST/ASTConsumer.h" |
| #include "clang/AST/ASTContext.h" |
| #include "clang/AST/ASTLambda.h" |
| #include "clang/AST/CXXInheritance.h" |
| #include "clang/AST/CharUnits.h" |
| #include "clang/AST/CommentDiagnostic.h" |
| #include "clang/AST/DeclCXX.h" |
| #include "clang/AST/DeclObjC.h" |
| #include "clang/AST/DeclTemplate.h" |
| #include "clang/AST/EvaluatedExprVisitor.h" |
| #include "clang/AST/ExprCXX.h" |
| #include "clang/AST/StmtCXX.h" |
| #include "clang/Basic/PartialDiagnostic.h" |
| #include "clang/Basic/SourceManager.h" |
| #include "clang/Basic/TargetInfo.h" |
| #include "clang/Lex/HeaderSearch.h" // FIXME: Sema shouldn't depend on Lex |
| #include "clang/Lex/ModuleLoader.h" // FIXME: Sema shouldn't depend on Lex |
| #include "clang/Lex/Preprocessor.h" // FIXME: Sema shouldn't depend on Lex |
| #include "clang/Parse/ParseDiagnostic.h" |
| #include "clang/Sema/CXXFieldCollector.h" |
| #include "clang/Sema/DeclSpec.h" |
| #include "clang/Sema/DelayedDiagnostic.h" |
| #include "clang/Sema/Initialization.h" |
| #include "clang/Sema/Lookup.h" |
| #include "clang/Sema/ParsedTemplate.h" |
| #include "clang/Sema/Scope.h" |
| #include "clang/Sema/ScopeInfo.h" |
| #include "clang/Sema/Template.h" |
| #include "llvm/ADT/SmallString.h" |
| #include "llvm/ADT/Triple.h" |
| #include <algorithm> |
| #include <cstring> |
| #include <functional> |
| using namespace clang; |
| using namespace sema; |
| |
| Sema::DeclGroupPtrTy Sema::ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType) { |
| if (OwnedType) { |
| Decl *Group[2] = { OwnedType, Ptr }; |
| return DeclGroupPtrTy::make(DeclGroupRef::Create(Context, Group, 2)); |
| } |
| |
| return DeclGroupPtrTy::make(DeclGroupRef(Ptr)); |
| } |
| |
| namespace { |
| |
| class TypeNameValidatorCCC : public CorrectionCandidateCallback { |
| public: |
| TypeNameValidatorCCC(bool AllowInvalid, bool WantClass=false, |
| bool AllowTemplates=false) |
| : AllowInvalidDecl(AllowInvalid), WantClassName(WantClass), |
| AllowClassTemplates(AllowTemplates) { |
| WantExpressionKeywords = false; |
| WantCXXNamedCasts = false; |
| WantRemainingKeywords = false; |
| } |
| |
| bool ValidateCandidate(const TypoCorrection &candidate) override { |
| if (NamedDecl *ND = candidate.getCorrectionDecl()) { |
| bool IsType = isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND); |
| bool AllowedTemplate = AllowClassTemplates && isa<ClassTemplateDecl>(ND); |
| return (IsType || AllowedTemplate) && |
| (AllowInvalidDecl || !ND->isInvalidDecl()); |
| } |
| return !WantClassName && candidate.isKeyword(); |
| } |
| |
| private: |
| bool AllowInvalidDecl; |
| bool WantClassName; |
| bool AllowClassTemplates; |
| }; |
| |
| } |
| |
| /// \brief Determine whether the token kind starts a simple-type-specifier. |
| bool Sema::isSimpleTypeSpecifier(tok::TokenKind Kind) const { |
| switch (Kind) { |
| // FIXME: Take into account the current language when deciding whether a |
| // token kind is a valid type specifier |
| case tok::kw_short: |
| case tok::kw_long: |
| case tok::kw___int64: |
| case tok::kw___int128: |
| case tok::kw_signed: |
| case tok::kw_unsigned: |
| case tok::kw_void: |
| case tok::kw_char: |
| case tok::kw_int: |
| case tok::kw_half: |
| case tok::kw_float: |
| case tok::kw_double: |
| case tok::kw_wchar_t: |
| case tok::kw_bool: |
| case tok::kw___underlying_type: |
| return true; |
| |
| case tok::annot_typename: |
| case tok::kw_char16_t: |
| case tok::kw_char32_t: |
| case tok::kw_typeof: |
| case tok::annot_decltype: |
| case tok::kw_decltype: |
| return getLangOpts().CPlusPlus; |
| |
| default: |
| break; |
| } |
| |
| return false; |
| } |
| |
| /// \brief If the identifier refers to a type name within this scope, |
| /// return the declaration of that type. |
| /// |
| /// This routine performs ordinary name lookup of the identifier II |
| /// within the given scope, with optional C++ scope specifier SS, to |
| /// determine whether the name refers to a type. If so, returns an |
| /// opaque pointer (actually a QualType) corresponding to that |
| /// type. Otherwise, returns NULL. |
| ParsedType Sema::getTypeName(const 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. |
| DeclContext *LookupCtx = 0; |
| if (ObjectTypePtr) { |
| QualType ObjectType = ObjectTypePtr.get(); |
| if (ObjectType->isRecordType()) |
| LookupCtx = computeDeclContext(ObjectType); |
| } else if (SS && SS->isNotEmpty()) { |
| LookupCtx = computeDeclContext(*SS, false); |
| |
| if (!LookupCtx) { |
| if (isDependentScopeSpecifier(*SS)) { |
| // C++ [temp.res]p3: |
| // A qualified-id that refers to a type and in which the |
| // nested-name-specifier depends on a template-parameter (14.6.2) |
| // shall be prefixed by the keyword typename to indicate that the |
| // qualified-id denotes a type, forming an |
| // elaborated-type-specifier (7.1.5.3). |
| // |
| // We therefore do not perform any name lookup if the result would |
| // refer to a member of an unknown specialization. |
| if (!isClassName && !IsCtorOrDtorName) |
| return ParsedType(); |
| |
| // We know from the grammar that this name refers to a type, |
| // so build a dependent node to describe the type. |
| if (WantNontrivialTypeSourceInfo) |
| return ActOnTypenameType(S, SourceLocation(), *SS, II, NameLoc).get(); |
| |
| NestedNameSpecifierLoc QualifierLoc = SS->getWithLocInContext(Context); |
| QualType T = |
| CheckTypenameType(ETK_None, SourceLocation(), QualifierLoc, |
| II, NameLoc); |
| |
| return ParsedType::make(T); |
| } |
| |
| return ParsedType(); |
| } |
| |
| if (!LookupCtx->isDependentContext() && |
| RequireCompleteDeclContext(*SS, LookupCtx)) |
| return ParsedType(); |
| } |
| |
| // FIXME: LookupNestedNameSpecifierName isn't the right kind of |
| // lookup for class-names. |
| LookupNameKind Kind = isClassName ? LookupNestedNameSpecifierName : |
| LookupOrdinaryName; |
| LookupResult Result(*this, &II, NameLoc, Kind); |
| if (LookupCtx) { |
| // Perform "qualified" name lookup into the declaration context we |
| // computed, which is either the type of the base of a member access |
| // expression or the declaration context associated with a prior |
| // nested-name-specifier. |
| LookupQualifiedName(Result, LookupCtx); |
| |
| if (ObjectTypePtr && Result.empty()) { |
| // C++ [basic.lookup.classref]p3: |
| // If the unqualified-id is ~type-name, the type-name is looked up |
| // in the context of the entire postfix-expression. If the type T of |
| // the object expression is of a class type C, the type-name is also |
| // looked up in the scope of class C. At least one of the lookups shall |
| // find a name that refers to (possibly cv-qualified) T. |
| LookupName(Result, S); |
| } |
| } else { |
| // Perform unqualified name lookup. |
| LookupName(Result, S); |
| } |
| |
| NamedDecl *IIDecl = 0; |
| switch (Result.getResultKind()) { |
| case LookupResult::NotFound: |
| case LookupResult::NotFoundInCurrentInstantiation: |
| if (CorrectedII) { |
| TypeNameValidatorCCC Validator(true, isClassName); |
| TypoCorrection Correction = CorrectTypo(Result.getLookupNameInfo(), |
| Kind, S, SS, Validator, |
| CTK_ErrorRecovery); |
| IdentifierInfo *NewII = Correction.getCorrectionAsIdentifierInfo(); |
| TemplateTy Template; |
| bool MemberOfUnknownSpecialization; |
| UnqualifiedId TemplateName; |
| TemplateName.setIdentifier(NewII, NameLoc); |
| NestedNameSpecifier *NNS = Correction.getCorrectionSpecifier(); |
| CXXScopeSpec NewSS, *NewSSPtr = SS; |
| if (SS && NNS) { |
| NewSS.MakeTrivial(Context, NNS, SourceRange(NameLoc)); |
| NewSSPtr = &NewSS; |
| } |
| if (Correction && (NNS || NewII != &II) && |
| // 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). |
| !(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) { |
| diagnoseTypo(Correction, |
| PDiag(diag::err_unknown_type_or_class_name_suggest) |
| << Result.getLookupName() << isClassName); |
| if (SS && NNS) |
| SS->MakeTrivial(Context, NNS, SourceRange(NameLoc)); |
| *CorrectedII = NewII; |
| return Ty; |
| } |
| } |
| } |
| // If typo correction failed or was not performed, fall through |
| case LookupResult::FoundOverloaded: |
| case LookupResult::FoundUnresolvedValue: |
| Result.suppressDiagnostics(); |
| return ParsedType(); |
| |
| case LookupResult::Ambiguous: |
| // Recover from type-hiding ambiguities by hiding the type. We'll |
| // do the lookup again when looking for an object, and we can |
| // diagnose the error then. If we don't do this, then the error |
| // about hiding the type will be immediately followed by an error |
| // that only makes sense if the identifier was treated like a type. |
| if (Result.getAmbiguityKind() == LookupResult::AmbiguousTagHiding) { |
| Result.suppressDiagnostics(); |
| return ParsedType(); |
| } |
| |
| // Look to see if we have a type anywhere in the list of results. |
| for (LookupResult::iterator Res = Result.begin(), ResEnd = Result.end(); |
| Res != ResEnd; ++Res) { |
| if (isa<TypeDecl>(*Res) || isa<ObjCInterfaceDecl>(*Res)) { |
| if (!IIDecl || |
| (*Res)->getLocation().getRawEncoding() < |
| IIDecl->getLocation().getRawEncoding()) |
| IIDecl = *Res; |
| } |
| } |
| |
| if (!IIDecl) { |
| // None of the entities we found is a type, so there is no way |
| // to even assume that the result is a type. In this case, don't |
| // complain about the ambiguity. The parser will either try to |
| // perform this lookup again (e.g., as an object name), which |
| // will produce the ambiguity, or will complain that it expected |
| // a type name. |
| Result.suppressDiagnostics(); |
| return ParsedType(); |
| } |
| |
| // We found a type within the ambiguous lookup; diagnose the |
| // ambiguity and then return that type. This might be the right |
| // answer, or it might not be, but it suppresses any attempt to |
| // perform the name lookup again. |
| break; |
| |
| case LookupResult::Found: |
| IIDecl = Result.getFoundDecl(); |
| break; |
| } |
| |
| assert(IIDecl && "Didn't find decl"); |
| |
| QualType T; |
| if (TypeDecl *TD = dyn_cast<TypeDecl>(IIDecl)) { |
| DiagnoseUseOfDecl(IIDecl, NameLoc); |
| |
| if (T.isNull()) |
| T = Context.getTypeDeclType(TD); |
| |
| // NOTE: avoid constructing an ElaboratedType(Loc) if this is a |
| // constructor or destructor name (in such a case, the scope specifier |
| // 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; |
| Builder.pushTypeSpec(T).setNameLoc(NameLoc); |
| |
| T = getElaboratedType(ETK_None, *SS, T); |
| ElaboratedTypeLoc ElabTL = Builder.push<ElaboratedTypeLoc>(T); |
| ElabTL.setElaboratedKeywordLoc(SourceLocation()); |
| ElabTL.setQualifierLoc(SS->getWithLocInContext(Context)); |
| return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T)); |
| } else { |
| T = getElaboratedType(ETK_None, *SS, T); |
| } |
| } |
| } else if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(IIDecl)) { |
| (void)DiagnoseUseOfDecl(IDecl, NameLoc); |
| if (!HasTrailingDot) |
| T = Context.getObjCInterfaceType(IDecl); |
| } |
| |
| if (T.isNull()) { |
| // If it's not plausibly a type, suppress diagnostics. |
| Result.suppressDiagnostics(); |
| return ParsedType(); |
| } |
| return ParsedType::make(T); |
| } |
| |
| /// isTagName() - This method is called *for error recovery purposes only* |
| /// to determine if the specified name is a valid tag name ("struct foo"). If |
| /// so, this returns the TST for the tag corresponding to it (TST_enum, |
| /// TST_union, TST_struct, TST_interface, TST_class). This is used to diagnose |
| /// cases in C where the user forgot to specify the tag. |
| DeclSpec::TST Sema::isTagName(IdentifierInfo &II, Scope *S) { |
| // Do a tag name lookup in this scope. |
| LookupResult R(*this, &II, SourceLocation(), LookupTagName); |
| LookupName(R, S, false); |
| R.suppressDiagnostics(); |
| if (R.getResultKind() == LookupResult::Found) |
| if (const TagDecl *TD = R.getAsSingle<TagDecl>()) { |
| switch (TD->getTagKind()) { |
| case TTK_Struct: return DeclSpec::TST_struct; |
| case TTK_Interface: return DeclSpec::TST_interface; |
| case TTK_Union: return DeclSpec::TST_union; |
| case TTK_Class: return DeclSpec::TST_class; |
| case TTK_Enum: return DeclSpec::TST_enum; |
| } |
| } |
| |
| return DeclSpec::TST_unspecified; |
| } |
| |
| /// isMicrosoftMissingTypename - In Microsoft mode, within class scope, |
| /// if a CXXScopeSpec's type is equal to the type of one of the base classes |
| /// then downgrade the missing typename error to a warning. |
| /// This is needed for MSVC compatibility; Example: |
| /// @code |
| /// template<class T> class A { |
| /// public: |
| /// typedef int TYPE; |
| /// }; |
| /// template<class T> class B : public A<T> { |
| /// public: |
| /// A<T>::TYPE a; // no typename required because A<T> is a base class. |
| /// }; |
| /// @endcode |
| bool Sema::isMicrosoftMissingTypename(const CXXScopeSpec *SS, Scope *S) { |
| if (CurContext->isRecord()) { |
| const Type *Ty = SS->getScopeRep()->getAsType(); |
| |
| CXXRecordDecl *RD = cast<CXXRecordDecl>(CurContext); |
| for (const auto &Base : RD->bases()) |
| if (Context.hasSameUnqualifiedType(QualType(Ty, 1), Base.getType())) |
| return true; |
| return S->isFunctionPrototypeScope(); |
| } |
| return CurContext->isFunctionOrMethod() || S->isFunctionPrototypeScope(); |
| } |
| |
| bool Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II, |
| SourceLocation IILoc, |
| Scope *S, |
| CXXScopeSpec *SS, |
| ParsedType &SuggestedType, |
| bool AllowClassTemplates) { |
| // We don't have anything to suggest (yet). |
| SuggestedType = ParsedType(); |
| |
| // There may have been a typo in the name of the type. Look up typo |
| // results, in case we have something that we can suggest. |
| TypeNameValidatorCCC Validator(false, false, AllowClassTemplates); |
| if (TypoCorrection Corrected = CorrectTypo(DeclarationNameInfo(II, IILoc), |
| LookupOrdinaryName, S, SS, |
| Validator, CTK_ErrorRecovery)) { |
| if (Corrected.isKeyword()) { |
| // We corrected to a keyword. |
| diagnoseTypo(Corrected, PDiag(diag::err_unknown_typename_suggest) << II); |
| II = Corrected.getCorrectionAsIdentifierInfo(); |
| } else { |
| // We found a similarly-named type or interface; suggest that. |
| if (!SS || !SS->isSet()) { |
| diagnoseTypo(Corrected, |
| PDiag(diag::err_unknown_typename_suggest) << II); |
| } else if (DeclContext *DC = computeDeclContext(*SS, false)) { |
| std::string CorrectedStr(Corrected.getAsString(getLangOpts())); |
| bool DroppedSpecifier = Corrected.WillReplaceSpecifier() && |
| II->getName().equals(CorrectedStr); |
| diagnoseTypo(Corrected, |
| PDiag(diag::err_unknown_nested_typename_suggest) |
| << II << DC << DroppedSpecifier << SS->getRange()); |
| } else { |
| llvm_unreachable("could not have corrected a typo here"); |
| } |
| |
| CXXScopeSpec tmpSS; |
| if (Corrected.getCorrectionSpecifier()) |
| tmpSS.MakeTrivial(Context, Corrected.getCorrectionSpecifier(), |
| SourceRange(IILoc)); |
| SuggestedType = getTypeName(*Corrected.getCorrectionAsIdentifierInfo(), |
| IILoc, S, tmpSS.isSet() ? &tmpSS : SS, false, |
| false, ParsedType(), |
| /*IsCtorOrDtorName=*/false, |
| /*NonTrivialTypeSourceInfo=*/true); |
| } |
| return true; |
| } |
| |
| if (getLangOpts().CPlusPlus) { |
| // See if II is a class template that the user forgot to pass arguments to. |
| UnqualifiedId Name; |
| Name.setIdentifier(II, IILoc); |
| CXXScopeSpec EmptySS; |
| TemplateTy TemplateResult; |
| bool MemberOfUnknownSpecialization; |
| if (isTemplateName(S, SS ? *SS : EmptySS, /*hasTemplateKeyword=*/false, |
| Name, ParsedType(), true, TemplateResult, |
| MemberOfUnknownSpecialization) == TNK_Type_template) { |
| TemplateName TplName = TemplateResult.get(); |
| Diag(IILoc, diag::err_template_missing_args) << TplName; |
| if (TemplateDecl *TplDecl = TplName.getAsTemplateDecl()) { |
| Diag(TplDecl->getLocation(), diag::note_template_decl_here) |
| << TplDecl->getTemplateParameters()->getSourceRange(); |
| } |
| return true; |
| } |
| } |
| |
| // FIXME: Should we move the logic that tries to recover from a missing tag |
| // (struct, union, enum) from Parser::ParseImplicitInt here, instead? |
| |
| if (!SS || (!SS->isSet() && !SS->isInvalid())) |
| Diag(IILoc, diag::err_unknown_typename) << II; |
| else if (DeclContext *DC = computeDeclContext(*SS, false)) |
| Diag(IILoc, diag::err_typename_nested_not_found) |
| << II << DC << SS->getRange(); |
| else if (isDependentScopeSpecifier(*SS)) { |
| unsigned DiagID = diag::err_typename_missing; |
| if (getLangOpts().MSVCCompat && isMicrosoftMissingTypename(SS, S)) |
| DiagID = diag::warn_typename_missing; |
| |
| Diag(SS->getRange().getBegin(), DiagID) |
| << SS->getScopeRep() << II->getName() |
| << SourceRange(SS->getRange().getBegin(), IILoc) |
| << FixItHint::CreateInsertion(SS->getRange().getBegin(), "typename "); |
| SuggestedType = ActOnTypenameType(S, SourceLocation(), |
| *SS, *II, IILoc).get(); |
| } else { |
| assert(SS && SS->isInvalid() && |
| "Invalid scope specifier has already been diagnosed"); |
| } |
| |
| return true; |
| } |
| |
| /// \brief Determine whether the given result set contains either a type name |
| /// or |
| static bool isResultTypeOrTemplate(LookupResult &R, const Token &NextToken) { |
| bool CheckTemplate = R.getSema().getLangOpts().CPlusPlus && |
| NextToken.is(tok::less); |
| |
| for (LookupResult::iterator I = R.begin(), IEnd = R.end(); I != IEnd; ++I) { |
| if (isa<TypeDecl>(*I) || isa<ObjCInterfaceDecl>(*I)) |
| return true; |
| |
| if (CheckTemplate && isa<TemplateDecl>(*I)) |
| return true; |
| } |
| |
| return false; |
| } |
| |
| static bool isTagTypeWithMissingTag(Sema &SemaRef, LookupResult &Result, |
| Scope *S, CXXScopeSpec &SS, |
| IdentifierInfo *&Name, |
| SourceLocation NameLoc) { |
| LookupResult R(SemaRef, Name, NameLoc, Sema::LookupTagName); |
| SemaRef.LookupParsedName(R, S, &SS); |
| if (TagDecl *Tag = R.getAsSingle<TagDecl>()) { |
| const char *TagName = 0; |
| const char *FixItTagName = 0; |
| switch (Tag->getTagKind()) { |
| case TTK_Class: |
| TagName = "class"; |
| FixItTagName = "class "; |
| break; |
| |
| case TTK_Enum: |
| TagName = "enum"; |
| FixItTagName = "enum "; |
| break; |
| |
| case TTK_Struct: |
| TagName = "struct"; |
| FixItTagName = "struct "; |
| break; |
| |
| case TTK_Interface: |
| TagName = "__interface"; |
| FixItTagName = "__interface "; |
| break; |
| |
| case TTK_Union: |
| TagName = "union"; |
| FixItTagName = "union "; |
| break; |
| } |
| |
| SemaRef.Diag(NameLoc, diag::err_use_of_tag_name_without_tag) |
| << Name << TagName << SemaRef.getLangOpts().CPlusPlus |
| << FixItHint::CreateInsertion(NameLoc, FixItTagName); |
| |
| for (LookupResult::iterator I = Result.begin(), IEnd = Result.end(); |
| I != IEnd; ++I) |
| SemaRef.Diag((*I)->getLocation(), diag::note_decl_hiding_tag_type) |
| << Name << TagName; |
| |
| // Replace lookup results with just the tag decl. |
| Result.clear(Sema::LookupTagName); |
| SemaRef.LookupParsedName(Result, S, &SS); |
| return true; |
| } |
| |
| return false; |
| } |
| |
| /// Build a ParsedType for a simple-type-specifier with a nested-name-specifier. |
| static ParsedType buildNestedType(Sema &S, CXXScopeSpec &SS, |
| QualType T, SourceLocation NameLoc) { |
| ASTContext &Context = S.Context; |
| |
| TypeLocBuilder Builder; |
| Builder.pushTypeSpec(T).setNameLoc(NameLoc); |
| |
| T = S.getElaboratedType(ETK_None, SS, T); |
| ElaboratedTypeLoc ElabTL = Builder.push<ElaboratedTypeLoc>(T); |
| ElabTL.setElaboratedKeywordLoc(SourceLocation()); |
| ElabTL.setQualifierLoc(SS.getWithLocInContext(Context)); |
| return S.CreateParsedType(T, Builder.getTypeSourceInfo(Context, T)); |
| } |
| |
| Sema::NameClassification Sema::ClassifyName(Scope *S, |
| CXXScopeSpec &SS, |
| IdentifierInfo *&Name, |
| SourceLocation NameLoc, |
| const Token &NextToken, |
| bool IsAddressOfOperand, |
| CorrectionCandidateCallback *CCC) { |
| DeclarationNameInfo NameInfo(Name, NameLoc); |
| ObjCMethodDecl *CurMethod = getCurMethodDecl(); |
| |
| if (NextToken.is(tok::coloncolon)) { |
| BuildCXXNestedNameSpecifier(S, *Name, NameLoc, NextToken.getLocation(), |
| QualType(), false, SS, 0, false); |
| } |
| |
| LookupResult Result(*this, Name, NameLoc, LookupOrdinaryName); |
| LookupParsedName(Result, S, &SS, !CurMethod); |
| |
| // Perform lookup for Objective-C instance variables (including automatically |
| // synthesized instance variables), if we're in an Objective-C method. |
| // FIXME: This lookup really, really needs to be folded in to the normal |
| // unqualified lookup mechanism. |
| if (!SS.isSet() && CurMethod && !isResultTypeOrTemplate(Result, NextToken)) { |
| ExprResult E = LookupInObjCMethod(Result, S, Name, true); |
| if (E.get() || E.isInvalid()) |
| return E; |
| } |
| |
| bool SecondTry = false; |
| bool IsFilteredTemplateName = false; |
| |
| Corrected: |
| switch (Result.getResultKind()) { |
| case LookupResult::NotFound: |
| // If an unqualified-id is followed by a '(', then we have a function |
| // call. |
| if (!SS.isSet() && NextToken.is(tok::l_paren)) { |
| // In C++, this is an ADL-only call. |
| // FIXME: Reference? |
| if (getLangOpts().CPlusPlus) |
| return BuildDeclarationNameExpr(SS, Result, /*ADL=*/true); |
| |
| // C90 6.3.2.2: |
| // If the expression that precedes the parenthesized argument list in a |
| // function call consists solely of an identifier, and if no |
| // declaration is visible for this identifier, the identifier is |
| // implicitly declared exactly as if, in the innermost block containing |
| // the function call, the declaration |
| // |
| // extern int identifier (); |
| // |
| // appeared. |
| // |
| // We also allow this in C99 as an extension. |
| if (NamedDecl *D = ImplicitlyDefineFunction(NameLoc, *Name, S)) { |
| Result.addDecl(D); |
| Result.resolveKind(); |
| return BuildDeclarationNameExpr(SS, Result, /*ADL=*/false); |
| } |
| } |
| |
| // 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 (!getLangOpts().CPlusPlus && !SecondTry && |
| isTagTypeWithMissingTag(*this, Result, S, SS, Name, NameLoc)) { |
| break; |
| } |
| |
| // Perform typo correction to determine if there is another name that is |
| // close to this name. |
| if (!SecondTry && CCC) { |
| SecondTry = true; |
| if (TypoCorrection Corrected = CorrectTypo(Result.getLookupNameInfo(), |
| Result.getLookupKind(), S, |
| &SS, *CCC, |
| CTK_ErrorRecovery)) { |
| unsigned UnqualifiedDiag = diag::err_undeclared_var_use_suggest; |
| unsigned QualifiedDiag = diag::err_no_member_suggest; |
| |
| NamedDecl *FirstDecl = Corrected.getCorrectionDecl(); |
| NamedDecl *UnderlyingFirstDecl |
| = FirstDecl? FirstDecl->getUnderlyingDecl() : 0; |
| if (getLangOpts().CPlusPlus && NextToken.is(tok::less) && |
| UnderlyingFirstDecl && isa<TemplateDecl>(UnderlyingFirstDecl)) { |
| UnqualifiedDiag = diag::err_no_template_suggest; |
| QualifiedDiag = diag::err_no_member_template_suggest; |
| } else if (UnderlyingFirstDecl && |
| (isa<TypeDecl>(UnderlyingFirstDecl) || |
| isa<ObjCInterfaceDecl>(UnderlyingFirstDecl) || |
| isa<ObjCCompatibleAliasDecl>(UnderlyingFirstDecl))) { |
| UnqualifiedDiag = diag::err_unknown_typename_suggest; |
| QualifiedDiag = diag::err_unknown_nested_typename_suggest; |
| } |
| |
| if (SS.isEmpty()) { |
| diagnoseTypo(Corrected, PDiag(UnqualifiedDiag) << Name); |
| } else {// FIXME: is this even reachable? Test it. |
| std::string CorrectedStr(Corrected.getAsString(getLangOpts())); |
| bool DroppedSpecifier = Corrected.WillReplaceSpecifier() && |
| Name->getName().equals(CorrectedStr); |
| diagnoseTypo(Corrected, PDiag(QualifiedDiag) |
| << Name << computeDeclContext(SS, false) |
| << DroppedSpecifier << SS.getRange()); |
| } |
| |
| // Update the name, so that the caller has the new name. |
| Name = Corrected.getCorrectionAsIdentifierInfo(); |
| |
| // Typo correction corrected to a keyword. |
| if (Corrected.isKeyword()) |
| return Name; |
| |
| // Also update the LookupResult... |
| // FIXME: This should probably go away at some point |
| Result.clear(); |
| Result.setLookupName(Corrected.getCorrection()); |
| if (FirstDecl) |
| Result.addDecl(FirstDecl); |
| |
| // If we found an Objective-C instance variable, let |
| // LookupInObjCMethod build the appropriate expression to |
| // reference the ivar. |
| // FIXME: This is a gross hack. |
| if (ObjCIvarDecl *Ivar = Result.getAsSingle<ObjCIvarDecl>()) { |
| Result.clear(); |
| ExprResult E(LookupInObjCMethod(Result, S, Ivar->getIdentifier())); |
| return E; |
| } |
| |
| goto Corrected; |
| } |
| } |
| |
| // We failed to correct; just fall through and let the parser deal with it. |
| Result.suppressDiagnostics(); |
| return NameClassification::Unknown(); |
| |
| 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. |
| |
| // C++ [temp.res]p2: |
| // A name used in a template declaration or definition and that is |
| // dependent on a template-parameter is assumed not to name a type |
| // unless the applicable name lookup finds a type name or the name is |
| // qualified by the keyword typename. |
| // |
| // FIXME: If the next token is '<', we might want to ask the parser to |
| // perform some heroics to see if we actually have a |
| // template-argument-list, which would indicate a missing 'template' |
| // keyword here. |
| return ActOnDependentIdExpression(SS, /*TemplateKWLoc=*/SourceLocation(), |
| NameInfo, IsAddressOfOperand, |
| /*TemplateArgs=*/0); |
| } |
| |
| case LookupResult::Found: |
| case LookupResult::FoundOverloaded: |
| case LookupResult::FoundUnresolvedValue: |
| break; |
| |
| case LookupResult::Ambiguous: |
| 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 |
| // ambiguity in certain cases (for example, if it is found in more than |
| // one base class). If all of the injected-class-names that are found |
| // refer to specializations of the same class template, and if the name |
| // is followed by a template-argument-list, the reference refers to the |
| // class template itself and not a specialization thereof, and is not |
| // ambiguous. |
| // |
| // This filtering can make an ambiguous result into an unambiguous one, |
| // so try again after filtering out template names. |
| FilterAcceptableTemplateNames(Result); |
| if (!Result.isAmbiguous()) { |
| IsFilteredTemplateName = true; |
| break; |
| } |
| } |
| |
| // Diagnose the ambiguity and return an error. |
| return NameClassification::Error(); |
| } |
| |
| 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 |
| // an operator-function-id or a literal- operator-id refers to a set of |
| // overloaded functions any member of which is a function template if |
| // this is followed by a <, the < is always taken as the delimiter of a |
| // template-argument-list and never as the less-than operator. |
| if (!IsFilteredTemplateName) |
| FilterAcceptableTemplateNames(Result); |
| |
| if (!Result.empty()) { |
| bool IsFunctionTemplate; |
| bool IsVarTemplate; |
| TemplateName Template; |
| if (Result.end() - Result.begin() > 1) { |
| IsFunctionTemplate = true; |
| Template = Context.getOverloadedTemplateName(Result.begin(), |
| Result.end()); |
| } else { |
| TemplateDecl *TD |
| = cast<TemplateDecl>((*Result.begin())->getUnderlyingDecl()); |
| IsFunctionTemplate = isa<FunctionTemplateDecl>(TD); |
| IsVarTemplate = isa<VarTemplateDecl>(TD); |
| |
| if (SS.isSet() && !SS.isInvalid()) |
| Template = Context.getQualifiedTemplateName(SS.getScopeRep(), |
| /*TemplateKeyword=*/false, |
| TD); |
| else |
| Template = TemplateName(TD); |
| } |
| |
| if (IsFunctionTemplate) { |
| // Function templates always go through overload resolution, at which |
| // point we'll perform the various checks (e.g., accessibility) we need |
| // to based on which function we selected. |
| Result.suppressDiagnostics(); |
| |
| return NameClassification::FunctionTemplate(Template); |
| } |
| |
| return IsVarTemplate ? NameClassification::VarTemplate(Template) |
| : NameClassification::TypeTemplate(Template); |
| } |
| } |
| |
| NamedDecl *FirstDecl = (*Result.begin())->getUnderlyingDecl(); |
| if (TypeDecl *Type = dyn_cast<TypeDecl>(FirstDecl)) { |
| DiagnoseUseOfDecl(Type, NameLoc); |
| QualType T = Context.getTypeDeclType(Type); |
| if (SS.isNotEmpty()) |
| return buildNestedType(*this, SS, T, NameLoc); |
| return ParsedType::make(T); |
| } |
| |
| ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(FirstDecl); |
| if (!Class) { |
| // FIXME: It's unfortunate that we don't have a Type node for handling this. |
| if (ObjCCompatibleAliasDecl *Alias |
| = dyn_cast<ObjCCompatibleAliasDecl>(FirstDecl)) |
| Class = Alias->getClassInterface(); |
| } |
| |
| if (Class) { |
| DiagnoseUseOfDecl(Class, NameLoc); |
| |
| if (NextToken.is(tok::period)) { |
| // Interface. <something> is parsed as a property reference expression. |
| // Just return "unknown" as a fall-through for now. |
| Result.suppressDiagnostics(); |
| return NameClassification::Unknown(); |
| } |
| |
| QualType T = Context.getObjCInterfaceType(Class); |
| return ParsedType::make(T); |
| } |
| |
| // We can have a type template here if we're classifying a template argument. |
| if (isa<TemplateDecl>(FirstDecl) && !isa<FunctionTemplateDecl>(FirstDecl)) |
| return NameClassification::TypeTemplate( |
| TemplateName(cast<TemplateDecl>(FirstDecl))); |
| |
| // Check for a tag type hidden by a non-type decl in a few cases where it |
| // seems likely a type is wanted instead of the non-type that was found. |
| bool NextIsOp = NextToken.is(tok::amp) || NextToken.is(tok::star); |
| if ((NextToken.is(tok::identifier) || |
| (NextIsOp && |
| FirstDecl->getUnderlyingDecl()->isFunctionOrFunctionTemplate())) && |
| isTagTypeWithMissingTag(*this, Result, S, SS, Name, NameLoc)) { |
| TypeDecl *Type = Result.getAsSingle<TypeDecl>(); |
| DiagnoseUseOfDecl(Type, NameLoc); |
| QualType T = Context.getTypeDeclType(Type); |
| if (SS.isNotEmpty()) |
| return buildNestedType(*this, SS, T, NameLoc); |
| return ParsedType::make(T); |
| } |
| |
| if (FirstDecl->isCXXClassMember()) |
| return BuildPossibleImplicitMemberExpr(SS, SourceLocation(), Result, 0); |
| |
| bool ADL = UseArgumentDependentLookup(SS, Result, NextToken.is(tok::l_paren)); |
| return BuildDeclarationNameExpr(SS, Result, ADL); |
| } |
| |
| // Determines the context to return to after temporarily entering a |
| // context. This depends in an unnecessarily complicated way on the |
| // exact ordering of callbacks from the parser. |
| DeclContext *Sema::getContainingDC(DeclContext *DC) { |
| |
| // Functions defined inline within classes aren't parsed until we've |
| // finished parsing the top-level class, so the top-level class is |
| // the context we'll need to return to. |
| // A Lambda call operator whose parent is a class must not be treated |
| // as an inline member function. A Lambda can be used legally |
| // either as an in-class member initializer or a default argument. These |
| // are parsed once the class has been marked complete and so the containing |
| // context would be the nested class (when the lambda is defined in one); |
| // If the class is not complete, then the lambda is being used in an |
| // ill-formed fashion (such as to specify the width of a bit-field, or |
| // in an array-bound) - in which case we still want to return the |
| // lexically containing DC (which could be a nested class). |
| if (isa<FunctionDecl>(DC) && !isLambdaCallOperator(DC)) { |
| DC = DC->getLexicalParent(); |
| |
| // A function not defined within a class will always return to its |
| // lexical context. |
| if (!isa<CXXRecordDecl>(DC)) |
| return DC; |
| |
| // A C++ inline method/friend is parsed *after* the topmost class |
| // it was declared in is fully parsed ("complete"); the topmost |
| // class is the context we need to return to. |
| while (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC->getLexicalParent())) |
| DC = RD; |
| |
| // Return the declaration context of the topmost class the inline method is |
| // declared in. |
| return DC; |
| } |
| |
| return DC->getLexicalParent(); |
| } |
| |
| void Sema::PushDeclContext(Scope *S, DeclContext *DC) { |
| assert(getContainingDC(DC) == CurContext && |
| "The next DeclContext should be lexically contained in the current one."); |
| CurContext = DC; |
| S->setEntity(DC); |
| } |
| |
| void Sema::PopDeclContext() { |
| assert(CurContext && "DeclContext imbalance!"); |
| |
| CurContext = getContainingDC(CurContext); |
| assert(CurContext && "Popped translation unit!"); |
| } |
| |
| /// EnterDeclaratorContext - Used when we must lookup names in the context |
| /// of a declarator's nested name specifier. |
| /// |
| void Sema::EnterDeclaratorContext(Scope *S, DeclContext *DC) { |
| // C++0x [basic.lookup.unqual]p13: |
| // A name used in the definition of a static data member of class |
| // X (after the qualified-id of the static member) is looked up as |
| // if the name was used in a member function of X. |
| // C++0x [basic.lookup.unqual]p14: |
| // If a variable member of a namespace is defined outside of the |
| // scope of its namespace then any name used in the definition of |
| // the variable member (after the declarator-id) is looked up as |
| // if the definition of the variable member occurred in its |
| // namespace. |
| // Both of these imply that we should push a scope whose context |
| // is the semantic context of the declaration. We can't use |
| // PushDeclContext here because that context is not necessarily |
| // lexically contained in the current context. Fortunately, |
| // the containing scope should have the appropriate information. |
| |
| assert(!S->getEntity() && "scope already has entity"); |
| |
| #ifndef NDEBUG |
| Scope *Ancestor = S->getParent(); |
| while (!Ancestor->getEntity()) Ancestor = Ancestor->getParent(); |
| assert(Ancestor->getEntity() == CurContext && "ancestor context mismatch"); |
| #endif |
| |
| CurContext = DC; |
| S->setEntity(DC); |
| } |
| |
| void Sema::ExitDeclaratorContext(Scope *S) { |
| assert(S->getEntity() == CurContext && "Context imbalance!"); |
| |
| // Switch back to the lexical context. The safety of this is |
| // enforced by an assert in EnterDeclaratorContext. |
| Scope *Ancestor = S->getParent(); |
| while (!Ancestor->getEntity()) Ancestor = Ancestor->getParent(); |
| CurContext = Ancestor->getEntity(); |
| |
| // We don't need to do anything with the scope, which is going to |
| // disappear. |
| } |
| |
| |
| void Sema::ActOnReenterFunctionContext(Scope* S, Decl *D) { |
| // We assume that the caller has already called |
| // ActOnReenterTemplateScope so getTemplatedDecl() works. |
| FunctionDecl *FD = D->getAsFunction(); |
| if (!FD) |
| return; |
| |
| // 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 |
| if (Param->getIdentifier()) { |
| S->AddDecl(Param); |
| IdResolver.AddDecl(Param); |
| } |
| } |
| } |
| |
| |
| 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. |
| /// |
| /// This routine determines whether overloading is possible, not |
| /// whether some new function is actually an overload. It will return |
| /// true in C++ (where we can always provide overloads) or, as an |
| /// extension, in C when the previous function is already an |
| /// overloaded function declaration or has the "overloadable" |
| /// attribute. |
| static bool AllowOverloadingOfFunction(LookupResult &Previous, |
| ASTContext &Context) { |
| if (Context.getLangOpts().CPlusPlus) |
| return true; |
| |
| if (Previous.getResultKind() == LookupResult::FoundOverloaded) |
| return true; |
| |
| return (Previous.getResultKind() == LookupResult::Found |
| && Previous.getFoundDecl()->hasAttr<OverloadableAttr>()); |
| } |
| |
| /// Add this decl to the scope shadowed decl chains. |
| void Sema::PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext) { |
| // Move up the scope chain until we find the nearest enclosing |
| // non-transparent context. The declaration will be introduced into this |
| // scope. |
| while (S->getEntity() && S->getEntity()->isTransparentContext()) |
| S = S->getParent(); |
| |
| // Add scoped declarations into their context, so that they can be |
| // found later. Declarations without a context won't be inserted |
| // into any context. |
| if (AddToContext) |
| CurContext->addDecl(D); |
| |
| // Out-of-line definitions shouldn't be pushed into scope in C++, unless they |
| // are function-local declarations. |
| if (getLangOpts().CPlusPlus && D->isOutOfLine() && |
| !D->getDeclContext()->getRedeclContext()->Equals( |
| D->getLexicalDeclContext()->getRedeclContext()) && |
| !D->getLexicalDeclContext()->isFunctionOrMethod()) |
| return; |
| |
| // Template instantiations should also not be pushed into scope. |
| if (isa<FunctionDecl>(D) && |
| cast<FunctionDecl>(D)->isFunctionTemplateSpecialization()) |
| return; |
| |
| // If this replaces anything in the current scope, |
| IdentifierResolver::iterator I = IdResolver.begin(D->getDeclName()), |
| IEnd = IdResolver.end(); |
| for (; I != IEnd; ++I) { |
| if (S->isDeclScope(*I) && D->declarationReplaces(*I)) { |
| S->RemoveDecl(*I); |
| IdResolver.RemoveDecl(*I); |
| |
| // Should only need to replace one decl. |
| break; |
| } |
| } |
| |
| S->AddDecl(D); |
| |
| if (isa<LabelDecl>(D) && !cast<LabelDecl>(D)->isGnuLocal()) { |
| // Implicitly-generated labels may end up getting generated in an order that |
| // isn't strictly lexical, which breaks name lookup. Be careful to insert |
| // the label at the appropriate place in the identifier chain. |
| for (I = IdResolver.begin(D->getDeclName()); I != IEnd; ++I) { |
| DeclContext *IDC = (*I)->getLexicalDeclContext()->getRedeclContext(); |
| if (IDC == CurContext) { |
| if (!S->isDeclScope(*I)) |
| continue; |
| } else if (IDC->Encloses(CurContext)) |
| break; |
| } |
| |
| IdResolver.InsertDeclAfter(I, D); |
| } else { |
| IdResolver.AddDecl(D); |
| } |
| } |
| |
| 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 AllowInlineNamespace) { |
| return IdResolver.isDeclInScope(D, Ctx, S, AllowInlineNamespace); |
| } |
| |
| Scope *Sema::getScopeForDeclContext(Scope *S, DeclContext *DC) { |
| DeclContext *TargetDC = DC->getPrimaryContext(); |
| do { |
| if (DeclContext *ScopeDC = S->getEntity()) |
| if (ScopeDC->getPrimaryContext() == TargetDC) |
| return S; |
| } while ((S = S->getParent())); |
| |
| return 0; |
| } |
| |
| static bool isOutOfScopePreviousDeclaration(NamedDecl *, |
| DeclContext*, |
| ASTContext&); |
| |
| /// Filters out lookup results that don't fall within the given scope |
| /// as determined by isDeclInScope. |
| void Sema::FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S, |
| bool ConsiderLinkage, |
| bool AllowInlineNamespace) { |
| LookupResult::Filter F = R.makeFilter(); |
| while (F.hasNext()) { |
| NamedDecl *D = F.next(); |
| |
| if (isDeclInScope(D, Ctx, S, AllowInlineNamespace)) |
| continue; |
| |
| if (ConsiderLinkage && isOutOfScopePreviousDeclaration(D, Ctx, Context)) |
| continue; |
| |
| F.erase(); |
| } |
| |
| F.done(); |
| } |
| |
| static bool isUsingDecl(NamedDecl *D) { |
| return isa<UsingShadowDecl>(D) || |
| isa<UnresolvedUsingTypenameDecl>(D) || |
| isa<UnresolvedUsingValueDecl>(D); |
| } |
| |
| /// Removes using shadow declarations from the lookup results. |
| static void RemoveUsingDecls(LookupResult &R) { |
| LookupResult::Filter F = R.makeFilter(); |
| while (F.hasNext()) |
| if (isUsingDecl(F.next())) |
| F.erase(); |
| |
| F.done(); |
| } |
| |
| /// \brief Check for this common pattern: |
| /// @code |
| /// class S { |
| /// S(const S&); // DO NOT IMPLEMENT |
| /// void operator=(const S&); // DO NOT IMPLEMENT |
| /// }; |
| /// @endcode |
| static bool IsDisallowedCopyOrAssign(const CXXMethodDecl *D) { |
| // FIXME: Should check for private access too but access is set after we get |
| // the decl here. |
| if (D->doesThisDeclarationHaveABody()) |
| return false; |
| |
| if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(D)) |
| return CD->isCopyConstructor(); |
| if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) |
| return Method->isCopyAssignmentOperator(); |
| return false; |
| } |
| |
| // We need this to handle |
| // |
| // typedef struct { |
| // void *foo() { return 0; } |
| // } A; |
| // |
| // When we see foo we don't know if after the typedef we will get 'A' or '*A' |
| // for example. If 'A', foo will have external linkage. If we have '*A', |
| // foo will have no linkage. Since we can't know until we get to the end |
| // of the typedef, this function finds out if D might have non-external linkage. |
| // Callers should verify at the end of the TU if it D has external linkage or |
| // not. |
| bool Sema::mightHaveNonExternalLinkage(const DeclaratorDecl *D) { |
| const DeclContext *DC = D->getDeclContext(); |
| while (!DC->isTranslationUnit()) { |
| if (const RecordDecl *RD = dyn_cast<RecordDecl>(DC)){ |
| if (!RD->hasNameForLinkage()) |
| return true; |
| } |
| DC = DC->getParent(); |
| } |
| |
| return !D->isExternallyVisible(); |
| } |
| |
| // FIXME: This needs to be refactored; some other isInMainFile users want |
| // these semantics. |
| static bool isMainFileLoc(const Sema &S, SourceLocation Loc) { |
| if (S.TUKind != TU_Complete) |
| return false; |
| return S.SourceMgr.isInMainFile(Loc); |
| } |
| |
| bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const { |
| assert(D); |
| |
| if (D->isInvalidDecl() || D->isUsed() || D->hasAttr<UnusedAttr>()) |
| return false; |
| |
| // Ignore all entities declared within templates, and out-of-line definitions |
| // of members of class templates. |
| if (D->getDeclContext()->isDependentContext() || |
| D->getLexicalDeclContext()->isDependentContext()) |
| return false; |
| |
| if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { |
| if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) |
| return false; |
| |
| if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) { |
| if (MD->isVirtual() || IsDisallowedCopyOrAssign(MD)) |
| return false; |
| } else { |
| // 'static inline' functions are defined in headers; don't warn. |
| if (FD->isInlineSpecified() && |
| !isMainFileLoc(*this, FD->getLocation())) |
| return false; |
| } |
| |
| if (FD->doesThisDeclarationHaveABody() && |
| Context.DeclMustBeEmitted(FD)) |
| return false; |
| } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { |
| // Constants and utility variables are defined in headers with internal |
| // linkage; don't warn. (Unlike functions, there isn't a convenient marker |
| // like "inline".) |
| if (!isMainFileLoc(*this, VD->getLocation())) |
| return false; |
| |
| if (Context.DeclMustBeEmitted(VD)) |
| return false; |
| |
| if (VD->isStaticDataMember() && |
| VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) |
| return false; |
| } else { |
| return false; |
| } |
| |
| // Only warn for unused decls internal to the translation unit. |
| return mightHaveNonExternalLinkage(D); |
| } |
| |
| void Sema::MarkUnusedFileScopedDecl(const DeclaratorDecl *D) { |
| if (!D) |
| return; |
| |
| if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { |
| const FunctionDecl *First = FD->getFirstDecl(); |
| if (FD != First && ShouldWarnIfUnusedFileScopedDecl(First)) |
| return; // First should already be in the vector. |
| } |
| |
| if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { |
| const VarDecl *First = VD->getFirstDecl(); |
| if (VD != First && ShouldWarnIfUnusedFileScopedDecl(First)) |
| return; // First should already be in the vector. |
| } |
| |
| if (ShouldWarnIfUnusedFileScopedDecl(D)) |
| UnusedFileScopedDecls.push_back(D); |
| } |
| |
| static bool ShouldDiagnoseUnusedDecl(const NamedDecl *D) { |
| if (D->isInvalidDecl()) |
| return false; |
| |
| if (D->isReferenced() || D->isUsed() || D->hasAttr<UnusedAttr>() || |
| D->hasAttr<ObjCPreciseLifetimeAttr>()) |
| return false; |
| |
| if (isa<LabelDecl>(D)) |
| return true; |
| |
| // White-list anything that isn't a local variable. |
| if (!isa<VarDecl>(D) || isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D) || |
| !D->getDeclContext()->isFunctionOrMethod()) |
| return false; |
| |
| // Types of valid local variables should be complete, so this should succeed. |
| if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { |
| |
| // White-list anything with an __attribute__((unused)) type. |
| QualType Ty = VD->getType(); |
| |
| // Only look at the outermost level of typedef. |
| if (const TypedefType *TT = Ty->getAs<TypedefType>()) { |
| if (TT->getDecl()->hasAttr<UnusedAttr>()) |
| return false; |
| } |
| |
| // If we failed to complete the type for some reason, or if the type is |
| // dependent, don't diagnose the variable. |
| if (Ty->isIncompleteType() || Ty->isDependentType()) |
| return false; |
| |
| if (const TagType *TT = Ty->getAs<TagType>()) { |
| const TagDecl *Tag = TT->getDecl(); |
| if (Tag->hasAttr<UnusedAttr>()) |
| return false; |
| |
| if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Tag)) { |
| if (!RD->hasTrivialDestructor() && !RD->hasAttr<WarnUnusedAttr>()) |
| return false; |
| |
| if (const Expr *Init = VD->getInit()) { |
| if (const ExprWithCleanups *Cleanups = dyn_cast<ExprWithCleanups>(Init)) |
| Init = Cleanups->getSubExpr(); |
| const CXXConstructExpr *Construct = |
| dyn_cast<CXXConstructExpr>(Init); |
| if (Construct && !Construct->isElidable()) { |
| CXXConstructorDecl *CD = Construct->getConstructor(); |
| if (!CD->isTrivial() && !RD->hasAttr<WarnUnusedAttr>()) |
| return false; |
| } |
| } |
| } |
| } |
| |
| // TODO: __attribute__((unused)) templates? |
| } |
| |
| return true; |
| } |
| |
| 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.getLangOpts(), true); |
| if (AfterColon.isInvalid()) |
| return; |
| Hint = FixItHint::CreateRemoval(CharSourceRange:: |
| getCharRange(D->getLocStart(), AfterColon)); |
| } |
| return; |
| } |
| |
| /// DiagnoseUnusedDecl - Emit warnings about declarations that are not used |
| /// unless they are marked attr(unused). |
| void Sema::DiagnoseUnusedDecl(const NamedDecl *D) { |
| FixItHint Hint; |
| if (!ShouldDiagnoseUnusedDecl(D)) |
| return; |
| |
| GenerateFixForUnusedDecl(D, Context, Hint); |
| |
| unsigned DiagID; |
| if (isa<VarDecl>(D) && cast<VarDecl>(D)->isExceptionVariable()) |
| DiagID = diag::warn_unused_exception_param; |
| else if (isa<LabelDecl>(D)) |
| DiagID = diag::warn_unused_label; |
| else |
| DiagID = diag::warn_unused_variable; |
| |
| Diag(D->getLocation(), DiagID) << D->getDeclName() << Hint; |
| } |
| |
| static void CheckPoppedLabel(LabelDecl *L, Sema &S) { |
| // Verify that we have no forward references left. If so, there was a goto |
| // or address of a label taken, but no definition of it. Label fwd |
| // definitions are indicated with a null substmt. |
| if (L->getStmt() == 0) |
| S.Diag(L->getLocation(), diag::err_undeclared_label_use) <<L->getDeclName(); |
| } |
| |
| void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { |
| if (S->decl_empty()) return; |
| assert((S->getFlags() & (Scope::DeclScope | Scope::TemplateParamScope)) && |
| "Scope shouldn't contain decls!"); |
| |
| for (auto *TmpD : S->decls()) { |
| assert(TmpD && "This decl didn't get pushed??"); |
| |
| assert(isa<NamedDecl>(TmpD) && "Decl isn't NamedDecl?"); |
| NamedDecl *D = cast<NamedDecl>(TmpD); |
| |
| if (!D->getDeclName()) continue; |
| |
| // Diagnose unused variables in this scope. |
| if (!S->hasUnrecoverableErrorOccurred()) |
| DiagnoseUnusedDecl(D); |
| |
| // If this was a forward reference to a label, verify it was defined. |
| if (LabelDecl *LD = dyn_cast<LabelDecl>(D)) |
| CheckPoppedLabel(LD, *this); |
| |
| // Remove this name from our lexical scope. |
| IdResolver.RemoveDecl(D); |
| } |
| } |
| |
| /// \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 |
| /// typo-correction fixes this name, the Id will be updated |
| /// to the fixed name. |
| /// |
| /// \param IdLoc The location of the name in the translation unit. |
| /// |
| /// \param DoTypoCorrection If true, this routine will attempt typo correction |
| /// if there is no class with the given name. |
| /// |
| /// \returns The declaration of the named Objective-C class, or NULL if the |
| /// class could not be found. |
| ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *&Id, |
| SourceLocation IdLoc, |
| bool DoTypoCorrection) { |
| // The third "scope" argument is 0 since we aren't enabling lazy built-in |
| // creation from this context. |
| NamedDecl *IDecl = LookupSingleName(TUScope, Id, IdLoc, LookupOrdinaryName); |
| |
| if (!IDecl && DoTypoCorrection) { |
| // Perform typo correction at the given location, but only if we |
| // find an Objective-C class name. |
| DeclFilterCCC<ObjCInterfaceDecl> Validator; |
| if (TypoCorrection C = CorrectTypo(DeclarationNameInfo(Id, IdLoc), |
| LookupOrdinaryName, TUScope, NULL, |
| Validator, CTK_ErrorRecovery)) { |
| diagnoseTypo(C, PDiag(diag::err_undef_interface_suggest) << Id); |
| IDecl = C.getCorrectionDeclAs<ObjCInterfaceDecl>(); |
| Id = IDecl->getIdentifier(); |
| } |
| } |
| 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 |
| /// from S, where a non-field would be declared. This routine copes |
| /// with the difference between C and C++ scoping rules in structs and |
| /// unions. For example, the following code is well-formed in C but |
| /// ill-formed in C++: |
| /// @code |
| /// struct S6 { |
| /// enum { BAR } e; |
| /// }; |
| /// |
| /// void test_S6() { |
| /// struct S6 a; |
| /// a.e = BAR; |
| /// } |
| /// @endcode |
| /// For the declaration of BAR, this routine will return a different |
| /// scope. The scope S will be the scope of the unnamed enumeration |
| /// within S6. In C++, this routine will return the scope associated |
| /// with S6, because the enumeration's scope is a transparent |
| /// context but structures can contain non-field names. In C, this |
| /// routine will return the translation unit scope, since the |
| /// enumeration's scope is a transparent context and structures cannot |
| /// contain non-field names. |
| Scope *Sema::getNonFieldDeclScope(Scope *S) { |
| while (((S->getFlags() & Scope::DeclScope) == 0) || |
| (S->getEntity() && S->getEntity()->isTransparentContext()) || |
| (S->isClassScope() && !getLangOpts().CPlusPlus)) |
| S = S->getParent(); |
| return S; |
| } |
| |
| /// \brief Looks up the declaration of "struct objc_super" and |
| /// saves it for later use in building builtin declaration of |
| /// objc_msgSendSuper and objc_msgSendSuper_stret. If no such |
| /// pre-existing declaration exists no action takes place. |
| static void LookupPredefedObjCSuperType(Sema &ThisSema, Scope *S, |
| IdentifierInfo *II) { |
| if (!II->isStr("objc_msgSendSuper")) |
| return; |
| ASTContext &Context = ThisSema.Context; |
| |
| LookupResult Result(ThisSema, &Context.Idents.get("objc_super"), |
| SourceLocation(), Sema::LookupTagName); |
| ThisSema.LookupName(Result, S); |
| if (Result.getResultKind() == LookupResult::Found) |
| if (const TagDecl *TD = Result.getAsSingle<TagDecl>()) |
| Context.setObjCSuperType(Context.getTagDeclType(TD)); |
| } |
| |
| /// LazilyCreateBuiltin - The specified Builtin-ID was first used at |
| /// file scope. lazily create a decl for it. ForRedeclaration is true |
| /// if we're creating this built-in in anticipation of redeclaring the |
| /// built-in. |
| NamedDecl *Sema::LazilyCreateBuiltin(IdentifierInfo *II, unsigned bid, |
| Scope *S, bool ForRedeclaration, |
| SourceLocation Loc) { |
| LookupPredefedObjCSuperType(*this, S, II); |
| |
| Builtin::ID BID = (Builtin::ID)bid; |
| |
| ASTContext::GetBuiltinTypeError Error; |
| QualType R = Context.GetBuiltinType(BID, Error); |
| switch (Error) { |
| case ASTContext::GE_None: |
| // Okay |
| break; |
| |
| case ASTContext::GE_Missing_stdio: |
| if (ForRedeclaration) |
| Diag(Loc, diag::warn_implicit_decl_requires_stdio) |
| << Context.BuiltinInfo.GetName(BID); |
| return 0; |
| |
| case ASTContext::GE_Missing_setjmp: |
| if (ForRedeclaration) |
| Diag(Loc, diag::warn_implicit_decl_requires_setjmp) |
| << Context.BuiltinInfo.GetName(BID); |
| return 0; |
| |
| case ASTContext::GE_Missing_ucontext: |
| if (ForRedeclaration) |
| Diag(Loc, diag::warn_implicit_decl_requires_ucontext) |
| << Context.BuiltinInfo.GetName(BID); |
| return 0; |
| } |
| |
| if (!ForRedeclaration && Context.BuiltinInfo.isPredefinedLibFunction(BID)) { |
| Diag(Loc, diag::ext_implicit_lib_function_decl) |
| << Context.BuiltinInfo.GetName(BID) |
| << R; |
| if (Context.BuiltinInfo.getHeaderName(BID) && |
| Diags.getDiagnosticLevel(diag::ext_implicit_lib_function_decl, Loc) |
| != DiagnosticsEngine::Ignored) |
| Diag(Loc, diag::note_please_include_header) |
| << Context.BuiltinInfo.getHeaderName(BID) |
| << Context.BuiltinInfo.GetName(BID); |
| } |
| |
| DeclContext *Parent = Context.getTranslationUnitDecl(); |
| if (getLangOpts().CPlusPlus) { |
| LinkageSpecDecl *CLinkageDecl = |
| LinkageSpecDecl::Create(Context, Parent, Loc, Loc, |
| LinkageSpecDecl::lang_c, false); |
| CLinkageDecl->setImplicit(); |
| Parent->addDecl(CLinkageDecl); |
| Parent = CLinkageDecl; |
| } |
| |
| FunctionDecl *New = FunctionDecl::Create(Context, |
| Parent, |
| Loc, Loc, II, R, /*TInfo=*/0, |
| SC_Extern, |
| false, |
| /*hasPrototype=*/true); |
| New->setImplicit(); |
| |
| // Create Decl objects for each parameter, adding them to the |
| // FunctionDecl. |
| if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(R)) { |
| SmallVector<ParmVarDecl*, 16> Params; |
| for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) { |
| ParmVarDecl *parm = |
| ParmVarDecl::Create(Context, New, SourceLocation(), SourceLocation(), |
| 0, FT->getParamType(i), /*TInfo=*/0, SC_None, 0); |
| parm->setScopeInfo(0, i); |
| Params.push_back(parm); |
| } |
| New->setParams(Params); |
| } |
| |
| AddKnownFunctionAttributes(New); |
| RegisterLocallyScopedExternCDecl(New, S); |
| |
| // TUScope is the translation-unit scope to insert this function into. |
| // FIXME: This is hideous. We need to teach PushOnScopeChains to |
| // relate Scopes to DeclContexts, and probably eliminate CurContext |
| // entirely, but we're not there yet. |
| DeclContext *SavedContext = CurContext; |
| CurContext = Parent; |
| PushOnScopeChains(New, TUScope); |
| CurContext = SavedContext; |
| return New; |
| } |
| |
| /// \brief Filter out any previous declarations that the given declaration |
| /// should not consider because they are not permitted to conflict, e.g., |
| /// because they come from hidden sub-modules and do not refer to the same |
| /// entity. |
| static void filterNonConflictingPreviousDecls(ASTContext &context, |
| NamedDecl *decl, |
| LookupResult &previous){ |
| // This is only interesting when modules are enabled. |
| if (!context.getLangOpts().Modules) |
| return; |
| |
| // Empty sets are uninteresting. |
| if (previous.empty()) |
| return; |
| |
| LookupResult::Filter filter = previous.makeFilter(); |
| while (filter.hasNext()) { |
| NamedDecl *old = filter.next(); |
| |
| // Non-hidden declarations are never ignored. |
| if (!old->isHidden()) |
| continue; |
| |
| if (!old->isExternallyVisible()) |
| filter.erase(); |
| } |
| |
| filter.done(); |
| } |
| |
| 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 |
| /// diagnostics as appropriate. If there was an error, set New to be invalid. |
| /// |
| void Sema::MergeTypedefNameDecl(TypedefNameDecl *New, LookupResult &OldDecls) { |
| // If the new decl is known invalid already, don't bother doing any |
| // merging checks. |
| if (New->isInvalidDecl()) return; |
| |
| // Allow multiple definitions for ObjC built-in typedefs. |
| // FIXME: Verify the underlying types are equivalent! |
| if (getLangOpts().ObjC1) { |
| const IdentifierInfo *TypeID = New->getIdentifier(); |
| switch (TypeID->getLength()) { |
| default: break; |
| case 2: |
| { |
| if (!TypeID->isStr("id")) |
| break; |
| QualType T = New->getUnderlyingType(); |
| if (!T->isPointerType()) |
| break; |
| if (!T->isVoidPointerType()) { |
| QualType PT = T->getAs<PointerType>()->getPointeeType(); |
| if (!PT->isStructureType()) |
| break; |
| } |
| Context.setObjCIdRedefinitionType(T); |
| // Install the built-in type for 'id', ignoring the current definition. |
| New->setTypeForDecl(Context.getObjCIdType().getTypePtr()); |
| return; |
| } |
| case 5: |
| if (!TypeID->isStr("Class")) |
| break; |
| Context.setObjCClassRedefinitionType(New->getUnderlyingType()); |
| // Install the built-in type for 'Class', ignoring the current definition. |
| New->setTypeForDecl(Context.getObjCClassType().getTypePtr()); |
| return; |
| case 3: |
| if (!TypeID->isStr("SEL")) |
| break; |
| Context.setObjCSelRedefinitionType(New->getUnderlyingType()); |
| // Install the built-in type for 'SEL', ignoring the current definition. |
| New->setTypeForDecl(Context.getObjCSelType().getTypePtr()); |
| return; |
| } |
| // Fall through - the typedef name was not a builtin type. |
| } |
| |
| // Verify the old decl was also a type. |
| TypeDecl *Old = OldDecls.getAsSingle<TypeDecl>(); |
| if (!Old) { |
| Diag(New->getLocation(), diag::err_redefinition_different_kind) |
| << New->getDeclName(); |
| |
| NamedDecl *OldD = OldDecls.getRepresentativeDecl(); |
| if (OldD->getLocation().isValid()) |
| Diag(OldD->getLocation(), diag::note_previous_definition); |
| |
| return New->setInvalidDecl(); |
| } |
| |
| // If the old declaration is invalid, just give up here. |
| if (Old->isInvalidDecl()) |
| return New->setInvalidDecl(); |
| |
| // If the typedef types are not identical, reject them in all languages and |
| // with any extensions enabled. |
| if (isIncompatibleTypedef(Old, New)) |
| return; |
| |
| // The types match. Link up the redeclaration chain and merge attributes if |
| // the old declaration was a typedef. |
| if (TypedefNameDecl *Typedef = dyn_cast<TypedefNameDecl>(Old)) { |
| New->setPreviousDecl(Typedef); |
| mergeDeclAttributes(New, Old); |
| } |
| |
| if (getLangOpts().MicrosoftExt) |
| return; |
| |
| 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 |
| // to the type to which it already refers. |
| if (!isa<CXXRecordDecl>(CurContext)) |
| return; |
| |
| // C++0x [dcl.typedef]p4: |
| // In a given class scope, a typedef specifier can be used to redefine |
| // any class-name declared in that scope that is not also a typedef-name |
| // to refer to the type to which it already refers. |
| // |
| // This wording came in via DR424, which was a correction to the |
| // wording in DR56, which accidentally banned code like: |
| // |
| // struct S { |
| // typedef struct A { } A; |
| // }; |
| // |
| // in the C++03 standard. We implement the C++0x semantics, which |
| // allow the above but disallow |
| // |
| // struct S { |
| // typedef int I; |
| // typedef int I; |
| // }; |
| // |
| // since that was the intent of DR56. |
| if (!isa<TypedefNameDecl>(Old)) |
| return; |
| |
| Diag(New->getLocation(), diag::err_redefinition) |
| << New->getDeclName(); |
| Diag(Old->getLocation(), diag::note_previous_definition); |
| 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 |
| // in a system header, don't emit this for compatibility with GCC. |
| if (getDiagnostics().getSuppressSystemWarnings() && |
| (Context.getSourceManager().isInSystemHeader(Old->getLocation()) || |
| Context.getSourceManager().isInSystemHeader(New->getLocation()))) |
| return; |
| |
| Diag(New->getLocation(), diag::warn_redefinition_of_typedef) |
| << New->getDeclName(); |
| Diag(Old->getLocation(), diag::note_previous_definition); |
| return; |
| } |
| |
| /// DeclhasAttr - returns true if decl Declaration already has the target |
| /// attribute. |
| static bool DeclHasAttr(const Decl *D, const Attr *A) { |
| const OwnershipAttr *OA = dyn_cast<OwnershipAttr>(A); |
| const AnnotateAttr *Ann = dyn_cast<AnnotateAttr>(A); |
| for (const auto *i : D->attrs()) |
| if (i->getKind() == A->getKind()) { |
| if (Ann) { |
| if (Ann->getAnnotation() == cast<AnnotateAttr>(i)->getAnnotation()) |
| return true; |
| continue; |
| } |
| // FIXME: Don't hardcode this check |
| if (OA && isa<OwnershipAttr>(i)) |
| return OA->getOwnKind() == cast<OwnershipAttr>(i)->getOwnKind(); |
| return true; |
| } |
| |
| return false; |
| } |
| |
| static bool isAttributeTargetADefinition(Decl *D) { |
| if (VarDecl *VD = dyn_cast<VarDecl>(D)) |
| return VD->isThisDeclarationADefinition(); |
| if (TagDecl *TD = dyn_cast<TagDecl>(D)) |
| return TD->isCompleteDefinition() || TD->isBeingDefined(); |
| return true; |
| } |
| |
| /// Merge alignment attributes from \p Old to \p New, taking into account the |
| /// special semantics of C11's _Alignas specifier and C++11's alignas attribute. |
| /// |
| /// \return \c true if any attributes were added to \p New. |
| static bool mergeAlignedAttrs(Sema &S, NamedDecl *New, Decl *Old) { |
| // Look for alignas attributes on Old, and pick out whichever attribute |
| // specifies the strictest alignment requirement. |
| AlignedAttr *OldAlignasAttr = 0; |
| AlignedAttr *OldStrictestAlignAttr = 0; |
| unsigned OldAlign = 0; |
| for (auto *I : Old->specific_attrs<AlignedAttr>()) { |
| // FIXME: We have no way of representing inherited dependent alignments |
| // in a case like: |
| // template<int A, int B> struct alignas(A) X; |
| // template<int A, int B> struct alignas(B) X {}; |
| // For now, we just ignore any alignas attributes which are not on the |
| // definition in such a case. |
| if (I->isAlignmentDependent()) |
| return false; |
| |
| if (I->isAlignas()) |
| OldAlignasAttr = I; |
| |
| unsigned Align = I->getAlignment(S.Context); |
| if (Align > OldAlign) { |
| OldAlign = Align; |
| OldStrictestAlignAttr = I; |
| } |
| } |
| |
| // Look for alignas attributes on New. |
| AlignedAttr *NewAlignasAttr = 0; |
| unsigned NewAlign = 0; |
| for (auto *I : New->specific_attrs<AlignedAttr>()) { |
| if (I->isAlignmentDependent()) |
| return false; |
| |
| if (I->isAlignas()) |
| NewAlignasAttr = I; |
| |
| unsigned Align = I->getAlignment(S.Context); |
| if (Align > NewAlign) |
| NewAlign = Align; |
| } |
| |
| if (OldAlignasAttr && NewAlignasAttr && OldAlign != NewAlign) { |
| // Both declarations have 'alignas' attributes. We require them to match. |
| // C++11 [dcl.align]p6 and C11 6.7.5/7 both come close to saying this, but |
| // fall short. (If two declarations both have alignas, they must both match |
| // every definition, and so must match each other if there is a definition.) |
| |
| // If either declaration only contains 'alignas(0)' specifiers, then it |
| // specifies the natural alignment for the type. |
| if (OldAlign == 0 || NewAlign == 0) { |
| QualType Ty; |
| if (ValueDecl *VD = dyn_cast<ValueDecl>(New)) |
| Ty = VD->getType(); |
| else |
| Ty = S.Context.getTagDeclType(cast<TagDecl>(New)); |
| |
| if (OldAlign == 0) |
| OldAlign = S.Context.getTypeAlign(Ty); |
| if (NewAlign == 0) |
| NewAlign = S.Context.getTypeAlign(Ty); |
| } |
| |
| if (OldAlign != NewAlign) { |
| S.Diag(NewAlignasAttr->getLocation(), diag::err_alignas_mismatch) |
| << (unsigned)S.Context.toCharUnitsFromBits(OldAlign).getQuantity() |
| << (unsigned)S.Context.toCharUnitsFromBits(NewAlign).getQuantity(); |
| S.Diag(OldAlignasAttr->getLocation(), diag::note_previous_declaration); |
| } |
| } |
| |
| if (OldAlignasAttr && !NewAlignasAttr && isAttributeTargetADefinition(New)) { |
| // C++11 [dcl.align]p6: |
| // if any declaration of an entity has an alignment-specifier, |
| // every defining declaration of that entity shall specify an |
| // equivalent alignment. |
| // C11 6.7.5/7: |
| // If the definition of an object does not have an alignment |
| // specifier, any other declaration of that object shall also |
| // have no alignment specifier. |
| S.Diag(New->getLocation(), diag::err_alignas_missing_on_definition) |
| << OldAlignasAttr; |
| S.Diag(OldAlignasAttr->getLocation(), diag::note_alignas_on_declaration) |
| << OldAlignasAttr; |
| } |
| |
| bool AnyAdded = false; |
| |
| // Ensure we have an attribute representing the strictest alignment. |
| if (OldAlign > NewAlign) { |
| AlignedAttr *Clone = OldStrictestAlignAttr->clone(S.Context); |
| Clone->setInherited(true); |
| New->addAttr(Clone); |
| AnyAdded = true; |
| } |
| |
| // Ensure we have an alignas attribute if the old declaration had one. |
| if (OldAlignasAttr && !NewAlignasAttr && |
| !(AnyAdded && OldStrictestAlignAttr->isAlignas())) { |
| AlignedAttr *Clone = OldAlignasAttr->clone(S.Context); |
| Clone->setInherited(true); |
| New->addAttr(Clone); |
| AnyAdded = true; |
| } |
| |
| return AnyAdded; |
| } |
| |
| static bool mergeDeclAttribute(Sema &S, NamedDecl *D, |
| const InheritableAttr *Attr, bool Override) { |
| InheritableAttr *NewAttr = nullptr; |
| unsigned AttrSpellingListIndex = Attr->getSpellingListIndex(); |
| if (const auto *AA = dyn_cast<AvailabilityAttr>(Attr)) |
| NewAttr = S.mergeAvailabilityAttr(D, AA->getRange(), AA->getPlatform(), |
| AA->getIntroduced(), AA->getDeprecated(), |
| AA->getObsoleted(), AA->getUnavailable(), |
| AA->getMessage(), Override, |
| AttrSpellingListIndex); |
| else if (const auto *VA = dyn_cast<VisibilityAttr>(Attr)) |
| NewAttr = S.mergeVisibilityAttr(D, VA->getRange(), VA->getVisibility(), |
| AttrSpellingListIndex); |
| else if (const auto *VA = dyn_cast<TypeVisibilityAttr>(Attr)) |
| NewAttr = S.mergeTypeVisibilityAttr(D, VA->getRange(), VA->getVisibility(), |
| AttrSpellingListIndex); |
| else if (const auto *ImportA = dyn_cast<DLLImportAttr>(Attr)) |
| NewAttr = S.mergeDLLImportAttr(D, ImportA->getRange(), |
| AttrSpellingListIndex); |
| else if (const auto *ExportA = dyn_cast<DLLExportAttr>(Attr)) |
| NewAttr = S.mergeDLLExportAttr(D, ExportA->getRange(), |
| AttrSpellingListIndex); |
| else if (const auto *FA = dyn_cast<FormatAttr>(Attr)) |
| NewAttr = S.mergeFormatAttr(D, FA->getRange(), FA->getType(), |
| FA->getFormatIdx(), FA->getFirstArg(), |
| AttrSpellingListIndex); |
| else if (const auto *SA = dyn_cast<SectionAttr>(Attr)) |
| NewAttr = S.mergeSectionAttr(D, SA->getRange(), SA->getName(), |
| AttrSpellingListIndex); |
| else if (const auto *IA = dyn_cast<MSInheritanceAttr>(Attr)) |
| NewAttr = S.mergeMSInheritanceAttr(D, IA->getRange(), IA->getBestCase(), |
| AttrSpellingListIndex, |
| IA->getSemanticSpelling()); |
| else if (isa<AlignedAttr>(Attr)) |
| // AlignedAttrs are handled separately, because we need to handle all |
| // such attributes on a declaration at the same time. |
| NewAttr = nullptr; |
| else if (Attr->duplicatesAllowed() || !DeclHasAttr(D, Attr)) |
| NewAttr = cast<InheritableAttr>(Attr->clone(S.Context)); |
| |
| if (NewAttr) { |
| NewAttr->setInherited(true); |
| D->addAttr(NewAttr); |
| return true; |
| } |
| |
| return false; |
| } |
| |
| static const Decl *getDefinition(const Decl *D) { |
| if (const TagDecl *TD = dyn_cast<TagDecl>(D)) |
| return TD->getDefinition(); |
| if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { |
| const VarDecl *Def = VD->getDefinition(); |
| if (Def) |
| return Def; |
| return VD->getActingDefinition(); |
| } |
| if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { |
| const FunctionDecl* Def; |
| if (FD->isDefined(Def)) |
| return Def; |
| } |
| return NULL; |
| } |
| |
| static bool hasAttribute(const Decl *D, attr::Kind Kind) { |
| for (const auto *Attribute : D->attrs()) |
| if (Attribute->getKind() == Kind) |
| return true; |
| return false; |
| } |
| |
| /// checkNewAttributesAfterDef - If we already have a definition, check that |
| /// there are no new attributes in this declaration. |
| static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) { |
| if (!New->hasAttrs()) |
| return; |
| |
| const Decl *Def = getDefinition(Old); |
| if (!Def || Def == New) |
| return; |
| |
| AttrVec &NewAttributes = New->getAttrs(); |
| for (unsigned I = 0, E = NewAttributes.size(); I != E;) { |
| const Attr *NewAttribute = NewAttributes[I]; |
| |
| if (isa<AliasAttr>(NewAttribute)) { |
| if (FunctionDecl *FD = dyn_cast<FunctionDecl>(New)) |
| S.CheckForFunctionRedefinition(FD, cast<FunctionDecl>(Def)); |
| else { |
| VarDecl *VD = cast<VarDecl>(New); |
| unsigned Diag = cast<VarDecl>(Def)->isThisDeclarationADefinition() == |
| VarDecl::TentativeDefinition |
| ? diag::err_alias_after_tentative |
| : diag::err_redefinition; |
| S.Diag(VD->getLocation(), Diag) << VD->getDeclName(); |
| S.Diag(Def->getLocation(), diag::note_previous_definition); |
| VD->setInvalidDecl(); |
| } |
| ++I; |
| continue; |
| } |
| |
| if (const VarDecl *VD = dyn_cast<VarDecl>(Def)) { |
| // Tentative definitions are only interesting for the alias check above. |
| if (VD->isThisDeclarationADefinition() != VarDecl::Definition) { |
| ++I; |
| continue; |
| } |
| } |
| |
| if (hasAttribute(Def, NewAttribute->getKind())) { |
| ++I; |
| continue; // regular attr merging will take care of validating this. |
| } |
| |
| if (isa<C11NoReturnAttr>(NewAttribute)) { |
| // C's _Noreturn is allowed to be added to a function after it is defined. |
| ++I; |
| continue; |
| } else if (const AlignedAttr *AA = dyn_cast<AlignedAttr>(NewAttribute)) { |
| if (AA->isAlignas()) { |
| // C++11 [dcl.align]p6: |
| // if any declaration of an entity has an alignment-specifier, |
| // every defining declaration of that entity shall specify an |
| // equivalent alignment. |
| // C11 6.7.5/7: |
| // If the definition of an object does not have an alignment |
| // specifier, any other declaration of that object shall also |
| // have no alignment specifier. |
| S.Diag(Def->getLocation(), diag::err_alignas_missing_on_definition) |
| << AA; |
| S.Diag(NewAttribute->getLocation(), diag::note_alignas_on_declaration) |
| << AA; |
| NewAttributes.erase(NewAttributes.begin() + I); |
| --E; |
| continue; |
| } |
| } |
| |
| S.Diag(NewAttribute->getLocation(), |
| diag::warn_attribute_precede_definition); |
| S.Diag(Def->getLocation(), diag::note_previous_definition); |
| NewAttributes.erase(NewAttributes.begin() + I); |
| --E; |
| } |
| } |
| |
| /// mergeDeclAttributes - Copy attributes from the Old decl to the New one. |
| void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old, |
| AvailabilityMergeKind AMK) { |
| if (UsedAttr *OldAttr = Old->getMostRecentDecl()->getAttr<UsedAttr>()) { |
| UsedAttr *NewAttr = OldAttr->clone(Context); |
| NewAttr->setInherited(true); |
| New->addAttr(NewAttr); |
| } |
| |
| if (!Old->hasAttrs() && !New->hasAttrs()) |
| return; |
| |
| // attributes declared post-definition are currently ignored |
| checkNewAttributesAfterDef(*this, New, Old); |
| |
| if (!Old->hasAttrs()) |
| return; |
| |
| bool foundAny = New->hasAttrs(); |
| |
| // Ensure that any moving of objects within the allocated map is done before |
| // we process them. |
| if (!foundAny) New->setAttrs(AttrVec()); |
| |
| for (auto *I : Old->specific_attrs<InheritableAttr>()) { |
| bool Override = false; |
| // Ignore deprecated/unavailable/availability attributes if requested. |
| if (isa<DeprecatedAttr>(I) || |
| isa<UnavailableAttr>(I) || |
| isa<AvailabilityAttr>(I)) { |
| switch (AMK) { |
| case AMK_None: |
| continue; |
| |
| case AMK_Redeclaration: |
| break; |
| |
| case AMK_Override: |
| Override = true; |
| break; |
| } |
| } |
| |
| // Already handled. |
| if (isa<UsedAttr>(I)) |
| continue; |
| |
| if (mergeDeclAttribute(*this, New, I, Override)) |
| foundAny = true; |
| } |
| |
| if (mergeAlignedAttrs(*this, New, Old)) |
| foundAny = true; |
| |
| if (!foundAny) New->dropAttrs(); |
| } |
| |
| /// mergeParamDeclAttributes - Copy attributes from the old parameter |
| /// to the new one. |
| static void mergeParamDeclAttributes(ParmVarDecl *newDecl, |
| const ParmVarDecl *oldDecl, |
| Sema &S) { |
| // C++11 [dcl.attr.depend]p2: |
| // The first declaration of a function shall specify the |
| // carries_dependency attribute for its declarator-id if any declaration |
| // of the function specifies the carries_dependency attribute. |
| const CarriesDependencyAttr *CDA = newDecl->getAttr<CarriesDependencyAttr>(); |
| if (CDA && !oldDecl->hasAttr<CarriesDependencyAttr>()) { |
| S.Diag(CDA->getLocation(), |
| diag::err_carries_dependency_missing_on_first_decl) << 1/*Param*/; |
| // Find the first declaration of the parameter. |
| // FIXME: Should we build redeclaration chains for function parameters? |
| const FunctionDecl *FirstFD = |
| cast<FunctionDecl>(oldDecl->getDeclContext())->getFirstDecl(); |
| const ParmVarDecl *FirstVD = |
| FirstFD->getParamDecl(oldDecl->getFunctionScopeIndex()); |
| S.Diag(FirstVD->getLocation(), |
| diag::note_carries_dependency_missing_first_decl) << 1/*Param*/; |
| } |
| |
| if (!oldDecl->hasAttrs()) |
| return; |
| |
| bool foundAny = newDecl->hasAttrs(); |
| |
| // Ensure that any moving of objects within the allocated map is |
| // done before we process them. |
| if (!foundAny) newDecl->setAttrs(AttrVec()); |
| |
| for (const auto *I : oldDecl->specific_attrs<InheritableParamAttr>()) { |
| if (!DeclHasAttr(newDecl, I)) { |
| InheritableAttr *newAttr = |
| cast<InheritableParamAttr>(I->clone(S.Context)); |
| newAttr->setInherited(true); |
| newDecl->addAttr(newAttr); |
| foundAny = true; |
| } |
| } |
| |
| if (!foundAny) newDecl->dropAttrs(); |
| } |
| |
| namespace { |
| |
| /// Used in MergeFunctionDecl to keep track of function parameters in |
| /// C. |
| struct GNUCompatibleParamWarning { |
| ParmVarDecl *OldParm; |
| ParmVarDecl *NewParm; |
| QualType PromotedType; |
| }; |
| |
| } |
| |
| /// getSpecialMember - get the special member enum for a method. |
| Sema::CXXSpecialMember Sema::getSpecialMember(const CXXMethodDecl *MD) { |
| if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(MD)) { |
| if (Ctor->isDefaultConstructor()) |
| return Sema::CXXDefaultConstructor; |
| |
| if (Ctor->isCopyConstructor()) |
| return Sema::CXXCopyConstructor; |
| |
| if (Ctor->isMoveConstructor()) |
| return Sema::CXXMoveConstructor; |
| } else if (isa<CXXDestructorDecl>(MD)) { |
| return Sema::CXXDestructor; |
| } else if (MD->isCopyAssignmentOperator()) { |
| return Sema::CXXCopyAssignment; |
| } else if (MD->isMoveAssignmentOperator()) { |
| return Sema::CXXMoveAssignment; |
| } |
| |
| return Sema::CXXInvalid; |
| } |
| |
| /// canRedefineFunction - checks if a function can be redefined. Currently, |
| /// only extern inline functions can be redefined, and even then only in |
| /// GNU89 mode. |
| static bool canRedefineFunction(const FunctionDecl *FD, |
| const LangOptions& LangOpts) { |
| return ((FD->hasAttr<GNUInlineAttr>() || LangOpts.GNUInline) && |
| !LangOpts.CPlusPlus && |
| FD->isInlineSpecified() && |
| FD->getStorageClass() == SC_Extern); |
| } |
| |
| const AttributedType *Sema::getCallingConvAttributedType(QualType T) const { |
| const AttributedType *AT = T->getAs<AttributedType>(); |
| while (AT && !AT->isCallingConv()) |
| AT = AT->getModifiedType()->getAs<AttributedType>(); |
| return AT; |
| } |
| |
| template <typename T> |
| static bool haveIncompatibleLanguageLinkages(const T *Old, const T *New) { |
| const DeclContext *DC = Old->getDeclContext(); |
| if (DC->isRecord()) |
| return false; |
| |
| LanguageLinkage OldLinkage = Old->getLanguageLinkage(); |
| if (OldLinkage == CXXLanguageLinkage && New->isInExternCContext()) |
| return true; |
| if (OldLinkage == CLanguageLinkage && New->isInExternCXXContext()) |
| return true; |
| return false; |
| } |
| |
| /// MergeFunctionDecl - We just parsed a function 'New' from |
| /// declarator D which has the same name and scope as a previous |
| /// declaration 'Old'. Figure out how to resolve this situation, |
| /// merging decls or emitting diagnostics as appropriate. |
| /// |
| /// In C++, New and Old must be declarations that are not |
| /// overloaded. Use IsOverload to determine whether New and Old are |
| /// overloaded, and to select the Old declaration that New should be |
| /// merged with. |
| /// |
| /// Returns true if there was an error, false otherwise. |
| bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD, |
| Scope *S, bool MergeTypeWithOld) { |
| // Verify the old decl was also a function. |
| FunctionDecl *Old = OldD->getAsFunction(); |
| if (!Old) { |
| if (UsingShadowDecl *Shadow = dyn_cast<UsingShadowDecl>(OldD)) { |
| if (New->getFriendObjectKind()) { |
| Diag(New->getLocation(), diag::err_using_decl_friend); |
| Diag(Shadow->getTargetDecl()->getLocation(), |
| diag::note_using_decl_target); |
| Diag(Shadow->getUsingDecl()->getLocation(), |
| diag::note_using_decl) << 0; |
| return true; |
| } |
| |
| // C++11 [namespace.udecl]p14: |
| // If a function declaration in namespace scope or block scope has the |
| // same name and the same parameter-type-list as a function introduced |
| // by a using-declaration, and the declarations do not declare the same |
| // function, the program is ill-formed. |
| |
| // Check whether the two declarations might declare the same function. |
| Old = dyn_cast<FunctionDecl>(Shadow->getTargetDecl()); |
| if (Old && |
| !Old->getDeclContext()->getRedeclContext()->Equals( |
| New->getDeclContext()->getRedeclContext()) && |
| !(Old->isExternC() && New->isExternC())) |
| Old = 0; |
| |
| if (!Old) { |
| Diag(New->getLocation(), diag::err_using_decl_conflict_reverse); |
| Diag(Shadow->getTargetDecl()->getLocation(), |
| diag::note_using_decl_target); |
| Diag(Shadow->getUsingDecl()->getLocation(), diag::note_using_decl) << 0; |
| return true; |
| } |
| OldD = Old; |
| } else { |
| Diag(New->getLocation(), diag::err_redefinition_different_kind) |
| << New->getDeclName(); |
| Diag(OldD->getLocation(), diag::note_previous_definition); |
| return true; |
| } |
| } |
| |
| // If the old declaration is invalid, just give up here. |
| if (Old->isInvalidDecl()) |
| return true; |
| |
| // Determine whether the previous declaration was a definition, |
| // implicit declaration, or a declaration. |
| diag::kind PrevDiag; |
| SourceLocation OldLocation = Old->getLocation(); |
| if (Old->isThisDeclarationADefinition()) |
| PrevDiag = diag::note_previous_definition; |
| else if (Old->isImplicit()) { |
| PrevDiag = diag::note_previous_implicit_declaration; |
| if (OldLocation.isInvalid()) |
| OldLocation = New->getLocation(); |
| } else |
| PrevDiag = diag::note_previous_declaration; |
| |
| // Don't complain about this if we're in GNU89 mode and the old function |
| // is an extern inline function. |
| // Don't complain about specializations. They are not supposed to have |
| // storage classes. |
| if (!isa<CXXMethodDecl>(New) && !isa<CXXMethodDecl>(Old) && |
| New->getStorageClass() == SC_Static && |
| Old->hasExternalFormalLinkage() && |
| !New->getTemplateSpecializationInfo() && |
| !canRedefineFunction(Old, getLangOpts())) { |
| if (getLangOpts().MicrosoftExt) { |
| Diag(New->getLocation(), diag::warn_static_non_static) << New; |
| Diag(OldLocation, PrevDiag); |
| } else { |
| Diag(New->getLocation(), diag::err_static_non_static) << New; |
| Diag(OldLocation, PrevDiag); |
| return true; |
| } |
| } |
| |
| |
| // If a function is first declared with a calling convention, but is later |
| // declared or defined without one, all following decls assume the calling |
| // convention of the first. |
| // |
| // It's OK if a function is first declared without a calling convention, |
| // but is later declared or defined with the default calling convention. |
| // |
| // To test if either decl has an explicit calling convention, we look for |
| // AttributedType sugar nodes on the type as written. If they are missing or |
| // were canonicalized away, we assume the calling convention was implicit. |
| // |
| // Note also that we DO NOT return at this point, because we still have |
| // other tests to run. |
| QualType OldQType = Context.getCanonicalType(Old->getType()); |
| QualType NewQType = Context.getCanonicalType(New->getType()); |
| const FunctionType *OldType = cast<FunctionType>(OldQType); |
| const FunctionType *NewType = cast<FunctionType>(NewQType); |
| FunctionType::ExtInfo OldTypeInfo = OldType->getExtInfo(); |
| FunctionType::ExtInfo NewTypeInfo = NewType->getExtInfo(); |
| bool RequiresAdjustment = false; |
| |
| if (OldTypeInfo.getCC() != NewTypeInfo.getCC()) { |
| FunctionDecl *First = Old->getFirstDecl(); |
| const FunctionType *FT = |
| First->getType().getCanonicalType()->castAs<FunctionType>(); |
| FunctionType::ExtInfo FI = FT->getExtInfo(); |
| bool NewCCExplicit = getCallingConvAttributedType(New->getType()); |
| if (!NewCCExplicit) { |
| // Inherit the CC from the previous declaration if it was specified |
| // there but not here. |
| NewTypeInfo = NewTypeInfo.withCallingConv(OldTypeInfo.getCC()); |
| RequiresAdjustment = true; |
| } else { |
| // Calling conventions aren't compatible, so complain. |
| bool FirstCCExplicit = getCallingConvAttributedType(First->getType()); |
| Diag(New->getLocation(), diag::err_cconv_change) |
| << FunctionType::getNameForCallConv(NewTypeInfo.getCC()) |
| << !FirstCCExplicit |
| << (!FirstCCExplicit ? "" : |
| FunctionType::getNameForCallConv(FI.getCC())); |
| |
| // Put the note on the first decl, since it is the one that matters. |
| Diag(First->getLocation(), diag::note_previous_declaration); |
| return true; |
| } |
| } |
| |
| // FIXME: diagnose the other way around? |
| if (OldTypeInfo.getNoReturn() && !NewTypeInfo.getNoReturn()) { |
| NewTypeInfo = NewTypeInfo.withNoReturn(true); |
| RequiresAdjustment = true; |
| } |
| |
| // Merge regparm attribute. |
| if (OldTypeInfo.getHasRegParm() != NewTypeInfo.getHasRegParm() || |
| OldTypeInfo.getRegParm() != NewTypeInfo.getRegParm()) { |
| if (NewTypeInfo.getHasRegParm()) { |
| Diag(New->getLocation(), diag::err_regparm_mismatch) |
| << NewType->getRegParmType() |
| << OldType->getRegParmType(); |
| Diag(OldLocation, diag::note_previous_declaration); |
| return true; |
| } |
| |
| NewTypeInfo = NewTypeInfo.withRegParm(OldTypeInfo.getRegParm()); |
| RequiresAdjustment = true; |
| } |
| |
| // Merge ns_returns_retained attribute. |
| if (OldTypeInfo.getProducesResult() != NewTypeInfo.getProducesResult()) { |
| if (NewTypeInfo.getProducesResult()) { |
| Diag(New->getLocation(), diag::err_returns_retained_mismatch); |
| Diag(OldLocation, diag::note_previous_declaration); |
| return true; |
| } |
| |
| NewTypeInfo = NewTypeInfo.withProducesResult(true); |
| RequiresAdjustment = true; |
| } |
| |
| if (RequiresAdjustment) { |
| const FunctionType *AdjustedType = New->getType()->getAs<FunctionType>(); |
| AdjustedType = Context.adjustFunctionType(AdjustedType, NewTypeInfo); |
| New->setType(QualType(AdjustedType, 0)); |
| NewQType = Context.getCanonicalType(New->getType()); |
| NewType = cast<FunctionType>(NewQType); |
| } |
| |
| // If this redeclaration makes the function inline, we may need to add it to |
| // UndefinedButUsed. |
| if (!Old->isInlined() && New->isInlined() && |
| !New->hasAttr<GNUInlineAttr>() && |
| (getLangOpts().CPlusPlus || !getLangOpts().GNUInline) && |
| Old->isUsed(false) && |
| !Old->isDefined() && !New->isThisDeclarationADefinition()) |
| UndefinedButUsed.insert(std::make_pair(Old->getCanonicalDecl(), |
| SourceLocation())); |
| |
| // If this redeclaration makes it newly gnu_inline, we don't want to warn |
| // about it. |
| if (New->hasAttr<GNUInlineAttr>() && |
| Old->isInlined() && !Old->hasAttr<GNUInlineAttr>()) { |
| UndefinedButUsed.erase(Old->getCanonicalDecl()); |
| } |
| |
| if (getLangOpts().CPlusPlus) { |
| // (C++98 13.1p2): |
| // Certain function declarations cannot be overloaded: |
| // -- Function declarations that differ only in the return type |
| // cannot be overloaded. |
| |
| // Go back to the type source info to compare the declared return types, |
| // per C++1y [dcl.type.auto]p13: |
| // Redeclarations or specializations of a function or function template |
| // with a declared return type that uses a placeholder type shall also |
| // use that placeholder, not a deduced type. |
| QualType OldDeclaredReturnType = |
| (Old->getTypeSourceInfo() |
| ? Old->getTypeSourceInfo()->getType()->castAs<FunctionType>() |
| : OldType)->getReturnType(); |
| QualType NewDeclaredReturnType = |
| (New->getTypeSourceInfo() |
| ? New->getTypeSourceInfo()->getType()->castAs<FunctionType>() |
| : NewType)->getReturnType(); |
| QualType ResQT; |
| if (!Context.hasSameType(OldDeclaredReturnType, NewDeclaredReturnType) && |
| !((NewQType->isDependentType() || OldQType->isDependentType()) && |
| New->isLocalExternDecl())) { |
| if (NewDeclaredReturnType->isObjCObjectPointerType() && |
| OldDeclaredReturnType->isObjCObjectPointerType()) |
| ResQT = Context.mergeObjCGCQualifiers(NewQType, OldQType); |
| if (ResQT.isNull()) { |
| if (New->isCXXClassMember() && New->isOutOfLine()) |
| Diag(New->getLocation(), |
| diag::err_member_def_does_not_match_ret_type) << New; |
| else |
| Diag(New->getLocation(), diag::err_ovl_diff_return_type); |
| Diag(OldLocation, PrevDiag) << Old << Old->getType(); |
| return true; |
| } |
| else |
| NewQType = ResQT; |
| } |
| |
| QualType OldReturnType = OldType->getReturnType(); |
| QualType NewReturnType = cast<FunctionType>(NewQType)->getReturnType(); |
| if (OldReturnType != NewReturnType) { |
| // If this function has a deduced return type and has already been |
| // defined, copy the deduced value from the old declaration. |
| AutoType *OldAT = Old->getReturnType()->getContainedAutoType(); |
| if (OldAT && OldAT->isDeduced()) { |
| New->setType( |
| SubstAutoType(New->getType(), |
| OldAT->isDependentType() ? Context.DependentTy |
| : OldAT->getDeducedType())); |
| NewQType = Context.getCanonicalType( |
| SubstAutoType(NewQType, |
| OldAT->isDependentType() ? Context.DependentTy |
| : OldAT->getDeducedType())); |
| } |
| } |
| |
| const CXXMethodDecl *OldMethod = dyn_cast<CXXMethodDecl>(Old); |
| CXXMethodDecl *NewMethod = dyn_cast<CXXMethodDecl>(New); |
| if (OldMethod && NewMethod) { |
| // Preserve triviality. |
| NewMethod->setTrivial(OldMethod->isTrivial()); |
| |
| // MSVC allows explicit template specialization at class scope: |
| // 2 CXXMethodDecls referring to the same function will be injected. |
| // We don't want a redeclaration error. |
| bool IsClassScopeExplicitSpecialization = |
| OldMethod->isFunctionTemplateSpecialization() && |
| NewMethod->isFunctionTemplateSpecialization(); |
| bool isFriend = NewMethod->getFriendObjectKind(); |
| |
| if (!isFriend && NewMethod->getLexicalDeclContext()->isRecord() && |
| !IsClassScopeExplicitSpecialization) { |
| // -- Member function declarations with the same name and the |
| // same parameter types cannot be overloaded if any of them |
| // is a static member function declaration. |
| if (OldMethod->isStatic() != NewMethod->isStatic()) { |
| Diag(New->getLocation(), diag::err_ovl_static_nonstatic_member); |
| Diag(OldLocation, PrevDiag) << Old << Old->getType(); |
| return true; |
| } |
| |
| // C++ [class.mem]p1: |
| // [...] A member shall not be declared twice in the |
| // member-specification, except that a nested class or member |
| // class template can be declared and then later defined. |
| if (ActiveTemplateInstantiations.empty()) { |
| unsigned NewDiag; |
| if (isa<CXXConstructorDecl>(OldMethod)) |
| NewDiag = diag::err_constructor_redeclared; |
| else if (isa<CXXDestructorDecl>(NewMethod)) |
| NewDiag = diag::err_destructor_redeclared; |
| else if (isa<CXXConversionDecl>(NewMethod)) |
| NewDiag = diag::err_conv_function_redeclared; |
| else |
| NewDiag = diag::err_member_redeclared; |
| |
| Diag(New->getLocation(), NewDiag); |
| } else { |
| Diag(New->getLocation(), diag::err_member_redeclared_in_instantiation) |
| << New << New->getType(); |
| } |
| Diag(OldLocation, PrevDiag) << Old << Old->getType(); |
| |
| // Complain if this is an explicit declaration of a special |
| // member that was initially declared implicitly. |
| // |
| // As an exception, it's okay to befriend such methods in order |
| // to permit the implicit constructor/destructor/operator calls. |
| } else if (OldMethod->isImplicit()) { |
| if (isFriend) { |
| NewMethod->setImplicit(); |
| } else { |
| Diag(NewMethod->getLocation(), |
| diag::err_definition_of_implicitly_declared_member) |
| << New << getSpecialMember(OldMethod); |
| return true; |
| } |
| } else if (OldMethod->isExplicitlyDefaulted() && !isFriend) { |
| Diag(NewMethod->getLocation(), |
| diag::err_definition_of_explicitly_defaulted_member) |
| << getSpecialMember(OldMethod); |
| return true; |
| } |
| } |
| |
| // C++11 [dcl.attr.noreturn]p1: |
| // The first declaration of a function shall specify the noreturn |
| // attribute if any declaration of that function specifies the noreturn |
| // attribute. |
| const CXX11NoReturnAttr *NRA = New->getAttr<CXX11NoReturnAttr>(); |
| if (NRA && !Old->hasAttr<CXX11NoReturnAttr>()) { |
| Diag(NRA->getLocation(), diag::err_noreturn_missing_on_first_decl); |
| Diag(Old->getFirstDecl()->getLocation(), |
| diag::note_noreturn_missing_first_decl); |
| } |
| |
| // C++11 [dcl.attr.depend]p2: |
| // The first declaration of a function shall specify the |
| // carries_dependency attribute for its declarator-id if any declaration |
| // of the function specifies the carries_dependency attribute. |
| const CarriesDependencyAttr *CDA = New->getAttr<CarriesDependencyAttr>(); |
| if (CDA && !Old->hasAttr<CarriesDependencyAttr>()) { |
| Diag(CDA->getLocation(), |
| diag::err_carries_dependency_missing_on_first_decl) << 0/*Function*/; |
| Diag(Old->getFirstDecl()->getLocation(), |
| diag::note_carries_dependency_missing_first_decl) << 0/*Function*/; |
| } |
| |
| // (C++98 8.3.5p3): |
| // All declarations for a function shall agree exactly in both the |
| // return type and the parameter-type-list. |
| // We also want to respect all the extended bits except noreturn. |
| |
| // noreturn should now match unless the old type info didn't have it. |
| QualType OldQTypeForComparison = OldQType; |
| if (!OldTypeInfo.getNoReturn() && NewTypeInfo.getNoReturn()) { |
| assert(OldQType == QualType(OldType, 0)); |
| const FunctionType *OldTypeForComparison |
| = Context.adjustFunctionType(OldType, OldTypeInfo.withNoReturn(true)); |
| OldQTypeForComparison = QualType(OldTypeForComparison, 0); |
| assert(OldQTypeForComparison.isCanonical()); |
| } |
| |
| if (haveIncompatibleLanguageLinkages(Old, New)) { |
| // As a special case, retain the language linkage from previous |
| // declarations of a friend function as an extension. |
| // |
| // This liberal interpretation of C++ [class.friend]p3 matches GCC/MSVC |
| // and is useful because there's otherwise no way to specify language |
| // linkage within class scope. |
| // |
| // Check cautiously as the friend object kind isn't yet complete. |
| if (New->getFriendObjectKind() != Decl::FOK_None) { |
| Diag(New->getLocation(), diag::ext_retained_language_linkage) << New; |
| Diag(OldLocation, PrevDiag); |
| } else { |
| Diag(New->getLocation(), diag::err_different_language_linkage) << New; |
| Diag(OldLocation, PrevDiag); |
| return true; |
| } |
| } |
| |
| if (OldQTypeForComparison == NewQType) |
| return MergeCompatibleFunctionDecls(New, Old, S, MergeTypeWithOld); |
| |
| if ((NewQType->isDependentType() || OldQType->isDependentType()) && |
| New->isLocalExternDecl()) { |
| // It's OK if we couldn't merge types for a local function declaraton |
| // if either the old or new type is dependent. We'll merge the types |
| // when we instantiate the function. |
| return false; |
| } |
| |
| // Fall through for conflicting redeclarations and redefinitions. |
| } |
| |
| // C: Function types need to be compatible, not identical. This handles |
| // duplicate function decls like "void f(int); void f(enum X);" properly. |
| if (!getLangOpts().CPlusPlus && |
| Context.typesAreCompatible(OldQType, NewQType)) { |
| const FunctionType *OldFuncType = OldQType->getAs<FunctionType>(); |
| const FunctionType *NewFuncType = NewQType->getAs<FunctionType>(); |
| const FunctionProtoType *OldProto = 0; |
| if (MergeTypeWithOld && isa<FunctionNoProtoType>(NewFuncType) && |
| (OldProto = dyn_cast<FunctionProtoType>(OldFuncType))) { |
| // The old declaration provided a function prototype, but the |
| // new declaration does not. Merge in the prototype. |
| assert(!OldProto->hasExceptionSpec() && "Exception spec in C"); |
| SmallVector<QualType, 16> ParamTypes(OldProto->param_types()); |
| NewQType = |
| Context.getFunctionType(NewFuncType->getReturnType(), ParamTypes, |
| OldProto->getExtProtoInfo()); |
| New->setType(NewQType); |
| New->setHasInheritedPrototype(); |
| |
| // Synthesize a parameter for each argument type. |
| SmallVector<ParmVarDecl*, 16> Params; |
| for (const auto &ParamType : OldProto->param_types()) { |
| ParmVarDecl *Param = ParmVarDecl::Create(Context, New, SourceLocation(), |
| SourceLocation(), 0, ParamType, |
| /*TInfo=*/0, SC_None, 0); |
| Param->setScopeInfo(0, Params.size()); |
| Param->setImplicit(); |
| Params.push_back(Param); |
| } |
| |
| New->setParams(Params); |
| } |
| |
| return MergeCompatibleFunctionDecls(New, Old, S, MergeTypeWithOld); |
| } |
| |
| // GNU C permits a K&R definition to follow a prototype declaration |
| // if the declared types of the parameters in the K&R definition |
| // match the types in the prototype declaration, even when the |
| // promoted types of the parameters from the K&R definition differ |
| // from the types in the prototype. GCC then keeps the types from |
| // the prototype. |
| // |
| // If a variadic prototype is followed by a non-variadic K&R definition, |
| // 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 (!getLangOpts().CPlusPlus && |
| Old->hasPrototype() && !New->hasPrototype() && |
| New->getType()->getAs<FunctionProtoType>() && |
| Old->getNumParams() == New->getNumParams()) { |
| SmallVector<QualType, 16> ArgTypes; |
| SmallVector<GNUCompatibleParamWarning, 16> Warnings; |
| const FunctionProtoType *OldProto |
| = Old->getType()->getAs<FunctionProtoType>(); |
| const FunctionProtoType *NewProto |
| = New->getType()->getAs<FunctionProtoType>(); |
| |
| // Determine whether this is the GNU C extension. |
| QualType MergedReturn = Context.mergeTypes(OldProto->getReturnType(), |
| NewProto->getReturnType()); |
| bool LooseCompatible = !MergedReturn.isNull(); |
| for (unsigned Idx = 0, End = Old->getNumParams(); |
| LooseCompatible && Idx != End; ++Idx) { |
| ParmVarDecl *OldParm = Old->getParamDecl(Idx); |
| ParmVarDecl *NewParm = New->getParamDecl(Idx); |
| if (Context.typesAreCompatible(OldParm->getType(), |
| NewProto->getParamType(Idx))) { |
| ArgTypes.push_back(NewParm->getType()); |
| } else if (Context.typesAreCompatible(OldParm->getType(), |
| NewParm->getType(), |
| /*CompareUnqualified=*/true)) { |
| GNUCompatibleParamWarning Warn = { OldParm, NewParm, |
| NewProto->getParamType(Idx) }; |
| Warnings.push_back(Warn); |
| ArgTypes.push_back(NewParm->getType()); |
| } else |
| LooseCompatible = false; |
| } |
| |
| if (LooseCompatible) { |
| for (unsigned Warn = 0; Warn < Warnings.size(); ++Warn) { |
| Diag(Warnings[Warn].NewParm->getLocation(), |
| diag::ext_param_promoted_not_compatible_with_prototype) |
| << Warnings[Warn].PromotedType |
| << Warnings[Warn].OldParm->getType(); |
| if (Warnings[Warn].OldParm->getLocation().isValid()) |
| Diag(Warnings[Warn].OldParm->getLocation(), |
| diag::note_previous_declaration); |
| } |
| |
| if (MergeTypeWithOld) |
| New->setType(Context.getFunctionType(MergedReturn, ArgTypes, |
| OldProto->getExtProtoInfo())); |
| return MergeCompatibleFunctionDecls(New, Old, S, MergeTypeWithOld); |
| } |
| |
| // Fall through to diagnose conflicting types. |
| } |
| |
| // A function that has already been declared has been redeclared or |
| // defined with a different type; show an appropriate diagnostic. |
| |
| // If the previous declaration was an implicitly-generated builtin |
| // declaration, then at the very least we should use a specialized note. |
| unsigned BuiltinID; |
| |