[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