diff options
Diffstat (limited to 'clang')
53 files changed, 4180 insertions, 3963 deletions
diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html index 9b30057..5b2a96d 100644 --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -1028,6 +1028,15 @@ Example matches X, Z, U, and S </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('requiresExprBodyDecl0')"><a name="requiresExprBodyDecl0Anchor">requiresExprBodyDecl</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1RequiresExprBodyDecl.html">RequiresExprBodyDecl</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="requiresExprBodyDecl0"><pre>Matches concept requirement body declaration. + +Example matches '{ *p; }' + template<typename T> + concept dereferencable = requires(T p) { *p; } +</pre></td></tr> + + <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('staticAssertDecl0')"><a name="staticAssertDecl0Anchor">staticAssertDecl</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1StaticAssertDecl.html">StaticAssertDecl</a>>...</td></tr> <tr><td colspan="4" class="doc" id="staticAssertDecl0"><pre>Matches a C++ static_assert declaration. @@ -1190,6 +1199,17 @@ usingEnumDecl() matches using enum X::x </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('usingShadowDecl0')"><a name="usingShadowDecl0Anchor">usingShadowDecl</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UsingShadowDecl.html">UsingShadowDecl</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="usingShadowDecl0"><pre>Matches shadow declarations introduced into a scope by a + (resolved) using declaration. + +Given + namespace n { int f; } + namespace declToImport { using n::f; } +usingShadowDecl() + matches f </pre></td></tr> + + <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('valueDecl0')"><a name="valueDecl0Anchor">valueDecl</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ValueDecl.html">ValueDecl</a>>...</td></tr> <tr><td colspan="4" class="doc" id="valueDecl0"><pre>Matches any value declaration. @@ -1210,6 +1230,15 @@ Example matches a </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>></td><td class="name" onclick="toggle('requiresExpr0')"><a name="requiresExpr0Anchor">requiresExpr</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1RequiresExpr.html">RequiresExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="requiresExpr0"><pre>Matches concept requirement. + +Example matches 'requires(T p) { *p; }' + template<typename T> + concept dereferencable = requires(T p) { *p; } +</pre></td></tr> + + <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LambdaCapture.html">LambdaCapture</a>></td><td class="name" onclick="toggle('lambdaCapture0')"><a name="lambdaCapture0Anchor">lambdaCapture</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LambdaCapture.html">LambdaCapture</a>>...</td></tr> <tr><td colspan="4" class="doc" id="lambdaCapture0"><pre>Matches lambda captures. @@ -1679,6 +1708,19 @@ Example matches x.y() </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('cxxNamedCastExpr0')"><a name="cxxNamedCastExpr0Anchor">cxxNamedCastExpr</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNamedCastExpr.html">CXXNamedCastExpr</a>>...</td></tr> +<tr><td colspan="4" class="doc" id="cxxNamedCastExpr0"><pre>Matches any named cast expression. + +Example: Matches all four of the casts in + struct S { virtual void f(); }; + S* p = nullptr; + S* ptr1 = static_cast<S*>(p); + S* ptr2 = reinterpret_cast<S*>(p); + S* ptr3 = dynamic_cast<S*>(p); + S* ptr4 = const_cast<S*>(p); +</pre></td></tr> + + <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('cxxNewExpr0')"><a name="cxxNewExpr0Anchor">cxxNewExpr</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>...</td></tr> <tr><td colspan="4" class="doc" id="cxxNewExpr0"><pre>Matches new expressions. @@ -2168,7 +2210,7 @@ Example matches @try </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('ompExecutableDirective0')"><a name="ompExecutableDirective0Anchor">ompExecutableDirective</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPExecutableDirective.html">OMPExecutableDirective</a>>...</td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('ompExecutableDirective0')"><a name="ompExecutableDirective0Anchor">ompExecutableDirective</a></td><td>Matcher<OMPExecutableDirective>...</td></tr> <tr><td colspan="4" class="doc" id="ompExecutableDirective0"><pre>Matches any ``#pragma omp`` executable directive. Given @@ -2393,17 +2435,6 @@ templateName() </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('elaboratedTypeLoc0')"><a name="elaboratedTypeLoc0Anchor">elaboratedTypeLoc</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ElaboratedTypeLoc.html">ElaboratedTypeLoc</a>>...</td></tr> -<tr><td colspan="4" class="doc" id="elaboratedTypeLoc0"><pre>Matches C or C++ elaborated `TypeLoc`s. - -Given - struct s {}; - struct s ss; -elaboratedTypeLoc() - matches the `TypeLoc` of the variable declaration of `ss`. -</pre></td></tr> - - <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>></td><td class="name" onclick="toggle('pointerTypeLoc0')"><a name="pointerTypeLoc0Anchor">pointerTypeLoc</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1PointerTypeLoc.html">PointerTypeLoc</a>>...</td></tr> <tr><td colspan="4" class="doc" id="pointerTypeLoc0"><pre>Matches pointer `TypeLoc`s. @@ -2474,7 +2505,7 @@ atomicType() </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('autoType0')"><a name="autoType0Anchor">autoType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1AutoType.html">AutoType</a>>...</td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('autoType0')"><a name="autoType0Anchor">autoType</a></td><td>Matcher<AutoType>...</td></tr> <tr><td colspan="4" class="doc" id="autoType0"><pre>Matches types nodes representing C++11 auto types. Given: @@ -2544,7 +2575,7 @@ Example matches i[1]. </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('decltypeType0')"><a name="decltypeType0Anchor">decltypeType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DecltypeType.html">DecltypeType</a>>...</td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('decltypeType0')"><a name="decltypeType0Anchor">decltypeType</a></td><td>Matcher<DecltypeType>...</td></tr> <tr><td colspan="4" class="doc" id="decltypeType0"><pre>Matches types nodes representing C++11 decltype(<expr>) types. Given: @@ -2556,7 +2587,7 @@ decltypeType() </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('deducedTemplateSpecializationType0')"><a name="deducedTemplateSpecializationType0Anchor">deducedTemplateSpecializationType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeducedTemplateSpecializationType.html">DeducedTemplateSpecializationType</a>>...</td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('deducedTemplateSpecializationType0')"><a name="deducedTemplateSpecializationType0Anchor">deducedTemplateSpecializationType</a></td><td>Matcher<DeducedTemplateSpecializationType>...</td></tr> <tr><td colspan="4" class="doc" id="deducedTemplateSpecializationType0"><pre>Matches C++17 deduced template specialization types, e.g. deduced class template types. @@ -2570,7 +2601,7 @@ of the variable c. </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('dependentNameType0')"><a name="dependentNameType0Anchor">dependentNameType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DependentNameType.html">DependentNameType</a>>...</td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('dependentNameType0')"><a name="dependentNameType0Anchor">dependentNameType</a></td><td>Matcher<DependentNameType>...</td></tr> <tr><td colspan="4" class="doc" id="dependentNameType0"><pre>Matches a dependent name type Example matches T::type @@ -2607,38 +2638,7 @@ dependentSizedExtVectorType() </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('dependentTemplateSpecializationType0')"><a name="dependentTemplateSpecializationType0Anchor">dependentTemplateSpecializationType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DependentTemplateSpecializationType.html">DependentTemplateSpecializationType</a>>...</td></tr> -<tr><td colspan="4" class="doc" id="dependentTemplateSpecializationType0"><pre>Matches a dependent template specialization type - -Example matches A<T>::template B<T> - template<typename T> struct A; - template<typename T> struct declToImport { - typename A<T>::template B<T> a; - }; -</pre></td></tr> - - -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('elaboratedType0')"><a name="elaboratedType0Anchor">elaboratedType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ElaboratedType.html">ElaboratedType</a>>...</td></tr> -<tr><td colspan="4" class="doc" id="elaboratedType0"><pre>Matches types specified with an elaborated type keyword or with a -qualified name. - -Given - namespace N { - namespace M { - class D {}; - } - } - class C {}; - - class C c; - N::M::D d; - -elaboratedType() matches the type of the variable declarations of both -c and d. -</pre></td></tr> - - -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('enumType0')"><a name="enumType0Anchor">enumType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>...</td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('enumType0')"><a name="enumType0Anchor">enumType</a></td><td>Matcher<EnumType>...</td></tr> <tr><td colspan="4" class="doc" id="enumType0"><pre>Matches enum types. Given @@ -2688,7 +2688,7 @@ incompleteArrayType() </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('injectedClassNameType0')"><a name="injectedClassNameType0Anchor">injectedClassNameType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>...</td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('injectedClassNameType0')"><a name="injectedClassNameType0Anchor">injectedClassNameType</a></td><td>Matcher<InjectedClassNameType>...</td></tr> <tr><td colspan="4" class="doc" id="injectedClassNameType0"><pre>Matches injected class name types. Example matches S s, but not S<T> s. @@ -2800,7 +2800,7 @@ matched as it is deduced to int& by reference collapsing rules. </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('recordType0')"><a name="recordType0Anchor">recordType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>...</td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('recordType0')"><a name="recordType0Anchor">recordType</a></td><td>Matcher<RecordType>...</td></tr> <tr><td colspan="4" class="doc" id="recordType0"><pre>Matches record types (e.g. structs, classes). Given @@ -2831,7 +2831,7 @@ referenceType() matches the types of b, c, d, e, and f. </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('substTemplateTypeParmType0')"><a name="substTemplateTypeParmType0Anchor">substTemplateTypeParmType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1SubstTemplateTypeParmType.html">SubstTemplateTypeParmType</a>>...</td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('substTemplateTypeParmType0')"><a name="substTemplateTypeParmType0Anchor">substTemplateTypeParmType</a></td><td>Matcher<SubstTemplateTypeParmType>...</td></tr> <tr><td colspan="4" class="doc" id="substTemplateTypeParmType0"><pre>Matches types that represent the result of substituting a type for a template type parameter. @@ -2845,7 +2845,7 @@ substTemplateTypeParmType() matches the type of 't' but not '1' </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('tagType0')"><a name="tagType0Anchor">tagType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>...</td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('tagType0')"><a name="tagType0Anchor">tagType</a></td><td>Matcher<TagType>...</td></tr> <tr><td colspan="4" class="doc" id="tagType0"><pre>Matches tag types (record and enum types). Given @@ -2860,7 +2860,7 @@ and c. </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('templateSpecializationType0')"><a name="templateSpecializationType0Anchor">templateSpecializationType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>...</td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('templateSpecializationType0')"><a name="templateSpecializationType0Anchor">templateSpecializationType</a></td><td>Matcher<TemplateSpecializationType>...</td></tr> <tr><td colspan="4" class="doc" id="templateSpecializationType0"><pre>Matches template specialization types. Given @@ -2875,7 +2875,7 @@ instantiation in A and the type of the variable declaration in B. </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('templateTypeParmType0')"><a name="templateTypeParmType0Anchor">templateTypeParmType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>...</td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('templateTypeParmType0')"><a name="templateTypeParmType0Anchor">templateTypeParmType</a></td><td>Matcher<TemplateTypeParmType>...</td></tr> <tr><td colspan="4" class="doc" id="templateTypeParmType0"><pre>Matches template type parameter types. Example matches T, but not int. @@ -2899,7 +2899,7 @@ typedefType() </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('unaryTransformType0')"><a name="unaryTransformType0Anchor">unaryTransformType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnaryTransformType.html">UnaryTransformType</a>>...</td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('unaryTransformType0')"><a name="unaryTransformType0Anchor">unaryTransformType</a></td><td>Matcher<UnaryTransformType>...</td></tr> <tr><td colspan="4" class="doc" id="unaryTransformType0"><pre>Matches types nodes representing unary type transformations. Given: @@ -3077,8 +3077,8 @@ Example 2: matches s1 < s2 <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXBaseSpecifier.html">CXXBaseSpecifier</a>></td><td class="name" onclick="toggle('isPrivate1')"><a name="isPrivate1Anchor">isPrivate</a></td><td></td></tr> -<tr><td colspan="4" class="doc" id="isPrivate1"><pre>Matches private C++ declarations and C++ base specifers that specify private -inheritance. +<tr><td colspan="4" class="doc" id="isPrivate1"><pre>Matches private C++ declarations and C++ base specifiers that specify +private inheritance. Examples: class C { @@ -3094,7 +3094,7 @@ Examples: <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXBaseSpecifier.html">CXXBaseSpecifier</a>></td><td class="name" onclick="toggle('isProtected1')"><a name="isProtected1Anchor">isProtected</a></td><td></td></tr> -<tr><td colspan="4" class="doc" id="isProtected1"><pre>Matches protected C++ declarations and C++ base specifers that specify +<tr><td colspan="4" class="doc" id="isProtected1"><pre>Matches protected C++ declarations and C++ base specifiers that specify protected inheritance. Examples: @@ -3110,7 +3110,7 @@ Examples: <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXBaseSpecifier.html">CXXBaseSpecifier</a>></td><td class="name" onclick="toggle('isPublic1')"><a name="isPublic1Anchor">isPublic</a></td><td></td></tr> -<tr><td colspan="4" class="doc" id="isPublic1"><pre>Matches public C++ declarations and C++ base specifers that specify public +<tr><td colspan="4" class="doc" id="isPublic1"><pre>Matches public C++ declarations and C++ base specifiers that specify public inheritance. Examples: @@ -3127,7 +3127,7 @@ Examples: <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXBaseSpecifier.html">CXXBaseSpecifier</a>></td><td class="name" onclick="toggle('isVirtual1')"><a name="isVirtual1Anchor">isVirtual</a></td><td></td></tr> -<tr><td colspan="4" class="doc" id="isVirtual1"><pre>Matches declarations of virtual methods and C++ base specifers that specify +<tr><td colspan="4" class="doc" id="isVirtual1"><pre>Matches declarations of virtual methods and C++ base specifiers that specify virtual inheritance. Example: @@ -3709,7 +3709,7 @@ cxxConstructorDecl(isUserProvided()) will match #1, but not #2 or #3. <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>></td><td class="name" onclick="toggle('isVirtual0')"><a name="isVirtual0Anchor">isVirtual</a></td><td></td></tr> -<tr><td colspan="4" class="doc" id="isVirtual0"><pre>Matches declarations of virtual methods and C++ base specifers that specify +<tr><td colspan="4" class="doc" id="isVirtual0"><pre>Matches declarations of virtual methods and C++ base specifiers that specify virtual inheritance. Example: @@ -4161,6 +4161,12 @@ declCountIs(2) </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('declaresSameEntityAsBoundNode0')"><a name="declaresSameEntityAsBoundNode0Anchor">declaresSameEntityAsBoundNode</a></td><td>std::string ID</td></tr> +<tr><td colspan="4" class="doc" id="declaresSameEntityAsBoundNode0"><pre>Matches a declaration if it declares the same entity as the node previously +bound to ID. +</pre></td></tr> + + <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('equalsBoundNode1')"><a name="equalsBoundNode1Anchor">equalsBoundNode</a></td><td>std::string ID</td></tr> <tr><td colspan="4" class="doc" id="equalsBoundNode1"><pre>Matches if a node equals a previously bound node. @@ -4322,8 +4328,8 @@ functionDecl(isInstantiated()) <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('isPrivate0')"><a name="isPrivate0Anchor">isPrivate</a></td><td></td></tr> -<tr><td colspan="4" class="doc" id="isPrivate0"><pre>Matches private C++ declarations and C++ base specifers that specify private -inheritance. +<tr><td colspan="4" class="doc" id="isPrivate0"><pre>Matches private C++ declarations and C++ base specifiers that specify +private inheritance. Examples: class C { @@ -4339,7 +4345,7 @@ Examples: <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('isProtected0')"><a name="isProtected0Anchor">isProtected</a></td><td></td></tr> -<tr><td colspan="4" class="doc" id="isProtected0"><pre>Matches protected C++ declarations and C++ base specifers that specify +<tr><td colspan="4" class="doc" id="isProtected0"><pre>Matches protected C++ declarations and C++ base specifiers that specify protected inheritance. Examples: @@ -4355,7 +4361,7 @@ Examples: <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('isPublic0')"><a name="isPublic0Anchor">isPublic</a></td><td></td></tr> -<tr><td colspan="4" class="doc" id="isPublic0"><pre>Matches public C++ declarations and C++ base specifers that specify public +<tr><td colspan="4" class="doc" id="isPublic0"><pre>Matches public C++ declarations and C++ base specifiers that specify public inheritance. Examples: @@ -4371,7 +4377,7 @@ Examples: </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DependentNameType.html">DependentNameType</a>></td><td class="name" onclick="toggle('hasDependentName1')"><a name="hasDependentName1Anchor">hasDependentName</a></td><td>std::string N</td></tr> +<tr><td>Matcher<DependentNameType></td><td class="name" onclick="toggle('hasDependentName1')"><a name="hasDependentName1Anchor">hasDependentName</a></td><td>std::string N</td></tr> <tr><td colspan="4" class="doc" id="hasDependentName1"><pre>Matches the dependent name of a DependentScopeDeclRefExpr or DependentNameType @@ -5046,7 +5052,7 @@ void f() { int z; Example matches f() because it has external formal linkage despite being -unique to the translation unit as though it has internal likage +unique to the translation unit as though it has internal linkage (matcher = functionDecl(hasExternalFormalLinkage())) namespace { @@ -5182,7 +5188,7 @@ Given </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPExecutableDirective.html">OMPExecutableDirective</a>></td><td class="name" onclick="toggle('isAllowedToContainClauseKind0')"><a name="isAllowedToContainClauseKind0Anchor">isAllowedToContainClauseKind</a></td><td>OpenMPClauseKind CKind</td></tr> +<tr><td>Matcher<OMPExecutableDirective></td><td class="name" onclick="toggle('isAllowedToContainClauseKind0')"><a name="isAllowedToContainClauseKind0Anchor">isAllowedToContainClauseKind</a></td><td>OpenMPClauseKind CKind</td></tr> <tr><td colspan="4" class="doc" id="isAllowedToContainClauseKind0"><pre>Matches if the OpenMP directive is allowed to contain the specified OpenMP clause kind. @@ -5192,7 +5198,7 @@ Given #pragma omp parallel for #pragma omp for -`ompExecutableDirective(isAllowedToContainClause(OMPC_default))`` matches +``ompExecutableDirective(isAllowedToContainClause(OMPC_default))`` matches ``omp parallel`` and ``omp parallel for``. If the matcher is use from clang-query, ``OpenMPClauseKind`` parameter @@ -5201,7 +5207,7 @@ should be passed as a quoted string. e.g., </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPExecutableDirective.html">OMPExecutableDirective</a>></td><td class="name" onclick="toggle('isStandaloneDirective0')"><a name="isStandaloneDirective0Anchor">isStandaloneDirective</a></td><td></td></tr> +<tr><td>Matcher<OMPExecutableDirective></td><td class="name" onclick="toggle('isStandaloneDirective0')"><a name="isStandaloneDirective0Anchor">isStandaloneDirective</a></td><td></td></tr> <tr><td colspan="4" class="doc" id="isStandaloneDirective0"><pre>Matches standalone OpenMP directives, i.e., directives that can't have a structured block. @@ -5545,10 +5551,10 @@ functionDecl(hasAnyParameter(hasType(isConstQualified()))) Given void a(int); - void b(long); + void b(unsigned long); void c(double); functionDecl(hasAnyParameter(hasType(isInteger()))) -matches "a(int)", "b(long)", but not "c(double)". +matches "a(int)", "b(unsigned long)", but not "c(double)". </pre></td></tr> @@ -5781,7 +5787,7 @@ Example matches U, but not C, S or E. <tr><td colspan="4" class="doc" id="equalsIntegralValue0"><pre>Matches a TemplateArgument of integral type with a given value. Note that 'Value' is a string as the template argument's value is -an arbitrary precision integer. 'Value' must be euqal to the canonical +an arbitrary precision integer. 'Value' must be equal to the canonical representation of that integral value in base 10. Given @@ -5806,7 +5812,7 @@ classTemplateSpecializationDecl( </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>></td><td class="name" onclick="toggle('templateArgumentCountIs3')"><a name="templateArgumentCountIs3Anchor">templateArgumentCountIs</a></td><td>unsigned N</td></tr> +<tr><td>Matcher<TemplateSpecializationType></td><td class="name" onclick="toggle('templateArgumentCountIs3')"><a name="templateArgumentCountIs3Anchor">templateArgumentCountIs</a></td><td>unsigned N</td></tr> <tr><td colspan="4" class="doc" id="templateArgumentCountIs3"><pre>Matches if the number of template arguments equals N. Given @@ -6571,8 +6577,8 @@ matches the variable declaration with "init" bound to the "3.0". <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1AbstractConditionalOperator.html">AbstractConditionalOperator</a>></td><td class="name" onclick="toggle('hasCondition5')"><a name="hasCondition5Anchor">hasCondition</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasCondition5"><pre>Matches the condition expression of an if statement, for loop, -switch statement or conditional operator. +<tr><td colspan="4" class="doc" id="hasCondition5"><pre>Matches the condition expression of an if statement, for loop, while loop, +do-while loop, switch statement or conditional operator. Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true)))) if (true) {} @@ -6600,8 +6606,8 @@ Example 2 (conditional binary operator): matches opaqueValueExpr(condition) </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1AddrLabelExpr.html">AddrLabelExpr</a>></td><td class="name" onclick="toggle('hasDeclaration15')"><a name="hasDeclaration15Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasDeclaration15"><pre>Matches a node if the declaration associated with that node +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1AddrLabelExpr.html">AddrLabelExpr</a>></td><td class="name" onclick="toggle('hasDeclaration16')"><a name="hasDeclaration16Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasDeclaration16"><pre>Matches a node if the declaration associated with that node matches the given matcher. The associated declaration is: @@ -6626,11 +6632,11 @@ In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1AddrLabelExpr.html">AddrLabelExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>> + Matcher<EnumType>, Matcher<InjectedClassNameType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<RecordType>, + Matcher<TagType>, Matcher<TemplateSpecializationType>, + Matcher<TemplateTypeParmType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UsingType.html">UsingType</a>> </pre></td></tr> @@ -6701,7 +6707,7 @@ Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Atom </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1AutoType.html">AutoType</a>></td><td class="name" onclick="toggle('hasDeducedType0')"><a name="hasDeducedType0Anchor">hasDeducedType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td></tr> +<tr><td>Matcher<AutoType></td><td class="name" onclick="toggle('hasDeducedType0')"><a name="hasDeducedType0Anchor">hasDeducedType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td></tr> <tr><td colspan="4" class="doc" id="hasDeducedType0"><pre>Matches AutoType nodes where the deduced type is a specific type. Note: There is no TypeLoc for the deduced type and thus no @@ -6713,7 +6719,7 @@ Given autoType(hasDeducedType(isInteger())) matches "auto a" -Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1AutoType.html">AutoType</a>> +Usable as: Matcher<AutoType> </pre></td></tr> @@ -7026,8 +7032,8 @@ Example matches y in x(y) </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>></td><td class="name" onclick="toggle('hasDeclaration13')"><a name="hasDeclaration13Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasDeclaration13"><pre>Matches a node if the declaration associated with that node +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>></td><td class="name" onclick="toggle('hasDeclaration14')"><a name="hasDeclaration14Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasDeclaration14"><pre>Matches a node if the declaration associated with that node matches the given matcher. The associated declaration is: @@ -7052,11 +7058,11 @@ In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1AddrLabelExpr.html">AddrLabelExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>> + Matcher<EnumType>, Matcher<InjectedClassNameType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<RecordType>, + Matcher<TagType>, Matcher<TemplateSpecializationType>, + Matcher<TemplateTypeParmType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UsingType.html">UsingType</a>> </pre></td></tr> @@ -7489,8 +7495,8 @@ cxxNewExpr(hasArraySize(integerLiteral(equals(10)))) </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>></td><td class="name" onclick="toggle('hasDeclaration12')"><a name="hasDeclaration12Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasDeclaration12"><pre>Matches a node if the declaration associated with that node +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>></td><td class="name" onclick="toggle('hasDeclaration13')"><a name="hasDeclaration13Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasDeclaration13"><pre>Matches a node if the declaration associated with that node matches the given matcher. The associated declaration is: @@ -7515,11 +7521,11 @@ In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1AddrLabelExpr.html">AddrLabelExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>> + Matcher<EnumType>, Matcher<InjectedClassNameType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<RecordType>, + Matcher<TagType>, Matcher<TemplateSpecializationType>, + Matcher<TemplateTypeParmType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UsingType.html">UsingType</a>> </pre></td></tr> @@ -7952,8 +7958,8 @@ Example matches y in x(y) </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>></td><td class="name" onclick="toggle('hasDeclaration14')"><a name="hasDeclaration14Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasDeclaration14"><pre>Matches a node if the declaration associated with that node +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>></td><td class="name" onclick="toggle('hasDeclaration15')"><a name="hasDeclaration15Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasDeclaration15"><pre>Matches a node if the declaration associated with that node matches the given matcher. The associated declaration is: @@ -7978,11 +7984,11 @@ In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1AddrLabelExpr.html">AddrLabelExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>> + Matcher<EnumType>, Matcher<InjectedClassNameType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<RecordType>, + Matcher<TagType>, Matcher<TemplateSpecializationType>, + Matcher<TemplateTypeParmType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UsingType.html">UsingType</a>> </pre></td></tr> @@ -8204,7 +8210,7 @@ with compoundStmt() <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DecayedType.html">DecayedType</a>></td><td class="name" onclick="toggle('hasDecayedType0')"><a name="hasDecayedType0Anchor">hasDecayedType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>> InnerType</td></tr> -<tr><td colspan="4" class="doc" id="hasDecayedType0"><pre>Matches the decayed type, whoes decayed type matches InnerMatcher +<tr><td colspan="4" class="doc" id="hasDecayedType0"><pre>Matches the decayed type, whose decayed type matches InnerMatcher </pre></td></tr> @@ -8223,8 +8229,8 @@ varDecl(hasTypeLoc(templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc( </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>></td><td class="name" onclick="toggle('hasDeclaration11')"><a name="hasDeclaration11Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasDeclaration11"><pre>Matches a node if the declaration associated with that node +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>></td><td class="name" onclick="toggle('hasDeclaration12')"><a name="hasDeclaration12Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasDeclaration12"><pre>Matches a node if the declaration associated with that node matches the given matcher. The associated declaration is: @@ -8249,11 +8255,11 @@ In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1AddrLabelExpr.html">AddrLabelExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>> + Matcher<EnumType>, Matcher<InjectedClassNameType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<RecordType>, + Matcher<TagType>, Matcher<TemplateSpecializationType>, + Matcher<TemplateTypeParmType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UsingType.html">UsingType</a>> </pre></td></tr> @@ -8373,24 +8379,11 @@ Given } } -cxxRcordDecl(hasDeclContext(namedDecl(hasName("M")))) matches the +cxxRecordDecl(hasDeclContext(namedDecl(hasName("M")))) matches the declaration of class D. </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DecltypeType.html">DecltypeType</a>></td><td class="name" onclick="toggle('hasUnderlyingType0')"><a name="hasUnderlyingType0Anchor">hasUnderlyingType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td></tr> -<tr><td colspan="4" class="doc" id="hasUnderlyingType0"><pre>Matches DecltypeType or UsingType nodes to find the underlying type. - -Given - decltype(1) a = 1; - decltype(2.0) b = 2.0; -decltypeType(hasUnderlyingType(isInteger())) - matches the type of "a" - -Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DecltypeType.html">DecltypeType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UsingType.html">UsingType</a>> -</pre></td></tr> - - <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DecompositionDecl.html">DecompositionDecl</a>></td><td class="name" onclick="toggle('hasAnyBinding0')"><a name="hasAnyBinding0Anchor">hasAnyBinding</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1BindingDecl.html">BindingDecl</a>> InnerMatcher</td></tr> <tr><td colspan="4" class="doc" id="hasAnyBinding0"><pre>Matches any binding of a DecompositionDecl. @@ -8451,66 +8444,16 @@ with compoundStmt() <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DoStmt.html">DoStmt</a>></td><td class="name" onclick="toggle('hasCondition3')"><a name="hasCondition3Anchor">hasCondition</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasCondition3"><pre>Matches the condition expression of an if statement, for loop, -switch statement or conditional operator. +<tr><td colspan="4" class="doc" id="hasCondition3"><pre>Matches the condition expression of an if statement, for loop, while loop, +do-while loop, switch statement or conditional operator. Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true)))) if (true) {} </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ElaboratedTypeLoc.html">ElaboratedTypeLoc</a>></td><td class="name" onclick="toggle('hasNamedTypeLoc0')"><a name="hasNamedTypeLoc0Anchor">hasNamedTypeLoc</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasNamedTypeLoc0"><pre>Matches elaborated `TypeLoc`s that have a named `TypeLoc` matching -`InnerMatcher`. - -Given - template <typename T> - class C {}; - class C<int> c; - - class D {}; - class D d; -elaboratedTypeLoc(hasNamedTypeLoc(templateSpecializationTypeLoc())); - matches the `TypeLoc` of the variable declaration of `c`, but not `d`. -</pre></td></tr> - - -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ElaboratedType.html">ElaboratedType</a>></td><td class="name" onclick="toggle('hasQualifier0')"><a name="hasQualifier0Anchor">hasQualifier</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1NestedNameSpecifier.html">NestedNameSpecifier</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasQualifier0"><pre>Matches ElaboratedTypes whose qualifier, a NestedNameSpecifier, -matches InnerMatcher if the qualifier exists. - -Given - namespace N { - namespace M { - class D {}; - } - } - N::M::D d; - -elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))) -matches the type of the variable declaration of d. -</pre></td></tr> - - -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ElaboratedType.html">ElaboratedType</a>></td><td class="name" onclick="toggle('namesType0')"><a name="namesType0Anchor">namesType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="namesType0"><pre>Matches ElaboratedTypes whose named type matches InnerMatcher. - -Given - namespace N { - namespace M { - class D {}; - } - } - N::M::D d; - -elaboratedType(namesType(recordType( -hasDeclaration(namedDecl(hasName("D")))))) matches the type of the variable -declaration of d. -</pre></td></tr> - - -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>></td><td class="name" onclick="toggle('hasDeclaration10')"><a name="hasDeclaration10Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasDeclaration10"><pre>Matches a node if the declaration associated with that node +<tr><td>Matcher<EnumType></td><td class="name" onclick="toggle('hasDeclaration11')"><a name="hasDeclaration11Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasDeclaration11"><pre>Matches a node if the declaration associated with that node matches the given matcher. The associated declaration is: @@ -8535,11 +8478,11 @@ In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1AddrLabelExpr.html">AddrLabelExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>> + Matcher<EnumType>, Matcher<InjectedClassNameType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<RecordType>, + Matcher<TagType>, Matcher<TemplateSpecializationType>, + Matcher<TemplateTypeParmType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UsingType.html">UsingType</a>> </pre></td></tr> @@ -8788,14 +8731,26 @@ with compoundStmt() <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ForStmt.html">ForStmt</a>></td><td class="name" onclick="toggle('hasCondition1')"><a name="hasCondition1Anchor">hasCondition</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasCondition1"><pre>Matches the condition expression of an if statement, for loop, -switch statement or conditional operator. +<tr><td colspan="4" class="doc" id="hasCondition1"><pre>Matches the condition expression of an if statement, for loop, while loop, +do-while loop, switch statement or conditional operator. Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true)))) if (true) {} </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ForStmt.html">ForStmt</a>></td><td class="name" onclick="toggle('hasConditionVariableStatement1')"><a name="hasConditionVariableStatement1Anchor">hasConditionVariableStatement</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclStmt.html">DeclStmt</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasConditionVariableStatement1"><pre>Matches the condition variable statement in an if statement, for loop, +while loop or switch statement. + +Given + if (A* a = GetAPointer()) {} + for (; A* a = GetAPointer(); ) {} +hasConditionVariableStatement(...) + matches both 'A* a = GetAPointer()'. +</pre></td></tr> + + <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ForStmt.html">ForStmt</a>></td><td class="name" onclick="toggle('hasIncrement0')"><a name="hasIncrement0Anchor">hasIncrement</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>> InnerMatcher</td></tr> <tr><td colspan="4" class="doc" id="hasIncrement0"><pre>Matches the increment statement of a for loop. @@ -9099,8 +9054,8 @@ cxxMethodDecl(returns(asString("int"))) <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1IfStmt.html">IfStmt</a>></td><td class="name" onclick="toggle('hasCondition0')"><a name="hasCondition0Anchor">hasCondition</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasCondition0"><pre>Matches the condition expression of an if statement, for loop, -switch statement or conditional operator. +<tr><td colspan="4" class="doc" id="hasCondition0"><pre>Matches the condition expression of an if statement, for loop, while loop, +do-while loop, switch statement or conditional operator. Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true)))) if (true) {} @@ -9108,12 +9063,14 @@ Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true)))) <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1IfStmt.html">IfStmt</a>></td><td class="name" onclick="toggle('hasConditionVariableStatement0')"><a name="hasConditionVariableStatement0Anchor">hasConditionVariableStatement</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclStmt.html">DeclStmt</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasConditionVariableStatement0"><pre>Matches the condition variable statement in an if statement. +<tr><td colspan="4" class="doc" id="hasConditionVariableStatement0"><pre>Matches the condition variable statement in an if statement, for loop, +while loop or switch statement. Given if (A* a = GetAPointer()) {} + for (; A* a = GetAPointer(); ) {} hasConditionVariableStatement(...) - matches 'A* a = GetAPointer()'. + matches both 'A* a = GetAPointer()'. </pre></td></tr> @@ -9179,8 +9136,8 @@ Example matches y. </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>></td><td class="name" onclick="toggle('hasDeclaration9')"><a name="hasDeclaration9Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasDeclaration9"><pre>Matches a node if the declaration associated with that node +<tr><td>Matcher<InjectedClassNameType></td><td class="name" onclick="toggle('hasDeclaration10')"><a name="hasDeclaration10Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasDeclaration10"><pre>Matches a node if the declaration associated with that node matches the given matcher. The associated declaration is: @@ -9205,16 +9162,16 @@ In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1AddrLabelExpr.html">AddrLabelExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>> + Matcher<EnumType>, Matcher<InjectedClassNameType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<RecordType>, + Matcher<TagType>, Matcher<TemplateSpecializationType>, + Matcher<TemplateTypeParmType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UsingType.html">UsingType</a>> </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>></td><td class="name" onclick="toggle('hasDeclaration8')"><a name="hasDeclaration8Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasDeclaration8"><pre>Matches a node if the declaration associated with that node +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>></td><td class="name" onclick="toggle('hasDeclaration9')"><a name="hasDeclaration9Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasDeclaration9"><pre>Matches a node if the declaration associated with that node matches the given matcher. The associated declaration is: @@ -9239,11 +9196,11 @@ In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1AddrLabelExpr.html">AddrLabelExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>> + Matcher<EnumType>, Matcher<InjectedClassNameType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<RecordType>, + Matcher<TagType>, Matcher<TemplateSpecializationType>, + Matcher<TemplateTypeParmType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UsingType.html">UsingType</a>> </pre></td></tr> @@ -9293,8 +9250,8 @@ lambdaExpr(hasAnyCapture(lambdaCapture(refersToVarDecl(hasName("t"))))) </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>></td><td class="name" onclick="toggle('hasDeclaration7')"><a name="hasDeclaration7Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasDeclaration7"><pre>Matches a node if the declaration associated with that node +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>></td><td class="name" onclick="toggle('hasDeclaration8')"><a name="hasDeclaration8Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasDeclaration8"><pre>Matches a node if the declaration associated with that node matches the given matcher. The associated declaration is: @@ -9319,11 +9276,11 @@ In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1AddrLabelExpr.html">AddrLabelExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>> + Matcher<EnumType>, Matcher<InjectedClassNameType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<RecordType>, + Matcher<TagType>, Matcher<TemplateSpecializationType>, + Matcher<TemplateTypeParmType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UsingType.html">UsingType</a>> </pre></td></tr> @@ -9456,7 +9413,7 @@ nestedNameSpecifier(specifiesType( </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPExecutableDirective.html">OMPExecutableDirective</a>></td><td class="name" onclick="toggle('hasAnyClause0')"><a name="hasAnyClause0Anchor">hasAnyClause</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPClause.html">OMPClause</a>> InnerMatcher</td></tr> +<tr><td>Matcher<OMPExecutableDirective></td><td class="name" onclick="toggle('hasAnyClause0')"><a name="hasAnyClause0Anchor">hasAnyClause</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPClause.html">OMPClause</a>> InnerMatcher</td></tr> <tr><td colspan="4" class="doc" id="hasAnyClause0"><pre>Matches any clause in an OpenMP directive. Given @@ -9469,7 +9426,7 @@ Given </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1OMPExecutableDirective.html">OMPExecutableDirective</a>></td><td class="name" onclick="toggle('hasStructuredBlock0')"><a name="hasStructuredBlock0Anchor">hasStructuredBlock</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>> InnerMatcher</td></tr> +<tr><td>Matcher<OMPExecutableDirective></td><td class="name" onclick="toggle('hasStructuredBlock0')"><a name="hasStructuredBlock0Anchor">hasStructuredBlock</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>> InnerMatcher</td></tr> <tr><td colspan="4" class="doc" id="hasStructuredBlock0"><pre>Matches the structured-block of the OpenMP executable directive Prerequisite: the executable directive must not be standalone directive. @@ -9826,8 +9783,8 @@ declaration of b but varDecl(hasType(qualType(hasCanonicalType(referenceType())) </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>></td><td class="name" onclick="toggle('hasDeclaration6')"><a name="hasDeclaration6Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasDeclaration6"><pre>Matches a node if the declaration associated with that node +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>></td><td class="name" onclick="toggle('hasDeclaration7')"><a name="hasDeclaration7Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasDeclaration7"><pre>Matches a node if the declaration associated with that node matches the given matcher. The associated declaration is: @@ -9852,11 +9809,11 @@ In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1AddrLabelExpr.html">AddrLabelExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>> + Matcher<EnumType>, Matcher<InjectedClassNameType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<RecordType>, + Matcher<TagType>, Matcher<TemplateSpecializationType>, + Matcher<TemplateTypeParmType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UsingType.html">UsingType</a>> </pre></td></tr> @@ -9920,8 +9877,8 @@ qualifiedTypeLoc(hasUnqualifiedLoc(pointerTypeLoc())) </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>></td><td class="name" onclick="toggle('hasDeclaration5')"><a name="hasDeclaration5Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasDeclaration5"><pre>Matches a node if the declaration associated with that node +<tr><td>Matcher<RecordType></td><td class="name" onclick="toggle('hasDeclaration6')"><a name="hasDeclaration6Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasDeclaration6"><pre>Matches a node if the declaration associated with that node matches the given matcher. The associated declaration is: @@ -9946,11 +9903,11 @@ In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1AddrLabelExpr.html">AddrLabelExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>> + Matcher<EnumType>, Matcher<InjectedClassNameType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<RecordType>, + Matcher<TagType>, Matcher<TemplateSpecializationType>, + Matcher<TemplateTypeParmType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UsingType.html">UsingType</a>> </pre></td></tr> @@ -10066,7 +10023,7 @@ sizeof. </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1SubstTemplateTypeParmType.html">SubstTemplateTypeParmType</a>></td><td class="name" onclick="toggle('hasReplacementType0')"><a name="hasReplacementType0Anchor">hasReplacementType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td></tr> +<tr><td>Matcher<SubstTemplateTypeParmType></td><td class="name" onclick="toggle('hasReplacementType0')"><a name="hasReplacementType0Anchor">hasReplacementType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td></tr> <tr><td colspan="4" class="doc" id="hasReplacementType0"><pre>Matches template type parameter substitutions that have a replacement type that matches the provided matcher. @@ -10094,14 +10051,26 @@ switchStmt(forEachSwitchCase(caseStmt().bind("c"))).bind("s") <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1SwitchStmt.html">SwitchStmt</a>></td><td class="name" onclick="toggle('hasCondition4')"><a name="hasCondition4Anchor">hasCondition</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasCondition4"><pre>Matches the condition expression of an if statement, for loop, -switch statement or conditional operator. +<tr><td colspan="4" class="doc" id="hasCondition4"><pre>Matches the condition expression of an if statement, for loop, while loop, +do-while loop, switch statement or conditional operator. Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true)))) if (true) {} </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1SwitchStmt.html">SwitchStmt</a>></td><td class="name" onclick="toggle('hasConditionVariableStatement3')"><a name="hasConditionVariableStatement3Anchor">hasConditionVariableStatement</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclStmt.html">DeclStmt</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasConditionVariableStatement3"><pre>Matches the condition variable statement in an if statement, for loop, +while loop or switch statement. + +Given + if (A* a = GetAPointer()) {} + for (; A* a = GetAPointer(); ) {} +hasConditionVariableStatement(...) + matches both 'A* a = GetAPointer()'. +</pre></td></tr> + + <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1SwitchStmt.html">SwitchStmt</a>></td><td class="name" onclick="toggle('hasInitStatement1')"><a name="hasInitStatement1Anchor">hasInitStatement</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>> InnerMatcher</td></tr> <tr><td colspan="4" class="doc" id="hasInitStatement1"><pre>Matches selection statements with initializer. @@ -10125,8 +10094,8 @@ cxxForRangeStmt(hasInitStatement(anything())) </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>></td><td class="name" onclick="toggle('hasDeclaration4')"><a name="hasDeclaration4Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasDeclaration4"><pre>Matches a node if the declaration associated with that node +<tr><td>Matcher<TagType></td><td class="name" onclick="toggle('hasDeclaration5')"><a name="hasDeclaration5Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasDeclaration5"><pre>Matches a node if the declaration associated with that node matches the given matcher. The associated declaration is: @@ -10151,11 +10120,11 @@ In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1AddrLabelExpr.html">AddrLabelExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>> + Matcher<EnumType>, Matcher<InjectedClassNameType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<RecordType>, + Matcher<TagType>, Matcher<TemplateSpecializationType>, + Matcher<TemplateTypeParmType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UsingType.html">UsingType</a>> </pre></td></tr> @@ -10284,7 +10253,7 @@ varDecl(hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(0, </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>></td><td class="name" onclick="toggle('forEachTemplateArgument3')"><a name="forEachTemplateArgument3Anchor">forEachTemplateArgument</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>> InnerMatcher</td></tr> +<tr><td>Matcher<TemplateSpecializationType></td><td class="name" onclick="toggle('forEachTemplateArgument3')"><a name="forEachTemplateArgument3Anchor">forEachTemplateArgument</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>> InnerMatcher</td></tr> <tr><td colspan="4" class="doc" id="forEachTemplateArgument3"><pre>Matches templateSpecializationType, class template specialization, variable template specialization, and function template specialization nodes where the template argument matches the inner matcher. This matcher @@ -10310,7 +10279,7 @@ functionDecl(forEachTemplateArgument(refersToType(builtinType()))) </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>></td><td class="name" onclick="toggle('hasAnyTemplateArgument3')"><a name="hasAnyTemplateArgument3Anchor">hasAnyTemplateArgument</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>> InnerMatcher</td></tr> +<tr><td>Matcher<TemplateSpecializationType></td><td class="name" onclick="toggle('hasAnyTemplateArgument3')"><a name="hasAnyTemplateArgument3Anchor">hasAnyTemplateArgument</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>> InnerMatcher</td></tr> <tr><td colspan="4" class="doc" id="hasAnyTemplateArgument3"><pre>Matches templateSpecializationTypes, class template specializations, variable template specializations, and function template specializations that have at least one TemplateArgument matching the given InnerMatcher. @@ -10332,8 +10301,8 @@ functionDecl(hasAnyTemplateArgument(refersToType(asString("int")))) </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>></td><td class="name" onclick="toggle('hasDeclaration3')"><a name="hasDeclaration3Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasDeclaration3"><pre>Matches a node if the declaration associated with that node +<tr><td>Matcher<TemplateSpecializationType></td><td class="name" onclick="toggle('hasDeclaration4')"><a name="hasDeclaration4Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasDeclaration4"><pre>Matches a node if the declaration associated with that node matches the given matcher. The associated declaration is: @@ -10358,15 +10327,15 @@ In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1AddrLabelExpr.html">AddrLabelExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>> + Matcher<EnumType>, Matcher<InjectedClassNameType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<RecordType>, + Matcher<TagType>, Matcher<TemplateSpecializationType>, + Matcher<TemplateTypeParmType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UsingType.html">UsingType</a>> </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>></td><td class="name" onclick="toggle('hasTemplateArgument3')"><a name="hasTemplateArgument3Anchor">hasTemplateArgument</a></td><td>unsigned N, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>> InnerMatcher</td></tr> +<tr><td>Matcher<TemplateSpecializationType></td><td class="name" onclick="toggle('hasTemplateArgument3')"><a name="hasTemplateArgument3Anchor">hasTemplateArgument</a></td><td>unsigned N, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>> InnerMatcher</td></tr> <tr><td colspan="4" class="doc" id="hasTemplateArgument3"><pre>Matches templateSpecializationType, class template specializations, variable template specializations, and function template specializations where the n'th TemplateArgument matches the given InnerMatcher. @@ -10387,8 +10356,8 @@ functionDecl(hasTemplateArgument(0, refersToType(asString("int")))) </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>></td><td class="name" onclick="toggle('hasDeclaration2')"><a name="hasDeclaration2Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasDeclaration2"><pre>Matches a node if the declaration associated with that node +<tr><td>Matcher<TemplateTypeParmType></td><td class="name" onclick="toggle('hasDeclaration3')"><a name="hasDeclaration3Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasDeclaration3"><pre>Matches a node if the declaration associated with that node matches the given matcher. The associated declaration is: @@ -10413,11 +10382,11 @@ In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1AddrLabelExpr.html">AddrLabelExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>> + Matcher<EnumType>, Matcher<InjectedClassNameType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<RecordType>, + Matcher<TagType>, Matcher<TemplateSpecializationType>, + Matcher<TemplateTypeParmType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UsingType.html">UsingType</a>> </pre></td></tr> @@ -10473,8 +10442,8 @@ Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X"))))) </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>></td><td class="name" onclick="toggle('hasDeclaration1')"><a name="hasDeclaration1Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasDeclaration1"><pre>Matches a node if the declaration associated with that node +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>></td><td class="name" onclick="toggle('hasDeclaration2')"><a name="hasDeclaration2Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasDeclaration2"><pre>Matches a node if the declaration associated with that node matches the given matcher. The associated declaration is: @@ -10499,11 +10468,41 @@ In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1AddrLabelExpr.html">AddrLabelExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>> + Matcher<EnumType>, Matcher<InjectedClassNameType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<RecordType>, + Matcher<TagType>, Matcher<TemplateSpecializationType>, + Matcher<TemplateTypeParmType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UsingType.html">UsingType</a>> +</pre></td></tr> + + +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('hasQualifier0')"><a name="hasQualifier0Anchor">hasQualifier</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1NestedNameSpecifier.html">NestedNameSpecifier</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasQualifier0"><pre>Matches Types whose qualifier, a NestedNameSpecifier, +matches InnerMatcher if the qualifier exists. + +Given + namespace N { + namespace M { + class D {}; + } + } + N::M::D d; + +elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))) +matches the type of the variable declaration of d. +</pre></td></tr> + + +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td><td class="name" onclick="toggle('hasUnderlyingType0')"><a name="hasUnderlyingType0Anchor">hasUnderlyingType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>> Inner</td></tr> +<tr><td colspan="4" class="doc" id="hasUnderlyingType0"><pre>Matches QualType nodes to find the underlying type. + +Given + decltype(1) a = 1; + decltype(2.0) b = 2.0; +decltypeType(hasUnderlyingType(isInteger())) + matches the type of "a" + +Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>> </pre></td></tr> @@ -10556,8 +10555,8 @@ memberExpr(hasObjectExpression(hasType(pointsTo( </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>></td><td class="name" onclick="toggle('hasDeclaration0')"><a name="hasDeclaration0Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasDeclaration0"><pre>Matches a node if the declaration associated with that node +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>></td><td class="name" onclick="toggle('hasDeclaration1')"><a name="hasDeclaration1Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasDeclaration1"><pre>Matches a node if the declaration associated with that node matches the given matcher. The associated declaration is: @@ -10582,11 +10581,11 @@ In this matcher, the decl will match the CXXRecordDecl of class X. Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1AddrLabelExpr.html">AddrLabelExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1EnumType.html">EnumType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1InjectedClassNameType.html">InjectedClassNameType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1RecordType.html">RecordType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TagType.html">TagType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateTypeParmType.html">TemplateTypeParmType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, - Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>> + Matcher<EnumType>, Matcher<InjectedClassNameType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<RecordType>, + Matcher<TagType>, Matcher<TemplateSpecializationType>, + Matcher<TemplateTypeParmType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UsingType.html">UsingType</a>> </pre></td></tr> @@ -10602,16 +10601,37 @@ usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(functionDecl()))) matches using X::b but not using X::a </pre></td></tr> -<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UsingType.html">UsingType</a>></td><td class="name" onclick="toggle('hasUnderlyingType1')"><a name="hasUnderlyingType1Anchor">hasUnderlyingType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td></tr> -<tr><td colspan="4" class="doc" id="hasUnderlyingType1"><pre>Matches DecltypeType or UsingType nodes to find the underlying type. +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UsingType.html">UsingType</a>></td><td class="name" onclick="toggle('hasDeclaration0')"><a name="hasDeclaration0Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasDeclaration0"><pre>Matches a node if the declaration associated with that node +matches the given matcher. -Given - decltype(1) a = 1; - decltype(2.0) b = 2.0; -decltypeType(hasUnderlyingType(isInteger())) - matches the type of "a" +The associated declaration is: +- for type nodes, the declaration of the underlying type +- for CallExpr, the declaration of the callee +- for MemberExpr, the declaration of the referenced member +- for CXXConstructExpr, the declaration of the constructor +- for CXXNewExpr, the declaration of the operator new +- for ObjCIvarExpr, the declaration of the ivar + +For type nodes, hasDeclaration will generally match the declaration of the +sugared type. Given + class X {}; + typedef X Y; + Y y; +in varDecl(hasType(hasDeclaration(decl()))) the decl will match the +typedefDecl. A common use case is to match the underlying, desugared type. +This can be achieved by using the hasUnqualifiedDesugaredType matcher: + varDecl(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl()))))) +In this matcher, the decl will match the CXXRecordDecl of class X. -Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DecltypeType.html">DecltypeType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UsingType.html">UsingType</a>> +Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1AddrLabelExpr.html">AddrLabelExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CallExpr.html">CallExpr</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXConstructExpr.html">CXXConstructExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>>, + Matcher<EnumType>, Matcher<InjectedClassNameType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1LabelStmt.html">LabelStmt</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1MemberExpr.html">MemberExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1QualType.html">QualType</a>>, Matcher<RecordType>, + Matcher<TagType>, Matcher<TemplateSpecializationType>, + Matcher<TemplateTypeParmType>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefType.html">TypedefType</a>>, + Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnresolvedUsingType.html">UnresolvedUsingType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UsingType.html">UsingType</a>> </pre></td></tr> @@ -10832,13 +10852,25 @@ with compoundStmt() <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1WhileStmt.html">WhileStmt</a>></td><td class="name" onclick="toggle('hasCondition2')"><a name="hasCondition2Anchor">hasCondition</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasCondition2"><pre>Matches the condition expression of an if statement, for loop, -switch statement or conditional operator. +<tr><td colspan="4" class="doc" id="hasCondition2"><pre>Matches the condition expression of an if statement, for loop, while loop, +do-while loop, switch statement or conditional operator. Example matches true (matcher = hasCondition(cxxBoolLiteral(equals(true)))) if (true) {} </pre></td></tr> + +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1WhileStmt.html">WhileStmt</a>></td><td class="name" onclick="toggle('hasConditionVariableStatement2')"><a name="hasConditionVariableStatement2Anchor">hasConditionVariableStatement</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclStmt.html">DeclStmt</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasConditionVariableStatement2"><pre>Matches the condition variable statement in an if statement, for loop, +while loop or switch statement. + +Given + if (A* a = GetAPointer()) {} + for (; A* a = GetAPointer(); ) {} +hasConditionVariableStatement(...) + matches both 'A* a = GetAPointer()'. +</pre></td></tr> + <!--END_TRAVERSAL_MATCHERS --> </table> diff --git a/clang/docs/ThreadSafetyAnalysis.rst b/clang/docs/ThreadSafetyAnalysis.rst index 853a8fa..d0f96f5 100644 --- a/clang/docs/ThreadSafetyAnalysis.rst +++ b/clang/docs/ThreadSafetyAnalysis.rst @@ -118,7 +118,7 @@ require exclusive access, while read operations require only shared access. At any given moment during program execution, a thread holds a specific set of capabilities (e.g. the set of mutexes that it has locked.) These act like keys or tokens that allow the thread to access a given resource. Just like physical -security keys, a thread cannot make copy of a capability, nor can it destroy +security keys, a thread cannot make a copy of a capability, nor can it destroy one. A thread can only release a capability to another thread, or acquire one from another thread. The annotations are deliberately agnostic about the exact mechanism used to acquire and release capabilities; it assumes that the @@ -131,7 +131,7 @@ by calculating an approximation of that set, called the *capability environment*. The capability environment is calculated for every program point, and describes the set of capabilities that are statically known to be held, or not held, at that particular point. This environment is a conservative -approximation of the full set of capabilities that will actually held by a +approximation of the full set of capabilities that will actually be held by a thread at run-time. @@ -369,7 +369,7 @@ thread-safe, but too complicated for the analysis to understand. Reasons for void unsafeIncrement() NO_THREAD_SAFETY_ANALYSIS { a++; } }; -Unlike the other attributes, NO_THREAD_SAFETY_ANALYSIS is not part of the +Unlike the other attributes, ``NO_THREAD_SAFETY_ANALYSIS`` is not part of the interface of a function, and should thus be placed on the function definition (in the ``.cc`` or ``.cpp`` file) rather than on the function declaration (in the header). @@ -509,7 +509,7 @@ ASSERT_CAPABILITY(...) and ASSERT_SHARED_CAPABILITY(...) *Previously:* ``ASSERT_EXCLUSIVE_LOCK``, ``ASSERT_SHARED_LOCK`` These are attributes on a function or method which asserts the calling thread -already holds the given capability, for example by performing a run-time test +already holds the given capability, for example, by performing a run-time test and terminating if the capability is not held. Presence of this annotation causes the analysis to assume the capability is held after calls to the annotated function. See :ref:`mutexheader`, below, for example uses. @@ -554,19 +554,19 @@ Negative Capabilities ===================== Thread Safety Analysis is designed to prevent both race conditions and -deadlock. The GUARDED_BY and REQUIRES attributes prevent race conditions, by +deadlock. The ``GUARDED_BY`` and ``REQUIRES`` attributes prevent race conditions, by ensuring that a capability is held before reading or writing to guarded data, -and the EXCLUDES attribute prevents deadlock, by making sure that a mutex is +and the ``EXCLUDES`` attribute prevents deadlock, by making sure that a mutex is *not* held. -However, EXCLUDES is an optional attribute, and does not provide the same -safety guarantee as REQUIRES. In particular: +However, ``EXCLUDES`` is an optional attribute, and does not provide the same +safety guarantee as ``REQUIRES``. In particular: * A function which acquires a capability does not have to exclude it. * A function which calls a function that excludes a capability does not - have transitively exclude that capability. + have to transitively exclude that capability. -As a result, EXCLUDES can easily produce false negatives: +As a result, ``EXCLUDES`` can easily produce false negatives: .. code-block:: c++ @@ -594,8 +594,8 @@ As a result, EXCLUDES can easily produce false negatives: }; -Negative requirements are an alternative EXCLUDES that provide -a stronger safety guarantee. A negative requirement uses the REQUIRES +Negative requirements are an alternative to ``EXCLUDES`` that provide +a stronger safety guarantee. A negative requirement uses the ``REQUIRES`` attribute, in conjunction with the ``!`` operator, to indicate that a capability should *not* be held. @@ -642,7 +642,7 @@ Frequently Asked Questions (A) Attributes are part of the formal interface of a function, and should always go in the header, where they are visible to anything that includes -the header. Attributes in the .cpp file are not visible outside of the +the header. Attributes in the ``.cpp`` file are not visible outside of the immediate translation unit, which leads to false negatives and false positives. @@ -684,7 +684,7 @@ Private Mutexes --------------- Good software engineering practice dictates that mutexes should be private -members, because the locking mechanism used by a thread-safe class is part of +members because the locking mechanism used by a thread-safe class is part of its internal implementation. However, private mutexes can sometimes leak into the public interface of a class. Thread safety attributes follow normal C++ access restrictions, so if ``mu`` diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index a2c2021..2b400b0 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -5030,6 +5030,12 @@ def HLSLWaveActiveMax : LangBuiltin<"HLSL_LANG"> { let Prototype = "void (...)"; } +def HLSLWaveActiveMin : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_wave_active_min"]; + let Attributes = [NoThrow, Const]; + let Prototype = "void (...)"; +} + def HLSLWaveActiveSum : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_wave_active_sum"]; let Attributes = [NoThrow, Const]; diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 8784c9d..cb5cb88 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5999,7 +5999,6 @@ def nofixprebinding : Flag<["-"], "nofixprebinding">; def nolibc : Flag<["-"], "nolibc">; def nomultidefs : Flag<["-"], "nomultidefs">; def nopie : Flag<["-"], "nopie">, Visibility<[ClangOption, FlangOption]>, Flags<[TargetSpecific]>; // OpenBSD -def no_pie : Flag<["-"], "no-pie">, Visibility<[ClangOption, FlangOption]>; def noprebind : Flag<["-"], "noprebind">; def noprofilelib : Flag<["-"], "noprofilelib">; def noseglinkedit : Flag<["-"], "noseglinkedit">; @@ -6113,7 +6112,6 @@ defm pthread : BoolOption<"", "pthread", PosFlag<SetTrue, [], [ClangOption], "Support POSIX threads in generated code">, NegFlag<SetFalse>, BothFlags<[], [ClangOption, CC1Option, FlangOption, FC1Option]>>; -def pie : Flag<["-"], "pie">, Group<Link_Group>; def static_pie : Flag<["-"], "static-pie">, Group<Link_Group>; def read__only__relocs : Separate<["-"], "read_only_relocs">; def remap : Flag<["-"], "remap">; @@ -6508,6 +6506,8 @@ def fpic : Flag<["-"], "fpic">, Group<f_Group>; def fno_pic : Flag<["-"], "fno-pic">, Group<f_Group>; def fpie : Flag<["-"], "fpie">, Group<f_Group>; def fno_pie : Flag<["-"], "fno-pie">, Group<f_Group>; +def pie : Flag<["-"], "pie">, Group<Link_Group>; +def no_pie : Flag<["-"], "no-pie">, Group<Link_Group>; } // let Vis = [Default, FlangOption] diff --git a/clang/include/clang/Frontend/TextDiagnostic.h b/clang/include/clang/Frontend/TextDiagnostic.h index e2e88d4..10028186d 100644 --- a/clang/include/clang/Frontend/TextDiagnostic.h +++ b/clang/include/clang/Frontend/TextDiagnostic.h @@ -16,10 +16,12 @@ #define LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H #include "clang/Frontend/DiagnosticRenderer.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/FormattedStream.h" namespace clang { +using llvm::formatted_raw_ostream; + /// Class to encapsulate the logic for formatting and printing a textual /// diagnostic message. /// @@ -33,7 +35,7 @@ namespace clang { /// DiagnosticClient is implemented through this class as is diagnostic /// printing coming out of libclang. class TextDiagnostic : public DiagnosticRenderer { - raw_ostream &OS; + formatted_raw_ostream OS; const Preprocessor *PP; public: @@ -47,7 +49,7 @@ public: unsigned End; enum llvm::raw_ostream::Colors Color; StyleRange(unsigned S, unsigned E, enum llvm::raw_ostream::Colors C) - : Start(S), End(E), Color(C){}; + : Start(S), End(E), Color(C) {}; }; /// Print the diagonstic level to a raw_ostream. diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 0d2316f..dad8efd0 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -7677,7 +7677,7 @@ private: /// [GNU] asm-clobbers: /// asm-string-literal /// asm-clobbers ',' asm-string-literal - /// \endverbatim + /// \endverbatim /// StmtResult ParseAsmStatement(bool &msAsm); diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index ab6b3ed..b3ab82d 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -859,7 +859,7 @@ static bool interp__builtin_carryop(InterpState &S, CodePtr OpPC, APSInt RHS = popToAPSInt(S.Stk, RHST); APSInt LHS = popToAPSInt(S.Stk, LHST); - if (CarryOutPtr.isDummy()) + if (CarryOutPtr.isDummy() || !CarryOutPtr.isBlockPointer()) return false; APSInt CarryOut; diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp index d8ec837..938c648 100644 --- a/clang/lib/Basic/SourceManager.cpp +++ b/clang/lib/Basic/SourceManager.cpp @@ -608,8 +608,7 @@ FileID SourceManager::createFileIDImpl(ContentCache &File, StringRef Filename, return FileID::get(LoadedID); } unsigned FileSize = File.getSize(); - llvm::ErrorOr<bool> NeedConversion = - llvm::needConversion(Filename.str().c_str()); + llvm::ErrorOr<bool> NeedConversion = llvm::needConversion(Filename); if (NeedConversion && *NeedConversion) { // Buffer size may increase due to potential z/OS EBCDIC to UTF-8 // conversion. diff --git a/clang/lib/Basic/Targets/BPF.cpp b/clang/lib/Basic/Targets/BPF.cpp index 0411bcc..8de1083 100644 --- a/clang/lib/Basic/Targets/BPF.cpp +++ b/clang/lib/Basic/Targets/BPF.cpp @@ -75,6 +75,7 @@ void BPFTargetInfo::getTargetDefines(const LangOptions &Opts, Builder.defineMacro("__BPF_FEATURE_GOTOL"); Builder.defineMacro("__BPF_FEATURE_ST"); Builder.defineMacro("__BPF_FEATURE_LOAD_ACQ_STORE_REL"); + Builder.defineMacro("__BPF_FEATURE_GOTOX"); } } diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h index 50d585d..e5066fa 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h +++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h @@ -108,11 +108,11 @@ public: cir::LongDoubleType getLongDoubleTy(const llvm::fltSemantics &format) const { if (&format == &llvm::APFloat::IEEEdouble()) - return cir::LongDoubleType::get(getContext(), typeCache.DoubleTy); + return cir::LongDoubleType::get(getContext(), typeCache.doubleTy); if (&format == &llvm::APFloat::x87DoubleExtended()) - return cir::LongDoubleType::get(getContext(), typeCache.FP80Ty); + return cir::LongDoubleType::get(getContext(), typeCache.fP80Ty); if (&format == &llvm::APFloat::IEEEquad()) - return cir::LongDoubleType::get(getContext(), typeCache.FP128Ty); + return cir::LongDoubleType::get(getContext(), typeCache.fP128Ty); if (&format == &llvm::APFloat::PPCDoubleDouble()) llvm_unreachable("NYI: PPC double-double format for long double"); llvm_unreachable("Unsupported format for long double"); @@ -258,17 +258,17 @@ public: } } - cir::VoidType getVoidTy() { return typeCache.VoidTy; } + cir::VoidType getVoidTy() { return typeCache.voidTy; } - cir::IntType getSInt8Ty() { return typeCache.SInt8Ty; } - cir::IntType getSInt16Ty() { return typeCache.SInt16Ty; } - cir::IntType getSInt32Ty() { return typeCache.SInt32Ty; } - cir::IntType getSInt64Ty() { return typeCache.SInt64Ty; } + cir::IntType getSInt8Ty() { return typeCache.sInt8Ty; } + cir::IntType getSInt16Ty() { return typeCache.sInt16Ty; } + cir::IntType getSInt32Ty() { return typeCache.sInt32Ty; } + cir::IntType getSInt64Ty() { return typeCache.sInt64Ty; } - cir::IntType getUInt8Ty() { return typeCache.UInt8Ty; } - cir::IntType getUInt16Ty() { return typeCache.UInt16Ty; } - cir::IntType getUInt32Ty() { return typeCache.UInt32Ty; } - cir::IntType getUInt64Ty() { return typeCache.UInt64Ty; } + cir::IntType getUInt8Ty() { return typeCache.uInt8Ty; } + cir::IntType getUInt16Ty() { return typeCache.uInt16Ty; } + cir::IntType getUInt32Ty() { return typeCache.uInt32Ty; } + cir::IntType getUInt64Ty() { return typeCache.uInt64Ty; } cir::ConstantOp getConstInt(mlir::Location loc, llvm::APSInt intVal); @@ -280,21 +280,21 @@ public: llvm::APFloat fpVal); bool isInt8Ty(mlir::Type i) { - return i == typeCache.UInt8Ty || i == typeCache.SInt8Ty; + return i == typeCache.uInt8Ty || i == typeCache.sInt8Ty; } bool isInt16Ty(mlir::Type i) { - return i == typeCache.UInt16Ty || i == typeCache.SInt16Ty; + return i == typeCache.uInt16Ty || i == typeCache.sInt16Ty; } bool isInt32Ty(mlir::Type i) { - return i == typeCache.UInt32Ty || i == typeCache.SInt32Ty; + return i == typeCache.uInt32Ty || i == typeCache.sInt32Ty; } bool isInt64Ty(mlir::Type i) { - return i == typeCache.UInt64Ty || i == typeCache.SInt64Ty; + return i == typeCache.uInt64Ty || i == typeCache.sInt64Ty; } bool isInt(mlir::Type i) { return mlir::isa<cir::IntType>(i); } // Fetch the type representing a pointer to unsigned int8 values. - cir::PointerType getUInt8PtrTy() { return typeCache.UInt8PtrTy; } + cir::PointerType getUInt8PtrTy() { return typeCache.uInt8PtrTy; } /// Get a CIR anonymous record type. cir::RecordType getAnonRecordTy(llvm::ArrayRef<mlir::Type> members, diff --git a/clang/lib/CIR/CodeGen/CIRGenClass.cpp b/clang/lib/CIR/CodeGen/CIRGenClass.cpp index 5046e09..a829678 100644 --- a/clang/lib/CIR/CodeGen/CIRGenClass.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenClass.cpp @@ -362,7 +362,7 @@ static Address applyNonVirtualAndVirtualOffset( // not bytes. So the pointer must be cast to a byte pointer and back. mlir::Value ptr = addr.getPointer(); - mlir::Type charPtrType = cgf.cgm.UInt8PtrTy; + mlir::Type charPtrType = cgf.cgm.uInt8PtrTy; mlir::Value charPtr = cgf.getBuilder().createBitcast(ptr, charPtrType); mlir::Value adjusted = cir::PtrStrideOp::create( cgf.getBuilder(), loc, charPtrType, charPtr, baseOffset); @@ -1105,7 +1105,7 @@ mlir::Value CIRGenFunction::getVTTParameter(GlobalDecl gd, bool forVirtualBase, // We're the complete constructor, so get the VTT by name. cir::GlobalOp vtt = cgm.getVTables().getAddrOfVTT(rd); return builder.createVTTAddrPoint( - loc, builder.getPointerTo(cgm.VoidPtrTy), + loc, builder.getPointerTo(cgm.voidPtrTy), mlir::FlatSymbolRefAttr::get(vtt.getSymNameAttr()), subVTTIndex); } } diff --git a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp index 8723a6e..930ae55 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp @@ -55,7 +55,7 @@ cir::CallOp CIRGenFunction::emitCoroIDBuiltinCall(mlir::Location loc, if (!builtin) { fnOp = cgm.createCIRBuiltinFunction( loc, cgm.builtinCoroId, - cir::FuncType::get({int32Ty, VoidPtrTy, VoidPtrTy, VoidPtrTy}, int32Ty), + cir::FuncType::get({int32Ty, voidPtrTy, voidPtrTy, voidPtrTy}, int32Ty), /*FD=*/nullptr); assert(fnOp && "should always succeed"); } else { @@ -75,7 +75,7 @@ cir::CallOp CIRGenFunction::emitCoroAllocBuiltinCall(mlir::Location loc) { cir::FuncOp fnOp; if (!builtin) { fnOp = cgm.createCIRBuiltinFunction(loc, cgm.builtinCoroAlloc, - cir::FuncType::get({UInt32Ty}, boolTy), + cir::FuncType::get({uInt32Ty}, boolTy), /*fd=*/nullptr); assert(fnOp && "should always succeed"); } else { @@ -95,7 +95,7 @@ CIRGenFunction::emitCoroBeginBuiltinCall(mlir::Location loc, if (!builtin) { fnOp = cgm.createCIRBuiltinFunction( loc, cgm.builtinCoroBegin, - cir::FuncType::get({UInt32Ty, VoidPtrTy}, VoidPtrTy), + cir::FuncType::get({uInt32Ty, voidPtrTy}, voidPtrTy), /*fd=*/nullptr); assert(fnOp && "should always succeed"); } else { @@ -110,7 +110,7 @@ CIRGenFunction::emitCoroBeginBuiltinCall(mlir::Location loc, mlir::LogicalResult CIRGenFunction::emitCoroutineBody(const CoroutineBodyStmt &s) { mlir::Location openCurlyLoc = getLoc(s.getBeginLoc()); - cir::ConstantOp nullPtrCst = builder.getNullPtr(VoidPtrTy, openCurlyLoc); + cir::ConstantOp nullPtrCst = builder.getNullPtr(voidPtrTy, openCurlyLoc); auto fn = mlir::cast<cir::FuncOp>(curFn); fn.setCoroutine(true); diff --git a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp index 5667273..aeea0ef 100644 --- a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp @@ -80,13 +80,13 @@ CIRGenFunction::emitAutoVarAlloca(const VarDecl &d, assert(!cir::MissingFeatures::openMP()); if (!didCallStackSave) { // Save the stack. - cir::PointerType defaultTy = AllocaInt8PtrTy; + cir::PointerType defaultTy = allocaInt8PtrTy; CharUnits align = CharUnits::fromQuantity( cgm.getDataLayout().getAlignment(defaultTy, false)); Address stack = createTempAlloca(defaultTy, align, loc, "saved_stack"); mlir::Value v = builder.createStackSave(loc, defaultTy); - assert(v.getType() == AllocaInt8PtrTy); + assert(v.getType() == allocaInt8PtrTy); builder.createStore(loc, v, stack); didCallStackSave = true; diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp index df6ee56..5ccb431 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp @@ -2529,7 +2529,7 @@ CIRGenFunction::emitConditionalBlocks(const AbstractConditionalOperator *e, // If both arms are void, so be it. if (!yieldTy) - yieldTy = VoidTy; + yieldTy = voidTy; // Insert required yields. for (mlir::OpBuilder::InsertPoint &toInsert : insertPoints) { diff --git a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp index 8fe0d9b4..3d3030c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprAggregate.cpp @@ -490,7 +490,7 @@ void AggExprEmitter::emitArrayInit(Address destPtr, cir::ArrayType arrayTy, for (uint64_t i = 0; i != numInitElements; ++i) { // Advance to the next element. if (i > 0) { - one = builder.getConstantInt(loc, cgf.PtrDiffTy, i); + one = builder.getConstantInt(loc, cgf.ptrDiffTy, i); element = builder.createPtrStride(loc, begin, one); } @@ -512,7 +512,7 @@ void AggExprEmitter::emitArrayInit(Address destPtr, cir::ArrayType arrayTy, cgf.getTypes().isZeroInitializable(elementType))) { // Advance to the start of the rest of the array. if (numInitElements) { - one = builder.getConstantInt(loc, cgf.PtrDiffTy, 1); + one = builder.getConstantInt(loc, cgf.ptrDiffTy, 1); element = cir::PtrStrideOp::create(builder, loc, cirElementPtrType, element, one); } @@ -526,7 +526,7 @@ void AggExprEmitter::emitArrayInit(Address destPtr, cir::ArrayType arrayTy, // Compute the end of array cir::ConstantOp numArrayElementsConst = builder.getConstInt( - loc, mlir::cast<cir::IntType>(cgf.PtrDiffTy), numArrayElements); + loc, mlir::cast<cir::IntType>(cgf.ptrDiffTy), numArrayElements); mlir::Value end = cir::PtrStrideOp::create(builder, loc, cirElementPtrType, begin, numArrayElementsConst); @@ -563,7 +563,7 @@ void AggExprEmitter::emitArrayInit(Address destPtr, cir::ArrayType arrayTy, // Advance pointer and store them to temporary variable cir::ConstantOp one = builder.getConstInt( - loc, mlir::cast<cir::IntType>(cgf.PtrDiffTy), 1); + loc, mlir::cast<cir::IntType>(cgf.ptrDiffTy), 1); auto nextElement = cir::PtrStrideOp::create( builder, loc, cirElementPtrType, currentElement, one); cgf.emitStoreThroughLValue(RValue::get(nextElement), tmpLV); diff --git a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp index 7a35382..9dd9b6d 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprCXX.cpp @@ -257,12 +257,12 @@ static mlir::Value emitCXXNewAllocSize(CIRGenFunction &cgf, const CXXNewExpr *e, if (!e->isArray()) { CharUnits typeSize = cgf.getContext().getTypeSizeInChars(type); sizeWithoutCookie = cgf.getBuilder().getConstant( - loc, cir::IntAttr::get(cgf.SizeTy, typeSize.getQuantity())); + loc, cir::IntAttr::get(cgf.sizeTy, typeSize.getQuantity())); return sizeWithoutCookie; } // The width of size_t. - unsigned sizeWidth = cgf.cgm.getDataLayout().getTypeSizeInBits(cgf.SizeTy); + unsigned sizeWidth = cgf.cgm.getDataLayout().getTypeSizeInBits(cgf.sizeTy); // The number of elements can be have an arbitrary integer type; // essentially, we need to multiply it by a constant factor, add a diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp index 928e5aa..6af87a0 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp @@ -46,7 +46,7 @@ namespace { class ConstExprEmitter; static mlir::TypedAttr computePadding(CIRGenModule &cgm, CharUnits size) { - mlir::Type eltTy = cgm.UCharTy; + mlir::Type eltTy = cgm.uCharTy; clang::CharUnits::QuantityType arSize = size.getQuantity(); CIRGenBuilderTy &bld = cgm.getBuilder(); if (size > CharUnits::One()) { diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index db6878d..119314f 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -762,9 +762,9 @@ public: // FIXME(cir): For now lets pretend we shouldn't use the conversion // intrinsics and insert a cast here unconditionally. src = builder.createCast(cgf.getLoc(loc), cir::CastKind::floating, src, - cgf.FloatTy); + cgf.floatTy); srcType = cgf.getContext().FloatTy; - mlirSrcType = cgf.FloatTy; + mlirSrcType = cgf.floatTy; } } @@ -1738,7 +1738,7 @@ mlir::Value ScalarExprEmitter::emitSub(const BinOpInfo &ops) { // // See more in `EmitSub` in CGExprScalar.cpp. assert(!cir::MissingFeatures::llvmLoweringPtrDiffConsidersPointee()); - return cir::PtrDiffOp::create(builder, cgf.getLoc(ops.loc), cgf.PtrDiffTy, + return cir::PtrDiffOp::create(builder, cgf.getLoc(ops.loc), cgf.ptrDiffTy, ops.lhs, ops.rhs); } @@ -2220,7 +2220,7 @@ mlir::Value ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr( "sizeof operator for VariableArrayType", e->getStmtClassName()); return builder.getConstant( - loc, cir::IntAttr::get(cgf.cgm.UInt64Ty, + loc, cir::IntAttr::get(cgf.cgm.uInt64Ty, llvm::APSInt(llvm::APInt(64, 1), true))); } } else if (e->getKind() == UETT_OpenMPRequiredSimdAlign) { @@ -2228,12 +2228,12 @@ mlir::Value ScalarExprEmitter::VisitUnaryExprOrTypeTraitExpr( e->getSourceRange(), "sizeof operator for OpenMpRequiredSimdAlign", e->getStmtClassName()); return builder.getConstant( - loc, cir::IntAttr::get(cgf.cgm.UInt64Ty, + loc, cir::IntAttr::get(cgf.cgm.uInt64Ty, llvm::APSInt(llvm::APInt(64, 1), true))); } return builder.getConstant( - loc, cir::IntAttr::get(cgf.cgm.UInt64Ty, + loc, cir::IntAttr::get(cgf.cgm.uInt64Ty, e->EvaluateKnownConstInt(cgf.getContext()))); } @@ -2329,14 +2329,14 @@ mlir::Value ScalarExprEmitter::VisitAbstractConditionalOperator( mlir::Value lhs = Visit(lhsExpr); if (!lhs) { - lhs = builder.getNullValue(cgf.VoidTy, loc); + lhs = builder.getNullValue(cgf.voidTy, loc); lhsIsVoid = true; } mlir::Value rhs = Visit(rhsExpr); if (lhsIsVoid) { assert(!rhs && "lhs and rhs types must match"); - rhs = builder.getNullValue(cgf.VoidTy, loc); + rhs = builder.getNullValue(cgf.voidTy, loc); } return builder.createSelect(loc, condV, lhs, rhs); @@ -2381,7 +2381,7 @@ mlir::Value ScalarExprEmitter::VisitAbstractConditionalOperator( if (!insertPoints.empty()) { // If both arms are void, so be it. if (!yieldTy) - yieldTy = cgf.VoidTy; + yieldTy = cgf.voidTy; // Insert required yields. for (mlir::OpBuilder::InsertPoint &toInsert : insertPoints) { diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp index 58feb36..71ff20a 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.cpp @@ -1008,7 +1008,7 @@ CIRGenFunction::emitArrayLength(const clang::ArrayType *origArrayType, if (isa<VariableArrayType>(arrayType)) { assert(cir::MissingFeatures::vlas()); cgm.errorNYI(*currSrcLoc, "VLAs"); - return builder.getConstInt(*currSrcLoc, SizeTy, 0); + return builder.getConstInt(*currSrcLoc, sizeTy, 0); } uint64_t countFromCLAs = 1; @@ -1037,7 +1037,7 @@ CIRGenFunction::emitArrayLength(const clang::ArrayType *origArrayType, } baseType = eltType; - return builder.getConstInt(*currSrcLoc, SizeTy, countFromCLAs); + return builder.getConstInt(*currSrcLoc, sizeTy, countFromCLAs); } mlir::Value CIRGenFunction::emitAlignmentAssumption( @@ -1074,7 +1074,7 @@ CIRGenFunction::getVLASize(const VariableArrayType *type) { elementType = type->getElementType(); mlir::Value vlaSize = vlaSizeMap[type->getSizeExpr()]; assert(vlaSize && "no size for VLA!"); - assert(vlaSize.getType() == SizeTy); + assert(vlaSize.getType() == sizeTy); if (!numElements) { numElements = vlaSize; @@ -1188,7 +1188,7 @@ void CIRGenFunction::emitVariablyModifiedType(QualType type) { // Always zexting here would be wrong if it weren't // undefined behavior to have a negative bound. // FIXME: What about when size's type is larger than size_t? - entry = builder.createIntCast(size, SizeTy); + entry = builder.createIntCast(size, sizeTy); } } type = vat->getElementType(); diff --git a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp index 88fedf1..f603f5ec 100644 --- a/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenItaniumCXXABI.cpp @@ -1846,13 +1846,13 @@ mlir::Value CIRGenItaniumCXXABI::getVirtualBaseClassOffset( const CXXRecordDecl *classDecl, const CXXRecordDecl *baseClassDecl) { CIRGenBuilderTy &builder = cgf.getBuilder(); mlir::Value vtablePtr = cgf.getVTablePtr(loc, thisAddr, classDecl); - mlir::Value vtableBytePtr = builder.createBitcast(vtablePtr, cgm.UInt8PtrTy); + mlir::Value vtableBytePtr = builder.createBitcast(vtablePtr, cgm.uInt8PtrTy); CharUnits vbaseOffsetOffset = cgm.getItaniumVTableContext().getVirtualBaseOffsetOffset(classDecl, baseClassDecl); mlir::Value offsetVal = builder.getSInt64(vbaseOffsetOffset.getQuantity(), loc); - auto vbaseOffsetPtr = cir::PtrStrideOp::create(builder, loc, cgm.UInt8PtrTy, + auto vbaseOffsetPtr = cir::PtrStrideOp::create(builder, loc, cgm.uInt8PtrTy, vtableBytePtr, offsetVal); mlir::Value vbaseOffset; @@ -1861,9 +1861,9 @@ mlir::Value CIRGenItaniumCXXABI::getVirtualBaseClassOffset( cgm.errorNYI(loc, "getVirtualBaseClassOffset: relative layout"); } else { mlir::Value offsetPtr = builder.createBitcast( - vbaseOffsetPtr, builder.getPointerTo(cgm.PtrDiffTy)); + vbaseOffsetPtr, builder.getPointerTo(cgm.ptrDiffTy)); vbaseOffset = builder.createLoad( - loc, Address(offsetPtr, cgm.PtrDiffTy, cgf.getPointerAlign())); + loc, Address(offsetPtr, cgm.ptrDiffTy, cgf.getPointerAlign())); } return vbaseOffset; } @@ -2244,7 +2244,7 @@ Address CIRGenItaniumCXXABI::initializeArrayCookie(CIRGenFunction &cgf, // Write the number of elements into the appropriate slot. Address numElementsPtr = - cookiePtr.withElementType(cgf.getBuilder(), cgf.SizeTy); + cookiePtr.withElementType(cgf.getBuilder(), cgf.sizeTy); cgf.getBuilder().createStore(loc, numElements, numElementsPtr); // Finally, compute a pointer to the actual data buffer by skipping diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 46adfe2..9f9b2db 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -67,28 +67,28 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext, abi(createCXXABI(*this)), genTypes(*this), vtables(*this) { // Initialize cached types - VoidTy = cir::VoidType::get(&getMLIRContext()); - VoidPtrTy = cir::PointerType::get(VoidTy); - SInt8Ty = cir::IntType::get(&getMLIRContext(), 8, /*isSigned=*/true); - SInt16Ty = cir::IntType::get(&getMLIRContext(), 16, /*isSigned=*/true); - SInt32Ty = cir::IntType::get(&getMLIRContext(), 32, /*isSigned=*/true); - SInt64Ty = cir::IntType::get(&getMLIRContext(), 64, /*isSigned=*/true); - SInt128Ty = cir::IntType::get(&getMLIRContext(), 128, /*isSigned=*/true); - UInt8Ty = cir::IntType::get(&getMLIRContext(), 8, /*isSigned=*/false); - UInt8PtrTy = cir::PointerType::get(UInt8Ty); + voidTy = cir::VoidType::get(&getMLIRContext()); + voidPtrTy = cir::PointerType::get(voidTy); + sInt8Ty = cir::IntType::get(&getMLIRContext(), 8, /*isSigned=*/true); + sInt16Ty = cir::IntType::get(&getMLIRContext(), 16, /*isSigned=*/true); + sInt32Ty = cir::IntType::get(&getMLIRContext(), 32, /*isSigned=*/true); + sInt64Ty = cir::IntType::get(&getMLIRContext(), 64, /*isSigned=*/true); + sInt128Ty = cir::IntType::get(&getMLIRContext(), 128, /*isSigned=*/true); + uInt8Ty = cir::IntType::get(&getMLIRContext(), 8, /*isSigned=*/false); + uInt8PtrTy = cir::PointerType::get(uInt8Ty); cirAllocaAddressSpace = getTargetCIRGenInfo().getCIRAllocaAddressSpace(); - UInt16Ty = cir::IntType::get(&getMLIRContext(), 16, /*isSigned=*/false); - UInt32Ty = cir::IntType::get(&getMLIRContext(), 32, /*isSigned=*/false); - UInt64Ty = cir::IntType::get(&getMLIRContext(), 64, /*isSigned=*/false); - UInt128Ty = cir::IntType::get(&getMLIRContext(), 128, /*isSigned=*/false); - FP16Ty = cir::FP16Type::get(&getMLIRContext()); - BFloat16Ty = cir::BF16Type::get(&getMLIRContext()); - FloatTy = cir::SingleType::get(&getMLIRContext()); - DoubleTy = cir::DoubleType::get(&getMLIRContext()); - FP80Ty = cir::FP80Type::get(&getMLIRContext()); - FP128Ty = cir::FP128Type::get(&getMLIRContext()); - - AllocaInt8PtrTy = cir::PointerType::get(UInt8Ty, cirAllocaAddressSpace); + uInt16Ty = cir::IntType::get(&getMLIRContext(), 16, /*isSigned=*/false); + uInt32Ty = cir::IntType::get(&getMLIRContext(), 32, /*isSigned=*/false); + uInt64Ty = cir::IntType::get(&getMLIRContext(), 64, /*isSigned=*/false); + uInt128Ty = cir::IntType::get(&getMLIRContext(), 128, /*isSigned=*/false); + fP16Ty = cir::FP16Type::get(&getMLIRContext()); + bFloat16Ty = cir::BF16Type::get(&getMLIRContext()); + floatTy = cir::SingleType::get(&getMLIRContext()); + doubleTy = cir::DoubleType::get(&getMLIRContext()); + fP80Ty = cir::FP80Type::get(&getMLIRContext()); + fP128Ty = cir::FP128Type::get(&getMLIRContext()); + + allocaInt8PtrTy = cir::PointerType::get(uInt8Ty, cirAllocaAddressSpace); PointerAlignInBytes = astContext @@ -97,16 +97,16 @@ CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext, .getQuantity(); const unsigned charSize = astContext.getTargetInfo().getCharWidth(); - UCharTy = cir::IntType::get(&getMLIRContext(), charSize, /*isSigned=*/false); + uCharTy = cir::IntType::get(&getMLIRContext(), charSize, /*isSigned=*/false); // TODO(CIR): Should be updated once TypeSizeInfoAttr is upstreamed const unsigned sizeTypeSize = astContext.getTypeSize(astContext.getSignedSizeType()); SizeSizeInBytes = astContext.toCharUnitsFromBits(sizeTypeSize).getQuantity(); // In CIRGenTypeCache, UIntPtrTy and SizeType are fields of the same union - UIntPtrTy = + uIntPtrTy = cir::IntType::get(&getMLIRContext(), sizeTypeSize, /*isSigned=*/false); - PtrDiffTy = + ptrDiffTy = cir::IntType::get(&getMLIRContext(), sizeTypeSize, /*isSigned=*/true); std::optional<cir::SourceLanguage> sourceLanguage = getCIRSourceLanguage(); diff --git a/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp b/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp index be063033..890f8a6 100644 --- a/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenOpenACCRecipe.cpp @@ -617,11 +617,11 @@ void OpenACCRecipeBuilderBase::createReductionRecipeCombiner( if (const auto *cat = cgf.getContext().getAsConstantArrayType(origType)) { // If we're in an array, we have to emit the combiner for each element of // the array. - auto itrTy = mlir::cast<cir::IntType>(cgf.PtrDiffTy); + auto itrTy = mlir::cast<cir::IntType>(cgf.ptrDiffTy); auto itrPtrTy = cir::PointerType::get(itrTy); mlir::Value zero = - builder.getConstInt(loc, mlir::cast<cir::IntType>(cgf.PtrDiffTy), 0); + builder.getConstInt(loc, mlir::cast<cir::IntType>(cgf.ptrDiffTy), 0); mlir::Value itr = cir::AllocaOp::create(builder, loc, itrPtrTy, itrTy, "itr", cgf.cgm.getSize(cgf.getPointerAlign())); @@ -633,7 +633,7 @@ void OpenACCRecipeBuilderBase::createReductionRecipeCombiner( [&](mlir::OpBuilder &b, mlir::Location loc) { auto loadItr = cir::LoadOp::create(builder, loc, {itr}); mlir::Value arraySize = builder.getConstInt( - loc, mlir::cast<cir::IntType>(cgf.PtrDiffTy), cat->getZExtSize()); + loc, mlir::cast<cir::IntType>(cgf.ptrDiffTy), cat->getZExtSize()); auto cmp = builder.createCompare(loc, cir::CmpOpKind::lt, loadItr, arraySize); builder.createCondition(cmp); diff --git a/clang/lib/CIR/CodeGen/CIRGenTypeCache.h b/clang/lib/CIR/CodeGen/CIRGenTypeCache.h index ff5842c..0f63e91 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTypeCache.h +++ b/clang/lib/CIR/CodeGen/CIRGenTypeCache.h @@ -26,47 +26,47 @@ struct CIRGenTypeCache { CIRGenTypeCache() {} // ClangIR void type - cir::VoidType VoidTy; + cir::VoidType voidTy; // ClangIR signed integral types of common sizes - cir::IntType SInt8Ty; - cir::IntType SInt16Ty; - cir::IntType SInt32Ty; - cir::IntType SInt64Ty; - cir::IntType SInt128Ty; + cir::IntType sInt8Ty; + cir::IntType sInt16Ty; + cir::IntType sInt32Ty; + cir::IntType sInt64Ty; + cir::IntType sInt128Ty; // ClangIR unsigned integral type of common sizes - cir::IntType UInt8Ty; - cir::IntType UInt16Ty; - cir::IntType UInt32Ty; - cir::IntType UInt64Ty; - cir::IntType UInt128Ty; + cir::IntType uInt8Ty; + cir::IntType uInt16Ty; + cir::IntType uInt32Ty; + cir::IntType uInt64Ty; + cir::IntType uInt128Ty; // ClangIR floating-point types with fixed formats - cir::FP16Type FP16Ty; - cir::BF16Type BFloat16Ty; - cir::SingleType FloatTy; - cir::DoubleType DoubleTy; - cir::FP80Type FP80Ty; - cir::FP128Type FP128Ty; + cir::FP16Type fP16Ty; + cir::BF16Type bFloat16Ty; + cir::SingleType floatTy; + cir::DoubleType doubleTy; + cir::FP80Type fP80Ty; + cir::FP128Type fP128Ty; /// ClangIR char - mlir::Type UCharTy; + mlir::Type uCharTy; /// intptr_t, size_t, and ptrdiff_t, which we assume are the same size. union { - mlir::Type UIntPtrTy; - mlir::Type SizeTy; + mlir::Type uIntPtrTy; + mlir::Type sizeTy; }; - mlir::Type PtrDiffTy; + mlir::Type ptrDiffTy; /// void* in address space 0 - cir::PointerType VoidPtrTy; - cir::PointerType UInt8PtrTy; + cir::PointerType voidPtrTy; + cir::PointerType uInt8PtrTy; /// void* in alloca address space - cir::PointerType AllocaInt8PtrTy; + cir::PointerType allocaInt8PtrTy; /// The size and alignment of a pointer into the generic address space. union { diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp index d1b91d0..03618d4 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp @@ -71,7 +71,7 @@ mlir::Type CIRGenTypes::convertFunctionTypeInternal(QualType qft) { if (!isFuncTypeConvertible(ft)) { cgm.errorNYI(SourceLocation(), "function type involving an incomplete type", qft); - return cir::FuncType::get(SmallVector<mlir::Type, 1>{}, cgm.VoidTy); + return cir::FuncType::get(SmallVector<mlir::Type, 1>{}, cgm.voidTy); } const CIRGenFunctionInfo *fi; @@ -298,7 +298,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) { switch (cast<BuiltinType>(ty)->getKind()) { // void case BuiltinType::Void: - resultType = cgm.VoidTy; + resultType = cgm.voidTy; break; // bool @@ -338,42 +338,42 @@ mlir::Type CIRGenTypes::convertType(QualType type) { // Floating-point types case BuiltinType::Float16: - resultType = cgm.FP16Ty; + resultType = cgm.fP16Ty; break; case BuiltinType::Half: if (astContext.getLangOpts().NativeHalfType || !astContext.getTargetInfo().useFP16ConversionIntrinsics()) { - resultType = cgm.FP16Ty; + resultType = cgm.fP16Ty; } else { cgm.errorNYI(SourceLocation(), "processing of built-in type", type); - resultType = cgm.SInt32Ty; + resultType = cgm.sInt32Ty; } break; case BuiltinType::BFloat16: - resultType = cgm.BFloat16Ty; + resultType = cgm.bFloat16Ty; break; case BuiltinType::Float: assert(&astContext.getFloatTypeSemantics(type) == &llvm::APFloat::IEEEsingle() && "ClangIR NYI: 'float' in a format other than IEEE 32-bit"); - resultType = cgm.FloatTy; + resultType = cgm.floatTy; break; case BuiltinType::Double: assert(&astContext.getFloatTypeSemantics(type) == &llvm::APFloat::IEEEdouble() && "ClangIR NYI: 'double' in a format other than IEEE 64-bit"); - resultType = cgm.DoubleTy; + resultType = cgm.doubleTy; break; case BuiltinType::LongDouble: resultType = builder.getLongDoubleTy(astContext.getFloatTypeSemantics(type)); break; case BuiltinType::Float128: - resultType = cgm.FP128Ty; + resultType = cgm.fP128Ty; break; case BuiltinType::Ibm128: cgm.errorNYI(SourceLocation(), "processing of built-in type", type); - resultType = cgm.SInt32Ty; + resultType = cgm.sInt32Ty; break; case BuiltinType::NullPtr: @@ -386,7 +386,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) { default: cgm.errorNYI(SourceLocation(), "processing of built-in type", type); - resultType = cgm.SInt32Ty; + resultType = cgm.sInt32Ty; break; } break; @@ -439,7 +439,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) { // int X[] -> [0 x int], unless the element type is not sized. If it is // unsized (e.g. an incomplete record) just use [0 x i8]. if (!cir::isSized(elemTy)) { - elemTy = cgm.SInt8Ty; + elemTy = cgm.sInt8Ty; } resultType = cir::ArrayType::get(elemTy, 0); @@ -454,7 +454,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) { // i8 just to have a concrete type" if (!cir::isSized(elemTy)) { cgm.errorNYI(SourceLocation(), "arrays of undefined struct type", type); - resultType = cgm.UInt32Ty; + resultType = cgm.uInt32Ty; break; } @@ -477,7 +477,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) { // Return a placeholder 'i32' type. This can be changed later when the // type is defined (see UpdateCompletedType), but is likely to be the // "right" answer. - resultType = cgm.UInt32Ty; + resultType = cgm.uInt32Ty; break; } @@ -490,7 +490,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) { const auto *bitIntTy = cast<BitIntType>(type); if (bitIntTy->getNumBits() > cir::IntType::maxBitwidth()) { cgm.errorNYI(SourceLocation(), "large _BitInt type", type); - resultType = cgm.SInt32Ty; + resultType = cgm.sInt32Ty; } else { resultType = cir::IntType::get(&getMLIRContext(), bitIntTy->getNumBits(), bitIntTy->isSigned()); @@ -515,7 +515,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) { default: cgm.errorNYI(SourceLocation(), "processing of type", type->getTypeClassName()); - resultType = cgm.SInt32Ty; + resultType = cgm.sInt32Ty; break; } diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index 2d2ef42..7ba03ce 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -286,14 +286,14 @@ void cir::ConditionOp::getSuccessorRegions( // Parent is a loop: condition may branch to the body or to the parent op. if (auto loopOp = dyn_cast<LoopOpInterface>(getOperation()->getParentOp())) { regions.emplace_back(&loopOp.getBody(), loopOp.getBody().getArguments()); - regions.emplace_back(loopOp->getResults()); + regions.emplace_back(getOperation(), loopOp->getResults()); } assert(!cir::MissingFeatures::awaitOp()); } MutableOperandRange -cir::ConditionOp::getMutableSuccessorOperands(RegionBranchPoint point) { +cir::ConditionOp::getMutableSuccessorOperands(RegionSuccessor point) { // No values are yielded to the successor region. return MutableOperandRange(getOperation(), 0, 0); } @@ -989,7 +989,8 @@ void cir::IfOp::getSuccessorRegions(mlir::RegionBranchPoint point, SmallVectorImpl<RegionSuccessor> ®ions) { // The `then` and the `else` region branch back to the parent operation. if (!point.isParent()) { - regions.push_back(RegionSuccessor()); + regions.push_back( + RegionSuccessor(getOperation(), getOperation()->getResults())); return; } @@ -1039,7 +1040,7 @@ void cir::ScopeOp::getSuccessorRegions( mlir::RegionBranchPoint point, SmallVectorImpl<RegionSuccessor> ®ions) { // The only region always branch back to the parent operation. if (!point.isParent()) { - regions.push_back(RegionSuccessor(getODSResults(0))); + regions.push_back(RegionSuccessor(getOperation(), getODSResults(0))); return; } @@ -1124,7 +1125,8 @@ Block *cir::BrCondOp::getSuccessorForOperands(ArrayRef<Attribute> operands) { void cir::CaseOp::getSuccessorRegions( mlir::RegionBranchPoint point, SmallVectorImpl<RegionSuccessor> ®ions) { if (!point.isParent()) { - regions.push_back(RegionSuccessor()); + regions.push_back( + RegionSuccessor(getOperation(), getOperation()->getResults())); return; } regions.push_back(RegionSuccessor(&getCaseRegion())); @@ -1188,7 +1190,8 @@ static void printSwitchOp(OpAsmPrinter &p, cir::SwitchOp op, void cir::SwitchOp::getSuccessorRegions( mlir::RegionBranchPoint point, SmallVectorImpl<RegionSuccessor> ®ion) { if (!point.isParent()) { - region.push_back(RegionSuccessor()); + region.push_back( + RegionSuccessor(getOperation(), getOperation()->getResults())); return; } @@ -1402,7 +1405,8 @@ void cir::GlobalOp::getSuccessorRegions( mlir::RegionBranchPoint point, SmallVectorImpl<RegionSuccessor> ®ions) { // The `ctor` and `dtor` regions always branch back to the parent operation. if (!point.isParent()) { - regions.push_back(RegionSuccessor()); + regions.push_back( + RegionSuccessor(getOperation(), getOperation()->getResults())); return; } @@ -1961,7 +1965,7 @@ void cir::TernaryOp::getSuccessorRegions( mlir::RegionBranchPoint point, SmallVectorImpl<RegionSuccessor> ®ions) { // The `true` and the `false` region branch back to the parent operation. if (!point.isParent()) { - regions.push_back(RegionSuccessor(this->getODSResults(0))); + regions.push_back(RegionSuccessor(getOperation(), this->getODSResults(0))); return; } @@ -2978,7 +2982,8 @@ void cir::TryOp::getSuccessorRegions( llvm::SmallVectorImpl<mlir::RegionSuccessor> ®ions) { // The `try` and the `catchers` region branch back to the parent operation. if (!point.isParent()) { - regions.push_back(mlir::RegionSuccessor()); + regions.push_back( + RegionSuccessor(getOperation(), getOperation()->getResults())); return; } diff --git a/clang/lib/CIR/Interfaces/CIRLoopOpInterface.cpp b/clang/lib/CIR/Interfaces/CIRLoopOpInterface.cpp index 0ce5017..6de51f12 100644 --- a/clang/lib/CIR/Interfaces/CIRLoopOpInterface.cpp +++ b/clang/lib/CIR/Interfaces/CIRLoopOpInterface.cpp @@ -17,7 +17,7 @@ namespace cir { void LoopOpInterface::getLoopOpSuccessorRegions( LoopOpInterface op, mlir::RegionBranchPoint point, llvm::SmallVectorImpl<mlir::RegionSuccessor> ®ions) { - assert(point.isParent() || point.getRegionOrNull()); + assert(point.isParent() || point.getTerminatorPredecessorOrNull()); // Branching to first region: go to condition or body (do-while). if (point.isParent()) { @@ -25,15 +25,18 @@ void LoopOpInterface::getLoopOpSuccessorRegions( return; } + mlir::Region *parentRegion = + point.getTerminatorPredecessorOrNull()->getParentRegion(); + // Branching from condition: go to body or exit. - if (&op.getCond() == point.getRegionOrNull()) { - regions.emplace_back(mlir::RegionSuccessor(op->getResults())); + if (&op.getCond() == parentRegion) { + regions.emplace_back(mlir::RegionSuccessor(op, op->getResults())); regions.emplace_back(&op.getBody(), op.getBody().getArguments()); return; } // Branching from body: go to step (for) or condition. - if (&op.getBody() == point.getRegionOrNull()) { + if (&op.getBody() == parentRegion) { // FIXME(cir): Should we consider break/continue statements here? mlir::Region *afterBody = (op.maybeGetStep() ? op.maybeGetStep() : &op.getCond()); @@ -42,7 +45,7 @@ void LoopOpInterface::getLoopOpSuccessorRegions( } // Branching from step: go to condition. - if (op.maybeGetStep() == point.getRegionOrNull()) { + if (op.maybeGetStep() == parentRegion) { regions.emplace_back(&op.getCond(), op.getCond().getArguments()); return; } diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 6af8066..07a2cfb 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -1174,14 +1174,13 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) { } llvm::DIType *CGDebugInfo::CreateType(const BitIntType *Ty) { - StringRef Name = Ty->isUnsigned() ? "unsigned _BitInt" : "_BitInt"; llvm::dwarf::TypeKind Encoding = Ty->isUnsigned() ? llvm::dwarf::DW_ATE_unsigned : llvm::dwarf::DW_ATE_signed; - return DBuilder.createBasicType(Name, CGM.getContext().getTypeSize(Ty), - Encoding); + Encoding, llvm::DINode::FlagZero, 0, + Ty->getNumBits()); } llvm::DIType *CGDebugInfo::CreateType(const ComplexType *Ty) { diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 301d577..01f2161 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -2297,9 +2297,13 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr, CGM.getABIInfo().getOptimalVectorMemoryType(VecTy, getLangOpts()); if (!ClangVecTy->isPackedVectorBoolType(getContext()) && VecTy != NewVecTy) { - SmallVector<int, 16> Mask(NewVecTy->getNumElements(), -1); + SmallVector<int, 16> Mask(NewVecTy->getNumElements(), + VecTy->getNumElements()); std::iota(Mask.begin(), Mask.begin() + VecTy->getNumElements(), 0); - Value = Builder.CreateShuffleVector(Value, Mask, "extractVec"); + // Use undef instead of poison for the padding lanes, to make sure no + // padding bits are poisoned, which may break coercion. + Value = Builder.CreateShuffleVector(Value, llvm::UndefValue::get(VecTy), + Mask, "extractVec"); SrcTy = NewVecTy; } if (Addr.getElementType() != SrcTy) diff --git a/clang/lib/CodeGen/CGHLSLBuiltins.cpp b/clang/lib/CodeGen/CGHLSLBuiltins.cpp index 384bd59..fbf4a57 100644 --- a/clang/lib/CodeGen/CGHLSLBuiltins.cpp +++ b/clang/lib/CodeGen/CGHLSLBuiltins.cpp @@ -206,7 +206,7 @@ static Intrinsic::ID getWaveActiveSumIntrinsic(llvm::Triple::ArchType Arch, } } -// Return wave active sum that corresponds to the QT scalar type +// Return wave active max that corresponds to the QT scalar type static Intrinsic::ID getWaveActiveMaxIntrinsic(llvm::Triple::ArchType Arch, CGHLSLRuntime &RT, QualType QT) { switch (Arch) { @@ -225,6 +225,25 @@ static Intrinsic::ID getWaveActiveMaxIntrinsic(llvm::Triple::ArchType Arch, } } +// Return wave active min that corresponds to the QT scalar type +static Intrinsic::ID getWaveActiveMinIntrinsic(llvm::Triple::ArchType Arch, + CGHLSLRuntime &RT, QualType QT) { + switch (Arch) { + case llvm::Triple::spirv: + if (QT->isUnsignedIntegerType()) + return Intrinsic::spv_wave_reduce_umin; + return Intrinsic::spv_wave_reduce_min; + case llvm::Triple::dxil: { + if (QT->isUnsignedIntegerType()) + return Intrinsic::dx_wave_reduce_umin; + return Intrinsic::dx_wave_reduce_min; + } + default: + llvm_unreachable("Intrinsic WaveActiveMin" + " not supported by target architecture"); + } +} + // Returns the mangled name for a builtin function that the SPIR-V backend // will expand into a spec Constant. static std::string getSpecConstantFunctionName(clang::QualType SpecConstantType, @@ -742,6 +761,17 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID, &CGM.getModule(), IID, {OpExpr->getType()}), ArrayRef{OpExpr}, "hlsl.wave.active.max"); } + case Builtin::BI__builtin_hlsl_wave_active_min: { + // Due to the use of variadic arguments, explicitly retreive argument + Value *OpExpr = EmitScalarExpr(E->getArg(0)); + Intrinsic::ID IID = getWaveActiveMinIntrinsic( + getTarget().getTriple().getArch(), CGM.getHLSLRuntime(), + E->getArg(0)->getType()); + + return EmitRuntimeCall(Intrinsic::getOrInsertDeclaration( + &CGM.getModule(), IID, {OpExpr->getType()}), + ArrayRef{OpExpr}, "hlsl.wave.active.min"); + } case Builtin::BI__builtin_hlsl_wave_get_lane_index: { // We don't define a SPIR-V intrinsic, instead it is a SPIR-V built-in // defined in SPIRVBuiltins.td. So instead we manually get the matching name diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 40ea513..71c5280 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -308,9 +308,18 @@ InputArgList Driver::ParseArgStrings(ArrayRef<const char *> ArgStrings, auto ArgString = A->getAsString(Args); std::string Nearest; if (getOpts().findNearest(ArgString, Nearest, VisibilityMask) > 1) { - if (!IsCLMode() && - getOpts().findExact(ArgString, Nearest, - llvm::opt::Visibility(options::CC1Option))) { + if (IsFlangMode()) { + if (getOpts().findExact(ArgString, Nearest, + llvm::opt::Visibility(options::FC1Option))) { + DiagID = diag::err_drv_unknown_argument_with_suggestion; + Diags.Report(DiagID) << ArgString << "-Xflang " + Nearest; + } else { + DiagID = diag::err_drv_unknown_argument; + Diags.Report(DiagID) << ArgString; + } + } else if (!IsCLMode() && getOpts().findExact(ArgString, Nearest, + llvm::opt::Visibility( + options::CC1Option))) { DiagID = diag::err_drv_unknown_argument_with_suggestion; Diags.Report(DiagID) << ArgString << "-Xclang " + Nearest; } else { diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 79edc56..4e8f63e 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1414,17 +1414,18 @@ static void CollectARMPACBTIOptions(const ToolChain &TC, const ArgList &Args, GuardedControlStack = PBP.GuardedControlStack; } - bool HasPtrauthReturns = llvm::any_of(CmdArgs, [](const char *Arg) { - return StringRef(Arg) == "-fptrauth-returns"; - }); + Arg *PtrauthReturnsArg = Args.getLastArg(options::OPT_fptrauth_returns, + options::OPT_fno_ptrauth_returns); + bool HasPtrauthReturns = + PtrauthReturnsArg && + PtrauthReturnsArg->getOption().matches(options::OPT_fptrauth_returns); // GCS is currently untested with ptrauth-returns, but enabling this could be // allowed in future after testing with a suitable system. - if (HasPtrauthReturns && - (Scope != "none" || BranchProtectionPAuthLR || GuardedControlStack)) { + if (Scope != "none" || BranchProtectionPAuthLR || GuardedControlStack) { if (Triple.getEnvironment() == llvm::Triple::PAuthTest) D.Diag(diag::err_drv_unsupported_opt_for_target) << A->getAsString(Args) << Triple.getTriple(); - else + else if (HasPtrauthReturns) D.Diag(diag::err_drv_incompatible_options) << A->getAsString(Args) << "-fptrauth-returns"; } @@ -1670,34 +1671,42 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args, AddUnalignedAccessWarning(CmdArgs); - Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_intrinsics, - options::OPT_fno_ptrauth_intrinsics); - Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_calls, - options::OPT_fno_ptrauth_calls); - Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_returns, - options::OPT_fno_ptrauth_returns); - Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_auth_traps, - options::OPT_fno_ptrauth_auth_traps); - Args.addOptInFlag( - CmdArgs, options::OPT_fptrauth_vtable_pointer_address_discrimination, - options::OPT_fno_ptrauth_vtable_pointer_address_discrimination); - Args.addOptInFlag( - CmdArgs, options::OPT_fptrauth_vtable_pointer_type_discrimination, - options::OPT_fno_ptrauth_vtable_pointer_type_discrimination); - Args.addOptInFlag( - CmdArgs, options::OPT_fptrauth_type_info_vtable_pointer_discrimination, - options::OPT_fno_ptrauth_type_info_vtable_pointer_discrimination); - Args.addOptInFlag( - CmdArgs, options::OPT_fptrauth_function_pointer_type_discrimination, - options::OPT_fno_ptrauth_function_pointer_type_discrimination); - - Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_indirect_gotos, - options::OPT_fno_ptrauth_indirect_gotos); - Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_init_fini, - options::OPT_fno_ptrauth_init_fini); - Args.addOptInFlag(CmdArgs, - options::OPT_fptrauth_init_fini_address_discrimination, - options::OPT_fno_ptrauth_init_fini_address_discrimination); + if (Triple.isOSDarwin() || + (Triple.isOSLinux() && + Triple.getEnvironment() == llvm::Triple::PAuthTest)) { + Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_intrinsics, + options::OPT_fno_ptrauth_intrinsics); + Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_calls, + options::OPT_fno_ptrauth_calls); + Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_returns, + options::OPT_fno_ptrauth_returns); + Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_auth_traps, + options::OPT_fno_ptrauth_auth_traps); + Args.addOptInFlag( + CmdArgs, options::OPT_fptrauth_vtable_pointer_address_discrimination, + options::OPT_fno_ptrauth_vtable_pointer_address_discrimination); + Args.addOptInFlag( + CmdArgs, options::OPT_fptrauth_vtable_pointer_type_discrimination, + options::OPT_fno_ptrauth_vtable_pointer_type_discrimination); + Args.addOptInFlag( + CmdArgs, options::OPT_fptrauth_type_info_vtable_pointer_discrimination, + options::OPT_fno_ptrauth_type_info_vtable_pointer_discrimination); + Args.addOptInFlag( + CmdArgs, options::OPT_fptrauth_function_pointer_type_discrimination, + options::OPT_fno_ptrauth_function_pointer_type_discrimination); + Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_indirect_gotos, + options::OPT_fno_ptrauth_indirect_gotos); + } + if (Triple.isOSLinux() && + Triple.getEnvironment() == llvm::Triple::PAuthTest) { + Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_init_fini, + options::OPT_fno_ptrauth_init_fini); + Args.addOptInFlag( + CmdArgs, options::OPT_fptrauth_init_fini_address_discrimination, + options::OPT_fno_ptrauth_init_fini_address_discrimination); + Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_elf_got, + options::OPT_fno_ptrauth_elf_got); + } Args.addOptInFlag(CmdArgs, options::OPT_faarch64_jump_table_hardening, options::OPT_fno_aarch64_jump_table_hardening); diff --git a/clang/lib/Driver/ToolChains/Fuchsia.cpp b/clang/lib/Driver/ToolChains/Fuchsia.cpp index 31c2f3f..507cc03 100644 --- a/clang/lib/Driver/ToolChains/Fuchsia.cpp +++ b/clang/lib/Driver/ToolChains/Fuchsia.cpp @@ -483,7 +483,8 @@ SanitizerMask Fuchsia::getSupportedSanitizers() const { Res |= SanitizerKind::Leak; Res |= SanitizerKind::Scudo; Res |= SanitizerKind::Thread; - if (getTriple().getArch() == llvm::Triple::x86_64) { + if (getTriple().getArch() == llvm::Triple::x86_64 || + getTriple().getArch() == llvm::Triple::x86) { Res |= SanitizerKind::SafeStack; } return Res; @@ -496,6 +497,7 @@ SanitizerMask Fuchsia::getDefaultSanitizers() const { case llvm::Triple::riscv64: Res |= SanitizerKind::ShadowCallStack; break; + case llvm::Triple::x86: case llvm::Triple::x86_64: Res |= SanitizerKind::SafeStack; break; diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index 1d0dfd0b..021d8c6 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -2674,8 +2674,11 @@ private: } // *a or &a or &&a. - if (PreviousNotConst->is(TT_PointerOrReference)) + if (PreviousNotConst->is(TT_PointerOrReference) || + PreviousNotConst->endsSequence(tok::coloncolon, + TT_PointerOrReference)) { return true; + } // MyClass a; if (PreviousNotConst->isTypeName(LangOpts)) diff --git a/clang/lib/Frontend/TextDiagnostic.cpp b/clang/lib/Frontend/TextDiagnostic.cpp index 5888571..f5add2a 100644 --- a/clang/lib/Frontend/TextDiagnostic.cpp +++ b/clang/lib/Frontend/TextDiagnostic.cpp @@ -17,7 +17,6 @@ #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Locale.h" -#include "llvm/Support/raw_ostream.h" #include <algorithm> #include <optional> @@ -662,7 +661,7 @@ void TextDiagnostic::emitDiagnosticMessage( FullSourceLoc Loc, PresumedLoc PLoc, DiagnosticsEngine::Level Level, StringRef Message, ArrayRef<clang::CharSourceRange> Ranges, DiagOrStoredDiag D) { - uint64_t StartOfLocationInfo = OS.tell(); + uint64_t StartOfLocationInfo = OS.getColumn(); // Emit the location of this particular diagnostic. if (Loc.isValid()) @@ -675,8 +674,11 @@ void TextDiagnostic::emitDiagnosticMessage( printDiagnosticLevel(OS, Level, DiagOpts.ShowColors); printDiagnosticMessage(OS, /*IsSupplemental*/ Level == DiagnosticsEngine::Note, - Message, OS.tell() - StartOfLocationInfo, + Message, OS.getColumn() - StartOfLocationInfo, DiagOpts.MessageLength, DiagOpts.ShowColors); + // We use a formatted ostream, which does its own buffering. Flush here + // so we keep the proper order of output. + OS.flush(); } /*static*/ void @@ -1485,7 +1487,7 @@ void TextDiagnostic::emitSnippet(StringRef SourceLine, if (CharStyle != Styles.end()) { if (!CurrentColor || (CurrentColor && *CurrentColor != CharStyle->Color)) { - OS.changeColor(CharStyle->Color, false); + OS.changeColor(CharStyle->Color); CurrentColor = CharStyle->Color; } } else if (CurrentColor) { diff --git a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h index d973371..a918af3 100644 --- a/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_alias_intrinsics.h @@ -2598,6 +2598,129 @@ _HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_max) __attribute__((convergent)) double4 WaveActiveMax(double4); //===----------------------------------------------------------------------===// +// WaveActiveMin builtins +//===----------------------------------------------------------------------===// + +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) half WaveActiveMin(half); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) half2 WaveActiveMin(half2); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) half3 WaveActiveMin(half3); +_HLSL_16BIT_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) half4 WaveActiveMin(half4); + +#ifdef __HLSL_ENABLE_16_BIT +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) int16_t WaveActiveMin(int16_t); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) int16_t2 WaveActiveMin(int16_t2); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) int16_t3 WaveActiveMin(int16_t3); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) int16_t4 WaveActiveMin(int16_t4); + +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) uint16_t WaveActiveMin(uint16_t); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) uint16_t2 WaveActiveMin(uint16_t2); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) uint16_t3 WaveActiveMin(uint16_t3); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) uint16_t4 WaveActiveMin(uint16_t4); +#endif + +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) int WaveActiveMin(int); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) int2 WaveActiveMin(int2); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) int3 WaveActiveMin(int3); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) int4 WaveActiveMin(int4); + +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) uint WaveActiveMin(uint); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) uint2 WaveActiveMin(uint2); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) uint3 WaveActiveMin(uint3); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) uint4 WaveActiveMin(uint4); + +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) int64_t WaveActiveMin(int64_t); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) int64_t2 WaveActiveMin(int64_t2); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) int64_t3 WaveActiveMin(int64_t3); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) int64_t4 WaveActiveMin(int64_t4); + +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) uint64_t WaveActiveMin(uint64_t); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) uint64_t2 WaveActiveMin(uint64_t2); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) uint64_t3 WaveActiveMin(uint64_t3); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) uint64_t4 WaveActiveMin(uint64_t4); + +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) float WaveActiveMin(float); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) float2 WaveActiveMin(float2); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) float3 WaveActiveMin(float3); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) float4 WaveActiveMin(float4); + +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) double WaveActiveMin(double); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) double2 WaveActiveMin(double2); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) double3 WaveActiveMin(double3); +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_min) +__attribute__((convergent)) double4 WaveActiveMin(double4); + +//===----------------------------------------------------------------------===// // WaveActiveSum builtins //===----------------------------------------------------------------------===// diff --git a/clang/lib/Interpreter/InterpreterValuePrinter.cpp b/clang/lib/Interpreter/InterpreterValuePrinter.cpp index 0ed02f3..cfa50ee 100644 --- a/clang/lib/Interpreter/InterpreterValuePrinter.cpp +++ b/clang/lib/Interpreter/InterpreterValuePrinter.cpp @@ -411,7 +411,8 @@ public: } InterfaceKind VisitReferenceType(const ReferenceType *Ty) { - ExprResult AddrOfE = S.CreateBuiltinUnaryOp(SourceLocation(), UO_AddrOf, E); + ExprResult AddrOfE = S.CreateBuiltinUnaryOp(SourceLocation(), UO_AddrOf, + E->IgnoreImpCasts()); assert(!AddrOfE.isInvalid() && "Can not create unary expression"); Args.push_back(AddrOfE.get()); return InterfaceKind::NoAlloc; @@ -537,7 +538,7 @@ llvm::Expected<Expr *> Interpreter::convertExprToValue(Expr *E) { QualType DesugaredTy = Ty.getDesugaredType(Ctx); // For lvalue struct, we treat it as a reference. - if (DesugaredTy->isRecordType() && E->isLValue()) { + if (DesugaredTy->isRecordType() && E->IgnoreImpCasts()->isLValue()) { DesugaredTy = Ctx.getLValueReferenceType(DesugaredTy); Ty = Ctx.getLValueReferenceType(Ty); } diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 96d5142..94a490a 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -3279,6 +3279,7 @@ bool SemaHLSL::CheckBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { break; } case Builtin::BI__builtin_hlsl_wave_active_max: + case Builtin::BI__builtin_hlsl_wave_active_min: case Builtin::BI__builtin_hlsl_wave_active_sum: { if (SemaRef.checkArgCount(TheCall, 1)) return true; diff --git a/clang/test/AST/ByteCode/builtin-functions.cpp b/clang/test/AST/ByteCode/builtin-functions.cpp index e9093b2..a90f636 100644 --- a/clang/test/AST/ByteCode/builtin-functions.cpp +++ b/clang/test/AST/ByteCode/builtin-functions.cpp @@ -1856,7 +1856,8 @@ namespace InitParam { #endif -namespace SAddOverflowInt { +namespace NonBlockPointerStore { int a; void foo(void) { a *= __builtin_sadd_overflow(1, 2, 0); } + void foo2(void) { a *= __builtin_addc(1, 2, 0, 0); } } diff --git a/clang/test/CodeGen/AArch64/ext-vector-coercion.c b/clang/test/CodeGen/AArch64/ext-vector-coercion.c new file mode 100644 index 0000000..354980a --- /dev/null +++ b/clang/test/CodeGen/AArch64/ext-vector-coercion.c @@ -0,0 +1,42 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6 +// RUN: %clang_cc1 -fenable-matrix -triple arm64-apple-macosx %s -emit-llvm -disable-llvm-passes -o - | FileCheck %s + +typedef float float3 __attribute__((ext_vector_type(3))); +struct Vec3 { + union { + struct { + float x; + float y; + float z; + }; + float vec __attribute__((ext_vector_type(3))); + }; +}; + +// CHECK-LABEL: define i128 @add( +// CHECK-SAME: i128 [[A_COERCE:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[RETVAL:%.*]] = alloca [[STRUCT_VEC3:%.*]], align 16 +// CHECK-NEXT: [[A:%.*]] = alloca [[STRUCT_VEC3]], align 16 +// CHECK-NEXT: [[COERCE_DIVE:%.*]] = getelementptr inbounds nuw [[STRUCT_VEC3]], ptr [[A]], i32 0, i32 0 +// CHECK-NEXT: store i128 [[A_COERCE]], ptr [[COERCE_DIVE]], align 16 +// CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw [[STRUCT_VEC3]], ptr [[A]], i32 0, i32 0 +// CHECK-NEXT: [[LOADVECN:%.*]] = load <4 x float>, ptr [[TMP0]], align 16 +// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <4 x float> [[LOADVECN]], <4 x float> poison, <3 x i32> <i32 0, i32 1, i32 2> +// CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw [[STRUCT_VEC3]], ptr [[A]], i32 0, i32 0 +// CHECK-NEXT: [[LOADVECN1:%.*]] = load <4 x float>, ptr [[TMP1]], align 16 +// CHECK-NEXT: [[EXTRACTVEC2:%.*]] = shufflevector <4 x float> [[LOADVECN1]], <4 x float> poison, <3 x i32> <i32 0, i32 1, i32 2> +// CHECK-NEXT: [[ADD:%.*]] = fadd <3 x float> [[EXTRACTVEC]], [[EXTRACTVEC2]] +// CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds nuw [[STRUCT_VEC3]], ptr [[RETVAL]], i32 0, i32 0 +// CHECK-NEXT: [[EXTRACTVEC3:%.*]] = shufflevector <3 x float> [[ADD]], <3 x float> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> +// CHECK-NEXT: store <4 x float> [[EXTRACTVEC3]], ptr [[TMP2]], align 16 +// CHECK-NEXT: [[COERCE_DIVE4:%.*]] = getelementptr inbounds nuw [[STRUCT_VEC3]], ptr [[RETVAL]], i32 0, i32 0 +// CHECK-NEXT: [[TMP3:%.*]] = load i128, ptr [[COERCE_DIVE4]], align 16 +// CHECK-NEXT: ret i128 [[TMP3]] +// +struct Vec3 add(struct Vec3 a) { + struct Vec3 res; + res.vec = a.vec + a.vec; + return res; +} + diff --git a/clang/test/CodeGenCXX/matrix-vector-bit-int.cpp b/clang/test/CodeGenCXX/matrix-vector-bit-int.cpp index 2e7531b..4be1cb3 100644 --- a/clang/test/CodeGenCXX/matrix-vector-bit-int.cpp +++ b/clang/test/CodeGenCXX/matrix-vector-bit-int.cpp @@ -19,7 +19,7 @@ using i4x3x3 = _BitInt(4) __attribute__((matrix_type(3, 3))); // CHECK-NEXT: store i32 [[A_COERCE]], ptr [[A]], align 4 // CHECK-NEXT: [[LOADVECN:%.*]] = load <4 x i8>, ptr [[A]], align 4 // CHECK-NEXT: [[A1:%.*]] = shufflevector <4 x i8> [[LOADVECN]], <4 x i8> poison, <3 x i32> <i32 0, i32 1, i32 2> -// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x i8> [[A1]], <3 x i8> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> +// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x i8> [[A1]], <3 x i8> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> // CHECK-NEXT: store <4 x i8> [[EXTRACTVEC]], ptr [[A_ADDR]], align 4 // CHECK-NEXT: [[LOADVECN2:%.*]] = load <4 x i8>, ptr [[A_ADDR]], align 4 // CHECK-NEXT: [[EXTRACTVEC3:%.*]] = shufflevector <4 x i8> [[LOADVECN2]], <4 x i8> poison, <3 x i32> <i32 0, i32 1, i32 2> @@ -38,7 +38,7 @@ i8x3 v1(i8x3 a) { // CHECK-SAME: <3 x i32> noundef [[A:%.*]]) #[[ATTR1:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[A_ADDR:%.*]] = alloca <3 x i32>, align 16 -// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x i32> [[A]], <3 x i32> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> +// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x i32> [[A]], <3 x i32> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> // CHECK-NEXT: store <4 x i32> [[EXTRACTVEC]], ptr [[A_ADDR]], align 16 // CHECK-NEXT: [[LOADVECN:%.*]] = load <4 x i32>, ptr [[A_ADDR]], align 16 // CHECK-NEXT: [[EXTRACTVEC1:%.*]] = shufflevector <4 x i32> [[LOADVECN]], <4 x i32> poison, <3 x i32> <i32 0, i32 1, i32 2> @@ -57,7 +57,7 @@ i32x3 v2(i32x3 a) { // CHECK-NEXT: [[A_ADDR:%.*]] = alloca <3 x i512>, align 256 // CHECK-NEXT: [[LOADVECN:%.*]] = load <4 x i512>, ptr [[TMP0]], align 256 // CHECK-NEXT: [[A:%.*]] = shufflevector <4 x i512> [[LOADVECN]], <4 x i512> poison, <3 x i32> <i32 0, i32 1, i32 2> -// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x i512> [[A]], <3 x i512> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> +// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x i512> [[A]], <3 x i512> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> // CHECK-NEXT: store <4 x i512> [[EXTRACTVEC]], ptr [[A_ADDR]], align 256 // CHECK-NEXT: [[LOADVECN1:%.*]] = load <4 x i512>, ptr [[A_ADDR]], align 256 // CHECK-NEXT: [[EXTRACTVEC2:%.*]] = shufflevector <4 x i512> [[LOADVECN1]], <4 x i512> poison, <3 x i32> <i32 0, i32 1, i32 2> @@ -80,7 +80,7 @@ i512x3 v3(i512x3 a) { // CHECK-NEXT: store i32 [[A_COERCE]], ptr [[A]], align 4 // CHECK-NEXT: [[LOADVECN:%.*]] = load <4 x i4>, ptr [[A]], align 4 // CHECK-NEXT: [[A1:%.*]] = shufflevector <4 x i4> [[LOADVECN]], <4 x i4> poison, <3 x i32> <i32 0, i32 1, i32 2> -// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x i4> [[A1]], <3 x i4> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> +// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x i4> [[A1]], <3 x i4> undef, <4 x i32> <i32 0, i32 1, i32 2, i32 3> // CHECK-NEXT: store <4 x i4> [[EXTRACTVEC]], ptr [[A_ADDR]], align 4 // CHECK-NEXT: [[LOADVECN2:%.*]] = load <4 x i4>, ptr [[A_ADDR]], align 4 // CHECK-NEXT: [[EXTRACTVEC3:%.*]] = shufflevector <4 x i4> [[LOADVECN2]], <4 x i4> poison, <3 x i32> <i32 0, i32 1, i32 2> diff --git a/clang/test/CodeGenHLSL/builtins/WaveActiveMin.hlsl b/clang/test/CodeGenHLSL/builtins/WaveActiveMin.hlsl new file mode 100644 index 0000000..1194f84 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/WaveActiveMin.hlsl @@ -0,0 +1,46 @@ +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -triple \ +// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes -o - | \ +// RUN: FileCheck %s --check-prefixes=CHECK,CHECK-DXIL +// RUN: %clang_cc1 -std=hlsl2021 -finclude-default-header -triple \ +// RUN: spirv-pc-vulkan-compute %s -emit-llvm -disable-llvm-passes -o - | \ +// RUN: FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV + +// Test basic lowering to runtime function call. + +// CHECK-LABEL: test_int +int test_int(int expr) { + // CHECK-SPIRV: %[[RET:.*]] = call spir_func [[TY:.*]] @llvm.spv.wave.reduce.min.i32([[TY]] %[[#]]) + // CHECK-DXIL: %[[RET:.*]] = call [[TY:.*]] @llvm.dx.wave.reduce.min.i32([[TY]] %[[#]]) + // CHECK: ret [[TY]] %[[RET]] + return WaveActiveMin(expr); +} + +// CHECK-DXIL: declare [[TY]] @llvm.dx.wave.reduce.min.i32([[TY]]) #[[#attr:]] +// CHECK-SPIRV: declare [[TY]] @llvm.spv.wave.reduce.min.i32([[TY]]) #[[#attr:]] + +// CHECK-LABEL: test_uint64_t +uint64_t test_uint64_t(uint64_t expr) { + // CHECK-SPIRV: %[[RET:.*]] = call spir_func [[TY:.*]] @llvm.spv.wave.reduce.umin.i64([[TY]] %[[#]]) + // CHECK-DXIL: %[[RET:.*]] = call [[TY:.*]] @llvm.dx.wave.reduce.umin.i64([[TY]] %[[#]]) + // CHECK: ret [[TY]] %[[RET]] + return WaveActiveMin(expr); +} + +// CHECK-DXIL: declare [[TY]] @llvm.dx.wave.reduce.umin.i64([[TY]]) #[[#attr:]] +// CHECK-SPIRV: declare [[TY]] @llvm.spv.wave.reduce.umin.i64([[TY]]) #[[#attr:]] + +// Test basic lowering to runtime function call with array and float value. + +// CHECK-LABEL: test_floatv4 +float4 test_floatv4(float4 expr) { + // CHECK-SPIRV: %[[RET1:.*]] = call reassoc nnan ninf nsz arcp afn spir_func [[TY1:.*]] @llvm.spv.wave.reduce.min.v4f32([[TY1]] %[[#]] + // CHECK-DXIL: %[[RET1:.*]] = call reassoc nnan ninf nsz arcp afn [[TY1:.*]] @llvm.dx.wave.reduce.min.v4f32([[TY1]] %[[#]]) + // CHECK: ret [[TY1]] %[[RET1]] + return WaveActiveMin(expr); +} + +// CHECK-DXIL: declare [[TY1]] @llvm.dx.wave.reduce.min.v4f32([[TY1]]) #[[#attr]] +// CHECK-SPIRV: declare [[TY1]] @llvm.spv.wave.reduce.min.v4f32([[TY1]]) #[[#attr]] + +// CHECK: attributes #[[#attr]] = {{{.*}} convergent {{.*}}} + diff --git a/clang/test/CodeGenOpenCL/preserve_vec3.cl b/clang/test/CodeGenOpenCL/preserve_vec3.cl index e76aa81..0017169 100644 --- a/clang/test/CodeGenOpenCL/preserve_vec3.cl +++ b/clang/test/CodeGenOpenCL/preserve_vec3.cl @@ -12,7 +12,7 @@ typedef float float4 __attribute__((ext_vector_type(4))); // CHECK-SAME: ptr addrspace(1) noundef readonly align 16 captures(none) [[A:%.*]], ptr addrspace(1) noundef writeonly align 16 captures(none) initializes((0, 16)) [[B:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] !kernel_arg_addr_space [[META7:![0-9]+]] !kernel_arg_access_qual [[META8:![0-9]+]] !kernel_arg_type [[META9:![0-9]+]] !kernel_arg_base_type [[META10:![0-9]+]] !kernel_arg_type_qual [[META11:![0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TMP0:%.*]] = load <3 x float>, ptr addrspace(1) [[A]], align 16 -// CHECK-NEXT: [[EXTRACTVEC1_I:%.*]] = shufflevector <3 x float> [[TMP0]], <3 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> +// CHECK-NEXT: [[EXTRACTVEC1_I:%.*]] = shufflevector <3 x float> [[TMP0]], <3 x float> <float undef, float poison, float poison>, <4 x i32> <i32 0, i32 1, i32 2, i32 3> // CHECK-NEXT: store <4 x float> [[EXTRACTVEC1_I]], ptr addrspace(1) [[B]], align 16, !tbaa [[CHAR_TBAA12:![0-9]+]] // CHECK-NEXT: ret void // @@ -24,7 +24,7 @@ void kernel foo(global float3 *a, global float3 *b) { // CHECK-SAME: ptr addrspace(1) noundef writeonly align 16 captures(none) initializes((0, 16)) [[A:%.*]], ptr addrspace(1) noundef readonly align 16 captures(none) [[B:%.*]]) local_unnamed_addr #[[ATTR0]] !kernel_arg_addr_space [[META7]] !kernel_arg_access_qual [[META8]] !kernel_arg_type [[META13:![0-9]+]] !kernel_arg_base_type [[META14:![0-9]+]] !kernel_arg_type_qual [[META11]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TMP0:%.*]] = load <3 x float>, ptr addrspace(1) [[B]], align 16, !tbaa [[CHAR_TBAA12]] -// CHECK-NEXT: [[EXTRACTVEC_I:%.*]] = shufflevector <3 x float> [[TMP0]], <3 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> +// CHECK-NEXT: [[EXTRACTVEC_I:%.*]] = shufflevector <3 x float> [[TMP0]], <3 x float> <float undef, float poison, float poison>, <4 x i32> <i32 0, i32 1, i32 2, i32 3> // CHECK-NEXT: store <4 x float> [[EXTRACTVEC_I]], ptr addrspace(1) [[A]], align 16, !tbaa [[CHAR_TBAA12]] // CHECK-NEXT: ret void // @@ -60,7 +60,7 @@ void kernel float3_to_double2(global float3 *a, global double2 *b) { // CHECK-SAME: ptr addrspace(1) noundef writeonly align 8 captures(none) initializes((0, 8)) [[A:%.*]], ptr addrspace(1) noundef readonly align 8 captures(none) [[B:%.*]]) local_unnamed_addr #[[ATTR0]] !kernel_arg_addr_space [[META7]] !kernel_arg_access_qual [[META8]] !kernel_arg_type [[META17:![0-9]+]] !kernel_arg_base_type [[META18:![0-9]+]] !kernel_arg_type_qual [[META11]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TMP0:%.*]] = load <3 x i16>, ptr addrspace(1) [[B]], align 8, !tbaa [[CHAR_TBAA12]] -// CHECK-NEXT: [[EXTRACTVEC_I:%.*]] = shufflevector <3 x i16> [[TMP0]], <3 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> +// CHECK-NEXT: [[EXTRACTVEC_I:%.*]] = shufflevector <3 x i16> [[TMP0]], <3 x i16> <i16 undef, i16 poison, i16 poison>, <4 x i32> <i32 0, i32 1, i32 2, i32 3> // CHECK-NEXT: store <4 x i16> [[EXTRACTVEC_I]], ptr addrspace(1) [[A]], align 8, !tbaa [[CHAR_TBAA12]] // CHECK-NEXT: ret void // @@ -71,8 +71,8 @@ void kernel char8_to_short3(global short3 *a, global char8 *b) { // CHECK-LABEL: define dso_local spir_func void @from_char3( // CHECK-SAME: <3 x i8> noundef [[A:%.*]], ptr addrspace(1) noundef writeonly captures(none) initializes((0, 4)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x i8> [[A]], <3 x i8> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> -// CHECK-NEXT: store <4 x i8> [[EXTRACTVEC]], ptr addrspace(1) [[OUT]], align 4, !tbaa [[INT_TBAA3:![0-9]+]] +// CHECK-NEXT: [[TMP0:%.*]] = shufflevector <3 x i8> [[A]], <3 x i8> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> +// CHECK-NEXT: store <4 x i8> [[TMP0]], ptr addrspace(1) [[OUT]], align 4, !tbaa [[INT_TBAA3:![0-9]+]] // CHECK-NEXT: ret void // void from_char3(char3 a, global int *out) { @@ -82,8 +82,8 @@ void from_char3(char3 a, global int *out) { // CHECK-LABEL: define dso_local spir_func void @from_short3( // CHECK-SAME: <3 x i16> noundef [[A:%.*]], ptr addrspace(1) noundef writeonly captures(none) initializes((0, 8)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR2]] { // CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x i16> [[A]], <3 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> -// CHECK-NEXT: store <4 x i16> [[EXTRACTVEC]], ptr addrspace(1) [[OUT]], align 8, !tbaa [[LONG_TBAA19:![0-9]+]] +// CHECK-NEXT: [[TMP0:%.*]] = shufflevector <3 x i16> [[A]], <3 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> +// CHECK-NEXT: store <4 x i16> [[TMP0]], ptr addrspace(1) [[OUT]], align 8, !tbaa [[LONG_TBAA19:![0-9]+]] // CHECK-NEXT: ret void // void from_short3(short3 a, global long *out) { @@ -94,7 +94,8 @@ void from_short3(short3 a, global long *out) { // CHECK-SAME: i32 noundef [[A:%.*]], ptr addrspace(1) noundef writeonly captures(none) initializes((0, 4)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR2]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TMP0:%.*]] = bitcast i32 [[A]] to <4 x i8> -// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <4 x i8> [[TMP0]], <4 x i8> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> +// CHECK-NEXT: [[ASTYPE:%.*]] = shufflevector <4 x i8> [[TMP0]], <4 x i8> poison, <3 x i32> <i32 0, i32 1, i32 2> +// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x i8> [[ASTYPE]], <3 x i8> <i8 undef, i8 poison, i8 poison>, <4 x i32> <i32 0, i32 1, i32 2, i32 3> // CHECK-NEXT: store <4 x i8> [[EXTRACTVEC]], ptr addrspace(1) [[OUT]], align 4, !tbaa [[CHAR_TBAA12]] // CHECK-NEXT: ret void // @@ -106,7 +107,8 @@ void scalar_to_char3(int a, global char3 *out) { // CHECK-SAME: i64 noundef [[A:%.*]], ptr addrspace(1) noundef writeonly captures(none) initializes((0, 8)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR2]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TMP0:%.*]] = bitcast i64 [[A]] to <4 x i16> -// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 poison> +// CHECK-NEXT: [[ASTYPE:%.*]] = shufflevector <4 x i16> [[TMP0]], <4 x i16> poison, <3 x i32> <i32 0, i32 1, i32 2> +// CHECK-NEXT: [[EXTRACTVEC:%.*]] = shufflevector <3 x i16> [[ASTYPE]], <3 x i16> <i16 undef, i16 poison, i16 poison>, <4 x i32> <i32 0, i32 1, i32 2, i32 3> // CHECK-NEXT: store <4 x i16> [[EXTRACTVEC]], ptr addrspace(1) [[OUT]], align 8, !tbaa [[CHAR_TBAA12]] // CHECK-NEXT: ret void // diff --git a/clang/test/DebugInfo/Generic/bit-int.c b/clang/test/DebugInfo/Generic/bit-int.c new file mode 100644 index 0000000..94b9301 --- /dev/null +++ b/clang/test/DebugInfo/Generic/bit-int.c @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 -x c++ %s -debug-info-kind=standalone -gno-column-info -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 -x c %s -debug-info-kind=standalone -gno-column-info -emit-llvm -o - | FileCheck %s + +unsigned _BitInt(17) a; +_BitInt(2) b; + +// CHECK: !DIBasicType(name: "_BitInt", size: 8, dataSize: 2, encoding: DW_ATE_signed) +// CHECK: !DIBasicType(name: "unsigned _BitInt", size: 32, dataSize: 17, encoding: DW_ATE_unsigned) diff --git a/clang/include/clang/Driver/aarch64-mlr-for-calls-only.c b/clang/test/Driver/aarch64-mlr-for-calls-only.c index e71a4cd..e71a4cd 100644 --- a/clang/include/clang/Driver/aarch64-mlr-for-calls-only.c +++ b/clang/test/Driver/aarch64-mlr-for-calls-only.c diff --git a/clang/test/Driver/aarch64-ptrauth.c b/clang/test/Driver/aarch64-ptrauth.c index b080a77..a67e98f 100644 --- a/clang/test/Driver/aarch64-ptrauth.c +++ b/clang/test/Driver/aarch64-ptrauth.c @@ -4,7 +4,8 @@ // NONE: "-cc1" // NONE-NOT: "-fptrauth- -// RUN: %clang -### -c --target=aarch64 \ +//// -fptauth-* driver flags on Linux are only supported with pauthtest ABI. +// RUN: %clang -### -c --target=aarch64-linux -mabi=pauthtest \ // RUN: -fno-ptrauth-intrinsics -fptrauth-intrinsics \ // RUN: -fno-ptrauth-calls -fptrauth-calls \ // RUN: -fno-ptrauth-returns -fptrauth-returns \ @@ -15,9 +16,43 @@ // RUN: -fno-ptrauth-indirect-gotos -fptrauth-indirect-gotos \ // RUN: -fno-ptrauth-init-fini -fptrauth-init-fini \ // RUN: -fno-ptrauth-init-fini-address-discrimination -fptrauth-init-fini-address-discrimination \ +// RUN: -fno-ptrauth-elf-got -fptrauth-elf-got \ // RUN: -fno-aarch64-jump-table-hardening -faarch64-jump-table-hardening \ -// RUN: %s 2>&1 | FileCheck %s --check-prefix=ALL -// ALL: "-cc1"{{.*}} "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-type-info-vtable-pointer-discrimination" "-fptrauth-indirect-gotos" "-fptrauth-init-fini" "-fptrauth-init-fini-address-discrimination" "-faarch64-jump-table-hardening" +// RUN: %s 2>&1 | FileCheck %s --check-prefix=ALL-LINUX-PAUTHABI +// RUN: %clang -### -c --target=aarch64-linux-pauthtest \ +// RUN: -fno-ptrauth-intrinsics -fptrauth-intrinsics \ +// RUN: -fno-ptrauth-calls -fptrauth-calls \ +// RUN: -fno-ptrauth-returns -fptrauth-returns \ +// RUN: -fno-ptrauth-auth-traps -fptrauth-auth-traps \ +// RUN: -fno-ptrauth-vtable-pointer-address-discrimination -fptrauth-vtable-pointer-address-discrimination \ +// RUN: -fno-ptrauth-vtable-pointer-type-discrimination -fptrauth-vtable-pointer-type-discrimination \ +// RUN: -fno-ptrauth-type-info-vtable-pointer-discrimination -fptrauth-type-info-vtable-pointer-discrimination \ +// RUN: -fno-ptrauth-indirect-gotos -fptrauth-indirect-gotos \ +// RUN: -fno-ptrauth-init-fini -fptrauth-init-fini \ +// RUN: -fno-ptrauth-init-fini-address-discrimination -fptrauth-init-fini-address-discrimination \ +// RUN: -fno-ptrauth-elf-got -fptrauth-elf-got \ +// RUN: -fno-aarch64-jump-table-hardening -faarch64-jump-table-hardening \ +// RUN: %s 2>&1 | FileCheck %s --check-prefix=ALL-LINUX-PAUTHABI +// ALL-LINUX-PAUTHABI: "-cc1"{{.*}} "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-type-info-vtable-pointer-discrimination" "-fptrauth-indirect-gotos" "-fptrauth-init-fini" "-fptrauth-init-fini-address-discrimination" "-fptrauth-elf-got"{{.*}} "-faarch64-jump-table-hardening" + +// RUN: %clang -### -c --target=aarch64-linux \ +// RUN: -fno-aarch64-jump-table-hardening -faarch64-jump-table-hardening \ +// RUN: %s 2>&1 | FileCheck %s --check-prefix=ALL-LINUX +// ALL-LINUX: "-cc1"{{.*}} "-faarch64-jump-table-hardening" + +//// Some -fptrauth-* flags are supported for ARM64 Darwin. +// RUN: %clang -### -c --target=arm64-darwin \ +// RUN: -fno-ptrauth-intrinsics -fptrauth-intrinsics \ +// RUN: -fno-ptrauth-calls -fptrauth-calls \ +// RUN: -fno-ptrauth-returns -fptrauth-returns \ +// RUN: -fno-ptrauth-auth-traps -fptrauth-auth-traps \ +// RUN: -fno-ptrauth-vtable-pointer-address-discrimination -fptrauth-vtable-pointer-address-discrimination \ +// RUN: -fno-ptrauth-vtable-pointer-type-discrimination -fptrauth-vtable-pointer-type-discrimination \ +// RUN: -fno-ptrauth-type-info-vtable-pointer-discrimination -fptrauth-type-info-vtable-pointer-discrimination \ +// RUN: -fno-ptrauth-indirect-gotos -fptrauth-indirect-gotos \ +// RUN: -fno-aarch64-jump-table-hardening -faarch64-jump-table-hardening \ +// RUN: %s 2>&1 | FileCheck %s --check-prefix=ALL-DARWIN +// ALL-DARWIN: "-cc1"{{.*}} "-fptrauth-intrinsics" "-fptrauth-calls" "-fptrauth-returns" "-fptrauth-auth-traps" "-fptrauth-vtable-pointer-address-discrimination" "-fptrauth-vtable-pointer-type-discrimination" "-fptrauth-type-info-vtable-pointer-discrimination" "-fptrauth-indirect-gotos"{{.*}} "-faarch64-jump-table-hardening" // RUN: %clang -### -c --target=aarch64-linux -mabi=pauthtest %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI1 // RUN: %clang -### -c --target=aarch64-linux-pauthtest %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI1 @@ -40,7 +75,7 @@ // RUN: -fno-aarch64-jump-table-hardening %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI2 //// Non-linux OS: pauthtest ABI has no effect in terms of passing ptrauth cc1 flags. -//// An error about unsupported ABI will be emitted later in pipeline (see ERR2 below) +//// An error about unsupported ABI will be emitted later in pipeline (see ERR3 below) // RUN: %clang -### -c --target=aarch64 -mabi=pauthtest %s 2>&1 | FileCheck %s --check-prefix=PAUTHABI2 // PAUTHABI2: "-cc1" @@ -55,10 +90,11 @@ // PAUTHABI3-NOT: "-fptrauth- // PAUTHABI3-NOT: "-faarch64-jump-table-hardening" -// RUN: not %clang -### -c --target=x86_64 -fptrauth-intrinsics -fptrauth-calls -fptrauth-returns -fptrauth-auth-traps \ +//// Non-pauthtest ABI. +// RUN: not %clang -### -c --target=aarch64-linux -fptrauth-intrinsics -fptrauth-calls -fptrauth-returns -fptrauth-auth-traps \ // RUN: -fptrauth-vtable-pointer-address-discrimination -fptrauth-vtable-pointer-type-discrimination \ // RUN: -fptrauth-type-info-vtable-pointer-discrimination -fptrauth-indirect-gotos -fptrauth-init-fini \ -// RUN: -fptrauth-init-fini-address-discrimination -faarch64-jump-table-hardening %s 2>&1 | FileCheck %s --check-prefix=ERR1 +// RUN: -fptrauth-init-fini-address-discrimination -fptrauth-elf-got %s 2>&1 | FileCheck %s --check-prefix=ERR1 // ERR1: error: unsupported option '-fptrauth-intrinsics' for target '{{.*}}' // ERR1-NEXT: error: unsupported option '-fptrauth-calls' for target '{{.*}}' // ERR1-NEXT: error: unsupported option '-fptrauth-returns' for target '{{.*}}' @@ -69,59 +105,64 @@ // ERR1-NEXT: error: unsupported option '-fptrauth-indirect-gotos' for target '{{.*}}' // ERR1-NEXT: error: unsupported option '-fptrauth-init-fini' for target '{{.*}}' // ERR1-NEXT: error: unsupported option '-fptrauth-init-fini-address-discrimination' for target '{{.*}}' -// ERR1-NEXT: error: unsupported option '-faarch64-jump-table-hardening' for target '{{.*}}' +// ERR1-NEXT: error: unsupported option '-fptrauth-elf-got' for target '{{.*}}' +//// Non-AArch64. +// RUN: not %clang -### -c --target=x86_64-linux -faarch64-jump-table-hardening %s 2>&1 | FileCheck %s --check-prefix=ERR2 +// ERR2: error: unsupported option '-faarch64-jump-table-hardening' for target '{{.*}}' + +//// Only support PAuth ABI for Linux as for now. +// RUN: not %clang -c --target=aarch64 -mabi=pauthtest %s 2>&1 | FileCheck %s --check-prefix=ERR3 +// ERR3: error: unknown target ABI 'pauthtest' -// RUN: not %clang -c --target=aarch64 -mabi=pauthtest %s 2>&1 | FileCheck %s --check-prefix=ERR2 //// The ABI is not specified explicitly, and for non-Linux pauthtest environment does not correspond //// to pauthtest ABI (each OS target defines this behavior separately). Do not emit an error. -// RUN: %clang -c --target=aarch64-pauthtest %s -o /dev/null -// ERR2: error: unknown target ABI 'pauthtest' +// RUN: %clang -c --target=aarch64-pauthtest %s -o /dev/null //// PAuth ABI is encoded as environment part of the triple, so don't allow to explicitly set other environments. -// RUN: not %clang -### -c --target=aarch64-linux-gnu -mabi=pauthtest %s 2>&1 | FileCheck %s --check-prefix=ERR3 -// ERR3: error: unsupported option '-mabi=pauthtest' for target 'aarch64-unknown-linux-gnu' +// RUN: not %clang -### -c --target=aarch64-linux-gnu -mabi=pauthtest %s 2>&1 | FileCheck %s --check-prefix=ERR4 +// ERR4: error: unsupported option '-mabi=pauthtest' for target 'aarch64-unknown-linux-gnu' // RUN: %clang -### -c --target=aarch64-linux-pauthtest -mabi=pauthtest %s //// The only branch protection option compatible with PAuthABI is BTI. // RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=pac-ret %s 2>&1 | \ -// RUN: FileCheck %s --check-prefix=ERR4_1 +// RUN: FileCheck %s --check-prefix=ERR5_1 // RUN: not %clang -### -c --target=aarch64-linux-pauthtest -mbranch-protection=pac-ret %s 2>&1 | \ -// RUN: FileCheck %s --check-prefix=ERR4_1 +// RUN: FileCheck %s --check-prefix=ERR5_1 // RUN: not %clang -### -c --target=aarch64 -fptrauth-returns -mbranch-protection=pac-ret %s 2>&1 | \ -// RUN: FileCheck %s --check-prefix=ERR4_2 -// ERR4_1: error: unsupported option '-mbranch-protection=pac-ret' for target 'aarch64-unknown-linux-pauthtest' -// ERR4_2: error: the combination of '-mbranch-protection=pac-ret' and '-fptrauth-returns' is incompatible +// RUN: FileCheck %s --check-prefix=ERR5_2 +// ERR5_1: error: unsupported option '-mbranch-protection=pac-ret' for target 'aarch64-unknown-linux-pauthtest' +// ERR5_2: error: the combination of '-mbranch-protection=pac-ret' and '-fptrauth-returns' is incompatible // RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=gcs %s 2>&1 | \ -// RUN: FileCheck %s --check-prefix=ERR5_1 +// RUN: FileCheck %s --check-prefix=ERR6_1 // RUN: not %clang -### -c --target=aarch64-linux-pauthtest -mbranch-protection=gcs %s 2>&1 | \ -// RUN: FileCheck %s --check-prefix=ERR5_1 +// RUN: FileCheck %s --check-prefix=ERR6_1 // RUN: not %clang -### -c --target=aarch64 -fptrauth-returns -mbranch-protection=gcs %s 2>&1 | \ -// RUN: FileCheck %s --check-prefix=ERR5_2 -// ERR5_1: error: unsupported option '-mbranch-protection=gcs' for target 'aarch64-unknown-linux-pauthtest' -// ERR5_2: error: the combination of '-mbranch-protection=gcs' and '-fptrauth-returns' is incompatible +// RUN: FileCheck %s --check-prefix=ERR6_2 +// ERR6_1: error: unsupported option '-mbranch-protection=gcs' for target 'aarch64-unknown-linux-pauthtest' +// ERR6_2: error: the combination of '-mbranch-protection=gcs' and '-fptrauth-returns' is incompatible // RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -mbranch-protection=standard %s 2>&1 | \ -// RUN: FileCheck %s --check-prefix=ERR6_1 +// RUN: FileCheck %s --check-prefix=ERR7_1 // RUN: not %clang -### -c --target=aarch64-linux-pauthtest -mbranch-protection=standard %s 2>&1 | \ -// RUN: FileCheck %s --check-prefix=ERR6_1 +// RUN: FileCheck %s --check-prefix=ERR7_1 // RUN: not %clang -### -c --target=aarch64 -fptrauth-returns -mbranch-protection=standard %s 2>&1 | \ -// RUN: FileCheck %s --check-prefix=ERR6_2 -// ERR6_1: error: unsupported option '-mbranch-protection=standard' for target 'aarch64-unknown-linux-pauthtest' -// ERR6_2: error: the combination of '-mbranch-protection=standard' and '-fptrauth-returns' is incompatible +// RUN: FileCheck %s --check-prefix=ERR7_2 +// ERR7_1: error: unsupported option '-mbranch-protection=standard' for target 'aarch64-unknown-linux-pauthtest' +// ERR7_2: error: the combination of '-mbranch-protection=standard' and '-fptrauth-returns' is incompatible // RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -msign-return-address=all %s 2>&1 | \ -// RUN: FileCheck %s --check-prefix=ERR7 +// RUN: FileCheck %s --check-prefix=ERR8 // RUN: not %clang -### -c --target=aarch64-linux-pauthtest -msign-return-address=all %s 2>&1 | \ -// RUN: FileCheck %s --check-prefix=ERR7 -// ERR7: error: unsupported option '-msign-return-address=all' for target 'aarch64-unknown-linux-pauthtest' +// RUN: FileCheck %s --check-prefix=ERR8 +// ERR8: error: unsupported option '-msign-return-address=all' for target 'aarch64-unknown-linux-pauthtest' // RUN: not %clang -### -c --target=aarch64-linux -mabi=pauthtest -msign-return-address=non-leaf %s 2>&1 | \ -// RUN: FileCheck %s --check-prefix=ERR8 +// RUN: FileCheck %s --check-prefix=ERR9 // RUN: not %clang -### -c --target=aarch64-linux-pauthtest -msign-return-address=non-leaf %s 2>&1 | \ -// RUN: FileCheck %s --check-prefix=ERR8 -// ERR8: error: unsupported option '-msign-return-address=non-leaf' for target 'aarch64-unknown-linux-pauthtest' +// RUN: FileCheck %s --check-prefix=ERR9 +// ERR9: error: unsupported option '-msign-return-address=non-leaf' for target 'aarch64-unknown-linux-pauthtest' // RUN: %clang -### -c --target=aarch64-linux -mabi=pauthtest -msign-return-address=none %s // RUN: %clang -### -c --target=aarch64-linux-pauthtest -msign-return-address=none %s diff --git a/clang/test/Driver/fuchsia.c b/clang/test/Driver/fuchsia.c index d0fec18..99e5018 100644 --- a/clang/test/Driver/fuchsia.c +++ b/clang/test/Driver/fuchsia.c @@ -130,6 +130,11 @@ // RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ // RUN: -fuse-ld=ld \ // RUN: | FileCheck %s -check-prefix=CHECK-SAFESTACK +// RUN: %clang -### %s --target=x86_64-unknown-fuchsia -m32 \ +// RUN: -fsanitize=safe-stack 2>&1 \ +// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ +// RUN: -fuse-ld=ld \ +// RUN: | FileCheck %s -check-prefix=CHECK-SAFESTACK // CHECK-SAFESTACK: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" // CHECK-SAFESTACK: "-fsanitize=safe-stack" // CHECK-SAFESTACK-NOT: "[[RESOURCE_DIR]]{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-fuchsia{{/|\\\\}}libclang_rt.safestack.a" diff --git a/clang/test/Frontend/aarch64-ignore-branch-protection-attribute.c b/clang/test/Frontend/aarch64-ignore-branch-protection-attribute.c index 32cc98d..e6605ce 100644 --- a/clang/test/Frontend/aarch64-ignore-branch-protection-attribute.c +++ b/clang/test/Frontend/aarch64-ignore-branch-protection-attribute.c @@ -1,7 +1,11 @@ // REQUIRES: aarch64-registered-target -// RUN: %clang -target aarch64-linux-pauthtest %s -S -emit-llvm -o - 2>&1 | FileCheck --implicit-check-not=warning: %s -// RUN: %clang -target aarch64 -fptrauth-returns %s -S -emit-llvm -o - 2>&1 | FileCheck --implicit-check-not=warning: %s +// RUN: %clang -target aarch64-linux-pauthtest %s -S -emit-llvm -o - 2>&1 | FileCheck --implicit-check-not=warning: %s +// RUN: not %clang -target aarch64 -fptrauth-returns %s -S -emit-llvm -o - 2>&1 | FileCheck --implicit-check-not=warning: --check-prefix=PTRAUTH-RETURNS %s + +// Clang fails early, no LLVM IR output produced. +// PTRAUTH-RETURNS: clang: error: unsupported option '-fptrauth-returns' for target 'aarch64' +// PTRAUTH-RETURNS-NOT: attributes /// Unsupported with pauthtest, warning emitted __attribute__((target("branch-protection=pac-ret"))) void f1() {} diff --git a/clang/test/Frontend/diag-wrap-colors.cpp b/clang/test/Frontend/diag-wrap-colors.cpp new file mode 100644 index 0000000..e3dccb1 --- /dev/null +++ b/clang/test/Frontend/diag-wrap-colors.cpp @@ -0,0 +1,6 @@ +// RUN: not %clang_cc1 %s -fmessage-length=50 -fcolor-diagnostics -fno-show-source-location -o - 2>&1 | FileCheck %s + +struct F { + float a : 10; +}; +// CHECK: bit-field 'a' has non-integral type 'float' diff --git a/clang/test/Interpreter/pretty-print.c b/clang/test/Interpreter/pretty-print.c index d0712fb..9a7bf75 100644 --- a/clang/test/Interpreter/pretty-print.c +++ b/clang/test/Interpreter/pretty-print.c @@ -78,14 +78,16 @@ int * null_ptr = (int*)0; null_ptr union U { int I; float F; } u; u.I = 12; u.I // CHECK-NEXT: (int) 12 -// TODO: _Bool, _Complex, _Atomic, and _BitInt -// struct S1{} s1; s1 -// TODO-CHECK-NEXT: (S1 &) @0x{{[0-9a-f]+}} +struct S1{} s1; s1 +// CHECK-NEXT: (S1 &) @0x{{[0-9a-f]+}} + +struct S2 {int d;} E = {22}; E +// CHECK-NEXT: (S2 &) @0x{{[0-9a-f]+}} -// struct S2 {int d;} E = {22}; E -// TODO-CHECK-NEXT: (struct S2 &) @0x{{[0-9a-f]+}} -// E.d -// TODO-CHECK-NEXT: (int) 22 +E.d +// CHECK-NEXT: (int) 22 + +// TODO: _Bool, _Complex, _Atomic, and _BitInt // ----------------------------------------------------------------------------- // Tentative definition handling (C99 6.9.2) diff --git a/clang/test/Preprocessor/bpf-predefined-macros.c b/clang/test/Preprocessor/bpf-predefined-macros.c index cd8a2ec..a9ae8c5 100644 --- a/clang/test/Preprocessor/bpf-predefined-macros.c +++ b/clang/test/Preprocessor/bpf-predefined-macros.c @@ -70,6 +70,9 @@ int u; #ifdef __BPF_FEATURE_LOAD_ACQ_STORE_REL int v; #endif +#ifdef __BPF_FEATURE_GOTOX +int w; +#endif // CHECK: int b; // CHECK: int c; @@ -110,6 +113,7 @@ int v; // CPU_V4: int u; // CPU_V4: int v; +// CPU_V4: int w; // CPU_GENERIC: int g; diff --git a/clang/test/SemaHLSL/BuiltIns/WaveActiveMin.hlsl b/clang/test/SemaHLSL/BuiltIns/WaveActiveMin.hlsl new file mode 100644 index 0000000..3b12faf --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/WaveActiveMin.hlsl @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -emit-llvm-only -disable-llvm-passes -verify + +int test_too_few_arg() { + return __builtin_hlsl_wave_active_min(); + // expected-error@-1 {{too few arguments to function call, expected 1, have 0}} +} + +float2 test_too_many_arg(float2 p0) { + return __builtin_hlsl_wave_active_min(p0, p0); + // expected-error@-1 {{too many arguments to function call, expected 1, have 2}} +} + +bool test_expr_bool_type_check(bool p0) { + return __builtin_hlsl_wave_active_min(p0); + // expected-error@-1 {{invalid operand of type 'bool'}} +} + +bool2 test_expr_bool_vec_type_check(bool2 p0) { + return __builtin_hlsl_wave_active_min(p0); + // expected-error@-1 {{invalid operand of type 'bool2' (aka 'vector<bool, 2>')}} +} + +struct S { float f; }; + +S test_expr_struct_type_check(S p0) { + return __builtin_hlsl_wave_active_min(p0); + // expected-error@-1 {{invalid operand of type 'S' where a scalar or vector is required}} +} + diff --git a/clang/unittests/Format/FormatTestComments.cpp b/clang/unittests/Format/FormatTestComments.cpp index 6b433bb..399f835 100644 --- a/clang/unittests/Format/FormatTestComments.cpp +++ b/clang/unittests/Format/FormatTestComments.cpp @@ -29,13 +29,13 @@ TEST_F(FormatTestComments, UnderstandsSingleLineComments) { "// line 2\n" "void f() {}"); - EXPECT_EQ("// comment", format("//comment")); - EXPECT_EQ("// #comment", format("//#comment")); + verifyFormat("// comment", "//comment"); + verifyFormat("// #comment", "//#comment"); - EXPECT_EQ("// comment\n" - "// clang-format on", - format("//comment\n" - "// clang-format on")); + verifyFormat("// comment\n" + "// clang-format on", + "//comment\n" + "// clang-format on"); verifyFormat("void f() {\n" " // Doesn't do anything\n" @@ -84,11 +84,11 @@ TEST_F(FormatTestComments, UnderstandsSingleLineComments) { "#include \"a/b/c\" // comment"); verifyFormat("#include <a> // comment\n" "#include <a/b/c> // comment"); - EXPECT_EQ("#include \"a\" // comment\n" - "#include \"a/b/c\" // comment", - format("#include \\\n" - " \"a\" // comment\n" - "#include \"a/b/c\" // comment")); + verifyFormat("#include \"a\" // comment\n" + "#include \"a/b/c\" // comment", + "#include \\\n" + " \"a\" // comment\n" + "#include \"a/b/c\" // comment"); verifyFormat("enum E {\n" " // comment\n" @@ -96,63 +96,65 @@ TEST_F(FormatTestComments, UnderstandsSingleLineComments) { " VAL_B\n" "};"); - EXPECT_EQ("enum A {\n" - " // line a\n" - " a,\n" - " b, // line b\n" - "\n" - " // line c\n" - " c\n" - "};", - format("enum A {\n" - " // line a\n" - " a,\n" - " b, // line b\n" - "\n" - " // line c\n" - " c\n" - "};", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("enum A {\n" - " a, // line 1\n" - " // line 2\n" - "};", - format("enum A {\n" - " a, // line 1\n" - " // line 2\n" - "};", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("enum A {\n" - " a, // line 1\n" - " // line 2\n" - "};", - format("enum A {\n" - " a, // line 1\n" - " // line 2\n" - "};", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("enum A {\n" - " a, // line 1\n" - " // line 2\n" - " b\n" - "};", - format("enum A {\n" - " a, // line 1\n" - " // line 2\n" - " b\n" - "};", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("enum A {\n" - " a, // line 1\n" - " // line 2\n" - " b\n" - "};", - format("enum A {\n" - " a, // line 1\n" - " // line 2\n" - " b\n" - "};", - getLLVMStyleWithColumns(20))); + const auto Style20 = getLLVMStyleWithColumns(20); + + verifyFormat("enum A {\n" + " // line a\n" + " a,\n" + " b, // line b\n" + "\n" + " // line c\n" + " c\n" + "};", + "enum A {\n" + " // line a\n" + " a,\n" + " b, // line b\n" + "\n" + " // line c\n" + " c\n" + "};", + Style20); + verifyFormat("enum A {\n" + " a, // line 1\n" + " // line 2\n" + "};", + "enum A {\n" + " a, // line 1\n" + " // line 2\n" + "};", + Style20); + verifyFormat("enum A {\n" + " a, // line 1\n" + " // line 2\n" + "};", + "enum A {\n" + " a, // line 1\n" + " // line 2\n" + "};", + Style20); + verifyFormat("enum A {\n" + " a, // line 1\n" + " // line 2\n" + " b\n" + "};", + "enum A {\n" + " a, // line 1\n" + " // line 2\n" + " b\n" + "};", + Style20); + verifyFormat("enum A {\n" + " a, // line 1\n" + " // line 2\n" + " b\n" + "};", + "enum A {\n" + " a, // line 1\n" + " // line 2\n" + " b\n" + "};", + Style20); verifyFormat( "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; // Trailing comment"); @@ -172,28 +174,28 @@ TEST_F(FormatTestComments, UnderstandsSingleLineComments) { verifyFormat("int aaaa; // aaaaa\n" "int aa; // aaaaaaa", - getLLVMStyleWithColumns(20)); + Style20); + + verifyFormat("void f() { // This does something ..\n" + "}\n" + "int a; // This is unrelated", + "void f() { // This does something ..\n" + " }\n" + "int a; // This is unrelated"); + verifyFormat("class C {\n" + " void f() { // This does something ..\n" + " } // awesome..\n" + "\n" + " int a; // This is unrelated\n" + "};", + "class C{void f() { // This does something ..\n" + " } // awesome..\n" + " \n" + "int a; // This is unrelated\n" + "};"); - EXPECT_EQ("void f() { // This does something ..\n" - "}\n" - "int a; // This is unrelated", - format("void f() { // This does something ..\n" - " }\n" - "int a; // This is unrelated")); - EXPECT_EQ("class C {\n" - " void f() { // This does something ..\n" - " } // awesome..\n" - "\n" - " int a; // This is unrelated\n" - "};", - format("class C{void f() { // This does something ..\n" - " } // awesome..\n" - " \n" - "int a; // This is unrelated\n" - "};")); - - EXPECT_EQ("int i; // single line trailing comment", - format("int i;\\\n// single line trailing comment")); + verifyFormat("int i; // single line trailing comment", + "int i;\\\n// single line trailing comment"); verifyGoogleFormat("int a; // Trailing comment."); @@ -210,99 +212,99 @@ TEST_F(FormatTestComments, UnderstandsSingleLineComments) { verifyGoogleFormat( "aaaaaaaaaaaaaaaaaaaaaaaaaa(\n" " aaaaaaaaaaaaaaaaaaaaaa); // 81_cols_with_this_comment"); - EXPECT_EQ("D(a, {\n" - " // test\n" - " int a;\n" - "});", - format("D(a, {\n" - "// test\n" - "int a;\n" - "});")); - - EXPECT_EQ("lineWith(); // comment\n" - "// at start\n" - "otherLine();", - format("lineWith(); // comment\n" - "// at start\n" - "otherLine();")); - EXPECT_EQ("lineWith(); // comment\n" - "/*\n" - " * at start */\n" - "otherLine();", - format("lineWith(); // comment\n" - "/*\n" - " * at start */\n" - "otherLine();")); - EXPECT_EQ("lineWith(); // comment\n" - " // at start\n" - "otherLine();", - format("lineWith(); // comment\n" - " // at start\n" - "otherLine();")); - - EXPECT_EQ("lineWith(); // comment\n" - "// at start\n" - "otherLine(); // comment", - format("lineWith(); // comment\n" - "// at start\n" - "otherLine(); // comment")); - EXPECT_EQ("lineWith();\n" - "// at start\n" - "otherLine(); // comment", - format("lineWith();\n" - " // at start\n" - "otherLine(); // comment")); - EXPECT_EQ("// first\n" - "// at start\n" - "otherLine(); // comment", - format("// first\n" - " // at start\n" - "otherLine(); // comment")); - EXPECT_EQ("f();\n" - "// first\n" - "// at start\n" - "otherLine(); // comment", - format("f();\n" - "// first\n" - " // at start\n" - "otherLine(); // comment")); + verifyFormat("D(a, {\n" + " // test\n" + " int a;\n" + "});", + "D(a, {\n" + "// test\n" + "int a;\n" + "});"); + + verifyFormat("lineWith(); // comment\n" + "// at start\n" + "otherLine();", + "lineWith(); // comment\n" + "// at start\n" + "otherLine();"); + verifyFormat("lineWith(); // comment\n" + "/*\n" + " * at start */\n" + "otherLine();", + "lineWith(); // comment\n" + "/*\n" + " * at start */\n" + "otherLine();"); + verifyFormat("lineWith(); // comment\n" + " // at start\n" + "otherLine();", + "lineWith(); // comment\n" + " // at start\n" + "otherLine();"); + + verifyFormat("lineWith(); // comment\n" + "// at start\n" + "otherLine(); // comment", + "lineWith(); // comment\n" + "// at start\n" + "otherLine(); // comment"); + verifyFormat("lineWith();\n" + "// at start\n" + "otherLine(); // comment", + "lineWith();\n" + " // at start\n" + "otherLine(); // comment"); + verifyFormat("// first\n" + "// at start\n" + "otherLine(); // comment", + "// first\n" + " // at start\n" + "otherLine(); // comment"); + verifyFormat("f();\n" + "// first\n" + "// at start\n" + "otherLine(); // comment", + "f();\n" + "// first\n" + " // at start\n" + "otherLine(); // comment"); verifyFormat("f(); // comment\n" "// first\n" "// at start\n" "otherLine();"); - EXPECT_EQ("f(); // comment\n" - "// first\n" - "// at start\n" - "otherLine();", - format("f(); // comment\n" - "// first\n" - " // at start\n" - "otherLine();")); - EXPECT_EQ("f(); // comment\n" - " // first\n" - "// at start\n" - "otherLine();", - format("f(); // comment\n" - " // first\n" - "// at start\n" - "otherLine();")); - EXPECT_EQ("void f() {\n" - " lineWith(); // comment\n" - " // at start\n" - "}", - format("void f() {\n" - " lineWith(); // comment\n" - " // at start\n" - "}")); - EXPECT_EQ("int xy; // a\n" - "int z; // b", - format("int xy; // a\n" - "int z; //b")); - EXPECT_EQ("int xy; // a\n" - "int z; // bb", - format("int xy; // a\n" - "int z; //bb", - getLLVMStyleWithColumns(12))); + verifyFormat("f(); // comment\n" + "// first\n" + "// at start\n" + "otherLine();", + "f(); // comment\n" + "// first\n" + " // at start\n" + "otherLine();"); + verifyFormat("f(); // comment\n" + " // first\n" + "// at start\n" + "otherLine();", + "f(); // comment\n" + " // first\n" + "// at start\n" + "otherLine();"); + verifyFormat("void f() {\n" + " lineWith(); // comment\n" + " // at start\n" + "}", + "void f() {\n" + " lineWith(); // comment\n" + " // at start\n" + "}"); + verifyFormat("int xy; // a\n" + "int z; // b", + "int xy; // a\n" + "int z; //b"); + verifyFormat("int xy; // a\n" + "int z; // bb", + "int xy; // a\n" + "int z; //bb", + getLLVMStyleWithColumns(12)); verifyFormat("#define A \\\n" " int i; /* iiiiiiiiiiiiiiiiiiiii */ \\\n" @@ -317,14 +319,14 @@ TEST_F(FormatTestComments, UnderstandsSingleLineComments) { verifyFormat("if ( // This is some comment\n" " x + 3) {\n" "}"); - EXPECT_EQ("if ( // This is some comment\n" - " // spanning two lines\n" - " x + 3) {\n" - "}", - format("if( // This is some comment\n" - " // spanning two lines\n" - " x + 3) {\n" - "}")); + verifyFormat("if ( // This is some comment\n" + " // spanning two lines\n" + " x + 3) {\n" + "}", + "if( // This is some comment\n" + " // spanning two lines\n" + " x + 3) {\n" + "}"); verifyNoCrash("/\\\n/"); verifyNoCrash("/\\\n* */"); @@ -333,35 +335,35 @@ TEST_F(FormatTestComments, UnderstandsSingleLineComments) { } TEST_F(FormatTestComments, KeepsParameterWithTrailingCommentsOnTheirOwnLine) { - EXPECT_EQ("SomeFunction(a,\n" - " b, // comment\n" - " c);", - format("SomeFunction(a,\n" - " b, // comment\n" - " c);")); - EXPECT_EQ("SomeFunction(a, b,\n" - " // comment\n" - " c);", - format("SomeFunction(a,\n" - " b,\n" - " // comment\n" - " c);")); - EXPECT_EQ("SomeFunction(a, b, // comment (unclear relation)\n" - " c);", - format("SomeFunction(a, b, // comment (unclear relation)\n" - " c);")); - EXPECT_EQ("SomeFunction(a, // comment\n" - " b,\n" - " c); // comment", - format("SomeFunction(a, // comment\n" - " b,\n" - " c); // comment")); - EXPECT_EQ("aaaaaaaaaa(aaaa(aaaa,\n" - " aaaa), //\n" - " aaaa, bbbbb);", - format("aaaaaaaaaa(aaaa(aaaa,\n" - "aaaa), //\n" - "aaaa, bbbbb);")); + verifyFormat("SomeFunction(a,\n" + " b, // comment\n" + " c);", + "SomeFunction(a,\n" + " b, // comment\n" + " c);"); + verifyFormat("SomeFunction(a, b,\n" + " // comment\n" + " c);", + "SomeFunction(a,\n" + " b,\n" + " // comment\n" + " c);"); + verifyFormat("SomeFunction(a, b, // comment (unclear relation)\n" + " c);", + "SomeFunction(a, b, // comment (unclear relation)\n" + " c);"); + verifyFormat("SomeFunction(a, // comment\n" + " b,\n" + " c); // comment", + "SomeFunction(a, // comment\n" + " b,\n" + " c); // comment"); + verifyFormat("aaaaaaaaaa(aaaa(aaaa,\n" + " aaaa), //\n" + " aaaa, bbbbb);", + "aaaaaaaaaa(aaaa(aaaa,\n" + "aaaa), //\n" + "aaaa, bbbbb);"); FormatStyle BreakAlways = getLLVMStyle(); BreakAlways.BinPackParameters = FormatStyle::BPPS_AlwaysOnePerLine; @@ -378,12 +380,12 @@ TEST_F(FormatTestComments, KeepsParameterWithTrailingCommentsOnTheirOwnLine) { } TEST_F(FormatTestComments, RemovesTrailingWhitespaceOfComments) { - EXPECT_EQ("// comment", format("// comment ")); - EXPECT_EQ("int aaaaaaa, bbbbbbb; // comment", - format("int aaaaaaa, bbbbbbb; // comment ", - getLLVMStyleWithColumns(33))); - EXPECT_EQ("// comment\\\n", format("// comment\\\n \t \v \f ")); - EXPECT_EQ("// comment \\\n", format("// comment \\\n \t \v \f ")); + verifyFormat("// comment", "// comment "); + verifyFormat("int aaaaaaa, bbbbbbb; // comment", + "int aaaaaaa, bbbbbbb; // comment ", + getLLVMStyleWithColumns(33)); + verifyFormat("// comment\\\n", "// comment\\\n \t \v \f "); + verifyFormat("// comment \\\n", "// comment \\\n \t \v \f "); } TEST_F(FormatTestComments, UnderstandsBlockComments) { @@ -393,16 +395,15 @@ TEST_F(FormatTestComments, UnderstandsBlockComments) { " /*qq_=*/move(q), [this, b](bar<void(uint32_t)> b) {},\n" " c);", getLLVMStyleWithColumns(60)); - EXPECT_EQ("f(aaaaaaaaaaaaaaaaaaaaaaaaa, /* Trailing comment for aa... */\n" - " bbbbbbbbbbbbbbbbbbbbbbbbb);", - format("f(aaaaaaaaaaaaaaaaaaaaaaaaa , \\\n" - "/* Trailing comment for aa... */\n" - " bbbbbbbbbbbbbbbbbbbbbbbbb);")); - EXPECT_EQ( - "f(aaaaaaaaaaaaaaaaaaaaaaaaa,\n" - " /* Leading comment for bb... */ bbbbbbbbbbbbbbbbbbbbbbbbb);", - format("f(aaaaaaaaaaaaaaaaaaaaaaaaa , \n" - "/* Leading comment for bb... */ bbbbbbbbbbbbbbbbbbbbbbbbb);")); + verifyFormat("f(aaaaaaaaaaaaaaaaaaaaaaaaa, /* Trailing comment for aa... */\n" + " bbbbbbbbbbbbbbbbbbbbbbbbb);", + "f(aaaaaaaaaaaaaaaaaaaaaaaaa , \\\n" + "/* Trailing comment for aa... */\n" + " bbbbbbbbbbbbbbbbbbbbbbbbb);"); + verifyFormat("f(aaaaaaaaaaaaaaaaaaaaaaaaa,\n" + " /* Leading comment for bb... */ bbbbbbbbbbbbbbbbbbbbbbbbb);", + "f(aaaaaaaaaaaaaaaaaaaaaaaaa , \n" + "/* Leading comment for bb... */ bbbbbbbbbbbbbbbbbbbbbbbbb);"); verifyFormat( "void aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n" @@ -445,77 +446,77 @@ TEST_F(FormatTestComments, UnderstandsBlockComments) { } TEST_F(FormatTestComments, AlignsBlockComments) { - EXPECT_EQ("/*\n" - " * Really multi-line\n" - " * comment.\n" - " */\n" - "void f() {}", - format(" /*\n" - " * Really multi-line\n" - " * comment.\n" - " */\n" - " void f() {}")); - EXPECT_EQ("class C {\n" - " /*\n" - " * Another multi-line\n" - " * comment.\n" - " */\n" - " void f() {}\n" - "};", - format("class C {\n" - "/*\n" - " * Another multi-line\n" - " * comment.\n" - " */\n" - "void f() {}\n" - "};")); - EXPECT_EQ("/*\n" - " 1. This is a comment with non-trivial formatting.\n" - " 1.1. We have to indent/outdent all lines equally\n" - " 1.1.1. to keep the formatting.\n" - " */", - format(" /*\n" - " 1. This is a comment with non-trivial formatting.\n" - " 1.1. We have to indent/outdent all lines equally\n" - " 1.1.1. to keep the formatting.\n" - " */")); - EXPECT_EQ("/*\n" - "Don't try to outdent if there's not enough indentation.\n" - "*/", - format(" /*\n" - " Don't try to outdent if there's not enough indentation.\n" - " */")); - - EXPECT_EQ("int i; /* Comment with empty...\n" - " *\n" - " * line. */", - format("int i; /* Comment with empty...\n" - " *\n" - " * line. */")); - EXPECT_EQ("int foobar = 0; /* comment */\n" - "int bar = 0; /* multiline\n" - " comment 1 */\n" - "int baz = 0; /* multiline\n" - " comment 2 */\n" - "int bzz = 0; /* multiline\n" - " comment 3 */", - format("int foobar = 0; /* comment */\n" - "int bar = 0; /* multiline\n" - " comment 1 */\n" - "int baz = 0; /* multiline\n" - " comment 2 */\n" - "int bzz = 0; /* multiline\n" - " comment 3 */")); - EXPECT_EQ("int foobar = 0; /* comment */\n" - "int bar = 0; /* multiline\n" - " comment */\n" - "int baz = 0; /* multiline\n" - "comment */", - format("int foobar = 0; /* comment */\n" - "int bar = 0; /* multiline\n" - "comment */\n" - "int baz = 0; /* multiline\n" - "comment */")); + verifyFormat("/*\n" + " * Really multi-line\n" + " * comment.\n" + " */\n" + "void f() {}", + " /*\n" + " * Really multi-line\n" + " * comment.\n" + " */\n" + " void f() {}"); + verifyFormat("class C {\n" + " /*\n" + " * Another multi-line\n" + " * comment.\n" + " */\n" + " void f() {}\n" + "};", + "class C {\n" + "/*\n" + " * Another multi-line\n" + " * comment.\n" + " */\n" + "void f() {}\n" + "};"); + verifyFormat("/*\n" + " 1. This is a comment with non-trivial formatting.\n" + " 1.1. We have to indent/outdent all lines equally\n" + " 1.1.1. to keep the formatting.\n" + " */", + " /*\n" + " 1. This is a comment with non-trivial formatting.\n" + " 1.1. We have to indent/outdent all lines equally\n" + " 1.1.1. to keep the formatting.\n" + " */"); + verifyFormat("/*\n" + "Don't try to outdent if there's not enough indentation.\n" + "*/", + " /*\n" + " Don't try to outdent if there's not enough indentation.\n" + " */"); + + verifyFormat("int i; /* Comment with empty...\n" + " *\n" + " * line. */", + "int i; /* Comment with empty...\n" + " *\n" + " * line. */"); + verifyFormat("int foobar = 0; /* comment */\n" + "int bar = 0; /* multiline\n" + " comment 1 */\n" + "int baz = 0; /* multiline\n" + " comment 2 */\n" + "int bzz = 0; /* multiline\n" + " comment 3 */", + "int foobar = 0; /* comment */\n" + "int bar = 0; /* multiline\n" + " comment 1 */\n" + "int baz = 0; /* multiline\n" + " comment 2 */\n" + "int bzz = 0; /* multiline\n" + " comment 3 */"); + verifyFormat("int foobar = 0; /* comment */\n" + "int bar = 0; /* multiline\n" + " comment */\n" + "int baz = 0; /* multiline\n" + "comment */", + "int foobar = 0; /* comment */\n" + "int bar = 0; /* multiline\n" + "comment */\n" + "int baz = 0; /* multiline\n" + "comment */"); } TEST_F(FormatTestComments, CommentReflowingCanBeTurnedOff) { @@ -553,11 +554,11 @@ TEST_F(FormatTestComments, CommentReflowingCanApplyOnlyToIndents) { } TEST_F(FormatTestComments, CorrectlyHandlesLengthOfBlockComments) { - EXPECT_EQ("double *x; /* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa */", - format("double *x; /* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa */")); - EXPECT_EQ( + verifyFormat("double *x; /* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa */", + "double *x; /* aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa */"); + verifyFormat( "void ffffffffffff(\n" " int aaaaaaaa, int bbbbbbbb,\n" " int cccccccccccc) { /*\n" @@ -567,150 +568,146 @@ TEST_F(FormatTestComments, CorrectlyHandlesLengthOfBlockComments) { " bbbbbbbbbb\n" " */\n" "}", - format("void ffffffffffff(int aaaaaaaa, int bbbbbbbb, int cccccccccccc)\n" - "{ /*\n" - " aaaaaaaaaa aaaaaaaaaaaaa\n" - " bbbbbbbbbbbbbb bbbbbbbbbb\n" - " */\n" - "}", - getLLVMStyleWithColumns(40))); + "void ffffffffffff(int aaaaaaaa, int bbbbbbbb, int cccccccccccc)\n" + "{ /*\n" + " aaaaaaaaaa aaaaaaaaaaaaa\n" + " bbbbbbbbbbbbbb bbbbbbbbbb\n" + " */\n" + "}", + getLLVMStyleWithColumns(40)); } TEST_F(FormatTestComments, DontBreakNonTrailingBlockComments) { - EXPECT_EQ("void ffffffffff(\n" - " int aaaaa /* test */);", - format("void ffffffffff(int aaaaa /* test */);", - getLLVMStyleWithColumns(35))); + verifyFormat("void ffffffffff(\n" + " int aaaaa /* test */);", + "void ffffffffff(int aaaaa /* test */);", + getLLVMStyleWithColumns(35)); } TEST_F(FormatTestComments, SplitsLongCxxComments) { - EXPECT_EQ("// A comment that\n" - "// doesn't fit on\n" - "// one line", - format("// A comment that doesn't fit on one line", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("/// A comment that\n" - "/// doesn't fit on\n" - "/// one line", - format("/// A comment that doesn't fit on one line", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("//! A comment that\n" - "//! doesn't fit on\n" - "//! one line", - format("//! A comment that doesn't fit on one line", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("// a b c d\n" - "// e f g\n" - "// h i j k", - format("// a b c d e f g h i j k", getLLVMStyleWithColumns(10))); - EXPECT_EQ( - "// a b c d\n" - "// e f g\n" - "// h i j k", - format("\\\n// a b c d e f g h i j k", getLLVMStyleWithColumns(10))); - EXPECT_EQ("if (true) // A comment that\n" - " // doesn't fit on\n" - " // one line", - format("if (true) // A comment that doesn't fit on one line ", - getLLVMStyleWithColumns(30))); - verifyNoChange("// Don't_touch_leading_whitespace", - getLLVMStyleWithColumns(20)); - EXPECT_EQ("// Add leading\n" - "// whitespace", - format("//Add leading whitespace", getLLVMStyleWithColumns(20))); - EXPECT_EQ("/// Add leading\n" - "/// whitespace", - format("///Add leading whitespace", getLLVMStyleWithColumns(20))); - EXPECT_EQ("//! Add leading\n" - "//! whitespace", - format("//!Add leading whitespace", getLLVMStyleWithColumns(20))); - EXPECT_EQ("// whitespace", format("//whitespace")); - EXPECT_EQ("// Even if it makes the line exceed the column\n" - "// limit", - format("//Even if it makes the line exceed the column limit", - getLLVMStyleWithColumns(51))); + const auto Style10 = getLLVMStyleWithColumns(10); + const auto Style20 = getLLVMStyleWithColumns(20); + const auto Style22 = getLLVMStyleWithColumns(22); + const auto Style30 = getLLVMStyleWithColumns(30); + + verifyFormat("// A comment that\n" + "// doesn't fit on\n" + "// one line", + "// A comment that doesn't fit on one line", Style20); + verifyFormat("/// A comment that\n" + "/// doesn't fit on\n" + "/// one line", + "/// A comment that doesn't fit on one line", Style20); + verifyFormat("//! A comment that\n" + "//! doesn't fit on\n" + "//! one line", + "//! A comment that doesn't fit on one line", Style20); + verifyFormat("// a b c d\n" + "// e f g\n" + "// h i j k", + "// a b c d e f g h i j k", Style10); + verifyFormat("// a b c d\n" + "// e f g\n" + "// h i j k", + "\\\n// a b c d e f g h i j k", Style10); + verifyFormat("if (true) // A comment that\n" + " // doesn't fit on\n" + " // one line", + "if (true) // A comment that doesn't fit on one line ", + Style30); + verifyNoChange("// Don't_touch_leading_whitespace", Style20); + verifyFormat("// Add leading\n" + "// whitespace", + "//Add leading whitespace", Style20); + verifyFormat("/// Add leading\n" + "/// whitespace", + "///Add leading whitespace", Style20); + verifyFormat("//! Add leading\n" + "//! whitespace", + "//!Add leading whitespace", Style20); + verifyFormat("// whitespace", "//whitespace"); + verifyFormat("// Even if it makes the line exceed the column\n" + "// limit", + "//Even if it makes the line exceed the column limit", + getLLVMStyleWithColumns(51)); verifyFormat("//--But not here"); - EXPECT_EQ("/// line 1\n" - "// add leading whitespace", - format("/// line 1\n" - "//add leading whitespace", - getLLVMStyleWithColumns(30))); - EXPECT_EQ("/// line 1\n" - "/// line 2\n" - "//! line 3\n" - "//! line 4\n" - "//! line 5\n" - "// line 6\n" - "// line 7", - format("///line 1\n" - "///line 2\n" - "//! line 3\n" - "//!line 4\n" - "//!line 5\n" - "// line 6\n" - "//line 7", - getLLVMStyleWithColumns(20))); - - EXPECT_EQ("// aa bb cc dd", - format("// aa bb cc dd ", - getLLVMStyleWithColumns(15))); - - EXPECT_EQ("// A comment before\n" - "// a macro\n" - "// definition\n" - "#define a b", - format("// A comment before a macro definition\n" - "#define a b", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("void ffffff(\n" - " int aaaaaaaaa, // wwww\n" - " int bbbbbbbbbb, // xxxxxxx\n" - " // yyyyyyyyyy\n" - " int c, int d, int e) {}", - format("void ffffff(\n" - " int aaaaaaaaa, // wwww\n" - " int bbbbbbbbbb, // xxxxxxx yyyyyyyyyy\n" - " int c, int d, int e) {}", - getLLVMStyleWithColumns(40))); - verifyFormat("//\t aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - getLLVMStyleWithColumns(20)); - EXPECT_EQ( - "#define XXX // a b c d\n" - " // e f g h", - format("#define XXX // a b c d e f g h", getLLVMStyleWithColumns(22))); - EXPECT_EQ( - "#define XXX // q w e r\n" - " // t y u i", - format("#define XXX //q w e r t y u i", getLLVMStyleWithColumns(22))); - EXPECT_EQ("{\n" - " //\n" - " //\\\n" - " // long 1 2 3 4 5\n" - "}", - format("{\n" - " //\n" - " //\\\n" - " // long 1 2 3 4 5\n" - "}", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("{\n" - " //\n" - " //\\\n" - " // long 1 2 3 4 5\n" - " // 6\n" - "}", - format("{\n" - " //\n" - " //\\\n" - " // long 1 2 3 4 5 6\n" - "}", - getLLVMStyleWithColumns(20))); - - EXPECT_EQ("//: A comment that\n" - "//: doesn't fit on\n" - "//: one line", - format("//: A comment that doesn't fit on one line", - getLLVMStyleWithColumns(20))); + verifyFormat("/// line 1\n" + "// add leading whitespace", + "/// line 1\n" + "//add leading whitespace", + Style30); + verifyFormat("/// line 1\n" + "/// line 2\n" + "//! line 3\n" + "//! line 4\n" + "//! line 5\n" + "// line 6\n" + "// line 7", + "///line 1\n" + "///line 2\n" + "//! line 3\n" + "//!line 4\n" + "//!line 5\n" + "// line 6\n" + "//line 7", + Style20); + + verifyFormat("// aa bb cc dd", + "// aa bb cc dd ", + getLLVMStyleWithColumns(15)); + + verifyFormat("// A comment before\n" + "// a macro\n" + "// definition\n" + "#define a b", + "// A comment before a macro definition\n" + "#define a b", + Style20); + verifyFormat("void ffffff(\n" + " int aaaaaaaaa, // wwww\n" + " int bbbbbbbbbb, // xxxxxxx\n" + " // yyyyyyyyyy\n" + " int c, int d, int e) {}", + "void ffffff(\n" + " int aaaaaaaaa, // wwww\n" + " int bbbbbbbbbb, // xxxxxxx yyyyyyyyyy\n" + " int c, int d, int e) {}", + getLLVMStyleWithColumns(40)); + verifyFormat("//\t aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", Style20); + verifyFormat("#define XXX // a b c d\n" + " // e f g h", + "#define XXX // a b c d e f g h", Style22); + verifyFormat("#define XXX // q w e r\n" + " // t y u i", + "#define XXX //q w e r t y u i", Style22); + verifyFormat("{\n" + " //\n" + " //\\\n" + " // long 1 2 3 4 5\n" + "}", + "{\n" + " //\n" + " //\\\n" + " // long 1 2 3 4 5\n" + "}", + Style20); + verifyFormat("{\n" + " //\n" + " //\\\n" + " // long 1 2 3 4 5\n" + " // 6\n" + "}", + "{\n" + " //\n" + " //\\\n" + " // long 1 2 3 4 5 6\n" + "}", + Style20); + + verifyFormat("//: A comment that\n" + "//: doesn't fit on\n" + "//: one line", + "//: A comment that doesn't fit on one line", Style20); verifyFormat( "//\t\t\t\tofMap(message.velocity, 0, 127, 0, ofGetWidth()\n" @@ -719,34 +716,33 @@ TEST_F(FormatTestComments, SplitsLongCxxComments) { } TEST_F(FormatTestComments, PreservesHangingIndentInCxxComments) { - EXPECT_EQ("// A comment\n" - "// that doesn't\n" - "// fit on one\n" - "// line", - format("// A comment that doesn't fit on one line", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("/// A comment\n" - "/// that doesn't\n" - "/// fit on one\n" - "/// line", - format("/// A comment that doesn't fit on one line", - getLLVMStyleWithColumns(20))); + const auto Style20 = getLLVMStyleWithColumns(20); + verifyFormat("// A comment\n" + "// that doesn't\n" + "// fit on one\n" + "// line", + "// A comment that doesn't fit on one line", Style20); + verifyFormat("/// A comment\n" + "/// that doesn't\n" + "/// fit on one\n" + "/// line", + "/// A comment that doesn't fit on one line", Style20); } TEST_F(FormatTestComments, DontSplitLineCommentsWithEscapedNewlines) { - EXPECT_EQ("// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" - "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" - "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", - format("// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" - "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" - "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")); - EXPECT_EQ("int a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" - " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" - " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - format("int a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" - " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" - " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", - getLLVMStyleWithColumns(50))); + verifyFormat("// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" + "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" + "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" + "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\\\n" + "// aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); + verifyFormat("int a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" + " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" + " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "int a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" + " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" + " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + getLLVMStyleWithColumns(50)); verifyFormat("double\n" " a; // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" " // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\\n" @@ -759,84 +755,83 @@ TEST_F(FormatTestComments, DontSplitLineCommentsWithEscapedNewlines) { TEST_F(FormatTestComments, DontIntroduceMultilineComments) { // Avoid introducing a multiline comment by breaking after `\`. + auto Style = getLLVMStyle(); for (int ColumnLimit = 15; ColumnLimit <= 17; ++ColumnLimit) { - EXPECT_EQ( - "// aaaaaaaaaa\n" - "// \\ bb", - format("// aaaaaaaaaa \\ bb", getLLVMStyleWithColumns(ColumnLimit))); - EXPECT_EQ( - "// aaaaaaaaa\n" - "// \\ bb", - format("// aaaaaaaaa \\ bb", getLLVMStyleWithColumns(ColumnLimit))); - EXPECT_EQ( - "// aaaaaaaaa\n" - "// \\ \\ bb", - format("// aaaaaaaaa \\ \\ bb", getLLVMStyleWithColumns(ColumnLimit))); + Style.ColumnLimit = ColumnLimit; + verifyFormat("// aaaaaaaaaa\n" + "// \\ bb", + "// aaaaaaaaaa \\ bb", Style); + verifyFormat("// aaaaaaaaa\n" + "// \\ bb", + "// aaaaaaaaa \\ bb", Style); + verifyFormat("// aaaaaaaaa\n" + "// \\ \\ bb", + "// aaaaaaaaa \\ \\ bb", Style); } } TEST_F(FormatTestComments, DontSplitLineCommentsWithPragmas) { FormatStyle Pragmas = getLLVMStyleWithColumns(30); Pragmas.CommentPragmas = "^ IWYU pragma:"; - EXPECT_EQ( - "// IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb", - format("// IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb", Pragmas)); - EXPECT_EQ( - "/* IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb */", - format("/* IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb */", Pragmas)); + verifyFormat("// IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb", + "// IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb", Pragmas); + verifyFormat("/* IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb */", + "/* IWYU pragma: aaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbb */", Pragmas); } TEST_F(FormatTestComments, PriorityOfCommentBreaking) { - EXPECT_EQ("if (xxx ==\n" - " yyy && // aaaaaaaaaaaa bbbbbbbbb\n" - " zzz)\n" - " q();", - format("if (xxx == yyy && // aaaaaaaaaaaa bbbbbbbbb\n" - " zzz) q();", - getLLVMStyleWithColumns(40))); - EXPECT_EQ("if (xxxxxxxxxx ==\n" - " yyy && // aaaaaa bbbbbbbb cccc\n" - " zzz)\n" - " q();", - format("if (xxxxxxxxxx == yyy && // aaaaaa bbbbbbbb cccc\n" - " zzz) q();", - getLLVMStyleWithColumns(40))); - EXPECT_EQ("if (xxxxxxxxxx &&\n" - " yyy || // aaaaaa bbbbbbbb cccc\n" - " zzz)\n" - " q();", - format("if (xxxxxxxxxx && yyy || // aaaaaa bbbbbbbb cccc\n" - " zzz) q();", - getLLVMStyleWithColumns(40))); - EXPECT_EQ("fffffffff(\n" - " &xxx, // aaaaaaaaaaaa bbbbbbbbbbb\n" - " zzz);", - format("fffffffff(&xxx, // aaaaaaaaaaaa bbbbbbbbbbb\n" - " zzz);", - getLLVMStyleWithColumns(40))); + const auto Style40 = getLLVMStyleWithColumns(40); + verifyFormat("if (xxx ==\n" + " yyy && // aaaaaaaaaaaa bbbbbbbbb\n" + " zzz)\n" + " q();", + "if (xxx == yyy && // aaaaaaaaaaaa bbbbbbbbb\n" + " zzz) q();", + Style40); + verifyFormat("if (xxxxxxxxxx ==\n" + " yyy && // aaaaaa bbbbbbbb cccc\n" + " zzz)\n" + " q();", + "if (xxxxxxxxxx == yyy && // aaaaaa bbbbbbbb cccc\n" + " zzz) q();", + Style40); + verifyFormat("if (xxxxxxxxxx &&\n" + " yyy || // aaaaaa bbbbbbbb cccc\n" + " zzz)\n" + " q();", + "if (xxxxxxxxxx && yyy || // aaaaaa bbbbbbbb cccc\n" + " zzz) q();", + Style40); + verifyFormat("fffffffff(\n" + " &xxx, // aaaaaaaaaaaa bbbbbbbbbbb\n" + " zzz);", + "fffffffff(&xxx, // aaaaaaaaaaaa bbbbbbbbbbb\n" + " zzz);", + Style40); } TEST_F(FormatTestComments, MultiLineCommentsInDefines) { - EXPECT_EQ("#define A(x) /* \\\n" - " a comment \\\n" - " inside */ \\\n" - " f();", - format("#define A(x) /* \\\n" - " a comment \\\n" - " inside */ \\\n" - " f();", - getLLVMStyleWithColumns(17))); - EXPECT_EQ("#define A( \\\n" - " x) /* \\\n" - " a comment \\\n" - " inside */ \\\n" - " f();", - format("#define A( \\\n" - " x) /* \\\n" - " a comment \\\n" - " inside */ \\\n" - " f();", - getLLVMStyleWithColumns(17))); + const auto Style17 = getLLVMStyleWithColumns(17); + verifyFormat("#define A(x) /* \\\n" + " a comment \\\n" + " inside */ \\\n" + " f();", + "#define A(x) /* \\\n" + " a comment \\\n" + " inside */ \\\n" + " f();", + Style17); + verifyFormat("#define A( \\\n" + " x) /* \\\n" + " a comment \\\n" + " inside */ \\\n" + " f();", + "#define A( \\\n" + " x) /* \\\n" + " a comment \\\n" + " inside */ \\\n" + " f();", + Style17); } TEST_F(FormatTestComments, LineCommentsInMacrosDoNotGetEscapedNewlines) { @@ -859,285 +854,285 @@ TEST_F(FormatTestComments, LineCommentsInMacrosDoNotGetEscapedNewlines) { } TEST_F(FormatTestComments, ParsesCommentsAdjacentToPPDirectives) { - EXPECT_EQ("namespace {}\n// Test\n#define A", - format("namespace {}\n // Test\n#define A")); - EXPECT_EQ("namespace {}\n/* Test */\n#define A", - format("namespace {}\n /* Test */\n#define A")); - EXPECT_EQ("namespace {}\n/* Test */ #define A", - format("namespace {}\n /* Test */ #define A")); + verifyFormat("namespace {}\n// Test\n#define A", + "namespace {}\n // Test\n#define A"); + verifyFormat("namespace {}\n/* Test */\n#define A", + "namespace {}\n /* Test */\n#define A"); + verifyFormat("namespace {}\n/* Test */ #define A", + "namespace {}\n /* Test */ #define A"); } TEST_F(FormatTestComments, KeepsLevelOfCommentBeforePPDirective) { // Keep the current level if the comment was originally not aligned with // the preprocessor directive. - EXPECT_EQ("void f() {\n" - " int i;\n" - " /* comment */\n" - "#ifdef A\n" - " int j;\n" - "}", - format("void f() {\n" - " int i;\n" - " /* comment */\n" - "#ifdef A\n" - " int j;\n" - "}")); - - EXPECT_EQ("void f() {\n" - " int i;\n" - " /* comment */\n" - "\n" - "#ifdef A\n" - " int j;\n" - "}", - format("void f() {\n" - " int i;\n" - " /* comment */\n" - "\n" - "#ifdef A\n" - " int j;\n" - "}")); - - EXPECT_EQ("int f(int i) {\n" - " if (true) {\n" - " ++i;\n" - " }\n" - " // comment\n" - "#ifdef A\n" - " int j;\n" - "#endif\n" - "}", - format("int f(int i) {\n" - " if (true) {\n" - " ++i;\n" - " }\n" - " // comment\n" - "#ifdef A\n" - "int j;\n" - "#endif\n" - "}")); - - EXPECT_EQ("int f(int i) {\n" - " if (true) {\n" - " i++;\n" - " } else {\n" - " // comment in else\n" - "#ifdef A\n" - " j++;\n" - "#endif\n" - " }\n" - "}", - format("int f(int i) {\n" - " if (true) {\n" - " i++;\n" - " } else {\n" - " // comment in else\n" - "#ifdef A\n" - " j++;\n" - "#endif\n" - " }\n" - "}")); - - EXPECT_EQ("int f(int i) {\n" - " if (true) {\n" - " i++;\n" - " } else {\n" - " /* comment in else */\n" - "#ifdef A\n" - " j++;\n" - "#endif\n" - " }\n" - "}", - format("int f(int i) {\n" - " if (true) {\n" - " i++;\n" - " } else {\n" - " /* comment in else */\n" - "#ifdef A\n" - " j++;\n" - "#endif\n" - " }\n" - "}")); + verifyFormat("void f() {\n" + " int i;\n" + " /* comment */\n" + "#ifdef A\n" + " int j;\n" + "}", + "void f() {\n" + " int i;\n" + " /* comment */\n" + "#ifdef A\n" + " int j;\n" + "}"); + + verifyFormat("void f() {\n" + " int i;\n" + " /* comment */\n" + "\n" + "#ifdef A\n" + " int j;\n" + "}", + "void f() {\n" + " int i;\n" + " /* comment */\n" + "\n" + "#ifdef A\n" + " int j;\n" + "}"); + + verifyFormat("int f(int i) {\n" + " if (true) {\n" + " ++i;\n" + " }\n" + " // comment\n" + "#ifdef A\n" + " int j;\n" + "#endif\n" + "}", + "int f(int i) {\n" + " if (true) {\n" + " ++i;\n" + " }\n" + " // comment\n" + "#ifdef A\n" + "int j;\n" + "#endif\n" + "}"); + + verifyFormat("int f(int i) {\n" + " if (true) {\n" + " i++;\n" + " } else {\n" + " // comment in else\n" + "#ifdef A\n" + " j++;\n" + "#endif\n" + " }\n" + "}", + "int f(int i) {\n" + " if (true) {\n" + " i++;\n" + " } else {\n" + " // comment in else\n" + "#ifdef A\n" + " j++;\n" + "#endif\n" + " }\n" + "}"); + + verifyFormat("int f(int i) {\n" + " if (true) {\n" + " i++;\n" + " } else {\n" + " /* comment in else */\n" + "#ifdef A\n" + " j++;\n" + "#endif\n" + " }\n" + "}", + "int f(int i) {\n" + " if (true) {\n" + " i++;\n" + " } else {\n" + " /* comment in else */\n" + "#ifdef A\n" + " j++;\n" + "#endif\n" + " }\n" + "}"); // Keep the current level if there is an empty line between the comment and // the preprocessor directive. - EXPECT_EQ("void f() {\n" - " int i;\n" - " /* comment */\n" - "\n" - "#ifdef A\n" - " int j;\n" - "}", - format("void f() {\n" - " int i;\n" - "/* comment */\n" - "\n" - "#ifdef A\n" - " int j;\n" - "}")); - - EXPECT_EQ("void f() {\n" - " int i;\n" - " return i;\n" - "}\n" - "// comment\n" - "\n" - "#ifdef A\n" - "int i;\n" - "#endif // A", - format("void f() {\n" - " int i;\n" - " return i;\n" - "}\n" - "// comment\n" - "\n" - "#ifdef A\n" - "int i;\n" - "#endif // A")); - - EXPECT_EQ("int f(int i) {\n" - " if (true) {\n" - " ++i;\n" - " }\n" - " // comment\n" - "\n" - "#ifdef A\n" - " int j;\n" - "#endif\n" - "}", - format("int f(int i) {\n" - " if (true) {\n" - " ++i;\n" - " }\n" - " // comment\n" - "\n" - "#ifdef A\n" - " int j;\n" - "#endif\n" - "}")); - - EXPECT_EQ("int f(int i) {\n" - " if (true) {\n" - " i++;\n" - " } else {\n" - " // comment in else\n" - "\n" - "#ifdef A\n" - " j++;\n" - "#endif\n" - " }\n" - "}", - format("int f(int i) {\n" - " if (true) {\n" - " i++;\n" - " } else {\n" - "// comment in else\n" - "\n" - "#ifdef A\n" - " j++;\n" - "#endif\n" - " }\n" - "}")); - - EXPECT_EQ("int f(int i) {\n" - " if (true) {\n" - " i++;\n" - " } else {\n" - " /* comment in else */\n" - "\n" - "#ifdef A\n" - " j++;\n" - "#endif\n" - " }\n" - "}", - format("int f(int i) {\n" - " if (true) {\n" - " i++;\n" - " } else {\n" - "/* comment in else */\n" - "\n" - "#ifdef A\n" - " j++;\n" - "#endif\n" - " }\n" - "}")); + verifyFormat("void f() {\n" + " int i;\n" + " /* comment */\n" + "\n" + "#ifdef A\n" + " int j;\n" + "}", + "void f() {\n" + " int i;\n" + "/* comment */\n" + "\n" + "#ifdef A\n" + " int j;\n" + "}"); + + verifyFormat("void f() {\n" + " int i;\n" + " return i;\n" + "}\n" + "// comment\n" + "\n" + "#ifdef A\n" + "int i;\n" + "#endif // A", + "void f() {\n" + " int i;\n" + " return i;\n" + "}\n" + "// comment\n" + "\n" + "#ifdef A\n" + "int i;\n" + "#endif // A"); + + verifyFormat("int f(int i) {\n" + " if (true) {\n" + " ++i;\n" + " }\n" + " // comment\n" + "\n" + "#ifdef A\n" + " int j;\n" + "#endif\n" + "}", + "int f(int i) {\n" + " if (true) {\n" + " ++i;\n" + " }\n" + " // comment\n" + "\n" + "#ifdef A\n" + " int j;\n" + "#endif\n" + "}"); + + verifyFormat("int f(int i) {\n" + " if (true) {\n" + " i++;\n" + " } else {\n" + " // comment in else\n" + "\n" + "#ifdef A\n" + " j++;\n" + "#endif\n" + " }\n" + "}", + "int f(int i) {\n" + " if (true) {\n" + " i++;\n" + " } else {\n" + "// comment in else\n" + "\n" + "#ifdef A\n" + " j++;\n" + "#endif\n" + " }\n" + "}"); + + verifyFormat("int f(int i) {\n" + " if (true) {\n" + " i++;\n" + " } else {\n" + " /* comment in else */\n" + "\n" + "#ifdef A\n" + " j++;\n" + "#endif\n" + " }\n" + "}", + "int f(int i) {\n" + " if (true) {\n" + " i++;\n" + " } else {\n" + "/* comment in else */\n" + "\n" + "#ifdef A\n" + " j++;\n" + "#endif\n" + " }\n" + "}"); // Align with the preprocessor directive if the comment was originally aligned // with the preprocessor directive and there is no newline between the comment // and the preprocessor directive. - EXPECT_EQ("void f() {\n" - " int i;\n" - "/* comment */\n" - "#ifdef A\n" - " int j;\n" - "}", - format("void f() {\n" - " int i;\n" - "/* comment */\n" - "#ifdef A\n" - " int j;\n" - "}")); - - EXPECT_EQ("int f(int i) {\n" - " if (true) {\n" - " ++i;\n" - " }\n" - "// comment\n" - "#ifdef A\n" - " int j;\n" - "#endif\n" - "}", - format("int f(int i) {\n" - " if (true) {\n" - " ++i;\n" - " }\n" - "// comment\n" - "#ifdef A\n" - " int j;\n" - "#endif\n" - "}")); - - EXPECT_EQ("int f(int i) {\n" - " if (true) {\n" - " i++;\n" - " } else {\n" - "// comment in else\n" - "#ifdef A\n" - " j++;\n" - "#endif\n" - " }\n" - "}", - format("int f(int i) {\n" - " if (true) {\n" - " i++;\n" - " } else {\n" - " // comment in else\n" - " #ifdef A\n" - " j++;\n" - "#endif\n" - " }\n" - "}")); - - EXPECT_EQ("int f(int i) {\n" - " if (true) {\n" - " i++;\n" - " } else {\n" - "/* comment in else */\n" - "#ifdef A\n" - " j++;\n" - "#endif\n" - " }\n" - "}", - format("int f(int i) {\n" - " if (true) {\n" - " i++;\n" - " } else {\n" - " /* comment in else */\n" - " #ifdef A\n" - " j++;\n" - "#endif\n" - " }\n" - "}")); + verifyFormat("void f() {\n" + " int i;\n" + "/* comment */\n" + "#ifdef A\n" + " int j;\n" + "}", + "void f() {\n" + " int i;\n" + "/* comment */\n" + "#ifdef A\n" + " int j;\n" + "}"); + + verifyFormat("int f(int i) {\n" + " if (true) {\n" + " ++i;\n" + " }\n" + "// comment\n" + "#ifdef A\n" + " int j;\n" + "#endif\n" + "}", + "int f(int i) {\n" + " if (true) {\n" + " ++i;\n" + " }\n" + "// comment\n" + "#ifdef A\n" + " int j;\n" + "#endif\n" + "}"); + + verifyFormat("int f(int i) {\n" + " if (true) {\n" + " i++;\n" + " } else {\n" + "// comment in else\n" + "#ifdef A\n" + " j++;\n" + "#endif\n" + " }\n" + "}", + "int f(int i) {\n" + " if (true) {\n" + " i++;\n" + " } else {\n" + " // comment in else\n" + " #ifdef A\n" + " j++;\n" + "#endif\n" + " }\n" + "}"); + + verifyFormat("int f(int i) {\n" + " if (true) {\n" + " i++;\n" + " } else {\n" + "/* comment in else */\n" + "#ifdef A\n" + " j++;\n" + "#endif\n" + " }\n" + "}", + "int f(int i) {\n" + " if (true) {\n" + " i++;\n" + " } else {\n" + " /* comment in else */\n" + " #ifdef A\n" + " j++;\n" + "#endif\n" + " }\n" + "}"); constexpr StringRef Code("void func() {\n" " // clang-format off\n" @@ -1189,245 +1184,242 @@ TEST_F(FormatTestComments, CommentsBetweenUnbracedBodyAndPPDirective) { } TEST_F(FormatTestComments, SplitsLongLinesInComments) { + const auto Style10 = getLLVMStyleWithColumns(10); + const auto Style15 = getLLVMStyleWithColumns(15); + const auto Style20 = getLLVMStyleWithColumns(20); + // FIXME: Do we need to fix up the " */" at the end? // It doesn't look like any of our current logic triggers this. - EXPECT_EQ("/* This is a long\n" - " * comment that\n" - " * doesn't fit on\n" - " * one line. */", - format("/* " - "This is a long " - "comment that " - "doesn't " - "fit on one line. */", - getLLVMStyleWithColumns(20))); - EXPECT_EQ( - "/* a b c d\n" - " * e f g\n" - " * h i j k\n" - " */", - format("/* a b c d e f g h i j k */", getLLVMStyleWithColumns(10))); - EXPECT_EQ( - "/* a b c d\n" - " * e f g\n" - " * h i j k\n" - " */", - format("\\\n/* a b c d e f g h i j k */", getLLVMStyleWithColumns(10))); - EXPECT_EQ("/*\n" - "This is a long\n" - "comment that doesn't\n" - "fit on one line.\n" - "*/", - format("/*\n" - "This is a long " - "comment that doesn't " - "fit on one line. \n" - "*/", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("/*\n" - " * This is a long\n" - " * comment that\n" - " * doesn't fit on\n" - " * one line.\n" - " */", - format("/* \n" - " * This is a long " - " comment that " - " doesn't fit on " - " one line. \n" - " */", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("/*\n" - " * This_is_a_comment_with_words_that_dont_fit_on_one_line\n" - " * so_it_should_be_broken\n" - " * wherever_a_space_occurs\n" - " */", - format("/*\n" - " * This_is_a_comment_with_words_that_dont_fit_on_one_line " - " so_it_should_be_broken " - " wherever_a_space_occurs \n" - " */", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("/*\n" - " * This_comment_can_not_be_broken_into_lines\n" - " */", - format("/*\n" - " * This_comment_can_not_be_broken_into_lines\n" - " */", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("{\n" - " /*\n" - " This is another\n" - " long comment that\n" - " doesn't fit on one\n" - " line 1234567890\n" - " */\n" - "}", - format("{\n" - "/*\n" - "This is another " - " long comment that " - " doesn't fit on one" - " line 1234567890\n" - "*/\n" - "}", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("{\n" - " /*\n" - " * This i s\n" - " * another comment\n" - " * t hat doesn' t\n" - " * fit on one l i\n" - " * n e\n" - " */\n" - "}", - format("{\n" - "/*\n" - " * This i s" - " another comment" - " t hat doesn' t" - " fit on one l i" - " n e\n" - " */\n" - "}", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("/*\n" - " * This is a long\n" - " * comment that\n" - " * doesn't fit on\n" - " * one line\n" - " */", - format(" /*\n" - " * This is a long comment that doesn't fit on one line\n" - " */", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("{\n" - " if (something) /* This is a\n" - " long\n" - " comment */\n" - " ;\n" - "}", - format("{\n" - " if (something) /* This is a long comment */\n" - " ;\n" - "}", - getLLVMStyleWithColumns(30))); - - EXPECT_EQ("/* A comment before\n" - " * a macro\n" - " * definition */\n" - "#define a b", - format("/* A comment before a macro definition */\n" - "#define a b", - getLLVMStyleWithColumns(20))); - - EXPECT_EQ("/* some comment\n" - " * a comment that\n" - " * we break another\n" - " * comment we have\n" - " * to break a left\n" - " * comment\n" - " */", - format(" /* some comment\n" - " * a comment that we break\n" - " * another comment we have to break\n" - "* a left comment\n" - " */", - getLLVMStyleWithColumns(20))); - - EXPECT_EQ("/**\n" - " * multiline block\n" - " * comment\n" - " *\n" - " */", - format("/**\n" - " * multiline block comment\n" - " *\n" - " */", - getLLVMStyleWithColumns(20))); + verifyFormat("/* This is a long\n" + " * comment that\n" + " * doesn't fit on\n" + " * one line. */", + "/* " + "This is a long " + "comment that " + "doesn't " + "fit on one line. */", + Style20); + verifyFormat("/* a b c d\n" + " * e f g\n" + " * h i j k\n" + " */", + "/* a b c d e f g h i j k */", Style10); + verifyFormat("/* a b c d\n" + " * e f g\n" + " * h i j k\n" + " */", + "\\\n/* a b c d e f g h i j k */", Style10); + verifyFormat("/*\n" + "This is a long\n" + "comment that doesn't\n" + "fit on one line.\n" + "*/", + "/*\n" + "This is a long " + "comment that doesn't " + "fit on one line. \n" + "*/", + Style20); + verifyFormat("/*\n" + " * This is a long\n" + " * comment that\n" + " * doesn't fit on\n" + " * one line.\n" + " */", + "/* \n" + " * This is a long " + " comment that " + " doesn't fit on " + " one line. \n" + " */", + Style20); + verifyFormat("/*\n" + " * This_is_a_comment_with_words_that_dont_fit_on_one_line\n" + " * so_it_should_be_broken\n" + " * wherever_a_space_occurs\n" + " */", + "/*\n" + " * This_is_a_comment_with_words_that_dont_fit_on_one_line " + " so_it_should_be_broken " + " wherever_a_space_occurs \n" + " */", + Style20); + verifyFormat("/*\n" + " * This_comment_can_not_be_broken_into_lines\n" + " */", + "/*\n" + " * This_comment_can_not_be_broken_into_lines\n" + " */", + Style20); + verifyFormat("{\n" + " /*\n" + " This is another\n" + " long comment that\n" + " doesn't fit on one\n" + " line 1234567890\n" + " */\n" + "}", + "{\n" + "/*\n" + "This is another " + " long comment that " + " doesn't fit on one" + " line 1234567890\n" + "*/\n" + "}", + Style20); + verifyFormat("{\n" + " /*\n" + " * This i s\n" + " * another comment\n" + " * t hat doesn' t\n" + " * fit on one l i\n" + " * n e\n" + " */\n" + "}", + "{\n" + "/*\n" + " * This i s" + " another comment" + " t hat doesn' t" + " fit on one l i" + " n e\n" + " */\n" + "}", + Style20); + verifyFormat("/*\n" + " * This is a long\n" + " * comment that\n" + " * doesn't fit on\n" + " * one line\n" + " */", + " /*\n" + " * This is a long comment that doesn't fit on one line\n" + " */", + Style20); + verifyFormat("{\n" + " if (something) /* This is a\n" + " long\n" + " comment */\n" + " ;\n" + "}", + "{\n" + " if (something) /* This is a long comment */\n" + " ;\n" + "}", + getLLVMStyleWithColumns(30)); + + verifyFormat("/* A comment before\n" + " * a macro\n" + " * definition */\n" + "#define a b", + "/* A comment before a macro definition */\n" + "#define a b", + Style20); + + verifyFormat("/* some comment\n" + " * a comment that\n" + " * we break another\n" + " * comment we have\n" + " * to break a left\n" + " * comment\n" + " */", + " /* some comment\n" + " * a comment that we break\n" + " * another comment we have to break\n" + "* a left comment\n" + " */", + Style20); + + verifyFormat("/**\n" + " * multiline block\n" + " * comment\n" + " *\n" + " */", + "/**\n" + " * multiline block comment\n" + " *\n" + " */", + Style20); // This reproduces a crashing bug where both adaptStartOfLine and // getCommentSplit were trying to wrap after the "/**". - verifyFormat("/** multilineblockcommentwithnowrapopportunity */", - getLLVMStyleWithColumns(20)); + verifyFormat("/** multilineblockcommentwithnowrapopportunity */", Style20); - EXPECT_EQ("/*\n" - "\n" - "\n" - " */", - format(" /* \n" - " \n" - " \n" - " */")); - - EXPECT_EQ("/* a a */", - format("/* a a */", getLLVMStyleWithColumns(15))); - EXPECT_EQ("/* a a bc */", - format("/* a a bc */", getLLVMStyleWithColumns(15))); - EXPECT_EQ("/* aaa aaa\n" - " * aaaaa */", - format("/* aaa aaa aaaaa */", getLLVMStyleWithColumns(15))); - EXPECT_EQ("/* aaa aaa\n" - " * aaaaa */", - format("/* aaa aaa aaaaa */", getLLVMStyleWithColumns(15))); + verifyFormat("/*\n" + "\n" + "\n" + " */", + " /* \n" + " \n" + " \n" + " */"); + + verifyFormat("/* a a */", "/* a a */", Style15); + verifyFormat("/* a a bc */", "/* a a bc */", Style15); + verifyFormat("/* aaa aaa\n" + " * aaaaa */", + "/* aaa aaa aaaaa */", Style15); + verifyFormat("/* aaa aaa\n" + " * aaaaa */", + "/* aaa aaa aaaaa */", Style15); } TEST_F(FormatTestComments, SplitsLongLinesInCommentsInPreprocessor) { - EXPECT_EQ("#define X \\\n" - " /* \\\n" - " Test \\\n" - " Macro comment \\\n" - " with a long \\\n" - " line \\\n" - " */ \\\n" - " A + B", - format("#define X \\\n" - " /*\n" - " Test\n" - " Macro comment with a long line\n" - " */ \\\n" - " A + B", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("#define X \\\n" - " /* Macro comment \\\n" - " with a long \\\n" - " line */ \\\n" - " A + B", - format("#define X \\\n" - " /* Macro comment with a long\n" - " line */ \\\n" - " A + B", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("#define X \\\n" - " /* Macro comment \\\n" - " * with a long \\\n" - " * line */ \\\n" - " A + B", - format("#define X \\\n" - " /* Macro comment with a long line */ \\\n" - " A + B", - getLLVMStyleWithColumns(20))); + const auto Style20 = getLLVMStyleWithColumns(20); + verifyFormat("#define X \\\n" + " /* \\\n" + " Test \\\n" + " Macro comment \\\n" + " with a long \\\n" + " line \\\n" + " */ \\\n" + " A + B", + "#define X \\\n" + " /*\n" + " Test\n" + " Macro comment with a long line\n" + " */ \\\n" + " A + B", + Style20); + verifyFormat("#define X \\\n" + " /* Macro comment \\\n" + " with a long \\\n" + " line */ \\\n" + " A + B", + "#define X \\\n" + " /* Macro comment with a long\n" + " line */ \\\n" + " A + B", + Style20); + verifyFormat("#define X \\\n" + " /* Macro comment \\\n" + " * with a long \\\n" + " * line */ \\\n" + " A + B", + "#define X \\\n" + " /* Macro comment with a long line */ \\\n" + " A + B", + Style20); } TEST_F(FormatTestComments, KeepsTrailingPPCommentsAndSectionCommentsSeparate) { verifyFormat("#ifdef A // line about A\n" "// section comment\n" - "#endif", - getLLVMStyleWithColumns(80)); + "#endif"); + verifyFormat("#ifdef A // line 1 about A\n" + " // line 2 about A\n" + "// section comment\n" + "#endif"); verifyFormat("#ifdef A // line 1 about A\n" " // line 2 about A\n" "// section comment\n" "#endif", - getLLVMStyleWithColumns(80)); - EXPECT_EQ("#ifdef A // line 1 about A\n" - " // line 2 about A\n" - "// section comment\n" - "#endif", - format("#ifdef A // line 1 about A\n" - " // line 2 about A\n" - "// section comment\n" - "#endif", - getLLVMStyleWithColumns(80))); + "#ifdef A // line 1 about A\n" + " // line 2 about A\n" + "// section comment\n" + "#endif"); verifyFormat("int f() {\n" " int i;\n" "#ifdef A // comment about A\n" @@ -1438,46 +1430,46 @@ TEST_F(FormatTestComments, KeepsTrailingPPCommentsAndSectionCommentsSeparate) { " // section comment 3\n" " i = 4;\n" "#endif\n" - "}", - getLLVMStyleWithColumns(80)); + "}"); } TEST_F(FormatTestComments, AlignsPPElseEndifComments) { + const auto Style20 = getLLVMStyleWithColumns(20); verifyFormat("#if A\n" "#else // A\n" "int iiii;\n" "#endif // B", - getLLVMStyleWithColumns(20)); + Style20); verifyFormat("#if A\n" "#else // A\n" "int iiii; // CC\n" "#endif // B", - getLLVMStyleWithColumns(20)); - EXPECT_EQ("#if A\n" - "#else // A1\n" - " // A2\n" - "int ii;\n" - "#endif // B", - format("#if A\n" - "#else // A1\n" - " // A2\n" - "int ii;\n" - "#endif // B", - getLLVMStyleWithColumns(20))); + Style20); + verifyFormat("#if A\n" + "#else // A1\n" + " // A2\n" + "int ii;\n" + "#endif // B", + "#if A\n" + "#else // A1\n" + " // A2\n" + "int ii;\n" + "#endif // B", + Style20); } TEST_F(FormatTestComments, CommentsInStaticInitializers) { - EXPECT_EQ( + verifyFormat( "static SomeType type = {aaaaaaaaaaaaaaaaaaaa, /* comment */\n" " aaaaaaaaaaaaaaaaaaaa /* comment */,\n" " /* comment */ aaaaaaaaaaaaaaaaaaaa,\n" " aaaaaaaaaaaaaaaaaaaa, // comment\n" " aaaaaaaaaaaaaaaaaaaa};", - format("static SomeType type = { aaaaaaaaaaaaaaaaaaaa , /* comment */\n" - " aaaaaaaaaaaaaaaaaaaa /* comment */ ,\n" - " /* comment */ aaaaaaaaaaaaaaaaaaaa ,\n" - " aaaaaaaaaaaaaaaaaaaa , // comment\n" - " aaaaaaaaaaaaaaaaaaaa };")); + "static SomeType type = { aaaaaaaaaaaaaaaaaaaa , /* comment */\n" + " aaaaaaaaaaaaaaaaaaaa /* comment */ ,\n" + " /* comment */ aaaaaaaaaaaaaaaaaaaa ,\n" + " aaaaaaaaaaaaaaaaaaaa , // comment\n" + " aaaaaaaaaaaaaaaaaaaa };"); verifyFormat("static SomeType type = {aaaaaaaaaaa, // comment for aa...\n" " bbbbbbbbbbb, ccccccccccc};"); verifyFormat("static SomeType type = {aaaaaaaaaaa,\n" @@ -1500,32 +1492,32 @@ TEST_F(FormatTestComments, CommentsInStaticInitializers) { " {// Group #3\n" " g, h, i}};"); - EXPECT_EQ("S s = {\n" - " // Some comment\n" - " a,\n" - "\n" - " // Comment after empty line\n" - " b}", - format("S s = {\n" - " // Some comment\n" - " a,\n" - " \n" - " // Comment after empty line\n" - " b\n" - "}")); - EXPECT_EQ("S s = {\n" - " /* Some comment */\n" - " a,\n" - "\n" - " /* Comment after empty line */\n" - " b}", - format("S s = {\n" - " /* Some comment */\n" - " a,\n" - " \n" - " /* Comment after empty line */\n" - " b\n" - "}")); + verifyFormat("S s = {\n" + " // Some comment\n" + " a,\n" + "\n" + " // Comment after empty line\n" + " b}", + "S s = {\n" + " // Some comment\n" + " a,\n" + " \n" + " // Comment after empty line\n" + " b\n" + "}"); + verifyFormat("S s = {\n" + " /* Some comment */\n" + " a,\n" + "\n" + " /* Comment after empty line */\n" + " b}", + "S s = {\n" + " /* Some comment */\n" + " a,\n" + " \n" + " /* Comment after empty line */\n" + " b\n" + "}"); verifyFormat("const uint8_t aaaaaaaaaaaaaaaaaaaaaa[0] = {\n" " 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // comment\n" " 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // comment\n" @@ -1533,486 +1525,485 @@ TEST_F(FormatTestComments, CommentsInStaticInitializers) { } TEST_F(FormatTestComments, LineCommentsAfterRightBrace) { - EXPECT_EQ("if (true) { // comment about branch\n" - " // comment about f\n" - " f();\n" - "}", - format("if (true) { // comment about branch\n" - " // comment about f\n" - " f();\n" - "}", - getLLVMStyleWithColumns(80))); - EXPECT_EQ("if (1) { // if line 1\n" - " // if line 2\n" - " // if line 3\n" - " // f line 1\n" - " // f line 2\n" - " f();\n" - "} else { // else line 1\n" - " // else line 2\n" - " // else line 3\n" - " // g line 1\n" - " g();\n" - "}", - format("if (1) { // if line 1\n" - " // if line 2\n" - " // if line 3\n" - " // f line 1\n" - " // f line 2\n" - " f();\n" - "} else { // else line 1\n" - " // else line 2\n" - " // else line 3\n" - " // g line 1\n" - " g();\n" - "}")); - EXPECT_EQ("do { // line 1\n" - " // line 2\n" - " // line 3\n" - " f();\n" - "} while (true);", - format("do { // line 1\n" - " // line 2\n" - " // line 3\n" - " f();\n" - "} while (true);", - getLLVMStyleWithColumns(80))); - EXPECT_EQ("while (a < b) { // line 1\n" - " // line 2\n" - " // line 3\n" - " f();\n" - "}", - format("while (a < b) {// line 1\n" - " // line 2\n" - " // line 3\n" - " f();\n" - "}", - getLLVMStyleWithColumns(80))); + verifyFormat("if (true) { // comment about branch\n" + " // comment about f\n" + " f();\n" + "}", + "if (true) { // comment about branch\n" + " // comment about f\n" + " f();\n" + "}"); + verifyFormat("if (1) { // if line 1\n" + " // if line 2\n" + " // if line 3\n" + " // f line 1\n" + " // f line 2\n" + " f();\n" + "} else { // else line 1\n" + " // else line 2\n" + " // else line 3\n" + " // g line 1\n" + " g();\n" + "}", + "if (1) { // if line 1\n" + " // if line 2\n" + " // if line 3\n" + " // f line 1\n" + " // f line 2\n" + " f();\n" + "} else { // else line 1\n" + " // else line 2\n" + " // else line 3\n" + " // g line 1\n" + " g();\n" + "}"); + verifyFormat("do { // line 1\n" + " // line 2\n" + " // line 3\n" + " f();\n" + "} while (true);", + "do { // line 1\n" + " // line 2\n" + " // line 3\n" + " f();\n" + "} while (true);"); + verifyFormat("while (a < b) { // line 1\n" + " // line 2\n" + " // line 3\n" + " f();\n" + "}", + "while (a < b) {// line 1\n" + " // line 2\n" + " // line 3\n" + " f();\n" + "}"); } TEST_F(FormatTestComments, ReflowsComments) { + const auto Style20 = getLLVMStyleWithColumns(20); + const auto Style22 = getLLVMStyleWithColumns(22); // Break a long line and reflow with the full next line. - EXPECT_EQ("// long long long\n" - "// long long", - format("// long long long long\n" - "// long", - getLLVMStyleWithColumns(20))); + verifyFormat("// long long long\n" + "// long long", + "// long long long long\n" + "// long", + Style20); // Keep the trailing newline while reflowing. - EXPECT_EQ("// long long long\n" - "// long long", - format("// long long long long\n" - "// long", - getLLVMStyleWithColumns(20))); + verifyFormat("// long long long\n" + "// long long", + "// long long long long\n" + "// long", + Style20); // Break a long line and reflow with a part of the next line. - EXPECT_EQ("// long long long\n" - "// long long\n" - "// long_long", - format("// long long long long\n" - "// long long_long", - getLLVMStyleWithColumns(20))); + verifyFormat("// long long long\n" + "// long long\n" + "// long_long", + "// long long long long\n" + "// long long_long", + Style20); // Break but do not reflow if the first word from the next line is too long. - EXPECT_EQ("// long long long\n" - "// long\n" - "// long_long_long", - format("// long long long long\n" - "// long_long_long", - getLLVMStyleWithColumns(20))); + verifyFormat("// long long long\n" + "// long\n" + "// long_long_long", + "// long long long long\n" + "// long_long_long", + Style20); // Don't break or reflow short lines. verifyFormat("// long\n" "// long long long lo\n" "// long long long lo\n" "// long", - getLLVMStyleWithColumns(20)); + Style20); // Keep prefixes and decorations while reflowing. - EXPECT_EQ("/// long long long\n" - "/// long long", - format("/// long long long long\n" - "/// long", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("//! long long long\n" - "//! long long", - format("//! long long long long\n" - "//! long", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("/* long long long\n" - " * long long */", - format("/* long long long long\n" - " * long */", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("///< long long long\n" - "///< long long", - format("///< long long long long\n" - "///< long", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("//!< long long long\n" - "//!< long long", - format("//!< long long long long\n" - "//!< long", - getLLVMStyleWithColumns(20))); + verifyFormat("/// long long long\n" + "/// long long", + "/// long long long long\n" + "/// long", + Style20); + verifyFormat("//! long long long\n" + "//! long long", + "//! long long long long\n" + "//! long", + Style20); + verifyFormat("/* long long long\n" + " * long long */", + "/* long long long long\n" + " * long */", + Style20); + verifyFormat("///< long long long\n" + "///< long long", + "///< long long long long\n" + "///< long", + Style20); + verifyFormat("//!< long long long\n" + "//!< long long", + "//!< long long long long\n" + "//!< long", + Style20); // Don't bring leading whitespace up while reflowing. - EXPECT_EQ("/* long long long\n" - " * long long long\n" - " */", - format("/* long long long long\n" - " * long long\n" - " */", - getLLVMStyleWithColumns(20))); + verifyFormat("/* long long long\n" + " * long long long\n" + " */", + "/* long long long long\n" + " * long long\n" + " */", + Style20); // Reflow the last line of a block comment with its trailing '*/'. - EXPECT_EQ("/* long long long\n" - " long long */", - format("/* long long long long\n" - " long */", - getLLVMStyleWithColumns(20))); + verifyFormat("/* long long long\n" + " long long */", + "/* long long long long\n" + " long */", + Style20); // Reflow two short lines; keep the postfix of the last one. - EXPECT_EQ("/* long long long\n" - " * long long long */", - format("/* long long long long\n" - " * long\n" - " * long */", - getLLVMStyleWithColumns(20))); + verifyFormat("/* long long long\n" + " * long long long */", + "/* long long long long\n" + " * long\n" + " * long */", + Style20); // Put the postfix of the last short reflow line on a newline if it doesn't // fit. - EXPECT_EQ("/* long long long\n" - " * long long longg\n" - " */", - format("/* long long long long\n" - " * long\n" - " * longg */", - getLLVMStyleWithColumns(20))); + verifyFormat("/* long long long\n" + " * long long longg\n" + " */", + "/* long long long long\n" + " * long\n" + " * longg */", + Style20); // Reflow lines with leading whitespace. - EXPECT_EQ("{\n" - " /*\n" - " * long long long\n" - " * long long long\n" - " * long long long\n" - " */\n" - "}", - format("{\n" - "/*\n" - " * long long long long\n" - " * long\n" - " * long long long long\n" - " */\n" - "}", - getLLVMStyleWithColumns(20))); + verifyFormat("{\n" + " /*\n" + " * long long long\n" + " * long long long\n" + " * long long long\n" + " */\n" + "}", + "{\n" + "/*\n" + " * long long long long\n" + " * long\n" + " * long long long long\n" + " */\n" + "}", + Style20); // Break single line block comments that are first in the line with ' *' // decoration. - EXPECT_EQ("/* long long long\n" - " * long */", - format("/* long long long long */", getLLVMStyleWithColumns(20))); + verifyFormat("/* long long long\n" + " * long */", + "/* long long long long */", Style20); // Break single line block comment that are not first in the line with ' ' // decoration. - EXPECT_EQ("int i; /* long long\n" - " long */", - format("int i; /* long long long */", getLLVMStyleWithColumns(20))); + verifyFormat("int i; /* long long\n" + " long */", + "int i; /* long long long */", Style20); // Reflow a line that goes just over the column limit. - EXPECT_EQ("// long long long\n" - "// lon long", - format("// long long long lon\n" - "// long", - getLLVMStyleWithColumns(20))); + verifyFormat("// long long long\n" + "// lon long", + "// long long long lon\n" + "// long", + Style20); // Stop reflowing if the next line has a different indentation than the // previous line. - EXPECT_EQ("// long long long\n" - "// long\n" - "// long long\n" - "// long", - format("// long long long long\n" - "// long long\n" - "// long", - getLLVMStyleWithColumns(20))); + verifyFormat("// long long long\n" + "// long\n" + "// long long\n" + "// long", + "// long long long long\n" + "// long long\n" + "// long", + Style20); // Reflow into the last part of a really long line that has been broken into // multiple lines. - EXPECT_EQ("// long long long\n" - "// long long long\n" - "// long long long", - format("// long long long long long long long long\n" - "// long", - getLLVMStyleWithColumns(20))); + verifyFormat("// long long long\n" + "// long long long\n" + "// long long long", + "// long long long long long long long long\n" + "// long", + Style20); // Break the first line, then reflow the beginning of the second and third // line up. - EXPECT_EQ("// long long long\n" - "// lon1 lon2 lon2\n" - "// lon2 lon3 lon3", - format("// long long long lon1\n" - "// lon2 lon2 lon2\n" - "// lon3 lon3", - getLLVMStyleWithColumns(20))); + verifyFormat("// long long long\n" + "// lon1 lon2 lon2\n" + "// lon2 lon3 lon3", + "// long long long lon1\n" + "// lon2 lon2 lon2\n" + "// lon3 lon3", + Style20); // Reflow the beginning of the second line, then break the rest. - EXPECT_EQ("// long long long\n" - "// lon1 lon2 lon2\n" - "// lon2 lon2 lon2\n" - "// lon3", - format("// long long long lon1\n" - "// lon2 lon2 lon2 lon2 lon2 lon3", - getLLVMStyleWithColumns(20))); + verifyFormat("// long long long\n" + "// lon1 lon2 lon2\n" + "// lon2 lon2 lon2\n" + "// lon3", + "// long long long lon1\n" + "// lon2 lon2 lon2 lon2 lon2 lon3", + Style20); // Shrink the first line, then reflow the second line up. - EXPECT_EQ("// long long long", format("// long long\n" - "// long", - getLLVMStyleWithColumns(20))); + verifyFormat("// long long long", + "// long long\n" + "// long", + Style20); // Don't shrink leading whitespace. - verifyNoChange("int i; /// a", getLLVMStyleWithColumns(20)); + verifyNoChange("int i; /// a", Style20); // Shrink trailing whitespace if there is no postfix and reflow. - EXPECT_EQ("// long long long\n" - "// long long", - format("// long long long long \n" - "// long", - getLLVMStyleWithColumns(20))); + verifyFormat("// long long long\n" + "// long long", + "// long long long long \n" + "// long", + Style20); // Shrink trailing whitespace to a single one if there is postfix. - EXPECT_EQ("/* long long long */", - format("/* long long long */", getLLVMStyleWithColumns(20))); + verifyFormat("/* long long long */", "/* long long long */", Style20); // Break a block comment postfix if exceeding the line limit. - EXPECT_EQ("/* long\n" - " */", - format("/* long */", getLLVMStyleWithColumns(20))); + verifyFormat("/* long\n" + " */", + "/* long */", Style20); // Reflow indented comments. - EXPECT_EQ("{\n" - " // long long long\n" - " // long long\n" - " int i; /* long lon\n" - " g long\n" - " */\n" - "}", - format("{\n" - " // long long long long\n" - " // long\n" - " int i; /* long lon g\n" - " long */\n" - "}", - getLLVMStyleWithColumns(20))); + verifyFormat("{\n" + " // long long long\n" + " // long long\n" + " int i; /* long lon\n" + " g long\n" + " */\n" + "}", + "{\n" + " // long long long long\n" + " // long\n" + " int i; /* long lon g\n" + " long */\n" + "}", + Style20); // Don't realign trailing comments after reflow has happened. - EXPECT_EQ("// long long long\n" - "// long long\n" - "long i; // long", - format("// long long long long\n" - "// long\n" - "long i; // long", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("// long long long\n" - "// longng long long\n" - "// long lo", - format("// long long long longng\n" - "// long long long\n" - "// lo", - getLLVMStyleWithColumns(20))); + verifyFormat("// long long long\n" + "// long long\n" + "long i; // long", + "// long long long long\n" + "// long\n" + "long i; // long", + Style20); + verifyFormat("// long long long\n" + "// longng long long\n" + "// long lo", + "// long long long longng\n" + "// long long long\n" + "// lo", + Style20); // Reflow lines after a broken line. - EXPECT_EQ("int a; // Trailing\n" - " // comment on\n" - " // 2 or 3\n" - " // lines.", - format("int a; // Trailing comment\n" - " // on 2\n" - " // or 3\n" - " // lines.", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("/// This long line\n" - "/// gets reflown.", - format("/// This long line gets\n" - "/// reflown.", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("//! This long line\n" - "//! gets reflown.", - format(" //! This long line gets\n" - " //! reflown.", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("/* This long line\n" - " * gets reflown.\n" - " */", - format("/* This long line gets\n" - " * reflown.\n" - " */", - getLLVMStyleWithColumns(20))); + verifyFormat("int a; // Trailing\n" + " // comment on\n" + " // 2 or 3\n" + " // lines.", + "int a; // Trailing comment\n" + " // on 2\n" + " // or 3\n" + " // lines.", + Style20); + verifyFormat("/// This long line\n" + "/// gets reflown.", + "/// This long line gets\n" + "/// reflown.", + Style20); + verifyFormat("//! This long line\n" + "//! gets reflown.", + " //! This long line gets\n" + " //! reflown.", + Style20); + verifyFormat("/* This long line\n" + " * gets reflown.\n" + " */", + "/* This long line gets\n" + " * reflown.\n" + " */", + Style20); // Reflow after indentation makes a line too long. - EXPECT_EQ("{\n" - " // long long long\n" - " // lo long\n" - "}", - format("{\n" - "// long long long lo\n" - "// long\n" - "}", - getLLVMStyleWithColumns(20))); + verifyFormat("{\n" + " // long long long\n" + " // lo long\n" + "}", + "{\n" + "// long long long lo\n" + "// long\n" + "}", + Style20); // Break and reflow multiple lines. - EXPECT_EQ("/*\n" - " * Reflow the end of\n" - " * line by 11 22 33\n" - " * 4.\n" - " */", - format("/*\n" - " * Reflow the end of line\n" - " * by\n" - " * 11\n" - " * 22\n" - " * 33\n" - " * 4.\n" - " */", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("/// First line gets\n" - "/// broken. Second\n" - "/// line gets\n" - "/// reflown and\n" - "/// broken. Third\n" - "/// gets reflown.", - format("/// First line gets broken.\n" - "/// Second line gets reflown and broken.\n" - "/// Third gets reflown.", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("int i; // first long\n" - " // long snd\n" - " // long.", - format("int i; // first long long\n" - " // snd long.", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("{\n" - " // first long line\n" - " // line second\n" - " // long line line\n" - " // third long line\n" - " // line\n" - "}", - format("{\n" - " // first long line line\n" - " // second long line line\n" - " // third long line line\n" - "}", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("int i; /* first line\n" - " * second\n" - " * line third\n" - " * line\n" - " */", - format("int i; /* first line\n" - " * second line\n" - " * third line\n" - " */", - getLLVMStyleWithColumns(20))); + verifyFormat("/*\n" + " * Reflow the end of\n" + " * line by 11 22 33\n" + " * 4.\n" + " */", + "/*\n" + " * Reflow the end of line\n" + " * by\n" + " * 11\n" + " * 22\n" + " * 33\n" + " * 4.\n" + " */", + Style20); + verifyFormat("/// First line gets\n" + "/// broken. Second\n" + "/// line gets\n" + "/// reflown and\n" + "/// broken. Third\n" + "/// gets reflown.", + "/// First line gets broken.\n" + "/// Second line gets reflown and broken.\n" + "/// Third gets reflown.", + Style20); + verifyFormat("int i; // first long\n" + " // long snd\n" + " // long.", + "int i; // first long long\n" + " // snd long.", + Style20); + verifyFormat("{\n" + " // first long line\n" + " // line second\n" + " // long line line\n" + " // third long line\n" + " // line\n" + "}", + "{\n" + " // first long line line\n" + " // second long line line\n" + " // third long line line\n" + "}", + Style20); + verifyFormat("int i; /* first line\n" + " * second\n" + " * line third\n" + " * line\n" + " */", + "int i; /* first line\n" + " * second line\n" + " * third line\n" + " */", + Style20); // Reflow the last two lines of a section that starts with a line having // different indentation. - EXPECT_EQ("// long\n" - "// long long long\n" - "// long long", - format("// long\n" - "// long long long long\n" - "// long", - getLLVMStyleWithColumns(20))); + verifyFormat("// long\n" + "// long long long\n" + "// long long", + "// long\n" + "// long long long long\n" + "// long", + Style20); // Keep the block comment endling '*/' while reflowing. - EXPECT_EQ("/* Long long long\n" - " * line short */", - format("/* Long long long line\n" - " * short */", - getLLVMStyleWithColumns(20))); + verifyFormat("/* Long long long\n" + " * line short */", + "/* Long long long line\n" + " * short */", + Style20); // Don't reflow between separate blocks of comments. - EXPECT_EQ("/* First comment\n" - " * block will */\n" - "/* Snd\n" - " */", - format("/* First comment block\n" - " * will */\n" - "/* Snd\n" - " */", - getLLVMStyleWithColumns(20))); + verifyFormat("/* First comment\n" + " * block will */\n" + "/* Snd\n" + " */", + "/* First comment block\n" + " * will */\n" + "/* Snd\n" + " */", + Style20); // Don't reflow across blank comment lines. - EXPECT_EQ("int i; // This long\n" - " // line gets\n" - " // broken.\n" - " //\n" - " // keep.", - format("int i; // This long line gets broken.\n" - " // \n" - " // keep.", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("{\n" - " /// long long long\n" - " /// long long\n" - " ///\n" - " /// long\n" - "}", - format("{\n" - " /// long long long long\n" - " /// long\n" - " ///\n" - " /// long\n" - "}", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("//! long long long\n" - "//! long\n" - "\n" - "//! long", - format("//! long long long long\n" - "\n" - "//! long", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("/* long long long\n" - " long\n" - "\n" - " long */", - format("/* long long long long\n" - "\n" - " long */", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("/* long long long\n" - " * long\n" - " *\n" - " * long */", - format("/* long long long long\n" - " *\n" - " * long */", - getLLVMStyleWithColumns(20))); + verifyFormat("int i; // This long\n" + " // line gets\n" + " // broken.\n" + " //\n" + " // keep.", + "int i; // This long line gets broken.\n" + " // \n" + " // keep.", + Style20); + verifyFormat("{\n" + " /// long long long\n" + " /// long long\n" + " ///\n" + " /// long\n" + "}", + "{\n" + " /// long long long long\n" + " /// long\n" + " ///\n" + " /// long\n" + "}", + Style20); + verifyFormat("//! long long long\n" + "//! long\n" + "\n" + "//! long", + "//! long long long long\n" + "\n" + "//! long", + Style20); + verifyFormat("/* long long long\n" + " long\n" + "\n" + " long */", + "/* long long long long\n" + "\n" + " long */", + Style20); + verifyFormat("/* long long long\n" + " * long\n" + " *\n" + " * long */", + "/* long long long long\n" + " *\n" + " * long */", + Style20); // Don't reflow lines having content that is a single character. - EXPECT_EQ("// long long long\n" - "// long\n" - "// l", - format("// long long long long\n" - "// l", - getLLVMStyleWithColumns(20))); + verifyFormat("// long long long\n" + "// long\n" + "// l", + "// long long long long\n" + "// l", + Style20); // Don't reflow lines starting with two punctuation characters. - EXPECT_EQ("// long long long\n" - "// long\n" - "// ... --- ...", - format("// long long long long\n" - "// ... --- ...", - getLLVMStyleWithColumns(20))); + verifyFormat("// long long long\n" + "// long\n" + "// ... --- ...", + "// long long long long\n" + "// ... --- ...", + Style20); // Don't reflow lines starting with '@'. - EXPECT_EQ("// long long long\n" - "// long\n" - "// @param arg", - format("// long long long long\n" - "// @param arg", - getLLVMStyleWithColumns(20))); + verifyFormat("// long long long\n" + "// long\n" + "// @param arg", + "// long long long long\n" + "// @param arg", + Style20); // Don't reflow lines starting with '\'. verifyFormat("// long long long\n" @@ -2020,433 +2011,435 @@ TEST_F(FormatTestComments, ReflowsComments) { "// \\param arg", "// long long long long\n" "// \\param arg", - getLLVMStyleWithColumns(20)); + Style20); // Don't reflow lines starting with 'TODO'. - EXPECT_EQ("// long long long\n" - "// long\n" - "// TODO: long", - format("// long long long long\n" - "// TODO: long", - getLLVMStyleWithColumns(20))); + verifyFormat("// long long long\n" + "// long\n" + "// TODO: long", + "// long long long long\n" + "// TODO: long", + Style20); // Don't reflow lines starting with 'FIXME'. - EXPECT_EQ("// long long long\n" - "// long\n" - "// FIXME: long", - format("// long long long long\n" - "// FIXME: long", - getLLVMStyleWithColumns(20))); + verifyFormat("// long long long\n" + "// long\n" + "// FIXME: long", + "// long long long long\n" + "// FIXME: long", + Style20); // Don't reflow lines starting with 'XXX'. - EXPECT_EQ("// long long long\n" - "// long\n" - "// XXX: long", - format("// long long long long\n" - "// XXX: long", - getLLVMStyleWithColumns(20))); + verifyFormat("// long long long\n" + "// long\n" + "// XXX: long", + "// long long long long\n" + "// XXX: long", + Style20); // Don't reflow comment pragmas. - EXPECT_EQ("// long long long\n" - "// long\n" - "// IWYU pragma:", - format("// long long long long\n" - "// IWYU pragma:", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("/* long long long\n" - " * long\n" - " * IWYU pragma:\n" - " */", - format("/* long long long long\n" - " * IWYU pragma:\n" - " */", - getLLVMStyleWithColumns(20))); + verifyFormat("// long long long\n" + "// long\n" + "// IWYU pragma:", + "// long long long long\n" + "// IWYU pragma:", + Style20); + verifyFormat("/* long long long\n" + " * long\n" + " * IWYU pragma:\n" + " */", + "/* long long long long\n" + " * IWYU pragma:\n" + " */", + Style20); // Reflow lines that have a non-punctuation character among their first 2 // characters. - EXPECT_EQ("// long long long\n" - "// long 'long'", - format("// long long long long\n" - "// 'long'", - getLLVMStyleWithColumns(20))); + verifyFormat("// long long long\n" + "// long 'long'", + "// long long long long\n" + "// 'long'", + Style20); // Don't reflow between separate blocks of comments. - EXPECT_EQ("/* First comment\n" - " * block will */\n" - "/* Snd\n" - " */", - format("/* First comment block\n" - " * will */\n" - "/* Snd\n" - " */", - getLLVMStyleWithColumns(20))); + verifyFormat("/* First comment\n" + " * block will */\n" + "/* Snd\n" + " */", + "/* First comment block\n" + " * will */\n" + "/* Snd\n" + " */", + Style20); // Don't reflow lines having different indentation. - EXPECT_EQ("// long long long\n" - "// long\n" - "// long", - format("// long long long long\n" - "// long", - getLLVMStyleWithColumns(20))); + verifyFormat("// long long long\n" + "// long\n" + "// long", + "// long long long long\n" + "// long", + Style20); // Don't reflow separate bullets in list - EXPECT_EQ("// - long long long\n" - "// long\n" - "// - long", - format("// - long long long long\n" - "// - long", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("// * long long long\n" - "// long\n" - "// * long", - format("// * long long long long\n" - "// * long", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("// + long long long\n" - "// long\n" - "// + long", - format("// + long long long long\n" - "// + long", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("// 1. long long long\n" - "// long\n" - "// 2. long", - format("// 1. long long long long\n" - "// 2. long", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("// -# long long long\n" - "// long\n" - "// -# long", - format("// -# long long long long\n" - "// -# long", - getLLVMStyleWithColumns(20))); - - EXPECT_EQ("// - long long long\n" - "// long long long\n" - "// - long", - format("// - long long long long\n" - "// long long\n" - "// - long", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("// - long long long\n" - "// long long long\n" - "// long\n" - "// - long", - format("// - long long long long\n" - "// long long long\n" - "// - long", - getLLVMStyleWithColumns(20))); + verifyFormat("// - long long long\n" + "// long\n" + "// - long", + "// - long long long long\n" + "// - long", + Style20); + verifyFormat("// * long long long\n" + "// long\n" + "// * long", + "// * long long long long\n" + "// * long", + Style20); + verifyFormat("// + long long long\n" + "// long\n" + "// + long", + "// + long long long long\n" + "// + long", + Style20); + verifyFormat("// 1. long long long\n" + "// long\n" + "// 2. long", + "// 1. long long long long\n" + "// 2. long", + Style20); + verifyFormat("// -# long long long\n" + "// long\n" + "// -# long", + "// -# long long long long\n" + "// -# long", + Style20); + + verifyFormat("// - long long long\n" + "// long long long\n" + "// - long", + "// - long long long long\n" + "// long long\n" + "// - long", + Style20); + verifyFormat("// - long long long\n" + "// long long long\n" + "// long\n" + "// - long", + "// - long long long long\n" + "// long long long\n" + "// - long", + Style20); // Large number (>2 digits) are not list items - EXPECT_EQ("// long long long\n" - "// long 1024. long.", - format("// long long long long\n" - "// 1024. long.", - getLLVMStyleWithColumns(20))); + verifyFormat("// long long long\n" + "// long 1024. long.", + "// long long long long\n" + "// 1024. long.", + Style20); // Do not break before number, to avoid introducing a non-reflowable doxygen // list item. - EXPECT_EQ("// long long\n" - "// long 10. long.", - format("// long long long 10.\n" - "// long.", - getLLVMStyleWithColumns(20))); + verifyFormat("// long long\n" + "// long 10. long.", + "// long long long 10.\n" + "// long.", + Style20); // Don't break or reflow after implicit string literals. verifyFormat("#include <t> // l l l\n" " // l", - getLLVMStyleWithColumns(20)); + Style20); // Don't break or reflow comments on import lines. - EXPECT_EQ("#include \"t\" /* l l l\n" - " * l */", - format("#include \"t\" /* l l l\n" - " * l */", - getLLVMStyleWithColumns(20))); + verifyFormat("#include \"t\" /* l l l\n" + " * l */", + "#include \"t\" /* l l l\n" + " * l */", + Style20); // Don't reflow between different trailing comment sections. - EXPECT_EQ("int i; // long long\n" - " // long\n" - "int j; // long long\n" - " // long", - format("int i; // long long long\n" - "int j; // long long long", - getLLVMStyleWithColumns(20))); + verifyFormat("int i; // long long\n" + " // long\n" + "int j; // long long\n" + " // long", + "int i; // long long long\n" + "int j; // long long long", + Style20); // Don't reflow if the first word on the next line is longer than the // available space at current line. - EXPECT_EQ("int i; // trigger\n" - " // reflow\n" - " // longsec", - format("int i; // trigger reflow\n" - " // longsec", - getLLVMStyleWithColumns(20))); + verifyFormat("int i; // trigger\n" + " // reflow\n" + " // longsec", + "int i; // trigger reflow\n" + " // longsec", + Style20); // Simple case that correctly handles reflow in parameter lists. - EXPECT_EQ("a = f(/* looooooooong\n" - " * long long\n" - " */\n" - " a);", - format("a = f(/* looooooooong long\n* long\n*/ a);", - getLLVMStyleWithColumns(22))); + verifyFormat("a = f(/* looooooooong\n" + " * long long\n" + " */\n" + " a);", + "a = f(/* looooooooong long\n* long\n*/ a);", Style22); // Tricky case that has fewer lines if we reflow the comment, ending up with // fewer lines. - EXPECT_EQ("a = f(/* loooooong\n" - " * long long\n" - " */\n" - " a);", - format("a = f(/* loooooong long\n* long\n*/ a);", - getLLVMStyleWithColumns(22))); + verifyFormat("a = f(/* loooooong\n" + " * long long\n" + " */\n" + " a);", + "a = f(/* loooooong long\n* long\n*/ a);", Style22); // Keep empty comment lines. - EXPECT_EQ("/**/", format(" /**/", getLLVMStyleWithColumns(20))); - EXPECT_EQ("/* */", format(" /* */", getLLVMStyleWithColumns(20))); - EXPECT_EQ("/* */", format(" /* */", getLLVMStyleWithColumns(20))); - EXPECT_EQ("//", format(" // ", getLLVMStyleWithColumns(20))); - EXPECT_EQ("///", format(" /// ", getLLVMStyleWithColumns(20))); + verifyFormat("/**/", " /**/", Style20); + verifyFormat("/* */", " /* */", Style20); + verifyFormat("/* */", " /* */", Style20); + verifyFormat("//", " // ", Style20); + verifyFormat("///", " /// ", Style20); } TEST_F(FormatTestComments, ReflowsCommentsPrecise) { + auto Style = getLLVMStyleWithColumns(20); + // FIXME: This assumes we do not continue compressing whitespace once we are // in reflow mode. Consider compressing whitespace. // Test that we stop reflowing precisely at the column limit. // After reflowing, "// reflows into foo" does not fit the column limit, // so we compress the whitespace. - EXPECT_EQ("// some text that\n" - "// reflows into foo", - format("// some text that reflows\n" - "// into foo", - getLLVMStyleWithColumns(20))); + verifyFormat("// some text that\n" + "// reflows into foo", + "// some text that reflows\n" + "// into foo", + Style); + Style.ColumnLimit = 21; // Given one more column, "// reflows into foo" does fit the limit, so we // do not compress the whitespace. - EXPECT_EQ("// some text that\n" - "// reflows into foo", - format("// some text that reflows\n" - "// into foo", - getLLVMStyleWithColumns(21))); + verifyFormat("// some text that\n" + "// reflows into foo", + "// some text that reflows\n" + "// into foo", + Style); // Make sure that we correctly account for the space added in the reflow case // when making the reflowing decision. // First, when the next line ends precisely one column over the limit, do not // reflow. - EXPECT_EQ("// some text that\n" - "// reflows\n" - "// into1234567", - format("// some text that reflows\n" - "// into1234567", - getLLVMStyleWithColumns(21))); + verifyFormat("// some text that\n" + "// reflows\n" + "// into1234567", + "// some text that reflows\n" + "// into1234567", + Style); // Secondly, when the next line ends later, but the first word in that line // is precisely one column over the limit, do not reflow. - EXPECT_EQ("// some text that\n" - "// reflows\n" - "// into1234567 f", - format("// some text that reflows\n" - "// into1234567 f", - getLLVMStyleWithColumns(21))); + verifyFormat("// some text that\n" + "// reflows\n" + "// into1234567 f", + "// some text that reflows\n" + "// into1234567 f", + Style); } TEST_F(FormatTestComments, ReflowsCommentsWithExtraWhitespace) { + const auto Style16 = getLLVMStyleWithColumns(16); // Baseline. - EXPECT_EQ("// some text\n" - "// that re flows", - format("// some text that\n" - "// re flows", - getLLVMStyleWithColumns(16))); - EXPECT_EQ("// some text\n" - "// that re flows", - format("// some text that\n" - "// re flows", - getLLVMStyleWithColumns(16))); - EXPECT_EQ("/* some text\n" - " * that re flows\n" - " */", - format("/* some text that\n" - "* re flows\n" - "*/", - getLLVMStyleWithColumns(16))); + verifyFormat("// some text\n" + "// that re flows", + "// some text that\n" + "// re flows", + Style16); + verifyFormat("// some text\n" + "// that re flows", + "// some text that\n" + "// re flows", + Style16); + verifyFormat("/* some text\n" + " * that re flows\n" + " */", + "/* some text that\n" + "* re flows\n" + "*/", + Style16); // FIXME: We do not reflow if the indent of two subsequent lines differs; // given that this is different behavior from block comments, do we want // to keep this? - EXPECT_EQ("// some text\n" - "// that\n" - "// re flows", - format("// some text that\n" - "// re flows", - getLLVMStyleWithColumns(16))); + verifyFormat("// some text\n" + "// that\n" + "// re flows", + "// some text that\n" + "// re flows", + Style16); // Space within parts of a line that fit. // FIXME: Use the earliest possible split while reflowing to compress the // whitespace within the line. - EXPECT_EQ("// some text that\n" - "// does re flow\n" - "// more here", - format("// some text that does\n" - "// re flow more here", - getLLVMStyleWithColumns(21))); + verifyFormat("// some text that\n" + "// does re flow\n" + "// more here", + "// some text that does\n" + "// re flow more here", + getLLVMStyleWithColumns(21)); } TEST_F(FormatTestComments, IgnoresIf0Contents) { - EXPECT_EQ("#if 0\n" - "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n" - "#endif\n" - "void f() {}", - format("#if 0\n" - "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n" - "#endif\n" - "void f( ) { }")); - EXPECT_EQ("#if false\n" - "void f( ) { }\n" - "#endif\n" - "void g() {}", - format("#if false\n" - "void f( ) { }\n" - "#endif\n" - "void g( ) { }")); - EXPECT_EQ("enum E {\n" - " One,\n" - " Two,\n" - "#if 0\n" - "Three,\n" - " Four,\n" - "#endif\n" - " Five\n" - "};", - format("enum E {\n" - " One,Two,\n" - "#if 0\n" - "Three,\n" - " Four,\n" - "#endif\n" - " Five};")); - EXPECT_EQ("enum F {\n" - " One,\n" - "#if 1\n" - " Two,\n" - "#if 0\n" - "Three,\n" - " Four,\n" - "#endif\n" - " Five\n" - "#endif\n" - "};", - format("enum F {\n" - "One,\n" - "#if 1\n" - "Two,\n" - "#if 0\n" - "Three,\n" - " Four,\n" - "#endif\n" - "Five\n" - "#endif\n" - "};")); - EXPECT_EQ("enum G {\n" - " One,\n" - "#if 0\n" - "Two,\n" - "#else\n" - " Three,\n" - "#endif\n" - " Four\n" - "};", - format("enum G {\n" - "One,\n" - "#if 0\n" - "Two,\n" - "#else\n" - "Three,\n" - "#endif\n" - "Four\n" - "};")); - EXPECT_EQ("enum H {\n" - " One,\n" - "#if 0\n" - "#ifdef Q\n" - "Two,\n" - "#else\n" - "Three,\n" - "#endif\n" - "#endif\n" - " Four\n" - "};", - format("enum H {\n" - "One,\n" - "#if 0\n" - "#ifdef Q\n" - "Two,\n" - "#else\n" - "Three,\n" - "#endif\n" - "#endif\n" - "Four\n" - "};")); - EXPECT_EQ("enum I {\n" - " One,\n" - "#if /* test */ 0 || 1\n" - "Two,\n" - "Three,\n" - "#endif\n" - " Four\n" - "};", - format("enum I {\n" - "One,\n" - "#if /* test */ 0 || 1\n" - "Two,\n" - "Three,\n" - "#endif\n" - "Four\n" - "};")); - EXPECT_EQ("enum J {\n" - " One,\n" - "#if 0\n" - "#if 0\n" - "Two,\n" - "#else\n" - "Three,\n" - "#endif\n" - "Four,\n" - "#endif\n" - " Five\n" - "};", - format("enum J {\n" - "One,\n" - "#if 0\n" - "#if 0\n" - "Two,\n" - "#else\n" - "Three,\n" - "#endif\n" - "Four,\n" - "#endif\n" - "Five\n" - "};")); + verifyFormat("#if 0\n" + "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n" + "#endif\n" + "void f() {}", + "#if 0\n" + "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n" + "#endif\n" + "void f( ) { }"); + verifyFormat("#if false\n" + "void f( ) { }\n" + "#endif\n" + "void g() {}", + "#if false\n" + "void f( ) { }\n" + "#endif\n" + "void g( ) { }"); + verifyFormat("enum E {\n" + " One,\n" + " Two,\n" + "#if 0\n" + "Three,\n" + " Four,\n" + "#endif\n" + " Five\n" + "};", + "enum E {\n" + " One,Two,\n" + "#if 0\n" + "Three,\n" + " Four,\n" + "#endif\n" + " Five};"); + verifyFormat("enum F {\n" + " One,\n" + "#if 1\n" + " Two,\n" + "#if 0\n" + "Three,\n" + " Four,\n" + "#endif\n" + " Five\n" + "#endif\n" + "};", + "enum F {\n" + "One,\n" + "#if 1\n" + "Two,\n" + "#if 0\n" + "Three,\n" + " Four,\n" + "#endif\n" + "Five\n" + "#endif\n" + "};"); + verifyFormat("enum G {\n" + " One,\n" + "#if 0\n" + "Two,\n" + "#else\n" + " Three,\n" + "#endif\n" + " Four\n" + "};", + "enum G {\n" + "One,\n" + "#if 0\n" + "Two,\n" + "#else\n" + "Three,\n" + "#endif\n" + "Four\n" + "};"); + verifyFormat("enum H {\n" + " One,\n" + "#if 0\n" + "#ifdef Q\n" + "Two,\n" + "#else\n" + "Three,\n" + "#endif\n" + "#endif\n" + " Four\n" + "};", + "enum H {\n" + "One,\n" + "#if 0\n" + "#ifdef Q\n" + "Two,\n" + "#else\n" + "Three,\n" + "#endif\n" + "#endif\n" + "Four\n" + "};"); + verifyFormat("enum I {\n" + " One,\n" + "#if /* test */ 0 || 1\n" + "Two,\n" + "Three,\n" + "#endif\n" + " Four\n" + "};", + "enum I {\n" + "One,\n" + "#if /* test */ 0 || 1\n" + "Two,\n" + "Three,\n" + "#endif\n" + "Four\n" + "};"); + verifyFormat("enum J {\n" + " One,\n" + "#if 0\n" + "#if 0\n" + "Two,\n" + "#else\n" + "Three,\n" + "#endif\n" + "Four,\n" + "#endif\n" + " Five\n" + "};", + "enum J {\n" + "One,\n" + "#if 0\n" + "#if 0\n" + "Two,\n" + "#else\n" + "Three,\n" + "#endif\n" + "Four,\n" + "#endif\n" + "Five\n" + "};"); // Ignore stuff in SWIG-blocks. - EXPECT_EQ("#ifdef SWIG\n" - "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n" - "#endif\n" - "void f() {}", - format("#ifdef SWIG\n" - "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n" - "#endif\n" - "void f( ) { }")); - EXPECT_EQ("#ifndef SWIG\n" - "void f() {}\n" - "#endif", - format("#ifndef SWIG\n" - "void f( ) { }\n" - "#endif")); + verifyFormat("#ifdef SWIG\n" + "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n" + "#endif\n" + "void f() {}", + "#ifdef SWIG\n" + "}{)(&*(^%%#%@! fsadj f;ldjs ,:;| <<<>>>][)(][\n" + "#endif\n" + "void f( ) { }"); + verifyFormat("#ifndef SWIG\n" + "void f() {}\n" + "#endif", + "#ifndef SWIG\n" + "void f( ) { }\n" + "#endif"); } TEST_F(FormatTestComments, DontCrashOnBlockComments) { - EXPECT_EQ( + verifyFormat( "int xxxxxxxxx; /* " "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\n" "zzzzzz\n" "0*/", - format("int xxxxxxxxx; /* " - "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy zzzzzz\n" - "0*/")); + "int xxxxxxxxx; /* " + "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy zzzzzz\n" + "0*/"); } TEST_F(FormatTestComments, BlockCommentsInControlLoops) { @@ -2470,225 +2463,229 @@ TEST_F(FormatTestComments, BlockCommentsInControlLoops) { } TEST_F(FormatTestComments, BlockComments) { - EXPECT_EQ("/* */ /* */ /* */\n/* */ /* */ /* */", - format("/* *//* */ /* */\n/* *//* */ /* */")); - EXPECT_EQ("/* */ a /* */ b;", format(" /* */ a/* */ b;")); - EXPECT_EQ("#define A /*123*/ \\\n" - " b\n" - "/* */\n" - "someCall(\n" - " parameter);", - format("#define A /*123*/ b\n" - "/* */\n" - "someCall(parameter);", - getLLVMStyleWithColumns(15))); - - EXPECT_EQ("#define A\n" - "/* */ someCall(\n" - " parameter);", - format("#define A\n" - "/* */someCall(parameter);", - getLLVMStyleWithColumns(15))); + const auto Style10 = getLLVMStyleWithColumns(10); + const auto Style15 = getLLVMStyleWithColumns(15); + + verifyFormat("/* */ /* */ /* */\n/* */ /* */ /* */", + "/* *//* */ /* */\n/* *//* */ /* */"); + verifyFormat("/* */ a /* */ b;", " /* */ a/* */ b;"); + verifyFormat("#define A /*123*/ \\\n" + " b\n" + "/* */\n" + "someCall(\n" + " parameter);", + "#define A /*123*/ b\n" + "/* */\n" + "someCall(parameter);", + Style15); + + verifyFormat("#define A\n" + "/* */ someCall(\n" + " parameter);", + "#define A\n" + "/* */someCall(parameter);", + Style15); verifyNoChange("/*\n**\n*/"); - EXPECT_EQ("/*\n" - " *\n" - " * aaaaaa\n" - " * aaaaaa\n" - " */", - format("/*\n" - "*\n" - " * aaaaaa aaaaaa\n" - "*/", - getLLVMStyleWithColumns(10))); - EXPECT_EQ("/*\n" - "**\n" - "* aaaaaa\n" - "* aaaaaa\n" - "*/", - format("/*\n" - "**\n" - "* aaaaaa aaaaaa\n" - "*/", - getLLVMStyleWithColumns(10))); - EXPECT_EQ("int aaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" - " /* line 1\n" - " bbbbbbbbbbbb */\n" - " bbbbbbbbbbbbbbbbbbbbbbbbbbbb;", - format("int aaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" - " /* line 1\n" - " bbbbbbbbbbbb */ bbbbbbbbbbbbbbbbbbbbbbbbbbbb;", - getLLVMStyleWithColumns(50))); + verifyFormat("/*\n" + " *\n" + " * aaaaaa\n" + " * aaaaaa\n" + " */", + "/*\n" + "*\n" + " * aaaaaa aaaaaa\n" + "*/", + Style10); + verifyFormat("/*\n" + "**\n" + "* aaaaaa\n" + "* aaaaaa\n" + "*/", + "/*\n" + "**\n" + "* aaaaaa aaaaaa\n" + "*/", + Style10); + verifyFormat("int aaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" + " /* line 1\n" + " bbbbbbbbbbbb */\n" + " bbbbbbbbbbbbbbbbbbbbbbbbbbbb;", + "int aaaaaaaaaaaaaaaaaaaaaaaaaaaa =\n" + " /* line 1\n" + " bbbbbbbbbbbb */ bbbbbbbbbbbbbbbbbbbbbbbbbbbb;", + getLLVMStyleWithColumns(50)); FormatStyle NoBinPacking = getLLVMStyle(); NoBinPacking.BinPackParameters = FormatStyle::BPPS_OnePerLine; - EXPECT_EQ("someFunction(1, /* comment 1 */\n" - " 2, /* comment 2 */\n" - " 3, /* comment 3 */\n" - " aaaa,\n" - " bbbb);", - format("someFunction (1, /* comment 1 */\n" - " 2, /* comment 2 */ \n" - " 3, /* comment 3 */\n" - "aaaa, bbbb );", - NoBinPacking)); + verifyFormat("someFunction(1, /* comment 1 */\n" + " 2, /* comment 2 */\n" + " 3, /* comment 3 */\n" + " aaaa,\n" + " bbbb);", + "someFunction (1, /* comment 1 */\n" + " 2, /* comment 2 */ \n" + " 3, /* comment 3 */\n" + "aaaa, bbbb );", + NoBinPacking); verifyFormat( "bool aaaaaaaaaaaaa = /* comment: */ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ||\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaa;"); - EXPECT_EQ( + verifyFormat( "bool aaaaaaaaaaaaa = /* trailing comment */\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaa ||\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaa;", - format( - "bool aaaaaaaaaaaaa = /* trailing comment */\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaa||aaaaaaaaaaaaaaaaaaaaaaaaa ||\n" - " aaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaa;")); - EXPECT_EQ( - "int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; /* comment */\n" - "int bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; /* comment */\n" - "int cccccccccccccccccccccccccccccc; /* comment */", - format("int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; /* comment */\n" - "int bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; /* comment */\n" - "int cccccccccccccccccccccccccccccc; /* comment */")); + "bool aaaaaaaaaaaaa = /* trailing comment */\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaa||aaaaaaaaaaaaaaaaaaaaaaaaa ||\n" + " aaaaaaaaaaaaaaaaaaaaaaaaaaaa || aaaaaaaaaaaaaaaaaaaaaaaaaa;"); + verifyFormat("int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; /* comment */\n" + "int bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; /* comment */\n" + "int cccccccccccccccccccccccccccccc; /* comment */", + "int aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa; /* comment */\n" + "int bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb; /* comment */\n" + "int cccccccccccccccccccccccccccccc; /* comment */"); verifyFormat("void f(int * /* unused */) {}"); - EXPECT_EQ("/*\n" - " **\n" - " */", - format("/*\n" - " **\n" - " */")); - EXPECT_EQ("/*\n" - " *q\n" - " */", - format("/*\n" - " *q\n" - " */")); - EXPECT_EQ("/*\n" - " * q\n" - " */", - format("/*\n" - " * q\n" - " */")); - EXPECT_EQ("/*\n" - " **/", - format("/*\n" - " **/")); - EXPECT_EQ("/*\n" - " ***/", - format("/*\n" - " ***/")); + verifyFormat("/*\n" + " **\n" + " */", + "/*\n" + " **\n" + " */"); + verifyFormat("/*\n" + " *q\n" + " */", + "/*\n" + " *q\n" + " */"); + verifyFormat("/*\n" + " * q\n" + " */", + "/*\n" + " * q\n" + " */"); + verifyFormat("/*\n" + " **/", + "/*\n" + " **/"); + verifyFormat("/*\n" + " ***/", + "/*\n" + " ***/"); } TEST_F(FormatTestComments, BlockCommentsInMacros) { - EXPECT_EQ("#define A \\\n" - " { \\\n" - " /* one line */ \\\n" - " someCall();", - format("#define A { \\\n" - " /* one line */ \\\n" - " someCall();", - getLLVMStyleWithColumns(20))); - EXPECT_EQ("#define A \\\n" - " { \\\n" - " /* previous */ \\\n" - " /* one line */ \\\n" - " someCall();", - format("#define A { \\\n" - " /* previous */ \\\n" - " /* one line */ \\\n" - " someCall();", - getLLVMStyleWithColumns(20))); + const auto Style20 = getLLVMStyleWithColumns(20); + + verifyFormat("#define A \\\n" + " { \\\n" + " /* one line */ \\\n" + " someCall();", + "#define A { \\\n" + " /* one line */ \\\n" + " someCall();", + Style20); + verifyFormat("#define A \\\n" + " { \\\n" + " /* previous */ \\\n" + " /* one line */ \\\n" + " someCall();", + "#define A { \\\n" + " /* previous */ \\\n" + " /* one line */ \\\n" + " someCall();", + Style20); } TEST_F(FormatTestComments, BlockCommentsAtEndOfLine) { - EXPECT_EQ("a = {\n" - " 1111 /* */\n" - "};", - format("a = {1111 /* */\n" - "};", - getLLVMStyleWithColumns(15))); - EXPECT_EQ("a = {\n" - " 1111 /* */\n" - "};", - format("a = {1111 /* */\n" - "};", - getLLVMStyleWithColumns(15))); - EXPECT_EQ("a = {\n" - " 1111 /* a\n" - " */\n" - "};", - format("a = {1111 /* a */\n" - "};", - getLLVMStyleWithColumns(15))); + const auto Style15 = getLLVMStyleWithColumns(15); + + verifyFormat("a = {\n" + " 1111 /* */\n" + "};", + "a = {1111 /* */\n" + "};", + Style15); + verifyFormat("a = {\n" + " 1111 /* */\n" + "};", + "a = {1111 /* */\n" + "};", + Style15); + verifyFormat("a = {\n" + " 1111 /* a\n" + " */\n" + "};", + "a = {1111 /* a */\n" + "};", + Style15); } TEST_F(FormatTestComments, BreaksAfterMultilineBlockCommentsInParamLists) { - EXPECT_EQ("a = f(/* long\n" - " long */\n" - " a);", - format("a = f(/* long long */ a);", getLLVMStyleWithColumns(16))); - EXPECT_EQ("a = f(\n" - " /* long\n" - " long */\n" - " a);", - format("a = f(/* long long */ a);", getLLVMStyleWithColumns(15))); - - EXPECT_EQ("a = f(/* long\n" - " long\n" - " */\n" - " a);", - format("a = f(/* long\n" - " long\n" - " */a);", - getLLVMStyleWithColumns(16))); - - EXPECT_EQ("a = f(/* long\n" - " long\n" - " */\n" - " a);", - format("a = f(/* long\n" - " long\n" - " */ a);", - getLLVMStyleWithColumns(16))); - - EXPECT_EQ("a = f(/* long\n" - " long\n" - " */\n" - " (1 + 1));", - format("a = f(/* long\n" - " long\n" - " */ (1 + 1));", - getLLVMStyleWithColumns(16))); - - EXPECT_EQ( - "a = f(a,\n" - " /* long\n" - " long */\n" - " b);", - format("a = f(a, /* long long */ b);", getLLVMStyleWithColumns(16))); - - EXPECT_EQ( - "a = f(\n" - " a,\n" - " /* long\n" - " long */\n" - " b);", - format("a = f(a, /* long long */ b);", getLLVMStyleWithColumns(15))); - - EXPECT_EQ("a = f(a,\n" - " /* long\n" - " long */\n" - " (1 + 1));", - format("a = f(a, /* long long */ (1 + 1));", - getLLVMStyleWithColumns(16))); - EXPECT_EQ("a = f(\n" - " a,\n" - " /* long\n" - " long */\n" - " (1 + 1));", - format("a = f(a, /* long long */ (1 + 1));", - getLLVMStyleWithColumns(15))); + const auto Style15 = getLLVMStyleWithColumns(15); + const auto Style16 = getLLVMStyleWithColumns(16); + + verifyFormat("a = f(/* long\n" + " long */\n" + " a);", + "a = f(/* long long */ a);", Style16); + verifyFormat("a = f(\n" + " /* long\n" + " long */\n" + " a);", + "a = f(/* long long */ a);", Style15); + + verifyFormat("a = f(/* long\n" + " long\n" + " */\n" + " a);", + "a = f(/* long\n" + " long\n" + " */a);", + Style16); + + verifyFormat("a = f(/* long\n" + " long\n" + " */\n" + " a);", + "a = f(/* long\n" + " long\n" + " */ a);", + Style16); + + verifyFormat("a = f(/* long\n" + " long\n" + " */\n" + " (1 + 1));", + "a = f(/* long\n" + " long\n" + " */ (1 + 1));", + Style16); + + verifyFormat("a = f(a,\n" + " /* long\n" + " long */\n" + " b);", + "a = f(a, /* long long */ b);", Style16); + + verifyFormat("a = f(\n" + " a,\n" + " /* long\n" + " long */\n" + " b);", + "a = f(a, /* long long */ b);", Style15); + + verifyFormat("a = f(a,\n" + " /* long\n" + " long */\n" + " (1 + 1));", + "a = f(a, /* long long */ (1 + 1));", Style16); + verifyFormat("a = f(\n" + " a,\n" + " /* long\n" + " long */\n" + " (1 + 1));", + "a = f(a, /* long long */ (1 + 1));", Style15); } TEST_F(FormatTestComments, IndentLineCommentsInStartOfBlockAtEndOfFile) { @@ -2698,229 +2695,224 @@ TEST_F(FormatTestComments, IndentLineCommentsInStartOfBlockAtEndOfFile) { } TEST_F(FormatTestComments, AlignTrailingComments) { - EXPECT_EQ("#define MACRO(V) \\\n" - " V(Rt2) /* one more char */ \\\n" - " V(Rs) /* than here */ \\\n" - "/* comment 3 */\n", - format("#define MACRO(V)\\\n" - "V(Rt2) /* one more char */ \\\n" - "V(Rs) /* than here */ \\\n" - "/* comment 3 */\n", - getLLVMStyleWithColumns(40))); - EXPECT_EQ("int i = f(abc, // line 1\n" - " d, // line 2\n" - " // line 3\n" - " b);", - format("int i = f(abc, // line 1\n" - " d, // line 2\n" - " // line 3\n" - " b);", - getLLVMStyleWithColumns(40))); + const auto Style15 = getLLVMStyleWithColumns(15); + const auto Style40 = getLLVMStyleWithColumns(40); + + verifyFormat("#define MACRO(V) \\\n" + " V(Rt2) /* one more char */ \\\n" + " V(Rs) /* than here */ \\\n" + "/* comment 3 */\n", + "#define MACRO(V)\\\n" + "V(Rt2) /* one more char */ \\\n" + "V(Rs) /* than here */ \\\n" + "/* comment 3 */\n", + Style40); + verifyFormat("int i = f(abc, // line 1\n" + " d, // line 2\n" + " // line 3\n" + " b);", + "int i = f(abc, // line 1\n" + " d, // line 2\n" + " // line 3\n" + " b);", + Style40); // Align newly broken trailing comments. - EXPECT_EQ("int ab; // line\n" - "int a; // long\n" - " // long", - format("int ab; // line\n" - "int a; // long long", - getLLVMStyleWithColumns(15))); - EXPECT_EQ("int ab; // line\n" - "int a; // long\n" - " // long\n" - " // long", - format("int ab; // line\n" - "int a; // long long\n" - " // long", - getLLVMStyleWithColumns(15))); - EXPECT_EQ("int ab; // line\n" - "int a; // long\n" - " // long\n" - "pt c; // long", - format("int ab; // line\n" - "int a; // long long\n" - "pt c; // long", - getLLVMStyleWithColumns(15))); - EXPECT_EQ("int ab; // line\n" - "int a; // long\n" - " // long\n" - "\n" - "// long", - format("int ab; // line\n" - "int a; // long long\n" - "\n" - "// long", - getLLVMStyleWithColumns(15))); + verifyFormat("int ab; // line\n" + "int a; // long\n" + " // long", + "int ab; // line\n" + "int a; // long long", + Style15); + verifyFormat("int ab; // line\n" + "int a; // long\n" + " // long\n" + " // long", + "int ab; // line\n" + "int a; // long long\n" + " // long", + Style15); + verifyFormat("int ab; // line\n" + "int a; // long\n" + " // long\n" + "pt c; // long", + "int ab; // line\n" + "int a; // long long\n" + "pt c; // long", + Style15); + verifyFormat("int ab; // line\n" + "int a; // long\n" + " // long\n" + "\n" + "// long", + "int ab; // line\n" + "int a; // long long\n" + "\n" + "// long", + Style15); // Don't align newly broken trailing comments if that would put them over the // column limit. - EXPECT_EQ("int i, j; // line 1\n" - "int k; // line longg\n" - " // long", - format("int i, j; // line 1\n" - "int k; // line longg long", - getLLVMStyleWithColumns(20))); + verifyFormat("int i, j; // line 1\n" + "int k; // line longg\n" + " // long", + "int i, j; // line 1\n" + "int k; // line longg long", + getLLVMStyleWithColumns(20)); // Always align if ColumnLimit = 0 - EXPECT_EQ("int i, j; // line 1\n" - "int k; // line longg long", - format("int i, j; // line 1\n" - "int k; // line longg long", - getLLVMStyleWithColumns(0))); + verifyFormat("int i, j; // line 1\n" + "int k; // line longg long", + "int i, j; // line 1\n" + "int k; // line longg long", + getLLVMStyleWithColumns(0)); // Align comment line sections aligned with the next token with the next // token. - EXPECT_EQ("class A {\n" - "public: // public comment\n" - " // comment about a\n" - " int a;\n" - "};", - format("class A {\n" - "public: // public comment\n" - " // comment about a\n" - " int a;\n" - "};", - getLLVMStyleWithColumns(40))); - EXPECT_EQ("class A {\n" - "public: // public comment 1\n" - " // public comment 2\n" - " // comment 1 about a\n" - " // comment 2 about a\n" - " int a;\n" - "};", - format("class A {\n" - "public: // public comment 1\n" - " // public comment 2\n" - " // comment 1 about a\n" - " // comment 2 about a\n" - " int a;\n" - "};", - getLLVMStyleWithColumns(40))); - EXPECT_EQ("int f(int n) { // comment line 1 on f\n" - " // comment line 2 on f\n" - " // comment line 1 before return\n" - " // comment line 2 before return\n" - " return n; // comment line 1 on return\n" - " // comment line 2 on return\n" - " // comment line 1 after return\n" - "}", - format("int f(int n) { // comment line 1 on f\n" - " // comment line 2 on f\n" - " // comment line 1 before return\n" - " // comment line 2 before return\n" - " return n; // comment line 1 on return\n" - " // comment line 2 on return\n" - " // comment line 1 after return\n" - "}", - getLLVMStyleWithColumns(40))); - EXPECT_EQ("int f(int n) {\n" - " switch (n) { // comment line 1 on switch\n" - " // comment line 2 on switch\n" - " // comment line 1 before case 1\n" - " // comment line 2 before case 1\n" - " case 1: // comment line 1 on case 1\n" - " // comment line 2 on case 1\n" - " // comment line 1 before return 1\n" - " // comment line 2 before return 1\n" - " return 1; // comment line 1 on return 1\n" - " // comment line 2 on return 1\n" - " // comment line 1 before default\n" - " // comment line 2 before default\n" - " default: // comment line 1 on default\n" - " // comment line 2 on default\n" - " // comment line 1 before return 2\n" - " return 2 * f(n - 1); // comment line 1 on return 2\n" - " // comment line 2 on return 2\n" - " // comment line 1 after return\n" - " // comment line 2 after return\n" - " }\n" - "}", - format("int f(int n) {\n" - " switch (n) { // comment line 1 on switch\n" - " // comment line 2 on switch\n" - " // comment line 1 before case 1\n" - " // comment line 2 before case 1\n" - " case 1: // comment line 1 on case 1\n" - " // comment line 2 on case 1\n" - " // comment line 1 before return 1\n" - " // comment line 2 before return 1\n" - " return 1; // comment line 1 on return 1\n" - " // comment line 2 on return 1\n" - " // comment line 1 before default\n" - " // comment line 2 before default\n" - " default: // comment line 1 on default\n" - " // comment line 2 on default\n" - " // comment line 1 before return 2\n" - " return 2 * f(n - 1); // comment line 1 on return 2\n" - " // comment line 2 on return 2\n" - " // comment line 1 after return\n" - " // comment line 2 after return\n" - " }\n" - "}", - getLLVMStyleWithColumns(80))); + verifyFormat("class A {\n" + "public: // public comment\n" + " // comment about a\n" + " int a;\n" + "};", + "class A {\n" + "public: // public comment\n" + " // comment about a\n" + " int a;\n" + "};", + Style40); + verifyFormat("class A {\n" + "public: // public comment 1\n" + " // public comment 2\n" + " // comment 1 about a\n" + " // comment 2 about a\n" + " int a;\n" + "};", + "class A {\n" + "public: // public comment 1\n" + " // public comment 2\n" + " // comment 1 about a\n" + " // comment 2 about a\n" + " int a;\n" + "};", + Style40); + verifyFormat("int f(int n) { // comment line 1 on f\n" + " // comment line 2 on f\n" + " // comment line 1 before return\n" + " // comment line 2 before return\n" + " return n; // comment line 1 on return\n" + " // comment line 2 on return\n" + " // comment line 1 after return\n" + "}", + "int f(int n) { // comment line 1 on f\n" + " // comment line 2 on f\n" + " // comment line 1 before return\n" + " // comment line 2 before return\n" + " return n; // comment line 1 on return\n" + " // comment line 2 on return\n" + " // comment line 1 after return\n" + "}", + Style40); + verifyFormat("int f(int n) {\n" + " switch (n) { // comment line 1 on switch\n" + " // comment line 2 on switch\n" + " // comment line 1 before case 1\n" + " // comment line 2 before case 1\n" + " case 1: // comment line 1 on case 1\n" + " // comment line 2 on case 1\n" + " // comment line 1 before return 1\n" + " // comment line 2 before return 1\n" + " return 1; // comment line 1 on return 1\n" + " // comment line 2 on return 1\n" + " // comment line 1 before default\n" + " // comment line 2 before default\n" + " default: // comment line 1 on default\n" + " // comment line 2 on default\n" + " // comment line 1 before return 2\n" + " return 2 * f(n - 1); // comment line 1 on return 2\n" + " // comment line 2 on return 2\n" + " // comment line 1 after return\n" + " // comment line 2 after return\n" + " }\n" + "}", + "int f(int n) {\n" + " switch (n) { // comment line 1 on switch\n" + " // comment line 2 on switch\n" + " // comment line 1 before case 1\n" + " // comment line 2 before case 1\n" + " case 1: // comment line 1 on case 1\n" + " // comment line 2 on case 1\n" + " // comment line 1 before return 1\n" + " // comment line 2 before return 1\n" + " return 1; // comment line 1 on return 1\n" + " // comment line 2 on return 1\n" + " // comment line 1 before default\n" + " // comment line 2 before default\n" + " default: // comment line 1 on default\n" + " // comment line 2 on default\n" + " // comment line 1 before return 2\n" + " return 2 * f(n - 1); // comment line 1 on return 2\n" + " // comment line 2 on return 2\n" + " // comment line 1 after return\n" + " // comment line 2 after return\n" + " }\n" + "}"); // If all the lines in a sequence of line comments are aligned with the next // token, the first line belongs to the previous token and the other lines // belong to the next token. - EXPECT_EQ("int a; // line about a\n" - "long b;", - format("int a; // line about a\n" - " long b;", - getLLVMStyleWithColumns(80))); - EXPECT_EQ("int a; // line about a\n" - "// line about b\n" - "long b;", - format("int a; // line about a\n" - " // line about b\n" - " long b;", - getLLVMStyleWithColumns(80))); - EXPECT_EQ("int a; // line about a\n" - "// line 1 about b\n" - "// line 2 about b\n" - "long b;", - format("int a; // line about a\n" - " // line 1 about b\n" - " // line 2 about b\n" - " long b;", - getLLVMStyleWithColumns(80))); + verifyFormat("int a; // line about a\n" + "long b;", + "int a; // line about a\n" + " long b;"); + verifyFormat("int a; // line about a\n" + "// line about b\n" + "long b;", + "int a; // line about a\n" + " // line about b\n" + " long b;"); + verifyFormat("int a; // line about a\n" + "// line 1 about b\n" + "// line 2 about b\n" + "long b;", + "int a; // line about a\n" + " // line 1 about b\n" + " // line 2 about b\n" + " long b;"); // Checks an edge case in preprocessor handling. // These comments should *not* be aligned - EXPECT_EQ( - "#if FOO\n" - "#else\n" - "long a; // Line about a\n" - "#endif\n" - "#if BAR\n" - "#else\n" - "long b_long_name; // Line about b\n" - "#endif", - format("#if FOO\n" - "#else\n" - "long a; // Line about a\n" // Previous (bad) behavior - "#endif\n" - "#if BAR\n" - "#else\n" - "long b_long_name; // Line about b\n" - "#endif", - getLLVMStyleWithColumns(80))); + verifyFormat("#if FOO\n" + "#else\n" + "long a; // Line about a\n" + "#endif\n" + "#if BAR\n" + "#else\n" + "long b_long_name; // Line about b\n" + "#endif", + "#if FOO\n" + "#else\n" + "long a; // Line about a\n" // Previous (bad) behavior + "#endif\n" + "#if BAR\n" + "#else\n" + "long b_long_name; // Line about b\n" + "#endif"); // bug 47589 - EXPECT_EQ( - "namespace m {\n\n" - "#define FOO_GLOBAL 0 // Global scope.\n" - "#define FOO_LINKLOCAL 1 // Link-local scope.\n" - "#define FOO_SITELOCAL 2 // Site-local scope (deprecated).\n" - "#define FOO_UNIQUELOCAL 3 // Unique local\n" - "#define FOO_NODELOCAL 4 // Loopback\n\n" - "} // namespace m", - format("namespace m {\n\n" - "#define FOO_GLOBAL 0 // Global scope.\n" - "#define FOO_LINKLOCAL 1 // Link-local scope.\n" - "#define FOO_SITELOCAL 2 // Site-local scope (deprecated).\n" - "#define FOO_UNIQUELOCAL 3 // Unique local\n" - "#define FOO_NODELOCAL 4 // Loopback\n\n" - "} // namespace m", - getLLVMStyleWithColumns(80))); + verifyFormat("namespace m {\n\n" + "#define FOO_GLOBAL 0 // Global scope.\n" + "#define FOO_LINKLOCAL 1 // Link-local scope.\n" + "#define FOO_SITELOCAL 2 // Site-local scope (deprecated).\n" + "#define FOO_UNIQUELOCAL 3 // Unique local\n" + "#define FOO_NODELOCAL 4 // Loopback\n\n" + "} // namespace m", + "namespace m {\n\n" + "#define FOO_GLOBAL 0 // Global scope.\n" + "#define FOO_LINKLOCAL 1 // Link-local scope.\n" + "#define FOO_SITELOCAL 2 // Site-local scope (deprecated).\n" + "#define FOO_UNIQUELOCAL 3 // Unique local\n" + "#define FOO_NODELOCAL 4 // Loopback\n\n" + "} // namespace m"); // https://llvm.org/PR53441 verifyFormat("/* */ //\n" @@ -2980,193 +2972,193 @@ TEST_F(FormatTestComments, AlignTrailingCommentsAcrossEmptyLines) { Style.AlignTrailingComments.OverEmptyLines = 2; // Cannot use verifyFormat here // test::messUp removes all new lines which changes the logic - EXPECT_EQ("#include \"a.h\" // comment\n" - "\n" - "\n" - "\n" - "#include \"ab.h\" // comment\n" - "\n" - "\n" - "#include \"abcdefg.h\" // comment", - format("#include \"a.h\" // comment\n" - "\n" - "\n" - "\n" - "#include \"ab.h\" // comment\n" - "\n" - "\n" - "#include \"abcdefg.h\" // comment", - Style)); + verifyFormat("#include \"a.h\" // comment\n" + "\n" + "\n" + "\n" + "#include \"ab.h\" // comment\n" + "\n" + "\n" + "#include \"abcdefg.h\" // comment", + "#include \"a.h\" // comment\n" + "\n" + "\n" + "\n" + "#include \"ab.h\" // comment\n" + "\n" + "\n" + "#include \"abcdefg.h\" // comment", + Style); Style.MaxEmptyLinesToKeep = 1; Style.AlignTrailingComments.OverEmptyLines = 1; // End of testing OverEmptyLines Style.ColumnLimit = 15; - EXPECT_EQ("int ab; // line\n" - "int a; // long\n" - " // long\n" - "\n" - " // long", - format("int ab; // line\n" - "int a; // long long\n" - "\n" - "// long", - Style)); + verifyFormat("int ab; // line\n" + "int a; // long\n" + " // long\n" + "\n" + " // long", + "int ab; // line\n" + "int a; // long long\n" + "\n" + "// long", + Style); Style.ColumnLimit = 15; - EXPECT_EQ("int ab; // line\n" - "\n" - "int a; // long\n" - " // long", - format("int ab; // line\n" - "\n" - "int a; // long long", - Style)); + verifyFormat("int ab; // line\n" + "\n" + "int a; // long\n" + " // long", + "int ab; // line\n" + "\n" + "int a; // long long", + Style); Style.ColumnLimit = 30; - EXPECT_EQ("int foo = 12345; // comment\n" - "int bar =\n" - " 1234; // This is a very\n" - " // long comment\n" - " // which is wrapped\n" - " // arround.\n" - "\n" - "int x = 2; // Is this still\n" - " // aligned?", - format("int foo = 12345; // comment\n" - "int bar = 1234; // This is a very long comment\n" - " // which is wrapped arround.\n" - "\n" - "int x = 2; // Is this still aligned?", - Style)); + verifyFormat("int foo = 12345; // comment\n" + "int bar =\n" + " 1234; // This is a very\n" + " // long comment\n" + " // which is wrapped\n" + " // arround.\n" + "\n" + "int x = 2; // Is this still\n" + " // aligned?", + "int foo = 12345; // comment\n" + "int bar = 1234; // This is a very long comment\n" + " // which is wrapped arround.\n" + "\n" + "int x = 2; // Is this still aligned?", + Style); Style.ColumnLimit = 35; - EXPECT_EQ("int foo = 12345; // comment\n" - "int bar =\n" - " 1234; // This is a very long\n" - " // comment which is\n" - " // wrapped arround.\n" - "\n" - "int x =\n" - " 2; // Is this still aligned?", - format("int foo = 12345; // comment\n" - "int bar = 1234; // This is a very long comment\n" - " // which is wrapped arround.\n" - "\n" - "int x = 2; // Is this still aligned?", - Style)); + verifyFormat("int foo = 12345; // comment\n" + "int bar =\n" + " 1234; // This is a very long\n" + " // comment which is\n" + " // wrapped arround.\n" + "\n" + "int x =\n" + " 2; // Is this still aligned?", + "int foo = 12345; // comment\n" + "int bar = 1234; // This is a very long comment\n" + " // which is wrapped arround.\n" + "\n" + "int x = 2; // Is this still aligned?", + Style); Style.ColumnLimit = 40; - EXPECT_EQ("int foo = 12345; // comment\n" - "int bar =\n" - " 1234; // This is a very long comment\n" - " // which is wrapped arround.\n" - "\n" - "int x = 2; // Is this still aligned?", - format("int foo = 12345; // comment\n" - "int bar = 1234; // This is a very long comment\n" - " // which is wrapped arround.\n" - "\n" - "int x = 2; // Is this still aligned?", - Style)); + verifyFormat("int foo = 12345; // comment\n" + "int bar =\n" + " 1234; // This is a very long comment\n" + " // which is wrapped arround.\n" + "\n" + "int x = 2; // Is this still aligned?", + "int foo = 12345; // comment\n" + "int bar = 1234; // This is a very long comment\n" + " // which is wrapped arround.\n" + "\n" + "int x = 2; // Is this still aligned?", + Style); Style.ColumnLimit = 45; - EXPECT_EQ("int foo = 12345; // comment\n" - "int bar =\n" - " 1234; // This is a very long comment\n" - " // which is wrapped arround.\n" - "\n" - "int x = 2; // Is this still aligned?", - format("int foo = 12345; // comment\n" - "int bar = 1234; // This is a very long comment\n" - " // which is wrapped arround.\n" - "\n" - "int x = 2; // Is this still aligned?", - Style)); + verifyFormat("int foo = 12345; // comment\n" + "int bar =\n" + " 1234; // This is a very long comment\n" + " // which is wrapped arround.\n" + "\n" + "int x = 2; // Is this still aligned?", + "int foo = 12345; // comment\n" + "int bar = 1234; // This is a very long comment\n" + " // which is wrapped arround.\n" + "\n" + "int x = 2; // Is this still aligned?", + Style); Style.ColumnLimit = 80; - EXPECT_EQ("int a; // line about a\n" - "\n" - "// line about b\n" - "long b;", - format("int a; // line about a\n" - "\n" - " // line about b\n" - " long b;", - Style)); + verifyFormat("int a; // line about a\n" + "\n" + "// line about b\n" + "long b;", + "int a; // line about a\n" + "\n" + " // line about b\n" + " long b;", + Style); Style.ColumnLimit = 80; - EXPECT_EQ("int a; // line about a\n" - "\n" - "// line 1 about b\n" - "// line 2 about b\n" - "long b;", - format("int a; // line about a\n" - "\n" - " // line 1 about b\n" - " // line 2 about b\n" - " long b;", - Style)); + verifyFormat("int a; // line about a\n" + "\n" + "// line 1 about b\n" + "// line 2 about b\n" + "long b;", + "int a; // line about a\n" + "\n" + " // line 1 about b\n" + " // line 2 about b\n" + " long b;", + Style); } TEST_F(FormatTestComments, AlignTrailingCommentsLeave) { FormatStyle Style = getLLVMStyle(); Style.AlignTrailingComments.Kind = FormatStyle::TCAS_Leave; - EXPECT_EQ("int a;// do not touch\n" - "int b; // any comments\n" - "int c; // comment\n" - "int d; // comment", - format("int a;// do not touch\n" - "int b; // any comments\n" - "int c; // comment\n" - "int d; // comment", - Style)); - - EXPECT_EQ("int a; // do not touch\n" - "int b; // any comments\n" - "int c; // comment\n" - "int d;// comment", - format("int a; // do not touch\n" - "int b; // any comments\n" - "int c; // comment\n" - "int d;// comment", - Style)); - - EXPECT_EQ("// do not touch\n" - "int a; // any comments\n" - "\n" - " // comment\n" - "// comment\n" - "\n" - "// comment", - format("// do not touch\n" - "int a; // any comments\n" - "\n" - " // comment\n" - "// comment\n" - "\n" - "// comment", - Style)); - - EXPECT_EQ("// do not touch\n" - "int a; // any comments\n" - "\n" - " // comment\n" - "// comment\n" - "\n" - "// comment", - format("// do not touch\n" - "int a; // any comments\n" - "\n" - "\n" - " // comment\n" - "// comment\n" - "\n" - "\n" - "// comment", - Style)); + verifyFormat("int a;// do not touch\n" + "int b; // any comments\n" + "int c; // comment\n" + "int d; // comment", + "int a;// do not touch\n" + "int b; // any comments\n" + "int c; // comment\n" + "int d; // comment", + Style); + + verifyFormat("int a; // do not touch\n" + "int b; // any comments\n" + "int c; // comment\n" + "int d;// comment", + "int a; // do not touch\n" + "int b; // any comments\n" + "int c; // comment\n" + "int d;// comment", + Style); + + verifyFormat("// do not touch\n" + "int a; // any comments\n" + "\n" + " // comment\n" + "// comment\n" + "\n" + "// comment", + "// do not touch\n" + "int a; // any comments\n" + "\n" + " // comment\n" + "// comment\n" + "\n" + "// comment", + Style); + + verifyFormat("// do not touch\n" + "int a; // any comments\n" + "\n" + " // comment\n" + "// comment\n" + "\n" + "// comment", + "// do not touch\n" + "int a; // any comments\n" + "\n" + "\n" + " // comment\n" + "// comment\n" + "\n" + "\n" + "// comment", + Style); verifyFormat("namespace ns {\n" "int i;\n" @@ -3186,36 +3178,36 @@ TEST_F(FormatTestComments, AlignTrailingCommentsLeave) { // Allow to keep 2 empty lines Style.MaxEmptyLinesToKeep = 2; - EXPECT_EQ("// do not touch\n" - "int a; // any comments\n" - "\n" - "\n" - " // comment\n" - "// comment\n" - "\n" - "// comment", - format("// do not touch\n" - "int a; // any comments\n" - "\n" - "\n" - " // comment\n" - "// comment\n" - "\n" - "// comment", - Style)); + verifyFormat("// do not touch\n" + "int a; // any comments\n" + "\n" + "\n" + " // comment\n" + "// comment\n" + "\n" + "// comment", + "// do not touch\n" + "int a; // any comments\n" + "\n" + "\n" + " // comment\n" + "// comment\n" + "\n" + "// comment", + Style); Style.MaxEmptyLinesToKeep = 1; // Just format comments normally when leaving exceeds the column limit Style.ColumnLimit = 35; - EXPECT_EQ("int foo = 12345; // comment\n" - "int bar =\n" - " 1234; // This is a very long\n" - " // comment which is\n" - " // wrapped arround.", - format("int foo = 12345; // comment\n" - "int bar = 1234; // This is a very long comment\n" - " // which is wrapped arround.", - Style)); + verifyFormat("int foo = 12345; // comment\n" + "int bar =\n" + " 1234; // This is a very long\n" + " // comment which is\n" + " // wrapped arround.", + "int foo = 12345; // comment\n" + "int bar = 1234; // This is a very long comment\n" + " // which is wrapped arround.", + Style); Style = getLLVMStyle(); Style.AlignTrailingComments.Kind = FormatStyle::TCAS_Leave; @@ -3502,171 +3494,171 @@ TEST_F(FormatTestComments, DontAlignOverScope) { } TEST_F(FormatTestComments, AlignsBlockCommentDecorations) { - EXPECT_EQ("/*\n" - " */", - format("/*\n" - "*/")); - EXPECT_EQ("/*\n" - " */", - format("/*\n" - " */")); - EXPECT_EQ("/*\n" - " */", - format("/*\n" - " */")); + verifyFormat("/*\n" + " */", + "/*\n" + "*/"); + verifyFormat("/*\n" + " */", + "/*\n" + " */"); + verifyFormat("/*\n" + " */", + "/*\n" + " */"); // Align a single line. - EXPECT_EQ("/*\n" - " * line */", - format("/*\n" - "* line */")); - EXPECT_EQ("/*\n" - " * line */", - format("/*\n" - " * line */")); - EXPECT_EQ("/*\n" - " * line */", - format("/*\n" - " * line */")); - EXPECT_EQ("/*\n" - " * line */", - format("/*\n" - " * line */")); - EXPECT_EQ("/**\n" - " * line */", - format("/**\n" - "* line */")); - EXPECT_EQ("/**\n" - " * line */", - format("/**\n" - " * line */")); - EXPECT_EQ("/**\n" - " * line */", - format("/**\n" - " * line */")); - EXPECT_EQ("/**\n" - " * line */", - format("/**\n" - " * line */")); - EXPECT_EQ("/**\n" - " * line */", - format("/**\n" - " * line */")); + verifyFormat("/*\n" + " * line */", + "/*\n" + "* line */"); + verifyFormat("/*\n" + " * line */", + "/*\n" + " * line */"); + verifyFormat("/*\n" + " * line */", + "/*\n" + " * line */"); + verifyFormat("/*\n" + " * line */", + "/*\n" + " * line */"); + verifyFormat("/**\n" + " * line */", + "/**\n" + "* line */"); + verifyFormat("/**\n" + " * line */", + "/**\n" + " * line */"); + verifyFormat("/**\n" + " * line */", + "/**\n" + " * line */"); + verifyFormat("/**\n" + " * line */", + "/**\n" + " * line */"); + verifyFormat("/**\n" + " * line */", + "/**\n" + " * line */"); // Align the end '*/' after a line. - EXPECT_EQ("/*\n" - " * line\n" - " */", - format("/*\n" - "* line\n" - "*/")); - EXPECT_EQ("/*\n" - " * line\n" - " */", - format("/*\n" - " * line\n" - " */")); - EXPECT_EQ("/*\n" - " * line\n" - " */", - format("/*\n" - " * line\n" - " */")); + verifyFormat("/*\n" + " * line\n" + " */", + "/*\n" + "* line\n" + "*/"); + verifyFormat("/*\n" + " * line\n" + " */", + "/*\n" + " * line\n" + " */"); + verifyFormat("/*\n" + " * line\n" + " */", + "/*\n" + " * line\n" + " */"); // Align two lines. - EXPECT_EQ("/* line 1\n" - " * line 2 */", - format("/* line 1\n" - " * line 2 */")); - EXPECT_EQ("/* line 1\n" - " * line 2 */", - format("/* line 1\n" - "* line 2 */")); - EXPECT_EQ("/* line 1\n" - " * line 2 */", - format("/* line 1\n" - " * line 2 */")); - EXPECT_EQ("/* line 1\n" - " * line 2 */", - format("/* line 1\n" - " * line 2 */")); - EXPECT_EQ("/* line 1\n" - " * line 2 */", - format("/* line 1\n" - " * line 2 */")); - EXPECT_EQ("int i; /* line 1\n" - " * line 2 */", - format("int i; /* line 1\n" - "* line 2 */")); - EXPECT_EQ("int i; /* line 1\n" - " * line 2 */", - format("int i; /* line 1\n" - " * line 2 */")); - EXPECT_EQ("int i; /* line 1\n" - " * line 2 */", - format("int i; /* line 1\n" - " * line 2 */")); + verifyFormat("/* line 1\n" + " * line 2 */", + "/* line 1\n" + " * line 2 */"); + verifyFormat("/* line 1\n" + " * line 2 */", + "/* line 1\n" + "* line 2 */"); + verifyFormat("/* line 1\n" + " * line 2 */", + "/* line 1\n" + " * line 2 */"); + verifyFormat("/* line 1\n" + " * line 2 */", + "/* line 1\n" + " * line 2 */"); + verifyFormat("/* line 1\n" + " * line 2 */", + "/* line 1\n" + " * line 2 */"); + verifyFormat("int i; /* line 1\n" + " * line 2 */", + "int i; /* line 1\n" + "* line 2 */"); + verifyFormat("int i; /* line 1\n" + " * line 2 */", + "int i; /* line 1\n" + " * line 2 */"); + verifyFormat("int i; /* line 1\n" + " * line 2 */", + "int i; /* line 1\n" + " * line 2 */"); // Align several lines. - EXPECT_EQ("/* line 1\n" - " * line 2\n" - " * line 3 */", - format("/* line 1\n" - " * line 2\n" - "* line 3 */")); - EXPECT_EQ("/* line 1\n" - " * line 2\n" - " * line 3 */", - format("/* line 1\n" - " * line 2\n" - "* line 3 */")); - EXPECT_EQ("/*\n" - "** line 1\n" - "** line 2\n" - "*/", - format("/*\n" - "** line 1\n" - " ** line 2\n" - "*/")); + verifyFormat("/* line 1\n" + " * line 2\n" + " * line 3 */", + "/* line 1\n" + " * line 2\n" + "* line 3 */"); + verifyFormat("/* line 1\n" + " * line 2\n" + " * line 3 */", + "/* line 1\n" + " * line 2\n" + "* line 3 */"); + verifyFormat("/*\n" + "** line 1\n" + "** line 2\n" + "*/", + "/*\n" + "** line 1\n" + " ** line 2\n" + "*/"); // Align with different indent after the decorations. - EXPECT_EQ("/*\n" - " * line 1\n" - " * line 2\n" - " * line 3\n" - " * line 4\n" - " */", - format("/*\n" - "* line 1\n" - " * line 2\n" - " * line 3\n" - "* line 4\n" - "*/")); + verifyFormat("/*\n" + " * line 1\n" + " * line 2\n" + " * line 3\n" + " * line 4\n" + " */", + "/*\n" + "* line 1\n" + " * line 2\n" + " * line 3\n" + "* line 4\n" + "*/"); // Align empty or blank lines. - EXPECT_EQ("/**\n" - " *\n" - " *\n" - " *\n" - " */", - format("/**\n" - "* \n" - " * \n" - " *\n" - "*/")); + verifyFormat("/**\n" + " *\n" + " *\n" + " *\n" + " */", + "/**\n" + "* \n" + " * \n" + " *\n" + "*/"); // Align while breaking and reflowing. - EXPECT_EQ("/*\n" - " * long long long\n" - " * long long\n" - " *\n" - " * long */", - format("/*\n" - " * long long long long\n" - " * long\n" - " *\n" - "* long */", - getLLVMStyleWithColumns(20))); + verifyFormat("/*\n" + " * long long long\n" + " * long long\n" + " *\n" + " * long */", + "/*\n" + " * long long long long\n" + " * long\n" + " *\n" + "* long */", + getLLVMStyleWithColumns(20)); } TEST_F(FormatTestComments, NoCrash_Bug34236) { @@ -3674,110 +3666,110 @@ TEST_F(FormatTestComments, NoCrash_Bug34236) { // https://bugs.llvm.org/show_bug.cgi?id=34236 // Temporarily disable formatting for readability. // clang-format off - EXPECT_EQ( + verifyFormat( "/* */ /*\n" " * a\n" " * b c d*/", - format( "/* */ /*\n" " * a b\n" -" * c d*/", - getLLVMStyleWithColumns(80))); +" * c d*/"); // clang-format on } TEST_F(FormatTestComments, NonTrailingBlockComments) { - verifyFormat("const /** comment comment */ A = B;", - getLLVMStyleWithColumns(40)); + const auto Style40 = getLLVMStyleWithColumns(40); + + verifyFormat("const /** comment comment */ A = B;", Style40); verifyFormat("const /** comment comment comment */ A =\n" " B;", - getLLVMStyleWithColumns(40)); - - EXPECT_EQ("const /** comment comment comment\n" - " comment */\n" - " A = B;", - format("const /** comment comment comment comment */\n" - " A = B;", - getLLVMStyleWithColumns(40))); + Style40); + + verifyFormat("const /** comment comment comment\n" + " comment */\n" + " A = B;", + "const /** comment comment comment comment */\n" + " A = B;", + Style40); } TEST_F(FormatTestComments, PythonStyleComments) { + const auto ProtoStyle20 = getTextProtoStyleWithColumns(20); // Keeps a space after '#'. - EXPECT_EQ("# comment\n" - "key: value", - format("#comment\n" - "key:value", - getTextProtoStyleWithColumns(20))); - EXPECT_EQ("# comment\n" - "key: value", - format("# comment\n" - "key:value", - getTextProtoStyleWithColumns(20))); + verifyFormat("# comment\n" + "key: value", + "#comment\n" + "key:value", + ProtoStyle20); + verifyFormat("# comment\n" + "key: value", + "# comment\n" + "key:value", + ProtoStyle20); // Breaks long comment. - EXPECT_EQ("# comment comment\n" - "# comment\n" - "key: value", - format("# comment comment comment\n" - "key:value", - getTextProtoStyleWithColumns(20))); + verifyFormat("# comment comment\n" + "# comment\n" + "key: value", + "# comment comment comment\n" + "key:value", + ProtoStyle20); // Indents comments. - EXPECT_EQ("data {\n" - " # comment comment\n" - " # comment\n" - " key: value\n" - "}", - format("data {\n" - "# comment comment comment\n" - "key: value}", - getTextProtoStyleWithColumns(20))); - EXPECT_EQ("data {\n" - " # comment comment\n" - " # comment\n" - " key: value\n" - "}", - format("data {# comment comment comment\n" - "key: value}", - getTextProtoStyleWithColumns(20))); + verifyFormat("data {\n" + " # comment comment\n" + " # comment\n" + " key: value\n" + "}", + "data {\n" + "# comment comment comment\n" + "key: value}", + ProtoStyle20); + verifyFormat("data {\n" + " # comment comment\n" + " # comment\n" + " key: value\n" + "}", + "data {# comment comment comment\n" + "key: value}", + ProtoStyle20); // Reflows long comments. - EXPECT_EQ("# comment comment\n" - "# comment comment\n" - "key: value", - format("# comment comment comment\n" - "# comment\n" - "key:value", - getTextProtoStyleWithColumns(20))); + verifyFormat("# comment comment\n" + "# comment comment\n" + "key: value", + "# comment comment comment\n" + "# comment\n" + "key:value", + ProtoStyle20); // Breaks trailing comments. - EXPECT_EQ("k: val # comment\n" - " # comment\n" - "a: 1", - format("k:val#comment comment\n" - "a:1", - getTextProtoStyleWithColumns(20))); - EXPECT_EQ("id {\n" - " k: val # comment\n" - " # comment\n" - " # line line\n" - " a: 1\n" - "}", - format("id {k:val#comment comment\n" - "# line line\n" - "a:1}", - getTextProtoStyleWithColumns(20))); + verifyFormat("k: val # comment\n" + " # comment\n" + "a: 1", + "k:val#comment comment\n" + "a:1", + ProtoStyle20); + verifyFormat("id {\n" + " k: val # comment\n" + " # comment\n" + " # line line\n" + " a: 1\n" + "}", + "id {k:val#comment comment\n" + "# line line\n" + "a:1}", + ProtoStyle20); // Aligns trailing comments. - EXPECT_EQ("k: val # commen1\n" - " # commen2\n" - " # commen3\n" - "# commen4\n" - "a: 1 # commen5\n" - " # commen6\n" - " # commen7", - format("k:val#commen1 commen2\n" - " #commen3\n" - "# commen4\n" - "a:1#commen5 commen6\n" - " #commen7", - getTextProtoStyleWithColumns(20))); + verifyFormat("k: val # commen1\n" + " # commen2\n" + " # commen3\n" + "# commen4\n" + "a: 1 # commen5\n" + " # commen6\n" + " # commen7", + "k:val#commen1 commen2\n" + " #commen3\n" + "# commen4\n" + "a:1#commen5 commen6\n" + " #commen7", + ProtoStyle20); } TEST_F(FormatTestComments, BreaksBeforeTrailingUnbreakableSequence) { @@ -3791,16 +3783,15 @@ TEST_F(FormatTestComments, BreaksBeforeTrailingUnbreakableSequence) { TEST_F(FormatTestComments, ReflowBackslashCrash) { // clang-format off - EXPECT_EQ( + verifyFormat( "// How to run:\n" "// bbbbb run \\\n" "// rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr\n" "// \\ <log_file> -- --output_directory=\"<output_directory>\"", - format( "// How to run:\n" "// bbbbb run \\\n" "// rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr \\\n" -"// <log_file> -- --output_directory=\"<output_directory>\"")); +"// <log_file> -- --output_directory=\"<output_directory>\""); // clang-format on } @@ -3809,136 +3800,135 @@ TEST_F(FormatTestComments, IndentsLongJavadocAnnotatedLines) { Style.ColumnLimit = 60; FormatStyle Style20 = getGoogleStyle(FormatStyle::LK_Java); Style20.ColumnLimit = 20; - EXPECT_EQ( - "/**\n" - " * @param x long long long long long long long long long\n" - " * long\n" - " */", - format("/**\n" - " * @param x long long long long long long long long long long\n" - " */", - Style)); - EXPECT_EQ("/**\n" - " * @param x long long long long long long long long long\n" - " * long long long long long long long long long long\n" - " */", - format("/**\n" - " * @param x long long long long long long long long long " - "long long long long long long long long long long\n" - " */", - Style)); - EXPECT_EQ("/**\n" - " * @param x long long long long long long long long long\n" - " * long long long long long long long long long long\n" - " * long\n" - " */", - format("/**\n" - " * @param x long long long long long long long long long " - "long long long long long long long long long long long\n" - " */", - Style)); - EXPECT_EQ("/**\n" - " * Sentence that\n" - " * should be broken.\n" - " * @param short\n" - " * keep indentation\n" - " */", - format("/**\n" - " * Sentence that should be broken.\n" - " * @param short\n" - " * keep indentation\n" - " */", - Style20)); - - EXPECT_EQ("/**\n" - " * @param l1 long1\n" - " * to break\n" - " * @param l2 long2\n" - " * to break\n" - " */", - format("/**\n" - " * @param l1 long1 to break\n" - " * @param l2 long2 to break\n" - " */", - Style20)); - - EXPECT_EQ("/**\n" - " * @param xx to\n" - " * break\n" - " * no reflow\n" - " */", - format("/**\n" - " * @param xx to break\n" - " * no reflow\n" - " */", - Style20)); - - EXPECT_EQ("/**\n" - " * @param xx to\n" - " * break yes\n" - " * reflow\n" - " */", - format("/**\n" - " * @param xx to break\n" - " * yes reflow\n" - " */", - Style20)); + verifyFormat("/**\n" + " * @param x long long long long long long long long long\n" + " * long\n" + " */", + "/**\n" + " * @param x long long long long long long long long long long\n" + " */", + Style); + verifyFormat("/**\n" + " * @param x long long long long long long long long long\n" + " * long long long long long long long long long long\n" + " */", + "/**\n" + " * @param x long long long long long long long long long " + "long long long long long long long long long long\n" + " */", + Style); + verifyFormat("/**\n" + " * @param x long long long long long long long long long\n" + " * long long long long long long long long long long\n" + " * long\n" + " */", + "/**\n" + " * @param x long long long long long long long long long " + "long long long long long long long long long long long\n" + " */", + Style); + verifyFormat("/**\n" + " * Sentence that\n" + " * should be broken.\n" + " * @param short\n" + " * keep indentation\n" + " */", + "/**\n" + " * Sentence that should be broken.\n" + " * @param short\n" + " * keep indentation\n" + " */", + Style20); + + verifyFormat("/**\n" + " * @param l1 long1\n" + " * to break\n" + " * @param l2 long2\n" + " * to break\n" + " */", + "/**\n" + " * @param l1 long1 to break\n" + " * @param l2 long2 to break\n" + " */", + Style20); + + verifyFormat("/**\n" + " * @param xx to\n" + " * break\n" + " * no reflow\n" + " */", + "/**\n" + " * @param xx to break\n" + " * no reflow\n" + " */", + Style20); + + verifyFormat("/**\n" + " * @param xx to\n" + " * break yes\n" + " * reflow\n" + " */", + "/**\n" + " * @param xx to break\n" + " * yes reflow\n" + " */", + Style20); FormatStyle JSStyle20 = getGoogleStyle(FormatStyle::LK_JavaScript); JSStyle20.ColumnLimit = 20; - EXPECT_EQ("/**\n" - " * @param l1 long1\n" - " * to break\n" - " */", - format("/**\n" - " * @param l1 long1 to break\n" - " */", - JSStyle20)); - EXPECT_EQ("/**\n" - " * @param {l1 long1\n" - " * to break}\n" - " */", - format("/**\n" - " * @param {l1 long1 to break}\n" - " */", - JSStyle20)); + verifyFormat("/**\n" + " * @param l1 long1\n" + " * to break\n" + " */", + "/**\n" + " * @param l1 long1 to break\n" + " */", + JSStyle20); + verifyFormat("/**\n" + " * @param {l1 long1\n" + " * to break}\n" + " */", + "/**\n" + " * @param {l1 long1 to break}\n" + " */", + JSStyle20); } TEST_F(FormatTestComments, SpaceAtLineCommentBegin) { FormatStyle Style = getLLVMStyle(); - StringRef NoTextInComment = " // \n" - "\n" - "void foo() {// \n" - "// \n" - "}"; - - EXPECT_EQ("//\n" - "\n" - "void foo() { //\n" - " //\n" - "}", - format(NoTextInComment, Style)); + constexpr StringRef NoTextInComment(" // \n" + "\n" + "void foo() {// \n" + "// \n" + "}"); + + verifyFormat("//\n" + "\n" + "void foo() { //\n" + " //\n" + "}", + NoTextInComment, Style); Style.SpacesInLineCommentPrefix.Minimum = 0; verifyFormat("//#comment", Style); - EXPECT_EQ("//\n" - "\n" - "void foo() { //\n" - " //\n" - "}", - format(NoTextInComment, Style)); + verifyFormat("//\n" + "\n" + "void foo() { //\n" + " //\n" + "}", + NoTextInComment, Style); Style.SpacesInLineCommentPrefix.Minimum = 5; - EXPECT_EQ("// #comment", format("//#comment", Style)); - EXPECT_EQ("//\n" - "\n" - "void foo() { //\n" - " //\n" - "}", - format(NoTextInComment, Style)); + verifyFormat("// #comment", "//#comment", Style); + verifyFormat("//\n" + "\n" + "void foo() { //\n" + " //\n" + "}", + NoTextInComment, Style); Style = getLLVMStyle(); - StringRef Code = + constexpr StringRef Code( "//Free comment without space\n" "\n" "// Free comment with 3 spaces\n" @@ -4008,226 +3998,232 @@ TEST_F(FormatTestComments, SpaceAtLineCommentBegin) { "//} will not move\n" "\n" "//vv will only move\n" - "//} if the line above does"; - - EXPECT_EQ("// Free comment without space\n" - "\n" - "// Free comment with 3 spaces\n" - "\n" - "/// Free Doxygen without space\n" - "\n" - "/// Free Doxygen with 3 spaces\n" - "\n" - "// 🐉 A nice dragon\n" - "\n" - "//\t abccba\n" - "\n" - "//\\t deffed\n" - "\n" - "// 🐉 Another nice dragon\n" - "\n" - "// \t Three leading spaces following tab\n" - "\n" - "// \\t Three leading spaces following backslash\n" - "\n" - "/// A Doxygen Comment with a nested list:\n" - "/// - Foo\n" - "/// - Bar\n" - "/// - Baz\n" - "/// - End\n" - "/// of the inner list\n" - "/// .\n" - "/// .\n" - "\n" - "namespace Foo {\n" - "bool bar(bool b) {\n" - " bool ret1 = true; ///< Doxygenstyle without space\n" - " bool ret2 = true; ///< Doxygenstyle with 3 spaces\n" - " if (b) {\n" - " // Foo\n" - "\n" - " // In function comment\n" - " ret2 = false;\n" - " } // End of if\n" - "\n" - " // if (ret1) {\n" - " // return ret2;\n" - " // }\n" - "\n" - " // if (ret1) {\n" - " // return ret2;\n" - " // }\n" - "\n" - " return ret1 && ret2;\n" - "}\n" - "} // namespace Foo\n" - "\n" - "namespace Bar {\n" - "int foo();\n" - "} // namespace Bar\n" - "//@Nothing added because of the non ascii char\n" - "\n" - "//@ Nothing removed because of the non ascii char\n" - "\n" - "// Comment to move to the left\n" - "// But not this?\n" - "// @but this\n" - "\n" - "// Comment to move to the right\n" - "//@ this stays\n" - "\n" - "//} will not move\n" - "\n" - "// vv will only move\n" - "// } if the line above does", - format(Code, Style)); + "//} if the line above does"); + + constexpr StringRef Code2( + "// Free comment without space\n" + "\n" + "// Free comment with 3 spaces\n" + "\n" + "/// Free Doxygen without space\n" + "\n" + "/// Free Doxygen with 3 spaces\n" + "\n" + "// 🐉 A nice dragon\n" + "\n" + "//\t abccba\n" + "\n" + "//\\t deffed\n" + "\n" + "// 🐉 Another nice dragon\n" + "\n" + "// \t Three leading spaces following tab\n" + "\n" + "// \\t Three leading spaces following backslash\n" + "\n" + "/// A Doxygen Comment with a nested list:\n" + "/// - Foo\n" + "/// - Bar\n" + "/// - Baz\n" + "/// - End\n" + "/// of the inner list\n" + "/// .\n" + "/// .\n" + "\n" + "namespace Foo {\n" + "bool bar(bool b) {\n" + " bool ret1 = true; ///< Doxygenstyle without space\n" + " bool ret2 = true; ///< Doxygenstyle with 3 spaces\n" + " if (b) {\n" + " // Foo\n" + "\n" + " // In function comment\n" + " ret2 = false;\n" + " } // End of if\n" + "\n" + " // if (ret1) {\n" + " // return ret2;\n" + " // }\n" + "\n" + " // if (ret1) {\n" + " // return ret2;\n" + " // }\n" + "\n" + " return ret1 && ret2;\n" + "}\n" + "} // namespace Foo\n" + "\n" + "namespace Bar {\n" + "int foo();\n" + "} // namespace Bar\n" + "//@Nothing added because of the non ascii char\n" + "\n" + "//@ Nothing removed because of the non ascii char\n" + "\n" + "// Comment to move to the left\n" + "// But not this?\n" + "// @but this\n" + "\n" + "// Comment to move to the right\n" + "//@ this stays\n" + "\n" + "//} will not move\n" + "\n" + "// vv will only move\n" + "// } if the line above does"); + + constexpr StringRef Code3( + "//Free comment without space\n" + "\n" + "//Free comment with 3 spaces\n" + "\n" + "///Free Doxygen without space\n" + "\n" + "///Free Doxygen with 3 spaces\n" + "\n" + "//🐉 A nice dragon\n" + "\n" + "//\t abccba\n" + "\n" + "//\\t deffed\n" + "\n" + "//🐉 Another nice dragon\n" + "\n" + "//\t Three leading spaces following tab\n" + "\n" + "//\\t Three leading spaces following backslash\n" + "\n" + "///A Doxygen Comment with a nested list:\n" + "///- Foo\n" + "///- Bar\n" + "/// - Baz\n" // Here we keep the relative indentation + "/// - End\n" + "/// of the inner list\n" + "/// .\n" + "///.\n" + "\n" + "namespace Foo {\n" + "bool bar(bool b) {\n" + " bool ret1 = true; ///<Doxygenstyle without space\n" + " bool ret2 = true; ///<Doxygenstyle with 3 spaces\n" + " if (b) {\n" + " //Foo\n" + "\n" + " //In function comment\n" + " ret2 = false;\n" + " } //End of if\n" + "\n" + " //if (ret1) {\n" + " // return ret2;\n" + " //}\n" + "\n" + " //if (ret1) {\n" + " // return ret2;\n" + " //}\n" + "\n" + " return ret1 && ret2;\n" + "}\n" + "} //namespace Foo\n" + "\n" + "namespace Bar {\n" + "int foo();\n" + "} //namespace Bar\n" + "//@Nothing added because of the non ascii char\n" + "\n" + "//@ Nothing removed because of the non ascii char\n" + "\n" + "//Comment to move to the left\n" + "//But not this?\n" + "//@but this\n" + "\n" + "//Comment to move to the right\n" + "//@ this stays\n" + "\n" + "//} will not move\n" + "\n" + "//vv will only move\n" + "//} if the line above does"); + + constexpr StringRef Code4( + "// Free comment without space\n" + "\n" + "// Free comment with 3 spaces\n" + "\n" + "/// Free Doxygen without space\n" + "\n" + "/// Free Doxygen with 3 spaces\n" + "\n" + "// 🐉 A nice dragon\n" + "\n" + "//\t abccba\n" + "\n" + "//\\t deffed\n" + "\n" + "// 🐉 Another nice dragon\n" + "\n" + "// \t Three leading spaces following tab\n" + "\n" + "// \\t Three leading spaces following backslash\n" + "\n" + "/// A Doxygen Comment with a nested list:\n" + "/// - Foo\n" + "/// - Bar\n" + "/// - Baz\n" + "/// - End\n" + "/// of the inner list\n" + "/// .\n" + "/// .\n" + "\n" + "namespace Foo {\n" + "bool bar(bool b) {\n" + " bool ret1 = true; ///< Doxygenstyle without space\n" + " bool ret2 = true; ///< Doxygenstyle with 3 spaces\n" + " if (b) {\n" + " // Foo\n" + "\n" + " // In function comment\n" + " ret2 = false;\n" + " } // End of if\n" + "\n" + " // if (ret1) {\n" + " // return ret2;\n" + " // }\n" + "\n" + " // if (ret1) {\n" + " // return ret2;\n" + " // }\n" + "\n" + " return ret1 && ret2;\n" + "}\n" + "} // namespace Foo\n" + "\n" + "namespace Bar {\n" + "int foo();\n" + "} // namespace Bar\n" + "//@Nothing added because of the non ascii char\n" + "\n" + "//@ Nothing removed because of the non ascii char\n" + "\n" + "// Comment to move to the left\n" + "// But not this?\n" + "// @but this\n" + "\n" + "// Comment to move to the right\n" + "//@ this stays\n" + "\n" + "//} will not move\n" + "\n" + "// vv will only move\n" + "// } if the line above does"); + + verifyFormat(Code2, Code, Style); Style.SpacesInLineCommentPrefix = {0, 0}; - EXPECT_EQ("//#comment", format("// #comment", Style)); - EXPECT_EQ("//Free comment without space\n" - "\n" - "//Free comment with 3 spaces\n" - "\n" - "///Free Doxygen without space\n" - "\n" - "///Free Doxygen with 3 spaces\n" - "\n" - "//🐉 A nice dragon\n" - "\n" - "//\t abccba\n" - "\n" - "//\\t deffed\n" - "\n" - "//🐉 Another nice dragon\n" - "\n" - "//\t Three leading spaces following tab\n" - "\n" - "//\\t Three leading spaces following backslash\n" - "\n" - "///A Doxygen Comment with a nested list:\n" - "///- Foo\n" - "///- Bar\n" - "/// - Baz\n" // Here we keep the relative indentation - "/// - End\n" - "/// of the inner list\n" - "/// .\n" - "///.\n" - "\n" - "namespace Foo {\n" - "bool bar(bool b) {\n" - " bool ret1 = true; ///<Doxygenstyle without space\n" - " bool ret2 = true; ///<Doxygenstyle with 3 spaces\n" - " if (b) {\n" - " //Foo\n" - "\n" - " //In function comment\n" - " ret2 = false;\n" - " } //End of if\n" - "\n" - " //if (ret1) {\n" - " // return ret2;\n" - " //}\n" - "\n" - " //if (ret1) {\n" - " // return ret2;\n" - " //}\n" - "\n" - " return ret1 && ret2;\n" - "}\n" - "} //namespace Foo\n" - "\n" - "namespace Bar {\n" - "int foo();\n" - "} //namespace Bar\n" - "//@Nothing added because of the non ascii char\n" - "\n" - "//@ Nothing removed because of the non ascii char\n" - "\n" - "//Comment to move to the left\n" - "//But not this?\n" - "//@but this\n" - "\n" - "//Comment to move to the right\n" - "//@ this stays\n" - "\n" - "//} will not move\n" - "\n" - "//vv will only move\n" - "//} if the line above does", - format(Code, Style)); + verifyFormat("//#comment", "// #comment", Style); + verifyFormat(Code3, Code, Style); Style.SpacesInLineCommentPrefix = {2, -1u}; - EXPECT_EQ("// Free comment without space\n" - "\n" - "// Free comment with 3 spaces\n" - "\n" - "/// Free Doxygen without space\n" - "\n" - "/// Free Doxygen with 3 spaces\n" - "\n" - "// 🐉 A nice dragon\n" - "\n" - "//\t abccba\n" - "\n" - "//\\t deffed\n" - "\n" - "// 🐉 Another nice dragon\n" - "\n" - "// \t Three leading spaces following tab\n" - "\n" - "// \\t Three leading spaces following backslash\n" - "\n" - "/// A Doxygen Comment with a nested list:\n" - "/// - Foo\n" - "/// - Bar\n" - "/// - Baz\n" - "/// - End\n" - "/// of the inner list\n" - "/// .\n" - "/// .\n" - "\n" - "namespace Foo {\n" - "bool bar(bool b) {\n" - " bool ret1 = true; ///< Doxygenstyle without space\n" - " bool ret2 = true; ///< Doxygenstyle with 3 spaces\n" - " if (b) {\n" - " // Foo\n" - "\n" - " // In function comment\n" - " ret2 = false;\n" - " } // End of if\n" - "\n" - " // if (ret1) {\n" - " // return ret2;\n" - " // }\n" - "\n" - " // if (ret1) {\n" - " // return ret2;\n" - " // }\n" - "\n" - " return ret1 && ret2;\n" - "}\n" - "} // namespace Foo\n" - "\n" - "namespace Bar {\n" - "int foo();\n" - "} // namespace Bar\n" - "//@Nothing added because of the non ascii char\n" - "\n" - "//@ Nothing removed because of the non ascii char\n" - "\n" - "// Comment to move to the left\n" - "// But not this?\n" - "// @but this\n" - "\n" - "// Comment to move to the right\n" - "//@ this stays\n" - "\n" - "//} will not move\n" - "\n" - "// vv will only move\n" - "// } if the line above does", - format(Code, Style)); + verifyFormat(Code4, Code, Style); Style = getLLVMStyleWithColumns(20); StringRef WrapCode = "//Lorem ipsum dolor sit amet\n" @@ -4237,485 +4233,276 @@ TEST_F(FormatTestComments, SpaceAtLineCommentBegin) { "void f() {//Hello World\n" "}"; - EXPECT_EQ("// Lorem ipsum dolor\n" - "// sit amet\n" - "\n" - "// Lorem ipsum\n" - "// dolor sit amet\n" - "\n" - "void f() { // Hello\n" - " // World\n" - "}", - format(WrapCode, Style)); + verifyFormat("// Lorem ipsum dolor\n" + "// sit amet\n" + "\n" + "// Lorem ipsum\n" + "// dolor sit amet\n" + "\n" + "void f() { // Hello\n" + " // World\n" + "}", + WrapCode, Style); Style.SpacesInLineCommentPrefix = {0, 0}; - EXPECT_EQ("//Lorem ipsum dolor\n" - "//sit amet\n" - "\n" - "//Lorem ipsum\n" - "//dolor sit amet\n" - "\n" - "void f() { //Hello\n" - " //World\n" - "}", - format(WrapCode, Style)); + verifyFormat("//Lorem ipsum dolor\n" + "//sit amet\n" + "\n" + "//Lorem ipsum\n" + "//dolor sit amet\n" + "\n" + "void f() { //Hello\n" + " //World\n" + "}", + WrapCode, Style); Style.SpacesInLineCommentPrefix = {1, 1}; - EXPECT_EQ("// Lorem ipsum dolor\n" - "// sit amet\n" - "\n" - "// Lorem ipsum\n" - "// dolor sit amet\n" - "\n" - "void f() { // Hello\n" - " // World\n" - "}", - format(WrapCode, Style)); - EXPECT_EQ("// x\n" - "// y", - format("// x\n" - "// y", - Style)); - EXPECT_EQ( + verifyFormat("// Lorem ipsum dolor\n" + "// sit amet\n" + "\n" + "// Lorem ipsum\n" + "// dolor sit amet\n" + "\n" + "void f() { // Hello\n" + " // World\n" + "}", + WrapCode, Style); + verifyFormat("// x\n" + "// y", + "// x\n" + "// y", + Style); + verifyFormat( "// loooooooooooooooooooooooooooooong\n" "// commentcomments\n" "// normal comments", - format("// loooooooooooooooooooooooooooooong commentcomments\n" - "// normal comments", - Style)); + "// loooooooooooooooooooooooooooooong commentcomments\n" + "// normal comments", + Style); Style.SpacesInLineCommentPrefix = {3, 3}; - EXPECT_EQ("// Lorem ipsum\n" - "// dolor sit amet\n" - "\n" - "// Lorem ipsum\n" - "// dolor sit\n" - "// amet\n" - "\n" - "void f() { // Hello\n" - " // World\n" - "}", - format(WrapCode, Style)); + verifyFormat("// Lorem ipsum\n" + "// dolor sit amet\n" + "\n" + "// Lorem ipsum\n" + "// dolor sit\n" + "// amet\n" + "\n" + "void f() { // Hello\n" + " // World\n" + "}", + WrapCode, Style); Style = getLLVMStyleWithColumns(20); - StringRef LotsOfSpaces = "// This are more spaces " - "than the ColumnLimit, what now?\n" - "\n" - "// Comment\n" - "\n" - "// This is a text to split in multiple " - "lines, please. Thank you very much!\n" - "\n" - "// A comment with\n" - "// some indentation that has to be split.\n" - "// And now without"; - EXPECT_EQ("// This are more spaces " - "than the ColumnLimit, what now?\n" - "\n" - "// Comment\n" - "\n" - "// This is a text to\n" - "// split in multiple\n" - "// lines, please.\n" - "// Thank you very\n" - "// much!\n" - "\n" - "// A comment with\n" - "// some\n" - "// indentation\n" - "// that has to be\n" - "// split.\n" - "// And now without", - format(LotsOfSpaces, Style)); + constexpr StringRef LotsOfSpaces( + "// This are more spaces " + "than the ColumnLimit, what now?\n" + "\n" + "// Comment\n" + "\n" + "// This is a text to split in multiple " + "lines, please. Thank you very much!\n" + "\n" + "// A comment with\n" + "// some indentation that has to be split.\n" + "// And now without"); + verifyFormat("// This are more spaces " + "than the ColumnLimit, what now?\n" + "\n" + "// Comment\n" + "\n" + "// This is a text to\n" + "// split in multiple\n" + "// lines, please.\n" + "// Thank you very\n" + "// much!\n" + "\n" + "// A comment with\n" + "// some\n" + "// indentation\n" + "// that has to be\n" + "// split.\n" + "// And now without", + LotsOfSpaces, Style); Style.SpacesInLineCommentPrefix = {0, 0}; - EXPECT_EQ("//This are more\n" - "//spaces than the\n" - "//ColumnLimit, what\n" - "//now?\n" - "\n" - "//Comment\n" - "\n" - "//This is a text to\n" - "//split in multiple\n" - "//lines, please.\n" - "//Thank you very\n" - "//much!\n" - "\n" - "//A comment with\n" - "// some indentation\n" - "// that has to be\n" - "// split.\n" - "//And now without", - format(LotsOfSpaces, Style)); + verifyFormat("//This are more\n" + "//spaces than the\n" + "//ColumnLimit, what\n" + "//now?\n" + "\n" + "//Comment\n" + "\n" + "//This is a text to\n" + "//split in multiple\n" + "//lines, please.\n" + "//Thank you very\n" + "//much!\n" + "\n" + "//A comment with\n" + "// some indentation\n" + "// that has to be\n" + "// split.\n" + "//And now without", + LotsOfSpaces, Style); Style.SpacesInLineCommentPrefix = {3, 3}; - EXPECT_EQ("// This are more\n" - "// spaces than the\n" - "// ColumnLimit,\n" - "// what now?\n" - "\n" - "// Comment\n" - "\n" - "// This is a text\n" - "// to split in\n" - "// multiple lines,\n" - "// please. Thank\n" - "// you very much!\n" - "\n" - "// A comment with\n" - "// some\n" - "// indentation\n" - "// that has to\n" - "// be split.\n" - "// And now without", - format(LotsOfSpaces, Style)); + verifyFormat("// This are more\n" + "// spaces than the\n" + "// ColumnLimit,\n" + "// what now?\n" + "\n" + "// Comment\n" + "\n" + "// This is a text\n" + "// to split in\n" + "// multiple lines,\n" + "// please. Thank\n" + "// you very much!\n" + "\n" + "// A comment with\n" + "// some\n" + "// indentation\n" + "// that has to\n" + "// be split.\n" + "// And now without", + LotsOfSpaces, Style); Style.SpacesInLineCommentPrefix = {30, -1u}; - EXPECT_EQ("// This are more spaces than the " - "ColumnLimit, what now?\n" - "\n" - "// Comment\n" - "\n" - "// This is a text to split in " - "multiple lines, please. Thank you very much!\n" - "\n" - "// A comment with\n" - "// some indentation that has to be " - "split.\n" - "// And now without", - format(LotsOfSpaces, Style)); + verifyFormat( + "// This are more spaces than the " + "ColumnLimit, what now?\n" + "\n" + "// Comment\n" + "\n" + "// This is a text to split in " + "multiple lines, please. Thank you very much!\n" + "\n" + "// A comment with\n" + "// some indentation that has to be " + "split.\n" + "// And now without", + LotsOfSpaces, Style); Style.SpacesInLineCommentPrefix = {2, 4}; - EXPECT_EQ("// A Comment to be\n" - "// moved\n" - "// with indent\n" - "\n" - "// A Comment to be\n" - "// moved\n" - "// with indent\n" - "\n" - "// A Comment to be\n" - "// moved\n" - "// with indent\n" - "\n" - "// A Comment to be\n" - "// moved\n" - "// with indent\n" - "\n" - "// A Comment to\n" - "// be moved\n" - "// with indent\n" - "\n" - "// A Comment to\n" - "// be moved\n" - "// with indent\n" - "\n" - "// A Comment to\n" - "// be moved\n" - "// with indent", - format("//A Comment to be moved\n" - "// with indent\n" - "\n" - "// A Comment to be moved\n" - "// with indent\n" - "\n" - "// A Comment to be moved\n" - "// with indent\n" - "\n" - "// A Comment to be moved\n" - "// with indent\n" - "\n" - "// A Comment to be moved\n" - "// with indent\n" - "\n" - "// A Comment to be moved\n" - "// with indent\n" - "\n" - "// A Comment to be moved\n" - "// with indent", - Style)); + verifyFormat("// A Comment to be\n" + "// moved\n" + "// with indent\n" + "\n" + "// A Comment to be\n" + "// moved\n" + "// with indent\n" + "\n" + "// A Comment to be\n" + "// moved\n" + "// with indent\n" + "\n" + "// A Comment to be\n" + "// moved\n" + "// with indent\n" + "\n" + "// A Comment to\n" + "// be moved\n" + "// with indent\n" + "\n" + "// A Comment to\n" + "// be moved\n" + "// with indent\n" + "\n" + "// A Comment to\n" + "// be moved\n" + "// with indent", + "//A Comment to be moved\n" + "// with indent\n" + "\n" + "// A Comment to be moved\n" + "// with indent\n" + "\n" + "// A Comment to be moved\n" + "// with indent\n" + "\n" + "// A Comment to be moved\n" + "// with indent\n" + "\n" + "// A Comment to be moved\n" + "// with indent\n" + "\n" + "// A Comment to be moved\n" + "// with indent\n" + "\n" + "// A Comment to be moved\n" + "// with indent", + Style); Style.ColumnLimit = 30; - EXPECT_EQ("int i; // A Comment to be\n" - " // moved\n" - " // with indent\n" - "\n" - "int i; // A Comment to be\n" - " // moved\n" - " // with indent\n" - "\n" - "int i; // A Comment to be\n" - " // moved\n" - " // with indent\n" - "\n" - "int i; // A Comment to be\n" - " // moved\n" - " // with indent\n" - "\n" - "int i; // A Comment to be\n" - " // moved\n" - " // with indent\n" - "\n" - "int i; // A Comment to be\n" - " // moved\n" - " // with indent\n" - "\n" - "int i; // A Comment to be\n" - " // moved\n" - " // with indent", - format("int i;//A Comment to be moved\n" - " // with indent\n" - "\n" - "int i;// A Comment to be moved\n" - " // with indent\n" - "\n" - "int i;// A Comment to be moved\n" - " // with indent\n" - "\n" - "int i;// A Comment to be moved\n" - " // with indent\n" - "\n" - "int i;// A Comment to be moved\n" - " // with indent\n" - "\n" - "int i;// A Comment to be moved\n" - " // with indent\n" - "\n" - "int i;// A Comment to be moved\n" - " // with indent", - Style)); + verifyFormat("int i; // A Comment to be\n" + " // moved\n" + " // with indent\n" + "\n" + "int i; // A Comment to be\n" + " // moved\n" + " // with indent\n" + "\n" + "int i; // A Comment to be\n" + " // moved\n" + " // with indent\n" + "\n" + "int i; // A Comment to be\n" + " // moved\n" + " // with indent\n" + "\n" + "int i; // A Comment to be\n" + " // moved\n" + " // with indent\n" + "\n" + "int i; // A Comment to be\n" + " // moved\n" + " // with indent\n" + "\n" + "int i; // A Comment to be\n" + " // moved\n" + " // with indent", + "int i;//A Comment to be moved\n" + " // with indent\n" + "\n" + "int i;// A Comment to be moved\n" + " // with indent\n" + "\n" + "int i;// A Comment to be moved\n" + " // with indent\n" + "\n" + "int i;// A Comment to be moved\n" + " // with indent\n" + "\n" + "int i;// A Comment to be moved\n" + " // with indent\n" + "\n" + "int i;// A Comment to be moved\n" + " // with indent\n" + "\n" + "int i;// A Comment to be moved\n" + " // with indent", + Style); Style = getLLVMStyleWithColumns(0); - EXPECT_EQ("// Free comment without space\n" - "\n" - "// Free comment with 3 spaces\n" - "\n" - "/// Free Doxygen without space\n" - "\n" - "/// Free Doxygen with 3 spaces\n" - "\n" - "// 🐉 A nice dragon\n" - "\n" - "//\t abccba\n" - "\n" - "//\\t deffed\n" - "\n" - "// 🐉 Another nice dragon\n" - "\n" - "// \t Three leading spaces following tab\n" - "\n" - "// \\t Three leading spaces following backslash\n" - "\n" - "/// A Doxygen Comment with a nested list:\n" - "/// - Foo\n" - "/// - Bar\n" - "/// - Baz\n" - "/// - End\n" - "/// of the inner list\n" - "/// .\n" - "/// .\n" - "\n" - "namespace Foo {\n" - "bool bar(bool b) {\n" - " bool ret1 = true; ///< Doxygenstyle without space\n" - " bool ret2 = true; ///< Doxygenstyle with 3 spaces\n" - " if (b) {\n" - " // Foo\n" - "\n" - " // In function comment\n" - " ret2 = false;\n" - " } // End of if\n" - "\n" - " // if (ret1) {\n" - " // return ret2;\n" - " // }\n" - "\n" - " // if (ret1) {\n" - " // return ret2;\n" - " // }\n" - "\n" - " return ret1 && ret2;\n" - "}\n" - "} // namespace Foo\n" - "\n" - "namespace Bar {\n" - "int foo();\n" - "} // namespace Bar\n" - "//@Nothing added because of the non ascii char\n" - "\n" - "//@ Nothing removed because of the non ascii char\n" - "\n" - "// Comment to move to the left\n" - "// But not this?\n" - "// @but this\n" - "\n" - "// Comment to move to the right\n" - "//@ this stays\n" - "\n" - "//} will not move\n" - "\n" - "// vv will only move\n" - "// } if the line above does", - format(Code, Style)); + verifyFormat(Code2, Code, Style); Style.SpacesInLineCommentPrefix = {0, 0}; - EXPECT_EQ("//Free comment without space\n" - "\n" - "//Free comment with 3 spaces\n" - "\n" - "///Free Doxygen without space\n" - "\n" - "///Free Doxygen with 3 spaces\n" - "\n" - "//🐉 A nice dragon\n" - "\n" - "//\t abccba\n" - "\n" - "//\\t deffed\n" - "\n" - "//🐉 Another nice dragon\n" - "\n" - "//\t Three leading spaces following tab\n" - "\n" - "//\\t Three leading spaces following backslash\n" - "\n" - "///A Doxygen Comment with a nested list:\n" - "///- Foo\n" - "///- Bar\n" - "/// - Baz\n" // Here we keep the relative indentation - "/// - End\n" - "/// of the inner list\n" - "/// .\n" - "///.\n" - "\n" - "namespace Foo {\n" - "bool bar(bool b) {\n" - " bool ret1 = true; ///<Doxygenstyle without space\n" - " bool ret2 = true; ///<Doxygenstyle with 3 spaces\n" - " if (b) {\n" - " //Foo\n" - "\n" - " //In function comment\n" - " ret2 = false;\n" - " } //End of if\n" - "\n" - " //if (ret1) {\n" - " // return ret2;\n" - " //}\n" - "\n" - " //if (ret1) {\n" - " // return ret2;\n" - " //}\n" - "\n" - " return ret1 && ret2;\n" - "}\n" - "} //namespace Foo\n" - "\n" - "namespace Bar {\n" - "int foo();\n" - "} //namespace Bar\n" - "//@Nothing added because of the non ascii char\n" - "\n" - "//@ Nothing removed because of the non ascii char\n" - "\n" - "//Comment to move to the left\n" - "//But not this?\n" - "//@but this\n" - "\n" - "//Comment to move to the right\n" - "//@ this stays\n" - "\n" - "//} will not move\n" - "\n" - "//vv will only move\n" - "//} if the line above does", - format(Code, Style)); + verifyFormat(Code3, Code, Style); Style.SpacesInLineCommentPrefix = {2, -1u}; - EXPECT_EQ("// Free comment without space\n" - "\n" - "// Free comment with 3 spaces\n" - "\n" - "/// Free Doxygen without space\n" - "\n" - "/// Free Doxygen with 3 spaces\n" - "\n" - "// 🐉 A nice dragon\n" - "\n" - "//\t abccba\n" - "\n" - "//\\t deffed\n" - "\n" - "// 🐉 Another nice dragon\n" - "\n" - "// \t Three leading spaces following tab\n" - "\n" - "// \\t Three leading spaces following backslash\n" - "\n" - "/// A Doxygen Comment with a nested list:\n" - "/// - Foo\n" - "/// - Bar\n" - "/// - Baz\n" - "/// - End\n" - "/// of the inner list\n" - "/// .\n" - "/// .\n" - "\n" - "namespace Foo {\n" - "bool bar(bool b) {\n" - " bool ret1 = true; ///< Doxygenstyle without space\n" - " bool ret2 = true; ///< Doxygenstyle with 3 spaces\n" - " if (b) {\n" - " // Foo\n" - "\n" - " // In function comment\n" - " ret2 = false;\n" - " } // End of if\n" - "\n" - " // if (ret1) {\n" - " // return ret2;\n" - " // }\n" - "\n" - " // if (ret1) {\n" - " // return ret2;\n" - " // }\n" - "\n" - " return ret1 && ret2;\n" - "}\n" - "} // namespace Foo\n" - "\n" - "namespace Bar {\n" - "int foo();\n" - "} // namespace Bar\n" - "//@Nothing added because of the non ascii char\n" - "\n" - "//@ Nothing removed because of the non ascii char\n" - "\n" - "// Comment to move to the left\n" - "// But not this?\n" - "// @but this\n" - "\n" - "// Comment to move to the right\n" - "//@ this stays\n" - "\n" - "//} will not move\n" - "\n" - "// vv will only move\n" - "// } if the line above does", - format(Code, Style)); + verifyFormat(Code4, Code, Style); } TEST_F(FormatTestComments, SplitCommentIntroducers) { - EXPECT_EQ(R"(// -/\ -/ -)", - format(R"(// -/\ -/ - )", - getLLVMStyleWithColumns(10))); + verifyFormat("//\n" + "/\\\n" + "/\n", + "//\n" + "/\\\n" + "/ \n" + " ", + getLLVMStyleWithColumns(10)); } TEST_F(FormatTestComments, LineCommentsOnStartOfFunctionCall) { diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index ca99940..c046142 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -1119,6 +1119,11 @@ TEST_F(TokenAnnotatorTest, UnderstandsOverloadedOperators) { EXPECT_TOKEN(Tokens[8], tok::amp, TT_PointerOrReference); EXPECT_TOKEN(Tokens[12], tok::amp, TT_PointerOrReference); + Tokens = annotate("::foo::bar& ::foo::bar::operator=(::foo::bar& other);"); + ASSERT_EQ(Tokens.size(), 22u) << Tokens; + EXPECT_TOKEN(Tokens[6], tok::identifier, TT_FunctionDeclarationName); + EXPECT_TOKEN(Tokens[17], tok::amp, TT_PointerOrReference); + Tokens = annotate("SomeLoooooooooooooooooType::Awaitable\n" "SomeLoooooooooooooooooType::operator co_await();"); ASSERT_EQ(Tokens.size(), 11u) << Tokens; @@ -3484,6 +3489,10 @@ TEST_F(TokenAnnotatorTest, StartOfName) { ASSERT_EQ(Tokens.size(), 8u) << Tokens; EXPECT_TOKEN(Tokens[2], tok::identifier, TT_Unknown); // Not StartOfName + Tokens = annotate("int* ::foo::bar;"); + ASSERT_EQ(Tokens.size(), 8u) << Tokens; + EXPECT_TOKEN(Tokens[3], tok::identifier, TT_StartOfName); + auto Style = getLLVMStyle(); Style.StatementAttributeLikeMacros.push_back("emit"); Tokens = annotate("emit foo = 0;", Style); |
