-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinsert_loops.cpp
More file actions
124 lines (105 loc) · 4.35 KB
/
insert_loops.cpp
File metadata and controls
124 lines (105 loc) · 4.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//----------------------------------------------------------------------------------------------------------
// Clang rewriter - re-write OpenCL Kernel and Driver from multi-threaded implementation,
// to single-threaded loop implementation.
//
// Kuba Kaszyk (kubakaszyk@gmail.com)
//
// Based on tutorial by Eli Bendersky:
// https://eli.thegreenplace.net/2014/05/01/modern-source-to-source-transformation-with-clang-and-libtooling
//----------------------------------------------------------------------------------------------------------
#include <cstdio>
#include <memory>
#include <sstream>
#include <string>
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/TargetOptions.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Parse/ParseAST.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "clang/Rewrite/Frontend/Rewriters.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
// By implementing RecursiveASTVisitor, we can specify which AST nodes
// we're interested in by overriding relevant methods.
class MyASTVisitor : public RecursiveASTVisitor<MyASTVisitor> {
public:
MyASTVisitor(Rewriter &R) : TheRewriter(R) {}
bool VisitFunctionDecl(FunctionDecl * f) {
//f->dump();
SourceLocation locToUse = f->getBody()->getLocStart().getLocWithOffset(1);
TheRewriter.InsertText(locToUse, "Start of Function Decl\n", true, true);
TheRewriter.InsertText(f->getLocEnd(), "End of Function Decl\n", true, true);
return true;
}
private:
Rewriter &TheRewriter;
};
// Implementation of the ASTConsumer interface for reading an AST produced
// by the Clang parser.
class MyASTConsumer : public ASTConsumer {
public:
MyASTConsumer(Rewriter &R) : Visitor(R) {}
// Override the method that gets called for each parsed top-level
// declaration.
virtual bool HandleTopLevelDecl(DeclGroupRef DR) {
for (DeclGroupRef::iterator b = DR.begin(), e = DR.end(); b != e; ++b)
// Traverse the declaration using our AST visitor.
Visitor.TraverseDecl(*b);
return true;
}
private:
MyASTVisitor Visitor;
};
int main(int argc, char * argv[]) {
if (argc != 2) {
llvm::errs() << "Usage: insert_loops <filename>\n";
return 1;
}
// CompilerInstance will hold the instance of the Clang compiler for us,
// managing the various objects needed to run the compiler.
CompilerInstance TheCompInst;
TheCompInst.createDiagnostics();
LangOptions &lo = TheCompInst.getLangOpts();
lo.OpenCL = 1;
// Initialize target info with the default triple for our platform.
// Is this necessary if we're just doing a source transformation??
auto TO = std::make_shared<TargetOptions>();
TO->Triple = llvm::sys::getDefaultTargetTriple();
TargetInfo *TI =
TargetInfo::CreateTargetInfo(TheCompInst.getDiagnostics(), TO);
TheCompInst.setTarget(TI);
TheCompInst.createFileManager();
FileManager &FileMgr = TheCompInst.getFileManager();
TheCompInst.createSourceManager(FileMgr);
SourceManager &SourceMgr = TheCompInst.getSourceManager();
TheCompInst.createPreprocessor(TU_Module);
TheCompInst.createASTContext();
// A Rewriter helps us manage the code rewriting task.
Rewriter TheRewriter;
TheRewriter.setSourceMgr(SourceMgr, TheCompInst.getLangOpts());
// Set the main file handled by the source manager to the input file.
const FileEntry *FileIn = FileMgr.getFile(argv[1]);
SourceMgr.setMainFileID(
SourceMgr.createFileID(FileIn, SourceLocation(), SrcMgr::C_User));
TheCompInst.getDiagnosticClient().BeginSourceFile(
TheCompInst.getLangOpts(), &TheCompInst.getPreprocessor());
// Create an AST consumer instance which is going to get called by
// ParseAST.
MyASTConsumer TheConsumer(TheRewriter);
// Parse the file to AST, registering our consumer as the AST consumer.
ParseAST(TheCompInst.getPreprocessor(), &TheConsumer,
TheCompInst.getASTContext());
// At this point the rewriter's buffer should be full with the rewritten
// file contents.
const RewriteBuffer *RewriteBuf =
TheRewriter.getRewriteBufferFor(SourceMgr.getMainFileID());
llvm::outs() << std::string(RewriteBuf->begin(), RewriteBuf->end());
return 0;
}