summaryrefslogtreecommitdiffstats
path: root/lib/Sema
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2010-03-06 09:23:02 +0000
committerrdivacky <rdivacky@FreeBSD.org>2010-03-06 09:23:02 +0000
commitd2e6cf1d1c6468396ec057119c32aa58b1ee5ac9 (patch)
tree7e0a88c3c6cb70271946aaa95a231b3da55d9f91 /lib/Sema
parentdf90325d4c0a65ee64d2dae3ed9b5b34f7418533 (diff)
downloadFreeBSD-src-d2e6cf1d1c6468396ec057119c32aa58b1ee5ac9.zip
FreeBSD-src-d2e6cf1d1c6468396ec057119c32aa58b1ee5ac9.tar.gz
Update clang to r97873.
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/Sema.h8
-rw-r--r--lib/Sema/SemaDeclCXX.cpp31
-rw-r--r--lib/Sema/SemaExpr.cpp134
-rw-r--r--lib/Sema/SemaExprCXX.cpp2
-rw-r--r--lib/Sema/SemaInit.cpp3
-rw-r--r--lib/Sema/SemaOverload.cpp41
-rw-r--r--lib/Sema/SemaType.cpp3
-rw-r--r--lib/Sema/TreeTransform.h2
8 files changed, 169 insertions, 55 deletions
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index efd04e8..a94d07a 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -1097,12 +1097,16 @@ public:
ImplicitConversionSequence
TryObjectArgumentInitialization(QualType FromType, CXXMethodDecl *Method,
CXXRecordDecl *ActingContext);
- bool PerformObjectArgumentInitialization(Expr *&From, CXXMethodDecl *Method);
+ bool PerformObjectArgumentInitialization(Expr *&From,
+ NestedNameSpecifier *Qualifier,
+ CXXMethodDecl *Method);
ImplicitConversionSequence TryContextuallyConvertToBool(Expr *From);
bool PerformContextuallyConvertToBool(Expr *&From);
- bool PerformObjectMemberConversion(Expr *&From, NamedDecl *Member);
+ bool PerformObjectMemberConversion(Expr *&From,
+ NestedNameSpecifier *Qualifier,
+ NamedDecl *Member);
// Members have to be NamespaceDecl* or TranslationUnitDecl*.
// TODO: make this is a typesafe union.
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index 574b225..0708d41 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -5212,14 +5212,35 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S, QualType ExDeclType,
AbstractVariableType))
Invalid = true;
- // FIXME: Need to test for ability to copy-construct and destroy the
- // exception variable.
-
- // FIXME: Need to check for abstract classes.
-
VarDecl *ExDecl = VarDecl::Create(Context, CurContext, Loc,
Name, ExDeclType, TInfo, VarDecl::None);
+ if (!Invalid) {
+ if (const RecordType *RecordTy = ExDeclType->getAs<RecordType>()) {
+ // C++ [except.handle]p16:
+ // The object declared in an exception-declaration or, if the
+ // exception-declaration does not specify a name, a temporary (12.2) is
+ // copy-initialized (8.5) from the exception object. [...]
+ // The object is destroyed when the handler exits, after the destruction
+ // of any automatic objects initialized within the handler.
+ //
+ // We just pretend to initialize the object with itself, then make sure
+ // it can be destroyed later.
+ InitializedEntity Entity = InitializedEntity::InitializeVariable(ExDecl);
+ Expr *ExDeclRef = DeclRefExpr::Create(Context, 0, SourceRange(), ExDecl,
+ Loc, ExDeclType, 0);
+ InitializationKind Kind = InitializationKind::CreateCopy(Loc,
+ SourceLocation());
+ InitializationSequence InitSeq(*this, Entity, Kind, &ExDeclRef, 1);
+ OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+ MultiExprArg(*this, (void**)&ExDeclRef, 1));
+ if (Result.isInvalid())
+ Invalid = true;
+ else
+ FinalizeVarWithDestructor(ExDecl, RecordTy);
+ }
+ }
+
if (Invalid)
ExDecl->setInvalidDecl();
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index d9464ad..10001c3 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -635,7 +635,7 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
MemberType = Context.getQualifiedType(MemberType, NewQuals);
MarkDeclarationReferenced(Loc, *FI);
- PerformObjectMemberConversion(Result, *FI);
+ PerformObjectMemberConversion(Result, /*FIXME:Qualifier=*/0, *FI);
// FIXME: Might this end up being a qualified name?
Result = new (Context) MemberExpr(Result, BaseObjectIsPointer, *FI,
OpLoc, MemberType);
@@ -1357,29 +1357,111 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
/// \brief Cast member's object to its own class if necessary.
bool
-Sema::PerformObjectMemberConversion(Expr *&From, NamedDecl *Member) {
- if (FieldDecl *FD = dyn_cast<FieldDecl>(Member))
- if (CXXRecordDecl *RD =
- dyn_cast<CXXRecordDecl>(FD->getDeclContext())) {
- QualType DestType =
- Context.getCanonicalType(Context.getTypeDeclType(RD));
- if (DestType->isDependentType() || From->getType()->isDependentType())
- return false;
- QualType FromRecordType = From->getType();
- QualType DestRecordType = DestType;
- if (FromRecordType->getAs<PointerType>()) {
- DestType = Context.getPointerType(DestType);
- FromRecordType = FromRecordType->getPointeeType();
- }
- if (!Context.hasSameUnqualifiedType(FromRecordType, DestRecordType) &&
- CheckDerivedToBaseConversion(FromRecordType,
- DestRecordType,
- From->getSourceRange().getBegin(),
- From->getSourceRange()))
- return true;
- ImpCastExprToType(From, DestType, CastExpr::CK_DerivedToBase,
- /*isLvalue=*/true);
+Sema::PerformObjectMemberConversion(Expr *&From,
+ NestedNameSpecifier *Qualifier,
+ NamedDecl *Member) {
+ CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Member->getDeclContext());
+ if (!RD)
+ return false;
+
+ QualType DestRecordType;
+ QualType DestType;
+ QualType FromRecordType;
+ QualType FromType = From->getType();
+ bool PointerConversions = false;
+ if (isa<FieldDecl>(Member)) {
+ DestRecordType = Context.getCanonicalType(Context.getTypeDeclType(RD));
+
+ if (FromType->getAs<PointerType>()) {
+ DestType = Context.getPointerType(DestRecordType);
+ FromRecordType = FromType->getPointeeType();
+ PointerConversions = true;
+ } else {
+ DestType = DestRecordType;
+ FromRecordType = FromType;
}
+ } else if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Member)) {
+ if (Method->isStatic())
+ return false;
+
+ DestType = Method->getThisType(Context);
+ DestRecordType = DestType->getPointeeType();
+
+ if (FromType->getAs<PointerType>()) {
+ FromRecordType = FromType->getPointeeType();
+ PointerConversions = true;
+ } else {
+ FromRecordType = FromType;
+ DestType = DestRecordType;
+ }
+ } else {
+ // No conversion necessary.
+ return false;
+ }
+
+ if (DestType->isDependentType() || FromType->isDependentType())
+ return false;
+
+ // If the unqualified types are the same, no conversion is necessary.
+ if (Context.hasSameUnqualifiedType(FromRecordType, DestRecordType))
+ return false;
+
+ // C++ [class.member.lookup]p8:
+ // [...] Ambiguities can often be resolved by qualifying a name with its
+ // class name.
+ //
+ // If the member was a qualified name and the qualified referred to a
+ // specific base subobject type, we'll cast to that intermediate type
+ // first and then to the object in which the member is declared. That allows
+ // one to resolve ambiguities in, e.g., a diamond-shaped hierarchy such as:
+ //
+ // class Base { public: int x; };
+ // class Derived1 : public Base { };
+ // class Derived2 : public Base { };
+ // class VeryDerived : public Derived1, public Derived2 { void f(); };
+ //
+ // void VeryDerived::f() {
+ // x = 17; // error: ambiguous base subobjects
+ // Derived1::x = 17; // okay, pick the Base subobject of Derived1
+ // }
+ QualType IntermediateRecordType;
+ QualType IntermediateType;
+ if (Qualifier) {
+ if (const RecordType *IntermediateRecord
+ = Qualifier->getAsType()->getAs<RecordType>()) {
+ IntermediateRecordType = QualType(IntermediateRecord, 0);
+ IntermediateType = IntermediateRecordType;
+ if (PointerConversions)
+ IntermediateType = Context.getPointerType(IntermediateType);
+ }
+ }
+
+ if (!IntermediateType.isNull() &&
+ IsDerivedFrom(FromRecordType, IntermediateRecordType) &&
+ IsDerivedFrom(IntermediateRecordType, DestRecordType)) {
+ if (CheckDerivedToBaseConversion(FromRecordType, IntermediateRecordType,
+ From->getSourceRange().getBegin(),
+ From->getSourceRange()) ||
+ CheckDerivedToBaseConversion(IntermediateRecordType, DestRecordType,
+ From->getSourceRange().getBegin(),
+ From->getSourceRange()))
+ return true;
+
+ ImpCastExprToType(From, IntermediateType, CastExpr::CK_DerivedToBase,
+ /*isLvalue=*/!PointerConversions);
+ ImpCastExprToType(From, DestType, CastExpr::CK_DerivedToBase,
+ /*isLvalue=*/!PointerConversions);
+ return false;
+ }
+
+ if (CheckDerivedToBaseConversion(FromRecordType,
+ DestRecordType,
+ From->getSourceRange().getBegin(),
+ From->getSourceRange()))
+ return true;
+
+ ImpCastExprToType(From, DestType, CastExpr::CK_DerivedToBase,
+ /*isLvalue=*/true);
return false;
}
@@ -1609,7 +1691,7 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
return ExprError();
}
- if (VD->getType()->isArrayType()) {
+ if (VD->getType()->isArrayType() && !VD->hasAttr<BlocksAttr>()) {
Diag(Loc, diag::err_ref_array_type);
Diag(D->getLocation(), diag::note_declared_at);
return ExprError();
@@ -2666,7 +2748,7 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType,
}
MarkDeclarationReferenced(MemberLoc, FD);
- if (PerformObjectMemberConversion(BaseExpr, FD))
+ if (PerformObjectMemberConversion(BaseExpr, Qualifier, FD))
return ExprError();
return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
FD, MemberLoc, MemberType));
@@ -6651,7 +6733,7 @@ Sema::OwningExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
Res = BuildAnonymousStructUnionMemberReference(
OC.LocEnd, MemberDecl, Res, OC.LocEnd).takeAs<Expr>();
} else {
- PerformObjectMemberConversion(Res, MemberDecl);
+ PerformObjectMemberConversion(Res, /*Qualifier=*/0, MemberDecl);
// MemberDecl->getType() doesn't get the right qualifiers, but it
// doesn't matter here.
Res = new (Context) MemberExpr(Res, false, MemberDecl, OC.LocEnd,
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 5f46019..309da29 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -2881,7 +2881,7 @@ Sema::OwningExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, ExprArg Base,
CXXMemberCallExpr *Sema::BuildCXXMemberCallExpr(Expr *Exp,
CXXMethodDecl *Method) {
- if (PerformObjectArgumentInitialization(Exp, Method))
+ if (PerformObjectArgumentInitialization(Exp, /*Qualifier=*/0, Method))
assert(0 && "Calling BuildCXXMemberCallExpr with invalid call?");
MemberExpr *ME =
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 0f8107a..bf9f73c 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -3365,7 +3365,8 @@ InitializationSequence::Perform(Sema &S,
// FIXME: Should we move this initialization into a separate
// derived-to-base conversion? I believe the answer is "no", because
// we don't want to turn off access control here for c-style casts.
- if (S.PerformObjectArgumentInitialization(CurInitExpr, Conversion))
+ if (S.PerformObjectArgumentInitialization(CurInitExpr, /*Qualifier=*/0,
+ Conversion))
return S.ExprError();
// Do a little dance to make sure that CurInit has the proper
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index ed0d137..ff59fc3 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -1282,8 +1282,8 @@ bool Sema::CheckPointerConversion(Expr *From, QualType ToType,
QualType FromPointeeType = FromPtrType->getPointeeType(),
ToPointeeType = ToPtrType->getPointeeType();
- if (FromPointeeType->isRecordType() &&
- ToPointeeType->isRecordType()) {
+ if (FromPointeeType->isRecordType() && ToPointeeType->isRecordType() &&
+ !Context.hasSameUnqualifiedType(FromPointeeType, ToPointeeType)) {
// We must have a derived-to-base conversion. Check an
// ambiguous or inaccessible conversion.
if (CheckDerivedToBaseConversion(FromPointeeType, ToPointeeType,
@@ -2304,7 +2304,9 @@ Sema::TryObjectArgumentInitialization(QualType OrigFromType,
/// the implicit object parameter for the given Method with the given
/// expression.
bool
-Sema::PerformObjectArgumentInitialization(Expr *&From, CXXMethodDecl *Method) {
+Sema::PerformObjectArgumentInitialization(Expr *&From,
+ NestedNameSpecifier *Qualifier,
+ CXXMethodDecl *Method) {
QualType FromRecordType, DestType;
QualType ImplicitParamRecordType =
Method->getThisType(Context)->getAs<PointerType>()->getPointeeType();
@@ -2327,15 +2329,12 @@ Sema::PerformObjectArgumentInitialization(Expr *&From, CXXMethodDecl *Method) {
diag::err_implicit_object_parameter_init)
<< ImplicitParamRecordType << FromRecordType << From->getSourceRange();
- if (ICS.Standard.Second == ICK_Derived_To_Base &&
- CheckDerivedToBaseConversion(FromRecordType,
- ImplicitParamRecordType,
- From->getSourceRange().getBegin(),
- From->getSourceRange()))
- return true;
+ if (ICS.Standard.Second == ICK_Derived_To_Base)
+ return PerformObjectMemberConversion(From, Qualifier, Method);
- ImpCastExprToType(From, DestType, CastExpr::CK_DerivedToBase,
- /*isLvalue=*/true);
+ if (!Context.hasSameType(From->getType(), DestType))
+ ImpCastExprToType(From, DestType, CastExpr::CK_NoOp,
+ /*isLvalue=*/!From->getType()->getAs<PointerType>());
return false;
}
@@ -5545,7 +5544,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn,
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(FnDecl)) {
CheckMemberOperatorAccess(OpLoc, Args[0], Method, Best->getAccess());
- if (PerformObjectArgumentInitialization(Input, Method))
+ if (PerformObjectArgumentInitialization(Input, /*Qualifier=*/0, Method))
return ExprError();
} else {
// Convert the arguments.
@@ -5738,7 +5737,8 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
if (Arg1.isInvalid())
return ExprError();
- if (PerformObjectArgumentInitialization(Args[0], Method))
+ if (PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/0,
+ Method))
return ExprError();
Args[1] = RHS = Arg1.takeAs<Expr>();
@@ -5904,7 +5904,8 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
// Convert the arguments.
CXXMethodDecl *Method = cast<CXXMethodDecl>(FnDecl);
- if (PerformObjectArgumentInitialization(Args[0], Method))
+ if (PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/0,
+ Method))
return ExprError();
// Convert the arguments.
@@ -6009,12 +6010,15 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
MemberExpr *MemExpr;
CXXMethodDecl *Method = 0;
+ NestedNameSpecifier *Qualifier = 0;
if (isa<MemberExpr>(NakedMemExpr)) {
MemExpr = cast<MemberExpr>(NakedMemExpr);
Method = cast<CXXMethodDecl>(MemExpr->getMemberDecl());
+ Qualifier = MemExpr->getQualifier();
} else {
UnresolvedMemberExpr *UnresExpr = cast<UnresolvedMemberExpr>(NakedMemExpr);
-
+ Qualifier = UnresExpr->getQualifier();
+
QualType ObjectType = UnresExpr->getBaseType();
// Add overload candidates
@@ -6113,7 +6117,7 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
// Convert the object argument (for a non-static member function call).
Expr *ObjectArg = MemExpr->getBase();
if (!Method->isStatic() &&
- PerformObjectArgumentInitialization(ObjectArg, Method))
+ PerformObjectArgumentInitialization(ObjectArg, Qualifier, Method))
return ExprError();
MemExpr->setBase(ObjectArg);
@@ -6333,7 +6337,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
bool IsError = false;
// Initialize the implicit object parameter.
- IsError |= PerformObjectArgumentInitialization(Object, Method);
+ IsError |= PerformObjectArgumentInitialization(Object, /*Qualifier=*/0,
+ Method);
TheCall->setArg(0, Object);
@@ -6458,7 +6463,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, ExprArg BaseIn, SourceLocation OpLoc) {
// Convert the object parameter.
CXXMethodDecl *Method = cast<CXXMethodDecl>(Best->Function);
- if (PerformObjectArgumentInitialization(Base, Method))
+ if (PerformObjectArgumentInitialization(Base, /*Qualifier=*/0, Method))
return ExprError();
// No concerns about early exits now.
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 2fb5c84..a79853a 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -1034,7 +1034,8 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
const ObjCInterfaceType *OIT = T->getAs<ObjCInterfaceType>();
T = Context.getObjCObjectPointerType(T,
(ObjCProtocolDecl **)OIT->qual_begin(),
- OIT->getNumProtocols());
+ OIT->getNumProtocols(),
+ DeclType.Ptr.TypeQuals);
break;
}
T = BuildPointerType(T, DeclType.Ptr.TypeQuals, DeclType.Loc, Name);
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 2f3c482..24ea62c 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -969,7 +969,7 @@ public:
assert(!Qualifier && "Can't have an unnamed field with a qualifier!");
Expr *BaseExpr = Base.takeAs<Expr>();
- if (getSema().PerformObjectMemberConversion(BaseExpr, Member))
+ if (getSema().PerformObjectMemberConversion(BaseExpr, Qualifier, Member))
return getSema().ExprError();
MemberExpr *ME =
OpenPOWER on IntegriCloud