Skip to content

Commit a8d8331

Browse files
Add tests for ASTImporter on newly added functions
Test cover all code path including new visit and import functions for concept and requirement declarations and expressions.
1 parent 1d726d5 commit a8d8331

File tree

3 files changed

+122
-0
lines changed

3 files changed

+122
-0
lines changed

clang/include/clang/ASTMatchers/ASTMatchers.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#include "clang/AST/DeclTemplate.h"
5656
#include "clang/AST/Expr.h"
5757
#include "clang/AST/ExprCXX.h"
58+
#include "clang/AST/ExprConcepts.h"
5859
#include "clang/AST/ExprObjC.h"
5960
#include "clang/AST/LambdaCapture.h"
6061
#include "clang/AST/NestedNameSpecifier.h"
@@ -1363,6 +1364,26 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, CXXDeductionGuideDecl>
13631364
extern const internal::VariadicDynCastAllOfMatcher<Decl, ConceptDecl>
13641365
conceptDecl;
13651366

1367+
/// Matches concept requirement.
1368+
///
1369+
/// Example matches requirement expression
1370+
/// \code
1371+
/// template<typename T>
1372+
/// concept dereferencable = requires(T p) { *p; }
1373+
/// \endcode
1374+
extern const internal::VariadicDynCastAllOfMatcher<Expr, RequiresExpr>
1375+
requiresExpr;
1376+
1377+
/// Matches concept requirement body declaration.
1378+
///
1379+
/// Example matches equirement body declaration
1380+
/// \code
1381+
/// template<typename T>
1382+
/// concept dereferencable = requires(T p) { *p; }
1383+
/// \endcode
1384+
extern const internal::VariadicDynCastAllOfMatcher<Decl, RequiresExprBodyDecl>
1385+
requiresExprBodyDecl;
1386+
13661387
/// Matches variable declarations.
13671388
///
13681389
/// Note: this does not match declarations of member variables, which are

clang/lib/ASTMatchers/ASTMatchersInternal.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "clang/AST/ASTTypeTraits.h"
1616
#include "clang/AST/Decl.h"
1717
#include "clang/AST/DeclTemplate.h"
18+
#include "clang/AST/ExprConcepts.h"
1819
#include "clang/AST/ParentMapContext.h"
1920
#include "clang/AST/PrettyPrinter.h"
2021
#include "clang/ASTMatchers/ASTMatchers.h"
@@ -826,6 +827,9 @@ const internal::VariadicDynCastAllOfMatcher<Decl, CXXMethodDecl> cxxMethodDecl;
826827
const internal::VariadicDynCastAllOfMatcher<Decl, CXXConversionDecl>
827828
cxxConversionDecl;
828829
const internal::VariadicDynCastAllOfMatcher<Decl, ConceptDecl> conceptDecl;
830+
const internal::VariadicDynCastAllOfMatcher<Expr, RequiresExpr> requiresExpr;
831+
const internal::VariadicDynCastAllOfMatcher<Decl, RequiresExprBodyDecl>
832+
requiresExprBodyDecl;
829833
const internal::VariadicDynCastAllOfMatcher<Decl, VarDecl> varDecl;
830834
const internal::VariadicDynCastAllOfMatcher<Decl, FieldDecl> fieldDecl;
831835
const internal::VariadicDynCastAllOfMatcher<Decl, IndirectFieldDecl>

clang/unittests/AST/ASTImporterTest.cpp

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
#include "clang/AST/ExprConcepts.h"
1314
#include "clang/AST/RecordLayout.h"
1415
#include "clang/ASTMatchers/ASTMatchers.h"
1516
#include "clang/Testing/CommandLineArgs.h"
@@ -3217,6 +3218,102 @@ TEST_P(ImportExpr, UnresolvedMemberExpr) {
32173218
compoundStmt(has(callExpr(has(unresolvedMemberExpr())))))))));
32183219
}
32193220

3221+
TEST_P(ImportExpr, ConceptNoRequirement) {
3222+
MatchVerifier<Decl> Verifier;
3223+
const char *Code = R"(
3224+
template<typename T>
3225+
struct is_int { static const bool value = false; };
3226+
template<> struct is_int<int> { static const bool value = true; };
3227+
template<typename T>
3228+
concept declToImport = is_int<T>::value;
3229+
)";
3230+
testImport(Code, Lang_CXX20, "", Lang_CXX20, Verifier,
3231+
conceptDecl(unless(has(requiresExpr()))));
3232+
}
3233+
3234+
TEST_P(ImportExpr, ConceptSimpleRequirement) {
3235+
MatchVerifier<Decl> Verifier;
3236+
const char *Code = R"(
3237+
template <class T1, class T2>
3238+
concept declToImport = requires(T1 i, T2 j) {
3239+
i + j;
3240+
};
3241+
)";
3242+
testImport(Code, Lang_CXX20, "", Lang_CXX20, Verifier,
3243+
conceptDecl(has(requiresExpr(has(requiresExprBodyDecl())))));
3244+
}
3245+
3246+
TEST_P(ImportExpr, ConceptCompoundNonTypeRequirement) {
3247+
MatchVerifier<Decl> Verifier;
3248+
const char *Code = R"(
3249+
template <class T1, class T2>
3250+
concept declToImport = requires(T1 i, T2 j) {
3251+
{i + j};
3252+
};
3253+
)";
3254+
testImport(Code, Lang_CXX20, "", Lang_CXX20, Verifier,
3255+
conceptDecl(has(requiresExpr(has(requiresExprBodyDecl())))));
3256+
}
3257+
3258+
TEST_P(ImportExpr, ConceptCompoundTypeRequirement) {
3259+
MatchVerifier<Decl> Verifier;
3260+
const char *Code = R"(
3261+
template<typename T>
3262+
struct is_int { static const bool value = false; };
3263+
template<> struct is_int<int> { static const bool value = true; };
3264+
3265+
template<typename T>
3266+
concept type_is_int = is_int<T>::value;
3267+
3268+
template<typename T>
3269+
concept declToImport = requires(T x) {
3270+
{x * 1} -> type_is_int;
3271+
};
3272+
)";
3273+
testImport(Code, Lang_CXX20, "", Lang_CXX20, Verifier,
3274+
conceptDecl(has(requiresExpr(has(requiresExprBodyDecl())))));
3275+
}
3276+
3277+
TEST_P(ImportExpr, ConceptTypeRequirement) {
3278+
MatchVerifier<Decl> Verifier;
3279+
const char *Code = R"(
3280+
template <class T>
3281+
concept declToImport = requires {
3282+
typename T::value;
3283+
};
3284+
)";
3285+
testImport(Code, Lang_CXX20, "", Lang_CXX20, Verifier,
3286+
conceptDecl(has(requiresExpr(has(requiresExprBodyDecl())))));
3287+
}
3288+
3289+
TEST_P(ImportExpr, ConceptNestedRequirement) {
3290+
MatchVerifier<Decl> Verifier;
3291+
const char *Code = R"(
3292+
template<typename T>
3293+
struct is_int { static const bool value = false; };
3294+
template<> struct is_int<int> { static const bool value = true; };
3295+
3296+
template<typename T>
3297+
concept declToImport = requires(T x) {
3298+
requires is_int<T>::value;
3299+
};
3300+
)";
3301+
testImport(Code, Lang_CXX20, "", Lang_CXX20, Verifier,
3302+
conceptDecl(has(requiresExpr(has(requiresExprBodyDecl())))));
3303+
}
3304+
3305+
TEST_P(ImportExpr, ConceptNestedNonInstantiationDependentRequirement) {
3306+
MatchVerifier<Decl> Verifier;
3307+
const char *Code = R"(
3308+
template<typename T>
3309+
concept declToImport = requires {
3310+
requires sizeof(long) == sizeof(int);
3311+
};
3312+
)";
3313+
testImport(Code, Lang_CXX20, "", Lang_CXX20, Verifier,
3314+
conceptDecl(has(requiresExpr(has(requiresExprBodyDecl())))));
3315+
}
3316+
32203317
class ImportImplicitMethods : public ASTImporterOptionSpecificTestBase {
32213318
public:
32223319
static constexpr auto DefaultCode = R"(

0 commit comments

Comments
 (0)