26 #include "llvm/Support/MemoryBuffer.h" 
   27 #include "llvm/Support/SourceMgr.h" 
   34 using llvm::MemoryBuffer;
 
   35 using llvm::SourceMgr;
 
   41 class CustomDialectAsmParser : 
public AsmParserImpl<DialectAsmParser> {
 
   43   CustomDialectAsmParser(StringRef fullSpec, 
Parser &parser)
 
   46   ~CustomDialectAsmParser() 
override = 
default;
 
   50   StringRef getFullSymbolSpec()
 const override { 
return fullSpec; }
 
   67                                            bool &isCodeCompletion) {
 
   76   assert(*curPtr == 
'<');
 
   81   auto emitPunctError = [&] {
 
   82     return emitError() << 
"unbalanced '" << nestedPunctuation.back()
 
   83                        << 
"' character in pretty dialect name";
 
   86   auto checkNestedPunctuation = [&](
char expectedToken) -> ParseResult {
 
   87     if (nestedPunctuation.back() != expectedToken)
 
   88       return emitPunctError();
 
   89     nestedPunctuation.pop_back();
 
   96     if (curPtr == codeCompleteLoc) {
 
   97       isCodeCompletion = 
true;
 
   98       nestedPunctuation.clear();
 
  102     if (curBufferEnd == curPtr) {
 
  103       if (!nestedPunctuation.empty())
 
  104         return emitPunctError();
 
  105       return emitError(
"unexpected nul or EOF in pretty dialect name");
 
  112       if (!nestedPunctuation.empty())
 
  113         return emitPunctError();
 
  114       return emitError(
"unexpected nul or EOF in pretty dialect name");
 
  119       nestedPunctuation.push_back(c);
 
  129       if (
failed(checkNestedPunctuation(
'<')))
 
  133       if (
failed(checkNestedPunctuation(
'[')))
 
  137       if (
failed(checkNestedPunctuation(
'(')))
 
  141       if (
failed(checkNestedPunctuation(
'{')))
 
  152         isCodeCompletion = 
true;
 
  153         nestedPunctuation.clear();
 
  166   } 
while (!nestedPunctuation.empty());
 
  172   unsigned length = curPtr - body.begin();
 
  173   body = StringRef(body.data(), length);
 
  178 template <
typename Symbol, 
typename SymbolAliasMap, 
typename CreateFn>
 
  180                                   SymbolAliasMap &aliases,
 
  181                                   CreateFn &&createSymbol) {
 
  185   StringRef identifier = tok.
getSpelling().drop_front();
 
  195   auto [dialectName, symbolData] = identifier.split(
'.');
 
  196   bool isPrettyName = !symbolData.empty() || identifier.back() == 
'.';
 
  200   bool hasTrailingData =
 
  206   if (!hasTrailingData && !isPrettyName) {
 
  208     auto aliasIt = aliases.find(identifier);
 
  209     if (aliasIt == aliases.end())
 
  214       if constexpr (std::is_same_v<Symbol, Type>)
 
  219     return aliasIt->second;
 
  227     symbolData = StringRef(dialectName.end(), 0);
 
  230     bool isCodeCompletion = 
false;
 
  233     symbolData = symbolData.drop_front();
 
  237     if (!isCodeCompletion)
 
  238       symbolData = symbolData.drop_back();
 
  240     loc = SMLoc::getFromPointer(symbolData.data());
 
  248   return createSymbol(dialectName, symbolData, loc);
 
  261   Attribute attr = parseExtendedSymbol<Attribute>(
 
  263       [&](StringRef dialectName, StringRef symbolData, SMLoc loc) -> 
Attribute {
 
  265         Type attrType = type;
 
  266         if (consumeIf(Token::colon) && !(attrType = parseType()))
 
  270         if (Dialect *dialect =
 
  271                 builder.getContext()->getOrLoadDialect(dialectName)) {
 
  273           const char *curLexerPos = getToken().getLoc().getPointer();
 
  274           resetToken(symbolData.data());
 
  277           CustomDialectAsmParser customParser(symbolData, *this);
 
  278           Attribute attr = dialect->parseAttribute(customParser, attrType);
 
  279           resetToken(curLexerPos);
 
  284         return OpaqueAttr::getChecked(
 
  290   auto typedAttr = dyn_cast_or_null<TypedAttr>(attr);
 
  291   if (type && typedAttr && typedAttr.getType() != type) {
 
  292     emitError(
"attribute type different than expected: expected ")
 
  293         << type << 
", but got " << typedAttr.getType();
 
  306 Type Parser::parseExtendedType() {
 
  308   return parseExtendedSymbol<Type>(
 
  309       *
this, state.asmState, state.symbols.typeAliasDefinitions,
 
  310       [&](StringRef dialectName, StringRef symbolData, SMLoc loc) -> 
Type {
 
  312         if (auto *dialect = ctx->getOrLoadDialect(dialectName)) {
 
  314           const char *curLexerPos = getToken().getLoc().getPointer();
 
  315           resetToken(symbolData.data());
 
  318           CustomDialectAsmParser customParser(symbolData, *this);
 
  319           Type type = dialect->parseType(customParser);
 
  320           resetToken(curLexerPos);
 
  325         return OpaqueType::getChecked([&] { return emitError(loc); },
 
  337 template <
typename T, 
typename ParserFn>
 
  339                      size_t *numReadOut, 
bool isKnownNullTerminated,
 
  340                      ParserFn &&parserFn) {
 
  344       isKnownNullTerminated
 
  345           ? MemoryBuffer::getMemBuffer(inputStr,
 
  347           : MemoryBuffer::getMemBufferCopy(inputStr, inputStr);
 
  349   sourceMgr.AddNewSourceBuffer(std::move(memBuffer), SMLoc());
 
  357   T symbol = parserFn(parser);
 
  364       endTok.
getLoc().getPointer() - startTok.
getLoc().getPointer();
 
  366     *numReadOut = numRead;
 
  367   } 
else if (numRead != inputStr.size()) {
 
  369                                       << inputStr.drop_front(numRead) << 
"'";
 
  376                                Type type, 
size_t *numRead,
 
  377                                bool isKnownNullTerminated) {
 
  378   return parseSymbol<Attribute>(
 
  379       attrStr, context, numRead, isKnownNullTerminated,
 
  383                      bool isKnownNullTerminated) {
 
  384   return parseSymbol<Type>(typeStr, context, numRead, isKnownNullTerminated,
 
static Symbol parseExtendedSymbol(Parser &p, AsmParserState *asmState, SymbolAliasMap &aliases, CreateFn &&createSymbol)
Parse an extended dialect symbol.
static T parseSymbol(StringRef inputStr, MLIRContext *context, size_t *numReadOut, bool isKnownNullTerminated, ParserFn &&parserFn)
Parses a symbol, of type 'T', and returns it if parsing was successful.
static MLIRContext * getContext(OpFoldResult val)
This class represents state from a parsed MLIR textual format string.
void addTypeAliasUses(StringRef name, SMRange locations)
void addAttrAliasUses(StringRef name, SMRange locations)
Attributes are known-constant values of operations.
The DialectAsmParser has methods for interacting with the asm parser when parsing attributes and type...
const char * getBufferEnd()
Returns the end of the buffer.
const char * getCodeCompleteLoc() const
Return the code completion location of the lexer, or nullptr if there is none.
MLIRContext is the top-level object for a collection of MLIR operations.
This class represents a configuration for the MLIR assembly parser.
This represents a token in the MLIR syntax.
SMRange getLocRange() const
bool isCodeCompletion() const
Returns true if the current token represents a code completion.
StringRef getSpelling() const
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
This class provides the implementation of the generic parser methods within AsmParser.
This class implement support for parsing global entities like attributes and types.
Type parseType()
Parse an arbitrary type.
InFlightDiagnostic emitError(const Twine &message={})
Emit an error and return failure.
ParserState & state
The Parser is subclassed and reinstantiated.
Attribute parseAttribute(Type type={})
Parse an arbitrary attribute with an optional type.
StringRef getTokenSpelling() const
void consumeToken()
Advance the current lexer onto the next token.
ParseResult parseDialectSymbolBody(StringRef &body, bool &isCodeCompletion)
Parse the body of a dialect symbol, which starts and ends with <>'s, and may be recursive.
MLIRContext * getContext() const
InFlightDiagnostic emitWrongTokenError(const Twine &message={})
Emit an error about a "wrong token".
void resetToken(const char *tokPos)
Reset the parser to the given lexer position.
Attribute parseExtendedAttr(Type type)
Parse an extended attribute.
const Token & getToken() const
Return the current token the parser is inspecting.
Attribute codeCompleteDialectSymbol(const llvm::StringMap< Attribute > &aliases)
Include the generated interface declarations.
const FrozenRewritePatternSet GreedyRewriteConfig config
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
Attribute parseAttribute(llvm::StringRef attrStr, MLIRContext *context, Type type={}, size_t *numRead=nullptr, bool isKnownNullTerminated=false)
This parses a single MLIR attribute to an MLIR context if it was valid.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
Type parseType(llvm::StringRef typeStr, MLIRContext *context, size_t *numRead=nullptr, bool isKnownNullTerminated=false)
This parses a single MLIR type to an MLIR context if it was valid.
This class refers to all of the state maintained globally by the parser, such as the current lexer po...
SymbolState & symbols
The current state for symbol parsing.
Lexer lex
The lexer for the source file we're parsing.
Token curToken
This is the next token that hasn't been consumed yet.
AsmParserState * asmState
An optional pointer to a struct containing high level parser state to be populated during parsing.
This class contains record of any parsed top-level symbols.
llvm::StringMap< Attribute > attributeAliasDefinitions
A map from attribute alias identifier to Attribute.