aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-05-19 20:55:31 +0000
committerDouglas Gregor <dgregor@apple.com>2009-05-19 20:55:31 +0000
commitdc241b42c7588f99027b035a09b71557a6db219e (patch)
treecd0fdab9b733c4d970f7b644bb20a96e175097f4
parentc8667a866bfc1d9f807282f2de5644d6aa4e9423 (diff)
Template instantiation for __builtin_types_compatible_p.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72134 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/Expr.h2
-rw-r--r--lib/Sema/SemaTemplateInstantiateExpr.cpp21
-rw-r--r--test/SemaTemplate/instantiate-expr-3.cpp12
3 files changed, 34 insertions, 1 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 0c5f63b509..5692ec880c 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -1616,7 +1616,7 @@ public:
virtual child_iterator child_end();
};
-/// TypesCompatibleExpr - GNU builtin-in function __builtin_type_compatible_p.
+/// TypesCompatibleExpr - GNU builtin-in function __builtin_types_compatible_p.
/// This AST node represents a function that returns 1 if two *types* (not
/// expressions) are compatible. The result of this built-in function can be
/// used in integer constant expressions.
diff --git a/lib/Sema/SemaTemplateInstantiateExpr.cpp b/lib/Sema/SemaTemplateInstantiateExpr.cpp
index 7cf403c282..fde3110234 100644
--- a/lib/Sema/SemaTemplateInstantiateExpr.cpp
+++ b/lib/Sema/SemaTemplateInstantiateExpr.cpp
@@ -56,6 +56,7 @@ namespace {
OwningExprResult VisitConditionalOperator(ConditionalOperator *E);
// FIXME: AddrLabelExpr
OwningExprResult VisitStmtExpr(StmtExpr *E);
+ OwningExprResult VisitTypesCompatibleExpr(TypesCompatibleExpr *E);
OwningExprResult VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E);
OwningExprResult VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E);
OwningExprResult VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E);
@@ -466,6 +467,26 @@ Sema::OwningExprResult TemplateExprInstantiator::VisitStmtExpr(StmtExpr *E) {
}
Sema::OwningExprResult
+TemplateExprInstantiator::VisitTypesCompatibleExpr(TypesCompatibleExpr *E) {
+ QualType Type1 = SemaRef.InstantiateType(E->getArgType1(), TemplateArgs,
+ /*FIXME:*/ E->getBuiltinLoc(),
+ DeclarationName());
+ if (Type1.isNull())
+ return SemaRef.ExprError();
+
+ QualType Type2 = SemaRef.InstantiateType(E->getArgType2(), TemplateArgs,
+ /*FIXME:*/ E->getBuiltinLoc(),
+ DeclarationName());
+ if (Type2.isNull())
+ return SemaRef.ExprError();
+
+ return SemaRef.ActOnTypesCompatibleExpr(E->getBuiltinLoc(),
+ Type1.getAsOpaquePtr(),
+ Type2.getAsOpaquePtr(),
+ E->getRParenLoc());
+}
+
+Sema::OwningExprResult
TemplateExprInstantiator::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
bool isSizeOf = E->isSizeOf();
diff --git a/test/SemaTemplate/instantiate-expr-3.cpp b/test/SemaTemplate/instantiate-expr-3.cpp
index d098f27860..bc1097c5aa 100644
--- a/test/SemaTemplate/instantiate-expr-3.cpp
+++ b/test/SemaTemplate/instantiate-expr-3.cpp
@@ -69,3 +69,15 @@ struct StatementExpr0 {
template struct StatementExpr0<int>;
template struct StatementExpr0<N1::X>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// __builtin_types_compatible_p
+// ---------------------------------------------------------------------
+template<typename T, typename U, bool Result>
+struct TypesCompatible0 {
+ void f() {
+ int a[__builtin_types_compatible_p(T, U) == Result? 1 : -1];
+ }
+};
+
+template struct TypesCompatible0<int, const int, true>;