summaryrefslogtreecommitdiffstats
path: root/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/SemaDecl.cpp6
-rw-r--r--lib/Sema/SemaDeclCXX.cpp33
-rw-r--r--lib/Sema/SemaExpr.cpp4
-rw-r--r--lib/Sema/SemaOverload.cpp2
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp21
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,
OpenPOWER on IntegriCloud