Changeset c6b4432 for src/SymTab
- Timestamp:
- Nov 8, 2023, 2:01:11 PM (6 months ago)
- Branches:
- master
- Children:
- 3e4bf0d, f5ec35a
- Parents:
- 790d835
- Location:
- src/SymTab
- Files:
-
- 8 deleted
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Demangle.cc
r790d835 rc6b4432 21 21 #include "CodeGen/GenType.h" 22 22 #include "CodeGen/OperatorTable.h" 23 #include "Common/PassVisitor.h"24 23 #include "Common/utility.h" // isPrefix 25 24 #include "Mangler.h" 26 #include "SynTree/Type.h"27 #include "SynTree/Declaration.h"28 25 29 26 #define DEBUG … … 33 30 #define PRINT(x) {} 34 31 #endif 35 36 namespace SymTab {37 namespace Mangler {38 namespace {39 struct StringView {40 private:41 std::string str;42 size_t idx = 0;43 // typedef Type * (StringView::*parser)(Type::Qualifiers);44 typedef std::function<Type * (Type::Qualifiers)> parser;45 std::vector<std::pair<std::string, parser>> parsers;46 public:47 StringView(const std::string & str);48 49 bool done() const { return idx >= str.size(); }50 char cur() const { assert(! done()); return str[idx]; }51 52 bool expect(char ch) { return str[idx++] == ch; }53 void next(size_t inc = 1) { idx += inc; }54 55 /// determines if `pref` is a prefix of `str`56 bool isPrefix(const std::string & pref);57 bool extractNumber(size_t & out);58 bool extractName(std::string & out);59 bool stripMangleName(std::string & name);60 61 Type * parseFunction(Type::Qualifiers tq);62 Type * parseTuple(Type::Qualifiers tq);63 Type * parseVoid(Type::Qualifiers tq);64 Type * parsePointer(Type::Qualifiers tq);65 Type * parseArray(Type::Qualifiers tq);66 Type * parseStruct(Type::Qualifiers tq);67 Type * parseUnion(Type::Qualifiers tq);68 Type * parseEnum(Type::Qualifiers tq);69 Type * parseType(Type::Qualifiers tq);70 71 Type * parseType();72 bool parse(std::string & name, Type *& type);73 };74 75 StringView::StringView(const std::string & str) : str(str) {76 // basic types77 for (size_t k = 0; k < BasicType::NUMBER_OF_BASIC_TYPES; ++k) {78 parsers.emplace_back(Encoding::basicTypes[k], [k](Type::Qualifiers tq) {79 PRINT( std::cerr << "basic type: " << k << std::endl; )80 return new BasicType(tq, (BasicType::Kind)k);81 });82 }83 // type variable types84 for (size_t k = 0; k < TypeDecl::NUMBER_OF_KINDS; ++k) {85 static const std::string typeVariableNames[] = { "DT", "DST", "OT", "FT", "TT", "ALT", };86 static_assert(87 sizeof(typeVariableNames)/sizeof(typeVariableNames[0]) == TypeDecl::NUMBER_OF_KINDS,88 "Each type variable kind should have a demangle name prefix"89 );90 parsers.emplace_back(Encoding::typeVariables[k], [k, this](Type::Qualifiers tq) -> TypeInstType * {91 PRINT( std::cerr << "type variable type: " << k << std::endl; )92 size_t N;93 if (! extractNumber(N)) return nullptr;94 return new TypeInstType(tq, toString(typeVariableNames[k], N), (TypeDecl::Kind)k != TypeDecl::Ftype);95 });96 }97 // everything else98 parsers.emplace_back(Encoding::void_t, [this](Type::Qualifiers tq) { return parseVoid(tq); });99 parsers.emplace_back(Encoding::function, [this](Type::Qualifiers tq) { return parseFunction(tq); });100 parsers.emplace_back(Encoding::pointer, [this](Type::Qualifiers tq) { return parsePointer(tq); });101 parsers.emplace_back(Encoding::array, [this](Type::Qualifiers tq) { return parseArray(tq); });102 parsers.emplace_back(Encoding::tuple, [this](Type::Qualifiers tq) { return parseTuple(tq); });103 parsers.emplace_back(Encoding::struct_t, [this](Type::Qualifiers tq) { return parseStruct(tq); });104 parsers.emplace_back(Encoding::union_t, [this](Type::Qualifiers tq) { return parseUnion(tq); });105 parsers.emplace_back(Encoding::enum_t, [this](Type::Qualifiers tq) { return parseEnum(tq); });106 parsers.emplace_back(Encoding::type, [this](Type::Qualifiers tq) { return parseType(tq); });107 parsers.emplace_back(Encoding::zero, [](Type::Qualifiers tq) { return new ZeroType(tq); });108 parsers.emplace_back(Encoding::one, [](Type::Qualifiers tq) { return new OneType(tq); });109 }110 111 bool StringView::extractNumber(size_t & out) {112 std::stringstream numss;113 if (idx >= str.size()) return false;114 while (isdigit(str[idx])) {115 numss << str[idx];116 ++idx;117 if (idx == str.size()) break;118 }119 if (! (numss >> out)) return false;120 PRINT( std::cerr << "extractNumber success: " << out << std::endl; )121 return true;122 }123 124 bool StringView::extractName(std::string & out) {125 size_t len;126 if (! extractNumber(len)) return false;127 if (idx+len > str.size()) return false;128 out = str.substr(idx, len);129 idx += len;130 PRINT( std::cerr << "extractName success: " << out << std::endl; )131 return true;132 }133 134 bool StringView::isPrefix(const std::string & pref) {135 // if ( pref.size() > str.size()-idx ) return false;136 // auto its = std::mismatch( pref.begin(), pref.end(), std::next(str.begin(), idx) );137 // if (its.first == pref.end()) {138 // idx += pref.size();139 // return true;140 // }141 142 // This update is untested because there are no tests for this code.143 if ( ::isPrefix( str, pref, idx ) ) {144 idx += pref.size();145 return true;146 }147 return false;148 }149 150 // strips __NAME__cfa__TYPE_N, where N is [0-9]+: returns str is a match is found, returns empty string otherwise151 bool StringView::stripMangleName(std::string & name) {152 PRINT( std::cerr << "====== " << str.size() << " " << str << std::endl; )153 if (str.size() < 2+Encoding::manglePrefix.size()) return false; // +2 for at least _1 suffix154 if ( ! isPrefix(Encoding::manglePrefix) || ! isdigit(str.back() ) ) return false;155 156 // get name157 if (! extractName(name)) return false;158 159 // find bounds for type160 PRINT( std::cerr << idx << " " << str.size() << std::endl; )161 PRINT( std::cerr << "[");162 while (isdigit(str.back())) {163 PRINT(std::cerr << ".");164 str.pop_back();165 if (str.size() <= idx) return false;166 }167 PRINT( std::cerr << "]" << std::endl );168 if (str.back() != '_') return false;169 str.pop_back();170 PRINT( std::cerr << str.size() << " " << name << " " << str.substr(idx) << std::endl; )171 return str.size() > idx;172 }173 174 Type * StringView::parseFunction(Type::Qualifiers tq) {175 PRINT( std::cerr << "function..." << std::endl; )176 if (done()) return nullptr;177 FunctionType * ftype = new FunctionType( tq, false );178 std::unique_ptr<Type> manager(ftype);179 Type * retVal = parseType();180 if (! retVal) return nullptr;181 PRINT( std::cerr << "with return type: " << retVal << std::endl; )182 ftype->returnVals.push_back(ObjectDecl::newObject("", retVal, nullptr));183 if (done() || ! expect('_')) return nullptr;184 while (! done()) {185 PRINT( std::cerr << "got ch: " << cur() << std::endl; )186 if (cur() == '_') return manager.release();187 Type * param = parseType();188 if (! param) return nullptr;189 PRINT( std::cerr << "with parameter : " << param << std::endl; )190 ftype->parameters.push_back(ObjectDecl::newObject("", param, nullptr));191 }192 return nullptr;193 }194 195 Type * StringView::parseTuple(Type::Qualifiers tq) {196 PRINT( std::cerr << "tuple..." << std::endl; )197 std::list< Type * > types;198 size_t ncomponents;199 if (! extractNumber(ncomponents)) return nullptr;200 for (size_t i = 0; i < ncomponents; ++i) {201 // TODO: delete all on return202 if (done()) return nullptr;203 PRINT( std::cerr << "got ch: " << cur() << std::endl; )204 Type * t = parseType();205 if (! t) return nullptr;206 PRINT( std::cerr << "with type : " << t << std::endl; )207 types.push_back(t);208 }209 return new TupleType( tq, types );210 }211 212 Type * StringView::parseVoid(Type::Qualifiers tq) {213 return new VoidType( tq );214 }215 216 Type * StringView::parsePointer(Type::Qualifiers tq) {217 PRINT( std::cerr << "pointer..." << std::endl; )218 Type * t = parseType();219 if (! t) return nullptr;220 return new PointerType( tq, t );221 }222 223 Type * StringView::parseArray(Type::Qualifiers tq) {224 PRINT( std::cerr << "array..." << std::endl; )225 size_t length;226 if (! extractNumber(length)) return nullptr;227 Type * t = parseType();228 if (! t) return nullptr;229 return new ArrayType( tq, t, new ConstantExpr( Constant::from_ulong(length) ), false, false );230 }231 232 Type * StringView::parseStruct(Type::Qualifiers tq) {233 PRINT( std::cerr << "struct..." << std::endl; )234 std::string name;235 if (! extractName(name)) return nullptr;236 return new StructInstType(tq, name);237 }238 239 Type * StringView::parseUnion(Type::Qualifiers tq) {240 PRINT( std::cerr << "union..." << std::endl; )241 std::string name;242 if (! extractName(name)) return nullptr;243 return new UnionInstType(tq, name);244 }245 246 Type * StringView::parseEnum(Type::Qualifiers tq) {247 PRINT( std::cerr << "enum..." << std::endl; )248 std::string name;249 if (! extractName(name)) return nullptr;250 return new EnumInstType(tq, name);251 }252 253 Type * StringView::parseType(Type::Qualifiers tq) {254 PRINT( std::cerr << "type..." << std::endl; )255 std::string name;256 if (! extractName(name)) return nullptr;257 PRINT( std::cerr << "typename..." << name << std::endl; )258 return new TypeInstType(tq, name, false);259 }260 261 Type * StringView::parseType() {262 if (done()) return nullptr;263 264 std::list<TypeDecl *> forall;265 if (isPrefix(Encoding::forall)) {266 PRINT( std::cerr << "polymorphic with..." << std::endl; )267 size_t dcount, fcount, vcount, acount;268 if (! extractNumber(dcount)) return nullptr;269 PRINT( std::cerr << dcount << " dtypes" << std::endl; )270 if (! expect('_')) return nullptr;271 if (! extractNumber(fcount)) return nullptr;272 PRINT( std::cerr << fcount << " ftypes" << std::endl; )273 if (! expect('_')) return nullptr;274 if (! extractNumber(vcount)) return nullptr;275 PRINT( std::cerr << vcount << " ttypes" << std::endl; )276 if (! expect('_')) return nullptr;277 if (! extractNumber(acount)) return nullptr;278 PRINT( std::cerr << acount << " assertions" << std::endl; )279 if (! expect('_')) return nullptr;280 for (size_t i = 0; i < acount; ++i) {281 // TODO: need to recursively parse assertions, but for now just return nullptr so that282 // demangler does not crash if there are assertions283 return nullptr;284 }285 if (! expect('_')) return nullptr;286 }287 288 // qualifiers289 Type::Qualifiers tq;290 while (true) {291 auto qual = std::find_if(Encoding::qualifiers.begin(), Encoding::qualifiers.end(), [this](decltype(Encoding::qualifiers)::value_type val) {292 return isPrefix(val.second);293 });294 if (qual == Encoding::qualifiers.end()) break;295 tq |= qual->first;296 }297 298 // find the correct type parser and use it299 auto iter = std::find_if(parsers.begin(), parsers.end(), [this](std::pair<std::string, parser> & p) {300 return isPrefix(p.first);301 });302 assertf(iter != parsers.end(), "Unhandled type letter: %c at index: %zd", cur(), idx);303 Type * ret = iter->second(tq);304 if (! ret) return nullptr;305 ret->forall = std::move(forall);306 return ret;307 }308 309 bool StringView::parse(std::string & name, Type *& type) {310 if (! stripMangleName(name)) return false;311 PRINT( std::cerr << "stripped name: " << name << std::endl; )312 Type * t = parseType();313 if (! t) return false;314 type = t;315 return true;316 }317 318 std::string demangle(const std::string & mangleName) {319 SymTab::Mangler::StringView view(mangleName);320 std::string name;321 Type * type = nullptr;322 if (! view.parse(name, type)) return mangleName;323 auto info = CodeGen::operatorLookupByOutput(name);324 if (info) name = info->inputName;325 std::unique_ptr<Type> manager(type);326 return CodeGen::genType(type, name);327 }328 } // namespace329 } // namespace Mangler330 } // namespace SymTab331 32 332 33 namespace Mangle { … … 550 251 if (done()) return nullptr; 551 252 552 std::list<TypeDecl *> forall;553 253 if (isPrefix(Encoding::forall)) { 554 254 PRINT( std::cerr << "polymorphic with..." << std::endl; ) -
src/SymTab/FixFunction.cc
r790d835 rc6b4432 22 22 #include "AST/Type.hpp" 23 23 #include "Common/utility.h" // for copy 24 #include "SynTree/Declaration.h" // for FunctionDecl, ObjectDecl, Declarati...25 #include "SynTree/Expression.h" // for Expression26 #include "SynTree/Type.h" // for ArrayType, PointerType, Type, Basic...27 24 28 25 namespace SymTab { 29 class FixFunction_old : public WithShortCircuiting {30 typedef Mutator Parent;31 public:32 FixFunction_old() : isVoid( false ) {}33 34 void premutate(FunctionDecl *functionDecl);35 DeclarationWithType* postmutate(FunctionDecl *functionDecl);36 37 Type * postmutate(ArrayType * arrayType);38 39 void premutate(ArrayType * arrayType);40 void premutate(VoidType * voidType);41 void premutate(BasicType * basicType);42 void premutate(PointerType * pointerType);43 void premutate(StructInstType * aggregateUseType);44 void premutate(UnionInstType * aggregateUseType);45 void premutate(EnumInstType * aggregateUseType);46 void premutate(TraitInstType * aggregateUseType);47 void premutate(TypeInstType * aggregateUseType);48 void premutate(TupleType * tupleType);49 void premutate(VarArgsType * varArgsType);50 void premutate(ZeroType * zeroType);51 void premutate(OneType * oneType);52 53 bool isVoid;54 };55 56 DeclarationWithType * FixFunction_old::postmutate(FunctionDecl *functionDecl) {57 // can't delete function type because it may contain assertions, so transfer ownership to new object58 ObjectDecl *pointer = new ObjectDecl( functionDecl->name, functionDecl->get_storageClasses(), functionDecl->linkage, nullptr, new PointerType( Type::Qualifiers(), functionDecl->type ), nullptr, functionDecl->attributes );59 pointer->location = functionDecl->location;60 functionDecl->attributes.clear();61 functionDecl->type = nullptr;62 delete functionDecl;63 return pointer;64 }65 66 // xxx - this passes on void[], e.g.67 // void foo(void [10]);68 // does not cause an error69 70 Type * FixFunction_old::postmutate(ArrayType *arrayType) {71 // need to recursively mutate the base type in order for multi-dimensional arrays to work.72 PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->base, arrayType->dimension, arrayType->isVarLen, arrayType->isStatic );73 pointerType->location = arrayType->location;74 arrayType->base = nullptr;75 arrayType->dimension = nullptr;76 delete arrayType;77 return pointerType;78 }79 80 void FixFunction_old::premutate(VoidType *) {81 isVoid = true;82 }83 84 void FixFunction_old::premutate(FunctionDecl *) { visit_children = false; }85 void FixFunction_old::premutate(ArrayType *) { visit_children = false; }86 void FixFunction_old::premutate(BasicType *) { visit_children = false; }87 void FixFunction_old::premutate(PointerType *) { visit_children = false; }88 void FixFunction_old::premutate(StructInstType *) { visit_children = false; }89 void FixFunction_old::premutate(UnionInstType *) { visit_children = false; }90 void FixFunction_old::premutate(EnumInstType *) { visit_children = false; }91 void FixFunction_old::premutate(TraitInstType *) { visit_children = false; }92 void FixFunction_old::premutate(TypeInstType *) { visit_children = false; }93 void FixFunction_old::premutate(TupleType *) { visit_children = false; }94 void FixFunction_old::premutate(VarArgsType *) { visit_children = false; }95 void FixFunction_old::premutate(ZeroType *) { visit_children = false; }96 void FixFunction_old::premutate(OneType *) { visit_children = false; }97 98 bool fixFunction( DeclarationWithType *& dwt ) {99 PassVisitor<FixFunction_old> fixer;100 dwt = dwt->acceptMutator( fixer );101 return fixer.pass.isVoid;102 }103 26 104 27 namespace { -
src/SymTab/FixFunction.h
r790d835 rc6b4432 16 16 #pragma once 17 17 18 #include "Common/PassVisitor.h" // for PassVisitor19 #include "SynTree/SynTree.h" // for Types20 21 18 namespace ast { 22 19 class DeclWithType; … … 25 22 26 23 namespace SymTab { 27 /// Replaces function and array types by equivalent pointer types. Returns true if type is28 /// void29 bool fixFunction( DeclarationWithType *& );30 31 24 /// Returns declaration with function and array types replaced by equivalent pointer types. 32 25 /// Sets isVoid to true if type is void -
src/SymTab/Mangler.cc
r790d835 rc6b4432 24 24 #include "AST/Pass.hpp" 25 25 #include "CodeGen/OperatorTable.h" // for OperatorInfo, operatorLookup 26 #include "Common/PassVisitor.h"27 26 #include "Common/ToString.hpp" // for toCString 28 27 #include "Common/SemanticError.h" // for SemanticError 29 #include "ResolvExpr/TypeEnvironment.h" // for TypeEnvironment30 #include "SynTree/LinkageSpec.h" // for Spec, isOverridable, AutoGen, Int...31 #include "SynTree/Declaration.h" // for TypeDecl, DeclarationWithType32 #include "SynTree/Expression.h" // for TypeExpr, Expression, operator<<33 #include "SynTree/Type.h" // for Type, ReferenceToType, Type::Fora...34 35 namespace SymTab {36 namespace Mangler {37 namespace {38 /// Mangles names to a unique C identifier39 struct Mangler_old : public WithShortCircuiting, public WithVisitorRef<Mangler_old>, public WithGuards {40 Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams );41 Mangler_old( const Mangler_old & ) = delete;42 43 void previsit( const BaseSyntaxNode * ) { visit_children = false; }44 45 void postvisit( const ObjectDecl * declaration );46 void postvisit( const FunctionDecl * declaration );47 void postvisit( const TypeDecl * declaration );48 49 void postvisit( const VoidType * voidType );50 void postvisit( const BasicType * basicType );51 void postvisit( const PointerType * pointerType );52 void postvisit( const ArrayType * arrayType );53 void postvisit( const ReferenceType * refType );54 void postvisit( const FunctionType * functionType );55 void postvisit( const StructInstType * aggregateUseType );56 void postvisit( const UnionInstType * aggregateUseType );57 void postvisit( const EnumInstType * aggregateUseType );58 void postvisit( const TypeInstType * aggregateUseType );59 void postvisit( const TraitInstType * inst );60 void postvisit( const TupleType * tupleType );61 void postvisit( const VarArgsType * varArgsType );62 void postvisit( const ZeroType * zeroType );63 void postvisit( const OneType * oneType );64 void postvisit( const QualifiedType * qualType );65 66 std::string get_mangleName() { return mangleName; }67 private:68 std::string mangleName; ///< Mangled name being constructed69 typedef std::map< std::string, std::pair< int, int > > VarMapType;70 VarMapType varNums; ///< Map of type variables to indices71 int nextVarNum; ///< Next type variable index72 bool isTopLevel; ///< Is the Mangler at the top level73 bool mangleOverridable; ///< Specially mangle overridable built-in methods74 bool typeMode; ///< Produce a unique mangled name for a type75 bool mangleGenericParams; ///< Include generic parameters in name mangling if true76 bool inFunctionType = false; ///< Include type qualifiers if false.77 bool inQualifiedType = false; ///< Add start/end delimiters around qualified type78 79 public:80 Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams,81 int nextVarNum, const VarMapType& varNums );82 83 private:84 void mangleDecl( const DeclarationWithType * declaration );85 void mangleRef( const ReferenceToType * refType, std::string prefix );86 87 void printQualifiers( const Type *type );88 }; // Mangler_old89 } // namespace90 91 std::string mangle( const BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) {92 PassVisitor<Mangler_old> mangler( mangleOverridable, typeMode, mangleGenericParams );93 maybeAccept( decl, mangler );94 return mangler.pass.get_mangleName();95 }96 97 std::string mangleType( const Type * ty ) {98 PassVisitor<Mangler_old> mangler( false, true, true );99 maybeAccept( ty, mangler );100 return mangler.pass.get_mangleName();101 }102 103 std::string mangleConcrete( const Type * ty ) {104 PassVisitor<Mangler_old> mangler( false, false, false );105 maybeAccept( ty, mangler );106 return mangler.pass.get_mangleName();107 }108 109 namespace {110 Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams )111 : nextVarNum( 0 ), isTopLevel( true ),112 mangleOverridable( mangleOverridable ), typeMode( typeMode ),113 mangleGenericParams( mangleGenericParams ) {}114 115 Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams,116 int nextVarNum, const VarMapType& varNums )117 : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ),118 mangleOverridable( mangleOverridable ), typeMode( typeMode ),119 mangleGenericParams( mangleGenericParams ) {}120 121 void Mangler_old::mangleDecl( const DeclarationWithType * declaration ) {122 bool wasTopLevel = isTopLevel;123 if ( isTopLevel ) {124 varNums.clear();125 nextVarNum = 0;126 isTopLevel = false;127 } // if128 mangleName += Encoding::manglePrefix;129 const CodeGen::OperatorInfo * opInfo = CodeGen::operatorLookup( declaration->get_name() );130 if ( opInfo ) {131 mangleName += std::to_string( opInfo->outputName.size() ) + opInfo->outputName;132 } else {133 mangleName += std::to_string( declaration->name.size() ) + declaration->name;134 } // if135 maybeAccept( declaration->get_type(), *visitor );136 if ( mangleOverridable && LinkageSpec::isOverridable( declaration->get_linkage() ) ) {137 // want to be able to override autogenerated and intrinsic routines,138 // so they need a different name mangling139 if ( declaration->get_linkage() == LinkageSpec::AutoGen ) {140 mangleName += Encoding::autogen;141 } else if ( declaration->get_linkage() == LinkageSpec::Intrinsic ) {142 mangleName += Encoding::intrinsic;143 } else {144 // if we add another kind of overridable function, this has to change145 assert( false && "unknown overrideable linkage" );146 } // if147 }148 isTopLevel = wasTopLevel;149 }150 151 void Mangler_old::postvisit( const ObjectDecl * declaration ) {152 mangleDecl( declaration );153 }154 155 void Mangler_old::postvisit( const FunctionDecl * declaration ) {156 mangleDecl( declaration );157 }158 159 void Mangler_old::postvisit( const VoidType * voidType ) {160 printQualifiers( voidType );161 mangleName += Encoding::void_t;162 }163 164 void Mangler_old::postvisit( const BasicType * basicType ) {165 printQualifiers( basicType );166 assertf( basicType->kind < BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->kind );167 mangleName += Encoding::basicTypes[ basicType->kind ];168 }169 170 void Mangler_old::postvisit( const PointerType * pointerType ) {171 printQualifiers( pointerType );172 // mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers173 if ( ! dynamic_cast<FunctionType *>( pointerType->base ) ) mangleName += Encoding::pointer;174 maybeAccept( pointerType->base, *visitor );175 }176 177 void Mangler_old::postvisit( const ArrayType * arrayType ) {178 // TODO: encode dimension179 printQualifiers( arrayType );180 mangleName += Encoding::array + "0";181 maybeAccept( arrayType->base, *visitor );182 }183 184 void Mangler_old::postvisit( const ReferenceType * refType ) {185 // don't print prefix (e.g. 'R') for reference types so that references and non-references do not overload.186 // Further, do not print the qualifiers for a reference type (but do run printQualifers because of TypeDecls, etc.),187 // by pretending every reference type is a function parameter.188 GuardValue( inFunctionType );189 inFunctionType = true;190 printQualifiers( refType );191 maybeAccept( refType->base, *visitor );192 }193 194 namespace {195 inline std::list< Type* > getTypes( const std::list< DeclarationWithType* > decls ) {196 std::list< Type* > ret;197 std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),198 std::mem_fun( &DeclarationWithType::get_type ) );199 return ret;200 }201 }202 203 void Mangler_old::postvisit( const FunctionType * functionType ) {204 printQualifiers( functionType );205 mangleName += Encoding::function;206 // turn on inFunctionType so that printQualifiers does not print most qualifiers for function parameters,207 // since qualifiers on outermost parameter type do not differentiate function types, e.g.,208 // void (*)(const int) and void (*)(int) are the same type, but void (*)(const int *) and void (*)(int *) are different209 GuardValue( inFunctionType );210 inFunctionType = true;211 std::list< Type* > returnTypes = getTypes( functionType->returnVals );212 if (returnTypes.empty()) mangleName += Encoding::void_t;213 else acceptAll( returnTypes, *visitor );214 mangleName += "_";215 std::list< Type* > paramTypes = getTypes( functionType->parameters );216 acceptAll( paramTypes, *visitor );217 mangleName += "_";218 }219 220 void Mangler_old::mangleRef( const ReferenceToType * refType, std::string prefix ) {221 printQualifiers( refType );222 223 mangleName += prefix + std::to_string( refType->name.length() ) + refType->name;224 225 if ( mangleGenericParams ) {226 const std::list< Expression* > & params = refType->parameters;227 if ( ! params.empty() ) {228 mangleName += "_";229 for ( const Expression * param : params ) {230 const TypeExpr * paramType = dynamic_cast< const TypeExpr * >( param );231 assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param));232 maybeAccept( paramType->type, *visitor );233 }234 mangleName += "_";235 }236 }237 }238 239 void Mangler_old::postvisit( const StructInstType * aggregateUseType ) {240 mangleRef( aggregateUseType, Encoding::struct_t );241 }242 243 void Mangler_old::postvisit( const UnionInstType * aggregateUseType ) {244 mangleRef( aggregateUseType, Encoding::union_t );245 }246 247 void Mangler_old::postvisit( const EnumInstType * aggregateUseType ) {248 mangleRef( aggregateUseType, Encoding::enum_t );249 }250 251 void Mangler_old::postvisit( const TypeInstType * typeInst ) {252 VarMapType::iterator varNum = varNums.find( typeInst->get_name() );253 if ( varNum == varNums.end() ) {254 mangleRef( typeInst, Encoding::type );255 } else {256 printQualifiers( typeInst );257 // Note: Can't use name here, since type variable names do not actually disambiguate a function, e.g.258 // forall(dtype T) void f(T);259 // forall(dtype S) void f(S);260 // are equivalent and should mangle the same way. This is accomplished by numbering the type variables when they261 // are first found and prefixing with the appropriate encoding for the type class.262 assertf( varNum->second.second < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", varNum->second.second );263 mangleName += Encoding::typeVariables[varNum->second.second] + std::to_string( varNum->second.first );264 } // if265 }266 267 void Mangler_old::postvisit( const TraitInstType * inst ) {268 printQualifiers( inst );269 mangleName += std::to_string( inst->name.size() ) + inst->name;270 }271 272 void Mangler_old::postvisit( const TupleType * tupleType ) {273 printQualifiers( tupleType );274 mangleName += Encoding::tuple + std::to_string( tupleType->types.size() );275 acceptAll( tupleType->types, *visitor );276 }277 278 void Mangler_old::postvisit( const VarArgsType * varArgsType ) {279 printQualifiers( varArgsType );280 static const std::string vargs = "__builtin_va_list";281 mangleName += Encoding::type + std::to_string( vargs.size() ) + vargs;282 }283 284 void Mangler_old::postvisit( const ZeroType * ) {285 mangleName += Encoding::zero;286 }287 288 void Mangler_old::postvisit( const OneType * ) {289 mangleName += Encoding::one;290 }291 292 void Mangler_old::postvisit( const QualifiedType * qualType ) {293 bool inqual = inQualifiedType;294 if (! inqual ) {295 // N marks the start of a qualified type296 inQualifiedType = true;297 mangleName += Encoding::qualifiedTypeStart;298 }299 maybeAccept( qualType->parent, *visitor );300 maybeAccept( qualType->child, *visitor );301 if ( ! inqual ) {302 // E marks the end of a qualified type303 inQualifiedType = false;304 mangleName += Encoding::qualifiedTypeEnd;305 }306 }307 308 void Mangler_old::postvisit( const TypeDecl * decl ) {309 // TODO: is there any case where mangling a TypeDecl makes sense? If so, this code needs to be310 // fixed to ensure that two TypeDecls mangle to the same name when they are the same type and vice versa.311 // Note: The current scheme may already work correctly for this case, I have not thought about this deeply312 // and the case has not yet come up in practice. Alternatively, if not then this code can be removed313 // aside from the assert false.314 assertf( false, "Mangler_old should not visit typedecl: %s", toCString(decl));315 assertf( decl->kind < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind );316 mangleName += Encoding::typeVariables[ decl->kind ] + std::to_string( decl->name.length() ) + decl->name;317 }318 319 __attribute__((unused)) void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) {320 for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {321 os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl;322 } // for323 }324 325 void Mangler_old::printQualifiers( const Type * type ) {326 // skip if not including qualifiers327 if ( typeMode ) return;328 if ( ! type->forall.empty() ) {329 std::list< std::string > assertionNames;330 int dcount = 0, fcount = 0, vcount = 0, acount = 0;331 mangleName += Encoding::forall;332 for ( const TypeDecl * i : type->forall ) {333 switch ( i->kind ) {334 case TypeDecl::Dtype:335 dcount++;336 break;337 case TypeDecl::Ftype:338 fcount++;339 break;340 case TypeDecl::Ttype:341 vcount++;342 break;343 default:344 assertf( false, "unimplemented kind for type variable %s", SymTab::Mangler::Encoding::typeVariables[i->kind].c_str() );345 } // switch346 varNums[ i->name ] = std::make_pair( nextVarNum, (int)i->kind );347 for ( const DeclarationWithType * assert : i->assertions ) {348 PassVisitor<Mangler_old> sub_mangler(349 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums );350 assert->accept( sub_mangler );351 assertionNames.push_back( sub_mangler.pass.get_mangleName() );352 acount++;353 } // for354 } // for355 mangleName += std::to_string( dcount ) + "_" + std::to_string( fcount ) + "_" + std::to_string( vcount ) + "_" + std::to_string( acount ) + "_";356 for(const auto & a : assertionNames) mangleName += a;357 // std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );358 mangleName += "_";359 } // if360 if ( ! inFunctionType ) {361 // these qualifiers do not distinguish the outermost type of a function parameter362 if ( type->get_const() ) {363 mangleName += Encoding::qualifiers.at(Type::Const);364 } // if365 if ( type->get_volatile() ) {366 mangleName += Encoding::qualifiers.at(Type::Volatile);367 } // if368 // Removed due to restrict not affecting function compatibility in GCC369 // if ( type->get_isRestrict() ) {370 // mangleName += "E";371 // } // if372 if ( type->get_atomic() ) {373 mangleName += Encoding::qualifiers.at(Type::Atomic);374 } // if375 }376 if ( type->get_mutex() ) {377 mangleName += Encoding::qualifiers.at(Type::Mutex);378 } // if379 if ( inFunctionType ) {380 // turn off inFunctionType so that types can be differentiated for nested qualifiers381 GuardValue( inFunctionType );382 inFunctionType = false;383 }384 }385 } // namespace386 } // namespace Mangler387 } // namespace SymTab388 28 389 29 namespace Mangle { -
src/SymTab/Mangler.h
r790d835 rc6b4432 22 22 23 23 #include "AST/Bitfield.hpp" 24 #include "SynTree/SynTree.h" // for Types25 #include "SynTree/Visitor.h" // for Visitor, maybeAccept26 24 27 25 // https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling … … 35 33 class Node; 36 34 } 37 namespace ResolvExpr {38 class TypeEnvironment;39 }40 35 41 36 namespace SymTab { 42 37 namespace Mangler { 43 /// Mangle syntax tree object; primary interface to clients44 std::string mangle( const BaseSyntaxNode * decl, bool mangleOverridable = true, bool typeMode = false, bool mangleGenericParams = true );45 46 /// Mangle a type name; secondary interface47 std::string mangleType( const Type * ty );48 /// Mangle ignoring generic type parameters49 std::string mangleConcrete( const Type * ty );50 51 38 namespace Encoding { 52 39 extern const std::string manglePrefix; -
src/SymTab/module.mk
r790d835 rc6b4432 16 16 17 17 SRC_SYMTAB = \ 18 SymTab/Autogen.cc \19 SymTab/Autogen.h \20 18 SymTab/FixFunction.cc \ 21 19 SymTab/FixFunction.h \ 22 20 SymTab/GenImplicitCall.cpp \ 23 21 SymTab/GenImplicitCall.hpp \ 24 SymTab/Indexer.cc \25 SymTab/Indexer.h \26 22 SymTab/Mangler.cc \ 27 23 SymTab/ManglerCommon.cc \ 28 SymTab/Mangler.h \ 29 SymTab/ValidateType.cc \ 30 SymTab/ValidateType.h 24 SymTab/Mangler.h 31 25 32 SRC += $(SRC_SYMTAB) \ 33 SymTab/Validate.cc \ 34 SymTab/Validate.h 26 SRC += $(SRC_SYMTAB) 35 27 36 28 SRCDEMANGLE += $(SRC_SYMTAB) \
Note: See TracChangeset
for help on using the changeset viewer.