diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 6 | ||||
-rw-r--r-- | lib/CodeGen/CGExprAgg.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/CGExprConstant.cpp | 1 | ||||
-rw-r--r-- | lib/CodeGen/CGExprScalar.cpp | 3 | ||||
-rw-r--r-- | lib/CodeGen/CGRTTI.cpp | 1 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 50 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 2 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenTypes.cpp | 5 |
8 files changed, 69 insertions, 3 deletions
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index 92e6a19c25..a35f81ca20 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -1930,6 +1930,12 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { ConvertType(ToType)); return MakeAddrLValue(V, E->getType()); } + case CK_ResolveUnknownAnyType: { + const DeclRefExpr *declRef = cast<DeclRefExpr>(E->getSubExpr()); + llvm::Constant *addr = CGM.getAddrOfUnknownAnyDecl(declRef->getDecl(), + E->getType()); + return MakeAddrLValue(addr, E->getType()); + } } llvm_unreachable("Unhandled lvalue cast kind?"); diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp index eb64996bd3..75e3a7879d 100644 --- a/lib/CodeGen/CGExprAgg.cpp +++ b/lib/CodeGen/CGExprAgg.cpp @@ -309,6 +309,10 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) { case CK_LValueBitCast: llvm_unreachable("should not be emitting lvalue bitcast as rvalue"); break; + + case CK_ResolveUnknownAnyType: + EmitAggLoadOfLValue(E); + break; case CK_Dependent: case CK_BitCast: diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index 3a2fb9bd9d..822a999b96 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -552,6 +552,7 @@ public: case CK_GetObjCProperty: case CK_ToVoid: case CK_Dynamic: + case CK_ResolveUnknownAnyType: return 0; // These might need to be supported for constexpr. diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp index 97effaa515..a3c765e352 100644 --- a/lib/CodeGen/CGExprScalar.cpp +++ b/lib/CodeGen/CGExprScalar.cpp @@ -1126,6 +1126,9 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) { RValue RV = CGF.EmitLoadOfLValue(CGF.EmitLValue(E), E->getType()); return RV.getScalarVal(); } + + case CK_ResolveUnknownAnyType: + return EmitLoadOfLValue(CE); case CK_LValueToRValue: assert(CGF.getContext().hasSameUnqualifiedType(E->getType(), DestTy)); diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp index e276d98f12..0726641030 100644 --- a/lib/CodeGen/CGRTTI.cpp +++ b/lib/CodeGen/CGRTTI.cpp @@ -196,6 +196,7 @@ static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) { case BuiltinType::Overload: case BuiltinType::Dependent: + case BuiltinType::UnknownAny: assert(false && "Should not see this type here!"); case BuiltinType::ObjCId: diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 34f594ecaa..fe8462bc7c 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -1072,12 +1072,60 @@ llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D, return GetOrCreateLLVMGlobal(MangledName, PTy, D); } +/// getAddrOfUnknownAnyDecl - Return an llvm::Constant for the address +/// of a global which was declared with unknown type. It is possible +/// for a VarDecl to end up getting resolved to have function type, +/// which complicates this substantially; on the other hand, these are +/// always external references, which does simplify the logic a lot. +llvm::Constant * +CodeGenModule::getAddrOfUnknownAnyDecl(const NamedDecl *decl, QualType type) { + GlobalDecl global; + + // FunctionDecls will always end up with function types, but + // VarDecls can end up with them too. + if (isa<FunctionDecl>(decl)) + global = GlobalDecl(cast<FunctionDecl>(decl)); + else + global = GlobalDecl(cast<VarDecl>(decl)); + llvm::StringRef mangledName = getMangledName(global); + + const llvm::Type *ty = getTypes().ConvertTypeForMem(type); + const llvm::PointerType *pty = + llvm::PointerType::get(ty, getContext().getTargetAddressSpace(type)); + + + // Check for an existing global value with this name. + llvm::GlobalValue *entry = GetGlobalValue(mangledName); + if (entry) + return llvm::ConstantExpr::getBitCast(entry, pty); + + // If we're creating something with function type, go ahead and + // create a function. + if (const llvm::FunctionType *fnty = dyn_cast<llvm::FunctionType>(ty)) { + llvm::Function *fn = llvm::Function::Create(fnty, + llvm::Function::ExternalLinkage, + mangledName, &getModule()); + return fn; + + // Otherwise, make a global variable. + } else { + llvm::GlobalVariable *var + = new llvm::GlobalVariable(getModule(), ty, false, + llvm::GlobalValue::ExternalLinkage, + 0, mangledName, 0, + false, pty->getAddressSpace()); + if (isa<VarDecl>(decl) && cast<VarDecl>(decl)->isThreadSpecified()) + var->setThreadLocal(true); + return var; + } +} + /// CreateRuntimeVariable - Create a new runtime global variable with the /// specified type and name. llvm::Constant * CodeGenModule::CreateRuntimeVariable(const llvm::Type *Ty, llvm::StringRef Name) { - return GetOrCreateLLVMGlobal(Name, llvm::PointerType::getUnqual(Ty), 0, + return GetOrCreateLLVMGlobal(Name, llvm::PointerType::getUnqual(Ty), 0, true); } diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 0f86257757..b29437d962 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -358,6 +358,8 @@ public: llvm::Constant *GetAddrOfGlobalVar(const VarDecl *D, const llvm::Type *Ty = 0); + llvm::Constant *getAddrOfUnknownAnyDecl(const NamedDecl *D, QualType type); + /// GetAddrOfFunction - Return the address of the given function. If Ty is /// non-null, then this function will use the specified type if it has to /// create it. diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp index b9acbc4e9b..13aa23d8d0 100644 --- a/lib/CodeGen/CodeGenTypes.cpp +++ b/lib/CodeGen/CodeGenTypes.cpp @@ -253,10 +253,11 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) { case BuiltinType::Overload: case BuiltinType::Dependent: - assert(0 && "Unexpected builtin type!"); + case BuiltinType::UnknownAny: + llvm_unreachable("Unexpected builtin type!"); break; } - assert(0 && "Unknown builtin type!"); + llvm_unreachable("Unknown builtin type!"); break; } case Type::Complex: { |