C2::ExprResult C2Sema::ActOnTypeQualifier(ExprResult R, unsigned qualifier) { assert(R.get()); if (qualifier) { #ifdef SEMA_DEBUG std::cerr << COL_SEMA << "SEMA: Qualifier Type" << ANSI_NORMAL"\n"; #endif TypeExpr* typeExpr = cast<TypeExpr>(R.get()); // TODO use typeExpr.addConst() and just return QualType (not ref) in getType() QualType qt = typeExpr->getType(); if (qualifier & TYPE_CONST) qt.addConst(); if (qualifier & TYPE_VOLATILE) qt.addVolatile(); if (qualifier & TYPE_LOCAL) typeExpr->setLocalQualifier(); typeExpr->setType(qt); } return R; }
QualType TypeResolver::resolveUnresolved(QualType Q) const { const Type* T = Q.getTypePtr(); switch (Q->getTypeClass()) { case TC_BUILTIN: return Q; case TC_POINTER: { // Dont return new type if not needed const PointerType* P = cast<PointerType>(T); QualType t1 = P->getPointeeType(); QualType Result = resolveUnresolved(t1); if (t1 == Result) return Q; // TODO qualifiers return typeContext.getPointerType(Result); } case TC_ARRAY: { const ArrayType* A = cast<ArrayType>(T); QualType t1 = A->getElementType(); QualType Result = resolveUnresolved(t1); if (t1 == Result) return Q; // TODO qualifiers return typeContext.getArrayType(Result, A->getSizeExpr(), false, A->isIncremental()); } case TC_UNRESOLVED: { const UnresolvedType* U = cast<UnresolvedType>(T); TypeDecl* TD = U->getDecl(); assert(TD); QualType result = TD->getType(); if (Q.isConstQualified()) result.addConst(); if (Q.isVolatileQualified()) result.addVolatile(); return result; } case TC_ALIAS: case TC_STRUCT: case TC_ENUM: case TC_FUNCTION: return Q; case TC_MODULE: assert(0 && "TBD"); return Q; } return Q; }
Expr *Sema::BuildObjCEncodeExpression(SourceLocation AtLoc, TypeSourceInfo *EncodedTypeInfo, SourceLocation RParenLoc) { QualType EncodedType = EncodedTypeInfo->getType(); QualType StrTy; if (EncodedType->isDependentType()) StrTy = Context.DependentTy; else { std::string Str; Context.getObjCEncodingForType(EncodedType, Str); // The type of @encode is the same as the type of the corresponding string, // which is an array type. StrTy = Context.CharTy; // A C++ string literal has a const-qualified element type (C++ 2.13.4p1). if (getLangOptions().CPlusPlus || getLangOptions().ConstStrings) StrTy.addConst(); StrTy = Context.getConstantArrayType(StrTy, llvm::APInt(32, Str.size()+1), ArrayType::Normal, 0); } return new (Context) ObjCEncodeExpr(StrTy, EncodedTypeInfo, AtLoc, RParenLoc); }
QualType Sema::CheckPointerToMemberOperands( Expr *&lex, Expr *&rex, SourceLocation Loc, bool isIndirect) { const char *OpSpelling = isIndirect ? "->*" : ".*"; // C++ 5.5p2 // The binary operator .* [p3: ->*] binds its second operand, which shall // be of type "pointer to member of T" (where T is a completely-defined // class type) [...] QualType RType = rex->getType(); const MemberPointerType *MemPtr = RType->getAsMemberPointerType(); if (!MemPtr) { Diag(Loc, diag::err_bad_memptr_rhs) << OpSpelling << RType << rex->getSourceRange(); return QualType(); } else if (RequireCompleteType(Loc, QualType(MemPtr->getClass(), 0), diag::err_memptr_rhs_incomplete, rex->getSourceRange())) return QualType(); QualType Class(MemPtr->getClass(), 0); // C++ 5.5p2 // [...] to its first operand, which shall be of class T or of a class of // which T is an unambiguous and accessible base class. [p3: a pointer to // such a class] QualType LType = lex->getType(); if (isIndirect) { if (const PointerType *Ptr = LType->getAsPointerType()) LType = Ptr->getPointeeType().getNonReferenceType(); else { Diag(Loc, diag::err_bad_memptr_lhs) << OpSpelling << 1 << LType << lex->getSourceRange(); return QualType(); } } if (Context.getCanonicalType(Class).getUnqualifiedType() != Context.getCanonicalType(LType).getUnqualifiedType()) { BasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/false, /*DetectVirtual=*/false); // FIXME: Would it be useful to print full ambiguity paths, // or is that overkill? if (!IsDerivedFrom(LType, Class, Paths) || Paths.isAmbiguous(Context.getCanonicalType(Class))) { Diag(Loc, diag::err_bad_memptr_lhs) << OpSpelling << (int)isIndirect << lex->getType() << lex->getSourceRange(); return QualType(); } } // C++ 5.5p2 // The result is an object or a function of the type specified by the // second operand. // The cv qualifiers are the union of those in the pointer and the left side, // in accordance with 5.5p5 and 5.2.5. // FIXME: This returns a dereferenced member function pointer as a normal // function type. However, the only operation valid on such functions is // calling them. There's also a GCC extension to get a function pointer to // the thing, which is another complication, because this type - unlike the // type that is the result of this expression - takes the class as the first // argument. // We probably need a "MemberFunctionClosureType" or something like that. QualType Result = MemPtr->getPointeeType(); if (LType.isConstQualified()) Result.addConst(); if (LType.isVolatileQualified()) Result.addVolatile(); return Result; }
C2::Module* C2ModuleLoader::load(const std::string& name) { // NOTE: MEMLEAK on Types clang::SourceLocation loc; if (name == "stdio") { Module* stdioMod = new C2::Module("stdio", true, true); // int puts(const char* s); { FunctionDecl* func = new FunctionDecl("puts", loc, true, Type::Int32()); // TODO correct arg QualType QT(new PointerType(Type::Int8()), QUAL_CONST); QT->setCanonicalType(QT); VarDecl* Arg1 = new VarDecl(VARDECL_PARAM, "s", loc, QT, 0, true); Arg1->setType(QT); func->addArg(Arg1); stdioMod->addSymbol(func); // function type func->setType(QualType(new FunctionType(func), 0)); } //int printf(const char *format, ...); { FunctionDecl* func = new FunctionDecl("printf", loc, true, Type::Int32()); // NOTE: MEMLEAK ON TYPE, this will go away when we remove these dummy protos QualType QT(new PointerType(Type::Int8()), QUAL_CONST); QT->setCanonicalType(QT); VarDecl* Arg1 = new VarDecl(VARDECL_PARAM, "format", loc, QT, 0, true); Arg1->setType(QT); func->addArg(Arg1); func->setVariadic(); stdioMod->addSymbol(func); // function type func->setType(QualType(new FunctionType(func), 0)); } //int sprintf(char *str, const char *format, ...); { FunctionDecl* func = new FunctionDecl("sprintf", loc, true, Type::Int32()); // NOTE: MEMLEAK ON TYPE, this will go away when we remove these dummy protos QualType QT(new PointerType(Type::Int8()), QUAL_CONST); QT->setCanonicalType(QT); VarDecl* Arg1 = new VarDecl(VARDECL_PARAM, "str", loc, QT, 0, true); Arg1->setType(QT); func->addArg(Arg1); VarDecl* Arg2 = new VarDecl(VARDECL_PARAM, "format", loc, QT, 0, true); Arg2->setType(QT); func->addArg(Arg2); func->setVariadic(); stdioMod->addSymbol(func); // function type func->setType(QualType(new FunctionType(func), 0)); } return stdioMod; } if (name == "string") { Module* stringMod = new C2::Module("string", true, true); // void *memset(void *s, int c, size_t n); { QualType VP(new PointerType(Type::Void())); VP->setCanonicalType(VP); FunctionDecl* func = new FunctionDecl("memset", loc, true, VP); // NOTE: MEMLEAK ON TYPE, this will go away when we remove these dummy protos VarDecl* Arg1 = new VarDecl(VARDECL_PARAM, "s", loc, VP, 0, true); Arg1->setType(VP); func->addArg(Arg1); VarDecl* Arg2 = new VarDecl(VARDECL_PARAM, "c", loc, Type::Int32(), 0, true); Arg2->setType(Type::Int32()); func->addArg(Arg2); // TEMP size_t -> uint32 VarDecl* Arg3 = new VarDecl(VARDECL_PARAM, "n", loc, Type::UInt32(), 0, true); Arg3->setType(Type::UInt32()); func->addArg(Arg3); stringMod->addSymbol(func); // function type func->setType(QualType(new FunctionType(func), 0)); } return stringMod; } if (name == "stdlib") { Module* stdlibMod = new C2::Module("stdlib", true, true); //void exit(int status); { FunctionDecl* func = new FunctionDecl("exit", loc, true, Type::Void()); // TODO correct arg VarDecl* Arg1 = new VarDecl(VARDECL_PARAM, "status", loc, Type::Int32(), 0, true); Arg1->setType(Type::Int32()); func->addArg(Arg1); stdlibMod->addSymbol(func); // function type func->setType(QualType(new FunctionType(func), 0)); } return stdlibMod; } if (name == "c2") { Module* c2Mod = new C2::Module("c2", true, false); // uint64 buildtime { // make constant, CTC_NONE QualType QT = Type::UInt64(); QT.addConst(); uint64_t value = time(0); Expr* init = new IntegerLiteral(loc, llvm::APInt(64, value, false)); // TODO get error without value if CTC_NONE, CTC_FULL gives out-of-bounds for value 123?!! init->setCTC(CTC_NONE); // Don't check range, only type init->setConstant(); init->setType(QT); VarDecl* var = new VarDecl(VARDECL_GLOBAL, "buildtime", loc, QT, init, true); var->setType(QT); c2Mod->addSymbol(var); } // int8 min_int8 { QualType QT = Type::Int8(); QT.addConst(); Expr* init = new IntegerLiteral(loc, llvm::APInt(64, -128, true)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new VarDecl(VARDECL_GLOBAL, "min_int8", loc, QT, init, true); var->setType(QT); c2Mod->addSymbol(var); } // int8 max_int8 { QualType QT = Type::Int8(); QT.addConst(); Expr* init = new IntegerLiteral(loc, llvm::APInt(64, 127, true)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new VarDecl(VARDECL_GLOBAL, "max_int8", loc, QT, init, true); var->setType(QT); c2Mod->addSymbol(var); } // uint8 min_uint8 { QualType QT = Type::UInt8(); QT.addConst(); Expr* init = new IntegerLiteral(loc, llvm::APInt(64, 0, false)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new VarDecl(VARDECL_GLOBAL, "min_uint8", loc, QT, init, true); var->setType(QT); c2Mod->addSymbol(var); } // uint8 max_uint8 { QualType QT = Type::UInt8(); QT.addConst(); Expr* init = new IntegerLiteral(loc, llvm::APInt(64, 255, false)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new VarDecl(VARDECL_GLOBAL, "max_uint8", loc, QT, init, true); var->setType(QT); c2Mod->addSymbol(var); } // int16 min_int16 { QualType QT = Type::Int16(); QT.addConst(); Expr* init = new IntegerLiteral(loc, llvm::APInt(64, -32768, true)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new VarDecl(VARDECL_GLOBAL, "min_int16", loc, QT, init, true); var->setType(QT); c2Mod->addSymbol(var); } // int16 max_int16 { QualType QT = Type::Int16(); QT.addConst(); Expr* init = new IntegerLiteral(loc, llvm::APInt(64, 32767, true)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new VarDecl(VARDECL_GLOBAL, "max_int16", loc, QT, init, true); var->setType(QT); c2Mod->addSymbol(var); } // uint16 min_uint16 { QualType QT = Type::UInt16(); QT.addConst(); Expr* init = new IntegerLiteral(loc, llvm::APInt(64, 0, false)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new VarDecl(VARDECL_GLOBAL, "min_uint16", loc, QT, init, true); var->setType(QT); c2Mod->addSymbol(var); } // uint16 max_uint16 { QualType QT = Type::UInt16(); QT.addConst(); Expr* init = new IntegerLiteral(loc, llvm::APInt(64, 65535, false)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new VarDecl(VARDECL_GLOBAL, "max_uint16", loc, QT, init, true); var->setType(QT); c2Mod->addSymbol(var); } // int32 min_int32 { QualType QT = Type::Int32(); QT.addConst(); Expr* init = new IntegerLiteral(loc, llvm::APInt(64, -2147483648, true)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new VarDecl(VARDECL_GLOBAL, "min_int32", loc, QT, init, true); var->setType(QT); c2Mod->addSymbol(var); } // int32 max_int32 { QualType QT = Type::Int32(); QT.addConst(); Expr* init = new IntegerLiteral(loc, llvm::APInt(64, 2147483647, true)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new VarDecl(VARDECL_GLOBAL, "max_int32", loc, QT, init, true); var->setType(QT); c2Mod->addSymbol(var); } // uint32 min_uint32 { QualType QT = Type::UInt32(); QT.addConst(); Expr* init = new IntegerLiteral(loc, llvm::APInt(64, 0, false)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new VarDecl(VARDECL_GLOBAL, "min_uint32", loc, QT, init, true); var->setType(QT); c2Mod->addSymbol(var); } // uint32 max_uint32 { QualType QT = Type::UInt32(); QT.addConst(); Expr* init = new IntegerLiteral(loc, llvm::APInt(64, 4294967295, false)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new VarDecl(VARDECL_GLOBAL, "max_uint32", loc, QT, init, true); var->setType(QT); c2Mod->addSymbol(var); } // int64 min_int64 { QualType QT = Type::Int64(); QT.addConst(); // NOTE: minimum should be -..808, but clang complains about it.. Expr* init = new IntegerLiteral(loc, llvm::APInt(64, -9223372036854775807ll, true)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new VarDecl(VARDECL_GLOBAL, "min_int64", loc, QT, init, true); var->setType(QT); c2Mod->addSymbol(var); } // int64 max_int64 { QualType QT = Type::Int64(); QT.addConst(); Expr* init = new IntegerLiteral(loc, llvm::APInt(64, 9223372036854775807ll, true)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new VarDecl(VARDECL_GLOBAL, "max_int64", loc, QT, init, true); var->setType(QT); c2Mod->addSymbol(var); } // uint64 min_uint64 { QualType QT = Type::UInt64(); QT.addConst(); Expr* init = new IntegerLiteral(loc, llvm::APInt(64, 0, false)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new VarDecl(VARDECL_GLOBAL, "min_uint64", loc, QT, init, true); var->setType(QT); c2Mod->addSymbol(var); } // uint64 max_uint64 { QualType QT = Type::UInt64(); QT.addConst(); Expr* init = new IntegerLiteral(loc, llvm::APInt(64, 18446744073709551615llu, false)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new VarDecl(VARDECL_GLOBAL, "max_uint64", loc, QT, init, true); var->setType(QT); c2Mod->addSymbol(var); } return c2Mod; } return 0; }
void C2ModuleLoader::load(C2::Module* c2Mod) { clang::SourceLocation loc; AST* ast = new AST("<generated>", false); ASTContext& Context = ast->getASTContext(); ast->setName("c2", loc); c2Mod->addAST(ast); // uint64 buildtime { // make constant, CTC_NONE QualType QT = Type::UInt64(); QT.addConst(); uint64_t value = time(0); Expr* init = new (Context) IntegerLiteral(loc, llvm::APInt(64, value, false)); // TODO get error without value if CTC_NONE, CTC_FULL gives out-of-bounds for value 123?!! init->setCTC(CTC_NONE); // Don't check range, only type init->setConstant(); init->setType(QT); VarDecl* var = new (Context) VarDecl(VARDECL_GLOBAL, "buildtime", loc, QT, init, true); var->setType(QT); ast->addVar(var); c2Mod->addSymbol(var); } // int8 min_int8 { QualType QT = Type::Int8(); QT.addConst(); Expr* init = new (Context) IntegerLiteral(loc, llvm::APInt(64, -128, true)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new (Context) VarDecl(VARDECL_GLOBAL, "min_int8", loc, QT, init, true); var->setType(QT); ast->addVar(var); c2Mod->addSymbol(var); } // int8 max_int8 { QualType QT = Type::Int8(); QT.addConst(); Expr* init = new (Context) IntegerLiteral(loc, llvm::APInt(64, 127, true)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new (Context) VarDecl(VARDECL_GLOBAL, "max_int8", loc, QT, init, true); var->setType(QT); ast->addVar(var); c2Mod->addSymbol(var); } // uint8 min_uint8 { QualType QT = Type::UInt8(); QT.addConst(); Expr* init = new (Context) IntegerLiteral(loc, llvm::APInt(64, 0, false)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new (Context) VarDecl(VARDECL_GLOBAL, "min_uint8", loc, QT, init, true); var->setType(QT); ast->addVar(var); c2Mod->addSymbol(var); } // uint8 max_uint8 { QualType QT = Type::UInt8(); QT.addConst(); Expr* init = new (Context) IntegerLiteral(loc, llvm::APInt(64, 255, false)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new (Context) VarDecl(VARDECL_GLOBAL, "max_uint8", loc, QT, init, true); var->setType(QT); ast->addVar(var); c2Mod->addSymbol(var); } // int16 min_int16 { QualType QT = Type::Int16(); QT.addConst(); Expr* init = new (Context) IntegerLiteral(loc, llvm::APInt(64, -32768, true)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new (Context) VarDecl(VARDECL_GLOBAL, "min_int16", loc, QT, init, true); var->setType(QT); ast->addVar(var); c2Mod->addSymbol(var); } // int16 max_int16 { QualType QT = Type::Int16(); QT.addConst(); Expr* init = new (Context) IntegerLiteral(loc, llvm::APInt(64, 32767, true)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new (Context) VarDecl(VARDECL_GLOBAL, "max_int16", loc, QT, init, true); var->setType(QT); ast->addVar(var); c2Mod->addSymbol(var); } // uint16 min_uint16 { QualType QT = Type::UInt16(); QT.addConst(); Expr* init = new (Context) IntegerLiteral(loc, llvm::APInt(64, 0, false)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new (Context) VarDecl(VARDECL_GLOBAL, "min_uint16", loc, QT, init, true); var->setType(QT); ast->addVar(var); c2Mod->addSymbol(var); } // uint16 max_uint16 { QualType QT = Type::UInt16(); QT.addConst(); Expr* init = new (Context) IntegerLiteral(loc, llvm::APInt(64, 65535, false)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new (Context) VarDecl(VARDECL_GLOBAL, "max_uint16", loc, QT, init, true); var->setType(QT); ast->addVar(var); c2Mod->addSymbol(var); } // int32 min_int32 { QualType QT = Type::Int32(); QT.addConst(); Expr* init = new (Context) IntegerLiteral(loc, llvm::APInt(64, -2147483648, true)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new (Context) VarDecl(VARDECL_GLOBAL, "min_int32", loc, QT, init, true); var->setType(QT); ast->addVar(var); c2Mod->addSymbol(var); } // int32 max_int32 { QualType QT = Type::Int32(); QT.addConst(); Expr* init = new (Context) IntegerLiteral(loc, llvm::APInt(64, 2147483647, true)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new (Context) VarDecl(VARDECL_GLOBAL, "max_int32", loc, QT, init, true); var->setType(QT); ast->addVar(var); c2Mod->addSymbol(var); } // uint32 min_uint32 { QualType QT = Type::UInt32(); QT.addConst(); Expr* init = new (Context) IntegerLiteral(loc, llvm::APInt(64, 0, false)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new (Context) VarDecl(VARDECL_GLOBAL, "min_uint32", loc, QT, init, true); var->setType(QT); ast->addVar(var); c2Mod->addSymbol(var); } // uint32 max_uint32 { QualType QT = Type::UInt32(); QT.addConst(); Expr* init = new (Context) IntegerLiteral(loc, llvm::APInt(64, 4294967295, false)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new (Context) VarDecl(VARDECL_GLOBAL, "max_uint32", loc, QT, init, true); var->setType(QT); ast->addVar(var); c2Mod->addSymbol(var); } // int64 min_int64 { QualType QT = Type::Int64(); QT.addConst(); // NOTE: minimum should be -..808, but clang complains about it.. Expr* init = new (Context) IntegerLiteral(loc, llvm::APInt(64, -9223372036854775807ll, true)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new (Context) VarDecl(VARDECL_GLOBAL, "min_int64", loc, QT, init, true); var->setType(QT); ast->addVar(var); c2Mod->addSymbol(var); } // int64 max_int64 { QualType QT = Type::Int64(); QT.addConst(); Expr* init = new (Context) IntegerLiteral(loc, llvm::APInt(64, 9223372036854775807ll, true)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new (Context) VarDecl(VARDECL_GLOBAL, "max_int64", loc, QT, init, true); var->setType(QT); ast->addVar(var); c2Mod->addSymbol(var); } // uint64 min_uint64 { QualType QT = Type::UInt64(); QT.addConst(); Expr* init = new (Context) IntegerLiteral(loc, llvm::APInt(64, 0, false)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new (Context) VarDecl(VARDECL_GLOBAL, "min_uint64", loc, QT, init, true); var->setType(QT); ast->addVar(var); c2Mod->addSymbol(var); } // uint64 max_uint64 { QualType QT = Type::UInt64(); QT.addConst(); // NOTE: capped to -1 since APInt is always signed? Expr* init = new (Context) IntegerLiteral(loc, llvm::APInt(64, 18446744073709551615llu, false)); init->setCTC(CTC_FULL); init->setConstant(); init->setType(QT); VarDecl* var = new (Context) VarDecl(VARDECL_GLOBAL, "max_uint64", loc, QT, init, true); var->setType(QT); ast->addVar(var); c2Mod->addSymbol(var); } #if 0 // type c_char int8 { QualType QT = Type::Int8(); static const char* name = "c_char"; AliasTypeDecl* T = new (Context) AliasTypeDecl(name, loc, QT, true); QualType A = Context.getAliasType(T, QT); A->setCanonicalType(QT); T->setType(A); c2Mod->addSymbol(T); } #endif // create C types (depend on target) // NOTE: all types are lower-cased! for (unsigned i=0; i<sizeof(ctypes)/sizeof(ctypes[0]); i++) { QualType QT = ctypes[i].type; AliasTypeDecl* T = new (Context) AliasTypeDecl(ctypes[i].name, loc, QT, true); QualType A = Context.getAliasType(T, QT); A->setCanonicalType(QT); T->setType(A); ast->addType(T); c2Mod->addSymbol(T); } }