summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaExprCXX.cpp
diff options
context:
space:
mode:
authorAlp Toker <alp@nuanti.com>2014-01-20 00:24:09 +0000
committerAlp Toker <alp@nuanti.com>2014-01-20 00:24:09 +0000
commit73287bfe40d4737c27458209d1ef9725b14120bc (patch)
treeba8e188ff8145e762b05cef3aebfa1456f45f6b2 /clang/lib/Sema/SemaExprCXX.cpp
parentb4bca4149184305988d77d41351ef8ec0504c094 (diff)
downloadbcm5719-llvm-73287bfe40d4737c27458209d1ef9725b14120bc.tar.gz
bcm5719-llvm-73287bfe40d4737c27458209d1ef9725b14120bc.zip
MSVC 2013 type trait support
Implement type trait primitives used in the latest edition of the Microsoft standard C++ library type_traits header. With this change we can parse much of the Visual Studio 2013 standard headers, particularly anything that includes <type_traits>. Fully implemented, available in all language modes: * __is_constructible() * __is_nothrow_constructible() * __is_nothrow_assignable() Partially implemented, semantic analysis WIP, available as MS extensions: * __is_destructible() * __is_nothrow_destructible() llvm-svn: 199619
Diffstat (limited to 'clang/lib/Sema/SemaExprCXX.cpp')
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp66
1 files changed, 47 insertions, 19 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index f9a3acc93f4..a7723d4b263 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -3156,6 +3156,8 @@ static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT,
case UTT_IsPolymorphic:
case UTT_IsAbstract:
case UTT_IsInterfaceClass:
+ case UTT_IsDestructible:
+ case UTT_IsNothrowDestructible:
// Fall-through
// These traits require a complete type.
@@ -3219,7 +3221,7 @@ static bool HasNoThrowOperator(const RecordType *RT, OverloadedOperatorKind Op,
const FunctionProtoType *CPT =
Operator->getType()->getAs<FunctionProtoType>();
CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
- if (!CPT || !CPT->isNothrow(Self.Context))
+ if (!CPT || !CPT->isNothrow(C))
return false;
}
}
@@ -3421,8 +3423,12 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
return RD->hasTrivialCopyAssignment() &&
!RD->hasNonTrivialCopyAssignment();
return false;
+ case UTT_IsDestructible:
+ case UTT_IsNothrowDestructible:
+ // FIXME: Implement UTT_IsDestructible and UTT_IsNothrowDestructible.
+ // For now, let's fall through.
case UTT_HasTrivialDestructor:
- // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html:
+ // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
// If __is_pod (type) is true or type is a reference type
// then the trait is true, else if type is a cv class or union
// type (or array thereof) with a trivial destructor
@@ -3505,7 +3511,7 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
CPT = Self.ResolveExceptionSpec(KeyLoc, CPT);
if (!CPT)
return false;
- // FIXME: check whether evaluating default arguments can throw.
+ // TODO: check whether evaluating default arguments can throw.
// For now, we'll be conservative and assume that they can throw.
if (!CPT->isNothrow(Self.Context) || CPT->getNumArgs() > 1)
return false;
@@ -3605,6 +3611,8 @@ static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc,
Args[1]->getType(), RParenLoc);
switch (Kind) {
+ case clang::TT_IsConstructible:
+ case clang::TT_IsNothrowConstructible:
case clang::TT_IsTriviallyConstructible: {
// C++11 [meta.unary.prop]:
// is_trivially_constructible is defined as:
@@ -3663,20 +3671,31 @@ static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc,
InitializationSequence Init(S, To, InitKind, ArgExprs);
if (Init.Failed())
return false;
-
+
ExprResult Result = Init.Perform(S, To, InitKind, ArgExprs);
if (Result.isInvalid() || SFINAE.hasErrorOccurred())
return false;
- // Under Objective-C ARC, if the destination has non-trivial Objective-C
- // lifetime, this is a non-trivial construction.
- if (S.getLangOpts().ObjCAutoRefCount &&
- hasNontrivialObjCLifetime(Args[0]->getType().getNonReferenceType()))
- return false;
+ if (Kind == clang::TT_IsConstructible)
+ return true;
+
+ if (Kind == clang::TT_IsNothrowConstructible)
+ return S.canThrow(Result.get()) == CT_Cannot;
- // The initialization succeeded; now make sure there are no non-trivial
- // calls.
- return !Result.get()->hasNonTrivialCall(S.Context);
+ if (Kind == clang::TT_IsTriviallyConstructible) {
+ // Under Objective-C ARC, if the destination has non-trivial Objective-C
+ // lifetime, this is a non-trivial construction.
+ if (S.getLangOpts().ObjCAutoRefCount &&
+ hasNontrivialObjCLifetime(Args[0]->getType().getNonReferenceType()))
+ return false;
+
+ // The initialization succeeded; now make sure there are no non-trivial
+ // calls.
+ return !Result.get()->hasNonTrivialCall(S.Context);
+ }
+
+ llvm_unreachable("unhandled type trait");
+ return false;
}
default: llvm_unreachable("not a TT");
}
@@ -3831,7 +3850,8 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
ExprResult Result = Init.Perform(Self, To, Kind, FromPtr);
return !Result.isInvalid() && !SFINAE.hasErrorOccurred();
}
-
+
+ case BTT_IsNothrowAssignable:
case BTT_IsTriviallyAssignable: {
// C++11 [meta.unary.prop]p3:
// is_trivially_assignable is defined as:
@@ -3877,13 +3897,21 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
if (Result.isInvalid() || SFINAE.hasErrorOccurred())
return false;
- // Under Objective-C ARC, if the destination has non-trivial Objective-C
- // lifetime, this is a non-trivial assignment.
- if (Self.getLangOpts().ObjCAutoRefCount &&
- hasNontrivialObjCLifetime(LhsT.getNonReferenceType()))
- return false;
+ if (BTT == BTT_IsNothrowAssignable)
+ return Self.canThrow(Result.get()) == CT_Cannot;
- return !Result.get()->hasNonTrivialCall(Self.Context);
+ if (BTT == BTT_IsTriviallyAssignable) {
+ // Under Objective-C ARC, if the destination has non-trivial Objective-C
+ // lifetime, this is a non-trivial assignment.
+ if (Self.getLangOpts().ObjCAutoRefCount &&
+ hasNontrivialObjCLifetime(LhsT.getNonReferenceType()))
+ return false;
+
+ return !Result.get()->hasNonTrivialCall(Self.Context);
+ }
+
+ llvm_unreachable("unhandled type trait");
+ return false;
}
default: llvm_unreachable("not a BTT");
}
OpenPOWER on IntegriCloud