aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/CGExpr.cpp6
-rw-r--r--lib/CodeGen/CGExprAgg.cpp4
-rw-r--r--lib/CodeGen/CGExprConstant.cpp1
-rw-r--r--lib/CodeGen/CGExprScalar.cpp3
-rw-r--r--lib/CodeGen/CGRTTI.cpp1
-rw-r--r--lib/CodeGen/CodeGenModule.cpp50
-rw-r--r--lib/CodeGen/CodeGenModule.h2
-rw-r--r--lib/CodeGen/CodeGenTypes.cpp5
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: {