summaryrefslogtreecommitdiffstats
path: root/clang/lib/ASTMatchers/Dynamic/Parser.cpp
diff options
context:
space:
mode:
authorSamuel Benzaquen <sbenza@google.com>2014-04-14 13:51:21 +0000
committerSamuel Benzaquen <sbenza@google.com>2014-04-14 13:51:21 +0000
commitf434c4fa3f86cacb7a9cee2f9ca827caf933fc0c (patch)
tree84b9047319abbb2cb0305ba05173ccf1e39616ce /clang/lib/ASTMatchers/Dynamic/Parser.cpp
parentdb2860f49e32bffd2c9159f0b7f6bd22050d4804 (diff)
downloadbcm5719-llvm-f434c4fa3f86cacb7a9cee2f9ca827caf933fc0c.tar.gz
bcm5719-llvm-f434c4fa3f86cacb7a9cee2f9ca827caf933fc0c.zip
Add support for named values in the parser.
Summary: Add support for named values in the parser. Reviewers: pcc CC: cfe-commits, klimek Differential Revision: http://llvm-reviews.chandlerc.com/D3276 llvm-svn: 206176
Diffstat (limited to 'clang/lib/ASTMatchers/Dynamic/Parser.cpp')
-rw-r--r--clang/lib/ASTMatchers/Dynamic/Parser.cpp87
1 files changed, 62 insertions, 25 deletions
diff --git a/clang/lib/ASTMatchers/Dynamic/Parser.cpp b/clang/lib/ASTMatchers/Dynamic/Parser.cpp
index 24ffdcda51b..70343811898 100644
--- a/clang/lib/ASTMatchers/Dynamic/Parser.cpp
+++ b/clang/lib/ASTMatchers/Dynamic/Parser.cpp
@@ -258,6 +258,10 @@ private:
Parser::Sema::~Sema() {}
+VariantValue Parser::Sema::getNamedValue(StringRef Name) {
+ return VariantValue();
+}
+
struct Parser::ScopedContextEntry {
Parser *P;
@@ -274,12 +278,43 @@ struct Parser::ScopedContextEntry {
}
};
+/// \brief Parse expressions that start with an identifier.
+///
+/// This function can parse named values and matchers.
+/// In case of failure it will try to determine the user's intent to give
+/// an appropriate error message.
+bool Parser::parseIdentifierPrefixImpl(VariantValue *Value) {
+ const TokenInfo NameToken = Tokenizer->consumeNextToken();
+
+ if (Tokenizer->nextTokenKind() != TokenInfo::TK_OpenParen) {
+ // Parse as a named value.
+ if (const VariantValue NamedValue = S->getNamedValue(NameToken.Text)) {
+ *Value = NamedValue;
+ return true;
+ }
+ // If the syntax is correct and the name is not a matcher either, report
+ // unknown named value.
+ if ((Tokenizer->nextTokenKind() == TokenInfo::TK_Comma ||
+ Tokenizer->nextTokenKind() == TokenInfo::TK_CloseParen ||
+ Tokenizer->nextTokenKind() == TokenInfo::TK_Eof) &&
+ !S->lookupMatcherCtor(NameToken.Text)) {
+ Error->addError(NameToken.Range, Error->ET_RegistryValueNotFound)
+ << NameToken.Text;
+ return false;
+ }
+ // Otherwise, fallback to the matcher parser.
+ }
+
+ // Parse as a matcher expression.
+ return parseMatcherExpressionImpl(NameToken, Value);
+}
+
/// \brief Parse and validate a matcher expression.
/// \return \c true on success, in which case \c Value has the matcher parsed.
/// If the input is malformed, or some argument has an error, it
/// returns \c false.
-bool Parser::parseMatcherExpressionImpl(VariantValue *Value) {
- const TokenInfo NameToken = Tokenizer->consumeNextToken();
+bool Parser::parseMatcherExpressionImpl(const TokenInfo &NameToken,
+ VariantValue *Value) {
assert(NameToken.Kind == TokenInfo::TK_Ident);
const TokenInfo OpenToken = Tokenizer->consumeNextToken();
if (OpenToken.Kind != TokenInfo::TK_OpenParen) {
@@ -288,8 +323,14 @@ bool Parser::parseMatcherExpressionImpl(VariantValue *Value) {
return false;
}
- llvm::Optional<MatcherCtor> Ctor =
- S->lookupMatcherCtor(NameToken.Text, NameToken.Range, Error);
+ llvm::Optional<MatcherCtor> Ctor = S->lookupMatcherCtor(NameToken.Text);
+
+ if (!Ctor) {
+ Error->addError(NameToken.Range, Error->ET_RegistryMatcherNotFound)
+ << NameToken.Text;
+ // Do not return here. We need to continue to give completion suggestions.
+ }
+
std::vector<ParserValue> Args;
TokenInfo EndToken;
@@ -425,7 +466,7 @@ bool Parser::parseExpressionImpl(VariantValue *Value) {
return true;
case TokenInfo::TK_Ident:
- return parseMatcherExpressionImpl(Value);
+ return parseIdentifierPrefixImpl(Value);
case TokenInfo::TK_CodeCompletion:
addExpressionCompletions();
@@ -457,27 +498,23 @@ Parser::Parser(CodeTokenizer *Tokenizer, Sema *S,
Diagnostics *Error)
: Tokenizer(Tokenizer), S(S), Error(Error) {}
-class RegistrySema : public Parser::Sema {
-public:
- virtual ~RegistrySema() {}
- llvm::Optional<MatcherCtor> lookupMatcherCtor(StringRef MatcherName,
- const SourceRange &NameRange,
- Diagnostics *Error) {
- return Registry::lookupMatcherCtor(MatcherName, NameRange, Error);
- }
- VariantMatcher actOnMatcherExpression(MatcherCtor Ctor,
- const SourceRange &NameRange,
- StringRef BindID,
- ArrayRef<ParserValue> Args,
- Diagnostics *Error) {
- if (BindID.empty()) {
- return Registry::constructMatcher(Ctor, NameRange, Args, Error);
- } else {
- return Registry::constructBoundMatcher(Ctor, NameRange, BindID, Args,
- Error);
- }
+Parser::RegistrySema::~RegistrySema() {}
+
+llvm::Optional<MatcherCtor>
+Parser::RegistrySema::lookupMatcherCtor(StringRef MatcherName) {
+ return Registry::lookupMatcherCtor(MatcherName);
+}
+
+VariantMatcher Parser::RegistrySema::actOnMatcherExpression(
+ MatcherCtor Ctor, const SourceRange &NameRange, StringRef BindID,
+ ArrayRef<ParserValue> Args, Diagnostics *Error) {
+ if (BindID.empty()) {
+ return Registry::constructMatcher(Ctor, NameRange, Args, Error);
+ } else {
+ return Registry::constructBoundMatcher(Ctor, NameRange, BindID, Args,
+ Error);
}
-};
+}
bool Parser::parseExpression(StringRef Code, VariantValue *Value,
Diagnostics *Error) {
OpenPOWER on IntegriCloud