]> granicus.if.org Git - clang/commitdiff
[ASTImporter] Support TypeTraitExpr
authorAleksei Sidorin <a.sidorin@samsung.com>
Sun, 26 Nov 2017 17:04:06 +0000 (17:04 +0000)
committerAleksei Sidorin <a.sidorin@samsung.com>
Sun, 26 Nov 2017 17:04:06 +0000 (17:04 +0000)
Patch by Takafumi Kubota!

Differential Revision: https://reviews.llvm.org/D39722

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@318998 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ASTImporter.cpp
unittests/AST/ASTImporterTest.cpp

index 15c9f69bbf0c534315157481cc3c7d89f1dd0e1d..8bfc9030a606b91f8e931eefb0bdd421f6703336 100644 (file)
@@ -291,6 +291,7 @@ namespace clang {
     Expr *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E);
     Expr *VisitCXXNamedCastExpr(CXXNamedCastExpr *E);
     Expr *VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *E);
+    Expr *VisitTypeTraitExpr(TypeTraitExpr *E);
 
 
     template<typename IIter, typename OIter>
@@ -5890,6 +5891,26 @@ Expr *ASTNodeImporter::VisitSubstNonTypeTemplateParmExpr(
         Replacement);
 }
 
+Expr *ASTNodeImporter::VisitTypeTraitExpr(TypeTraitExpr *E) {
+  QualType ToType = Importer.Import(E->getType());
+  if (ToType.isNull())
+    return nullptr;
+
+  SmallVector<TypeSourceInfo *, 4> ToArgs(E->getNumArgs());
+  if (ImportContainerChecked(E->getArgs(), ToArgs))
+    return nullptr;
+
+  // According to Sema::BuildTypeTrait(), if E is value-dependent,
+  // Value is always false.
+  bool ToValue = false;
+  if (!E->isValueDependent())
+    ToValue = E->getValue();
+
+  return TypeTraitExpr::Create(
+      Importer.getToContext(), ToType, Importer.Import(E->getLocStart()),
+      E->getTrait(), ToArgs, Importer.Import(E->getLocEnd()), ToValue);
+}
+
 void ASTNodeImporter::ImportOverrides(CXXMethodDecl *ToMethod,
                                       CXXMethodDecl *FromMethod) {
   for (auto *FromOverriddenMethod : FromMethod->overridden_methods())
index 7b41c5d5793ccacec219fd6aa9b323f6956b6288..2a8f70c214358c8b2742d76b2424b9a66fe8c1a7 100644 (file)
@@ -525,6 +525,47 @@ TEST(ImportType, ImportPackExpansion) {
                                          declRefExpr()))))))))));
 }
 
+/// \brief Matches __builtin_types_compatible_p:
+/// GNU extension to check equivalent types
+/// Given
+/// \code
+///   __builtin_types_compatible_p(int, int)
+/// \endcode
+//  will generate TypeTraitExpr <...> 'int'
+const internal::VariadicDynCastAllOfMatcher<Stmt, TypeTraitExpr> typeTraitExpr;
+
+TEST(ImportExpr, ImportTypeTraitExpr) {
+  MatchVerifier<Decl> Verifier;
+  EXPECT_TRUE(testImport("void declToImport() { "
+                         "  __builtin_types_compatible_p(int, int);"
+                         "}",
+                         Lang_C, "", Lang_C, Verifier,
+                         functionDecl(
+                           hasBody(
+                             compoundStmt(
+                               has(
+                                 typeTraitExpr(hasType(asString("int")))))))));
+}
+
+TEST(ImportExpr, ImportTypeTraitExprValDep) {
+  MatchVerifier<Decl> Verifier;
+  EXPECT_TRUE(testImport("template<typename T> struct declToImport {"
+                         "  void m() { __is_pod(T); }"
+                         "};"
+                         "void f() { declToImport<int>().m(); }",
+                         Lang_CXX11, "", Lang_CXX11, Verifier,
+                         classTemplateDecl(
+                           has(
+                             cxxRecordDecl(
+                               has(
+                                 functionDecl(
+                                   hasBody(
+                                     compoundStmt(
+                                       has(
+                                         typeTraitExpr(
+                                           hasType(booleanType())
+                                           )))))))))));
+}
 
 } // end namespace ast_matchers
 } // end namespace clang