diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 33 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 21 |
5 files changed, 57 insertions, 9 deletions
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 0e839a9..a802679 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -3243,8 +3243,10 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, for (FunctionProtoType::arg_type_iterator AI = FT->arg_type_begin(), AE = FT->arg_type_end(); AI != AE; ++AI) { ParmVarDecl *Param = ParmVarDecl::Create(Context, NewFD, - SourceLocation(), 0, - *AI, /*TInfo=*/0, + D.getIdentifierLoc(), 0, + *AI, + Context.getTrivialTypeSourceInfo(*AI, + D.getIdentifierLoc()), VarDecl::None, VarDecl::None, 0); Param->setImplicit(); diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 6259b85a..b9c7d79 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -4134,13 +4134,16 @@ void Sema::DefineImplicitDestructor(SourceLocation CurrentLocation, /// /// \param From The expression we are copying from. /// +/// \param CopyingBaseSubobject Whether we're copying a base subobject. +/// Otherwise, it's a non-static member subobject. +/// /// \param Depth Internal parameter recording the depth of the recursion. /// /// \returns A statement or a loop that copies the expressions. static Sema::OwningStmtResult BuildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T, Sema::OwningExprResult To, Sema::OwningExprResult From, - unsigned Depth = 0) { + bool CopyingBaseSubobject, unsigned Depth = 0) { typedef Sema::OwningStmtResult OwningStmtResult; typedef Sema::OwningExprResult OwningExprResult; @@ -4172,6 +4175,25 @@ BuildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T, } F.done(); + // Suppress the protected check (C++ [class.protected]) for each of the + // assignment operators we found. This strange dance is required when + // we're assigning via a base classes's copy-assignment operator. To + // ensure that we're getting the right base class subobject (without + // ambiguities), we need to cast "this" to that subobject type; to + // ensure that we don't go through the virtual call mechanism, we need + // to qualify the operator= name with the base class (see below). However, + // this means that if the base class has a protected copy assignment + // operator, the protected member access check will fail. So, we + // rewrite "protected" access to "public" access in this case, since we + // know by construction that we're calling from a derived class. + if (CopyingBaseSubobject) { + for (LookupResult::iterator L = OpLookup.begin(), LEnd = OpLookup.end(); + L != LEnd; ++L) { + if (L.getAccess() == AS_protected) + L.setAccess(AS_public); + } + } + // Create the nested-name-specifier that will be used to qualify the // reference to operator=; this is required to suppress the virtual // call mechanism. @@ -4277,7 +4299,8 @@ BuildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T, // Build the copy for an individual element of the array. OwningStmtResult Copy = BuildSingleCopyAssign(S, Loc, ArrayTy->getElementType(), - move(To), move(From), Depth+1); + move(To), move(From), + CopyingBaseSubobject, Depth+1); if (Copy.isInvalid()) { InitStmt->Destroy(S.Context); return S.StmtError(); @@ -4381,7 +4404,8 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation, // Build the copy. OwningStmtResult Copy = BuildSingleCopyAssign(*this, Loc, BaseType, - move(To), Owned(From)); + move(To), Owned(From), + /*CopyingBaseSubobject=*/true); if (Copy.isInvalid()) { Invalid = true; continue; @@ -4501,7 +4525,8 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation, // Build the copy of this field. OwningStmtResult Copy = BuildSingleCopyAssign(*this, Loc, FieldType, - move(To), move(From)); + move(To), move(From), + /*CopyingBaseSubobject=*/false); if (Copy.isInvalid()) { Invalid = true; continue; diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index c4ab03f..869d6df 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -3565,8 +3565,8 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, if (BinaryOperator *BO = dyn_cast<BinaryOperator>(NakedFn)) { if (BO->getOpcode() == BinaryOperator::PtrMemD || BO->getOpcode() == BinaryOperator::PtrMemI) { - if (const FunctionProtoType *FPT = - dyn_cast<FunctionProtoType>(BO->getType())) { + if (const FunctionProtoType *FPT + = BO->getType()->getAs<FunctionProtoType>()) { QualType ResultTy = FPT->getResultType().getNonReferenceType(); ExprOwningPtr<CXXMemberCallExpr> diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 21f2a51..b87fa7d 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -6513,7 +6513,7 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, MemExpr->setBase(ObjectArg); // Convert the rest of the arguments - const FunctionProtoType *Proto = cast<FunctionProtoType>(Method->getType()); + const FunctionProtoType *Proto = Method->getType()->getAs<FunctionProtoType>(); if (ConvertArgumentsForCall(&*TheCall, MemExpr, Method, Proto, Args, NumArgs, RParenLoc)) return ExprError(); diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 8b851b2..da84806 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1169,6 +1169,27 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, return 0; QualType T = TInfo->getType(); + // \brief If the type of this function is not *directly* a function + // type, then we're instantiating the a function that was declared + // via a typedef, e.g., + // + // typedef int functype(int, int); + // functype func; + // + // In this case, we'll just go instantiate the ParmVarDecls that we + // synthesized in the method declaration. + if (!isa<FunctionProtoType>(T)) { + assert(!Params.size() && "Instantiating type could not yield parameters"); + for (unsigned I = 0, N = D->getNumParams(); I != N; ++I) { + ParmVarDecl *P = SemaRef.SubstParmVarDecl(D->getParamDecl(I), + TemplateArgs); + if (!P) + return 0; + + Params.push_back(P); + } + } + NestedNameSpecifier *Qualifier = D->getQualifier(); if (Qualifier) { Qualifier = SemaRef.SubstNestedNameSpecifier(Qualifier, |