3030#include " tsar/Frontend/Clang/Pragma.h"
3131#include " tsar/Frontend/Clang/TransformationContext.h"
3232#include " tsar/Support/Clang/Diagnostic.h"
33+ #include " tsar/Support/Clang/Utils.h"
3334#include < clang/AST/Decl.h>
3435#include < clang/AST/RecursiveASTVisitor.h>
3536#include < clang/AST/Stmt.h>
4546#include < vector>
4647#include < string>
4748#include < stack>
49+ #include < iostream>
50+ #include < deque>
4851
4952using namespace llvm ;
5053using namespace clang ;
@@ -79,6 +82,7 @@ namespace {
7982// / after it. It also checks absence a macros in this scope and print some
8083// / other warnings.
8184bool isNotSingleFlag = false ;
85+ bool isAfterNotSingleFlag = false ;
8286class ClangSplitter : public RecursiveASTVisitor <ClangSplitter> {
8387public:
8488 ClangSplitter (TransformationContext &TfmCtx, const ASTImportInfo &ImportInfo,
@@ -94,16 +98,6 @@ class ClangSplitter : public RecursiveASTVisitor<ClangSplitter> {
9498 }
9599 Pragma P (*S); // the Pragma class is used to check if a statement is a pragma or not
96100 if (findClause (P, ClauseId::SplitDeclaration, mClauses )) { // mClauses contains all SplitDeclaration pragmas
97- std::vector<std::string> inits;
98- while (starts.size ()) {
99- SourceRange toInsert (starts.top (), ends.top ());
100- CharSourceRange txtToInsert (toInsert, true );
101- starts.pop ();
102- ends.pop ();
103- txtStr = mRewriter .getRewrittenText (txtToInsert);
104- txtStr += " ;\n " ;
105- inits.push_back (txtStr);
106- }
107101 llvm::SmallVector<clang::CharSourceRange, 8 > ToRemove; // a vector of statements that will match the root in the tree
108102 auto IsPossible = pragmaRangeToRemove (P, mClauses , mSrcMgr , mLangOpts ,
109103 mImportInfo , ToRemove); // ToRemove - the range of positions we want to remove
@@ -124,21 +118,18 @@ class ClangSplitter : public RecursiveASTVisitor<ClangSplitter> {
124118 for (auto SR : ToRemove)
125119 mRewriter .RemoveText (SR, RemoveEmptyLine); // delete each range
126120 if (isNotSingleFlag) {
127- SourceRange toInsert (start, end );
121+ SourceRange toInsert (notSingleDeclStart, notSingleDeclEnd );
128122 mRewriter .RemoveText (toInsert, RemoveEmptyLine);
129123 }
130- // Rewriter::RewriteOptions RemoveEmptyLine;
131- for (std::vector<std::string>::iterator it = inits.begin (); it != inits.end (); ++it) {
132- mRewriter .InsertTextAfterToken (end, *it);
133- }
134124 return true ;
135125 }
136126 Rewriter::RewriteOptions RemoveEmptyLine;
137127 RemoveEmptyLine.RemoveLineIfEmpty = false ;
138128
139129 if (isNotSingleFlag) {
140- SourceRange toInsert (start, end );
130+ SourceRange toInsert (notSingleDeclStart, notSingleDeclEnd );
141131 mRewriter .RemoveText (toInsert, RemoveEmptyLine);
132+
142133 }
143134 if (mClauses .empty () || !isa<CompoundStmt>(S) &&
144135 !isa<ForStmt>(S) && !isa<DoStmt>(S) && !isa<WhileStmt>(S))
@@ -190,30 +181,62 @@ class ClangSplitter : public RecursiveASTVisitor<ClangSplitter> {
190181 }
191182 }
192183
184+ // bool VisitVarDecl(VarDecl *S) { // to traverse the parse tree and visit each statement
185+ // if (isNotSingleFlag) {
186+ // std::string varType = S->getType().getAsString();
187+ // SourceLocation locat = S->getLocation();
188+ // CharSourceRange txtToInsert(locat, true);
189+ // std::string varName = S->getName().str();
190+ // int n = varType.length();
191+ // char char_array[n + 1];
192+ // strcpy(char_array, varType.c_str());
193+ // if (strchr(char_array, '[')) {
194+ // buildTxtStr(varType, varName);
195+ // } else {
196+ // txtStr = varType + " " + varName + ";\n";
197+ // }
198+ // mRewriter.InsertTextAfterToken(notSingleDeclEnd, txtStr);
199+ // }
200+ // return true;
201+ // }
202+
193203 bool VisitVarDecl (VarDecl *S) { // to traverse the parse tree and visit each statement
194204 if (isNotSingleFlag) {
195- std::string varType = S->getType ().getAsString ();
196- SourceLocation locat = S->getLocation ();
197- CharSourceRange txtToInsert (locat, true );
198- std::string varName = S->getName ().str ();
199- int n = varType.length ();
200- char char_array[n + 1 ];
201- strcpy (char_array, varType.c_str ());
202- if (strchr (char_array, ' [' )) {
203- buildTxtStr (varType, varName);
204- } else {
205- txtStr = varType + " " + varName + " ;\n " ;
205+ varDeclsNum++;
206+ SourceRange toInsert (notSingleDeclStart, notSingleDeclEnd);
207+ ExternalRewriter Canvas (toInsert, mSrcMgr , mLangOpts );
208+ SourceRange Range (S->getLocation ());
209+ varDeclsStarts.push_front (S->getBeginLoc ());
210+ varDeclsEnds.push_front (S->getEndLoc ());
211+ SourceRange varDeclRange (S->getBeginLoc (), S->getEndLoc ());
212+ if (varDeclsNum == 1 ) {
213+ SourceRange toInsert2 (Range.getBegin (), S->getEndLoc ());
214+ txtStr = Canvas.getRewrittenText (varDeclRange).str ();
215+ Canvas.RemoveText (toInsert2);
216+ varDeclType = Canvas.getRewrittenText (varDeclRange);
217+ }
218+ if (varDeclsNum > 1 ) {
219+ SourceRange prevVarDeclRange (varDeclsStarts.back (), varDeclsEnds.back ());
220+ varDeclsStarts.pop_back ();
221+ varDeclsEnds.pop_back ();
222+ Canvas.ReplaceText (prevVarDeclRange, varDeclType);
223+ txtStr = Canvas.getRewrittenText (varDeclRange).str ();
224+ auto it = std::remove (txtStr.begin (), txtStr.end (), ' ,' );
225+ txtStr.erase (it, txtStr.end ());
206226 }
207- mRewriter .InsertTextAfterToken (end , txtStr);
227+ mRewriter .InsertTextAfterToken (notSingleDeclEnd , txtStr + " ; \n " );
208228 }
209229 return true ;
210230 }
211231
212232 bool TraverseDeclStmt (DeclStmt *S) {
213- if (!S->isSingleDecl ()) {
233+ bool tmp;
234+ if (!(S->isSingleDecl ())) {
235+ if (!isNotSingleFlag)
236+ varDeclsNum = 0 ;
214237 isNotSingleFlag = true ;
215- start = S->getBeginLoc ();
216- end = S->getEndLoc ();
238+ notSingleDeclStart = S->getBeginLoc ();
239+ notSingleDeclEnd = S->getEndLoc ();
217240 } else {
218241 isNotSingleFlag = false ;
219242 }
@@ -248,11 +271,13 @@ class ClangSplitter : public RecursiveASTVisitor<ClangSplitter> {
248271 SmallVector<Stmt *, 1 > mClauses ;
249272 bool mActiveSplit = false ;
250273 DenseSet<DeclStmt*> mMultipleDecls ;
251- std::stack<SourceLocation> starts;
252- std::stack<SourceLocation> ends;
253- SourceLocation start;
254- SourceLocation end;
274+ std::deque<SourceLocation> varDeclsStarts;
275+ std::deque<SourceLocation> varDeclsEnds;
276+ int varDeclsNum = 0 ;
277+ SourceLocation notSingleDeclStart;
278+ SourceLocation notSingleDeclEnd;
255279 std::string txtStr;
280+ std::string varDeclType;
256281};
257282}
258283
@@ -272,4 +297,4 @@ bool ClangSplitDeclsPass::runOnModule(llvm::Module &M) {
272297 ClangSplitter Vis (*TfmCtx, *ImportInfo, GIP.getRawInfo ());
273298 Vis.TraverseDecl (TfmCtx->getContext ().getTranslationUnitDecl ());
274299 return false ;
275- }
300+ }
0 commit comments