[llvm-branch-commits] [cfe-branch] r134805 - in /cfe/branches/type-system-rewrite: ./ INPUTS/ include/clang/Basic/ lib/AST/ lib/Analysis/ lib/Basic/ lib/CodeGen/ lib/Frontend/ lib/Lex/ lib/Parse/ lib/Sema/ test/CodeGen/ test/CodeGenCXX/ test/CodeGenObjC/ test/Frontend/ test/Sema/ test/SemaCXX/ test/SemaObjC/ test/SemaObjCXX/ test/SemaTemplate/ tools/driver/
Chris Lattner
sabre at nondot.org
Sat Jul 9 00:09:13 PDT 2011
Author: lattner
Date: Sat Jul 9 02:09:12 2011
New Revision: 134805
URL: http://llvm.org/viewvc/llvm-project?rev=134805&view=rev
Log:
Merging r134685 through r134804 from mainline.
Added:
cfe/branches/type-system-rewrite/INPUTS/cfg-big-switch.c
- copied unchanged from r134804, cfe/trunk/INPUTS/cfg-big-switch.c
cfe/branches/type-system-rewrite/INPUTS/cfg-long-chain1.c
- copied unchanged from r134804, cfe/trunk/INPUTS/cfg-long-chain1.c
cfe/branches/type-system-rewrite/INPUTS/cfg-long-chain2.c
- copied unchanged from r134804, cfe/trunk/INPUTS/cfg-long-chain2.c
cfe/branches/type-system-rewrite/INPUTS/cfg-long-chain3.c
- copied unchanged from r134804, cfe/trunk/INPUTS/cfg-long-chain3.c
cfe/branches/type-system-rewrite/INPUTS/cfg-nested-switches.c
- copied unchanged from r134804, cfe/trunk/INPUTS/cfg-nested-switches.c
cfe/branches/type-system-rewrite/test/CodeGen/x86_32-arguments-nommx.c
- copied unchanged from r134804, cfe/trunk/test/CodeGen/x86_32-arguments-nommx.c
cfe/branches/type-system-rewrite/test/SemaTemplate/unresolved-construct.cpp
- copied unchanged from r134804, cfe/trunk/test/SemaTemplate/unresolved-construct.cpp
Modified:
cfe/branches/type-system-rewrite/ (props changed)
cfe/branches/type-system-rewrite/include/clang/Basic/Builtins.def
cfe/branches/type-system-rewrite/include/clang/Basic/DiagnosticSemaKinds.td
cfe/branches/type-system-rewrite/lib/AST/ExprCXX.cpp
cfe/branches/type-system-rewrite/lib/AST/ExprClassification.cpp
cfe/branches/type-system-rewrite/lib/Analysis/UninitializedValues.cpp
cfe/branches/type-system-rewrite/lib/Basic/Targets.cpp
cfe/branches/type-system-rewrite/lib/CodeGen/CGBuiltin.cpp
cfe/branches/type-system-rewrite/lib/CodeGen/CGClass.cpp
cfe/branches/type-system-rewrite/lib/CodeGen/CGDecl.cpp
cfe/branches/type-system-rewrite/lib/CodeGen/CGExprAgg.cpp
cfe/branches/type-system-rewrite/lib/CodeGen/CGObjC.cpp
cfe/branches/type-system-rewrite/lib/CodeGen/CodeGenFunction.cpp
cfe/branches/type-system-rewrite/lib/CodeGen/CodeGenFunction.h
cfe/branches/type-system-rewrite/lib/CodeGen/TargetInfo.cpp
cfe/branches/type-system-rewrite/lib/Frontend/DependencyFile.cpp
cfe/branches/type-system-rewrite/lib/Lex/HeaderSearch.cpp
cfe/branches/type-system-rewrite/lib/Parse/ParseExpr.cpp
cfe/branches/type-system-rewrite/lib/Sema/AnalysisBasedWarnings.cpp
cfe/branches/type-system-rewrite/lib/Sema/SemaCXXCast.cpp
cfe/branches/type-system-rewrite/lib/Sema/SemaExpr.cpp
cfe/branches/type-system-rewrite/lib/Sema/SemaExprCXX.cpp
cfe/branches/type-system-rewrite/lib/Sema/SemaTemplate.cpp
cfe/branches/type-system-rewrite/test/CodeGen/builtin-expect.c
cfe/branches/type-system-rewrite/test/CodeGen/libcalls.c
cfe/branches/type-system-rewrite/test/CodeGen/x86_32-arguments-darwin.c
cfe/branches/type-system-rewrite/test/CodeGen/x86_32-arguments-linux.c
cfe/branches/type-system-rewrite/test/CodeGenCXX/destructors.cpp
cfe/branches/type-system-rewrite/test/CodeGenCXX/temporaries.cpp
cfe/branches/type-system-rewrite/test/CodeGenCXX/value-init.cpp
cfe/branches/type-system-rewrite/test/CodeGenObjC/arc.m
cfe/branches/type-system-rewrite/test/Frontend/dependency-gen.c
cfe/branches/type-system-rewrite/test/Sema/x86-builtin-palignr.c
cfe/branches/type-system-rewrite/test/SemaCXX/warn-unreachable.cpp (props changed)
cfe/branches/type-system-rewrite/test/SemaObjC/arc-unavailable-for-weakref.m
cfe/branches/type-system-rewrite/test/SemaObjCXX/arc-unavailable-for-weakref.mm
cfe/branches/type-system-rewrite/tools/driver/cc1as_main.cpp
Propchange: cfe/branches/type-system-rewrite/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Jul 9 02:09:12 2011
@@ -1 +1,2 @@
+/cfe/trunk:134685-134804
/cfe/trunk/test/SemaTemplate:126920
Modified: cfe/branches/type-system-rewrite/include/clang/Basic/Builtins.def
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/include/clang/Basic/Builtins.def?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/include/clang/Basic/Builtins.def (original)
+++ cfe/branches/type-system-rewrite/include/clang/Basic/Builtins.def Sat Jul 9 02:09:12 2011
@@ -729,6 +729,10 @@
LIBBUILTIN(cosl, "LdLd", "fe", "math.h", ALL_LANGUAGES)
LIBBUILTIN(cosf, "ff", "fe", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fma, "dddd", "fc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fmal, "LdLdLdLd", "fc", "math.h", ALL_LANGUAGES)
+LIBBUILTIN(fmaf, "ffff", "fc", "math.h", ALL_LANGUAGES)
+
// Blocks runtime Builtin math library functions
LIBBUILTIN(_Block_object_assign, "vv*vC*iC", "f", "Blocks.h", ALL_LANGUAGES)
LIBBUILTIN(_Block_object_dispose, "vvC*iC", "f", "Blocks.h", ALL_LANGUAGES)
Modified: cfe/branches/type-system-rewrite/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/include/clang/Basic/DiagnosticSemaKinds.td?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/branches/type-system-rewrite/include/clang/Basic/DiagnosticSemaKinds.td Sat Jul 9 02:09:12 2011
@@ -2574,9 +2574,9 @@
"class is incompatible with __weak references">;
def err_arc_weak_unavailable_assign : Error<
"assignment of a weak-unavailable object to a __weak object">;
-def err_arc_cast_of_weak_unavailable : Error<
- "cast of weak-unavailable object of type %0 to"
- " a __weak object of type %1">;
+def err_arc_convesion_of_weak_unavailable : Error<
+ "%select{implicit conversion|cast}0 of weak-unavailable object of type %1 to"
+ " a __weak object of type %2">;
def err_arc_illegal_explicit_message : Error<
"ARC forbids explicit message send of %0">;
def err_arc_unused_init_message : Error<
Modified: cfe/branches/type-system-rewrite/lib/AST/ExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/lib/AST/ExprCXX.cpp?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/lib/AST/ExprCXX.cpp (original)
+++ cfe/branches/type-system-rewrite/lib/AST/ExprCXX.cpp Sat Jul 9 02:09:12 2011
@@ -725,7 +725,10 @@
SourceLocation RParenLoc)
: Expr(CXXUnresolvedConstructExprClass,
Type->getType().getNonReferenceType(),
- VK_LValue, OK_Ordinary,
+ (Type->getType()->isLValueReferenceType() ? VK_LValue
+ :Type->getType()->isRValueReferenceType()? VK_XValue
+ :VK_RValue),
+ OK_Ordinary,
Type->getType()->isDependentType(), true, true,
Type->getType()->containsUnexpandedParameterPack()),
Type(Type),
Modified: cfe/branches/type-system-rewrite/lib/AST/ExprClassification.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/lib/AST/ExprClassification.cpp?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/lib/AST/ExprClassification.cpp (original)
+++ cfe/branches/type-system-rewrite/lib/AST/ExprClassification.cpp Sat Jul 9 02:09:12 2011
@@ -117,7 +117,6 @@
case Expr::UnresolvedLookupExprClass:
case Expr::UnresolvedMemberExprClass:
case Expr::CXXDependentScopeMemberExprClass:
- case Expr::CXXUnresolvedConstructExprClass:
case Expr::DependentScopeDeclRefExprClass:
// ObjC instance variables are lvalues
// FIXME: ObjC++0x might have different rules
@@ -295,6 +294,10 @@
if (!Lang.CPlusPlus) return Cl::CL_PRValue;
return ClassifyUnnamed(Ctx, cast<ExplicitCastExpr>(E)->getTypeAsWritten());
+ case Expr::CXXUnresolvedConstructExprClass:
+ return ClassifyUnnamed(Ctx,
+ cast<CXXUnresolvedConstructExpr>(E)->getTypeAsWritten());
+
case Expr::BinaryConditionalOperatorClass: {
if (!Lang.CPlusPlus) return Cl::CL_PRValue;
const BinaryConditionalOperator *co = cast<BinaryConditionalOperator>(E);
Modified: cfe/branches/type-system-rewrite/lib/Analysis/UninitializedValues.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/lib/Analysis/UninitializedValues.cpp?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/lib/Analysis/UninitializedValues.cpp (original)
+++ cfe/branches/type-system-rewrite/lib/Analysis/UninitializedValues.cpp Sat Jul 9 02:09:12 2011
@@ -288,28 +288,28 @@
public:
DataflowWorklist(const CFG &cfg) : enqueuedBlocks(cfg.getNumBlockIDs()) {}
- void enqueue(const CFGBlock *block);
void enqueueSuccessors(const CFGBlock *block);
const CFGBlock *dequeue();
-
};
}
-void DataflowWorklist::enqueue(const CFGBlock *block) {
- if (!block)
- return;
- unsigned idx = block->getBlockID();
- if (enqueuedBlocks[idx])
- return;
- worklist.push_back(block);
- enqueuedBlocks[idx] = true;
-}
-
void DataflowWorklist::enqueueSuccessors(const clang::CFGBlock *block) {
+ unsigned OldWorklistSize = worklist.size();
for (CFGBlock::const_succ_iterator I = block->succ_begin(),
E = block->succ_end(); I != E; ++I) {
- enqueue(*I);
+ const CFGBlock *Successor = *I;
+ if (!Successor || enqueuedBlocks[Successor->getBlockID()])
+ continue;
+ worklist.push_back(Successor);
+ enqueuedBlocks[Successor->getBlockID()] = true;
}
+ if (OldWorklistSize == 0 || OldWorklistSize == worklist.size())
+ return;
+
+ // Rotate the newly added blocks to the start of the worklist so that it forms
+ // a proper queue when we pop off the end of the worklist.
+ std::rotate(worklist.begin(), worklist.begin() + OldWorklistSize,
+ worklist.end());
}
const CFGBlock *DataflowWorklist::dequeue() {
Modified: cfe/branches/type-system-rewrite/lib/Basic/Targets.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/lib/Basic/Targets.cpp?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/lib/Basic/Targets.cpp (original)
+++ cfe/branches/type-system-rewrite/lib/Basic/Targets.cpp Sat Jul 9 02:09:12 2011
@@ -1110,18 +1110,18 @@
// most of the implementation can be shared.
class X86TargetInfo : public TargetInfo {
enum X86SSEEnum {
- NoMMXSSE, MMX, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
+ NoSSE, SSE1, SSE2, SSE3, SSSE3, SSE41, SSE42
} SSELevel;
- enum AMD3DNowEnum {
- NoAMD3DNow, AMD3DNow, AMD3DNowAthlon
- } AMD3DNowLevel;
+ enum MMX3DNowEnum {
+ NoMMX3DNow, MMX, AMD3DNow, AMD3DNowAthlon
+ } MMX3DNowLevel;
bool HasAES;
bool HasAVX;
public:
X86TargetInfo(const std::string& triple)
- : TargetInfo(triple), SSELevel(NoMMXSSE), AMD3DNowLevel(NoAMD3DNow),
+ : TargetInfo(triple), SSELevel(NoSSE), MMX3DNowLevel(NoMMX3DNow),
HasAES(false), HasAVX(false) {
LongDoubleFormat = &llvm::APFloat::x87DoubleExtended;
}
@@ -1159,6 +1159,9 @@
virtual void getDefaultFeatures(const std::string &CPU,
llvm::StringMap<bool> &Features) const;
virtual void HandleTargetFeatures(std::vector<std::string> &Features);
+ virtual const char* getABI() const {
+ return MMX3DNowLevel == NoMMX3DNow ? "no-mmx" : "";
+ }
};
void X86TargetInfo::getDefaultFeatures(const std::string &CPU,
@@ -1190,23 +1193,31 @@
;
else if (CPU == "pentium-mmx" || CPU == "pentium2")
setFeatureEnabled(Features, "mmx", true);
- else if (CPU == "pentium3")
+ else if (CPU == "pentium3") {
+ setFeatureEnabled(Features, "mmx", true);
setFeatureEnabled(Features, "sse", true);
- else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64")
+ } else if (CPU == "pentium-m" || CPU == "pentium4" || CPU == "x86-64") {
+ setFeatureEnabled(Features, "mmx", true);
setFeatureEnabled(Features, "sse2", true);
- else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona")
+ } else if (CPU == "yonah" || CPU == "prescott" || CPU == "nocona") {
+ setFeatureEnabled(Features, "mmx", true);
setFeatureEnabled(Features, "sse3", true);
- else if (CPU == "core2")
+ } else if (CPU == "core2") {
+ setFeatureEnabled(Features, "mmx", true);
setFeatureEnabled(Features, "ssse3", true);
- else if (CPU == "penryn") {
+ } else if (CPU == "penryn") {
+ setFeatureEnabled(Features, "mmx", true);
setFeatureEnabled(Features, "sse4", true);
Features["sse42"] = false;
- } else if (CPU == "atom")
+ } else if (CPU == "atom") {
+ setFeatureEnabled(Features, "mmx", true);
setFeatureEnabled(Features, "sse3", true);
- else if (CPU == "corei7") {
+ } else if (CPU == "corei7") {
+ setFeatureEnabled(Features, "mmx", true);
setFeatureEnabled(Features, "sse4", true);
setFeatureEnabled(Features, "aes", true);
} else if (CPU == "corei7-avx") {
+ setFeatureEnabled(Features, "mmx", true);
setFeatureEnabled(Features, "sse4", true);
setFeatureEnabled(Features, "aes", true);
// setFeatureEnabled(Features, "avx", true);
@@ -1214,7 +1225,6 @@
setFeatureEnabled(Features, "mmx", true);
else if (CPU == "k6-2" || CPU == "k6-3" || CPU == "athlon" ||
CPU == "athlon-tbird" || CPU == "winchip2" || CPU == "c3") {
- setFeatureEnabled(Features, "mmx", true);
setFeatureEnabled(Features, "3dnow", true);
} else if (CPU == "athlon-4" || CPU == "athlon-xp" || CPU == "athlon-mp") {
setFeatureEnabled(Features, "sse", true);
@@ -1226,8 +1236,10 @@
} else if (CPU == "k8-sse3") {
setFeatureEnabled(Features, "sse3", true);
setFeatureEnabled(Features, "3dnowa", true);
- } else if (CPU == "c3-2")
+ } else if (CPU == "c3-2") {
+ setFeatureEnabled(Features, "mmx", true);
setFeatureEnabled(Features, "sse", true);
+ }
}
bool X86TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
@@ -1243,34 +1255,31 @@
if (Name == "mmx")
Features["mmx"] = true;
else if (Name == "sse")
- Features["mmx"] = Features["sse"] = true;
+ Features["sse"] = true;
else if (Name == "sse2")
- Features["mmx"] = Features["sse"] = Features["sse2"] = true;
+ Features["sse"] = Features["sse2"] = true;
else if (Name == "sse3")
- Features["mmx"] = Features["sse"] = Features["sse2"] =
- Features["sse3"] = true;
+ Features["sse"] = Features["sse2"] = Features["sse3"] = true;
else if (Name == "ssse3")
- Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
+ Features["sse"] = Features["sse2"] = Features["sse3"] =
Features["ssse3"] = true;
else if (Name == "sse4" || Name == "sse4.2")
- Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
+ Features["sse"] = Features["sse2"] = Features["sse3"] =
Features["ssse3"] = Features["sse41"] = Features["sse42"] = true;
else if (Name == "sse4.1")
- Features["mmx"] = Features["sse"] = Features["sse2"] = Features["sse3"] =
+ Features["sse"] = Features["sse2"] = Features["sse3"] =
Features["ssse3"] = Features["sse41"] = true;
else if (Name == "3dnow")
- Features["3dnowa"] = true;
+ Features["mmx"] = Features["3dnow"] = true;
else if (Name == "3dnowa")
- Features["3dnow"] = Features["3dnowa"] = true;
+ Features["mmx"] = Features["3dnow"] = Features["3dnowa"] = true;
else if (Name == "aes")
Features["aes"] = true;
else if (Name == "avx")
Features["avx"] = true;
} else {
if (Name == "mmx")
- Features["mmx"] = Features["3dnow"] = Features["3dnowa"] =
- Features["sse"] = Features["sse2"] = Features["sse3"] =
- Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
+ Features["mmx"] = Features["3dnow"] = Features["3dnowa"] = false;
else if (Name == "sse")
Features["sse"] = Features["sse2"] = Features["sse3"] =
Features["ssse3"] = Features["sse41"] = Features["sse42"] = false;
@@ -1328,18 +1337,25 @@
.Case("sse3", SSE3)
.Case("sse2", SSE2)
.Case("sse", SSE1)
- .Case("mmx", MMX)
- .Default(NoMMXSSE);
+ .Default(NoSSE);
SSELevel = std::max(SSELevel, Level);
- AMD3DNowEnum ThreeDNowLevel =
- llvm::StringSwitch<AMD3DNowEnum>(Features[i].substr(1))
+ MMX3DNowEnum ThreeDNowLevel =
+ llvm::StringSwitch<MMX3DNowEnum>(Features[i].substr(1))
.Case("3dnowa", AMD3DNowAthlon)
.Case("3dnow", AMD3DNow)
- .Default(NoAMD3DNow);
+ .Case("mmx", MMX)
+ .Default(NoMMX3DNow);
- AMD3DNowLevel = std::max(AMD3DNowLevel, ThreeDNowLevel);
+ MMX3DNowLevel = std::max(MMX3DNowLevel, ThreeDNowLevel);
}
+
+ // Don't tell the backend if we're turning off mmx; it will end up disabling
+ // SSE, which we don't want.
+ std::vector<std::string>::iterator it;
+ it = std::find(Features.begin(), Features.end(), "-mmx");
+ if (it != Features.end())
+ Features.erase(it);
}
/// X86TargetInfo::getTargetDefines - Return a set of the X86-specific #defines
@@ -1394,9 +1410,7 @@
case SSE1:
Builder.defineMacro("__SSE__");
Builder.defineMacro("__SSE_MATH__"); // -mfp-math=sse always implied.
- case MMX:
- Builder.defineMacro("__MMX__");
- case NoMMXSSE:
+ case NoSSE:
break;
}
@@ -1418,12 +1432,14 @@
}
// Each case falls through to the previous one here.
- switch (AMD3DNowLevel) {
+ switch (MMX3DNowLevel) {
case AMD3DNowAthlon:
Builder.defineMacro("__3dNOW_A__");
case AMD3DNow:
Builder.defineMacro("__3dNOW__");
- case NoAMD3DNow:
+ case MMX:
+ Builder.defineMacro("__MMX__");
+ case NoMMX3DNow:
break;
}
}
@@ -1967,11 +1983,6 @@
void getDefaultFeatures(const std::string &CPU,
llvm::StringMap<bool> &Features) const {
- // FIXME: This should not be here.
- Features["vfp2"] = false;
- Features["vfp3"] = false;
- Features["neon"] = false;
-
if (CPU == "arm1136jf-s" || CPU == "arm1176jzf-s" || CPU == "mpcore")
Features["vfp2"] = true;
else if (CPU == "cortex-a8" || CPU == "cortex-a9")
@@ -1981,12 +1992,8 @@
virtual bool setFeatureEnabled(llvm::StringMap<bool> &Features,
const std::string &Name,
bool Enabled) const {
- if (Name == "soft-float" || Name == "soft-float-abi") {
- Features[Name] = Enabled;
- } else if (Name == "vfp2" || Name == "vfp3" || Name == "neon") {
- // These effectively are a single option, reset them when any is enabled.
- if (Enabled)
- Features["vfp2"] = Features["vfp3"] = Features["neon"] = false;
+ if (Name == "soft-float" || Name == "soft-float-abi" ||
+ Name == "vfp2" || Name == "vfp3" || Name == "neon") {
Features[Name] = Enabled;
} else
return false;
Modified: cfe/branches/type-system-rewrite/lib/CodeGen/CGBuiltin.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/lib/CodeGen/CGBuiltin.cpp?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/branches/type-system-rewrite/lib/CodeGen/CGBuiltin.cpp Sat Jul 9 02:09:12 2011
@@ -22,6 +22,7 @@
#include "clang/Basic/TargetBuiltins.h"
#include "llvm/Intrinsics.h"
#include "llvm/Target/TargetData.h"
+
using namespace clang;
using namespace CodeGen;
using namespace llvm;
@@ -312,11 +313,16 @@
return RValue::get(Result);
}
case Builtin::BI__builtin_expect: {
- // FIXME: pass expect through to LLVM
Value *ArgValue = EmitScalarExpr(E->getArg(0));
- if (E->getArg(1)->HasSideEffects(getContext()))
- (void)EmitScalarExpr(E->getArg(1));
- return RValue::get(ArgValue);
+ const llvm::Type *ArgType = ArgValue->getType();
+
+ Value *FnExpect = CGM.getIntrinsic(Intrinsic::expect, &ArgType, 1);
+ Value *ExpectedValue = EmitScalarExpr(E->getArg(1));
+
+ Value *Result = Builder.CreateCall2(FnExpect, ArgValue, ExpectedValue,
+ "expval");
+ return RValue::get(Result);
+
}
case Builtin::BI__builtin_bswap32:
case Builtin::BI__builtin_bswap64: {
@@ -984,6 +990,22 @@
return RValue::get(Builder.CreateCall2(F, Base, Exponent, "tmp"));
}
+ case Builtin::BIfma:
+ case Builtin::BIfmaf:
+ case Builtin::BIfmal:
+ case Builtin::BI__builtin_fma:
+ case Builtin::BI__builtin_fmaf:
+ case Builtin::BI__builtin_fmal: {
+ // Rewrite fma to intrinsic.
+ Value *FirstArg = EmitScalarExpr(E->getArg(0));
+ const llvm::Type *ArgType = FirstArg->getType();
+ Value *F = CGM.getIntrinsic(Intrinsic::fma, &ArgType, 1);
+ return RValue::get(Builder.CreateCall3(F, FirstArg,
+ EmitScalarExpr(E->getArg(1)),
+ EmitScalarExpr(E->getArg(2)),
+ "tmp"));
+ }
+
case Builtin::BI__builtin_signbit:
case Builtin::BI__builtin_signbitf:
case Builtin::BI__builtin_signbitl: {
Modified: cfe/branches/type-system-rewrite/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/lib/CodeGen/CGClass.cpp?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/lib/CodeGen/CGClass.cpp (original)
+++ cfe/branches/type-system-rewrite/lib/CodeGen/CGClass.cpp Sat Jul 9 02:09:12 2011
@@ -1172,6 +1172,17 @@
EmitBlock(AfterFor, true);
}
+void CodeGenFunction::destroyCXXObject(CodeGenFunction &CGF,
+ llvm::Value *addr,
+ QualType type) {
+ const RecordType *rtype = type->castAs<RecordType>();
+ const CXXRecordDecl *record = cast<CXXRecordDecl>(rtype->getDecl());
+ const CXXDestructorDecl *dtor = record->getDestructor();
+ assert(!dtor->isTrivial());
+ CGF.EmitCXXDestructorCall(dtor, Dtor_Complete, /*for vbase*/ false,
+ addr);
+}
+
/// EmitCXXAggrDestructorCall - calls the default destructor on array
/// elements in reverse order of construction.
void
Modified: cfe/branches/type-system-rewrite/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/lib/CodeGen/CGDecl.cpp?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/branches/type-system-rewrite/lib/CodeGen/CGDecl.cpp Sat Jul 9 02:09:12 2011
@@ -304,30 +304,25 @@
}
namespace {
- struct CallArrayDtor : EHScopeStack::Cleanup {
- CallArrayDtor(const CXXDestructorDecl *Dtor,
- const ConstantArrayType *Type,
- llvm::Value *Loc)
- : Dtor(Dtor), Type(Type), Loc(Loc) {}
-
- const CXXDestructorDecl *Dtor;
- const ConstantArrayType *Type;
- llvm::Value *Loc;
+ struct DestroyObject : EHScopeStack::Cleanup {
+ DestroyObject(llvm::Value *addr, QualType type,
+ CodeGenFunction::Destroyer *destroyer)
+ : addr(addr), type(type), destroyer(*destroyer) {}
+
+ llvm::Value *addr;
+ QualType type;
+ CodeGenFunction::Destroyer &destroyer;
void Emit(CodeGenFunction &CGF, bool IsForEH) {
- QualType BaseElementTy = CGF.getContext().getBaseElementType(Type);
- const llvm::Type *BasePtr = CGF.ConvertType(BaseElementTy);
- BasePtr = llvm::PointerType::getUnqual(BasePtr);
- llvm::Value *BaseAddrPtr = CGF.Builder.CreateBitCast(Loc, BasePtr);
- CGF.EmitCXXAggrDestructorCall(Dtor, Type, BaseAddrPtr);
+ CGF.emitDestroy(addr, type, destroyer);
}
};
- struct CallVarDtor : EHScopeStack::Cleanup {
- CallVarDtor(const CXXDestructorDecl *Dtor,
- llvm::Value *NRVOFlag,
- llvm::Value *Loc)
- : Dtor(Dtor), NRVOFlag(NRVOFlag), Loc(Loc) {}
+ struct DestroyNRVOVariable : EHScopeStack::Cleanup {
+ DestroyNRVOVariable(llvm::Value *addr,
+ const CXXDestructorDecl *Dtor,
+ llvm::Value *NRVOFlag)
+ : Dtor(Dtor), NRVOFlag(NRVOFlag), Loc(addr) {}
const CXXDestructorDecl *Dtor;
llvm::Value *NRVOFlag;
@@ -1014,6 +1009,59 @@
}
}
+/// Enter a destroy cleanup for the given local variable.
+void CodeGenFunction::emitAutoVarTypeCleanup(
+ const CodeGenFunction::AutoVarEmission &emission,
+ QualType::DestructionKind dtorKind) {
+ assert(dtorKind != QualType::DK_none);
+
+ // Note that for __block variables, we want to destroy the
+ // original stack object, not the possibly forwarded object.
+ llvm::Value *addr = emission.getObjectAddress(*this);
+
+ const VarDecl *var = emission.Variable;
+ QualType type = var->getType();
+
+ CleanupKind cleanupKind = NormalAndEHCleanup;
+ CodeGenFunction::Destroyer *destroyer = 0;
+
+ switch (dtorKind) {
+ case QualType::DK_none:
+ llvm_unreachable("no cleanup for trivially-destructible variable");
+
+ case QualType::DK_cxx_destructor:
+ // If there's an NRVO flag on the emission, we need a different
+ // cleanup.
+ if (emission.NRVOFlag) {
+ assert(!type->isArrayType());
+ CXXDestructorDecl *dtor = type->getAsCXXRecordDecl()->getDestructor();
+ EHStack.pushCleanup<DestroyNRVOVariable>(cleanupKind, addr, dtor,
+ emission.NRVOFlag);
+ return;
+ }
+ break;
+
+ case QualType::DK_objc_strong_lifetime:
+ // Suppress cleanups for pseudo-strong variables.
+ if (var->isARCPseudoStrong()) return;
+
+ // Otherwise, consider whether to use an EH cleanup or not.
+ cleanupKind = getARCCleanupKind();
+
+ // Use the imprecise destroyer by default.
+ if (!var->hasAttr<ObjCPreciseLifetimeAttr>())
+ destroyer = CodeGenFunction::destroyARCStrongImprecise;
+ break;
+
+ case QualType::DK_objc_weak_lifetime:
+ break;
+ }
+
+ // If we haven't chosen a more specific destroyer, use the default.
+ if (!destroyer) destroyer = &getDestroyer(dtorKind);
+ EHStack.pushCleanup<DestroyObject>(cleanupKind, addr, type, destroyer);
+}
+
void CodeGenFunction::EmitAutoVarCleanups(const AutoVarEmission &emission) {
assert(emission.Variable && "emission was not valid!");
@@ -1022,44 +1070,9 @@
const VarDecl &D = *emission.Variable;
- // Handle C++ or ARC destruction of variables.
- if (getLangOptions().CPlusPlus) {
- QualType type = D.getType();
- QualType baseType = getContext().getBaseElementType(type);
- if (const RecordType *RT = baseType->getAs<RecordType>()) {
- CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(RT->getDecl());
- if (!ClassDecl->hasTrivialDestructor()) {
- // Note: We suppress the destructor call when the corresponding NRVO
- // flag has been set.
-
- // Note that for __block variables, we want to destroy the
- // original stack object, not the possible forwarded object.
- llvm::Value *Loc = emission.getObjectAddress(*this);
-
- const CXXDestructorDecl *D = ClassDecl->getDestructor();
- assert(D && "EmitLocalBlockVarDecl - destructor is nul");
-
- if (type != baseType) {
- const ConstantArrayType *Array =
- getContext().getAsConstantArrayType(type);
- assert(Array && "types changed without array?");
- EHStack.pushCleanup<CallArrayDtor>(NormalAndEHCleanup,
- D, Array, Loc);
- } else {
- EHStack.pushCleanup<CallVarDtor>(NormalAndEHCleanup,
- D, emission.NRVOFlag, Loc);
- }
- }
- }
- }
-
- if (Qualifiers::ObjCLifetime lifetime
- = D.getType().getQualifiers().getObjCLifetime()) {
- if (!D.isARCPseudoStrong()) {
- llvm::Value *loc = emission.getObjectAddress(*this);
- EmitAutoVarWithLifetime(*this, D, loc, lifetime);
- }
- }
+ // Check the type for a cleanup.
+ if (QualType::DestructionKind dtorKind = D.getType().isDestructedType())
+ emitAutoVarTypeCleanup(emission, dtorKind);
// In GC mode, honor objc_precise_lifetime.
if (getLangOptions().getGCMode() != LangOptions::NonGC &&
@@ -1084,6 +1097,152 @@
enterByrefCleanup(emission);
}
+CodeGenFunction::Destroyer &
+CodeGenFunction::getDestroyer(QualType::DestructionKind kind) {
+ // GCC 4.2 requires the *& on these function references.
+ switch (kind) {
+ case QualType::DK_none: llvm_unreachable("no destroyer for trivial dtor");
+ case QualType::DK_cxx_destructor: return *&destroyCXXObject;
+ case QualType::DK_objc_strong_lifetime: return *&destroyARCStrongPrecise;
+ case QualType::DK_objc_weak_lifetime: return *&destroyARCWeak;
+ }
+}
+
+void CodeGenFunction::pushDestroy(CleanupKind cleanupKind, llvm::Value *addr,
+ QualType type, Destroyer &destroyer) {
+ EHStack.pushCleanup<DestroyObject>(cleanupKind, addr, type, destroyer);
+}
+
+void CodeGenFunction::emitDestroy(llvm::Value *addr, QualType type,
+ Destroyer &destroyer) {
+ const ArrayType *arrayType = getContext().getAsArrayType(type);
+ if (!arrayType)
+ return destroyer(*this, addr, type);
+
+ llvm::Value *begin = addr;
+ llvm::Value *length = emitArrayLength(arrayType, type, begin);
+ llvm::Value *end = Builder.CreateInBoundsGEP(begin, length);
+ emitArrayDestroy(begin, end, type, destroyer);
+}
+
+void CodeGenFunction::emitArrayDestroy(llvm::Value *begin,
+ llvm::Value *end,
+ QualType type,
+ Destroyer &destroyer) {
+ assert(!type->isArrayType());
+
+ // The basic structure here is a do-while loop, because we don't
+ // need to check for the zero-element case.
+ llvm::BasicBlock *bodyBB = createBasicBlock("arraydestroy.body");
+ llvm::BasicBlock *doneBB = createBasicBlock("arraydestroy.done");
+
+ // Enter the loop body, making that address the current address.
+ llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
+ EmitBlock(bodyBB);
+ llvm::PHINode *elementPast =
+ Builder.CreatePHI(begin->getType(), 2, "arraydestroy.elementPast");
+ elementPast->addIncoming(end, entryBB);
+
+ // Shift the address back by one element.
+ llvm::Value *negativeOne = llvm::ConstantInt::get(SizeTy, -1, true);
+ llvm::Value *element = Builder.CreateInBoundsGEP(elementPast, negativeOne,
+ "arraydestroy.element");
+
+ // Perform the actual destruction there.
+ destroyer(*this, element, type);
+
+ // Check whether we've reached the end.
+ llvm::Value *done = Builder.CreateICmpEQ(element, begin, "arraydestroy.done");
+ Builder.CreateCondBr(done, doneBB, bodyBB);
+ elementPast->addIncoming(element, Builder.GetInsertBlock());
+
+ // Done.
+ EmitBlock(doneBB);
+}
+
+namespace {
+ class PartialArrayDestroy : public EHScopeStack::Cleanup {
+ llvm::Value *ArrayBegin;
+ llvm::Value *ArrayEndPointer;
+ QualType ElementType;
+ CodeGenFunction::Destroyer &Destroyer;
+ public:
+ PartialArrayDestroy(llvm::Value *arrayBegin, llvm::Value *arrayEndPointer,
+ QualType elementType,
+ CodeGenFunction::Destroyer *destroyer)
+ : ArrayBegin(arrayBegin), ArrayEndPointer(arrayEndPointer),
+ ElementType(elementType), Destroyer(*destroyer) {}
+
+ void Emit(CodeGenFunction &CGF, bool isForEH) {
+ llvm::Value *arrayBegin = ArrayBegin;
+ llvm::Value *arrayEnd = CGF.Builder.CreateLoad(ArrayEndPointer);
+
+ // It's possible for the count to be zero here, so we're going
+ // to need a check. For the sake of prettier IR, we just want
+ // to jump to the end of the array destroy loop. This assumes
+ // the structure of the IR generated by emitArrayDestroy, but
+ // that assumption is pretty reliable.
+ llvm::Value *earlyTest =
+ CGF.Builder.CreateICmpEQ(arrayBegin, arrayEnd, "pad.isempty");
+
+ llvm::BasicBlock *nextBB = CGF.createBasicBlock("pad.arraydestroy");
+
+ // For now, use a conditional branch with both successors the
+ // same. We'll patch this later.
+ llvm::BranchInst *br =
+ CGF.Builder.CreateCondBr(earlyTest, nextBB, nextBB);
+ CGF.EmitBlock(nextBB);
+
+ llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0);
+
+ // If the element type is itself an array, drill down.
+ QualType type = ElementType;
+ llvm::SmallVector<llvm::Value*,4> gepIndices;
+ gepIndices.push_back(zero);
+ while (const ArrayType *arrayType = CGF.getContext().getAsArrayType(type)) {
+ // VLAs don't require a GEP index to walk into.
+ if (!isa<VariableArrayType>(arrayType))
+ gepIndices.push_back(zero);
+ type = arrayType->getElementType();
+ }
+ if (gepIndices.size() != 1) {
+ arrayBegin =
+ CGF.Builder.CreateInBoundsGEP(arrayBegin, gepIndices.begin(),
+ gepIndices.end(), "pad.arraybegin");
+ arrayEnd =
+ CGF.Builder.CreateInBoundsGEP(arrayEnd, gepIndices.begin(),
+ gepIndices.end(), "pad.arrayend");
+ }
+
+ CGF.emitArrayDestroy(arrayBegin, arrayEnd, type, Destroyer);
+
+ // Set the conditional branch's 'false' successor to doneBB.
+ llvm::BasicBlock *doneBB = CGF.Builder.GetInsertBlock();
+ assert(CGF.Builder.GetInsertPoint() == doneBB->begin());
+ br->setSuccessor(1, doneBB);
+ }
+ };
+}
+
+/// pushPartialArrayCleanup - Push a cleanup to destroy
+/// already-constructed elements of the given array. The cleanup
+/// may be popped with DeactivateCleanupBlock.
+///
+/// \param elementType - the immediate element type of the array;
+/// possibly still an array type
+/// \param array - a value of type elementType*
+/// \param destructionKind - the kind of destruction required
+/// \param initializedElementCount - a value of type size_t* holding
+/// the number of successfully-constructed elements
+void CodeGenFunction::pushPartialArrayCleanup(llvm::Value *array,
+ QualType elementType,
+ Destroyer &destroyer,
+ llvm::Value *arrayEndPointer) {
+ // FIXME: can this be in a conditional expression?
+ EHStack.pushCleanup<PartialArrayDestroy>(EHCleanup, array, arrayEndPointer,
+ elementType, &destroyer);
+}
+
namespace {
/// A cleanup to perform a release of an object at the end of a
/// function. This is used to balance out the incoming +1 of a
Modified: cfe/branches/type-system-rewrite/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/lib/CodeGen/CGExprAgg.cpp?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/branches/type-system-rewrite/lib/CodeGen/CGExprAgg.cpp Sat Jul 9 02:09:12 2011
@@ -661,45 +661,132 @@
}
uint64_t NumArrayElements = AType->getNumElements();
- QualType ElementType = CGF.getContext().getCanonicalType(E->getType());
- ElementType = CGF.getContext().getAsArrayType(ElementType)->getElementType();
- ElementType = CGF.getContext().getQualifiedType(ElementType,
- Dest.getQualifiers());
-
- bool hasNonTrivialCXXConstructor = false;
- if (CGF.getContext().getLangOptions().CPlusPlus)
- if (const RecordType *RT = CGF.getContext()
- .getBaseElementType(ElementType)->getAs<RecordType>()) {
- const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
- hasNonTrivialCXXConstructor = !RD->hasTrivialDefaultConstructor();
- }
+ assert(NumInitElements <= NumArrayElements);
- for (uint64_t i = 0; i != NumArrayElements; ++i) {
- // If we're done emitting initializers and the destination is known-zeroed
- // then we're done.
- if (i == NumInitElements &&
- Dest.isZeroed() &&
- CGF.getTypes().isZeroInitializable(ElementType) &&
- !hasNonTrivialCXXConstructor)
- break;
+ QualType elementType = E->getType().getCanonicalType();
+ elementType = CGF.getContext().getQualifiedType(
+ cast<ArrayType>(elementType)->getElementType(),
+ elementType.getQualifiers() + Dest.getQualifiers());
+
+ // DestPtr is an array*. Construct an elementType* by drilling
+ // down a level.
+ llvm::Value *zero = llvm::ConstantInt::get(CGF.SizeTy, 0);
+ llvm::Value *indices[] = { zero, zero };
+ llvm::Value *begin =
+ Builder.CreateInBoundsGEP(DestPtr, indices, indices+2, "arrayinit.begin");
+
+ // Exception safety requires us to destroy all the
+ // already-constructed members if an initializer throws.
+ // For that, we'll need an EH cleanup.
+ QualType::DestructionKind dtorKind = elementType.isDestructedType();
+ llvm::AllocaInst *endOfInit = 0;
+ EHScopeStack::stable_iterator cleanup;
+ if (CGF.needsEHCleanup(dtorKind)) {
+ // In principle we could tell the cleanup where we are more
+ // directly, but the control flow can get so varied here that it
+ // would actually be quite complex. Therefore we go through an
+ // alloca.
+ endOfInit = CGF.CreateTempAlloca(begin->getType(),
+ "arrayinit.endOfInit");
+ Builder.CreateStore(begin, endOfInit);
+ CGF.pushPartialArrayCleanup(begin, elementType,
+ CGF.getDestroyer(dtorKind), endOfInit);
+ cleanup = CGF.EHStack.stable_begin();
- llvm::Value *NextVal = Builder.CreateStructGEP(DestPtr, i, ".array");
- LValue LV = CGF.MakeAddrLValue(NextVal, ElementType);
-
- if (i < NumInitElements)
- EmitInitializationToLValue(E->getInit(i), LV);
- else if (Expr *filler = E->getArrayFiller())
- EmitInitializationToLValue(filler, LV);
+ // Otherwise, remember that we didn't need a cleanup.
+ } else {
+ dtorKind = QualType::DK_none;
+ }
+
+ llvm::Value *one = llvm::ConstantInt::get(CGF.SizeTy, 1);
+
+ // The 'current element to initialize'. The invariants on this
+ // variable are complicated. Essentially, after each iteration of
+ // the loop, it points to the last initialized element, except
+ // that it points to the beginning of the array before any
+ // elements have been initialized.
+ llvm::Value *element = begin;
+
+ // Emit the explicit initializers.
+ for (uint64_t i = 0; i != NumInitElements; ++i) {
+ // Advance to the next element.
+ if (i > 0)
+ element = Builder.CreateInBoundsGEP(element, one, "arrayinit.element");
+
+ LValue elementLV = CGF.MakeAddrLValue(element, elementType);
+ EmitInitializationToLValue(E->getInit(i), elementLV);
+
+ // Tell the cleanup that it needs to destroy this element.
+ // TODO: some of these stores can be trivially observed to be
+ // unnecessary.
+ if (endOfInit) Builder.CreateStore(element, endOfInit);
+ }
+
+ // Check whether there's a non-trivial array-fill expression.
+ // Note that this will be a CXXConstructExpr even if the element
+ // type is an array (or array of array, etc.) of class type.
+ Expr *filler = E->getArrayFiller();
+ bool hasTrivialFiller = true;
+ if (CXXConstructExpr *cons = dyn_cast_or_null<CXXConstructExpr>(filler)) {
+ assert(cons->getConstructor()->isDefaultConstructor());
+ hasTrivialFiller = cons->getConstructor()->isTrivial();
+ }
+
+ // Any remaining elements need to be zero-initialized, possibly
+ // using the filler expression. We can skip this if the we're
+ // emitting to zeroed memory.
+ if (NumInitElements != NumArrayElements &&
+ !(Dest.isZeroed() && hasTrivialFiller &&
+ CGF.getTypes().isZeroInitializable(elementType))) {
+
+ // Use an actual loop. This is basically
+ // do { *array++ = filler; } while (array != end);
+
+ // Advance to the start of the rest of the array.
+ if (NumInitElements)
+ element = Builder.CreateInBoundsGEP(element, one, "arrayinit.start");
+
+ // Compute the end of the array.
+ llvm::Value *end = Builder.CreateInBoundsGEP(begin,
+ llvm::ConstantInt::get(CGF.SizeTy, NumArrayElements),
+ "arrayinit.end");
+
+ llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
+ llvm::BasicBlock *bodyBB = CGF.createBasicBlock("arrayinit.body");
+
+ // Jump into the body.
+ CGF.EmitBlock(bodyBB);
+ llvm::PHINode *currentElement =
+ Builder.CreatePHI(element->getType(), 2, "arrayinit.cur");
+ currentElement->addIncoming(element, entryBB);
+
+ // Emit the actual filler expression.
+ LValue elementLV = CGF.MakeAddrLValue(currentElement, elementType);
+ if (filler)
+ EmitInitializationToLValue(filler, elementLV);
else
- EmitNullInitializationToLValue(LV);
-
- // If the GEP didn't get used because of a dead zero init or something
- // else, clean it up for -O0 builds and general tidiness.
- if (llvm::GetElementPtrInst *GEP =
- dyn_cast<llvm::GetElementPtrInst>(NextVal))
- if (GEP->use_empty())
- GEP->eraseFromParent();
+ EmitNullInitializationToLValue(elementLV);
+
+ // Tell the EH cleanup that we finished with that element.
+ if (endOfInit) Builder.CreateStore(element, endOfInit);
+
+ // Move on to the next element.
+ llvm::Value *nextElement =
+ Builder.CreateInBoundsGEP(currentElement, one, "arrayinit.next");
+
+ // Leave the loop if we're done.
+ llvm::Value *done = Builder.CreateICmpEQ(nextElement, end,
+ "arrayinit.done");
+ llvm::BasicBlock *endBB = CGF.createBasicBlock("arrayinit.end");
+ Builder.CreateCondBr(done, endBB, bodyBB);
+ currentElement->addIncoming(nextElement, Builder.GetInsertBlock());
+
+ CGF.EmitBlock(endBB);
}
+
+ // Leave the partial-array cleanup if we entered one.
+ if (dtorKind) CGF.DeactivateCleanupBlock(cleanup);
+
return;
}
Modified: cfe/branches/type-system-rewrite/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/lib/CodeGen/CGObjC.cpp?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/branches/type-system-rewrite/lib/CodeGen/CGObjC.cpp Sat Jul 9 02:09:12 2011
@@ -1807,25 +1807,43 @@
getContext().VoidTy, DrainSel, Arg, Args);
}
+void CodeGenFunction::destroyARCStrongPrecise(CodeGenFunction &CGF,
+ llvm::Value *addr,
+ QualType type) {
+ llvm::Value *ptr = CGF.Builder.CreateLoad(addr, "strongdestroy");
+ CGF.EmitARCRelease(ptr, /*precise*/ true);
+}
+
+void CodeGenFunction::destroyARCStrongImprecise(CodeGenFunction &CGF,
+ llvm::Value *addr,
+ QualType type) {
+ llvm::Value *ptr = CGF.Builder.CreateLoad(addr, "strongdestroy");
+ CGF.EmitARCRelease(ptr, /*precise*/ false);
+}
+
+void CodeGenFunction::destroyARCWeak(CodeGenFunction &CGF,
+ llvm::Value *addr,
+ QualType type) {
+ CGF.EmitARCDestroyWeak(addr);
+}
+
namespace {
struct ObjCReleasingCleanup : EHScopeStack::Cleanup {
private:
QualType type;
llvm::Value *addr;
+ CodeGenFunction::Destroyer &destroyer;
protected:
- ObjCReleasingCleanup(QualType type, llvm::Value *addr)
- : type(type), addr(addr) {}
+ ObjCReleasingCleanup(QualType type, llvm::Value *addr,
+ CodeGenFunction::Destroyer *destroyer)
+ : type(type), addr(addr), destroyer(*destroyer) {}
virtual llvm::Value *getAddress(CodeGenFunction &CGF,
llvm::Value *addr) {
return addr;
}
- virtual void release(CodeGenFunction &CGF,
- QualType type,
- llvm::Value *addr) = 0;
-
public:
void Emit(CodeGenFunction &CGF, bool isForEH) {
const ArrayType *arrayType = CGF.getContext().getAsArrayType(type);
@@ -1834,14 +1852,13 @@
// If we don't have an array type, this is easy.
if (!arrayType)
- return release(CGF, type, addr);
+ return destroyer(CGF, addr, type);
llvm::Value *begin = addr;
QualType baseType;
// Otherwise, this is more painful.
- llvm::Value *count = emitArrayLength(CGF, arrayType, baseType,
- begin);
+ llvm::Value *count = CGF.emitArrayLength(arrayType, baseType, begin);
assert(baseType == CGF.getContext().getBaseElementType(arrayType));
@@ -1867,7 +1884,7 @@
CGF.EmitBlock(bodyBB);
// Release the value at 'cur'.
- release(CGF, baseType, cur);
+ destroyer(CGF, cur, baseType);
// ++cur;
// goto loopBB;
@@ -1878,112 +1895,18 @@
// endBB:
CGF.EmitBlock(endBB);
}
-
- private:
- /// Computes the length of an array in elements, as well
- /// as the base
- static llvm::Value *emitArrayLength(CodeGenFunction &CGF,
- const ArrayType *origArrayType,
- QualType &baseType,
- llvm::Value *&addr) {
- ASTContext &Ctx = CGF.getContext();
- const ArrayType *arrayType = origArrayType;
-
- // If it's a VLA, we have to load the stored size. Note that
- // this is the size of the VLA in bytes, not its size in elements.
- llvm::Value *numVLAElements = 0;
- if (isa<VariableArrayType>(arrayType)) {
- numVLAElements =
- CGF.getVLASize(cast<VariableArrayType>(arrayType)).first;
-
- // Walk into all VLAs. This doesn't require changes to addr,
- // which has type T* where T is the first non-VLA element type.
- do {
- QualType elementType = arrayType->getElementType();
- arrayType = Ctx.getAsArrayType(elementType);
-
- // If we only have VLA components, 'addr' requires no adjustment.
- if (!arrayType) {
- baseType = elementType;
- return numVLAElements;
- }
- } while (isa<VariableArrayType>(arrayType));
-
- // We get out here only if we find a constant array type
- // inside the VLA.
- }
-
- // We have some number of constant-length arrays, so addr should
- // have LLVM type [M x [N x [...]]]*. Build a GEP that walks
- // down to the first element of addr.
- llvm::SmallVector<llvm::Value*, 8> gepIndices;
-
- // GEP down to the array type.
- llvm::ConstantInt *zero = CGF.Builder.getInt32(0);
- gepIndices.push_back(zero);
-
- // It's more efficient to calculate the count from the LLVM
- // constant-length arrays than to re-evaluate the array bounds.
- uint64_t countFromCLAs = 1;
-
- const llvm::ArrayType *llvmArrayType =
- cast<llvm::ArrayType>(
- cast<llvm::PointerType>(addr->getType())->getElementType());
- while (true) {
- assert(isa<ConstantArrayType>(arrayType));
- assert(cast<ConstantArrayType>(arrayType)->getSize().getZExtValue()
- == llvmArrayType->getNumElements());
-
- gepIndices.push_back(zero);
- countFromCLAs *= llvmArrayType->getNumElements();
-
- llvmArrayType =
- dyn_cast<llvm::ArrayType>(llvmArrayType->getElementType());
- if (!llvmArrayType) break;
-
- arrayType = Ctx.getAsArrayType(arrayType->getElementType());
- assert(arrayType && "LLVM and Clang types are out-of-synch");
- }
-
- baseType = arrayType->getElementType();
-
- // Create the actual GEP.
- addr = CGF.Builder.CreateInBoundsGEP(addr, gepIndices.begin(),
- gepIndices.end(), "array.begin");
-
- llvm::Value *numElements
- = llvm::ConstantInt::get(CGF.IntPtrTy, countFromCLAs);
-
- // If we had any VLA dimensions, factor them in.
- if (numVLAElements)
- numElements = CGF.Builder.CreateNUWMul(numVLAElements, numElements);
-
- return numElements;
- }
-
- static llvm::Value *divideVLASizeByBaseType(CodeGenFunction &CGF,
- llvm::Value *vlaSizeInBytes,
- QualType baseType) {
- // Divide the base type size back out of the
- CharUnits baseSize = CGF.getContext().getTypeSizeInChars(baseType);
- llvm::Value *baseSizeInBytes =
- llvm::ConstantInt::get(vlaSizeInBytes->getType(),
- baseSize.getQuantity());
-
- return CGF.Builder.CreateUDiv(vlaSizeInBytes, baseSizeInBytes,
- "array.vla-count");
- }
};
/// A cleanup that calls @objc_release on all the objects to release.
struct CallReleaseForObject : ObjCReleasingCleanup {
- bool precise;
- CallReleaseForObject(QualType type, llvm::Value *addr, bool precise)
- : ObjCReleasingCleanup(type, addr), precise(precise) {}
+ CallReleaseForObject(QualType type, llvm::Value *addr,
+ CodeGenFunction::Destroyer *destroyer)
+ : ObjCReleasingCleanup(type, addr, destroyer) {}
using ObjCReleasingCleanup::Emit;
static void Emit(CodeGenFunction &CGF, bool IsForEH,
- QualType type, llvm::Value *addr, bool precise) {
+ QualType type, llvm::Value *addr,
+ CodeGenFunction::Destroyer *destroyer) {
// EHScopeStack::Cleanup objects can never have their destructors called,
// so use placement new to construct our temporary object.
union {
@@ -1992,15 +1915,10 @@
};
CallReleaseForObject *Object
- = new (&align) CallReleaseForObject(type, addr, precise);
+ = new (&align) CallReleaseForObject(type, addr, destroyer);
Object->Emit(CGF, IsForEH);
(void)data[0];
}
-
- void release(CodeGenFunction &CGF, QualType type, llvm::Value *addr) {
- llvm::Value *ptr = CGF.Builder.CreateLoad(addr, "tmp");
- CGF.EmitARCRelease(ptr, precise);
- }
};
/// A cleanup that calls @objc_storeStrong(nil) on all the objects to
@@ -2008,7 +1926,8 @@
struct CallReleaseForIvar : ObjCReleasingCleanup {
const ObjCIvarDecl *ivar;
CallReleaseForIvar(const ObjCIvarDecl *ivar, llvm::Value *self)
- : ObjCReleasingCleanup(ivar->getType(), self), ivar(ivar) {}
+ : ObjCReleasingCleanup(ivar->getType(), self,
+ destroyARCStrongIvar), ivar(ivar) {}
llvm::Value *getAddress(CodeGenFunction &CGF, llvm::Value *addr) {
LValue lvalue
@@ -2016,8 +1935,9 @@
return lvalue.getAddress();
}
- void release(CodeGenFunction &CGF, QualType type, llvm::Value *addr) {
- // Release ivars by storing nil into them; it just makes things easier.
+ static void destroyARCStrongIvar(CodeGenFunction &CGF,
+ llvm::Value *addr,
+ QualType type) {
llvm::Value *null = getNullForVariable(addr);
CGF.EmitARCStoreStrongCall(addr, null, /*ignored*/ true);
}
@@ -2029,7 +1949,8 @@
const FieldDecl *Field;
explicit CallReleaseForField(const FieldDecl *Field)
- : CallReleaseForObject(Field->getType(), 0, /*precise=*/true),
+ : CallReleaseForObject(Field->getType(), 0,
+ CodeGenFunction::destroyARCStrongPrecise),
Field(Field) { }
llvm::Value *getAddress(CodeGenFunction &CGF, llvm::Value *) {
@@ -2043,7 +1964,7 @@
/// release in an object.
struct CallWeakReleaseForObject : ObjCReleasingCleanup {
CallWeakReleaseForObject(QualType type, llvm::Value *addr)
- : ObjCReleasingCleanup(type, addr) {}
+ : ObjCReleasingCleanup(type, addr, CodeGenFunction::destroyARCWeak) {}
using ObjCReleasingCleanup::Emit;
static void Emit(CodeGenFunction &CGF, bool IsForEH,
@@ -2060,10 +1981,6 @@
Object->Emit(CGF, IsForEH);
(void)data[0];
}
-
- void release(CodeGenFunction &CGF, QualType type, llvm::Value *addr) {
- CGF.EmitARCDestroyWeak(addr);
- }
};
@@ -2129,10 +2046,12 @@
llvm::Value *addr,
bool precise,
bool forFullExpr) {
+ Destroyer *dtor =
+ (precise ? destroyARCStrongPrecise : destroyARCStrongImprecise);
if (forFullExpr)
- pushFullExprCleanup<CallReleaseForObject>(cleanupKind, type, addr, precise);
+ pushFullExprCleanup<CallReleaseForObject>(cleanupKind, type, addr, dtor);
else
- EHStack.pushCleanup<CallReleaseForObject>(cleanupKind, type, addr, precise);
+ EHStack.pushCleanup<CallReleaseForObject>(cleanupKind, type, addr, dtor);
}
/// PushARCWeakReleaseCleanup - Enter a cleanup to perform a weak
Modified: cfe/branches/type-system-rewrite/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/lib/CodeGen/CodeGenFunction.cpp?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/branches/type-system-rewrite/lib/CodeGen/CodeGenFunction.cpp Sat Jul 9 02:09:12 2011
@@ -785,6 +785,84 @@
return IndirectBranch->getParent();
}
+/// Computes the length of an array in elements, as well as the base
+/// element type and a properly-typed first element pointer.
+llvm::Value *CodeGenFunction::emitArrayLength(const ArrayType *origArrayType,
+ QualType &baseType,
+ llvm::Value *&addr) {
+ const ArrayType *arrayType = origArrayType;
+
+ // If it's a VLA, we have to load the stored size. Note that
+ // this is the size of the VLA in bytes, not its size in elements.
+ llvm::Value *numVLAElements = 0;
+ if (isa<VariableArrayType>(arrayType)) {
+ numVLAElements = getVLASize(cast<VariableArrayType>(arrayType)).first;
+
+ // Walk into all VLAs. This doesn't require changes to addr,
+ // which has type T* where T is the first non-VLA element type.
+ do {
+ QualType elementType = arrayType->getElementType();
+ arrayType = getContext().getAsArrayType(elementType);
+
+ // If we only have VLA components, 'addr' requires no adjustment.
+ if (!arrayType) {
+ baseType = elementType;
+ return numVLAElements;
+ }
+ } while (isa<VariableArrayType>(arrayType));
+
+ // We get out here only if we find a constant array type
+ // inside the VLA.
+ }
+
+ // We have some number of constant-length arrays, so addr should
+ // have LLVM type [M x [N x [...]]]*. Build a GEP that walks
+ // down to the first element of addr.
+ llvm::SmallVector<llvm::Value*, 8> gepIndices;
+
+ // GEP down to the array type.
+ llvm::ConstantInt *zero = Builder.getInt32(0);
+ gepIndices.push_back(zero);
+
+ // It's more efficient to calculate the count from the LLVM
+ // constant-length arrays than to re-evaluate the array bounds.
+ uint64_t countFromCLAs = 1;
+
+ const llvm::ArrayType *llvmArrayType =
+ cast<llvm::ArrayType>(
+ cast<llvm::PointerType>(addr->getType())->getElementType());
+ while (true) {
+ assert(isa<ConstantArrayType>(arrayType));
+ assert(cast<ConstantArrayType>(arrayType)->getSize().getZExtValue()
+ == llvmArrayType->getNumElements());
+
+ gepIndices.push_back(zero);
+ countFromCLAs *= llvmArrayType->getNumElements();
+
+ llvmArrayType =
+ dyn_cast<llvm::ArrayType>(llvmArrayType->getElementType());
+ if (!llvmArrayType) break;
+
+ arrayType = getContext().getAsArrayType(arrayType->getElementType());
+ assert(arrayType && "LLVM and Clang types are out-of-synch");
+ }
+
+ baseType = arrayType->getElementType();
+
+ // Create the actual GEP.
+ addr = Builder.CreateInBoundsGEP(addr, gepIndices.begin(),
+ gepIndices.end(), "array.begin");
+
+ llvm::Value *numElements
+ = llvm::ConstantInt::get(SizeTy, countFromCLAs);
+
+ // If we had any VLA dimensions, factor them in.
+ if (numVLAElements)
+ numElements = Builder.CreateNUWMul(numVLAElements, numElements);
+
+ return numElements;
+}
+
std::pair<llvm::Value*, QualType>
CodeGenFunction::getVLASize(QualType type) {
const VariableArrayType *vla = getContext().getAsVariableArrayType(type);
Modified: cfe/branches/type-system-rewrite/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/lib/CodeGen/CodeGenFunction.h?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/branches/type-system-rewrite/lib/CodeGen/CodeGenFunction.h Sat Jul 9 02:09:12 2011
@@ -1151,6 +1151,40 @@
llvm::LLVMContext &getLLVMContext() { return CGM.getLLVMContext(); }
//===--------------------------------------------------------------------===//
+ // Cleanups
+ //===--------------------------------------------------------------------===//
+
+ typedef void Destroyer(CodeGenFunction &CGF, llvm::Value *addr, QualType ty);
+
+ void pushPartialArrayCleanup(llvm::Value *arrayBegin,
+ QualType elementType,
+ Destroyer &destroyer,
+ llvm::Value *arrayEndPointer);
+
+ Destroyer &getDestroyer(QualType::DestructionKind destructionKind);
+ void pushDestroy(CleanupKind kind, llvm::Value *addr, QualType type,
+ Destroyer &destroyer);
+ void emitDestroy(llvm::Value *addr, QualType type, Destroyer &destroyer);
+ void emitArrayDestroy(llvm::Value *begin, llvm::Value *end,
+ QualType type, Destroyer &destroyer);
+
+ /// Determines whether an EH cleanup is required to destroy a type
+ /// with the given destruction kind.
+ bool needsEHCleanup(QualType::DestructionKind kind) {
+ switch (kind) {
+ case QualType::DK_none:
+ return false;
+ case QualType::DK_cxx_destructor:
+ case QualType::DK_objc_weak_lifetime:
+ return getLangOptions().Exceptions;
+ case QualType::DK_objc_strong_lifetime:
+ return getLangOptions().Exceptions &&
+ CGM.getCodeGenOpts().ObjCAutoRefCountExceptions;
+ }
+ llvm_unreachable("bad destruction kind");
+ }
+
+ //===--------------------------------------------------------------------===//
// Objective-C
//===--------------------------------------------------------------------===//
@@ -1526,6 +1560,12 @@
// instruction in LLVM instead once it works well enough.
llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty);
+ /// emitArrayLength - Compute the length of an array, even if it's a
+ /// VLA, and drill down to the base element type.
+ llvm::Value *emitArrayLength(const ArrayType *arrayType,
+ QualType &baseType,
+ llvm::Value *&addr);
+
/// EmitVLASize - Capture all the sizes for the VLA expressions in
/// the given variably-modified type and store them in the VLASizeMap.
///
@@ -1616,6 +1656,8 @@
const ArrayType *Array,
llvm::Value *This);
+ static Destroyer destroyCXXObject;
+
void EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
llvm::Value *NumElements,
llvm::Value *This);
@@ -1720,6 +1762,8 @@
AutoVarEmission EmitAutoVarAlloca(const VarDecl &var);
void EmitAutoVarInit(const AutoVarEmission &emission);
void EmitAutoVarCleanups(const AutoVarEmission &emission);
+ void emitAutoVarTypeCleanup(const AutoVarEmission &emission,
+ QualType::DestructionKind dtorKind);
void EmitStaticVarDecl(const VarDecl &D,
llvm::GlobalValue::LinkageTypes Linkage);
@@ -2101,8 +2145,20 @@
void PushARCReleaseCleanup(CleanupKind kind, QualType type,
llvm::Value *addr, bool precise,
bool forFullExpr = false);
+ void PushARCArrayReleaseCleanup(CleanupKind kind, QualType elementType,
+ llvm::Value *addr,
+ llvm::Value *countOrCountPtr,
+ bool precise, bool forFullExpr = false);
void PushARCWeakReleaseCleanup(CleanupKind kind, QualType type,
llvm::Value *addr, bool forFullExpr = false);
+ void PushARCArrayWeakReleaseCleanup(CleanupKind kind, QualType elementType,
+ llvm::Value *addr,
+ llvm::Value *countOrCountPtr,
+ bool forFullExpr = false);
+ static Destroyer destroyARCStrongImprecise;
+ static Destroyer destroyARCStrongPrecise;
+ static Destroyer destroyARCWeak;
+
void PushARCFieldReleaseCleanup(CleanupKind cleanupKind,
const FieldDecl *Field);
void PushARCFieldWeakReleaseCleanup(CleanupKind cleanupKind,
Modified: cfe/branches/type-system-rewrite/lib/CodeGen/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/lib/CodeGen/TargetInfo.cpp?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/lib/CodeGen/TargetInfo.cpp (original)
+++ cfe/branches/type-system-rewrite/lib/CodeGen/TargetInfo.cpp Sat Jul 9 02:09:12 2011
@@ -374,6 +374,7 @@
bool IsDarwinVectorABI;
bool IsSmallStructInRegABI;
+ bool IsMMXDisabled;
static bool isRegisterSize(unsigned Size) {
return (Size == 8 || Size == 16 || Size == 32 || Size == 64);
@@ -403,14 +404,15 @@
virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty,
CodeGenFunction &CGF) const;
- X86_32ABIInfo(CodeGen::CodeGenTypes &CGT, bool d, bool p)
- : ABIInfo(CGT), IsDarwinVectorABI(d), IsSmallStructInRegABI(p) {}
+ X86_32ABIInfo(CodeGen::CodeGenTypes &CGT, bool d, bool p, bool m)
+ : ABIInfo(CGT), IsDarwinVectorABI(d), IsSmallStructInRegABI(p),
+ IsMMXDisabled(m) {}
};
class X86_32TargetCodeGenInfo : public TargetCodeGenInfo {
public:
- X86_32TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, bool d, bool p)
- :TargetCodeGenInfo(new X86_32ABIInfo(CGT, d, p)) {}
+ X86_32TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, bool d, bool p, bool m)
+ :TargetCodeGenInfo(new X86_32ABIInfo(CGT, d, p, m)) {}
void SetTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
CodeGen::CodeGenModule &CGM) const;
@@ -701,6 +703,9 @@
llvm::Type *IRType = CGT.ConvertType(Ty);
if (UseX86_MMXType(IRType)) {
+ if (IsMMXDisabled)
+ return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),
+ 64));
ABIArgInfo AAI = ABIArgInfo::getDirect(IRType);
AAI.setCoerceToType(llvm::Type::getX86_MMXTy(getVMContext()));
return AAI;
@@ -3003,10 +3008,12 @@
case llvm::Triple::msp430:
return *(TheTargetCodeGenInfo = new MSP430TargetCodeGenInfo(Types));
- case llvm::Triple::x86:
+ case llvm::Triple::x86: {
+ bool DisableMMX = strcmp(getContext().Target.getABI(), "no-mmx") == 0;
+
if (Triple.isOSDarwin())
return *(TheTargetCodeGenInfo =
- new X86_32TargetCodeGenInfo(Types, true, true));
+ new X86_32TargetCodeGenInfo(Types, true, true, DisableMMX));
switch (Triple.getOS()) {
case llvm::Triple::Cygwin:
@@ -3017,12 +3024,13 @@
case llvm::Triple::OpenBSD:
case llvm::Triple::NetBSD:
return *(TheTargetCodeGenInfo =
- new X86_32TargetCodeGenInfo(Types, false, true));
+ new X86_32TargetCodeGenInfo(Types, false, true, DisableMMX));
default:
return *(TheTargetCodeGenInfo =
- new X86_32TargetCodeGenInfo(Types, false, false));
+ new X86_32TargetCodeGenInfo(Types, false, false, DisableMMX));
}
+ }
case llvm::Triple::x86_64:
switch (Triple.getOS()) {
Modified: cfe/branches/type-system-rewrite/lib/Frontend/DependencyFile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/lib/Frontend/DependencyFile.cpp?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/lib/Frontend/DependencyFile.cpp (original)
+++ cfe/branches/type-system-rewrite/lib/Frontend/DependencyFile.cpp Sat Jul 9 02:09:12 2011
@@ -20,6 +20,7 @@
#include "clang/Lex/PPCallbacks.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/StringSet.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
@@ -103,13 +104,18 @@
SM.getFileEntryForID(SM.getFileID(SM.getInstantiationLoc(Loc)));
if (FE == 0) return;
- const char *Filename = FE->getName();
- if (!FileMatchesDepCriteria(Filename, FileType))
+ llvm::StringRef Filename = FE->getName();
+ if (!FileMatchesDepCriteria(Filename.data(), FileType))
return;
- // Remove leading "./"
- if (Filename[0] == '.' && Filename[1] == '/')
- Filename = &Filename[2];
+ // Remove leading "./" (or ".//" or "././" etc.)
+ while (Filename.size() > 2 && Filename[0] == '.' &&
+ llvm::sys::path::is_separator(Filename[1])) {
+ Filename = Filename.substr(1);
+ while (llvm::sys::path::is_separator(Filename[0]))
+ Filename = Filename.substr(1);
+ }
+
if (FilesSet.insert(Filename))
Files.push_back(Filename);
Modified: cfe/branches/type-system-rewrite/lib/Lex/HeaderSearch.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/lib/Lex/HeaderSearch.cpp?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/lib/Lex/HeaderSearch.cpp (original)
+++ cfe/branches/type-system-rewrite/lib/Lex/HeaderSearch.cpp Sat Jul 9 02:09:12 2011
@@ -123,10 +123,8 @@
llvm::SmallString<1024> TmpDir;
if (isNormalDir()) {
// Concatenate the requested file onto the directory.
- // FIXME: Portability. Filename concatenation should be in sys::Path.
- TmpDir += getDir()->getName();
- TmpDir.push_back('/');
- TmpDir.append(Filename.begin(), Filename.end());
+ TmpDir = getDir()->getName();
+ llvm::sys::path::append(TmpDir, Filename);
if (SearchPath != NULL) {
llvm::StringRef SearchPathRef(getDir()->getName());
SearchPath->clear();
Modified: cfe/branches/type-system-rewrite/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/lib/Parse/ParseExpr.cpp?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/lib/Parse/ParseExpr.cpp (original)
+++ cfe/branches/type-system-rewrite/lib/Parse/ParseExpr.cpp Sat Jul 9 02:09:12 2011
@@ -792,7 +792,7 @@
return ParseBuiltinPrimaryExpression();
case tok::kw___null:
return Actions.ActOnGNUNullExpr(ConsumeToken());
- break;
+
case tok::plusplus: // unary-expression: '++' unary-expression [C99]
case tok::minusminus: { // unary-expression: '--' unary-expression [C99]
// C++ [expr.unary] has:
@@ -1718,7 +1718,7 @@
ConsumeParen());
break;
}
-}
+ }
if (Res.isInvalid())
return ExprError();
Modified: cfe/branches/type-system-rewrite/lib/Sema/AnalysisBasedWarnings.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/lib/Sema/AnalysisBasedWarnings.cpp?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/lib/Sema/AnalysisBasedWarnings.cpp (original)
+++ cfe/branches/type-system-rewrite/lib/Sema/AnalysisBasedWarnings.cpp Sat Jul 9 02:09:12 2011
@@ -600,8 +600,14 @@
clang::sema::AnalysisBasedWarnings::AnalysisBasedWarnings(Sema &s)
: S(s),
NumFunctionsAnalyzed(0),
+ NumFunctionsWithBadCFGs(0),
NumCFGBlocks(0),
- MaxCFGBlocksPerFunction(0) {
+ MaxCFGBlocksPerFunction(0),
+ NumUninitAnalysisFunctions(0),
+ NumUninitAnalysisVariables(0),
+ MaxUninitAnalysisVariablesPerFunction(0),
+ NumUninitAnalysisBlockVisits(0),
+ MaxUninitAnalysisBlockVisitsPerFunction(0) {
Diagnostic &D = S.getDiagnostics();
DefaultPolicy.enableCheckUnreachable = (unsigned)
(D.getDiagnosticLevel(diag::warn_unreachable, SourceLocation()) !=
Modified: cfe/branches/type-system-rewrite/lib/Sema/SemaCXXCast.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/lib/Sema/SemaCXXCast.cpp?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/lib/Sema/SemaCXXCast.cpp (original)
+++ cfe/branches/type-system-rewrite/lib/Sema/SemaCXXCast.cpp Sat Jul 9 02:09:12 2011
@@ -1717,8 +1717,7 @@
Kind = CK_Dependent;
return Owned(CastExpr);
}
-
- QualType origCastExprType = CastExpr->getType();
+
if (VK == VK_RValue && !CastTy->isRecordType()) {
ExprResult CastExprRes = DefaultFunctionArrayLvalueConversion(CastExpr);
if (CastExprRes.isInvalid())
@@ -1774,15 +1773,8 @@
}
}
- if (getLangOptions().ObjCAutoRefCount && tcr == TC_Success) {
+ if (getLangOptions().ObjCAutoRefCount && tcr == TC_Success)
CheckObjCARCConversion(R, CastTy, CastExpr, CCK);
- if (!CheckObjCARCUnavailableWeakConversion(CastTy,
- origCastExprType))
- Diag(CastExpr->getLocStart(),
- diag::err_arc_cast_of_weak_unavailable)
- << origCastExprType << CastTy
- << CastExpr->getSourceRange();
- }
if (tcr != TC_Success && msg != 0) {
if (CastExpr->getType() == Context.OverloadTy) {
Modified: cfe/branches/type-system-rewrite/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/lib/Sema/SemaExpr.cpp?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/lib/Sema/SemaExpr.cpp (original)
+++ cfe/branches/type-system-rewrite/lib/Sema/SemaExpr.cpp Sat Jul 9 02:09:12 2011
@@ -4068,7 +4068,7 @@
}
else if (!CheckObjCARCUnavailableWeakConversion(castType, castExprType)) {
Diag(castExpr->getLocStart(),
- diag::err_arc_cast_of_weak_unavailable)
+ diag::err_arc_convesion_of_weak_unavailable) << 1
<< castExprType << castType
<< castExpr->getSourceRange();
return ExprError();
Modified: cfe/branches/type-system-rewrite/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/lib/Sema/SemaExprCXX.cpp?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/branches/type-system-rewrite/lib/Sema/SemaExprCXX.cpp Sat Jul 9 02:09:12 2011
@@ -2340,8 +2340,20 @@
if (From->getType()->isObjCObjectPointerType() &&
ToType->isObjCObjectPointerType())
EmitRelatedResultTypeNote(From);
- }
-
+ }
+ else if (getLangOptions().ObjCAutoRefCount &&
+ !CheckObjCARCUnavailableWeakConversion(ToType,
+ From->getType())) {
+ if (Action == AA_Initializing)
+ Diag(From->getSourceRange().getBegin(),
+ diag::err_arc_weak_unavailable_assign);
+ else
+ Diag(From->getSourceRange().getBegin(),
+ diag::err_arc_convesion_of_weak_unavailable)
+ << (Action == AA_Casting) << From->getType() << ToType
+ << From->getSourceRange();
+ }
+
CastKind Kind = CK_Invalid;
CXXCastPath BasePath;
if (CheckPointerConversion(From, ToType, Kind, BasePath, CStyle))
Modified: cfe/branches/type-system-rewrite/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/lib/Sema/SemaTemplate.cpp?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/branches/type-system-rewrite/lib/Sema/SemaTemplate.cpp Sat Jul 9 02:09:12 2011
@@ -5364,7 +5364,7 @@
/// explicitly provided as in, e.g., \c void sort<>(char*, char*);
/// as it anyway contains info on the angle brackets locations.
///
-/// \param PrevDecl the set of declarations that may be specialized by
+/// \param Previous the set of declarations that may be specialized by
/// this function specialization.
bool
Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
@@ -5428,13 +5428,12 @@
FunctionTemplateSpecializationInfo *SpecInfo
= Specialization->getTemplateSpecializationInfo();
assert(SpecInfo && "Function template specialization info missing?");
- {
- // Note: do not overwrite location info if previous template
- // specialization kind was explicit.
- TemplateSpecializationKind TSK = SpecInfo->getTemplateSpecializationKind();
- if (TSK == TSK_Undeclared || TSK == TSK_ImplicitInstantiation)
- Specialization->setLocation(FD->getLocation());
- }
+
+ // Note: do not overwrite location info if previous template
+ // specialization kind was explicit.
+ TemplateSpecializationKind TSK = SpecInfo->getTemplateSpecializationKind();
+ if (TSK == TSK_Undeclared || TSK == TSK_ImplicitInstantiation)
+ Specialization->setLocation(FD->getLocation());
// FIXME: Check if the prior specialization has a point of instantiation.
// If so, we have run afoul of .
Modified: cfe/branches/type-system-rewrite/test/CodeGen/builtin-expect.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/test/CodeGen/builtin-expect.c?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/test/CodeGen/builtin-expect.c (original)
+++ cfe/branches/type-system-rewrite/test/CodeGen/builtin-expect.c Sat Jul 9 02:09:12 2011
@@ -19,3 +19,29 @@
// CHECK: call void @isigprocmask()
// CHECK: [[C:%.*]] = call i64 (...)* @bar()
+
+
+// CHECK: @test1
+int test1(int x) {
+// CHECK: @llvm.expect
+ if (__builtin_expect (x, 1))
+ return 0;
+ return x;
+}
+
+// CHECK: @test2
+int test2(int x) {
+// CHECK: @llvm.expect
+ switch(__builtin_expect(x, 5)) {
+ default:
+ return 0;
+ case 0:
+ case 1:
+ case 2:
+ return 1;
+ case 5:
+ return 5;
+ };
+
+ return 0;
+}
Modified: cfe/branches/type-system-rewrite/test/CodeGen/libcalls.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/test/CodeGen/libcalls.c?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/test/CodeGen/libcalls.c (original)
+++ cfe/branches/type-system-rewrite/test/CodeGen/libcalls.c Sat Jul 9 02:09:12 2011
@@ -50,3 +50,26 @@
// CHECK-NO: declare float @llvm.pow.f32(float, float) nounwind readonly
// CHECK-NO: declare double @llvm.pow.f64(double, double) nounwind readonly
// CHECK-NO: declare x86_fp80 @llvm.pow.f80(x86_fp80, x86_fp80) nounwind readonly
+
+// CHECK-YES: define void @test_fma
+// CHECK-NO: define void @test_fma
+void test_fma(float a0, double a1, long double a2) {
+ // CHECK-YES: call float @llvm.fma.f32
+ // CHECK-NO: call float @llvm.fma.f32
+ float l0 = fmaf(a0, a0, a0);
+
+ // CHECK-YES: call double @llvm.fma.f64
+ // CHECK-NO: call double @llvm.fma.f64
+ double l1 = fma(a1, a1, a1);
+
+ // CHECK-YES: call x86_fp80 @llvm.fma.f80
+ // CHECK-NO: call x86_fp80 @llvm.fma.f80
+ long double l2 = fmal(a2, a2, a2);
+}
+
+// CHECK-YES: declare float @llvm.fma.f32(float, float, float) nounwind readnone
+// CHECK-YES: declare double @llvm.fma.f64(double, double, double) nounwind readnone
+// CHECK-YES: declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80) nounwind readnone
+// CHECK-NO: declare float @llvm.fma.f32(float, float, float) nounwind readnone
+// CHECK-NO: declare double @llvm.fma.f64(double, double, double) nounwind readnone
+// CHECK-NO: declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80) nounwind readnone
Modified: cfe/branches/type-system-rewrite/test/CodeGen/x86_32-arguments-darwin.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/test/CodeGen/x86_32-arguments-darwin.c?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/test/CodeGen/x86_32-arguments-darwin.c (original)
+++ cfe/branches/type-system-rewrite/test/CodeGen/x86_32-arguments-darwin.c Sat Jul 9 02:09:12 2011
@@ -1,5 +1,4 @@
-// RUN: %clang_cc1 -w -fblocks -triple i386-apple-darwin9 -emit-llvm -o %t %s
-// RUN: FileCheck < %t %s
+// RUN: %clang_cc1 -w -fblocks -triple i386-apple-darwin9 -target-cpu yonah -emit-llvm -o - %s | FileCheck %s
// CHECK: define signext i8 @f0()
char f0(void) {
Modified: cfe/branches/type-system-rewrite/test/CodeGen/x86_32-arguments-linux.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/test/CodeGen/x86_32-arguments-linux.c?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/test/CodeGen/x86_32-arguments-linux.c (original)
+++ cfe/branches/type-system-rewrite/test/CodeGen/x86_32-arguments-linux.c Sat Jul 9 02:09:12 2011
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -w -fblocks -triple i386-pc-linux-gnu -emit-llvm -o %t %s
+// RUN: %clang_cc1 -w -fblocks -triple i386-pc-linux-gnu -target-cpu pentium4 -emit-llvm -o %t %s
// RUN: FileCheck < %t %s
// CHECK: define void @f56(
Modified: cfe/branches/type-system-rewrite/test/CodeGenCXX/destructors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/test/CodeGenCXX/destructors.cpp?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/test/CodeGenCXX/destructors.cpp (original)
+++ cfe/branches/type-system-rewrite/test/CodeGenCXX/destructors.cpp Sat Jul 9 02:09:12 2011
@@ -233,27 +233,16 @@
namespace test5 {
struct A { ~A(); };
- // This is really unnecessarily verbose; we should be using phis,
- // even at -O0.
-
// CHECK: define void @_ZN5test53fooEv()
// CHECK: [[ELEMS:%.*]] = alloca [5 x [[A:%.*]]], align
- // CHECK-NEXT: [[IVAR:%.*]] = alloca i64
- // CHECK: [[ELEMSARRAY:%.*]] = bitcast [5 x [[A]]]* [[ELEMS]] to [[A]]
- // CHECK-NEXT: store i64 5, i64* [[IVAR]]
- // CHECK-NEXT: br label
- // CHECK: [[I:%.*]] = load i64* [[IVAR]]
- // CHECK-NEXT: icmp ne i64 [[I]], 0
- // CHECK-NEXT: br i1
- // CHECK: [[I:%.*]] = load i64* [[IVAR]]
- // CHECK-NEXT: [[I2:%.*]] = sub i64 [[I]], 1
- // CHECK-NEXT: getelementptr inbounds [[A]]* [[ELEMSARRAY]], i64 [[I2]]
- // CHECK-NEXT: call void @_ZN5test51AD1Ev(
- // CHECK-NEXT: br label
- // CHECK: [[I:%.*]] = load i64* [[IVAR]]
- // CHECK-NEXT: [[I1:%.*]] = sub i64 [[I]], 1
- // CHECK-NEXT: store i64 [[I1]], i64* [[IVAR]]
+ // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [5 x [[A]]]* [[ELEMS]], i32 0, i32 0
+ // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 5
// CHECK-NEXT: br label
+ // CHECK: [[POST:%.*]] = phi [[A]]* [ [[END]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ]
+ // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A]]* [[POST]], i64 -1
+ // CHECK-NEXT: call void @_ZN5test51AD1Ev([[A]]* [[ELT]])
+ // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[ELT]], [[BEGIN]]
+ // CHECK-NEXT: br i1 [[T0]],
// CHECK: ret void
void foo() {
A elems[5];
Modified: cfe/branches/type-system-rewrite/test/CodeGenCXX/temporaries.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/test/CodeGenCXX/temporaries.cpp?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/test/CodeGenCXX/temporaries.cpp (original)
+++ cfe/branches/type-system-rewrite/test/CodeGenCXX/temporaries.cpp Sat Jul 9 02:09:12 2011
@@ -421,28 +421,24 @@
void test4() {
// CHECK: [[X:%.*]] = alloca [[A]], align 8
// CHECK-NEXT: [[XS:%.*]] = alloca [2 x [[A]]], align 16
- // CHECK-NEXT: [[I:%.*]] = alloca i64
// CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[X]])
A x;
- // CHECK-NEXT: [[XS0:%.*]] = getelementptr inbounds [2 x [[A]]]* [[XS]], i32 0, i32 0
+ // CHECK-NEXT: [[XS0:%.*]] = getelementptr inbounds [2 x [[A]]]* [[XS]], i64 0, i64 0
// CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[XS0]])
- // CHECK-NEXT: [[XS1:%.*]] = getelementptr inbounds [2 x [[A]]]* [[XS]], i32 0, i32 1
+ // CHECK-NEXT: [[XS1:%.*]] = getelementptr inbounds [[A]]* [[XS0]], i64 1
// CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[XS1]], [[A]]* [[X]])
- // CHECK-NEXT: [[XSB:%.*]] = bitcast [2 x [[A]]]* [[XS]] to [[A]]*
A xs[] = { A(), x };
- // CHECK-NEXT: store i64 2, i64* [[I]]
- // CHECK-NEXT: br label
- // CHECK: [[I0:%.*]] = load i64* [[I]]
- // CHECK-NEXT: icmp ne i64 [[I0]], 0
- // CHECK-NEXT: br i1
- // CHECK: [[I1:%.*]] = load i64* [[I]]
- // CHECK-NEXT: [[I2:%.*]] = sub i64 [[I1]], 1
- // CHECK-NEXT: [[XSI:%.*]] = getelementptr inbounds [[A]]* [[XSB]], i64 [[I2]]
- // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[XSI]])
+ // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [2 x [[A]]]* [[XS]], i32 0, i32 0
+ // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 2
// CHECK-NEXT: br label
+ // CHECK: [[AFTER:%.*]] = phi [[A]]*
+ // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]]* [[AFTER]], i64 -1
+ // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[CUR]])
+ // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]]
+ // CHECK-NEXT: br i1 [[T0]],
// CHECK: call void @_ZN7Elision1AD1Ev([[A]]* [[X]])
}
Modified: cfe/branches/type-system-rewrite/test/CodeGenCXX/value-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/test/CodeGenCXX/value-init.cpp?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/test/CodeGenCXX/value-init.cpp (original)
+++ cfe/branches/type-system-rewrite/test/CodeGenCXX/value-init.cpp Sat Jul 9 02:09:12 2011
@@ -105,34 +105,24 @@
// CHECK: call void @_ZN6PR98014TestC1Ei
// CHECK-NOT: call void @llvm.memset.p0i8.i64
// CHECK: call void @_ZN6PR98014TestC1Ev
- // CHECK-NOT: call void @llvm.memset.p0i8.i64
- // CHECK: call void @_ZN6PR98014TestC1Ev
Test partial[3] = { 1 };
// CHECK-NOT: call void @llvm.memset.p0i8.i64
// CHECK: call void @_ZN6PR98014TestC1Ev
- // CHECK-NOT: call void @llvm.memset.p0i8.i64
- // CHECK: call void @_ZN6PR98014TestC1Ev
- // CHECK-NOT: call void @llvm.memset.p0i8.i64
- // CHECK: call void @_ZN6PR98014TestC1Ev
+ // CHECK-NOT: call void @_ZN6PR98014TestC1Ev
Test empty[3] = {};
// CHECK: call void @llvm.memset.p0i8.i64
// CHECK-NOT: call void @llvm.memset.p0i8.i64
// CHECK: call void @_ZN6PR98015Test2C1Ev
- // CHECK-NOT: call void @llvm.memset.p0i8.i64
- // CHECK: call void @_ZN6PR98015Test2C1Ev
- // CHECK-NOT: call void @llvm.memset.p0i8.i64
- // CHECK: call void @_ZN6PR98015Test2C1Ev
+ // CHECK-NOT: call void @_ZN6PR98015Test2C1Ev
Test2 empty2[3] = {};
// CHECK: call void @llvm.memset.p0i8.i64
// CHECK-NOT: call void @llvm.memset.p0i8.i64
// CHECK: call void @_ZN6PR98015Test3C1Ev
// CHECK-NOT: call void @llvm.memset.p0i8.i64
- // CHECK: call void @_ZN6PR98015Test3C1Ev
- // CHECK-NOT: call void @llvm.memset.p0i8.i64
- // CHECK: call void @_ZN6PR98015Test3C1Ev
+ // CHECK-NOT: call void @_ZN6PR98015Test3C1Ev
Test3 empty3[3] = {};
}
@@ -189,10 +179,7 @@
X3<int>().f();
}
- // CHECK: define linkonce_odr void @_ZN8zeroinit2X3IiEC2Ev(%"struct.zeroinit::X3"* %this) unnamed_addr
- // CHECK: call void @llvm.memset.p0i8.i64
- // CHECK-NEXT: call void @_ZN8zeroinit2X2IiEC2Ev
- // CHECK-NEXT: ret void
+ // More checks at EOF
}
namespace PR8726 {
@@ -207,3 +194,58 @@
}
}
+
+// rdar://problem/9355931
+namespace test6 {
+ struct A { A(); A(int); };
+
+ void test() {
+ A arr[10][20] = { 5 };
+ };
+ // CHECK: define void @_ZN5test64testEv()
+ // CHECK: [[ARR:%.*]] = alloca [10 x [20 x [[A:%.*]]]],
+ // CHECK-NEXT: [[IDX:%.*]] = alloca i64
+
+ // CHECK-NEXT: [[INNER:%.*]] = getelementptr inbounds [10 x [20 x [[A]]]]* [[ARR]], i64 0, i64 0
+ // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [20 x [[A]]]* [[INNER]], i64 0, i64 0
+ // CHECK-NEXT: call void @_ZN5test61AC1Ei([[A]]* [[T0]], i32 5)
+ // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [[A]]* [[T0]], i64 1
+ // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[T0]], i64 20
+ // CHECK-NEXT: br label
+ // CHECK: [[CUR:%.*]] = phi [[A]]* [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
+ // CHECK-NEXT: call void @_ZN5test61AC1Ev([[A]]* [[CUR]])
+ // CHECK-NEXT: [[NEXT]] = getelementptr inbounds [[A]]* [[CUR]], i64 1
+ // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[NEXT]], [[END]]
+ // CHECK-NEXT: br i1
+
+ // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [20 x [[A]]]* [[INNER]], i64 1
+ // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [20 x [[A]]]* [[INNER]], i64 10
+ // CHECK-NEXT: br label
+ // CHECK: [[CUR:%.*]] = phi [20 x [[A]]]* [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
+ // CHECK-NEXT: [[FIRST:%.*]] = bitcast [20 x [[A]]]* [[CUR]] to [[A]]*
+
+ // TODO: this loop should use phis, too, and for preference would be
+ // merged with the outer loop.
+ // CHECK-NEXT: store i64 0, i64* [[IDX]]
+ // CHECK-NEXT: br label
+ // CHECK: [[T0:%.*]] = load i64* [[IDX]]
+ // CHECK-NEXT: [[T1:%.*]] = icmp ult i64 [[T0]], 20
+ // CHECK-NEXT: br i1 [[T1]]
+ // CHECK: [[T0:%.*]] = load i64* [[IDX]]
+ // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[A]]* [[FIRST]], i64 [[T0]]
+ // CHECK-NEXT: call void @_ZN5test61AC1Ev([[A]]* [[T1]])
+ // CHECK-NEXT: br label
+ // CHECK: [[T0:%.*]] = load i64* [[IDX]]
+ // CHECK-NEXT: [[T1:%.*]] = add i64 [[T0]], 1
+ // CHECK-NEXT: store i64 [[T1]], i64* [[IDX]]
+ // CHECK-NEXT: br label
+ // CHECK: [[NEXT]] = getelementptr inbounds [20 x [[A]]]* [[CUR]], i64 1
+ // CHECK-NEXT: [[T0:%.*]] = icmp eq [20 x [[A]]]* [[NEXT]], [[END]]
+ // CHECK-NEXT: br i1 [[T0]]
+ // CHECK: ret void
+}
+
+// CHECK: define linkonce_odr void @_ZN8zeroinit2X3IiEC2Ev(%"struct.zeroinit::X3"* %this) unnamed_addr
+// CHECK: call void @llvm.memset.p0i8.i64
+// CHECK-NEXT: call void @_ZN8zeroinit2X2IiEC2Ev
+// CHECK-NEXT: ret void
Modified: cfe/branches/type-system-rewrite/test/CodeGenObjC/arc.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/test/CodeGenObjC/arc.m?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/test/CodeGenObjC/arc.m (original)
+++ cfe/branches/type-system-rewrite/test/CodeGenObjC/arc.m Sat Jul 9 02:09:12 2011
@@ -475,14 +475,12 @@
// CHECK-NEXT: [[END:%.*]] = getelementptr inbounds i8** [[BEGIN]], i64 5
// CHECK-NEXT: br label
- // CHECK: [[CUR:%.*]] = phi i8**
- // CHECK-NEXT: [[EQ:%.*]] = icmp eq i8** [[CUR]], [[END]]
- // CHECK-NEXT: br i1 [[EQ]],
-
- // CHECK: [[T0:%.*]] = load i8** [[CUR]]
+ // CHECK: [[AFTER:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]
+ // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds i8** [[AFTER]], i64 -1
+ // CHECK-NEXT: [[T0:%.*]] = load i8** [[CUR]]
// CHECK-NEXT: call void @objc_release(i8* [[T0]]) nounwind, !clang.imprecise_release
- // CHECK-NEXT: [[NEXT:%.*]] = getelementptr inbounds i8** [[CUR]], i32 1
- // CHECK-NEXT: br label
+ // CHECK-NEXT: [[EQ:%.*]] = icmp eq i8** [[CUR]], [[BEGIN]]
+ // CHECK-NEXT: br i1 [[EQ]],
// CHECK: ret void
}
@@ -515,14 +513,12 @@
// CHECK-NEXT: [[END:%.*]] = getelementptr inbounds i8** [[VLA]], i64 [[DIM]]
// CHECK-NEXT: br label
- // CHECK: [[CUR:%.*]] = phi i8**
- // CHECK-NEXT: [[EQ:%.*]] = icmp eq i8** [[CUR]], [[END]]
- // CHECK-NEXT: br i1 [[EQ]],
-
- // CHECK: [[T0:%.*]] = load i8** [[CUR]]
+ // CHECK: [[AFTER:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]
+ // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds i8** [[AFTER]], i64 -1
+ // CHECK-NEXT: [[T0:%.*]] = load i8** [[CUR]]
// CHECK-NEXT: call void @objc_release(i8* [[T0]]) nounwind, !clang.imprecise_release
- // CHECK-NEXT: [[NEXT:%.*]] = getelementptr inbounds i8** [[CUR]], i32 1
- // CHECK-NEXT: br label
+ // CHECK-NEXT: [[EQ:%.*]] = icmp eq i8** [[CUR]], [[VLA]]
+ // CHECK-NEXT: br i1 [[EQ]],
// CHECK: [[T0:%.*]] = load i8** [[SAVED_STACK]]
// CHECK-NEXT: call void @llvm.stackrestore(i8* [[T0]])
@@ -562,14 +558,12 @@
// CHECK-NEXT: [[END:%.*]] = getelementptr inbounds i8** [[BEGIN]], i64 [[T1]]
// CHECK-NEXT: br label
- // CHECK: [[CUR:%.*]] = phi i8**
- // CHECK-NEXT: [[EQ:%.*]] = icmp eq i8** [[CUR]], [[END]]
- // CHECK-NEXT: br i1 [[EQ]],
-
- // CHECK: [[T0:%.*]] = load i8** [[CUR]]
+ // CHECK: [[AFTER:%.*]] = phi i8** [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ]
+ // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds i8** [[AFTER]], i64 -1
+ // CHECK-NEXT: [[T0:%.*]] = load i8** [[CUR]]
// CHECK-NEXT: call void @objc_release(i8* [[T0]]) nounwind, !clang.imprecise_release
- // CHECK-NEXT: [[NEXT:%.*]] = getelementptr inbounds i8** [[CUR]], i32 1
- // CHECK-NEXT: br label
+ // CHECK-NEXT: [[EQ:%.*]] = icmp eq i8** [[CUR]], [[BEGIN]]
+ // CHECK-NEXT: br i1 [[EQ]],
// CHECK: [[T0:%.*]] = load i8** [[SAVED_STACK]]
// CHECK-NEXT: call void @llvm.stackrestore(i8* [[T0]])
@@ -1120,7 +1114,7 @@
// CHECK: br label
// CHECK: call void @objc_release
- // CHECK: br label
+ // CHECK: br i1
// CHECK: call void @objc_release
// CHECK-NEXT: ret void
Modified: cfe/branches/type-system-rewrite/test/Frontend/dependency-gen.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/test/Frontend/dependency-gen.c?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/test/Frontend/dependency-gen.c (original)
+++ cfe/branches/type-system-rewrite/test/Frontend/dependency-gen.c Sat Jul 9 02:09:12 2011
@@ -1,19 +1,27 @@
-// rdar://6533411
-// RUN: %clang -MD -MF %t.d -S -x c -o %t.o %s
-// RUN: grep '.*dependency-gen.*:' %t.d
-// RUN: grep 'dependency-gen.c' %t.d
-
-// RUN: %clang -S -M -x c %s -o %t.d
-// RUN: grep '.*dependency-gen.*:' %t.d
-// RUN: grep 'dependency-gen.c' %t.d
-
-// PR8974
// REQUIRES: shell
-// "cd %t.dir" requires shell.
+// Basic test
// RUN: rm -rf %t.dir
// RUN: mkdir -p %t.dir/a/b
// RUN: echo > %t.dir/a/b/x.h
// RUN: cd %t.dir
-// RUN: %clang -include a/b/x.h -MD -MF %t.d -S -x c -o %t.o %s
-// RUN: grep ' a/b/x\.h' %t.d
+// RUN: %clang -MD -MF - %s -fsyntax-only -I a/b | FileCheck -check-prefix=CHECK-ONE %s
+// CHECK-ONE: {{ }}a/b/x.h
+
+// PR8974 (-include flag)
+// RUN: %clang -MD -MF - %s -fsyntax-only -include a/b/x.h -DINCLUDE_FLAG_TEST | FileCheck -check-prefix=CHECK-TWO %s
+// CHECK-TWO: {{ }}a/b/x.h
+
+// rdar://problem/9734352 (paths involving ".")
+// RUN: %clang -MD -MF - %s -fsyntax-only -I ./a/b | FileCheck -check-prefix=CHECK-THREE %s
+// CHECK-THREE: {{ }}a/b/x.h
+// RUN: %clang -MD -MF - %s -fsyntax-only -I .//./a/b/ | FileCheck -check-prefix=CHECK-FOUR %s
+// CHECK-FOUR: {{ }}a/b/x.h
+// RUN: %clang -MD -MF - %s -fsyntax-only -I a/b/. | FileCheck -check-prefix=CHECK-FIVE %s
+// CHECK-FIVE: {{ }}a/b/./x.h
+// RUN: cd a/b
+// RUN: %clang -MD -MF - %s -fsyntax-only -I ./ | FileCheck -check-prefix=CHECK-SIX %s
+// CHECK-SIX: {{ }}x.h
+#ifndef INCLUDE_FLAG_TEST
+#include <x.h>
+#endif
Modified: cfe/branches/type-system-rewrite/test/Sema/x86-builtin-palignr.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/test/Sema/x86-builtin-palignr.c?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/test/Sema/x86-builtin-palignr.c (original)
+++ cfe/branches/type-system-rewrite/test/Sema/x86-builtin-palignr.c Sat Jul 9 02:09:12 2011
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -ffreestanding -fsyntax-only -target-feature +ssse3 -verify -triple x86_64-pc-linux-gnu %s
-// RUN: %clang_cc1 -ffreestanding -fsyntax-only -target-feature +ssse3 -verify -triple i686-apple-darwin10 %s
+// RUN: %clang_cc1 -ffreestanding -fsyntax-only -target-feature +ssse3 -target-feature +mmx -verify -triple x86_64-pc-linux-gnu %s
+// RUN: %clang_cc1 -ffreestanding -fsyntax-only -target-feature +ssse3 -target-feature +mmx -verify -triple i686-apple-darwin10 %s
#include <tmmintrin.h>
Propchange: cfe/branches/type-system-rewrite/test/SemaCXX/warn-unreachable.cpp
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Jul 9 02:09:12 2011
@@ -1 +1 @@
-/cfe/trunk/test/SemaCXX/warn-unreachable.cpp:121961
+/cfe/trunk/test/SemaCXX/warn-unreachable.cpp:121961,134685-134804
Modified: cfe/branches/type-system-rewrite/test/SemaObjC/arc-unavailable-for-weakref.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/test/SemaObjC/arc-unavailable-for-weakref.m?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/test/SemaObjC/arc-unavailable-for-weakref.m (original)
+++ cfe/branches/type-system-rewrite/test/SemaObjC/arc-unavailable-for-weakref.m Sat Jul 9 02:09:12 2011
@@ -24,7 +24,7 @@
+ (id) new;
@end
-NOWEAK * Test9732636() {
+NOWEAK * Test1() {
NOWEAK * strong1 = [NOWEAK new];
__weak id weak1;
weak1 = strong1; // expected-error {{assignment of a weak-unavailable object to a __weak object}}
@@ -33,3 +33,15 @@
return (__weak id)strong1; // expected-error {{cast of weak-unavailable object of type 'NOWEAK *' to a __weak object of type '__weak id'}}
}
+ at protocol P @end
+ at protocol P1 @end
+
+NOWEAK<P, P1> * Test2() {
+ NOWEAK<P, P1> * strong1 = 0;
+ __weak id<P> weak1;
+ weak1 = strong1; // expected-error {{assignment of a weak-unavailable object to a __weak object}}
+
+ __weak id<P> weak2 = strong1; // expected-error {{assignment of a weak-unavailable object to a __weak object}}
+ return (__weak id<P>)strong1; // expected-error {{cast of weak-unavailable object of type 'NOWEAK<P,P1> *' to a __weak object of type '__weak id<P>'}}
+}
+
Modified: cfe/branches/type-system-rewrite/test/SemaObjCXX/arc-unavailable-for-weakref.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/test/SemaObjCXX/arc-unavailable-for-weakref.mm?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/test/SemaObjCXX/arc-unavailable-for-weakref.mm (original)
+++ cfe/branches/type-system-rewrite/test/SemaObjCXX/arc-unavailable-for-weakref.mm Sat Jul 9 02:09:12 2011
@@ -24,13 +24,24 @@
+ (id) new;
@end
-NOWEAK * Test9732636() {
+NOWEAK * Test1() {
NOWEAK * strong1 = [NOWEAK new];
__weak id weak1;
weak1 = strong1; // expected-error {{assignment of a weak-unavailable object to a __weak object}}
-// FIXME. NYI.
- __weak id weak2 = strong1; // expected-FIXME {{assignment of a weak-unavailable object to a __weak object}}
- return (__weak id)strong1; // expected-error {{cast of weak-unavailable object of type 'NOWEAK *__strong' to a __weak object of type '__weak id'}}
+ __weak id weak2 = strong1; // expected-error {{assignment of a weak-unavailable object to a __weak object}}
+ return (__weak id)strong1; // expected-error {{cast of weak-unavailable object of type 'NOWEAK *' to a __weak object of type '__weak id'}}
+}
+
+ at protocol P @end
+ at protocol P1 @end
+
+NOWEAK<P, P1> * Test2() {
+ NOWEAK<P, P1> * strong1 = 0;
+ __weak id<P> weak1;
+ weak1 = strong1; // expected-error {{assignment of a weak-unavailable object to a __weak object}}
+
+ __weak id<P> weak2 = strong1; // expected-error {{assignment of a weak-unavailable object to a __weak object}}
+ return (__weak id<P, P1>)strong1; // expected-error {{cast of weak-unavailable object of type 'NOWEAK<P,P1> *' to a __weak object of type '__weak id<P,P1>'}}
}
Modified: cfe/branches/type-system-rewrite/tools/driver/cc1as_main.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/type-system-rewrite/tools/driver/cc1as_main.cpp?rev=134805&r1=134804&r2=134805&view=diff
==============================================================================
--- cfe/branches/type-system-rewrite/tools/driver/cc1as_main.cpp (original)
+++ cfe/branches/type-system-rewrite/tools/driver/cc1as_main.cpp Sat Jul 9 02:09:12 2011
@@ -30,6 +30,7 @@
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/ErrorHandling.h"
@@ -308,9 +309,11 @@
OwningPtr<MCAsmParser> Parser(createMCAsmParser(*TheTarget, SrcMgr, Ctx,
*Str.get(), *MAI));
- OwningPtr<TargetAsmParser> TAP(
- TheTarget->createAsmParser(TM->getTargetTriple(), TM->getTargetCPU(),
- TM->getTargetFeatureString(), *Parser));
+ OwningPtr<MCSubtargetInfo>
+ STI(TheTarget->createMCSubtargetInfo(TM->getTargetTriple(),
+ TM->getTargetCPU(),
+ TM->getTargetFeatureString()));
+ OwningPtr<TargetAsmParser> TAP(TheTarget->createAsmParser(*STI, *Parser));
if (!TAP) {
Diags.Report(diag::err_target_unknown_triple) << Opts.Triple;
return false;
More information about the llvm-branch-commits
mailing list