summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-04-07 08:22:57 +0000
committerJohn McCall <rjmccall@apple.com>2011-04-07 08:22:57 +0000
commit319963434cab037c9fabf7d631816d3eaf5bfc1d (patch)
tree51089b4e3f62260bc84aafbe72e10dc2e382339a /clang/lib/CodeGen
parent5ddaab1789d7a7ac6bee56b75ec6f44184d66e8b (diff)
downloadbcm5719-llvm-319963434cab037c9fabf7d631816d3eaf5bfc1d.tar.gz
bcm5719-llvm-319963434cab037c9fabf7d631816d3eaf5bfc1d.zip
Basic, untested implementation for an "unknown any" type requested by LLDB.
The idea is that you can create a VarDecl with an unknown type, or a FunctionDecl with an unknown return type, and it will still be valid to access that object as long as you explicitly cast it at every use. I'm still going back and forth about how I want to test this effectively, but I wanted to go ahead and provide a skeletal implementation for the LLDB folks' benefit and because it also improves some diagnostic goodness for placeholder expressions. llvm-svn: 129065
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp6
-rw-r--r--clang/lib/CodeGen/CGExprAgg.cpp4
-rw-r--r--clang/lib/CodeGen/CGExprConstant.cpp1
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp3
-rw-r--r--clang/lib/CodeGen/CGRTTI.cpp1
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp50
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h2
-rw-r--r--clang/lib/CodeGen/CodeGenTypes.cpp5
8 files changed, 69 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 92e6a19c25d..a35f81ca206 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/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/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index eb64996bd33..75e3a7879d4 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/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/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index 3a2fb9bd9d4..822a999b963 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/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/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 97effaa5158..a3c765e3528 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/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/clang/lib/CodeGen/CGRTTI.cpp b/clang/lib/CodeGen/CGRTTI.cpp
index e276d98f12a..07266410300 100644
--- a/clang/lib/CodeGen/CGRTTI.cpp
+++ b/clang/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/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 34f594ecaa9..fe8462bc7c2 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/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/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index 0f86257757d..b29437d9620 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/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/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp
index b9acbc4e9b6..13aa23d8d0d 100644
--- a/clang/lib/CodeGen/CodeGenTypes.cpp
+++ b/clang/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: {
OpenPOWER on IntegriCloud