diff --git a/clang-tools-extra/docs/clang-tidy/checks/openmp-use-default-none.rst b/clang-tools-extra/docs/clang-tidy/checks/openmp-use-default-none.rst --- a/clang-tools-extra/docs/clang-tidy/checks/openmp-use-default-none.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/openmp-use-default-none.rst @@ -51,3 +51,12 @@ // WARNING: OpenMP directive ``parallel`` specifies ``default(shared)`` // clause. Consider using ``default(none)`` clause instead. } + + // ``parallel`` directive can have ``default`` clause, and said clause is + // specified, but with ``firstprivate`` kind, which is not ``none``, diagnose. + void p0_3() { + #pragma omp parallel default(firstprivate) + ; + // WARNING: OpenMP directive ``parallel`` specifies ``default(firstprivate)`` + // clause. Consider using ``default(none)`` clause instead. + } diff --git a/clang-tools-extra/test/clang-tidy/checkers/openmp-use-default-none.cpp b/clang-tools-extra/test/clang-tidy/checkers/openmp-use-default-none.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/openmp-use-default-none.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/openmp-use-default-none.cpp @@ -1,5 +1,5 @@ -// RUN: %check_clang_tidy %s openmp-use-default-none %t -- -- -fopenmp=libomp -fopenmp-version=40 -// RUN: %check_clang_tidy -std=c11 %s openmp-use-default-none %t -- -- -x c -fopenmp=libomp -fopenmp-version=40 +// RUN: %check_clang_tidy %s openmp-use-default-none %t -- -- -fopenmp=libomp -fopenmp-version=51 +// RUN: %check_clang_tidy -std=c11 %s openmp-use-default-none %t -- -- -x c -fopenmp=libomp -fopenmp-version=51 //----------------------------------------------------------------------------// // Null cases. @@ -42,6 +42,15 @@ // CHECK-NOTES: :[[@LINE-3]]:22: note: existing 'default' clause specified here } +// 'parallel' directive can have 'default' clause, and said clause specified, +// but with 'firstprivate' kind, which is not 'none', diagnose. +void p0_3() { +#pragma omp parallel default(firstprivate) + ; + // CHECK-NOTES: :[[@LINE-2]]:1: warning: OpenMP directive 'parallel' specifies 'default(firstprivate)' clause, consider using 'default(none)' clause instead + // CHECK-NOTES: :[[@LINE-3]]:22: note: existing 'default' clause specified here +} + // 'task' directive. // 'task' directive can have 'default' clause, but said clause is not @@ -68,6 +77,15 @@ // CHECK-NOTES: :[[@LINE-3]]:18: note: existing 'default' clause specified here } +// 'task' directive can have 'default' clause, and said clause specified, +// but with 'firstprivate' kind, which is not 'none', diagnose. +void p1_3() { +#pragma omp task default(firstprivate) + ; + // CHECK-NOTES: :[[@LINE-2]]:1: warning: OpenMP directive 'task' specifies 'default(firstprivate)' clause, consider using 'default(none)' clause instead + // CHECK-NOTES: :[[@LINE-3]]:18: note: existing 'default' clause specified here +} + // 'teams' directive. (has to be inside of 'target' directive) // 'teams' directive can have 'default' clause, but said clause is not @@ -97,6 +115,16 @@ // CHECK-NOTES: :[[@LINE-3]]:19: note: existing 'default' clause specified here } +// 'teams' directive can have 'default' clause, and said clause specified, +// but with 'firstprivate' kind, which is not 'none', diagnose. +void p2_3() { +#pragma omp target +#pragma omp teams default(firstprivate) + ; + // CHECK-NOTES: :[[@LINE-2]]:1: warning: OpenMP directive 'teams' specifies 'default(firstprivate)' clause, consider using 'default(none)' clause instead + // CHECK-NOTES: :[[@LINE-3]]:19: note: existing 'default' clause specified here +} + // 'taskloop' directive. // 'taskloop' directive can have 'default' clause, but said clause is not @@ -126,6 +154,16 @@ // CHECK-NOTES: :[[@LINE-4]]:22: note: existing 'default' clause specified here } +// 'taskloop' directive can have 'default' clause, and said clause specified, +// but with 'firstprivate' kind, which is not 'none', diagnose. +void p3_3(const int a) { +#pragma omp taskloop default(firstprivate) + for (int b = 0; b < a; b++) + ; + // CHECK-NOTES: :[[@LINE-3]]:1: warning: OpenMP directive 'taskloop' specifies 'default(firstprivate)' clause, consider using 'default(none)' clause instead + // CHECK-NOTES: :[[@LINE-4]]:22: note: existing 'default' clause specified here +} + //----------------------------------------------------------------------------// // Combined directives. // Let's not test every single possible permutation/combination of directives, @@ -158,3 +196,13 @@ // CHECK-NOTES: :[[@LINE-3]]:1: warning: OpenMP directive 'parallel for' specifies 'default(shared)' clause, consider using 'default(none)' clause instead // CHECK-NOTES: :[[@LINE-4]]:26: note: existing 'default' clause specified here } + +// 'parallel' directive can have 'default' clause, and said clause specified, +// but with 'firstprivate' kind, which is not 'none', diagnose. +void p4_3(const int a) { +#pragma omp parallel for default(firstprivate) + for (int b = 0; b < a; b++) + ; + // CHECK-NOTES: :[[@LINE-3]]:1: warning: OpenMP directive 'parallel for' specifies 'default(firstprivate)' clause, consider using 'default(none)' clause instead + // CHECK-NOTES: :[[@LINE-4]]:26: note: existing 'default' clause specified here +} diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -676,9 +676,10 @@ #pragma omp parallel default(none) #pragma omp parallel default(shared) + #pragma omp parallel default(firstprivate) #pragma omp parallel -``ompDefaultClause()`` matches ``default(none)`` and ``default(shared)``. +``ompDefaultClause()`` matches ``default(none)``, ``default(shared)``, and ``default(firstprivate)``. @@ -3783,6 +3784,7 @@ #pragma omp parallel #pragma omp parallel default(none) #pragma omp parallel default(shared) + #pragma omp parallel default(firstprivate) ``ompDefaultClause(isNoneKind())`` matches only ``default(none)``. @@ -3796,11 +3798,26 @@ #pragma omp parallel #pragma omp parallel default(none) #pragma omp parallel default(shared) + #pragma omp parallel default(firstprivate) ``ompDefaultClause(isSharedKind())`` matches only ``default(shared)``. +
Matches if the OpenMP ``default`` clause has ``firstprivate`` kind specified. + +Given + + #pragma omp parallel + #pragma omp parallel default(none) + #pragma omp parallel default(shared) + #pragma omp parallel default(firstprivate) + +``ompDefaultClause(isFirstPrivateKind())`` matches only ``default(firstprivate)``. +
Matches if the OpenMP directive is allowed to contain the specified OpenMP clause kind. diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -7190,10 +7190,12 @@ /// \code /// #pragma omp parallel default(none) /// #pragma omp parallel default(shared) +/// #pragma omp parallel default(firstprivate) /// #pragma omp parallel /// \endcode /// -/// ``ompDefaultClause()`` matches ``default(none)`` and ``default(shared)``. +/// ``ompDefaultClause()`` matches ``default(none)``, ``default(shared)``, and +/// ``default(firstprivate)`` extern const internal::VariadicDynCastAllOfMatcherompDefaultClause; @@ -7205,6 +7207,7 @@ /// #pragma omp parallel /// #pragma omp parallel default(none) /// #pragma omp parallel default(shared) +/// #pragma omp parallel default(firstprivate) /// \endcode /// /// ``ompDefaultClause(isNoneKind())`` matches only ``default(none)``. @@ -7220,6 +7223,7 @@ /// #pragma omp parallel /// #pragma omp parallel default(none) /// #pragma omp parallel default(shared) +/// #pragma omp parallel default(firstprivate) /// \endcode /// /// ``ompDefaultClause(isSharedKind())`` matches only ``default(shared)``. @@ -7227,6 +7231,24 @@ return Node.getDefaultKind() == llvm::omp::OMP_DEFAULT_shared; } +/// Matches if the OpenMP ``default`` clause has ``firstprivate`` kind +/// specified. +/// +/// Given +/// +/// \code +/// #pragma omp parallel +/// #pragma omp parallel default(none) +/// #pragma omp parallel default(shared) +/// #pragma omp parallel default(firstprivate) +/// \endcode +/// +/// ``ompDefaultClause(isFirstPrivateKind())`` matches only +/// ``default(firstprivate)``. +AST_MATCHER(OMPDefaultClause, isFirstPrivateKind) { + return Node.getDefaultKind() == llvm::omp::OMP_DEFAULT_firstprivate; +} + /// Matches if the OpenMP directive is allowed to contain the specified OpenMP /// clause kind. /// diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -1334,6 +1334,8 @@ InGroup ; def err_omp_variant_ctx_second_match_extension : Error< "only a single match extension allowed per OpenMP context selector">; +def err_omp_invalid_dsa: Error< + "data-sharing attribute '%0' in '%1' clause requires OpenMP version %2 or above">; // Pragma loop support. def err_pragma_loop_missing_argument : Error< diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp --- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -389,6 +389,7 @@ REGISTER_MATCHER(isExpr); REGISTER_MATCHER(isExternC); REGISTER_MATCHER(isFinal); + REGISTER_MATCHER(isFirstPrivateKind); REGISTER_MATCHER(isImplicit); REGISTER_MATCHER(isInStdNamespace); REGISTER_MATCHER(isInTemplateInstantiation); diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -1441,7 +1441,7 @@ /// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'. /// /// default-clause: -/// 'default' '(' 'none' | 'shared' ') +/// 'default' '(' 'none' | 'shared' | 'firstprivate' ') /// /// proc_bind-clause: /// 'proc_bind' '(' 'master' | 'close' | 'spread' ') @@ -2772,7 +2772,7 @@ /// Parsing of simple OpenMP clauses like 'default' or 'proc_bind'. /// /// default-clause: -/// 'default' '(' 'none' | 'shared' ')' +/// 'default' '(' 'none' | 'shared' | 'firstprivate' ')' /// /// proc_bind-clause: /// 'proc_bind' '(' 'master' | 'close' | 'spread' ')' @@ -2785,6 +2785,14 @@ llvm::Optional Val = parseOpenMPSimpleClause(*this, Kind); if (!Val || ParseOnly) return nullptr; + if (getLangOpts().OpenMP < 51 && Kind == OMPC_default && + static_cast (Val.getValue().Type) == + OMP_DEFAULT_firstprivate) { + Diag(Val.getValue().LOpen, diag::err_omp_invalid_dsa) + << getOpenMPClauseName(OMPC_firstprivate) + << getOpenMPClauseName(OMPC_default) << "5.1"; + return nullptr; + } return Actions.ActOnOpenMPSimpleClause( Kind, Val.getValue().Type, Val.getValue().TypeLoc, Val.getValue().LOpen, Val.getValue().Loc, Val.getValue().RLoc); diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp --- a/clang/lib/Sema/SemaOpenMP.cpp +++ b/clang/lib/Sema/SemaOpenMP.cpp @@ -53,9 +53,10 @@ namespace { /// Default data sharing attributes, which can be applied to directive. enum DefaultDataSharingAttributes { - DSA_unspecified = 0, /// Data sharing attribute not specified. - DSA_none = 1 << 0, /// Default data sharing attribute 'none'. - DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. + DSA_unspecified = 0, /// Data sharing attribute not specified. + DSA_none = 1 << 0, /// Default data sharing attribute 'none'. + DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. + DSA_firstprivate = 1 << 2, /// Default data sharing attribute 'firstprivate'. }; /// Stack for tracking declarations used in OpenMP directives and @@ -684,6 +685,11 @@ getTopOfStack().DefaultAttr = DSA_shared; getTopOfStack().DefaultAttrLoc = Loc; } + /// Set default data sharing attribute to firstprivate. + void setDefaultDSAFirstPrivate(SourceLocation Loc) { + getTopOfStack().DefaultAttr = DSA_firstprivate; + getTopOfStack().DefaultAttrLoc = Loc; + } /// Set default data mapping attribute to Modifier:Kind void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, @@ -1183,6 +1189,15 @@ return DVar; case DSA_none: return DVar; + case DSA_firstprivate: + if (VD->getStorageDuration() == SD_Static && + VD->getDeclContext()->isFileContext()) { + DVar.CKind = OMPC_unknown; + } else { + DVar.CKind = OMPC_firstprivate; + } + DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; + return DVar; case DSA_unspecified: // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced // in a Construct, implicitly determined, p.2] @@ -2058,7 +2073,13 @@ // If the variable is artificial and must be captured by value - try to // capture by value. !(isa (D) && !D->hasAttr () && - !cast (D)->getInit()->isGLValue()); + !cast (D)->getInit()->isGLValue()) && + // If the variable is implicitly firstprivate and scalar - capture by + // copy + !(DSAStack->getDefaultDSA() == DSA_firstprivate && + !DSAStack->hasExplicitDSA( + D, [](OpenMPClauseKind K) { return K != OMPC_unknown; }, Level) && + !DSAStack->isLoopControlVariable(D, Level).first); } // When passing data by copy, we need to make sure it fits the uintptr size @@ -2185,10 +2206,13 @@ DSAStack->isClauseParsingMode()); // Global shared must not be captured. if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown && - (DSAStack->getDefaultDSA() != DSA_none || DVarTop.CKind == OMPC_shared)) + ((DSAStack->getDefaultDSA() != DSA_none && + DSAStack->getDefaultDSA() != DSA_firstprivate) || + DVarTop.CKind == OMPC_shared)) return nullptr; if (DVarPrivate.CKind != OMPC_unknown || - (VD && DSAStack->getDefaultDSA() == DSA_none)) + (VD && (DSAStack->getDefaultDSA() == DSA_none || + DSAStack->getDefaultDSA() == DSA_firstprivate))) return VD ? VD : cast (DVarPrivate.PrivateCopy->getDecl()); } return nullptr; @@ -3333,10 +3357,19 @@ // in the construct, and does not have a predetermined data-sharing // attribute, must have its data-sharing attribute explicitly determined // by being listed in a data-sharing attribute clause. - if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && + if (DVar.CKind == OMPC_unknown && + (Stack->getDefaultDSA() == DSA_none || + Stack->getDefaultDSA() == DSA_firstprivate) && isImplicitOrExplicitTaskingRegion(DKind) && VarsWithInheritedDSA.count(VD) == 0) { - VarsWithInheritedDSA[VD] = E; + bool InheritedDSA = Stack->getDefaultDSA() == DSA_none; + if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) { + DSAStackTy::DSAVarData DVar = + Stack->getImplicitDSA(VD, /*FromParent=*/false); + InheritedDSA = DVar.CKind == OMPC_unknown; + } + if (InheritedDSA) + VarsWithInheritedDSA[VD] = E; return; } @@ -3438,7 +3471,9 @@ // Define implicit data-sharing attributes for task. DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); - if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && + if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) || + (Stack->getDefaultDSA() == DSA_firstprivate && + DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) && !Stack->isLoopControlVariable(VD).first) { ImplicitFirstprivate.push_back(E); return; @@ -5342,8 +5377,10 @@ ErrorFound = Res.isInvalid() || ErrorFound; - // Check variables in the clauses if default(none) was specified. - if (DSAStack->getDefaultDSA() == DSA_none) { + // Check variables in the clauses if default(none) or + // default(firstprivate) was specified. + if (DSAStack->getDefaultDSA() == DSA_none || + DSAStack->getDefaultDSA() == DSA_firstprivate) { DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); for (OMPClause *C : Clauses) { switch (C->getClauseKind()) { @@ -5454,7 +5491,8 @@ if (P.getFirst()->isImplicit() || isa (P.getFirst())) continue; ErrorFound = true; - if (DSAStack->getDefaultDSA() == DSA_none) { + if (DSAStack->getDefaultDSA() == DSA_none || + DSAStack->getDefaultDSA() == DSA_firstprivate) { Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) << P.first << P.second->getSourceRange(); Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); @@ -12932,10 +12970,20 @@ << getOpenMPClauseName(OMPC_default); return nullptr; } - if (Kind == OMP_DEFAULT_none) + + switch (Kind) { + case OMP_DEFAULT_none: DSAStack->setDefaultDSANone(KindKwLoc); - else if (Kind == OMP_DEFAULT_shared) + break; + case OMP_DEFAULT_shared: DSAStack->setDefaultDSAShared(KindKwLoc); + break; + case OMP_DEFAULT_firstprivate: + DSAStack->setDefaultDSAFirstPrivate(KindKwLoc); + break; + default: + llvm_unreachable("DSA unexpected in OpenMP default clause"); + } return new (Context) OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); diff --git a/clang/test/OpenMP/distribute_parallel_for_default_messages.cpp b/clang/test/OpenMP/distribute_parallel_for_default_messages.cpp --- a/clang/test/OpenMP/distribute_parallel_for_default_messages.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_default_messages.cpp @@ -2,8 +2,17 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp -ferror-limit 100 -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + template T tmain(T argc) { int i; @@ -14,12 +23,12 @@ foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp distribute parallel for default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp distribute parallel for default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -34,7 +43,7 @@ foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp distribute parallel for default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -62,12 +71,12 @@ foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp distribute parallel for default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp distribute parallel for default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -82,7 +91,7 @@ foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp distribute parallel for default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -98,5 +107,15 @@ for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} foo(); +#ifdef OMP51 +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + for (i = 0; i < argc; ++i) { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif + return (tmain (argc) + tmain (argv[0][0])); // expected-note {{in instantiation of function template specialization 'tmain ' requested here}} expected-note {{in instantiation of function template specialization 'tmain ' requested here}} } diff --git a/clang/test/OpenMP/distribute_parallel_for_simd_default_messages.cpp b/clang/test/OpenMP/distribute_parallel_for_simd_default_messages.cpp --- a/clang/test/OpenMP/distribute_parallel_for_simd_default_messages.cpp +++ b/clang/test/OpenMP/distribute_parallel_for_simd_default_messages.cpp @@ -2,8 +2,17 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 100 -o - %s -Wuninitialized -DOMP51 -fopenmp-version=51 + +// RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized -DOMP51 -fopenmp-version=51 + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + template T tmain(T argc) { int i; @@ -14,12 +23,12 @@ foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp distribute parallel for simd default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp distribute parallel for simd default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -34,7 +43,7 @@ foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp distribute parallel for simd default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -62,12 +71,12 @@ foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp distribute parallel for simd default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp distribute parallel for simd default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -82,7 +91,7 @@ foo(); #pragma omp target #pragma omp teams -#pragma omp distribute parallel for simd default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp distribute parallel for simd default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target @@ -90,6 +99,15 @@ #pragma omp distribute parallel for simd default(none) // expected-note {{explicit data sharing attribute requested here}} for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} foo(); +#ifdef OpenMP51 +#pragma omp target +#pragma omp teams +#pragma omp distribute parallel for simd default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + for (i = 0; i < argc; ++i) { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif #pragma omp parallel default(none) // expected-note 2 {{explicit data sharing attribute requested here}} #pragma omp target diff --git a/clang/test/OpenMP/driver.c b/clang/test/OpenMP/driver.c --- a/clang/test/OpenMP/driver.c +++ b/clang/test/OpenMP/driver.c @@ -47,6 +47,7 @@ // RUN: %clang %s -c -E -dM -fopenmp-simd -fopenmp-version=31 | FileCheck --check-prefix=CHECK-VERSION %s // RUN: %clang %s -c -E -dM -fopenmp-simd -fopenmp-version=40 | FileCheck --check-prefix=CHECK-VERSION %s // RUN: %clang %s -c -E -dM -fopenmp-simd -fopenmp-version=45 | FileCheck --check-prefix=CHECK-VERSION %s +// RUN: %clang %s -c -E -dM -fopenmp-simd -fopenmp-version=51 | FileCheck --check-prefix=CHECK-VERSION %s // CHECK-VERSION-NOT: #define _OPENMP diff --git a/clang/test/OpenMP/parallel_default_messages.cpp b/clang/test/OpenMP/parallel_default_messages.cpp --- a/clang/test/OpenMP/parallel_default_messages.cpp +++ b/clang/test/OpenMP/parallel_default_messages.cpp @@ -4,18 +4,25 @@ // RUN: %clang_cc1 -verify=expected,ge40 -fopenmp-version=40 -fopenmp -ferror-limit 100 -o - %s -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp-version=31 -fopenmp -ferror-limit 100 -o - %s -Wuninitialized // RUN: %clang_cc1 -verify -fopenmp-version=30 -fopenmp -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,ge40 -fopenmp-version=51 -fopenmp -DOMP51 -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,ge40 -fopenmp-version=51 -fopenmp-simd -DOMP51 -ferror-limit 100 -o - %s -Wuninitialized void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { const int c = 0; #pragma omp parallel default // expected-error {{expected '(' after 'default'}} - #pragma omp parallel default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp parallel default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} - #pragma omp parallel default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} - #pragma omp parallel default (shared), default(shared) // expected-error {{directive '#pragma omp parallel' cannot contain more than one 'default' clause}} - #pragma omp parallel default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp parallel default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} +#pragma omp parallel default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp parallel default(shared), default(shared) // expected-error {{directive '#pragma omp parallel' cannot contain more than one 'default' clause}} +#pragma omp parallel default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} foo(); #pragma omp parallel default(none) // expected-note {{explicit data sharing attribute requested here}} @@ -27,5 +34,14 @@ #pragma omp parallel default(none) // ge40-note {{explicit data sharing attribute requested here}} (void)c; // ge40-error {{variable 'c' must have explicitly specified data sharing attributes}} + +#ifdef OMP51 +#pragma omp parallel default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif + return 0; } diff --git a/clang/test/OpenMP/parallel_for_default_messages.cpp b/clang/test/OpenMP/parallel_for_default_messages.cpp --- a/clang/test/OpenMP/parallel_for_default_messages.cpp +++ b/clang/test/OpenMP/parallel_for_default_messages.cpp @@ -2,17 +2,26 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -DOMP51 -ferror-limit 100 -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=51 -DOMP51 -ferror-limit 100 -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { int i; #pragma omp parallel for default // expected-error {{expected '(' after 'default'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp parallel for default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel for default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{explicit data sharing attribute requested here}} @@ -21,7 +30,7 @@ #pragma omp parallel for default(shared), default(shared) // expected-error {{directive '#pragma omp parallel for' cannot contain more than one 'default' clause}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel for default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); @@ -34,5 +43,13 @@ for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} foo(); +#ifdef OMP51 +#pragma omp parallel for default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + for (i = 0; i < argc; ++i) { + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + } +#endif + return 0; } diff --git a/clang/test/OpenMP/parallel_for_simd_default_messages.cpp b/clang/test/OpenMP/parallel_for_simd_default_messages.cpp --- a/clang/test/OpenMP/parallel_for_simd_default_messages.cpp +++ b/clang/test/OpenMP/parallel_for_simd_default_messages.cpp @@ -2,17 +2,26 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { int i; #pragma omp parallel for simd default // expected-error {{expected '(' after 'default'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for simd default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp parallel for simd default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for simd default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel for simd default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp parallel for simd default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{explicit data sharing attribute requested here}} @@ -21,7 +30,7 @@ #pragma omp parallel for simd default(shared), default(shared) // expected-error {{directive '#pragma omp parallel for simd' cannot contain more than one 'default' clause}} for (i = 0; i < argc; ++i) foo(); -#pragma omp parallel for simd default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel for simd default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); @@ -34,5 +43,13 @@ for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} expected-error {{variable 'i' must have explicitly specified data sharing attributes}} foo(); +#ifdef OMP51 +#pragma omp parallel for default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + for (i = 0; i < argc; ++i) { + x++; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + y++; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif + return 0; } diff --git a/clang/test/OpenMP/parallel_master_codegen.cpp b/clang/test/OpenMP/parallel_master_codegen.cpp --- a/clang/test/OpenMP/parallel_master_codegen.cpp +++ b/clang/test/OpenMP/parallel_master_codegen.cpp @@ -118,6 +118,162 @@ #endif +#ifdef CK31 +///==========================================================================/// +// RUN: %clang_cc1 -DCK31 -fopenmp-version=51 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefix CK31 +// RUN: %clang_cc1 -DCK31 -fopenmp-version=51 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK31 -fopenmp-version=51 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK31 + +// RUN: %clang_cc1 -DCK31 -fopenmp-version=51 -verify -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck --check-prefix SIMD-ONLY0 %s +// RUN: %clang_cc1 -DCK31 -fopenmp-version=51 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK31 -fopenmp-version=51 -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s +// SIMD-ONLY0-NOT: {{__kmpc|__tgt}} + +// CK31-DAG: %struct.ident_t = type { i32, i32, i32, i32, i8* } +// CK31-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00" + +void parallel_master_default_firstprivate() { + int a; +#pragma omp parallel master default(firstprivate) + a++; +} + +// CK31-LABEL: define void @{{.+}}parallel_master{{.+}} +// CK31: [[A_VAL:%.+]] = alloca i32{{.+}} +// CK31: [[A_CASTED:%.+]] = alloca i64 +// CK31: [[ZERO_VAL:%.+]] = load i32, i32* [[A_VAL]] +// CK31: [[CONV:%.+]] = bitcast i64* [[A_CASTED]] to i32* +// CK31: store i32 [[ZERO_VAL]], i32* [[CONV]] +// CK31: [[ONE_VAL:%.+]] = load i64, i64* [[A_CASTED]] +// CK31: call void (%struct.ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%struct.ident_t* @0, i32 1, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i64)* @.omp_outlined. to void (i32*, i32*, ...)*), i64 [[ONE_VAL]]) +// CK31: ret void + +// CK31: [[GLOBAL_TID_ADDR:%.+]] = alloca i32* +// CK31: [[BOUND_TID_ADDR:%.+]] = alloca i32* +// CK31: [[A_ADDR:%.+]] = alloca i64{{.+}} +// CK31: store i32* [[GLOBAL_TID:%.+]], i32** [[GLOBAL_TID_ADDR]]{{.+}} +// CK31: store i32* [[BOUND_TID:%.+]], i32** [[BOUND_TID_ADDR]] +// CK31: store i64 [[A_VAL]], i64* [[A_ADDR]] +// CK31: [[CONV]] = bitcast i64* [[A_ADDR]] +// CK31: [[ZERO_VAL]] = load i32*, i32** [[GLOBAL_TID_ADDR]] +// CK31: [[ONE_VAL]] = load i32, i32* [[ZERO_VAL]] +// CK31: [[TWO_VAL:%.+]] = call i32 @__kmpc_master(%struct.ident_t* @0, i32 [[ONE_VAL]]) +// CK31: [[THREE:%.+]] = icmp ne i32 [[TWO_VAL]], 0 +// CK31: br i1 %3, label [[OMP_IF_THEN:%.+]], label [[OMP_IF_END:%.+]] + +// CK31: [[FOUR:%.+]] = load i32, i32* [[CONV:%.+]] +// CK31: [[INC:%.+]] = add nsw i32 [[FOUR]] +// CK31: store i32 [[INC]], i32* [[CONV]] +// CK31: call void @__kmpc_end_master(%struct.ident_t* @0, i32 [[ONE_VAL]]) +// CK31: br label [[OMP_IF_END]] + +// CK31: ret void + +#endif + +#ifdef CK32 +///==========================================================================/// +// RUN: %clang_cc1 -DCK32 -fopenmp-version=51 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefix CK32 +// RUN: %clang_cc1 -DCK32 -fopenmp-version=51 -fopenmp -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK32 -fopenmp-version=51 -fopenmp -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s --check-prefix CK32 + +// RUN: %clang_cc1 -DCK32 -fopenmp-version=51 -verify -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck --check-prefix SIMD-ONLY0 %s +// RUN: %clang_cc1 -DCK32 -fopenmp-version=51 -fopenmp-simd -x c++ -std=c++11 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-pch -o %t %s +// RUN: %clang_cc1 -DCK32 -fopenmp-version=51 -fopenmp-simd -x c++ -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix SIMD-ONLY0 %s +// SIMD-ONLY0-NOT: {{__kmpc|__tgt}} + +// CK32-DAG: %struct.ident_t = type { i32, i32, i32, i32, i8* } +// CK32-DAG: [[STR:@.+]] = private unnamed_addr constant [23 x i8] c";unknown;unknown;0;0;;\00" + +struct St { + int a, b; + static int y; + St() : a(0), b(0) {} + ~St() {} +}; +int St::y = 0; + +void parallel_master_default_firstprivate() { + St a = St(); + static int y = 0; +#pragma omp parallel master default(firstprivate) + { + a.a += 1; + a.b += 1; + y++; + a.y++; + } +} + +// CK32-LABEL: define {{.+}} @{{.+}}parallel_master_default_firstprivate{{.+}} +// CK32: [[A_VAL:%.+]] = alloca %struct.St{{.+}} +// CK32: [[Y_CASTED:%.+]] = alloca i64 +// CK32: call void @[[CTOR:.+]](%struct.St* [[A_VAL]]) +// CK32: [[ZERO:%.+]] = load i32, i32* @{{.+}}parallel_master_default_firstprivate{{.+}} +// CK32: [[CONV:%.+]] = bitcast i64* [[Y_CASTED]] to i32* +// CK32: store i32 [[ZERO]], i32* [[CONV]] +// CK32: [[ONE:%.+]] = load i64, i64* [[Y_CASTED]] +// CK32: call void {{.+}}@{{.+}} %struct.St* [[A_VAL]], i64 [[ONE]]) +// CK32: call void [[DTOR:@.+]](%struct.St* [[A_VAL]]) + +// CK32: [[THIS_ADDR:%.+]] = alloca %struct.St* +// CK32: store %struct.St* [[THIS:%.+]], %struct.St** [[THIS_ADDR]] +// CK32: [[THIS_ONE:%.+]] = load %struct.St*, %struct.St** [[THIS_ADDR]] +// CK32: call void [[CTOR_2:.+]](%struct.St* [[THIS_ONE]]) +// CK32: ret void + +// CK32: [[GLOBAL_TID_ADDR:%.+]] = alloca i32* +// CK32: [[BOUND_TID_ADDR:%.+]] = alloca i32* +// CK32: [[A_ADDR:%.+]] = alloca %struct.St +// CK32: [[Y_ADDR:%.+]] = alloca i64 +// CK32: store i32* [[GLOBAL_TID:%.+]], i32** [[GLOBAL_TID_ADDR]] +// CK32: store i32* %.bound_tid., i32** [[BOUND_TID_ADDR]] +// CK32: store %struct.St* [[A_VAL]], %struct.St** [[A_ADDR]]{{.+}} +// CK32: store i64 [[Y:%.+]], i64* [[Y_ADDR]] +// CK32: [[ONE:%.+]] = load i32*, i32** [[GLOBAL_TID_ADDR]] +// CK32: [[TWO:%.+]] = load i32, i32* [[ONE]] +// CK32: [[THREE:%.+]] = call i32 @{{.+}} i32 [[TWO]]) +// CK32: [[FOUR:%.+]] = icmp ne i32 [[THREE]], 0 +// CK32: br i1 [[FOUR]], label [[IF_THEN:%.+]], label [[IF_END:%.+]] + +// CK32: [[A_1:%.+]] = getelementptr inbounds %struct.St, %struct.St* [[ZERO]], i32 0, i32 0 +// CK32: [[FIVE:%.+]] = load i32, i32* [[A_1]] +// CK32: [[ADD:%.+]] = add nsw i32 [[FIVE]], 1 +// CK32: store i32 [[ADD]], i32* [[A_1]] +// CK32: [[B:%.+]] = getelementptr inbounds %struct.St, %struct.St* [[ZERO]], i32 0, i32 1 +// CK32: [[SIX:%.+]] = load i32, i32* [[B]] +// CK32: [[ADD_2:%.+]] = add nsw i32 [[SIX]], 1 +// CK32: store i32 [[ADD_2]], i32* [[B]] +// CK32: [[SEVEN:%.+]] = load i32, i32* [[CONV]] +// CK32: [[INC:%.+]] = add nsw i32 [[SEVEN]], 1 +// CK32: store i32 [[INC]], i32* [[CONV]] +// CK32: [[EIGHT:%.+]] = load i32, i32* [[FUNC:@.+]] +// CK32: [[INC_3:%.+]] = add nsw i32 [[EIGHT]], 1 +// CK32: store i32 [[INC_3]], i32* @{{.+}} +// CK32: call void @{{.+}} i32 [[TWO]]) +// CK32: br label [[IF_END]] + +// CK32: [[DTOR]](%struct.St* [[THIS]]) +// CK32: [[THIS_ADDR]] = alloca %struct.St* +// CK32: store %struct.St* [[THIS]], %struct.St** [[THIS_ADDR]] +// CK32: [[THIS_ONE]] = load %struct.St*, %struct.St** [[THIS_ADDR]] +// CK32: call void @_ZN2StD2Ev(%struct.St* [[THIS_ONE]]) + +// CK32: [[THIS_ADDR]] = alloca %struct.St* +// CK32: store %struct.St* [[THIS]], %struct.St** [[THIS_ADDR]] +// CK32: [[THIS_ONE]] = load %struct.St*, %struct.St** [[THIS_ADDR]] +// CK32: [[A_VAL]] = getelementptr inbounds %struct.St, %struct.St* [[THIS_ONE]], i32 0, i32 0 +// CK32: store i32 0, i32* [[A_VAL]] +// CK32: [[B_VAL:%.+]] = getelementptr inbounds %struct.St, %struct.St* [[THIS_ONE]], i32 0, i32 1 +// CK32: store i32 0, i32* [[B_VAL]] +// CK32: ret void + +// CK32: [[THIS_ADDR:%.+]] = alloca %struct.St* +// CK32: store %struct.St* %this, %struct.St** [[THIS_ADDR]] +// CK32: [[THIS_ONE]] = load %struct.St*, %struct.St** [[THIS_ADDR]] + +#endif + #ifdef CK4 ///==========================================================================/// // RUN: %clang_cc1 -DCK4 -verify -fopenmp -x c++ -triple x86_64-unknown-unknown -emit-llvm %s -fexceptions -fcxx-exceptions -o - | FileCheck %s --check-prefix CK4 diff --git a/clang/test/OpenMP/parallel_master_default_messages.cpp b/clang/test/OpenMP/parallel_master_default_messages.cpp --- a/clang/test/OpenMP/parallel_master_default_messages.cpp +++ b/clang/test/OpenMP/parallel_master_default_messages.cpp @@ -2,20 +2,29 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp -ferror-limit 100 -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp parallel master default // expected-error {{expected '(' after 'default'}} { -#pragma omp parallel master default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp parallel master default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} { -#pragma omp parallel master default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel master default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} { #pragma omp parallel master default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} { #pragma omp parallel master default(shared), default(shared) // expected-error {{directive '#pragma omp parallel master' cannot contain more than one 'default' clause}} { -#pragma omp parallel master default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel master default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} { foo(); } @@ -37,5 +46,14 @@ ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} } } + +#ifdef OMP51 +#pragma omp parallel master default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif + return 0; } diff --git a/clang/test/OpenMP/parallel_sections_default_messages.cpp b/clang/test/OpenMP/parallel_sections_default_messages.cpp --- a/clang/test/OpenMP/parallel_sections_default_messages.cpp +++ b/clang/test/OpenMP/parallel_sections_default_messages.cpp @@ -7,15 +7,15 @@ int main(int argc, char **argv) { #pragma omp parallel sections default // expected-error {{expected '(' after 'default'}} { -#pragma omp parallel sections default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp parallel sections default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} { -#pragma omp parallel sections default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel sections default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} { #pragma omp parallel sections default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} { #pragma omp parallel sections default(shared), default(shared) // expected-error {{directive '#pragma omp parallel sections' cannot contain more than one 'default' clause}} { -#pragma omp parallel sections default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp parallel sections default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} { foo(); } diff --git a/clang/test/OpenMP/target_parallel_default_messages.cpp b/clang/test/OpenMP/target_parallel_default_messages.cpp --- a/clang/test/OpenMP/target_parallel_default_messages.cpp +++ b/clang/test/OpenMP/target_parallel_default_messages.cpp @@ -2,20 +2,29 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp -ferror-limit 100 -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target parallel default // expected-error {{expected '(' after 'default'}} foo(); - #pragma omp target parallel default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target parallel default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} foo(); - #pragma omp target parallel default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target parallel default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} foo(); #pragma omp target parallel default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} foo(); #pragma omp target parallel default (shared), default(shared) // expected-error {{directive '#pragma omp target parallel' cannot contain more than one 'default' clause}} foo(); - #pragma omp target parallel default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target parallel default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} foo(); #pragma omp target parallel default(none) // expected-note {{explicit data sharing attribute requested here}} @@ -28,5 +37,14 @@ #pragma omp target parallel default(none) // expected-note {{explicit data sharing attribute requested here}} #pragma omp parallel default(shared) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + +#ifndef OMP51 +#pragma omp target parallel default(firstprivate) // expected-error {{data-sharing attribute 'firstprivate' in 'default' clause requires OpenMP version 5.1 or above}} + { + ++x; + ++y; + } +#endif + return 0; } diff --git a/clang/test/OpenMP/target_parallel_for_default_messages.cpp b/clang/test/OpenMP/target_parallel_for_default_messages.cpp --- a/clang/test/OpenMP/target_parallel_for_default_messages.cpp +++ b/clang/test/OpenMP/target_parallel_for_default_messages.cpp @@ -2,17 +2,26 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -DOMP51 -ferror-limit 100 -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=51 -DOMP51 -ferror-limit 100 -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { int i; #pragma omp target parallel for default // expected-error {{expected '(' after 'default'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target parallel for default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target parallel for default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{explicit data sharing attribute requested here}} @@ -21,7 +30,7 @@ #pragma omp target parallel for default(shared), default(shared) // expected-error {{directive '#pragma omp target parallel for' cannot contain more than one 'default' clause}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target parallel for default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); @@ -34,5 +43,13 @@ for (i = 0; i < argc; ++i) // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} foo(); +#ifndef OMP51 +#pragma omp target parallel for default(firstprivate) // expected-error {{data-sharing attribute 'firstprivate' in 'default' clause requires OpenMP version 5.1 or above}} + for (i = 0; i < argc; ++i) { + ++x; + ++y; + } +#endif + return 0; } diff --git a/clang/test/OpenMP/target_parallel_for_simd_default_messages.cpp b/clang/test/OpenMP/target_parallel_for_simd_default_messages.cpp --- a/clang/test/OpenMP/target_parallel_for_simd_default_messages.cpp +++ b/clang/test/OpenMP/target_parallel_for_simd_default_messages.cpp @@ -2,17 +2,26 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp -ferror-limit 100 -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { int i; #pragma omp target parallel for simd default // expected-error {{expected '(' after 'default'}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for simd default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target parallel for simd default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for simd default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target parallel for simd default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); #pragma omp target parallel for simd default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-note {{explicit data sharing attribute requested here}} @@ -21,7 +30,7 @@ #pragma omp target parallel for simd default(shared), default(shared) // expected-error {{directive '#pragma omp target parallel for simd' cannot contain more than one 'default' clause}} for (i = 0; i < argc; ++i) foo(); -#pragma omp target parallel for simd default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target parallel for simd default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (i = 0; i < argc; ++i) foo(); @@ -34,5 +43,13 @@ for (i = 0; i < argc; ++i) // expected-error {{variable 'i' must have explicitly specified data sharing attributes}} expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} foo(); +#ifndef OMP51 +#pragma omp target parallel for simd default(firstprivate) // expected-error {{data-sharing attribute 'firstprivate' in 'default' clause requires OpenMP version 5.1 or above}} + for (int i = 0; i < argc; i++) { + ++x; + ++y; + } +#endif + return 0; } diff --git a/clang/test/OpenMP/target_teams_default_messages.cpp b/clang/test/OpenMP/target_teams_default_messages.cpp --- a/clang/test/OpenMP/target_teams_default_messages.cpp +++ b/clang/test/OpenMP/target_teams_default_messages.cpp @@ -2,20 +2,29 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target teams default // expected-error {{expected '(' after 'default'}} foo(); -#pragma omp target teams default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target teams default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} foo(); -#pragma omp target teams default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target teams default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} foo(); #pragma omp target teams default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} foo(); #pragma omp target teams default (shared), default(shared) // expected-error {{directive '#pragma omp target teams' cannot contain more than one 'default' clause}} foo(); -#pragma omp target teams default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target teams default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} foo(); #pragma omp target teams default(none) // expected-note {{explicit data sharing attribute requested here}} @@ -24,5 +33,14 @@ #pragma omp target teams default(none) // expected-note {{explicit data sharing attribute requested here}} #pragma omp parallel default(shared) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + +#ifndef OMP51 +#pragma omp target teams default(firstprivate) // expected-error {{data-sharing attribute 'firstprivate' in 'default' clause requires OpenMP version 5.1 or above}} + { + ++x; + ++y; + } +#endif + return 0; } diff --git a/clang/test/OpenMP/target_teams_distribute_default_messages.cpp b/clang/test/OpenMP/target_teams_distribute_default_messages.cpp --- a/clang/test/OpenMP/target_teams_distribute_default_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_default_messages.cpp @@ -2,24 +2,41 @@ // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=51 -DOMP51 %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-simd -fopenmp-version=51 -DOMP51 %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target teams distribute default // expected-error {{expected '(' after 'default'}} for (int i=0; i<200; i++) foo(); - #pragma omp target teams distribute default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target teams distribute default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); - #pragma omp target teams distribute default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target teams distribute default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target teams distribute default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); #pragma omp target teams distribute default (shared), default(shared) // expected-error {{directive '#pragma omp target teams distribute' cannot contain more than one 'default' clause}} for (int i=0; i<200; i++) foo(); - #pragma omp target teams distribute default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target teams distribute default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target teams distribute default(none) // expected-note {{explicit data sharing attribute requested here}} for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} +#ifndef OMP51 +#pragma omp target teams distribute default(firstprivate) // expected-error {{data-sharing attribute 'firstprivate' in 'default' clause requires OpenMP version 5.1 or above}} + for (int i = 0; i < 200; i++) { + ++x; + ++y; + } +#endif + return 0; } diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_default_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_default_messages.cpp --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_default_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_default_messages.cpp @@ -2,24 +2,41 @@ // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target teams distribute parallel for default // expected-error {{expected '(' after 'default'}} for (int i=0; i<200; i++) foo(); - #pragma omp target teams distribute parallel for default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target teams distribute parallel for default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); -#pragma omp target teams distribute parallel for default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target teams distribute parallel for default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target teams distribute parallel for default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); #pragma omp target teams distribute parallel for default (shared), default(shared) // expected-error {{directive '#pragma omp target teams distribute parallel for' cannot contain more than one 'default' clause}} for (int i=0; i<200; i++) foo(); -#pragma omp target teams distribute parallel for default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target teams distribute parallel for default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target teams distribute parallel for default(none) // expected-note {{explicit data sharing attribute requested here}} for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} +#ifndef OMP51 +#pragma omp target teams distribute parallel for default(firstprivate) // expected-error {{data-sharing attribute 'firstprivate' in 'default' clause requires OpenMP version 5.1 or above}} + for (int i = 0; i < 200; i++) { + ++x; + ++y; + } +#endif + return 0; } diff --git a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_default_messages.cpp b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_default_messages.cpp --- a/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_default_messages.cpp +++ b/clang/test/OpenMP/target_teams_distribute_parallel_for_simd_default_messages.cpp @@ -2,16 +2,25 @@ // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target teams distribute parallel for simd default // expected-error {{expected '(' after 'default'}} for (int i=0; i<200; i++) foo(); -#pragma omp target teams distribute parallel for simd default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp target teams distribute parallel for simd default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); -#pragma omp target teams distribute parallel for simd default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target teams distribute parallel for simd default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target teams distribute parallel for simd default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -20,11 +29,19 @@ #pragma omp target teams distribute parallel for simd default (shared), default(shared) // expected-error {{directive '#pragma omp target teams distribute parallel for simd' cannot contain more than one 'default' clause}} for (int i=0; i<200; i++) foo(); -#pragma omp target teams distribute parallel for simd default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp target teams distribute parallel for simd default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target teams distribute parallel for simd default(none) // expected-note {{explicit data sharing attribute requested here}} for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} +#ifndef OMP51 +#pragma omp target teams distribute parallel for simd default(firstprivate) // expected-error {{data-sharing attribute 'firstprivate' in 'default' clause requires OpenMP version 5.1 or above}} + for (int i = 0; i < argc; ++i) { + ++x; + ++y; + } +#endif + return 0; } diff --git a/clang/test/OpenMP/task_default_messages.cpp b/clang/test/OpenMP/task_default_messages.cpp --- a/clang/test/OpenMP/task_default_messages.cpp +++ b/clang/test/OpenMP/task_default_messages.cpp @@ -2,15 +2,24 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp -ferror-limit 100 -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd -ferror-limit 100 -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp task default // expected-error {{expected '(' after 'default'}} -#pragma omp task default( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} -#pragma omp task default() // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp task default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp task default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} #pragma omp task default(none // expected-error {{expected ')'}} expected-note {{to match this '('}} #pragma omp task default(shared), default(shared) // expected-error {{directive '#pragma omp task' cannot contain more than one 'default' clause}} -#pragma omp task default(x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp task default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} foo(); #pragma omp task default(none) // expected-note {{explicit data sharing attribute requested here}} @@ -19,5 +28,13 @@ #pragma omp task default(none) // expected-note {{explicit data sharing attribute requested here}} #pragma omp task default(shared) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + +#ifdef OMP51 +#pragma omp task default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif return 0; } diff --git a/clang/test/OpenMP/task_messages.cpp b/clang/test/OpenMP/task_messages.cpp --- a/clang/test/OpenMP/task_messages.cpp +++ b/clang/test/OpenMP/task_messages.cpp @@ -4,6 +4,9 @@ // RUN: %clang_cc1 -verify=expected,omp45 -fopenmp-version=45 -fopenmp-simd -ferror-limit 200 -std=c++11 -o - %s -Wuninitialized // RUN: %clang_cc1 -verify=expected,omp50 -fopenmp-version=50 -fopenmp-simd -ferror-limit 200 -std=c++11 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp-version=51 -DOMP51 -fopenmp -ferror-limit 100 -std=c++11 -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify=expected,omp50 -fopenmp-version=51 -DOMP51 -fopenmp-simd -ferror-limit 100 -std=c++11 -o - %s -Wuninitialized + void xxx(int argc) { int x; // expected-note {{initialize the variable 'x' to silence this warning}} #pragma omp task @@ -16,6 +19,10 @@ } typedef unsigned long omp_event_handle_t; +namespace { +static int y = 0; +} +static int x = 0; #pragma omp task // expected-error {{unexpected OpenMP directive '#pragma omp task'}} @@ -52,6 +59,15 @@ #pragma omp task default(none) // expected-note 2 {{explicit data sharing attribute requested here}} #pragma omp task default(shared) ++a; // expected-error 2 {{variable 'a' must have explicitly specified data sharing attributes}} +#ifdef OMP51 +#pragma omp task default(firstprivate) // expected-note 4 {{explicit data sharing attribute requested here}} +#pragma omp task + { + ++x; // expected-error 2 {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error 2 {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif + #pragma omp task default(none) // expected-note 2 {{explicit data sharing attribute requested here}} #pragma omp task // expected-error@+1 {{calling a private constructor of class 'S'}} diff --git a/clang/test/OpenMP/teams_default_messages.cpp b/clang/test/OpenMP/teams_default_messages.cpp --- a/clang/test/OpenMP/teams_default_messages.cpp +++ b/clang/test/OpenMP/teams_default_messages.cpp @@ -2,17 +2,26 @@ // RUN: %clang_cc1 -verify -fopenmp-simd -o - %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp -o - %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd -o - %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target #pragma omp teams default // expected-error {{expected '(' after 'default'}} foo(); #pragma omp target - #pragma omp teams default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp teams default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} foo(); #pragma omp target - #pragma omp teams default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} foo(); #pragma omp target #pragma omp teams default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -21,7 +30,7 @@ #pragma omp teams default (shared), default(shared) // expected-error {{directive '#pragma omp teams' cannot contain more than one 'default' clause}} foo(); #pragma omp target - #pragma omp teams default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} foo(); #pragma omp target @@ -32,5 +41,14 @@ #pragma omp teams default(none) // expected-note {{explicit data sharing attribute requested here}} #pragma omp parallel default(shared) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} + +#ifdef OMP51 +#pragma omp target +#pragma omp teams default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif return 0; } diff --git a/clang/test/OpenMP/teams_distribute_default_messages.cpp b/clang/test/OpenMP/teams_distribute_default_messages.cpp --- a/clang/test/OpenMP/teams_distribute_default_messages.cpp +++ b/clang/test/OpenMP/teams_distribute_default_messages.cpp @@ -2,17 +2,26 @@ // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target #pragma omp teams distribute default // expected-error {{expected '(' after 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp teams distribute default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams distribute default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target #pragma omp teams distribute default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -21,12 +30,21 @@ #pragma omp teams distribute default (shared), default(shared) // expected-error {{directive '#pragma omp teams distribute' cannot contain more than one 'default' clause}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams distribute default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target #pragma omp teams distribute default(none) // expected-note {{explicit data sharing attribute requested here}} for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} +#ifdef OMP51 +#pragma omp target +#pragma omp teams distribute default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + for (int i = 0; i < 200; i++) { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif + return 0; } diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_default_messages.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_default_messages.cpp --- a/clang/test/OpenMP/teams_distribute_parallel_for_default_messages.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_default_messages.cpp @@ -2,17 +2,26 @@ // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp %s -Wuninitialized + +// RUN: %clang_cc1 -verify -fopenmp-version=51 -DOMP51 -fopenmp-simd %s -Wuninitialized + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target #pragma omp teams distribute parallel for default // expected-error {{expected '(' after 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute parallel for default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp teams distribute parallel for default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute parallel for default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams distribute parallel for default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target #pragma omp teams distribute parallel for default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -21,12 +30,21 @@ #pragma omp teams distribute parallel for default (shared), default(shared) // expected-error {{directive '#pragma omp teams distribute parallel for' cannot contain more than one 'default' clause}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute parallel for default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams distribute parallel for default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target #pragma omp teams distribute parallel for default(none) // expected-note {{explicit data sharing attribute requested here}} for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} +#ifdef OMP51 +#pragma omp target +#pragma omp teams distribute parallel for default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + for (int i = 0; i < 200; i++) { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif + return 0; } diff --git a/clang/test/OpenMP/teams_distribute_parallel_for_simd_default_messages.cpp b/clang/test/OpenMP/teams_distribute_parallel_for_simd_default_messages.cpp --- a/clang/test/OpenMP/teams_distribute_parallel_for_simd_default_messages.cpp +++ b/clang/test/OpenMP/teams_distribute_parallel_for_simd_default_messages.cpp @@ -2,17 +2,26 @@ // RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized -fopenmp-version=51 -DOMP51 + +// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized -fopenmp-version=51 -DOMP51 + void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target #pragma omp teams distribute parallel for simd default // expected-error {{expected '(' after 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute parallel for simd default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp teams distribute parallel for simd default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute parallel for simd default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams distribute parallel for simd default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target #pragma omp teams distribute parallel for simd default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -21,12 +30,20 @@ #pragma omp teams distribute parallel for simd default (shared), default(shared) // expected-error {{directive '#pragma omp teams distribute parallel for simd' cannot contain more than one 'default' clause}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute parallel for simd default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams distribute parallel for simd default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target #pragma omp teams distribute parallel for simd default(none) // expected-note {{explicit data sharing attribute requested here}} for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} +#ifdef OpenMP51 +#pragma omp teams distribute parallel for default(firstprivate) // expected-note 2 {{explicit data sharing attribute requested here}} + for (int i = 0; i < 200; i++) { + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + } +#endif + return 0; } diff --git a/clang/test/OpenMP/teams_distribute_simd_default_messages.cpp b/clang/test/OpenMP/teams_distribute_simd_default_messages.cpp --- a/clang/test/OpenMP/teams_distribute_simd_default_messages.cpp +++ b/clang/test/OpenMP/teams_distribute_simd_default_messages.cpp @@ -1,18 +1,23 @@ -// RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp %s -Wuninitialized -fopenmp-version=51 -// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized +// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized -fopenmp-version=51 void foo(); +namespace { +static int y = 0; +} +static int x = 0; + int main(int argc, char **argv) { #pragma omp target #pragma omp teams distribute simd default // expected-error {{expected '(' after 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute simd default ( // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} +#pragma omp teams distribute simd default( // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} expected-error {{expected ')'}} expected-note {{to match this '('}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute simd default () // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams distribute simd default() // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target #pragma omp teams distribute simd default (none // expected-error {{expected ')'}} expected-note {{to match this '('}} @@ -21,12 +26,22 @@ #pragma omp teams distribute simd default (shared), default(shared) // expected-error {{directive '#pragma omp teams distribute simd' cannot contain more than one 'default' clause}} for (int i=0; i<200; i++) foo(); #pragma omp target - #pragma omp teams distribute simd default (x) // expected-error {{expected 'none' or 'shared' in OpenMP clause 'default'}} +#pragma omp teams distribute simd default(x) // expected-error {{expected 'none', 'shared' or 'firstprivate' in OpenMP clause 'default'}} for (int i=0; i<200; i++) foo(); #pragma omp target #pragma omp teams distribute simd default(none) // expected-note {{explicit data sharing attribute requested here}} for (int i=0; i<200; i++) ++argc; // expected-error {{variable 'argc' must have explicitly specified data sharing attributes}} +#pragma omp target +#pragma omp teams distribute simd default(firstprivate) // expected-note {{explicit data sharing attribute requested here}} + for (int i = 0; i < 200; i++) + ++x; // expected-error {{variable 'x' must have explicitly specified data sharing attributes}} + +#pragma omp target +#pragma omp teams distribute simd default(firstprivate) // expected-note {{explicit data sharing attribute requested here}} + for (int i = 0; i < 200; i++) + ++y; // expected-error {{variable 'y' must have explicitly specified data sharing attributes}} + return 0; } diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp --- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp @@ -103,9 +103,9 @@ StringRef input = R"cc( void Test() { FOUR_PLUS_FOUR; } )cc"; - EXPECT_TRUE(matchesConditionally(input, - binaryOperator(isExpandedFromMacro("FOUR_PLUS_FOUR")), - true, {"-std=c++11", "-DFOUR_PLUS_FOUR=4+4"})); + EXPECT_TRUE(matchesConditionally( + input, binaryOperator(isExpandedFromMacro("FOUR_PLUS_FOUR")), true, + {"-std=c++11", "-DFOUR_PLUS_FOUR=4+4"})); } TEST(IsExpandedFromMacro, ShouldNotMatchBeginOnly) { @@ -143,31 +143,31 @@ } TEST(AllOf, AllOverloadsWork) { - const char Program[] = - "struct T { };" - "int f(int, T*, int, int);" - "void g(int x) { T t; f(x, &t, 3, 4); }"; - EXPECT_TRUE(matches(Program, - callExpr(allOf(callee(functionDecl(hasName("f"))), - hasArgument(0, declRefExpr(to(varDecl()))))))); - EXPECT_TRUE(matches(Program, - callExpr(allOf(callee(functionDecl(hasName("f"))), - hasArgument(0, declRefExpr(to(varDecl()))), - hasArgument(1, hasType(pointsTo( - recordDecl(hasName("T"))))))))); - EXPECT_TRUE(matches(Program, - callExpr(allOf(callee(functionDecl(hasName("f"))), - hasArgument(0, declRefExpr(to(varDecl()))), - hasArgument(1, hasType(pointsTo( - recordDecl(hasName("T"))))), - hasArgument(2, integerLiteral(equals(3))))))); - EXPECT_TRUE(matches(Program, - callExpr(allOf(callee(functionDecl(hasName("f"))), - hasArgument(0, declRefExpr(to(varDecl()))), - hasArgument(1, hasType(pointsTo( - recordDecl(hasName("T"))))), - hasArgument(2, integerLiteral(equals(3))), - hasArgument(3, integerLiteral(equals(4))))))); + const char Program[] = "struct T { };" + "int f(int, T*, int, int);" + "void g(int x) { T t; f(x, &t, 3, 4); }"; + EXPECT_TRUE(matches( + Program, callExpr(allOf(callee(functionDecl(hasName("f"))), + hasArgument(0, declRefExpr(to(varDecl()))))))); + EXPECT_TRUE(matches( + Program, + callExpr( + allOf(callee(functionDecl(hasName("f"))), + hasArgument(0, declRefExpr(to(varDecl()))), + hasArgument(1, hasType(pointsTo(recordDecl(hasName("T"))))))))); + EXPECT_TRUE(matches( + Program, callExpr(allOf( + callee(functionDecl(hasName("f"))), + hasArgument(0, declRefExpr(to(varDecl()))), + hasArgument(1, hasType(pointsTo(recordDecl(hasName("T"))))), + hasArgument(2, integerLiteral(equals(3))))))); + EXPECT_TRUE(matches( + Program, callExpr(allOf( + callee(functionDecl(hasName("f"))), + hasArgument(0, declRefExpr(to(varDecl()))), + hasArgument(1, hasType(pointsTo(recordDecl(hasName("T"))))), + hasArgument(2, integerLiteral(equals(3))), + hasArgument(3, integerLiteral(equals(4))))))); } TEST(DeclarationMatcher, MatchHas) { @@ -176,127 +176,103 @@ EXPECT_TRUE(matches("class X {};", HasClassX)); DeclarationMatcher YHasClassX = - recordDecl(hasName("Y"), has(recordDecl(hasName("X")))); + recordDecl(hasName("Y"), has(recordDecl(hasName("X")))); EXPECT_TRUE(matches("class Y { class X {}; };", YHasClassX)); EXPECT_TRUE(notMatches("class X {};", YHasClassX)); - EXPECT_TRUE( - notMatches("class Y { class Z { class X {}; }; };", YHasClassX)); + EXPECT_TRUE(notMatches("class Y { class Z { class X {}; }; };", YHasClassX)); } TEST(DeclarationMatcher, MatchHasRecursiveAllOf) { DeclarationMatcher Recursive = - recordDecl( - has(recordDecl( - has(recordDecl(hasName("X"))), - has(recordDecl(hasName("Y"))), - hasName("Z"))), - has(recordDecl( - has(recordDecl(hasName("A"))), - has(recordDecl(hasName("B"))), - hasName("C"))), - hasName("F")); - - EXPECT_TRUE(matches( - "class F {" - " class Z {" - " class X {};" - " class Y {};" - " };" - " class C {" - " class A {};" - " class B {};" - " };" - "};", Recursive)); - - EXPECT_TRUE(matches( - "class F {" - " class Z {" - " class A {};" - " class X {};" - " class Y {};" - " };" - " class C {" - " class X {};" - " class A {};" - " class B {};" - " };" - "};", Recursive)); - - EXPECT_TRUE(matches( - "class O1 {" - " class O2 {" - " class F {" - " class Z {" - " class A {};" - " class X {};" - " class Y {};" - " };" - " class C {" - " class X {};" - " class A {};" - " class B {};" - " };" - " };" - " };" - "};", Recursive)); + recordDecl(has(recordDecl(has(recordDecl(hasName("X"))), + has(recordDecl(hasName("Y"))), hasName("Z"))), + has(recordDecl(has(recordDecl(hasName("A"))), + has(recordDecl(hasName("B"))), hasName("C"))), + hasName("F")); + + EXPECT_TRUE(matches("class F {" + " class Z {" + " class X {};" + " class Y {};" + " };" + " class C {" + " class A {};" + " class B {};" + " };" + "};", + Recursive)); + + EXPECT_TRUE(matches("class F {" + " class Z {" + " class A {};" + " class X {};" + " class Y {};" + " };" + " class C {" + " class X {};" + " class A {};" + " class B {};" + " };" + "};", + Recursive)); + + EXPECT_TRUE(matches("class O1 {" + " class O2 {" + " class F {" + " class Z {" + " class A {};" + " class X {};" + " class Y {};" + " };" + " class C {" + " class X {};" + " class A {};" + " class B {};" + " };" + " };" + " };" + "};", + Recursive)); } TEST(DeclarationMatcher, MatchHasRecursiveAnyOf) { - DeclarationMatcher Recursive = - recordDecl( - anyOf( - has(recordDecl( - anyOf( - has(recordDecl( - hasName("X"))), - has(recordDecl( - hasName("Y"))), - hasName("Z")))), - has(recordDecl( - anyOf( - hasName("C"), - has(recordDecl( - hasName("A"))), - has(recordDecl( - hasName("B")))))), - hasName("F"))); + DeclarationMatcher Recursive = recordDecl( + anyOf(has(recordDecl(anyOf(has(recordDecl(hasName("X"))), + has(recordDecl(hasName("Y"))), hasName("Z")))), + has(recordDecl(anyOf(hasName("C"), has(recordDecl(hasName("A"))), + has(recordDecl(hasName("B")))))), + hasName("F"))); EXPECT_TRUE(matches("class F {};", Recursive)); EXPECT_TRUE(matches("class Z {};", Recursive)); EXPECT_TRUE(matches("class C {};", Recursive)); EXPECT_TRUE(matches("class M { class N { class X {}; }; };", Recursive)); EXPECT_TRUE(matches("class M { class N { class B {}; }; };", Recursive)); - EXPECT_TRUE( - matches("class O1 { class O2 {" - " class M { class N { class B {}; }; }; " - "}; };", Recursive)); + EXPECT_TRUE(matches("class O1 { class O2 {" + " class M { class N { class B {}; }; }; " + "}; };", + Recursive)); } TEST(DeclarationMatcher, MatchNot) { DeclarationMatcher NotClassX = - cxxRecordDecl( - isDerivedFrom("Y"), - unless(hasName("X"))); + cxxRecordDecl(isDerivedFrom("Y"), unless(hasName("X"))); EXPECT_TRUE(notMatches("", NotClassX)); EXPECT_TRUE(notMatches("class Y {};", NotClassX)); EXPECT_TRUE(matches("class Y {}; class Z : public Y {};", NotClassX)); EXPECT_TRUE(notMatches("class Y {}; class X : public Y {};", NotClassX)); EXPECT_TRUE( - notMatches("class Y {}; class Z {}; class X : public Y {};", - NotClassX)); + notMatches("class Y {}; class Z {}; class X : public Y {};", NotClassX)); DeclarationMatcher ClassXHasNotClassY = - recordDecl( - hasName("X"), - has(recordDecl(hasName("Z"))), - unless( - has(recordDecl(hasName("Y"))))); + recordDecl(hasName("X"), has(recordDecl(hasName("Z"))), + unless(has(recordDecl(hasName("Y"))))); EXPECT_TRUE(matches("class X { class Z {}; };", ClassXHasNotClassY)); - EXPECT_TRUE(notMatches("class X { class Y {}; class Z {}; };", - ClassXHasNotClassY)); + EXPECT_TRUE( + notMatches("class X { class Y {}; class Z {}; };", ClassXHasNotClassY)); DeclarationMatcher NamedNotRecord = - namedDecl(hasName("Foo"), unless(recordDecl())); + namedDecl(hasName("Foo"), unless(recordDecl())); EXPECT_TRUE(matches("void Foo(){}", NamedNotRecord)); EXPECT_TRUE(notMatches("struct Foo {};", NamedNotRecord)); } @@ -318,67 +294,61 @@ TEST(DeclarationMatcher, HasDescendant) { DeclarationMatcher ZDescendantClassX = - recordDecl( - hasDescendant(recordDecl(hasName("X"))), - hasName("Z")); + recordDecl(hasDescendant(recordDecl(hasName("X"))), hasName("Z")); EXPECT_TRUE(matches("class Z { class X {}; };", ZDescendantClassX)); EXPECT_TRUE( - matches("class Z { class Y { class X {}; }; };", ZDescendantClassX)); + matches("class Z { class Y { class X {}; }; };", ZDescendantClassX)); + EXPECT_TRUE(matches("class Z { class A { class Y { class X {}; }; }; };", + ZDescendantClassX)); EXPECT_TRUE( - matches("class Z { class A { class Y { class X {}; }; }; };", - ZDescendantClassX)); - EXPECT_TRUE( - matches("class Z { class A { class B { class Y { class X {}; }; }; }; };", - ZDescendantClassX)); + matches("class Z { class A { class B { class Y { class X {}; }; }; }; };", + ZDescendantClassX)); EXPECT_TRUE(notMatches("class Z {};", ZDescendantClassX)); - DeclarationMatcher ZDescendantClassXHasClassY = - recordDecl( - hasDescendant(recordDecl(has(recordDecl(hasName("Y"))), - hasName("X"))), + DeclarationMatcher ZDescendantClassXHasClassY = recordDecl( + hasDescendant(recordDecl(has(recordDecl(hasName("Y"))), hasName("X"))), hasName("Z")); EXPECT_TRUE(matches("class Z { class X { class Y {}; }; };", ZDescendantClassXHasClassY)); EXPECT_TRUE( - matches("class Z { class A { class B { class X { class Y {}; }; }; }; };", - ZDescendantClassXHasClassY)); - EXPECT_TRUE(notMatches( - "class Z {" - " class A {" - " class B {" - " class X {" - " class C {" - " class Y {};" - " };" - " };" - " }; " - " };" - "};", ZDescendantClassXHasClassY)); + matches("class Z { class A { class B { class X { class Y {}; }; }; }; };", + ZDescendantClassXHasClassY)); + EXPECT_TRUE(notMatches("class Z {" + " class A {" + " class B {" + " class X {" + " class C {" + " class Y {};" + " };" + " };" + " }; " + " };" + "};", + ZDescendantClassXHasClassY)); DeclarationMatcher ZDescendantClassXDescendantClassY = - recordDecl( - hasDescendant(recordDecl(hasDescendant(recordDecl(hasName("Y"))), - hasName("X"))), - hasName("Z")); - EXPECT_TRUE( - matches("class Z { class A { class X { class B { class Y {}; }; }; }; };", - ZDescendantClassXDescendantClassY)); - EXPECT_TRUE(matches( - "class Z {" - " class A {" - " class X {" - " class B {" - " class Y {};" - " };" - " class Y {};" - " };" - " };" - "};", ZDescendantClassXDescendantClassY)); + recordDecl(hasDescendant(recordDecl( + hasDescendant(recordDecl(hasName("Y"))), hasName("X"))), + hasName("Z")); + EXPECT_TRUE( + matches("class Z { class A { class X { class B { class Y {}; }; }; }; };", + ZDescendantClassXDescendantClassY)); + EXPECT_TRUE(matches("class Z {" + " class A {" + " class X {" + " class B {" + " class Y {};" + " };" + " class Y {};" + " };" + " };" + "};", + ZDescendantClassXDescendantClassY)); } TEST(DeclarationMatcher, HasDescendantMemoization) { DeclarationMatcher CannotMemoize = - decl(hasDescendant(typeLoc().bind("x")), has(decl())); + decl(hasDescendant(typeLoc().bind("x")), has(decl())); EXPECT_TRUE(matches("void f() { int i; }", CannotMemoize)); } @@ -401,39 +371,36 @@ // That node can't be memoized so we have to check for it before trying to put // it on the cache. DeclarationMatcher CannotMemoize = classTemplateSpecializationDecl( - hasAnyTemplateArgument(templateArgument().bind("targ")), - forEach(fieldDecl(hasAncestor(forStmt())))); + hasAnyTemplateArgument(templateArgument().bind("targ")), + forEach(fieldDecl(hasAncestor(forStmt())))); EXPECT_TRUE(notMatches("template struct S;" - "template <> struct S { int i; int j; };", + "template <> struct S { int i; int j; };", CannotMemoize)); } TEST(DeclarationMatcher, HasAttr) { EXPECT_TRUE(matches("struct __attribute__((warn_unused)) X {};", decl(hasAttr(clang::attr::WarnUnused)))); - EXPECT_FALSE(matches("struct X {};", - decl(hasAttr(clang::attr::WarnUnused)))); + EXPECT_FALSE(matches("struct X {};", decl(hasAttr(clang::attr::WarnUnused)))); } - TEST(DeclarationMatcher, MatchAnyOf) { DeclarationMatcher YOrZDerivedFromX = cxxRecordDecl( - anyOf(hasName("Y"), allOf(isDerivedFrom("X"), hasName("Z")))); + anyOf(hasName("Y"), allOf(isDerivedFrom("X"), hasName("Z")))); EXPECT_TRUE(matches("class X {}; class Z : public X {};", YOrZDerivedFromX)); EXPECT_TRUE(matches("class Y {};", YOrZDerivedFromX)); EXPECT_TRUE( - notMatches("class X {}; class W : public X {};", YOrZDerivedFromX)); + notMatches("class X {}; class W : public X {};", YOrZDerivedFromX)); EXPECT_TRUE(notMatches("class Z {};", YOrZDerivedFromX)); DeclarationMatcher XOrYOrZOrU = - recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U"))); + recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U"))); EXPECT_TRUE(matches("class X {};", XOrYOrZOrU)); EXPECT_TRUE(notMatches("class V {};", XOrYOrZOrU)); - DeclarationMatcher XOrYOrZOrUOrV = - recordDecl(anyOf(hasName("X"), hasName("Y"), hasName("Z"), hasName("U"), - hasName("V"))); + DeclarationMatcher XOrYOrZOrUOrV = recordDecl(anyOf( + hasName("X"), hasName("Y"), hasName("Z"), hasName("U"), hasName("V"))); EXPECT_TRUE(matches("class X {};", XOrYOrZOrUOrV)); EXPECT_TRUE(matches("class Y {};", XOrYOrZOrUOrV)); EXPECT_TRUE(matches("class Z {};", XOrYOrZOrUOrV)); @@ -447,8 +414,8 @@ EXPECT_TRUE(notMatches("int F() { return 1; }", MixedTypes)); EXPECT_TRUE( - matches("void f() try { } catch (int) { } catch (...) { }", - cxxCatchStmt(anyOf(hasDescendant(varDecl()), isCatchAll())))); + matches("void f() try { } catch (int) { } catch (...) { }", + cxxCatchStmt(anyOf(hasDescendant(varDecl()), isCatchAll())))); } TEST(DeclarationMatcher, ClassIsDerived) { @@ -460,19 +427,17 @@ EXPECT_TRUE(notMatches("class Y;", IsDerivedFromX)); EXPECT_TRUE(notMatches("", IsDerivedFromX)); EXPECT_TRUE(matches("class X {}; template class Y : Y , X {};", - IsDerivedFromX)); + IsDerivedFromX)); EXPECT_TRUE(matches("class X {}; template class Y : X, Y {};", - IsDerivedFromX)); + IsDerivedFromX)); - DeclarationMatcher IsZDerivedFromX = cxxRecordDecl(hasName("Z"), - isDerivedFrom("X")); - EXPECT_TRUE( - matches( - "class X {};" - "template class Y : Y {};" - "template<> class Y<0> : X {};" - "class Z : Y<1> {};", - IsZDerivedFromX)); + DeclarationMatcher IsZDerivedFromX = + cxxRecordDecl(hasName("Z"), isDerivedFrom("X")); + EXPECT_TRUE(matches("class X {};" + "template class Y : Y {};" + "template<> class Y<0> : X {};" + "class Z : Y<1> {};", + IsZDerivedFromX)); DeclarationMatcher IsDirectlyDerivedFromX = cxxRecordDecl(isDirectlyDerivedFrom("X")); @@ -493,145 +458,138 @@ EXPECT_TRUE(notMatches("", IsAX)); DeclarationMatcher ZIsDerivedFromX = - cxxRecordDecl(hasName("Z"), isDerivedFrom("X")); + cxxRecordDecl(hasName("Z"), isDerivedFrom("X")); DeclarationMatcher ZIsDirectlyDerivedFromX = cxxRecordDecl(hasName("Z"), isDirectlyDerivedFrom("X")); EXPECT_TRUE( - matches("class X {}; class Y : public X {}; class Z : public Y {};", - ZIsDerivedFromX)); + matches("class X {}; class Y : public X {}; class Z : public Y {};", + ZIsDerivedFromX)); EXPECT_TRUE( notMatches("class X {}; class Y : public X {}; class Z : public Y {};", ZIsDirectlyDerivedFromX)); - EXPECT_TRUE( - matches("class X {};" - "template class Y : public X {};" - "class Z : public Y {};", ZIsDerivedFromX)); + EXPECT_TRUE(matches("class X {};" + "template class Y : public X {};" + "class Z : public Y {};", + ZIsDerivedFromX)); EXPECT_TRUE(notMatches("class X {};" "template class Y : public X {};" "class Z : public Y {};", ZIsDirectlyDerivedFromX)); EXPECT_TRUE(matches("class X {}; template class Z : public X {};", ZIsDerivedFromX)); + EXPECT_TRUE(matches("template class X {}; " + "template class Z : public X {};", + ZIsDerivedFromX)); + EXPECT_TRUE(matches("template class X {}; " + "template class Z : public X {};", + ZIsDerivedFromX)); EXPECT_TRUE( - matches("template class X {}; " - "template class Z : public X {};", - ZIsDerivedFromX)); - EXPECT_TRUE( - matches("template class X {}; " - "template class Z : public X {};", - ZIsDerivedFromX)); - EXPECT_TRUE( - notMatches("template class A { class Z : public X {}; };", - ZIsDerivedFromX)); + notMatches("template class A { class Z : public X {}; };", + ZIsDerivedFromX)); EXPECT_TRUE( - matches("template class A { public: class Z : public X {}; }; " - "class X{}; void y() { A ::Z z; }", ZIsDerivedFromX)); + matches("template class A { public: class Z : public X {}; }; " + "class X{}; void y() { A ::Z z; }", + ZIsDerivedFromX)); EXPECT_TRUE( - matches("template class X {}; " + matches("template class X {}; " "template class A { class Z : public X {}; };", - ZIsDerivedFromX)); - EXPECT_TRUE( - notMatches("template class X> class A { " - " class Z : public X {}; };", ZIsDerivedFromX)); - EXPECT_TRUE( - matches("template class X> class A { " - " public: class Z : public X {}; }; " - "template class X {}; void y() { A ::Z z; }", - ZIsDerivedFromX)); - EXPECT_TRUE( - notMatches("template class A { class Z : public X::D {}; };", - ZIsDerivedFromX)); - EXPECT_TRUE( - matches("template class A { public: " - " class Z : public X::D {}; }; " - "class Y { public: class X {}; typedef X D; }; " - "void y() { A ::Z z; }", ZIsDerivedFromX)); - EXPECT_TRUE( - matches("class X {}; typedef X Y; class Z : public Y {};", - ZIsDerivedFromX)); + ZIsDerivedFromX)); + EXPECT_TRUE(notMatches("template class X> class A { " + " class Z : public X {}; };", + ZIsDerivedFromX)); + EXPECT_TRUE(matches("template class X> class A { " + " public: class Z : public X {}; }; " + "template class X {}; void y() { A ::Z z; }", + ZIsDerivedFromX)); EXPECT_TRUE( - matches("template class Y { typedef typename T::U X; " - " class Z : public X {}; };", ZIsDerivedFromX)); - EXPECT_TRUE(matches("class X {}; class Z : public ::X {};", + notMatches("template class A { class Z : public X::D {}; };", + ZIsDerivedFromX)); + EXPECT_TRUE(matches("template class A { public: " + " class Z : public X::D {}; }; " + "class Y { public: class X {}; typedef X D; }; " + "void y() { A ::Z z; }", ZIsDerivedFromX)); + EXPECT_TRUE(matches("class X {}; typedef X Y; class Z : public Y {};", + ZIsDerivedFromX)); + EXPECT_TRUE(matches("template class Y { typedef typename T::U X; " + " class Z : public X {}; };", + ZIsDerivedFromX)); + EXPECT_TRUE(matches("class X {}; class Z : public ::X {};", ZIsDerivedFromX)); EXPECT_TRUE( - notMatches("template class X {}; " + notMatches("template class X {}; " "template class A { class Z : public X ::D {}; };", - ZIsDerivedFromX)); + ZIsDerivedFromX)); EXPECT_TRUE( - matches("template class X { public: typedef X D; }; " + matches("template class X { public: typedef X D; }; " "template class A { public: " " class Z : public X ::D {}; }; void y() { A ::Z z; }", - ZIsDerivedFromX)); + ZIsDerivedFromX)); EXPECT_TRUE( - notMatches("template class A { class Z : public X::D::E {}; };", - ZIsDerivedFromX)); + notMatches("template class A { class Z : public X::D::E {}; };", + ZIsDerivedFromX)); EXPECT_TRUE( - matches("class X {}; typedef X V; typedef V W; class Z : public W {};", - ZIsDerivedFromX)); - EXPECT_TRUE( - matches("class X {}; class Y : public X {}; " - "typedef Y V; typedef V W; class Z : public W {};", - ZIsDerivedFromX)); + matches("class X {}; typedef X V; typedef V W; class Z : public W {};", + ZIsDerivedFromX)); + EXPECT_TRUE(matches("class X {}; class Y : public X {}; " + "typedef Y V; typedef V W; class Z : public W {};", + ZIsDerivedFromX)); EXPECT_TRUE(notMatches("class X {}; class Y : public X {}; " "typedef Y V; typedef V W; class Z : public W {};", ZIsDirectlyDerivedFromX)); EXPECT_TRUE( - matches("template class X {}; " + matches("template class X {}; " "template class A { class Z : public X {}; };", - ZIsDerivedFromX)); + ZIsDerivedFromX)); EXPECT_TRUE( - notMatches("template class D { typedef X A; typedef A B; " + notMatches("template class D { typedef X A; typedef A B; " " typedef B C; class Z : public C {}; };", - ZIsDerivedFromX)); - EXPECT_TRUE( - matches("class X {}; typedef X A; typedef A B; " - "class Z : public B {};", ZIsDerivedFromX)); - EXPECT_TRUE( - matches("class X {}; typedef X A; typedef A B; typedef B C; " - "class Z : public C {};", ZIsDerivedFromX)); - EXPECT_TRUE( - matches("class U {}; typedef U X; typedef X V; " - "class Z : public V {};", ZIsDerivedFromX)); - EXPECT_TRUE( - matches("class Base {}; typedef Base X; " - "class Z : public Base {};", ZIsDerivedFromX)); - EXPECT_TRUE( - matches("class Base {}; typedef Base Base2; typedef Base2 X; " - "class Z : public Base {};", ZIsDerivedFromX)); - EXPECT_TRUE( - notMatches("class Base {}; class Base2 {}; typedef Base2 X; " - "class Z : public Base {};", ZIsDerivedFromX)); - EXPECT_TRUE( - matches("class A {}; typedef A X; typedef A Y; " - "class Z : public Y {};", ZIsDerivedFromX)); - EXPECT_TRUE( - notMatches("template class Z;" - "template <> class Z {};" - "template class Z : public Z {};", - IsDerivedFromX)); - EXPECT_TRUE( - matches("template class X;" - "template <> class X {};" - "template class X : public X {};", - IsDerivedFromX)); - EXPECT_TRUE(matches( - "class X {};" - "template class Z;" - "template <> class Z {};" - "template class Z : public Z , public X {};", - ZIsDerivedFromX)); - EXPECT_TRUE( - notMatches("template struct X;" + ZIsDerivedFromX)); + EXPECT_TRUE(matches("class X {}; typedef X A; typedef A B; " + "class Z : public B {};", + ZIsDerivedFromX)); + EXPECT_TRUE(matches("class X {}; typedef X A; typedef A B; typedef B C; " + "class Z : public C {};", + ZIsDerivedFromX)); + EXPECT_TRUE(matches("class U {}; typedef U X; typedef X V; " + "class Z : public V {};", + ZIsDerivedFromX)); + EXPECT_TRUE(matches("class Base {}; typedef Base X; " + "class Z : public Base {};", + ZIsDerivedFromX)); + EXPECT_TRUE(matches("class Base {}; typedef Base Base2; typedef Base2 X; " + "class Z : public Base {};", + ZIsDerivedFromX)); + EXPECT_TRUE(notMatches("class Base {}; class Base2 {}; typedef Base2 X; " + "class Z : public Base {};", + ZIsDerivedFromX)); + EXPECT_TRUE(matches("class A {}; typedef A X; typedef A Y; " + "class Z : public Y {};", + ZIsDerivedFromX)); + EXPECT_TRUE(notMatches("template class Z;" + "template <> class Z {};" + "template class Z : public Z {};", + IsDerivedFromX)); + EXPECT_TRUE(matches("template class X;" + "template <> class X {};" + "template class X : public X {};", + IsDerivedFromX)); + EXPECT_TRUE( + matches("class X {};" + "template class Z;" + "template <> class Z {};" + "template class Z : public Z , public X {};", + ZIsDerivedFromX)); + EXPECT_TRUE( + notMatches("template struct X;" "template struct X : public X {};", - cxxRecordDecl(isDerivedFrom(recordDecl(hasName("Some")))))); + cxxRecordDecl(isDerivedFrom(recordDecl(hasName("Some")))))); EXPECT_TRUE(matches( - "struct A {};" + "struct A {};" "template struct X;" "template struct X : public X {};" "template<> struct X<0> : public A {};" "struct B : public X<42> {};", - cxxRecordDecl(hasName("B"), isDerivedFrom(recordDecl(hasName("A")))))); + cxxRecordDecl(hasName("B"), isDerivedFrom(recordDecl(hasName("A")))))); EXPECT_TRUE(notMatches( "struct A {};" "template struct X;" @@ -645,7 +603,7 @@ // get rid of the Variable(...) matching and match the right template // declarations directly. const char *RecursiveTemplateOneParameter = - "class Base1 {}; class Base2 {};" + "class Base1 {}; class Base2 {};" "template class Z;" "template <> class Z : public Base1 {};" "template <> class Z : public Base2 {};" @@ -654,21 +612,21 @@ "template class Z : public Z , public Z {};" "void f() { Z z_float; Z z_double; Z z_char; }"; EXPECT_TRUE(matches( - RecursiveTemplateOneParameter, - varDecl(hasName("z_float"), - hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1"))))))); + RecursiveTemplateOneParameter, + varDecl(hasName("z_float"), + hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1"))))))); EXPECT_TRUE(notMatches( - RecursiveTemplateOneParameter, - varDecl(hasName("z_float"), - hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base2"))))))); - EXPECT_TRUE(matches( - RecursiveTemplateOneParameter, - varDecl(hasName("z_char"), - hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1"), - isDerivedFrom("Base2"))))))); + RecursiveTemplateOneParameter, + varDecl(hasName("z_float"), + hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base2"))))))); + EXPECT_TRUE( + matches(RecursiveTemplateOneParameter, + varDecl(hasName("z_char"), + hasInitializer(hasType(cxxRecordDecl( + isDerivedFrom("Base1"), isDerivedFrom("Base2"))))))); const char *RecursiveTemplateTwoParameters = - "class Base1 {}; class Base2 {};" + "class Base1 {}; class Base2 {};" "template class Z;" "template class Z : public Base1 {};" "template class Z : public Base2 {};" @@ -679,34 +637,31 @@ "void f() { Z z_float; Z z_double; " " Z z_char; }"; EXPECT_TRUE(matches( - RecursiveTemplateTwoParameters, - varDecl(hasName("z_float"), - hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1"))))))); - EXPECT_TRUE(notMatches( - RecursiveTemplateTwoParameters, - varDecl(hasName("z_float"), - hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base2"))))))); - EXPECT_TRUE(matches( - RecursiveTemplateTwoParameters, - varDecl(hasName("z_char"), - hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1"), - isDerivedFrom("Base2"))))))); - EXPECT_TRUE(matches( - "namespace ns { class X {}; class Y : public X {}; }", - cxxRecordDecl(isDerivedFrom("::ns::X")))); + RecursiveTemplateTwoParameters, + varDecl(hasName("z_float"), + hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base1"))))))); EXPECT_TRUE(notMatches( - "class X {}; class Y : public X {};", - cxxRecordDecl(isDerivedFrom("::ns::X")))); + RecursiveTemplateTwoParameters, + varDecl(hasName("z_float"), + hasInitializer(hasType(cxxRecordDecl(isDerivedFrom("Base2"))))))); + EXPECT_TRUE( + matches(RecursiveTemplateTwoParameters, + varDecl(hasName("z_char"), + hasInitializer(hasType(cxxRecordDecl( + isDerivedFrom("Base1"), isDerivedFrom("Base2"))))))); + EXPECT_TRUE(matches("namespace ns { class X {}; class Y : public X {}; }", + cxxRecordDecl(isDerivedFrom("::ns::X")))); + EXPECT_TRUE(notMatches("class X {}; class Y : public X {};", + cxxRecordDecl(isDerivedFrom("::ns::X")))); EXPECT_TRUE(matches( - "class X {}; class Y : public X {};", - cxxRecordDecl(isDerivedFrom(recordDecl(hasName("X")).bind("test"))))); + "class X {}; class Y : public X {};", + cxxRecordDecl(isDerivedFrom(recordDecl(hasName("X")).bind("test"))))); - EXPECT_TRUE(matches( - "template class X {};" - "template using Z = X ;" - "template class Y : Z {};", - cxxRecordDecl(isDerivedFrom(namedDecl(hasName("X")))))); + EXPECT_TRUE(matches("template class X {};" + "template using Z = X ;" + "template class Y : Z {};", + cxxRecordDecl(isDerivedFrom(namedDecl(hasName("X")))))); } TEST(DeclarationMatcher, IsDerivedFromEmptyName) { @@ -737,24 +692,24 @@ DeclarationMatcher IsDirectlyDerivedFromX = objcInterfaceDecl(isDirectlyDerivedFrom("X")); - EXPECT_TRUE( - matchesObjC("@interface X @end @interface Y : X @end", IsDirectlyDerivedFromX)); + EXPECT_TRUE(matchesObjC("@interface X @end @interface Y : X @end", + IsDirectlyDerivedFromX)); EXPECT_TRUE(matchesObjC( "@interface X @end @interface Y<__covariant ObjectType> : X @end", IsDirectlyDerivedFromX)); EXPECT_TRUE(matchesObjC( "@interface X @end @compatibility_alias Y X; @interface Z : Y @end", IsDirectlyDerivedFromX)); - EXPECT_TRUE(matchesObjC( - "@interface X @end typedef X Y; @interface Z : Y @end", - IsDirectlyDerivedFromX)); + EXPECT_TRUE( + matchesObjC("@interface X @end typedef X Y; @interface Z : Y @end", + IsDirectlyDerivedFromX)); EXPECT_TRUE(notMatchesObjC("@interface X @end", IsDirectlyDerivedFromX)); EXPECT_TRUE(notMatchesObjC("@class X;", IsDirectlyDerivedFromX)); EXPECT_TRUE(notMatchesObjC("@class Y;", IsDirectlyDerivedFromX)); EXPECT_TRUE(notMatchesObjC("@interface X @end @compatibility_alias Y X;", IsDirectlyDerivedFromX)); - EXPECT_TRUE(notMatchesObjC("@interface X @end typedef X Y;", - IsDirectlyDerivedFromX)); + EXPECT_TRUE( + notMatchesObjC("@interface X @end typedef X Y;", IsDirectlyDerivedFromX)); DeclarationMatcher IsAX = objcInterfaceDecl(isSameOrDerivedFrom("X")); EXPECT_TRUE(matchesObjC("@interface X @end @interface Y : X @end", IsAX)); @@ -775,9 +730,9 @@ ZIsDerivedFromX)); EXPECT_TRUE(matchesObjC( "@interface X @end typedef X Y; @interface Z : Y @end", ZIsDerivedFromX)); - EXPECT_TRUE(matchesObjC( - "@interface X @end typedef X Y; @interface Z : Y @end", - ZIsDirectlyDerivedFromX)); + EXPECT_TRUE( + matchesObjC("@interface X @end typedef X Y; @interface Z : Y @end", + ZIsDirectlyDerivedFromX)); EXPECT_TRUE(matchesObjC( "@interface A @end typedef A X; typedef A Y; @interface Z : Y @end", ZIsDerivedFromX)); @@ -798,27 +753,33 @@ ZIsDirectlyDerivedFromX)); EXPECT_TRUE(matchesObjC( "@interface A @end @compatibility_alias X A; @compatibility_alias Y A;" - "@interface Z : Y @end", ZIsDerivedFromX)); + "@interface Z : Y @end", + ZIsDerivedFromX)); EXPECT_TRUE(matchesObjC( "@interface A @end @compatibility_alias X A; @compatibility_alias Y A;" - "@interface Z : Y @end", ZIsDirectlyDerivedFromX)); - EXPECT_TRUE(matchesObjC( - "@interface Y @end typedef Y X; @interface Z : X @end", ZIsDerivedFromX)); - EXPECT_TRUE(matchesObjC( - "@interface Y @end typedef Y X; @interface Z : X @end", + "@interface Z : Y @end", ZIsDirectlyDerivedFromX)); EXPECT_TRUE(matchesObjC( - "@interface A @end @compatibility_alias Y A; typedef Y X;" - "@interface Z : A @end", ZIsDerivedFromX)); - EXPECT_TRUE(matchesObjC( - "@interface A @end @compatibility_alias Y A; typedef Y X;" - "@interface Z : A @end", ZIsDirectlyDerivedFromX)); - EXPECT_TRUE(matchesObjC( - "@interface A @end typedef A Y; @compatibility_alias X Y;" - "@interface Z : A @end", ZIsDerivedFromX)); - EXPECT_TRUE(matchesObjC( - "@interface A @end typedef A Y; @compatibility_alias X Y;" - "@interface Z : A @end", ZIsDirectlyDerivedFromX)); + "@interface Y @end typedef Y X; @interface Z : X @end", ZIsDerivedFromX)); + EXPECT_TRUE( + matchesObjC("@interface Y @end typedef Y X; @interface Z : X @end", + ZIsDirectlyDerivedFromX)); + EXPECT_TRUE( + matchesObjC("@interface A @end @compatibility_alias Y A; typedef Y X;" + "@interface Z : A @end", + ZIsDerivedFromX)); + EXPECT_TRUE( + matchesObjC("@interface A @end @compatibility_alias Y A; typedef Y X;" + "@interface Z : A @end", + ZIsDirectlyDerivedFromX)); + EXPECT_TRUE( + matchesObjC("@interface A @end typedef A Y; @compatibility_alias X Y;" + "@interface Z : A @end", + ZIsDerivedFromX)); + EXPECT_TRUE( + matchesObjC("@interface A @end typedef A Y; @compatibility_alias X Y;" + "@interface Z : A @end", + ZIsDirectlyDerivedFromX)); } TEST(DeclarationMatcher, IsLambda) { @@ -830,42 +791,41 @@ TEST(Matcher, BindMatchedNodes) { DeclarationMatcher ClassX = has(recordDecl(hasName("::X")).bind("x")); - EXPECT_TRUE(matchAndVerifyResultTrue("class X {};", - ClassX, std::make_unique >("x"))); + EXPECT_TRUE(matchAndVerifyResultTrue( + "class X {};", ClassX, + std::make_unique >("x"))); - EXPECT_TRUE(matchAndVerifyResultFalse("class X {};", - ClassX, std::make_unique >("other-id"))); + EXPECT_TRUE(matchAndVerifyResultFalse( + "class X {};", ClassX, + std::make_unique >("other-id"))); TypeMatcher TypeAHasClassB = hasDeclaration( - recordDecl(hasName("A"), has(recordDecl(hasName("B")).bind("b")))); + recordDecl(hasName("A"), has(recordDecl(hasName("B")).bind("b")))); - EXPECT_TRUE(matchAndVerifyResultTrue("class A { public: A *a; class B {}; };", - TypeAHasClassB, - std::make_unique >("b"))); + EXPECT_TRUE(matchAndVerifyResultTrue( + "class A { public: A *a; class B {}; };", TypeAHasClassB, + std::make_unique >("b"))); StatementMatcher MethodX = - callExpr(callee(cxxMethodDecl(hasName("x")))).bind("x"); + callExpr(callee(cxxMethodDecl(hasName("x")))).bind("x"); - EXPECT_TRUE(matchAndVerifyResultTrue("class A { void x() { x(); } };", - MethodX, - std::make_unique >("x"))); + EXPECT_TRUE(matchAndVerifyResultTrue( + "class A { void x() { x(); } };", MethodX, + std::make_unique >("x"))); } TEST(Matcher, BindTheSameNameInAlternatives) { StatementMatcher matcher = anyOf( - binaryOperator(hasOperatorName("+"), - hasLHS(expr().bind("x")), - hasRHS(integerLiteral(equals(0)))), - binaryOperator(hasOperatorName("+"), - hasLHS(integerLiteral(equals(0))), - hasRHS(expr().bind("x")))); + binaryOperator(hasOperatorName("+"), hasLHS(expr().bind("x")), + hasRHS(integerLiteral(equals(0)))), + binaryOperator(hasOperatorName("+"), hasLHS(integerLiteral(equals(0))), + hasRHS(expr().bind("x")))); EXPECT_TRUE(matchAndVerifyResultTrue( - // The first branch of the matcher binds x to 0 but then fails. - // The second branch binds x to f() and succeeds. - "int f() { return 0 + f(); }", - matcher, - std::make_unique >("x"))); + // The first branch of the matcher binds x to 0 but then fails. + // The second branch binds x to f() and succeeds. + "int f() { return 0 + f(); }", matcher, + std::make_unique >("x"))); } TEST(Matcher, BindsIDForMemoizedResults) { @@ -873,48 +833,48 @@ // kick in. DeclarationMatcher ClassX = recordDecl(hasName("X")).bind("x"); EXPECT_TRUE(matchAndVerifyResultTrue( - "class A { class B { class X {}; }; };", - DeclarationMatcher(anyOf( - recordDecl(hasName("A"), hasDescendant(ClassX)), - recordDecl(hasName("B"), hasDescendant(ClassX)))), - std::make_unique >("x", 2))); + "class A { class B { class X {}; }; };", + DeclarationMatcher( + anyOf(recordDecl(hasName("A"), hasDescendant(ClassX)), + recordDecl(hasName("B"), hasDescendant(ClassX)))), + std::make_unique >("x", 2))); } TEST(HasType, MatchesAsString) { EXPECT_TRUE( - matches("class Y { public: void x(); }; void z() {Y* y; y->x(); }", - cxxMemberCallExpr(on(hasType(asString("class Y *")))))); + matches("class Y { public: void x(); }; void z() {Y* y; y->x(); }", + cxxMemberCallExpr(on(hasType(asString("class Y *")))))); EXPECT_TRUE( - matches("class X { void x(int x) {} };", - cxxMethodDecl(hasParameter(0, hasType(asString("int")))))); + matches("class X { void x(int x) {} };", + cxxMethodDecl(hasParameter(0, hasType(asString("int")))))); EXPECT_TRUE(matches("namespace ns { struct A {}; } struct B { ns::A a; };", fieldDecl(hasType(asString("ns::A"))))); - EXPECT_TRUE(matches("namespace { struct A {}; } struct B { A a; };", - fieldDecl(hasType(asString("struct (anonymous namespace)::A"))))); + EXPECT_TRUE( + matches("namespace { struct A {}; } struct B { A a; };", + fieldDecl(hasType(asString("struct (anonymous namespace)::A"))))); } TEST(Matcher, HasOperatorNameForOverloadedOperatorCall) { StatementMatcher OpCallAndAnd = - cxxOperatorCallExpr(hasOverloadedOperatorName("&&")); + cxxOperatorCallExpr(hasOverloadedOperatorName("&&")); EXPECT_TRUE(matches("class Y { }; " - "bool operator&&(Y x, Y y) { return true; }; " - "Y a; Y b; bool c = a && b;", OpCallAndAnd)); + "bool operator&&(Y x, Y y) { return true; }; " + "Y a; Y b; bool c = a && b;", + OpCallAndAnd)); StatementMatcher OpCallLessLess = - cxxOperatorCallExpr(hasOverloadedOperatorName("<<")); + cxxOperatorCallExpr(hasOverloadedOperatorName("<<")); EXPECT_TRUE(notMatches("class Y { }; " - "bool operator&&(Y x, Y y) { return true; }; " - "Y a; Y b; bool c = a && b;", + "bool operator&&(Y x, Y y) { return true; }; " + "Y a; Y b; bool c = a && b;", OpCallLessLess)); StatementMatcher OpStarCall = - cxxOperatorCallExpr(hasOverloadedOperatorName("*")); - EXPECT_TRUE(matches("class Y; int operator*(Y &); void f(Y &y) { *y; }", - OpStarCall)); + cxxOperatorCallExpr(hasOverloadedOperatorName("*")); + EXPECT_TRUE( + matches("class Y; int operator*(Y &); void f(Y &y) { *y; }", OpStarCall)); DeclarationMatcher ClassWithOpStar = - cxxRecordDecl(hasMethod(hasOverloadedOperatorName("*"))); - EXPECT_TRUE(matches("class Y { int operator*(); };", - ClassWithOpStar)); - EXPECT_TRUE(notMatches("class Y { void myOperator(); };", - ClassWithOpStar)) ; + cxxRecordDecl(hasMethod(hasOverloadedOperatorName("*"))); + EXPECT_TRUE(matches("class Y { int operator*(); };", ClassWithOpStar)); + EXPECT_TRUE(notMatches("class Y { void myOperator(); };", ClassWithOpStar)); DeclarationMatcher AnyOpStar = functionDecl(hasOverloadedOperatorName("*")); EXPECT_TRUE(matches("class Y; int operator*(Y &);", AnyOpStar)); EXPECT_TRUE(matches("class Y { int operator*(); };", AnyOpStar)); @@ -926,23 +886,22 @@ EXPECT_TRUE(matches("class Y { Y operator&&(Y &); };", AnyAndOp)); } - TEST(Matcher, NestedOverloadedOperatorCalls) { EXPECT_TRUE(matchAndVerifyResultTrue( - "class Y { }; " + "class Y { }; " "Y& operator&&(Y& x, Y& y) { return x; }; " "Y a; Y b; Y c; Y d = a && b && c;", - cxxOperatorCallExpr(hasOverloadedOperatorName("&&")).bind("x"), - std::make_unique >("x", 2))); + cxxOperatorCallExpr(hasOverloadedOperatorName("&&")).bind("x"), + std::make_unique >("x", 2))); EXPECT_TRUE(matches("class Y { }; " - "Y& operator&&(Y& x, Y& y) { return x; }; " - "Y a; Y b; Y c; Y d = a && b && c;", + "Y& operator&&(Y& x, Y& y) { return x; }; " + "Y a; Y b; Y c; Y d = a && b && c;", cxxOperatorCallExpr(hasParent(cxxOperatorCallExpr())))); EXPECT_TRUE( - matches("class Y { }; " + matches("class Y { }; " "Y& operator&&(Y& x, Y& y) { return x; }; " "Y a; Y b; Y c; Y d = a && b && c;", - cxxOperatorCallExpr(hasDescendant(cxxOperatorCallExpr())))); + cxxOperatorCallExpr(hasDescendant(cxxOperatorCallExpr())))); } TEST(Matcher, VarDecl_Storage) { @@ -971,9 +930,9 @@ EXPECT_TRUE(matches(T, varDecl(hasName("x"), hasAutomaticStorageDuration()))); EXPECT_TRUE( - notMatches(T, varDecl(hasName("y"), hasAutomaticStorageDuration()))); + notMatches(T, varDecl(hasName("y"), hasAutomaticStorageDuration()))); EXPECT_TRUE( - notMatches(T, varDecl(hasName("a"), hasAutomaticStorageDuration()))); + notMatches(T, varDecl(hasName("a"), hasAutomaticStorageDuration()))); EXPECT_TRUE(matches(T, varDecl(hasName("y"), hasStaticStorageDuration()))); EXPECT_TRUE(matches(T, varDecl(hasName("a"), hasStaticStorageDuration()))); @@ -991,48 +950,48 @@ } TEST(Matcher, FindsVarDeclInFunctionParameter) { - EXPECT_TRUE(matches( - "void f(int i) {}", - varDecl(hasName("i")))); + EXPECT_TRUE(matches("void f(int i) {}", varDecl(hasName("i")))); } TEST(UnaryExpressionOrTypeTraitExpression, MatchesCorrectType) { - EXPECT_TRUE(matches("void x() { int a = sizeof(a); }", sizeOfExpr( - hasArgumentOfType(asString("int"))))); - EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr( - hasArgumentOfType(asString("float"))))); + EXPECT_TRUE(matches("void x() { int a = sizeof(a); }", + sizeOfExpr(hasArgumentOfType(asString("int"))))); + EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", + sizeOfExpr(hasArgumentOfType(asString("float"))))); EXPECT_TRUE(matches( - "struct A {}; void x() { A a; int b = sizeof(a); }", - sizeOfExpr(hasArgumentOfType(hasDeclaration(recordDecl(hasName("A"))))))); - EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", sizeOfExpr( - hasArgumentOfType(hasDeclaration(recordDecl(hasName("string"))))))); + "struct A {}; void x() { A a; int b = sizeof(a); }", + sizeOfExpr(hasArgumentOfType(hasDeclaration(recordDecl(hasName("A"))))))); + EXPECT_TRUE(notMatches("void x() { int a = sizeof(a); }", + sizeOfExpr(hasArgumentOfType( + hasDeclaration(recordDecl(hasName("string"))))))); } TEST(IsInteger, MatchesIntegers) { EXPECT_TRUE(matches("int i = 0;", varDecl(hasType(isInteger())))); - EXPECT_TRUE(matches( - "long long i = 0; void f(long long) { }; void g() {f(i);}", - callExpr(hasArgument(0, declRefExpr( - to(varDecl(hasType(isInteger())))))))); + EXPECT_TRUE( + matches("long long i = 0; void f(long long) { }; void g() {f(i);}", + callExpr(hasArgument( + 0, declRefExpr(to(varDecl(hasType(isInteger())))))))); } TEST(IsInteger, ReportsNoFalsePositives) { EXPECT_TRUE(notMatches("int *i;", varDecl(hasType(isInteger())))); - EXPECT_TRUE(notMatches("struct T {}; T t; void f(T *) { }; void g() {f(&t);}", - callExpr(hasArgument(0, declRefExpr( - to(varDecl(hasType(isInteger())))))))); + EXPECT_TRUE( + notMatches("struct T {}; T t; void f(T *) { }; void g() {f(&t);}", + callExpr(hasArgument( + 0, declRefExpr(to(varDecl(hasType(isInteger())))))))); } TEST(IsSignedInteger, MatchesSignedIntegers) { EXPECT_TRUE(matches("int i = 0;", varDecl(hasType(isSignedInteger())))); - EXPECT_TRUE(notMatches("unsigned i = 0;", - varDecl(hasType(isSignedInteger())))); + EXPECT_TRUE( + notMatches("unsigned i = 0;", varDecl(hasType(isSignedInteger())))); } TEST(IsUnsignedInteger, MatchesUnsignedIntegers) { EXPECT_TRUE(notMatches("int i = 0;", varDecl(hasType(isUnsignedInteger())))); - EXPECT_TRUE(matches("unsigned i = 0;", - varDecl(hasType(isUnsignedInteger())))); + EXPECT_TRUE( + matches("unsigned i = 0;", varDecl(hasType(isUnsignedInteger())))); } TEST(IsAnyPointer, MatchesPointers) { @@ -1059,8 +1018,8 @@ TEST(IsArrow, MatchesMemberVariablesViaArrow) { EXPECT_TRUE(matches("class Y { void x() { this->y; } int y; };", memberExpr(isArrow()))); - EXPECT_TRUE(matches("class Y { void x() { y; } int y; };", - memberExpr(isArrow()))); + EXPECT_TRUE( + matches("class Y { void x() { y; } int y; };", memberExpr(isArrow()))); EXPECT_TRUE(notMatches("class Y { void x() { (*this).y; } int y; };", memberExpr(isArrow()))); EXPECT_TRUE(matches("template class Y { void x() { this->m; } };", @@ -1080,10 +1039,9 @@ } TEST(IsArrow, MatchesMemberCallsViaArrow) { - EXPECT_TRUE(matches("class Y { void x() { this->x(); } };", - memberExpr(isArrow()))); - EXPECT_TRUE(matches("class Y { void x() { x(); } };", - memberExpr(isArrow()))); + EXPECT_TRUE( + matches("class Y { void x() { this->x(); } };", memberExpr(isArrow()))); + EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpr(isArrow()))); EXPECT_TRUE(notMatches("class Y { void x() { Y y; y.x(); } };", memberExpr(isArrow()))); EXPECT_TRUE( @@ -1128,20 +1086,18 @@ } TEST(Matcher, References) { - DeclarationMatcher ReferenceClassX = varDecl( - hasType(references(recordDecl(hasName("X"))))); - EXPECT_TRUE(matches("class X {}; void y(X y) { X &x = y; }", - ReferenceClassX)); + DeclarationMatcher ReferenceClassX = + varDecl(hasType(references(recordDecl(hasName("X"))))); EXPECT_TRUE( - matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX)); + matches("class X {}; void y(X y) { X &x = y; }", ReferenceClassX)); + EXPECT_TRUE( + matches("class X {}; void y(X y) { const X &x = y; }", ReferenceClassX)); // The match here is on the implicit copy constructor code for // class X, not on code 'X x = y'. + EXPECT_TRUE(matches("class X {}; void y(X y) { X x = y; }", ReferenceClassX)); + EXPECT_TRUE(notMatches("class X {}; extern X x;", ReferenceClassX)); EXPECT_TRUE( - matches("class X {}; void y(X y) { X x = y; }", ReferenceClassX)); - EXPECT_TRUE( - notMatches("class X {}; extern X x;", ReferenceClassX)); - EXPECT_TRUE( - notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX)); + notMatches("class X {}; void y(X *y) { X *&x = y; }", ReferenceClassX)); } TEST(QualType, hasLocalQualifiers) { @@ -1149,16 +1105,15 @@ varDecl(hasType(hasLocalQualifiers())))); EXPECT_TRUE(matches("int *const j = nullptr;", varDecl(hasType(hasLocalQualifiers())))); - EXPECT_TRUE(matches("int *volatile k;", - varDecl(hasType(hasLocalQualifiers())))); - EXPECT_TRUE(notMatches("int m;", - varDecl(hasType(hasLocalQualifiers())))); + EXPECT_TRUE( + matches("int *volatile k;", varDecl(hasType(hasLocalQualifiers())))); + EXPECT_TRUE(notMatches("int m;", varDecl(hasType(hasLocalQualifiers())))); } TEST(IsExternC, MatchesExternCFunctionDeclarations) { EXPECT_TRUE(matches("extern \"C\" void f() {}", functionDecl(isExternC()))); - EXPECT_TRUE(matches("extern \"C\" { void f() {} }", - functionDecl(isExternC()))); + EXPECT_TRUE( + matches("extern \"C\" { void f() {} }", functionDecl(isExternC()))); EXPECT_TRUE(notMatches("void f() {}", functionDecl(isExternC()))); } @@ -1186,7 +1141,7 @@ TEST(IsDeleted, MatchesDeletedFunctionDeclarations) { EXPECT_TRUE( - notMatches("void Func();", functionDecl(hasName("Func"), isDeleted()))); + notMatches("void Func();", functionDecl(hasName("Func"), isDeleted()))); EXPECT_TRUE(matches("void Func() = delete;", functionDecl(hasName("Func"), isDeleted()))); } @@ -1195,14 +1150,15 @@ EXPECT_TRUE(notMatches("void f();", functionDecl(isNoThrow()))); EXPECT_TRUE(notMatches("void f() throw(int);", functionDecl(isNoThrow()))); EXPECT_TRUE( - notMatches("void f() noexcept(false);", functionDecl(isNoThrow()))); + notMatches("void f() noexcept(false);", functionDecl(isNoThrow()))); EXPECT_TRUE(matches("void f() throw();", functionDecl(isNoThrow()))); EXPECT_TRUE(matches("void f() noexcept;", functionDecl(isNoThrow()))); EXPECT_TRUE(notMatches("void f();", functionProtoType(isNoThrow()))); - EXPECT_TRUE(notMatches("void f() throw(int);", functionProtoType(isNoThrow()))); EXPECT_TRUE( - notMatches("void f() noexcept(false);", functionProtoType(isNoThrow()))); + notMatches("void f() throw(int);", functionProtoType(isNoThrow()))); + EXPECT_TRUE( + notMatches("void f() noexcept(false);", functionProtoType(isNoThrow()))); EXPECT_TRUE(matches("void f() throw();", functionProtoType(isNoThrow()))); EXPECT_TRUE(matches("void f() noexcept;", functionProtoType(isNoThrow()))); } @@ -1249,41 +1205,41 @@ TEST(TemplateArgumentCountIs, Matches) { EXPECT_TRUE( - matches("template struct C {}; C c;", - classTemplateSpecializationDecl(templateArgumentCountIs(1)))); + matches("template struct C {}; C c;", + classTemplateSpecializationDecl(templateArgumentCountIs(1)))); EXPECT_TRUE( - notMatches("template struct C {}; C c;", - classTemplateSpecializationDecl(templateArgumentCountIs(2)))); + notMatches("template struct C {}; C c;", + classTemplateSpecializationDecl(templateArgumentCountIs(2)))); EXPECT_TRUE(matches("template struct C {}; C c;", templateSpecializationType(templateArgumentCountIs(1)))); EXPECT_TRUE( - notMatches("template struct C {}; C c;", - templateSpecializationType(templateArgumentCountIs(2)))); + notMatches("template struct C {}; C c;", + templateSpecializationType(templateArgumentCountIs(2)))); } TEST(IsIntegral, Matches) { - EXPECT_TRUE(matches("template struct C {}; C<42> c;", - classTemplateSpecializationDecl( - hasAnyTemplateArgument(isIntegral())))); + EXPECT_TRUE(matches( + "template struct C {}; C<42> c;", + classTemplateSpecializationDecl(hasAnyTemplateArgument(isIntegral())))); EXPECT_TRUE(notMatches("template struct C {}; C c;", classTemplateSpecializationDecl(hasAnyTemplateArgument( - templateArgument(isIntegral()))))); + templateArgument(isIntegral()))))); } TEST(EqualsIntegralValue, Matches) { EXPECT_TRUE(matches("template struct C {}; C<42> c;", classTemplateSpecializationDecl( - hasAnyTemplateArgument(equalsIntegralValue("42"))))); + hasAnyTemplateArgument(equalsIntegralValue("42"))))); EXPECT_TRUE(matches("template struct C {}; C<-42> c;", classTemplateSpecializationDecl( - hasAnyTemplateArgument(equalsIntegralValue("-42"))))); + hasAnyTemplateArgument(equalsIntegralValue("-42"))))); EXPECT_TRUE(matches("template struct C {}; C<-0042> c;", classTemplateSpecializationDecl( - hasAnyTemplateArgument(equalsIntegralValue("-34"))))); + hasAnyTemplateArgument(equalsIntegralValue("-34"))))); EXPECT_TRUE(notMatches("template struct C {}; C<42> c;", classTemplateSpecializationDecl(hasAnyTemplateArgument( - equalsIntegralValue("0042"))))); + equalsIntegralValue("0042"))))); } TEST(Matcher, MatchesAccessSpecDecls) { @@ -1304,7 +1260,7 @@ cxxMethodDecl(isFinal()))); EXPECT_TRUE(notMatches("class X {};", cxxRecordDecl(isFinal()))); EXPECT_TRUE( - notMatches("class X { virtual void f(); };", cxxMethodDecl(isFinal()))); + notMatches("class X { virtual void f(); };", cxxMethodDecl(isFinal()))); } TEST(Matcher, MatchesVirtualMethod) { @@ -1315,12 +1271,12 @@ TEST(Matcher, MatchesVirtualAsWrittenMethod) { EXPECT_TRUE(matches("class A { virtual int f(); };" - "class B : public A { int f(); };", + "class B : public A { int f(); };", cxxMethodDecl(isVirtualAsWritten(), hasName("::A::f")))); EXPECT_TRUE( - notMatches("class A { virtual int f(); };" + notMatches("class A { virtual int f(); };" "class B : public A { int f(); };", - cxxMethodDecl(isVirtualAsWritten(), hasName("::B::f")))); + cxxMethodDecl(isVirtualAsWritten(), hasName("::B::f")))); } TEST(Matcher, MatchesPureMethod) { @@ -1358,26 +1314,26 @@ TEST(Matcher, MatchesConstMethod) { EXPECT_TRUE( - matches("struct A { void foo() const; };", cxxMethodDecl(isConst()))); + matches("struct A { void foo() const; };", cxxMethodDecl(isConst()))); EXPECT_TRUE( - notMatches("struct A { void foo(); };", cxxMethodDecl(isConst()))); + notMatches("struct A { void foo(); };", cxxMethodDecl(isConst()))); } TEST(Matcher, MatchesOverridingMethod) { EXPECT_TRUE(matches("class X { virtual int f(); }; " - "class Y : public X { int f(); };", + "class Y : public X { int f(); };", cxxMethodDecl(isOverride(), hasName("::Y::f")))); EXPECT_TRUE(notMatches("class X { virtual int f(); }; " - "class Y : public X { int f(); };", + "class Y : public X { int f(); };", cxxMethodDecl(isOverride(), hasName("::X::f")))); EXPECT_TRUE(notMatches("class X { int f(); }; " - "class Y : public X { int f(); };", + "class Y : public X { int f(); };", cxxMethodDecl(isOverride()))); EXPECT_TRUE(notMatches("class X { int f(); int f(int); }; ", cxxMethodDecl(isOverride()))); EXPECT_TRUE( - matches("template struct Y : Base { void f() override;};", - cxxMethodDecl(isOverride(), hasName("::Y::f")))); + matches("template struct Y : Base { void f() override;};", + cxxMethodDecl(isOverride(), hasName("::Y::f")))); } TEST(Matcher, ConstructorArgument) { @@ -1385,44 +1341,38 @@ ast_type_traits::TK_AsIs, cxxConstructExpr(hasArgument(0, declRefExpr(to(varDecl(hasName("y"))))))); + EXPECT_TRUE(matches( + "class X { public: X(int); }; void x() { int y; X x(y); }", Constructor)); EXPECT_TRUE( - matches("class X { public: X(int); }; void x() { int y; X x(y); }", - Constructor)); - EXPECT_TRUE( - matches("class X { public: X(int); }; void x() { int y; X x = X(y); }", - Constructor)); - EXPECT_TRUE( - matches("class X { public: X(int); }; void x() { int y; X x = y; }", - Constructor)); + matches("class X { public: X(int); }; void x() { int y; X x = X(y); }", + Constructor)); EXPECT_TRUE( - notMatches("class X { public: X(int); }; void x() { int z; X x(z); }", - Constructor)); + matches("class X { public: X(int); }; void x() { int y; X x = y; }", + Constructor)); + EXPECT_TRUE(notMatches( + "class X { public: X(int); }; void x() { int z; X x(z); }", Constructor)); StatementMatcher WrongIndex = traverse(ast_type_traits::TK_AsIs, cxxConstructExpr( hasArgument(42, declRefExpr(to(varDecl(hasName("y"))))))); - EXPECT_TRUE( - notMatches("class X { public: X(int); }; void x() { int y; X x(y); }", - WrongIndex)); + EXPECT_TRUE(notMatches( + "class X { public: X(int); }; void x() { int y; X x(y); }", WrongIndex)); } TEST(Matcher, ConstructorArgumentCount) { auto Constructor1Arg = traverse(ast_type_traits::TK_AsIs, cxxConstructExpr(argumentCountIs(1))); + EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x(0); }", + Constructor1Arg)); + EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x = X(0); }", + Constructor1Arg)); + EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x = 0; }", + Constructor1Arg)); EXPECT_TRUE( - matches("class X { public: X(int); }; void x() { X x(0); }", - Constructor1Arg)); - EXPECT_TRUE( - matches("class X { public: X(int); }; void x() { X x = X(0); }", - Constructor1Arg)); - EXPECT_TRUE( - matches("class X { public: X(int); }; void x() { X x = 0; }", - Constructor1Arg)); - EXPECT_TRUE( - notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }", - Constructor1Arg)); + notMatches("class X { public: X(int, int); }; void x() { X x(0, 0); }", + Constructor1Arg)); } TEST(Matcher, ConstructorListInitialization) { @@ -1430,19 +1380,16 @@ traverse(ast_type_traits::TK_AsIs, varDecl(has(cxxConstructExpr(isListInitialization())))); - EXPECT_TRUE( - matches("class X { public: X(int); }; void x() { X x{0}; }", - ConstructorListInit)); - EXPECT_FALSE( - matches("class X { public: X(int); }; void x() { X x(0); }", - ConstructorListInit)); + EXPECT_TRUE(matches("class X { public: X(int); }; void x() { X x{0}; }", + ConstructorListInit)); + EXPECT_FALSE(matches("class X { public: X(int); }; void x() { X x(0); }", + ConstructorListInit)); } TEST(ConstructorDeclaration, IsImplicit) { // This one doesn't match because the constructor is not added by the // compiler (it is not needed). - EXPECT_TRUE(notMatches("class Foo { };", - cxxConstructorDecl(isImplicit()))); + EXPECT_TRUE(notMatches("class Foo { };", cxxConstructorDecl(isImplicit()))); // The compiler added the implicit default constructor. EXPECT_TRUE(matches("class Foo { }; Foo* f = new Foo();", cxxConstructorDecl(isImplicit()))); @@ -1456,8 +1403,8 @@ TEST(ConstructorDeclaration, IsExplicit) { EXPECT_TRUE(matches("struct S { explicit S(int); };", cxxConstructorDecl(isExplicit()))); - EXPECT_TRUE(notMatches("struct S { S(int); };", - cxxConstructorDecl(isExplicit()))); + EXPECT_TRUE( + notMatches("struct S { S(int); };", cxxConstructorDecl(isExplicit()))); EXPECT_TRUE(notMatches("template struct S { explicit(b) S(int);};", cxxConstructorDecl(isExplicit()), langCxx20OrLater())); EXPECT_TRUE(matches("struct S { explicit(true) S(int);};", @@ -1488,9 +1435,9 @@ } TEST(ConstructorDeclaration, Kinds) { - EXPECT_TRUE(matches( - "struct S { S(); };", - cxxConstructorDecl(isDefaultConstructor(), unless(isImplicit())))); + EXPECT_TRUE( + matches("struct S { S(); };", cxxConstructorDecl(isDefaultConstructor(), + unless(isImplicit())))); EXPECT_TRUE(notMatches( "struct S { S(); };", cxxConstructorDecl(isCopyConstructor(), unless(isImplicit())))); @@ -1501,9 +1448,9 @@ EXPECT_TRUE(notMatches( "struct S { S(const S&); };", cxxConstructorDecl(isDefaultConstructor(), unless(isImplicit())))); - EXPECT_TRUE(matches( - "struct S { S(const S&); };", - cxxConstructorDecl(isCopyConstructor(), unless(isImplicit())))); + EXPECT_TRUE( + matches("struct S { S(const S&); };", + cxxConstructorDecl(isCopyConstructor(), unless(isImplicit())))); EXPECT_TRUE(notMatches( "struct S { S(const S&); };", cxxConstructorDecl(isMoveConstructor(), unless(isImplicit())))); @@ -1514,9 +1461,9 @@ EXPECT_TRUE(notMatches( "struct S { S(S&&); };", cxxConstructorDecl(isCopyConstructor(), unless(isImplicit())))); - EXPECT_TRUE(matches( - "struct S { S(S&&); };", - cxxConstructorDecl(isMoveConstructor(), unless(isImplicit())))); + EXPECT_TRUE( + matches("struct S { S(S&&); };", + cxxConstructorDecl(isMoveConstructor(), unless(isImplicit())))); } TEST(ConstructorDeclaration, IsUserProvided) { @@ -1527,7 +1474,7 @@ EXPECT_TRUE(notMatches("struct S { S() = delete; };", cxxConstructorDecl(isUserProvided()))); EXPECT_TRUE( - matches("struct S { S(); };", cxxConstructorDecl(isUserProvided()))); + matches("struct S { S(); };", cxxConstructorDecl(isUserProvided()))); EXPECT_TRUE(matches("struct S { S(); }; S::S(){}", cxxConstructorDecl(isUserProvided()))); } @@ -1538,11 +1485,11 @@ EXPECT_TRUE(notMatches("struct S { S(){} S(int X) : X(X) {} int X; };", cxxConstructorDecl(isDelegatingConstructor()))); EXPECT_TRUE(matches( - "struct S { S() : S(0) {} S(int X) : X(X) {} int X; };", - cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(0)))); + "struct S { S() : S(0) {} S(int X) : X(X) {} int X; };", + cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(0)))); EXPECT_TRUE(matches( - "struct S { S(); S(int X); int X; }; S::S(int X) : S() {}", - cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(1)))); + "struct S { S(); S(int X); int X; }; S::S(int X) : S() {}", + cxxConstructorDecl(isDelegatingConstructor(), parameterCountIs(1)))); } TEST(StringLiteral, HasSize) { @@ -1584,38 +1531,28 @@ } TEST(Matcher, HasNameSupportsOuterClasses) { - EXPECT_TRUE( - matches("class A { class B { class C; }; };", - recordDecl(hasName("A::B::C")))); - EXPECT_TRUE( - matches("class A { class B { class C; }; };", - recordDecl(hasName("::A::B::C")))); - EXPECT_TRUE( - matches("class A { class B { class C; }; };", - recordDecl(hasName("B::C")))); - EXPECT_TRUE( - matches("class A { class B { class C; }; };", - recordDecl(hasName("C")))); - EXPECT_TRUE( - notMatches("class A { class B { class C; }; };", - recordDecl(hasName("c::B::C")))); - EXPECT_TRUE( - notMatches("class A { class B { class C; }; };", - recordDecl(hasName("A::c::C")))); - EXPECT_TRUE( - notMatches("class A { class B { class C; }; };", - recordDecl(hasName("A::B::A")))); - EXPECT_TRUE( - notMatches("class A { class B { class C; }; };", - recordDecl(hasName("::C")))); - EXPECT_TRUE( - notMatches("class A { class B { class C; }; };", - recordDecl(hasName("::B::C")))); + EXPECT_TRUE(matches("class A { class B { class C; }; };", + recordDecl(hasName("A::B::C")))); + EXPECT_TRUE(matches("class A { class B { class C; }; };", + recordDecl(hasName("::A::B::C")))); + EXPECT_TRUE(matches("class A { class B { class C; }; };", + recordDecl(hasName("B::C")))); + EXPECT_TRUE( + matches("class A { class B { class C; }; };", recordDecl(hasName("C")))); + EXPECT_TRUE(notMatches("class A { class B { class C; }; };", + recordDecl(hasName("c::B::C")))); + EXPECT_TRUE(notMatches("class A { class B { class C; }; };", + recordDecl(hasName("A::c::C")))); + EXPECT_TRUE(notMatches("class A { class B { class C; }; };", + recordDecl(hasName("A::B::A")))); + EXPECT_TRUE(notMatches("class A { class B { class C; }; };", + recordDecl(hasName("::C")))); + EXPECT_TRUE(notMatches("class A { class B { class C; }; };", + recordDecl(hasName("::B::C")))); EXPECT_TRUE(notMatches("class A { class B { class C; }; };", recordDecl(hasName("z::A::B::C")))); - EXPECT_TRUE( - notMatches("class A { class B { class C; }; };", - recordDecl(hasName("A+B::C")))); + EXPECT_TRUE(notMatches("class A { class B { class C; }; };", + recordDecl(hasName("A+B::C")))); } TEST(Matcher, HasNameSupportsInlinedNamespaces) { @@ -1629,10 +1566,10 @@ TEST(Matcher, HasNameSupportsAnonymousNamespaces) { StringRef code = "namespace a { namespace { class C; } }"; EXPECT_TRUE( - matches(code, recordDecl(hasName("a::(anonymous namespace)::C")))); + matches(code, recordDecl(hasName("a::(anonymous namespace)::C")))); EXPECT_TRUE(matches(code, recordDecl(hasName("a::C")))); EXPECT_TRUE( - matches(code, recordDecl(hasName("::a::(anonymous namespace)::C")))); + matches(code, recordDecl(hasName("::a::(anonymous namespace)::C")))); EXPECT_TRUE(matches(code, recordDecl(hasName("::a::C")))); } @@ -1689,7 +1626,7 @@ EXPECT_TRUE(notMatches(Code, recordDecl(hasAnyName("::C", "::b::C")))); EXPECT_TRUE( - matches(Code, recordDecl(hasAnyName("::C", "::b::C", "::a::b::C")))); + matches(Code, recordDecl(hasAnyName("::C", "::b::C", "::a::b::C")))); std::vector Names = {"::C", "::b::C", "::a::b::C"}; EXPECT_TRUE(matches(Code, recordDecl(hasAnyName(Names)))); @@ -1697,27 +1634,27 @@ TEST(Matcher, IsDefinition) { DeclarationMatcher DefinitionOfClassA = - recordDecl(hasName("A"), isDefinition()); + recordDecl(hasName("A"), isDefinition()); EXPECT_TRUE(matches("class A {};", DefinitionOfClassA)); EXPECT_TRUE(notMatches("class A;", DefinitionOfClassA)); DeclarationMatcher DefinitionOfVariableA = - varDecl(hasName("a"), isDefinition()); + varDecl(hasName("a"), isDefinition()); EXPECT_TRUE(matches("int a;", DefinitionOfVariableA)); EXPECT_TRUE(notMatches("extern int a;", DefinitionOfVariableA)); DeclarationMatcher DefinitionOfMethodA = - cxxMethodDecl(hasName("a"), isDefinition()); + cxxMethodDecl(hasName("a"), isDefinition()); EXPECT_TRUE(matches("class A { void a() {} };", DefinitionOfMethodA)); EXPECT_TRUE(notMatches("class A { void a(); };", DefinitionOfMethodA)); DeclarationMatcher DefinitionOfObjCMethodA = - objcMethodDecl(hasName("a"), isDefinition()); + objcMethodDecl(hasName("a"), isDefinition()); EXPECT_TRUE(matchesObjC("@interface A @end " "@implementation A; -(void)a {} @end", DefinitionOfObjCMethodA)); - EXPECT_TRUE(notMatchesObjC("@interface A; - (void)a; @end", - DefinitionOfObjCMethodA)); + EXPECT_TRUE( + notMatchesObjC("@interface A; - (void)a; @end", DefinitionOfObjCMethodA)); } TEST(Matcher, HandlesNullQualTypes) { @@ -1728,7 +1665,7 @@ // We don't really care whether this matcher succeeds; we're testing that // it completes without crashing. EXPECT_TRUE(matches( - "struct A { };" + "struct A { };" "template " "void f(T t) {" " T local_t(t /* this becomes a null QualType in the AST */);" @@ -1736,13 +1673,10 @@ "void g() {" " f(0);" "}", - expr(hasType(TypeMatcher( - anyOf( - TypeMatcher(hasDeclaration(anything())), - pointsTo(AnyType), - references(AnyType) - // Other QualType matchers should go here. - )))))); + expr(hasType(TypeMatcher(anyOf(TypeMatcher(hasDeclaration(anything())), + pointsTo(AnyType), references(AnyType) + // Other QualType matchers should go here. + )))))); } TEST(ObjCIvarRefExprMatcher, IvarExpr) { @@ -1750,10 +1684,10 @@ "@interface A @end " "@implementation A { A *x; } - (void) func { x = 0; } @end"; EXPECT_TRUE(matchesObjC(ObjCString, objcIvarRefExpr())); - EXPECT_TRUE(matchesObjC(ObjCString, objcIvarRefExpr( - hasDeclaration(namedDecl(hasName("x")))))); - EXPECT_FALSE(matchesObjC(ObjCString, objcIvarRefExpr( - hasDeclaration(namedDecl(hasName("y")))))); + EXPECT_TRUE(matchesObjC( + ObjCString, objcIvarRefExpr(hasDeclaration(namedDecl(hasName("x")))))); + EXPECT_FALSE(matchesObjC( + ObjCString, objcIvarRefExpr(hasDeclaration(namedDecl(hasName("y")))))); } TEST(BlockExprMatcher, BlockExpr) { @@ -1761,24 +1695,19 @@ } TEST(StatementCountIs, FindsNoStatementsInAnEmptyCompoundStatement) { - EXPECT_TRUE(matches("void f() { }", - compoundStmt(statementCountIs(0)))); - EXPECT_TRUE(notMatches("void f() {}", - compoundStmt(statementCountIs(1)))); + EXPECT_TRUE(matches("void f() { }", compoundStmt(statementCountIs(0)))); + EXPECT_TRUE(notMatches("void f() {}", compoundStmt(statementCountIs(1)))); } TEST(StatementCountIs, AppearsToMatchOnlyOneCount) { - EXPECT_TRUE(matches("void f() { 1; }", - compoundStmt(statementCountIs(1)))); - EXPECT_TRUE(notMatches("void f() { 1; }", - compoundStmt(statementCountIs(0)))); - EXPECT_TRUE(notMatches("void f() { 1; }", - compoundStmt(statementCountIs(2)))); + EXPECT_TRUE(matches("void f() { 1; }", compoundStmt(statementCountIs(1)))); + EXPECT_TRUE(notMatches("void f() { 1; }", compoundStmt(statementCountIs(0)))); + EXPECT_TRUE(notMatches("void f() { 1; }", compoundStmt(statementCountIs(2)))); } TEST(StatementCountIs, WorksWithMultipleStatements) { - EXPECT_TRUE(matches("void f() { 1; 2; 3; }", - compoundStmt(statementCountIs(3)))); + EXPECT_TRUE( + matches("void f() { 1; 2; 3; }", compoundStmt(statementCountIs(3)))); } TEST(StatementCountIs, WorksWithNestedCompoundStatements) { @@ -1806,19 +1735,19 @@ TEST(Member, MatchesInMemberFunctionCall) { EXPECT_TRUE(matches("void f() {" - " struct { void first() {}; } s;" - " s.first();" - "};", + " struct { void first() {}; } s;" + " s.first();" + "};", memberExpr(member(hasName("first"))))); } TEST(Member, MatchesMember) { - EXPECT_TRUE(matches( - "struct A { int i; }; void f() { A a; a.i = 2; }", - memberExpr(hasDeclaration(fieldDecl(hasType(isInteger())))))); - EXPECT_TRUE(notMatches( - "struct A { float f; }; void f() { A a; a.f = 2.0f; }", - memberExpr(hasDeclaration(fieldDecl(hasType(isInteger())))))); + EXPECT_TRUE( + matches("struct A { int i; }; void f() { A a; a.i = 2; }", + memberExpr(hasDeclaration(fieldDecl(hasType(isInteger())))))); + EXPECT_TRUE( + notMatches("struct A { float f; }; void f() { A a; a.f = 2.0f; }", + memberExpr(hasDeclaration(fieldDecl(hasType(isInteger())))))); } TEST(Member, BitFields) { @@ -1841,26 +1770,26 @@ } TEST(Member, UnderstandsAccess) { - EXPECT_TRUE(matches( - "struct A { int i; };", fieldDecl(isPublic(), hasName("i")))); - EXPECT_TRUE(notMatches( - "struct A { int i; };", fieldDecl(isProtected(), hasName("i")))); - EXPECT_TRUE(notMatches( - "struct A { int i; };", fieldDecl(isPrivate(), hasName("i")))); + EXPECT_TRUE( + matches("struct A { int i; };", fieldDecl(isPublic(), hasName("i")))); + EXPECT_TRUE(notMatches("struct A { int i; };", + fieldDecl(isProtected(), hasName("i")))); + EXPECT_TRUE( + notMatches("struct A { int i; };", fieldDecl(isPrivate(), hasName("i")))); - EXPECT_TRUE(notMatches( - "class A { int i; };", fieldDecl(isPublic(), hasName("i")))); - EXPECT_TRUE(notMatches( - "class A { int i; };", fieldDecl(isProtected(), hasName("i")))); - EXPECT_TRUE(matches( - "class A { int i; };", fieldDecl(isPrivate(), hasName("i")))); + EXPECT_TRUE( + notMatches("class A { int i; };", fieldDecl(isPublic(), hasName("i")))); + EXPECT_TRUE(notMatches("class A { int i; };", + fieldDecl(isProtected(), hasName("i")))); + EXPECT_TRUE( + matches("class A { int i; };", fieldDecl(isPrivate(), hasName("i")))); - EXPECT_TRUE(notMatches( - "class A { protected: int i; };", fieldDecl(isPublic(), hasName("i")))); + EXPECT_TRUE(notMatches("class A { protected: int i; };", + fieldDecl(isPublic(), hasName("i")))); EXPECT_TRUE(matches("class A { protected: int i; };", fieldDecl(isProtected(), hasName("i")))); - EXPECT_TRUE(notMatches( - "class A { protected: int i; };", fieldDecl(isPrivate(), hasName("i")))); + EXPECT_TRUE(notMatches("class A { protected: int i; };", + fieldDecl(isPrivate(), hasName("i")))); // Non-member decls have the AccessSpecifier AS_none and thus aren't matched. EXPECT_TRUE(notMatches("int i;", varDecl(isPublic(), hasName("i")))); @@ -1883,35 +1812,35 @@ EXPECT_TRUE( matches("void l() throw(...);", functionDecl(hasDynamicExceptionSpec()))); - EXPECT_TRUE(notMatches("void f();", functionProtoType(hasDynamicExceptionSpec()))); + EXPECT_TRUE( + notMatches("void f();", functionProtoType(hasDynamicExceptionSpec()))); EXPECT_TRUE(notMatches("void g() noexcept;", functionProtoType(hasDynamicExceptionSpec()))); EXPECT_TRUE(notMatches("void h() noexcept(true);", functionProtoType(hasDynamicExceptionSpec()))); EXPECT_TRUE(notMatches("void i() noexcept(false);", functionProtoType(hasDynamicExceptionSpec()))); - EXPECT_TRUE( - matches("void j() throw();", functionProtoType(hasDynamicExceptionSpec()))); - EXPECT_TRUE( - matches("void k() throw(int);", functionProtoType(hasDynamicExceptionSpec()))); - EXPECT_TRUE( - matches("void l() throw(...);", functionProtoType(hasDynamicExceptionSpec()))); + EXPECT_TRUE(matches("void j() throw();", + functionProtoType(hasDynamicExceptionSpec()))); + EXPECT_TRUE(matches("void k() throw(int);", + functionProtoType(hasDynamicExceptionSpec()))); + EXPECT_TRUE(matches("void l() throw(...);", + functionProtoType(hasDynamicExceptionSpec()))); } TEST(HasObjectExpression, DoesNotMatchMember) { EXPECT_TRUE(notMatches( - "class X {}; struct Z { X m; }; void f(Z z) { z.m; }", - memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X"))))))); + "class X {}; struct Z { X m; }; void f(Z z) { z.m; }", + memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X"))))))); } TEST(HasObjectExpression, MatchesBaseOfVariable) { EXPECT_TRUE(matches( - "struct X { int m; }; void f(X x) { x.m; }", - memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X"))))))); - EXPECT_TRUE(matches( - "struct X { int m; }; void f(X* x) { x->m; }", - memberExpr(hasObjectExpression( - hasType(pointsTo(recordDecl(hasName("X")))))))); + "struct X { int m; }; void f(X x) { x.m; }", + memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X"))))))); + EXPECT_TRUE(matches("struct X { int m; }; void f(X* x) { x->m; }", + memberExpr(hasObjectExpression( + hasType(pointsTo(recordDecl(hasName("X")))))))); EXPECT_TRUE(matches("template struct X { void f() { T t; t.m; } };", cxxDependentScopeMemberExpr(hasObjectExpression( declRefExpr(to(namedDecl(hasName("t")))))))); @@ -1936,14 +1865,12 @@ TEST(HasObjectExpression, MatchesObjectExpressionOfImplicitlyFormedMemberExpression) { - EXPECT_TRUE(matches( - "class X {}; struct S { X m; void f() { this->m; } };", - memberExpr(hasObjectExpression( - hasType(pointsTo(recordDecl(hasName("S")))))))); - EXPECT_TRUE(matches( - "class X {}; struct S { X m; void f() { m; } };", - memberExpr(hasObjectExpression( - hasType(pointsTo(recordDecl(hasName("S")))))))); + EXPECT_TRUE(matches("class X {}; struct S { X m; void f() { this->m; } };", + memberExpr(hasObjectExpression( + hasType(pointsTo(recordDecl(hasName("S")))))))); + EXPECT_TRUE(matches("class X {}; struct S { X m; void f() { m; } };", + memberExpr(hasObjectExpression( + hasType(pointsTo(recordDecl(hasName("S")))))))); } TEST(Field, DoesNotMatchNonFieldMembers) { @@ -1958,17 +1885,17 @@ } TEST(IsVolatileQualified, QualifiersMatch) { - EXPECT_TRUE(matches("volatile int i = 42;", - varDecl(hasType(isVolatileQualified())))); - EXPECT_TRUE(notMatches("volatile int *i;", - varDecl(hasType(isVolatileQualified())))); + EXPECT_TRUE( + matches("volatile int i = 42;", varDecl(hasType(isVolatileQualified())))); + EXPECT_TRUE( + notMatches("volatile int *i;", varDecl(hasType(isVolatileQualified())))); EXPECT_TRUE(matches("typedef volatile int v_int; v_int i = 42;", varDecl(hasType(isVolatileQualified())))); } TEST(IsConstQualified, MatchesConstInt) { - EXPECT_TRUE(matches("const int i = 42;", - varDecl(hasType(isConstQualified())))); + EXPECT_TRUE( + matches("const int i = 42;", varDecl(hasType(isConstQualified())))); } TEST(IsConstQualified, MatchesConstPointer) { @@ -1986,43 +1913,41 @@ TEST(IsConstQualified, DoesNotMatchInappropriately) { EXPECT_TRUE(notMatches("typedef int nonconst_int; nonconst_int i = 42;", varDecl(hasType(isConstQualified())))); - EXPECT_TRUE(notMatches("int const* p;", - varDecl(hasType(isConstQualified())))); + EXPECT_TRUE( + notMatches("int const* p;", varDecl(hasType(isConstQualified())))); } TEST(DeclCount, DeclCountIsCorrect) { - EXPECT_TRUE(matches("void f() {int i,j;}", - declStmt(declCountIs(2)))); - EXPECT_TRUE(notMatches("void f() {int i,j; int k;}", - declStmt(declCountIs(3)))); - EXPECT_TRUE(notMatches("void f() {int i,j, k, l;}", - declStmt(declCountIs(3)))); + EXPECT_TRUE(matches("void f() {int i,j;}", declStmt(declCountIs(2)))); + EXPECT_TRUE( + notMatches("void f() {int i,j; int k;}", declStmt(declCountIs(3)))); + EXPECT_TRUE( + notMatches("void f() {int i,j, k, l;}", declStmt(declCountIs(3)))); } - TEST(EachOf, TriggersForEachMatch) { EXPECT_TRUE(matchAndVerifyResultTrue( - "class A { int a; int b; };", - recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")), - has(fieldDecl(hasName("b")).bind("v")))), - std::make_unique >("v", 2))); + "class A { int a; int b; };", + recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")), + has(fieldDecl(hasName("b")).bind("v")))), + std::make_unique >("v", 2))); } TEST(EachOf, BehavesLikeAnyOfUnlessBothMatch) { EXPECT_TRUE(matchAndVerifyResultTrue( - "class A { int a; int c; };", - recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")), - has(fieldDecl(hasName("b")).bind("v")))), - std::make_unique >("v", 1))); + "class A { int a; int c; };", + recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")), + has(fieldDecl(hasName("b")).bind("v")))), + std::make_unique >("v", 1))); EXPECT_TRUE(matchAndVerifyResultTrue( - "class A { int c; int b; };", - recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")), - has(fieldDecl(hasName("b")).bind("v")))), - std::make_unique >("v", 1))); - EXPECT_TRUE(notMatches( - "class A { int c; int d; };", - recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")), - has(fieldDecl(hasName("b")).bind("v")))))); + "class A { int c; int b; };", + recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")), + has(fieldDecl(hasName("b")).bind("v")))), + std::make_unique >("v", 1))); + EXPECT_TRUE( + notMatches("class A { int c; int d; };", + recordDecl(eachOf(has(fieldDecl(hasName("a")).bind("v")), + has(fieldDecl(hasName("b")).bind("v")))))); } TEST(Optionally, SubmatchersDoNotMatch) { @@ -2056,29 +1981,30 @@ // Make sure that we can both match the class by name (::X) and by the type // the template was instantiated with (via a field). - EXPECT_TRUE(matches( - "template class X {}; class A {}; X x;", - cxxRecordDecl(hasName("::X"), isTemplateInstantiation()))); + EXPECT_TRUE( + matches("template class X {}; class A {}; X x;", + cxxRecordDecl(hasName("::X"), isTemplateInstantiation()))); EXPECT_TRUE(matches( - "template class X { T t; }; class A {}; X x;", - cxxRecordDecl(isTemplateInstantiation(), hasDescendant( - fieldDecl(hasType(recordDecl(hasName("A")))))))); + "template class X { T t; }; class A {}; X x;", + cxxRecordDecl( + isTemplateInstantiation(), + hasDescendant(fieldDecl(hasType(recordDecl(hasName("A")))))))); } TEST(IsTemplateInstantiation, MatchesImplicitFunctionTemplateInstantiation) { EXPECT_TRUE(matches( - "template void f(T t) {} class A {}; void g() { f(A()); }", - functionDecl(hasParameter(0, hasType(recordDecl(hasName("A")))), - isTemplateInstantiation()))); + "template void f(T t) {} class A {}; void g() { f(A()); }", + functionDecl(hasParameter(0, hasType(recordDecl(hasName("A")))), + isTemplateInstantiation()))); } TEST(IsTemplateInstantiation, MatchesExplicitClassTemplateInstantiation) { - EXPECT_TRUE(matches( - "template class X { T t; }; class A {};" - "template class X;", - cxxRecordDecl(isTemplateInstantiation(), hasDescendant( - fieldDecl(hasType(recordDecl(hasName("A")))))))); + EXPECT_TRUE(matches("template class X { T t; }; class A {};" + "template class X;", + cxxRecordDecl(isTemplateInstantiation(), + hasDescendant(fieldDecl( + hasType(recordDecl(hasName("A")))))))); // Make sure that we match the instantiation instead of the template // definition by checking whether the member function is present. @@ -2091,21 +2017,21 @@ TEST(IsTemplateInstantiation, MatchesInstantiationOfPartiallySpecializedClassTemplate) { - EXPECT_TRUE(matches( - "template class X {};" - "template class X {}; class A {}; X x;", - cxxRecordDecl(hasName("::X"), isTemplateInstantiation()))); + EXPECT_TRUE( + matches("template class X {};" + "template class X {}; class A {}; X x;", + cxxRecordDecl(hasName("::X"), isTemplateInstantiation()))); } TEST(IsTemplateInstantiation, MatchesInstantiationOfClassTemplateNestedInNonTemplate) { - EXPECT_TRUE(matches( - "class A {};" - "class X {" - " template class Y { U u; };" - " Y y;" - "};", - cxxRecordDecl(hasName("::X::Y"), isTemplateInstantiation()))); + EXPECT_TRUE( + matches("class A {};" + "class X {" + " template class Y { U u; };" + " Y y;" + "};", + cxxRecordDecl(hasName("::X::Y"), isTemplateInstantiation()))); } TEST(IsTemplateInstantiation, DoesNotMatchInstantiationsInsideOfInstantiation) { @@ -2113,31 +2039,30 @@ // normal use case as long as the uppermost instantiation always is marked // as template instantiation, but it might be confusing as a predicate. EXPECT_TRUE(matches( - "class A {};" + "class A {};" "template class X {" " template class Y { U u; };" " Y y;" "}; X x;", - cxxRecordDecl(hasName("::X::Y"), unless(isTemplateInstantiation())))); + cxxRecordDecl(hasName("::X::Y"), unless(isTemplateInstantiation())))); } TEST(IsTemplateInstantiation, DoesNotMatchExplicitClassTemplateSpecialization) { - EXPECT_TRUE(notMatches( - "template class X {}; class A {};" - "template <> class X {}; X x;", - cxxRecordDecl(hasName("::X"), isTemplateInstantiation()))); + EXPECT_TRUE( + notMatches("template class X {}; class A {};" + "template <> class X {}; X x;", + cxxRecordDecl(hasName("::X"), isTemplateInstantiation()))); } TEST(IsTemplateInstantiation, DoesNotMatchNonTemplate) { - EXPECT_TRUE(notMatches( - "class A {}; class Y { A a; };", - cxxRecordDecl(isTemplateInstantiation()))); + EXPECT_TRUE(notMatches("class A {}; class Y { A a; };", + cxxRecordDecl(isTemplateInstantiation()))); } TEST(IsInstantiated, MatchesInstantiation) { EXPECT_TRUE( - matches("template class A { T i; }; class Y { A a; };", - cxxRecordDecl(isInstantiated()))); + matches("template class A { T i; }; class Y { A a; };", + cxxRecordDecl(isInstantiated()))); } TEST(IsInstantiated, NotMatchesDefinition) { @@ -2147,7 +2072,7 @@ TEST(IsInTemplateInstantiation, MatchesInstantiationStmt) { EXPECT_TRUE(matches("template struct A { A() { T i; } };" - "class Y { A a; }; Y y;", + "class Y { A a; }; Y y;", declStmt(isInTemplateInstantiation()))); } @@ -2158,8 +2083,8 @@ TEST(IsInstantiated, MatchesFunctionInstantiation) { EXPECT_TRUE( - matches("template void A(T t) { T i; } void x() { A(0); }", - functionDecl(isInstantiated()))); + matches("template void A(T t) { T i; } void x() { A(0); }", + functionDecl(isInstantiated()))); } TEST(IsInstantiated, NotMatchesFunctionDefinition) { @@ -2169,8 +2094,8 @@ TEST(IsInTemplateInstantiation, MatchesFunctionInstantiationStmt) { EXPECT_TRUE( - matches("template void A(T t) { T i; } void x() { A(0); }", - declStmt(isInTemplateInstantiation()))); + matches("template void A(T t) { T i; } void x() { A(0); }", + declStmt(isInTemplateInstantiation()))); } TEST(IsInTemplateInstantiation, NotMatchesFunctionDefinitionStmt) { @@ -2183,11 +2108,11 @@ // FIXME: Node sharing is an implementation detail, exposing it is ugly // and makes the matcher behave in non-obvious ways. EXPECT_TRUE(notMatches( - "int j; template void A(T t) { j += 42; } void x() { A(0); }", - Matcher)); + "int j; template void A(T t) { j += 42; } void x() { A(0); }", + Matcher)); EXPECT_TRUE(matches( - "int j; template void A(T t) { j += t; } void x() { A(0); }", - Matcher)); + "int j; template void A(T t) { j += t; } void x() { A(0); }", + Matcher)); } TEST(IsInstantiationDependent, MatchesNonValueTypeDependent) { @@ -2232,48 +2157,41 @@ expr(isValueDependent()))); } -TEST(IsExplicitTemplateSpecialization, - DoesNotMatchPrimaryTemplate) { - EXPECT_TRUE(notMatches( - "template