diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp | 383 |
1 files changed, 263 insertions, 120 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp index 510738e..b1dfe0e 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaDeclCXX.cpp @@ -316,8 +316,17 @@ Sema::ActOnParamDefaultArgument(Decl *param, SourceLocation EqualLoc, if (DiagnoseUnexpandedParameterPack(DefaultArg, UPPC_DefaultArgument)) { Param->setInvalidDecl(); return; - } - + } + + // C++11 [dcl.fct.default]p3 + // A default argument expression [...] shall not be specified for a + // parameter pack. + if (Param->isParameterPack()) { + Diag(EqualLoc, diag::err_param_default_argument_on_parameter_pack) + << DefaultArg->getSourceRange(); + return; + } + // Check that the default argument is well-formed CheckDefaultArgumentVisitor DefaultArgChecker(DefaultArg, this); if (DefaultArgChecker.Visit(DefaultArg)) { @@ -429,6 +438,45 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, Scope *S) { bool Invalid = false; + // The declaration context corresponding to the scope is the semantic + // parent, unless this is a local function declaration, in which case + // it is that surrounding function. + DeclContext *ScopeDC = New->isLocalExternDecl() + ? New->getLexicalDeclContext() + : New->getDeclContext(); + + // Find the previous declaration for the purpose of default arguments. + FunctionDecl *PrevForDefaultArgs = Old; + for (/**/; PrevForDefaultArgs; + // Don't bother looking back past the latest decl if this is a local + // extern declaration; nothing else could work. + PrevForDefaultArgs = New->isLocalExternDecl() + ? nullptr + : PrevForDefaultArgs->getPreviousDecl()) { + // Ignore hidden declarations. + if (!LookupResult::isVisible(*this, PrevForDefaultArgs)) + continue; + + if (S && !isDeclInScope(PrevForDefaultArgs, ScopeDC, S) && + !New->isCXXClassMember()) { + // Ignore default arguments of old decl if they are not in + // the same scope and this is not an out-of-line definition of + // a member function. + continue; + } + + if (PrevForDefaultArgs->isLocalExternDecl() != New->isLocalExternDecl()) { + // If only one of these is a local function declaration, then they are + // declared in different scopes, even though isDeclInScope may think + // they're in the same scope. (If both are local, the scope check is + // sufficent, and if neither is local, then they are in the same scope.) + continue; + } + + // We found our guy. + break; + } + // C++ [dcl.fct.default]p4: // For non-template functions, default arguments can be added in // later declarations of a function in the same @@ -447,34 +495,17 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, // in a member function definition that appears outside of the class // definition are added to the set of default arguments provided by the // member function declaration in the class definition. - for (unsigned p = 0, NumParams = Old->getNumParams(); p < NumParams; ++p) { - ParmVarDecl *OldParam = Old->getParamDecl(p); + for (unsigned p = 0, NumParams = PrevForDefaultArgs + ? PrevForDefaultArgs->getNumParams() + : 0; + p < NumParams; ++p) { + ParmVarDecl *OldParam = PrevForDefaultArgs->getParamDecl(p); ParmVarDecl *NewParam = New->getParamDecl(p); - bool OldParamHasDfl = OldParam->hasDefaultArg(); + bool OldParamHasDfl = OldParam ? OldParam->hasDefaultArg() : false; bool NewParamHasDfl = NewParam->hasDefaultArg(); - // The declaration context corresponding to the scope is the semantic - // parent, unless this is a local function declaration, in which case - // it is that surrounding function. - DeclContext *ScopeDC = New->isLocalExternDecl() - ? New->getLexicalDeclContext() - : New->getDeclContext(); - if (S && !isDeclInScope(Old, ScopeDC, S) && - !New->getDeclContext()->isRecord()) - // Ignore default parameters of old decl if they are not in - // the same scope and this is not an out-of-line definition of - // a member function. - OldParamHasDfl = false; - if (New->isLocalExternDecl() != Old->isLocalExternDecl()) - // If only one of these is a local function declaration, then they are - // declared in different scopes, even though isDeclInScope may think - // they're in the same scope. (If both are local, the scope check is - // sufficent, and if neither is local, then they are in the same scope.) - OldParamHasDfl = false; - if (OldParamHasDfl && NewParamHasDfl) { - unsigned DiagDefaultParamID = diag::err_param_default_argument_redefinition; @@ -482,7 +513,7 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, // of template class. The new default parameter's value is ignored. Invalid = true; if (getLangOpts().MicrosoftExt) { - CXXMethodDecl* MD = dyn_cast<CXXMethodDecl>(New); + CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(New); if (MD && MD->getParent()->getDescribedClassTemplate()) { // Merge the old default argument into the new parameter. NewParam->setHasInheritedDefaultArg(); @@ -509,14 +540,12 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, // Look for the function declaration where the default argument was // actually written, which may be a declaration prior to Old. - for (FunctionDecl *Older = Old->getPreviousDecl(); - Older; Older = Older->getPreviousDecl()) { - if (!Older->getParamDecl(p)->hasDefaultArg()) - break; - + for (auto Older = PrevForDefaultArgs; + OldParam->hasInheritedDefaultArg(); /**/) { + Older = Older->getPreviousDecl(); OldParam = Older->getParamDecl(p); - } - + } + Diag(OldParam->getLocation(), diag::note_previous_definition) << OldParam->getDefaultArgRange(); } else if (OldParamHasDfl) { @@ -524,7 +553,9 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, // It's important to use getInit() here; getDefaultArg() // strips off any top-level ExprWithCleanups. NewParam->setHasInheritedDefaultArg(); - if (OldParam->hasUninstantiatedDefaultArg()) + if (OldParam->hasUnparsedDefaultArg()) + NewParam->setUnparsedDefaultArg(); + else if (OldParam->hasUninstantiatedDefaultArg()) NewParam->setUninstantiatedDefaultArg( OldParam->getUninstantiatedDefaultArg()); else @@ -535,8 +566,9 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, Diag(NewParam->getLocation(), diag::err_param_default_argument_template_redecl) << NewParam->getDefaultArgRange(); - Diag(Old->getLocation(), diag::note_template_prev_declaration) - << false; + Diag(PrevForDefaultArgs->getLocation(), + diag::note_template_prev_declaration) + << false; } else if (New->getTemplateSpecializationKind() != TSK_ImplicitInstantiation && New->getTemplateSpecializationKind() != TSK_Undeclared) { @@ -607,7 +639,8 @@ bool Sema::MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, << New << New->isConstexpr(); Diag(Old->getLocation(), diag::note_previous_declaration); Invalid = true; - } else if (!Old->isInlined() && New->isInlined() && Old->isDefined(Def)) { + } else if (!Old->getMostRecentDecl()->isInlined() && New->isInlined() && + Old->isDefined(Def)) { // C++11 [dcl.fcn.spec]p4: // If the definition of a function appears in a translation unit before its // first declaration as inline, the program is ill-formed. @@ -689,16 +722,16 @@ void Sema::CheckCXXDefaultArguments(FunctionDecl *FD) { break; } - // C++ [dcl.fct.default]p4: - // In a given function declaration, all parameters - // subsequent to a parameter with a default argument shall - // have default arguments supplied in this or previous - // declarations. A default argument shall not be redefined - // by a later declaration (not even to the same value). + // C++11 [dcl.fct.default]p4: + // In a given function declaration, each parameter subsequent to a parameter + // with a default argument shall have a default argument supplied in this or + // a previous declaration or shall be a function parameter pack. A default + // argument shall not be redefined by a later declaration (not even to the + // same value). unsigned LastMissingDefaultArg = 0; for (; p < NumParams; ++p) { ParmVarDecl *Param = FD->getParamDecl(p); - if (!Param->hasDefaultArg()) { + if (!Param->hasDefaultArg() && !Param->isParameterPack()) { if (Param->isInvalidDecl()) /* We already complained about this parameter. */; else if (Param->getIdentifier()) @@ -795,7 +828,8 @@ bool Sema::CheckConstexprFunctionDecl(const FunctionDecl *NewFD) { // - it shall not be virtual; const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(NewFD); if (Method && Method->isVirtual()) { - Diag(NewFD->getLocation(), diag::err_constexpr_virtual); + Method = Method->getCanonicalDecl(); + Diag(Method->getLocation(), diag::err_constexpr_virtual); // If it's not obvious why this function is virtual, find an overridden // function which uses the 'virtual' keyword. @@ -1545,6 +1579,31 @@ Sema::ActOnBaseSpecifier(Decl *classdecl, SourceRange SpecifierRange, return true; } +/// Use small set to collect indirect bases. As this is only used +/// locally, there's no need to abstract the small size parameter. +typedef llvm::SmallPtrSet<QualType, 4> IndirectBaseSet; + +/// \brief Recursively add the bases of Type. Don't add Type itself. +static void +NoteIndirectBases(ASTContext &Context, IndirectBaseSet &Set, + const QualType &Type) +{ + // Even though the incoming type is a base, it might not be + // a class -- it could be a template parm, for instance. + if (auto Rec = Type->getAs<RecordType>()) { + auto Decl = Rec->getAsCXXRecordDecl(); + + // Iterate over its bases. + for (const auto &BaseSpec : Decl->bases()) { + QualType Base = Context.getCanonicalType(BaseSpec.getType()) + .getUnqualifiedType(); + if (Set.insert(Base).second) + // If we've not already seen it, recurse. + NoteIndirectBases(Context, Set, Base); + } + } +} + /// \brief Performs the actual work of attaching the given base class /// specifiers to a C++ class. bool Sema::AttachBaseSpecifiers(CXXRecordDecl *Class, CXXBaseSpecifier **Bases, @@ -1558,6 +1617,10 @@ bool Sema::AttachBaseSpecifiers(CXXRecordDecl *Class, CXXBaseSpecifier **Bases, // class. std::map<QualType, CXXBaseSpecifier*, QualTypeOrdering> KnownBaseTypes; + // Used to track indirect bases so we can see if a direct base is + // ambiguous. + IndirectBaseSet IndirectBaseTypes; + // Copy non-redundant base specifiers into permanent storage. unsigned NumGoodBases = 0; bool Invalid = false; @@ -1585,6 +1648,11 @@ bool Sema::AttachBaseSpecifiers(CXXRecordDecl *Class, CXXBaseSpecifier **Bases, // Okay, add this new base class. KnownBase = Bases[idx]; Bases[NumGoodBases++] = Bases[idx]; + + // Note this base's direct & indirect bases, if there could be ambiguity. + if (NumBases > 1) + NoteIndirectBases(Context, IndirectBaseTypes, NewBaseType); + if (const RecordType *Record = NewBaseType->getAs<RecordType>()) { const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl()); if (Class->isInterface() && @@ -1605,11 +1673,33 @@ bool Sema::AttachBaseSpecifiers(CXXRecordDecl *Class, CXXBaseSpecifier **Bases, // Attach the remaining base class specifiers to the derived class. Class->setBases(Bases, NumGoodBases); + + for (unsigned idx = 0; idx < NumGoodBases; ++idx) { + // Check whether this direct base is inaccessible due to ambiguity. + QualType BaseType = Bases[idx]->getType(); + CanQualType CanonicalBase = Context.getCanonicalType(BaseType) + .getUnqualifiedType(); + + if (IndirectBaseTypes.count(CanonicalBase)) { + CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, + /*DetectVirtual=*/true); + bool found + = Class->isDerivedFrom(CanonicalBase->getAsCXXRecordDecl(), Paths); + assert(found); + (void)found; + + if (Paths.isAmbiguous(CanonicalBase)) + Diag(Bases[idx]->getLocStart (), diag::warn_inaccessible_base_class) + << BaseType << getAmbiguousPathsDisplayString(Paths) + << Bases[idx]->getSourceRange(); + else + assert(Bases[idx]->isVirtual()); + } - // Delete the remaining (good) base class specifiers, since their - // data has been copied into the CXXRecordDecl. - for (unsigned idx = 0; idx < NumGoodBases; ++idx) + // Delete the base class specifier, since its data has been copied + // into the CXXRecordDecl. Context.Deallocate(Bases[idx]); + } return Invalid; } @@ -1689,18 +1779,6 @@ void Sema::BuildBasePathArray(const CXXBasePaths &Paths, BasePathArray.push_back(const_cast<CXXBaseSpecifier*>(Path[I].Base)); } -/// \brief Determine whether the given base path includes a virtual -/// base class. -bool Sema::BasePathInvolvesVirtualBase(const CXXCastPath &BasePath) { - for (CXXCastPath::const_iterator B = BasePath.begin(), - BEnd = BasePath.end(); - B != BEnd; ++B) - if ((*B)->isVirtual()) - return true; - - return false; -} - /// CheckDerivedToBaseConversion - Check whether the Derived-to-Base /// conversion (where Derived and Base are class types) is /// well-formed, meaning that the conversion is unambiguous (and @@ -2159,7 +2237,8 @@ Sema::ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, assert(Member && "HandleField never returns null"); } } else { - assert(InitStyle == ICIS_NoInit || D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static); + assert(InitStyle == ICIS_NoInit || + D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static); Member = HandleDeclarator(S, D, TemplateParameterLists); if (!Member) @@ -3537,8 +3616,9 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, InitializationKind::CreateDirect(Loc, SourceLocation(), SourceLocation()); Expr *CtorArgE = CtorArg.getAs<Expr>(); - InitializationSequence InitSeq(SemaRef, Entities.back(), InitKind, CtorArgE); - + InitializationSequence InitSeq(SemaRef, Entities.back(), InitKind, + CtorArgE); + ExprResult MemberInit = InitSeq.Perform(SemaRef, Entities.back(), InitKind, MultiExprArg(&CtorArgE, 1)); @@ -4659,15 +4739,15 @@ static void CheckAbstractClassUsage(AbstractUsageInfo &Info, } /// \brief Check class-level dllimport/dllexport attribute. -static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) { +void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) { Attr *ClassAttr = getDLLAttr(Class); // MSVC inherits DLL attributes to partial class template specializations. - if (S.Context.getTargetInfo().getCXXABI().isMicrosoft() && !ClassAttr) { + if (Context.getTargetInfo().getCXXABI().isMicrosoft() && !ClassAttr) { if (auto *Spec = dyn_cast<ClassTemplatePartialSpecializationDecl>(Class)) { if (Attr *TemplateAttr = getDLLAttr(Spec->getSpecializedTemplate()->getTemplatedDecl())) { - auto *A = cast<InheritableAttr>(TemplateAttr->clone(S.getASTContext())); + auto *A = cast<InheritableAttr>(TemplateAttr->clone(getASTContext())); A->setInherited(true); ClassAttr = A; } @@ -4678,12 +4758,12 @@ static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) { return; if (!Class->isExternallyVisible()) { - S.Diag(Class->getLocation(), diag::err_attribute_dll_not_extern) + Diag(Class->getLocation(), diag::err_attribute_dll_not_extern) << Class << ClassAttr; return; } - if (S.Context.getTargetInfo().getCXXABI().isMicrosoft() && + if (Context.getTargetInfo().getCXXABI().isMicrosoft() && !ClassAttr->isInherited()) { // Diagnose dll attributes on members of class with dll attribute. for (Decl *Member : Class->decls()) { @@ -4693,10 +4773,10 @@ static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) { if (!MemberAttr || MemberAttr->isInherited() || Member->isInvalidDecl()) continue; - S.Diag(MemberAttr->getLocation(), + Diag(MemberAttr->getLocation(), diag::err_attribute_dll_member_of_dll_class) << MemberAttr << ClassAttr; - S.Diag(ClassAttr->getLocation(), diag::note_previous_attribute); + Diag(ClassAttr->getLocation(), diag::note_previous_attribute); Member->setInvalidDecl(); } } @@ -4709,15 +4789,20 @@ static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) { const bool ClassExported = ClassAttr->getKind() == attr::DLLExport; const bool ClassImported = !ClassExported; + TemplateSpecializationKind TSK = Class->getTemplateSpecializationKind(); + + // Don't dllexport explicit class template instantiation declarations. + if (ClassExported && TSK == TSK_ExplicitInstantiationDeclaration) { + Class->dropAttr<DLLExportAttr>(); + return; + } + // Force declaration of implicit members so they can inherit the attribute. - S.ForceDeclarationOfImplicitMembers(Class); + ForceDeclarationOfImplicitMembers(Class); // FIXME: MSVC's docs say all bases must be exportable, but this doesn't // seem to be true in practice? - TemplateSpecializationKind TSK = - Class->getTemplateSpecializationKind(); - for (Decl *Member : Class->decls()) { VarDecl *VD = dyn_cast<VarDecl>(Member); CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(Member); @@ -4731,22 +4816,25 @@ static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) { if (MD->isDeleted()) continue; - if (MD->isMoveAssignmentOperator() && ClassImported && MD->isInlined()) { - // Current MSVC versions don't export the move assignment operators, so - // don't attempt to import them if we have a definition. - continue; - } + if (MD->isInlined()) { + // MinGW does not import or export inline methods. + if (!Context.getTargetInfo().getCXXABI().isMicrosoft()) + continue; - if (MD->isInlined() && ClassImported && - !S.Context.getTargetInfo().getCXXABI().isMicrosoft()) { - // MinGW does not import inline functions. - continue; + // MSVC versions before 2015 don't export the move assignment operators, + // so don't attempt to import them if we have a definition. + if (ClassImported && MD->isMoveAssignmentOperator() && + !getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015)) + continue; } } + if (!cast<NamedDecl>(Member)->isExternallyVisible()) + continue; + if (!getDLLAttr(Member)) { auto *NewAttr = - cast<InheritableAttr>(ClassAttr->clone(S.getASTContext())); + cast<InheritableAttr>(ClassAttr->clone(getASTContext())); NewAttr->setInherited(true); Member->addAttr(NewAttr); } @@ -4761,7 +4849,7 @@ static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) { if (TSK == TSK_ImplicitInstantiation && !ClassAttr->isInherited()) continue; - S.MarkFunctionReferenced(Class->getLocation(), MD); + MarkFunctionReferenced(Class->getLocation(), MD); // The function will be passed to the consumer when its definition is // encountered. @@ -4772,11 +4860,17 @@ static void checkDLLAttribute(Sema &S, CXXRecordDecl *Class) { // defaulted methods, and the copy and move assignment operators. The // latter are exported even if they are trivial, because the address of // an operator can be taken and should compare equal accross libraries. - S.MarkFunctionReferenced(Class->getLocation(), MD); + DiagnosticErrorTrap Trap(Diags); + MarkFunctionReferenced(Class->getLocation(), MD); + if (Trap.hasErrorOccurred()) { + Diag(ClassAttr->getLocation(), diag::note_due_to_dllexported_class) + << Class->getName() << !getLangOpts().CPlusPlus11; + break; + } // There is no later point when we will see the definition of this // function, so pass it to the consumer now. - S.Consumer.HandleTopLevelDecl(DeclGroupRef(MD)); + Consumer.HandleTopLevelDecl(DeclGroupRef(MD)); } } } @@ -4820,9 +4914,6 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) { } } - if (Record->isDynamicClass() && !Record->isDependentType()) - DynamicClasses.push_back(Record); - if (Record->getIdentifier()) { // C++ [class.mem]p13: // If T is the name of a class, then each of the following shall have a @@ -4923,7 +5014,7 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) { // have inheriting constructors. DeclareInheritingConstructors(Record); - checkDLLAttribute(*this, Record); + checkClassLevelDLLAttribute(Record); } /// Look up the special member function that would be called by a special @@ -7318,7 +7409,7 @@ bool Sema::isStdInitializerList(QualType Ty, QualType *Element) { StdInitializerList = Template; } - if (Template != StdInitializerList) + if (Template->getCanonicalDecl() != StdInitializerList->getCanonicalDecl()) return false; // This is an instance of std::initializer_list. Find the argument type. @@ -8029,15 +8120,7 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS, if (RequireCompleteDeclContext(SS, LookupContext)) return BuildInvalid(); - // The normal rules do not apply to inheriting constructor declarations. - if (NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName) { - UsingDecl *UD = BuildValid(); - CheckInheritingConstructorUsingDecl(UD); - return UD; - } - - // Otherwise, look up the target name. - + // Look up the target name. LookupResult R(*this, NameInfo, LookupOrdinaryName); // Unlike most lookups, we don't always want to hide tag @@ -8056,8 +8139,12 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS, LookupQualifiedName(R, LookupContext); - // Try to correct typos if possible. - if (R.empty()) { + // Try to correct typos if possible. If constructor name lookup finds no + // results, that means the named class has no explicit constructors, and we + // suppressed declaring implicit ones (probably because it's dependent or + // invalid). + if (R.empty() && + NameInfo.getName().getNameKind() != DeclarationName::CXXConstructorName) { if (TypoCorrection Corrected = CorrectTypo( R.getLookupNameInfo(), R.getLookupKind(), S, &SS, llvm::make_unique<UsingValidatorCCC>( @@ -8087,16 +8174,12 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS, NameInfo.setName(Context.DeclarationNames.getCXXConstructorName( Context.getCanonicalType(Context.getRecordType(RD)))); NameInfo.setNamedTypeInfo(nullptr); - - // Build it and process it as an inheriting constructor. - UsingDecl *UD = BuildValid(); - CheckInheritingConstructorUsingDecl(UD); - return UD; + for (auto *Ctor : LookupConstructors(RD)) + R.addDecl(Ctor); + } else { + // FIXME: Pick up all the declarations if we found an overloaded function. + R.addDecl(ND); } - - // FIXME: Pick up all the declarations if we found an overloaded function. - R.setLookupName(Corrected.getCorrection()); - R.addDecl(ND); } else { Diag(IdentLoc, diag::err_no_member) << NameInfo.getName() << LookupContext << SS.getRange(); @@ -8136,6 +8219,18 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS, } UsingDecl *UD = BuildValid(); + + // The normal rules do not apply to inheriting constructor declarations. + if (NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName) { + // Suppress access diagnostics; the access check is instead performed at the + // point of use for an inheriting constructor. + R.suppressDiagnostics(); + CheckInheritingConstructorUsingDecl(UD); + return UD; + } + + // Otherwise, look up the target name. + for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) { UsingShadowDecl *PrevDecl = nullptr; if (!CheckUsingShadowDecl(UD, *I, Previous, PrevDecl)) @@ -8421,7 +8516,8 @@ Decl *Sema::ActOnAliasDeclaration(Scope *S, SourceLocation UsingLoc, UnqualifiedId &Name, AttributeList *AttrList, - TypeResult Type) { + TypeResult Type, + Decl *DeclFromDeclSpec) { // Skip up to the relevant declaration scope. while (S->getFlags() & Scope::TemplateParamScope) S = S->getParent(); @@ -8549,6 +8645,10 @@ Decl *Sema::ActOnAliasDeclaration(Scope *S, NewND = NewDecl; } else { + if (auto *TD = dyn_cast_or_null<TagDecl>(DeclFromDeclSpec)) { + setTagNameForLinkagePurposes(TD, NewTD); + handleTagNumbering(TD, S); + } ActOnTypedefNameDecl(S, CurContext, NewTD, Previous, Redeclaration); NewND = NewTD; } @@ -9014,7 +9114,7 @@ private: ASTContext &Context = SemaRef.Context; DeclarationName Name = Context.DeclarationNames.getCXXConstructorName( Context.getCanonicalType(Context.getRecordType(Base))); - DeclContext::lookup_const_result Decls = Derived->lookup(Name); + DeclContext::lookup_result Decls = Derived->lookup(Name); return Decls.empty() ? Derived->getLocation() : Decls[0]->getLocation(); } @@ -9363,6 +9463,44 @@ void Sema::ActOnFinishCXXMemberDecls() { } } +static void getDefaultArgExprsForConstructors(Sema &S, CXXRecordDecl *Class) { + // Don't do anything for template patterns. + if (Class->getDescribedClassTemplate()) + return; + + for (Decl *Member : Class->decls()) { + auto *CD = dyn_cast<CXXConstructorDecl>(Member); + if (!CD) { + // Recurse on nested classes. + if (auto *NestedRD = dyn_cast<CXXRecordDecl>(Member)) + getDefaultArgExprsForConstructors(S, NestedRD); + continue; + } else if (!CD->isDefaultConstructor() || !CD->hasAttr<DLLExportAttr>()) { + continue; + } + + for (unsigned I = 0, E = CD->getNumParams(); I != E; ++I) { + // Skip any default arguments that we've already instantiated. + if (S.Context.getDefaultArgExprForConstructor(CD, I)) + continue; + + Expr *DefaultArg = S.BuildCXXDefaultArgExpr(Class->getLocation(), CD, + CD->getParamDecl(I)).get(); + S.Context.addDefaultArgExprForConstructor(CD, I, DefaultArg); + } + } +} + +void Sema::ActOnFinishCXXMemberDefaultArgs(Decl *D) { + auto *RD = dyn_cast<CXXRecordDecl>(D); + + // Default constructors that are annotated with __declspec(dllexport) which + // have default arguments or don't use the standard calling convention are + // wrapped with a thunk called the default constructor closure. + if (RD && Context.getTargetInfo().getCXXABI().isMicrosoft()) + getDefaultArgExprsForConstructors(*this, RD); +} + void Sema::AdjustDestructorExceptionSpec(CXXRecordDecl *ClassDecl, CXXDestructorDecl *Destructor) { assert(getLangOpts().CPlusPlus11 && @@ -9397,8 +9535,8 @@ namespace { // copy/move operators. These classes serve as factory functions and help us // avoid using the same Expr* in the AST twice. class ExprBuilder { - ExprBuilder(const ExprBuilder&) LLVM_DELETED_FUNCTION; - ExprBuilder &operator=(const ExprBuilder&) LLVM_DELETED_FUNCTION; + ExprBuilder(const ExprBuilder&) = delete; + ExprBuilder &operator=(const ExprBuilder&) = delete; protected: static Expr *assertNotNull(Expr *E) { @@ -10101,7 +10239,9 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation, // Assign non-static members. for (auto *Field : ClassDecl->fields()) { - if (Field->isUnnamedBitfield()) + // FIXME: We should form some kind of AST representation for the implied + // memcpy in a union copy operation. + if (Field->isUnnamedBitfield() || Field->getParent()->isUnion()) continue; if (Field->isInvalidDecl()) { @@ -10531,7 +10671,9 @@ void Sema::DefineImplicitMoveAssignment(SourceLocation CurrentLocation, // Assign non-static members. for (auto *Field : ClassDecl->fields()) { - if (Field->isUnnamedBitfield()) + // FIXME: We should form some kind of AST representation for the implied + // memcpy in a union copy operation. + if (Field->isUnnamedBitfield() || Field->getParent()->isUnion()) continue; if (Field->isInvalidDecl()) { @@ -11881,7 +12023,7 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S, // // We just pretend to initialize the object with itself, then make sure // it can be destroyed later. - QualType initType = ExDeclType; + QualType initType = Context.getExceptionObjectType(ExDeclType); InitializedEntity entity = InitializedEntity::InitializeVariable(ExDecl); @@ -13122,7 +13264,8 @@ bool Sema::DefineUsedVTables() { DefinedAnything = true; MarkVirtualMembersReferenced(Loc, Class); CXXRecordDecl *Canonical = cast<CXXRecordDecl>(Class->getCanonicalDecl()); - Consumer.HandleVTable(Class, VTablesUsed[Canonical]); + if (VTablesUsed[Canonical]) + Consumer.HandleVTable(Class); // Optionally warn if we're emitting a weak vtable. if (Class->isExternallyVisible() && |