@@ -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
@@ -416,12 +427,12 @@ class Parser {
416
427
FailureOr<ast::MemberAccessExpr *>
417
428
createMemberAccessExpr (ast::Expr *parentExpr, StringRef name, SMRange loc);
418
429
419
- // Create a native call with \p nativeFuncName and \p arguments.
430
+ // Create a native call with \p function and \p arguments.
420
431
// This should be accompanied by a C++ implementation of the function that
421
432
// needs to be linked and registered in passes that process PDLL files.
422
- FailureOr<ast::DeclRefExpr *>
423
- createNativeCall (SMRange loc, StringRef nativeFuncName ,
424
- MutableArrayRef<ast::Expr *> arguments);
433
+ FailureOr<ast::Expr *>
434
+ createBuiltinCall (SMRange loc, ast::Decl *function ,
435
+ MutableArrayRef<ast::Expr *> arguments);
425
436
426
437
// / Validate the member access `name` into the given parent expression. On
427
438
// / success, this also returns the type of the member accessed.
@@ -576,13 +587,64 @@ class Parser {
576
587
577
588
// / The optional code completion context.
578
589
CodeCompleteContext *codeCompleteContext;
590
+
591
+ struct {
592
+ ast::UserRewriteDecl *createDictionaryAttr;
593
+ ast::UserRewriteDecl *addEntryToDictionaryAttr;
594
+ ast::UserRewriteDecl *createArrayAttr;
595
+ ast::UserRewriteDecl *addElemToArrayAttr;
596
+ } builtins{};
579
597
};
580
598
} // namespace
581
599
600
+ template <class T >
601
+ T *Parser::declareBuiltin (StringRef name, ArrayRef<StringRef> argNames,
602
+ bool returnsAttr) {
603
+ SMRange loc;
604
+ auto attrConstr = ast::ConstraintRef (
605
+ ast::AttrConstraintDecl::create (ctx, loc, nullptr ), loc);
606
+
607
+ pushDeclScope ();
608
+ SmallVector<ast::VariableDecl *> args;
609
+ for (auto argName : argNames) {
610
+ FailureOr<ast::VariableDecl *> arg =
611
+ createArgOrResultVariableDecl (argName, loc, attrConstr);
612
+ assert (succeeded (arg));
613
+ args.push_back (*arg);
614
+ }
615
+ SmallVector<ast::VariableDecl *> results;
616
+ if (returnsAttr) {
617
+ auto result = createArgOrResultVariableDecl (" " , loc, attrConstr);
618
+ assert (succeeded (result));
619
+ results.push_back (*result);
620
+ }
621
+ popDeclScope ();
622
+
623
+ auto *constraintDecl = T::createNative (ctx, ast::Name::create (ctx, name, loc),
624
+ args, results, {}, attrTy);
625
+ curDeclScope->add (constraintDecl);
626
+ return constraintDecl;
627
+ }
628
+
629
+ void Parser::declareBuiltins () {
630
+ builtins.createDictionaryAttr = declareBuiltin<ast::UserRewriteDecl>(
631
+ " __builtin_createDictionaryAttr" , {}, /* returnsAttr=*/ true );
632
+ builtins.addEntryToDictionaryAttr = declareBuiltin<ast::UserRewriteDecl>(
633
+ " __builtin_addEntryToDictionaryAttr" , {" attr" , " attrName" , " attrEntry" },
634
+ /* returnsAttr=*/ true );
635
+ builtins.createArrayAttr = declareBuiltin<ast::UserRewriteDecl>(
636
+ " __builtin_createArrayAttr" , {}, /* returnsAttr=*/ true );
637
+ builtins.addElemToArrayAttr = declareBuiltin<ast::UserRewriteDecl>(
638
+ " __builtin_addElemToArrayAttr" , {" attr" , " element" },
639
+ /* returnsAttr=*/ true );
640
+ }
641
+
582
642
FailureOr<ast::Module *> Parser::parseModule () {
583
643
SMLoc moduleLoc = curToken.getStartLoc ();
584
644
pushDeclScope ();
585
645
646
+ declareBuiltins ();
647
+
586
648
// Parse the top-level decls of the module.
587
649
SmallVector<ast::Decl *> decls;
588
650
if (failed (parseModuleBody (decls)))
@@ -1869,7 +1931,7 @@ FailureOr<ast::Expr *> Parser::parseArrayAttrExpr() {
1869
1931
" Parsing of array attributes as constraint not supported!" );
1870
1932
1871
1933
auto arrayAttrCall =
1872
- createNativeCall (curToken.getLoc (), " createArrayAttr" , {});
1934
+ createBuiltinCall (curToken.getLoc (), builtins. createArrayAttr , {});
1873
1935
if (failed (arrayAttrCall))
1874
1936
return failure ();
1875
1937
@@ -1879,8 +1941,8 @@ FailureOr<ast::Expr *> Parser::parseArrayAttrExpr() {
1879
1941
return failure ();
1880
1942
1881
1943
SmallVector<ast::Expr *> arrayAttrArgs{*arrayAttrCall, *attr};
1882
- auto elemToArrayCall = createNativeCall (
1883
- curToken.getLoc (), " addElemToArrayAttr" , arrayAttrArgs);
1944
+ auto elemToArrayCall = createBuiltinCall (
1945
+ curToken.getLoc (), builtins. addElemToArrayAttr , arrayAttrArgs);
1884
1946
if (failed (elemToArrayCall))
1885
1947
return failure ();
1886
1948
@@ -1961,7 +2023,7 @@ FailureOr<ast::Expr *> Parser::parseDictAttrExpr() {
1961
2023
return emitError (
1962
2024
" Parsing of dictionary attributes as constraint not supported!" );
1963
2025
1964
- auto dictAttrCall = createNativeCall (loc, " createDictionaryAttr" , {});
2026
+ auto dictAttrCall = createBuiltinCall (loc, builtins. createDictionaryAttr , {});
1965
2027
if (failed (dictAttrCall))
1966
2028
return failure ();
1967
2029
@@ -1995,8 +2057,8 @@ FailureOr<ast::Expr *> Parser::parseDictAttrExpr() {
1995
2057
// Create addEntryToDictionaryAttr native call.
1996
2058
SmallVector<ast::Expr *> arrayAttrArgs{*dictAttrCall, *stringAttrRef,
1997
2059
namedDecl->getValue ()};
1998
- auto entryToDictionaryCall =
1999
- createNativeCall ( loc, " addEntryToDictionaryAttr" , arrayAttrArgs);
2060
+ auto entryToDictionaryCall = createBuiltinCall (
2061
+ loc, builtins. addEntryToDictionaryAttr , arrayAttrArgs);
2000
2062
if (failed (entryToDictionaryCall))
2001
2063
return failure ();
2002
2064
@@ -2895,33 +2957,20 @@ Parser::createMemberAccessExpr(ast::Expr *parentExpr, StringRef name,
2895
2957
return ast::MemberAccessExpr::create (ctx, loc, parentExpr, name, *memberType);
2896
2958
}
2897
2959
2898
- FailureOr<ast::DeclRefExpr *>
2899
- Parser::createNativeCall (SMRange loc, StringRef nativeFuncName ,
2900
- MutableArrayRef<ast::Expr *> arguments) {
2960
+ FailureOr<ast::Expr *>
2961
+ Parser::createBuiltinCall (SMRange loc, ast::Decl *function ,
2962
+ MutableArrayRef<ast::Expr *> arguments) {
2901
2963
2902
- FailureOr<ast::Expr *> nativeFuncExpr = parseDeclRefExpr (nativeFuncName, loc );
2964
+ FailureOr<ast::Expr *> nativeFuncExpr = createDeclRefExpr (loc, function );
2903
2965
if (failed (nativeFuncExpr))
2904
2966
return failure ();
2905
2967
2906
- if (!(*nativeFuncExpr)->getType ().isa <ast::RewriteType>())
2907
- return emitError (nativeFuncName + " should be defined as a rewriter." );
2908
-
2909
2968
FailureOr<ast::CallExpr *> nativeCall =
2910
2969
createCallExpr (loc, *nativeFuncExpr, arguments);
2911
2970
if (failed (nativeCall))
2912
2971
return failure ();
2913
2972
2914
- // Create a unique anonymous name declaration to use, as its name is not
2915
- // important.
2916
- std::string anonName =
2917
- llvm::formatv (" {0}_{1}" , nativeFuncName, anonymousDeclNameCounter++)
2918
- .str ();
2919
- FailureOr<ast::VariableDecl *> varDecl = defineVariableDecl (
2920
- anonName, loc, (*nativeCall)->getType (), *nativeCall, {});
2921
- if (failed (varDecl))
2922
- return failure ();
2923
-
2924
- return createDeclRefExpr (loc, *varDecl);
2973
+ return *nativeCall;
2925
2974
}
2926
2975
2927
2976
FailureOr<ast::Type> Parser::validateMemberAccess (ast::Expr *parentExpr,
0 commit comments