[llvm-branch-commits] [cfe-branch] r153953 - in /cfe/branches/tooling: ./ docs/ include/clang-c/ include/clang/AST/ include/clang/Analysis/ include/clang/Basic/ include/clang/Driver/ include/clang/Lex/ include/clang/Sema/ include/clang/StaticAnalyzer/Core/BugReporter/ include/clang/StaticAnalyzer/Core/PathSensitive/ lib/ARCMigrate/ lib/AST/ lib/Basic/ lib/CodeGen/ lib/Driver/ lib/Headers/ lib/Lex/ lib/Parse/ lib/Rewrite/ lib/Sema/ lib/Serialization/ lib/StaticAnalyzer/Checkers/ lib/StaticAnalyzer/Core/ lib/StaticAnalyzer/Fron...

Manuel Klimek klimek at google.com
Tue Apr 3 05:29:13 PDT 2012


Author: klimek
Date: Tue Apr  3 07:29:12 2012
New Revision: 153953

URL: http://llvm.org/viewvc/llvm-project?rev=153953&view=rev
Log:
Merging mainline.

Added:
    cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
      - copied unchanged from r153950, cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
    cfe/branches/tooling/lib/StaticAnalyzer/Core/FunctionSummary.cpp
      - copied unchanged from r153950, cfe/trunk/lib/StaticAnalyzer/Core/FunctionSummary.cpp
    cfe/branches/tooling/test/Analysis/malloc.cpp
      - copied unchanged from r153950, cfe/trunk/test/Analysis/malloc.cpp
    cfe/branches/tooling/test/CXX/expr/expr.const/p3-0x-nowarn.cpp
      - copied unchanged from r153950, cfe/trunk/test/CXX/expr/expr.const/p3-0x-nowarn.cpp
    cfe/branches/tooling/test/CodeGen/mips-constraint-regs.c
      - copied unchanged from r153950, cfe/trunk/test/CodeGen/mips-constraint-regs.c
    cfe/branches/tooling/test/CodeGen/utf16-cfstrings.c
      - copied unchanged from r153950, cfe/trunk/test/CodeGen/utf16-cfstrings.c
    cfe/branches/tooling/test/CodeGenObjC/debug-info-synthesis.m
      - copied unchanged from r153950, cfe/trunk/test/CodeGenObjC/debug-info-synthesis.m
    cfe/branches/tooling/test/Driver/rewrite-legacy-objc.m
      - copied unchanged from r153950, cfe/trunk/test/Driver/rewrite-legacy-objc.m
    cfe/branches/tooling/test/Rewriter/objc-modern-metadata-visibility.mm
      - copied unchanged from r153950, cfe/trunk/test/Rewriter/objc-modern-metadata-visibility.mm
    cfe/branches/tooling/test/Rewriter/objc-modern-numeric-literal.mm
      - copied unchanged from r153950, cfe/trunk/test/Rewriter/objc-modern-numeric-literal.mm
Modified:
    cfe/branches/tooling/   (props changed)
    cfe/branches/tooling/NOTES.txt
    cfe/branches/tooling/docs/AutomaticReferenceCounting.html
    cfe/branches/tooling/include/clang-c/Index.h
    cfe/branches/tooling/include/clang/AST/ExprObjC.h
    cfe/branches/tooling/include/clang/Analysis/ProgramPoint.h
    cfe/branches/tooling/include/clang/Basic/BuiltinsX86.def
    cfe/branches/tooling/include/clang/Basic/DiagnosticParseKinds.td
    cfe/branches/tooling/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/branches/tooling/include/clang/Driver/Options.td
    cfe/branches/tooling/include/clang/Driver/Types.def
    cfe/branches/tooling/include/clang/Lex/Preprocessor.h
    cfe/branches/tooling/include/clang/Sema/Initialization.h
    cfe/branches/tooling/include/clang/Sema/Sema.h
    cfe/branches/tooling/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
    cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
    cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
    cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
    cfe/branches/tooling/lib/ARCMigrate/TransUnusedInitDelegate.cpp
    cfe/branches/tooling/lib/AST/StmtDumper.cpp
    cfe/branches/tooling/lib/AST/StmtProfile.cpp
    cfe/branches/tooling/lib/Basic/Targets.cpp
    cfe/branches/tooling/lib/CodeGen/CGBlocks.cpp
    cfe/branches/tooling/lib/CodeGen/CGCall.cpp
    cfe/branches/tooling/lib/CodeGen/CGClass.cpp
    cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp
    cfe/branches/tooling/lib/CodeGen/CGDecl.cpp
    cfe/branches/tooling/lib/CodeGen/CGDeclCXX.cpp
    cfe/branches/tooling/lib/CodeGen/CGException.cpp
    cfe/branches/tooling/lib/CodeGen/CGExpr.cpp
    cfe/branches/tooling/lib/CodeGen/CGExprAgg.cpp
    cfe/branches/tooling/lib/CodeGen/CGExprCXX.cpp
    cfe/branches/tooling/lib/CodeGen/CGExprConstant.cpp
    cfe/branches/tooling/lib/CodeGen/CGObjC.cpp
    cfe/branches/tooling/lib/CodeGen/CGObjCMac.cpp
    cfe/branches/tooling/lib/CodeGen/CGStmt.cpp
    cfe/branches/tooling/lib/CodeGen/CGValue.h
    cfe/branches/tooling/lib/CodeGen/CodeGenFunction.h
    cfe/branches/tooling/lib/CodeGen/CodeGenModule.cpp
    cfe/branches/tooling/lib/CodeGen/CodeGenModule.h
    cfe/branches/tooling/lib/CodeGen/ItaniumCXXABI.cpp
    cfe/branches/tooling/lib/Driver/Driver.cpp
    cfe/branches/tooling/lib/Driver/ToolChain.cpp
    cfe/branches/tooling/lib/Driver/Tools.cpp
    cfe/branches/tooling/lib/Driver/Types.cpp
    cfe/branches/tooling/lib/Headers/avx2intrin.h
    cfe/branches/tooling/lib/Headers/avxintrin.h
    cfe/branches/tooling/lib/Headers/smmintrin.h
    cfe/branches/tooling/lib/Lex/ModuleMap.cpp
    cfe/branches/tooling/lib/Lex/PPDirectives.cpp
    cfe/branches/tooling/lib/Parse/ParseTemplate.cpp
    cfe/branches/tooling/lib/Rewrite/RewriteModernObjC.cpp
    cfe/branches/tooling/lib/Sema/SemaChecking.cpp
    cfe/branches/tooling/lib/Sema/SemaDecl.cpp
    cfe/branches/tooling/lib/Sema/SemaDeclCXX.cpp
    cfe/branches/tooling/lib/Sema/SemaExpr.cpp
    cfe/branches/tooling/lib/Sema/SemaExprCXX.cpp
    cfe/branches/tooling/lib/Sema/SemaInit.cpp
    cfe/branches/tooling/lib/Sema/SemaLookup.cpp
    cfe/branches/tooling/lib/Sema/SemaOverload.cpp
    cfe/branches/tooling/lib/Sema/SemaPseudoObject.cpp
    cfe/branches/tooling/lib/Sema/SemaStmt.cpp
    cfe/branches/tooling/lib/Sema/SemaTemplate.cpp
    cfe/branches/tooling/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/branches/tooling/lib/Serialization/ASTReaderStmt.cpp
    cfe/branches/tooling/lib/Serialization/ASTWriterStmt.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/BugReporter.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/CMakeLists.txt
    cfe/branches/tooling/lib/StaticAnalyzer/Core/CoreEngine.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngine.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/RegionStore.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
    cfe/branches/tooling/test/ARCMT/init.m
    cfe/branches/tooling/test/ARCMT/init.m.result
    cfe/branches/tooling/test/Analysis/malloc.mm
    cfe/branches/tooling/test/Analysis/misc-ps-region-store.m
    cfe/branches/tooling/test/Analysis/retain-release.mm
    cfe/branches/tooling/test/Analysis/stats.c
    cfe/branches/tooling/test/Analysis/system-header-simulator-objc.h
    cfe/branches/tooling/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp
    cfe/branches/tooling/test/CXX/special/class.copy/implicit-move.cpp
    cfe/branches/tooling/test/CXX/special/class.copy/p11.0x.copy.cpp
    cfe/branches/tooling/test/CXX/special/class.copy/p11.0x.move.cpp
    cfe/branches/tooling/test/CXX/special/class.ctor/p5-0x.cpp
    cfe/branches/tooling/test/CXX/special/class.dtor/p5-0x.cpp
    cfe/branches/tooling/test/CXX/special/class.inhctor/elsewhere.cpp
    cfe/branches/tooling/test/CXX/special/class.inhctor/p3.cpp
    cfe/branches/tooling/test/CXX/special/class.inhctor/p7.cpp
    cfe/branches/tooling/test/CodeGen/atomic-ops.c
    cfe/branches/tooling/test/CodeGen/avx-shuffle-builtins.c
    cfe/branches/tooling/test/CodeGen/darwin-string-literals.c
    cfe/branches/tooling/test/CodeGen/sse-builtins.c
    cfe/branches/tooling/test/CodeGenCXX/assign-operator.cpp
    cfe/branches/tooling/test/CodeGenCXX/const-init-cxx11.cpp
    cfe/branches/tooling/test/CodeGenCXX/debug-info-artificial-arg.cpp
    cfe/branches/tooling/test/CodeGenCXX/static-init.cpp
    cfe/branches/tooling/test/CodeGenObjC/2009-08-05-utf16.m
    cfe/branches/tooling/test/CodeGenObjC/arc.m
    cfe/branches/tooling/test/CodeGenObjC/debug-info-block-helper.m
    cfe/branches/tooling/test/CodeGenObjC/debug-info-property3.m
    cfe/branches/tooling/test/CodeGenObjC/debug-property-synth.m
    cfe/branches/tooling/test/Driver/rewrite-objc.m
    cfe/branches/tooling/test/FixIt/fixit.cpp
    cfe/branches/tooling/test/Index/get-cursor.m
    cfe/branches/tooling/test/Index/index-attrs.m
    cfe/branches/tooling/test/Parser/cxx-template-decl.cpp
    cfe/branches/tooling/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
    cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-constructor.cpp
    cfe/branches/tooling/test/SemaCXX/cxx98-compat-flags.cpp
    cfe/branches/tooling/test/SemaCXX/cxx98-compat.cpp
    cfe/branches/tooling/test/SemaCXX/defaulted-private-dtor.cpp
    cfe/branches/tooling/test/SemaCXX/dr1301.cpp
    cfe/branches/tooling/test/SemaCXX/implicit-exception-spec.cpp
    cfe/branches/tooling/test/SemaCXX/value-initialization.cpp
    cfe/branches/tooling/test/SemaCXX/warn-unreachable.cpp   (props changed)
    cfe/branches/tooling/test/SemaObjC/arc-invalid.m
    cfe/branches/tooling/test/SemaObjC/foreach.m
    cfe/branches/tooling/test/SemaObjC/instancetype.m
    cfe/branches/tooling/test/SemaObjC/related-result-type-inference.m
    cfe/branches/tooling/test/SemaObjCXX/arc-0x.mm
    cfe/branches/tooling/test/SemaTemplate/canonical-expr-type-0x.cpp
    cfe/branches/tooling/test/SemaTemplate/friend-template.cpp
    cfe/branches/tooling/tools/c-index-test/c-index-test.c
    cfe/branches/tooling/tools/driver/cc1as_main.cpp
    cfe/branches/tooling/tools/libclang/CIndex.cpp
    cfe/branches/tooling/tools/libclang/IndexingContext.cpp
    cfe/branches/tooling/tools/libclang/IndexingContext.h
    cfe/branches/tooling/tools/libclang/libclang.exports

Propchange: cfe/branches/tooling/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Apr  3 07:29:12 2012
@@ -1,3 +1,3 @@
 /cfe/branches/type-system-rewrite:134693-134817
-/cfe/trunk:146581-153647
+/cfe/trunk:146581-153950
 /cfe/trunk/test/SemaTemplate:126920

Modified: cfe/branches/tooling/NOTES.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/NOTES.txt?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/NOTES.txt (original)
+++ cfe/branches/tooling/NOTES.txt Tue Apr  3 07:29:12 2012
@@ -101,3 +101,14 @@
 metaprogramming.
 
 //===---------------------------------------------------------------------===//
+
+We can still apply a modified version of the constructor/destructor
+delegation optimization in cases of virtual inheritance where:
+  - there is no function-try-block,
+  - the constructor signature is not variadic, and
+  - the parameter variables can safely be copied and repassed
+    to the base constructor because either
+    - they have not had their addresses taken by the vbase initializers or
+    - they were passed indirectly.
+
+//===---------------------------------------------------------------------===//

Modified: cfe/branches/tooling/docs/AutomaticReferenceCounting.html
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/docs/AutomaticReferenceCounting.html?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/docs/AutomaticReferenceCounting.html (original)
+++ cfe/branches/tooling/docs/AutomaticReferenceCounting.html Tue Apr  3 07:29:12 2012
@@ -1006,7 +1006,9 @@
 <h1>Storage duration of <tt>__autoreleasing</tt> objects</h1>
 
 <p>A program is ill-formed if it declares an <tt>__autoreleasing</tt>
-object of non-automatic storage duration.</p>
+object of non-automatic storage duration.  A program is ill-formed
+if it captures an <tt>__autoreleasing</tt> object in a block or,
+unless by reference, in a C++11 lambda.</p>
 
 <div class="rationale"><p>Rationale: autorelease pools are tied to the
 current thread and scope by their nature.  While it is possible to

Modified: cfe/branches/tooling/include/clang-c/Index.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang-c/Index.h?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang-c/Index.h (original)
+++ cfe/branches/tooling/include/clang-c/Index.h Tue Apr  3 07:29:12 2012
@@ -2904,6 +2904,21 @@
 CINDEX_LINKAGE CXString clang_getCursorSpelling(CXCursor);
 
 /**
+ * \brief Retrieve a range for a piece that forms the cursors spelling name.
+ * Most of the times there is only one range for the complete spelling but for
+ * objc methods and objc message expressions, there are multiple pieces for each
+ * selector identifier.
+ * 
+ * \param pieceIndex the index of the spelling name piece. If this is greater
+ * than the actual number of pieces, it will return a NULL (invalid) range.
+ *  
+ * \param options Reserved.
+ */
+CINDEX_LINKAGE CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor,
+                                                          unsigned pieceIndex,
+                                                          unsigned options);
+
+/**
  * \brief Retrieve the display name for the entity referenced by this cursor.
  *
  * The display name contains extra information that helps identify the cursor,
@@ -2986,6 +3001,20 @@
  */
 CINDEX_LINKAGE CXCursor clang_getCanonicalCursor(CXCursor);
 
+
+/**
+ * \brief If the cursor points to a selector identifier in a objc method or
+ * message expression, this returns the selector index.
+ *
+ * After getting a cursor with \see clang_getCursor, this can be called to
+ * determine if the location points to a selector identifier.
+ *
+ * \returns The selector index if the cursor is an objc method or message
+ * expression and the cursor is pointing to a selector identifier, or -1
+ * otherwise.
+ */
+CINDEX_LINKAGE int clang_Cursor_getObjCSelectorIndex(CXCursor);
+
 /**
  * @}
  */

Modified: cfe/branches/tooling/include/clang/AST/ExprObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/ExprObjC.h?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/ExprObjC.h (original)
+++ cfe/branches/tooling/include/clang/AST/ExprObjC.h Tue Apr  3 07:29:12 2012
@@ -510,7 +510,18 @@
   /// if the bool is false, this is an explicit property reference;
   /// the pointer is an ObjCPropertyDecl and Setter is always null.
   llvm::PointerIntPair<NamedDecl*, 1, bool> PropertyOrGetter;
-  ObjCMethodDecl *Setter;
+
+  /// \brief Indicates whether the property reference will result in a message
+  /// to the getter, the setter, or both.
+  /// This applies to both implicit and explicit property references.
+  enum MethodRefFlags {
+    MethodRef_None = 0,
+    MethodRef_Getter = 0x1,
+    MethodRef_Setter = 0x2
+  };
+
+  /// \brief Contains the Setter method pointer and MethodRefFlags bit flags.
+  llvm::PointerIntPair<ObjCMethodDecl *, 2, unsigned> SetterAndMethodRefFlags;
 
   // FIXME: Maybe we should store the property identifier here,
   // because it's not rederivable from the other data when there's an
@@ -533,7 +544,7 @@
            /*TypeDependent=*/false, base->isValueDependent(),
            base->isInstantiationDependent(),
            base->containsUnexpandedParameterPack()),
-      PropertyOrGetter(PD, false), Setter(0),
+      PropertyOrGetter(PD, false), SetterAndMethodRefFlags(),
       IdLoc(l), ReceiverLoc(), Receiver(base) {
     assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
   }
@@ -544,7 +555,7 @@
     : Expr(ObjCPropertyRefExprClass, t, VK, OK,
            /*TypeDependent=*/false, false, st->isInstantiationDependentType(),
            st->containsUnexpandedParameterPack()),
-      PropertyOrGetter(PD, false), Setter(0),
+      PropertyOrGetter(PD, false), SetterAndMethodRefFlags(),
       IdLoc(l), ReceiverLoc(sl), Receiver(st.getTypePtr()) {
     assert(t->isSpecificPlaceholderType(BuiltinType::PseudoObject));
   }
@@ -555,7 +566,7 @@
     : Expr(ObjCPropertyRefExprClass, T, VK, OK, false,
            Base->isValueDependent(), Base->isInstantiationDependent(),
            Base->containsUnexpandedParameterPack()),
-      PropertyOrGetter(Getter, true), Setter(Setter),
+      PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
       IdLoc(IdLoc), ReceiverLoc(), Receiver(Base) {
     assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
   }
@@ -565,7 +576,7 @@
                       SourceLocation IdLoc,
                       SourceLocation SuperLoc, QualType SuperTy)
     : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
-      PropertyOrGetter(Getter, true), Setter(Setter),
+      PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
       IdLoc(IdLoc), ReceiverLoc(SuperLoc), Receiver(SuperTy.getTypePtr()) {
     assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
   }
@@ -575,7 +586,7 @@
                       SourceLocation IdLoc,
                       SourceLocation ReceiverLoc, ObjCInterfaceDecl *Receiver)
     : Expr(ObjCPropertyRefExprClass, T, VK, OK, false, false, false, false),
-      PropertyOrGetter(Getter, true), Setter(Setter),
+      PropertyOrGetter(Getter, true), SetterAndMethodRefFlags(Setter, 0),
       IdLoc(IdLoc), ReceiverLoc(ReceiverLoc), Receiver(Receiver) {
     assert(T->isSpecificPlaceholderType(BuiltinType::PseudoObject));
   }
@@ -598,7 +609,7 @@
 
   ObjCMethodDecl *getImplicitPropertySetter() const {
     assert(isImplicitProperty());
-    return Setter;
+    return SetterAndMethodRefFlags.getPointer();
   }
 
   Selector getGetterSelector() const {
@@ -613,6 +624,28 @@
     return getExplicitProperty()->getSetterName();
   }
 
+  /// \brief True if the property reference will result in a message to the
+  /// getter.
+  /// This applies to both implicit and explicit property references.
+  bool isMessagingGetter() const {
+    return SetterAndMethodRefFlags.getInt() & MethodRef_Getter;
+  }
+
+  /// \brief True if the property reference will result in a message to the
+  /// setter.
+  /// This applies to both implicit and explicit property references.
+  bool isMessagingSetter() const {
+    return SetterAndMethodRefFlags.getInt() & MethodRef_Setter;
+  }
+
+  void setIsMessagingGetter(bool val = true) {
+    setMethodRefFlag(MethodRef_Getter, val);
+  }
+
+  void setIsMessagingSetter(bool val = true) {
+    setMethodRefFlag(MethodRef_Setter, val);
+  }
+
   const Expr *getBase() const { 
     return cast<Expr>(Receiver.get<Stmt*>()); 
   }
@@ -689,15 +722,19 @@
 
 private:
   friend class ASTStmtReader;
-  void setExplicitProperty(ObjCPropertyDecl *D) {
+  friend class ASTStmtWriter;
+  void setExplicitProperty(ObjCPropertyDecl *D, unsigned methRefFlags) {
     PropertyOrGetter.setPointer(D);
     PropertyOrGetter.setInt(false);
-    Setter = 0;
+    SetterAndMethodRefFlags.setPointer(0);
+    SetterAndMethodRefFlags.setInt(methRefFlags);
   }
-  void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter) {
+  void setImplicitProperty(ObjCMethodDecl *Getter, ObjCMethodDecl *Setter,
+                           unsigned methRefFlags) {
     PropertyOrGetter.setPointer(Getter);
     PropertyOrGetter.setInt(true);
-    this->Setter = Setter;
+    SetterAndMethodRefFlags.setPointer(Setter);
+    SetterAndMethodRefFlags.setInt(methRefFlags);
   }
   void setBase(Expr *Base) { Receiver = Base; }
   void setSuperReceiver(QualType T) { Receiver = T.getTypePtr(); }
@@ -705,6 +742,15 @@
 
   void setLocation(SourceLocation L) { IdLoc = L; }
   void setReceiverLocation(SourceLocation Loc) { ReceiverLoc = Loc; }
+
+  void setMethodRefFlag(MethodRefFlags flag, bool val) {
+    unsigned f = SetterAndMethodRefFlags.getInt();
+    if (val)
+      f |= flag;
+    else
+      f &= ~flag;
+    SetterAndMethodRefFlags.setInt(f);
+  }
 };
   
 /// ObjCSubscriptRefExpr - used for array and dictionary subscripting.

Modified: cfe/branches/tooling/include/clang/Analysis/ProgramPoint.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Analysis/ProgramPoint.h?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Analysis/ProgramPoint.h (original)
+++ cfe/branches/tooling/include/clang/Analysis/ProgramPoint.h Tue Apr  3 07:29:12 2012
@@ -19,6 +19,7 @@
 #include "clang/Analysis/CFG.h"
 #include "llvm/Support/DataTypes.h"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerIntPair.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/ADT/StringRef.h"
@@ -55,42 +56,68 @@
               EpsilonKind};
 
 private:
-  std::pair<const void *, const void *> Data;
-  Kind K;
+  llvm::PointerIntPair<const void *, 2, unsigned> Data1;
+  llvm::PointerIntPair<const void *, 2, unsigned> Data2;
 
   // The LocationContext could be NULL to allow ProgramPoint to be used in
   // context insensitive analysis.
-  const LocationContext *L;
+  llvm::PointerIntPair<const LocationContext *, 2, unsigned> L;
+
   const ProgramPointTag *Tag;
 
   ProgramPoint();
   
 protected:
-  ProgramPoint(const void *P, Kind k, const LocationContext *l,
+  ProgramPoint(const void *P,
+               Kind k,
+               const LocationContext *l,
                const ProgramPointTag *tag = 0)
-    : Data(P, static_cast<const void*>(NULL)), K(k), L(l), Tag(tag) {}
-
-  ProgramPoint(const void *P1, const void *P2, Kind k, const LocationContext *l,
+    : Data1(P, ((unsigned) k) & 0x3),
+      Data2(0, (((unsigned) k) >> 2) & 0x3),
+      L(l, (((unsigned) k) >> 4) & 0x3),
+      Tag(tag) {
+        assert(getKind() == k);
+        assert(getLocationContext() == l);
+        assert(getData1() == P);
+      }
+        
+  ProgramPoint(const void *P1,
+               const void *P2,
+               Kind k,
+               const LocationContext *l,
                const ProgramPointTag *tag = 0)
-    : Data(P1, P2), K(k), L(l), Tag(tag) {}
+    : Data1(P1, ((unsigned) k) & 0x3),
+      Data2(P2, (((unsigned) k) >> 2) & 0x3),
+      L(l, (((unsigned) k) >> 4) & 0x3),
+      Tag(tag) {}
 
 protected:
-  const void *getData1() const { return Data.first; }
-  const void *getData2() const { return Data.second; }
-  void setData2(const void *d) { Data.second = d; }
+  const void *getData1() const { return Data1.getPointer(); }
+  const void *getData2() const { return Data2.getPointer(); }
+  void setData2(const void *d) { Data2.setPointer(d); }
 
 public:
   /// Create a new ProgramPoint object that is the same as the original
   /// except for using the specified tag value.
   ProgramPoint withTag(const ProgramPointTag *tag) const {
-    return ProgramPoint(Data.first, Data.second, K, L, tag);
+    return ProgramPoint(getData1(), getData2(), getKind(),
+                        getLocationContext(), tag);
   }
 
-  Kind getKind() const { return K; }
+  Kind getKind() const {
+    unsigned x = L.getInt();
+    x <<= 2;
+    x |= Data2.getInt();
+    x <<= 2;
+    x |= Data1.getInt();
+    return (Kind) x;
+  }
 
   const ProgramPointTag *getTag() const { return Tag; }
 
-  const LocationContext *getLocationContext() const { return L; }
+  const LocationContext *getLocationContext() const {
+    return L.getPointer();
+  }
 
   // For use with DenseMap.  This hash is probably slow.
   unsigned getHashValue() const {
@@ -102,25 +129,30 @@
   static bool classof(const ProgramPoint*) { return true; }
 
   bool operator==(const ProgramPoint & RHS) const {
-    return K == RHS.K && Data == RHS.Data && L == RHS.L && Tag == RHS.Tag;
+    return Data1 == Data1 &&
+           Data2 == RHS.Data2 &&
+           L == RHS.L &&
+           Tag == RHS.Tag;
   }
 
   bool operator!=(const ProgramPoint &RHS) const {
-    return K != RHS.K || Data != RHS.Data || L != RHS.L || Tag != RHS.Tag;
+    return Data1 != RHS.Data1 ||
+           Data2 != RHS.Data2 ||
+           L != RHS.L ||
+           Tag != RHS.Tag;
   }
 
   void Profile(llvm::FoldingSetNodeID& ID) const {
-    ID.AddInteger((unsigned) K);
-    ID.AddPointer(Data.first);
-    ID.AddPointer(Data.second);
-    ID.AddPointer(L);
+    ID.AddInteger((unsigned) getKind());
+    ID.AddPointer(getData1());
+    ID.AddPointer(getData2());
+    ID.AddPointer(getLocationContext());
     ID.AddPointer(Tag);
   }
 
   static ProgramPoint getProgramPoint(const Stmt *S, ProgramPoint::Kind K,
                                       const LocationContext *LC,
                                       const ProgramPointTag *tag);
-
 };
 
 class BlockEntrance : public ProgramPoint {

Modified: cfe/branches/tooling/include/clang/Basic/BuiltinsX86.def
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/BuiltinsX86.def?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/BuiltinsX86.def (original)
+++ cfe/branches/tooling/include/clang/Basic/BuiltinsX86.def Tue Apr  3 07:29:12 2012
@@ -346,6 +346,7 @@
 BUILTIN(__builtin_ia32_ptestc128, "iV2LLiV2LLi", "")
 BUILTIN(__builtin_ia32_ptestnzc128, "iV2LLiV2LLi", "")
 BUILTIN(__builtin_ia32_mpsadbw128, "V16cV16cV16ci", "")
+BUILTIN(__builtin_ia32_phminposuw128, "V8sV8s", "")
 
 // SSE 4.2
 BUILTIN(__builtin_ia32_pcmpistrm128, "V16cV16cV16cIc", "")

Modified: cfe/branches/tooling/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/DiagnosticParseKinds.td?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticParseKinds.td Tue Apr  3 07:29:12 2012
@@ -480,6 +480,7 @@
 def err_expected_comma_greater : Error<
   "expected ',' or '>' in template-parameter-list">;
 def err_expected_class_before : Error<"expected 'class' before '%0'">;
+def err_expected_class_instead : Error<"expected 'class' instead of '%0'">;
 def err_template_spec_syntax_non_template : Error<
   "identifier followed by '<' indicates a class template specialization but "
   "%0 %select{does not refer to a template|refers to a function "

Modified: cfe/branches/tooling/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/DiagnosticSemaKinds.td?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticSemaKinds.td Tue Apr  3 07:29:12 2012
@@ -27,7 +27,12 @@
 def err_expr_not_cce : Error<
   "%select{case value|enumerator value|non-type template argument}0 "
   "is not a constant expression">;
-def err_cce_narrowing : Error<
+def err_cce_narrowing : ExtWarn<
+  "%select{case value|enumerator value|non-type template argument}0 "
+  "%select{cannot be narrowed from type %2 to %3|"
+  "evaluates to %2, which cannot be narrowed to type %3}1">,
+  InGroup<CXX11Narrowing>, DefaultError;
+def err_cce_narrowing_sfinae : Error<
   "%select{case value|enumerator value|non-type template argument}0 "
   "%select{cannot be narrowed from type %2 to %3|"
   "evaluates to %2, which cannot be narrowed to type %3}1">;
@@ -1184,6 +1189,10 @@
   "an inaccessible constructor|find no viable constructor|find ambiguous "
   "constructors|invoke a deleted constructor}0 in C++98">,
   InGroup<CXX98CompatBindToTemporaryCopy>, DefaultIgnore;
+def err_selected_explicit_constructor : Error<
+  "chosen constructor is explicit in copy-initialization">;
+def note_constructor_declared_here : Note<
+  "constructor declared here">;
 
 // C++11 decltype
 def err_decltype_in_declarator : Error<
@@ -1980,8 +1989,9 @@
     "constructor (the implicit move constructor)|"
     "function (the implicit copy assignment operator)|"
     "function (the implicit move assignment operator)|"
-    "constructor (inherited)}0%1 "
-    "has been explicitly %select{made unavailable|deleted}2">;
+    "constructor (inherited)}0%1 has been "
+    "%select{explicitly made unavailable|explicitly deleted|"
+    "implicitly deleted}2">;
 
 // Giving the index of the bad argument really clutters this message, and
 // it's relatively unimportant because 1) it's generally obvious which
@@ -2499,7 +2509,7 @@
     "no function template matches function template specialization %0">;
 def err_function_template_spec_ambiguous : Error<
     "function template specialization %0 ambiguously refers to more than one "
-    "function template; explicitly specify%select{|additional }1 template "
+    "function template; explicitly specify%select{| additional}1 template "
     "arguments to identify a particular function template">;
 def note_function_template_spec_matched : Note<
     "function template matches specialization %0">;
@@ -2789,6 +2799,8 @@
 def note_unavailable_here : Note<
   "%select{declaration|function}0 has been explicitly marked "
   "%select{unavailable|deleted|deprecated}1 here">;
+def note_implicitly_deleted : Note<
+  "explicitly defaulted function was implicitly deleted here">;
 def warn_not_enough_argument : Warning<
   "not enough variable arguments in %0 declaration to fit a sentinel">,
   InGroup<Sentinel>;
@@ -2816,6 +2828,34 @@
   "friend function %0 would be implicitly redefined in C++98">,
   InGroup<CXX98Compat>, DefaultIgnore;
 
+def note_deleted_dtor_no_operator_delete : Note<
+  "virtual destructor requires an unambiguous, accessible 'operator delete'">;
+def note_deleted_special_member_class_subobject : Note<
+  "%select{default constructor|copy constructor|move constructor|"
+  "copy assignment operator|move assignment operator|destructor}0 of "
+  "%select{||||union }4%1 is implicitly deleted because "
+  "%select{base class %3|field %3}2 has "
+  "%select{no|a deleted|multiple|an inaccessible|a non-trivial}4 "
+  "%select{%select{default constructor|copy constructor|move constructor|copy "
+  "assignment operator|move assignment operator|destructor}0|destructor}5"
+  "%select{||s||}4">;
+def note_deleted_default_ctor_uninit_field : Note<
+  "default constructor of %0 is implicitly deleted because field %1 of "
+  "%select{reference|const-qualified}3 type %2 would not be initialized">;
+def note_deleted_default_ctor_all_const : Note<
+  "default constructor of %0 is implicitly deleted because all "
+  "%select{data members|data members of an anonymous union member}1"
+  " are const-qualified">;
+def note_deleted_copy_ctor_rvalue_reference : Note<
+  "copy constructor of %0 is implicitly deleted because field %1 is of "
+  "rvalue reference type %2">;
+def note_deleted_copy_user_declared_move : Note<
+  "copy %select{constructor|assignment operator}0 is implicitly deleted because"
+  " %1 has a user-declared move %select{constructor|assignment operator}2">;
+def note_deleted_assign_field : Note<
+  "%select{copy|move}0 assignment operator of %0 is implicitly deleted "
+  "because field %1 is of %select{reference|const-qualified}3 type %2">;
+
 // This should eventually be an error.
 def warn_undefined_internal : Warning<
   "%select{function|variable}0 %q1 has internal linkage but is not defined">,
@@ -2990,18 +3030,18 @@
 def err_illegal_initializer_type : Error<"illegal initializer type %0">;
 def err_init_list_type_narrowing_sfinae : Error<
   "type %0 cannot be narrowed to %1 in initializer list">;
-def err_init_list_type_narrowing : Warning<
+def err_init_list_type_narrowing : ExtWarn<
   "type %0 cannot be narrowed to %1 in initializer list">, 
   InGroup<CXX11Narrowing>, DefaultError;
 def err_init_list_variable_narrowing_sfinae : Error<
   "non-constant-expression cannot be narrowed from type %0 to %1 in "
   "initializer list">;
-def err_init_list_variable_narrowing : Warning<
+def err_init_list_variable_narrowing : ExtWarn<
   "non-constant-expression cannot be narrowed from type %0 to %1 in "
   "initializer list">, InGroup<CXX11Narrowing>, DefaultError;
 def err_init_list_constant_narrowing_sfinae : Error<
   "constant expression evaluates to %0 which cannot be narrowed to type %1">;
-def err_init_list_constant_narrowing : Warning<
+def err_init_list_constant_narrowing : ExtWarn<
   "constant expression evaluates to %0 which cannot be narrowed to type %1">,
   InGroup<CXX11Narrowing>, DefaultError;
 def warn_init_list_type_narrowing : Warning<
@@ -3265,6 +3305,9 @@
 def err_arc_autoreleasing_var : Error<
   "%select{__block variables|global variables|fields|ivars}0 cannot have "
   "__autoreleasing ownership">;
+def err_arc_autoreleasing_capture : Error<
+  "cannot capture __autoreleasing variable in a "
+  "%select{block|lambda by copy}0">;
 def err_arc_thread_ownership : Error<
   "thread-local variable has non-trivial ownership: type is %0">;
 def err_arc_indirect_no_ownership : Error<

Modified: cfe/branches/tooling/include/clang/Driver/Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Driver/Options.td?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Driver/Options.td (original)
+++ cfe/branches/tooling/include/clang/Driver/Options.td Tue Apr  3 07:29:12 2012
@@ -21,6 +21,7 @@
 def CompileOnly_Group     : OptionGroup<"<CompileOnly group>">;
 
 def I_Group               : OptionGroup<"<I group>">, Group<CompileOnly_Group>;
+def L_Group               : OptionGroup<"<L group>">, Group<CompileOnly_Group>;
 def M_Group               : OptionGroup<"<M group>">, Group<CompileOnly_Group>;
 def T_Group               : OptionGroup<"<T group>">;
 def O_Group               : OptionGroup<"<O group>">, Group<CompileOnly_Group>;
@@ -736,6 +737,8 @@
 def remap : Flag<"-remap">;
 def rewrite_objc : Flag<"-rewrite-objc">, Flags<[DriverOption]>,
   HelpText<"Rewrite Objective-C source to C++">;
+def rewrite_legacy_objc : Flag<"-rewrite-legacy-objc">, Flags<[DriverOption]>,
+  HelpText<"Rewrite Legacy Objective-C source to C++">;
 def rdynamic : Flag<"-rdynamic">;
 def rpath : Separate<"-rpath">, Flags<[LinkerInput]>;
 def rtlib_EQ : Joined<"-rtlib=">;
@@ -765,7 +768,7 @@
 def static_libstdcxx : Flag<"-static-libstdc++">;
 def static : Flag<"-static">, Flags<[NoArgumentUnused]>;
 def std_default_EQ : Joined<"-std-default=">;
-def std_EQ : Joined<"-std=">;
+def std_EQ : Joined<"-std=">, Group<L_Group>;
 def stdlib_EQ : Joined<"-stdlib=">;
 def sub__library : JoinedOrSeparate<"-sub_library">;
 def sub__umbrella : JoinedOrSeparate<"-sub_umbrella">;

Modified: cfe/branches/tooling/include/clang/Driver/Types.def
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Driver/Types.def?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Driver/Types.def (original)
+++ cfe/branches/tooling/include/clang/Driver/Types.def Tue Apr  3 07:29:12 2012
@@ -82,6 +82,7 @@
 TYPE("ast",                      AST,          INVALID,         "ast",   "u")
 TYPE("plist",                    Plist,        INVALID,         "plist", "")
 TYPE("rewritten-objc",           RewrittenObjC,INVALID,         "cpp",   "")
+TYPE("rewritten-legacy-objc",    RewrittenLegacyObjC,INVALID,   "cpp",   "")
 TYPE("remap",                    Remap,        INVALID,         "remap", "")
 TYPE("precompiled-header",       PCH,          INVALID,         "gch",   "A")
 TYPE("object",                   Object,       INVALID,         "o",     "")

Modified: cfe/branches/tooling/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Lex/Preprocessor.h?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Lex/Preprocessor.h (original)
+++ cfe/branches/tooling/include/clang/Lex/Preprocessor.h Tue Apr  3 07:29:12 2012
@@ -1120,9 +1120,10 @@
 
   /// ReadMacroDefinitionArgList - The ( starting an argument list of a macro
   /// definition has just been read.  Lex the rest of the arguments and the
-  /// closing ), updating MI with what we learn.  Return true if an error occurs
-  /// parsing the arg list.
-  bool ReadMacroDefinitionArgList(MacroInfo *MI);
+  /// closing ), updating MI with what we learn and saving in LastTok the
+  /// last token read.
+  /// Return true if an error occurs parsing the arg list.
+  bool ReadMacroDefinitionArgList(MacroInfo *MI, Token& LastTok);
 
   /// SkipExcludedConditionalBlock - We just read a #if or related directive and
   /// decided that the subsequent tokens are in the #if'd out portion of the

Modified: cfe/branches/tooling/include/clang/Sema/Initialization.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Sema/Initialization.h?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/Initialization.h (original)
+++ cfe/branches/tooling/include/clang/Sema/Initialization.h Tue Apr  3 07:29:12 2012
@@ -719,7 +719,9 @@
     FK_PlaceholderType,
     /// \brief Failed to initialize a std::initializer_list because copy
     /// construction of some element failed.
-    FK_InitListElementCopyFailure
+    FK_InitListElementCopyFailure,
+    /// \brief List-copy-initialization chose an explicit constructor.
+    FK_ExplicitConstructor
   };
   
 private:

Modified: cfe/branches/tooling/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Sema/Sema.h?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/Sema.h (original)
+++ cfe/branches/tooling/include/clang/Sema/Sema.h Tue Apr  3 07:29:12 2012
@@ -660,7 +660,17 @@
   /// This is used for determining parameter types of other objects and is
   /// utterly meaningless on other types of special members.
   class SpecialMemberOverloadResult : public llvm::FastFoldingSetNode {
+  public:
+    enum Kind {
+      NoMemberOrDeleted,
+      Ambiguous,
+      SuccessNonConst,
+      SuccessConst
+    };
+
+  private:
     llvm::PointerIntPair<CXXMethodDecl*, 2> Pair;
+
   public:
     SpecialMemberOverloadResult(const llvm::FoldingSetNodeID &ID)
       : FastFoldingSetNode(ID)
@@ -669,15 +679,11 @@
     CXXMethodDecl *getMethod() const { return Pair.getPointer(); }
     void setMethod(CXXMethodDecl *MD) { Pair.setPointer(MD); }
 
-    bool hasSuccess() const { return Pair.getInt() & 0x1; }
-    void setSuccess(bool B) {
-      Pair.setInt(unsigned(B) | hasConstParamMatch() << 1);
-    }
+    Kind getKind() const { return static_cast<Kind>(Pair.getInt()); }
+    void setKind(Kind K) { Pair.setInt(K); }
 
-    bool hasConstParamMatch() const { return Pair.getInt() & 0x2; }
-    void setConstParamMatch(bool B) {
-      Pair.setInt(B << 1 | unsigned(hasSuccess()));
-    }
+    bool hasSuccess() const { return getKind() >= SuccessNonConst; }
+    bool hasConstParamMatch() const { return getKind() == SuccessConst; }
   };
 
   /// \brief A cache of special member function overload resolution results
@@ -2421,6 +2427,7 @@
   bool CanUseDecl(NamedDecl *D);
   bool DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc,
                          const ObjCInterfaceDecl *UnknownObjCClass=0);
+  void NoteDeletedFunction(FunctionDecl *FD);
   std::string getDeletedOrUnavailableSuffix(const FunctionDecl *FD);
   bool DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *PD,
                                         ObjCMethodDecl *Getter,
@@ -2971,7 +2978,7 @@
                                    bool IsTypeName,
                                    SourceLocation TypenameLoc);
 
-  bool CheckInheritedConstructorUsingDecl(UsingDecl *UD);
+  bool CheckInheritingConstructorUsingDecl(UsingDecl *UD);
 
   Decl *ActOnUsingDeclaration(Scope *CurScope,
                               AccessSpecifier AS,
@@ -3127,7 +3134,8 @@
 
   /// \brief Determine if a special member function should have a deleted
   /// definition when it is defaulted.
-  bool ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM);
+  bool ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM,
+                                 bool Diagnose = false);
 
   /// \brief Declare the implicit default constructor for the given class.
   ///

Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h Tue Apr  3 07:29:12 2012
@@ -20,11 +20,10 @@
 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/ImmutableList.h"
+#include "llvm/ADT/ilist.h"
+#include "llvm/ADT/ilist_node.h"
 #include "llvm/ADT/ImmutableSet.h"
-#include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/DenseSet.h"
-#include <list>
 
 namespace clang {
 
@@ -50,7 +49,7 @@
 
 /// This class provides an interface through which checkers can create
 /// individual bug reports.
-class BugReport {
+class BugReport : public llvm::ilist_node<BugReport> {
 public:  
   class NodeResolver {
     virtual void anchor();
@@ -208,13 +207,38 @@
   virtual void Profile(llvm::FoldingSetNodeID& hash) const;
 };
 
+} // end ento namespace
+} // end clang namespace
+
+namespace llvm {
+  template<> struct ilist_traits<clang::ento::BugReport>
+    : public ilist_default_traits<clang::ento::BugReport> {
+    clang::ento::BugReport *createSentinel() const {
+      return static_cast<clang::ento::BugReport *>(&Sentinel);
+    }
+    void destroySentinel(clang::ento::BugReport *) const {}
+
+    clang::ento::BugReport *provideInitialHead() const {
+      return createSentinel();
+    }
+    clang::ento::BugReport *ensureHead(clang::ento::BugReport *) const {
+      return createSentinel();
+    }
+  private:
+    mutable ilist_half_node<clang::ento::BugReport> Sentinel;
+  };
+}
+
+namespace clang {
+namespace ento {
+
 //===----------------------------------------------------------------------===//
 // BugTypes (collections of related reports).
 //===----------------------------------------------------------------------===//
 
 class BugReportEquivClass : public llvm::FoldingSetNode {
   /// List of *owned* BugReport objects.
-  std::list<BugReport*> Reports;
+  llvm::ilist<BugReport> Reports;
 
   friend class BugReporter;
   void AddReport(BugReport* R) { Reports.push_back(R); }
@@ -224,36 +248,17 @@
 
   void Profile(llvm::FoldingSetNodeID& ID) const {
     assert(!Reports.empty());
-    (*Reports.begin())->Profile(ID);
+    Reports.front().Profile(ID);
   }
 
-  class iterator {
-    std::list<BugReport*>::iterator impl;
-  public:
-    iterator(std::list<BugReport*>::iterator i) : impl(i) {}
-    iterator &operator++() { ++impl; return *this; }
-    bool operator==(const iterator &I) const { return I.impl == impl; }
-    bool operator!=(const iterator &I) const { return I.impl != impl; }
-    BugReport* operator*() const { return *impl; }
-    BugReport* operator->() const { return *impl; }
-  };
-
-  class const_iterator {
-    std::list<BugReport*>::const_iterator impl;
-  public:
-    const_iterator(std::list<BugReport*>::const_iterator i) : impl(i) {}
-    const_iterator &operator++() { ++impl; return *this; }
-    bool operator==(const const_iterator &I) const { return I.impl == impl; }
-    bool operator!=(const const_iterator &I) const { return I.impl != impl; }
-    const BugReport* operator*() const { return *impl; }
-    const BugReport* operator->() const { return *impl; }
-  };
+  typedef llvm::ilist<BugReport>::iterator iterator;
+  typedef llvm::ilist<BugReport>::const_iterator const_iterator;
 
-  iterator begin() { return iterator(Reports.begin()); }
-  iterator end() { return iterator(Reports.end()); }
+  iterator begin() { return Reports.begin(); }
+  iterator end() { return Reports.end(); }
 
-  const_iterator begin() const { return const_iterator(Reports.begin()); }
-  const_iterator end() const { return const_iterator(Reports.end()); }
+  const_iterator begin() const { return Reports.begin(); }
+  const_iterator end() const { return Reports.end(); }
 };
 
 //===----------------------------------------------------------------------===//

Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h Tue Apr  3 07:29:12 2012
@@ -30,8 +30,6 @@
 namespace ento {
   class CheckerManager;
 
-typedef llvm::SmallPtrSet<const Decl*,24> SetOfDecls;
-
 class AnalysisManager : public BugReporterData {
   virtual void anchor();
   AnalysisDeclContextManager AnaCtxMgr;

Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h Tue Apr  3 07:29:12 2012
@@ -18,6 +18,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/Analysis/AnalysisContext.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/WorkList.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h"
 #include "llvm/ADT/OwningPtr.h"
@@ -83,6 +84,10 @@
   /// AnalysisConsumer. It can be null.
   SetOfDecls *AnalyzedCallees;
 
+  /// The information about functions shared by the whole translation unit.
+  /// (This data is owned by AnalysisConsumer.)
+  FunctionSummariesTy *FunctionSummaries;
+
   void generateNode(const ProgramPoint &Loc,
                     ProgramStateRef State,
                     ExplodedNode *Pred);
@@ -104,11 +109,13 @@
 public:
   /// Construct a CoreEngine object to analyze the provided CFG using
   ///  a DFS exploration of the exploded graph.
-  CoreEngine(SubEngine& subengine, SetOfDecls *VisitedCallees)
+  CoreEngine(SubEngine& subengine, SetOfDecls *VisitedCallees,
+             FunctionSummariesTy *FS)
     : SubEng(subengine), G(new ExplodedGraph()),
       WList(WorkList::makeBFS()),
       BCounterFactory(G->getAllocator()),
-      AnalyzedCallees(VisitedCallees) {}
+      AnalyzedCallees(VisitedCallees),
+      FunctionSummaries(FS){}
 
   ~CoreEngine() {
     delete WList;

Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Tue Apr  3 07:29:12 2012
@@ -91,7 +91,8 @@
   GRBugReporter BR;
 
 public:
-  ExprEngine(AnalysisManager &mgr, bool gcEnabled, SetOfDecls *VisitedCallees);
+  ExprEngine(AnalysisManager &mgr, bool gcEnabled, SetOfDecls *VisitedCallees,
+             FunctionSummariesTy *FS);
 
   ~ExprEngine();
 

Modified: cfe/branches/tooling/lib/ARCMigrate/TransUnusedInitDelegate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/ARCMigrate/TransUnusedInitDelegate.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/ARCMigrate/TransUnusedInitDelegate.cpp (original)
+++ cfe/branches/tooling/lib/ARCMigrate/TransUnusedInitDelegate.cpp Tue Apr  3 07:29:12 2012
@@ -54,7 +54,11 @@
       Transaction Trans(Pass.TA);
       Pass.TA.clearDiagnostic(diag::err_arc_unused_init_message,
                               ME->getExprLoc());
-      Pass.TA.insert(ME->getExprLoc(), "self = ");
+      SourceRange ExprRange = ME->getSourceRange();
+      Pass.TA.insert(ExprRange.getBegin(), "if (!(self = ");
+      std::string retStr = ")) return ";
+      retStr += getNilString(Pass.Ctx);
+      Pass.TA.insertAfterToken(ExprRange.getEnd(), retStr);
     }
     return true;
   }

Modified: cfe/branches/tooling/lib/AST/StmtDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/StmtDumper.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/StmtDumper.cpp (original)
+++ cfe/branches/tooling/lib/AST/StmtDumper.cpp Tue Apr  3 07:29:12 2012
@@ -686,6 +686,14 @@
 
   if (Node->isSuperReceiver())
     OS << " super";
+
+  OS << " Messaging=";
+  if (Node->isMessagingGetter() && Node->isMessagingSetter())
+    OS << "Getter&Setter";
+  else if (Node->isMessagingGetter())
+    OS << "Getter";
+  else if (Node->isMessagingSetter())
+    OS << "Setter";
 }
 
 void StmtDumper::VisitObjCSubscriptRefExpr(ObjCSubscriptRefExpr *Node) {

Modified: cfe/branches/tooling/lib/AST/StmtProfile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/StmtProfile.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/StmtProfile.cpp (original)
+++ cfe/branches/tooling/lib/AST/StmtProfile.cpp Tue Apr  3 07:29:12 2012
@@ -1083,6 +1083,14 @@
       return;
     }
 
+    if (const TemplateTypeParmDecl *TTP =
+          dyn_cast<TemplateTypeParmDecl>(D)) {
+      ID.AddInteger(TTP->getDepth());
+      ID.AddInteger(TTP->getIndex());
+      ID.AddBoolean(TTP->isParameterPack());
+      return;
+    }
+
     if (const TemplateTemplateParmDecl *TTP =
           dyn_cast<TemplateTemplateParmDecl>(D)) {
       ID.AddInteger(TTP->getDepth());

Modified: cfe/branches/tooling/lib/Basic/Targets.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Basic/Targets.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Basic/Targets.cpp (original)
+++ cfe/branches/tooling/lib/Basic/Targets.cpp Tue Apr  3 07:29:12 2012
@@ -2791,6 +2791,7 @@
       .Cases("arm1156t2-s", "arm1156t2f-s", "6T2")
       .Cases("cortex-a8", "cortex-a9", "7A")
       .Case("cortex-m3", "7M")
+      .Case("cortex-m4", "7M")
       .Case("cortex-m0", "6M")
       .Default(0);
   }
@@ -3521,6 +3522,9 @@
     case 'd': // Equivalent to "r" unless generating MIPS16 code.
     case 'y': // Equivalent to "r", backwards compatibility only.
     case 'f': // floating-point registers.
+    case 'c': // $25 for indirect jumps
+    case 'l': // lo register
+    case 'x': // hilo register pair
       Info.setAllowsRegister();
       return true;
     }

Modified: cfe/branches/tooling/lib/CodeGen/CGBlocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGBlocks.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGBlocks.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGBlocks.cpp Tue Apr  3 07:29:12 2012
@@ -734,8 +734,7 @@
             AggValueSlot::forAddr(blockField, Align, Qualifiers(),
                                   AggValueSlot::IsDestructed,
                                   AggValueSlot::DoesNotNeedGCBarriers,
-                                  AggValueSlot::IsNotAliased,
-                                  AggValueSlot::IsCompleteObject);
+                                  AggValueSlot::IsNotAliased);
         EmitAggExpr(copyExpr, Slot);
       } else {
         EmitSynthesizedCXXCopyCtor(blockField, src, copyExpr);

Modified: cfe/branches/tooling/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGCall.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGCall.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGCall.cpp Tue Apr  3 07:29:12 2012
@@ -1875,8 +1875,7 @@
           if (Align > AI->getAlignment())
             AI->setAlignment(Align);
           Args.push_back(AI);
-          EmitAggregateCopy(AI, Addr, I->Ty, RV.isVolatileQualified(),
-                            /*destIsCompleteObject*/ true);
+          EmitAggregateCopy(AI, Addr, I->Ty, RV.isVolatileQualified());
               
           // Validate argument match.
           checkArgMatches(AI, IRArgNo, IRFuncTy);

Modified: cfe/branches/tooling/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGClass.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGClass.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGClass.cpp Tue Apr  3 07:29:12 2012
@@ -401,8 +401,7 @@
     AggValueSlot::forAddr(V, Alignment, Qualifiers(),
                           AggValueSlot::IsDestructed,
                           AggValueSlot::DoesNotNeedGCBarriers,
-                          AggValueSlot::IsNotAliased,
-                          AggValueSlot::IsNotCompleteObject);
+                          AggValueSlot::IsNotAliased);
 
   CGF.EmitAggExpr(BaseInit->getInit(), AggSlot);
   
@@ -450,8 +449,7 @@
           AggValueSlot::forLValue(LV,
                                   AggValueSlot::IsDestructed,
                                   AggValueSlot::DoesNotNeedGCBarriers,
-                                  AggValueSlot::IsNotAliased,
-                                  AggValueSlot::IsCompleteObject);
+                                  AggValueSlot::IsNotAliased);
 
         CGF.EmitAggExpr(Init, Slot);
       }
@@ -591,8 +589,7 @@
       
       // Copy the aggregate.
       CGF.EmitAggregateCopy(LHS.getAddress(), Src.getAddress(), FieldType,
-                            LHS.isVolatileQualified(),
-                            /*destIsCompleteObject*/ true);
+                            LHS.isVolatileQualified());
       return;
     }
   }
@@ -734,6 +731,9 @@
 
   EHScopeStack::stable_iterator CleanupDepth = EHStack.stable_begin();
 
+  // TODO: in restricted cases, we can emit the vbase initializers of
+  // a complete ctor and then delegate to the base ctor.
+
   // Emit the constructor prologue, i.e. the base and member
   // initializers.
   EmitCtorPrologue(Ctor, CtorType, Args);
@@ -1374,10 +1374,7 @@
     AggValueSlot::forAddr(ThisPtr, Alignment, Qualifiers(),
                           AggValueSlot::IsDestructed,
                           AggValueSlot::DoesNotNeedGCBarriers,
-                          AggValueSlot::IsNotAliased,
-                          CurGD.getCtorType() == Ctor_Complete
-                            ? AggValueSlot::IsCompleteObject
-                            : AggValueSlot::IsNotCompleteObject);
+                          AggValueSlot::IsNotAliased);
 
   EmitAggExpr(Ctor->init_begin()[0]->getInit(), AggSlot);
 

Modified: cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp Tue Apr  3 07:29:12 2012
@@ -165,6 +165,15 @@
   return StringRef(StrPtr, OS.tell());
 }
 
+/// getSelectorName - Return selector name. This is used for debugging
+/// info.
+StringRef CGDebugInfo::getSelectorName(Selector S) {
+  const std::string &SName = S.getAsString();
+  char *StrPtr = DebugInfoNames.Allocate<char>(SName.size());
+  memcpy(StrPtr, SName.data(), SName.size());
+  return StringRef(StrPtr, SName.size());
+}
+
 /// getClassName - Get class name including template argument list.
 StringRef 
 CGDebugInfo::getClassName(const RecordDecl *RD) {
@@ -1318,13 +1327,11 @@
     SourceLocation Loc = PD->getLocation();
     llvm::DIFile PUnit = getOrCreateFile(Loc);
     unsigned PLine = getLineNumber(Loc);
-    ObjCMethodDecl *GDecl = PD->getGetterMethodDecl();
-    ObjCMethodDecl *SDecl = PD->getSetterMethodDecl();
     llvm::MDNode *PropertyNode =
       DBuilder.createObjCProperty(PD->getName(),
 				  PUnit, PLine,
-				  GDecl ? getObjCMethodName(GDecl) : "",
-				  SDecl ? getObjCMethodName(SDecl) : "",
+                                  getSelectorName(PD->getGetterName()),
+                                  getSelectorName(PD->getSetterName()),
                                   PD->getPropertyAttributes(),
 				  getOrCreateType(PD->getType(), PUnit));
     EltTys.push_back(PropertyNode);
@@ -1381,13 +1388,11 @@
 	  SourceLocation Loc = PD->getLocation();
 	  llvm::DIFile PUnit = getOrCreateFile(Loc);
 	  unsigned PLine = getLineNumber(Loc);
-	  ObjCMethodDecl *GDecl = PD->getGetterMethodDecl();
-	  ObjCMethodDecl *SDecl = PD->getSetterMethodDecl();
 	  PropertyNode =
 	    DBuilder.createObjCProperty(PD->getName(),
 					PUnit, PLine,
-					GDecl ? getObjCMethodName(GDecl) : "",
-					SDecl ? getObjCMethodName(SDecl) : "",
+                                        getSelectorName(PD->getGetterName()),
+                                        getSelectorName(PD->getSetterName()),
 					PD->getPropertyAttributes(),
 					getOrCreateType(PD->getType(),PUnit));
         }
@@ -1964,9 +1969,11 @@
   FnBeginRegionCount.push_back(LexicalBlockStack.size());
 
   const Decl *D = GD.getDecl();
+  // Use the location of the declaration.
+  SourceLocation Loc = D->getLocation();
   
   unsigned Flags = 0;
-  llvm::DIFile Unit = getOrCreateFile(CurLoc);
+  llvm::DIFile Unit = getOrCreateFile(Loc);
   llvm::DIDescriptor FDContext(Unit);
   llvm::DIArray TParamsArray;
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
@@ -2010,17 +2017,16 @@
   if (!Name.empty() && Name[0] == '\01')
     Name = Name.substr(1);
 
-  // It is expected that CurLoc is set before using EmitFunctionStart.
-  // Usually, CurLoc points to the left bracket location of compound
-  // statement representing function body.
-  unsigned LineNo = getLineNumber(CurLoc);
+  unsigned LineNo = getLineNumber(Loc);
   if (D->isImplicit())
     Flags |= llvm::DIDescriptor::FlagArtificial;
+
   llvm::DISubprogram SPDecl = getFunctionDeclaration(D);
   llvm::DISubprogram SP =
     DBuilder.createFunction(FDContext, Name, LinkageName, Unit,
                             LineNo, getOrCreateFunctionType(D, FnType, Unit),
                             Fn->hasInternalLinkage(), true/*definition*/,
+                            getLineNumber(CurLoc),
                             Flags, CGM.getLangOpts().Optimize, Fn,
                             TParamsArray, SPDecl);
 

Modified: cfe/branches/tooling/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGDecl.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGDecl.cpp Tue Apr  3 07:29:12 2012
@@ -273,11 +273,23 @@
   llvm::Value *&DMEntry = LocalDeclMap[&D];
   assert(DMEntry == 0 && "Decl already exists in localdeclmap!");
 
-  llvm::GlobalVariable *GV = CreateStaticVarDecl(D, ".", Linkage);
+  // Check to see if we already have a global variable for this
+  // declaration.  This can happen when double-emitting function
+  // bodies, e.g. with complete and base constructors.
+  llvm::Constant *addr =
+    CGM.getStaticLocalDeclAddress(&D);
+
+  llvm::GlobalVariable *var;
+  if (addr) {
+    var = cast<llvm::GlobalVariable>(addr->stripPointerCasts());
+  } else {
+    addr = var = CreateStaticVarDecl(D, ".", Linkage);
+  }
 
   // Store into LocalDeclMap before generating initializer to handle
   // circular references.
-  DMEntry = GV;
+  DMEntry = addr;
+  CGM.setStaticLocalDeclAddress(&D, addr);
 
   // We can't have a VLA here, but we can have a pointer to a VLA,
   // even though that doesn't really make any sense.
@@ -285,42 +297,38 @@
   if (D.getType()->isVariablyModifiedType())
     EmitVariablyModifiedType(D.getType());
 
-  // Local static block variables must be treated as globals as they may be
-  // referenced in their RHS initializer block-literal expresion.
-  CGM.setStaticLocalDeclAddress(&D, GV);
+  // Save the type in case adding the initializer forces a type change.
+  llvm::Type *expectedType = addr->getType();
 
   // If this value has an initializer, emit it.
   if (D.getInit())
-    GV = AddInitializerToStaticVarDecl(D, GV);
+    var = AddInitializerToStaticVarDecl(D, var);
 
-  GV->setAlignment(getContext().getDeclAlign(&D).getQuantity());
+  var->setAlignment(getContext().getDeclAlign(&D).getQuantity());
 
   if (D.hasAttr<AnnotateAttr>())
-    CGM.AddGlobalAnnotations(&D, GV);
+    CGM.AddGlobalAnnotations(&D, var);
 
   if (const SectionAttr *SA = D.getAttr<SectionAttr>())
-    GV->setSection(SA->getName());
+    var->setSection(SA->getName());
 
   if (D.hasAttr<UsedAttr>())
-    CGM.AddUsedGlobal(GV);
+    CGM.AddUsedGlobal(var);
 
   // We may have to cast the constant because of the initializer
   // mismatch above.
   //
   // FIXME: It is really dangerous to store this in the map; if anyone
   // RAUW's the GV uses of this constant will be invalid.
-  llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(D.getType());
-  llvm::Type *LPtrTy =
-    LTy->getPointerTo(CGM.getContext().getTargetAddressSpace(D.getType()));
-  llvm::Constant *CastedVal = llvm::ConstantExpr::getBitCast(GV, LPtrTy);
-  DMEntry = CastedVal;
-  CGM.setStaticLocalDeclAddress(&D, CastedVal);
+  llvm::Constant *castedAddr = llvm::ConstantExpr::getBitCast(var, expectedType);
+  DMEntry = castedAddr;
+  CGM.setStaticLocalDeclAddress(&D, castedAddr);
 
   // Emit global variable debug descriptor for static vars.
   CGDebugInfo *DI = getDebugInfo();
   if (DI) {
     DI->setLocation(D.getLocation());
-    DI->EmitGlobalVariable(static_cast<llvm::GlobalVariable *>(GV), &D);
+    DI->EmitGlobalVariable(var, &D);
   }
 }
 
@@ -1092,10 +1100,9 @@
   } else {
     // TODO: how can we delay here if D is captured by its initializer?
     EmitAggExpr(init, AggValueSlot::forLValue(lvalue,
-                                         AggValueSlot::IsDestructed,
+                                              AggValueSlot::IsDestructed,
                                          AggValueSlot::DoesNotNeedGCBarriers,
-                                         AggValueSlot::IsNotAliased,
-                                         AggValueSlot::IsCompleteObject));
+                                              AggValueSlot::IsNotAliased));
     MaybeEmitStdInitializerListCleanup(lvalue.getAddress(), init);
   }
 }

Modified: cfe/branches/tooling/lib/CodeGen/CGDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGDeclCXX.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGDeclCXX.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGDeclCXX.cpp Tue Apr  3 07:29:12 2012
@@ -46,11 +46,9 @@
   } else if (type->isAnyComplexType()) {
     CGF.EmitComplexExprIntoAddr(Init, DeclPtr, lv.isVolatile());
   } else {
-    CGF.EmitAggExpr(Init, AggValueSlot::forLValue(lv,
-                                           AggValueSlot::IsDestructed,
-                                           AggValueSlot::DoesNotNeedGCBarriers,
-                                           AggValueSlot::IsNotAliased,
-                                           AggValueSlot::IsCompleteObject));
+    CGF.EmitAggExpr(Init, AggValueSlot::forLValue(lv,AggValueSlot::IsDestructed,
+                                          AggValueSlot::DoesNotNeedGCBarriers,
+                                                  AggValueSlot::IsNotAliased));
   }
 }
 

Modified: cfe/branches/tooling/lib/CodeGen/CGException.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGException.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGException.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGException.cpp Tue Apr  3 07:29:12 2012
@@ -373,7 +373,8 @@
   // evaluated but before the exception is caught.  But the best way
   // to handle that is to teach EmitAggExpr to do the final copy
   // differently if it can't be elided.
-  CGF.EmitAnyExprToMem(e, typedAddr, e->getType().getQualifiers());
+  CGF.EmitAnyExprToMem(e, typedAddr, e->getType().getQualifiers(), 
+                       /*IsInit*/ true);
 
   // Deactivate the cleanup block.
   CGF.DeactivateCleanupBlock(cleanup, cast<llvm::Instruction>(typedAddr));
@@ -1047,8 +1048,7 @@
   if (!copyExpr) {
     llvm::Value *rawAdjustedExn = CallBeginCatch(CGF, Exn, true);
     llvm::Value *adjustedExn = CGF.Builder.CreateBitCast(rawAdjustedExn, PtrTy);
-    CGF.EmitAggregateCopy(ParamAddr, adjustedExn, CatchType,
-                          /*volatile*/ false, 0, /*destIsCompleteObject*/ true);
+    CGF.EmitAggregateCopy(ParamAddr, adjustedExn, CatchType);
     return;
   }
 
@@ -1076,8 +1076,7 @@
                   AggValueSlot::forAddr(ParamAddr, Alignment, Qualifiers(),
                                         AggValueSlot::IsNotDestructed,
                                         AggValueSlot::DoesNotNeedGCBarriers,
-                                        AggValueSlot::IsNotAliased,
-                                        AggValueSlot::IsCompleteObject));
+                                        AggValueSlot::IsNotAliased));
 
   // Leave the terminate scope.
   CGF.EHStack.popTerminate();

Modified: cfe/branches/tooling/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGExpr.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGExpr.cpp Tue Apr  3 07:29:12 2012
@@ -133,17 +133,17 @@
 /// location.
 void CodeGenFunction::EmitAnyExprToMem(const Expr *E,
                                        llvm::Value *Location,
-                                       Qualifiers Quals) {
+                                       Qualifiers Quals,
+                                       bool IsInit) {
   // FIXME: This function should take an LValue as an argument.
   if (E->getType()->isAnyComplexType()) {
     EmitComplexExprIntoAddr(E, Location, Quals.hasVolatile());
   } else if (hasAggregateLLVMType(E->getType())) {
     CharUnits Alignment = getContext().getTypeAlignInChars(E->getType());
     EmitAggExpr(E, AggValueSlot::forAddr(Location, Alignment, Quals,
-                                         AggValueSlot::IsDestructed,
+                                         AggValueSlot::IsDestructed_t(IsInit),
                                          AggValueSlot::DoesNotNeedGCBarriers,
-                                         AggValueSlot::IsNotAliased,
-                                         AggValueSlot::IsCompleteObject));
+                                         AggValueSlot::IsAliased_t(!IsInit)));
   } else {
     RValue RV = RValue::get(EmitScalarExpr(E, /*Ignore*/ false));
     LValue LV = MakeAddrLValue(Location, E->getType());
@@ -366,8 +366,7 @@
       AggSlot = AggValueSlot::forAddr(ReferenceTemporary, Alignment,
                                       Qualifiers(), isDestructed,
                                       AggValueSlot::DoesNotNeedGCBarriers,
-                                      AggValueSlot::IsNotAliased,
-                                      AggValueSlot::IsCompleteObject);
+                                      AggValueSlot::IsNotAliased);
     }
     
     if (InitializedDecl) {
@@ -2152,7 +2151,8 @@
   const Expr *InitExpr = E->getInitializer();
   LValue Result = MakeAddrLValue(DeclPtr, E->getType());
 
-  EmitAnyExprToMem(InitExpr, DeclPtr, E->getType().getQualifiers());
+  EmitAnyExprToMem(InitExpr, DeclPtr, E->getType().getQualifiers(),
+                   /*Init*/ true);
 
   return Result;
 }
@@ -2283,7 +2283,7 @@
     // as a value, copy it into a temporary, and return an lvalue referring to
     // that temporary.
     llvm::Value *V = CreateMemTemp(E->getType(), "ref.temp");
-    EmitAnyExprToMem(E, V, E->getType().getQualifiers());
+    EmitAnyExprToMem(E, V, E->getType().getQualifiers(), false);
     return MakeAddrLValue(V, E->getType());
   }
 
@@ -2754,7 +2754,8 @@
 static llvm::Value *
 EmitValToTemp(CodeGenFunction &CGF, Expr *E) {
   llvm::Value *DeclPtr = CGF.CreateMemTemp(E->getType(), ".atomictmp");
-  CGF.EmitAnyExprToMem(E, DeclPtr, E->getType().getQualifiers());
+  CGF.EmitAnyExprToMem(E, DeclPtr, E->getType().getQualifiers(),
+                       /*Init*/ true);
   return DeclPtr;
 }
 
@@ -2797,7 +2798,6 @@
     Val1 = EmitScalarExpr(E->getVal1());
     Val2 = EmitValToTemp(*this, E->getVal2());
     OrderFail = EmitScalarExpr(E->getOrderFail());
-    (void)OrderFail; // OrderFail is unused at the moment
   } else if ((E->getOp() == AtomicExpr::Add || E->getOp() == AtomicExpr::Sub) &&
              MemTy->isPointerType()) {
     // For pointers, we're required to do a bit of math: adding 1 to an int*
@@ -2816,50 +2816,78 @@
   if (E->getOp() != AtomicExpr::Store && !Dest)
     Dest = CreateMemTemp(E->getType(), ".atomicdst");
 
+  // Use a library call.  See: http://gcc.gnu.org/wiki/Atomic/GCCMM/LIbrary .
   if (UseLibcall) {
-    // FIXME: Finalize what the libcalls are actually supposed to look like.
-    // See also http://gcc.gnu.org/wiki/Atomic/GCCMM/LIbrary .
-    return EmitUnsupportedRValue(E, "atomic library call");
-  }
-#if 0
-  if (UseLibcall) {
+
+    llvm::SmallVector<QualType, 5> Params;
+    CallArgList Args;
+    // Size is always the first parameter
+    Args.add(RValue::get(llvm::ConstantInt::get(SizeTy, Size)),
+             getContext().getSizeType());
+    // Atomic address is always the second parameter
+    Args.add(RValue::get(EmitCastToVoidPtr(Ptr)),
+             getContext().VoidPtrTy);
+
     const char* LibCallName;
+    QualType RetTy = getContext().VoidTy;
     switch (E->getOp()) {
+    // There is only one libcall for compare an exchange, because there is no
+    // optimisation benefit possible from a libcall version of a weak compare
+    // and exchange.
+    // bool __atomic_compare_exchange(size_t size, void *obj, void *expected,
+     //                               void *desired, int success, int failure)
     case AtomicExpr::CmpXchgWeak:
-      LibCallName = "__atomic_compare_exchange_generic"; break;
     case AtomicExpr::CmpXchgStrong:
-      LibCallName = "__atomic_compare_exchange_generic"; break;
-    case AtomicExpr::Add:   LibCallName = "__atomic_fetch_add_generic"; break;
-    case AtomicExpr::Sub:   LibCallName = "__atomic_fetch_sub_generic"; break;
-    case AtomicExpr::And:   LibCallName = "__atomic_fetch_and_generic"; break;
-    case AtomicExpr::Or:    LibCallName = "__atomic_fetch_or_generic"; break;
-    case AtomicExpr::Xor:   LibCallName = "__atomic_fetch_xor_generic"; break;
-    case AtomicExpr::Xchg:  LibCallName = "__atomic_exchange_generic"; break;
-    case AtomicExpr::Store: LibCallName = "__atomic_store_generic"; break;
-    case AtomicExpr::Load:  LibCallName = "__atomic_load_generic"; break;
-    }
-    llvm::SmallVector<QualType, 4> Params;
-    CallArgList Args;
-    QualType RetTy = getContext().VoidTy;
-    if (E->getOp() != AtomicExpr::Store && !E->isCmpXChg())
+      LibCallName = "__atomic_compare_exchange";
+      RetTy = getContext().BoolTy;
+      Args.add(RValue::get(EmitCastToVoidPtr(Val1)),
+               getContext().VoidPtrTy);
+      Args.add(RValue::get(EmitCastToVoidPtr(Val2)),
+               getContext().VoidPtrTy);
+      Args.add(RValue::get(Order),
+               getContext().IntTy);
+      Order = OrderFail;
+      break;
+    // void __atomic_exchange(size_t size, void *mem, void *val, void *return,
+    //                        int order)
+    case AtomicExpr::Xchg:
+      LibCallName = "__atomic_exchange";
+      Args.add(RValue::get(EmitCastToVoidPtr(Val1)),
+               getContext().VoidPtrTy);
       Args.add(RValue::get(EmitCastToVoidPtr(Dest)),
                getContext().VoidPtrTy);
-    Args.add(RValue::get(EmitCastToVoidPtr(Ptr)),
-             getContext().VoidPtrTy);
-    if (E->getOp() != AtomicExpr::Load)
+      break;
+    // void __atomic_store(size_t size, void *mem, void *val, int order)
+    case AtomicExpr::Store:
+      LibCallName = "__atomic_store";
       Args.add(RValue::get(EmitCastToVoidPtr(Val1)),
                getContext().VoidPtrTy);
-    if (E->isCmpXChg()) {
-      Args.add(RValue::get(EmitCastToVoidPtr(Val2)),
+      break;
+    // void __atomic_load(size_t size, void *mem, void *return, int order)
+    case AtomicExpr::Load:
+      LibCallName = "__atomic_load";
+      Args.add(RValue::get(EmitCastToVoidPtr(Dest)),
                getContext().VoidPtrTy);
-      RetTy = getContext().IntTy;
+      break;
+#if 0
+    // These are only defined for 1-16 byte integers.  It is not clear what
+    // their semantics would be on anything else...
+    case AtomicExpr::Add:   LibCallName = "__atomic_fetch_add_generic"; break;
+    case AtomicExpr::Sub:   LibCallName = "__atomic_fetch_sub_generic"; break;
+    case AtomicExpr::And:   LibCallName = "__atomic_fetch_and_generic"; break;
+    case AtomicExpr::Or:    LibCallName = "__atomic_fetch_or_generic"; break;
+    case AtomicExpr::Xor:   LibCallName = "__atomic_fetch_xor_generic"; break;
+#endif
+    default: return EmitUnsupportedRValue(E, "atomic library call");
     }
-    Args.add(RValue::get(llvm::ConstantInt::get(SizeTy, Size)),
-             getContext().getSizeType());
+    // order is always the last parameter
+    Args.add(RValue::get(Order),
+             getContext().IntTy);
+
     const CGFunctionInfo &FuncInfo =
-        CGM.getTypes().arrangeFunctionCall(RetTy, Args, FunctionType::ExtInfo(),
-                                           /*variadic*/ false);
-    llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo, false);
+        CGM.getTypes().arrangeFunctionCall(RetTy, Args,
+            FunctionType::ExtInfo(), RequiredArgs::All);
+    llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo);
     llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, LibCallName);
     RValue Res = EmitCall(FuncInfo, Func, ReturnValueSlot(), Args);
     if (E->isCmpXChg())
@@ -2868,7 +2896,7 @@
       return RValue::get(0);
     return ConvertTempToRValue(*this, E->getType(), Dest);
   }
-#endif
+
   llvm::Type *IPtrTy =
       llvm::IntegerType::get(getLLVMContext(), Size * 8)->getPointerTo();
   llvm::Value *OrigDest = Dest;

Modified: cfe/branches/tooling/lib/CodeGen/CGExprAgg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGExprAgg.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGExprAgg.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGExprAgg.cpp Tue Apr  3 07:29:12 2012
@@ -179,8 +179,7 @@
 
   void VisitVAArgExpr(VAArgExpr *E);
 
-  void EmitInitializationToLValue(Expr *E, LValue Address,
-                          AggValueSlot::IsCompleteObject_t isCompleteObject);
+  void EmitInitializationToLValue(Expr *E, LValue Address);
   void EmitNullInitializationToLValue(LValue Address);
   //  case Expr::ChooseExprClass:
   void VisitCXXThrowExpr(const CXXThrowExpr *E) { CGF.EmitCXXThrowExpr(E); }
@@ -280,7 +279,7 @@
   // is volatile, unless copy has volatile for both source and destination..
   CGF.EmitAggregateCopy(Dest.getAddr(), Src.getAggregateAddr(), E->getType(),
                         Dest.isVolatile()|Src.isVolatileQualified(),
-                        Alignment, Dest.isCompleteObject());
+                        Alignment);
 }
 
 /// EmitFinalDestCopy - Perform the final copy to DestPtr, if desired.
@@ -442,8 +441,7 @@
       EmitStdInitializerList(element, initList);
     } else {
       LValue elementLV = CGF.MakeAddrLValue(element, elementType);
-      EmitInitializationToLValue(E->getInit(i), elementLV,
-                                 AggValueSlot::IsCompleteObject);
+      EmitInitializationToLValue(E->getInit(i), elementLV);
     }
   }
 
@@ -490,8 +488,7 @@
     // Emit the actual filler expression.
     LValue elementLV = CGF.MakeAddrLValue(currentElement, elementType);
     if (filler)
-      EmitInitializationToLValue(filler, elementLV,
-                                 AggValueSlot::IsCompleteObject);
+      EmitInitializationToLValue(filler, elementLV);
     else
       EmitNullInitializationToLValue(elementLV);
 
@@ -570,8 +567,7 @@
     llvm::Value *CastPtr = Builder.CreateBitCast(Dest.getAddr(),
                                                  CGF.ConvertType(PtrTy));
     EmitInitializationToLValue(E->getSubExpr(),
-                               CGF.MakeAddrLValue(CastPtr, Ty),
-                               Dest.isCompleteObject());
+                               CGF.MakeAddrLValue(CastPtr, Ty));
     break;
   }
 
@@ -679,29 +675,6 @@
   EmitFinalDestCopy(E, LV);
 }
 
-/// Quickly check whether the object looks like it might be a complete
-/// object.
-static AggValueSlot::IsCompleteObject_t isCompleteObject(const Expr *E) {
-  E = E->IgnoreParens();
-
-  QualType objectType;
-  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
-    objectType = DRE->getDecl()->getType();
-  } else if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
-    objectType = ME->getMemberDecl()->getType();
-  } else {
-    // Be conservative.
-    return AggValueSlot::MayNotBeCompleteObject;
-  }
-
-  // The expression refers directly to some sort of object.
-  // If that object has reference type, be conservative.
-  if (objectType->isReferenceType())
-    return AggValueSlot::MayNotBeCompleteObject;
-
-  return AggValueSlot::IsCompleteObject;
-}
-
 void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
   // For an assignment to work, the value on the right has
   // to be compatible with the value on the left.
@@ -709,8 +682,7 @@
                                                  E->getRHS()->getType())
          && "Invalid assignment");
 
-  if (const DeclRefExpr *DRE
-        = dyn_cast<DeclRefExpr>(E->getLHS()->IgnoreParens()))
+  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->getLHS()))
     if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl()))
       if (VD->hasAttr<BlocksAttr>() &&
           E->getRHS()->HasSideEffects(CGF.getContext())) {
@@ -720,20 +692,18 @@
         LValue LHS = CGF.EmitLValue(E->getLHS());
         Dest = AggValueSlot::forLValue(LHS, AggValueSlot::IsDestructed,
                                        needsGC(E->getLHS()->getType()),
-                                       AggValueSlot::IsAliased,
-                                       AggValueSlot::IsCompleteObject);
+                                       AggValueSlot::IsAliased);
         EmitFinalDestCopy(E, RHS, true);
         return;
       }
-
+  
   LValue LHS = CGF.EmitLValue(E->getLHS());
 
   // Codegen the RHS so that it stores directly into the LHS.
   AggValueSlot LHSSlot =
     AggValueSlot::forLValue(LHS, AggValueSlot::IsDestructed, 
                             needsGC(E->getLHS()->getType()),
-                            AggValueSlot::IsAliased,
-                            isCompleteObject(E->getLHS()));
+                            AggValueSlot::IsAliased);
   CGF.EmitAggExpr(E->getRHS(), LHSSlot, false);
   EmitFinalDestCopy(E, LHS, true);
 }
@@ -866,8 +836,7 @@
 
 
 void 
-AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV,
-                                 AggValueSlot::IsCompleteObject_t isCompleteObject) {
+AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV) {
   QualType type = LV.getType();
   // FIXME: Ignore result?
   // FIXME: Are initializers affected by volatile?
@@ -885,7 +854,6 @@
                                                AggValueSlot::IsDestructed,
                                       AggValueSlot::DoesNotNeedGCBarriers,
                                                AggValueSlot::IsNotAliased,
-                                               isCompleteObject,
                                                Dest.isZeroed()));
   } else if (LV.isSimple()) {
     CGF.EmitScalarInit(E, /*D=*/0, LV, /*Captured=*/false);
@@ -1001,8 +969,7 @@
     LValue FieldLoc = CGF.EmitLValueForFieldInitialization(DestPtr, Field, 0);
     if (NumInitElements) {
       // Store the initializer into the field
-      EmitInitializationToLValue(E->getInit(0), FieldLoc,
-                                 AggValueSlot::IsCompleteObject);
+      EmitInitializationToLValue(E->getInit(0), FieldLoc);
     } else {
       // Default-initialize to null.
       EmitNullInitializationToLValue(FieldLoc);
@@ -1044,8 +1011,7 @@
     
     if (curInitIndex < NumInitElements) {
       // Store the initializer into the field.
-      EmitInitializationToLValue(E->getInit(curInitIndex++), LV,
-                                 AggValueSlot::IsCompleteObject);
+      EmitInitializationToLValue(E->getInit(curInitIndex++), LV);
     } else {
       // We're out of initalizers; default-initialize to null
       EmitNullInitializationToLValue(LV);
@@ -1220,106 +1186,105 @@
   LValue LV = MakeAddrLValue(Temp, E->getType());
   EmitAggExpr(E, AggValueSlot::forLValue(LV, AggValueSlot::IsNotDestructed,
                                          AggValueSlot::DoesNotNeedGCBarriers,
-                                         AggValueSlot::IsNotAliased,
-                                         AggValueSlot::IsCompleteObject));
+                                         AggValueSlot::IsNotAliased));
   return LV;
 }
 
-void CodeGenFunction::EmitAggregateCopy(llvm::Value *dest, llvm::Value *src,
-                                        QualType type,
-                                        bool isVolatile, unsigned alignment,
-                                        bool destIsCompleteObject) {
-  assert(!type->isAnyComplexType() && "Shouldn't happen for complex");
-
-  // Get size and alignment info for this type.  Note that the type
-  // might include an alignment attribute, so we can't just rely on
-  // the layout.
-  // FIXME: Do we need to handle VLAs here?
-  std::pair<CharUnits, CharUnits> typeInfo =
-    getContext().getTypeInfoInChars(type);
-
-  // If we weren't given an alignment, use the natural alignment.
-  if (!alignment) alignment = typeInfo.second.getQuantity();
-
-  CharUnits sizeToCopy = typeInfo.first;
+void CodeGenFunction::EmitAggregateCopy(llvm::Value *DestPtr,
+                                        llvm::Value *SrcPtr, QualType Ty,
+                                        bool isVolatile, unsigned Alignment) {
+  assert(!Ty->isAnyComplexType() && "Shouldn't happen for complex");
 
-  // There's some special logic that applies to C++ classes:
   if (getContext().getLangOpts().CPlusPlus) {
-    if (const RecordType *RT = type->getAs<RecordType>()) {
-      // First, we want to assert that we're not doing this to
-      // something with a non-trivial operator/constructor.
-      CXXRecordDecl *record = cast<CXXRecordDecl>(RT->getDecl());
-      assert((record->hasTrivialCopyConstructor() || 
-              record->hasTrivialCopyAssignment() ||
-              record->hasTrivialMoveConstructor() ||
-              record->hasTrivialMoveAssignment()) &&
+    if (const RecordType *RT = Ty->getAs<RecordType>()) {
+      CXXRecordDecl *Record = cast<CXXRecordDecl>(RT->getDecl());
+      assert((Record->hasTrivialCopyConstructor() || 
+              Record->hasTrivialCopyAssignment() ||
+              Record->hasTrivialMoveConstructor() ||
+              Record->hasTrivialMoveAssignment()) &&
              "Trying to aggregate-copy a type without a trivial copy "
              "constructor or assignment operator");
-
-      // Second, we want to ignore empty classes.
-      if (record->isEmpty())
+      // Ignore empty classes in C++.
+      if (Record->isEmpty())
         return;
-
-      // Third, if it's possible that the destination might not be a
-      // complete object, then we need to make sure we only copy the
-      // data size, not the full sizeof, so that we don't overwrite
-      // subclass fields in the tailing padding.  It's generally going
-      // to be more efficient to copy the sizeof, since we can use
-      // larger stores.
-      //
-      // Unions and final classes can never be base classes.
-      if (!destIsCompleteObject && !record->isUnion() &&
-          !record->hasAttr<FinalAttr>()) {
-        const ASTRecordLayout &layout
-          = getContext().getASTRecordLayout(record);
-        sizeToCopy = layout.getDataSize();
-      }
     }
   }
   
-  llvm::PointerType *DPT = cast<llvm::PointerType>(dest->getType());
+  // Aggregate assignment turns into llvm.memcpy.  This is almost valid per
+  // C99 6.5.16.1p3, which states "If the value being stored in an object is
+  // read from another object that overlaps in anyway the storage of the first
+  // object, then the overlap shall be exact and the two objects shall have
+  // qualified or unqualified versions of a compatible type."
+  //
+  // memcpy is not defined if the source and destination pointers are exactly
+  // equal, but other compilers do this optimization, and almost every memcpy
+  // implementation handles this case safely.  If there is a libc that does not
+  // safely handle this, we can add a target hook.
+
+  // Get size and alignment info for this aggregate.
+  std::pair<CharUnits, CharUnits> TypeInfo = 
+    getContext().getTypeInfoInChars(Ty);
+
+  if (!Alignment)
+    Alignment = TypeInfo.second.getQuantity();
+
+  // FIXME: Handle variable sized types.
+
+  // FIXME: If we have a volatile struct, the optimizer can remove what might
+  // appear to be `extra' memory ops:
+  //
+  // volatile struct { int i; } a, b;
+  //
+  // int main() {
+  //   a = b;
+  //   a = b;
+  // }
+  //
+  // we need to use a different call here.  We use isVolatile to indicate when
+  // either the source or the destination is volatile.
+
+  llvm::PointerType *DPT = cast<llvm::PointerType>(DestPtr->getType());
   llvm::Type *DBP =
     llvm::Type::getInt8PtrTy(getLLVMContext(), DPT->getAddressSpace());
-  dest = Builder.CreateBitCast(dest, DBP);
+  DestPtr = Builder.CreateBitCast(DestPtr, DBP);
 
-  llvm::PointerType *SPT = cast<llvm::PointerType>(src->getType());
+  llvm::PointerType *SPT = cast<llvm::PointerType>(SrcPtr->getType());
   llvm::Type *SBP =
     llvm::Type::getInt8PtrTy(getLLVMContext(), SPT->getAddressSpace());
-  src = Builder.CreateBitCast(src, SBP);
-
-  llvm::Value *sizeVal =
-    llvm::ConstantInt::get(CGM.SizeTy, sizeToCopy.getQuantity());
+  SrcPtr = Builder.CreateBitCast(SrcPtr, SBP);
 
   // Don't do any of the memmove_collectable tests if GC isn't set.
   if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
     // fall through
-  } else if (const RecordType *RT = type->getAs<RecordType>()) {
-    if (RT->getDecl()->hasObjectMember()) {
-      CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, dest, src, sizeVal);
+  } else if (const RecordType *RecordTy = Ty->getAs<RecordType>()) {
+    RecordDecl *Record = RecordTy->getDecl();
+    if (Record->hasObjectMember()) {
+      CharUnits size = TypeInfo.first;
+      llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
+      llvm::Value *SizeVal = llvm::ConstantInt::get(SizeTy, size.getQuantity());
+      CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr, 
+                                                    SizeVal);
       return;
     }
-  } else if (type->isArrayType()) {
-    QualType baseType = getContext().getBaseElementType(type);
-    if (const RecordType *RT = baseType->getAs<RecordType>()) {
-      if (RT->getDecl()->hasObjectMember()) {
-        CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, dest, src,sizeVal);
+  } else if (Ty->isArrayType()) {
+    QualType BaseType = getContext().getBaseElementType(Ty);
+    if (const RecordType *RecordTy = BaseType->getAs<RecordType>()) {
+      if (RecordTy->getDecl()->hasObjectMember()) {
+        CharUnits size = TypeInfo.first;
+        llvm::Type *SizeTy = ConvertType(getContext().getSizeType());
+        llvm::Value *SizeVal = 
+          llvm::ConstantInt::get(SizeTy, size.getQuantity());
+        CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr, 
+                                                      SizeVal);
         return;
       }
     }
   }
-
-  // Aggregate assignment turns into llvm.memcpy.  This is almost valid per
-  // C99 6.5.16.1p3, which states "If the value being stored in an object is
-  // read from another object that overlaps in anyway the storage of the first
-  // object, then the overlap shall be exact and the two objects shall have
-  // qualified or unqualified versions of a compatible type."
-  //
-  // memcpy is not defined if the source and destination pointers are exactly
-  // equal, but other compilers do this optimization, and almost every memcpy
-  // implementation handles this case safely.  If there is a libc that does not
-  // safely handle this, we can add a target hook.
   
-  Builder.CreateMemCpy(dest, src, sizeVal, alignment, isVolatile);
+  Builder.CreateMemCpy(DestPtr, SrcPtr,
+                       llvm::ConstantInt::get(IntPtrTy, 
+                                              TypeInfo.first.getQuantity()),
+                       Alignment, isVolatile);
 }
 
 void CodeGenFunction::MaybeEmitStdInitializerListCleanup(llvm::Value *loc,

Modified: cfe/branches/tooling/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGExprCXX.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGExprCXX.cpp Tue Apr  3 07:29:12 2012
@@ -781,8 +781,7 @@
       = AggValueSlot::forAddr(NewPtr, Alignment, AllocType.getQualifiers(),
                               AggValueSlot::IsDestructed,
                               AggValueSlot::DoesNotNeedGCBarriers,
-                              AggValueSlot::IsNotAliased,
-                              AggValueSlot::IsCompleteObject);
+                              AggValueSlot::IsNotAliased);
     CGF.EmitAggExpr(Init, Slot);
 
     CGF.MaybeEmitStdInitializerListCleanup(NewPtr, Init);

Modified: cfe/branches/tooling/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGExprConstant.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGExprConstant.cpp Tue Apr  3 07:29:12 2012
@@ -102,7 +102,7 @@
     llvm::ConstantExpr::getInBoundsGetElementPtr(VTable, Indices);
 
   // Add the vtable at the start of the object.
-  AppendBytes(CharUnits::Zero(), VTableAddressPoint);
+  AppendBytes(Base.getBaseOffset(), VTableAddressPoint);
 }
 
 void ConstStructBuilder::
@@ -469,21 +469,17 @@
 
     for (unsigned I = 0, N = Bases.size(); I != N; ++I) {
       BaseInfo &Base = Bases[I];
-      // Build the base class subobject at the appropriately-offset location
-      // within this object.
-      NextFieldOffsetInChars -= Base.Offset;
 
       bool IsPrimaryBase = Layout.getPrimaryBase() == Base.Decl;
       Build(Val.getStructBase(Base.Index), Base.Decl, IsPrimaryBase,
             VTable, VTableClass, Offset + Base.Offset);
-
-      NextFieldOffsetInChars += Base.Offset;
     }
   }
 
   unsigned FieldNo = 0;
   const FieldDecl *LastFD = 0;
   bool IsMsStruct = RD->hasAttr<MsStructAttr>();
+  uint64_t OffsetBits = CGM.getContext().toBits(Offset);
 
   for (RecordDecl::field_iterator Field = RD->field_begin(),
        FieldEnd = RD->field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
@@ -516,10 +512,10 @@
 
     if (!Field->isBitField()) {
       // Handle non-bitfield members.
-      AppendField(*Field, Layout.getFieldOffset(FieldNo), EltInit);
+      AppendField(*Field, Layout.getFieldOffset(FieldNo) + OffsetBits, EltInit);
     } else {
       // Otherwise we have a bitfield.
-      AppendBitField(*Field, Layout.getFieldOffset(FieldNo),
+      AppendBitField(*Field, Layout.getFieldOffset(FieldNo) + OffsetBits,
                      cast<llvm::ConstantInt>(EltInit));
     }
   }

Modified: cfe/branches/tooling/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGObjC.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGObjC.cpp Tue Apr  3 07:29:12 2012
@@ -54,7 +54,8 @@
 /// EmitObjCNumericLiteral - This routine generates code for
 /// the appropriate +[NSNumber numberWith<Type>:] method.
 ///
-llvm::Value *CodeGenFunction::EmitObjCNumericLiteral(const ObjCNumericLiteral *E) {
+llvm::Value *
+CodeGenFunction::EmitObjCNumericLiteral(const ObjCNumericLiteral *E) {
   // Generate the correct selector for this literal's concrete type.
   const Expr *NL = E->getNumber();
   // Get the method.
@@ -165,11 +166,12 @@
   llvm::Value *Receiver = Runtime.GetClass(Builder, Class);
 
   // Generate the message send.
-  RValue result = Runtime.GenerateMessageSend(*this, ReturnValueSlot(), 
-                                              MethodWithObjects->getResultType(),
-                                              Sel,
-                                              Receiver, Args, Class,
-                                              MethodWithObjects);
+  RValue result
+    = Runtime.GenerateMessageSend(*this, ReturnValueSlot(), 
+                                  MethodWithObjects->getResultType(),
+                                  Sel,
+                                  Receiver, Args, Class,
+                                  MethodWithObjects);
   return Builder.CreateBitCast(result.getScalarVal(), 
                                ConvertType(E->getType()));
 }
@@ -450,7 +452,7 @@
   args.push_back(OMD->getCmdDecl());
 
   for (ObjCMethodDecl::param_const_iterator PI = OMD->param_begin(),
-       E = OMD->param_end(); PI != E; ++PI)
+         E = OMD->param_end(); PI != E; ++PI)
     args.push_back(*PI);
 
   CurGD = OMD;
@@ -706,7 +708,7 @@
   const ObjCPropertyDecl *PD = PID->getPropertyDecl();
   ObjCMethodDecl *OMD = PD->getGetterMethodDecl();
   assert(OMD && "Invalid call to generate getter (empty method)");
-  StartObjCMethod(OMD, IMP->getClassInterface(), PID->getLocStart());
+  StartObjCMethod(OMD, IMP->getClassInterface(), OMD->getLocStart());
 
   generateObjCGetterBody(IMP, PID, AtomicHelperFn);
 
@@ -885,8 +887,7 @@
       // The return value slot is guaranteed to not be aliased, but
       // that's not necessarily the same as "on the stack", so
       // we still potentially need objc_memmove_collectable.
-      EmitAggregateCopy(ReturnValue, LV.getAddress(), ivarType,
-                        /*volatile*/ false, 0, /*destIsCompleteObject*/ true);
+      EmitAggregateCopy(ReturnValue, LV.getAddress(), ivarType);
     } else {
       llvm::Value *value;
       if (propType->isReferenceType()) {
@@ -1091,8 +1092,9 @@
     if (UseOptimizedSetter(CGM)) {
       // 10.8 code and GC is off
       setOptimizedPropertyFn = 
-        CGM.getObjCRuntime().GetOptimizedPropertySetFunction(strategy.isAtomic(),
-                                                             strategy.isCopy());
+        CGM.getObjCRuntime()
+           .GetOptimizedPropertySetFunction(strategy.isAtomic(),
+                                            strategy.isCopy());
       if (!setOptimizedPropertyFn) {
         CGM.ErrorUnsupported(propImpl, "Obj-C optimized setter - NYI");
         return;
@@ -1214,7 +1216,7 @@
   const ObjCPropertyDecl *PD = PID->getPropertyDecl();
   ObjCMethodDecl *OMD = PD->getSetterMethodDecl();
   assert(OMD && "Invalid call to generate setter (empty method)");
-  StartObjCMethod(OMD, IMP->getClassInterface(), PID->getLocStart());
+  StartObjCMethod(OMD, IMP->getClassInterface(), OMD->getLocStart());
 
   generateObjCSetterBody(IMP, PID, AtomicHelperFn);
 
@@ -1310,8 +1312,7 @@
       EmitAggExpr(IvarInit->getInit(),
                   AggValueSlot::forLValue(LV, AggValueSlot::IsDestructed,
                                           AggValueSlot::DoesNotNeedGCBarriers,
-                                          AggValueSlot::IsNotAliased,
-                                          AggValueSlot::IsCompleteObject));
+                                          AggValueSlot::IsNotAliased));
     }
     // constructor returns 'self'.
     CodeGenTypes &Types = CGM.getTypes();
@@ -2706,7 +2707,7 @@
 }
 
 void CodeGenFunction::EmitObjCAutoreleasePoolStmt(
-                                             const ObjCAutoreleasePoolStmt &ARPS) {
+                                          const ObjCAutoreleasePoolStmt &ARPS) {
   const Stmt *subStmt = ARPS.getSubStmt();
   const CompoundStmt &S = cast<CompoundStmt>(*subStmt);
 
@@ -2803,7 +2804,8 @@
   
   llvm::Function *Fn =
     llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
-                           "__assign_helper_atomic_property_", &CGM.getModule());
+                           "__assign_helper_atomic_property_",
+                           &CGM.getModule());
   
   if (CGM.getModuleDebugInfo())
     DebugInfo = CGM.getModuleDebugInfo();
@@ -2922,19 +2924,20 @@
                              CXXConstExpr->hadMultipleCandidates(),
                              CXXConstExpr->isListInitialization(),
                              CXXConstExpr->requiresZeroInitialization(),
-                             CXXConstExpr->getConstructionKind(), SourceRange());
+                             CXXConstExpr->getConstructionKind(),
+                             SourceRange());
   
   DeclRefExpr DstExpr(&dstDecl, false, DestTy,
                       VK_RValue, SourceLocation());
   
   RValue DV = EmitAnyExpr(&DstExpr);
-  CharUnits Alignment = getContext().getTypeAlignInChars(TheCXXConstructExpr->getType());
+  CharUnits Alignment
+    = getContext().getTypeAlignInChars(TheCXXConstructExpr->getType());
   EmitAggExpr(TheCXXConstructExpr, 
               AggValueSlot::forAddr(DV.getScalarVal(), Alignment, Qualifiers(),
                                     AggValueSlot::IsDestructed,
                                     AggValueSlot::DoesNotNeedGCBarriers,
-                                    AggValueSlot::IsNotAliased,
-                                    AggValueSlot::IsCompleteObject));
+                                    AggValueSlot::IsNotAliased));
   
   FinishFunction();
   HelperFn = llvm::ConstantExpr::getBitCast(Fn, VoidPtrTy);

Modified: cfe/branches/tooling/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGObjCMac.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGObjCMac.cpp Tue Apr  3 07:29:12 2012
@@ -1914,7 +1914,7 @@
 See EmitProtocolExtension().
 */
 llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
-  llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
+  llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
 
   // Early exit if a defining object has already been generated.
   if (Entry && Entry->hasInitializer())
@@ -1997,6 +1997,8 @@
     Entry->setSection("__OBJC,__protocol,regular,no_dead_strip");
     // FIXME: Is this necessary? Why only for protocol?
     Entry->setAlignment(4);
+
+    Protocols[PD->getIdentifier()] = Entry;
   }
   CGM.AddUsedGlobal(Entry);
 
@@ -5552,7 +5554,7 @@
 
 llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
   const ObjCProtocolDecl *PD) {
-  llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
+  llvm::GlobalVariable *Entry = Protocols[PD->getIdentifier()];
 
   // Early exit if a defining object has already been generated.
   if (Entry && Entry->hasInitializer())
@@ -5649,6 +5651,8 @@
     Entry->setAlignment(
       CGM.getTargetData().getABITypeAlignment(ObjCTypes.ProtocolnfABITy));
     Entry->setSection("__DATA,__datacoal_nt,coalesced");
+
+    Protocols[PD->getIdentifier()] = Entry;
   }
   Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
   CGM.AddUsedGlobal(Entry);

Modified: cfe/branches/tooling/lib/CodeGen/CGStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGStmt.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGStmt.cpp Tue Apr  3 07:29:12 2012
@@ -722,8 +722,7 @@
   if (RV.isScalar()) {
     Builder.CreateStore(RV.getScalarVal(), ReturnValue);
   } else if (RV.isAggregate()) {
-    EmitAggregateCopy(ReturnValue, RV.getAggregateAddr(), Ty,
-                      /*volatile*/ false, 0, /*destIsCompleteObject*/ true);
+    EmitAggregateCopy(ReturnValue, RV.getAggregateAddr(), Ty);
   } else {
     StoreComplexToAddr(RV.getComplexVal(), ReturnValue, false);
   }
@@ -770,8 +769,7 @@
     EmitAggExpr(RV, AggValueSlot::forAddr(ReturnValue, Alignment, Qualifiers(),
                                           AggValueSlot::IsDestructed,
                                           AggValueSlot::DoesNotNeedGCBarriers,
-                                          AggValueSlot::IsNotAliased,
-                                          AggValueSlot::IsCompleteObject));
+                                          AggValueSlot::IsNotAliased));
   }
 
   EmitBranchThroughCleanup(ReturnBlock);

Modified: cfe/branches/tooling/lib/CodeGen/CGValue.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGValue.h?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGValue.h (original)
+++ cfe/branches/tooling/lib/CodeGen/CGValue.h Tue Apr  3 07:29:12 2012
@@ -318,22 +318,22 @@
   // Qualifiers
   Qualifiers Quals;
 
-  unsigned Alignment : 16;
+  unsigned short Alignment;
 
   /// DestructedFlag - This is set to true if some external code is
   /// responsible for setting up a destructor for the slot.  Otherwise
   /// the code which constructs it should push the appropriate cleanup.
-  unsigned DestructedFlag : 1;
+  bool DestructedFlag : 1;
 
   /// ObjCGCFlag - This is set to true if writing to the memory in the
   /// slot might require calling an appropriate Objective-C GC
   /// barrier.  The exact interaction here is unnecessarily mysterious.
-  unsigned ObjCGCFlag : 1;
+  bool ObjCGCFlag : 1;
   
   /// ZeroedFlag - This is set to true if the memory in the slot is
   /// known to be zero before the assignment into it.  This means that
   /// zero fields don't need to be set.
-  unsigned ZeroedFlag : 1;
+  bool ZeroedFlag : 1;
 
   /// AliasedFlag - This is set to true if the slot might be aliased
   /// and it's not undefined behavior to access it through such an
@@ -347,32 +347,19 @@
   /// over.  Since it's invalid in general to memcpy a non-POD C++
   /// object, it's important that this flag never be set when
   /// evaluating an expression which constructs such an object.
-  unsigned AliasedFlag : 1;
-
-  /// CompleteObjectFlag - This is set to true if the slot is known to
-  /// be a complete object.  When emitting an aggregate copy of a
-  /// non-POD C++ struct to a location which may not be a complete
-  /// object, only the data size of the type can be copied in order to
-  /// prevent unrelated fields from being overwritten.
-  unsigned CompleteObjectFlag : 1;
+  bool AliasedFlag : 1;
 
 public:
   enum IsAliased_t { IsNotAliased, IsAliased };
   enum IsDestructed_t { IsNotDestructed, IsDestructed };
   enum IsZeroed_t { IsNotZeroed, IsZeroed };
-  enum IsCompleteObject_t {
-    IsNotCompleteObject,
-    MayNotBeCompleteObject = IsNotCompleteObject,
-    IsCompleteObject
-  };
   enum NeedsGCBarriers_t { DoesNotNeedGCBarriers, NeedsGCBarriers };
 
   /// ignored - Returns an aggregate value slot indicating that the
   /// aggregate value is being ignored.
   static AggValueSlot ignored() {
     return forAddr(0, CharUnits(), Qualifiers(), IsNotDestructed,
-                   DoesNotNeedGCBarriers, IsNotAliased,
-                   IsCompleteObject);
+                   DoesNotNeedGCBarriers, IsNotAliased);
   }
 
   /// forAddr - Make a slot for an aggregate value.
@@ -390,7 +377,6 @@
                               IsDestructed_t isDestructed,
                               NeedsGCBarriers_t needsGC,
                               IsAliased_t isAliased,
-                              IsCompleteObject_t isCompleteObject,
                               IsZeroed_t isZeroed = IsNotZeroed) {
     AggValueSlot AV;
     AV.Addr = addr;
@@ -400,18 +386,15 @@
     AV.ObjCGCFlag = needsGC;
     AV.ZeroedFlag = isZeroed;
     AV.AliasedFlag = isAliased;
-    AV.CompleteObjectFlag = isCompleteObject;
     return AV;
   }
 
   static AggValueSlot forLValue(LValue LV, IsDestructed_t isDestructed,
                                 NeedsGCBarriers_t needsGC,
                                 IsAliased_t isAliased,
-                                IsCompleteObject_t isCompleteObject,
                                 IsZeroed_t isZeroed = IsNotZeroed) {
     return forAddr(LV.getAddress(), LV.getAlignment(),
-                   LV.getQuals(), isDestructed, needsGC, isAliased,
-                   isCompleteObject, isZeroed);
+                   LV.getQuals(), isDestructed, needsGC, isAliased, isZeroed);
   }
 
   IsDestructed_t isExternallyDestructed() const {
@@ -451,10 +434,6 @@
     return IsAliased_t(AliasedFlag);
   }
 
-  IsCompleteObject_t isCompleteObject() const {
-    return IsCompleteObject_t(CompleteObjectFlag);
-  }
-
   // FIXME: Alignment?
   RValue asRValue() const {
     return RValue::getAggregate(getAddr(), isVolatile());

Modified: cfe/branches/tooling/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CodeGenFunction.h?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/branches/tooling/lib/CodeGen/CodeGenFunction.h Tue Apr  3 07:29:12 2012
@@ -1596,9 +1596,7 @@
                                  T.getQualifiers(),
                                  AggValueSlot::IsNotDestructed,
                                  AggValueSlot::DoesNotNeedGCBarriers,
-                                 AggValueSlot::IsNotAliased,
-                                 AggValueSlot::IsCompleteObject,
-                                 AggValueSlot::IsNotZeroed);
+                                 AggValueSlot::IsNotAliased);
   }
 
   /// Emit a cast to void* in the appropriate address space.
@@ -1630,10 +1628,9 @@
   RValue EmitAnyExprToTemp(const Expr *E);
 
   /// EmitAnyExprToMem - Emits the code necessary to evaluate an
-  /// arbitrary expression as an initialization of the given memory
-  /// location.
+  /// arbitrary expression into the given memory location.
   void EmitAnyExprToMem(const Expr *E, llvm::Value *Location,
-                        Qualifiers Quals);
+                        Qualifiers Quals, bool IsInitializer);
 
   /// EmitExprAsInit - Emits the code necessary to initialize a
   /// location in memory with the given initializer.
@@ -1644,12 +1641,9 @@
   ///
   /// \param isVolatile - True iff either the source or the destination is
   /// volatile.
-  /// \param destIsCompleteObject - True if the destination is known to be
-  /// a complete object.
   void EmitAggregateCopy(llvm::Value *DestPtr, llvm::Value *SrcPtr,
                          QualType EltTy, bool isVolatile=false,
-                         unsigned alignment = 0,
-                         bool destIsCompleteObject = false);
+                         unsigned Alignment = 0);
 
   /// StartBlock - Start new block named N. If insert block is a dummy block
   /// then reuse it.

Modified: cfe/branches/tooling/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CodeGenModule.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CodeGenModule.cpp Tue Apr  3 07:29:12 2012
@@ -1903,8 +1903,10 @@
     return Map.GetOrCreateValue(String);
   }
 
-  // Otherwise, convert the UTF8 literals into a byte string.
-  SmallVector<UTF16, 128> ToBuf(NumBytes);
+  // Otherwise, convert the UTF8 literals into a string of shorts.
+  IsUTF16 = true;
+
+  SmallVector<UTF16, 128> ToBuf(NumBytes + 1); // +1 for ending nulls.
   const UTF8 *FromPtr = (UTF8 *)String.data();
   UTF16 *ToPtr = &ToBuf[0];
 
@@ -1915,38 +1917,20 @@
   // ConvertUTF8toUTF16 returns the length in ToPtr.
   StringLength = ToPtr - &ToBuf[0];
 
-  // Render the UTF-16 string into a byte array and convert to the target byte
-  // order.
-  //
-  // FIXME: This isn't something we should need to do here.
-  SmallString<128> AsBytes;
-  AsBytes.reserve(StringLength * 2);
-  for (unsigned i = 0; i != StringLength; ++i) {
-    unsigned short Val = ToBuf[i];
-    if (TargetIsLSB) {
-      AsBytes.push_back(Val & 0xFF);
-      AsBytes.push_back(Val >> 8);
-    } else {
-      AsBytes.push_back(Val >> 8);
-      AsBytes.push_back(Val & 0xFF);
-    }
-  }
-  // Append one extra null character, the second is automatically added by our
-  // caller.
-  AsBytes.push_back(0);
-
-  IsUTF16 = true;
-  return Map.GetOrCreateValue(StringRef(AsBytes.data(), AsBytes.size()));
+  // Add an explicit null.
+  *ToPtr = 0;
+  return Map.
+    GetOrCreateValue(StringRef(reinterpret_cast<const char *>(ToBuf.data()),
+                               (StringLength + 1) * 2));
 }
 
 static llvm::StringMapEntry<llvm::Constant*> &
 GetConstantStringEntry(llvm::StringMap<llvm::Constant*> &Map,
-		       const StringLiteral *Literal,
-		       unsigned &StringLength)
-{
-	StringRef String = Literal->getString();
-	StringLength = String.size();
-	return Map.GetOrCreateValue(String);
+                       const StringLiteral *Literal,
+                       unsigned &StringLength) {
+  StringRef String = Literal->getString();
+  StringLength = String.size();
+  return Map.GetOrCreateValue(String);
 }
 
 llvm::Constant *
@@ -1991,8 +1975,15 @@
     llvm::ConstantInt::get(Ty, 0x07C8);
 
   // String pointer.
-  llvm::Constant *C = llvm::ConstantDataArray::getString(VMContext,
-                                                         Entry.getKey());
+  llvm::Constant *C = 0;
+  if (isUTF16) {
+    ArrayRef<uint16_t> Arr =
+      llvm::makeArrayRef<uint16_t>((uint16_t*)Entry.getKey().data(),
+                                   Entry.getKey().size() / 2);
+    C = llvm::ConstantDataArray::get(VMContext, Arr);
+  } else {
+    C = llvm::ConstantDataArray::getString(VMContext, Entry.getKey());
+  }
 
   llvm::GlobalValue::LinkageTypes Linkage;
   if (isUTF16)
@@ -2017,8 +2008,14 @@
     CharUnits Align = getContext().getTypeAlignInChars(getContext().CharTy);
     GV->setAlignment(Align.getQuantity());
   }
+
+  // String.
   Fields[2] = llvm::ConstantExpr::getGetElementPtr(GV, Zeros);
 
+  if (isUTF16)
+    // Cast the UTF16 string to the correct type.
+    Fields[2] = llvm::ConstantExpr::getBitCast(Fields[2], Int8PtrTy);
+
   // String length.
   Ty = getTypes().ConvertType(getContext().LongTy);
   Fields[3] = llvm::ConstantInt::get(Ty, StringLength);

Modified: cfe/branches/tooling/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CodeGenModule.h?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/branches/tooling/lib/CodeGen/CodeGenModule.h Tue Apr  3 07:29:12 2012
@@ -280,6 +280,7 @@
   llvm::StringMap<llvm::Constant*> CFConstantStringMap;
   llvm::StringMap<llvm::GlobalVariable*> ConstantStringMap;
   llvm::DenseMap<const Decl*, llvm::Constant *> StaticLocalDeclMap;
+  llvm::DenseMap<const Decl*, llvm::GlobalVariable*> StaticLocalDeclGuardMap;
   
   llvm::DenseMap<QualType, llvm::Constant *> AtomicSetterHelperFnMap;
   llvm::DenseMap<QualType, llvm::Constant *> AtomicGetterHelperFnMap;
@@ -405,6 +406,14 @@
     StaticLocalDeclMap[D] = C;
   }
 
+  llvm::GlobalVariable *getStaticLocalDeclGuardAddress(const VarDecl *D) {
+    return StaticLocalDeclGuardMap[D];
+  }
+  void setStaticLocalDeclGuardAddress(const VarDecl *D, 
+                                      llvm::GlobalVariable *C) {
+    StaticLocalDeclGuardMap[D] = C;
+  }
+
   llvm::Constant *getAtomicSetterHelperFnMap(QualType Ty) {
     return AtomicSetterHelperFnMap[Ty];
   }

Modified: cfe/branches/tooling/lib/CodeGen/ItaniumCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/ItaniumCXXABI.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/ItaniumCXXABI.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/ItaniumCXXABI.cpp Tue Apr  3 07:29:12 2012
@@ -1064,8 +1064,8 @@
 /// just special-case it at particular places.
 void ItaniumCXXABI::EmitGuardedInit(CodeGenFunction &CGF,
                                     const VarDecl &D,
-                                    llvm::GlobalVariable *GV,
-                                    bool PerformInit) {
+                                    llvm::GlobalVariable *var,
+                                    bool shouldPerformInit) {
   CGBuilderTy &Builder = CGF.Builder;
 
   // We only need to use thread-safe statics for local variables;
@@ -1073,35 +1073,44 @@
   bool threadsafe =
     (getContext().getLangOpts().ThreadsafeStatics && D.isLocalVarDecl());
 
-  llvm::IntegerType *GuardTy;
-
   // If we have a global variable with internal linkage and thread-safe statics
   // are disabled, we can just let the guard variable be of type i8.
-  bool useInt8GuardVariable = !threadsafe && GV->hasInternalLinkage();
+  bool useInt8GuardVariable = !threadsafe && var->hasInternalLinkage();
+
+  llvm::IntegerType *guardTy;
   if (useInt8GuardVariable) {
-    GuardTy = CGF.Int8Ty;
+    guardTy = CGF.Int8Ty;
   } else {
     // Guard variables are 64 bits in the generic ABI and 32 bits on ARM.
-    GuardTy = (IsARM ? CGF.Int32Ty : CGF.Int64Ty);
+    guardTy = (IsARM ? CGF.Int32Ty : CGF.Int64Ty);
   }
-  llvm::PointerType *GuardPtrTy = GuardTy->getPointerTo();
+  llvm::PointerType *guardPtrTy = guardTy->getPointerTo();
 
-  // Create the guard variable.
-  SmallString<256> GuardVName;
-  llvm::raw_svector_ostream Out(GuardVName);
-  getMangleContext().mangleItaniumGuardVariable(&D, Out);
-  Out.flush();
-
-  // Just absorb linkage and visibility from the variable.
-  llvm::GlobalVariable *GuardVariable =
-    new llvm::GlobalVariable(CGM.getModule(), GuardTy,
-                             false, GV->getLinkage(),
-                             llvm::ConstantInt::get(GuardTy, 0),
-                             GuardVName.str());
-  GuardVariable->setVisibility(GV->getVisibility());
+  // Create the guard variable if we don't already have it (as we
+  // might if we're double-emitting this function body).
+  llvm::GlobalVariable *guard = CGM.getStaticLocalDeclGuardAddress(&D);
+  if (!guard) {
+    // Mangle the name for the guard.
+    SmallString<256> guardName;
+    {
+      llvm::raw_svector_ostream out(guardName);
+      getMangleContext().mangleItaniumGuardVariable(&D, out);
+      out.flush();
+    }
+
+    // Create the guard variable with a zero-initializer.
+    // Just absorb linkage and visibility from the guarded variable.
+    guard = new llvm::GlobalVariable(CGM.getModule(), guardTy,
+                                     false, var->getLinkage(),
+                                     llvm::ConstantInt::get(guardTy, 0),
+                                     guardName.str());
+    guard->setVisibility(var->getVisibility());
+
+    CGM.setStaticLocalDeclGuardAddress(&D, guard);
+  }
 
   // Test whether the variable has completed initialization.
-  llvm::Value *IsInitialized;
+  llvm::Value *isInitialized;
 
   // ARM C++ ABI 3.2.3.1:
   //   To support the potential use of initialization guard variables
@@ -1115,9 +1124,9 @@
   //         ...
   //     }
   if (IsARM && !useInt8GuardVariable) {
-    llvm::Value *V = Builder.CreateLoad(GuardVariable);
+    llvm::Value *V = Builder.CreateLoad(guard);
     V = Builder.CreateAnd(V, Builder.getInt32(1));
-    IsInitialized = Builder.CreateIsNull(V, "guard.uninitialized");
+    isInitialized = Builder.CreateIsNull(V, "guard.uninitialized");
 
   // Itanium C++ ABI 3.3.2:
   //   The following is pseudo-code showing how these functions can be used:
@@ -1135,9 +1144,8 @@
   //     }
   } else {
     // Load the first byte of the guard variable.
-    llvm::Type *PtrTy = Builder.getInt8PtrTy();
     llvm::LoadInst *LI = 
-      Builder.CreateLoad(Builder.CreateBitCast(GuardVariable, PtrTy));
+      Builder.CreateLoad(Builder.CreateBitCast(guard, CGM.Int8PtrTy));
     LI->setAlignment(1);
 
     // Itanium ABI:
@@ -1149,14 +1157,14 @@
     if (threadsafe)
       LI->setAtomic(llvm::Acquire);
 
-    IsInitialized = Builder.CreateIsNull(LI, "guard.uninitialized");
+    isInitialized = Builder.CreateIsNull(LI, "guard.uninitialized");
   }
 
   llvm::BasicBlock *InitCheckBlock = CGF.createBasicBlock("init.check");
   llvm::BasicBlock *EndBlock = CGF.createBasicBlock("init.end");
 
   // Check if the first byte of the guard variable is zero.
-  Builder.CreateCondBr(IsInitialized, InitCheckBlock, EndBlock);
+  Builder.CreateCondBr(isInitialized, InitCheckBlock, EndBlock);
 
   CGF.EmitBlock(InitCheckBlock);
 
@@ -1164,7 +1172,7 @@
   if (threadsafe) {    
     // Call __cxa_guard_acquire.
     llvm::Value *V
-      = Builder.CreateCall(getGuardAcquireFn(CGM, GuardPtrTy), GuardVariable);
+      = Builder.CreateCall(getGuardAcquireFn(CGM, guardPtrTy), guard);
                
     llvm::BasicBlock *InitBlock = CGF.createBasicBlock("init");
   
@@ -1172,22 +1180,22 @@
                          InitBlock, EndBlock);
   
     // Call __cxa_guard_abort along the exceptional edge.
-    CGF.EHStack.pushCleanup<CallGuardAbort>(EHCleanup, GuardVariable);
+    CGF.EHStack.pushCleanup<CallGuardAbort>(EHCleanup, guard);
     
     CGF.EmitBlock(InitBlock);
   }
 
   // Emit the initializer and add a global destructor if appropriate.
-  CGF.EmitCXXGlobalVarDeclInit(D, GV, PerformInit);
+  CGF.EmitCXXGlobalVarDeclInit(D, var, shouldPerformInit);
 
   if (threadsafe) {
     // Pop the guard-abort cleanup if we pushed one.
     CGF.PopCleanupBlock();
 
     // Call __cxa_guard_release.  This cannot throw.
-    Builder.CreateCall(getGuardReleaseFn(CGM, GuardPtrTy), GuardVariable);
+    Builder.CreateCall(getGuardReleaseFn(CGM, guardPtrTy), guard);
   } else {
-    Builder.CreateStore(llvm::ConstantInt::get(GuardTy, 1), GuardVariable);
+    Builder.CreateStore(llvm::ConstantInt::get(guardTy, 1), guard);
   }
 
   CGF.EmitBlock(EndBlock);

Modified: cfe/branches/tooling/lib/Driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Driver/Driver.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Driver/Driver.cpp (original)
+++ cfe/branches/tooling/lib/Driver/Driver.cpp Tue Apr  3 07:29:12 2012
@@ -141,6 +141,7 @@
     // -{fsyntax-only,-analyze,emit-ast,S} only run up to the compiler.
   } else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
              (PhaseArg = DAL.getLastArg(options::OPT_rewrite_objc)) ||
+             (PhaseArg = DAL.getLastArg(options::OPT_rewrite_legacy_objc)) ||
              (PhaseArg = DAL.getLastArg(options::OPT__migrate)) ||
              (PhaseArg = DAL.getLastArg(options::OPT__analyze,
                                         options::OPT__analyze_auto)) ||
@@ -1143,6 +1144,8 @@
       return new CompileJobAction(Input, types::TY_Nothing);
     } else if (Args.hasArg(options::OPT_rewrite_objc)) {
       return new CompileJobAction(Input, types::TY_RewrittenObjC);
+    } else if (Args.hasArg(options::OPT_rewrite_legacy_objc)) {
+      return new CompileJobAction(Input, types::TY_RewrittenLegacyObjC);
     } else if (Args.hasArg(options::OPT__analyze, options::OPT__analyze_auto)) {
       return new AnalyzeJobAction(Input, types::TY_Plist);
     } else if (Args.hasArg(options::OPT__migrate)) {

Modified: cfe/branches/tooling/lib/Driver/ToolChain.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Driver/ToolChain.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Driver/ToolChain.cpp (original)
+++ cfe/branches/tooling/lib/Driver/ToolChain.cpp Tue Apr  3 07:29:12 2012
@@ -137,6 +137,7 @@
     .Cases("arm1156t2-s",  "arm1156t2f-s", "v6t2")
     .Cases("cortex-a8", "cortex-a9", "v7")
     .Case("cortex-m3", "v7m")
+    .Case("cortex-m4", "v7m")
     .Case("cortex-m0", "v6m")
     .Default("");
 }

Modified: cfe/branches/tooling/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Driver/Tools.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Driver/Tools.cpp (original)
+++ cfe/branches/tooling/lib/Driver/Tools.cpp Tue Apr  3 07:29:12 2012
@@ -484,6 +484,7 @@
     .Cases("arm1156t2-s",  "arm1156t2f-s", "v6t2")
     .Cases("cortex-a8", "cortex-a9", "v7")
     .Case("cortex-m3", "v7m")
+    .Case("cortex-m4", "v7m")
     .Case("cortex-m0", "v6m")
     .Default("");
 }
@@ -1348,6 +1349,8 @@
       CmdArgs.push_back("-emit-pch");
     } else if (JA.getType() == types::TY_RewrittenObjC) {
       CmdArgs.push_back("-rewrite-objc");
+    } else if (JA.getType() == types::TY_RewrittenLegacyObjC) {
+      CmdArgs.push_back("-rewrite-objc");
       IsRewriter = true;
     } else {
       assert(JA.getType() == types::TY_PP_Asm &&
@@ -3618,6 +3621,9 @@
 
   assert(Inputs.size() == 1 && "Unexpected number of inputs!");
 
+  // Silence warning about unused --serialize-diagnostics
+  Args.ClaimAllArgs(options::OPT__serialize_diags);
+
   types::ID InputType = Inputs[0].getType();
   const Arg *A;
   if ((A = Args.getLastArg(options::OPT_traditional)))

Modified: cfe/branches/tooling/lib/Driver/Types.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Driver/Types.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Driver/Types.cpp (original)
+++ cfe/branches/tooling/lib/Driver/Types.cpp Tue Apr  3 07:29:12 2012
@@ -102,6 +102,7 @@
   case TY_LLVM_IR:
   case TY_LLVM_BC:
   case TY_RewrittenObjC:
+  case TY_RewrittenLegacyObjC:
     return true;
   }
 }

Modified: cfe/branches/tooling/lib/Headers/avx2intrin.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Headers/avx2intrin.h?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Headers/avx2intrin.h (original)
+++ cfe/branches/tooling/lib/Headers/avx2intrin.h Tue Apr  3 07:29:12 2012
@@ -157,7 +157,7 @@
 #define _mm256_blend_epi16(V1, V2, M) __extension__ ({ \
   __m256i __V1 = (V1); \
   __m256i __V2 = (V2); \
-  (__m256i)__builtin_ia32_pblendw256((__v16hi)__V1, (__v16hi)__V2, M); })
+  (__m256i)__builtin_ia32_pblendw256((__v16hi)__V1, (__v16hi)__V2, (M)); })
 
 static __inline__ __m256i __attribute__((__always_inline__, __nodebug__))
 _mm256_cmpeq_epi8(__m256i a, __m256i b)

Modified: cfe/branches/tooling/lib/Headers/avxintrin.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Headers/avxintrin.h?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Headers/avxintrin.h (original)
+++ cfe/branches/tooling/lib/Headers/avxintrin.h Tue Apr  3 07:29:12 2012
@@ -274,7 +274,7 @@
   __m128 __A = (A); \
   (__m128)__builtin_shufflevector((__v4sf)__A, (__v4sf) _mm_setzero_ps(), \
                                    (C) & 0x3, ((C) & 0xc) >> 2, \
-                                   ((C) & 0x30) >> 4, ((C) & 0xc0) >> 8); })
+                                   ((C) & 0x30) >> 4, ((C) & 0xc0) >> 6); })
 
 #define _mm256_permute_ps(A, C) __extension__ ({ \
   __m256 __A = (A); \

Modified: cfe/branches/tooling/lib/Headers/smmintrin.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Headers/smmintrin.h?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Headers/smmintrin.h (original)
+++ cfe/branches/tooling/lib/Headers/smmintrin.h Tue Apr  3 07:29:12 2012
@@ -57,21 +57,34 @@
 #define _mm_floor_ss(X, Y)   _mm_round_ss((X), (Y), _MM_FROUND_FLOOR)
 #define _mm_floor_sd(X, Y)   _mm_round_sd((X), (Y), _MM_FROUND_FLOOR)
 
-#define _mm_round_ps(X, Y)      __builtin_ia32_roundps((X), (Y))
-#define _mm_round_ss(X, Y, M)   __builtin_ia32_roundss((X), (Y), (M))
-#define _mm_round_pd(X, M)      __builtin_ia32_roundpd((X), (M))
-#define _mm_round_sd(X, Y, M)   __builtin_ia32_roundsd((X), (Y), (M))
+#define _mm_round_ps(X, M) __extension__ ({ \
+  __m128 __X = (X); \
+  (__m128) __builtin_ia32_roundps((__v4sf)__X, (M)); })
+
+#define _mm_round_ss(X, Y, M) __extension__ ({ \
+  __m128 __X = (X); \
+  __m128 __Y = (Y); \
+  (__m128) __builtin_ia32_roundss((__v4sf)__X, (__v4sf)__Y, (M)); })
+
+#define _mm_round_pd(X, M) __extension__ ({ \
+  __m128d __X = (X); \
+  (__m128d) __builtin_ia32_roundpd((__v2df)__X, (M)); })
+
+#define _mm_round_sd(X, Y, M) __extension__ ({ \
+  __m128d __X = (X); \
+  __m128d __Y = (Y); \
+  (__m128d) __builtin_ia32_roundsd((__v2df)__X, (__v2df)__Y, (M)); })
 
 /* SSE4 Packed Blending Intrinsics.  */
 #define _mm_blend_pd(V1, V2, M) __extension__ ({ \
   __m128d __V1 = (V1); \
   __m128d __V2 = (V2); \
-  (__m128d) __builtin_ia32_blendpd ((__v2df)__V1, (__v2df)__V2, M); })
+  (__m128d) __builtin_ia32_blendpd ((__v2df)__V1, (__v2df)__V2, (M)); })
 
 #define _mm_blend_ps(V1, V2, M) __extension__ ({ \
   __m128 __V1 = (V1); \
   __m128 __V2 = (V2); \
-  (__m128) __builtin_ia32_blendps ((__v4sf)__V1, (__v4sf)__V2, M); })
+  (__m128) __builtin_ia32_blendps ((__v4sf)__V1, (__v4sf)__V2, (M)); })
 
 static __inline__ __m128d __attribute__((__always_inline__, __nodebug__))
 _mm_blendv_pd (__m128d __V1, __m128d __V2, __m128d __M)
@@ -97,7 +110,7 @@
 #define _mm_blend_epi16(V1, V2, M) __extension__ ({ \
   __m128i __V1 = (V1); \
   __m128i __V2 = (V2); \
-  (__m128i) __builtin_ia32_pblendw128 ((__v8hi)__V1, (__v8hi)__V2, M); })
+  (__m128i) __builtin_ia32_pblendw128 ((__v8hi)__V1, (__v8hi)__V2, (M)); })
 
 /* SSE4 Dword Multiply Instructions.  */
 static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
@@ -113,8 +126,15 @@
 }
 
 /* SSE4 Floating Point Dot Product Instructions.  */
-#define _mm_dp_ps(X, Y, M) __builtin_ia32_dpps ((X), (Y), (M))
-#define _mm_dp_pd(X, Y, M) __builtin_ia32_dppd ((X), (Y), (M))
+#define _mm_dp_ps(X, Y, M) __extension__ ({ \
+  __m128 __X = (X); \
+  __m128 __Y = (Y); \
+  (__m128) __builtin_ia32_dpps((__v4sf)__X, (__v4sf)__Y, (M)); })
+
+#define _mm_dp_pd(X, Y, M) __extension__ ({\
+  __m128d __X = (X); \
+  __m128d __Y = (Y); \
+  (__m128d) __builtin_ia32_dppd((__v2df)__X, (__v2df)__Y, (M)); })
 
 /* SSE4 Streaming Load Hint Instruction.  */
 static __inline__  __m128i __attribute__((__always_inline__, __nodebug__))
@@ -195,14 +215,14 @@
                                              
 /* Insert int into packed integer array at index.  */
 #define _mm_insert_epi8(X, I, N) (__extension__ ({ __v16qi __a = (__v16qi)(X); \
-                                                   __a[N] = I;               \
+                                                   __a[(N)] = (I);             \
                                                    __a;}))
 #define _mm_insert_epi32(X, I, N) (__extension__ ({ __v4si __a = (__v4si)(X); \
-                                                    __a[N] = I;             \
+                                                    __a[(N)] = (I);           \
                                                     __a;}))
 #ifdef __x86_64__
 #define _mm_insert_epi64(X, I, N) (__extension__ ({ __v2di __a = (__v2di)(X); \
-                                                    __a[N] = I;             \
+                                                    __a[(N)] = (I);           \
                                                     __a;}))
 #endif /* __x86_64__ */
 
@@ -210,12 +230,12 @@
  * as a zero extended value, so it is unsigned.
  */
 #define _mm_extract_epi8(X, N) (__extension__ ({ __v16qi __a = (__v16qi)(X); \
-                                                 (unsigned char)__a[N];}))
+                                                 (unsigned char)__a[(N)];}))
 #define _mm_extract_epi32(X, N) (__extension__ ({ __v4si __a = (__v4si)(X); \
-                                                  (unsigned)__a[N];}))
+                                                  (unsigned)__a[(N)];}))
 #ifdef __x86_64__
 #define _mm_extract_epi64(X, N) (__extension__ ({ __v2di __a = (__v2di)(X); \
-                                                  __a[N];}))
+                                                  __a[(N)];}))
 #endif /* __x86_64 */
 
 /* SSE4 128-bit Packed Integer Comparisons.  */
@@ -330,7 +350,16 @@
 }
 
 /* SSE4 Multiple Packed Sums of Absolute Difference.  */
-#define _mm_mpsadbw_epu8(X, Y, M) __builtin_ia32_mpsadbw128((X), (Y), (M))
+#define _mm_mpsadbw_epu8(X, Y, M) __extension__ ({ \
+  __m128i __X = (X); \
+  __m128i __Y = (Y); \
+  (__m128i) __builtin_ia32_mpsadbw128((__v16qi)__X, (__v16qi)__Y, (M)); })
+
+static __inline__ __m128i __attribute__((__always_inline__, __nodebug__))
+_mm_minpos_epu16(__m128i __V)
+{
+  return (__m128i) __builtin_ia32_phminposuw128((__v8hi)__V);
+}
 
 /* These definitions are normally in nmmintrin.h, but gcc puts them in here
    so we'll do the same.  */

Modified: cfe/branches/tooling/lib/Lex/ModuleMap.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Lex/ModuleMap.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Lex/ModuleMap.cpp (original)
+++ cfe/branches/tooling/lib/Lex/ModuleMap.cpp Tue Apr  3 07:29:12 2012
@@ -508,7 +508,7 @@
     
     /// \brief Default target information, used only for string literal
     /// parsing.
-    TargetInfo *Target;
+    OwningPtr<TargetInfo> Target;
     
     /// \brief Stores string data for the various string literals referenced
     /// during parsing.
@@ -551,7 +551,7 @@
     {
       TargetOptions TargetOpts;
       TargetOpts.Triple = llvm::sys::getDefaultTargetTriple();
-      Target = TargetInfo::CreateTargetInfo(Diags, TargetOpts);
+      Target.reset(TargetInfo::CreateTargetInfo(Diags, TargetOpts));
       
       Tok.clear();
       consumeToken();

Modified: cfe/branches/tooling/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Lex/PPDirectives.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Lex/PPDirectives.cpp (original)
+++ cfe/branches/tooling/lib/Lex/PPDirectives.cpp Tue Apr  3 07:29:12 2012
@@ -1549,10 +1549,9 @@
 /// definition has just been read.  Lex the rest of the arguments and the
 /// closing ), updating MI with what we learn.  Return true if an error occurs
 /// parsing the arg list.
-bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI) {
+bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI, Token &Tok) {
   SmallVector<IdentifierInfo*, 32> Arguments;
 
-  Token Tok;
   while (1) {
     LexUnexpandedToken(Tok);
     switch (Tok.getKind()) {
@@ -1671,7 +1670,7 @@
   } else if (Tok.is(tok::l_paren)) {
     // This is a function-like macro definition.  Read the argument list.
     MI->setIsFunctionLike();
-    if (ReadMacroDefinitionArgList(MI)) {
+    if (ReadMacroDefinitionArgList(MI, LastTok)) {
       // Forget about MI.
       ReleaseMacroInfo(MI);
       // Throw away the rest of the line.

Modified: cfe/branches/tooling/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseTemplate.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseTemplate.cpp Tue Apr  3 07:29:12 2012
@@ -540,12 +540,17 @@
 
   // Generate a meaningful error if the user forgot to put class before the
   // identifier, comma, or greater.
-  if (!Tok.is(tok::kw_class)) {
-    Diag(Tok.getLocation(), diag::err_expected_class_before)
-      << PP.getSpelling(Tok);
-    return 0;
-  }
-  ConsumeToken();
+  if (Tok.is(tok::kw_typename) || Tok.is(tok::kw_struct)) {
+    Diag(Tok.getLocation(), diag::err_expected_class_instead)
+      << PP.getSpelling(Tok)
+      << FixItHint::CreateReplacement(Tok.getLocation(), "class");
+    ConsumeToken();
+  } else if (!Tok.is(tok::kw_class))
+      Diag(Tok.getLocation(), diag::err_expected_class_before)
+        << PP.getSpelling(Tok)
+        << FixItHint::CreateInsertion(Tok.getLocation(), "class ");
+  else 
+    ConsumeToken();
 
   // Parse the ellipsis, if given.
   SourceLocation EllipsisLoc;
@@ -1157,113 +1162,113 @@
 
   llvm_unreachable("Late templated function without associated lexed tokens");
 }
-
-/// \brief Late parse a C++ function template in Microsoft mode.
-void Parser::ParseLateTemplatedFuncDef(LateParsedTemplatedFunction &LMT) {
-  if(!LMT.D)
-     return;
-
-  // Get the FunctionDecl.
-  FunctionDecl *FD = 0;
-  if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(LMT.D))
-    FD = FunTmpl->getTemplatedDecl();
-  else
-    FD = cast<FunctionDecl>(LMT.D);
-  
+
+/// \brief Late parse a C++ function template in Microsoft mode.
+void Parser::ParseLateTemplatedFuncDef(LateParsedTemplatedFunction &LMT) {
+  if(!LMT.D)
+     return;
+
+  // Get the FunctionDecl.
+  FunctionDecl *FD = 0;
+  if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(LMT.D))
+    FD = FunTmpl->getTemplatedDecl();
+  else
+    FD = cast<FunctionDecl>(LMT.D);
+
   // To restore the context after late parsing.
-  Sema::ContextRAII GlobalSavedContext(Actions, Actions.CurContext);
-
-  SmallVector<ParseScope*, 4> TemplateParamScopeStack;
-  DeclaratorDecl* Declarator = dyn_cast<DeclaratorDecl>(FD);
-  if (Declarator && Declarator->getNumTemplateParameterLists() != 0) {
-    TemplateParamScopeStack.push_back(new ParseScope(this, Scope::TemplateParamScope));
-    Actions.ActOnReenterDeclaratorTemplateScope(getCurScope(), Declarator);
-    Actions.ActOnReenterTemplateScope(getCurScope(), LMT.D);
-  } else {
-    // Get the list of DeclContext to reenter.
-    SmallVector<DeclContext*, 4> DeclContextToReenter;
-    DeclContext *DD = FD->getLexicalParent();
-    while (DD && !DD->isTranslationUnit()) {
-      DeclContextToReenter.push_back(DD);
-      DD = DD->getLexicalParent();
-    }
-
-    // Reenter template scopes from outmost to innermost.
-    SmallVector<DeclContext*, 4>::reverse_iterator II =
-    DeclContextToReenter.rbegin();
-    for (; II != DeclContextToReenter.rend(); ++II) {
-      if (ClassTemplatePartialSpecializationDecl* MD =
-                dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>(*II)) {
-        TemplateParamScopeStack.push_back(new ParseScope(this,
-                                                   Scope::TemplateParamScope));
-        Actions.ActOnReenterTemplateScope(getCurScope(), MD);
-      } else if (CXXRecordDecl* MD = dyn_cast_or_null<CXXRecordDecl>(*II)) {
-        TemplateParamScopeStack.push_back(new ParseScope(this,
-                                                    Scope::TemplateParamScope,
-                                       MD->getDescribedClassTemplate() != 0 ));
-        Actions.ActOnReenterTemplateScope(getCurScope(),
-                                          MD->getDescribedClassTemplate());
-      }
-      TemplateParamScopeStack.push_back(new ParseScope(this, Scope::DeclScope));
-      Actions.PushDeclContext(Actions.getCurScope(), *II);
-    }
-    TemplateParamScopeStack.push_back(new ParseScope(this,
-                                      Scope::TemplateParamScope));
-    Actions.ActOnReenterTemplateScope(getCurScope(), LMT.D);
-  }
-
-  assert(!LMT.Toks.empty() && "Empty body!");
-
-  // Append the current token at the end of the new token stream so that it
-  // doesn't get lost.
-  LMT.Toks.push_back(Tok);
-  PP.EnterTokenStream(LMT.Toks.data(), LMT.Toks.size(), true, false);
-
-  // Consume the previously pushed token.
-  ConsumeAnyToken();
-  assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try))
-         && "Inline method not starting with '{', ':' or 'try'");
-
-  // Parse the method body. Function body parsing code is similar enough
-  // to be re-used for method bodies as well.
-  ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope);
-
-  // Recreate the containing function DeclContext.
-  Sema::ContextRAII FunctionSavedContext(Actions, Actions.getContainingDC(FD));
-
-  if (FunctionTemplateDecl *FunctionTemplate
-        = dyn_cast_or_null<FunctionTemplateDecl>(LMT.D))
-    Actions.ActOnStartOfFunctionDef(getCurScope(),
-                                   FunctionTemplate->getTemplatedDecl());
-  if (FunctionDecl *Function = dyn_cast_or_null<FunctionDecl>(LMT.D))
-    Actions.ActOnStartOfFunctionDef(getCurScope(), Function);
-  
-
-  if (Tok.is(tok::kw_try)) {
-    ParseFunctionTryBlock(LMT.D, FnScope);
-  } else {
-    if (Tok.is(tok::colon))
-      ParseConstructorInitializer(LMT.D);
-    else
-      Actions.ActOnDefaultCtorInitializers(LMT.D);
-
-    if (Tok.is(tok::l_brace)) {
-      ParseFunctionStatementBody(LMT.D, FnScope);
-      Actions.MarkAsLateParsedTemplate(FD, false);
-    } else
-      Actions.ActOnFinishFunctionBody(LMT.D, 0);
-  }
-
-  // Exit scopes.
+  Sema::ContextRAII GlobalSavedContext(Actions, Actions.CurContext);
+
+  SmallVector<ParseScope*, 4> TemplateParamScopeStack;
+  DeclaratorDecl* Declarator = dyn_cast<DeclaratorDecl>(FD);
+  if (Declarator && Declarator->getNumTemplateParameterLists() != 0) {
+    TemplateParamScopeStack.push_back(new ParseScope(this, Scope::TemplateParamScope));
+    Actions.ActOnReenterDeclaratorTemplateScope(getCurScope(), Declarator);
+    Actions.ActOnReenterTemplateScope(getCurScope(), LMT.D);
+  } else {
+    // Get the list of DeclContext to reenter.
+    SmallVector<DeclContext*, 4> DeclContextToReenter;
+    DeclContext *DD = FD->getLexicalParent();
+    while (DD && !DD->isTranslationUnit()) {
+      DeclContextToReenter.push_back(DD);
+      DD = DD->getLexicalParent();
+    }
+
+    // Reenter template scopes from outmost to innermost.
+    SmallVector<DeclContext*, 4>::reverse_iterator II =
+    DeclContextToReenter.rbegin();
+    for (; II != DeclContextToReenter.rend(); ++II) {
+      if (ClassTemplatePartialSpecializationDecl* MD =
+                dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>(*II)) {
+        TemplateParamScopeStack.push_back(new ParseScope(this,
+                                                   Scope::TemplateParamScope));
+        Actions.ActOnReenterTemplateScope(getCurScope(), MD);
+      } else if (CXXRecordDecl* MD = dyn_cast_or_null<CXXRecordDecl>(*II)) {
+        TemplateParamScopeStack.push_back(new ParseScope(this,
+                                                    Scope::TemplateParamScope,
+                                       MD->getDescribedClassTemplate() != 0 ));
+        Actions.ActOnReenterTemplateScope(getCurScope(),
+                                          MD->getDescribedClassTemplate());
+      }
+      TemplateParamScopeStack.push_back(new ParseScope(this, Scope::DeclScope));
+      Actions.PushDeclContext(Actions.getCurScope(), *II);
+    }
+    TemplateParamScopeStack.push_back(new ParseScope(this,
+                                      Scope::TemplateParamScope));
+    Actions.ActOnReenterTemplateScope(getCurScope(), LMT.D);
+  }
+
+  assert(!LMT.Toks.empty() && "Empty body!");
+
+  // Append the current token at the end of the new token stream so that it
+  // doesn't get lost.
+  LMT.Toks.push_back(Tok);
+  PP.EnterTokenStream(LMT.Toks.data(), LMT.Toks.size(), true, false);
+
+  // Consume the previously pushed token.
+  ConsumeAnyToken();
+  assert((Tok.is(tok::l_brace) || Tok.is(tok::colon) || Tok.is(tok::kw_try))
+         && "Inline method not starting with '{', ':' or 'try'");
+
+  // Parse the method body. Function body parsing code is similar enough
+  // to be re-used for method bodies as well.
+  ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope);
+
+  // Recreate the containing function DeclContext.
+  Sema::ContextRAII FunctionSavedContext(Actions, Actions.getContainingDC(FD));
+
+  if (FunctionTemplateDecl *FunctionTemplate
+        = dyn_cast_or_null<FunctionTemplateDecl>(LMT.D))
+    Actions.ActOnStartOfFunctionDef(getCurScope(),
+                                   FunctionTemplate->getTemplatedDecl());
+  if (FunctionDecl *Function = dyn_cast_or_null<FunctionDecl>(LMT.D))
+    Actions.ActOnStartOfFunctionDef(getCurScope(), Function);
+
+
+  if (Tok.is(tok::kw_try)) {
+    ParseFunctionTryBlock(LMT.D, FnScope);
+  } else {
+    if (Tok.is(tok::colon))
+      ParseConstructorInitializer(LMT.D);
+    else
+      Actions.ActOnDefaultCtorInitializers(LMT.D);
+
+    if (Tok.is(tok::l_brace)) {
+      ParseFunctionStatementBody(LMT.D, FnScope);
+      Actions.MarkAsLateParsedTemplate(FD, false);
+    } else
+      Actions.ActOnFinishFunctionBody(LMT.D, 0);
+  }
+
+  // Exit scopes.
   FnScope.Exit();
-  SmallVector<ParseScope*, 4>::reverse_iterator I =
-   TemplateParamScopeStack.rbegin();
-  for (; I != TemplateParamScopeStack.rend(); ++I)
-    delete *I;
-
-  DeclGroupPtrTy grp = Actions.ConvertDeclToDeclGroup(LMT.D);
-  if (grp)
-    Actions.getASTConsumer().HandleTopLevelDecl(grp.get());
+  SmallVector<ParseScope*, 4>::reverse_iterator I =
+   TemplateParamScopeStack.rbegin();
+  for (; I != TemplateParamScopeStack.rend(); ++I)
+    delete *I;
+
+  DeclGroupPtrTy grp = Actions.ConvertDeclToDeclGroup(LMT.D);
+  if (grp)
+    Actions.getASTConsumer().HandleTopLevelDecl(grp.get());
 }
 
 /// \brief Lex a delayed template function for late parsing.

Modified: cfe/branches/tooling/lib/Rewrite/RewriteModernObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Rewrite/RewriteModernObjC.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Rewrite/RewriteModernObjC.cpp (original)
+++ cfe/branches/tooling/lib/Rewrite/RewriteModernObjC.cpp Tue Apr  3 07:29:12 2012
@@ -318,6 +318,8 @@
     Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp);
     Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp);
     Stmt *RewriteObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Exp);
+    Stmt *RewriteObjCNumericLiteralExpr(ObjCNumericLiteral *Exp);
+    Stmt *RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp);
     Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp);
     Stmt *RewriteObjCTryStmt(ObjCAtTryStmt *S);
     Stmt *RewriteObjCSynchronizedStmt(ObjCAtSynchronizedStmt *S);
@@ -2466,6 +2468,210 @@
   return PE;
 }
 
+Stmt *RewriteModernObjC::RewriteObjCNumericLiteralExpr(ObjCNumericLiteral *Exp) {
+  // synthesize declaration of helper functions needed in this routine.
+  if (!SelGetUidFunctionDecl)
+    SynthSelGetUidFunctionDecl();
+  // use objc_msgSend() for all.
+  if (!MsgSendFunctionDecl)
+    SynthMsgSendFunctionDecl();
+  if (!GetClassFunctionDecl)
+    SynthGetClassFunctionDecl();
+  
+  FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
+  SourceLocation StartLoc = Exp->getLocStart();
+  SourceLocation EndLoc = Exp->getLocEnd();
+  
+  // Synthesize a call to objc_msgSend().
+  SmallVector<Expr*, 4> MsgExprs;
+  SmallVector<Expr*, 4> ClsExprs;
+  QualType argType = Context->getPointerType(Context->CharTy);
+  QualType expType = Exp->getType();
+  
+  // Create a call to objc_getClass("NSNumber"). It will be th 1st argument.
+  ObjCInterfaceDecl *Class = 
+    expType->getPointeeType()->getAs<ObjCObjectType>()->getInterface();
+  
+  IdentifierInfo *clsName = Class->getIdentifier();
+  ClsExprs.push_back(StringLiteral::Create(*Context,
+                                           clsName->getName(),
+                                           StringLiteral::Ascii, false,
+                                           argType, SourceLocation()));
+  CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+                                               &ClsExprs[0],
+                                               ClsExprs.size(), 
+                                               StartLoc, EndLoc);
+  MsgExprs.push_back(Cls);
+  
+  // Create a call to sel_registerName("numberWithBool:"), etc.
+  // it will be the 2nd argument.
+  SmallVector<Expr*, 4> SelExprs;
+  ObjCMethodDecl *NumericMethod = Exp->getObjCNumericLiteralMethod();
+  SelExprs.push_back(StringLiteral::Create(*Context,
+                                           NumericMethod->getSelector().getAsString(),
+                                           StringLiteral::Ascii, false,
+                                           argType, SourceLocation()));
+  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
+                                                  &SelExprs[0], SelExprs.size(),
+                                                  StartLoc, EndLoc);
+  MsgExprs.push_back(SelExp);
+  
+  // User provided numeric literal is the 3rd, and last, argument.
+  Expr *userExpr  = Exp->getNumber();
+  if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(userExpr)) {
+    QualType type = ICE->getType();
+    const Expr *SubExpr = ICE->IgnoreParenImpCasts();
+    CastKind CK = CK_BitCast;
+    if (SubExpr->getType()->isIntegralType(*Context) && type->isBooleanType())
+      CK = CK_IntegralToBoolean;
+    userExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, userExpr);
+  }
+  MsgExprs.push_back(userExpr);
+  
+  SmallVector<QualType, 4> ArgTypes;
+  ArgTypes.push_back(Context->getObjCIdType());
+  ArgTypes.push_back(Context->getObjCSelType());
+  for (ObjCMethodDecl::param_iterator PI = NumericMethod->param_begin(),
+       E = NumericMethod->param_end(); PI != E; ++PI)
+    ArgTypes.push_back((*PI)->getType());
+    
+  QualType returnType = Exp->getType();
+  // Get the type, we will need to reference it in a couple spots.
+  QualType msgSendType = MsgSendFlavor->getType();
+  
+  // Create a reference to the objc_msgSend() declaration.
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
+                                               VK_LValue, SourceLocation());
+  
+  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
+                                  Context->getPointerType(Context->VoidTy),
+                                  CK_BitCast, DRE);
+  
+  // Now do the "normal" pointer to function cast.
+  QualType castType =
+    getSimpleFunctionType(returnType, &ArgTypes[0], ArgTypes.size(),
+                          NumericMethod->isVariadic());
+  castType = Context->getPointerType(castType);
+  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
+                                  cast);
+  
+  // Don't forget the parens to enforce the proper binding.
+  ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
+  
+  const FunctionType *FT = msgSendType->getAs<FunctionType>();
+  CallExpr *CE = new (Context) CallExpr(*Context, PE, &MsgExprs[0],
+                                        MsgExprs.size(),
+                                        FT->getResultType(), VK_RValue,
+                                        EndLoc);
+  ReplaceStmt(Exp, CE);
+  return CE;
+}
+
+Stmt *RewriteModernObjC::RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp) {
+  // synthesize declaration of helper functions needed in this routine.
+  if (!SelGetUidFunctionDecl)
+    SynthSelGetUidFunctionDecl();
+  // use objc_msgSend() for all.
+  if (!MsgSendFunctionDecl)
+    SynthMsgSendFunctionDecl();
+  if (!GetClassFunctionDecl)
+    SynthGetClassFunctionDecl();
+  
+  FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
+  SourceLocation StartLoc = Exp->getLocStart();
+  SourceLocation EndLoc = Exp->getLocEnd();
+  
+  // Synthesize a call to objc_msgSend().
+  SmallVector<Expr*, 32> MsgExprs;
+  SmallVector<Expr*, 4> ClsExprs;
+  QualType argType = Context->getPointerType(Context->CharTy);
+  QualType expType = Exp->getType();
+  
+  // Create a call to objc_getClass("NSArray"). It will be th 1st argument.
+  ObjCInterfaceDecl *Class = 
+    expType->getPointeeType()->getAs<ObjCObjectType>()->getInterface();
+  
+  IdentifierInfo *clsName = Class->getIdentifier();
+  ClsExprs.push_back(StringLiteral::Create(*Context,
+                                           clsName->getName(),
+                                           StringLiteral::Ascii, false,
+                                           argType, SourceLocation()));
+  CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+                                               &ClsExprs[0],
+                                               ClsExprs.size(), 
+                                               StartLoc, EndLoc);
+  MsgExprs.push_back(Cls);
+  
+  // Create a call to sel_registerName("arrayWithObjects:count:").
+  // it will be the 2nd argument.
+  SmallVector<Expr*, 4> SelExprs;
+  ObjCMethodDecl *ArrayMethod = Exp->getArrayWithObjectsMethod();
+  SelExprs.push_back(StringLiteral::Create(*Context,
+                                           ArrayMethod->getSelector().getAsString(),
+                                           StringLiteral::Ascii, false,
+                                           argType, SourceLocation()));
+  CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
+                                                  &SelExprs[0], SelExprs.size(),
+                                                  StartLoc, EndLoc);
+  MsgExprs.push_back(SelExp);
+  
+  unsigned NumElements = Exp->getNumElements();
+  
+  // FIXME. Incomplete.
+  InitListExpr *ILE =
+    new (Context) InitListExpr(*Context, SourceLocation(),
+                               Exp->getElements(), NumElements,
+                               SourceLocation());
+  MsgExprs.push_back(ILE);
+  unsigned UnsignedIntSize = 
+    static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
+  
+  Expr *count = IntegerLiteral::Create(*Context,
+                                       llvm::APInt(UnsignedIntSize, NumElements),
+                                       Context->UnsignedIntTy,
+                                       SourceLocation());
+  MsgExprs.push_back(count);
+  
+  
+  SmallVector<QualType, 4> ArgTypes;
+  ArgTypes.push_back(Context->getObjCIdType());
+  ArgTypes.push_back(Context->getObjCSelType());
+  for (ObjCMethodDecl::param_iterator PI = ArrayMethod->param_begin(),
+       E = ArrayMethod->param_end(); PI != E; ++PI)
+    ArgTypes.push_back((*PI)->getType());
+  
+  QualType returnType = Exp->getType();
+  // Get the type, we will need to reference it in a couple spots.
+  QualType msgSendType = MsgSendFlavor->getType();
+  
+  // Create a reference to the objc_msgSend() declaration.
+  DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, false, msgSendType,
+                                               VK_LValue, SourceLocation());
+  
+  CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
+                                            Context->getPointerType(Context->VoidTy),
+                                            CK_BitCast, DRE);
+  
+  // Now do the "normal" pointer to function cast.
+  QualType castType =
+  getSimpleFunctionType(returnType, &ArgTypes[0], ArgTypes.size(),
+                        ArrayMethod->isVariadic());
+  castType = Context->getPointerType(castType);
+  cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
+                                  cast);
+  
+  // Don't forget the parens to enforce the proper binding.
+  ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
+  
+  const FunctionType *FT = msgSendType->getAs<FunctionType>();
+  CallExpr *CE = new (Context) CallExpr(*Context, PE, &MsgExprs[0],
+                                        MsgExprs.size(),
+                                        FT->getResultType(), VK_RValue,
+                                        EndLoc);
+  ReplaceStmt(Exp, CE);
+  return CE;
+}
+
 // struct objc_super { struct objc_object *receiver; struct objc_class *super; };
 QualType RewriteModernObjC::getSuperStructType() {
   if (!SuperStructDecl) {
@@ -3217,16 +3423,14 @@
        e = Ivars.end(); i != e; i++) {
     ObjCIvarDecl *IvarDecl = (*i);
     Result += "\n";
-    Result += "extern \"C\" ";
     if (LangOpts.MicrosoftExt)
       Result += "__declspec(allocate(\".objc_ivar$B\")) ";
+    Result += "extern \"C\" ";
     if (LangOpts.MicrosoftExt && 
         IvarDecl->getAccessControl() != ObjCIvarDecl::Private &&
-        IvarDecl->getAccessControl() != ObjCIvarDecl::Package) {
-      const ObjCInterfaceDecl *CDecl = IvarDecl->getContainingInterface();
-      if (CDecl->getImplementation())
-        Result += "__declspec(dllexport) ";
-    }
+        IvarDecl->getAccessControl() != ObjCIvarDecl::Package)
+        Result += "__declspec(dllimport) ";
+
     Result += "unsigned long ";
     WriteInternalIvarName(CDecl, IvarDecl, Result);
     Result += ";";
@@ -4760,6 +4964,12 @@
   
   if (ObjCBoolLiteralExpr *BoolLitExpr = dyn_cast<ObjCBoolLiteralExpr>(S))
     return RewriteObjCBoolLiteralExpr(BoolLitExpr);
+  
+  if (ObjCNumericLiteral *NumericLitExpr = dyn_cast<ObjCNumericLiteral>(S))
+    return RewriteObjCNumericLiteralExpr(NumericLitExpr);
+  
+  if (ObjCArrayLiteral *ArrayLitExpr = dyn_cast<ObjCArrayLiteral>(S))
+    return RewriteObjCArrayLiteralExpr(ArrayLitExpr);
 
   if (ObjCMessageExpr *MessExpr = dyn_cast<ObjCMessageExpr>(S)) {
 #if 0
@@ -5440,7 +5650,7 @@
   Result += "};\n";
   
   Result += "extern \"C\" __declspec(dllimport) struct objc_cache _objc_empty_cache;\n";
-  
+  Result += "#pragma warning(disable:4273)\n";
   meta_data_declared = true;
 }
 
@@ -5682,25 +5892,35 @@
     Result += "extern \"C\" ";
     if (CDecl->getImplementation())
       Result += "__declspec(dllexport) ";
+    else
+      Result += "__declspec(dllimport) ";
+    
     Result += "struct _class_t OBJC_CLASS_$_";
     Result += CDecl->getNameAsString();
     Result += ";\n";
   }
   // Also, for possibility of 'super' metadata class not having been defined yet.
   if (!rootClass) {
+    ObjCInterfaceDecl *SuperClass = CDecl->getSuperClass();
     Result += "\n";
     Result += "extern \"C\" ";
-    if (CDecl->getSuperClass()->getImplementation())
+    if (SuperClass->getImplementation())
       Result += "__declspec(dllexport) ";
+    else
+      Result += "__declspec(dllimport) ";
+
     Result += "struct _class_t "; 
     Result += VarName;
-    Result += CDecl->getSuperClass()->getNameAsString();
+    Result += SuperClass->getNameAsString();
     Result += ";\n";
     
-    if (metaclass) {
+    if (metaclass && RootClass != SuperClass) {
       Result += "extern \"C\" ";
       if (RootClass->getImplementation())
         Result += "__declspec(dllexport) ";
+      else
+        Result += "__declspec(dllimport) ";
+
       Result += "struct _class_t "; 
       Result += VarName;
       Result += RootClass->getNameAsString();
@@ -5708,7 +5928,8 @@
     }
   }
   
-  Result += "\n__declspec(dllexport) struct _class_t "; Result += VarName; Result += CDecl->getNameAsString();
+  Result += "\nextern \"C\" __declspec(dllexport) struct _class_t "; 
+  Result += VarName; Result += CDecl->getNameAsString();
   Result += " __attribute__ ((used, section (\"__DATA,__objc_data\"))) = {\n";
   Result += "\t";
   if (metaclass) {
@@ -5807,6 +6028,8 @@
   Result += "extern \"C\" ";
   if (ClassDecl->getImplementation())
     Result += "__declspec(dllexport) ";
+  else
+    Result += "__declspec(dllimport) ";
   
   Result += "struct _class_t ";
   Result += "OBJC_CLASS_$_"; Result += ClassName;
@@ -5921,9 +6144,9 @@
     if (!Context->getLangOpts().MicrosoftExt ||
         IvarDecl->getAccessControl() == ObjCIvarDecl::Private ||
         IvarDecl->getAccessControl() == ObjCIvarDecl::Package)
-      Result += "unsigned long int "; 
+      Result += "extern \"C\" unsigned long int "; 
     else
-      Result += "__declspec(dllexport) unsigned long int ";
+      Result += "extern \"C\" __declspec(dllexport) unsigned long int ";
     WriteInternalIvarName(CDecl, IvarDecl, Result);
     Result += " __attribute__ ((used, section (\"__DATA,__objc_ivar\")))";
     Result += " = ";

Modified: cfe/branches/tooling/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaChecking.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaChecking.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaChecking.cpp Tue Apr  3 07:29:12 2012
@@ -637,8 +637,8 @@
   } else {
     SubExprs.push_back(TheCall->getArg(3)); // Order
     SubExprs.push_back(TheCall->getArg(1)); // Val1
-    SubExprs.push_back(TheCall->getArg(2)); // Val2
     SubExprs.push_back(TheCall->getArg(4)); // OrderFail
+    SubExprs.push_back(TheCall->getArg(2)); // Val2
   }
 
   return Owned(new (Context) AtomicExpr(TheCall->getCallee()->getLocStart(),

Modified: cfe/branches/tooling/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaDecl.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaDecl.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaDecl.cpp Tue Apr  3 07:29:12 2012
@@ -118,7 +118,7 @@
         //
         // We therefore do not perform any name lookup if the result would
         // refer to a member of an unknown specialization.
-        if (!isClassName)
+        if (!isClassName && !IsCtorOrDtorName)
           return ParsedType();
         
         // We know from the grammar that this name refers to a type,
@@ -4651,8 +4651,9 @@
 
     if (unsigned Idx = NearMatch->second) {
       ParmVarDecl *FDParam = FD->getParamDecl(Idx-1);
-      SemaRef.Diag(FDParam->getTypeSpecStartLoc(),
-             diag::note_member_def_close_param_match)
+      SourceLocation Loc = FDParam->getTypeSpecStartLoc();
+      if (Loc.isInvalid()) Loc = FD->getLocation();
+      SemaRef.Diag(Loc, diag::note_member_def_close_param_match)
           << Idx << FDParam->getType() << NewFD->getParamDecl(Idx-1)->getType();
     } else if (Correction) {
       SemaRef.Diag(FD->getLocation(), diag::note_previous_decl)

Modified: cfe/branches/tooling/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaDeclCXX.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaDeclCXX.cpp Tue Apr  3 07:29:12 2012
@@ -4333,6 +4333,7 @@
   Sema &S;
   CXXMethodDecl *MD;
   Sema::CXXSpecialMember CSM;
+  bool Diagnose;
 
   // Properties of the special member, computed for convenience.
   bool IsConstructor, IsAssignment, IsMove, ConstArg, VolatileArg;
@@ -4341,8 +4342,8 @@
   bool AllFieldsAreConst;
 
   SpecialMemberDeletionInfo(Sema &S, CXXMethodDecl *MD,
-                            Sema::CXXSpecialMember CSM)
-    : S(S), MD(MD), CSM(CSM),
+                            Sema::CXXSpecialMember CSM, bool Diagnose)
+    : S(S), MD(MD), CSM(CSM), Diagnose(Diagnose),
       IsConstructor(false), IsAssignment(false), IsMove(false),
       ConstArg(false), VolatileArg(false), Loc(MD->getLocation()),
       AllFieldsAreConst(true) {
@@ -4385,38 +4386,80 @@
                                  TQ & Qualifiers::Volatile);
   }
 
-  bool shouldDeleteForClassSubobject(CXXRecordDecl *Class, FieldDecl *Field);
+  typedef llvm::PointerUnion<CXXBaseSpecifier*, FieldDecl*> Subobject;
 
-  bool shouldDeleteForBase(CXXRecordDecl *BaseDecl, bool IsVirtualBase);
+  bool shouldDeleteForBase(CXXBaseSpecifier *Base);
   bool shouldDeleteForField(FieldDecl *FD);
   bool shouldDeleteForAllConstMembers();
+
+  bool shouldDeleteForClassSubobject(CXXRecordDecl *Class, Subobject Subobj);
+  bool shouldDeleteForSubobjectCall(Subobject Subobj,
+                                    Sema::SpecialMemberOverloadResult *SMOR,
+                                    bool IsDtorCallInCtor);
 };
 }
 
+/// Check whether we should delete a special member due to the implicit
+/// definition containing a call to a special member of a subobject.
+bool SpecialMemberDeletionInfo::shouldDeleteForSubobjectCall(
+    Subobject Subobj, Sema::SpecialMemberOverloadResult *SMOR,
+    bool IsDtorCallInCtor) {
+  CXXMethodDecl *Decl = SMOR->getMethod();
+  FieldDecl *Field = Subobj.dyn_cast<FieldDecl*>();
+
+  int DiagKind = -1;
+
+  if (SMOR->getKind() == Sema::SpecialMemberOverloadResult::NoMemberOrDeleted)
+    DiagKind = !Decl ? 0 : 1;
+  else if (SMOR->getKind() == Sema::SpecialMemberOverloadResult::Ambiguous)
+    DiagKind = 2;
+  else if (S.CheckDirectMemberAccess(Loc, Decl, S.PDiag())
+             != Sema::AR_accessible)
+    DiagKind = 3;
+  else if (!IsDtorCallInCtor && Field && Field->getParent()->isUnion() &&
+           !Decl->isTrivial()) {
+    // A member of a union must have a trivial corresponding special member.
+    // As a weird special case, a destructor call from a union's constructor
+    // must be accessible and non-deleted, but need not be trivial. Such a
+    // destructor is never actually called, but is semantically checked as
+    // if it were.
+    DiagKind = 4;
+  }
+
+  if (DiagKind == -1)
+    return false;
+
+  if (Diagnose) {
+    if (Field) {
+      S.Diag(Field->getLocation(),
+             diag::note_deleted_special_member_class_subobject)
+        << CSM << MD->getParent() << /*IsField*/true
+        << Field << DiagKind << IsDtorCallInCtor;
+    } else {
+      CXXBaseSpecifier *Base = Subobj.get<CXXBaseSpecifier*>();
+      S.Diag(Base->getLocStart(),
+             diag::note_deleted_special_member_class_subobject)
+        << CSM << MD->getParent() << /*IsField*/false
+        << Base->getType() << DiagKind << IsDtorCallInCtor;
+    }
+
+    if (DiagKind == 1)
+      S.NoteDeletedFunction(Decl);
+    // FIXME: Explain inaccessibility if DiagKind == 3.
+  }
+
+  return true;
+}
+
 /// Check whether we should delete a special member function due to having a
 /// direct or virtual base class or static data member of class type M.
 bool SpecialMemberDeletionInfo::shouldDeleteForClassSubobject(
-    CXXRecordDecl *Class, FieldDecl *Field) {
-  // C++11 [class.ctor]p5, C++11 [class.copy]p11, C++11 [class.dtor]p5:
-  // -- any direct or virtual base class [...] has a type with a destructor
-  //    that is deleted or inaccessible
-  if (!IsAssignment) {
-    CXXDestructorDecl *Dtor = S.LookupDestructor(Class);
-    if (Dtor->isDeleted())
-      return true;
-    if (S.CheckDestructorAccess(Loc, Dtor, S.PDiag()) != Sema::AR_accessible)
-      return true;
-
-    // C++11 [class.dtor]p5:
-    // -- X is a union-like class that has a variant member with a non-trivial
-    //    destructor
-    if (CSM == Sema::CXXDestructor && Field && Field->getParent()->isUnion() &&
-        !Dtor->isTrivial())
-      return true;
-  }
+    CXXRecordDecl *Class, Subobject Subobj) {
+  FieldDecl *Field = Subobj.dyn_cast<FieldDecl*>();
 
   // C++11 [class.ctor]p5:
-  // -- any direct or virtual base class [...] has class type M [...] and
+  // -- any direct or virtual base class, or non-static data member with no
+  //    brace-or-equal-initializer, has class type M (or array thereof) and
   //    either M has no default constructor or overload resolution as applied
   //    to M's default constructor results in an ambiguity or in a function
   //    that is deleted or inaccessible
@@ -4425,41 +4468,23 @@
   //    overload resolution, as applied to B's corresponding special member,
   //    results in an ambiguity or a function that is deleted or inaccessible
   //    from the defaulted special member
-  // FIXME: in-class initializers should be handled here
-  if (CSM != Sema::CXXDestructor) {
-    Sema::SpecialMemberOverloadResult *SMOR = lookupIn(Class);
-    if (!SMOR->hasSuccess())
-      return true;
+  // C++11 [class.dtor]p5:
+  // -- any direct or virtual base class [...] has a type with a destructor
+  //    that is deleted or inaccessible
+  if (!(CSM == Sema::CXXDefaultConstructor &&
+        Field && Field->hasInClassInitializer()) &&
+      shouldDeleteForSubobjectCall(Subobj, lookupIn(Class), false))
+    return true;
 
-    CXXMethodDecl *Member = SMOR->getMethod();
-    // A member of a union must have a trivial corresponding special member.
-    if (Field && Field->getParent()->isUnion() && !Member->isTrivial())
+  // C++11 [class.ctor]p5, C++11 [class.copy]p11:
+  // -- any direct or virtual base class or non-static data member has a
+  //    type with a destructor that is deleted or inaccessible
+  if (IsConstructor) {
+    Sema::SpecialMemberOverloadResult *SMOR =
+        S.LookupSpecialMember(Class, Sema::CXXDestructor,
+                              false, false, false, false, false);
+    if (shouldDeleteForSubobjectCall(Subobj, SMOR, true))
       return true;
-
-    if (IsConstructor) {
-      CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(Member);
-      if (S.CheckConstructorAccess(Loc, Ctor, Ctor->getAccess(), S.PDiag())
-            != Sema::AR_accessible)
-        return true;
-
-      // -- for the move constructor, a [...] direct or virtual base class with
-      //    a type that does not have a move constructor and is not trivially
-      //    copyable.
-      if (IsMove && !Ctor->isMoveConstructor() && !Class->isTriviallyCopyable())
-        return true;
-    } else {
-      assert(IsAssignment && "unexpected kind of special member");
-      if (S.CheckDirectMemberAccess(Loc, Member, S.PDiag())
-            != Sema::AR_accessible)
-        return true;
-
-      // -- for the move assignment operator, a direct base class with a type
-      //    that does not have a move assignment operator and is not trivially
-      //    copyable.
-      if (IsMove && !Member->isMoveAssignmentOperator() &&
-          !Class->isTriviallyCopyable())
-        return true;
-    }
   }
 
   return false;
@@ -4467,18 +4492,9 @@
 
 /// Check whether we should delete a special member function due to the class
 /// having a particular direct or virtual base class.
-bool SpecialMemberDeletionInfo::shouldDeleteForBase(CXXRecordDecl *BaseDecl,
-                                                    bool IsVirtualBase) {
-  // C++11 [class.copy]p23:
-  // -- for the move assignment operator, any direct or indirect virtual
-  //    base class.
-  if (CSM == Sema::CXXMoveAssignment && IsVirtualBase)
-    return true;
-
-  if (shouldDeleteForClassSubobject(BaseDecl, 0))
-    return true;
-
-  return false;
+bool SpecialMemberDeletionInfo::shouldDeleteForBase(CXXBaseSpecifier *Base) {
+  CXXRecordDecl *BaseClass = Base->getType()->getAsCXXRecordDecl();
+  return shouldDeleteForClassSubobject(BaseClass, Base);
 }
 
 /// Check whether we should delete a special member function due to the class
@@ -4490,29 +4506,52 @@
   if (CSM == Sema::CXXDefaultConstructor) {
     // For a default constructor, all references must be initialized in-class
     // and, if a union, it must have a non-const member.
-    if (FieldType->isReferenceType() && !FD->hasInClassInitializer())
+    if (FieldType->isReferenceType() && !FD->hasInClassInitializer()) {
+      if (Diagnose)
+        S.Diag(FD->getLocation(), diag::note_deleted_default_ctor_uninit_field)
+          << MD->getParent() << FD << FieldType << /*Reference*/0;
       return true;
-
-    if (inUnion() && !FieldType.isConstQualified())
-      AllFieldsAreConst = false;
-
+    }
     // C++11 [class.ctor]p5: any non-variant non-static data member of
     // const-qualified type (or array thereof) with no
     // brace-or-equal-initializer does not have a user-provided default
     // constructor.
     if (!inUnion() && FieldType.isConstQualified() &&
         !FD->hasInClassInitializer() &&
-        (!FieldRecord || !FieldRecord->hasUserProvidedDefaultConstructor()))
+        (!FieldRecord || !FieldRecord->hasUserProvidedDefaultConstructor())) {
+      if (Diagnose)
+        S.Diag(FD->getLocation(), diag::note_deleted_default_ctor_uninit_field)
+          << MD->getParent() << FD << FieldType << /*Const*/1;
       return true;
+    }
+
+    if (inUnion() && !FieldType.isConstQualified())
+      AllFieldsAreConst = false;
   } else if (CSM == Sema::CXXCopyConstructor) {
     // For a copy constructor, data members must not be of rvalue reference
     // type.
-    if (FieldType->isRValueReferenceType())
+    if (FieldType->isRValueReferenceType()) {
+      if (Diagnose)
+        S.Diag(FD->getLocation(), diag::note_deleted_copy_ctor_rvalue_reference)
+          << MD->getParent() << FD << FieldType;
       return true;
+    }
   } else if (IsAssignment) {
     // For an assignment operator, data members must not be of reference type.
-    if (FieldType->isReferenceType())
+    if (FieldType->isReferenceType()) {
+      if (Diagnose)
+        S.Diag(FD->getLocation(), diag::note_deleted_assign_field)
+          << IsMove << MD->getParent() << FD << FieldType << /*Reference*/0;
       return true;
+    }
+    if (!FieldRecord && FieldType.isConstQualified()) {
+      // C++11 [class.copy]p23:
+      // -- a non-static data member of const non-class type (or array thereof)
+      if (Diagnose)
+        S.Diag(FD->getLocation(), diag::note_deleted_assign_field)
+          << IsMove << MD->getParent() << FD << FieldType << /*Const*/1;
+      return true;
+    }
   }
 
   if (FieldRecord) {
@@ -4521,6 +4560,7 @@
         FieldRecord->isAnonymousStructOrUnion()) {
       bool AllVariantFieldsAreConst = true;
 
+      // FIXME: Handle anonymous unions declared within anonymous unions.
       for (CXXRecordDecl::field_iterator UI = FieldRecord->field_begin(),
                                          UE = FieldRecord->field_end();
            UI != UE; ++UI) {
@@ -4537,77 +4577,21 @@
 
       // At least one member in each anonymous union must be non-const
       if (CSM == Sema::CXXDefaultConstructor && AllVariantFieldsAreConst &&
-          FieldRecord->field_begin() != FieldRecord->field_end())
+          FieldRecord->field_begin() != FieldRecord->field_end()) {
+        if (Diagnose)
+          S.Diag(FieldRecord->getLocation(),
+                 diag::note_deleted_default_ctor_all_const)
+            << MD->getParent() << /*anonymous union*/1;
         return true;
+      }
 
-      // Don't try to initialize the anonymous union
+      // Don't check the implicit member of the anonymous union type.
       // This is technically non-conformant, but sanity demands it.
       return false;
     }
 
-    // When checking a constructor, the field's destructor must be accessible
-    // and not deleted.
-    if (IsConstructor) {
-      CXXDestructorDecl *FieldDtor = S.LookupDestructor(FieldRecord);
-      if (FieldDtor->isDeleted())
-        return true;
-      if (S.CheckDestructorAccess(Loc, FieldDtor, S.PDiag()) !=
-          Sema::AR_accessible)
-        return true;
-    }
-
-    // Check that the corresponding member of the field is accessible,
-    // unique, and non-deleted. We don't do this if it has an explicit
-    // initialization when default-constructing.
-    if (!(CSM == Sema::CXXDefaultConstructor && FD->hasInClassInitializer())) {
-      Sema::SpecialMemberOverloadResult *SMOR = lookupIn(FieldRecord);
-      if (!SMOR->hasSuccess())
-        return true;
-
-      CXXMethodDecl *FieldMember = SMOR->getMethod();
-
-      // We need the corresponding member of a union to be trivial so that
-      // we can safely process all members simultaneously.
-      if (inUnion() && !FieldMember->isTrivial())
-        return true;
-
-      if (IsConstructor) {
-        CXXConstructorDecl *FieldCtor = cast<CXXConstructorDecl>(FieldMember);
-        if (S.CheckConstructorAccess(Loc, FieldCtor, FieldCtor->getAccess(),
-                                     S.PDiag()) != Sema::AR_accessible)
-        return true;
-
-        // For a move operation, the corresponding operation must actually
-        // be a move operation (and not a copy selected by overload
-        // resolution) unless we are working on a trivially copyable class.
-        if (IsMove && !FieldCtor->isMoveConstructor() &&
-            !FieldRecord->isTriviallyCopyable())
-          return true;
-      } else if (CSM == Sema::CXXDestructor) {
-        CXXDestructorDecl *FieldDtor = S.LookupDestructor(FieldRecord);
-        if (FieldDtor->isDeleted())
-          return true;
-        if (S.CheckDestructorAccess(Loc, FieldDtor, S.PDiag()) !=
-            Sema::AR_accessible)
-          return true;
-      } else {
-        assert(IsAssignment && "unexpected kind of special member");
-        if (S.CheckDirectMemberAccess(Loc, FieldMember, S.PDiag())
-              != Sema::AR_accessible)
-          return true;
-
-        // -- for the move assignment operator, a non-static data member with a
-        //    type that does not have a move assignment operator and is not
-        //    trivially copyable.
-        if (IsMove && !FieldMember->isMoveAssignmentOperator() &&
-            !FieldRecord->isTriviallyCopyable())
-          return true;
-      }
-    }
-  } else if (IsAssignment && FieldType.isConstQualified()) {
-    // C++11 [class.copy]p23:
-    // -- a non-static data member of const non-class type (or array thereof)
-    return true;
+    if (shouldDeleteForClassSubobject(FieldRecord, FD))
+      return true;
   }
 
   return false;
@@ -4619,40 +4603,37 @@
 bool SpecialMemberDeletionInfo::shouldDeleteForAllConstMembers() {
   // This is a silly definition, because it gives an empty union a deleted
   // default constructor. Don't do that.
-  return CSM == Sema::CXXDefaultConstructor && inUnion() && AllFieldsAreConst &&
-    (MD->getParent()->field_begin() != MD->getParent()->field_end());
+  if (CSM == Sema::CXXDefaultConstructor && inUnion() && AllFieldsAreConst &&
+      (MD->getParent()->field_begin() != MD->getParent()->field_end())) {
+    if (Diagnose)
+      S.Diag(MD->getParent()->getLocation(),
+             diag::note_deleted_default_ctor_all_const)
+        << MD->getParent() << /*not anonymous union*/0;
+    return true;
+  }
+  return false;
 }
 
 /// Determine whether a defaulted special member function should be defined as
 /// deleted, as specified in C++11 [class.ctor]p5, C++11 [class.copy]p11,
 /// C++11 [class.copy]p23, and C++11 [class.dtor]p5.
-bool Sema::ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM) {
+bool Sema::ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMember CSM,
+                                     bool Diagnose) {
   assert(!MD->isInvalidDecl());
   CXXRecordDecl *RD = MD->getParent();
   assert(!RD->isDependentType() && "do deletion after instantiation");
   if (!LangOpts.CPlusPlus0x || RD->isInvalidDecl())
     return false;
 
-  // FIXME: Provide the ability to diagnose why a special member was deleted.
-
   // C++11 [expr.lambda.prim]p19:
   //   The closure type associated with a lambda-expression has a
   //   deleted (8.4.3) default constructor and a deleted copy
   //   assignment operator.
   if (RD->isLambda() &&
-      (CSM == CXXDefaultConstructor || CSM == CXXCopyAssignment))
+      (CSM == CXXDefaultConstructor || CSM == CXXCopyAssignment)) {
+    if (Diagnose)
+      Diag(RD->getLocation(), diag::note_lambda_decl);
     return true;
-
-  // C++11 [class.dtor]p5:
-  // -- for a virtual destructor, lookup of the non-array deallocation function
-  //    results in an ambiguity or in a function that is deleted or inaccessible
-  if (CSM == Sema::CXXDestructor && MD->isVirtual()) {
-    FunctionDecl *OperatorDelete = 0;
-    DeclarationName Name =
-      Context.DeclarationNames.getCXXOperatorName(OO_Delete);
-    if (FindDeallocationFunction(MD->getLocation(), MD->getParent(), Name,
-                                 OperatorDelete, false))
-      return true;
   }
 
   // For an anonymous struct or union, the copy and assignment special members
@@ -4662,20 +4643,66 @@
       RD->isAnonymousStructOrUnion())
     return false;
 
+  // C++11 [class.copy]p7, p18:
+  //   If the class definition declares a move constructor or move assignment
+  //   operator, an implicitly declared copy constructor or copy assignment
+  //   operator is defined as deleted.
+  if (MD->isImplicit() &&
+      (CSM == CXXCopyConstructor || CSM == CXXCopyAssignment)) {
+    CXXMethodDecl *UserDeclaredMove = 0;
+
+    // In Microsoft mode, a user-declared move only causes the deletion of the
+    // corresponding copy operation, not both copy operations.
+    if (RD->hasUserDeclaredMoveConstructor() &&
+        (!getLangOpts().MicrosoftMode || CSM == CXXCopyConstructor)) {
+      if (!Diagnose) return true;
+      UserDeclaredMove = RD->getMoveConstructor();
+      assert(UserDeclaredMove);
+    } else if (RD->hasUserDeclaredMoveAssignment() &&
+               (!getLangOpts().MicrosoftMode || CSM == CXXCopyAssignment)) {
+      if (!Diagnose) return true;
+      UserDeclaredMove = RD->getMoveAssignmentOperator();
+      assert(UserDeclaredMove);
+    }
+
+    if (UserDeclaredMove) {
+      Diag(UserDeclaredMove->getLocation(),
+           diag::note_deleted_copy_user_declared_move)
+        << (CSM == CXXCopyAssignment) << RD
+        << UserDeclaredMove->isMoveAssignmentOperator();
+      return true;
+    }
+  }
+
   // Do access control from the special member function
   ContextRAII MethodContext(*this, MD);
 
-  SpecialMemberDeletionInfo SMI(*this, MD, CSM);
+  // C++11 [class.dtor]p5:
+  // -- for a virtual destructor, lookup of the non-array deallocation function
+  //    results in an ambiguity or in a function that is deleted or inaccessible
+  if (CSM == CXXDestructor && MD->isVirtual()) {
+    FunctionDecl *OperatorDelete = 0;
+    DeclarationName Name =
+      Context.DeclarationNames.getCXXOperatorName(OO_Delete);
+    if (FindDeallocationFunction(MD->getLocation(), MD->getParent(), Name,
+                                 OperatorDelete, false)) {
+      if (Diagnose)
+        Diag(RD->getLocation(), diag::note_deleted_dtor_no_operator_delete);
+      return true;
+    }
+  }
+
+  SpecialMemberDeletionInfo SMI(*this, MD, CSM, Diagnose);
 
   for (CXXRecordDecl::base_class_iterator BI = RD->bases_begin(),
                                           BE = RD->bases_end(); BI != BE; ++BI)
     if (!BI->isVirtual() &&
-        SMI.shouldDeleteForBase(BI->getType()->getAsCXXRecordDecl(), false))
+        SMI.shouldDeleteForBase(BI))
       return true;
 
   for (CXXRecordDecl::base_class_iterator BI = RD->vbases_begin(),
                                           BE = RD->vbases_end(); BI != BE; ++BI)
-    if (SMI.shouldDeleteForBase(BI->getType()->getAsCXXRecordDecl(), true))
+    if (SMI.shouldDeleteForBase(BI))
       return true;
 
   for (CXXRecordDecl::field_iterator FI = RD->field_begin(),
@@ -4830,7 +4857,7 @@
       DeclareImplicitCopyAssignment(ClassDecl);
   }
 
-  if (getLangOpts().CPlusPlus0x && ClassDecl->needsImplicitMoveAssignment()){
+  if (getLangOpts().CPlusPlus0x && ClassDecl->needsImplicitMoveAssignment()) {
     ++ASTContext::NumImplicitMoveAssignmentOperators;
 
     // Likewise for the move assignment operator.
@@ -6233,9 +6260,9 @@
     return UD;
   }
 
-  // Constructor inheriting using decls get special treatment.
+  // The normal rules do not apply to inheriting constructor declarations.
   if (NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName) {
-    if (CheckInheritedConstructorUsingDecl(UD))
+    if (CheckInheritingConstructorUsingDecl(UD))
       UD->setInvalidDecl();
     return UD;
   }
@@ -6305,11 +6332,8 @@
 }
 
 /// Additional checks for a using declaration referring to a constructor name.
-bool Sema::CheckInheritedConstructorUsingDecl(UsingDecl *UD) {
-  if (UD->isTypeName()) {
-    // FIXME: Cannot specify typename when specifying constructor
-    return true;
-  }
+bool Sema::CheckInheritingConstructorUsingDecl(UsingDecl *UD) {
+  assert(!UD->isTypeName() && "expecting a constructor name");
 
   const Type *SourceType = UD->getQualifier()->getAsType();
   assert(SourceType &&
@@ -6324,6 +6348,8 @@
     CanQualType BaseType = BaseIt->getType()->getCanonicalTypeUnqualified();
     if (CanonicalSourceType == BaseType)
       break;
+    if (BaseIt->getType()->isDependentType())
+      break;
   }
 
   if (BaseIt == BaseE) {
@@ -6335,7 +6361,8 @@
     return true;
   }
 
-  BaseIt->setInheritConstructors();
+  if (!CurContext->isDependentContext())
+    BaseIt->setInheritConstructors();
 
   return false;
 }
@@ -6984,7 +7011,6 @@
         Context.getCanonicalType(CtorIt->getType()).getTypePtr());
   }
 
-  Scope *S = getScopeForContext(ClassDecl);
   DeclarationName CreatedCtorName =
       Context.DeclarationNames.getCXXConstructorName(
           ClassDecl->getTypeForDecl()->getCanonicalTypeUnqualified());
@@ -7006,10 +7032,12 @@
                                       CtorE = BaseDecl->ctor_end();
          CtorIt != CtorE; ++CtorIt) {
       // Find the using declaration for inheriting this base's constructors.
+      // FIXME: Don't perform name lookup just to obtain a source location!
       DeclarationName Name =
           Context.DeclarationNames.getCXXConstructorName(CanonicalBase);
-      UsingDecl *UD = dyn_cast_or_null<UsingDecl>(
-          LookupSingleName(S, Name,SourceLocation(), LookupUsingDeclName));
+      LookupResult Result(*this, Name, SourceLocation(), LookupUsingDeclName);
+      LookupQualifiedName(Result, CurContext);
+      UsingDecl *UD = Result.getAsSingle<UsingDecl>();
       SourceLocation UsingLoc = UD ? UD->getLocation() :
                                      ClassDecl->getLocation();
 
@@ -7120,7 +7148,6 @@
         NewCtor->setParams(ParamDecls);
         NewCtor->setInheritedConstructor(BaseCtor);
 
-        PushOnScopeChains(NewCtor, S, false);
         ClassDecl->addDecl(NewCtor);
         result.first->second.second = NewCtor;
       }
@@ -7339,8 +7366,8 @@
     while (F.hasNext()) {
       NamedDecl *D = F.next();
       if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D))
-        if (Copying ? Method->isCopyAssignmentOperator() :
-                      Method->isMoveAssignmentOperator())
+        if (Method->isCopyAssignmentOperator() ||
+            (!Copying && Method->isMoveAssignmentOperator()))
           continue;
 
       F.erase();
@@ -7657,12 +7684,9 @@
   //   assignment operator, there is no user-declared move constructor, and
   //   there is no user-declared move assignment operator, a copy assignment
   //   operator is implicitly declared as defaulted.
-  if ((ClassDecl->hasUserDeclaredMoveConstructor() &&
-          !getLangOpts().MicrosoftMode) ||
-      ClassDecl->hasUserDeclaredMoveAssignment() ||
-      ShouldDeleteSpecialMember(CopyAssignment, CXXCopyAssignment))
+  if (ShouldDeleteSpecialMember(CopyAssignment, CXXCopyAssignment))
     CopyAssignment->setDeletedAsWritten();
-  
+
   AddOverriddenMethods(ClassDecl, CopyAssignment);
   return CopyAssignment;
 }
@@ -8033,7 +8057,115 @@
   return ExceptSpec;
 }
 
+/// Determine whether the class type has any direct or indirect virtual base
+/// classes which have a non-trivial move assignment operator.
+static bool
+hasVirtualBaseWithNonTrivialMoveAssignment(Sema &S, CXXRecordDecl *ClassDecl) {
+  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
+                                          BaseEnd = ClassDecl->vbases_end();
+       Base != BaseEnd; ++Base) {
+    CXXRecordDecl *BaseClass =
+        cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl());
+
+    // Try to declare the move assignment. If it would be deleted, then the
+    // class does not have a non-trivial move assignment.
+    if (BaseClass->needsImplicitMoveAssignment())
+      S.DeclareImplicitMoveAssignment(BaseClass);
+
+    // If the class has both a trivial move assignment and a non-trivial move
+    // assignment, hasTrivialMoveAssignment() is false.
+    if (BaseClass->hasDeclaredMoveAssignment() &&
+        !BaseClass->hasTrivialMoveAssignment())
+      return true;
+  }
+
+  return false;
+}
+
+/// Determine whether the given type either has a move constructor or is
+/// trivially copyable.
+static bool
+hasMoveOrIsTriviallyCopyable(Sema &S, QualType Type, bool IsConstructor) {
+  Type = S.Context.getBaseElementType(Type);
+
+  // FIXME: Technically, non-trivially-copyable non-class types, such as
+  // reference types, are supposed to return false here, but that appears
+  // to be a standard defect.
+  CXXRecordDecl *ClassDecl = Type->getAsCXXRecordDecl();
+  if (!ClassDecl)
+    return true;
+
+  if (Type.isTriviallyCopyableType(S.Context))
+    return true;
+
+  if (IsConstructor) {
+    if (ClassDecl->needsImplicitMoveConstructor())
+      S.DeclareImplicitMoveConstructor(ClassDecl);
+    return ClassDecl->hasDeclaredMoveConstructor();
+  }
+
+  if (ClassDecl->needsImplicitMoveAssignment())
+    S.DeclareImplicitMoveAssignment(ClassDecl);
+  return ClassDecl->hasDeclaredMoveAssignment();
+}
+
+/// Determine whether all non-static data members and direct or virtual bases
+/// of class \p ClassDecl have either a move operation, or are trivially
+/// copyable.
+static bool subobjectsHaveMoveOrTrivialCopy(Sema &S, CXXRecordDecl *ClassDecl,
+                                            bool IsConstructor) {
+  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
+                                          BaseEnd = ClassDecl->bases_end();
+       Base != BaseEnd; ++Base) {
+    if (Base->isVirtual())
+      continue;
+
+    if (!hasMoveOrIsTriviallyCopyable(S, Base->getType(), IsConstructor))
+      return false;
+  }
+
+  for (CXXRecordDecl::base_class_iterator Base = ClassDecl->vbases_begin(),
+                                          BaseEnd = ClassDecl->vbases_end();
+       Base != BaseEnd; ++Base) {
+    if (!hasMoveOrIsTriviallyCopyable(S, Base->getType(), IsConstructor))
+      return false;
+  }
+
+  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),
+                                     FieldEnd = ClassDecl->field_end();
+       Field != FieldEnd; ++Field) {
+    if (!hasMoveOrIsTriviallyCopyable(S, (*Field)->getType(), IsConstructor))
+      return false;
+  }
+
+  return true;
+}
+
 CXXMethodDecl *Sema::DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl) {
+  // C++11 [class.copy]p20:
+  //   If the definition of a class X does not explicitly declare a move
+  //   assignment operator, one will be implicitly declared as defaulted
+  //   if and only if:
+  //
+  //   - [first 4 bullets]
+  assert(ClassDecl->needsImplicitMoveAssignment());
+
+  // [Checked after we build the declaration]
+  //   - the move assignment operator would not be implicitly defined as
+  //     deleted,
+
+  // [DR1402]:
+  //   - X has no direct or indirect virtual base class with a non-trivial
+  //     move assignment operator, and
+  //   - each of X's non-static data members and direct or virtual base classes
+  //     has a type that either has a move assignment operator or is trivially
+  //     copyable.
+  if (hasVirtualBaseWithNonTrivialMoveAssignment(*this, ClassDecl) ||
+      !subobjectsHaveMoveOrTrivialCopy(*this, ClassDecl,/*Constructor*/false)) {
+    ClassDecl->setFailedImplicitMoveAssignment();
+    return 0;
+  }
+
   // Note: The following rules are largely analoguous to the move
   // constructor rules.
 
@@ -8149,7 +8281,7 @@
   // ASTs.
   Expr *This = ActOnCXXThis(Loc).takeAs<Expr>();
   assert(This && "Reference to this cannot fail!");
-  
+
   // Assign base classes.
   bool Invalid = false;
   for (CXXRecordDecl::base_class_iterator Base = ClassDecl->bases_begin(),
@@ -8576,12 +8708,9 @@
   //   constructor, there is no user-declared move constructor, and there is no
   //   user-declared move assignment operator, a copy constructor is implicitly
   //   declared as defaulted.
-  if (ClassDecl->hasUserDeclaredMoveConstructor() ||
-      (ClassDecl->hasUserDeclaredMoveAssignment() &&
-          !getLangOpts().MicrosoftMode) ||
-      ShouldDeleteSpecialMember(CopyConstructor, CXXCopyConstructor))
+  if (ShouldDeleteSpecialMember(CopyConstructor, CXXCopyConstructor))
     CopyConstructor->setDeletedAsWritten();
-  
+
   return CopyConstructor;
 }
 
@@ -8683,6 +8812,25 @@
 
 CXXConstructorDecl *Sema::DeclareImplicitMoveConstructor(
                                                     CXXRecordDecl *ClassDecl) {
+  // C++11 [class.copy]p9:
+  //   If the definition of a class X does not explicitly declare a move
+  //   constructor, one will be implicitly declared as defaulted if and only if:
+  //
+  //   - [first 4 bullets]
+  assert(ClassDecl->needsImplicitMoveConstructor());
+
+  // [Checked after we build the declaration]
+  //   - the move assignment operator would not be implicitly defined as
+  //     deleted,
+
+  // [DR1402]:
+  //   - each of X's non-static data members and direct or virtual base classes
+  //     has a type that either has a move constructor or is trivially copyable.
+  if (!subobjectsHaveMoveOrTrivialCopy(*this, ClassDecl, /*Constructor*/true)) {
+    ClassDecl->setFailedImplicitMoveConstructor();
+    return 0;
+  }
+
   ImplicitExceptionSpecification Spec(
       ComputeDefaultedMoveCtorExceptionSpec(ClassDecl));
 

Modified: cfe/branches/tooling/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaExpr.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaExpr.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaExpr.cpp Tue Apr  3 07:29:12 2012
@@ -108,6 +108,28 @@
     return Result;
 }
 
+/// \brief Emit a note explaining that this function is deleted or unavailable.
+void Sema::NoteDeletedFunction(FunctionDecl *Decl) {
+  CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Decl);
+
+  if (Method && Method->isDeleted() && !Method->isDeletedAsWritten()) {
+    // If the method was explicitly defaulted, point at that declaration.
+    if (!Method->isImplicit())
+      Diag(Decl->getLocation(), diag::note_implicitly_deleted);
+
+    // Try to diagnose why this special member function was implicitly
+    // deleted. This might fail, if that reason no longer applies.
+    CXXSpecialMember CSM = getSpecialMember(Method);
+    if (CSM != CXXInvalid)
+      ShouldDeleteSpecialMember(Method, CSM, /*Diagnose=*/true);
+
+    return;
+  }
+
+  Diag(Decl->getLocation(), diag::note_unavailable_here)
+    << 1 << Decl->isDeleted();
+}
+
 /// \brief Determine whether the use of this declaration is valid, and
 /// emit any corresponding diagnostics.
 ///
@@ -151,7 +173,7 @@
   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     if (FD->isDeleted()) {
       Diag(Loc, diag::err_deleted_function_use);
-      Diag(D->getLocation(), diag::note_unavailable_here) << 1 << true;
+      NoteDeletedFunction(FD);
       return true;
     }
   }
@@ -10087,6 +10109,17 @@
         return true;
       }
 
+      // Forbid the block-capture of autoreleasing variables.
+      if (CaptureType.getObjCLifetime() == Qualifiers::OCL_Autoreleasing) {
+        if (BuildAndDiagnose) {
+          Diag(Loc, diag::err_arc_autoreleasing_capture)
+            << /*block*/ 0;
+          Diag(Var->getLocation(), diag::note_previous_decl)
+            << Var->getDeclName();
+        }
+        return true;
+      }
+
       if (HasBlocksAttr || CaptureType->isReferenceType()) {
         // Block capture by reference does not change the capture or
         // declaration reference types.
@@ -10179,6 +10212,16 @@
         if (!RefType->getPointeeType()->isFunctionType())
           CaptureType = RefType->getPointeeType();
       }
+
+      // Forbid the lambda copy-capture of autoreleasing variables.
+      if (CaptureType.getObjCLifetime() == Qualifiers::OCL_Autoreleasing) {
+        if (BuildAndDiagnose) {
+          Diag(Loc, diag::err_arc_autoreleasing_capture) << /*lambda*/ 1;
+          Diag(Var->getLocation(), diag::note_previous_decl)
+            << Var->getDeclName();
+        }
+        return true;
+      }
     }
 
     // Capture this variable in the lambda.

Modified: cfe/branches/tooling/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaExprCXX.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaExprCXX.cpp Tue Apr  3 07:29:12 2012
@@ -1899,8 +1899,7 @@
     if (Operator->isDeleted()) {
       if (Diagnose) {
         Diag(StartLoc, diag::err_deleted_function_use);
-        Diag(Operator->getLocation(), diag::note_unavailable_here)
-          << /*function*/ 1 << /*deleted*/ 1;
+        NoteDeletedFunction(Operator);
       }
       return true;
     }

Modified: cfe/branches/tooling/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaInit.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaInit.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaInit.cpp Tue Apr  3 07:29:12 2012
@@ -2465,6 +2465,7 @@
   case FK_VariableLengthArrayHasInitializer:
   case FK_PlaceholderType:
   case FK_InitListElementCopyFailure:
+  case FK_ExplicitConstructor:
     return false;
 
   case FK_ReferenceInitOverloadFailed:
@@ -2896,7 +2897,7 @@
 
   // Determine whether we are allowed to call explicit constructors or
   // explicit conversion operators.
-  bool AllowExplicit = Kind.AllowExplicit();
+  bool AllowExplicit = Kind.AllowExplicit() || InitListSyntax;
   bool CopyInitialization = Kind.getKind() == InitializationKind::IK_Copy;
 
   //   - Otherwise, if T is a class type, constructors are considered. The
@@ -2961,10 +2962,18 @@
     return;
   }
 
+  // C++11 [over.match.list]p1:
+  //   In copy-list-initialization, if an explicit constructor is chosen, the
+  //   initializer is ill-formed.
+  CXXConstructorDecl *CtorDecl = cast<CXXConstructorDecl>(Best->Function);
+  if (InitListSyntax && !Kind.AllowExplicit() && CtorDecl->isExplicit()) {
+    Sequence.SetFailed(InitializationSequence::FK_ExplicitConstructor);
+    return;
+  }
+
   // Add the constructor initialization step. Any cv-qualification conversion is
   // subsumed by the initialization.
   bool HadMultipleCandidates = (CandidateSet.size() > 1);
-  CXXConstructorDecl *CtorDecl = cast<CXXConstructorDecl>(Best->Function);
   Sequence.AddConstructorInitializationStep(CtorDecl,
                                             Best->FoundDecl.getAccess(),
                                             DestType, HadMultipleCandidates,
@@ -4482,8 +4491,7 @@
     S.Diag(Loc, diag::err_temp_copy_deleted)
       << (int)Entity.getKind() << CurInitExpr->getType()
       << CurInitExpr->getSourceRange();
-    S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
-      << 1 << Best->Function->isDeleted();
+    S.NoteDeletedFunction(Best->Function);
     return ExprError();
   }
 
@@ -4592,8 +4600,7 @@
 
   case OR_Deleted:
     S.Diag(Loc, Diag);
-    S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
-      << 1 << Best->Function->isDeleted();
+    S.NoteDeletedFunction(Best->Function);
     break;
   }
 }
@@ -5362,26 +5369,6 @@
   return move(CurInit);
 }
 
-/// \brief Provide some notes that detail why a function was implicitly
-/// deleted.
-static void diagnoseImplicitlyDeletedFunction(Sema &S, CXXMethodDecl *Method) {
-  // FIXME: This is a work in progress. It should dig deeper to figure out
-  // why the function was deleted (e.g., because one of its members doesn't
-  // have a copy constructor, for the copy-constructor case).
-  if (!Method->isImplicit()) {
-    S.Diag(Method->getLocation(), diag::note_callee_decl)
-      << Method->getDeclName();
-  }
-  
-  if (Method->getParent()->isLambda()) {
-    S.Diag(Method->getParent()->getLocation(), diag::note_lambda_decl);
-    return;
-  }
-  
-  S.Diag(Method->getParent()->getLocation(), diag::note_defined_here)
-    << Method->getParent();
-}
-
 //===----------------------------------------------------------------------===//
 // Diagnose initialization failures
 //===----------------------------------------------------------------------===//
@@ -5469,8 +5456,7 @@
         = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best,
                                                 true);
       if (Ovl == OR_Deleted) {
-        S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
-          << 1 << Best->Function->isDeleted();
+        S.NoteDeletedFunction(Best->Function);
       } else {
         llvm_unreachable("Inconsistent overload resolution?");
       }
@@ -5661,20 +5647,15 @@
         // If this is a defaulted or implicitly-declared function, then
         // it was implicitly deleted. Make it clear that the deletion was
         // implicit.
-        if (S.isImplicitlyDeleted(Best->Function)) {
+        if (S.isImplicitlyDeleted(Best->Function))
           S.Diag(Kind.getLocation(), diag::err_ovl_deleted_special_init)
-            << S.getSpecialMember(cast<CXXMethodDecl>(Best->Function)) 
+            << S.getSpecialMember(cast<CXXMethodDecl>(Best->Function))
             << DestType << ArgsRange;
-        
-          diagnoseImplicitlyDeletedFunction(S, 
-            cast<CXXMethodDecl>(Best->Function));            
-          break;
-        }
-        
-        S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init)
-          << true << DestType << ArgsRange;
-        S.Diag(Best->Function->getLocation(), diag::note_unavailable_here)
-          << 1 << Best->Function->isDeleted();
+        else
+          S.Diag(Kind.getLocation(), diag::err_ovl_deleted_init)
+            << true << DestType << ArgsRange;
+
+        S.NoteDeletedFunction(Best->Function);
         break;
       }
 
@@ -5757,6 +5738,19 @@
     }
     break;
   }
+
+  case FK_ExplicitConstructor: {
+    S.Diag(Kind.getLocation(), diag::err_selected_explicit_constructor)
+      << Args[0]->getSourceRange();
+    OverloadCandidateSet::iterator Best;
+    OverloadingResult Ovl
+      = FailedCandidateSet.BestViableFunction(S, Kind.getLocation(), Best);
+    (void)Ovl;
+    assert(Ovl == OR_Success && "Inconsistent overload resolution");
+    CXXConstructorDecl *CtorDecl = cast<CXXConstructorDecl>(Best->Function);
+    S.Diag(CtorDecl->getLocation(), diag::note_constructor_declared_here);
+    break;
+  }
   }
 
   PrintInitLocationNote(S, Entity);
@@ -5871,6 +5865,10 @@
     case FK_InitListElementCopyFailure:
       OS << "copy construction of initializer list element failed";
       break;
+
+    case FK_ExplicitConstructor:
+      OS << "list copy initialization chose explicit constructor";
+      break;
     }
     OS << '\n';
     return;

Modified: cfe/branches/tooling/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaLookup.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaLookup.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaLookup.cpp Tue Apr  3 07:29:12 2012
@@ -2274,8 +2274,9 @@
     CXXDestructorDecl *DD = RD->getDestructor();
     assert(DD && "record without a destructor");
     Result->setMethod(DD);
-    Result->setSuccess(!DD->isDeleted());
-    Result->setConstParamMatch(false);
+    Result->setKind(DD->isDeleted() ?
+                    SpecialMemberOverloadResult::NoMemberOrDeleted :
+                    SpecialMemberOverloadResult::SuccessNonConst);
     return Result;
   }
 
@@ -2345,7 +2346,8 @@
   // will always be a (possibly implicit) declaration to shadow any others.
   OverloadCandidateSet OCS((SourceLocation()));
   DeclContext::lookup_iterator I, E;
-  Result->setConstParamMatch(false);
+  SpecialMemberOverloadResult::Kind SuccessKind =
+      SpecialMemberOverloadResult::SuccessNonConst;
 
   llvm::tie(I, E) = RD->lookup(Name);
   assert((I != E) &&
@@ -2384,7 +2386,7 @@
         QualType ArgType = M->getType()->getAs<FunctionProtoType>()->getArgType(0);
         if (!ArgType->isReferenceType() ||
             ArgType->getPointeeType().isConstQualified())
-          Result->setConstParamMatch(true);
+          SuccessKind = SpecialMemberOverloadResult::SuccessConst;
       }
     } else if (FunctionTemplateDecl *Tmpl =
                  dyn_cast<FunctionTemplateDecl>(Cand)) {
@@ -2406,18 +2408,22 @@
   switch (OCS.BestViableFunction(*this, SourceLocation(), Best)) {
     case OR_Success:
       Result->setMethod(cast<CXXMethodDecl>(Best->Function));
-      Result->setSuccess(true);
+      Result->setKind(SuccessKind);
       break;
 
     case OR_Deleted:
       Result->setMethod(cast<CXXMethodDecl>(Best->Function));
-      Result->setSuccess(false);
+      Result->setKind(SpecialMemberOverloadResult::NoMemberOrDeleted);
       break;
 
     case OR_Ambiguous:
+      Result->setMethod(0);
+      Result->setKind(SpecialMemberOverloadResult::Ambiguous);
+      break;
+
     case OR_No_Viable_Function:
       Result->setMethod(0);
-      Result->setSuccess(false);
+      Result->setKind(SpecialMemberOverloadResult::NoMemberOrDeleted);
       break;
   }
 

Modified: cfe/branches/tooling/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaOverload.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaOverload.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaOverload.cpp Tue Apr  3 07:29:12 2012
@@ -4808,7 +4808,6 @@
   // Check for a narrowing implicit conversion.
   APValue PreNarrowingValue;
   QualType PreNarrowingType;
-  bool Diagnosed = false;
   switch (SCS->getNarrowingKind(Context, Result.get(), PreNarrowingValue,
                                 PreNarrowingType)) {
   case NK_Variable_Narrowing:
@@ -4818,16 +4817,18 @@
     break;
 
   case NK_Constant_Narrowing:
-    Diag(From->getLocStart(), diag::err_cce_narrowing)
+    Diag(From->getLocStart(),
+         isSFINAEContext() ? diag::err_cce_narrowing_sfinae :
+                             diag::err_cce_narrowing)
       << CCE << /*Constant*/1
       << PreNarrowingValue.getAsString(Context, PreNarrowingType) << T;
-    Diagnosed = true;
     break;
 
   case NK_Type_Narrowing:
-    Diag(From->getLocStart(), diag::err_cce_narrowing)
+    Diag(From->getLocStart(),
+         isSFINAEContext() ? diag::err_cce_narrowing_sfinae :
+                             diag::err_cce_narrowing)
       << CCE << /*Constant*/0 << From->getType() << T;
-    Diagnosed = true;
     break;
   }
 
@@ -4849,10 +4850,6 @@
     }
   }
 
-  // Only issue one narrowing diagnostic.
-  if (Diagnosed)
-    return Result;
-
   // It's not a constant expression. Produce an appropriate diagnostic.
   if (Notes.size() == 1 &&
       Notes[0].second.getDiagID() == diag::note_invalid_subexpr_in_const_expr)
@@ -8240,7 +8237,8 @@
     OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Fn, FnDesc);
 
     S.Diag(Fn->getLocation(), diag::note_ovl_candidate_deleted)
-      << FnKind << FnDesc << Fn->isDeleted();
+      << FnKind << FnDesc
+      << (Fn->isDeleted() ? (Fn->isDeletedAsWritten() ? 1 : 2) : 0);
     MaybeEmitInheritedConstructorNote(S, Fn);
     return;
   }
@@ -10089,9 +10087,11 @@
           << getSpecialMember(Method)
           << BinaryOperator::getOpcodeStr(Opc)
           << getDeletedOrUnavailableSuffix(Best->Function);
-        
-        if (Method->getParent()->isLambda()) {
-          Diag(Method->getParent()->getLocation(), diag::note_lambda_decl);
+
+        if (getSpecialMember(Method) != CXXInvalid) {
+          // The user probably meant to call this special member. Just
+          // explain why it's deleted.
+          NoteDeletedFunction(Method);
           return ExprError();
         }
       } else {

Modified: cfe/branches/tooling/lib/Sema/SemaPseudoObject.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaPseudoObject.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaPseudoObject.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaPseudoObject.cpp Tue Apr  3 07:29:12 2012
@@ -208,6 +208,7 @@
   /// A PseudoOpBuilder for Objective-C @properties.
   class ObjCPropertyOpBuilder : public PseudoOpBuilder {
     ObjCPropertyRefExpr *RefExpr;
+    ObjCPropertyRefExpr *SyntacticRefExpr;
     OpaqueValueExpr *InstanceReceiver;
     ObjCMethodDecl *Getter;
 
@@ -217,7 +218,7 @@
   public:
     ObjCPropertyOpBuilder(Sema &S, ObjCPropertyRefExpr *refExpr) :
       PseudoOpBuilder(S, refExpr->getLocation()), RefExpr(refExpr),
-      InstanceReceiver(0), Getter(0), Setter(0) {
+      SyntacticRefExpr(0), InstanceReceiver(0), Getter(0), Setter(0) {
     }
 
     ExprResult buildRValueOperation(Expr *op);
@@ -538,6 +539,10 @@
       ObjCPropertyRefRebuilder(S, InstanceReceiver).rebuild(syntacticBase);
   }
 
+  if (ObjCPropertyRefExpr *
+        refE = dyn_cast<ObjCPropertyRefExpr>(syntacticBase->IgnoreParens()))
+    SyntacticRefExpr = refE;
+
   return syntacticBase;
 }
 
@@ -545,7 +550,10 @@
 ExprResult ObjCPropertyOpBuilder::buildGet() {
   findGetter();
   assert(Getter);
-  
+
+  if (SyntacticRefExpr)
+    SyntacticRefExpr->setIsMessagingGetter();
+
   QualType receiverType;
   if (RefExpr->isClassReceiver()) {
     receiverType = S.Context.getObjCInterfaceType(RefExpr->getClassReceiver());
@@ -581,6 +589,9 @@
   bool hasSetter = findSetter();
   assert(hasSetter); (void) hasSetter;
 
+  if (SyntacticRefExpr)
+    SyntacticRefExpr->setIsMessagingSetter();
+
   QualType receiverType;
   if (RefExpr->isClassReceiver()) {
     receiverType = S.Context.getObjCInterfaceType(RefExpr->getClassReceiver());

Modified: cfe/branches/tooling/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaStmt.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaStmt.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaStmt.cpp Tue Apr  3 07:29:12 2012
@@ -1079,10 +1079,18 @@
 /// x can be an arbitrary l-value expression.  Bind it up as a
 /// full-expression.
 StmtResult Sema::ActOnForEachLValueExpr(Expr *E) {
+  // Reduce placeholder expressions here.  Note that this rejects the
+  // use of pseudo-object l-values in this position.
+  ExprResult result = CheckPlaceholderExpr(E);
+  if (result.isInvalid()) return StmtError();
+  E = result.take();
+
   CheckImplicitConversions(E);
-  ExprResult Result = MaybeCreateExprWithCleanups(E);
-  if (Result.isInvalid()) return StmtError();
-  return Owned(static_cast<Stmt*>(Result.get()));
+
+  result = MaybeCreateExprWithCleanups(E);
+  if (result.isInvalid()) return StmtError();
+
+  return Owned(static_cast<Stmt*>(result.take()));
 }
 
 ExprResult
@@ -1945,24 +1953,21 @@
     return ActOnCapScopeReturnStmt(ReturnLoc, RetValExp);
 
   QualType FnRetType;
-  QualType DeclaredRetType;
+  QualType RelatedRetType;
   if (const FunctionDecl *FD = getCurFunctionDecl()) {
     FnRetType = FD->getResultType();
-    DeclaredRetType = FnRetType;
     if (FD->hasAttr<NoReturnAttr>() ||
         FD->getType()->getAs<FunctionType>()->getNoReturnAttr())
       Diag(ReturnLoc, diag::warn_noreturn_function_has_return_expr)
         << FD->getDeclName();
   } else if (ObjCMethodDecl *MD = getCurMethodDecl()) {
-    DeclaredRetType = MD->getResultType();
+    FnRetType = MD->getResultType();
     if (MD->hasRelatedResultType() && MD->getClassInterface()) {
       // In the implementation of a method with a related return type, the
       // type used to type-check the validity of return statements within the 
       // method body is a pointer to the type of the class being implemented.
-      FnRetType = Context.getObjCInterfaceType(MD->getClassInterface());
-      FnRetType = Context.getObjCObjectPointerType(FnRetType);
-    } else {
-      FnRetType = DeclaredRetType;
+      RelatedRetType = Context.getObjCInterfaceType(MD->getClassInterface());
+      RelatedRetType = Context.getObjCObjectPointerType(RelatedRetType);
     }
   } else // If we don't have a function/method context, bail.
     return StmtError();
@@ -2045,6 +2050,21 @@
     if (!FnRetType->isDependentType() && !RetValExp->isTypeDependent()) {
       // we have a non-void function with an expression, continue checking
 
+      if (!RelatedRetType.isNull()) {
+        // If we have a related result type, perform an extra conversion here.
+        // FIXME: The diagnostics here don't really describe what is happening.
+        InitializedEntity Entity =
+            InitializedEntity::InitializeTemporary(RelatedRetType);
+        
+        ExprResult Res = PerformCopyInitialization(Entity, SourceLocation(),
+                                                   RetValExp);
+        if (Res.isInvalid()) {
+          // FIXME: Cleanup temporaries here, anyway?
+          return StmtError();
+        }
+        RetValExp = Res.takeAs<Expr>();
+      }
+
       // C99 6.8.6.4p3(136): The return statement is not an assignment. The
       // overlap restriction of subclause 6.5.16.1 does not apply to the case of
       // function return.
@@ -2068,17 +2088,6 @@
     }
 
     if (RetValExp) {
-      // If we type-checked an Objective-C method's return type based
-      // on a related return type, we may need to adjust the return
-      // type again. Do so now.
-      if (DeclaredRetType != FnRetType) {
-        ExprResult result = PerformImplicitConversion(RetValExp,
-                                                      DeclaredRetType,
-                                                      AA_Returning);
-        if (result.isInvalid()) return StmtError();
-        RetValExp = result.take();
-      }
-
       CheckImplicitConversions(RetValExp, ReturnLoc);
       RetValExp = MaybeCreateExprWithCleanups(RetValExp);
     }

Modified: cfe/branches/tooling/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaTemplate.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaTemplate.cpp Tue Apr  3 07:29:12 2012
@@ -872,8 +872,12 @@
   if (SS.isNotEmpty() && !SS.isInvalid()) {
     SemanticContext = computeDeclContext(SS, true);
     if (!SemanticContext) {
-      Diag(NameLoc, diag::err_template_qualified_declarator_no_match)
-        << SS.getScopeRep() << SS.getRange();
+      // FIXME: Horrible, horrible hack! We can't currently represent this
+      // in the AST, and historically we have just ignored such friend
+      // class templates, so don't complain here.
+      if (TUK != TUK_Friend)
+        Diag(NameLoc, diag::err_template_qualified_declarator_no_match)
+          << SS.getScopeRep() << SS.getRange();
       return true;
     }
 

Modified: cfe/branches/tooling/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaTemplateInstantiateDecl.cpp Tue Apr  3 07:29:12 2012
@@ -1856,6 +1856,12 @@
   if (NewUD->isInvalidDecl())
     return NewUD;
 
+  if (NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName) {
+    if (SemaRef.CheckInheritingConstructorUsingDecl(NewUD))
+      NewUD->setInvalidDecl();
+    return NewUD;
+  }
+
   bool isFunctionScope = Owner->isFunctionOrMethod();
 
   // Process the shadow decls.

Modified: cfe/branches/tooling/lib/Serialization/ASTReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Serialization/ASTReaderStmt.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/branches/tooling/lib/Serialization/ASTReaderStmt.cpp Tue Apr  3 07:29:12 2012
@@ -887,13 +887,15 @@
 
 void ASTStmtReader::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
   VisitExpr(E);
+  unsigned MethodRefFlags = Record[Idx++];
   bool Implicit = Record[Idx++] != 0;
   if (Implicit) {
     ObjCMethodDecl *Getter = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
     ObjCMethodDecl *Setter = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
-    E->setImplicitProperty(Getter, Setter);
+    E->setImplicitProperty(Getter, Setter, MethodRefFlags);
   } else {
-    E->setExplicitProperty(ReadDeclAs<ObjCPropertyDecl>(Record, Idx));
+    E->setExplicitProperty(ReadDeclAs<ObjCPropertyDecl>(Record, Idx),
+                           MethodRefFlags);
   }
   E->setLocation(ReadSourceLocation(Record, Idx));
   E->setReceiverLocation(ReadSourceLocation(Record, Idx));

Modified: cfe/branches/tooling/lib/Serialization/ASTWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Serialization/ASTWriterStmt.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Serialization/ASTWriterStmt.cpp (original)
+++ cfe/branches/tooling/lib/Serialization/ASTWriterStmt.cpp Tue Apr  3 07:29:12 2012
@@ -851,6 +851,7 @@
 
 void ASTStmtWriter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
   VisitExpr(E);
+  Record.push_back(E->SetterAndMethodRefFlags.getInt());
   Record.push_back(E->isImplicitProperty());
   if (E->isImplicitProperty()) {
     Writer.AddDeclRef(E->getImplicitPropertyGetter(), Record);

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Tue Apr  3 07:29:12 2012
@@ -1262,6 +1262,11 @@
       return false;
     }
 
+    // Whitelist NSXXInsertXX, for example NSMapInsertIfAbsent, since they can
+    // be deallocated by NSMapRemove.
+    if (FName.startswith("NS") && (FName.find("Insert") != StringRef::npos))
+      return false;
+
     // Otherwise, assume that the function does not free memory.
     // Most system calls, do not free the memory.
     return true;

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp Tue Apr  3 07:29:12 2012
@@ -993,6 +993,13 @@
       // libdispatch finalizers.
       ScratchArgs = AF.add(ScratchArgs, 1, StopTracking);
       S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
+    } else if (FName.startswith("NS") &&
+                (FName.find("Insert") != StringRef::npos)) {
+      // Whitelist NSXXInsertXX, for example NSMapInsertIfAbsent, since they can
+      // be deallocated by NSMapRemove. (radar://11152419)
+      ScratchArgs = AF.add(ScratchArgs, 1, StopTracking);
+      ScratchArgs = AF.add(ScratchArgs, 2, StopTracking);
+      S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);
     }
 
     // Did we get a summary?

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp Tue Apr  3 07:29:12 2012
@@ -24,7 +24,7 @@
 #include "clang/AST/ParentMap.h"
 #include "clang/Basic/Builtins.h"
 #include "clang/Basic/SourceManager.h"
-#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallSet.h"
 
 // The number of CFGBlock pointers we want to reserve memory for. This is used
 // once for each function we analyze.

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/BugReporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/BugReporter.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/BugReporter.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/BugReporter.cpp Tue Apr  3 07:29:12 2012
@@ -1383,10 +1383,7 @@
 // Methods for BugReporter and subclasses.
 //===----------------------------------------------------------------------===//
 
-BugReportEquivClass::~BugReportEquivClass() {
-  for (iterator I=begin(), E=end(); I!=E; ++I) delete *I;
-}
-
+BugReportEquivClass::~BugReportEquivClass() { }
 GRBugReporter::~GRBugReporter() { }
 BugReporterData::~BugReporterData() {}
 
@@ -1809,17 +1806,17 @@
 
   BugReportEquivClass::iterator I = EQ.begin(), E = EQ.end();
   assert(I != E);
-  BugReport *R = *I;
-  BugType& BT = R->getBugType();
+  BugType& BT = I->getBugType();
 
   // If we don't need to suppress any of the nodes because they are
   // post-dominated by a sink, simply add all the nodes in the equivalence class
   // to 'Nodes'.  Any of the reports will serve as a "representative" report.
   if (!BT.isSuppressOnSink()) {
+    BugReport *R = I;
     for (BugReportEquivClass::iterator I=EQ.begin(), E=EQ.end(); I!=E; ++I) {
       const ExplodedNode *N = I->getErrorNode();
       if (N) {
-        R = *I;
+        R = I;
         bugReports.push_back(R);
       }
     }
@@ -1835,8 +1832,7 @@
   BugReport *exampleReport = 0;
 
   for (; I != E; ++I) {
-    R = *I;
-    const ExplodedNode *errorNode = R->getErrorNode();
+    const ExplodedNode *errorNode = I->getErrorNode();
 
     if (!errorNode)
       continue;
@@ -1846,9 +1842,9 @@
     }
     // No successors?  By definition this nodes isn't post-dominated by a sink.
     if (errorNode->succ_empty()) {
-      bugReports.push_back(R);
+      bugReports.push_back(I);
       if (!exampleReport)
-        exampleReport = R;
+        exampleReport = I;
       continue;
     }
 
@@ -1872,9 +1868,9 @@
         if (Succ->succ_empty()) {
           // If we found an end-of-path node that is not a sink.
           if (!Succ->isSink()) {
-            bugReports.push_back(R);
+            bugReports.push_back(I);
             if (!exampleReport)
-              exampleReport = R;
+              exampleReport = I;
             WL.clear();
             break;
           }

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/CMakeLists.txt?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/CMakeLists.txt (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/CMakeLists.txt Tue Apr  3 07:29:12 2012
@@ -22,6 +22,7 @@
   ExprEngineCXX.cpp
   ExprEngineCallAndReturn.cpp
   ExprEngineObjC.cpp
+  FunctionSummary.cpp
   HTMLDiagnostics.cpp
   MemRegion.cpp
   ObjCMessage.cpp

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/CoreEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/CoreEngine.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/CoreEngine.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/CoreEngine.cpp Tue Apr  3 07:29:12 2012
@@ -174,6 +174,11 @@
     assert (Entry->succ_size() == 1 &&
             "Entry block must have 1 successor.");
 
+    // Mark the entry block as visited.
+    FunctionSummaries->markVisitedBasicBlock(Entry->getBlockID(),
+                                             L->getDecl(),
+                                             L->getCFG()->getNumBlockIDs());
+
     // Get the solitary successor.
     const CFGBlock *Succ = *(Entry->succ_begin());
 
@@ -280,6 +285,12 @@
   const CFGBlock *Blk = L.getDst();
   NodeBuilderContext BuilderCtx(*this, Blk, Pred);
 
+  // Mark this block as visited.
+  const LocationContext *LC = Pred->getLocationContext();
+  FunctionSummaries->markVisitedBasicBlock(Blk->getBlockID(),
+                                           LC->getDecl(),
+                                           LC->getCFG()->getNumBlockIDs());
+
   // Check if we are entering the EXIT block.
   if (Blk == &(L.getLocationContext()->getCFG()->getExit())) {
 
@@ -312,10 +323,11 @@
                                        ExplodedNode *Pred) {
 
   // Increment the block counter.
+  const LocationContext *LC = Pred->getLocationContext();
+  unsigned BlockId = L.getBlock()->getBlockID();
   BlockCounter Counter = WList->getBlockCounter();
-  Counter = BCounterFactory.IncrementCount(Counter, 
-                             Pred->getLocationContext()->getCurrentStackFrame(),
-                                           L.getBlock()->getBlockID());
+  Counter = BCounterFactory.IncrementCount(Counter, LC->getCurrentStackFrame(),
+                                           BlockId);
   WList->setBlockCounter(Counter);
 
   // Process the entrance of the block.

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngine.cpp Tue Apr  3 07:29:12 2012
@@ -67,10 +67,11 @@
 //===----------------------------------------------------------------------===//
 
 ExprEngine::ExprEngine(AnalysisManager &mgr, bool gcEnabled,
-                       SetOfDecls *VisitedCallees)
+                       SetOfDecls *VisitedCallees,
+                       FunctionSummariesTy *FS)
   : AMgr(mgr),
     AnalysisDeclContexts(mgr.getAnalysisDeclContextManager()),
-    Engine(*this, VisitedCallees),
+    Engine(*this, VisitedCallees, FS),
     G(Engine.getGraph()),
     StateMgr(getContext(), mgr.getStoreManagerCreator(),
              mgr.getConstraintManagerCreator(), G.getAllocator(),
@@ -1046,9 +1047,12 @@
     // Check if we stopped at the top level function or not.
     // Root node should have the location context of the top most function.
     const LocationContext *CalleeLC = pred->getLocation().getLocationContext();
+    const LocationContext *CalleeSF = CalleeLC->getCurrentStackFrame();
     const LocationContext *RootLC =
                         (*G.roots_begin())->getLocation().getLocationContext();
-    if (RootLC->getCurrentStackFrame() != CalleeLC->getCurrentStackFrame()) {
+    if (RootLC->getCurrentStackFrame() != CalleeSF) {
+      Engine.FunctionSummaries->markReachedMaxBlockCount(CalleeSF->getDecl());
+
       // Re-run the call evaluation without inlining it, by storing the
       // no-inlining policy in the state and enqueuing the new work item on
       // the list. Replay should almost never fail. Use the stats to catch it
@@ -2022,9 +2026,7 @@
     // Iterate through the reports and get their nodes.
     for (BugReporter::EQClasses_iterator
            EI = BR.EQClasses_begin(), EE = BR.EQClasses_end(); EI != EE; ++EI) {
-      BugReportEquivClass& EQ = *EI;
-      const BugReport &R = **EQ.begin();
-      ExplodedNode *N = const_cast<ExplodedNode*>(R.getErrorNode());
+      ExplodedNode *N = const_cast<ExplodedNode*>(EI->begin()->getErrorNode());
       if (N) Src.push_back(N);
     }
 

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp Tue Apr  3 07:29:12 2012
@@ -14,8 +14,9 @@
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h"
-#include "llvm/Support/SaveAndRestore.h"
 #include "clang/AST/DeclCXX.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/Support/SaveAndRestore.h"
 
 using namespace clang;
 using namespace ento;
@@ -137,6 +138,9 @@
         == AMgr.InlineMaxStackDepth)
     return false;
 
+  if (Engine.FunctionSummaries->hasReachedMaxBlockCount(FD))
+    return false;
+
   if (CalleeCFG->getNumBlockIDs() > AMgr.InlineMaxFunctionSize)
     return false;
 
@@ -198,10 +202,11 @@
       
       CallEnter Loc(CE, CalleeSFC, Pred->getLocationContext());
       bool isNew;
-      ExplodedNode *N = G.getNode(Loc, state, false, &isNew);
-      N->addPredecessor(Pred, G);
-      if (isNew)
-        Engine.getWorkList()->enqueue(N);
+      if (ExplodedNode *N = G.getNode(Loc, state, false, &isNew)) {
+        N->addPredecessor(Pred, G);
+        if (isNew)
+          Engine.getWorkList()->enqueue(N);
+      }
       return true;
     }
   }
@@ -242,9 +247,13 @@
       // in buffer.
       // - Many CF containers allow objects to escape through custom
       // allocators/deallocators upon container construction.
+      // - NSXXInsertXX, for example NSMapInsertIfAbsent, since they can
+      // be deallocated by NSMapRemove.
       if (FName == "pthread_setspecific" ||
           FName == "funopen" ||
           FName.endswith("NoCopy") ||
+          (FName.startswith("NS") &&
+            (FName.find("Insert") != StringRef::npos)) ||
           Call.isCFCGAllowingEscape(FName))
         return;
     }

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/RegionStore.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/RegionStore.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/RegionStore.cpp Tue Apr  3 07:29:12 2012
@@ -1194,14 +1194,23 @@
 
   // At this point we have already checked in either getBindingForElement or
   // getBindingForField if 'R' has a direct binding.
-
   RegionBindings B = GetRegionBindings(store);
+  
+  // Record whether or not we see a symbolic index.  That can completely
+  // be out of scope of our lookup.
+  bool hasSymbolicIndex = false;
 
   while (superR) {
     if (const Optional<SVal> &D =
         getBindingForDerivedDefaultValue(B, superR, R, Ty))
       return *D;
 
+    if (const ElementRegion *ER = dyn_cast<ElementRegion>(superR)) {
+      NonLoc index = ER->getIndex();
+      if (!index.isConstant())
+        hasSymbolicIndex = true;
+    }
+    
     // If our super region is a field or element itself, walk up the region
     // hierarchy to see if there is a default value installed in an ancestor.
     if (const SubRegion *SR = dyn_cast<SubRegion>(superR)) {
@@ -1220,7 +1229,7 @@
     return getLazyBinding(lazyBindingRegion, lazyBindingStore);
 
   if (R->hasStackNonParametersStorage()) {
-    if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
+    if (isa<ElementRegion>(R)) {
       // Currently we don't reason specially about Clang-style vectors.  Check
       // if superR is a vector and if so return Unknown.
       if (const TypedValueRegion *typedSuperR = 
@@ -1228,13 +1237,15 @@
         if (typedSuperR->getValueType()->isVectorType())
           return UnknownVal();
       }
-      
-      // FIXME: We also need to take ElementRegions with symbolic indexes into
-      // account.
-      if (!ER->getIndex().isConstant())
-        return UnknownVal();
     }
 
+    // FIXME: We also need to take ElementRegions with symbolic indexes into
+    // account.  This case handles both directly accessing an ElementRegion
+    // with a symbolic offset, but also fields within an element with
+    // a symbolic offset.
+    if (hasSymbolicIndex)
+      return UnknownVal();
+    
     return UndefinedVal();
   }
 

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp Tue Apr  3 07:29:12 2012
@@ -53,6 +53,9 @@
 
 STATISTIC(NumFunctionTopLevel, "The # of functions at top level.");
 STATISTIC(NumFunctionsAnalyzed, "The # of functions analysed (as top level).");
+STATISTIC(NumBlocksInAnalyzedFunctions,
+                     "The # of basic blocks in the analyzed functions.");
+STATISTIC(PercentReachableBlocks, "The % of reachable basic blocks.");
 
 //===----------------------------------------------------------------------===//
 // Special PathDiagnosticConsumers.
@@ -104,6 +107,10 @@
   /// Time the analyzes time of each translation unit.
   static llvm::Timer* TUTotalTimer;
 
+  /// The information about analyzed functions shared throughout the
+  /// translation unit.
+  FunctionSummariesTy FunctionSummaries;
+
   AnalysisConsumer(const Preprocessor& pp,
                    const std::string& outdir,
                    const AnalyzerOptions& opts,
@@ -118,6 +125,13 @@
   }
 
   ~AnalysisConsumer() {
+    // Count how many basic blocks we have not covered.
+    NumBlocksInAnalyzedFunctions = FunctionSummaries.getTotalNumBasicBlocks();
+    if (NumBlocksInAnalyzedFunctions > 0)
+      PercentReachableBlocks =
+        (FunctionSummaries.getTotalNumVisitedBasicBlocks() * 100) /
+          NumBlocksInAnalyzedFunctions;
+
     if (Opts.PrintStats)
       delete TUTotalTimer;
   }
@@ -449,7 +463,7 @@
   if (!Mgr->getCFG(D))
     return;
 
-  ExprEngine Eng(*Mgr, ObjCGCEnabled, VisitedCallees);
+  ExprEngine Eng(*Mgr, ObjCGCEnabled, VisitedCallees, &FunctionSummaries);
 
   // Set the graph auditor.
   OwningPtr<ExplodedNode::Auditor> Auditor;

Modified: cfe/branches/tooling/test/ARCMT/init.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/ARCMT/init.m?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/ARCMT/init.m (original)
+++ cfe/branches/tooling/test/ARCMT/init.m Tue Apr  3 07:29:12 2012
@@ -3,6 +3,8 @@
 // RUN: diff %t %s.result
 // DISABLE: mingw32
 
+#define nil (void *)0
+
 @interface NSObject
 -init;
 @end

Modified: cfe/branches/tooling/test/ARCMT/init.m.result
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/ARCMT/init.m.result?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/ARCMT/init.m.result (original)
+++ cfe/branches/tooling/test/ARCMT/init.m.result Tue Apr  3 07:29:12 2012
@@ -3,6 +3,8 @@
 // RUN: diff %t %s.result
 // DISABLE: mingw32
 
+#define nil (void *)0
+
 @interface NSObject
 -init;
 @end
@@ -16,7 +18,7 @@
 
 @implementation A
 -(id) init {
-  self = [self init];
+  if (!(self = [self init])) return nil;
   id a;
   [a init];
   a = [[A alloc] init];
@@ -25,7 +27,7 @@
 }
 
 -(id) init2 {
-  self = [super init];
+  if (!(self = [super init])) return nil;
   return self;
 }
 

Modified: cfe/branches/tooling/test/Analysis/malloc.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Analysis/malloc.mm?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/Analysis/malloc.mm (original)
+++ cfe/branches/tooling/test/Analysis/malloc.mm Tue Apr  3 07:29:12 2012
@@ -106,6 +106,25 @@
   myBlock(3);
 }
 
+// Test NSMapInsert. 
+ at interface NSMapTable : NSObject <NSCopying, NSCoding, NSFastEnumeration>
+ at end
+extern void *NSMapGet(NSMapTable *table, const void *key);
+extern void NSMapInsert(NSMapTable *table, const void *key, const void *value);
+extern void NSMapInsertKnownAbsent(NSMapTable *table, const void *key, const void *value);
+char *strdup(const char *s);
+
+NSString * radar11152419(NSString *string1, NSMapTable *map) {
+    const char *strkey = "key";
+    NSString *string = ( NSString *)NSMapGet(map, strkey);
+    if (!string) {
+        string = [string1 copy];
+        NSMapInsert(map, strdup(strkey), (void*)string); // no warning
+        NSMapInsertKnownAbsent(map, strdup(strkey), (void*)string); // no warning
+    }
+    return string;
+}
+
 // Test that we handle pointer escaping through OSAtomicEnqueue.
 typedef volatile struct {
  void *opaque1;

Modified: cfe/branches/tooling/test/Analysis/misc-ps-region-store.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Analysis/misc-ps-region-store.m?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/Analysis/misc-ps-region-store.m (original)
+++ cfe/branches/tooling/test/Analysis/misc-ps-region-store.m Tue Apr  3 07:29:12 2012
@@ -1325,3 +1325,19 @@
   *dst = '\0';
 }
 
+// Test handling symbolic elements with field accesses.
+// <rdar://problem/11127008>
+typedef struct {
+    unsigned value;
+} RDar11127008;
+
+signed rdar_11127008_index();
+
+static unsigned rdar_11127008(void) {
+    RDar11127008 values[] = {{.value = 0}, {.value = 1}};
+    signed index = rdar_11127008_index();
+    if (index < 0) return 0;
+    if (index >= 2) return 0;
+    return values[index].value;
+}
+

Modified: cfe/branches/tooling/test/Analysis/retain-release.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Analysis/retain-release.mm?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/Analysis/retain-release.mm (original)
+++ cfe/branches/tooling/test/Analysis/retain-release.mm Tue Apr  3 07:29:12 2012
@@ -111,6 +111,7 @@
 @protocol NSObject
 - (BOOL)isEqual:(id)object;
 - (id)retain;
+- (id)copy;
 - (oneway void)release;
 - (id)autorelease;
 @end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
@@ -347,3 +348,21 @@
   return 0;
 }
 
+ at interface NSMapTable : NSObject <NSCopying, NSCoding, NSFastEnumeration>
+ at end
+extern void *NSMapGet(NSMapTable *table, const void *key);
+extern void NSMapInsert(NSMapTable *table, const void *key, const void *value);
+extern void NSMapInsertKnownAbsent(NSMapTable *table, const void *key, const void *value);
+char *strdup(const char *s);
+
+NSString * radar11152419(NSString *string1, NSString *key1, NSMapTable *map) {
+    NSString *string = ( NSString *)NSMapGet(map, key1);
+    if (!string) {
+        string = [string1 copy];
+        NSString *key = [key1 copy];
+        NSMapInsert(map, (void*) key, (void*)string); // no warning
+        NSMapInsertKnownAbsent(map, (void*)key, (void*)string); // no warning
+    }
+    return string;
+}
+

Modified: cfe/branches/tooling/test/Analysis/stats.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Analysis/stats.c?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/Analysis/stats.c (original)
+++ cfe/branches/tooling/test/Analysis/stats.c Tue Apr  3 07:29:12 2012
@@ -4,4 +4,5 @@
   int x;
 }
 // CHECK: ... Statistics Collected ...
+// CHECK:100 AnalysisConsumer - The % of reachable basic blocks.
 // CHECK:The # of times RemoveDeadBindings is called

Modified: cfe/branches/tooling/test/Analysis/system-header-simulator-objc.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Analysis/system-header-simulator-objc.h?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/Analysis/system-header-simulator-objc.h (original)
+++ cfe/branches/tooling/test/Analysis/system-header-simulator-objc.h Tue Apr  3 07:29:12 2012
@@ -39,6 +39,7 @@
 @protocol NSObject
 - (BOOL)isEqual:(id)object;
 - (id)retain;
+- (id)copy;
 - (oneway void)release;
 - (id)autorelease;
 - (id)init;

Modified: cfe/branches/tooling/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp (original)
+++ cfe/branches/tooling/test/CXX/dcl.decl/dcl.init/dcl.init.aggr/p1-0x.cpp Tue Apr  3 07:29:12 2012
@@ -8,7 +8,7 @@
 protected:
   struct Inner { int m; };
 public:
-  bool &br;
+  bool &br; // expected-note {{default constructor of 'Aggr' is implicitly deleted because field 'br' of reference type 'bool &' would not be initialized}}
 };
 bool b;
 Aggr ag = { b };
@@ -54,7 +54,7 @@
 };
 NonAggr5 na5 = { b }; // expected-error {{no matching constructor for initialization of 'NonAggr5'}}
 template<typename...BaseList>
-struct MaybeAggr5a : BaseList... {}; // expected-note {{defined here}}
+struct MaybeAggr5a : BaseList... {}; // expected-note {{default constructor of 'MaybeAggr5a<Aggr>' is implicitly deleted because base class 'Aggr' has a deleted default constructor}}
 MaybeAggr5a<> ma5a0 = {}; // ok
 MaybeAggr5a<Aggr> ma5a1 = {}; // expected-error {{call to implicitly-deleted default constructor of 'MaybeAggr5a<Aggr>'}}
 

Modified: cfe/branches/tooling/test/CXX/special/class.copy/implicit-move.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/special/class.copy/implicit-move.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/special/class.copy/implicit-move.cpp (original)
+++ cfe/branches/tooling/test/CXX/special/class.copy/implicit-move.cpp Tue Apr  3 07:29:12 2012
@@ -25,10 +25,10 @@
   HasCopyAssignment & operator =(const HasCopyAssignment &) noexcept(false);
 };
 
-struct HasMoveConstructor { // expected-note {{implicit copy assignment}}
+struct HasMoveConstructor {
   ThrowingCopy tc;
   HasMoveConstructor() noexcept;
-  HasMoveConstructor(HasMoveConstructor &&) noexcept;
+  HasMoveConstructor(HasMoveConstructor &&) noexcept; // expected-note {{copy assignment operator is implicitly deleted because 'HasMoveConstructor' has a user-declared move constructor}}
 };
 
 struct HasMoveAssignment { // expected-note {{implicit copy constructor}}
@@ -87,9 +87,9 @@
   ~PrivateDestructor() noexcept;
 };
 
-struct InheritsPrivateDestructor : PrivateDestructor {}; // expected-note{{defined here}}
-struct ContainsPrivateDestructor { // expected-note{{defined here}}
-  PrivateDestructor pd;
+struct InheritsPrivateDestructor : PrivateDestructor {}; // expected-note{{base class 'PrivateDestructor' has an inaccessible destructor}}
+struct ContainsPrivateDestructor {
+  PrivateDestructor pd; // expected-note{{field 'pd' has an inaccessible destructor}}
 };
 
 struct NonTrivialCopyOnly {
@@ -162,3 +162,75 @@
 void test_contains_rref() {
   (ContainsRValueRef(ContainsRValueRef()));
 }
+
+
+namespace DR1402 {
+  struct NonTrivialCopyCtor {
+    NonTrivialCopyCtor(const NonTrivialCopyCtor &);
+  };
+  struct NonTrivialCopyAssign {
+    NonTrivialCopyAssign &operator=(const NonTrivialCopyAssign &);
+  };
+
+  struct NonTrivialCopyCtorVBase : virtual NonTrivialCopyCtor {
+    NonTrivialCopyCtorVBase(NonTrivialCopyCtorVBase &&);
+    NonTrivialCopyCtorVBase &operator=(NonTrivialCopyCtorVBase &&) = default;
+  };
+  struct NonTrivialCopyAssignVBase : virtual NonTrivialCopyAssign {
+    NonTrivialCopyAssignVBase(NonTrivialCopyAssignVBase &&);
+    NonTrivialCopyAssignVBase &operator=(NonTrivialCopyAssignVBase &&) = default;
+  };
+
+  struct NonTrivialMoveAssign {
+    NonTrivialMoveAssign(NonTrivialMoveAssign&&);
+    NonTrivialMoveAssign &operator=(NonTrivialMoveAssign &&);
+  };
+  struct NonTrivialMoveAssignVBase : virtual NonTrivialMoveAssign {
+    NonTrivialMoveAssignVBase(NonTrivialMoveAssignVBase &&);
+    NonTrivialMoveAssignVBase &operator=(NonTrivialMoveAssignVBase &&) = default;
+  };
+
+  // A non-movable, non-trivially-copyable class type as a subobject inhibits
+  // the declaration of a move operation.
+  struct NoMove1 { NonTrivialCopyCtor ntcc; }; // expected-note 2{{'const DR1402::NoMove1 &'}}
+  struct NoMove2 { NonTrivialCopyAssign ntcc; }; // expected-note 2{{'const DR1402::NoMove2 &'}}
+  struct NoMove3 : NonTrivialCopyCtor {}; // expected-note 2{{'const DR1402::NoMove3 &'}}
+  struct NoMove4 : NonTrivialCopyAssign {}; // expected-note 2{{'const DR1402::NoMove4 &'}}
+  struct NoMove5 : virtual NonTrivialCopyCtor {}; // expected-note 2{{'const DR1402::NoMove5 &'}}
+  struct NoMove6 : virtual NonTrivialCopyAssign {}; // expected-note 2{{'const DR1402::NoMove6 &'}}
+  struct NoMove7 : NonTrivialCopyCtorVBase {}; // expected-note 2{{'DR1402::NoMove7 &'}}
+  struct NoMove8 : NonTrivialCopyAssignVBase {}; // expected-note 2{{'DR1402::NoMove8 &'}}
+
+  // A non-trivially-move-assignable virtual base class inhibits the declaration
+  // of a move assignment (which might move-assign the base class multiple
+  // times).
+  struct NoMove9 : NonTrivialMoveAssign {};
+  struct NoMove10 : virtual NonTrivialMoveAssign {}; // expected-note {{'DR1402::NoMove10 &'}}
+  struct NoMove11 : NonTrivialMoveAssignVBase {}; // expected-note {{'DR1402::NoMove11 &'}}
+
+  struct Test {
+    friend NoMove1::NoMove1(NoMove1 &&); // expected-error {{no matching function}}
+    friend NoMove2::NoMove2(NoMove2 &&); // expected-error {{no matching function}}
+    friend NoMove3::NoMove3(NoMove3 &&); // expected-error {{no matching function}}
+    friend NoMove4::NoMove4(NoMove4 &&); // expected-error {{no matching function}}
+    friend NoMove5::NoMove5(NoMove5 &&); // expected-error {{no matching function}}
+    friend NoMove6::NoMove6(NoMove6 &&); // expected-error {{no matching function}}
+    friend NoMove7::NoMove7(NoMove7 &&); // expected-error {{no matching function}}
+    friend NoMove8::NoMove8(NoMove8 &&); // expected-error {{no matching function}}
+    friend NoMove9::NoMove9(NoMove9 &&);
+    friend NoMove10::NoMove10(NoMove10 &&);
+    friend NoMove11::NoMove11(NoMove11 &&);
+
+    friend NoMove1 &NoMove1::operator=(NoMove1 &&); // expected-error {{no matching function}}
+    friend NoMove2 &NoMove2::operator=(NoMove2 &&); // expected-error {{no matching function}}
+    friend NoMove3 &NoMove3::operator=(NoMove3 &&); // expected-error {{no matching function}}
+    friend NoMove4 &NoMove4::operator=(NoMove4 &&); // expected-error {{no matching function}}
+    friend NoMove5 &NoMove5::operator=(NoMove5 &&); // expected-error {{no matching function}}
+    friend NoMove6 &NoMove6::operator=(NoMove6 &&); // expected-error {{no matching function}}
+    friend NoMove7 &NoMove7::operator=(NoMove7 &&); // expected-error {{no matching function}}
+    friend NoMove8 &NoMove8::operator=(NoMove8 &&); // expected-error {{no matching function}}
+    friend NoMove9 &NoMove9::operator=(NoMove9 &&);
+    friend NoMove10 &NoMove10::operator=(NoMove10 &&); // expected-error {{no matching function}}
+    friend NoMove11 &NoMove11::operator=(NoMove11 &&); // expected-error {{no matching function}}
+  };
+}

Modified: cfe/branches/tooling/test/CXX/special/class.copy/p11.0x.copy.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/special/class.copy/p11.0x.copy.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/special/class.copy/p11.0x.copy.cpp (original)
+++ cfe/branches/tooling/test/CXX/special/class.copy/p11.0x.copy.cpp Tue Apr  3 07:29:12 2012
@@ -7,16 +7,16 @@
 // A defaulted copy constructor for a class X is defined as deleted if X has:
 
 // -- a variant member with a non-trivial corresponding constructor
-union DeletedNTVariant { // expected-note{{here}}
-  NonTrivial NT;
+union DeletedNTVariant {
+  NonTrivial NT; // expected-note{{copy constructor of union 'DeletedNTVariant' is implicitly deleted because field 'NT' has a non-trivial copy constructor}}
   DeletedNTVariant();
 };
 DeletedNTVariant DVa;
 DeletedNTVariant DVb(DVa); // expected-error{{call to implicitly-deleted copy constructor}}
 
-struct DeletedNTVariant2 { // expected-note{{here}}
+struct DeletedNTVariant2 {
   union {
-    NonTrivial NT;
+    NonTrivial NT; // expected-note{{copy constructor of union 'DeletedNTVariant2' is implicitly deleted because field 'NT' has a non-trivial copy constructor}}
   };
   DeletedNTVariant2();
 };
@@ -34,8 +34,8 @@
   friend struct HasAccess;
 };
 
-struct HasNoAccess { // expected-note{{here}}
-  NoAccess NA;
+struct HasNoAccess {
+  NoAccess NA; // expected-note{{copy constructor of 'HasNoAccess' is implicitly deleted because field 'NA' has an inaccessible copy constructor}}
 };
 HasNoAccess HNAa;
 HasNoAccess HNAb(HNAa); // expected-error{{call to implicitly-deleted copy constructor}}
@@ -55,16 +55,16 @@
   Ambiguity(volatile Ambiguity&);
 };
 
-struct IsAmbiguous { // expected-note{{here}}
+struct IsAmbiguous {
   NonConst NC;
-  Ambiguity A;
+  Ambiguity A; // expected-note 2{{copy constructor of 'IsAmbiguous' is implicitly deleted because field 'A' has multiple copy constructors}}
   IsAmbiguous();
 };
 IsAmbiguous IAa;
 IsAmbiguous IAb(IAa); // expected-error{{call to implicitly-deleted copy constructor}}
 
-struct Deleted { // expected-note{{here}}
-  IsAmbiguous IA;
+struct Deleted {
+  IsAmbiguous IA; // expected-note{{copy constructor of 'Deleted' is implicitly deleted because field 'IA' has a deleted copy constructor}}
 };
 Deleted Da;
 Deleted Db(Da); // expected-error{{call to implicitly-deleted copy constructor}}
@@ -72,17 +72,17 @@
 // -- a direct or virtual base class B that cannot be copied because overload
 //    resolution results in an ambiguity or a function that is deleted or
 //    inaccessible
-struct AmbiguousCopyBase : Ambiguity { // expected-note {{here}}
+struct AmbiguousCopyBase : Ambiguity { // expected-note 2{{copy constructor of 'AmbiguousCopyBase' is implicitly deleted because base class 'Ambiguity' has multiple copy constructors}}
   NonConst NC;
 };
 extern AmbiguousCopyBase ACBa;
 AmbiguousCopyBase ACBb(ACBa); // expected-error {{deleted copy constructor}}
 
-struct DeletedCopyBase : AmbiguousCopyBase {}; // expected-note {{here}}
+struct DeletedCopyBase : AmbiguousCopyBase {}; // expected-note {{copy constructor of 'DeletedCopyBase' is implicitly deleted because base class 'AmbiguousCopyBase' has a deleted copy constructor}}
 extern DeletedCopyBase DCBa;
 DeletedCopyBase DCBb(DCBa); // expected-error {{deleted copy constructor}}
 
-struct InaccessibleCopyBase : NoAccess {}; // expected-note {{here}}
+struct InaccessibleCopyBase : NoAccess {}; // expected-note {{copy constructor of 'InaccessibleCopyBase' is implicitly deleted because base class 'NoAccess' has an inaccessible copy constructor}}
 extern InaccessibleCopyBase ICBa;
 InaccessibleCopyBase ICBb(ICBa); // expected-error {{deleted copy constructor}}
 
@@ -94,8 +94,8 @@
   friend struct HasAccessDtor;
 };
 
-struct HasNoAccessDtor { // expected-note{{here}}
-  NoAccessDtor NAD;
+struct HasNoAccessDtor {
+  NoAccessDtor NAD; // expected-note{{copy constructor of 'HasNoAccessDtor' is implicitly deleted because field 'NAD' has an inaccessible destructor}}
   HasNoAccessDtor();
   ~HasNoAccessDtor();
 };
@@ -108,14 +108,14 @@
 HasAccessDtor HADa;
 HasAccessDtor HADb(HADa);
 
-struct HasNoAccessDtorBase : NoAccessDtor { // expected-note{{here}}
+struct HasNoAccessDtorBase : NoAccessDtor { // expected-note{{copy constructor of 'HasNoAccessDtorBase' is implicitly deleted because base class 'NoAccessDtor' has an inaccessible destructor}}
 };
 extern HasNoAccessDtorBase HNADBa;
 HasNoAccessDtorBase HNADBb(HNADBa); // expected-error{{implicitly-deleted copy constructor}}
 
 // -- a non-static data member of rvalue reference type
-struct RValue { // expected-note{{here}}
-  int && ri = 1;
+struct RValue {
+  int && ri = 1; // expected-note{{copy constructor of 'RValue' is implicitly deleted because field 'ri' is of rvalue reference type 'int &&'}}
 };
 RValue RVa;
 RValue RVb(RVa); // expected-error{{call to implicitly-deleted copy constructor}}

Modified: cfe/branches/tooling/test/CXX/special/class.copy/p11.0x.move.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/special/class.copy/p11.0x.move.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/special/class.copy/p11.0x.move.cpp (original)
+++ cfe/branches/tooling/test/CXX/special/class.copy/p11.0x.move.cpp Tue Apr  3 07:29:12 2012
@@ -82,7 +82,7 @@
 // -- any direct or virtual base class or non-static data member of a type with
 //    a destructor that is deleted or inaccessible
 struct NoAccessDtor {
-  NoAccessDtor(NoAccessDtor&&);
+  NoAccessDtor(NoAccessDtor&&); // expected-note{{copy constructor is implicitly deleted because 'NoAccessDtor' has a user-declared move constructor}}
 private:
   ~NoAccessDtor();
   friend struct HasAccessDtor;
@@ -100,7 +100,7 @@
 };
 HasAccessDtor::HasAccessDtor(HasAccessDtor&&) = default;
 
-struct HasNoAccessDtorBase : NoAccessDtor { // expected-note{{here}}
+struct HasNoAccessDtorBase : NoAccessDtor { // expected-note{{copy constructor of 'HasNoAccessDtorBase' is implicitly deleted because base class 'NoAccessDtor' has a deleted copy constructor}}
 };
 extern HasNoAccessDtorBase HNADBa;
 HasNoAccessDtorBase HNADBb(HNADBa); // expected-error{{implicitly-deleted copy constructor}}
@@ -123,7 +123,7 @@
   CopyOnly CO;
   NonMove(NonMove&&);
 };
-NonMove::NonMove(NonMove&&) = default; // expected-error{{would delete}}
+NonMove::NonMove(NonMove&&) = default; // ok under DR1402
 
 struct Moveable {
   Moveable();
@@ -135,3 +135,30 @@
   HasMove(HasMove&&);
 };
 HasMove::HasMove(HasMove&&) = default;
+
+namespace DR1402 {
+  struct member {
+    member();
+    member(const member&);
+    member& operator=(const member&);
+    ~member();
+  };
+
+  struct A {
+    member m_;
+
+    A() = default;
+    A(const A&) = default;
+    A& operator=(const A&) = default;
+    A(A&&) = default;
+    A& operator=(A&&) = default;
+    ~A() = default;
+  };
+
+  // ok, A's explicitly-defaulted move operations copy m_.
+  void f() {
+    A a, b(a), c(static_cast<A&&>(a));
+    a = b;
+    b = static_cast<A&&>(c);
+  }
+}

Modified: cfe/branches/tooling/test/CXX/special/class.ctor/p5-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/special/class.ctor/p5-0x.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/special/class.ctor/p5-0x.cpp (original)
+++ cfe/branches/tooling/test/CXX/special/class.ctor/p5-0x.cpp Tue Apr  3 07:29:12 2012
@@ -2,9 +2,9 @@
 
 struct DefaultedDefCtor1 {};
 struct DefaultedDefCtor2 { DefaultedDefCtor2() = default; };
-struct DeletedDefCtor { DeletedDefCtor() = delete; DeletedDefCtor(int); };
+struct DeletedDefCtor { DeletedDefCtor() = delete; DeletedDefCtor(int); }; // expected-note {{explicitly marked deleted here}}
 class PrivateDefCtor { PrivateDefCtor() = default; public: PrivateDefCtor(int); };
-struct DeletedDtor { ~DeletedDtor() = delete; };
+struct DeletedDtor { ~DeletedDtor() = delete; }; // expected-note 4{{explicitly marked deleted here}}
 class PrivateDtor { ~PrivateDtor() = default; };
 class Friend {
   Friend() = default; ~Friend() = default;
@@ -21,7 +21,7 @@
 
 // - X is a union-like class that has a variant member with a non-trivial
 // default constructor,
-union Deleted1a { UserProvidedDefCtor u; }; // expected-note {{defined here}}
+union Deleted1a { UserProvidedDefCtor u; }; // expected-note {{default constructor of union 'Deleted1a' is implicitly deleted because field 'u' has a non-trivial default constructor}}
 Deleted1a d1a; // expected-error {{implicitly-deleted default constructor}}
 union NotDeleted1a { DefaultedDefCtor1 nu; };
 NotDeleted1a nd1a;
@@ -30,13 +30,13 @@
 
 // - any non-static data member with no brace-or-equal-initializer is of
 // reference type,
-class Deleted2a {  // expected-note {{defined here}}
-  Deleted2a() = default;  // expected-note {{declared here}}
-  int &a; 
-}; 
+class Deleted2a {
+  Deleted2a() = default;  // expected-note 4{{implicitly deleted here}}
+  int &a; // expected-note 4{{because field 'a' of reference type 'int &' would not be initialized}}
+};
 Deleted2a d2a; // expected-error {{implicitly-deleted default constructor}}
-struct Deleted2b { // expected-note {{here}}
-  int &&b;
+struct Deleted2b {
+  int &&b; // expected-note {{default constructor of 'Deleted2b' is implicitly deleted because field 'b' of reference type 'int &&' would not be initialized}}
 };
 Deleted2b d2b; // expected-error {{deleted default constructor}}
 class NotDeleted2a { int &a = n; };
@@ -49,13 +49,13 @@
 // - any non-variant non-static data member of const qualified type (or array
 // thereof) with no brace-or-equal-initializer does not have a user-provided
 // default constructor,
-class Deleted3a { const int a; }; // expected-note {{here}} \
+class Deleted3a { const int a; }; // expected-note {{because field 'a' of const-qualified type 'const int' would not be initialized}} \
                                      expected-warning {{does not declare any constructor}} \
                                      expected-note {{will never be initialized}}
 Deleted3a d3a; // expected-error {{implicitly-deleted default constructor}}
-class Deleted3b { const DefaultedDefCtor1 a[42]; }; // expected-note {{here}}
+class Deleted3b { const DefaultedDefCtor1 a[42]; }; // expected-note {{because field 'a' of const-qualified type 'const DefaultedDefCtor1' would not be initialized}}
 Deleted3b d3b; // expected-error {{implicitly-deleted default constructor}}
-class Deleted3c { const DefaultedDefCtor2 a; }; // expected-note {{defined here}}
+class Deleted3c { const DefaultedDefCtor2 a; }; // expected-note {{because field 'a' of const-qualified type 'const DefaultedDefCtor2' would not be initialized}}
 Deleted3c d3c; // expected-error {{implicitly-deleted default constructor}}
 class NotDeleted3a { const int a = 0; };
 NotDeleted3a nd3a;
@@ -74,14 +74,21 @@
 
 // - X is a union and all of its variant members are of const-qualified type (or
 // array thereof),
-union Deleted4a { const int a; const int b; const UserProvidedDefCtor c; }; // expected-note {{here}}
+union Deleted4a {
+  const int a;
+  const int b;
+  const UserProvidedDefCtor c; // expected-note {{because field 'c' has a non-trivial default constructor}}
+};
 Deleted4a d4a; // expected-error {{implicitly-deleted default constructor}}
 union NotDeleted4a { const int a; int b; };
 NotDeleted4a nd4a;
 
 // - X is a non-union class and all members of any anonymous union member are of
 // const-qualified type (or array thereof),
-struct Deleted5a { union { const int a; }; union { int b; }; }; // expected-note {{here}}
+struct Deleted5a {
+  union { const int a; }; // expected-note {{because all data members of an anonymous union member are const-qualified}}
+  union { int b; };
+};
 Deleted5a d5a; // expected-error {{implicitly-deleted default constructor}}
 struct NotDeleted5a { union { const int a; int b; }; union { const int c; int d; }; };
 NotDeleted5a nd5a;
@@ -91,17 +98,17 @@
 // M has no default constructor or overload resolution as applied to M's default
 // constructor results in an ambiguity or in a function that is deleted or
 // inaccessible from the defaulted default constructor, or
-struct Deleted6a : Deleted2a {}; // expected-note {{here}}
+struct Deleted6a : Deleted2a {}; // expected-note {{because base class 'Deleted2a' has a deleted default constructor}}
 Deleted6a d6a; // expected-error {{implicitly-deleted default constructor}}
-struct Deleted6b : virtual Deleted2a {}; // expected-note {{here}}
+struct Deleted6b : virtual Deleted2a {}; // expected-note {{because base class 'Deleted2a' has a deleted default constructor}}
 Deleted6b d6b; // expected-error {{implicitly-deleted default constructor}}
-struct Deleted6c { Deleted2a a; }; // expected-note {{here}}
+struct Deleted6c { Deleted2a a; }; // expected-note {{because field 'a' has a deleted default constructor}}
 Deleted6c d6c; // expected-error {{implicitly-deleted default constructor}}
-struct Deleted6d { DeletedDefCtor a; }; // expected-note {{here}}
+struct Deleted6d { DeletedDefCtor a; }; // expected-note {{because field 'a' has a deleted default constructor}}
 Deleted6d d6d; // expected-error {{implicitly-deleted default constructor}}
 struct NotDeleted6a { DeletedDefCtor a = 0; };
 NotDeleted6a nd6a;
-struct Deleted6e { PrivateDefCtor a; }; // expected-note {{here}}
+struct Deleted6e { PrivateDefCtor a; }; // expected-note {{because field 'a' has an inaccessible default constructor}}
 Deleted6e d6e; // expected-error {{implicitly-deleted default constructor}}
 struct NotDeleted6b { PrivateDefCtor a = 0; };
 NotDeleted6b nd6b;
@@ -111,21 +118,21 @@
 // - any direct or virtual base class or non-static data member has a type with
 // a destructor that is deleted or inaccessible from the defaulted default
 // constructor.
-struct Deleted7a : DeletedDtor {}; // expected-note {{here}}
+struct Deleted7a : DeletedDtor {}; // expected-note {{because base class 'DeletedDtor' has a deleted destructor}}
 Deleted7a d7a; // expected-error {{implicitly-deleted default constructor}}
-struct Deleted7b : virtual DeletedDtor {}; // expected-note {{here}}
+struct Deleted7b : virtual DeletedDtor {}; // expected-note {{because base class 'DeletedDtor' has a deleted destructor}}
 Deleted7b d7b; // expected-error {{implicitly-deleted default constructor}}
-struct Deleted7c { DeletedDtor a; }; // expected-note {{here}}
+struct Deleted7c { DeletedDtor a; }; // expected-note {{because field 'a' has a deleted destructor}}
 Deleted7c d7c; // expected-error {{implicitly-deleted default constructor}}
-struct Deleted7d { DeletedDtor a = {}; }; // expected-note {{here}}
+struct Deleted7d { DeletedDtor a = {}; }; // expected-note {{because field 'a' has a deleted destructor}}
 Deleted7d d7d; // expected-error {{implicitly-deleted default constructor}}
-struct Deleted7e : PrivateDtor {}; // expected-note {{here}}
+struct Deleted7e : PrivateDtor {}; // expected-note {{base class 'PrivateDtor' has an inaccessible destructor}}
 Deleted7e d7e; // expected-error {{implicitly-deleted default constructor}}
-struct Deleted7f : virtual PrivateDtor {}; // expected-note {{here}}
+struct Deleted7f : virtual PrivateDtor {}; // expected-note {{base class 'PrivateDtor' has an inaccessible destructor}}
 Deleted7f d7f; // expected-error {{implicitly-deleted default constructor}}
-struct Deleted7g { PrivateDtor a; }; // expected-note {{here}}
+struct Deleted7g { PrivateDtor a; }; // expected-note {{field 'a' has an inaccessible destructor}}
 Deleted7g d7g; // expected-error {{implicitly-deleted default constructor}}
-struct Deleted7h { PrivateDtor a = {}; }; // expected-note {{here}}
+struct Deleted7h { PrivateDtor a = {}; }; // expected-note {{field 'a' has an inaccessible destructor}}
 Deleted7h d7h; // expected-error {{implicitly-deleted default constructor}}
 struct NotDeleted7i : Friend {};
 NotDeleted7i d7i;

Modified: cfe/branches/tooling/test/CXX/special/class.dtor/p5-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/special/class.dtor/p5-0x.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/special/class.dtor/p5-0x.cpp (original)
+++ cfe/branches/tooling/test/CXX/special/class.dtor/p5-0x.cpp Tue Apr  3 07:29:12 2012
@@ -4,7 +4,7 @@
   ~NonTrivDtor();
 };
 struct DeletedDtor {
-  ~DeletedDtor() = delete;
+  ~DeletedDtor() = delete; // expected-note 5 {{deleted here}}
 };
 class InaccessibleDtor {
   ~InaccessibleDtor() = default;
@@ -14,73 +14,74 @@
 
 // -- X is a union-like class that has a variant member with a non-trivial
 // destructor.
-union A1 { // expected-note {{here}}
+union A1 {
   A1();
-  NonTrivDtor n;
+  NonTrivDtor n; // expected-note {{destructor of union 'A1' is implicitly deleted because field 'n' has a non-trivial destructor}}
 };
 A1 a1; // expected-error {{deleted function}}
-struct A2 { // expected-note {{here}}
+struct A2 {
   A2();
   union {
-    NonTrivDtor n;
+    NonTrivDtor n; // expected-note {{because field 'n' has a non-trivial destructor}}
   };
 };
 A2 a2; // expected-error {{deleted function}}
-union A3 { // expected-note {{here}}
+union A3 {
   A3();
-  NonTrivDtor n[3];
+  NonTrivDtor n[3]; // expected-note {{because field 'n' has a non-trivial destructor}}
 };
 A3 a3; // expected-error {{deleted function}}
-struct A4 { // expected-note {{here}}
+struct A4 {
   A4();
   union {
-    NonTrivDtor n[3];
+    NonTrivDtor n[3]; // expected-note {{because field 'n' has a non-trivial destructor}}
   };
 };
 A4 a4; // expected-error {{deleted function}}
 
 // -- any of the non-static data members has class type M (or array thereof) and
 // M has a deleted or inaccessible destructor.
-struct B1 { // expected-note {{here}}
+struct B1 {
   B1();
-  DeletedDtor a;
+  DeletedDtor a; // expected-note {{because field 'a' has a deleted destructor}}
 };
 B1 b1; // expected-error {{deleted function}}
-struct B2 { // expected-note {{here}}
+struct B2 {
   B2();
-  InaccessibleDtor a;
+  InaccessibleDtor a; // expected-note {{because field 'a' has an inaccessible destructor}}
 };
 B2 b2; // expected-error {{deleted function}}
-struct B3 { // expected-note {{here}}
+struct B3 {
   B3();
-  DeletedDtor a[4];
+  DeletedDtor a[4]; // expected-note {{because field 'a' has a deleted destructor}}
 };
 B3 b3; // expected-error {{deleted function}}
-struct B4 { // expected-note {{here}}
+struct B4 {
   B4();
-  InaccessibleDtor a[4];
+  InaccessibleDtor a[4]; // expected-note {{because field 'a' has an inaccessible destructor}}
 };
 B4 b4; // expected-error {{deleted function}}
-union B5 { // expected-note {{here}}
+union B5 {
   B5();
-  union {
-    DeletedDtor a;
+  // FIXME: Describe the anonymous union member better than ''.
+  union { // expected-note {{because field '' has a deleted destructor}}
+    DeletedDtor a; // expected-note {{because field 'a' has a deleted destructor}}
   };
 };
 B5 b5; // expected-error {{deleted function}}
-union B6 { // expected-note {{here}}
+union B6 {
   B6();
-  union {
-    InaccessibleDtor a;
+  union { // expected-note {{because field '' has a deleted destructor}}
+    InaccessibleDtor a; // expected-note {{because field 'a' has an inaccessible destructor}}
   };
 };
 B6 b6; // expected-error {{deleted function}}
 
 // -- any direct or virtual base class has a deleted or inaccessible destructor.
-struct C1 : DeletedDtor { C1(); } c1; // expected-error {{deleted function}} expected-note {{here}}
-struct C2 : InaccessibleDtor { C2(); } c2; // expected-error {{deleted function}} expected-note {{here}}
-struct C3 : virtual DeletedDtor { C3(); } c3; // expected-error {{deleted function}} expected-note {{here}}
-struct C4 : virtual InaccessibleDtor { C4(); } c4; // expected-error {{deleted function}} expected-note {{here}}
+struct C1 : DeletedDtor { C1(); } c1; // expected-error {{deleted function}} expected-note {{base class 'DeletedDtor' has a deleted destructor}}
+struct C2 : InaccessibleDtor { C2(); } c2; // expected-error {{deleted function}} expected-note {{base class 'InaccessibleDtor' has an inaccessible destructor}}
+struct C3 : virtual DeletedDtor { C3(); } c3; // expected-error {{deleted function}} expected-note {{base class 'DeletedDtor' has a deleted destructor}}
+struct C4 : virtual InaccessibleDtor { C4(); } c4; // expected-error {{deleted function}} expected-note {{base class 'InaccessibleDtor' has an inaccessible destructor}}
 
 // -- for a virtual destructor, lookup of the non-array deallocation function
 // results in an ambiguity or a function that is deleted or inaccessible.
@@ -89,15 +90,15 @@
 public:
   virtual ~D1() = default;
 } d1; // ok
-struct D2 : D1 { // expected-note {{deleted here}}
+struct D2 : D1 { // expected-note {{virtual destructor requires an unambiguous, accessible 'operator delete'}}
   // implicitly-virtual destructor
 } d2; // expected-error {{deleted function}}
-struct D3 {
-  virtual ~D3() = default; // expected-note {{deleted here}}
+struct D3 { // expected-note {{virtual destructor requires an unambiguous, accessible 'operator delete'}}
+  virtual ~D3() = default; // expected-note {{explicitly defaulted function was implicitly deleted here}}
   void operator delete(void*, double = 0.0);
   void operator delete(void*, char = 0);
 } d3; // expected-error {{deleted function}}
-struct D4 {
-  virtual ~D4() = default; // expected-note {{deleted here}}
+struct D4 { // expected-note {{virtual destructor requires an unambiguous, accessible 'operator delete'}}
+  virtual ~D4() = default; // expected-note {{implicitly deleted here}}
   void operator delete(void*) = delete;
 } d4; // expected-error {{deleted function}}

Modified: cfe/branches/tooling/test/CXX/special/class.inhctor/elsewhere.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/special/class.inhctor/elsewhere.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/special/class.inhctor/elsewhere.cpp (original)
+++ cfe/branches/tooling/test/CXX/special/class.inhctor/elsewhere.cpp Tue Apr  3 07:29:12 2012
@@ -29,3 +29,29 @@
 struct D1 : I1 {
   using B1::B1; // expected-error {{'B1' is not a direct base of 'D1', can not inherit constructors}}
 };
+
+template<typename T> struct A {};
+
+template<typename T> struct B : A<bool>, A<char> {
+  using A<T>::A; // expected-error {{'A<double>::', which is not a base class of 'B<double>'}}
+};
+B<bool> bb;
+B<char> bc;
+B<double> bd; // expected-note {{here}}
+
+template<typename T> struct C : A<T> {
+  using A<bool>::A; // expected-error {{'A<bool>::', which is not a base class of 'C<char>'}}
+};
+C<bool> cb;
+C<char> cc; // expected-note {{here}}
+
+template<typename T> struct D : A<T> {};
+template<typename T> struct E : D<T> {
+  using A<bool>::A; // expected-error {{'A<bool>' is not a direct base of 'E<bool>', can not inherit}}
+};
+E<bool> eb; // expected-note {{here}}
+
+template<typename T> struct F : D<bool> {
+  using A<T>::A; // expected-error {{'A<bool>' is not a direct base of 'F<bool>'}}
+};
+F<bool> fb; // expected-note {{here}}

Modified: cfe/branches/tooling/test/CXX/special/class.inhctor/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/special/class.inhctor/p3.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/special/class.inhctor/p3.cpp (original)
+++ cfe/branches/tooling/test/CXX/special/class.inhctor/p3.cpp Tue Apr  3 07:29:12 2012
@@ -28,3 +28,21 @@
   using B3::B3; // expected-note {{candidate constructor (inherited)}}
 };
 D3 fd3() { return 1; } // expected-error {{no viable conversion}}
+
+template<typename T> struct T1 : B1 {
+  using B1::B1;
+};
+template<typename T> struct T2 : T1<T> {
+  using T1<int>::T1;
+};
+template<typename T> struct T3 : T1<int> {
+  using T1<T>::T1;
+};
+struct U {
+  friend T1<int>::T1(int);
+  friend T1<int>::T1(int, int);
+  friend T2<int>::T2(int);
+  friend T2<int>::T2(int, int);
+  friend T3<int>::T3(int);
+  friend T3<int>::T3(int, int);
+};

Modified: cfe/branches/tooling/test/CXX/special/class.inhctor/p7.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/special/class.inhctor/p7.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/special/class.inhctor/p7.cpp (original)
+++ cfe/branches/tooling/test/CXX/special/class.inhctor/p7.cpp Tue Apr  3 07:29:12 2012
@@ -2,7 +2,7 @@
 
 // Straight from the standard
 struct B1 {
-  B1(int); // expected-note {{previous constructor}}
+  B1(int); // expected-note {{previous constructor}} expected-note {{conflicting constructor}}
 };
 struct B2 {
   B2(int); // expected-note {{conflicting constructor}}
@@ -16,3 +16,14 @@
   using B2::B2;
   D2(int);
 };
+
+template<typename T> struct B3 {
+  B3(T); // expected-note {{previous constructor}}
+};
+template<typename T> struct B4 : B3<T>, B1 {
+  B4();
+  using B3<T>::B3; // expected-note {{inherited here}}
+  using B1::B1; // expected-error {{already inherited}}
+};
+B4<char> b4c;
+B4<int> b4i; // expected-note {{here}}

Modified: cfe/branches/tooling/test/CodeGen/atomic-ops.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGen/atomic-ops.c?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGen/atomic-ops.c (original)
+++ cfe/branches/tooling/test/CodeGen/atomic-ops.c Tue Apr  3 07:29:12 2012
@@ -81,3 +81,39 @@
   // CHECK: ret i32 1
   return __atomic_is_lock_free(sizeof(_Atomic(int)));
 }
+
+// Tests for atomic operations on big values.  These should call the functions
+// defined here:
+// http://gcc.gnu.org/wiki/Atomic/GCCMM/LIbrary#The_Library_interface
+
+struct foo {
+  int big[128];
+};
+
+_Atomic(struct foo) bigAtomic;
+
+void structAtomicStore() {
+  // CHECK: @structAtomicStore
+  struct foo f = {0};
+  __atomic_store(&bigAtomic, f, 5);
+  // CHECK: call void @__atomic_store(i32 512, i8* bitcast (%struct.foo* @bigAtomic to i8*), 
+}
+void structAtomicLoad() {
+  // CHECK: @structAtomicLoad
+  struct foo f = __atomic_load(&bigAtomic, 5);
+  // CHECK: call void @__atomic_load(i32 512, i8* bitcast (%struct.foo* @bigAtomic to i8*), 
+}
+struct foo structAtomicExchange() {
+  // CHECK: @structAtomicExchange
+  struct foo f = {0};
+  return __atomic_exchange(&bigAtomic, f, 5);
+  // CHECK: call void @__atomic_exchange(i32 512, i8* bitcast (%struct.foo* @bigAtomic to i8*), 
+}
+int structAtomicCmpExchange() {
+  // CHECK: @structAtomicCmpExchange
+  struct foo f = {0};
+  struct foo g = {0};
+  g.big[12] = 12;
+  return __atomic_compare_exchange_strong(&bigAtomic, &f, g, 5, 5);
+  // CHECK: call zeroext i1 @__atomic_compare_exchange(i32 512, i8* bitcast (%struct.foo* @bigAtomic to i8*), 
+}

Modified: cfe/branches/tooling/test/CodeGen/avx-shuffle-builtins.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGen/avx-shuffle-builtins.c?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGen/avx-shuffle-builtins.c (original)
+++ cfe/branches/tooling/test/CodeGen/avx-shuffle-builtins.c Tue Apr  3 07:29:12 2012
@@ -33,6 +33,13 @@
   return _mm_permute_ps(a, 0x1b);
 }
 
+// Test case for PR12401
+__m128 test_mm_permute_ps2(__m128 a) {
+  // Check if the mask is correct
+  // CHECK: shufflevector{{.*}}<i32 2, i32 1, i32 2, i32 3>
+  return _mm_permute_ps(a, 0xe6);
+}
+
 __m256 test_mm256_permute_ps(__m256 a) {
   // Check if the mask is correct
   // CHECK: shufflevector{{.*}}<i32 3, i32 2, i32 1, i32 0, i32 7, i32 6, i32 5, i32 4>

Modified: cfe/branches/tooling/test/CodeGen/darwin-string-literals.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGen/darwin-string-literals.c?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGen/darwin-string-literals.c (original)
+++ cfe/branches/tooling/test/CodeGen/darwin-string-literals.c Tue Apr  3 07:29:12 2012
@@ -2,13 +2,16 @@
 
 // CHECK-LSB: @.str = private unnamed_addr constant [8 x i8] c"string0\00"
 // CHECK-LSB: @.str1 = linker_private unnamed_addr constant [8 x i8] c"string1\00"
-// CHECK-LSB: @.str2 = internal unnamed_addr constant [36 x i8] c"h\00e\00l\00l\00o\00 \00\92! \00\03& \00\90! \00w\00o\00r\00l\00d\00\00\00", align 2
+// CHECK-LSB: @.str2 = internal unnamed_addr constant [18 x i16] [i16 104, i16 101, i16 108, i16 108, i16 111, i16 32, i16 8594, i16 32, i16 9731, i16 32, i16 8592, i16 32, i16 119, i16 111, i16 114, i16 108, i16 100, i16 0], align 2
+// CHECK-LSB: @.str4 = internal unnamed_addr constant [6 x i16] [i16 116, i16 101, i16 115, i16 116, i16 8482, i16 0], align 2
+
 
 // RUN: %clang_cc1 -triple powerpc-apple-darwin9 -emit-llvm %s -o - | FileCheck -check-prefix MSB %s
 
 // CHECK-MSB: @.str = private unnamed_addr constant [8 x i8] c"string0\00"
 // CHECK-MSB: @.str1 = linker_private unnamed_addr constant [8 x i8] c"string1\00"
-// CHECK-MSB: @.str2 = internal unnamed_addr constant [36 x i8] c"\00h\00e\00l\00l\00o\00 !\92\00 &\03\00 !\90\00 \00w\00o\00r\00l\00d\00\00", align 2
+// CHECK-MSB: @.str2 = internal unnamed_addr constant [18 x i16] [i16 104, i16 101, i16 108, i16 108, i16 111, i16 32, i16 8594, i16 32, i16 9731, i16 32, i16 8592, i16 32, i16 119, i16 111, i16 114, i16 108, i16 100, i16 0], align 2
+// CHECK-MSB: @.str4 = internal unnamed_addr constant [6 x i16] [i16 116, i16 101, i16 115, i16 116, i16 8482, i16 0], align 2
 
 const char *g0 = "string0";
 const void *g1 = __builtin___CFStringMakeConstantString("string1");

Modified: cfe/branches/tooling/test/CodeGen/sse-builtins.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGen/sse-builtins.c?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGen/sse-builtins.c (original)
+++ cfe/branches/tooling/test/CodeGen/sse-builtins.c Tue Apr  3 07:29:12 2012
@@ -1,6 +1,7 @@
 // RUN: %clang_cc1 -ffreestanding -triple i386-apple-darwin9 -target-cpu pentium4 -target-feature +sse4.1 -g -emit-llvm %s -o - | FileCheck %s
 
 #include <emmintrin.h>
+#include <smmintrin.h>
 
 __m128 test_loadl_pi(__m128 x, void* y) {
   // CHECK: define {{.*}} @test_loadl_pi
@@ -102,3 +103,51 @@
   // CHECK: load i64* {{.*}}, align 1{{$}}
   return _mm_loadl_epi64(y);
 }
+
+__m128i test_mm_minpos_epu16(__m128i x) {
+  // CHECK: define {{.*}} @test_mm_minpos_epu16
+  // CHECK: @llvm.x86.sse41.phminposuw
+  return _mm_minpos_epu16(x);
+}
+
+__m128i test_mm_mpsadbw_epu8(__m128i x, __m128i y) {
+  // CHECK: define {{.*}} @test_mm_mpsadbw_epu8
+  // CHECK: @llvm.x86.sse41.mpsadbw
+  return _mm_mpsadbw_epu8(x, y, 1);
+}
+
+__m128 test_mm_dp_ps(__m128 x, __m128 y) {
+  // CHECK: define {{.*}} @test_mm_dp_ps
+  // CHECK: @llvm.x86.sse41.dpps
+  return _mm_dp_ps(x, y, 2);
+}
+
+__m128d test_mm_dp_pd(__m128d x, __m128d y) {
+  // CHECK: define {{.*}} @test_mm_dp_pd
+  // CHECK: @llvm.x86.sse41.dppd
+  return _mm_dp_pd(x, y, 2);
+}
+
+__m128 test_mm_round_ps(__m128 x) {
+  // CHECK: define {{.*}} @test_mm_round_ps
+  // CHECK: @llvm.x86.sse41.round.ps
+  return _mm_round_ps(x, 2);
+}
+
+__m128 test_mm_round_ss(__m128 x, __m128 y) {
+  // CHECK: define {{.*}} @test_mm_round_ss
+  // CHECK: @llvm.x86.sse41.round.ss
+  return _mm_round_ss(x, y, 2);
+}
+
+__m128d test_mm_round_pd(__m128d x) {
+  // CHECK: define {{.*}} @test_mm_round_pd
+  // CHECK: @llvm.x86.sse41.round.pd
+  return _mm_round_pd(x, 2);
+}
+
+__m128d test_mm_round_sd(__m128d x, __m128d y) {
+  // CHECK: define {{.*}} @test_mm_round_sd
+  // CHECK: @llvm.x86.sse41.round.sd
+  return _mm_round_sd(x, y, 2);
+}

Modified: cfe/branches/tooling/test/CodeGenCXX/assign-operator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenCXX/assign-operator.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenCXX/assign-operator.cpp (original)
+++ cfe/branches/tooling/test/CodeGenCXX/assign-operator.cpp Tue Apr  3 07:29:12 2012
@@ -28,24 +28,3 @@
 
   A<int> a;
 }
-
-// PR12204
-namespace test2 {
-  struct A {
-    A() {} // make this non-POD to enable tail layout
-    void *ptr;
-    char c;
-  };
-
-  void test(A &out) {
-    out = A();
-  }
-}
-// CHECK:    define void @_ZN5test24testERNS_1AE(
-// CHECK:      [[OUT:%.*]] = alloca [[A:%.*]]*, align 8
-// CHECK-NEXT: [[TMP:%.*]] = alloca [[A]], align 8
-// CHECK:      [[REF:%.*]] = load [[A]]** [[OUT]], align 8
-// CHECK-NEXT: call void @_ZN5test21AC1Ev([[A]]* [[TMP]])
-// CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[REF]] to i8*
-// CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[TMP]] to i8*
-// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[T0]], i8* [[T1]], i64 9, i32 8, i1 false)

Modified: cfe/branches/tooling/test/CodeGenCXX/const-init-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenCXX/const-init-cxx11.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenCXX/const-init-cxx11.cpp (original)
+++ cfe/branches/tooling/test/CodeGenCXX/const-init-cxx11.cpp Tue Apr  3 07:29:12 2012
@@ -78,6 +78,11 @@
   struct Test2 : X<E,0>, X<E,1>, X<E,2>, X<E,3> {};
   // CHECK: @_ZN9BaseClass2t2E = constant {{.*}} undef
   extern constexpr Test2 t2 = Test2();
+
+  struct __attribute((packed)) PackedD { double y = 2; };
+  struct Test3 : C, PackedD { constexpr Test3() {} };
+  // CHECK: @_ZN9BaseClass2t3E = constant <{ i8, double }> <{ i8 1, double 2.000000e+00 }>
+  extern constexpr Test3 t3 = Test3();
 }
 
 namespace Array {

Modified: cfe/branches/tooling/test/CodeGenCXX/debug-info-artificial-arg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenCXX/debug-info-artificial-arg.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenCXX/debug-info-artificial-arg.cpp (original)
+++ cfe/branches/tooling/test/CodeGenCXX/debug-info-artificial-arg.cpp Tue Apr  3 07:29:12 2012
@@ -25,6 +25,6 @@
 // FIXME: The numbers are truly awful.
 // CHECK: !18 = metadata !{i32 {{.*}}, i32 0, metadata !"", i32 0, i32 0, i64 64, i64 64, i64 0, i32 64, metadata !19} ; [ DW_TAG_pointer_type ]
 // CHECK: !19 = metadata !{i32 {{.*}}, null, metadata !"A", metadata !6, i32 8, i64 128, i64 64, i32 0, i32 0, null, metadata !20, i32 0, metadata !19, null} ; [ DW_TAG_class_type ]
-// CHECK: metadata !19, metadata !"A", metadata !"A", metadata !"", metadata !6, i32 12, metadata !45, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null, i32 0, metadata !47} ; [ DW_TAG_subprogram ]
+// CHECK: metadata !19, metadata !"A", metadata !"A", metadata !"", metadata !6, i32 12, metadata !45, i1 false, i1 false, i32 0, i32 0, null, i32 256, i1 false, null, null, i32 0, metadata !47, i32 12} ; [ DW_TAG_subprogram ]
 // CHECK: metadata !"", i32 0, i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !46, i32 0, i32 0} ; [ DW_TAG_subroutine_type ]
 // CHECK: !46 = metadata !{null, metadata !18, metadata !9, metadata !34}

Modified: cfe/branches/tooling/test/CodeGenCXX/static-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenCXX/static-init.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenCXX/static-init.cpp (original)
+++ cfe/branches/tooling/test/CodeGenCXX/static-init.cpp Tue Apr  3 07:29:12 2012
@@ -3,6 +3,7 @@
 // CHECK: @_ZZ1hvE1i = internal global i32 0, align 4
 // CHECK: @base_req = global [4 x i8] c"foo\00", align 1
 
+// CHECK: @_ZZN5test31BC1EvE1u = internal global { i8, [3 x i8] } { i8 97, [3 x i8] undef }, align 4
 // CHECK: @_ZZN5test1L6getvarEiE3var = internal constant [4 x i32] [i32 1, i32 0, i32 2, i32 4], align 16
 // CHECK: @_ZZ2h2vE1i = linkonce_odr global i32 0
 // CHECK: @_ZGVZ2h2vE1i = linkonce_odr global i64 0
@@ -79,3 +80,73 @@
     c::main();
   }
 }
+
+// rdar://problem/11091093
+//   Static variables should be consistent across constructor
+//   or destructor variants.
+namespace test2 {
+  struct A {
+    A();
+    ~A();
+  };
+
+  struct B : virtual A {
+    B();
+    ~B();
+  };
+
+  // If we ever implement this as a delegate ctor call, just change
+  // this to take variadic arguments or something.
+  extern int foo();
+  B::B() {
+    static int x = foo();
+  }
+  // CHECK: define void @_ZN5test21BC1Ev
+  // CHECK:   load atomic i8* bitcast (i64* @_ZGVZN5test21BC1EvE1x to i8*) acquire,
+  // CHECK:   call i32 @__cxa_guard_acquire(i64* @_ZGVZN5test21BC1EvE1x)
+  // CHECK:   [[T0:%.*]] = call i32 @_ZN5test23fooEv()
+  // CHECK:   store i32 [[T0]], i32* @_ZZN5test21BC1EvE1x,
+  // CHECK:   call void @__cxa_guard_release(i64* @_ZGVZN5test21BC1EvE1x)
+
+  // CHECK: define void @_ZN5test21BC2Ev
+  // CHECK:   load atomic i8* bitcast (i64* @_ZGVZN5test21BC1EvE1x to i8*) acquire,
+  // CHECK:   call i32 @__cxa_guard_acquire(i64* @_ZGVZN5test21BC1EvE1x)
+  // CHECK:   [[T0:%.*]] = call i32 @_ZN5test23fooEv()
+  // CHECK:   store i32 [[T0]], i32* @_ZZN5test21BC1EvE1x,
+  // CHECK:   call void @__cxa_guard_release(i64* @_ZGVZN5test21BC1EvE1x)
+
+  // This is just for completeness, because we actually emit this
+  // using a delegate dtor call.
+  B::~B() {
+    static int y = foo();
+  }
+  // CHECK: define void @_ZN5test21BD1Ev(
+  // CHECK:   call void @_ZN5test21BD2Ev(
+
+  // CHECK: define void @_ZN5test21BD2Ev(
+  // CHECK:   load atomic i8* bitcast (i64* @_ZGVZN5test21BD1EvE1y to i8*) acquire,
+  // CHECK:   call i32 @__cxa_guard_acquire(i64* @_ZGVZN5test21BD1EvE1y)
+  // CHECK:   [[T0:%.*]] = call i32 @_ZN5test23fooEv()
+  // CHECK:   store i32 [[T0]], i32* @_ZZN5test21BD1EvE1y,
+  // CHECK:   call void @__cxa_guard_release(i64* @_ZGVZN5test21BD1EvE1y)
+}
+
+// This shouldn't error out.
+namespace test3 {
+  struct A {
+    A();
+    ~A();
+  };
+
+  struct B : virtual A {
+    B();
+    ~B();
+  };
+
+  B::B() {
+    union U { char x; int i; };
+    static U u = { 'a' };
+  }
+  // CHECK: define void @_ZN5test31BC1Ev(
+  // CHECK: define void @_ZN5test31BC2Ev(
+}

Modified: cfe/branches/tooling/test/CodeGenObjC/2009-08-05-utf16.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenObjC/2009-08-05-utf16.m?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenObjC/2009-08-05-utf16.m (original)
+++ cfe/branches/tooling/test/CodeGenObjC/2009-08-05-utf16.m Tue Apr  3 07:29:12 2012
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -emit-llvm -w -x objective-c %s -o - | FileCheck %s
 // rdar://7095855 rdar://7115749
 
-// CHECK: internal unnamed_addr constant [12 x i8]
+// CHECK: internal unnamed_addr constant [6 x i16] [i16 105, i16 80, i16 111, i16 100, i16 8482, i16 0], align 2
 void *P = @"iPod™";

Modified: cfe/branches/tooling/test/CodeGenObjC/arc.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenObjC/arc.m?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenObjC/arc.m (original)
+++ cfe/branches/tooling/test/CodeGenObjC/arc.m Tue Apr  3 07:29:12 2012
@@ -640,9 +640,7 @@
 // CHECK-NEXT: store i8* {{%.*}}, i8** [[CMD]]
 // CHECK-NEXT: [[T0:%.*]] = load [[TEST27]]** [[SELF]]
 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST27]]* [[T0]] to i8*
-// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]])
-// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]]
-// CHECK-NEXT: [[RET:%.*]] = bitcast
+// CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[T1]])
 // CHECK-NEXT: store i32 {{[0-9]+}}, i32* [[DEST]]
 // CHECK-NEXT: [[T0:%.*]] = load [[TEST27]]** [[SELF]]
 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST27]]* [[T0]] to i8*
@@ -706,9 +704,7 @@
 // Return statement.
 // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[CALL]]
 // CHECK-NEXT: [[CALL:%.*]] = bitcast
-// CHECK-NEXT: [[T1:%.*]] = call i8* @objc_retain(i8* [[CALL]]) nounwind
-// CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]]
-// CHECK-NEXT: [[RET:%.*]] = bitcast
+// CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[CALL]]) nounwind
 // CHECK-NEXT: store i32 1, i32* [[CLEANUP]]
 
 // Cleanup.
@@ -762,9 +758,7 @@
 // Return statement.
 // CHECK-NEXT: [[T0:%.*]] = load [[TEST29]]** [[SELF]]
 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST29]]* [[T0]] to i8*
-// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]]) nounwind
-// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]]
-// CHECK-NEXT: [[RET:%.*]] = bitcast
+// CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[T1]]) nounwind
 // CHECK-NEXT: store i32 1, i32* [[CLEANUP]]
 
 // Cleanup.
@@ -819,9 +813,7 @@
 // Return.
 // CHECK-NEXT: [[T0:%.*]] = load [[TEST30]]** [[SELF]]
 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST30]]* [[T0]] to i8*
-// CHECK-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]])
-// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]]
-// CHECK-NEXT: [[RET:%.*]] = bitcast
+// CHECK-NEXT: [[RET:%.*]] = call i8* @objc_retain(i8* [[T1]])
 // CHECK-NEXT: store i32 1
 
 // Cleanup.

Modified: cfe/branches/tooling/test/CodeGenObjC/debug-info-block-helper.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenObjC/debug-info-block-helper.m?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenObjC/debug-info-block-helper.m (original)
+++ cfe/branches/tooling/test/CodeGenObjC/debug-info-block-helper.m Tue Apr  3 07:29:12 2012
@@ -2,7 +2,7 @@
 // RUN: %clang_cc1 -emit-llvm -fblocks -g -triple x86_64-apple-darwin10 -fobjc-fragile-abi %s -o - | FileCheck %s
 extern void foo(void(^)(void));
 
-// CHECK: !40 = metadata !{i32 {{.*}}, i32 0, metadata !10, metadata !"__destroy_helper_block_", metadata !"__destroy_helper_block_", metadata !"", metadata !10, i32 24, metadata !41, i1 true, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (i8*)* @__destroy_helper_block_, null, null, metadata !43} ; [ DW_TAG_subprogram ]
+// CHECK: !40 = metadata !{i32 {{.*}}, i32 0, metadata !25, metadata !"__destroy_helper_block_", metadata !"__destroy_helper_block_", metadata !"", metadata !25, i32 24, metadata !41, i1 true, i1 true, i32 0, i32 0, null, i32 256, i1 false, void (i8*)* @__destroy_helper_block_, null, null, metadata !43, i32 24} ; [ DW_TAG_subprogram ]
 
 @interface NSObject {
   struct objc_object *isa;

Modified: cfe/branches/tooling/test/CodeGenObjC/debug-info-property3.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenObjC/debug-info-property3.m?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenObjC/debug-info-property3.m (original)
+++ cfe/branches/tooling/test/CodeGenObjC/debug-info-property3.m Tue Apr  3 07:29:12 2012
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -S -emit-llvm -g %s -o - | FileCheck %s
 
-// CHECK: metadata !"p1", metadata !6, i32 5, metadata !"-[I1 p1]", metadata !"-[I1 setP1:]", i32 2316, metadata !9} ; [ DW_TAG_APPLE_property ]
+// CHECK: metadata !"p1", metadata !6, i32 5, metadata !"p1", metadata !"setP1:", i32 2316, metadata !9} ; [ DW_TAG_APPLE_property ]
 @interface I1
 @property int p1;
 @end

Modified: cfe/branches/tooling/test/CodeGenObjC/debug-property-synth.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenObjC/debug-property-synth.m?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenObjC/debug-property-synth.m (original)
+++ cfe/branches/tooling/test/CodeGenObjC/debug-property-synth.m Tue Apr  3 07:29:12 2012
@@ -16,4 +16,5 @@
   return 0;
 }
 
-// CHECK:       .loc    2 10 0
+// FIXME: Make this test ir files.
+// CHECK:       .loc    2 6 0

Modified: cfe/branches/tooling/test/Driver/rewrite-objc.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Driver/rewrite-objc.m?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/Driver/rewrite-objc.m (original)
+++ cfe/branches/tooling/test/Driver/rewrite-objc.m Tue Apr  3 07:29:12 2012
@@ -3,7 +3,7 @@
 // TEST0: clang{{.*}}" "-cc1"
 // TEST0: "-rewrite-objc"
 // FIXME: CHECK-NOT is broken somehow, it doesn't work here. Check adjacency instead.
-// TEST0: "-fmessage-length" "0" "-stack-protector" "1" "-mstackrealign" "-fblocks" "-fobjc-runtime-has-arc" "-fobjc-runtime-has-weak" "-fobjc-fragile-abi" "-fobjc-default-synthesize-properties" "-fno-objc-infer-related-result-type" "-fobjc-exceptions" "-fexceptions" "-fdiagnostics-show-option"
+// TEST0: "-fmessage-length" "0" "-stack-protector" "1" "-mstackrealign" "-fblocks" "-fobjc-runtime-has-arc" "-fobjc-runtime-has-weak" "-fobjc-dispatch-method=mixed" "-fobjc-default-synthesize-properties" "-fobjc-exceptions" "-fexceptions" "-fdiagnostics-show-option"
 // TEST0: rewrite-objc.m"
 
 // RUN: not %clang -ccc-no-clang -target unknown -rewrite-objc %s -o - -### 2>&1 | \

Modified: cfe/branches/tooling/test/FixIt/fixit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/FixIt/fixit.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/FixIt/fixit.cpp (original)
+++ cfe/branches/tooling/test/FixIt/fixit.cpp Tue Apr  3 07:29:12 2012
@@ -199,3 +199,8 @@
   expected-error {{missing 'typename' prior to dependent}}
   return Mystery<T>::get();
 }
+
+template<template<typename> Foo, // expected-error {{expected 'class' before 'Foo'}}
+         template<typename> typename Bar, // expected-error {{expected 'class' instead of 'typename'}}
+         template<typename> struct Baz> // expected-error {{expected 'class' instead of 'struct'}}
+void func();

Modified: cfe/branches/tooling/test/Index/get-cursor.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Index/get-cursor.m?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/Index/get-cursor.m (original)
+++ cfe/branches/tooling/test/Index/get-cursor.m Tue Apr  3 07:29:12 2012
@@ -31,13 +31,35 @@
 
 @implementation rdar10902015
 
-struct S {};
+struct S { int x; };
 
 -(void)mm:(struct S*)s {
   rdar10902015 *i = 0;
+  s->x = 0;
+  Test1 *test1;
+  test1.name = 0;
 }
 @end
 
+ at interface Test2
+-(int)implicitProp;
+-(void)setImplicitProp:(int)x;
+ at end
+
+void foo1(Test2 *test2) {
+  int x = test2.implicitProp;
+  test2.implicitProp = x;
+  ++test2.implicitProp;
+}
+
+ at interface Test3
+-(void)setFoo:(int)x withBar:(int)y;
+ at end
+
+void foo3(Test3 *test3) {
+  [test3 setFoo:2 withBar:4];
+}
+
 // RUN: c-index-test -cursor-at=%s:4:28 -cursor-at=%s:5:28 %s | FileCheck -check-prefix=CHECK-PROP %s
 // CHECK-PROP: ObjCPropertyDecl=foo1:4:26
 // CHECK-PROP: ObjCPropertyDecl=foo2:5:27
@@ -46,7 +68,20 @@
 // CHECK-WITH-WEAK: ObjCClassRef=Foo:8:8
 
 // RUN: c-index-test -cursor-at=%s:20:10 %s | FileCheck -check-prefix=CHECK-METHOD %s
-// CHECK-METHOD: ObjCInstanceMethodDecl=name:20:7
+// CHECK-METHOD: 20:7 ObjCInstanceMethodDecl=name:20:7 Extent=[20:1 - 20:12]
 
 // RUN: c-index-test -cursor-at=%s:37:17 %s | FileCheck -check-prefix=CHECK-IN-IMPL %s
 // CHECK-IN-IMPL: VarDecl=i:37:17
+
+// RUN: c-index-test -cursor-at=%s:38:6 -cursor-at=%s:40:11 \
+// RUN:   -cursor-at=%s:50:20 -cursor-at=%s:51:15 -cursor-at=%s:52:20 %s | FileCheck -check-prefix=CHECK-MEMBERREF %s
+// CHECK-MEMBERREF: 38:6 MemberRefExpr=x:34:16 SingleRefName=[38:6 - 38:7] RefName=[38:6 - 38:7] Extent=[38:3 - 38:7]
+// CHECK-MEMBERREF: 40:9 MemberRefExpr=name:23:21 Extent=[40:3 - 40:13] Spelling=name ([40:9 - 40:13])
+// CHECK-MEMBERREF: 50:17 MemberRefExpr=implicitProp:45:7 Extent=[50:11 - 50:29] Spelling=implicitProp ([50:17 - 50:29])
+// CHECK-MEMBERREF: 51:9 MemberRefExpr=setImplicitProp::46:8 Extent=[51:3 - 51:21] Spelling=setImplicitProp: ([51:9 - 51:21])
+// CHECK-MEMBERREF: 52:11 MemberRefExpr=setImplicitProp::46:8 Extent=[52:5 - 52:23] Spelling=setImplicitProp: ([52:11 - 52:23])
+
+// RUN: c-index-test -cursor-at=%s:56:24 -cursor-at=%s:60:14 \
+// RUN:   %s | FileCheck -check-prefix=CHECK-SPELLRANGE %s
+// CHECK-SPELLRANGE: 56:8 ObjCInstanceMethodDecl=setFoo:withBar::56:8 Extent=[56:1 - 56:37] Spelling=setFoo:withBar: ([56:8 - 56:14][56:22 - 56:29]) Selector index=1
+// CHECK-SPELLRANGE: 60:3 ObjCMessageExpr=setFoo:withBar::56:8 Extent=[60:3 - 60:29] Spelling=setFoo:withBar: ([60:10 - 60:16][60:19 - 60:26]) Selector index=0

Modified: cfe/branches/tooling/test/Index/index-attrs.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Index/index-attrs.m?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/Index/index-attrs.m (original)
+++ cfe/branches/tooling/test/Index/index-attrs.m Tue Apr  3 07:29:12 2012
@@ -3,5 +3,15 @@
 @property (retain) __attribute__((iboutletcollection(Foo))) Foo *prop;
 @end
 
+ at interface I
+-(id)prop __attribute__((annotate("anno")));
+-(void)setProp:(id)p __attribute__((annotate("anno")));
+ at property (assign) id prop __attribute__((annotate("anno")));
+ at end
+
 // RUN: c-index-test -index-file %s | FileCheck %s
 // CHECK:      <attribute>: attribute(iboutletcollection)= [IBOutletCollection=ObjCInterface]
+
+// CHECK: <attribute>: attribute(annotate)=anno
+// CHECK: <getter>: kind: objc-instance-method | name: prop | {{.*}} <attribute>: attribute(annotate)=anno
+// CHECK: <setter>: kind: objc-instance-method | name: setProp: | {{.*}} <attribute>: attribute(annotate)=anno

Modified: cfe/branches/tooling/test/Parser/cxx-template-decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Parser/cxx-template-decl.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/Parser/cxx-template-decl.cpp (original)
+++ cfe/branches/tooling/test/Parser/cxx-template-decl.cpp Tue Apr  3 07:29:12 2012
@@ -11,10 +11,8 @@
 // expected-warning {{declaration does not declare anything}}
 template <template X> struct Err1; // expected-error {{expected '<' after 'template'}} \
 // expected-error{{extraneous}}
-template <template <typename> > struct Err2;       // expected-error {{expected 'class' before '>'}} \
-// expected-error{{extraneous}}
-template <template <typename> Foo> struct Err3;    // expected-error {{expected 'class' before 'Foo'}} \
-// expected-error{{extraneous}}
+template <template <typename> > struct Err2;       // expected-error {{expected 'class' before '>'}}
+template <template <typename> Foo> struct Err3;    // expected-error {{expected 'class' before 'Foo'}}
 
 // Template function declarations
 template <typename T> void foo();

Modified: cfe/branches/tooling/test/SemaCXX/cxx0x-deleted-default-ctor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/cxx0x-deleted-default-ctor.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/cxx0x-deleted-default-ctor.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/cxx0x-deleted-default-ctor.cpp Tue Apr  3 07:29:12 2012
@@ -7,23 +7,23 @@
   ~non_trivial();
 };
 
-union bad_union { // expected-note {{defined here}}
-  non_trivial nt;
+union bad_union {
+  non_trivial nt; // expected-note {{non-trivial default constructor}}
 };
 bad_union u; // expected-error {{call to implicitly-deleted default constructor}}
-union bad_union2 { // expected-note {{defined here}}
+union bad_union2 { // expected-note {{all data members are const-qualified}}
   const int i;
 };
 bad_union2 u2; // expected-error {{call to implicitly-deleted default constructor}}
 
-struct bad_anon { // expected-note {{defined here}}
+struct bad_anon {
   union {
-    non_trivial nt;
+    non_trivial nt; // expected-note {{non-trivial default constructor}}
   };
 };
 bad_anon a; // expected-error {{call to implicitly-deleted default constructor}}
-struct bad_anon2 { // expected-note {{defined here}}
-  union {
+struct bad_anon2 {
+  union { // expected-note {{all data members of an anonymous union member are const-qualified}}
     const int i;
   };
 };
@@ -48,8 +48,8 @@
 };
 good g;
 
-struct bad_const { // expected-note {{defined here}}
-  const good g;
+struct bad_const {
+  const good g; // expected-note {{field 'g' of const-qualified type 'const good' would not be initialized}}
 };
 bad_const bc; // expected-error {{call to implicitly-deleted default constructor}}
 
@@ -59,25 +59,25 @@
 good_const gc;
 
 struct no_default {
-  no_default() = delete;
+  no_default() = delete; // expected-note 3{{deleted here}}
 };
 struct no_dtor {
-  ~no_dtor() = delete;
+  ~no_dtor() = delete; // expected-note 2{{deleted here}}
 };
 
-struct bad_field_default { // expected-note {{defined here}}
-  no_default nd;
+struct bad_field_default {
+  no_default nd; // expected-note {{field 'nd' has a deleted default constructor}}
 };
 bad_field_default bfd; // expected-error {{call to implicitly-deleted default constructor}}
-struct bad_base_default : no_default { // expected-note {{defined here}}
+struct bad_base_default : no_default { // expected-note {{base class 'no_default' has a deleted default constructor}}
 };
 bad_base_default bbd; // expected-error {{call to implicitly-deleted default constructor}}
 
-struct bad_field_dtor { // expected-note {{defined here}}
-  no_dtor nd;
+struct bad_field_dtor {
+  no_dtor nd; // expected-note {{field 'nd' has a deleted destructor}}
 };
 bad_field_dtor bfx; // expected-error {{call to implicitly-deleted default constructor}}
-struct bad_base_dtor : no_dtor { // expected-note {{defined here}}
+struct bad_base_dtor : no_dtor { // expected-note {{base class 'no_dtor' has a deleted destructor}}
 };
 bad_base_dtor bbx; // expected-error {{call to implicitly-deleted default constructor}}
 
@@ -85,16 +85,16 @@
   ambiguous_default();
   ambiguous_default(int = 2);
 };
-struct has_amb_field { // expected-note {{defined here}}
-  ambiguous_default ad;
+struct has_amb_field {
+  ambiguous_default ad; // expected-note {{field 'ad' has multiple default constructors}}
 };
 has_amb_field haf; // expected-error {{call to implicitly-deleted default constructor}}
 
 class inaccessible_default {
   inaccessible_default();
 };
-struct has_inacc_field { // expected-note {{defined here}}
-  inaccessible_default id;
+struct has_inacc_field {
+  inaccessible_default id; // expected-note {{field 'id' has an inaccessible default constructor}}
 };
 has_inacc_field hif; // expected-error {{call to implicitly-deleted default constructor}}
 
@@ -107,9 +107,9 @@
 };
 has_friend hf;
 
-struct defaulted_delete { // expected-note {{defined here}}
-  no_default nd;
-  defaulted_delete() = default; // expected-note{{declared here}}
+struct defaulted_delete {
+  no_default nd; // expected-note {{because field 'nd' has a deleted default constructor}}
+  defaulted_delete() = default; // expected-note{{implicitly deleted here}}
 };
 defaulted_delete dd; // expected-error {{call to implicitly-deleted default constructor}}
 

Modified: cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-constructor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-constructor.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-constructor.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/cxx0x-initializer-constructor.cpp Tue Apr  3 07:29:12 2012
@@ -38,7 +38,7 @@
 namespace objects {
 
   struct X1 { X1(int); };
-  struct X2 { explicit X2(int); }; // expected-note 2 {{candidate constructor}}
+  struct X2 { explicit X2(int); }; // expected-note {{constructor declared here}}
 
   template <int N>
   struct A {
@@ -94,7 +94,7 @@
     { X1 x{0}; }
     { X1 x = {0}; }
     { X2 x{0}; }
-    { X2 x = {0}; } // expected-error {{no matching constructor}}
+    { X2 x = {0}; } // expected-error {{constructor is explicit}}
   }
 
   struct C {
@@ -153,9 +153,9 @@
     G(std::initializer_list<int>, T ...);  // expected-note 3 {{not viable}}
   };
 
-  struct H { // expected-note 8 {{not viable}}
-    explicit H(int, int); // expected-note 3 {{not viable}}
-    H(int, void*); // expected-note 4 {{not viable}}
+  struct H { // expected-note 6 {{not viable}}
+    explicit H(int, int); // expected-note 3 {{not viable}} expected-note {{declared here}}
+    H(int, void*); // expected-note 3 {{not viable}}
   };
 
   void edge_cases() {
@@ -191,7 +191,7 @@
     H h1{1, nullptr};
     H h2 = {1, nullptr};
     H h3{1, 1};
-    H h4 = {1, 1}; // expected-error {{no matching constructor}}
+    H h4 = {1, 1}; // expected-error {{constructor is explicit}}
   };
 }
 
@@ -259,3 +259,11 @@
   // 4 levels: init list, gen_pair, command_map via init list, command_pair
   const std::initializer_list<generator_pair> y = {{{{1, 2}}}};
 }
+
+namespace PR12120 {
+  struct A { explicit A(int); A(float); }; // expected-note {{declared here}}
+  A a = { 0 }; // expected-error {{constructor is explicit}}
+
+  struct B { explicit B(short); B(long); }; // expected-note 2 {{candidate}}
+  B b = { 0 }; // expected-error {{ambiguous}}
+}

Modified: cfe/branches/tooling/test/SemaCXX/cxx98-compat-flags.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/cxx98-compat-flags.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/cxx98-compat-flags.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/cxx98-compat-flags.cpp Tue Apr  3 07:29:12 2012
@@ -24,10 +24,8 @@
     Ambiguous(const Ambiguous &, int = 0); // expected-note {{candidate}}
     Ambiguous(const Ambiguous &, double = 0); // expected-note {{candidate}}
   };
-  struct Deleted { // expected-note {{here}}
-    // Copy ctor implicitly defined as deleted because Private's copy ctor is
-    // inaccessible.
-    Private p;
+  struct Deleted {
+    Private p; // expected-note {{copy constructor of 'Deleted' is implicitly deleted because field 'p' has an inaccessible copy constructor}}
   };
 
   const Private &a = Private(); // expected-warning {{copying variable of type 'CopyCtorIssues::Private' when binding a reference to a temporary would invoke an inaccessible constructor in C++98}}

Modified: cfe/branches/tooling/test/SemaCXX/cxx98-compat.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/cxx98-compat.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/cxx98-compat.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/cxx98-compat.cpp Tue Apr  3 07:29:12 2012
@@ -214,10 +214,8 @@
     Ambiguous(const Ambiguous &, int = 0); // expected-note {{candidate}}
     Ambiguous(const Ambiguous &, double = 0); // expected-note {{candidate}}
   };
-  struct Deleted { // expected-note {{here}}
-    // Copy ctor implicitly defined as deleted because Private's copy ctor is
-    // inaccessible.
-    Private p;
+  struct Deleted {
+    Private p; // expected-note {{implicitly deleted}}
   };
 
   const Private &a = Private(); // expected-warning {{copying variable of type 'CopyCtorIssues::Private' when binding a reference to a temporary would invoke an inaccessible constructor in C++98}}

Modified: cfe/branches/tooling/test/SemaCXX/defaulted-private-dtor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/defaulted-private-dtor.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/defaulted-private-dtor.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/defaulted-private-dtor.cpp Tue Apr  3 07:29:12 2012
@@ -12,12 +12,12 @@
   BadDtor dd; // expected-error {{private destructor}}
   throw dd; // expected-error {{private destructor}}
 }
-struct V { // expected-note {{here}}
+struct V {
   V();
-  BadDtor bd;
+  BadDtor bd; // expected-note {{inaccessible destructor}}
 };
 V v; // expected-error {{deleted function}}
-struct W : BadDtor { // expected-note {{here}}
+struct W : BadDtor { // expected-note {{inaccessible destructor}}
   W();
 };
 W w; // expected-error {{deleted function}}

Modified: cfe/branches/tooling/test/SemaCXX/dr1301.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/dr1301.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/dr1301.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/dr1301.cpp Tue Apr  3 07:29:12 2012
@@ -6,19 +6,19 @@
 int a = A().n; // expected-error {{no matching constructor}}
 
 struct B {
-  B() = delete; // expected-note {{here}}
+  B() = delete; // expected-note 3{{here}}
   int n;
 };
 int b = B().n; // expected-error {{call to deleted}}
 
-struct C { // expected-note {{here}}
-  B b;
+struct C {
+  B b; // expected-note {{deleted default constructor}}
 };
 int c = C().b.n; // expected-error {{call to implicitly-deleted default}}
 
-struct D { // expected-note {{defined here}}
-  D() = default; // expected-note {{declared here}}
-  B b;
+struct D {
+  D() = default; // expected-note {{here}}
+  B b; // expected-note {{'b' has a deleted default constructor}}
 };
 int d = D().b.n; // expected-error {{call to implicitly-deleted default}}
 
@@ -34,8 +34,8 @@
 };
 int f = F().n; // ok
 
-union G { // expected-note {{here}}
-  F f;
+union G {
+  F f; // expected-note {{non-trivial default constructor}}
 };
 int g = G().f.n; // expected-error {{call to implicitly-deleted default}}
 
@@ -46,8 +46,8 @@
 };
 int h = H().n; // expected-error {{private constructor}}
 
-struct I { // expected-note {{here}}
-  H h;
+struct I {
+  H h; // expected-note {{inaccessible default constructor}}
 };
 int i = I().h.n; // expected-error {{call to implicitly-deleted default}}
 
@@ -59,8 +59,8 @@
 int j1 = J().n; // ok
 int j2 = J().f(); // ok
 
-union K { // expected-note 2{{here}}
-  J j;
+union K {
+  J j; // expected-note 2{{non-trivial default constructor}}
   int m;
 };
 int k1 = K().j.n; // expected-error {{call to implicitly-deleted default}}

Modified: cfe/branches/tooling/test/SemaCXX/implicit-exception-spec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/implicit-exception-spec.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/implicit-exception-spec.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/implicit-exception-spec.cpp Tue Apr  3 07:29:12 2012
@@ -54,9 +54,9 @@
 // The same problem arises in delayed parsing of default arguments,
 // which clang does not yet support.
 namespace DefaultArgument {
-  struct Default { // expected-note {{defined here}}
+  struct Default {
     struct T {
       T(int = ExceptionIf<noexcept(Default())::f()); // expected-error {{call to implicitly-deleted default constructor}}
-    } t;
+    } t; // expected-note {{has no default constructor}}
   };
 }

Modified: cfe/branches/tooling/test/SemaCXX/value-initialization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/value-initialization.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/value-initialization.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/value-initialization.cpp Tue Apr  3 07:29:12 2012
@@ -1,8 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
 
-struct A { //expected-note {{defined here}} \
-     // expected-warning {{does not declare any constructor to initialize}}
-     const int i; // expected-note{{const member 'i' will never be initialized}}
+struct A { // expected-warning {{does not declare any constructor to initialize}}
+     const int i; // expected-note{{const member 'i' will never be initialized}} expected-note {{implicitly deleted}}
      virtual void f() { } 
 };
 

Propchange: cfe/branches/tooling/test/SemaCXX/warn-unreachable.cpp
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Apr  3 07:29:12 2012
@@ -1,2 +1,2 @@
 /cfe/branches/type-system-rewrite/test/SemaCXX/warn-unreachable.cpp:134693-134817
-/cfe/trunk/test/SemaCXX/warn-unreachable.cpp:121961,146581-153647
+/cfe/trunk/test/SemaCXX/warn-unreachable.cpp:121961,146581-153950

Modified: cfe/branches/tooling/test/SemaObjC/arc-invalid.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaObjC/arc-invalid.m?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaObjC/arc-invalid.m (original)
+++ cfe/branches/tooling/test/SemaObjC/arc-invalid.m Tue Apr  3 07:29:12 2012
@@ -11,3 +11,8 @@
 void test0(id p) {
   takeBlock(^{ [p foo] + p; }); // expected-error {{invalid operands to binary expression}}
 }
+
+void test1(void) {
+  __autoreleasing id p; // expected-note {{'p' declared here}}
+  takeBlock(^{ (void) p; }); // expected-error {{cannot capture __autoreleasing variable in a block}}
+}

Modified: cfe/branches/tooling/test/SemaObjC/foreach.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaObjC/foreach.m?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaObjC/foreach.m (original)
+++ cfe/branches/tooling/test/SemaObjC/foreach.m Tue Apr  3 07:29:12 2012
@@ -46,3 +46,12 @@
  return 0;
 }
 
+/* rdar://problem/11068137 */
+ at interface Test2
+ at property (assign) id prop;
+ at end
+void test2(NSObject<NSFastEnumeration> *collection) {
+  Test2 *obj;
+  for (obj.prop in collection) { /* expected-error {{selector element is not a valid lvalue}} */
+  }
+}

Modified: cfe/branches/tooling/test/SemaObjC/instancetype.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaObjC/instancetype.m?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaObjC/instancetype.m (original)
+++ cfe/branches/tooling/test/SemaObjC/instancetype.m Tue Apr  3 07:29:12 2012
@@ -143,7 +143,7 @@
 
 @implementation Subclass4
 + (id)alloc {
-  return self; // expected-warning{{incompatible pointer types returning 'Class' from a function with result type 'Subclass4 *'}}
+  return self; // expected-warning{{incompatible pointer types casting 'Class' to type 'Subclass4 *'}}
 }
 
 - (Subclass3 *)init { return 0; } // don't complain: we lost the related return type
@@ -166,12 +166,12 @@
 @implementation Subclass2
 - (instancetype)initSubclass2 {
   Subclass1 *sc1 = [[Subclass1 alloc] init];
-  return sc1; // expected-warning{{incompatible pointer types returning 'Subclass1 *' from a function with result type 'Subclass2 *'}}
+  return sc1; // expected-warning{{incompatible pointer types casting 'Subclass1 *' to type 'Subclass2 *'}}
 }
 - (void)methodOnSubclass2 {}
 - (id)self {
   Subclass1 *sc1 = [[Subclass1 alloc] init];
-  return sc1; // expected-warning{{incompatible pointer types returning 'Subclass1 *' from a function with result type 'Subclass2 *'}}
+  return sc1; // expected-warning{{incompatible pointer types casting 'Subclass1 *' to type 'Subclass2 *'}}
 }
 @end
 

Modified: cfe/branches/tooling/test/SemaObjC/related-result-type-inference.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaObjC/related-result-type-inference.m?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaObjC/related-result-type-inference.m (original)
+++ cfe/branches/tooling/test/SemaObjC/related-result-type-inference.m Tue Apr  3 07:29:12 2012
@@ -169,3 +169,12 @@
 }
 @end
 
+// PR12384
+ at interface Fail @end
+ at protocol X @end
+ at implementation Fail
+- (id<X>) initWithX
+{
+  return (id)self; // expected-warning {{returning 'Fail *' from a function with incompatible result type 'id<X>'}}
+}
+ at end

Modified: cfe/branches/tooling/test/SemaObjCXX/arc-0x.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaObjCXX/arc-0x.mm?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaObjCXX/arc-0x.mm (original)
+++ cfe/branches/tooling/test/SemaObjCXX/arc-0x.mm Tue Apr  3 07:29:12 2012
@@ -30,3 +30,24 @@
   } @catch (auto e) { // expected-error {{'auto' not allowed in exception declaration}}
   }
 }
+
+// rdar://problem/11068137
+void test1a() {
+  __autoreleasing id p; // expected-note 2 {{'p' declared here}}
+  (void) [&p] {};
+  (void) [p] {}; // expected-error {{cannot capture __autoreleasing variable in a lambda by copy}}
+  (void) [=] { (void) p; }; // expected-error {{cannot capture __autoreleasing variable in a lambda by copy}}
+}
+void test1b() {
+  __autoreleasing id v;
+  __autoreleasing id &p = v; // expected-note 2 {{'p' declared here}}
+  (void) [&p] {};
+  (void) [p] {}; // expected-error {{cannot capture __autoreleasing variable in a lambda by copy}}
+  (void) [=] { (void) p; }; // expected-error {{cannot capture __autoreleasing variable in a lambda by copy}}
+}
+void test1c() {
+  __autoreleasing id v; // expected-note {{'v' declared here}}
+  __autoreleasing id &p = v;
+  (void) ^{ (void) p; };
+  (void) ^{ (void) v; }; // expected-error {{cannot capture __autoreleasing variable in a block}}
+}

Modified: cfe/branches/tooling/test/SemaTemplate/canonical-expr-type-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaTemplate/canonical-expr-type-0x.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaTemplate/canonical-expr-type-0x.cpp (original)
+++ cfe/branches/tooling/test/SemaTemplate/canonical-expr-type-0x.cpp Tue Apr  3 07:29:12 2012
@@ -2,15 +2,24 @@
 
 void f();
 
-// FIXME: would like to refer to the first function parameter in these test,
-// but that won't work (yet).
-
 // Test typeof(expr) canonicalization
 template<typename T, T N>
-void f0(T x, decltype(f(N)) y) { } // expected-note{{previous}}
+void f0(T x, decltype(f(N, x)) y) { } // expected-note{{previous}}
 
 template<typename T, T N>
-void f0(T x, decltype((f)(N)) y) { }
+void f0(T x, decltype((f)(N, x)) y) { }
 
 template<typename U, U M>
-void f0(U u, decltype(f(M))) { } // expected-error{{redefinition}}
+void f0(U u, decltype(f(M, u))) { } // expected-error{{redefinition}}
+
+// PR12438: Test sizeof...() canonicalization
+template<int> struct N {};
+
+template<typename...T>
+N<sizeof...(T)> f1() {} // expected-note{{previous}}
+
+template<typename, typename...T>
+N<sizeof...(T)> f1() {}
+
+template<class...U>
+N<sizeof...(U)> f1() {} // expected-error{{redefinition}}

Modified: cfe/branches/tooling/test/SemaTemplate/friend-template.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaTemplate/friend-template.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaTemplate/friend-template.cpp (original)
+++ cfe/branches/tooling/test/SemaTemplate/friend-template.cpp Tue Apr  3 07:29:12 2012
@@ -230,3 +230,16 @@
     template <> friend class B; // expected-error{{extraneous 'template<>' in declaration of class 'B'}}
   };
 }
+
+namespace rdar11147355 {
+  template <class T> 
+  struct A {
+    template <class U> class B;
+    template <class S> template <class U> friend class A<S>::B; 
+  };
+  
+  template <class S> template <class U> class A<S>::B {
+  }; 
+  
+  A<double>::B<double>  ab;
+}

Modified: cfe/branches/tooling/tools/c-index-test/c-index-test.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/c-index-test/c-index-test.c?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/tools/c-index-test/c-index-test.c (original)
+++ cfe/branches/tooling/tools/c-index-test/c-index-test.c Tue Apr  3 07:29:12 2012
@@ -171,7 +171,8 @@
   if (!begin_file || !end_file)
     return;
 
-  printf(" %s=", str);
+  if (str)
+    printf(" %s=", str);
   PrintExtent(stdout, begin_line, begin_column, end_line, end_column);
 }
 
@@ -1439,7 +1440,31 @@
       if (I + 1 == Repeats) {
         CXCompletionString completionString = clang_getCursorCompletionString(
                                                                         Cursor);
+        CXSourceLocation CursorLoc = clang_getCursorLocation(Cursor);
+        CXString Spelling;
+        const char *cspell;
+        unsigned line, column;
+        clang_getSpellingLocation(CursorLoc, 0, &line, &column, 0);
+        printf("%d:%d ", line, column);
         PrintCursor(Cursor);
+        PrintCursorExtent(Cursor);
+        Spelling = clang_getCursorSpelling(Cursor);
+        cspell = clang_getCString(Spelling);
+        if (cspell && strlen(cspell) != 0) {
+          unsigned pieceIndex;
+          printf(" Spelling=%s (", cspell);
+          for (pieceIndex = 0; ; ++pieceIndex) {
+            CXSourceRange range =
+              clang_Cursor_getSpellingNameRange(Cursor, pieceIndex, 0);
+            if (clang_Range_isNull(range))
+              break;
+            PrintRange(range, 0);
+          }
+          printf(")");
+        }
+        clang_disposeString(Spelling);
+        if (clang_Cursor_getObjCSelectorIndex(Cursor) != -1)
+          printf(" Selector index=%d",clang_Cursor_getObjCSelectorIndex(Cursor));
         if (completionString != NULL) {
           printf("\nCompletion string: ");
           print_completion_string(completionString, stdout);

Modified: cfe/branches/tooling/tools/driver/cc1as_main.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/driver/cc1as_main.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/tools/driver/cc1as_main.cpp (original)
+++ cfe/branches/tooling/tools/driver/cc1as_main.cpp Tue Apr  3 07:29:12 2012
@@ -323,7 +323,8 @@
   // FIXME: There is a bit of code duplication with addPassesToEmitFile.
   if (Opts.OutputType == AssemblerInvocation::FT_Asm) {
     MCInstPrinter *IP =
-      TheTarget->createMCInstPrinter(Opts.OutputAsmVariant, *MAI, *MRI, *STI);
+      TheTarget->createMCInstPrinter(Opts.OutputAsmVariant, *MAI, *MCII, *MRI,
+                                     *STI);
     MCCodeEmitter *CE = 0;
     MCAsmBackend *MAB = 0;
     if (Opts.ShowEncoding) {

Modified: cfe/branches/tooling/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/libclang/CIndex.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/tools/libclang/CIndex.cpp (original)
+++ cfe/branches/tooling/tools/libclang/CIndex.cpp Tue Apr  3 07:29:12 2012
@@ -2901,8 +2901,17 @@
     return ME->getMemberDecl();
   if (ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
     return RE->getDecl();
-  if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E))
-    return PRE->isExplicitProperty() ? PRE->getExplicitProperty() : 0;
+  if (ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
+    if (PRE->isExplicitProperty())
+      return PRE->getExplicitProperty();
+    // It could be messaging both getter and setter as in:
+    // ++myobj.myprop;
+    // in which case prefer to associate the setter since it is less obvious
+    // from inspecting the source that the setter is going to get called.
+    if (PRE->isMessagingSetter())
+      return PRE->getImplicitPropertySetter();
+    return PRE->getImplicitPropertyGetter();
+  }
   if (PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
     return getDeclFromExpr(POE->getSyntacticForm());
   if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
@@ -2944,6 +2953,8 @@
     return Ivar->getLocation();
   if (SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
     return SizeOfPack->getPackLoc();
+  if (ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
+    return PropRef->getLocation();
   
   return E->getLocStart();
 }
@@ -3156,6 +3167,63 @@
   return createCXString("");
 }
 
+CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C,
+                                                unsigned pieceIndex,
+                                                unsigned options) {
+  if (clang_Cursor_isNull(C))
+    return clang_getNullRange();
+
+  ASTContext &Ctx = getCursorContext(C);
+
+  if (clang_isStatement(C.kind)) {
+    Stmt *S = getCursorStmt(C);
+    if (LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
+      if (pieceIndex > 0)
+        return clang_getNullRange();
+      return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
+    }
+
+    return clang_getNullRange();
+  }
+
+  if (C.kind == CXCursor_ObjCMessageExpr) {
+    if (ObjCMessageExpr *
+          ME = dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
+      if (pieceIndex >= ME->getNumSelectorLocs())
+        return clang_getNullRange();
+      return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
+    }
+  }
+
+  if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
+      C.kind == CXCursor_ObjCClassMethodDecl) {
+    if (ObjCMethodDecl *
+          MD = dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
+      if (pieceIndex >= MD->getNumSelectorLocs())
+        return clang_getNullRange();
+      return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
+    }
+  }
+
+  // FIXME: A CXCursor_InclusionDirective should give the location of the
+  // filename, but we don't keep track of this.
+
+  // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
+  // but we don't keep track of this.
+
+  // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
+  // but we don't keep track of this.
+
+  // Default handling, give the location of the cursor.
+
+  if (pieceIndex > 0)
+    return clang_getNullRange();
+
+  CXSourceLocation CXLoc = clang_getCursorLocation(C);
+  SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
+  return cxloc::translateSourceRange(Ctx, Loc);
+}
+
 CXString clang_getCursorDisplayName(CXCursor C) {
   if (!clang_isDeclaration(C.kind))
     return clang_getCursorSpelling(C);
@@ -4357,6 +4425,10 @@
   
   return C;
 }
+
+int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
+  return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
+}
   
 unsigned clang_getNumOverloadedDecls(CXCursor C) {
   if (C.kind != CXCursor_OverloadedDeclRef)

Modified: cfe/branches/tooling/tools/libclang/IndexingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/libclang/IndexingContext.cpp?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/tools/libclang/IndexingContext.cpp (original)
+++ cfe/branches/tooling/tools/libclang/IndexingContext.cpp Tue Apr  3 07:29:12 2012
@@ -61,9 +61,9 @@
     IBCollInfo.objcClass = 0;
 }
 
-AttrListInfo::AttrListInfo(const Decl *D,
-                           IndexingContext &IdxCtx,
-                           ScratchAlloc &SA) : ref_cnt(0) {
+AttrListInfo::AttrListInfo(const Decl *D, IndexingContext &IdxCtx)
+  : SA(IdxCtx), ref_cnt(0) {
+
   if (!D->hasAttrs())
     return;
 
@@ -113,19 +113,11 @@
     CXAttrs.push_back(&Attrs[i]);
 }
 
-AttrListInfo::AttrListInfo(const AttrListInfo &other) {
-  assert(other.ref_cnt == 0 &&
-         "Should not copy an AttrListInfo that is ref-counted");
-  ref_cnt = 0;
-
-  Attrs = other.Attrs;
-  IBCollAttrs = other.IBCollAttrs;
-
-  for (unsigned i = 0, e = IBCollAttrs.size(); i != e; ++i)
-    CXAttrs.push_back(&IBCollAttrs[i]);
-
-  for (unsigned i = 0, e = Attrs.size(); i != e; ++i)
-    CXAttrs.push_back(&Attrs[i]);
+IntrusiveRefCntPtr<AttrListInfo>
+AttrListInfo::create(const Decl *D, IndexingContext &IdxCtx) {
+  ScratchAlloc SA(IdxCtx);
+  AttrListInfo *attrs = SA.allocate<AttrListInfo>();
+  return new (attrs) AttrListInfo(D, IdxCtx);
 }
 
 IndexingContext::CXXBasesListInfo::CXXBasesListInfo(const CXXRecordDecl *D,
@@ -281,9 +273,8 @@
   DInfo.loc = getIndexLoc(Loc);
   DInfo.isImplicit = D->isImplicit();
 
-  AttrListInfo AttrList(D, *this, SA);
-  DInfo.attributes = AttrList.getAttrs();
-  DInfo.numAttributes = AttrList.getNumAttrs();
+  DInfo.attributes = DInfo.EntInfo.attributes;
+  DInfo.numAttributes = DInfo.EntInfo.numAttributes;
 
   getContainerInfo(D->getDeclContext(), DInfo.SemanticContainer);
   DInfo.semanticContainer = &DInfo.SemanticContainer;
@@ -443,9 +434,10 @@
 }
 
 bool IndexingContext::handleObjCCategory(const ObjCCategoryDecl *D) {
+  ScratchAlloc SA(*this);
+
   ObjCCategoryDeclInfo CatDInfo(/*isImplementation=*/false);
   EntityInfo ClassEntity;
-  ScratchAlloc SA(*this);
   const ObjCInterfaceDecl *IFaceD = D->getClassInterface();
   SourceLocation ClassLoc = D->getLocation();
   SourceLocation CategoryLoc = D->IsClassExtension() ? ClassLoc
@@ -474,10 +466,11 @@
 }
 
 bool IndexingContext::handleObjCCategoryImpl(const ObjCCategoryImplDecl *D) {
+  ScratchAlloc SA(*this);
+
   const ObjCCategoryDecl *CatD = D->getCategoryDecl();
   ObjCCategoryDeclInfo CatDInfo(/*isImplementation=*/true);
   EntityInfo ClassEntity;
-  ScratchAlloc SA(*this);
   const ObjCInterfaceDecl *IFaceD = CatD->getClassInterface();
   SourceLocation ClassLoc = D->getLocation();
   SourceLocation CategoryLoc = D->getCategoryNameLoc();
@@ -522,10 +515,11 @@
 }
 
 bool IndexingContext::handleObjCProperty(const ObjCPropertyDecl *D) {
+  ScratchAlloc SA(*this);
+
   ObjCPropertyDeclInfo DInfo;
   EntityInfo GetterEntity;
   EntityInfo SetterEntity;
-  ScratchAlloc SA(*this);
 
   DInfo.ObjCPropDeclInfo.declInfo = &DInfo;
 
@@ -846,11 +840,9 @@
   EntityInfo.lang = CXIdxEntityLang_C;
 
   if (D->hasAttrs()) {
-    AttrListInfo *attrs = SA.allocate<AttrListInfo>();
-    new (attrs) AttrListInfo(D, *this, SA);
-    EntityInfo.AttrList = attrs;
-    EntityInfo.attributes = attrs->getAttrs();
-    EntityInfo.numAttributes = attrs->getNumAttrs();
+    EntityInfo.AttrList = AttrListInfo::create(D, *this);
+    EntityInfo.attributes = EntityInfo.AttrList->getAttrs();
+    EntityInfo.numAttributes = EntityInfo.AttrList->getNumAttrs();
   }
 
   if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {

Modified: cfe/branches/tooling/tools/libclang/IndexingContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/libclang/IndexingContext.h?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/tools/libclang/IndexingContext.h (original)
+++ cfe/branches/tooling/tools/libclang/IndexingContext.h Tue Apr  3 07:29:12 2012
@@ -25,9 +25,24 @@
 
 namespace cxindex {
   class IndexingContext;
-  class ScratchAlloc;
   class AttrListInfo;
 
+class ScratchAlloc {
+  IndexingContext &IdxCtx;
+
+public:
+  explicit ScratchAlloc(IndexingContext &indexCtx);
+  ScratchAlloc(const ScratchAlloc &SA);
+
+  ~ScratchAlloc();
+
+  const char *toCStr(StringRef Str);
+  const char *copyCStr(StringRef Str);
+
+  template <typename T>
+  T *allocate();
+};
+
 struct EntityInfo : public CXIdxEntityInfo {
   const NamedDecl *Dcl;
   IndexingContext *IndexCtx;
@@ -229,16 +244,20 @@
 };
 
 class AttrListInfo {
+  ScratchAlloc SA;
+
   SmallVector<AttrInfo, 2> Attrs;
   SmallVector<IBOutletCollectionInfo, 2> IBCollAttrs;
   SmallVector<CXIdxAttrInfo *, 2> CXAttrs;
   unsigned ref_cnt;
 
+  AttrListInfo(const AttrListInfo&); // DO NOT IMPLEMENT
+  void operator=(const AttrListInfo&); // DO NOT IMPLEMENT
 public:
-  AttrListInfo(const Decl *D,
-               IndexingContext &IdxCtx,
-               ScratchAlloc &SA);
-  AttrListInfo(const AttrListInfo &other);
+  AttrListInfo(const Decl *D, IndexingContext &IdxCtx);
+
+  static IntrusiveRefCntPtr<AttrListInfo> create(const Decl *D,
+                                                 IndexingContext &IdxCtx);
 
   const CXIdxAttrInfo *const *getAttrs() const {
     if (CXAttrs.empty())
@@ -488,28 +507,23 @@
   static bool shouldIgnoreIfImplicit(const Decl *D);
 };
 
-class ScratchAlloc {
-  IndexingContext &IdxCtx;
-
-public:
-  explicit ScratchAlloc(IndexingContext &indexCtx) : IdxCtx(indexCtx) {
-    ++IdxCtx.StrAdapterCount;
-  }
-
-  ~ScratchAlloc() {
-    --IdxCtx.StrAdapterCount;
-    if (IdxCtx.StrAdapterCount == 0)
-      IdxCtx.StrScratch.Reset();
-  }
+inline ScratchAlloc::ScratchAlloc(IndexingContext &idxCtx) : IdxCtx(idxCtx) {
+  ++IdxCtx.StrAdapterCount;
+}
+inline ScratchAlloc::ScratchAlloc(const ScratchAlloc &SA) : IdxCtx(SA.IdxCtx) {
+  ++IdxCtx.StrAdapterCount;
+}
 
-  const char *toCStr(StringRef Str);
-  const char *copyCStr(StringRef Str);
+inline ScratchAlloc::~ScratchAlloc() {
+  --IdxCtx.StrAdapterCount;
+  if (IdxCtx.StrAdapterCount == 0)
+    IdxCtx.StrScratch.Reset();
+}
 
-  template <typename T>
-  T *allocate() {
-    return IdxCtx.StrScratch.Allocate<T>();
-  }
-};
+template <typename T>
+inline T *ScratchAlloc::allocate() {
+  return IdxCtx.StrScratch.Allocate<T>();
+}
 
 }} // end clang::cxindex
 

Modified: cfe/branches/tooling/tools/libclang/libclang.exports
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/tools/libclang/libclang.exports?rev=153953&r1=153952&r2=153953&view=diff
==============================================================================
--- cfe/branches/tooling/tools/libclang/libclang.exports (original)
+++ cfe/branches/tooling/tools/libclang/libclang.exports Tue Apr  3 07:29:12 2012
@@ -4,7 +4,9 @@
 clang_CXIndex_setGlobalOptions
 clang_CXXMethod_isStatic
 clang_CXXMethod_isVirtual
+clang_Cursor_getSpellingNameRange
 clang_Cursor_getTranslationUnit
+clang_Cursor_getObjCSelectorIndex
 clang_Cursor_isNull
 clang_IndexAction_create
 clang_IndexAction_dispose





More information about the llvm-branch-commits mailing list