Skip to content

Commit dc6681b

Browse files
committed
split of global declarations
1 parent 1603f31 commit dc6681b

File tree

1 file changed

+178
-84
lines changed

1 file changed

+178
-84
lines changed

lib/Transform/Clang/SplitDecls.cpp

Lines changed: 178 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,6 @@
3232
#include "tsar/Support/Clang/Diagnostic.h"
3333
#include "tsar/Support/Clang/Utils.h"
3434

35-
#include "tsar/Analysis/Clang/GlobalInfoExtractor.h"
36-
3735
#include <clang/AST/TypeLoc.h>
3836
#include <clang/AST/Decl.h>
3937
#include <clang/AST/Type.h>
@@ -44,7 +42,6 @@
4442
#include <llvm/ADT/SmallString.h>
4543
#include <clang/Basic/SourceLocation.h>
4644
#include <llvm/ADT/StringSet.h>
47-
//#include <llvm/IR/GlobalVariable.h>
4845
#include <llvm/IR/DebugInfoMetadata.h>
4946
#include <llvm/IR/Function.h>
5047
#include <llvm/IR/Module.h>
@@ -55,6 +52,7 @@
5552
#include <stack>
5653
#include <iostream>
5754
#include <deque>
55+
#include <map>
5856

5957
using namespace llvm;
6058
using namespace clang;
@@ -65,6 +63,19 @@ using namespace tsar;
6563

6664
char ClangSplitDeclsPass::ID = 0;
6765

66+
struct notSingleDecl {
67+
bool isNotSingleFlag = false;
68+
int varDeclsNum = 0;
69+
bool isFirstVar = true;
70+
SourceLocation notSingleDeclStart;
71+
SourceLocation notSingleDeclEnd;
72+
std::deque<SourceLocation> starts;
73+
std::deque<SourceLocation> ends;
74+
std::deque<std::string> names;
75+
std::string varDeclType;
76+
};
77+
78+
6879
INITIALIZE_PASS_IN_GROUP_BEGIN(ClangSplitDeclsPass, "clang-split",
6980
"Separation of variable declaration statements (Clang)", false, false,
7081
tsar::TransformationQueryManager::getPassRegistry())
@@ -90,9 +101,9 @@ namespace {
90101
/// other warnings.
91102
class ClangSplitter : public RecursiveASTVisitor<ClangSplitter> {
92103
public:
93-
ClangSplitter(TransformationContext &TfmCtx, const ASTImportInfo &ImportInfo,
104+
ClangSplitter(TransformationContext &TfmCtx, const ASTImportInfo &ImportInfo, const GlobalInfoExtractor &GlobalInfo,
94105
ClangGlobalInfoPass::RawInfo &RawInfo) :
95-
mTfmCtx(&TfmCtx), mImportInfo(ImportInfo),
106+
mTfmCtx(&TfmCtx), mImportInfo(ImportInfo), mGlobalInfo(GlobalInfo),
96107
mRawInfo(&RawInfo), mRewriter(TfmCtx.getRewriter()),
97108
mContext(TfmCtx.getContext()), mSrcMgr(mRewriter.getSourceMgr()),
98109
mLangOpts(mRewriter.getLangOpts()) {}
@@ -102,11 +113,11 @@ class ClangSplitter : public RecursiveASTVisitor<ClangSplitter> {
102113
return RecursiveASTVisitor::TraverseStmt(S);
103114
}
104115
Pragma P(*S); // the Pragma class is used to check if a statement is a pragma or not
116+
splitPragmaFlag = true;
105117
if (findClause(P, ClauseId::SplitDeclaration, mClauses)) { // mClauses contains all SplitDeclaration pragmas
106118
llvm::SmallVector<clang::CharSourceRange, 8> ToRemove; // a vector of statements that will match the root in the tree
107119
auto IsPossible = pragmaRangeToRemove(P, mClauses, mSrcMgr, mLangOpts,
108120
mImportInfo, ToRemove); // ToRemove - the range of positions we want to remove
109-
SplitDeclarationFlag = true;
110121
if (!IsPossible.first)
111122
if (IsPossible.second & PragmaFlags::IsInMacro)
112123
toDiag(mSrcMgr.getDiagnostics(), mClauses.front()->getBeginLoc(),
@@ -123,29 +134,60 @@ class ClangSplitter : public RecursiveASTVisitor<ClangSplitter> {
123134
RemoveEmptyLine.RemoveLineIfEmpty = false;
124135
for (auto SR : ToRemove)
125136
mRewriter.RemoveText(SR, RemoveEmptyLine); // delete each range
126-
if (isNotSingleFlag) {
127-
SourceRange toInsert(notSingleDeclStart, notSingleDeclEnd);
137+
std::map<clang::SourceLocation, notSingleDecl>::iterator it;
138+
for (it = globalVarDeclsMap.begin(); it != globalVarDeclsMap.end(); it++) {
139+
if (it->second.isNotSingleFlag) {
140+
SourceRange toInsert(it->second.notSingleDeclStart, it->second.notSingleDeclEnd);
141+
ExternalRewriter Canvas(toInsert, mSrcMgr, mLangOpts);
142+
std::cout << "Global range: " << Canvas.getRewrittenText(toInsert).str() << std::endl;
143+
mRewriter.RemoveText(toInsert, RemoveEmptyLine);
144+
}
145+
}
146+
if (localVarDecls.isNotSingleFlag) {
147+
SourceRange toInsert(localVarDecls.notSingleDeclStart, localVarDecls.notSingleDeclEnd);
128148
mRewriter.RemoveText(toInsert, RemoveEmptyLine);
129149
}
130150
return true;
131151
}
132152
Rewriter::RewriteOptions RemoveEmptyLine;
133153
RemoveEmptyLine.RemoveLineIfEmpty = false;
154+
if (splitPragmaFlag) {
155+
if (localVarDecls.isNotSingleFlag) {
156+
SourceRange toInsert(localVarDecls.notSingleDeclStart, localVarDecls.notSingleDeclEnd);
157+
mRewriter.RemoveText(toInsert, RemoveEmptyLine);
158+
while (localVarDecls.names.size()) {
159+
if (localVarDecls.isFirstVar) {
160+
mRewriter.InsertTextAfterToken(localVarDecls.notSingleDeclEnd, localVarDecls.names.back());
161+
localVarDecls.isFirstVar = false;
162+
} else {
163+
mRewriter.InsertTextAfterToken(localVarDecls.notSingleDeclEnd, localVarDecls.varDeclType + localVarDecls.names.back());
164+
}
165+
localVarDecls.names.pop_back();
166+
}
167+
}
134168

135-
if (SplitDeclarationFlag && isNotSingleFlag) {
136-
SourceRange toInsert(notSingleDeclStart, notSingleDeclEnd);
137-
mRewriter.RemoveText(toInsert, RemoveEmptyLine);
138-
while (varDeclsNames.size()) {
139-
if (isFirstVar) {
140-
mRewriter.InsertTextAfterToken(notSingleDeclEnd, varDeclsNames.back());
141-
isFirstVar = false;
142-
} else {
143-
mRewriter.InsertTextAfterToken(notSingleDeclEnd, varDeclType + varDeclsNames.back());
169+
std::map<clang::SourceLocation, notSingleDecl>::iterator it;
170+
for (it = globalVarDeclsMap.begin(); it != globalVarDeclsMap.end(); it++) {
171+
if (it->second.isNotSingleFlag) {
172+
// SourceRange toInsert(it->second.notSingleDeclStart, it->second.ends.back());
173+
SourceRange toInsert(it->second.notSingleDeclStart, it->second.ends.back());
174+
mRewriter.RemoveText(toInsert, RemoveEmptyLine);
175+
while (it->second.names.size()) {
176+
if (it->second.isFirstVar) {
177+
mRewriter.InsertTextAfterToken(it->second.ends.back(), it->second.names.back());
178+
it->second.isFirstVar = false;
179+
} else {
180+
if (it->second.names.size() == 1) {
181+
mRewriter.InsertTextAfterToken(it->second.ends.back(), it->second.varDeclType + it->second.names.back());
182+
} else {
183+
mRewriter.InsertTextAfterToken(it->second.ends.back(), it->second.varDeclType + it->second.names.back() + ";\n");
184+
}
185+
}
186+
it->second.names.pop_back();
187+
}
144188
}
145-
varDeclsNames.pop_back();
146189
}
147190
}
148-
149191
if (mClauses.empty() || !isa<CompoundStmt>(S) &&
150192
!isa<ForStmt>(S) && !isa<DoStmt>(S) && !isa<WhileStmt>(S))
151193
return RecursiveASTVisitor::TraverseStmt(S);
@@ -176,72 +218,136 @@ class ClangSplitter : public RecursiveASTVisitor<ClangSplitter> {
176218
return Res;
177219
}
178220

221+
std::string getType(SourceLocation start, SourceLocation endLoc) {
222+
SourceRange varDeclRange(start, endLoc);
223+
std::string type = mRewriter.getRewrittenText(varDeclRange);
224+
std::cout << "type = " << type << std::endl;
225+
return type;
226+
}
227+
179228
bool TraverseTypeLoc(TypeLoc Loc) {
180-
if (isNotSingleFlag && varDeclsNum == 1) {
181-
SourceRange varDeclRange(start, Loc.getEndLoc());
182-
std::string type = mRewriter.getRewrittenText(varDeclRange);
183-
std::cout << "type = " << type << std::endl;
184-
varDeclType = type;
229+
std::map<clang::SourceLocation, notSingleDecl>::iterator it;
230+
if (localVarDecls.isNotSingleFlag && localVarDecls.varDeclsNum == 1) {
231+
localVarDecls.varDeclType = getType(start, Loc.getEndLoc());
185232
return RecursiveASTVisitor::TraverseTypeLoc(Loc);
186233
}
234+
for (it = globalVarDeclsMap.begin(); it != globalVarDeclsMap.end(); it++) {
235+
if (it->second.varDeclsNum == 1) {
236+
it->second.varDeclType = getType(it->first, Loc.getEndLoc());
237+
return RecursiveASTVisitor::TraverseTypeLoc(Loc);
238+
}
239+
}
187240
return true;
188241
}
189242

190-
bool VisitVarDecl(VarDecl *S) { // to traverse the parse tree and visit each statement
191-
if (isNotSingleFlag) {
192-
varDeclsNum++;
193-
SourceRange toInsert(notSingleDeclStart, notSingleDeclEnd);
194-
ExternalRewriter Canvas(toInsert, mSrcMgr, mLangOpts);
243+
void ProcessLocalDeclaration(VarDecl *S, SourceRange toInsert) {
244+
ExternalRewriter Canvas(toInsert, mSrcMgr, mLangOpts);
245+
SourceRange Range(S->getLocation());
246+
std::cout << "Range: " << Canvas.getRewrittenText(Range).str() << std::endl;
247+
localVarDecls.starts.push_front(S->getBeginLoc());
248+
localVarDecls.ends.push_front(S->getEndLoc());
249+
SourceRange varDeclRange(S->getBeginLoc(), S->getEndLoc());
250+
if (localVarDecls.varDeclsNum == 1) {
251+
localVarDecls.isFirstVar = true;
252+
txtStr = Canvas.getRewrittenText(varDeclRange).str();
253+
std::cout << "first localVarDeclsNum = " << localVarDecls.varDeclsNum << " " << txtStr << std::endl;
254+
}
255+
if (localVarDecls.varDeclsNum > 1) {
256+
SourceRange prevVarDeclRange(localVarDecls.starts.back(), localVarDecls.ends.back());
257+
localVarDecls.starts.pop_back();
258+
localVarDecls.ends.pop_back();
259+
Canvas.ReplaceText(prevVarDeclRange, "");
260+
txtStr = Canvas.getRewrittenText(varDeclRange).str();
261+
std::cout << "varDeclsNum = " << localVarDecls.varDeclsNum << " " << txtStr << std::endl;
262+
auto it = std::remove(txtStr.begin(), txtStr.end(), ',');
263+
txtStr.erase(it, txtStr.end());
264+
std::cout << "varDeclsNum = " << localVarDecls.varDeclsNum << " " << txtStr << std::endl;
265+
}
266+
localVarDecls.names.push_front(txtStr + ";\n");
267+
}
268+
269+
void ProcessGlobalDeclaration(VarDecl *S, SourceRange toInsert) {
270+
ExternalRewriter Canvas(toInsert, mSrcMgr, mLangOpts);
271+
SourceRange Range(S->getLocation());
272+
std::cout << "Range: " << Canvas.getRewrittenText(Range).str() << std::endl;
273+
globalVarDeclsMap[S->getBeginLoc()].starts.push_front(S->getBeginLoc());
274+
globalVarDeclsMap[S->getBeginLoc()].ends.push_front(S->getEndLoc());
275+
SourceRange varDeclRange(S->getBeginLoc(), S->getEndLoc());
276+
if (globalVarDeclsMap[S->getBeginLoc()].varDeclsNum == 1) {
277+
globalVarDeclsMap[S->getBeginLoc()].isFirstVar = true;
278+
txtStr = Canvas.getRewrittenText(varDeclRange).str();
279+
std::cout << "first localVarDeclsNum = " << globalVarDeclsMap[S->getBeginLoc()].varDeclsNum << " " << txtStr << std::endl;
280+
281+
globalVarDeclsMap[S->getBeginLoc()].notSingleDeclStart = S->getBeginLoc();
282+
globalVarDeclsMap[S->getBeginLoc()].names.push_front(txtStr + ";\n");
283+
}
284+
if (globalVarDeclsMap[S->getBeginLoc()].varDeclsNum > 1) {
285+
SourceRange prevVarDeclRange(globalVarDeclsMap[S->getBeginLoc()].starts.back(), globalVarDeclsMap[S->getBeginLoc()].ends.back());
286+
globalVarDeclsMap[S->getBeginLoc()].starts.pop_back();
287+
globalVarDeclsMap[S->getBeginLoc()].ends.pop_back();
288+
Canvas.ReplaceText(prevVarDeclRange, "");
289+
txtStr = Canvas.getRewrittenText(varDeclRange).str();
290+
std::cout << "varDeclsNum = " << globalVarDeclsMap[S->getBeginLoc()].varDeclsNum << " " << txtStr << std::endl;
291+
auto it = std::remove(txtStr.begin(), txtStr.end(), ',');
292+
txtStr.erase(it, txtStr.end());
293+
std::cout << "varDeclsNum = " << globalVarDeclsMap[S->getBeginLoc()].varDeclsNum << " " << txtStr << std::endl;
195294

196-
SourceRange Range(S->getLocation());
197-
std::cout << "Range: " << Canvas.getRewrittenText(Range).str() << std::endl;
198-
varDeclsStarts.push_front(S->getBeginLoc());
199-
varDeclsEnds.push_front(S->getEndLoc());
200-
SourceRange varDeclRange(S->getBeginLoc(), S->getEndLoc());
201-
if (varDeclsNum == 1) {
202-
isFirstVar = true;
203-
txtStr = Canvas.getRewrittenText(varDeclRange).str();
204-
std::cout << "first varDeclsNum = " << varDeclsNum << " " << txtStr << std::endl;
295+
globalVarDeclsMap[S->getBeginLoc()].names.push_front(txtStr);
296+
}
297+
globalVarDeclsMap[S->getBeginLoc()].notSingleDeclEnd = S->getEndLoc();
298+
}
299+
300+
bool VisitVarDecl(VarDecl *S) { // to traverse the parse tree and visit each statement
301+
if (mGlobalInfo.findOutermostDecl(S)) {
302+
if (globalVarDeclsMap[S->getBeginLoc()].varDeclsNum == 0) {
303+
std::map<clang::SourceLocation, notSingleDecl>::iterator it;
304+
for (it = globalVarDeclsMap.begin(); it != globalVarDeclsMap.end(); it++) {
305+
if (it->first != S->getBeginLoc()) {
306+
it->second.starts.clear();
307+
it->second.ends.clear();
308+
it->second.names.clear();
309+
globalVarDeclsMap.erase(it->first);
310+
}
311+
}
205312
}
206-
if (varDeclsNum > 1) {
207-
SourceRange prevVarDeclRange(varDeclsStarts.back(), varDeclsEnds.back());
208-
varDeclsStarts.pop_back();
209-
varDeclsEnds.pop_back();
210-
Canvas.ReplaceText(prevVarDeclRange, "");
211-
txtStr = Canvas.getRewrittenText(varDeclRange).str();
212-
auto it = std::remove(txtStr.begin(), txtStr.end(), ',');
213-
txtStr.erase(it, txtStr.end());
214-
size_t foundIndex = txtStr.find("\n");
215-
if (foundIndex != std::string::npos)
216-
txtStr.erase(foundIndex, 2);
217-
std::cout << "varDeclsNum = " << varDeclsNum << " " << txtStr << std::endl;
313+
if (globalVarDeclsMap[S->getBeginLoc()].varDeclsNum == 1) {
314+
globalVarDeclsMap[S->getBeginLoc()].isNotSingleFlag = true;
218315
}
219-
varDeclsNames.push_front(txtStr + ";\n");
316+
globalVarDeclsMap[S->getBeginLoc()].varDeclsNum++;
317+
SourceRange toInsert(S->getBeginLoc(), S->getEndLoc());
318+
ProcessGlobalDeclaration(S, toInsert);
319+
}
320+
if (localVarDecls.isNotSingleFlag) {
321+
localVarDecls.varDeclsNum++;
322+
SourceRange toInsert(localVarDecls.notSingleDeclStart, localVarDecls.notSingleDeclEnd);
323+
ProcessLocalDeclaration(S, toInsert);
220324
}
221325
return true;
222326
}
223327

328+
224329
bool VisitDeclStmt(DeclStmt *S) {
225330
if(!(S->isSingleDecl())) {
226331
start = S->getBeginLoc();
227-
//if (!isNotSingleFlag) {
228-
varDeclsNum = 0;
229-
//}
230-
varDeclsStarts.clear();
231-
varDeclsEnds.clear();
232-
varDeclsNames.clear();
233-
isNotSingleFlag = true;
234-
notSingleDeclStart = S->getBeginLoc();
235-
notSingleDeclEnd = S->getEndLoc();
332+
localVarDecls.varDeclsNum = 0;
333+
localVarDecls.starts.clear();
334+
localVarDecls.ends.clear();
335+
localVarDecls.names.clear();
336+
localVarDecls.isNotSingleFlag = true;
337+
std::cout << "IS NOT SINGLE\n";
338+
localVarDecls.notSingleDeclStart = S->getBeginLoc();
339+
localVarDecls.notSingleDeclEnd = S->getEndLoc();
340+
varPositions[S->getBeginLoc()] = S->getEndLoc();
236341
} else {
237-
isNotSingleFlag = false;
342+
std::cout << "IS SINGLE\n";
343+
localVarDecls.isNotSingleFlag = false;
238344
}
239345
return true;
240346
}
241347

242348
bool VisitParmVarDecl(ParmVarDecl *S) {
243349
std::cout << "is ParmVarDecl" << std::endl;
244-
isNotSingleFlag = false;
350+
localVarDecls.isNotSingleFlag = false;
245351
return true;
246352
}
247353

@@ -266,35 +372,21 @@ class ClangSplitter : public RecursiveASTVisitor<ClangSplitter> {
266372

267373
TransformationContext *mTfmCtx;
268374
const ASTImportInfo &mImportInfo;
375+
const GlobalInfoExtractor &mGlobalInfo;
376+
269377
ClangGlobalInfoPass::RawInfo *mRawInfo;
270378
Rewriter &mRewriter;
271379
ASTContext &mContext;
272380
SourceManager &mSrcMgr;
273381
const LangOptions &mLangOpts;
274382
SmallVector<Stmt *, 1> mClauses;
275383
bool mActiveSplit = false;
276-
DenseSet<DeclStmt*> mMultipleDecls;
277-
std::deque<SourceLocation> varDeclsStarts;
278-
std::deque<SourceLocation> varDeclsEnds;
279-
std::deque<SourceLocation> starts;
280-
std::deque<SourceLocation> ends;
281-
std::deque<SourceRange> Ranges;
282-
std::deque<std::string> varDeclsNames;
283-
std::deque<std::string> names;
284-
int varDeclsNum = 0;
285-
int varsNum = 0;
286-
SourceLocation notSingleDeclStart;
287-
SourceLocation notSingleDeclEnd;
288-
SourceLocation DeclStart;
289-
SourceLocation DeclEnd;
290-
SourceRange TypeRange;
291-
bool SplitDeclarationFlag = false;
292-
bool isNotSingleFlag = false;
293-
bool isAfterNotSingleFlag = false;
294-
bool isFirstVar = true;
384+
bool splitPragmaFlag = false;
385+
386+
std::map<SourceLocation, notSingleDecl> globalVarDeclsMap;
387+
std::map<SourceLocation, SourceLocation> varPositions;
388+
notSingleDecl localVarDecls;
295389
std::string txtStr;
296-
std::string varDeclType;
297-
std::string DeclType;
298390
SourceLocation start;
299391
};
300392
}
@@ -326,7 +418,9 @@ bool ClangSplitDeclsPass::runOnModule(llvm::Module &M) {
326418
if (auto *ImportPass = getAnalysisIfAvailable<ImmutableASTImportInfoPass>())
327419
ImportInfo = &ImportPass->getImportInfo();
328420
auto &GIP = getAnalysis<ClangGlobalInfoPass>();
329-
ClangSplitter Vis(*TfmCtx, *ImportInfo, GIP.getRawInfo());
421+
//mGlobalInfo = &GIP.getGlobalInfo();
422+
const auto &GlobalInfo = GIP.getGlobalInfo();
423+
ClangSplitter Vis(*TfmCtx, *ImportInfo, GlobalInfo, GIP.getRawInfo());
330424
Vis.TraverseDecl(TfmCtx->getContext().getTranslationUnitDecl());
331425
return false;
332426
}

0 commit comments

Comments
 (0)