18 auto IsConstllvmStringRef = qualType(
19 isConstQualified(), hasUnqualifiedDesugaredType(recordType(hasDeclaration(
20 cxxRecordDecl(hasName(
"::llvm::StringRef"))))));
21 auto IsConstStdString = qualType(
22 isConstQualified(), hasUnqualifiedDesugaredType(recordType(hasDeclaration(
23 cxxRecordDecl(hasName(
"::std::basic_string"))))));
24 auto GetStringLiteral =
25 ignoringImplicit(stringLiteral().bind(
"stringLiteral"));
26 auto GetStringLiteralFromObject =
27 ignoringImplicit(cxxConstructExpr(hasAnyArgument(GetStringLiteral)));
28 auto IsConstCharPtr = pointerType(pointee(builtinType(), isConstQualified()));
29 auto IsCharArray = qualType(
30 hasUnqualifiedDesugaredType(arrayType(hasElementType(builtinType()))));
31 auto IsStdStringView = qualType(hasUnqualifiedDesugaredType(recordType(
32 hasDeclaration(cxxRecordDecl(hasName(
"::std::basic_string_view"))))));
33 const auto HasStringContainerType =
34 hasType(qualType(anyOf(IsConstStdString, IsConstllvmStringRef,
35 IsStdStringView, IsConstCharPtr, IsCharArray)));
36 const auto GetString = anyOf(GetStringLiteralFromObject, GetStringLiteral);
37 const auto AnyCastedToStringRef = ignoringImplicit(
38 anyOf(stringLiteral().bind(
"stringLiteral"),
40 to(varDecl(HasStringContainerType, hasInitializer(GetString)))),
41 memberExpr(member(fieldDecl(HasStringContainerType,
42 hasInClassInitializer(GetString))))));
44 const auto IsRegexFlagsType = ignoringParenImpCasts(
45 anyOf(integerLiteral().bind(
"regexFlagsInt"),
46 declRefExpr(to(enumConstantDecl().bind(
"regexFlagEnum")))));
49 hasDeclaration(cxxConstructorDecl(ofClass(hasName(
"llvm::Regex")))),
50 hasArgument(0, ignoringImplicit(cxxConstructExpr(
51 hasDeclaration(cxxConstructorDecl(
52 ofClass(hasName(
"::llvm::StringRef")))),
53 hasArgument(0, AnyCastedToStringRef)))),
54 optionally(hasArgument(1, IsRegexFlagsType))),
59 const auto *DetectedPattern =
60 Result.Nodes.getNodeAs<StringLiteral>(
"stringLiteral");
61 assert(DetectedPattern &&
"stringLiteral must be bound in matcher");
63 unsigned int Flag = llvm::Regex::RegexFlags::NoFlags;
64 if (
const auto *FlagInt =
65 Result.Nodes.getNodeAs<IntegerLiteral>(
"regexFlagsInt"))
66 Flag = FlagInt->getValue().getZExtValue();
67 if (
const auto *FlagEnum =
68 Result.Nodes.getNodeAs<EnumConstantDecl>(
"regexFlagEnum"))
69 Flag = FlagEnum->getInitVal().getZExtValue();
70 const llvm::Regex TestRegex(DetectedPattern->getString(), Flag);
71 std::string RegexError;
72 if (!TestRegex.isValid(RegexError))
73 diag(DetectedPattern->getBeginLoc(),
"invalid regex pattern: %0")
74 << RegexError << DetectedPattern->getSourceRange();