source: src/Validate/FixQualifiedTypes.cpp@ 34ed17b

ADT ast-experimental
Last change on this file since 34ed17b was 5408b59, checked in by JiadaL <j82liang@…>, 3 years ago

Remove var in QualifiedNameExpr

  • Property mode set to 100644
File size: 4.0 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// FixQualifiedTypes.cpp -- Replace the qualified type with a direct type.
8//
9// Author : Andrew Beach
10// Created On : Thr Apr 21 11:13:00 2022
11// Last Modified By : Andrew Beach
12// Last Modified On : Tue Sep 20 16:15:00 2022
13// Update Count : 1
14//
15
16#include "Validate/FixQualifiedTypes.hpp"
17
18#include "AST/Pass.hpp"
19#include "AST/TranslationUnit.hpp"
20#include "Validate/NoIdSymbolTable.hpp"
21#include "SymTab/Mangler.h" // for Mangler
22#include "AST/LinkageSpec.hpp" // for Linkage
23
24namespace Validate {
25
26namespace {
27
28struct FixQualifiedTypesCore :
29 public WithNoIdSymbolTable,
30 public ast::WithCodeLocation {
31 ast::Type const * postvisit( ast::QualifiedType const * type ) {
32 assert( location );
33
34 ast::ptr<ast::Type> const & parent = type->parent;
35 ast::ptr<ast::Type> const & child = type->child;
36 if ( parent.as<ast::GlobalScopeType>() ) {
37 // .T => lookup T at global scope.
38 if ( auto inst = child.as<ast::TypeInstType>() ) {
39 auto td = symtab.globalLookupType( inst->name );
40 if ( !td ) {
41 SemanticError( *location, toString("Use of undefined global type ", inst->name) );
42 }
43 auto base = td->base;
44 assert( base );
45 ast::Type * ret = ast::deepCopy( base );
46 ret->qualifiers = type->qualifiers;
47 return ret;
48 } else {
49 // .T => T is not a type name.
50 assertf( false, "unhandled global qualified child type: %s", toCString(child) );
51 }
52 } else {
53 // S.T => S must be an aggregate type, find the declaration for T in S.
54 ast::AggregateDecl const * aggr = nullptr;
55 ast::BaseInstType const * instp = nullptr;
56 if ( auto inst = parent.as<ast::StructInstType>() ) {
57 aggr = inst->base;
58 instp = inst;
59 } else if ( auto inst = parent.as<ast::UnionInstType>() ) {
60 aggr = inst->base;
61 instp = inst;
62 } else {
63 SemanticError( *location, toString("Qualified type requires an aggregate on the left, but has: ", parent) );
64 }
65 // TODO: Need to handle forward declarations.
66 assert( aggr );
67 for ( ast::ptr<ast::Decl> const & member : aggr->members ) {
68 if ( auto inst = child.as<ast::TypeInstType>() ) {
69 if ( auto decl = member.as<ast::NamedTypeDecl>() ) {
70 if ( decl->name == inst->name ) {
71 assert( decl->base );
72 ast::Type * ret = ast::deepCopy( decl->base );
73 ret->qualifiers = type->qualifiers;
74 ast::TypeSubstitution sub( aggr->params, instp->params );
75 auto result = sub.apply(ret);
76 return result.node.release();
77 }
78 }
79 } else {
80 // S.T - S is not an aggregate => error.
81 assertf( false, "unhandled qualified child type: %s", toCString(type) );
82 }
83 }
84 // failed to find a satisfying definition of type
85 SemanticError( *location, toString("Undefined type in qualified type: ", type) );
86 }
87 }
88
89 ast::Expr const * postvisit( ast::QualifiedNameExpr const * t) {
90 assert( location );
91 if ( t->type_decl ) {
92 auto enumName = t->type_decl->name;
93 const ast::EnumDecl * enumDecl = symtab.lookupEnum( enumName );
94 for ( ast::ptr<ast::Decl> const & member : enumDecl->members ) {
95 if ( auto memberAsObj = member.as<ast::ObjectDecl>() ) {
96 if ( memberAsObj->name == t->name ) {
97 return new ast::VariableExpr( t->location, memberAsObj );
98 }
99 } else {
100 assertf( false, "unhandled qualified child type");
101 }
102 }
103
104 auto var = new ast::ObjectDecl( t->location, t->name,
105 new ast::EnumInstType(enumDecl, ast::CV::Const), nullptr, {}, ast::Linkage::Cforall );
106 var->mangleName = Mangle::mangle( var );
107 return new ast::VariableExpr( t->location, var );
108 }
109
110 return t;
111 }
112
113};
114
115} // namespace
116
117void fixQualifiedTypes( ast::TranslationUnit & translationUnit ) {
118 ast::Pass<FixQualifiedTypesCore>::run( translationUnit );
119}
120
121} // namespace Validate
122
123// Local Variables: //
124// tab-width: 4 //
125// mode: c++ //
126// compile-command: "make install" //
127// End: //
Note: See TracBrowser for help on using the repository browser.