diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-05-19 20:55:31 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-05-19 20:55:31 +0000 |
commit | dc241b42c7588f99027b035a09b71557a6db219e (patch) | |
tree | cd0fdab9b733c4d970f7b644bb20a96e175097f4 | |
parent | c8667a866bfc1d9f807282f2de5644d6aa4e9423 (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.h | 2 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateExpr.cpp | 21 | ||||
-rw-r--r-- | test/SemaTemplate/instantiate-expr-3.cpp | 12 |
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>; |