clang++: Backport C++0x patches from the 3.0 branch (#729308)
This commit is contained in:
parent
62fe881ff6
commit
4e1a1955b0
|
@ -0,0 +1,286 @@
|
|||
From 96fdb1843b17f4acad796229b53793da328ea476 Mon Sep 17 00:00:00 2001
|
||||
From: Michel Alexandre Salim <salimma@fedoraproject.org>
|
||||
Date: Mon, 26 Mar 2012 15:34:11 +0700
|
||||
Subject: [PATCH] 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
|
||||
|
||||
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130057 91177308-0d34-0410-b5e6-96231b3b80d8
|
||||
(cherry picked from commit b7e9589bce9852b4db9575f55ac9137572147eb5)
|
||||
|
||||
Conflicts:
|
||||
|
||||
include/clang/Basic/TypeTraits.h
|
||||
lib/Parse/ParseExpr.cpp
|
||||
---
|
||||
include/clang/AST/DeclCXX.h | 4 ++++
|
||||
include/clang/AST/Type.h | 4 ++++
|
||||
include/clang/Basic/TokenKinds.def | 1 +
|
||||
include/clang/Basic/TypeTraits.h | 1 +
|
||||
lib/AST/DeclCXX.cpp | 17 +++++++++++++++++
|
||||
lib/AST/StmtPrinter.cpp | 1 +
|
||||
lib/AST/Type.cpp | 27 +++++++++++++++++++++++++++
|
||||
lib/Lex/PPMacroExpansion.cpp | 1 +
|
||||
lib/Parse/ParseExpr.cpp | 2 ++
|
||||
lib/Parse/ParseExprCXX.cpp | 1 +
|
||||
lib/Parse/ParseTentative.cpp | 1 +
|
||||
lib/Sema/SemaExprCXX.cpp | 1 +
|
||||
test/SemaCXX/type-traits.cpp | 34 ++++++++++++++++++++++++++++++++++
|
||||
13 files changed, 95 insertions(+)
|
||||
|
||||
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
|
||||
index 0473ae0..b36b35b 100644
|
||||
--- a/include/clang/AST/DeclCXX.h
|
||||
+++ b/include/clang/AST/DeclCXX.h
|
||||
@@ -743,6 +743,10 @@ public:
|
||||
// (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.
|
||||
///
|
||||
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
|
||||
index c071056..8270530 100644
|
||||
--- a/include/clang/AST/Type.h
|
||||
+++ b/include/clang/AST/Type.h
|
||||
@@ -1163,6 +1163,10 @@ public:
|
||||
/// (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.
|
||||
|
||||
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
|
||||
index 96a817b..bc1a97e 100644
|
||||
--- a/include/clang/Basic/TokenKinds.def
|
||||
+++ b/include/clang/Basic/TokenKinds.def
|
||||
@@ -331,6 +331,7 @@ KEYWORD(__is_empty , KEYCXX)
|
||||
KEYWORD(__is_enum , KEYCXX)
|
||||
KEYWORD(__is_pod , KEYCXX)
|
||||
KEYWORD(__is_polymorphic , KEYCXX)
|
||||
+KEYWORD(__is_trivial , KEYCXX)
|
||||
KEYWORD(__is_union , KEYCXX)
|
||||
// Tentative name - there's no implementation of std::is_literal_type yet.
|
||||
KEYWORD(__is_literal , KEYCXX)
|
||||
diff --git a/include/clang/Basic/TypeTraits.h b/include/clang/Basic/TypeTraits.h
|
||||
index 00c6e9e..d39ddf9 100644
|
||||
--- a/include/clang/Basic/TypeTraits.h
|
||||
+++ b/include/clang/Basic/TypeTraits.h
|
||||
@@ -32,6 +32,7 @@ namespace clang {
|
||||
UTT_IsEnum,
|
||||
UTT_IsPOD,
|
||||
UTT_IsPolymorphic,
|
||||
+ UTT_IsTrivial,
|
||||
UTT_IsUnion,
|
||||
UTT_IsLiteral
|
||||
};
|
||||
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
|
||||
index b6cba0a..6c80d00 100644
|
||||
--- a/lib/AST/DeclCXX.cpp
|
||||
+++ b/lib/AST/DeclCXX.cpp
|
||||
@@ -218,6 +218,23 @@ bool CXXRecordDecl::hasConstCopyConstructor(const ASTContext &Context) const {
|
||||
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).
|
||||
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
|
||||
index 1cdd220..2f35b62 100644
|
||||
--- a/lib/AST/StmtPrinter.cpp
|
||||
+++ b/lib/AST/StmtPrinter.cpp
|
||||
@@ -1227,6 +1227,7 @@ static const char *getTypeTraitName(UnaryTypeTrait UTT) {
|
||||
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 "";
|
||||
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
|
||||
index cde865f..07b90e5 100644
|
||||
--- a/lib/AST/Type.cpp
|
||||
+++ b/lib/AST/Type.cpp
|
||||
@@ -891,6 +891,33 @@ bool Type::isLiteralType() const {
|
||||
}
|
||||
}
|
||||
|
||||
+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()) {
|
||||
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
|
||||
index 10abfb4..5ac8661 100644
|
||||
--- a/lib/Lex/PPMacroExpansion.cpp
|
||||
+++ b/lib/Lex/PPMacroExpansion.cpp
|
||||
@@ -584,6 +584,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
|
||||
.Case("is_enum", LangOpts.CPlusPlus)
|
||||
.Case("is_pod", LangOpts.CPlusPlus)
|
||||
.Case("is_polymorphic", LangOpts.CPlusPlus)
|
||||
+ .Case("is_trivial", LangOpts.CPlusPlus)
|
||||
.Case("is_union", LangOpts.CPlusPlus)
|
||||
.Case("is_literal", LangOpts.CPlusPlus)
|
||||
.Case("tls", PP.getTargetInfo().isTLSSupported())
|
||||
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
|
||||
index 03b3417..d663da4 100644
|
||||
--- a/lib/Parse/ParseExpr.cpp
|
||||
+++ b/lib/Parse/ParseExpr.cpp
|
||||
@@ -535,6 +535,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
|
||||
/// '__is_enum'
|
||||
/// '__is_pod'
|
||||
/// '__is_polymorphic'
|
||||
+/// '__is_trivial'
|
||||
/// '__is_union'
|
||||
///
|
||||
/// binary-type-trait:
|
||||
@@ -981,6 +982,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
|
||||
case tok::kw___is_pod: // [GNU] unary-type-trait
|
||||
case tok::kw___is_class:
|
||||
case tok::kw___is_enum:
|
||||
+ case tok::kw___is_trivial:
|
||||
case tok::kw___is_union:
|
||||
case tok::kw___is_empty:
|
||||
case tok::kw___is_polymorphic:
|
||||
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
|
||||
index d09f20e..d94cac6 100644
|
||||
--- a/lib/Parse/ParseExprCXX.cpp
|
||||
+++ b/lib/Parse/ParseExprCXX.cpp
|
||||
@@ -1825,6 +1825,7 @@ static UnaryTypeTrait UnaryTypeTraitFromTokKind(tok::TokenKind kind) {
|
||||
case tok::kw___is_enum: return UTT_IsEnum;
|
||||
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;
|
||||
case tok::kw___is_literal: return UTT_IsLiteral;
|
||||
}
|
||||
diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp
|
||||
index 1099327..93122b3 100644
|
||||
--- a/lib/Parse/ParseTentative.cpp
|
||||
+++ b/lib/Parse/ParseTentative.cpp
|
||||
@@ -660,6 +660,7 @@ Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) {
|
||||
case tok::kw___is_enum:
|
||||
case tok::kw___is_pod:
|
||||
case tok::kw___is_polymorphic:
|
||||
+ case tok::kw___is_trivial:
|
||||
case tok::kw___is_union:
|
||||
case tok::kw___is_literal:
|
||||
case tok::kw___uuidof:
|
||||
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
|
||||
index 884011e..e8220ff 100644
|
||||
--- a/lib/Sema/SemaExprCXX.cpp
|
||||
+++ b/lib/Sema/SemaExprCXX.cpp
|
||||
@@ -2310,6 +2310,7 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, QualType T,
|
||||
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>()) {
|
||||
diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp
|
||||
index ff9a6bf..cbb3549 100644
|
||||
--- a/test/SemaCXX/type-traits.cpp
|
||||
+++ b/test/SemaCXX/type-traits.cpp
|
||||
@@ -548,3 +548,37 @@ void is_convertible_to() {
|
||||
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))];
|
||||
+}
|
||||
--
|
||||
1.7.9.3
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
From ddd23feca95aa2341654f225010675ea873ea38f Mon Sep 17 00:00:00 2001
|
||||
From: Eli Friedman <eli.friedman@gmail.com>
|
||||
Date: Mon, 4 Apr 2011 07:19:40 +0000
|
||||
Subject: [PATCH] PR9585: add __decltype as a keyword. While I'm here,
|
||||
alphabetize the list.
|
||||
|
||||
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128809 91177308-0d34-0410-b5e6-96231b3b80d8
|
||||
(cherry picked from commit cccc02ac215ffc16fc4b3ebfee5ee87c40e30505)
|
||||
---
|
||||
include/clang/Basic/TokenKinds.def | 9 +++++----
|
||||
test/SemaCXX/decltype-98.cpp | 3 +++
|
||||
2 files changed, 8 insertions(+), 4 deletions(-)
|
||||
create mode 100644 test/SemaCXX/decltype-98.cpp
|
||||
|
||||
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
|
||||
index bc1a97e..df67d13 100644
|
||||
--- a/include/clang/Basic/TokenKinds.def
|
||||
+++ b/include/clang/Basic/TokenKinds.def
|
||||
@@ -360,18 +360,19 @@ KEYWORD(__pixel , KEYALTIVEC)
|
||||
|
||||
// Alternate spelling for various tokens. There are GCC extensions in all
|
||||
// languages, but should not be disabled in strict conformance mode.
|
||||
-ALIAS("__attribute__", __attribute, KEYALL)
|
||||
-ALIAS("__const" , const , KEYALL)
|
||||
-ALIAS("__const__" , const , KEYALL)
|
||||
ALIAS("__alignof__" , __alignof , KEYALL)
|
||||
ALIAS("__asm" , asm , KEYALL)
|
||||
ALIAS("__asm__" , asm , KEYALL)
|
||||
+ALIAS("__attribute__", __attribute, KEYALL)
|
||||
ALIAS("__complex" , _Complex , KEYALL)
|
||||
ALIAS("__complex__" , _Complex , KEYALL)
|
||||
+ALIAS("__const" , const , KEYALL)
|
||||
+ALIAS("__const__" , const , KEYALL)
|
||||
+ALIAS("__decltype" , decltype , KEYCXX)
|
||||
ALIAS("__imag__" , __imag , KEYALL)
|
||||
ALIAS("__inline" , inline , KEYALL)
|
||||
ALIAS("__inline__" , inline , KEYALL)
|
||||
-ALIAS("__nullptr" , nullptr , KEYCXX)
|
||||
+ALIAS("__nullptr" , nullptr , KEYCXX)
|
||||
ALIAS("__real__" , __real , KEYALL)
|
||||
ALIAS("__restrict" , restrict , KEYALL)
|
||||
ALIAS("__restrict__" , restrict , KEYALL)
|
||||
diff --git a/test/SemaCXX/decltype-98.cpp b/test/SemaCXX/decltype-98.cpp
|
||||
new file mode 100644
|
||||
index 0000000..db52565
|
||||
--- /dev/null
|
||||
+++ b/test/SemaCXX/decltype-98.cpp
|
||||
@@ -0,0 +1,3 @@
|
||||
+// RUN: %clang_cc1 -std=c++98 -fsyntax-only -verify %s
|
||||
+extern int x;
|
||||
+__decltype(1) x = 3;
|
||||
--
|
||||
1.7.9.3
|
||||
|
12
llvm.spec
12
llvm.spec
|
@ -19,7 +19,7 @@
|
|||
|
||||
Name: llvm
|
||||
Version: 2.9
|
||||
Release: 9%{?dist}
|
||||
Release: 10%{?dist}
|
||||
Summary: The Low Level Virtual Machine
|
||||
|
||||
Group: Development/Languages
|
||||
|
@ -39,6 +39,11 @@ Patch1: clang-2.9-add_gcc_vers.patch
|
|||
# Operator.h incompatibility with GCC 4.6 in C++0x mode
|
||||
# http://llvm.org/bugs/show_bug.cgi?id=9869
|
||||
Patch2: llvm-2.9-PR9869_operator_destructor.patch
|
||||
# Backports from clang 3.0 needed for libstdc++ 4.6.x
|
||||
# __is_trivial implementation
|
||||
Patch3: clang-2.9-PR9472_is_trivial.patch
|
||||
# __decltype
|
||||
Patch4: clang-2.9-PR9585_decltype.patch
|
||||
|
||||
BuildRequires: bison
|
||||
BuildRequires: chrpath
|
||||
|
@ -226,6 +231,8 @@ mv clang-%{version}%{?prerel} tools/clang
|
|||
# clang patches
|
||||
pushd tools/clang
|
||||
%patch1 -p1 -b .add_gcc_ver
|
||||
%patch3 -p1 -b .is_trivial
|
||||
%patch4 -p1 -b .decltype
|
||||
popd
|
||||
|
||||
# Encoding fix
|
||||
|
@ -476,6 +483,9 @@ exit 0
|
|||
|
||||
|
||||
%changelog
|
||||
* Mon Mar 26 2012 Michel Salim <salimma@fedoraproject.org> - 2.9-10
|
||||
- clang++: Backport C++0x patches from the 3.0 branch (#729308)
|
||||
|
||||
* Fri Mar 23 2012 Michel Salim <salimma@fedoraproject.org> - 2.9-9
|
||||
- Actually rebuild against GCC 4.6.3 (BR override expired when building -8)
|
||||
|
||||
|
|
Loading…
Reference in New Issue