From dc241b42c7588f99027b035a09b71557a6db219e Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Tue, 19 May 2009 20:55:31 +0000 Subject: [PATCH] Template instantiation for __builtin_types_compatible_p. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72134 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Expr.h | 2 +- lib/Sema/SemaTemplateInstantiateExpr.cpp | 21 +++++++++++++++++++++ test/SemaTemplate/instantiate-expr-3.cpp | 12 ++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) 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); @@ -465,6 +466,26 @@ Sema::OwningExprResult TemplateExprInstantiator::VisitStmtExpr(StmtExpr *E) { E->getRParenLoc()); } +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; template struct StatementExpr0; // expected-note{{instantiation}} + +// --------------------------------------------------------------------- +// __builtin_types_compatible_p +// --------------------------------------------------------------------- +template +struct TypesCompatible0 { + void f() { + int a[__builtin_types_compatible_p(T, U) == Result? 1 : -1]; + } +}; + +template struct TypesCompatible0; -- 2.40.0