Skip to content

Commit 9044b79

Browse files
author
Hal Finkel
authoredAug 17, 2020
Merge pull request hfinkel#1 from tpops/pull-request-syntax-plugin
Updating plugin interface to allow inserting entities prior to the function being replaced.
2 parents e6b6a57 + f03474c commit 9044b79

File tree

4 files changed

+55
-28
lines changed

4 files changed

+55
-28
lines changed
 

‎clang/examples/PrintTokensSyntax/PrintTokensSyntax.cpp

+8-2
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,17 @@ class PrintTokensHandler : public SyntaxHandler {
2323
void GetReplacement(Preprocessor &PP, Declarator &D,
2424
CachedTokens &Toks,
2525
llvm::raw_string_ostream &OS) override {
26+
27+
OS << "static const char* tokens = \"";
2628
for (auto &Tok : Toks) {
27-
OS << "printf(\"%s\\n\", \"";
29+
OS << " ";
2830
OS.write_escaped(PP.getSpelling(Tok));
29-
OS << "\");\n";
3031
}
32+
OS << "\";\n";
33+
// Rewrite syntax original function.
34+
OS << getDeclText(PP,D) << "{\n";
35+
OS << "printf(\"%s\",tokens);\n";
36+
OS <<"}\n";
3137
}
3238

3339
void AddToPredefines(llvm::raw_string_ostream &OS) override {

‎clang/include/clang/Parse/Parser.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -3117,7 +3117,6 @@ class SyntaxHandler {
31173117
std::string Name;
31183118

31193119
virtual void anchor();
3120-
31213120
public:
31223121
SyntaxHandler() = default;
31233122
explicit SyntaxHandler(StringRef name) : Name(name) {}
@@ -3128,6 +3127,8 @@ class SyntaxHandler {
31283127
CachedTokens &Toks,
31293128
llvm::raw_string_ostream &OS) = 0;
31303129
virtual void AddToPredefines(llvm::raw_string_ostream &OS) = 0;
3130+
/// Utility function returns actual text of a declarator.
3131+
StringRef getDeclText(Preprocessor &PP,Declarator &D);
31313132
};
31323133

31333134
/// Registry of syntax handlers added by plugins

‎clang/lib/Parse/Parser.cpp

+23-4
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,14 @@ using namespace clang;
2525
LLVM_INSTANTIATE_REGISTRY(SyntaxHandlerRegistry)
2626

2727
void SyntaxHandler::anchor() {}
28-
28+
// Utility function returning actual text for a declarator.
29+
llvm::StringRef SyntaxHandler::getDeclText(Preprocessor &PP,Declarator &D){
30+
auto DeclCharRange = Lexer::getAsCharRange (D.getSourceRange(),
31+
PP.getSourceManager(), PP.getLangOpts());
32+
auto DeclText= Lexer::getSourceText (DeclCharRange,
33+
PP.getSourceManager(), PP.getLangOpts());
34+
return DeclText;
35+
}
2936
namespace {
3037
/// A comment handler that passes comments found by the preprocessor
3138
/// to the parser action.
@@ -1190,15 +1197,27 @@ void Parser::ProcessPluginSyntax(ParsingDeclarator &D) {
11901197
return;
11911198
}
11921199

1193-
// Provide the token stream to the plugin and get back the replacement text.
11941200

11951201
std::string Replacement;
11961202
llvm::raw_string_ostream ReplacementOS(Replacement);
1197-
11981203
ReplacementOS << "\n{\n";
1199-
SHI->second->GetReplacement(PP, D, Toks, ReplacementOS);
1204+
// Place __builtin_unreachable(); in the forgoten function. This
1205+
// is done to avoid warnings from the compiler.
1206+
ReplacementOS << "__builtin_unreachable();\n";
12001207
ReplacementOS << "\n}\n";
1208+
1209+
// Provide the token stream to the plugin and get back the replacement text.
1210+
SHI->second->GetReplacement(PP, D, Toks, ReplacementOS);
12011211
ReplacementOS.flush();
1212+
1213+
// Change the identifier name in the declarator to forget
1214+
// the original function.
1215+
1216+
std::string NewName;
1217+
NewName ="__"+ D.getIdentifier()->getName().str();
1218+
1219+
IdentifierInfo &VariantII = Actions.Context.Idents.get(NewName);
1220+
D.SetIdentifier(&VariantII, D.getBeginLoc());
12021221

12031222
// Now we have a replacement text buffer from the plugin, enter it for
12041223
// lexing. After we're done with that, we'll resume parsing the original

‎clang/test/Frontend/plugin-syntax-print-tokens.cpp

+22-21
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,27 @@
55
This is a test with a "string".
66
}
77

8-
// CHECK: [[STR_VAR:@.+]] = private unnamed_addr constant [4 x i8] c"%s\0A\00", align 1
9-
// CHECK-NEXT: [[STR_VAR1:@.+]] = private unnamed_addr constant [5 x i8] c"This\00", align 1
10-
// CHECK-NEXT: [[STR_VAR2:@.+]] = private unnamed_addr constant [3 x i8] c"is\00", align 1
11-
// CHECK-NEXT: [[STR_VAR3:@.+]] = private unnamed_addr constant [2 x i8] c"a\00", align 1
12-
// CHECK-NEXT: [[STR_VAR4:@.+]] = private unnamed_addr constant [5 x i8] c"test\00", align 1
13-
// CHECK-NEXT: [[STR_VAR5:@.+]] = private unnamed_addr constant [5 x i8] c"with\00", align 1
14-
// CHECK-NEXT: [[STR_VAR6:@.+]] = private unnamed_addr constant [9 x i8] c"\22string\22\00", align 1
15-
// CHECK-NEXT: [[STR_VAR7:@.+]] = private unnamed_addr constant [2 x i8] c".\00", align 1
16-
17-
// CHECK: define dso_local void @_Z3fn1v() #0 {
18-
// CHECK-NEXT: entry:
19-
// CHECK-NEXT: %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* [[STR_VAR]], {{.*}}), i8* getelementptr inbounds ([5 x i8], [5 x i8]* [[STR_VAR1]], {{.*}}))
20-
// CHECK-NEXT: %call1 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* [[STR_VAR]], {{.*}}), i8* getelementptr inbounds ([3 x i8], [3 x i8]* [[STR_VAR2]], {{.*}}))
21-
// CHECK-NEXT: %call2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* [[STR_VAR]], {{.*}}), i8* getelementptr inbounds ([2 x i8], [2 x i8]* [[STR_VAR3]], {{.*}}))
22-
// CHECK-NEXT: %call3 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* [[STR_VAR]], {{.*}}), i8* getelementptr inbounds ([5 x i8], [5 x i8]* [[STR_VAR4]], {{.*}}))
23-
// CHECK-NEXT: %call4 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* [[STR_VAR]], {{.*}}), i8* getelementptr inbounds ([5 x i8], [5 x i8]* [[STR_VAR5]], {{.*}}))
24-
// CHECK-NEXT: %call5 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* [[STR_VAR]], {{.*}}), i8* getelementptr inbounds ([2 x i8], [2 x i8]* [[STR_VAR3]], {{.*}}))
25-
// CHECK-NEXT: %call6 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* [[STR_VAR]], {{.*}}), i8* getelementptr inbounds ([9 x i8], [9 x i8]* [[STR_VAR6]], {{.*}}))
26-
// CHECK-NEXT: %call7 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* [[STR_VAR]], {{.*}}), i8* getelementptr inbounds ([2 x i8], [2 x i8]* [[STR_VAR7]], {{.*}}))
27-
// CHECK-NEXT: ret void
28-
// CHECK-NEXT: }
8+
//CHECK: [[STR_VAR:@.+]] = private unnamed_addr constant [3 x i8] c"%s\00", align 1
9+
//CHECK-NEXT:@_ZL6tokens = internal global i8* getelementptr inbounds ([34 x i8], [34 x i8]* @.str.1, i32 0, i32 0), align 8
10+
//CHECK-NEXT: [[STR_VAR:@.+]] = private unnamed_addr constant [34 x i8] c" This is a test with a \22string\22 .\00", align 1
11+
12+
13+
14+
//CHECK: define dso_local void @_Z5__fn1v() #0 {
15+
//CHECK-NEXT: entry:
16+
//CHECK-NEXT: unreachable
17+
//CHECK-NEXT: }
18+
19+
20+
21+
//CHECK: define dso_local void @_Z3fn1v() #1 {
22+
//CHECK-NEXT: entry:
23+
//CHECK-NEXT: %0 = load i8*, i8** @_ZL6tokens, align 8
24+
//CHECK-NEXT: %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0), i8* %0)
25+
//CHECK-NEXT: ret void
26+
//CHECK-NEXT: }
27+
28+
29+
2930

3031

0 commit comments

Comments
 (0)
Please sign in to comment.