diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html --- a/clang/docs/LibASTMatchersReference.html +++ b/clang/docs/LibASTMatchersReference.html @@ -2531,6 +2531,19 @@ +
Matches C++ extended vector type where either the type or size is dependent. + +Given + template<typename T, int Size> + class vector { + typedef T __attribute__((ext_vector_type(Size))) type; + }; +dependentSizedExtVectorType + matches "T __attribute__((ext_vector_type(Size)))" +
Matches types specified with an elaborated type keyword or with a qualified name. diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -228,6 +228,7 @@ AST Matchers ------------ +- Add ``dependentSizedExtVectorType``. clang-format ------------ diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -6938,6 +6938,21 @@ /// matches "T data[Size]" extern const AstTypeMatcherdependentSizedArrayType; +/// Matches C++ extended vector type where either the type or size is +/// dependent. +/// +/// Given +/// \code +/// template +/// class vector { +/// typedef T __attribute__((ext_vector_type(Size))) type; +/// }; +/// \endcode +/// dependentSizedExtVectorType +/// matches "T __attribute__((ext_vector_type(Size)))" +extern const AstTypeMatcher + dependentSizedExtVectorType; + /// Matches C arrays with unspecified size. /// /// Given diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -381,7 +381,8 @@ ExpectedType VisitIncompleteArrayType(const IncompleteArrayType *T); ExpectedType VisitVariableArrayType(const VariableArrayType *T); ExpectedType VisitDependentSizedArrayType(const DependentSizedArrayType *T); - // FIXME: DependentSizedExtVectorType + ExpectedType + VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T); ExpectedType VisitVectorType(const VectorType *T); ExpectedType VisitExtVectorType(const ExtVectorType *T); ExpectedType VisitFunctionNoProtoType(const FunctionNoProtoType *T); @@ -1264,6 +1265,18 @@ T->getIndexTypeCVRQualifiers(), ToBracketsRange); } +ExpectedType ASTNodeImporter::VisitDependentSizedExtVectorType( + const DependentSizedExtVectorType *T) { + Error Err = Error::success(); + QualType ToElementType = importChecked(Err, T->getElementType()); + Expr *ToSizeExpr = importChecked(Err, T->getSizeExpr()); + SourceLocation ToAttrLoc = importChecked(Err, T->getAttributeLoc()); + if (Err) + return std::move(Err); + return Importer.getToContext().getDependentSizedExtVectorType( + ToElementType, ToSizeExpr, ToAttrLoc); +} + ExpectedType ASTNodeImporter::VisitVectorType(const VectorType *T) { ExpectedType ToElementTypeOrErr = import(T->getElementType()); if (!ToElementTypeOrErr) diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp --- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp +++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp @@ -1046,6 +1046,7 @@ const AstTypeMatcher deducedTemplateSpecializationType; const AstTypeMatcher dependentSizedArrayType; +const AstTypeMatcher dependentSizedExtVectorType; const AstTypeMatcher incompleteArrayType; const AstTypeMatcher variableArrayType; const AstTypeMatcher atomicType; diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp --- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -227,6 +227,7 @@ REGISTER_MATCHER(defaultStmt); REGISTER_MATCHER(dependentCoawaitExpr); REGISTER_MATCHER(dependentSizedArrayType); + REGISTER_MATCHER(dependentSizedExtVectorType); REGISTER_MATCHER(designatedInitExpr); REGISTER_MATCHER(designatorCountIs); REGISTER_MATCHER(doStmt); diff --git a/clang/unittests/AST/ASTImporterFixtures.h b/clang/unittests/AST/ASTImporterFixtures.h --- a/clang/unittests/AST/ASTImporterFixtures.h +++ b/clang/unittests/AST/ASTImporterFixtures.h @@ -260,6 +260,8 @@ FromAST->getFileManager(), false); auto FoundNodes = match(SearchMatcher, FromCtx); + if (FoundNodes.empty()) + return testing::AssertionFailure() << "No node was found!"; if (FoundNodes.size() != 1) return testing::AssertionFailure() << "Multiple potential nodes were found!"; diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -1044,6 +1044,17 @@ has(fieldDecl(hasType(dependentSizedArrayType()))))))); } +TEST_P(ImportExpr, DependentSizedExtVectorType) { + MatchVerifier Verifier; + testImport("template " + "class declToImport {" + " typedef T __attribute__((ext_vector_type(Size))) type;" + "};", + Lang_CXX03, "", Lang_CXX03, Verifier, + classTemplateDecl(has(cxxRecordDecl( + has(typedefDecl(hasType(dependentSizedExtVectorType()))))))); +} + TEST_P(ASTImporterOptionSpecificTestBase, ImportUsingPackDecl) { Decl *FromTU = getTuDecl( "struct A { int operator()() { return 1; } };" diff --git a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp --- a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp @@ -1560,6 +1560,20 @@ dependentSizedArrayType())); } +TEST_P(ASTMatchersTest, DependentSizedExtVectorType) { + if (!GetParam().isCXX()) { + return; + } + EXPECT_TRUE(matches("template " + "class vector {" + " typedef T __attribute__((ext_vector_type(Size))) type;" + "};", + dependentSizedExtVectorType())); + EXPECT_TRUE( + notMatches("int a[42]; int b[] = { 2, 3 }; void f() { int c[b[0]]; }", + dependentSizedExtVectorType())); +} + TEST_P(ASTMatchersTest, IncompleteArrayType) { EXPECT_TRUE(matches("int a[] = { 2, 3 };", incompleteArrayType())); EXPECT_TRUE(matches("void f(int a[]) {}", incompleteArrayType()));