Changeset 3b0c8cb for src/ResolvExpr


Ignore:
Timestamp:
Dec 5, 2019, 5:49:23 PM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
924c5ce
Parents:
1805b1b
Message:

Implemented Keyword cast in the alternative finder to remove aliassing problems

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/AlternativeFinder.cc

    r1805b1b r3b0c8cb  
    6969                void postvisit( CastExpr * castExpr );
    7070                void postvisit( VirtualCastExpr * castExpr );
     71                void postvisit( KeywordCastExpr * castExpr );
    7172                void postvisit( UntypedMemberExpr * memberExpr );
    7273                void postvisit( MemberExpr * memberExpr );
     
    12551256        }
    12561257
     1258        void AlternativeFinder::Finder::postvisit( KeywordCastExpr * castExpr ) {
     1259                assertf( castExpr->get_result(), "Cast target should have been set in Validate." );
     1260                auto ref = dynamic_cast<ReferenceType*>(castExpr->get_result());
     1261                assert(ref);
     1262                auto inst = dynamic_cast<StructInstType*>(ref->base);
     1263                assert(inst);
     1264                auto target = inst->baseStruct;
     1265
     1266                AlternativeFinder finder( indexer, env );
     1267
     1268                auto pick_alternatives = [target, this](AltList & found, bool expect_ref) {
     1269                        for(auto & alt : found) {
     1270                                Type * expr = alt.expr->get_result();
     1271                                if(expect_ref) {
     1272                                        auto res = dynamic_cast<ReferenceType*>(expr);
     1273                                        if(!res) { continue; }
     1274                                        expr = res->base;
     1275                                }
     1276
     1277                                if(auto insttype = dynamic_cast<TypeInstType*>(expr)) {
     1278                                        auto td = alt.env.lookup(insttype->name);
     1279                                        if(!td) { continue; }
     1280                                        expr = td->type;
     1281                                }
     1282
     1283                                if(auto base = dynamic_cast<StructInstType*>(expr)) {
     1284                                        if(base->baseStruct == target) {
     1285                                                alternatives.push_back(
     1286                                                        std::move(alt)
     1287                                                );
     1288                                        }
     1289                                }
     1290                        }
     1291                };
     1292
     1293                try {
     1294                        // Attempt 1 : turn (thread&)X into (thread_desc&)X.__thrd
     1295                        // Clone is purely for memory management
     1296                        std::unique_ptr<Expression> tech1 { new UntypedMemberExpr(new NameExpr(castExpr->concrete_target.field), castExpr->arg->clone()) };
     1297
     1298                        // don't prune here, since it's guaranteed all alternatives will have the same type
     1299                        finder.findWithoutPrune( tech1.get() );
     1300                        pick_alternatives(finder.alternatives, false);
     1301
     1302                        return;
     1303                } catch(SemanticErrorException & ) {}
     1304
     1305                // Fallback : turn (thread&)X into (thread_desc&)get_thread(X)
     1306                std::unique_ptr<Expression> fallback { UntypedExpr::createDeref( new UntypedExpr(new NameExpr(castExpr->concrete_target.getter), { castExpr->arg->clone() })) };
     1307                // don't prune here, since it's guaranteed all alternatives will have the same type
     1308                finder.findWithoutPrune( fallback.get() );
     1309
     1310                pick_alternatives(finder.alternatives, true);
     1311
     1312                // Whatever happens here, we have no more fallbacks
     1313        }
     1314
    12571315        namespace {
    12581316                /// Gets name from untyped member expression (member must be NameExpr)
Note: See TracChangeset for help on using the changeset viewer.