summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/CGBuiltin.cpp2
-rw-r--r--lib/CodeGen/CGCall.cpp40
-rw-r--r--lib/CodeGen/CGExpr.cpp3
-rw-r--r--lib/CodeGen/CGExprComplex.cpp48
-rw-r--r--lib/CodeGen/CGExprConstant.cpp1
-rw-r--r--lib/CodeGen/CGObjCMac.cpp2
-rw-r--r--lib/CodeGen/CodeGenModule.cpp13
-rw-r--r--lib/CodeGen/Mangle.cpp27
-rw-r--r--lib/CodeGen/TargetABIInfo.cpp38
9 files changed, 140 insertions, 34 deletions
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index f9c44c8..a919dfa 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -17,7 +17,7 @@
#include "clang/AST/APValue.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
-#include "clang/AST/TargetBuiltins.h"
+#include "clang/Basic/TargetBuiltins.h"
#include "llvm/Intrinsics.h"
using namespace clang;
using namespace CodeGen;
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index b10b9c2..4037f32 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -682,10 +682,12 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
// location that we would like to return into.
QualType RetTy = CallInfo.getReturnType();
const ABIArgInfo &RetAI = CallInfo.getReturnInfo();
- if (CGM.ReturnTypeUsesSret(CallInfo)) {
- // Create a temporary alloca to hold the result of the call. :(
+
+
+ // If the call returns a temporary with struct return, create a temporary
+ // alloca to hold the result.
+ if (CGM.ReturnTypeUsesSret(CallInfo))
Args.push_back(CreateTempAlloca(ConvertTypeForMem(RetTy)));
- }
assert(CallInfo.arg_size() == CallArgs.size() &&
"Mismatch between function signature & arguments.");
@@ -747,6 +749,35 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
break;
}
}
+
+ // If the callee is a bitcast of a function to a varargs pointer to function
+ // type, check to see if we can remove the bitcast. This handles some cases
+ // with unprototyped functions.
+ if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(Callee))
+ if (llvm::Function *CalleeF = dyn_cast<llvm::Function>(CE->getOperand(0))) {
+ const llvm::PointerType *CurPT=cast<llvm::PointerType>(Callee->getType());
+ const llvm::FunctionType *CurFT =
+ cast<llvm::FunctionType>(CurPT->getElementType());
+ const llvm::FunctionType *ActualFT = CalleeF->getFunctionType();
+
+ if (CE->getOpcode() == llvm::Instruction::BitCast &&
+ ActualFT->getReturnType() == CurFT->getReturnType() &&
+ ActualFT->getNumParams() == CurFT->getNumParams()) {
+ bool ArgsMatch = true;
+ for (unsigned i = 0, e = ActualFT->getNumParams(); i != e; ++i)
+ if (ActualFT->getParamType(i) != CurFT->getParamType(i)) {
+ ArgsMatch = false;
+ break;
+ }
+
+ // Strip the cast if we can get away with it. This is a nice cleanup,
+ // but also allows us to inline the function at -O0 if it is marked
+ // always_inline.
+ if (ArgsMatch)
+ Callee = CalleeF;
+ }
+ }
+
llvm::BasicBlock *InvokeDest = getInvokeDest();
CodeGen::AttributeListType AttributeList;
@@ -765,7 +796,8 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
}
CS.setAttributes(Attrs);
- if (const llvm::Function *F = dyn_cast<llvm::Function>(Callee->stripPointerCasts()))
+ if (const llvm::Function *F =
+ dyn_cast<llvm::Function>(Callee->stripPointerCasts()))
CS.setCallingConv(F->getCallingConv());
// If the call doesn't return, finish the basic block and clear the
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index c52e6bd..eb0db61 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -1156,10 +1156,9 @@ RValue CodeGenFunction::EmitCallExpr(const CallExpr *E) {
}
}
- if (const CXXOperatorCallExpr *CE = dyn_cast<CXXOperatorCallExpr>(E)) {
+ if (const CXXOperatorCallExpr *CE = dyn_cast<CXXOperatorCallExpr>(E))
if (const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(TargetDecl))
return EmitCXXOperatorMemberCallExpr(CE, MD);
- }
llvm::Value *Callee = EmitScalarExpr(E->getCallee());
return EmitCall(Callee, E->getCallee()->getType(),
diff --git a/lib/CodeGen/CGExprComplex.cpp b/lib/CodeGen/CGExprComplex.cpp
index 41fb725..e1332ff 100644
--- a/lib/CodeGen/CGExprComplex.cpp
+++ b/lib/CodeGen/CGExprComplex.cpp
@@ -77,7 +77,14 @@ public:
/// and returns the result.
ComplexPairTy EmitLoadOfLValue(const Expr *E) {
LValue LV = CGF.EmitLValue(E);
- return EmitLoadOfComplex(LV.getAddress(), LV.isVolatileQualified());
+ if (LV.isSimple())
+ return EmitLoadOfComplex(LV.getAddress(), LV.isVolatileQualified());
+
+ if (LV.isPropertyRef())
+ return CGF.EmitObjCPropertyGet(LV.getPropertyRefExpr()).getComplexVal();
+
+ assert(LV.isKVCRef() && "Unknown LValue type!");
+ return CGF.EmitObjCPropertyGet(LV.getKVCRefExpr()).getComplexVal();
}
/// EmitLoadOfComplex - Given a pointer to a complex value, emit code to load
@@ -107,6 +114,18 @@ public:
// l-values.
ComplexPairTy VisitDeclRefExpr(const Expr *E) { return EmitLoadOfLValue(E); }
+ ComplexPairTy VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
+ return EmitLoadOfLValue(E);
+ }
+ ComplexPairTy VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
+ return EmitLoadOfLValue(E);
+ }
+ ComplexPairTy VisitObjCKVCRefExpr(ObjCKVCRefExpr *E) {
+ return EmitLoadOfLValue(E);
+ }
+ ComplexPairTy VisitObjCMessageExpr(ObjCMessageExpr *E) {
+ return CGF.EmitObjCMessageExpr(E).getComplexVal();
+ }
ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); }
ComplexPairTy VisitMemberExpr(const Expr *E) { return EmitLoadOfLValue(E); }
@@ -522,15 +541,32 @@ ComplexPairTy ComplexExprEmitter::VisitBinAssign(const BinaryOperator *E) {
// Compute the address to store into.
LValue LHS = CGF.EmitLValue(E->getLHS());
-
- // Store into it.
- EmitStoreOfComplex(Val, LHS.getAddress(), LHS.isVolatileQualified());
- // And now return the LHS
+
+ // Store into it, if simple.
+ if (LHS.isSimple()) {
+ EmitStoreOfComplex(Val, LHS.getAddress(), LHS.isVolatileQualified());
+
+ // And now return the LHS
+ IgnoreReal = ignreal;
+ IgnoreImag = ignimag;
+ IgnoreRealAssign = ignreal;
+ IgnoreImagAssign = ignimag;
+ return EmitLoadOfComplex(LHS.getAddress(), LHS.isVolatileQualified());
+ }
+
+ // Otherwise we must have a property setter (no complex vector/bitfields).
+ if (LHS.isPropertyRef())
+ CGF.EmitObjCPropertySet(LHS.getPropertyRefExpr(), RValue::getComplex(Val));
+ else
+ CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(), RValue::getComplex(Val));
+
+ // There is no reload after a store through a method, but we need to restore
+ // the Ignore* flags.
IgnoreReal = ignreal;
IgnoreImag = ignimag;
IgnoreRealAssign = ignreal;
IgnoreImagAssign = ignimag;
- return EmitLoadOfComplex(LHS.getAddress(), LHS.isVolatileQualified());
+ return Val;
}
ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) {
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp
index b30bafb..0e21a00 100644
--- a/lib/CodeGen/CGExprConstant.cpp
+++ b/lib/CodeGen/CGExprConstant.cpp
@@ -17,6 +17,7 @@
#include "clang/AST/APValue.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/StmtVisitor.h"
+#include "clang/Basic/Builtins.h"
#include "llvm/Constants.h"
#include "llvm/Function.h"
#include "llvm/GlobalVariable.h"
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 75755ec..bd5b05a 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -1508,6 +1508,8 @@ CodeGen::RValue CGObjCCommonMac::EmitLegacyMessageSend(
BuiltinType::Kind k = BT->getKind();
Fn = (k == BuiltinType::LongDouble) ? ObjCTypes.getSendFpretFn2(IsSuper)
: ObjCTypes.getSendFn2(IsSuper);
+ } else {
+ Fn = ObjCTypes.getSendFn2(IsSuper);
}
}
else
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 5c12c81..82156e9 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -21,6 +21,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/Basic/Builtins.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
@@ -1107,9 +1108,9 @@ llvm::Value *CodeGenModule::getBuiltinLibFunction(unsigned BuiltinID) {
Name += 10;
// Get the type for the builtin.
- Builtin::Context::GetBuiltinTypeError Error;
- QualType Type = Context.BuiltinInfo.GetBuiltinType(BuiltinID, Context, Error);
- assert(Error == Builtin::Context::GE_None && "Can't get builtin type");
+ ASTContext::GetBuiltinTypeError Error;
+ QualType Type = Context.GetBuiltinType(BuiltinID, Error);
+ assert(Error == ASTContext::GE_None && "Can't get builtin type");
const llvm::FunctionType *Ty =
cast<llvm::FunctionType>(getTypes().ConvertType(Type));
@@ -1481,7 +1482,11 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
case Decl::CXXDestructor:
EmitCXXDestructors(cast<CXXDestructorDecl>(D));
break;
-
+
+ case Decl::StaticAssert:
+ // Nothing to do.
+ break;
+
// Objective-C Decls
// Forward declarations, no (immediate) code generation.
diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp
index 6ee1223..14392ab 100644
--- a/lib/CodeGen/Mangle.cpp
+++ b/lib/CodeGen/Mangle.cpp
@@ -87,19 +87,20 @@ static bool isInCLinkageSpecification(const Decl *D) {
bool CXXNameMangler::mangleFunctionDecl(const FunctionDecl *FD) {
// Clang's "overloadable" attribute extension to C/C++ implies
// name mangling (always).
- if (FD->hasAttr<OverloadableAttr>()) {
- ; // fall into mangling code unconditionally.
- } else if (// C functions are not mangled
- !Context.getLangOptions().CPlusPlus ||
- // "main" is not mangled in C++
- FD->isMain() ||
- // No mangling in an "implicit extern C" header.
- (FD->getLocation().isValid() &&
- Context.getSourceManager().getFileCharacteristic(FD->getLocation()))
- == SrcMgr::C_ExternCSystem ||
- // No name mangling in a C linkage specification.
- isInCLinkageSpecification(FD))
- return false;
+ if (!FD->hasAttr<OverloadableAttr>()) {
+ // C functions are not mangled, and "main" is never mangled.
+ if (!Context.getLangOptions().CPlusPlus || FD->isMain())
+ return false;
+
+ // No mangling in an "implicit extern C" header.
+ if (FD->getLocation().isValid() &&
+ Context.getSourceManager().isInExternCSystemHeader(FD->getLocation()))
+ return false;
+
+ // No name mangling in a C linkage specification.
+ if (isInCLinkageSpecification(FD))
+ return false;
+ }
// If we get here, mangle the decl name!
Out << "_Z";
diff --git a/lib/CodeGen/TargetABIInfo.cpp b/lib/CodeGen/TargetABIInfo.cpp
index 6f7bea2..361e5c0 100644
--- a/lib/CodeGen/TargetABIInfo.cpp
+++ b/lib/CodeGen/TargetABIInfo.cpp
@@ -159,6 +159,23 @@ static bool areAllFields32Or64BitBasicType(const RecordDecl *RD,
return true;
}
+static bool typeContainsSSEVector(const RecordDecl *RD, ASTContext &Context) {
+ for (RecordDecl::field_iterator i = RD->field_begin(Context),
+ e = RD->field_end(Context); i != e; ++i) {
+ const FieldDecl *FD = *i;
+
+ if (FD->getType()->isVectorType() &&
+ Context.getTypeSize(FD->getType()) >= 128)
+ return true;
+
+ if (const RecordType* RT = FD->getType()->getAsRecordType())
+ if (typeContainsSSEVector(RT->getDecl(), Context))
+ return true;
+ }
+
+ return false;
+}
+
namespace {
/// DefaultABIInfo - The default implementation for ABI specific
/// details. This implementation provides information which results in
@@ -193,6 +210,9 @@ class X86_32ABIInfo : public ABIInfo {
static bool shouldReturnTypeInRegister(QualType Ty, ASTContext &Context);
+ static unsigned getIndirectArgumentAlignment(QualType Ty,
+ ASTContext &Context);
+
public:
ABIArgInfo classifyReturnType(QualType RetTy,
ASTContext &Context) const;
@@ -350,6 +370,16 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
}
}
+unsigned X86_32ABIInfo::getIndirectArgumentAlignment(QualType Ty,
+ ASTContext &Context) {
+ unsigned Align = Context.getTypeAlign(Ty);
+ if (Align < 128) return 0;
+ if (const RecordType* RT = Ty->getAsRecordType())
+ if (typeContainsSSEVector(RT->getDecl(), Context))
+ return 16;
+ return 0;
+}
+
ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
ASTContext &Context) const {
// FIXME: Set alignment on indirect arguments.
@@ -357,11 +387,11 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
// Structures with flexible arrays are always indirect.
if (const RecordType *RT = Ty->getAsStructureType())
if (RT->getDecl()->hasFlexibleArrayMember())
- return ABIArgInfo::getIndirect(0);
+ return ABIArgInfo::getIndirect(getIndirectArgumentAlignment(Ty,
+ Context));
// Ignore empty structs.
- uint64_t Size = Context.getTypeSize(Ty);
- if (Ty->isStructureType() && Size == 0)
+ if (Ty->isStructureType() && Context.getTypeSize(Ty) == 0)
return ABIArgInfo::getIgnore();
// Expand structs with size <= 128-bits which consist only of
@@ -373,7 +403,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty,
return ABIArgInfo::getExpand();
}
- return ABIArgInfo::getIndirect(0);
+ return ABIArgInfo::getIndirect(getIndirectArgumentAlignment(Ty, Context));
} else {
return (Ty->isPromotableIntegerType() ?
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
OpenPOWER on IntegriCloud