diff options
| -rw-r--r-- | clang/docs/LibASTMatchersReference.html | 5 | ||||
| -rw-r--r-- | clang/include/clang/ASTMatchers/ASTMatchers.h | 4 | ||||
| -rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 28 | ||||
| -rw-r--r-- | clang/lib/ASTMatchers/ASTMatchersInternal.cpp | 1 | ||||
| -rw-r--r-- | clang/lib/ASTMatchers/Dynamic/Registry.cpp | 1 | ||||
| -rw-r--r-- | clang/test/ASTMerge/choose-expr/Inputs/choose.c | 2 | ||||
| -rw-r--r-- | clang/test/ASTMerge/choose-expr/test.c | 4 | ||||
| -rw-r--r-- | clang/unittests/AST/ASTImporterTest.cpp | 34 | ||||
| -rw-r--r-- | clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp | 5 |
9 files changed, 84 insertions, 0 deletions
diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html index 6506282f080..d2984844a4d 100644 --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -788,6 +788,11 @@ Example matches 'a', L'a' </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('chooseExpr0')"><a name="chooseExpr0Anchor">chooseExpr</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ChooseExpr.html">ChooseExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="chooseExpr0"><pre>Matches GNU __builtin_choose_expr. +</pre></td></tr> + + <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('compoundLiteralExpr0')"><a name="compoundLiteralExpr0Anchor">compoundLiteralExpr</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>...</td></tr> <tr><td colspan="4" class="doc" id="compoundLiteralExpr0"><pre>Matches compound (i.e. non-scalar) literals diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 4c62ea05872..1f3e1f936d4 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -2158,6 +2158,10 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundLiteralExpr> extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNullPtrLiteralExpr> cxxNullPtrLiteralExpr; +/// Matches GNU __builtin_choose_expr. +extern const internal::VariadicDynCastAllOfMatcher<Stmt, ChooseExpr> + chooseExpr; + /// Matches GNU __null expression. extern const internal::VariadicDynCastAllOfMatcher<Stmt, GNUNullExpr> gnuNullExpr; diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 10346941153..27a39f3a78b 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -552,6 +552,7 @@ namespace clang { // Importing expressions ExpectedStmt VisitExpr(Expr *E); ExpectedStmt VisitVAArgExpr(VAArgExpr *E); + ExpectedStmt VisitChooseExpr(ChooseExpr *E); ExpectedStmt VisitGNUNullExpr(GNUNullExpr *E); ExpectedStmt VisitPredefinedExpr(PredefinedExpr *E); ExpectedStmt VisitDeclRefExpr(DeclRefExpr *E); @@ -6135,6 +6136,33 @@ ExpectedStmt ASTNodeImporter::VisitVAArgExpr(VAArgExpr *E) { E->isMicrosoftABI()); } +ExpectedStmt ASTNodeImporter::VisitChooseExpr(ChooseExpr *E) { + auto Imp = importSeq(E->getCond(), E->getLHS(), E->getRHS(), + E->getBuiltinLoc(), E->getRParenLoc(), E->getType()); + if (!Imp) + return Imp.takeError(); + + Expr *ToCond; + Expr *ToLHS; + Expr *ToRHS; + SourceLocation ToBuiltinLoc, ToRParenLoc; + QualType ToType; + std::tie(ToCond, ToLHS, ToRHS, ToBuiltinLoc, ToRParenLoc, ToType) = *Imp; + + ExprValueKind VK = E->getValueKind(); + ExprObjectKind OK = E->getObjectKind(); + + bool TypeDependent = ToCond->isTypeDependent(); + bool ValueDependent = ToCond->isValueDependent(); + + // The value of CondIsTrue only matters if the value is not + // condition-dependent. + bool CondIsTrue = !E->isConditionDependent() && E->isConditionTrue(); + + return new (Importer.getToContext()) + ChooseExpr(ToBuiltinLoc, ToCond, ToLHS, ToRHS, ToType, VK, OK, + ToRParenLoc, CondIsTrue, TypeDependent, ValueDependent); +} ExpectedStmt ASTNodeImporter::VisitGNUNullExpr(GNUNullExpr *E) { ExpectedType TypeOrErr = import(E->getType()); diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp index 8c5425680dc..8c75b761567 100644 --- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp +++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp @@ -727,6 +727,7 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundLiteralExpr> compoundLiteralExpr; const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNullPtrLiteralExpr> cxxNullPtrLiteralExpr; +const internal::VariadicDynCastAllOfMatcher<Stmt, ChooseExpr> chooseExpr; const internal::VariadicDynCastAllOfMatcher<Stmt, GNUNullExpr> gnuNullExpr; const internal::VariadicDynCastAllOfMatcher<Stmt, AtomicExpr> atomicExpr; const internal::VariadicDynCastAllOfMatcher<Stmt, StmtExpr> stmtExpr; diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp index 8405cabcce0..5a417c9dd69 100644 --- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -147,6 +147,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(caseStmt); REGISTER_MATCHER(castExpr); REGISTER_MATCHER(characterLiteral); + REGISTER_MATCHER(chooseExpr); REGISTER_MATCHER(classTemplateDecl); REGISTER_MATCHER(classTemplateSpecializationDecl); REGISTER_MATCHER(complexType); diff --git a/clang/test/ASTMerge/choose-expr/Inputs/choose.c b/clang/test/ASTMerge/choose-expr/Inputs/choose.c new file mode 100644 index 00000000000..0b413a65544 --- /dev/null +++ b/clang/test/ASTMerge/choose-expr/Inputs/choose.c @@ -0,0 +1,2 @@ +_Static_assert(__builtin_choose_expr(1, 1, 0), "Incorrect semantics of __builtin_choose_expr"); +_Static_assert(__builtin_choose_expr(0, 0, 1), "Incorrect semantics of __builtin_choose_expr"); diff --git a/clang/test/ASTMerge/choose-expr/test.c b/clang/test/ASTMerge/choose-expr/test.c new file mode 100644 index 00000000000..0f95cd59681 --- /dev/null +++ b/clang/test/ASTMerge/choose-expr/test.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -std=c11 -emit-pch -o %t.ast %S/Inputs/choose.c +// RUN: %clang_cc1 -std=c11 -ast-merge %t.ast -fsyntax-only -verify %s +// expected-no-diagnostics + diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index 5ab03709290..6bfb7ad065e 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -563,6 +563,17 @@ TEST_P(ImportExpr, ImportStringLiteral) { stringLiteral(hasType(asString("const char [7]")))))); } +TEST_P(ImportExpr, ImportChooseExpr) { + MatchVerifier<Decl> Verifier; + + // This case tests C code that is not condition-dependent and has a true + // condition. + testImport( + "void declToImport() { (void)__builtin_choose_expr(1, 2, 3); }", + Lang_C, "", Lang_C, Verifier, + functionDecl(hasDescendant(chooseExpr()))); +} + TEST_P(ImportExpr, ImportGNUNullExpr) { MatchVerifier<Decl> Verifier; testImport( @@ -1312,6 +1323,29 @@ TEST_P(ASTImporterOptionSpecificTestBase, ImportCorrectTemplatedDecl) { ASSERT_EQ(ToTemplated1, ToTemplated); } +TEST_P(ASTImporterOptionSpecificTestBase, ImportChooseExpr) { + // This tests the import of isConditionTrue directly to make sure the importer + // gets it right. + Decl *From, *To; + std::tie(From, To) = getImportedDecl( + "void declToImport() { (void)__builtin_choose_expr(1, 0, 1); }", + Lang_C, "", Lang_C); + + auto ToResults = match(chooseExpr().bind("choose"), To->getASTContext()); + auto FromResults = match(chooseExpr().bind("choose"), From->getASTContext()); + + const ChooseExpr *FromChooseExpr = + selectFirst<ChooseExpr>("choose", FromResults); + ASSERT_TRUE(FromChooseExpr); + + const ChooseExpr *ToChooseExpr = selectFirst<ChooseExpr>("choose", ToResults); + ASSERT_TRUE(ToChooseExpr); + + EXPECT_EQ(FromChooseExpr->isConditionTrue(), ToChooseExpr->isConditionTrue()); + EXPECT_EQ(FromChooseExpr->isConditionDependent(), + ToChooseExpr->isConditionDependent()); +} + TEST_P(ASTImporterOptionSpecificTestBase, ImportFunctionWithBackReferringParameter) { Decl *From, *To; diff --git a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp index fd5b112fae9..3f9981cd6db 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp @@ -754,6 +754,11 @@ TEST(Matcher, NullPtrLiteral) { EXPECT_TRUE(matches("int* i = nullptr;", cxxNullPtrLiteralExpr())); } +TEST(Matcher, ChooseExpr) { + EXPECT_TRUE(matchesC("void f() { (void)__builtin_choose_expr(1, 2, 3); }", + chooseExpr())); +} + TEST(Matcher, GNUNullExpr) { EXPECT_TRUE(matches("int* i = __null;", gnuNullExpr())); } |

