@@ -485,6 +485,7 @@ std::pair<SValue, std::vector<SValue> >
485485 iival = evaluateConstInt (iexpr, ival, checkConst);
486486 initvals.push_back (ival);
487487 }
488+ // cout << "parseValueDecl val " << val << " ival " << ival << endl;
488489
489490 if (isRef) {
490491 // It needs to put reference value into state
@@ -851,8 +852,12 @@ void ScParseExpr::parseExpr(clang::StringLiteral* expr, SValue& val)
851852// Used for local variables access in left/right parts
852853void ScParseExpr::parseExpr (clang::DeclRefExpr* expr, SValue& val)
853854{
854- using namespace llvm ;
855- auto * decl = expr->getDecl ();
855+ ValueDecl* decl = expr->getDecl ();
856+
857+ // Parameter variable has @modval parent, local variable has @recval
858+ bool isParamVar = isa<ParmVarDecl>(decl);
859+ SValue recVal = recval ? recval : modval;
860+ // cout << "DeclRefExpr recVal " << recVal << endl;
856861
857862 if (auto * enumConstDecl = dyn_cast<clang::EnumConstantDecl>(decl)) {
858863 // Enum constants are not stored in state, evaluated immediately
@@ -869,40 +874,38 @@ void ScParseExpr::parseExpr(clang::DeclRefExpr* expr, SValue& val)
869874
870875 } else {
871876 // Regular data member
872- val = SValue (decl, modval );
877+ val = SValue (decl, recVal );
873878 }
874879 } else {
875880 // This happens for function pointer passed as parameter
876881 decl->dumpColor ();
877882 SCT_TOOL_ASSERT (false , " Record has not variable declaration" );
878883 }
884+ // cout << "Record variable val " << val << endl;
879885
880886 } else
881887 if (!isa<clang::FunctionDecl>(decl->getDeclContext ())) {
882888 // Global variable
883889 val = SValue (decl, NO_VALUE);
884-
885- } else
886- if (isUserDefinedClass (decl->getType ())) {
887- // Local record value
888- val = SValue (decl, modval);
889- // cout << "Local record val " << val << ", modval " << modval << endl;
890+ // cout << "Global variable val " << val << endl;
890891
891892 } else {
892893 // Function local variable
893- val = SValue (decl, modval);
894+ val = SValue (decl, isParamVar ? modval : recVal);
895+ // cout << "Local variable val " << val << " isParamVar " << isParamVar << endl;
894896 }
895897 }
896898}
897899
898900void ScParseExpr::parseExpr (clang::MemberExpr* expr, SValue& val)
899901{
902+ // cout << "ScParseExpr::MemberExpr # " << hex << expr << dec << endl;
903+
900904 // Get record from variable/dynamic object
901905 SCT_TOOL_ASSERT (expr->getBase (), " In parseExpr for MemberExpr no base found" );
902906 SValue tval = evalSubExpr (expr->getBase ());
903907 SValue ttval = getRecordFromState (tval, ArrayUnkwnMode::amArrayUnknown);
904908
905- // cout << "ScParseExpr::MemberExpr # " << hex << expr << dec << endl;
906909 // cout << "ScParseExpr::MemberExpr tval = " << tval << ", base->getType() = "
907910 // << expr->getBase()->getType().getAsString() << endl;
908911 // cout << "final ttval = " << ttval << endl;
@@ -945,13 +948,11 @@ void ScParseExpr::parseExpr(clang::MemberExpr* expr, SValue& val)
945948 }
946949 }
947950
948- // cout << " tval = " << tval << ", val = " << val
949- // << ", expr->getType() = " << expr->getType().getAsString() << endl;
951+ // cout << " tval = " << tval << ", val = " << val << endl;
950952}
951953
952954void ScParseExpr::parseExpr (clang::CXXThisExpr* expr, SValue& thisPtrVal)
953955{
954- using namespace std ;
955956 // cout << "parse CXXThisExpr, recval " << recval << ", modval " << modval << endl;
956957
957958 thisPtrVal = SValue (expr->getType ()); // pointer
@@ -962,8 +963,8 @@ void ScParseExpr::parseExpr(clang::CXXThisExpr* expr, SValue& thisPtrVal)
962963 // cout << " level " << level << ", thisPtrVal " << thisPtrVal << endl;
963964}
964965
965- // Create record/module object value and parse its field declarations
966- // Used for arrays of record elements
966+ // Create record/module object value and parse its field declarations,
967+ // no constructor function call. Used for arrays of record elements
967968SValue ScParseExpr::createRecValue (const clang::CXXRecordDecl* recDecl,
968969 const SValue& parent, const SValue& var,
969970 bool parseFields, size_t index)
@@ -982,7 +983,7 @@ SValue ScParseExpr::createRecValue(const clang::CXXRecordDecl* recDecl,
982983 // Record value
983984 SValue currec = SValue (QualType (recDecl->getTypeForDecl (), 0 ),
984985 bases, parent, var, index);
985-
986+
986987 // Current module in @recval required for field initialization
987988 SValue lastRecval (recval); recval = currec;
988989
@@ -1047,30 +1048,32 @@ SValue ScParseExpr::createRecordCopy(CXXConstructExpr* expr,
10471048SValue ScParseExpr::parseRecordCtor (CXXConstructExpr* expr, SValue parent,
10481049 SValue currecvar, bool analyzeRecordCtor)
10491050{
1050- // cout << "parseRecordCtor for var " << currecvar << endl;
1051+ // cout << "parseRecordCtor for currecvar " << currecvar << " parent " << parent << endl;
1052+
1053+ // Prepare constructor parameters before base constructors and
1054+ // initialization list because they can be used there,
1055+ // parameters declared in previous module
1056+ prepareCallParams (expr, modval, expr->getConstructor ());
10511057
10521058 // Base classes constructors
1059+ std::vector<SValue> bases;
10531060 for (auto init : expr->getConstructor ()->inits ()) {
10541061 if (init->isBaseInitializer ()) {
1055-
1062+ auto baseInit = removeExprCleanups (init->getInit ());
1063+ auto baseExpr = dyn_cast<CXXConstructExpr>(baseInit);
1064+ SCT_TOOL_ASSERT (baseExpr, " No base class constructor found" );
10561065 // Parse base constructor
1057- if (auto baseExpr = dyn_cast<CXXConstructExpr>(init->getInit ())) {
1058- parseRecordCtor (baseExpr, currecvar, parent, false );
1059- }
1066+ SValue bval = parseRecordCtor (baseExpr, parent, currecvar, false );
1067+ bases.push_back (bval);
10601068 }
10611069 }
10621070
10631071 // Create value for this record and put it into record variable,
10641072 // required to have variable for record in state, replaced in parseValueDecl
1065- SValue currec = createRecValue (expr->getBestDynamicClassType (),
1066- parent, currecvar, false );
1073+ SValue currec = SValue (expr->getType (), bases, parent, currecvar, 0 );
10671074 state->putValue (currecvar, currec);
10681075 // cout << "currecvar " << currecvar << ", currec " << currec << endl;
10691076
1070- // Prepare constructor parameters before initialization list because
1071- // they can be used there, parameters declared in previous module
1072- prepareCallParams (expr, modval, expr->getConstructor ());
1073-
10741077 // Current module in @recval required for field initialization
10751078 SValue lastRecval (recval); recval = currec;
10761079
@@ -1139,9 +1142,19 @@ SValue ScParseExpr::parseRecordCtor(CXXConstructExpr* expr, SValue parent,
11391142 // Restore current module before parse constructor call
11401143 recval = lastRecval;
11411144
1142- // Activate call constructor body as function, parameters already prepared
11431145 if (analyzeRecordCtor) {
1146+ // Activate call constructor body as function, parameters already prepared
11441147 prepareCallContext (expr, modval, currec, expr->getConstructor (), NO_VALUE);
1148+
1149+ } else {
1150+ // Check constructor is empty
1151+ auto ctorDecl = expr->getConstructor ();
1152+ if (auto ctorStmt = dyn_cast<CompoundStmt>(ctorDecl->getBody ())) {
1153+ if (!ctorStmt->body_empty ()) {
1154+ ScDiag::reportScDiag (ctorStmt->getBeginLoc (),
1155+ ScDiag::SYNTH_RECORD_CTOR_NONEMPTY);
1156+ }
1157+ }
11451158 }
11461159
11471160 state->fillDerivedClasses (currec);
@@ -1185,45 +1198,39 @@ void ScParseExpr::parseExpr(clang::ImplicitCastExpr *expr, SValue& rval, SValue
11851198 }
11861199 }
11871200
1188- // !!! Use getRecordFromState -- need to ensure it really required
11891201 // Get record from variable/dynamic object
1190- bool isVariable = !tval.isRecord ();
1191- if (isVariable) {
1192- SValue ttval;
1193- state->getValue (tval, ttval, false );
1194- tval = ttval;
1195- }
1202+ SValue ttval = getRecordFromState (tval, ArrayUnkwnMode::amFirstElement);
11961203
1197- if (tval .isRecord ()) {
1204+ if (ttval .isRecord ()) {
11981205 // CXX class type cast
11991206 if (!isUserDefinedClass (castType)) {
12001207 SCT_TOOL_ASSERT (false , " Derived cast type is not class" );
12011208 }
12021209
12031210 // Get base class of @tval with @castType type
1204- SValue bval = getBaseClass (tval , castType);
1205- // cout << "Base class " << bval.asString() << endl;
1211+ SValue bval = getBaseClass (ttval , castType);
1212+ // cout << " base class " << bval << " for tval " << ttval << endl;
12061213
1207- // Add variable for base record object
1208- if (isVariable) {
1214+ // Add variable for base record object, required for passing record
1215+ // as reference to base class
1216+ if (tval.isVariable ()) {
12091217 SValue bbval (castType);
12101218 state->putValue (bbval, bval);
12111219 state->setValueLevel (bbval, level+1 );
1212-
12131220 bval = bbval;
1214- // cout << "Variable to base class bval = " << bval.asString() << endl;
1221+ // cout << " variable to base class bval = " << bval << endl;
12151222 }
12161223
12171224 // Create pointer to base record object
12181225 if (isPtr || isPortIf) {
12191226 val = SValue (exprType);
12201227 state->putValue (val, bval);
12211228 state->setValueLevel (val, level+1 );
1222- // cout << "Pointer to base class variable val = " << val.asString() << endl;
1229+ // cout << " pointer to base class variable val = " << val << endl;
12231230 } else {
12241231 val = bval;
12251232 }
1226- // cout << "Return val " << val.asString() << endl;
1233+ // cout << " return val " << val << endl;
12271234
12281235 } else {
12291236 // Do nothing, it can be SC data type cast
0 commit comments