summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2009-04-16 17:51:27 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2009-04-16 17:51:27 +0000
commit1a99f441e64c853f5f7a029c4e159db8209aa685 (patch)
tree73b614ae91c7147f477eada462b643a5b7da49c4 /clang/lib/Sema/SemaOverload.cpp
parent8d25b096fa022b4d9af53470067d0a15cf26f588 (diff)
downloadbcm5719-llvm-1a99f441e64c853f5f7a029c4e159db8209aa685.tar.gz
bcm5719-llvm-1a99f441e64c853f5f7a029c4e159db8209aa685.zip
Fix a crash bug when comparing overload quality of conversion operators with conversion constructors.
Remove an atrocious amount of trailing whitespace in the overloaded operator mangler. Sorry, couldn't help myself. Change the DeclType parameter of Sema::CheckReferenceInit to be passed by value instead of reference. It wasn't changed anywhere. Let the parser handle C++'s irregular grammar around assignment-expression and conditional-expression. And finally, the reason for all this stuff: implement C++ semantics for the conditional operator. The implementation is complete except for determining lvalueness. llvm-svn: 69299
Diffstat (limited to 'clang/lib/Sema/SemaOverload.cpp')
-rw-r--r--clang/lib/Sema/SemaOverload.cpp61
1 files changed, 49 insertions, 12 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 70c9ee7ef9a..6e2e72040ed 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -2026,15 +2026,19 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,
"Use AddConversionCandidate for conversion functions");
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Function)) {
- // If we get here, it's because we're calling a member function
- // that is named without a member access expression (e.g.,
- // "this->f") that was either written explicitly or created
- // implicitly. This can happen with a qualified call to a member
- // function, e.g., X::f(). We use a NULL object as the implied
- // object argument (C++ [over.call.func]p3).
- AddMethodCandidate(Method, 0, Args, NumArgs, CandidateSet,
- SuppressUserConversions, ForceRValue);
- return;
+ if (!isa<CXXConstructorDecl>(Method)) {
+ // If we get here, it's because we're calling a member function
+ // that is named without a member access expression (e.g.,
+ // "this->f") that was either written explicitly or created
+ // implicitly. This can happen with a qualified call to a member
+ // function, e.g., X::f(). We use a NULL object as the implied
+ // object argument (C++ [over.call.func]p3).
+ AddMethodCandidate(Method, 0, Args, NumArgs, CandidateSet,
+ SuppressUserConversions, ForceRValue);
+ return;
+ }
+ // We treat a constructor like a non-member function, since its object
+ // argument doesn't participate in overload resolution.
}
@@ -2127,8 +2131,10 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, Expr *Object,
const FunctionProtoType* Proto
= dyn_cast<FunctionProtoType>(Method->getType()->getAsFunctionType());
assert(Proto && "Methods without a prototype cannot be overloaded");
- assert(!isa<CXXConversionDecl>(Method) &&
+ assert(!isa<CXXConversionDecl>(Method) &&
"Use AddConversionCandidate for conversion functions");
+ assert(!isa<CXXConstructorDecl>(Method) &&
+ "Use AddOverloadCandidate for constructors");
// Add this candidate
CandidateSet.push_back(OverloadCandidate());
@@ -2664,7 +2670,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
Op == OO_Plus || (Op == OO_Minus && NumArgs == 2) || Op == OO_Equal ||
Op == OO_PlusEqual || Op == OO_MinusEqual || Op == OO_Subscript ||
Op == OO_ArrowStar || Op == OO_PlusPlus || Op == OO_MinusMinus ||
- (Op == OO_Star && NumArgs == 1)) {
+ (Op == OO_Star && NumArgs == 1) || Op == OO_Conditional) {
for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx)
CandidateTypes.AddTypesConvertedFrom(Args[ArgIdx]->getType(),
true,
@@ -2939,6 +2945,7 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
case OO_Slash:
BinaryStar:
+ Conditional:
// C++ [over.built]p12:
//
// For every pair of promoted arithmetic types L and R, there
@@ -2957,6 +2964,17 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
//
// where LR is the result of the usual arithmetic conversions
// between types L and R.
+ //
+ // C++ [over.built]p24:
+ //
+ // For every pair of promoted arithmetic types L and R, there exist
+ // candidate operator functions of the form
+ //
+ // LR operator?(bool, L, R);
+ //
+ // where LR is the result of the usual arithmetic conversions
+ // between types L and R.
+ // Our candidates ignore the first parameter.
for (unsigned Left = FirstPromotedArithmeticType;
Left < LastPromotedArithmeticType; ++Left) {
for (unsigned Right = FirstPromotedArithmeticType;
@@ -3201,6 +3219,25 @@ Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op,
case OO_ArrowStar:
// FIXME: No support for pointer-to-members yet.
break;
+
+ case OO_Conditional:
+ // Note that we don't consider the first argument, since it has been
+ // contextually converted to bool long ago. The candidates below are
+ // therefore added as binary.
+ //
+ // C++ [over.built]p24:
+ // For every type T, where T is a pointer or pointer-to-member type,
+ // there exist candidate operator functions of the form
+ //
+ // T operator?(bool, T, T);
+ //
+ // FIXME: pointer-to-member
+ for (BuiltinCandidateTypeSet::iterator Ptr = CandidateTypes.pointer_begin(),
+ E = CandidateTypes.pointer_end(); Ptr != E; ++Ptr) {
+ QualType ParamTypes[2] = { *Ptr, *Ptr };
+ AddBuiltinCandidate(*Ptr, ParamTypes, Args, 2, CandidateSet);
+ }
+ goto Conditional;
}
}
@@ -3852,7 +3889,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
// Perform overload resolution.
OverloadCandidateSet::iterator Best;
switch (BestViableFunction(CandidateSet, Best)) {
- case OR_Success: {
+ case OR_Success: {
// We found a built-in operator or an overloaded operator.
FunctionDecl *FnDecl = Best->Function;
OpenPOWER on IntegriCloud