@@ -50,18 +50,20 @@ using namespace tsar;
5050#undef DEBUG_TYPE
5151#define DEBUG_TYPE " clang-rfp"
5252
53- static bool isNameOfArray (std::string type) {
54- if (type.find (' [' ) != std::string::npos || type.find (' *' ) != std::string::npos) {
55- return true ;
53+ static int getDimensionsNum (QualType qt) {
54+ int res = 0 ;
55+ if (qt -> isPointerType ()) { // todo: multidimensional dynamyc-sized arrays
56+ return 1 ;
57+ }
58+ while (1 ) {
59+ if (qt -> isArrayType ()) {
60+ auto at = qt->getAsArrayTypeUnsafe ();
61+ qt = at -> getElementType ();
62+ res++;
63+ } else {
64+ return res;
65+ }
5666 }
57- return false ;
58- }
59-
60- static void replaceSqrBrWithAsterisk (std::string &str) {
61- size_t openingSqrBracket = str.find (" [" );
62- size_t closingSqrBracket = str.find (" ]" );
63- str.erase (openingSqrBracket, closingSqrBracket - openingSqrBracket + 1 );
64- str += " *" ;
6567}
6668
6769namespace {
@@ -78,12 +80,13 @@ class ClangRemoveFirstPrivate : public FunctionPass, private bcl::Uncopyable {
7880 void getAnalysisUsage (AnalysisUsage &AU) const override ;
7981};
8082
81- struct vars { // contains information about variables in
82- std::string var1Type; // removefirstprivate clause
83- std::string var2Type;
84- std::string var1Name;
85- std::string var2Name;
83+ struct vars { // contains information about variables in
84+ bool rvalIsArray = false ; // removefirstprivate clause
85+ std::string lvalName;
86+ std::string rvalName;
8687 std::string count = " " ;
88+ int dimensionsNum;
89+ std::vector<int > dimensions;
8790};
8891}
8992
@@ -130,28 +133,43 @@ class DeclVisitor : public RecursiveASTVisitor<DeclVisitor> {
130133 ast = RecursiveASTVisitor::TraverseStmt (S);
131134 isInPragma = false ;
132135
133- std::string txtStr, beforeFor, forBody, type1, type2 ;
136+ std::string txtStr, beforeFor, forBody, lval, rval, indeces ;
134137 std::vector<std::string> inits;
135138 while (varStack.size ()) {
136- if (isNameOfArray (varStack.top ().var1Type )) {
139+ for (std::vector<int >::iterator it = varStack.top ().dimensions .begin ();
140+ it != varStack.top ().dimensions .end ();
141+ it ++) {
142+ }
143+ if (varStack.top ().dimensionsNum ) { // lvalue is array
137144 if (varStack.top ().count .empty ()) {
138145 varStack.pop ();
139146 continue ; // count is mandatory for arrays, skip initialization if no count found
140147 }
141- if (type1.find (' [' ) != std::string::npos) {
142- replaceSqrBrWithAsterisk (type1);
148+ forBody = std::string ();
149+ indeces = std::string ();
150+ lval = varStack.top ().lvalName ;
151+ rval = varStack.top ().rvalName ;
152+ txtStr = std::string ();
153+ for (std::vector<int >::iterator it = varStack.top ().dimensions .begin ();
154+ it != varStack.top ().dimensions .end ();
155+ it ++) {
156+ int intCounter = it - varStack.top ().dimensions .begin ();
157+ std::string strCounter = " i" + std::to_string (intCounter);
158+ indeces += " [" + strCounter + " ]" ;
159+ txtStr += " for (int " + strCounter + " ; " + strCounter + " < " +
160+ std::to_string (*it) + " ; " + strCounter + " ++) {\n " ;
143161 }
144- if (type2. find ( ' [ ' ) != std::string::npos ) {
145- replaceSqrBrWithAsterisk (type2) ;
162+ if (varStack. top (). rvalIsArray ) {
163+ rval += indeces ;
146164 }
147- if (isNameOfArray (varStack.top ().var2Type )) { // arr1 = arr2
148- forBody = varStack.top ().var1Name + " [i] = " + varStack.top ().var2Name + " [i];\n " ;
149- } else { // arr1 = val
150- forBody = varStack.top ().var1Name + " [i] = " + varStack.top ().var2Name + " ;\n " ;
165+ lval += indeces;
166+ forBody = lval + " = " + rval + " ;\n " ;
167+ txtStr += forBody;
168+ for (int i = 0 ; i < varStack.top ().dimensionsNum ; i++) {
169+ txtStr += " }\n " ;
151170 }
152- txtStr = " for (int i = 0; i < " + varStack.top ().count + " ; i++) {\n " + forBody + " \n }\n " ;
153171 } else { // Initialize non-array variable
154- txtStr = varStack.top ().var1Name + " = " + varStack.top ().var2Name + " ;\n " ;
172+ txtStr = varStack.top ().lvalName + " = " + varStack.top ().rvalName + " ;\n " ;
155173 }
156174 inits.push_back (txtStr);
157175 varStack.pop ();
@@ -188,26 +206,34 @@ class DeclVisitor : public RecursiveASTVisitor<DeclVisitor> {
188206 bool TraverseDeclRefExpr (clang::DeclRefExpr *Ex) {
189207 std::string varName;
190208 if (isInPragma) {
209+ if (waitingForDimensions && curDimensionNum == varStack.top ().dimensionsNum ) {
210+ waitingForDimensions = false ;
211+ curDimensionNum = 0 ;
212+
213+ }
191214 if (auto *Var{dyn_cast<VarDecl>(Ex->getDecl ())}) {
192215 varName = Var -> getName ();
193216 }
194- if (waitingForVar) {
217+ if (waitingForVar) { // get lvalue
195218 ValueDecl *vd = Ex -> getDecl ();
196219 QualType qt = vd -> getType ();
197220 std::string typeStr = qt.getCanonicalType ().getAsString ();
198-
199221 vars tmp;
200- tmp.var1Type = typeStr;
201- tmp.var1Name = varName;
202- varStack.push (tmp);
203-
204- } else {
205222
223+ tmp.lvalName = varName;
224+ tmp.dimensionsNum = getDimensionsNum (qt);
225+ varStack.push (tmp);
226+ } else { // get rvalue
206227 ValueDecl *vd = Ex -> getDecl ();
207228 QualType qt = vd -> getType ();
229+ if (qt -> isArrayType () || qt -> isPointerType ()) {
230+ varStack.top ().rvalIsArray = true ;
231+ }
208232 std::string typeStr = qt.getCanonicalType ().getAsString ();
209- varStack.top ().var2Type = typeStr;
210- varStack.top ().var2Name = varName;
233+ varStack.top ().rvalName = varName;
234+ if (varStack.top ().dimensionsNum > 0 ) {
235+ waitingForDimensions = true ;
236+ }
211237
212238 }
213239 waitingForVar = !waitingForVar;
@@ -216,9 +242,21 @@ class DeclVisitor : public RecursiveASTVisitor<DeclVisitor> {
216242 }
217243
218244 bool TraverseIntegerLiteral (IntegerLiteral *IL) {
219- if (isInPragma && waitingForVar) {
220- if (varStack.size ()) {
221- varStack.top ().count = std::to_string (IL -> getValue ().getLimitedValue ());
245+
246+ if (isInPragma) {
247+ int val = IL -> getValue ().getLimitedValue ();
248+ if (waitingForDimensions) {
249+ if (varStack.size ()) {
250+ varStack.top ().dimensions .push_back (val);
251+ curDimensionNum++;
252+ varStack.top ().count = std::to_string (val);
253+ }
254+ } else if (!waitingForVar) { // get rvalue
255+ varStack.top ().rvalName = std::to_string (val);
256+ waitingForVar = !waitingForVar;
257+ if (varStack.top ().dimensionsNum > 0 ) {
258+ waitingForDimensions = true ;
259+ }
222260 }
223261 }
224262 return RecursiveASTVisitor::TraverseIntegerLiteral (IL);
@@ -239,6 +277,9 @@ class DeclVisitor : public RecursiveASTVisitor<DeclVisitor> {
239277
240278 bool isInPragma = false ;
241279 bool waitingForVar = true ;
280+ bool waitingForDimensions = false ;
281+ int curDimensionNum = 0 ;
282+
242283 std::vector<Stmt*> mScopes ;
243284
244285 TransformationContext *mTfmCtx ;
0 commit comments