[cfe-commits] r130057 - in /cfe/trunk: include/clang/AST/DeclCXX.h include/clang/AST/Type.h include/clang/Basic/TokenKinds.def include/clang/Basic/TypeTraits.h lib/AST/DeclCXX.cpp lib/AST/StmtPrinter.cpp lib/AST/Type.cpp lib/Lex/PPMacroExpansion.cpp lib/Parse/ParseExpr.cpp lib/Parse/ParseExprCXX.cpp lib/Parse/ParseTentative.cpp lib/Sema/SemaExprCXX.cpp test/SemaCXX/type-traits.cpp
Chandler Carruth
chandlerc at gmail.com
Sat Apr 23 03:47:28 PDT 2011
Author: chandlerc
Date: Sat Apr 23 05:47:28 2011
New Revision: 130057
URL: http://llvm.org/viewvc/llvm-project?rev=130057&view=rev
Log:
Implement basic __is_trivial type-trait support, enough to close PR9472.
This introduces a few APIs on the AST to bundle up the standard-based
logic so that programmatic clients have access to exactly the same
behavior.
There is only one serious FIXME here: checking for non-trivial move
constructors and move assignment operators. Those bits need to be added
to the declaration and accessors provided.
This implementation should be enough for the uses of __is_trivial in
libstdc++ 4.6's C++98 library implementation.
Ideas for more thorough test cases or any edge cases missing would be
appreciated. =D
Modified:
cfe/trunk/include/clang/AST/DeclCXX.h
cfe/trunk/include/clang/AST/Type.h
cfe/trunk/include/clang/Basic/TokenKinds.def
cfe/trunk/include/clang/Basic/TypeTraits.h
cfe/trunk/lib/AST/DeclCXX.cpp
cfe/trunk/lib/AST/StmtPrinter.cpp
cfe/trunk/lib/AST/Type.cpp
cfe/trunk/lib/Lex/PPMacroExpansion.cpp
cfe/trunk/lib/Parse/ParseExpr.cpp
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Parse/ParseTentative.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/test/SemaCXX/type-traits.cpp
Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=130057&r1=130056&r2=130057&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Sat Apr 23 05:47:28 2011
@@ -741,6 +741,10 @@
// (C++ [class.dtor]p3)
bool hasTrivialDestructor() const { return data().HasTrivialDestructor; }
+ // isTriviallyCopyable - Whether this class is considered trivially copyable
+ // (C++0x [class]p5).
+ bool isTriviallyCopyable() const;
+
/// \brief If this record is an instantiation of a member class,
/// retrieves the member class from which it was instantiated.
///
Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=130057&r1=130056&r2=130057&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Sat Apr 23 05:47:28 2011
@@ -1171,6 +1171,10 @@
/// (C++0x [basic.types]p10)
bool isLiteralType() const;
+ /// isTrivialType - Return true if this is a literal type
+ /// (C++0x [basic.types]p9)
+ bool isTrivialType() const;
+
/// Helper methods to distinguish type categories. All type predicates
/// operate on the canonical type, ignoring typedefs and qualifiers.
Modified: cfe/trunk/include/clang/Basic/TokenKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=130057&r1=130056&r2=130057&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TokenKinds.def (original)
+++ cfe/trunk/include/clang/Basic/TokenKinds.def Sat Apr 23 05:47:28 2011
@@ -340,6 +340,7 @@
KEYWORD(__is_literal , KEYCXX)
KEYWORD(__is_pod , KEYCXX)
KEYWORD(__is_polymorphic , KEYCXX)
+KEYWORD(__is_trivial , KEYCXX)
KEYWORD(__is_union , KEYCXX)
// Apple Extension.
Modified: cfe/trunk/include/clang/Basic/TypeTraits.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TypeTraits.h?rev=130057&r1=130056&r2=130057&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TypeTraits.h (original)
+++ cfe/trunk/include/clang/Basic/TypeTraits.h Sat Apr 23 05:47:28 2011
@@ -33,6 +33,7 @@
UTT_IsLiteral,
UTT_IsPOD,
UTT_IsPolymorphic,
+ UTT_IsTrivial,
UTT_IsUnion
};
Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=130057&r1=130056&r2=130057&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Sat Apr 23 05:47:28 2011
@@ -217,6 +217,23 @@
return getCopyConstructor(Context, Qualifiers::Const) != 0;
}
+bool CXXRecordDecl::isTriviallyCopyable() const {
+ // C++0x [class]p5:
+ // A trivially copyable class is a class that:
+ // -- has no non-trivial copy constructors,
+ if (!hasTrivialCopyConstructor()) return false;
+ // -- has no non-trivial move constructors,
+ // FIXME: C++0x: Track and check trivial move constructors.
+ // -- has no non-trivial copy assignment operators,
+ if (!hasTrivialCopyAssignment()) return false;
+ // -- has no non-trivial move assignment operators, and
+ // FIXME: C++0x: Track and check trivial move assignment operators.
+ // -- has a trivial destructor.
+ if (!hasTrivialDestructor()) return false;
+
+ return true;
+}
+
/// \brief Perform a simplistic form of overload resolution that only considers
/// cv-qualifiers on a single parameter, and return the best overload candidate
/// (if there is one).
Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=130057&r1=130056&r2=130057&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Sat Apr 23 05:47:28 2011
@@ -1266,6 +1266,7 @@
case UTT_IsEnum: return "__is_enum";
case UTT_IsPOD: return "__is_pod";
case UTT_IsPolymorphic: return "__is_polymorphic";
+ case UTT_IsTrivial: return "__is_trivial";
case UTT_IsUnion: return "__is_union";
}
return "";
Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=130057&r1=130056&r2=130057&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Sat Apr 23 05:47:28 2011
@@ -902,6 +902,33 @@
}
}
+bool Type::isTrivialType() const {
+ if (isIncompleteType())
+ return false;
+
+ // C++0x [basic.types]p9:
+ // Scalar types, trivial class types, arrays of such types, and
+ // cv-qualified versions of these types are collectively called trivial
+ // types.
+ const Type *BaseTy = getBaseElementTypeUnsafe();
+ assert(BaseTy && "NULL element type");
+ if (BaseTy->isScalarType()) return true;
+ if (const RecordType *RT = BaseTy->getAs<RecordType>()) {
+ const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(RT->getDecl());
+
+ // C++0x [class]p5:
+ // A trivial class is a class that has a trivial default constructor
+ if (!ClassDecl->hasTrivialConstructor()) return false;
+ // and is trivially copyable.
+ if (!ClassDecl->isTriviallyCopyable()) return false;
+
+ return true;
+ }
+
+ // No other types can match.
+ return false;
+}
+
bool Type::isPromotableIntegerType() const {
if (const BuiltinType *BT = getAs<BuiltinType>())
switch (BT->getKind()) {
Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=130057&r1=130056&r2=130057&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Sat Apr 23 05:47:28 2011
@@ -590,6 +590,7 @@
.Case("is_literal", LangOpts.CPlusPlus)
.Case("is_pod", LangOpts.CPlusPlus)
.Case("is_polymorphic", LangOpts.CPlusPlus)
+ .Case("is_trivial", LangOpts.CPlusPlus)
.Case("is_union", LangOpts.CPlusPlus)
.Case("tls", PP.getTargetInfo().isTLSSupported())
.Default(false);
Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=130057&r1=130056&r2=130057&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Sat Apr 23 05:47:28 2011
@@ -536,6 +536,7 @@
/// '__is_enum'
/// '__is_pod'
/// '__is_polymorphic'
+/// '__is_trivial'
/// '__is_union'
///
/// binary-type-trait:
@@ -990,6 +991,7 @@
case tok::kw___is_literal:
case tok::kw___is_pod:
case tok::kw___is_polymorphic:
+ case tok::kw___is_trivial:
case tok::kw___is_union:
case tok::kw___has_trivial_constructor:
case tok::kw___has_trivial_copy:
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=130057&r1=130056&r2=130057&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Sat Apr 23 05:47:28 2011
@@ -1929,6 +1929,7 @@
case tok::kw___is_literal: return UTT_IsLiteral;
case tok::kw___is_pod: return UTT_IsPOD;
case tok::kw___is_polymorphic: return UTT_IsPolymorphic;
+ case tok::kw___is_trivial: return UTT_IsTrivial;
case tok::kw___is_union: return UTT_IsUnion;
}
}
Modified: cfe/trunk/lib/Parse/ParseTentative.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTentative.cpp?rev=130057&r1=130056&r2=130057&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTentative.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTentative.cpp Sat Apr 23 05:47:28 2011
@@ -662,6 +662,7 @@
case tok::kw___is_literal:
case tok::kw___is_pod:
case tok::kw___is_polymorphic:
+ case tok::kw___is_trivial:
case tok::kw___is_union:
case tok::kw___uuidof:
return TPResult::True();
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=130057&r1=130056&r2=130057&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Sat Apr 23 05:47:28 2011
@@ -2362,6 +2362,7 @@
default: assert(false && "Unknown type trait or not implemented");
case UTT_IsPOD: return T->isPODType();
case UTT_IsLiteral: return T->isLiteralType();
+ case UTT_IsTrivial: return T->isTrivialType();
case UTT_IsClass: // Fallthrough
case UTT_IsUnion:
if (const RecordType *Record = T->getAs<RecordType>()) {
Modified: cfe/trunk/test/SemaCXX/type-traits.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/type-traits.cpp?rev=130057&r1=130056&r2=130057&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/type-traits.cpp (original)
+++ cfe/trunk/test/SemaCXX/type-traits.cpp Sat Apr 23 05:47:28 2011
@@ -548,3 +548,37 @@
int t22[F(__is_convertible_to(PrivateCopy, PrivateCopy))];
int t23[T(__is_convertible_to(X0<int>, X0<float>))];
}
+
+void is_trivial()
+{
+ int t01[T(__is_trivial(int))];
+ int t02[T(__is_trivial(Enum))];
+ int t03[T(__is_trivial(POD))];
+ int t04[T(__is_trivial(Int))];
+ int t05[T(__is_trivial(IntAr))];
+ int t06[T(__is_trivial(Statics))];
+ int t07[T(__is_trivial(Empty))];
+ int t08[T(__is_trivial(EmptyUnion))];
+ int t09[T(__is_trivial(Union))];
+ int t10[T(__is_trivial(HasFunc))];
+ int t11[T(__is_trivial(HasOp))];
+ int t12[T(__is_trivial(HasConv))];
+ int t13[T(__is_trivial(HasAssign))];
+ int t15[T(__is_trivial(HasAnonymousUnion))];
+ int t16[T(__is_trivial(Derives))];
+ int t17[T(__is_trivial(DerivesEmpty))];
+ int t18[T(__is_trivial(NonPODAr))];
+ int t19[T(__is_trivial(HasPriv))];
+ int t20[T(__is_trivial(HasProt))];
+
+ int f01[F(__is_trivial(IntArNB))];
+ int f02[F(__is_trivial(HasCons))];
+ int f03[F(__is_trivial(HasCopyAssign))];
+ int f04[F(__is_trivial(HasDest))];
+ int f05[F(__is_trivial(HasRef))];
+ int f06[F(__is_trivial(HasNonPOD))];
+ int f07[F(__is_trivial(HasVirt))];
+ int f08[F(__is_trivial(void))];
+ int f09[F(__is_trivial(cvoid))];
+ int f10[F(__is_trivial(NonPODArNB))];
+}
More information about the cfe-commits
mailing list