@@ -106,6 +106,17 @@ class Parser {
106
106
// / Pop the last decl scope from the lexer.
107
107
void popDeclScope () { curDeclScope = curDeclScope->getParentScope (); }
108
108
109
+ // / Creates a native constraint taking a set of Attr as arguments.
110
+ // / The number of arguments and their names is given by argNames.
111
+ // / The native returns an Attr when returnsAttr is true, otherwise returns
112
+ // / nothing.
113
+ template <class T >
114
+ T *declareBuiltin (StringRef name, ArrayRef<StringRef> argNames,
115
+ bool returnsAttr);
116
+
117
+ // / Register all builtin natives.
118
+ void declareBuiltins ();
119
+
109
120
// / Parse the body of an AST module.
110
121
LogicalResult parseModuleBody (SmallVectorImpl<ast::Decl *> &decls);
111
122
@@ -418,12 +429,12 @@ class Parser {
418
429
FailureOr<ast::MemberAccessExpr *>
419
430
createMemberAccessExpr (ast::Expr *parentExpr, StringRef name, SMRange loc);
420
431
421
- // Create a native call with \p nativeFuncName and \p arguments.
432
+ // Create a native call with \p function and \p arguments.
422
433
// This should be accompanied by a C++ implementation of the function that
423
434
// needs to be linked and registered in passes that process PDLL files.
424
- FailureOr<ast::DeclRefExpr *>
425
- createNativeCall (SMRange loc, StringRef nativeFuncName ,
426
- MutableArrayRef<ast::Expr *> arguments);
435
+ FailureOr<ast::Expr *>
436
+ createBuiltinCall (SMRange loc, ast::Decl *function ,
437
+ MutableArrayRef<ast::Expr *> arguments);
427
438
428
439
// / Validate the member access `name` into the given parent expression. On
429
440
// / success, this also returns the type of the member accessed.
@@ -578,13 +589,64 @@ class Parser {
578
589
579
590
// / The optional code completion context.
580
591
CodeCompleteContext *codeCompleteContext;
592
+
593
+ struct {
594
+ ast::UserRewriteDecl *createDictionaryAttr;
595
+ ast::UserRewriteDecl *addEntryToDictionaryAttr;
596
+ ast::UserRewriteDecl *createArrayAttr;
597
+ ast::UserRewriteDecl *addElemToArrayAttr;
598
+ } builtins{};
581
599
};
582
600
} // namespace
583
601
602
+ template <class T >
603
+ T *Parser::declareBuiltin (StringRef name, ArrayRef<StringRef> argNames,
604
+ bool returnsAttr) {
605
+ SMRange loc;
606
+ auto attrConstr = ast::ConstraintRef (
607
+ ast::AttrConstraintDecl::create (ctx, loc, nullptr ), loc);
608
+
609
+ pushDeclScope ();
610
+ SmallVector<ast::VariableDecl *> args;
611
+ for (auto argName : argNames) {
612
+ FailureOr<ast::VariableDecl *> arg =
613
+ createArgOrResultVariableDecl (argName, loc, attrConstr);
614
+ assert (succeeded (arg));
615
+ args.push_back (*arg);
616
+ }
617
+ SmallVector<ast::VariableDecl *> results;
618
+ if (returnsAttr) {
619
+ auto result = createArgOrResultVariableDecl (" " , loc, attrConstr);
620
+ assert (succeeded (result));
621
+ results.push_back (*result);
622
+ }
623
+ popDeclScope ();
624
+
625
+ auto *constraintDecl = T::createNative (ctx, ast::Name::create (ctx, name, loc),
626
+ args, results, {}, attrTy);
627
+ curDeclScope->add (constraintDecl);
628
+ return constraintDecl;
629
+ }
630
+
631
+ void Parser::declareBuiltins () {
632
+ builtins.createDictionaryAttr = declareBuiltin<ast::UserRewriteDecl>(
633
+ " __builtin_createDictionaryAttr" , {}, /* returnsAttr=*/ true );
634
+ builtins.addEntryToDictionaryAttr = declareBuiltin<ast::UserRewriteDecl>(
635
+ " __builtin_addEntryToDictionaryAttr" , {" attr" , " attrName" , " attrEntry" },
636
+ /* returnsAttr=*/ true );
637
+ builtins.createArrayAttr = declareBuiltin<ast::UserRewriteDecl>(
638
+ " __builtin_createArrayAttr" , {}, /* returnsAttr=*/ true );
639
+ builtins.addElemToArrayAttr = declareBuiltin<ast::UserRewriteDecl>(
640
+ " __builtin_addElemToArrayAttr" , {" attr" , " element" },
641
+ /* returnsAttr=*/ true );
642
+ }
643
+
584
644
FailureOr<ast::Module *> Parser::parseModule () {
585
645
SMLoc moduleLoc = curToken.getStartLoc ();
586
646
pushDeclScope ();
587
647
648
+ declareBuiltins ();
649
+
588
650
// Parse the top-level decls of the module.
589
651
SmallVector<ast::Decl *> decls;
590
652
if (failed (parseModuleBody (decls)))
@@ -1874,7 +1936,7 @@ FailureOr<ast::Expr *> Parser::parseArrayAttrExpr() {
1874
1936
" Parsing of array attributes as constraint not supported!" );
1875
1937
1876
1938
auto arrayAttrCall =
1877
- createNativeCall (curToken.getLoc (), " createArrayAttr" , {});
1939
+ createBuiltinCall (curToken.getLoc (), builtins. createArrayAttr , {});
1878
1940
if (failed (arrayAttrCall))
1879
1941
return failure ();
1880
1942
@@ -1884,8 +1946,8 @@ FailureOr<ast::Expr *> Parser::parseArrayAttrExpr() {
1884
1946
return failure ();
1885
1947
1886
1948
SmallVector<ast::Expr *> arrayAttrArgs{*arrayAttrCall, *attr};
1887
- auto elemToArrayCall = createNativeCall (
1888
- curToken.getLoc (), " addElemToArrayAttr" , arrayAttrArgs);
1949
+ auto elemToArrayCall = createBuiltinCall (
1950
+ curToken.getLoc (), builtins. addElemToArrayAttr , arrayAttrArgs);
1889
1951
if (failed (elemToArrayCall))
1890
1952
return failure ();
1891
1953
@@ -1966,7 +2028,7 @@ FailureOr<ast::Expr *> Parser::parseDictAttrExpr() {
1966
2028
return emitError (
1967
2029
" Parsing of dictionary attributes as constraint not supported!" );
1968
2030
1969
- auto dictAttrCall = createNativeCall (loc, " createDictionaryAttr" , {});
2031
+ auto dictAttrCall = createBuiltinCall (loc, builtins. createDictionaryAttr , {});
1970
2032
if (failed (dictAttrCall))
1971
2033
return failure ();
1972
2034
@@ -2000,8 +2062,8 @@ FailureOr<ast::Expr *> Parser::parseDictAttrExpr() {
2000
2062
// Create addEntryToDictionaryAttr native call.
2001
2063
SmallVector<ast::Expr *> arrayAttrArgs{*dictAttrCall, *stringAttrRef,
2002
2064
namedDecl->getValue ()};
2003
- auto entryToDictionaryCall =
2004
- createNativeCall ( loc, " addEntryToDictionaryAttr" , arrayAttrArgs);
2065
+ auto entryToDictionaryCall = createBuiltinCall (
2066
+ loc, builtins. addEntryToDictionaryAttr , arrayAttrArgs);
2005
2067
if (failed (entryToDictionaryCall))
2006
2068
return failure ();
2007
2069
@@ -2923,33 +2985,20 @@ Parser::createMemberAccessExpr(ast::Expr *parentExpr, StringRef name,
2923
2985
return ast::MemberAccessExpr::create (ctx, loc, parentExpr, name, *memberType);
2924
2986
}
2925
2987
2926
- FailureOr<ast::DeclRefExpr *>
2927
- Parser::createNativeCall (SMRange loc, StringRef nativeFuncName ,
2928
- MutableArrayRef<ast::Expr *> arguments) {
2988
+ FailureOr<ast::Expr *>
2989
+ Parser::createBuiltinCall (SMRange loc, ast::Decl *function ,
2990
+ MutableArrayRef<ast::Expr *> arguments) {
2929
2991
2930
- FailureOr<ast::Expr *> nativeFuncExpr = parseDeclRefExpr (nativeFuncName, loc );
2992
+ FailureOr<ast::Expr *> nativeFuncExpr = createDeclRefExpr (loc, function );
2931
2993
if (failed (nativeFuncExpr))
2932
2994
return failure ();
2933
2995
2934
- if (!(*nativeFuncExpr)->getType ().isa <ast::RewriteType>())
2935
- return emitError (nativeFuncName + " should be defined as a rewriter." );
2936
-
2937
2996
FailureOr<ast::CallExpr *> nativeCall =
2938
2997
createCallExpr (loc, *nativeFuncExpr, arguments);
2939
2998
if (failed (nativeCall))
2940
2999
return failure ();
2941
3000
2942
- // Create a unique anonymous name declaration to use, as its name is not
2943
- // important.
2944
- std::string anonName =
2945
- llvm::formatv (" {0}_{1}" , nativeFuncName, anonymousDeclNameCounter++)
2946
- .str ();
2947
- FailureOr<ast::VariableDecl *> varDecl = defineVariableDecl (
2948
- anonName, loc, (*nativeCall)->getType (), *nativeCall, {});
2949
- if (failed (varDecl))
2950
- return failure ();
2951
-
2952
- return createDeclRefExpr (loc, *varDecl);
3001
+ return *nativeCall;
2953
3002
}
2954
3003
2955
3004
FailureOr<ast::Type> Parser::validateMemberAccess (ast::Expr *parentExpr,
0 commit comments