@@ -443,10 +443,10 @@ predicate hasTranslatedSyntheticTemporaryObject(Expr expr) {
443
443
* necessary for automatic local variables, or for static local variables with dynamic
444
444
* initialization.
445
445
*/
446
- private predicate translateDeclarationEntry ( DeclarationEntry entry ) {
446
+ private predicate translateDeclarationEntry ( IRDeclarationEntry entry ) {
447
447
exists ( DeclStmt declStmt , LocalVariable var |
448
448
translateStmt ( declStmt ) and
449
- declStmt . getADeclarationEntry ( ) = entry and
449
+ declStmt = entry . getStmt ( ) and
450
450
// Only declarations of local variables need to be translated to IR.
451
451
var = entry .getDeclaration ( ) and
452
452
(
@@ -458,6 +458,102 @@ private predicate translateDeclarationEntry(DeclarationEntry entry) {
458
458
)
459
459
}
460
460
461
+ private module IRDeclarationEntries {
462
+ private newtype TIRDeclarationEntry =
463
+ TPresentDeclarationEntry ( DeclarationEntry entry ) or
464
+ TMissingDeclarationEntry ( DeclStmt stmt , Declaration d , int index ) {
465
+ not exists ( stmt .getDeclarationEntry ( index ) ) and
466
+ stmt .getDeclaration ( index ) = d
467
+ }
468
+
469
+ /**
470
+ * An entity that represents a declaration entry in the database.
471
+ *
472
+ * This class exists to work around the fact that `DeclStmt`s in some cases
473
+ * do not have `DeclarationEntry`s. Currently, this is the case for:
474
+ * - `DeclStmt`s in template instantiations.
475
+ * - `DeclStmt`s that are generated by the desugaring of range-based for-loops.
476
+ *
477
+ * So instead, the IR works with `IRDeclarationEntry`s that synthesize missing
478
+ * `DeclarationEntry`s when there is no result for `DeclStmt::getDeclarationEntry`.
479
+ */
480
+ abstract class IRDeclarationEntry extends TIRDeclarationEntry {
481
+ /** Gets a string representation of this `IRDeclarationEntry`. */
482
+ abstract string toString ( ) ;
483
+
484
+ /** Gets the `DeclStmt` that this `IRDeclarationEntry` belongs to. */
485
+ abstract DeclStmt getStmt ( ) ;
486
+
487
+ /** Gets the `Declaration` declared by this `IRDeclarationEntry`. */
488
+ abstract Declaration getDeclaration ( ) ;
489
+
490
+ /** Gets the AST represented by this `IRDeclarationEntry`. */
491
+ abstract Locatable getAst ( ) ;
492
+
493
+ /**
494
+ * Holds if this `IRDeclarationEntry` is the `index`'th entry
495
+ * declared by the enclosing `DeclStmt`.
496
+ */
497
+ abstract predicate hasIndex ( int index ) ;
498
+ }
499
+
500
+ /** A `IRDeclarationEntry` for an existing `DeclarationEntry`. */
501
+ private class PresentDeclarationEntry extends IRDeclarationEntry , TPresentDeclarationEntry {
502
+ DeclarationEntry entry ;
503
+
504
+ PresentDeclarationEntry ( ) { this = TPresentDeclarationEntry ( entry ) }
505
+
506
+ override string toString ( ) { result = entry .toString ( ) }
507
+
508
+ override DeclStmt getStmt ( ) { result .getADeclarationEntry ( ) = entry }
509
+
510
+ override Declaration getDeclaration ( ) { result = entry .getDeclaration ( ) }
511
+
512
+ override Locatable getAst ( ) { result = entry }
513
+
514
+ override predicate hasIndex ( int index ) { this .getStmt ( ) .getDeclarationEntry ( index ) = entry }
515
+ }
516
+
517
+ /**
518
+ * A synthesized `DeclarationEntry` that is created when a `DeclStmt` is missing a
519
+ * result for `DeclStmt::getDeclarationEntry`
520
+ */
521
+ private class MissingDeclarationEntry extends IRDeclarationEntry , TMissingDeclarationEntry {
522
+ DeclStmt stmt ;
523
+ Declaration d ;
524
+ int index ;
525
+
526
+ MissingDeclarationEntry ( ) { this = TMissingDeclarationEntry ( stmt , d , index ) }
527
+
528
+ override string toString ( ) { result = "missing declaration of " + d .getName ( ) }
529
+
530
+ override DeclStmt getStmt ( ) { result = stmt }
531
+
532
+ override Declaration getDeclaration ( ) { result = d }
533
+
534
+ override Locatable getAst ( ) { result = stmt }
535
+
536
+ override predicate hasIndex ( int idx ) { idx = index }
537
+ }
538
+
539
+ /** A `IRDeclarationEntry` that represents an entry for a `Variable`. */
540
+ class IRVariableDeclarationEntry instanceof IRDeclarationEntry {
541
+ Variable v ;
542
+
543
+ IRVariableDeclarationEntry ( ) { super .getDeclaration ( ) = v }
544
+
545
+ Variable getDeclaration ( ) { result = v }
546
+
547
+ string toString ( ) { result = super .toString ( ) }
548
+
549
+ Locatable getAst ( ) { result = super .getAst ( ) }
550
+
551
+ DeclStmt getStmt ( ) { result = super .getStmt ( ) }
552
+ }
553
+ }
554
+
555
+ import IRDeclarationEntries
556
+
461
557
newtype TTranslatedElement =
462
558
// An expression that is not being consumed as a condition
463
559
TTranslatedValueExpr ( Expr expr ) {
@@ -613,23 +709,13 @@ newtype TTranslatedElement =
613
709
)
614
710
} or
615
711
// A local declaration
616
- TTranslatedDeclarationEntry ( DeclarationEntry entry ) { translateDeclarationEntry ( entry ) } or
712
+ TTranslatedDeclarationEntry ( IRDeclarationEntry entry ) { translateDeclarationEntry ( entry ) } or
617
713
// The dynamic initialization of a static local variable. This is a separate object from the
618
714
// declaration entry.
619
- TTranslatedStaticLocalVariableInitialization ( DeclarationEntry entry ) {
715
+ TTranslatedStaticLocalVariableInitialization ( IRDeclarationEntry entry ) {
620
716
translateDeclarationEntry ( entry ) and
621
717
entry .getDeclaration ( ) instanceof StaticLocalVariable
622
718
} or
623
- // A compiler-generated variable to implement a range-based for loop. These don't have a
624
- // `DeclarationEntry` in the database, so we have to go by the `Variable` itself.
625
- TTranslatedRangeBasedForVariableDeclaration ( RangeBasedForStmt forStmt , LocalVariable var ) {
626
- translateStmt ( forStmt ) and
627
- (
628
- var = forStmt .getRangeVariable ( ) or
629
- var = forStmt .getBeginEndDeclaration ( ) .getADeclaration ( ) or
630
- var = forStmt .getVariable ( )
631
- )
632
- } or
633
719
// An allocator call in a `new` or `new[]` expression
634
720
TTranslatedAllocatorCall ( NewOrNewArrayExpr newExpr ) { not ignoreExpr ( newExpr ) } or
635
721
// An allocation size for a `new` or `new[]` expression
0 commit comments