HELLO·Android
系统源代码
IT资讯
技术文章
我的收藏
注册
登录
-
我收藏的文章
创建代码块
我的代码块
我的账号
Lollipop
|
5.0.1_r1
下载
查看原文件
收藏
根目录
external
clang
lib
Sema
SemaDecl.cpp
//===--- 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/Builtins.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "clang/Lex/HeaderSearch.h" // TODO: Sema shouldn't depend on Lex #include "clang/Lex/Lexer.h" // TODO: Extract static functions to fix layering. #include "clang/Lex/ModuleLoader.h" // TODO: Sema shouldn't depend on Lex #include "clang/Lex/Preprocessor.h" // Included for isCodeCompletionEnabled() #include "clang/Parse/ParseDiagnostic.h" #include "clang/Sema/CXXFieldCollector.h" #include "clang/Sema/DeclSpec.h" #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
#include
#include
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
(ND) || isa
(ND); bool AllowedTemplate = AllowClassTemplates && isa
(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; } static ParsedType recoverFromTypeInKnownDependentBase(Sema &S, const IdentifierInfo &II, SourceLocation NameLoc) { // Find the first parent class template context, if any. // FIXME: Perform the lookup in all enclosing class templates. const CXXRecordDecl *RD = nullptr; for (DeclContext *DC = S.CurContext; DC; DC = DC->getParent()) { RD = dyn_cast
(DC); if (RD && RD->getDescribedClassTemplate()) break; } if (!RD) return ParsedType(); // Look for type decls in dependent base classes that have known primary // templates. bool FoundTypeDecl = false; for (const auto &Base : RD->bases()) { auto *TST = Base.getType()->getAs
(); if (!TST || !TST->isDependentType()) continue; auto *TD = TST->getTemplateName().getAsTemplateDecl(); if (!TD) continue; auto *BasePrimaryTemplate = cast
(TD->getTemplatedDecl()); // FIXME: Allow lookup into non-dependent bases of dependent bases, possibly // by calling or integrating with the main LookupQualifiedName mechanism. for (NamedDecl *ND : BasePrimaryTemplate->lookup(&II)) { if (FoundTypeDecl) return ParsedType(); FoundTypeDecl = isa
(ND); if (!FoundTypeDecl) return ParsedType(); } } if (!FoundTypeDecl) return ParsedType(); // We found some types in dependent base classes. Recover as if the user // wrote 'typename MyClass::II' instead of 'II'. We'll fully resolve the // lookup during template instantiation. S.Diag(NameLoc, diag::ext_found_via_dependent_bases_lookup) << &II; ASTContext &Context = S.Context; auto *NNS = NestedNameSpecifier::Create(Context, nullptr, false, cast
(Context.getRecordType(RD))); QualType T = Context.getDependentNameType(ETK_Typename, NNS, &II); CXXScopeSpec SS; SS.MakeTrivial(Context, NNS, SourceRange(NameLoc)); TypeLocBuilder Builder; DependentNameTypeLoc DepTL = Builder.push
(T); DepTL.setNameLoc(NameLoc); DepTL.setElaboratedKeywordLoc(SourceLocation()); DepTL.setQualifierLoc(SS.getWithLocInContext(Context)); return S.CreateParsedType(T, Builder.getTypeSourceInfo(Context, T)); } /// \brief If the identifier refers to a type name within this scope, /// return the declaration of that type. /// /// 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 = nullptr; 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); // For unqualified lookup in a class template in MSVC mode, look into // dependent base classes where the primary class template is known. if (Result.empty() && getLangOpts().MSVCCompat && (!SS || SS->isEmpty())) { if (ParsedType TypeInBase = recoverFromTypeInKnownDependentBase(*this, II, NameLoc)) return TypeInBase; } } NamedDecl *IIDecl = nullptr; switch (Result.getResultKind()) { case LookupResult::NotFound: case LookupResult::NotFoundInCurrentInstantiation: if (CorrectedII) { TypeNameValidatorCCC Validator(true, isClassName); TypoCorrection Correction = CorrectTypo(Result.getLookupNameInfo(), Kind, S, SS, Validator, 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
(*Res) || isa
(*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
(IIDecl)) { DiagnoseUseOfDecl(IIDecl, NameLoc); 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
(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
(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); } // Builds a fake NNS for the given decl context. static NestedNameSpecifier * synthesizeCurrentNestedNameSpecifier(ASTContext &Context, DeclContext *DC) { for (;; DC = DC->getLookupParent()) { DC = DC->getPrimaryContext(); auto *ND = dyn_cast
(DC); if (ND && !ND->isInline() && !ND->isAnonymousNamespace()) return NestedNameSpecifier::Create(Context, nullptr, ND); else if (auto *RD = dyn_cast
(DC)) return NestedNameSpecifier::Create(Context, nullptr, RD->isTemplateDecl(), RD->getTypeForDecl()); else if (isa
(DC)) return NestedNameSpecifier::GlobalSpecifier(Context); } llvm_unreachable("something isn't in TU scope?"); } ParsedType Sema::ActOnDelayedDefaultTemplateArg(const IdentifierInfo &II, SourceLocation NameLoc) { // Accepting an undeclared identifier as a default argument for a template // type parameter is a Microsoft extension. Diag(NameLoc, diag::ext_ms_delayed_template_argument) << &II; // Build a fake DependentNameType that will perform lookup into CurContext at // instantiation time. The name specifier isn't dependent, so template // instantiation won't transform it. It will retry the lookup, however. NestedNameSpecifier *NNS = synthesizeCurrentNestedNameSpecifier(Context, CurContext); QualType T = Context.getDependentNameType(ETK_None, NNS, &II); // Build type location information. We synthesized the qualifier, so we have // to build a fake NestedNameSpecifierLoc. NestedNameSpecifierLocBuilder NNSLocBuilder; NNSLocBuilder.MakeTrivial(Context, NNS, SourceRange(NameLoc)); NestedNameSpecifierLoc QualifierLoc = NNSLocBuilder.getWithLocInContext(Context); TypeLocBuilder Builder; DependentNameTypeLoc DepTL = Builder.push
(T); DepTL.setNameLoc(NameLoc); DepTL.setElaboratedKeywordLoc(SourceLocation()); DepTL.setQualifierLoc(QualifierLoc); return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T)); } /// isTagName() - This method is called *for error recovery purposes only* /// to determine if the specified name is a valid tag name ("struct foo"). If /// so, this returns the TST for the tag corresponding to it (TST_enum, /// 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
()) { 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 A { /// public: /// typedef int TYPE; /// }; /// template
class B : public A
{ /// public: /// A
::TYPE a; // no typename required because A
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
(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(); } void 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; } 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; } } // 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::ext_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"); } } /// \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
(*I) || isa
(*I)) return true; if (CheckTemplate && isa
(*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
()) { StringRef FixItTagName; switch (Tag->getTagKind()) { case TTK_Class: FixItTagName = "class "; break; case TTK_Enum: FixItTagName = "enum "; break; case TTK_Struct: FixItTagName = "struct "; break; case TTK_Interface: FixItTagName = "__interface "; break; case TTK_Union: FixItTagName = "union "; break; } StringRef TagName = FixItTagName.drop_back(); SemaRef.Diag(NameLoc, diag::err_use_of_tag_name_without_tag) << Name << TagName << SemaRef.getLangOpts().CPlusPlus << FixItHint::CreateInsertion(NameLoc, FixItTagName); 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
(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, nullptr, false); } LookupResult Result(*this, Name, NameLoc, LookupOrdinaryName); LookupParsedName(Result, S, &SS, !CurMethod); // For unqualified lookup in a class template in MSVC mode, look into // dependent base classes where the primary class template is known. if (Result.empty() && SS.isEmpty() && getLangOpts().MSVCCompat) { if (ParsedType TypeInBase = recoverFromTypeInKnownDependentBase(*this, *Name, NameLoc)) return TypeInBase; } // Perform lookup for Objective-C instance variables (including automatically // synthesized instance variables), if we're in an Objective-C method. // FIXME: This lookup really, really needs to be folded in to the normal // 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() : nullptr; if (getLangOpts().CPlusPlus && NextToken.is(tok::less) && UnderlyingFirstDecl && isa
(UnderlyingFirstDecl)) { UnqualifiedDiag = diag::err_no_template_suggest; QualifiedDiag = diag::err_no_member_template_suggest; } else if (UnderlyingFirstDecl && (isa
(UnderlyingFirstDecl) || isa
(UnderlyingFirstDecl) || isa
(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
()) { 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=*/nullptr); } 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
((*Result.begin())->getUnderlyingDecl()); IsFunctionTemplate = isa
(TD); IsVarTemplate = isa
(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
(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
(FirstDecl); if (!Class) { // FIXME: It's unfortunate that we don't have a Type node for handling this. if (ObjCCompatibleAliasDecl *Alias = dyn_cast
(FirstDecl)) Class = Alias->getClassInterface(); } if (Class) { DiagnoseUseOfDecl(Class, NameLoc); if (NextToken.is(tok::period)) { // Interface.
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
(FirstDecl) && !isa
(FirstDecl)) return NameClassification::TypeTemplate( TemplateName(cast
(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
(); 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, nullptr); 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
(DC) && !isLambdaCallOperator(DC)) { DC = DC->getLexicalParent(); // A function not defined within a class will always return to its // lexical context. if (!isa
(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
(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
()); } /// 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
(D) && cast
(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
(D) && !cast
(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 nullptr; } 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
(D) || isa
(D) || isa
(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
(D)) return CD->isCopyConstructor(); if (const CXXMethodDecl *Method = dyn_cast
(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
(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
()) 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
(D)) { if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) return false; if (const CXXMethodDecl *MD = dyn_cast
(FD)) { if (MD->isVirtual() || IsDisallowedCopyOrAssign(MD)) return false; } else { // 'static inline' functions are defined in headers; don't warn. if (FD->isInlined() && !isMainFileLoc(*this, FD->getLocation())) return false; } if (FD->doesThisDeclarationHaveABody() && Context.DeclMustBeEmitted(FD)) return false; } else if (const VarDecl *VD = dyn_cast
(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. // FIXME: This seems like a bogus check; it suppresses -Wunused-function // for inline functions defined in the main source file, for instance. return mightHaveNonExternalLinkage(D); } void Sema::MarkUnusedFileScopedDecl(const DeclaratorDecl *D) { if (!D) return; if (const FunctionDecl *FD = dyn_cast
(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
(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
() || D->hasAttr
()) return false; if (isa
(D)) return true; // White-list anything that isn't a local variable. if (!isa
(D) || isa
(D) || isa
(D) || !D->getDeclContext()->isFunctionOrMethod()) return false; // Types of valid local variables should be complete, so this should succeed. if (const VarDecl *VD = dyn_cast
(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
()) { if (TT->getDecl()->hasAttr
()) 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
()) { const TagDecl *Tag = TT->getDecl(); if (Tag->hasAttr
()) return false; if (const CXXRecordDecl *RD = dyn_cast
(Tag)) { if (!RD->hasTrivialDestructor() && !RD->hasAttr
()) return false; if (const Expr *Init = VD->getInit()) { if (const ExprWithCleanups *Cleanups = dyn_cast
(Init)) Init = Cleanups->getSubExpr(); const CXXConstructExpr *Construct = dyn_cast
(Init); if (Construct && !Construct->isElidable()) { CXXConstructorDecl *CD = Construct->getConstructor(); if (!CD->isTrivial() && !RD->hasAttr
()) return false; } } } } // TODO: __attribute__((unused)) templates? } return true; } static void GenerateFixForUnusedDecl(const NamedDecl *D, ASTContext &Ctx, FixItHint &Hint) { if (isa
(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) { if (!ShouldDiagnoseUnusedDecl(D)) return; FixItHint Hint; GenerateFixForUnusedDecl(D, Context, Hint); unsigned DiagID; if (isa
(D) && cast
(D)->isExceptionVariable()) DiagID = diag::warn_unused_exception_param; else if (isa
(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() == nullptr) S.Diag(L->getLocation(), diag::err_undeclared_label_use) <
getDeclName(); } void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) { S->mergeNRVOIntoParent(); if (S->decl_empty()) return; assert((S->getFlags() & (Scope::DeclScope | Scope::TemplateParamScope)) && "Scope shouldn't contain decls!"); for (auto *TmpD : S->decls()) { assert(TmpD && "This decl didn't get pushed??"); assert(isa
(TmpD) && "Decl isn't NamedDecl?"); NamedDecl *D = cast
(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
(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
Validator; if (TypoCorrection C = CorrectTypo(DeclarationNameInfo(Id, IdLoc), LookupOrdinaryName, TUScope, nullptr, Validator, CTK_ErrorRecovery)) { diagnoseTypo(C, PDiag(diag::err_undef_interface_suggest) << Id); IDecl = C.getCorrectionDeclAs
(); Id = IDecl->getIdentifier(); } } ObjCInterfaceDecl *Def = dyn_cast_or_null
(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
()) 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 nullptr; case ASTContext::GE_Missing_setjmp: if (ForRedeclaration) Diag(Loc, diag::warn_implicit_decl_requires_setjmp) << Context.BuiltinInfo.GetName(BID); return nullptr; case ASTContext::GE_Missing_ucontext: if (ForRedeclaration) Diag(Loc, diag::warn_implicit_decl_requires_ucontext) << Context.BuiltinInfo.GetName(BID); return nullptr; } 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.isIgnored(diag::ext_implicit_lib_function_decl, Loc)) 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=*/nullptr, SC_Extern, false, /*hasPrototype=*/true); New->setImplicit(); // Create Decl objects for each parameter, adding them to the // FunctionDecl. if (const FunctionProtoType *FT = dyn_cast
(R)) { SmallVector
Params; for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) { ParmVarDecl *parm = ParmVarDecl::Create(Context, New, SourceLocation(), SourceLocation(), nullptr, FT->getParamType(i), /*TInfo=*/nullptr, SC_None, nullptr); 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
(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
(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
(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
()->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
(); 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
(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
(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
(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
(A); const AnnotateAttr *Ann = dyn_cast
(A); for (const auto *i : D->attrs()) if (i->getKind() == A->getKind()) { if (Ann) { if (Ann->getAnnotation() == cast
(i)->getAnnotation()) return true; continue; } // FIXME: Don't hardcode this check if (OA && isa
(i)) return OA->getOwnKind() == cast
(i)->getOwnKind(); return true; } return false; } static bool isAttributeTargetADefinition(Decl *D) { if (VarDecl *VD = dyn_cast
(D)) return VD->isThisDeclarationADefinition(); if (TagDecl *TD = dyn_cast
(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 = nullptr; AlignedAttr *OldStrictestAlignAttr = nullptr; unsigned OldAlign = 0; for (auto *I : Old->specific_attrs
()) { // FIXME: We have no way of representing inherited dependent alignments // in a case like: // template
struct alignas(A) X; // template
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 = nullptr; unsigned NewAlign = 0; for (auto *I : New->specific_attrs
()) { 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
(New)) Ty = VD->getType(); else Ty = S.Context.getTagDeclType(cast
(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
(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
(Attr)) NewAttr = S.mergeVisibilityAttr(D, VA->getRange(), VA->getVisibility(), AttrSpellingListIndex); else if (const auto *VA = dyn_cast
(Attr)) NewAttr = S.mergeTypeVisibilityAttr(D, VA->getRange(), VA->getVisibility(), AttrSpellingListIndex); else if (const auto *ImportA = dyn_cast
(Attr)) NewAttr = S.mergeDLLImportAttr(D, ImportA->getRange(), AttrSpellingListIndex); else if (const auto *ExportA = dyn_cast
(Attr)) NewAttr = S.mergeDLLExportAttr(D, ExportA->getRange(), AttrSpellingListIndex); else if (const auto *FA = dyn_cast
(Attr)) NewAttr = S.mergeFormatAttr(D, FA->getRange(), FA->getType(), FA->getFormatIdx(), FA->getFirstArg(), AttrSpellingListIndex); else if (const auto *SA = dyn_cast
(Attr)) NewAttr = S.mergeSectionAttr(D, SA->getRange(), SA->getName(), AttrSpellingListIndex); else if (const auto *IA = dyn_cast
(Attr)) NewAttr = S.mergeMSInheritanceAttr(D, IA->getRange(), IA->getBestCase(), AttrSpellingListIndex, IA->getSemanticSpelling()); else if (isa
(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
(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
(D)) return TD->getDefinition(); if (const VarDecl *VD = dyn_cast
(D)) { const VarDecl *Def = VD->getDefinition(); if (Def) return Def; return VD->getActingDefinition(); } if (const FunctionDecl *FD = dyn_cast
(D)) { const FunctionDecl* Def; if (FD->isDefined(Def)) return Def; } return nullptr; } 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
(NewAttribute)) { if (FunctionDecl *FD = dyn_cast
(New)) S.CheckForFunctionRedefinition(FD, cast
(Def)); else { VarDecl *VD = cast
(New); unsigned Diag = cast
(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
(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
(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
(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 *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
()) { bool Override = false; // Ignore deprecated/unavailable/availability attributes if requested. if (isa
(I) || isa
(I) || isa
(I)) { switch (AMK) { case AMK_None: continue; case AMK_Redeclaration: break; case AMK_Override: Override = true; break; } } // Already handled. if (isa
(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
(); if (CDA && !oldDecl->hasAttr
()) { 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
(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
()) { if (!DeclHasAttr(newDecl, I)) { InheritableAttr *newAttr = cast
(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
(MD)) { if (Ctor->isDefaultConstructor()) return Sema::CXXDefaultConstructor; if (Ctor->isCopyConstructor()) return Sema::CXXCopyConstructor; if (Ctor->isMoveConstructor()) return Sema::CXXMoveConstructor; } else if (isa
(MD)) { return Sema::CXXDestructor; } else if (MD->isCopyAssignmentOperator()) { return Sema::CXXCopyAssignment; } else if (MD->isMoveAssignmentOperator()) { return Sema::CXXMoveAssignment; } return Sema::CXXInvalid; } // Determine whether the previous declaration was a definition, implicit // declaration, or a declaration. template
static std::pair
getNoteDiagForInvalidRedeclaration(const T *Old, const T *New) { diag::kind PrevDiag; SourceLocation OldLocation = Old->getLocation(); if (Old->isThisDeclarationADefinition()) PrevDiag = diag::note_previous_definition; else if (Old->isImplicit()) { PrevDiag = diag::note_previous_implicit_declaration; if (OldLocation.isInvalid()) OldLocation = New->getLocation(); } else PrevDiag = diag::note_previous_declaration; return std::make_pair(PrevDiag, OldLocation); } /// canRedefineFunction - checks if a function can be redefined. Currently, /// only extern inline functions can be redefined, and even then only in /// GNU89 mode. static bool canRedefineFunction(const FunctionDecl *FD, const LangOptions& LangOpts) { return ((FD->hasAttr
() || LangOpts.GNUInline) && !LangOpts.CPlusPlus && FD->isInlineSpecified() && FD->getStorageClass() == SC_Extern); } const AttributedType *Sema::getCallingConvAttributedType(QualType T) const { const AttributedType *AT = T->getAs
(); while (AT && !AT->isCallingConv()) AT = AT->getModifiedType()->getAs
(); return AT; } template
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
(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
(Shadow->getTargetDecl()); if (Old && !Old->getDeclContext()->getRedeclContext()->Equals( New->getDeclContext()->getRedeclContext()) && !(Old->isExternC() && New->isExternC())) Old = nullptr; if (!Old) { Diag(New->getLocation(), diag::err_using_decl_conflict_reverse); Diag(Shadow->getTargetDecl()->getLocation(), diag::note_using_decl_target); Diag(Shadow->getUsingDecl()->getLocation(), diag::note_using_decl) << 0; return true; } OldD = Old; } else { Diag(New->getLocation(), diag::err_redefinition_different_kind) << New->getDeclName(); Diag(OldD->getLocation(), diag::note_previous_definition); return true; } } // If the old declaration is invalid, just give up here. if (Old->isInvalidDecl()) return true; diag::kind PrevDiag; SourceLocation OldLocation; std::tie(PrevDiag, OldLocation) = getNoteDiagForInvalidRedeclaration(Old, New); // Don't complain about this if we're in GNU89 mode and the old function // is an extern inline function. // Don't complain about specializations. They are not supposed to have // storage classes. if (!isa
(New) && !isa
(Old) && New->getStorageClass() == SC_Static && Old->hasExternalFormalLinkage() && !New->getTemplateSpecializationInfo() && !canRedefineFunction(Old, getLangOpts())) { if (getLangOpts().MicrosoftExt) { Diag(New->getLocation(), diag::ext_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
(OldQType); const FunctionType *NewType = cast
(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::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
(); AdjustedType = Context.adjustFunctionType(AdjustedType, NewTypeInfo); New->setType(QualType(AdjustedType, 0)); NewQType = Context.getCanonicalType(New->getType()); NewType = cast
(NewQType); } // If this redeclaration makes the function inline, we may need to add it to // UndefinedButUsed. if (!Old->isInlined() && New->isInlined() && !New->hasAttr
() && (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
() && Old->isInlined() && !Old->hasAttr
()) { 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
() : OldType)->getReturnType(); QualType NewDeclaredReturnType = (New->getTypeSourceInfo() ? New->getTypeSourceInfo()->getType()->castAs
() : 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 << New->getReturnTypeSourceRange(); else Diag(New->getLocation(), diag::err_ovl_diff_return_type) << New->getReturnTypeSourceRange(); Diag(OldLocation, PrevDiag) << Old << Old->getType() << Old->getReturnTypeSourceRange(); return true; } else NewQType = ResQT; } QualType OldReturnType = OldType->getReturnType(); QualType NewReturnType = cast
(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
(Old); CXXMethodDecl *NewMethod = dyn_cast
(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
(OldMethod)) NewDiag = diag::err_constructor_redeclared; else if (isa
(NewMethod)) NewDiag = diag::err_destructor_redeclared; else if (isa
(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
(); if (NRA && !Old->hasAttr
()) { 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
(); if (CDA && !Old->hasAttr
()) { 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
(); const FunctionType *NewFuncType = NewQType->getAs
(); const FunctionProtoType *OldProto = nullptr; if (MergeTypeWithOld && isa
(NewFuncType) && (OldProto = dyn_cast
(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
ParamTypes(OldProto->param_types()); NewQType = Context.getFunctionType(NewFuncType->getReturnType(), ParamTypes, OldProto->getExtProtoInfo()); New->setType(NewQType); New->setHasInheritedPrototype(); // Synthesize parameters with the same types. SmallVector
Params; for (const auto &ParamType : OldProto->param_types()) { ParmVarDecl *Param = ParmVarDecl::Create(Context, New, SourceLocation(), SourceLocation(), nullptr, ParamType, /*TInfo=*/nullptr, SC_None, nullptr); Param->setScopeInfo(0, Params.size()); Param->setImplicit(); Params.push_back(Param); } 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
() && Old->getNumParams() == New->getNumParams()) { SmallVector
ArgTypes; SmallVector
Warnings; const FunctionProtoType *OldProto = Old->getType()->getAs
(); const FunctionProtoType *NewProto = New->getType()->getAs
(); // 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; if (Old->isImplicit() && (BuiltinID = Old->getBuiltinID())) { // If it's actually a library-defined builtin function like 'malloc' // or 'printf', just warn about the incompatible redeclaration. if (Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) { Diag(New->getLocation(), diag::warn_redecl_library_builtin) << New; Diag(OldLocation, diag::note_previous_builtin_declaration) << Old << Old->getType(); // If this is a global redeclaration, just forget hereafter // about the "builtin-ness" of the function. // // Doing this for local extern declarations is problematic. If // the builtin declaration remains visible, a second invalid // local declaration will produce a hard error; if it doesn't // remain visible, a single bogus local redeclaration (which is // actually only a warning) could break all the downstream code. if (!New->getLexicalDeclContext()->isFunctionOrMethod()) New->getIdentifier()->setBuiltinID(Builtin::NotBuiltin); return false; } PrevDiag = diag::note_previous_builtin_declaration; } Diag(New->getLocation(), diag::err_conflicting_types) << New->getDeclName(); Diag(OldLocation, PrevDiag) << Old << Old->getType(); return true; } /// \brief Completes the merge of two function declarations that are /// known to be compatible. /// /// This routine handles the merging of attributes and other /// properties of function declarations from the old declaration to /// the new declaration, once we know that New is in fact a /// redeclaration of Old. /// /// \returns false bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old, Scope *S, bool MergeTypeWithOld) { // Merge the attributes mergeDeclAttributes(New, Old); // Merge "pure" flag. if (Old->isPure()) New->setPure(); // Merge "used" flag. if (Old->getMostRecentDecl()->isUsed(false)) New->setIsUsed(); // Merge attributes from the parameters. These can mismatch with K&R // declarations. if (New->getNumParams() == Old->getNumParams()) for (unsigned i = 0, e = New->getNumParams(); i != e; ++i) mergeParamDeclAttributes(New->getParamDecl(i), Old->getParamDecl(i), *this); if (getLangOpts().CPlusPlus) return MergeCXXFunctionDecl(New, Old, S); // Merge the function types so the we get the composite types for the return // and argument types. Per C11 6.2.7/4, only update the type if the old decl // was visible. QualType Merged = Context.mergeTypes(Old->getType(), New->getType()); if (!Merged.isNull() && MergeTypeWithOld) New->setType(Merged); return false; } void Sema::mergeObjCMethodDecls(ObjCMethodDecl *newMethod, ObjCMethodDecl *oldMethod) { // Merge the attributes, including deprecated/unavailable AvailabilityMergeKind MergeKind = isa
(newMethod->getDeclContext()) ? AMK_Redeclaration : AMK_Override; mergeDeclAttributes(newMethod, oldMethod, MergeKind); // Merge attributes from the parameters. ObjCMethodDecl::param_const_iterator oi = oldMethod->param_begin(), oe = oldMethod->param_end(); for (ObjCMethodDecl::param_iterator ni = newMethod->param_begin(), ne = newMethod->param_end(); ni != ne && oi != oe; ++ni, ++oi) mergeParamDeclAttributes(*ni, *oi, *this); CheckObjCMethodOverride(newMethod, oldMethod); } /// MergeVarDeclTypes - We parsed a variable 'New' which has the same name and /// scope as a previous declaration 'Old'. Figure out how to merge their types, /// emitting diagnostics as appropriate. /// /// Declarations using the auto type specifier (C++ [decl.spec.auto]) call back /// to here in AddInitializerToDecl. We can't check them before the initializer /// is attached. void Sema::MergeVarDeclTypes(VarDecl *New, VarDecl *Old, bool MergeTypeWithOld) { if (New->isInvalidDecl() || Old->isInvalidDecl()) return; QualType MergedT; if (getLangOpts().CPlusPlus) { if (New->getType()->isUndeducedType()) { // We don't know what the new type is until the initializer is attached. return; } else if (Context.hasSameType(New->getType(), Old->getType())) { // These could still be something that needs exception specs checked. return MergeVarDeclExceptionSpecs(New, Old); } // C++ [basic.link]p10: // [...] the types specified by all declarations referring to a given // object or function shall be identical, except that declarations for an // array object can specify array types that differ by the presence or // absence of a major array bound (8.3.4). else if (Old->getType()->isIncompleteArrayType() && New->getType()->isArrayType()) { const ArrayType *OldArray = Context.getAsArrayType(Old->getType()); const ArrayType *NewArray = Context.getAsArrayType(New->getType()); if (Context.hasSameType(OldArray->getElementType(), NewArray->getElementType())) MergedT = New->getType(); } else if (Old->getType()->isArrayType() && New->getType()->isIncompleteArrayType()) { const ArrayType *OldArray = Context.getAsArrayType(Old->getType()); const ArrayType *NewArray = Context.getAsArrayType(New->getType()); if (Context.hasSameType(OldArray->getElementType(), NewArray->getElementType())) MergedT = Old->getType(); } else if (New->getType()->isObjCObjectPointerType() && Old->getType()->isObjCObjectPointerType()) { MergedT = Context.mergeObjCGCQualifiers(New->getType(), Old->getType()); } } else { // C 6.2.7p2: // All declarations that refer to the same object or function shall have // compatible type. MergedT = Context.mergeTypes(New->getType(), Old->getType()); } if (MergedT.isNull()) { // It's OK if we couldn't merge types if either type is dependent, for a // block-scope variable. In other cases (static data members of class // templates, variable templates, ...), we require the types to be // equivalent. // FIXME: The C++ standard doesn't say anything about this. if ((New->getType()->isDependentType() || Old->getType()->isDependentType()) && New->isLocalVarDecl()) { // If the old type was dependent, we can't merge with it, so the new type // becomes dependent for now. We'll reproduce the original type when we // instantiate the TypeSourceInfo for the variable. if (!New->getType()->isDependentType() && MergeTypeWithOld) New->setType(Context.DependentTy); return; } // FIXME: Even if this merging succeeds, some other non-visible declaration // of this variable might have an incompatible type. For instance: // // extern int arr[]; // void f() { extern int arr[2]; } // void g() { extern int arr[3]; } // // Neither C nor C++ requires a diagnostic for this, but we should still try // to diagnose it. Diag(New->getLocation(), diag::err_redefinition_different_type) << New->getDeclName() << New->getType() << Old->getType(); Diag(Old->getLocation(), diag::note_previous_definition); return New->setInvalidDecl(); } // Don't actually update the type on the new declaration if the old // declaration was an extern declaration in a different scope. if (MergeTypeWithOld) New->setType(MergedT); } static bool mergeTypeWithPrevious(Sema &S, VarDecl *NewVD, VarDecl *OldVD, LookupResult &Previous) { // C11 6.2.7p4: // For an identifier with internal or external linkage declared // in a scope in which a prior declaration of that identifier is // visible, if the prior declaration specifies internal or // external linkage, the type of the identifier at the later // declaration becomes the composite type. // // If the variable isn't visible, we do not merge with its type. if (Previous.isShadowed()) return false; if (S.getLangOpts().CPlusPlus) { // C++11 [dcl.array]p3: // If there is a preceding declaration of the entity in the same // scope in which the bound was specified, an omitted array bound // is taken to be the same as in that earlier declaration. return NewVD->isPreviousDeclInSameBlockScope() || (!OldVD->getLexicalDeclContext()->isFunctionOrMethod() && !NewVD->getLexicalDeclContext()->isFunctionOrMethod()); } else { // If the old declaration was function-local, don't merge with its // type unless we're in the same function. return !OldVD->getLexicalDeclContext()->isFunctionOrMethod() || OldVD->getLexicalDeclContext() == NewVD->getLexicalDeclContext(); } } /// MergeVarDecl - We just parsed a variable 'New' which has the same name /// and scope as a previous declaration 'Old'. Figure out how to resolve this /// situation, merging decls or emitting diagnostics as appropriate. /// /// Tentative definition rules (C99 6.9.2p2) are checked by /// FinalizeDeclaratorGroup. Unfortunately, we can't analyze tentative /// definitions here, since the initializer hasn't been attached. /// void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) { // If the new decl is already invalid, don't do any other checking. if (New->isInvalidDecl()) return; VarTemplateDecl *NewTemplate = New->getDescribedVarTemplate(); // Verify the old decl was also a variable or variable template. VarDecl *Old = nullptr; VarTemplateDecl *OldTemplate = nullptr; if (Previous.isSingleResult()) { if (NewTemplate) { OldTemplate = dyn_cast
(Previous.getFoundDecl()); Old = OldTemplate ? OldTemplate->getTemplatedDecl() : nullptr; } else Old = dyn_cast
(Previous.getFoundDecl()); } if (!Old) { Diag(New->getLocation(), diag::err_redefinition_different_kind) << New->getDeclName(); Diag(Previous.getRepresentativeDecl()->getLocation(), diag::note_previous_definition); return New->setInvalidDecl(); } if (!shouldLinkPossiblyHiddenDecl(Old, New)) return; // Ensure the template parameters are compatible. if (NewTemplate && !TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(), OldTemplate->getTemplateParameters(), /*Complain=*/true, TPL_TemplateMatch)) return; // C++ [class.mem]p1: // A member shall not be declared twice in the member-specification [...] // // Here, we need only consider static data members. if (Old->isStaticDataMember() && !New->isOutOfLine()) { Diag(New->getLocation(), diag::err_duplicate_member) << New->getIdentifier(); Diag(Old->getLocation(), diag::note_previous_declaration); New->setInvalidDecl(); } mergeDeclAttributes(New, Old); // Warn if an already-declared variable is made a weak_import in a subsequent // declaration if (New->hasAttr
() && Old->getStorageClass() == SC_None && !Old->hasAttr
()) { Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName(); Diag(Old->getLocation(), diag::note_previous_definition); // Remove weak_import attribute on new declaration. New->dropAttr
(); } // Merge the types. MergeVarDeclTypes(New, Old, mergeTypeWithPrevious(*this, New, Old, Previous)); if (New->isInvalidDecl()) return; diag::kind PrevDiag; SourceLocation OldLocation; std::tie(PrevDiag, OldLocation) = getNoteDiagForInvalidRedeclaration(Old, New); // [dcl.stc]p8: Check if we have a non-static decl followed by a static. if (New->getStorageClass() == SC_Static && !New->isStaticDataMember() && Old->hasExternalFormalLinkage()) { if (getLangOpts().MicrosoftExt) { Diag(New->getLocation(), diag::ext_static_non_static) << New->getDeclName(); Diag(OldLocation, PrevDiag); } else { Diag(New->getLocation(), diag::err_static_non_static) << New->getDeclName(); Diag(OldLocation, PrevDiag); return New->setInvalidDecl(); } } // C99 6.2.2p4: // For an identifier declared with the storage-class specifier // extern in a scope in which a prior declaration of that // identifier is visible,23) if the prior declaration specifies // internal or external linkage, the linkage of the identifier at // the later declaration is the same as the linkage specified at // the prior declaration. If no prior declaration is visible, or // if the prior declaration specifies no linkage, then the // identifier has external linkage. if (New->hasExternalStorage() && Old->hasLinkage()) /* Okay */; else if (New->getCanonicalDecl()->getStorageClass() != SC_Static && !New->isStaticDataMember() && Old->getCanonicalDecl()->getStorageClass() == SC_Static) { Diag(New->getLocation(), diag::err_non_static_static) << New->getDeclName(); Diag(OldLocation, PrevDiag); return New->setInvalidDecl(); } // Check if extern is followed by non-extern and vice-versa. if (New->hasExternalStorage() && !Old->hasLinkage() && Old->isLocalVarDecl()) { Diag(New->getLocation(), diag::err_extern_non_extern) << New->getDeclName(); Diag(OldLocation, PrevDiag); return New->setInvalidDecl(); } if (Old->hasLinkage() && New->isLocalVarDecl() && !New->hasExternalStorage()) { Diag(New->getLocation(), diag::err_non_extern_extern) << New->getDeclName(); Diag(OldLocation, PrevDiag); return New->setInvalidDecl(); } // Variables with external linkage are analyzed in FinalizeDeclaratorGroup. // FIXME: The test for external storage here seems wrong? We still // need to check for mismatches. if (!New->hasExternalStorage() && !New->isFileVarDecl() && // Don't complain about out-of-line definitions of static members. !(Old->getLexicalDeclContext()->isRecord() && !New->getLexicalDeclContext()->isRecord())) { Diag(New->getLocation(), diag::err_redefinition) << New->getDeclName(); Diag(OldLocation, PrevDiag); return New->setInvalidDecl(); } if (New->getTLSKind() != Old->getTLSKind()) { if (!Old->getTLSKind()) { Diag(New->getLocation(), diag::err_thread_non_thread) << New->getDeclName(); Diag(OldLocation, PrevDiag); } else if (!New->getTLSKind()) { Diag(New->getLocation(), diag::err_non_thread_thread) << New->getDeclName(); Diag(OldLocation, PrevDiag); } else { // Do not allow redeclaration to change the variable between requiring // static and dynamic initialization. // FIXME: GCC allows this, but uses the TLS keyword on the first // declaration to determine the kind. Do we need to be compatible here? Diag(New->getLocation(), diag::err_thread_thread_different_kind) << New->getDeclName() << (New->getTLSKind() == VarDecl::TLS_Dynamic); Diag(OldLocation, PrevDiag); } } // C++ doesn't have tentative definitions, so go right ahead and check here. const VarDecl *Def; if (getLangOpts().CPlusPlus && New->isThisDeclarationADefinition() == VarDecl::Definition && (Def = Old->getDefinition())) { Diag(New->getLocation(), diag::err_redefinition) << New; Diag(Def->getLocation(), diag::note_previous_definition); New->setInvalidDecl(); return; } if (haveIncompatibleLanguageLinkages(Old, New)) { Diag(New->getLocation(), diag::err_different_language_linkage) << New; Diag(OldLocation, PrevDiag); New->setInvalidDecl(); return; } // Merge "used" flag. if (Old->getMostRecentDecl()->isUsed(false)) New->setIsUsed(); // Keep a chain of previous declarations. New->setPreviousDecl(Old); if (NewTemplate) NewTemplate->setPreviousDecl(OldTemplate); // Inherit access appropriately. New->setAccess(Old->getAccess()); if (NewTemplate) NewTemplate->setAccess(New->getAccess()); } /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with /// no declarator (e.g. "struct foo;") is parsed. Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS) { return ParsedFreeStandingDeclSpec(S, AS, DS, MultiTemplateParamsArg()); } static void HandleTagNumbering(Sema &S, const TagDecl *Tag, Scope *TagScope) { if (!S.Context.getLangOpts().CPlusPlus) return; if (isa
(Tag->getParent())) { // If this tag is the direct child of a class, number it if // it is anonymous. if (!Tag->getName().empty() || Tag->getTypedefNameForAnonDecl()) return; MangleNumberingContext &MCtx = S.Context.getManglingNumberContext(Tag->getParent()); S.Context.setManglingNumber( Tag, MCtx.getManglingNumber(Tag, TagScope->getMSLocalManglingNumber())); return; } // If this tag isn't a direct child of a class, number it if it is local. Decl *ManglingContextDecl; if (MangleNumberingContext *MCtx = S.getCurrentMangleNumberContext(Tag->getDeclContext(), ManglingContextDecl)) { S.Context.setManglingNumber( Tag, MCtx->getManglingNumber(Tag, TagScope->getMSLocalManglingNumber())); } } /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with /// no declarator (e.g. "struct foo;") is parsed. It also accepts template /// parameters to cope with template friend declarations. Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS, DeclSpec &DS, MultiTemplateParamsArg TemplateParams, bool IsExplicitInstantiation) { Decl *TagD = nullptr; TagDecl *Tag = nullptr; if (DS.getTypeSpecType() == DeclSpec::TST_class || DS.getTypeSpecType() == DeclSpec::TST_struct || DS.getTypeSpecType() == DeclSpec::TST_interface || DS.getTypeSpecType() == DeclSpec::TST_union || DS.getTypeSpecType() == DeclSpec::TST_enum) { TagD = DS.getRepAsDecl(); if (!TagD) // We probably had an error return nullptr; // Note that the above type specs guarantee that the // type rep is a Decl, whereas in many of the others // it's a Type. if (isa
(TagD)) Tag = cast
(TagD); else if (ClassTemplateDecl *CTD = dyn_cast
(TagD)) Tag = CTD->getTemplatedDecl(); } if (Tag) { HandleTagNumbering(*this, Tag, S); Tag->setFreeStanding(); if (Tag->isInvalidDecl()) return Tag; } if (unsigned TypeQuals = DS.getTypeQualifiers()) { // Enforce C99 6.7.3p2: "Types other than pointer types derived from object // or incomplete types shall not be restrict-qualified." if (TypeQuals & DeclSpec::TQ_restrict) Diag(DS.getRestrictSpecLoc(), diag::err_typecheck_invalid_restrict_not_pointer_noarg) << DS.getSourceRange(); } if (DS.isConstexprSpecified()) { // C++0x [dcl.constexpr]p1: constexpr can only be applied to declarations // and definitions of functions and variables. if (Tag) Diag(DS.getConstexprSpecLoc(), diag::err_constexpr_tag) << (DS.getTypeSpecType() == DeclSpec::TST_class ? 0 : DS.getTypeSpecType() == DeclSpec::TST_struct ? 1 : DS.getTypeSpecType() == DeclSpec::TST_interface ? 2 : DS.getTypeSpecType() == DeclSpec::TST_union ? 3 : 4); else Diag(DS.getConstexprSpecLoc(), diag::err_constexpr_no_declarators); // Don't emit warnings after this error. return TagD; } DiagnoseFunctionSpecifiers(DS); if (DS.isFriendSpecified()) { // If we're dealing with a decl but not a TagDecl, assume that // whatever routines created it handled the friendship aspect. if (TagD && !Tag) return nullptr; return ActOnFriendTypeDecl(S, DS, TemplateParams); } CXXScopeSpec &SS = DS.getTypeSpecScope(); bool IsExplicitSpecialization = !TemplateParams.empty() && TemplateParams.back()->size() == 0; if (Tag && SS.isNotEmpty() && !Tag->isCompleteDefinition() && !IsExplicitInstantiation && !IsExplicitSpecialization) { // Per C++ [dcl.type.elab]p1, a class declaration cannot have a // nested-name-specifier unless it is an explicit instantiation // or an explicit specialization. // Per C++ [dcl.enum]p1, an opaque-enum-declaration can't either. Diag(SS.getBeginLoc(), diag::err_standalone_class_nested_name_specifier) << (DS.getTypeSpecType() == DeclSpec::TST_class ? 0 : DS.getTypeSpecType() == DeclSpec::TST_struct ? 1 : DS.getTypeSpecType() == DeclSpec::TST_interface ? 2 : DS.getTypeSpecType() == DeclSpec::TST_union ? 3 : 4) << SS.getRange(); return nullptr; } // Track whether this decl-specifier declares anything. bool DeclaresAnything = true; // Handle anonymous struct definitions. if (RecordDecl *Record = dyn_cast_or_null
(Tag)) { if (!Record->getDeclName() && Record->isCompleteDefinition() && DS.getStorageClassSpec() != DeclSpec::SCS_typedef) { if (getLangOpts().CPlusPlus || Record->getDeclContext()->isRecord()) return BuildAnonymousStructOrUnion(S, DS, AS, Record, Context.getPrintingPolicy()); DeclaresAnything = false; } } // Check for Microsoft C extension: anonymous struct member. if (getLangOpts().MicrosoftExt && !getLangOpts().CPlusPlus && CurContext->isRecord() && DS.getStorageClassSpec() == DeclSpec::SCS_unspecified) { // Handle 2 kinds of anonymous struct: // struct STRUCT; // and // STRUCT_TYPE; <- where STRUCT_TYPE is a typedef struct. RecordDecl *Record = dyn_cast_or_null
(Tag); if ((Record && Record->getDeclName() && !Record->isCompleteDefinition()) || (DS.getTypeSpecType() == DeclSpec::TST_typename && DS.getRepAsType().get()->isStructureType())) { Diag(DS.getLocStart(), diag::ext_ms_anonymous_struct) << DS.getSourceRange(); return BuildMicrosoftCAnonymousStruct(S, DS, Record); } } // Skip all the checks below if we have a type error. if (DS.getTypeSpecType() == DeclSpec::TST_error || (TagD && TagD->isInvalidDecl())) return TagD; if (getLangOpts().CPlusPlus && DS.getStorageClassSpec() != DeclSpec::SCS_typedef) if (EnumDecl *Enum = dyn_cast_or_null
(Tag)) if (Enum->enumerator_begin() == Enum->enumerator_end() && !Enum->getIdentifier() && !Enum->isInvalidDecl()) DeclaresAnything = false; if (!DS.isMissingDeclaratorOk()) { // Customize diagnostic for a typedef missing a name. if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) Diag(DS.getLocStart(), diag::ext_typedef_without_a_name) << DS.getSourceRange(); else DeclaresAnything = false; } if (DS.isModulePrivateSpecified() && Tag && Tag->getDeclContext()->isFunctionOrMethod()) Diag(DS.getModulePrivateSpecLoc(), diag::err_module_private_local_class) << Tag->getTagKind() << FixItHint::CreateRemoval(DS.getModulePrivateSpecLoc()); ActOnDocumentableDecl(TagD); // C 6.7/2: // A declaration [...] shall declare at least a declarator [...], a tag, // or the members of an enumeration. // C++ [dcl.dcl]p3: // [If there are no declarators], and except for the declaration of an // unnamed bit-field, the decl-specifier-seq shall introduce one or more // names into the program, or shall redeclare a name introduced by a // previous declaration. if (!DeclaresAnything) { // In C, we allow this as a (popular) extension / bug. Don't bother // producing further diagnostics for redundant qualifiers after this. Diag(DS.getLocStart(), diag::ext_no_declarators) << DS.getSourceRange(); return TagD; } // C++ [dcl.stc]p1: // If a storage-class-specifier appears in a decl-specifier-seq, [...] the // init-declarator-list of the declaration shall not be empty. // C++ [dcl.fct.spec]p1: // If a cv-qualifier appears in a decl-specifier-seq, the // init-declarator-list of the declaration shall not be empty. // // Spurious qualifiers here appear to be valid in C. unsigned DiagID = diag::warn_standalone_specifier; if (getLangOpts().CPlusPlus) DiagID = diag::ext_standalone_specifier; // Note that a linkage-specification sets a storage class, but // 'extern "C" struct foo;' is actually valid and not theoretically // useless. if (DeclSpec::SCS SCS = DS.getStorageClassSpec()) { if (SCS == DeclSpec::SCS_mutable) // Since mutable is not a viable storage class specifier in C, there is // no reason to treat it as an extension. Instead, diagnose as an error. Diag(DS.getStorageClassSpecLoc(), diag::err_mutable_nonmember); else if (!DS.isExternInLinkageSpec() && SCS != DeclSpec::SCS_typedef) Diag(DS.getStorageClassSpecLoc(), DiagID) << DeclSpec::getSpecifierName(SCS); } if (DeclSpec::TSCS TSCS = DS.getThreadStorageClassSpec()) Diag(DS.getThreadStorageClassSpecLoc(), DiagID) << DeclSpec::getSpecifierName(TSCS); if (DS.getTypeQualifiers()) { if (DS.getTypeQualifiers() & DeclSpec::TQ_const) Diag(DS.getConstSpecLoc(), DiagID) << "const"; if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile) Diag(DS.getConstSpecLoc(), DiagID) << "volatile"; // Restrict is covered above. if (DS.getTypeQualifiers() & DeclSpec::TQ_atomic) Diag(DS.getAtomicSpecLoc(), DiagID) << "_Atomic"; } // Warn about ignored type attributes, for example: // __attribute__((aligned)) struct A; // Attributes should be placed after tag to apply to type declaration. if (!DS.getAttributes().empty()) { DeclSpec::TST TypeSpecType = DS.getTypeSpecType(); if (TypeSpecType == DeclSpec::TST_class || TypeSpecType == DeclSpec::TST_struct || TypeSpecType == DeclSpec::TST_interface || TypeSpecType == DeclSpec::TST_union || TypeSpecType == DeclSpec::TST_enum) { AttributeList* attrs = DS.getAttributes().getList(); while (attrs) { Diag(attrs->getLoc(), diag::warn_declspec_attribute_ignored) << attrs->getName() << (TypeSpecType == DeclSpec::TST_class ? 0 : TypeSpecType == DeclSpec::TST_struct ? 1 : TypeSpecType == DeclSpec::TST_union ? 2 : TypeSpecType == DeclSpec::TST_interface ? 3 : 4); attrs = attrs->getNext(); } } } return TagD; } /// We are trying to inject an anonymous member into the given scope; /// check if there's an existing declaration that can't be overloaded. /// /// \return true if this is a forbidden redeclaration static bool CheckAnonMemberRedeclaration(Sema &SemaRef, Scope *S, DeclContext *Owner, DeclarationName Name, SourceLocation NameLoc, unsigned diagnostic) { LookupResult R(SemaRef, Name, NameLoc, Sema::LookupMemberName, Sema::ForRedeclaration); if (!SemaRef.LookupName(R, S)) return false; if (R.getAsSingle
()) return false; // Pick a representative declaration. NamedDecl *PrevDecl = R.getRepresentativeDecl()->getUnderlyingDecl(); assert(PrevDecl && "Expected a non-null Decl"); if (!SemaRef.isDeclInScope(PrevDecl, Owner, S)) return false; SemaRef.Diag(NameLoc, diagnostic) << Name; SemaRef.Diag(PrevDecl->getLocation(), diag::note_previous_declaration); return true; } /// InjectAnonymousStructOrUnionMembers - Inject the members of the /// anonymous struct or union AnonRecord into the owning context Owner /// and scope S. This routine will be invoked just after we realize /// that an unnamed union or struct is actually an anonymous union or /// struct, e.g., /// /// @code /// union { /// int i; /// float f; /// }; // InjectAnonymousStructOrUnionMembers called here to inject i and /// // f into the surrounding scope.x /// @endcode /// /// This routine is recursive, injecting the names of nested anonymous /// structs/unions into the owning context and scope as well. static bool InjectAnonymousStructOrUnionMembers(Sema &SemaRef, Scope *S, DeclContext *Owner, RecordDecl *AnonRecord, AccessSpecifier AS, SmallVectorImpl
&Chaining, bool MSAnonStruct) { unsigned diagKind = AnonRecord->isUnion() ? diag::err_anonymous_union_member_redecl : diag::err_anonymous_struct_member_redecl; bool Invalid = false; // Look every FieldDecl and IndirectFieldDecl with a name. for (auto *D : AnonRecord->decls()) { if ((isa
(D) || isa
(D)) && cast
(D)->getDeclName()) { ValueDecl *VD = cast
(D); if (CheckAnonMemberRedeclaration(SemaRef, S, Owner, VD->getDeclName(), VD->getLocation(), diagKind)) { // C++ [class.union]p2: // The names of the members of an anonymous union shall be // distinct from the names of any other entity in the // scope in which the anonymous union is declared. Invalid = true; } else { // C++ [class.union]p2: // For the purpose of name lookup, after the anonymous union // definition, the members of the anonymous union are // considered to have been defined in the scope in which the // anonymous union is declared. unsigned OldChainingSize = Chaining.size(); if (IndirectFieldDecl *IF = dyn_cast
(VD)) for (auto *PI : IF->chain()) Chaining.push_back(PI); else Chaining.push_back(VD); assert(Chaining.size() >= 2); NamedDecl **NamedChain = new (SemaRef.Context)NamedDecl*[Chaining.size()]; for (unsigned i = 0; i < Chaining.size(); i++) NamedChain[i] = Chaining[i]; IndirectFieldDecl* IndirectField = IndirectFieldDecl::Create(SemaRef.Context, Owner, VD->getLocation(), VD->getIdentifier(), VD->getType(), NamedChain, Chaining.size()); IndirectField->setAccess(AS); IndirectField->setImplicit(); SemaRef.PushOnScopeChains(IndirectField, S); // That includes picking up the appropriate access specifier. if (AS != AS_none) IndirectField->setAccess(AS); Chaining.resize(OldChainingSize); } } } return Invalid; } /// StorageClassSpecToVarDeclStorageClass - Maps a DeclSpec::SCS to /// a VarDecl::StorageClass. Any error reporting is up to the caller: /// illegal input values are mapped to SC_None. static StorageClass StorageClassSpecToVarDeclStorageClass(const DeclSpec &DS) { DeclSpec::SCS StorageClassSpec = DS.getStorageClassSpec(); assert(StorageClassSpec != DeclSpec::SCS_typedef && "Parser allowed 'typedef' as storage class VarDecl."); switch (StorageClassSpec) { case DeclSpec::SCS_unspecified: return SC_None; case DeclSpec::SCS_extern: if (DS.isExternInLinkageSpec()) return SC_None; return SC_Extern; case DeclSpec::SCS_static: return SC_Static; case DeclSpec::SCS_auto: return SC_Auto; case DeclSpec::SCS_register: return SC_Register; case DeclSpec::SCS_private_extern: return SC_PrivateExtern; // Illegal SCSs map to None: error reporting is up to the caller. case DeclSpec::SCS_mutable: // Fall through. case DeclSpec::SCS_typedef: return SC_None; } llvm_unreachable("unknown storage class specifier"); } static SourceLocation findDefaultInitializer(const CXXRecordDecl *Record) { assert(Record->hasInClassInitializer()); for (const auto *I : Record->decls()) { const auto *FD = dyn_cast
(I); if (const auto *IFD = dyn_cast
(I)) FD = IFD->getAnonField(); if (FD && FD->hasInClassInitializer()) return FD->getLocation(); } llvm_unreachable("couldn't find in-class initializer"); } static void checkDuplicateDefaultInit(Sema &S, CXXRecordDecl *Parent, SourceLocation DefaultInitLoc) { if (!Parent->isUnion() || !Parent->hasInClassInitializer()) return; S.Diag(DefaultInitLoc, diag::err_multiple_mem_union_initialization); S.Diag(findDefaultInitializer(Parent), diag::note_previous_initializer) << 0; } static void checkDuplicateDefaultInit(Sema &S, CXXRecordDecl *Parent, CXXRecordDecl *AnonUnion) { if (!Parent->isUnion() || !Parent->hasInClassInitializer()) return; checkDuplicateDefaultInit(S, Parent, findDefaultInitializer(AnonUnion)); } /// BuildAnonymousStructOrUnion - Handle the declaration of an /// anonymous structure or union. Anonymous unions are a C++ feature /// (C++ [class.union]) and a C11 feature; anonymous structures /// are a C11 feature and GNU C++ extension. Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, AccessSpecifier AS, RecordDecl *Record, const PrintingPolicy &Policy) { DeclContext *Owner = Record->getDeclContext(); // Diagnose whether this anonymous struct/union is an extension. if (Record->isUnion() && !getLangOpts().CPlusPlus && !getLangOpts().C11) Diag(Record->getLocation(), diag::ext_anonymous_union); else if (!Record->isUnion() && getLangOpts().CPlusPlus) Diag(Record->getLocation(), diag::ext_gnu_anonymous_struct); else if (!Record->isUnion() && !getLangOpts().C11) Diag(Record->getLocation(), diag::ext_c11_anonymous_struct); // C and C++ require different kinds of checks for anonymous // structs/unions. bool Invalid = false; if (getLangOpts().CPlusPlus) { const char *PrevSpec = nullptr; unsigned DiagID; if (Record->isUnion()) { // C++ [class.union]p6: // Anonymous unions declared in a named namespace or in the // global namespace shall be declared static. if (DS.getStorageClassSpec() != DeclSpec::SCS_static && (isa
(Owner) || (isa
(Owner) && cast
(Owner)->getDeclName()))) { Diag(Record->getLocation(), diag::err_anonymous_union_not_static) << FixItHint::CreateInsertion(Record->getLocation(), "static "); // Recover by adding 'static'. DS.SetStorageClassSpec(*this, DeclSpec::SCS_static, SourceLocation(), PrevSpec, DiagID, Policy); } // C++ [class.union]p6: // A storage class is not allowed in a declaration of an // anonymous union in a class scope. else if (DS.getStorageClassSpec() != DeclSpec::SCS_unspecified && isa
(Owner)) { Diag(DS.getStorageClassSpecLoc(), diag::err_anonymous_union_with_storage_spec) << FixItHint::CreateRemoval(DS.getStorageClassSpecLoc()); // Recover by removing the storage specifier. DS.SetStorageClassSpec(*this, DeclSpec::SCS_unspecified, SourceLocation(), PrevSpec, DiagID, Context.getPrintingPolicy()); } } // Ignore const/volatile/restrict qualifiers. if (DS.getTypeQualifiers()) { if (DS.getTypeQualifiers() & DeclSpec::TQ_const) Diag(DS.getConstSpecLoc(), diag::ext_anonymous_struct_union_qualified) << Record->isUnion() << "const" << FixItHint::CreateRemoval(DS.getConstSpecLoc()); if (DS.getTypeQualifiers() & DeclSpec::TQ_volatile) Diag(DS.getVolatileSpecLoc(), diag::ext_anonymous_struct_union_qualified) << Record->isUnion() << "volatile" << FixItHint::CreateRemoval(DS.getVolatileSpecLoc()); if (DS.getTypeQualifiers() & DeclSpec::TQ_restrict) Diag(DS.getRestrictSpecLoc(), diag::ext_anonymous_struct_union_qualified) << Record->isUnion() << "restrict" << FixItHint::CreateRemoval(DS.getRestrictSpecLoc()); if (DS.getTypeQualifiers() & DeclSpec::TQ_atomic) Diag(DS.getAtomicSpecLoc(), diag::ext_anonymous_struct_union_qualified) << Record->isUnion() << "_Atomic" << FixItHint::CreateRemoval(DS.getAtomicSpecLoc()); DS.ClearTypeQualifiers(); } // C++ [class.union]p2: // The member-specification of an anonymous union shall only // define non-static data members. [Note: nested types and // functions cannot be declared within an anonymous union. ] for (auto *Mem : Record->decls()) { if (auto *FD = dyn_cast
(Mem)) { // C++ [class.union]p3: // An anonymous union shall not have private or protected // members (clause 11). assert(FD->getAccess() != AS_none); if (FD->getAccess() != AS_public) { Diag(FD->getLocation(), diag::err_anonymous_record_nonpublic_member) << (int)Record->isUnion() << (int)(FD->getAccess() == AS_protected); Invalid = true; } // C++ [class.union]p1 // An object of a class with a non-trivial constructor, a non-trivial // copy constructor, a non-trivial destructor, or a non-trivial copy // assignment operator cannot be a member of a union, nor can an // array of such objects. if (CheckNontrivialField(FD)) Invalid = true; } else if (Mem->isImplicit()) { // Any implicit members are fine. } else if (isa
(Mem) && Mem->getDeclContext() != Record) { // This is a type that showed up in an // elaborated-type-specifier inside the anonymous struct or // union, but which actually declares a type outside of the // anonymous struct or union. It's okay. } else if (auto *MemRecord = dyn_cast
(Mem)) { if (!MemRecord->isAnonymousStructOrUnion() && MemRecord->getDeclName()) { // Visual C++ allows type definition in anonymous struct or union. if (getLangOpts().MicrosoftExt) Diag(MemRecord->getLocation(), diag::ext_anonymous_record_with_type) << (int)Record->isUnion(); else { // This is a nested type declaration. Diag(MemRecord->getLocation(), diag::err_anonymous_record_with_type) << (int)Record->isUnion(); Invalid = true; } } else { // This is an anonymous type definition within another anonymous type. // This is a popular extension, provided by Plan9, MSVC and GCC, but // not part of standard C++. Diag(MemRecord->getLocation(), diag::ext_anonymous_record_with_anonymous_type) << (int)Record->isUnion(); } } else if (isa
(Mem)) { // Any access specifier is fine. } else if (isa
(Mem)) { // In C++1z, static_assert declarations are also fine. } else { // We have something that isn't a non-static data // member. Complain about it. unsigned DK = diag::err_anonymous_record_bad_member; if (isa
(Mem)) DK = diag::err_anonymous_record_with_type; else if (isa
(Mem)) DK = diag::err_anonymous_record_with_function; else if (isa
(Mem)) DK = diag::err_anonymous_record_with_static; // Visual C++ allows type definition in anonymous struct or union. if (getLangOpts().MicrosoftExt && DK == diag::err_anonymous_record_with_type) Diag(Mem->getLocation(), diag::ext_anonymous_record_with_type) << (int)Record->isUnion(); else { Diag(Mem->getLocation(), DK) << (int)Record->isUnion(); Invalid = true; } } } // C++11 [class.union]p8 (DR1460): // At most one variant member of a union may have a // brace-or-equal-initializer. if (cast
(Record)->hasInClassInitializer() && Owner->isRecord()) checkDuplicateDefaultInit(*this, cast
(Owner), cast
(Record)); } if (!Record->isUnion() && !Owner->isRecord()) { Diag(Record->getLocation(), diag::err_anonymous_struct_not_member) << (int)getLangOpts().CPlusPlus; Invalid = true; } // Mock up a declarator. Declarator Dc(DS, Declarator::MemberContext); TypeSourceInfo *TInfo = GetTypeForDeclarator(Dc, S); assert(TInfo && "couldn't build declarator info for anonymous struct/union"); // Create a declaration for this anonymous struct/union. NamedDecl *Anon = nullptr; if (RecordDecl *OwningClass = dyn_cast
(Owner)) { Anon = FieldDecl::Create(Context, OwningClass, DS.getLocStart(), Record->getLocation(), /*IdentifierInfo=*/nullptr, Context.getTypeDeclType(Record), TInfo, /*BitWidth=*/nullptr, /*Mutable=*/false, /*InitStyle=*/ICIS_NoInit); Anon->setAccess(AS); if (getLangOpts().CPlusPlus) FieldCollector->Add(cast
(Anon)); } else { DeclSpec::SCS SCSpec = DS.getStorageClassSpec(); VarDecl::StorageClass SC = StorageClassSpecToVarDeclStorageClass(DS); if (SCSpec == DeclSpec::SCS_mutable) { // mutable can only appear on non-static class members, so it's always // an error here Diag(Record->getLocation(), diag::err_mutable_nonmember); Invalid = true; SC = SC_None; } Anon = VarDecl::Create(Context, Owner, DS.getLocStart(), Record->getLocation(), /*IdentifierInfo=*/nullptr, Context.getTypeDeclType(Record), TInfo, SC); // Default-initialize the implicit variable. This initialization will be // trivial in almost all cases, except if a union member has an in-class // initializer: // union { int n = 0; }; ActOnUninitializedDecl(Anon, /*TypeMayContainAuto=*/false); } Anon->setImplicit(); // Mark this as an anonymous struct/union type. Record->setAnonymousStructOrUnion(true); // Add the anonymous struct/union object to the current // context. We'll be referencing this object when we refer to one of // its members. Owner->addDecl(Anon); // Inject the members of the anonymous struct/union into the owning // context and into the identifier resolver chain for name lookup // purposes. SmallVector
Chain; Chain.push_back(Anon); if (InjectAnonymousStructOrUnionMembers(*this, S, Owner, Record, AS, Chain, false)) Invalid = true; if (VarDecl *NewVD = dyn_cast
(Anon)) { if (getLangOpts().CPlusPlus && NewVD->isStaticLocal()) { Decl *ManglingContextDecl; if (MangleNumberingContext *MCtx = getCurrentMangleNumberContext(NewVD->getDeclContext(), ManglingContextDecl)) { Context.setManglingNumber(NewVD, MCtx->getManglingNumber(NewVD, S->getMSLocalManglingNumber())); Context.setStaticLocalNumber(NewVD, MCtx->getStaticLocalNumber(NewVD)); } } } if (Invalid) Anon->setInvalidDecl(); return Anon; } /// BuildMicrosoftCAnonymousStruct - Handle the declaration of an /// Microsoft C anonymous structure. /// Ref: http://msdn.microsoft.com/en-us/library/z2cx9y4f.aspx /// Example: /// /// struct A { int a; }; /// struct B { struct A; int b; }; /// /// void foo() { /// B var; /// var.a = 3; /// } /// Decl *Sema::BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS, RecordDecl *Record) { // If there is no Record, get the record via the typedef. if (!Record) Record = DS.getRepAsType().get()->getAsStructureType()->getDecl(); // Mock up a declarator. Declarator Dc(DS, Declarator::TypeNameContext); TypeSourceInfo *TInfo = GetTypeForDeclarator(Dc, S); assert(TInfo && "couldn't build declarator info for anonymous struct"); // Create a declaration for this anonymous struct. NamedDecl *Anon = FieldDecl::Create(Context, cast
(CurContext), DS.getLocStart(), DS.getLocStart(), /*IdentifierInfo=*/nullptr, Context.getTypeDeclType(Record), TInfo, /*BitWidth=*/nullptr, /*Mutable=*/false, /*InitStyle=*/ICIS_NoInit); Anon->setImplicit(); // Add the anonymous struct object to the current context. CurContext->addDecl(Anon); // Inject the members of the anonymous struct into the current // context and into the identifier resolver chain for name lookup // purposes. SmallVector
Chain; Chain.push_back(Anon); RecordDecl *RecordDef = Record->getDefinition(); if (!RecordDef || InjectAnonymousStructOrUnionMembers(*this, S, CurContext, RecordDef, AS_none, Chain, true)) Anon->setInvalidDecl(); return Anon; } /// GetNameForDeclarator - Determine the full declaration name for the /// given Declarator. DeclarationNameInfo Sema::GetNameForDeclarator(Declarator &D) { return GetNameFromUnqualifiedId(D.getName()); } /// \brief Retrieves the declaration name from a parsed unqualified-id. DeclarationNameInfo Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) { DeclarationNameInfo NameInfo; NameInfo.setLoc(Name.StartLocation); switch (Name.getKind()) { case UnqualifiedId::IK_ImplicitSelfParam: case UnqualifiedId::IK_Identifier: NameInfo.setName(Name.Identifier); NameInfo.setLoc(Name.StartLocation); return NameInfo; case UnqualifiedId::IK_OperatorFunctionId: NameInfo.setName(Context.DeclarationNames.getCXXOperatorName( Name.OperatorFunctionId.Operator)); NameInfo.setLoc(Name.StartLocation); NameInfo.getInfo().CXXOperatorName.BeginOpNameLoc = Name.OperatorFunctionId.SymbolLocations[0]; NameInfo.getInfo().CXXOperatorName.EndOpNameLoc = Name.EndLocation.getRawEncoding(); return NameInfo; case UnqualifiedId::IK_LiteralOperatorId: NameInfo.setName(Context.DeclarationNames.getCXXLiteralOperatorName( Name.Identifier)); NameInfo.setLoc(Name.StartLocation); NameInfo.setCXXLiteralOperatorNameLoc(Name.EndLocation); return NameInfo; case UnqualifiedId::IK_ConversionFunctionId: { TypeSourceInfo *TInfo; QualType Ty = GetTypeFromParser(Name.ConversionFunctionId, &TInfo); if (Ty.isNull()) return DeclarationNameInfo(); NameInfo.setName(Context.DeclarationNames.getCXXConversionFunctionName( Context.getCanonicalType(Ty))); NameInfo.setLoc(Name.StartLocation); NameInfo.setNamedTypeInfo(TInfo); return NameInfo; } case UnqualifiedId::IK_ConstructorName: { TypeSourceInfo *TInfo; QualType Ty = GetTypeFromParser(Name.ConstructorName, &TInfo); if (Ty.isNull()) return DeclarationNameInfo(); NameInfo.setName(Context.DeclarationNames.getCXXConstructorName( Context.getCanonicalType(Ty))); NameInfo.setLoc(Name.StartLocation); NameInfo.setNamedTypeInfo(TInfo); return NameInfo; } case UnqualifiedId::IK_ConstructorTemplateId: { // In well-formed code, we can only have a constructor // template-id that refers to the current context, so go there // to find the actual type being constructed. CXXRecordDecl *CurClass = dyn_cast
(CurContext); if (!CurClass || CurClass->getIdentifier() != Name.TemplateId->Name) return DeclarationNameInfo(); // Determine the type of the class being constructed. QualType CurClassType = Context.getTypeDeclType(CurClass); // FIXME: Check two things: that the template-id names the same type as // CurClassType, and that the template-id does not occur when the name // was qualified. NameInfo.setName(Context.DeclarationNames.getCXXConstructorName( Context.getCanonicalType(CurClassType))); NameInfo.setLoc(Name.StartLocation); // FIXME: should we retrieve TypeSourceInfo? NameInfo.setNamedTypeInfo(nullptr); return NameInfo; } case UnqualifiedId::IK_DestructorName: { TypeSourceInfo *TInfo; QualType Ty = GetTypeFromParser(Name.DestructorName, &TInfo); if (Ty.isNull()) return DeclarationNameInfo(); NameInfo.setName(Context.DeclarationNames.getCXXDestructorName( Context.getCanonicalType(Ty))); NameInfo.setLoc(Name.StartLocation); NameInfo.setNamedTypeInfo(TInfo); return NameInfo; } case UnqualifiedId::IK_TemplateId: { TemplateName TName = Name.TemplateId->Template.get(); SourceLocation TNameLoc = Name.TemplateId->TemplateNameLoc; return Context.getNameForTemplate(TName, TNameLoc); } } // switch (Name.getKind()) llvm_unreachable("Unknown name kind"); } static QualType getCoreType(QualType Ty) { do { if (Ty->isPointerType() || Ty->isReferenceType()) Ty = Ty->getPointeeType(); else if (Ty->isArrayType()) Ty = Ty->castAsArrayTypeUnsafe()->getElementType(); else return Ty.withoutLocalFastQualifiers(); } while (true); } /// hasSimilarParameters - Determine whether the C++ functions Declaration /// and Definition have "nearly" matching parameters. This heuristic is /// used to improve diagnostics in the case where an out-of-line function /// definition doesn't match any declaration within the class or namespace. /// Also sets Params to the list of indices to the parameters that differ /// between the declaration and the definition. If hasSimilarParameters /// returns true and Params is empty, then all of the parameters match. static bool hasSimilarParameters(ASTContext &Context, FunctionDecl *Declaration, FunctionDecl *Definition, SmallVectorImpl
&Params) { Params.clear(); if (Declaration->param_size() != Definition->param_size()) return false; for (unsigned Idx = 0; Idx < Declaration->param_size(); ++Idx) { QualType DeclParamTy = Declaration->getParamDecl(Idx)->getType(); QualType DefParamTy = Definition->getParamDecl(Idx)->getType(); // The parameter types are identical if (Context.hasSameType(DefParamTy, DeclParamTy)) continue; QualType DeclParamBaseTy = getCoreType(DeclParamTy); QualType DefParamBaseTy = getCoreType(DefParamTy); const IdentifierInfo *DeclTyName = DeclParamBaseTy.getBaseTypeIdentifier(); const IdentifierInfo *DefTyName = DefParamBaseTy.getBaseTypeIdentifier(); if (Context.hasSameUnqualifiedType(DeclParamBaseTy, DefParamBaseTy) || (DeclTyName && DeclTyName == DefTyName)) Params.push_back(Idx); else // The two parameters aren't even close return false; } return true; } /// NeedsRebuildingInCurrentInstantiation - Checks whether the given /// declarator needs to be rebuilt in the current instantiation. /// Any bits of declarator which appear before the name are valid for /// consideration here. That's specifically the type in the decl spec /// and the base type in any member-pointer chunks. static bool RebuildDeclaratorInCurrentInstantiation(Sema &S, Declarator &D, DeclarationName Name) { // The types we specifically need to rebuild are: // - typenames, typeofs, and decltypes // - types which will become injected class names // Of course, we also need to rebuild any type referencing such a // type. It's safest to just say "dependent", but we call out a // few cases here. DeclSpec &DS = D.getMutableDeclSpec(); switch (DS.getTypeSpecType()) { case DeclSpec::TST_typename: case DeclSpec::TST_typeofType: case DeclSpec::TST_underlyingType: case DeclSpec::TST_atomic: { // Grab the type from the parser. TypeSourceInfo *TSI = nullptr; QualType T = S.GetTypeFromParser(DS.getRepAsType(), &TSI); if (T.isNull() || !T->isDependentType()) break; // Make sure there's a type source info. This isn't really much // of a waste; most dependent types should have type source info // attached already. if (!TSI) TSI = S.Context.getTrivialTypeSourceInfo(T, DS.getTypeSpecTypeLoc()); // Rebuild the type in the current instantiation. TSI = S.RebuildTypeInCurrentInstantiation(TSI, D.getIdentifierLoc(), Name); if (!TSI) return true; // Store the new type back in the decl spec. ParsedType LocType = S.CreateParsedType(TSI->getType(), TSI); DS.UpdateTypeRep(LocType); break; } case DeclSpec::TST_decltype: case DeclSpec::TST_typeofExpr: { Expr *E = DS.getRepAsExpr(); ExprResult Result = S.RebuildExprInCurrentInstantiation(E); if (Result.isInvalid()) return true; DS.UpdateExprRep(Result.get()); break; } default: // Nothing to do for these decl specs. break; } // It doesn't matter what order we do this in. for (unsigned I = 0, E = D.getNumTypeObjects(); I != E; ++I) { DeclaratorChunk &Chunk = D.getTypeObject(I); // The only type information in the declarator which can come // before the declaration name is the base type of a member // pointer. if (Chunk.Kind != DeclaratorChunk::MemberPointer) continue; // Rebuild the scope specifier in-place. CXXScopeSpec &SS = Chunk.Mem.Scope(); if (S.RebuildNestedNameSpecifierInCurrentInstantiation(SS)) return true; } return false; } Decl *Sema::ActOnDeclarator(Scope *S, Declarator &D) { D.setFunctionDefinitionKind(FDK_Declaration); Decl *Dcl = HandleDeclarator(S, D, MultiTemplateParamsArg()); if (OriginalLexicalContext && OriginalLexicalContext->isObjCContainer() && Dcl && Dcl->getDeclContext()->isFileContext()) Dcl->setTopLevelDeclInObjCContainer(); return Dcl; } /// DiagnoseClassNameShadow - Implement C++ [class.mem]p13: /// If T is the name of a class, then each of the following shall have a /// name different from T: /// - every static data member of class T; /// - every member function of class T /// - every member of class T that is itself a type; /// \returns true if the declaration name violates these rules. bool Sema::DiagnoseClassNameShadow(DeclContext *DC, DeclarationNameInfo NameInfo) { DeclarationName Name = NameInfo.getName(); if (CXXRecordDecl *Record = dyn_cast
(DC)) if (Record->getIdentifier() && Record->getDeclName() == Name) { Diag(NameInfo.getLoc(), diag::err_member_name_of_class) << Name; return true; } return false; } /// \brief Diagnose a declaration whose declarator-id has the given /// nested-name-specifier. /// /// \param SS The nested-name-specifier of the declarator-id. /// /// \param DC The declaration context to which the nested-name-specifier /// resolves. /// /// \param Name The name of the entity being declared. /// /// \param Loc The location of the name of the entity being declared. /// /// \returns true if we cannot safely recover from this error, false otherwise. bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC, DeclarationName Name, SourceLocation Loc) { DeclContext *Cur = CurContext; while (isa
(Cur) || isa
(Cur)) Cur = Cur->getParent(); // If the user provided a superfluous scope specifier that refers back to the // class in which the entity is already declared, diagnose and ignore it. // // class X { // void X::f(); // }; // // Note, it was once ill-formed to give redundant qualification in all // contexts, but that rule was removed by DR482. if (Cur->Equals(DC)) { if (Cur->isRecord()) { Diag(Loc, LangOpts.MicrosoftExt ? diag::warn_member_extra_qualification : diag::err_member_extra_qualification) << Name << FixItHint::CreateRemoval(SS.getRange()); SS.clear(); } else { Diag(Loc, diag::warn_namespace_member_extra_qualification) << Name; } return false; } // Check whether the qualifying scope encloses the scope of the original // declaration. if (!Cur->Encloses(DC)) { if (Cur->isRecord()) Diag(Loc, diag::err_member_qualification) << Name << SS.getRange(); else if (isa
(DC)) Diag(Loc, diag::err_invalid_declarator_global_scope) << Name << SS.getRange(); else if (isa
(Cur)) Diag(Loc, diag::err_invalid_declarator_in_function) << Name << SS.getRange(); else if (isa
(Cur)) Diag(Loc, diag::err_invalid_declarator_in_block) << Name << SS.getRange(); else Diag(Loc, diag::err_invalid_declarator_scope) << Name << cast
(Cur) << cast
(DC) << SS.getRange(); return true; } if (Cur->isRecord()) { // Cannot qualify members within a class. Diag(Loc, diag::err_member_qualification) << Name << SS.getRange(); SS.clear(); // C++ constructors and destructors with incorrect scopes can break // our AST invariants by having the wrong underlying types. If // that's the case, then drop this declaration entirely. if ((Name.getNameKind() == DeclarationName::CXXConstructorName || Name.getNameKind() == DeclarationName::CXXDestructorName) && !Context.hasSameType(Name.getCXXNameType(), Context.getTypeDeclType(cast
(Cur)))) return true; return false; } // C++11 [dcl.meaning]p1: // [...] "The nested-name-specifier of the qualified declarator-id shall // not begin with a decltype-specifer" NestedNameSpecifierLoc SpecLoc(SS.getScopeRep(), SS.location_data()); while (SpecLoc.getPrefix()) SpecLoc = SpecLoc.getPrefix(); if (dyn_cast_or_null
( SpecLoc.getNestedNameSpecifier()->getAsType())) Diag(Loc, diag::err_decltype_in_declarator) << SpecLoc.getTypeLoc().getSourceRange(); return false; } NamedDecl *Sema::HandleDeclarator(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists) { // TODO: consider using NameInfo for diagnostic. DeclarationNameInfo NameInfo = GetNameForDeclarator(D); DeclarationName Name = NameInfo.getName(); // All of these full declarators require an identifier. If it doesn't have // one, the ParsedFreeStandingDeclSpec action should be used. if (!Name) { if (!D.isInvalidType()) // Reject this if we think it is valid. Diag(D.getDeclSpec().getLocStart(), diag::err_declarator_need_ident) << D.getDeclSpec().getSourceRange() << D.getSourceRange(); return nullptr; } else if (DiagnoseUnexpandedParameterPack(NameInfo, UPPC_DeclarationType)) return nullptr; // The scope passed in may not be a decl scope. Zip up the scope tree until // we find one that is. while ((S->getFlags() & Scope::DeclScope) == 0 || (S->getFlags() & Scope::TemplateParamScope) != 0) S = S->getParent(); DeclContext *DC = CurContext; if (D.getCXXScopeSpec().isInvalid()) D.setInvalidType(); else if (D.getCXXScopeSpec().isSet()) { if (DiagnoseUnexpandedParameterPack(D.getCXXScopeSpec(), UPPC_DeclarationQualifier)) return nullptr; bool EnteringContext = !D.getDeclSpec().isFriendSpecified(); DC = computeDeclContext(D.getCXXScopeSpec(), EnteringContext); if (!DC || isa
(DC)) { // If we could not compute the declaration context, it's because the // declaration context is dependent but does not refer to a class, // class template, or class template partial specialization. Complain // and return early, to avoid the coming semantic disaster. Diag(D.getIdentifierLoc(), diag::err_template_qualified_declarator_no_match) << D.getCXXScopeSpec().getScopeRep() << D.getCXXScopeSpec().getRange(); return nullptr; } bool IsDependentContext = DC->isDependentContext(); if (!IsDependentContext && RequireCompleteDeclContext(D.getCXXScopeSpec(), DC)) return nullptr; if (isa
(DC) && !cast
(DC)->hasDefinition()) { Diag(D.getIdentifierLoc(), diag::err_member_def_undefined_record) << Name << DC << D.getCXXScopeSpec().getRange(); D.setInvalidType(); } else if (!D.getDeclSpec().isFriendSpecified()) { if (diagnoseQualifiedDeclaration(D.getCXXScopeSpec(), DC, Name, D.getIdentifierLoc())) { if (DC->isRecord()) return nullptr; D.setInvalidType(); } } // Check whether we need to rebuild the type of the given // declaration in the current instantiation. if (EnteringContext && IsDependentContext && TemplateParamLists.size() != 0) { ContextRAII SavedContext(*this, DC); if (RebuildDeclaratorInCurrentInstantiation(*this, D, Name)) D.setInvalidType(); } } if (DiagnoseClassNameShadow(DC, NameInfo)) // If this is a typedef, we'll end up spewing multiple diagnostics. // Just return early; it's safer. if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) return nullptr; TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); QualType R = TInfo->getType(); if (DiagnoseUnexpandedParameterPack(D.getIdentifierLoc(), TInfo, UPPC_DeclarationType)) D.setInvalidType(); LookupResult Previous(*this, NameInfo, LookupOrdinaryName, ForRedeclaration); // See if this is a redefinition of a variable in the same scope. if (!D.getCXXScopeSpec().isSet()) { bool IsLinkageLookup = false; bool CreateBuiltins = false; // If the declaration we're planning to build will be a function // or object with linkage, then look for another declaration with // linkage (C99 6.2.2p4-5 and C++ [basic.link]p6). // // If the declaration we're planning to build will be declared with // external linkage in the translation unit, create any builtin with // the same name. if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) /* Do nothing*/; else if (CurContext->isFunctionOrMethod() && (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_extern || R->isFunctionType())) { IsLinkageLookup = true; CreateBuiltins = CurContext->getEnclosingNamespaceContext()->isTranslationUnit(); } else if (CurContext->getRedeclContext()->isTranslationUnit() && D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_static) CreateBuiltins = true; if (IsLinkageLookup) Previous.clear(LookupRedeclarationWithLinkage); LookupName(Previous, S, CreateBuiltins); } else { // Something like "int foo::x;" LookupQualifiedName(Previous, DC); // C++ [dcl.meaning]p1: // When the declarator-id is qualified, the declaration shall refer to a // previously declared member of the class or namespace to which the // qualifier refers (or, in the case of a namespace, of an element of the // inline namespace set of that namespace (7.3.1)) or to a specialization // thereof; [...] // // Note that we already checked the context above, and that we do not have // enough information to make sure that Previous contains the declaration // we want to match. For example, given: // // class X { // void f(); // void f(float); // }; // // void X::f(int) { } // ill-formed // // In this case, Previous will point to the overload set // containing the two f's declared in X, but neither of them // matches. // C++ [dcl.meaning]p1: // [...] the member shall not merely have been introduced by a // using-declaration in the scope of the class or namespace nominated by // the nested-name-specifier of the declarator-id. RemoveUsingDecls(Previous); } if (Previous.isSingleResult() && Previous.getFoundDecl()->isTemplateParameter()) { // Maybe we will complain about the shadowed template parameter. if (!D.isInvalidType()) DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), Previous.getFoundDecl()); // Just pretend that we didn't see the previous declaration. Previous.clear(); } // In C++, the previous declaration we find might be a tag type // (class or enum). In this case, the new declaration will hide the // tag type. Note that this does does not apply if we're declaring a // typedef (C++ [dcl.typedef]p4). if (Previous.isSingleTagDecl() && D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef) Previous.clear(); // Check that there are no default arguments other than in the parameters // of a function declaration (C++ only). if (getLangOpts().CPlusPlus) CheckExtraCXXDefaultArguments(D); NamedDecl *New; bool AddToScope = true; if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) { if (TemplateParamLists.size()) { Diag(D.getIdentifierLoc(), diag::err_template_typedef); return nullptr; } New = ActOnTypedefDeclarator(S, D, DC, TInfo, Previous); } else if (R->isFunctionType()) { New = ActOnFunctionDeclarator(S, D, DC, TInfo, Previous, TemplateParamLists, AddToScope); } else { New = ActOnVariableDeclarator(S, D, DC, TInfo, Previous, TemplateParamLists, AddToScope); } if (!New) return nullptr; // If this has an identifier and is not an invalid redeclaration or // function template specialization, add it to the scope stack. if (New->getDeclName() && AddToScope && !(D.isRedeclaration() && New->isInvalidDecl())) { // Only make a locally-scoped extern declaration visible if it is the first // declaration of this entity. Qualified lookup for such an entity should // only find this declaration if there is no visible declaration of it. bool AddToContext = !D.isRedeclaration() || !New->isLocalExternDecl(); PushOnScopeChains(New, S, AddToContext); if (!AddToContext) CurContext->addHiddenDecl(New); } return New; } /// Helper method to turn variable array types into constant array /// types in certain situations which would otherwise be errors (for /// GCC compatibility). static QualType TryToFixInvalidVariablyModifiedType(QualType T, ASTContext &Context, bool &SizeIsNegative, llvm::APSInt &Oversized) { // This method tries to turn a variable array into a constant // array even when the size isn't an ICE. This is necessary // for compatibility with code that depends on gcc's buggy // constant expression folding, like struct {char x[(int)(char*)2];} SizeIsNegative = false; Oversized = 0; if (T->isDependentType()) return QualType(); QualifierCollector Qs; const Type *Ty = Qs.strip(T); if (const PointerType* PTy = dyn_cast