[cfe-commits] r147290 - in /cfe/trunk: include/clang/Basic/DiagnosticASTKinds.td lib/AST/ExprConstant.cpp lib/CodeGen/CGExprConstant.cpp test/CXX/expr/expr.const/p2-0x.cpp test/CodeGenCXX/typeid-cxx11.cpp test/CodeGenCXX/typeid.cpp
Richard Smith
richard-llvm at metafoo.co.uk
Tue Dec 27 04:18:28 PST 2011
Author: rsmith
Date: Tue Dec 27 06:18:28 2011
New Revision: 147290
URL: http://llvm.org/viewvc/llvm-project?rev=147290&view=rev
Log:
constexpr: support for evaluation and codegen of typeid constants.
Added:
cfe/trunk/test/CodeGenCXX/typeid-cxx11.cpp
Modified:
cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/lib/CodeGen/CGExprConstant.cpp
cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp
cfe/trunk/test/CodeGenCXX/typeid.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td?rev=147290&r1=147289&r2=147290&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td Tue Dec 27 06:18:28 2011
@@ -33,6 +33,9 @@
"%select{temporary|%2}1 is not a constant expression">;
def note_constexpr_var_init_non_constant : Note<
"initializer of %0 is not a constant expression">;
+def note_constexpr_typeid_polymorphic : Note<
+ "typeid applied to expression of polymorphic type %0 is "
+ "not allowed in a constant expression">;
def note_constexpr_temporary_here : Note<"temporary created here">;
def note_constexpr_literal_here : Note<"literal written here">;
def note_constexpr_depth_limit_exceeded : Note<
Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=147290&r1=147289&r2=147290&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Tue Dec 27 06:18:28 2011
@@ -697,6 +697,7 @@
case Expr::PredefinedExprClass:
case Expr::ObjCStringLiteralClass:
case Expr::ObjCEncodeExprClass:
+ case Expr::CXXTypeidExprClass:
return true;
case Expr::CallExprClass:
return IsStringLiteralCall(cast<CallExpr>(E));
@@ -2329,6 +2330,7 @@
// - Literals
// * CompoundLiteralExpr in C
// * StringLiteral
+// * CXXTypeidExpr
// * PredefinedExpr
// * ObjCStringLiteralExpr
// * ObjCEncodeExpr
@@ -2356,6 +2358,7 @@
bool VisitMemberExpr(const MemberExpr *E);
bool VisitStringLiteral(const StringLiteral *E) { return Success(E); }
bool VisitObjCEncodeExpr(const ObjCEncodeExpr *E) { return Success(E); }
+ bool VisitCXXTypeidExpr(const CXXTypeidExpr *E);
bool VisitArraySubscriptExpr(const ArraySubscriptExpr *E);
bool VisitUnaryDeref(const UnaryOperator *E);
@@ -2451,6 +2454,19 @@
return Success(E);
}
+bool LValueExprEvaluator::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
+ if (E->isTypeOperand())
+ return Success(E);
+ CXXRecordDecl *RD = E->getExprOperand()->getType()->getAsCXXRecordDecl();
+ if (RD && RD->isPolymorphic()) {
+ Info.Diag(E->getExprLoc(), diag::note_constexpr_typeid_polymorphic)
+ << E->getExprOperand()->getType()
+ << E->getExprOperand()->getSourceRange();
+ return false;
+ }
+ return Success(E);
+}
+
bool LValueExprEvaluator::VisitMemberExpr(const MemberExpr *E) {
// Handle static data members.
if (const VarDecl *VD = dyn_cast<VarDecl>(E->getMemberDecl())) {
Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=147290&r1=147289&r2=147290&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Tue Dec 27 06:18:28 2011
@@ -934,6 +934,15 @@
return CGM.GetAddrOfGlobalBlock(cast<BlockExpr>(E), FunctionName.c_str());
}
+ case Expr::CXXTypeidExprClass: {
+ CXXTypeidExpr *Typeid = cast<CXXTypeidExpr>(E);
+ QualType T;
+ if (Typeid->isTypeOperand())
+ T = Typeid->getTypeOperand();
+ else
+ T = Typeid->getExprOperand()->getType();
+ return CGM.GetAddrOfRTTIDescriptor(T);
+ }
}
return 0;
Modified: cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp?rev=147290&r1=147289&r2=147290&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp Tue Dec 27 06:18:28 2011
@@ -280,11 +280,10 @@
namespace TypeId {
struct S { virtual void f(); };
constexpr S *p = 0;
- constexpr const std::type_info &ti1 = typeid(*p); // expected-error {{must be initialized by a constant expression}}
+ constexpr const std::type_info &ti1 = typeid(*p); // expected-error {{must be initialized by a constant expression}} expected-note {{typeid applied to expression of polymorphic type 'TypeId::S'}}
- // FIXME: Implement typeid evaluation.
struct T {} t;
- constexpr const std::type_info &ti2 = typeid(t); // unexpected-error {{must be initialized by a constant expression}}
+ constexpr const std::type_info &ti2 = typeid(t);
}
// - a new-expression (5.3.4);
Added: cfe/trunk/test/CodeGenCXX/typeid-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/typeid-cxx11.cpp?rev=147290&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/typeid-cxx11.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/typeid-cxx11.cpp Tue Dec 27 06:18:28 2011
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -I%S %s -triple x86_64-apple-darwin10 -emit-llvm -std=c++11 -o - | FileCheck %s
+#include <typeinfo>
+
+namespace Test1 {
+
+struct Item {
+ const std::type_info &ti;
+ const char *name;
+ void *(*make)();
+};
+
+template<typename T> void *make_impl() { return new T; }
+template<typename T> constexpr Item item(const char *name) {
+ return { typeid(T), name, make_impl<T> };
+}
+
+struct A { virtual ~A(); };
+struct B : virtual A {};
+struct C { int n; };
+
+// FIXME: check we produce a constant array for this, once we support IRGen of
+// folded structs and arrays.
+constexpr Item items[] = {
+ item<A>("A"), item<B>("B"), item<C>("C"), item<int>("int")
+};
+
+// CHECK: @_ZN5Test11xE = constant %"class.std::type_info"* bitcast (i8** @_ZTIN5Test11AE to %"class.std::type_info"*), align 8
+constexpr auto &x = items[0].ti;
+
+}
Modified: cfe/trunk/test/CodeGenCXX/typeid.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/typeid.cpp?rev=147290&r1=147289&r2=147290&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/typeid.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/typeid.cpp Tue Dec 27 06:18:28 2011
@@ -6,6 +6,27 @@
// PR7400
struct A { virtual void f(); };
+// CHECK: @_ZN5Test16int_tiE = constant %"class.std::type_info"* bitcast (i8** @_ZTIi to %"class.std::type_info"*), align 8
+const std::type_info &int_ti = typeid(int);
+
+// CHECK: @_ZN5Test14A_tiE = constant %"class.std::type_info"* bitcast (i8** @_ZTIN5Test11AE to %"class.std::type_info"*), align 8
+const std::type_info &A_ti = typeid(const volatile A &);
+
+volatile char c;
+
+// CHECK: @_ZN5Test14c_tiE = constant %"class.std::type_info"* bitcast (i8** @_ZTIc to %"class.std::type_info"*), align 8
+const std::type_info &c_ti = typeid(c);
+
+extern const double &d;
+
+// CHECK: @_ZN5Test14d_tiE = constant %"class.std::type_info"* bitcast (i8** @_ZTId to %"class.std::type_info"*), align 8
+const std::type_info &d_ti = typeid(d);
+
+extern A &a;
+
+// CHECK: @_ZN5Test14a_tiE = global
+const std::type_info &a_ti = typeid(a);
+
// CHECK: define i8* @_ZN5Test11fEv
const char *f() {
try {
More information about the cfe-commits
mailing list