aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2011-03-23 19:50:54 +0000
committerFariborz Jahanian <fjahanian@apple.com>2011-03-23 19:50:54 +0000
commitd97f558f48865aa96e7bdf9c1c9315790c3d77c9 (patch)
tree176d8051874c0a21a5ddcb1e3376ad1e375b5aea /lib/Sema/SemaOverload.cpp
parent31798a6bddc5265c50ece1aecf4d2abc66be7554 (diff)
Support for Transparent unions used as overloadable
function parameter. // rdar:// 9129552 and PR9406. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128159 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r--lib/Sema/SemaOverload.cpp43
1 files changed, 41 insertions, 2 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 7a4e68d3cb..6fa78a9a46 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -48,6 +48,12 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
bool InOverloadResolution,
StandardConversionSequence &SCS,
bool CStyle);
+
+static bool IsTransparentUnionStandardConversion(Sema &S, Expr* From,
+ QualType &ToType,
+ bool InOverloadResolution,
+ StandardConversionSequence &SCS,
+ bool CStyle);
static OverloadingResult
IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
UserDefinedConversionSequence& User,
@@ -128,7 +134,9 @@ ImplicitConversionRank GetConversionRank(ImplicitConversionKind Kind) {
ICR_Conversion,
ICR_Conversion,
ICR_Conversion,
- ICR_Complex_Real_Conversion
+ ICR_Complex_Real_Conversion,
+ ICR_Conversion,
+ ICR_Conversion
};
return Rank[(int)Kind];
}
@@ -157,7 +165,9 @@ const char* GetImplicitConversionName(ImplicitConversionKind Kind) {
"Derived-to-base conversion",
"Vector conversion",
"Vector splat",
- "Complex-real conversion"
+ "Complex-real conversion",
+ "Block Pointer conversion",
+ "Transparent Union Conversion"
};
return Name[Kind];
}
@@ -1203,6 +1213,11 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
} else if (IsNoReturnConversion(S.Context, FromType, ToType, FromType)) {
// Treat a conversion that strips "noreturn" as an identity conversion.
SCS.Second = ICK_NoReturn_Adjustment;
+ } else if (IsTransparentUnionStandardConversion(S, From, ToType,
+ InOverloadResolution,
+ SCS, CStyle)) {
+ SCS.Second = ICK_TransparentUnionConversion;
+ FromType = ToType;
} else {
// No second conversion required.
SCS.Second = ICK_Identity;
@@ -1244,6 +1259,30 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
return true;
}
+
+static bool
+IsTransparentUnionStandardConversion(Sema &S, Expr* From,
+ QualType &ToType,
+ bool InOverloadResolution,
+ StandardConversionSequence &SCS,
+ bool CStyle) {
+
+ const RecordType *UT = ToType->getAsUnionType();
+ if (!UT || !UT->getDecl()->hasAttr<TransparentUnionAttr>())
+ return false;
+ // The field to initialize within the transparent union.
+ RecordDecl *UD = UT->getDecl();
+ // It's compatible if the expression matches any of the fields.
+ for (RecordDecl::field_iterator it = UD->field_begin(),
+ itend = UD->field_end();
+ it != itend; ++it) {
+ if (IsStandardConversion(S, From, it->getType(), InOverloadResolution, SCS, CStyle)) {
+ ToType = it->getType();
+ return true;
+ }
+ }
+ return false;
+}
/// IsIntegralPromotion - Determines whether the conversion from the
/// expression From (whose potentially-adjusted type is FromType) to