Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ASTMatchers] Matchers that take enumerations args provide hints with…
… invalid arguments Summary: This adds support for giving hints when using dynamic matchers with enum args. Take this query, I couldn't figure out why the matcher wasn't working: (Turns out it needed to be "IntegralToBoolean", but thats another bug itself) ``` clang-query> match implicitCastExpr(hasCastKind("CK_IntegralToBoolean")) 1:1: Error parsing argument 1 for matcher implicitCastExpr. 1:18: Error building matcher hasCastKind. 1:30: Incorrect type for arg 1. (Expected = string) != (Actual = String) ``` With this patch the new behaviour looks like this: ``` clang-query> match implicitCastExpr(hasCastKind("CK_IntegralToBoolean")) 1:1: Error parsing argument 1 for matcher implicitCastExpr. 1:18: Error building matcher hasCastKind. 1:30: Unknown value 'CK_IntegralToBoolean' for arg 1; did you mean 'IntegralToBoolean' ``` There are no test cases for this yet as there simply isn't any infrastructure for testing errors reported when parsing args that I can see. Reviewers: klimek, jdoerfert, aaron.ballman Reviewed By: aaron.ballman Subscribers: aaron.ballman, dexonsmith, mgorny, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D77499
- Loading branch information
Showing
6 changed files
with
146 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
#include "Marshallers.h" | ||
#include "llvm/ADT/ArrayRef.h" | ||
#include "llvm/ADT/Optional.h" | ||
#include "llvm/ADT/StringRef.h" | ||
#include <string> | ||
|
||
static llvm::Optional<std::string> | ||
getBestGuess(llvm::StringRef Search, llvm::ArrayRef<llvm::StringRef> Allowed, | ||
llvm::StringRef DropPrefix = "", unsigned MaxEditDistance = 3) { | ||
if (MaxEditDistance != ~0U) | ||
++MaxEditDistance; | ||
llvm::StringRef Res; | ||
for (const llvm::StringRef &Item : Allowed) { | ||
if (Item.equals_lower(Search)) { | ||
assert(!Item.equals(Search) && "This should be handled earlier on."); | ||
MaxEditDistance = 1; | ||
Res = Item; | ||
continue; | ||
} | ||
unsigned Distance = Item.edit_distance(Search); | ||
if (Distance < MaxEditDistance) { | ||
MaxEditDistance = Distance; | ||
Res = Item; | ||
} | ||
} | ||
if (!Res.empty()) | ||
return Res.str(); | ||
if (!DropPrefix.empty()) { | ||
--MaxEditDistance; // Treat dropping the prefix as 1 edit | ||
for (const llvm::StringRef &Item : Allowed) { | ||
auto NoPrefix = Item; | ||
if (!NoPrefix.consume_front(DropPrefix)) | ||
continue; | ||
if (NoPrefix.equals_lower(Search)) { | ||
if (NoPrefix.equals(Search)) | ||
return Item.str(); | ||
MaxEditDistance = 1; | ||
Res = Item; | ||
continue; | ||
} | ||
unsigned Distance = NoPrefix.edit_distance(Search); | ||
if (Distance < MaxEditDistance) { | ||
MaxEditDistance = Distance; | ||
Res = Item; | ||
} | ||
} | ||
if (!Res.empty()) | ||
return Res.str(); | ||
} | ||
return llvm::None; | ||
} | ||
|
||
llvm::Optional<std::string> | ||
clang::ast_matchers::dynamic::internal::ArgTypeTraits< | ||
clang::attr::Kind>::getBestGuess(const VariantValue &Value) { | ||
static constexpr llvm::StringRef Allowed[] = { | ||
#define ATTR(X) "attr::" #X, | ||
#include "clang/Basic/AttrList.inc" | ||
}; | ||
if (Value.isString()) | ||
return ::getBestGuess(Value.getString(), llvm::makeArrayRef(Allowed), | ||
"attr::"); | ||
return llvm::None; | ||
} | ||
|
||
llvm::Optional<std::string> | ||
clang::ast_matchers::dynamic::internal::ArgTypeTraits< | ||
clang::CastKind>::getBestGuess(const VariantValue &Value) { | ||
static constexpr llvm::StringRef Allowed[] = { | ||
#define CAST_OPERATION(Name) #Name, | ||
#include "clang/AST/OperationKinds.def" | ||
}; | ||
if (Value.isString()) | ||
return ::getBestGuess(Value.getString(), llvm::makeArrayRef(Allowed)); | ||
return llvm::None; | ||
} | ||
|
||
llvm::Optional<std::string> | ||
clang::ast_matchers::dynamic::internal::ArgTypeTraits< | ||
clang::OpenMPClauseKind>::getBestGuess(const VariantValue &Value) { | ||
static constexpr llvm::StringRef Allowed[] = { | ||
#define OPENMP_CLAUSE(TextualSpelling, Class) "OMPC_" #TextualSpelling, | ||
#include "clang/Basic/OpenMPKinds.def" | ||
}; | ||
if (Value.isString()) | ||
return ::getBestGuess(Value.getString(), llvm::makeArrayRef(Allowed), | ||
"OMPC_"); | ||
return llvm::None; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters