[llvm-branch-commits] [cfe-branch] r146823 - in /cfe/branches/tooling: ./ include/clang/AST/ include/clang/Basic/ include/clang/Driver/ include/clang/Frontend/ include/clang/Sema/ include/clang/StaticAnalyzer/Core/PathSensitive/ lib/AST/ lib/Basic/ lib/CodeGen/ lib/Driver/ lib/Frontend/ lib/Headers/ lib/Lex/ lib/Parse/ lib/Sema/ lib/Serialization/ lib/StaticAnalyzer/Checkers/ lib/StaticAnalyzer/Core/ test/Analysis/ test/CXX/expr/expr.const/ test/CXX/special/class.dtor/ test/CXX/temp/temp.decls/temp.variadic/ test/CodeGen/ tes...

Chandler Carruth chandlerc at gmail.com
Fri Dec 16 22:38:55 PST 2011


Author: chandlerc
Date: Sat Dec 17 00:38:54 2011
New Revision: 146823

URL: http://llvm.org/viewvc/llvm-project?rev=146823&view=rev
Log:
Merge up to head of trunk. The build will be broken until I update the code to
match API changes during code review on LLVM.

Added:
    cfe/branches/tooling/include/clang/Frontend/DiagnosticRenderer.h
      - copied unchanged from r146820, cfe/trunk/include/clang/Frontend/DiagnosticRenderer.h
    cfe/branches/tooling/lib/Frontend/DiagnosticRenderer.cpp
      - copied unchanged from r146820, cfe/trunk/lib/Frontend/DiagnosticRenderer.cpp
    cfe/branches/tooling/test/CodeGenCXX/debug-info-fwd-ref.cpp
      - copied unchanged from r146820, cfe/trunk/test/CodeGenCXX/debug-info-fwd-ref.cpp
    cfe/branches/tooling/test/Misc/serialized-diags.h
      - copied unchanged from r146820, cfe/trunk/test/Misc/serialized-diags.h
    cfe/branches/tooling/test/Modules/Inputs/decl2.h
      - copied unchanged from r146820, cfe/trunk/test/Modules/Inputs/decl2.h
    cfe/branches/tooling/test/PCH/single-token-macro.c
      - copied unchanged from r146820, cfe/trunk/test/PCH/single-token-macro.c
    cfe/branches/tooling/test/Preprocessor/macro_arg_directive.c
      - copied unchanged from r146820, cfe/trunk/test/Preprocessor/macro_arg_directive.c
    cfe/branches/tooling/test/Preprocessor/macro_arg_directive.h
      - copied unchanged from r146820, cfe/trunk/test/Preprocessor/macro_arg_directive.h
    cfe/branches/tooling/test/Sema/attr-declspec-ignored.c
      - copied unchanged from r146820, cfe/trunk/test/Sema/attr-declspec-ignored.c
    cfe/branches/tooling/test/SemaCXX/attr-declspec-ignored.cpp
      - copied unchanged from r146820, cfe/trunk/test/SemaCXX/attr-declspec-ignored.cpp
    cfe/branches/tooling/test/SemaCXX/constexpr-backtrace-limit.cpp
      - copied unchanged from r146820, cfe/trunk/test/SemaCXX/constexpr-backtrace-limit.cpp
    cfe/branches/tooling/test/SemaCXX/constexpr-printing.cpp
      - copied unchanged from r146820, cfe/trunk/test/SemaCXX/constexpr-printing.cpp
Removed:
    cfe/branches/tooling/unittests/AST/
Modified:
    cfe/branches/tooling/   (props changed)
    cfe/branches/tooling/include/clang/AST/APValue.h
    cfe/branches/tooling/include/clang/AST/ASTContext.h
    cfe/branches/tooling/include/clang/AST/DeclObjC.h
    cfe/branches/tooling/include/clang/AST/Redeclarable.h
    cfe/branches/tooling/include/clang/AST/Type.h
    cfe/branches/tooling/include/clang/Basic/BuiltinsX86.def
    cfe/branches/tooling/include/clang/Basic/Diagnostic.h
    cfe/branches/tooling/include/clang/Basic/DiagnosticASTKinds.td
    cfe/branches/tooling/include/clang/Basic/DiagnosticGroups.td
    cfe/branches/tooling/include/clang/Basic/DiagnosticLexKinds.td
    cfe/branches/tooling/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/branches/tooling/include/clang/Basic/TargetInfo.h
    cfe/branches/tooling/include/clang/Driver/CC1Options.td
    cfe/branches/tooling/include/clang/Driver/Options.td
    cfe/branches/tooling/include/clang/Frontend/DiagnosticOptions.h
    cfe/branches/tooling/include/clang/Frontend/SerializedDiagnosticPrinter.h
    cfe/branches/tooling/include/clang/Frontend/TextDiagnostic.h
    cfe/branches/tooling/include/clang/Sema/Sema.h
    cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
    cfe/branches/tooling/lib/AST/APValue.cpp
    cfe/branches/tooling/lib/AST/ASTContext.cpp
    cfe/branches/tooling/lib/AST/ASTImporter.cpp
    cfe/branches/tooling/lib/AST/DeclObjC.cpp
    cfe/branches/tooling/lib/AST/ExprConstant.cpp
    cfe/branches/tooling/lib/Basic/Diagnostic.cpp
    cfe/branches/tooling/lib/Basic/TargetInfo.cpp
    cfe/branches/tooling/lib/Basic/Targets.cpp
    cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp
    cfe/branches/tooling/lib/CodeGen/CGDebugInfo.h
    cfe/branches/tooling/lib/Driver/Tools.cpp
    cfe/branches/tooling/lib/Frontend/CMakeLists.txt
    cfe/branches/tooling/lib/Frontend/CompilerInstance.cpp
    cfe/branches/tooling/lib/Frontend/CompilerInvocation.cpp
    cfe/branches/tooling/lib/Frontend/SerializedDiagnosticPrinter.cpp
    cfe/branches/tooling/lib/Frontend/TextDiagnostic.cpp
    cfe/branches/tooling/lib/Frontend/VerifyDiagnosticConsumer.cpp
    cfe/branches/tooling/lib/Frontend/Warnings.cpp
    cfe/branches/tooling/lib/Headers/avxintrin.h
    cfe/branches/tooling/lib/Lex/PPDirectives.cpp
    cfe/branches/tooling/lib/Lex/PPMacroExpansion.cpp
    cfe/branches/tooling/lib/Parse/ParseExprCXX.cpp
    cfe/branches/tooling/lib/Parse/ParseObjc.cpp
    cfe/branches/tooling/lib/Parse/Parser.cpp
    cfe/branches/tooling/lib/Sema/Sema.cpp
    cfe/branches/tooling/lib/Sema/SemaChecking.cpp
    cfe/branches/tooling/lib/Sema/SemaDecl.cpp
    cfe/branches/tooling/lib/Sema/SemaDeclAttr.cpp
    cfe/branches/tooling/lib/Sema/SemaDeclObjC.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/Serialization/ASTReader.cpp
    cfe/branches/tooling/lib/Serialization/ASTReaderDecl.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
    cfe/branches/tooling/lib/StaticAnalyzer/Core/ProgramState.cpp
    cfe/branches/tooling/test/Analysis/taint-tester.c
    cfe/branches/tooling/test/CXX/expr/expr.const/p2-0x.cpp
    cfe/branches/tooling/test/CXX/special/class.dtor/p10-0x.cpp
    cfe/branches/tooling/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
    cfe/branches/tooling/test/CodeGen/builtins-x86.c
    cfe/branches/tooling/test/CodeGenCXX/visibility.cpp
    cfe/branches/tooling/test/CodeGenObjC/debug-info-fwddecl.m
    cfe/branches/tooling/test/CodeGenObjC/debug-info-pubtypes.m
    cfe/branches/tooling/test/Misc/serialized-diags-single-issue.c
    cfe/branches/tooling/test/Misc/serialized-diags.c
    cfe/branches/tooling/test/Misc/warning-flags.c
    cfe/branches/tooling/test/Modules/Inputs/module.map
    cfe/branches/tooling/test/Parser/method-def-in-class.m
    cfe/branches/tooling/test/Sema/array-bounds-ptr-arith.c
    cfe/branches/tooling/test/Sema/attr-deprecated.c
    cfe/branches/tooling/test/Sema/warn-cast-align.c
    cfe/branches/tooling/test/SemaCXX/attr-cxx0x.cpp
    cfe/branches/tooling/test/SemaCXX/constant-expression-cxx11.cpp
    cfe/branches/tooling/test/SemaCXX/pseudo-destructors.cpp
    cfe/branches/tooling/test/SemaObjC/forward-class-1.m
    cfe/branches/tooling/test/SemaObjC/nsobject-attribute.m
    cfe/branches/tooling/unittests/CMakeLists.txt
    cfe/branches/tooling/unittests/Makefile

Propchange: cfe/branches/tooling/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Sat Dec 17 00:38:54 2011
@@ -1,3 +1,3 @@
 /cfe/branches/type-system-rewrite:134693-134817
-/cfe/trunk:146581-146719
+/cfe/trunk:146581-146820
 /cfe/trunk/test/SemaTemplate:126920

Modified: cfe/branches/tooling/include/clang/AST/APValue.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/APValue.h?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/APValue.h (original)
+++ cfe/branches/tooling/include/clang/AST/APValue.h Sat Dec 17 00:38:54 2011
@@ -21,6 +21,7 @@
 #include "llvm/ADT/PointerUnion.h"
 
 namespace clang {
+  class ASTContext;
   class CharUnits;
   class DiagnosticBuilder;
   class Expr;
@@ -28,6 +29,7 @@
   class Decl;
   class ValueDecl;
   class CXXRecordDecl;
+  class QualType;
 
 /// APValue - This class implements a discriminated union of [uninitialized]
 /// [APSInt] [APFloat], [Complex APSInt] [Complex APFloat], [Expr + Offset],
@@ -171,8 +173,11 @@
   bool isUnion() const { return Kind == Union; }
   bool isMemberPointer() const { return Kind == MemberPointer; }
 
-  void print(raw_ostream &OS) const;
   void dump() const;
+  void dump(raw_ostream &OS) const;
+
+  void printPretty(raw_ostream &OS, ASTContext &Ctx, QualType Ty) const;
+  std::string getAsString(ASTContext &Ctx, QualType Ty) const;
 
   APSInt &getInt() {
     assert(isInt() && "Invalid accessor");
@@ -394,15 +399,6 @@
                          ArrayRef<const CXXRecordDecl*> Path);
 };
 
-inline raw_ostream &operator<<(raw_ostream &OS, const APValue &V) {
-  V.print(OS);
-  return OS;
-}
-
-// Writes a concise representation of V to DB, in a single << operation.
-const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
-                                    const APValue &V);
-
 } // end namespace clang.
 
 #endif

Modified: cfe/branches/tooling/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/ASTContext.h?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/ASTContext.h (original)
+++ cfe/branches/tooling/include/clang/AST/ASTContext.h Sat Dec 17 00:38:54 2011
@@ -853,7 +853,8 @@
   QualType getPackExpansionType(QualType Pattern,
                                 llvm::Optional<unsigned> NumExpansions);
 
-  QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl) const;
+  QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
+                                ObjCInterfaceDecl *PrevDecl = 0) const;
 
   QualType getObjCObjectType(QualType Base,
                              ObjCProtocolDecl * const *Protocols,

Modified: cfe/branches/tooling/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/DeclObjC.h?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/DeclObjC.h (original)
+++ cfe/branches/tooling/include/clang/AST/DeclObjC.h Sat Dec 17 00:38:54 2011
@@ -589,7 +589,8 @@
   };
 
   ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
-                    SourceLocation CLoc, bool isInternal);
+                    SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
+                    bool isInternal);
 
   void LoadExternalDefinition() const;
 
@@ -614,9 +615,12 @@
   static ObjCInterfaceDecl *Create(ASTContext &C, DeclContext *DC,
                                    SourceLocation atLoc,
                                    IdentifierInfo *Id,
+                                   ObjCInterfaceDecl *PrevDecl,
                                    SourceLocation ClassLoc = SourceLocation(),
                                    bool isInternal = false);
 
+  static ObjCInterfaceDecl *CreateEmpty(ASTContext &C);
+
   virtual SourceRange getSourceRange() const {
     if (isThisDeclarationADefinition())
       return ObjCContainerDecl::getSourceRange();
@@ -916,8 +920,6 @@
     return getFirstDeclaration();
   }
 
-  void setPreviousDeclaration(ObjCInterfaceDecl *PrevDecl);
-
   // Low-level accessor
   const Type *getTypeForDecl() const { return TypeForDecl; }
   void setTypeForDecl(const Type *TD) const { TypeForDecl = TD; }

Modified: cfe/branches/tooling/include/clang/AST/Redeclarable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/Redeclarable.h?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/Redeclarable.h (original)
+++ cfe/branches/tooling/include/clang/AST/Redeclarable.h Sat Dec 17 00:38:54 2011
@@ -116,6 +116,7 @@
     /// Current - The current declaration.
     decl_type *Current;
     decl_type *Starter;
+    bool PassedFirst;
 
   public:
     typedef decl_type*                value_type;
@@ -125,13 +126,24 @@
     typedef std::ptrdiff_t            difference_type;
 
     redecl_iterator() : Current(0) { }
-    explicit redecl_iterator(decl_type *C) : Current(C), Starter(C) { }
+    explicit redecl_iterator(decl_type *C)
+      : Current(C), Starter(C), PassedFirst(false) { }
 
     reference operator*() const { return Current; }
     pointer operator->() const { return Current; }
 
     redecl_iterator& operator++() {
       assert(Current && "Advancing while iterator has reached end");
+      // Sanity check to avoid infinite loop on invalid redecl chain.
+      if (Current->isFirstDeclaration()) {
+        if (PassedFirst) {
+          assert(0 && "Passed first decl twice, invalid redecl chain!");
+          Current = 0;
+          return *this;
+        }
+        PassedFirst = true;
+      }
+
       // Get either previous decl or latest decl.
       decl_type *Next = Current->RedeclLink.getNext();
       Current = (Next != Starter ? Next : 0);

Modified: cfe/branches/tooling/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/AST/Type.h?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/AST/Type.h (original)
+++ cfe/branches/tooling/include/clang/AST/Type.h Sat Dec 17 00:38:54 2011
@@ -4139,12 +4139,13 @@
 ///   - It is its own base type.  That is, if T is an ObjCInterfaceType*,
 ///     T->getBaseType() == QualType(T, 0).
 class ObjCInterfaceType : public ObjCObjectType {
-  ObjCInterfaceDecl *Decl;
+  mutable ObjCInterfaceDecl *Decl;
 
   ObjCInterfaceType(const ObjCInterfaceDecl *D)
     : ObjCObjectType(Nonce_ObjCInterface),
       Decl(const_cast<ObjCInterfaceDecl*>(D)) {}
   friend class ASTContext;  // ASTContext creates these.
+  friend class ObjCInterfaceDecl;
 
 public:
   /// getDecl - Get the declaration of this interface.

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=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/BuiltinsX86.def (original)
+++ cfe/branches/tooling/include/clang/Basic/BuiltinsX86.def Sat Dec 17 00:38:54 2011
@@ -411,9 +411,9 @@
 BUILTIN(__builtin_ia32_dpps256, "V8fV8fV8fIi", "")
 BUILTIN(__builtin_ia32_cmppd256, "V4dV4dV4dc", "")
 BUILTIN(__builtin_ia32_cmpps256, "V8fV8fV8fc", "")
-BUILTIN(__builtin_ia32_vextractf128_pd256, "V2dV4dc", "")
-BUILTIN(__builtin_ia32_vextractf128_ps256, "V4fV8fc", "")
-BUILTIN(__builtin_ia32_vextractf128_si256, "V4iV8ic", "")
+BUILTIN(__builtin_ia32_vextractf128_pd256, "V2dV4dIc", "")
+BUILTIN(__builtin_ia32_vextractf128_ps256, "V4fV8fIc", "")
+BUILTIN(__builtin_ia32_vextractf128_si256, "V4iV8iIc", "")
 BUILTIN(__builtin_ia32_cvtdq2pd256, "V4dV4i", "")
 BUILTIN(__builtin_ia32_cvtdq2ps256, "V8fV8i", "")
 BUILTIN(__builtin_ia32_cvtpd2ps256, "V4fV4d", "")
@@ -422,22 +422,22 @@
 BUILTIN(__builtin_ia32_cvttpd2dq256, "V4iV4d", "")
 BUILTIN(__builtin_ia32_cvtpd2dq256, "V4iV4d", "")
 BUILTIN(__builtin_ia32_cvttps2dq256, "V8iV8f", "")
-BUILTIN(__builtin_ia32_vperm2f128_pd256, "V4dV4dV4dc", "")
-BUILTIN(__builtin_ia32_vperm2f128_ps256, "V8fV8fV8fc", "")
-BUILTIN(__builtin_ia32_vperm2f128_si256, "V8iV8iV8ic", "")
-BUILTIN(__builtin_ia32_vpermilpd, "V2dV2dc", "")
-BUILTIN(__builtin_ia32_vpermilps, "V4fV4fc", "")
-BUILTIN(__builtin_ia32_vpermilpd256, "V4dV4dc", "")
-BUILTIN(__builtin_ia32_vpermilps256, "V8fV8fc", "")
-BUILTIN(__builtin_ia32_vinsertf128_pd256, "V4dV4dV2dc", "")
-BUILTIN(__builtin_ia32_vinsertf128_ps256, "V8fV8fV4fc", "")
-BUILTIN(__builtin_ia32_vinsertf128_si256, "V8iV8iV4ic", "")
+BUILTIN(__builtin_ia32_vperm2f128_pd256, "V4dV4dV4dIc", "")
+BUILTIN(__builtin_ia32_vperm2f128_ps256, "V8fV8fV8fIc", "")
+BUILTIN(__builtin_ia32_vperm2f128_si256, "V8iV8iV8iIc", "")
+BUILTIN(__builtin_ia32_vpermilpd, "V2dV2dIc", "")
+BUILTIN(__builtin_ia32_vpermilps, "V4fV4fIc", "")
+BUILTIN(__builtin_ia32_vpermilpd256, "V4dV4dIc", "")
+BUILTIN(__builtin_ia32_vpermilps256, "V8fV8fIc", "")
+BUILTIN(__builtin_ia32_vinsertf128_pd256, "V4dV4dV2dIc", "")
+BUILTIN(__builtin_ia32_vinsertf128_ps256, "V8fV8fV4fIc", "")
+BUILTIN(__builtin_ia32_vinsertf128_si256, "V8iV8iV4iIc", "")
 BUILTIN(__builtin_ia32_sqrtpd256, "V4dV4d", "")
 BUILTIN(__builtin_ia32_sqrtps256, "V8fV8f", "")
 BUILTIN(__builtin_ia32_rsqrtps256, "V8fV8f", "")
 BUILTIN(__builtin_ia32_rcpps256, "V8fV8f", "")
-BUILTIN(__builtin_ia32_roundpd256, "V4dV4di", "")
-BUILTIN(__builtin_ia32_roundps256, "V8fV8fi", "")
+BUILTIN(__builtin_ia32_roundpd256, "V4dV4dIi", "")
+BUILTIN(__builtin_ia32_roundps256, "V8fV8fIi", "")
 BUILTIN(__builtin_ia32_vtestzpd, "iV2dV2d", "")
 BUILTIN(__builtin_ia32_vtestcpd, "iV2dV2d", "")
 BUILTIN(__builtin_ia32_vtestnzcpd, "iV2dV2d", "")

Modified: cfe/branches/tooling/include/clang/Basic/Diagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/Diagnostic.h?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/Diagnostic.h (original)
+++ cfe/branches/tooling/include/clang/Basic/Diagnostic.h Sat Dec 17 00:38:54 2011
@@ -158,6 +158,8 @@
   unsigned ErrorLimit;           // Cap of # errors emitted, 0 -> no limit.
   unsigned TemplateBacktraceLimit; // Cap on depth of template backtrace stack,
                                    // 0 -> no limit.
+  unsigned ConstexprBacktraceLimit; // Cap on depth of constexpr evaluation
+                                    // backtrace stack, 0 -> no limit.
   ExtensionHandling ExtBehavior; // Map extensions onto warnings or errors?
   llvm::IntrusiveRefCntPtr<DiagnosticIDs> Diags;
   DiagnosticConsumer *Client;
@@ -363,13 +365,25 @@
   void setTemplateBacktraceLimit(unsigned Limit) {
     TemplateBacktraceLimit = Limit;
   }
-  
+
   /// \brief Retrieve the maximum number of template instantiation
-  /// nodes to emit along with a given diagnostic.
+  /// notes to emit along with a given diagnostic.
   unsigned getTemplateBacktraceLimit() const {
     return TemplateBacktraceLimit;
   }
-  
+
+  /// \brief Specify the maximum number of constexpr evaluation
+  /// notes to emit along with a given diagnostic.
+  void setConstexprBacktraceLimit(unsigned Limit) {
+    ConstexprBacktraceLimit = Limit;
+  }
+
+  /// \brief Retrieve the maximum number of constexpr evaluation
+  /// notes to emit along with a given diagnostic.
+  unsigned getConstexprBacktraceLimit() const {
+    return ConstexprBacktraceLimit;
+  }
+
   /// setIgnoreAllWarnings - When set to true, any unmapped warnings are
   /// ignored.  If this and WarningsAsErrors are both set, then this one wins.
   void setIgnoreAllWarnings(bool Val) { IgnoreAllWarnings = Val; }

Modified: cfe/branches/tooling/include/clang/Basic/DiagnosticASTKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/DiagnosticASTKinds.td?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticASTKinds.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticASTKinds.td Sat Dec 17 00:38:54 2011
@@ -33,6 +33,10 @@
 def note_constexpr_temporary_here : Note<"temporary created here">;
 def note_constexpr_depth_limit_exceeded : Note<
   "constexpr evaluation exceeded maximum depth of %0 calls">;
+def note_constexpr_calls_suppressed : Note<
+  "(skipping %0 call%s0 in backtrace; use -fconstexpr-backtrace-limit=0 to "
+  "see all)">;
+def note_constexpr_call_here : Note<"in call to '%0'">;
 
 // inline asm related.
 let CategoryName = "Inline Assembly Issue" in {

Modified: cfe/branches/tooling/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/DiagnosticGroups.td?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticGroups.td Sat Dec 17 00:38:54 2011
@@ -186,6 +186,7 @@
 def UnknownPragmas : DiagGroup<"unknown-pragmas">;
 def NSobjectAttribute : DiagGroup<"NSObject-attribute">;
 def UnknownAttributes : DiagGroup<"attributes">;
+def IgnoredAttributes : DiagGroup<"ignored-attributes">;
 def UnnamedTypeTemplateArgs : DiagGroup<"unnamed-type-template-args",
                                         [CXX98CompatUnnamedTypeTemplateArgs]>;
 def UnusedArgument : DiagGroup<"unused-argument">;

Modified: cfe/branches/tooling/include/clang/Basic/DiagnosticLexKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/DiagnosticLexKinds.td?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticLexKinds.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticLexKinds.td Sat Dec 17 00:38:54 2011
@@ -202,8 +202,11 @@
   InGroup<CXX98CompatPedantic>, DefaultIgnore;
 def ext_named_variadic_macro : Extension<
   "named variadic macros are a GNU extension">, InGroup<VariadicMacros>;
+def err_embedded_include : Error<
+  "embedding a #%0 directive within macro arguments is not supported">;
 def ext_embedded_directive : Extension<
-  "embedding a directive within macro arguments is not portable">;
+  "embedding a directive within macro arguments has undefined behavior">,
+  InGroup<DiagGroup<"embedded-directive">>;
 def ext_missing_varargs_arg : Extension<
   "varargs argument missing, but tolerated as an extension">;
 def ext_empty_fnmacro_arg : Extension<

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=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/branches/tooling/include/clang/Basic/DiagnosticSemaKinds.td Sat Dec 17 00:38:54 2011
@@ -1465,6 +1465,8 @@
 def warn_attribute_ignored : Warning<"%0 attribute ignored">;
 def warn_unknown_attribute_ignored : Warning<
   "unknown attribute %0 ignored">, InGroup<UnknownAttributes>;
+def warn_declspec_attribute_ignored : Warning<
+  "attribute %0 is ignored, place it after \"%select{class|struct|union|enum}1\" to apply attribute to type declaration">, InGroup<IgnoredAttributes>;
 def warn_attribute_precede_definition : Warning<
   "attribute declaration must precede definition">;
 def warn_attribute_void_function_method : Warning<

Modified: cfe/branches/tooling/include/clang/Basic/TargetInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Basic/TargetInfo.h?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Basic/TargetInfo.h (original)
+++ cfe/branches/tooling/include/clang/Basic/TargetInfo.h Sat Dec 17 00:38:54 2011
@@ -76,6 +76,7 @@
   unsigned char LargeArrayMinWidth, LargeArrayAlign;
   unsigned char LongWidth, LongAlign;
   unsigned char LongLongWidth, LongLongAlign;
+  unsigned char SuitableAlign;
   unsigned char MaxAtomicPromoteWidth, MaxAtomicInlineWidth;
   const char *DescriptionString;
   const char *UserLabelPrefix;
@@ -212,6 +213,10 @@
   unsigned getLongLongWidth() const { return LongLongWidth; }
   unsigned getLongLongAlign() const { return LongLongAlign; }
 
+  /// getSuitableAlign - Return the alignment that is suitable for storing any
+  /// object with a fundamental alignment requirement.
+  unsigned getSuitableAlign() const { return SuitableAlign; }
+
   /// getWCharWidth/Align - Return the size of 'wchar_t' for this target, in
   /// bits.
   unsigned getWCharWidth() const { return getTypeWidth(WCharType); }

Modified: cfe/branches/tooling/include/clang/Driver/CC1Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Driver/CC1Options.td?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Driver/CC1Options.td (original)
+++ cfe/branches/tooling/include/clang/Driver/CC1Options.td Sat Dec 17 00:38:54 2011
@@ -291,6 +291,8 @@
   HelpText<"Set the maximum number of entries to print in a macro expansion backtrace (0 = no limit).">;
 def ftemplate_backtrace_limit : Separate<"-ftemplate-backtrace-limit">, MetaVarName<"<N>">,
   HelpText<"Set the maximum number of entries to print in a template instantiation backtrace (0 = no limit).">;
+def fconstexpr_backtrace_limit : Separate<"-fconstexpr-backtrace-limit">, MetaVarName<"<N>">,
+  HelpText<"Set the maximum number of entries to print in a constexpr evaluation backtrace (0 = no limit).">;
 def fmessage_length : Separate<"-fmessage-length">, MetaVarName<"<N>">,
   HelpText<"Format message diagnostics so that they fit within N columns or fewer, when possible.">;
 def fcolor_diagnostics : Flag<"-fcolor-diagnostics">,

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=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Driver/Options.td (original)
+++ cfe/branches/tooling/include/clang/Driver/Options.td Sat Dec 17 00:38:54 2011
@@ -290,6 +290,9 @@
 def fcompile_resource_EQ : Joined<"-fcompile-resource=">, Group<f_Group>;
 def fconstant_cfstrings : Flag<"-fconstant-cfstrings">, Group<f_Group>;
 def fconstant_string_class_EQ : Joined<"-fconstant-string-class=">, Group<f_Group>;
+def fconstexpr_depth_EQ : Joined<"-fconstexpr-depth=">, Group<f_Group>;
+def fconstexpr_backtrace_limit_EQ : Joined<"-fconstexpr-backtrace-limit=">,
+                                    Group<f_Group>;
 def fcreate_profile : Flag<"-fcreate-profile">, Group<f_Group>;
 def fcxx_exceptions: Flag<"-fcxx-exceptions">, Group<f_Group>;
 def fdebug_pass_arguments : Flag<"-fdebug-pass-arguments">, Group<f_Group>;
@@ -490,7 +493,6 @@
 def ftabstop_EQ : Joined<"-ftabstop=">, Group<f_Group>;
 def ftemplate_depth_EQ : Joined<"-ftemplate-depth=">, Group<f_Group>;
 def ftemplate_depth_ : Joined<"-ftemplate-depth-">, Group<f_Group>;
-def fconstexpr_depth_EQ : Joined<"-fconstexpr-depth=">, Group<f_Group>;
 def ftemplate_backtrace_limit_EQ : Joined<"-ftemplate-backtrace-limit=">,
                                    Group<f_Group>;
 def ftest_coverage : Flag<"-ftest-coverage">, Group<f_Group>;

Modified: cfe/branches/tooling/include/clang/Frontend/DiagnosticOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Frontend/DiagnosticOptions.h?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Frontend/DiagnosticOptions.h (original)
+++ cfe/branches/tooling/include/clang/Frontend/DiagnosticOptions.h Sat Dec 17 00:38:54 2011
@@ -51,12 +51,14 @@
   unsigned ErrorLimit;           /// Limit # errors emitted.
   unsigned MacroBacktraceLimit;  /// Limit depth of macro expansion backtrace.
   unsigned TemplateBacktraceLimit; /// Limit depth of instantiation backtrace.
+  unsigned ConstexprBacktraceLimit; /// Limit depth of constexpr backtrace.
 
   /// The distance between tab stops.
   unsigned TabStop;
   enum { DefaultTabStop = 8, MaxTabStop = 100, 
          DefaultMacroBacktraceLimit = 6,
-         DefaultTemplateBacktraceLimit = 10 };
+         DefaultTemplateBacktraceLimit = 10,
+         DefaultConstexprBacktraceLimit = 10 };
 
   /// Column limit for formatting message diagnostics, or 0 if unused.
   unsigned MessageLength;
@@ -99,6 +101,7 @@
     ErrorLimit = 0;
     TemplateBacktraceLimit = DefaultTemplateBacktraceLimit;
     MacroBacktraceLimit = DefaultMacroBacktraceLimit;
+    ConstexprBacktraceLimit = DefaultConstexprBacktraceLimit;
   }
 };
 

Modified: cfe/branches/tooling/include/clang/Frontend/SerializedDiagnosticPrinter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Frontend/SerializedDiagnosticPrinter.h?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Frontend/SerializedDiagnosticPrinter.h (original)
+++ cfe/branches/tooling/include/clang/Frontend/SerializedDiagnosticPrinter.h Sat Dec 17 00:38:54 2011
@@ -19,6 +19,7 @@
 namespace clang {
 class DiagnosticConsumer;
 class DiagnosticsEngine;
+class DiagnosticOptions;
 
 namespace serialized_diags {
   
@@ -52,7 +53,8 @@
 /// This allows wrapper tools for Clang to get diagnostics from Clang
 /// (via libclang) without needing to parse Clang's command line output.
 ///
-DiagnosticConsumer *create(llvm::raw_ostream *OS);
+DiagnosticConsumer *create(llvm::raw_ostream *OS,
+                           const DiagnosticOptions &diags);
 
 } // end serialized_diags namespace
 } // end clang namespace

Modified: cfe/branches/tooling/include/clang/Frontend/TextDiagnostic.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/Frontend/TextDiagnostic.h?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Frontend/TextDiagnostic.h (original)
+++ cfe/branches/tooling/include/clang/Frontend/TextDiagnostic.h Sat Dec 17 00:38:54 2011
@@ -16,14 +16,9 @@
 #ifndef LLVM_CLANG_FRONTEND_TEXT_DIAGNOSTIC_H_
 #define LLVM_CLANG_FRONTEND_TEXT_DIAGNOSTIC_H_
 
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/SourceLocation.h"
+#include "clang/Frontend/DiagnosticRenderer.h"
 
 namespace clang {
-class DiagnosticOptions;
-class LangOptions;
-class SourceManager;
 
 /// \brief Class to encapsulate the logic for formatting and printing a textual
 /// diagnostic message.
@@ -37,34 +32,8 @@
 /// beautiful text diagnostics from any particular interfaces. The Clang
 /// DiagnosticClient is implemented through this class as is diagnostic
 /// printing coming out of libclang.
-///
-/// A brief worklist:
-/// FIXME: Sink the recursive printing of template instantiations into this
-/// class.
-class TextDiagnostic {
+class TextDiagnostic : public DiagnosticRenderer {
   raw_ostream &OS;
-  const SourceManager &SM;
-  const LangOptions &LangOpts;
-  const DiagnosticOptions &DiagOpts;
-
-  /// \brief The location of the previous diagnostic if known.
-  ///
-  /// This will be invalid in cases where there is no (known) previous
-  /// diagnostic location, or that location itself is invalid or comes from
-  /// a different source manager than SM.
-  SourceLocation LastLoc;
-
-  /// \brief The location of the last include whose stack was printed if known.
-  ///
-  /// Same restriction as \see LastLoc essentially, but tracking include stack
-  /// root locations rather than diagnostic locations.
-  SourceLocation LastIncludeLoc;
-
-  /// \brief The level of the last diagnostic emitted.
-  ///
-  /// The level of the last diagnostic emitted. Used to detect level changes
-  /// which change the amount of information displayed.
-  DiagnosticsEngine::Level LastLevel;
 
 public:
   TextDiagnostic(raw_ostream &OS,
@@ -72,22 +41,8 @@
                  const LangOptions &LangOpts,
                  const DiagnosticOptions &DiagOpts);
 
-  /// \brief Emit a textual diagnostic.
-  ///
-  /// This is the primary entry point for emitting textual diagnostic messages.
-  /// It handles formatting and printing the message as well as any ancillary
-  /// information needed based on macros whose expansions impact the
-  /// diagnostic.
-  ///
-  /// \param Loc The location for this caret.
-  /// \param Level The level of the diagnostic to be emitted.
-  /// \param Message The diagnostic message to emit.
-  /// \param Ranges The underlined ranges for this code snippet.
-  /// \param FixItHints The FixIt hints active for this diagnostic.
-  void emitDiagnostic(SourceLocation Loc, DiagnosticsEngine::Level Level,
-                      StringRef Message, ArrayRef<CharSourceRange> Ranges,
-                      ArrayRef<FixItHint> FixItHints);
-
+  virtual ~TextDiagnostic();
+  
   /// \brief Print the diagonstic level to a raw_ostream.
   ///
   /// This is a static helper that handles colorizing the level and formatting
@@ -121,18 +76,29 @@
                                      unsigned CurrentColumn, unsigned Columns,
                                      bool ShowColors);
 
+protected:
+  virtual void emitDiagnosticMessage(SourceLocation Loc,PresumedLoc PLoc,
+                                     DiagnosticsEngine::Level Level,
+                                     StringRef Message,
+                                     ArrayRef<CharSourceRange> Ranges,
+                                     const Diagnostic *Info);
+
+  virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
+                                 DiagnosticsEngine::Level Level,
+                                 ArrayRef<CharSourceRange> Ranges);
+  
+  virtual void emitCodeContext(SourceLocation Loc,
+                               DiagnosticsEngine::Level Level,
+                               SmallVectorImpl<CharSourceRange>& Ranges,
+                               ArrayRef<FixItHint> Hints) {
+    emitSnippetAndCaret(Loc, Level, Ranges, Hints);
+  }
+  
+  virtual void emitBasicNote(StringRef Message);
+  
+  virtual void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc);
+
 private:
-  void emitIncludeStack(SourceLocation Loc, DiagnosticsEngine::Level Level);
-  void emitIncludeStackRecursively(SourceLocation Loc);
-  void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
-                         DiagnosticsEngine::Level Level,
-                         ArrayRef<CharSourceRange> Ranges);
-  void emitMacroExpansionsAndCarets(SourceLocation Loc,
-                                    DiagnosticsEngine::Level Level,
-                                    SmallVectorImpl<CharSourceRange>& Ranges,
-                                    ArrayRef<FixItHint> Hints,
-                                    unsigned &MacroDepth,
-                                    unsigned OnMacroInst = 0);
   void emitSnippetAndCaret(SourceLocation Loc, DiagnosticsEngine::Level Level,
                            SmallVectorImpl<CharSourceRange>& Ranges,
                            ArrayRef<FixItHint> Hints);

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=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/Sema/Sema.h (original)
+++ cfe/branches/tooling/include/clang/Sema/Sema.h Sat Dec 17 00:38:54 2011
@@ -3250,6 +3250,13 @@
                                        UnqualifiedId &SecondTypeName,
                                        bool HasTrailingLParen);
 
+  ExprResult ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
+                                       SourceLocation OpLoc,
+                                       tok::TokenKind OpKind,
+                                       SourceLocation TildeLoc, 
+                                       const DeclSpec& DS,
+                                       bool HasTrailingLParen);
+
   /// MaybeCreateExprWithCleanups - If the current full-expression
   /// requires any cleanups, surround it with a ExprWithCleanups node.
   /// Otherwise, just returns the passed-in expression.
@@ -6193,7 +6200,7 @@
 private:
   void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
                         const ArraySubscriptExpr *ASE=0,
-                        bool AllowOnePastEnd=true);
+                        bool AllowOnePastEnd=true, bool IndexNegated=false);
   void CheckArrayAccess(const Expr *E);
   bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall);
   bool CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall);

Modified: cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h (original)
+++ cfe/branches/tooling/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h Sat Dec 17 00:38:54 2011
@@ -34,7 +34,10 @@
     : Eng(eng),
       Pred(pred),
       Location(loc),
-      NB(builder) {}
+      NB(builder) {
+    assert(Pred->getState() &&
+           "We should not call the checkers on an empty state.");
+  }
 
   AnalysisManager &getAnalysisManager() {
     return Eng.getAnalysisManager();

Modified: cfe/branches/tooling/lib/AST/APValue.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/APValue.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/APValue.cpp (original)
+++ cfe/branches/tooling/lib/AST/APValue.cpp Sat Dec 17 00:38:54 2011
@@ -12,7 +12,11 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/APValue.h"
+#include "clang/AST/ASTContext.h"
 #include "clang/AST/CharUnits.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/Type.h"
 #include "clang/Basic/Diagnostic.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/raw_ostream.h"
@@ -203,7 +207,7 @@
 }
 
 void APValue::dump() const {
-  print(llvm::errs());
+  dump(llvm::errs());
   llvm::errs() << '\n';
 }
 
@@ -215,7 +219,7 @@
   return V.convertToDouble();
 }
 
-void APValue::print(raw_ostream &OS) const {
+void APValue::dump(raw_ostream &OS) const {
   switch (getKind()) {
   case Uninitialized:
     OS << "Uninitialized";
@@ -227,9 +231,12 @@
     OS << "Float: " << GetApproxValue(getFloat());
     return;
   case Vector:
-    OS << "Vector: " << getVectorElt(0);
-    for (unsigned i = 1; i != getVectorLength(); ++i)
-      OS << ", " << getVectorElt(i);
+    OS << "Vector: ";
+    getVectorElt(0).dump(OS);
+    for (unsigned i = 1; i != getVectorLength(); ++i) {
+      OS << ", ";
+      getVectorElt(i).dump(OS);
+    }
     return;
   case ComplexInt:
     OS << "ComplexInt: " << getComplexIntReal() << ", " << getComplexIntImag();
@@ -244,28 +251,36 @@
   case Array:
     OS << "Array: ";
     for (unsigned I = 0, N = getArrayInitializedElts(); I != N; ++I) {
-      OS << getArrayInitializedElt(I);
+      getArrayInitializedElt(I).dump(OS);
       if (I != getArraySize() - 1) OS << ", ";
     }
-    if (hasArrayFiller())
-      OS << getArraySize() - getArrayInitializedElts() << " x "
-         << getArrayFiller();
+    if (hasArrayFiller()) {
+      OS << getArraySize() - getArrayInitializedElts() << " x ";
+      getArrayFiller().dump(OS);
+    }
     return;
   case Struct:
     OS << "Struct ";
     if (unsigned N = getStructNumBases()) {
-      OS << " bases: " << getStructBase(0);
-      for (unsigned I = 1; I != N; ++I)
-        OS << ", " << getStructBase(I);
+      OS << " bases: ";
+      getStructBase(0).dump(OS);
+      for (unsigned I = 1; I != N; ++I) {
+        OS << ", ";
+        getStructBase(I).dump(OS);
+      }
     }
     if (unsigned N = getStructNumFields()) {
-      OS << " fields: " << getStructField(0);
-      for (unsigned I = 1; I != N; ++I)
-        OS << ", " << getStructField(I);
+      OS << " fields: ";
+      getStructField(0).dump(OS);
+      for (unsigned I = 1; I != N; ++I) {
+        OS << ", ";
+        getStructField(I).dump(OS);
+      }
     }
     return;
   case Union:
-    OS << "Union: " << getUnionValue();
+    OS << "Union: ";
+    getUnionValue().dump(OS);
     return;
   case MemberPointer:
     OS << "MemberPointer: <todo>";
@@ -274,78 +289,199 @@
   llvm_unreachable("Unknown APValue kind!");
 }
 
-static void WriteShortAPValueToStream(raw_ostream& Out,
-                                      const APValue& V) {
-  switch (V.getKind()) {
+void APValue::printPretty(raw_ostream &Out, ASTContext &Ctx, QualType Ty) const{
+  switch (getKind()) {
   case APValue::Uninitialized:
-    Out << "Uninitialized";
+    Out << "<uninitialized>";
     return;
   case APValue::Int:
-    Out << V.getInt();
+    Out << getInt();
     return;
   case APValue::Float:
-    Out << GetApproxValue(V.getFloat());
+    Out << GetApproxValue(getFloat());
     return;
-  case APValue::Vector:
-    Out << '[';
-    WriteShortAPValueToStream(Out, V.getVectorElt(0));
-    for (unsigned i = 1; i != V.getVectorLength(); ++i) {
+  case APValue::Vector: {
+    Out << '{';
+    QualType ElemTy = Ty->getAs<VectorType>()->getElementType();
+    getVectorElt(0).printPretty(Out, Ctx, ElemTy);
+    for (unsigned i = 1; i != getVectorLength(); ++i) {
       Out << ", ";
-      WriteShortAPValueToStream(Out, V.getVectorElt(i));
+      getVectorElt(i).printPretty(Out, Ctx, ElemTy);
     }
-    Out << ']';
+    Out << '}';
     return;
+  }
   case APValue::ComplexInt:
-    Out << V.getComplexIntReal() << "+" << V.getComplexIntImag() << "i";
+    Out << getComplexIntReal() << "+" << getComplexIntImag() << "i";
     return;
   case APValue::ComplexFloat:
-    Out << GetApproxValue(V.getComplexFloatReal()) << "+"
-        << GetApproxValue(V.getComplexFloatImag()) << "i";
+    Out << GetApproxValue(getComplexFloatReal()) << "+"
+        << GetApproxValue(getComplexFloatImag()) << "i";
     return;
-  case APValue::LValue:
-    Out << "LValue: <todo>";
+  case APValue::LValue: {
+    LValueBase Base = getLValueBase();
+    if (!Base) {
+      Out << "0";
+      return;
+    }
+
+    bool IsReference = Ty->isReferenceType();
+    QualType InnerTy
+      = IsReference ? Ty.getNonReferenceType() : Ty->getPointeeType();
+
+    if (!hasLValuePath()) {
+      // No lvalue path: just print the offset.
+      CharUnits O = getLValueOffset();
+      CharUnits S = Ctx.getTypeSizeInChars(InnerTy);
+      if (!O.isZero()) {
+        if (IsReference)
+          Out << "*(";
+        if (O % S) {
+          Out << "(char*)";
+          S = CharUnits::One();
+        }
+        Out << '&';
+      } else if (!IsReference)
+        Out << '&';
+
+      if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>())
+        Out << *VD;
+      else
+        Base.get<const Expr*>()->printPretty(Out, Ctx, 0,
+                                             Ctx.getPrintingPolicy());
+      if (!O.isZero()) {
+        Out << " + " << (O / S);
+        if (IsReference)
+          Out << ')';
+      }
+      return;
+    }
+
+    // We have an lvalue path. Print it out nicely.
+    if (!IsReference)
+      Out << '&';
+    else if (isLValueOnePastTheEnd())
+      Out << "*(&";
+
+    QualType ElemTy;
+    if (const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>()) {
+      Out << *VD;
+      ElemTy = VD->getType();
+    } else {
+      const Expr *E = Base.get<const Expr*>();
+      E->printPretty(Out, Ctx, 0,Ctx.getPrintingPolicy());
+      ElemTy = E->getType();
+    }
+
+    ArrayRef<LValuePathEntry> Path = getLValuePath();
+    const CXXRecordDecl *CastToBase = 0;
+    for (unsigned I = 0, N = Path.size(); I != N; ++I) {
+      if (ElemTy->getAs<RecordType>()) {
+        // The lvalue refers to a class type, so the next path entry is a base
+        // or member.
+        const Decl *BaseOrMember =
+        BaseOrMemberType::getFromOpaqueValue(Path[I].BaseOrMember).getPointer();
+        if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(BaseOrMember)) {
+          CastToBase = RD;
+          ElemTy = Ctx.getRecordType(RD);
+        } else {
+          const ValueDecl *VD = cast<ValueDecl>(BaseOrMember);
+          Out << ".";
+          if (CastToBase)
+            Out << *CastToBase << "::";
+          Out << *VD;
+          ElemTy = VD->getType();
+        }
+      } else {
+        // The lvalue must refer to an array.
+        Out << '[' << Path[I].ArrayIndex << ']';
+        ElemTy = Ctx.getAsArrayType(ElemTy)->getElementType();
+      }
+    }
+
+    // Handle formatting of one-past-the-end lvalues.
+    if (isLValueOnePastTheEnd()) {
+      // FIXME: If CastToBase is non-0, we should prefix the output with
+      // "(CastToBase*)".
+      Out << " + 1";
+      if (IsReference)
+        Out << ')';
+    }
     return;
-  case APValue::Array:
+  }
+  case APValue::Array: {
+    const ArrayType *AT = Ctx.getAsArrayType(Ty);
+    QualType ElemTy = AT->getElementType();
     Out << '{';
-    if (unsigned N = V.getArrayInitializedElts()) {
-      Out << V.getArrayInitializedElt(0);
-      for (unsigned I = 1; I != N; ++I)
-        Out << ", " << V.getArrayInitializedElt(I);
+    if (unsigned N = getArrayInitializedElts()) {
+      getArrayInitializedElt(0).printPretty(Out, Ctx, ElemTy);
+      for (unsigned I = 1; I != N; ++I) {
+        Out << ", ";
+        if (I == 10) {
+          // Avoid printing out the entire contents of large arrays.
+          Out << "...";
+          break;
+        }
+        getArrayInitializedElt(I).printPretty(Out, Ctx, ElemTy);
+      }
     }
     Out << '}';
     return;
-  case APValue::Struct:
+  }
+  case APValue::Struct: {
     Out << '{';
-    if (unsigned N = V.getStructNumBases()) {
-      Out << V.getStructBase(0);
-      for (unsigned I = 1; I != N; ++I)
-        Out << ", " << V.getStructBase(I);
-      if (V.getStructNumFields())
-        Out << ", ";
+    const RecordDecl *RD = Ty->getAs<RecordType>()->getDecl();
+    bool First = true;
+    if (unsigned N = getStructNumBases()) {
+      const CXXRecordDecl *CD = cast<CXXRecordDecl>(RD);
+      CXXRecordDecl::base_class_const_iterator BI = CD->bases_begin();
+      for (unsigned I = 0; I != N; ++I, ++BI) {
+        assert(BI != CD->bases_end());
+        if (!First)
+          Out << ", ";
+        getStructBase(I).printPretty(Out, Ctx, BI->getType());
+        First = false;
+      }
     }
-    if (unsigned N = V.getStructNumFields()) {
-      Out << V.getStructField(0);
-      for (unsigned I = 1; I != N; ++I)
-        Out << ", " << V.getStructField(I);
+    for (RecordDecl::field_iterator FI = RD->field_begin();
+         FI != RD->field_end(); ++FI) {
+      if (!First)
+        Out << ", ";
+      if ((*FI)->isUnnamedBitfield()) continue;
+      getStructField((*FI)->getFieldIndex()).
+        printPretty(Out, Ctx, (*FI)->getType());
+      First = false;
     }
     Out << '}';
     return;
+  }
   case APValue::Union:
-    Out << '{' << V.getUnionValue() << '}';
+    Out << '{';
+    if (const FieldDecl *FD = getUnionField()) {
+      Out << "." << *FD << " = ";
+      getUnionValue().printPretty(Out, Ctx, FD->getType());
+    }
+    Out << '}';
     return;
   case APValue::MemberPointer:
-    Out << "MemberPointer: <todo>";
+    // FIXME: This is not enough to unambiguously identify the member in a
+    // multiple-inheritance scenario.
+    if (const ValueDecl *VD = getMemberPointerDecl()) {
+      Out << '&' << *cast<CXXRecordDecl>(VD->getDeclContext()) << "::" << *VD;
+      return;
+    }
+    Out << "0";
     return;
   }
   llvm_unreachable("Unknown APValue kind!");
 }
 
-const DiagnosticBuilder &clang::operator<<(const DiagnosticBuilder &DB,
-                                           const APValue &V) {
-  llvm::SmallString<64> Buffer;
-  llvm::raw_svector_ostream Out(Buffer);
-  WriteShortAPValueToStream(Out, V);
-  return DB << Out.str();
+std::string APValue::getAsString(ASTContext &Ctx, QualType Ty) const {
+  std::string Result;
+  llvm::raw_string_ostream Out(Result);
+  printPretty(Out, Ctx, Ty);
+  Out.flush();
+  return Result;
 }
 
 const APValue::LValueBase APValue::getLValueBase() const {

Modified: cfe/branches/tooling/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/ASTContext.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/ASTContext.cpp (original)
+++ cfe/branches/tooling/lib/AST/ASTContext.cpp Sat Dec 17 00:38:54 2011
@@ -2808,11 +2808,21 @@
 
 /// getObjCInterfaceType - Return the unique reference to the type for the
 /// specified ObjC interface decl. The list of protocols is optional.
-QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl) const {
+QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
+                                          ObjCInterfaceDecl *PrevDecl) const {
   if (Decl->TypeForDecl)
     return QualType(Decl->TypeForDecl, 0);
 
-  // FIXME: redeclarations?
+  if (PrevDecl) {
+    assert(PrevDecl->TypeForDecl && "previous decl has no TypeForDecl");
+    Decl->TypeForDecl = PrevDecl->TypeForDecl;
+    return QualType(PrevDecl->TypeForDecl, 0);
+  }
+
+  // Prefer the definition, if there is one.
+  if (const ObjCInterfaceDecl *Def = Decl->getDefinition())
+    Decl = Def;
+  
   void *Mem = Allocate(sizeof(ObjCInterfaceType), TypeAlignment);
   ObjCInterfaceType *T = new (Mem) ObjCInterfaceType(Decl);
   Decl->TypeForDecl = T;

Modified: cfe/branches/tooling/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/ASTImporter.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/ASTImporter.cpp (original)
+++ cfe/branches/tooling/lib/AST/ASTImporter.cpp Sat Dec 17 00:38:54 2011
@@ -3182,7 +3182,8 @@
     if (!ToIface) {
       ToIface = ObjCInterfaceDecl::Create(Importer.getToContext(), DC,
                                           Importer.Import(D->getAtStartLoc()),
-                                          Name.getAsIdentifierInfo(), Loc,
+                                          Name.getAsIdentifierInfo(), 
+                                          /*PrevDecl=*/0,Loc,
                                           D->isImplicitInterfaceDecl());
       ToIface->setLexicalDeclContext(LexicalDC);
       LexicalDC->addDeclInternal(ToIface);

Modified: cfe/branches/tooling/lib/AST/DeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/DeclObjC.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/DeclObjC.cpp (original)
+++ cfe/branches/tooling/lib/AST/DeclObjC.cpp Sat Dec 17 00:38:54 2011
@@ -226,17 +226,22 @@
   assert(!hasDefinition() && "ObjC class already has a definition");
   Data = new (getASTContext()) DefinitionData();
   Data->Definition = this;
-  
+
+  // Make the type point at the definition, now that we have one.
+  if (TypeForDecl)
+    cast<ObjCInterfaceType>(TypeForDecl)->Decl = this;
+}
+
+void ObjCInterfaceDecl::startDefinition() {
+  allocateDefinitionData();
+
   // Update all of the declarations with a pointer to the definition.
   for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
        RD != RDEnd; ++RD) {
     if (*RD != this)
       RD->Data = Data;
   }
-}
 
-void ObjCInterfaceDecl::startDefinition() {
-  allocateDefinitionData();
   if (ASTMutationListener *L = getASTContext().getASTMutationListener())
     L->CompletedObjCForwardRef(this);
 }
@@ -674,17 +679,33 @@
                                              DeclContext *DC,
                                              SourceLocation atLoc,
                                              IdentifierInfo *Id,
+                                             ObjCInterfaceDecl *PrevDecl,
                                              SourceLocation ClassLoc,
                                              bool isInternal){
-  return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, isInternal);
+  ObjCInterfaceDecl *Result = new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, 
+                                                        PrevDecl, isInternal);
+  C.getObjCInterfaceType(Result, PrevDecl);
+  return Result;
+}
+
+ObjCInterfaceDecl *ObjCInterfaceDecl::CreateEmpty(ASTContext &C) {
+  return new (C) ObjCInterfaceDecl(0, SourceLocation(), 0, SourceLocation(),
+                                   0, false);
 }
 
 ObjCInterfaceDecl::
 ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
-                  SourceLocation CLoc, bool isInternal)
+                  SourceLocation CLoc, ObjCInterfaceDecl *PrevDecl,
+                  bool isInternal)
   : ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, atLoc),
     TypeForDecl(0), Data()
 {
+  setPreviousDeclaration(PrevDecl);
+  
+  // Copy the 'data' pointer over.
+  if (PrevDecl)
+    Data = PrevDecl->Data;
+  
   setImplicit(isInternal);
 }
 
@@ -851,14 +872,6 @@
   return false;
 }
 
-void ObjCInterfaceDecl::setPreviousDeclaration(ObjCInterfaceDecl *PrevDecl) {
-  redeclarable_base::setPreviousDeclaration(PrevDecl);
-  
-  // Inherit the 'Data' pointer from the previous declaration.
-  if (PrevDecl)
-    Data = PrevDecl->Data;
-}
-
 //===----------------------------------------------------------------------===//
 // ObjCIvarDecl
 //===----------------------------------------------------------------------===//

Modified: cfe/branches/tooling/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/AST/ExprConstant.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/AST/ExprConstant.cpp (original)
+++ cfe/branches/tooling/lib/AST/ExprConstant.cpp Sat Dec 17 00:38:54 2011
@@ -231,6 +231,12 @@
     /// Parent - The caller of this stack frame.
     CallStackFrame *Caller;
 
+    /// CallLoc - The location of the call expression for this call.
+    SourceLocation CallLoc;
+
+    /// Callee - The function which was called.
+    const FunctionDecl *Callee;
+
     /// This - The binding for the this pointer in this call, if any.
     const LValue *This;
 
@@ -243,7 +249,8 @@
     /// Temporaries - Temporary lvalues materialized within this stack frame.
     MapTy Temporaries;
 
-    CallStackFrame(EvalInfo &Info, const LValue *This,
+    CallStackFrame(EvalInfo &Info, SourceLocation CallLoc,
+                   const FunctionDecl *Callee, const LValue *This,
                    const CCValue *Arguments);
     ~CallStackFrame();
   };
@@ -300,8 +307,8 @@
 
     EvalInfo(const ASTContext &C, Expr::EvalStatus &S)
       : Ctx(const_cast<ASTContext&>(C)), EvalStatus(S), CurrentCall(0),
-        CallStackDepth(0), BottomFrame(*this, 0, 0), EvaluatingDecl(0),
-        EvaluatingDeclValue(0), HasActiveDiagnostic(false) {}
+        CallStackDepth(0), BottomFrame(*this, SourceLocation(), 0, 0, 0),
+        EvaluatingDecl(0), EvaluatingDeclValue(0), HasActiveDiagnostic(false) {}
 
     const CCValue *getOpaqueValue(const OpaqueValueExpr *e) const {
       MapTy::const_iterator i = OpaqueValues.find(e);
@@ -332,6 +339,9 @@
       return EvalStatus.Diag->back().second;
     }
 
+    /// Add notes containing a call stack to the current point of evaluation.
+    void addCallStack(unsigned Limit);
+
   public:
     /// Diagnose that the evaluation cannot be folded.
     OptionalDiagnostic Diag(SourceLocation Loc, diag::kind DiagId,
@@ -340,11 +350,17 @@
       // isn't a constant expression. This diagnostic is more important.
       // FIXME: We might want to show both diagnostics to the user.
       if (EvalStatus.Diag) {
+        unsigned CallStackNotes = CallStackDepth - 1;
+        unsigned Limit = Ctx.getDiagnostics().getConstexprBacktraceLimit();
+        if (Limit)
+          CallStackNotes = std::min(CallStackNotes, Limit + 1);
+
         HasActiveDiagnostic = true;
         EvalStatus.Diag->clear();
-        EvalStatus.Diag->reserve(1 + ExtraNotes);
-        // FIXME: Add a call stack for constexpr evaluation.
-        return OptionalDiagnostic(&addDiag(Loc, DiagId));
+        EvalStatus.Diag->reserve(1 + ExtraNotes + CallStackNotes);
+        addDiag(Loc, DiagId);
+        addCallStack(Limit);
+        return OptionalDiagnostic(&(*EvalStatus.Diag)[0].second);
       }
       HasActiveDiagnostic = false;
       return OptionalDiagnostic();
@@ -367,20 +383,87 @@
       return OptionalDiagnostic(&addDiag(Loc, DiagId));
     }
   };
+}
 
-  CallStackFrame::CallStackFrame(EvalInfo &Info, const LValue *This,
-                                 const CCValue *Arguments)
-      : Info(Info), Caller(Info.CurrentCall), This(This), Arguments(Arguments) {
-    Info.CurrentCall = this;
-    ++Info.CallStackDepth;
-  }
+CallStackFrame::CallStackFrame(EvalInfo &Info, SourceLocation CallLoc,
+                               const FunctionDecl *Callee, const LValue *This,
+                               const CCValue *Arguments)
+    : Info(Info), Caller(Info.CurrentCall), CallLoc(CallLoc), Callee(Callee),
+      This(This), Arguments(Arguments) {
+  Info.CurrentCall = this;
+  ++Info.CallStackDepth;
+}
+
+CallStackFrame::~CallStackFrame() {
+  assert(Info.CurrentCall == this && "calls retired out of order");
+  --Info.CallStackDepth;
+  Info.CurrentCall = Caller;
+}
+
+/// Produce a string describing the given constexpr call.
+static void describeCall(CallStackFrame *Frame, llvm::raw_ostream &Out) {
+  unsigned ArgIndex = 0;
+  bool IsMemberCall = isa<CXXMethodDecl>(Frame->Callee) &&
+                      !isa<CXXConstructorDecl>(Frame->Callee);
+
+  if (!IsMemberCall)
+    Out << *Frame->Callee << '(';
+
+  for (FunctionDecl::param_const_iterator I = Frame->Callee->param_begin(),
+       E = Frame->Callee->param_end(); I != E; ++I, ++ArgIndex) {
+    if (ArgIndex > IsMemberCall)
+      Out << ", ";
+
+    const ParmVarDecl *Param = *I;
+    const CCValue &Arg = Frame->Arguments[ArgIndex];
+    if (!Arg.isLValue() || Arg.getLValueDesignator().Invalid)
+      Arg.printPretty(Out, Frame->Info.Ctx, Param->getType());
+    else {
+      // Deliberately slice off the frame to form an APValue we can print.
+      APValue Value(Arg.getLValueBase(), Arg.getLValueOffset(),
+                    Arg.getLValueDesignator().Entries,
+                    Arg.getLValueDesignator().OnePastTheEnd);
+      Value.printPretty(Out, Frame->Info.Ctx, Param->getType());
+    }
+
+    if (ArgIndex == 0 && IsMemberCall)
+      Out << "->" << *Frame->Callee << '(';
+  }
+
+  Out << ')';
+}
+
+void EvalInfo::addCallStack(unsigned Limit) {
+  // Determine which calls to skip, if any.
+  unsigned ActiveCalls = CallStackDepth - 1;
+  unsigned SkipStart = ActiveCalls, SkipEnd = SkipStart;
+  if (Limit && Limit < ActiveCalls) {
+    SkipStart = Limit / 2 + Limit % 2;
+    SkipEnd = ActiveCalls - Limit / 2;
+  }
+
+  // Walk the call stack and add the diagnostics.
+  unsigned CallIdx = 0;
+  for (CallStackFrame *Frame = CurrentCall; Frame != &BottomFrame;
+       Frame = Frame->Caller, ++CallIdx) {
+    // Skip this call?
+    if (CallIdx >= SkipStart && CallIdx < SkipEnd) {
+      if (CallIdx == SkipStart) {
+        // Note that we're skipping calls.
+        addDiag(Frame->CallLoc, diag::note_constexpr_calls_suppressed)
+          << unsigned(ActiveCalls - Limit);
+      }
+      continue;
+    }
 
-  CallStackFrame::~CallStackFrame() {
-    assert(Info.CurrentCall == this && "calls retired out of order");
-    --Info.CallStackDepth;
-    Info.CurrentCall = Caller;
+    llvm::SmallVector<char, 128> Buffer;
+    llvm::raw_svector_ostream Out(Buffer);
+    describeCall(Frame, Out);
+    addDiag(Frame->CallLoc, diag::note_constexpr_call_here) << Out.str();
   }
+}
 
+namespace {
   struct ComplexValue {
   private:
     bool IsInt;
@@ -1465,7 +1548,8 @@
 }
 
 /// Evaluate a function call.
-static bool HandleFunctionCall(const Expr *CallExpr, const LValue *This,
+static bool HandleFunctionCall(const Expr *CallExpr, const FunctionDecl *Callee,
+                               const LValue *This,
                                ArrayRef<const Expr*> Args, const Stmt *Body,
                                EvalInfo &Info, APValue &Result) {
   if (!Info.CheckCallLimit(CallExpr->getExprLoc()))
@@ -1475,7 +1559,8 @@
   if (!EvaluateArgs(Args, ArgValues, Info))
     return false;
 
-  CallStackFrame Frame(Info, This, ArgValues.data());
+  CallStackFrame Frame(Info, CallExpr->getExprLoc(), Callee, This,
+                       ArgValues.data());
   return EvaluateStmt(Result, Info, Body) == ESR_Returned;
 }
 
@@ -1492,7 +1577,8 @@
   if (!EvaluateArgs(Args, ArgValues, Info))
     return false;
 
-  CallStackFrame Frame(Info, &This, ArgValues.data());
+  CallStackFrame Frame(Info, CallExpr->getExprLoc(), Definition,
+                       &This, ArgValues.data());
 
   // If it's a delegating constructor, just delegate.
   if (Definition->isDelegatingConstructor()) {
@@ -1855,7 +1941,7 @@
     APValue Result;
 
     if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition) ||
-        !HandleFunctionCall(E, This, Args, Body, Info, Result))
+        !HandleFunctionCall(E, Definition, This, Args, Body, Info, Result))
       return false;
 
     return DerivedSuccess(CCValue(Result, CCValue::GlobalValue()), E);
@@ -1980,6 +2066,9 @@
         return false;
       BaseTy = E->getBase()->getType()->getAs<PointerType>()->getPointeeType();
     } else if (E->getBase()->isRValue()) {
+      if (!E->getBase()->getType()->isRecordType() ||
+          !E->getBase()->getType()->isLiteralType())
+        return false;
       if (!EvaluateTemporary(E->getBase(), Result, this->Info))
         return false;
       BaseTy = E->getBase()->getType();

Modified: cfe/branches/tooling/lib/Basic/Diagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Basic/Diagnostic.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Basic/Diagnostic.cpp (original)
+++ cfe/branches/tooling/lib/Basic/Diagnostic.cpp Sat Dec 17 00:38:54 2011
@@ -53,6 +53,7 @@
 
   ErrorLimit = 0;
   TemplateBacktraceLimit = 0;
+  ConstexprBacktraceLimit = 0;
 
   Reset();
 }

Modified: cfe/branches/tooling/lib/Basic/TargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Basic/TargetInfo.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Basic/TargetInfo.cpp (original)
+++ cfe/branches/tooling/lib/Basic/TargetInfo.cpp Sat Dec 17 00:38:54 2011
@@ -34,6 +34,7 @@
   IntWidth = IntAlign = 32;
   LongWidth = LongAlign = 32;
   LongLongWidth = LongLongAlign = 64;
+  SuitableAlign = 64;
   HalfWidth = 16;
   HalfAlign = 16;
   FloatWidth = 32;

Modified: cfe/branches/tooling/lib/Basic/Targets.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Basic/Targets.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Basic/Targets.cpp (original)
+++ cfe/branches/tooling/lib/Basic/Targets.cpp Sat Dec 17 00:38:54 2011
@@ -432,13 +432,14 @@
   PS3PPUTargetInfo(const std::string& triple)
     : OSTargetInfo<Target>(triple) {
     this->UserLabelPrefix = "";
-    this->LongWidth = this->LongAlign = this->PointerWidth = this->PointerAlign = 32;
+    this->LongWidth = this->LongAlign = 32;
+    this->PointerWidth = this->PointerAlign = 32;
     this->IntMaxType = TargetInfo::SignedLongLong;
     this->UIntMaxType = TargetInfo::UnsignedLongLong;
     this->Int64Type = TargetInfo::SignedLongLong;
     this->SizeType = TargetInfo::UnsignedInt;
     this->DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
-                        "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
+                              "i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32";
   }
 };
 
@@ -2048,6 +2049,7 @@
     DoubleAlign = LongLongAlign = 32;
     LongDoubleWidth = 96;
     LongDoubleAlign = 32;
+    SuitableAlign = 32;
     DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
                         "i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-"
                         "a0:0:64-f80:32:32-n8:16:32-S128";
@@ -2097,6 +2099,7 @@
     DarwinTargetInfo<X86_32TargetInfo>(triple) {
     LongDoubleWidth = 128;
     LongDoubleAlign = 128;
+    SuitableAlign = 128;
     SizeType = UnsignedLong;
     IntPtrType = SignedLong;
     DescriptionString = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
@@ -2289,6 +2292,7 @@
     LongDoubleAlign = 128;
     LargeArrayMinWidth = 128;
     LargeArrayAlign = 128;
+    SuitableAlign = 128;
     IntMaxType = SignedLong;
     UIntMaxType = UnsignedLong;
     Int64Type = SignedLong;
@@ -2497,7 +2501,7 @@
     // FIXME: We need support for -meabi... we could just mangle it into the
     // name.
     if (Name == "apcs-gnu") {
-      DoubleAlign = LongLongAlign = LongDoubleAlign = 32;
+      DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
       SizeType = UnsignedLong;
 
       // Revert to using SignedInt on apcs-gnu to comply with existing behaviour.
@@ -3086,6 +3090,7 @@
       LongWidth = 32; LongLongWidth = 64;
       LongAlign = LongLongAlign = 16;
       PointerWidth = 16; PointerAlign = 16;
+      SuitableAlign = 16;
       SizeType = UnsignedInt;
       IntMaxType = SignedLong;
       UIntMaxType = UnsignedLong;
@@ -3167,6 +3172,7 @@
       IntAlign = 32;
       LongAlign = LongLongAlign = 32;
       PointerAlign = 32;
+      SuitableAlign = 32;
       SizeType = UnsignedInt;
       IntMaxType = SignedLong;
       UIntMaxType = UnsignedLong;
@@ -3396,6 +3402,7 @@
     PointerWidth = PointerAlign = 64;
     LongDoubleWidth = LongDoubleAlign = 128;
     LongDoubleFormat = &llvm::APFloat::IEEEquad;
+    SuitableAlign = 128;
   }
   virtual bool setABI(const std::string &Name) {
     SetDescriptionString(Name);

Modified: cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/branches/tooling/lib/CodeGen/CGDebugInfo.cpp Sat Dec 17 00:38:54 2011
@@ -488,6 +488,11 @@
 
   // Limit debug info for the pointee type.
 
+  // If we have an existing type, use that, it's still smaller than creating
+  // a new type.
+  llvm::DIType Ty = getTypeOrNull(PointeeTy);
+  if (Ty.Verify()) return Ty;
+
   // Handle qualifiers.
   if (PointeeTy.hasLocalQualifiers())
     return CreateQualifiedType(PointeeTy, Unit);
@@ -499,7 +504,12 @@
     llvm::DIDescriptor FDContext =
       getContextDescriptor(cast<Decl>(RD->getDeclContext()));
 
-    if (RD->isStruct())
+    CXXRecordDecl *CXXDecl = dyn_cast<CXXRecordDecl>(RD);
+    if (CXXDecl)
+      return DBuilder.createClassType(FDContext, RD->getName(), DefUnit,
+                                      Line, 0, 0, 0, llvm::DIType::FlagFwdDecl,
+                                      llvm::DIType(), llvm::DIArray());
+    else if (RD->isStruct())
       return DBuilder.createStructType(FDContext, RD->getName(), DefUnit,
                                        Line, 0, 0, llvm::DIType::FlagFwdDecl,
                                        llvm::DIArray());
@@ -507,12 +517,8 @@
       return DBuilder.createUnionType(FDContext, RD->getName(), DefUnit,
                                       Line, 0, 0, llvm::DIType::FlagFwdDecl,
                                       llvm::DIArray());
-    else {
-      assert(RD->isClass() && "Unknown RecordType!");
-      return DBuilder.createClassType(FDContext, RD->getName(), DefUnit,
-                                      Line, 0, 0, 0, llvm::DIType::FlagFwdDecl,
-                                      llvm::DIType(), llvm::DIArray());
-    }
+    else
+      llvm_unreachable("Unknown RecordDecl type!");
   }
   return getOrCreateType(PointeeTy, Unit);
 
@@ -1175,11 +1181,13 @@
     else if (CXXDecl->isDynamicClass()) 
       ContainingType = FwdDecl;
 
-   RealDecl = DBuilder.createClassType(RDContext, RDName, DefUnit, Line,
-                                       Size, Align, 0, 0, llvm::DIType(),
-                                       Elements, ContainingType,
-                                       TParamsArray);
-  } else 
+    // FIXME: This could be a struct type giving a default visibility different
+    // than C++ class type, but needs llvm metadata changes first.
+    RealDecl = DBuilder.createClassType(RDContext, RDName, DefUnit, Line,
+                                        Size, Align, 0, 0, llvm::DIType(),
+                                        Elements, ContainingType,
+                                        TParamsArray);
+  } else
     RealDecl = DBuilder.createStructType(RDContext, RDName, DefUnit, Line,
                                          Size, Align, 0, Elements);
 
@@ -1562,15 +1570,12 @@
   return T;
 }
 
-/// getOrCreateType - Get the type from the cache or create a new
-/// one if necessary.
-llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) {
-  if (Ty.isNull())
-    return llvm::DIType();
+/// getType - Get the type from the cache or return null type if it doesn't exist.
+llvm::DIType CGDebugInfo::getTypeOrNull(QualType Ty) {
 
   // Unwrap the type as needed for debug information.
   Ty = UnwrapTypeForDebugInfo(Ty);
-
+  
   // Check for existing entry.
   llvm::DenseMap<void *, llvm::WeakVH>::iterator it =
     TypeCache.find(Ty.getAsOpaquePtr());
@@ -1580,6 +1585,21 @@
       return llvm::DIType(cast<llvm::MDNode>(it->second));
   }
 
+  return llvm::DIType();
+}
+
+/// getOrCreateType - Get the type from the cache or create a new
+/// one if necessary.
+llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile Unit) {
+  if (Ty.isNull())
+    return llvm::DIType();
+
+  // Unwrap the type as needed for debug information.
+  Ty = UnwrapTypeForDebugInfo(Ty);
+  
+  llvm::DIType T = getTypeOrNull(Ty);
+  if (T.Verify()) return T;
+
   // Otherwise create the type.
   llvm::DIType Res = CreateTypeNode(Ty, Unit);
 

Modified: cfe/branches/tooling/lib/CodeGen/CGDebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/CodeGen/CGDebugInfo.h?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/CodeGen/CGDebugInfo.h (original)
+++ cfe/branches/tooling/lib/CodeGen/CGDebugInfo.h Sat Dec 17 00:38:54 2011
@@ -93,6 +93,7 @@
   llvm::DIType CreateType(const MemberPointerType *Ty, llvm::DIFile F);
   llvm::DIType CreateType(const AtomicType *Ty, llvm::DIFile F);
   llvm::DIType CreateEnumType(const EnumDecl *ED);
+  llvm::DIType getTypeOrNull(const QualType);
   llvm::DIType getOrCreateMethodType(const CXXMethodDecl *Method,
                                      llvm::DIFile F);
   llvm::DIType getOrCreateFunctionType(const Decl *D, QualType FnType,

Modified: cfe/branches/tooling/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Driver/Tools.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Driver/Tools.cpp (original)
+++ cfe/branches/tooling/lib/Driver/Tools.cpp Sat Dec 17 00:38:54 2011
@@ -1808,6 +1808,11 @@
     CmdArgs.push_back(A->getValue(Args));
   }
 
+  if (Arg *A = Args.getLastArg(options::OPT_fconstexpr_backtrace_limit_EQ)) {
+    CmdArgs.push_back("-fconstexpr-backtrace-limit");
+    CmdArgs.push_back(A->getValue(Args));
+  }
+
   // Pass -fmessage-length=.
   CmdArgs.push_back("-fmessage-length");
   if (Arg *A = Args.getLastArg(options::OPT_fmessage_length_EQ)) {

Modified: cfe/branches/tooling/lib/Frontend/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/CMakeLists.txt?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/CMakeLists.txt (original)
+++ cfe/branches/tooling/lib/Frontend/CMakeLists.txt Sat Dec 17 00:38:54 2011
@@ -18,6 +18,7 @@
   CompilerInvocation.cpp
   CreateInvocationFromCommandLine.cpp
   DependencyFile.cpp
+  DiagnosticRenderer.cpp
   FrontendAction.cpp
   FrontendActions.cpp
   FrontendOptions.cpp

Modified: cfe/branches/tooling/lib/Frontend/CompilerInstance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/CompilerInstance.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/CompilerInstance.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/CompilerInstance.cpp Sat Dec 17 00:38:54 2011
@@ -170,7 +170,7 @@
   }
   
   DiagnosticConsumer *SerializedConsumer =
-    clang::serialized_diags::create(OS.take());
+    clang::serialized_diags::create(OS.take(), DiagOpts);
 
   
   Diags.setClient(new ChainedDiagnosticConsumer(Diags.takeClient(),

Modified: cfe/branches/tooling/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/CompilerInvocation.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/CompilerInvocation.cpp Sat Dec 17 00:38:54 2011
@@ -354,6 +354,11 @@
     Res.push_back("-ftemplate-backtrace-limit");
     Res.push_back(llvm::utostr(Opts.TemplateBacktraceLimit));
   }
+  if (Opts.ConstexprBacktraceLimit
+                        != DiagnosticOptions::DefaultConstexprBacktraceLimit) {
+    Res.push_back("-fconstexpr-backtrace-limit");
+    Res.push_back(llvm::utostr(Opts.ConstexprBacktraceLimit));
+  }
 
   if (Opts.TabStop != DiagnosticOptions::DefaultTabStop) {
     Res.push_back("-ftabstop");
@@ -1229,6 +1234,10 @@
     = Args.getLastArgIntValue(OPT_ftemplate_backtrace_limit,
                          DiagnosticOptions::DefaultTemplateBacktraceLimit,
                          Diags);
+  Opts.ConstexprBacktraceLimit
+    = Args.getLastArgIntValue(OPT_fconstexpr_backtrace_limit,
+                         DiagnosticOptions::DefaultConstexprBacktraceLimit,
+                         Diags);
   Opts.TabStop = Args.getLastArgIntValue(OPT_ftabstop,
                                     DiagnosticOptions::DefaultTabStop, Diags);
   if (Opts.TabStop == 0 || Opts.TabStop > DiagnosticOptions::MaxTabStop) {

Modified: cfe/branches/tooling/lib/Frontend/SerializedDiagnosticPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/SerializedDiagnosticPrinter.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/SerializedDiagnosticPrinter.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/SerializedDiagnosticPrinter.cpp Sat Dec 17 00:38:54 2011
@@ -18,6 +18,7 @@
 #include "clang/Basic/Version.h"
 #include "clang/Lex/Lexer.h"
 #include "clang/Frontend/SerializedDiagnosticPrinter.h"
+#include "clang/Frontend/DiagnosticRenderer.h"
 
 using namespace clang;
 using namespace clang::serialized_diags;
@@ -44,11 +45,58 @@
  
 typedef llvm::SmallVector<uint64_t, 64> RecordData;
 typedef llvm::SmallVectorImpl<uint64_t> RecordDataImpl;
+
+class SDiagsWriter;
+  
+class SDiagsRenderer : public DiagnosticRenderer {
+  SDiagsWriter &Writer;
+  RecordData &Record;
+public:
+  SDiagsRenderer(SDiagsWriter &Writer, RecordData &Record,
+                 const SourceManager &SM,
+                 const LangOptions &LangOpts,
+                 const DiagnosticOptions &DiagOpts)
+    : DiagnosticRenderer(SM, LangOpts, DiagOpts),
+      Writer(Writer), Record(Record){}
+
+  virtual ~SDiagsRenderer() {}
+  
+protected:
+  virtual void emitDiagnosticMessage(SourceLocation Loc,
+                                     PresumedLoc PLoc,
+                                     DiagnosticsEngine::Level Level,
+                                     StringRef Message,
+                                     ArrayRef<CharSourceRange> Ranges,
+                                     const Diagnostic *Info);
+  
+  virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc,
+                                 DiagnosticsEngine::Level Level,
+                                 ArrayRef<CharSourceRange> Ranges) {}
+  
+  virtual void emitBasicNote(StringRef Message);
+  
+  void emitNote(SourceLocation Loc, StringRef Message);
+  
+  virtual void emitIncludeLocation(SourceLocation Loc,
+                                   PresumedLoc PLoc);
+  
+  virtual void emitCodeContext(SourceLocation Loc,
+                               DiagnosticsEngine::Level Level,
+                               SmallVectorImpl<CharSourceRange>& Ranges,
+                               ArrayRef<FixItHint> Hints);
+  
+  virtual void beginDiagnostic(const Diagnostic *Info,
+                               DiagnosticsEngine::Level Level);
+  virtual void endDiagnostic(const Diagnostic *Info,
+                             DiagnosticsEngine::Level Level);
+};
   
 class SDiagsWriter : public DiagnosticConsumer {
+  friend class SDiagsRenderer;
 public:  
-  explicit SDiagsWriter(llvm::raw_ostream *os) 
-    : LangOpts(0), Stream(Buffer), OS(os), inNonNoteDiagnostic(false)
+  explicit SDiagsWriter(llvm::raw_ostream *os, const DiagnosticOptions &diags) 
+    : LangOpts(0), DiagOpts(diags),
+      Stream(Buffer), OS(os), inNonNoteDiagnostic(false)
   { 
     EmitPreamble();
   }
@@ -81,31 +129,39 @@
   void EmitMetaBlock();
   
   /// \brief Emit a record for a CharSourceRange.
-  void EmitCharSourceRange(CharSourceRange R, SourceManager &SM);
+  void EmitCharSourceRange(CharSourceRange R, const SourceManager &SM);
   
-  /// \brief Emit the string information for the category for a diagnostic.
-  unsigned getEmitCategory(unsigned DiagID);
+  /// \brief Emit the string information for the category.
+  unsigned getEmitCategory(unsigned category = 0);
   
   /// \brief Emit the string information for diagnostic flags.
   unsigned getEmitDiagnosticFlag(DiagnosticsEngine::Level DiagLevel,
-                                 const Diagnostic &Info);
+                                 unsigned DiagID = 0);
   
   /// \brief Emit (lazily) the file string and retrieved the file identifier.
-  unsigned getEmitFile(SourceLocation Loc, SourceManager &SM);
-  
+  unsigned getEmitFile(const char *Filename);
+
+  /// \brief Add SourceLocation information the specified record.  
+  void AddLocToRecord(SourceLocation Loc, const SourceManager &SM,
+                      PresumedLoc PLoc, RecordDataImpl &Record,
+                      unsigned TokSize = 0);
+
   /// \brief Add SourceLocation information the specified record.
   void AddLocToRecord(SourceLocation Loc, RecordDataImpl &Record,
-                      SourceManager &SM,
-                      unsigned TokSize = 0);
+                      const SourceManager &SM,
+                      unsigned TokSize = 0) {
+    AddLocToRecord(Loc, SM, SM.getPresumedLoc(Loc), Record, TokSize);
+  }
 
   /// \brief Add CharSourceRange information the specified record.
   void AddCharSourceRangeToRecord(CharSourceRange R, RecordDataImpl &Record,
-                                  SourceManager &SM);
+                                  const SourceManager &SM);
 
   /// \brief The version of the diagnostics file.
   enum { Version = 1 };
 
   const LangOptions *LangOpts;
+  const DiagnosticOptions &DiagOpts;
   
   /// \brief The byte buffer for the serialized content.
   std::vector<unsigned char> Buffer;
@@ -129,7 +185,7 @@
   llvm::DenseSet<unsigned> Categories;
   
   /// \brief The collection of files used.
-  llvm::DenseMap<const FileEntry *, unsigned> Files;
+  llvm::DenseMap<const char *, unsigned> Files;
 
   typedef llvm::DenseMap<const void *, std::pair<unsigned, llvm::StringRef> > 
           DiagFlagsTy;
@@ -145,8 +201,9 @@
 
 namespace clang {
 namespace serialized_diags {
-DiagnosticConsumer *create(llvm::raw_ostream *OS) {
-  return new SDiagsWriter(OS);
+DiagnosticConsumer *create(llvm::raw_ostream *OS,
+                           const DiagnosticOptions &diags) {
+  return new SDiagsWriter(OS, diags);
 }
 } // end namespace serialized_diags
 } // end namespace clang
@@ -189,10 +246,11 @@
 }
 
 void SDiagsWriter::AddLocToRecord(SourceLocation Loc,
+                                  const SourceManager &SM,
+                                  PresumedLoc PLoc,
                                   RecordDataImpl &Record,
-                                  SourceManager &SM,
                                   unsigned TokSize) {
-  if (Loc.isInvalid()) {
+  if (PLoc.isInvalid()) {
     // Emit a "sentinel" location.
     Record.push_back((unsigned)0); // File.
     Record.push_back((unsigned)0); // Line.
@@ -201,16 +259,15 @@
     return;
   }
 
-  Loc = SM.getSpellingLoc(Loc);
-  Record.push_back(getEmitFile(Loc, SM));
-  Record.push_back(SM.getSpellingLineNumber(Loc));
-  Record.push_back(SM.getSpellingColumnNumber(Loc)+TokSize);
+  Record.push_back(getEmitFile(PLoc.getFilename()));
+  Record.push_back(PLoc.getLine());
+  Record.push_back(PLoc.getColumn()+TokSize);
   Record.push_back(SM.getFileOffset(Loc));
 }
 
 void SDiagsWriter::AddCharSourceRangeToRecord(CharSourceRange Range,
                                               RecordDataImpl &Record,
-                                              SourceManager &SM) {
+                                              const SourceManager &SM) {
   AddLocToRecord(Range.getBegin(), Record, SM);
   unsigned TokSize = 0;
   if (Range.isTokenRange())
@@ -220,14 +277,11 @@
   AddLocToRecord(Range.getEnd(), Record, SM, TokSize);
 }
 
-unsigned SDiagsWriter::getEmitFile(SourceLocation Loc, SourceManager &SM) {
-  assert(Loc.isValid());
-  const std::pair<FileID, unsigned> &LocInfo = SM.getDecomposedLoc(Loc);
-  const FileEntry *FE = SM.getFileEntryForID(LocInfo.first);
-  if (!FE)
+unsigned SDiagsWriter::getEmitFile(const char *FileName){
+  if (!FileName)
     return 0;
   
-  unsigned &entry = Files[FE];
+  unsigned &entry = Files[FileName];
   if (entry)
     return entry;
   
@@ -236,9 +290,9 @@
   RecordData Record;
   Record.push_back(RECORD_FILENAME);
   Record.push_back(entry);
-  Record.push_back(FE->getSize());
-  Record.push_back(FE->getModificationTime());
-  StringRef Name = FE->getName();
+  Record.push_back(0); // For legacy.
+  Record.push_back(0); // For legacy.
+  StringRef Name(FileName);
   Record.push_back(Name.size());
   Stream.EmitRecordWithBlob(Abbrevs.get(RECORD_FILENAME), Record, Name);
 
@@ -246,7 +300,7 @@
 }
 
 void SDiagsWriter::EmitCharSourceRange(CharSourceRange R,
-                                       SourceManager &SM) {
+                                       const SourceManager &SM) {
   Record.clear();
   Record.push_back(RECORD_SOURCE_RANGE);
   AddCharSourceRangeToRecord(R, Record, SM);
@@ -373,9 +427,7 @@
   Stream.ExitBlock();
 }
 
-unsigned SDiagsWriter::getEmitCategory(unsigned int DiagID) {
-  unsigned category = DiagnosticIDs::getCategoryNumberForDiag(DiagID);
-  
+unsigned SDiagsWriter::getEmitCategory(unsigned int category) {
   if (Categories.count(category))
     return category;
   
@@ -394,11 +446,11 @@
 }
 
 unsigned SDiagsWriter::getEmitDiagnosticFlag(DiagnosticsEngine::Level DiagLevel,
-                                             const Diagnostic &Info) {
+                                             unsigned DiagID) {
   if (DiagLevel == DiagnosticsEngine::Note)
     return 0; // No flag for notes.
   
-  StringRef FlagName = DiagnosticIDs::getWarningOptionForDiag(Info.getID());
+  StringRef FlagName = DiagnosticIDs::getWarningOptionForDiag(DiagID);
   if (FlagName.empty())
     return 0;
 
@@ -424,8 +476,6 @@
 
 void SDiagsWriter::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
                                     const Diagnostic &Info) {
-  SourceManager &SM = Info.getSourceManager();
-
   if (DiagLevel != DiagnosticsEngine::Note) {
     if (inNonNoteDiagnostic) {
       // We have encountered a non-note diagnostic.  Finish up the previous
@@ -434,52 +484,117 @@
     }
     inNonNoteDiagnostic = true;
   }
-  
-  Stream.EnterSubblock(BLOCK_DIAG, 4);
-  
-  // Emit the RECORD_DIAG record.
-  Record.clear();
-  Record.push_back(RECORD_DIAG);
-  Record.push_back(DiagLevel);
-  AddLocToRecord(Info.getLocation(), Record, SM);
-  // Emit the category string lazily and get the category ID.
-  Record.push_back(getEmitCategory(Info.getID()));
-  // Emit the diagnostic flag string lazily and get the mapped ID.
-  Record.push_back(getEmitDiagnosticFlag(DiagLevel, Info));
-  // Emit the diagnostic text.
+
+  // Compute the diagnostic text.
   diagBuf.clear();   
-  Info.FormatDiagnostic(diagBuf); // Compute the diagnostic text.
-  Record.push_back(diagBuf.str().size());
-  Stream.EmitRecordWithBlob(Abbrevs.get(RECORD_DIAG), Record, diagBuf.str());
+  Info.FormatDiagnostic(diagBuf);
+
+  SourceManager &SM = Info.getSourceManager();
+  SDiagsRenderer Renderer(*this, Record, SM, *LangOpts, DiagOpts);
+  Renderer.emitDiagnostic(Info.getLocation(), DiagLevel,
+                          diagBuf.str(),
+                          Info.getRanges(),
+                          llvm::makeArrayRef(Info.getFixItHints(),
+                                             Info.getNumFixItHints()),
+                          &Info);
+}
+
+void
+SDiagsRenderer::emitDiagnosticMessage(SourceLocation Loc,
+                                      PresumedLoc PLoc,
+                                      DiagnosticsEngine::Level Level,
+                                      StringRef Message,
+                                      ArrayRef<clang::CharSourceRange> Ranges,
+                                      const Diagnostic *Info) {
+  // Emit the RECORD_DIAG record.
+  Writer.Record.clear();
+  Writer.Record.push_back(RECORD_DIAG);
+  Writer.Record.push_back(Level);
+  Writer.AddLocToRecord(Loc, SM, PLoc, Record);
 
+  if (Info) {
+    // Emit the category string lazily and get the category ID.
+    unsigned DiagID = DiagnosticIDs::getCategoryNumberForDiag(Info->getID());
+    Writer.Record.push_back(Writer.getEmitCategory(DiagID));
+    // Emit the diagnostic flag string lazily and get the mapped ID.
+    Writer.Record.push_back(Writer.getEmitDiagnosticFlag(Level, Info->getID()));
+  }
+  else {
+    Writer.Record.push_back(Writer.getEmitCategory());
+    Writer.Record.push_back(Writer.getEmitDiagnosticFlag(Level));
+  }
+
+  Writer.Record.push_back(Message.size());
+  Writer.Stream.EmitRecordWithBlob(Writer.Abbrevs.get(RECORD_DIAG),
+                                   Writer.Record, Message);
+}
+
+void SDiagsRenderer::beginDiagnostic(const Diagnostic *Info,
+                                     DiagnosticsEngine::Level Level) {
+  Writer.Stream.EnterSubblock(BLOCK_DIAG, 4);  
+}
+
+void SDiagsRenderer::endDiagnostic(const Diagnostic *Info,
+                                   DiagnosticsEngine::Level Level) {
+  if (Info && Level != DiagnosticsEngine::Note)
+    return;
+  Writer.Stream.ExitBlock();
+}
+
+void SDiagsRenderer::emitCodeContext(SourceLocation Loc,
+                                     DiagnosticsEngine::Level Level,
+                                     SmallVectorImpl<CharSourceRange> &Ranges,
+                                     ArrayRef<FixItHint> Hints) {  
   // Emit Source Ranges.
-  ArrayRef<CharSourceRange> Ranges = Info.getRanges();
   for (ArrayRef<CharSourceRange>::iterator it=Ranges.begin(), ei=Ranges.end();
        it != ei; ++it) {
     if (it->isValid())
-      EmitCharSourceRange(*it, SM);
+      Writer.EmitCharSourceRange(*it, SM);
   }
-
+  
   // Emit FixIts.
-  for (unsigned i = 0, n = Info.getNumFixItHints(); i != n; ++i) {
-    const FixItHint &fix = Info.getFixItHint(i);
+  for (ArrayRef<FixItHint>::iterator it = Hints.begin(), et = Hints.end();
+       it != et; ++it) {
+    const FixItHint &fix = *it;
     if (fix.isNull())
       continue;
-    Record.clear();
-    Record.push_back(RECORD_FIXIT);
-    AddCharSourceRangeToRecord(fix.RemoveRange, Record, SM);
-    Record.push_back(fix.CodeToInsert.size());
-    Stream.EmitRecordWithBlob(Abbrevs.get(RECORD_FIXIT), Record,
-                              fix.CodeToInsert);    
-  }
-  
-  if (DiagLevel == DiagnosticsEngine::Note) {
-    // Notes currently cannot have child diagnostics.  Complete the
-    // diagnostic now.
-    Stream.ExitBlock();
+    Writer.Record.clear();
+    Writer.Record.push_back(RECORD_FIXIT);
+    Writer.AddCharSourceRangeToRecord(fix.RemoveRange, Record, SM);
+    Writer.Record.push_back(fix.CodeToInsert.size());
+    Writer.Stream.EmitRecordWithBlob(Writer.Abbrevs.get(RECORD_FIXIT), Record,
+                                     fix.CodeToInsert);    
   }
 }
 
+void SDiagsRenderer::emitNote(SourceLocation Loc, StringRef Message) {
+  Writer.Stream.EnterSubblock(BLOCK_DIAG, 4);
+  RecordData Record;
+  Record.push_back(RECORD_DIAG);
+  Record.push_back(DiagnosticsEngine::Note);
+  Writer.AddLocToRecord(Loc, Record, SM);
+  Record.push_back(Writer.getEmitCategory());
+  Record.push_back(Writer.getEmitDiagnosticFlag(DiagnosticsEngine::Note));
+  Record.push_back(Message.size());
+  Writer.Stream.EmitRecordWithBlob(Writer.Abbrevs.get(RECORD_DIAG),
+                                   Record, Message);
+  Writer.Stream.ExitBlock();
+}
+
+void SDiagsRenderer::emitIncludeLocation(SourceLocation Loc,
+                                         PresumedLoc PLoc) {
+  // Generate a note indicating the include location.
+  llvm::SmallString<200> MessageStorage;
+  llvm::raw_svector_ostream Message(MessageStorage);
+  Message << "in file included from " << PLoc.getFilename() << ':'
+          << PLoc.getLine() << ":";
+  emitNote(Loc, Message.str());
+}
+
+void SDiagsRenderer::emitBasicNote(StringRef Message) {
+  emitNote(SourceLocation(), Message);
+}
+
 void SDiagsWriter::finish() {
   if (inNonNoteDiagnostic) {
     // Finish off any diagnostics we were in the process of emitting.

Modified: cfe/branches/tooling/lib/Frontend/TextDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/TextDiagnostic.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/TextDiagnostic.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/TextDiagnostic.cpp Sat Dec 17 00:38:54 2011
@@ -174,70 +174,6 @@
   }
 }
 
-/// Look through spelling locations for a macro argument expansion, and
-/// if found skip to it so that we can trace the argument rather than the macros
-/// in which that argument is used. If no macro argument expansion is found,
-/// don't skip anything and return the starting location.
-static SourceLocation skipToMacroArgExpansion(const SourceManager &SM,
-                                                  SourceLocation StartLoc) {
-  for (SourceLocation L = StartLoc; L.isMacroID();
-       L = SM.getImmediateSpellingLoc(L)) {
-    if (SM.isMacroArgExpansion(L))
-      return L;
-  }
-
-  // Otherwise just return initial location, there's nothing to skip.
-  return StartLoc;
-}
-
-/// Gets the location of the immediate macro caller, one level up the stack
-/// toward the initial macro typed into the source.
-static SourceLocation getImmediateMacroCallerLoc(const SourceManager &SM,
-                                                 SourceLocation Loc) {
-  if (!Loc.isMacroID()) return Loc;
-
-  // When we have the location of (part of) an expanded parameter, its spelling
-  // location points to the argument as typed into the macro call, and
-  // therefore is used to locate the macro caller.
-  if (SM.isMacroArgExpansion(Loc))
-    return SM.getImmediateSpellingLoc(Loc);
-
-  // Otherwise, the caller of the macro is located where this macro is
-  // expanded (while the spelling is part of the macro definition).
-  return SM.getImmediateExpansionRange(Loc).first;
-}
-
-/// Gets the location of the immediate macro callee, one level down the stack
-/// toward the leaf macro.
-static SourceLocation getImmediateMacroCalleeLoc(const SourceManager &SM,
-                                                 SourceLocation Loc) {
-  if (!Loc.isMacroID()) return Loc;
-
-  // When we have the location of (part of) an expanded parameter, its
-  // expansion location points to the unexpanded paramater reference within
-  // the macro definition (or callee).
-  if (SM.isMacroArgExpansion(Loc))
-    return SM.getImmediateExpansionRange(Loc).first;
-
-  // Otherwise, the callee of the macro is located where this location was
-  // spelled inside the macro definition.
-  return SM.getImmediateSpellingLoc(Loc);
-}
-
-/// Get the presumed location of a diagnostic message. This computes the
-/// presumed location for the top of any macro backtrace when present.
-static PresumedLoc getDiagnosticPresumedLoc(const SourceManager &SM,
-                                            SourceLocation Loc) {
-  // This is a condensed form of the algorithm used by emitCaretDiagnostic to
-  // walk to the top of the macro call stack.
-  while (Loc.isMacroID()) {
-    Loc = skipToMacroArgExpansion(SM, Loc);
-    Loc = getImmediateMacroCallerLoc(SM, Loc);
-  }
-
-  return SM.getPresumedLoc(Loc);
-}
-
 /// \brief Skip over whitespace in the string, starting at the given
 /// index.
 ///
@@ -389,85 +325,33 @@
   return Wrapped;
 }
 
-/// \brief Retrieve the name of the immediate macro expansion.
-///
-/// This routine starts from a source location, and finds the name of the macro
-/// responsible for its immediate expansion. It looks through any intervening
-/// macro argument expansions to compute this. It returns a StringRef which
-/// refers to the SourceManager-owned buffer of the source where that macro
-/// name is spelled. Thus, the result shouldn't out-live that SourceManager.
-///
-static StringRef getImmediateMacroName(SourceLocation Loc,
-                                       const SourceManager &SM,
-                                       const LangOptions &LangOpts) {
-  assert(Loc.isMacroID() && "Only reasonble to call this on macros");
-  // Walk past macro argument expanions.
-  while (SM.isMacroArgExpansion(Loc))
-    Loc = SM.getImmediateExpansionRange(Loc).first;
-
-  // Find the spelling location of the start of the non-argument expansion
-  // range. This is where the macro name was spelled in order to begin
-  // expanding this macro.
-  Loc = SM.getSpellingLoc(SM.getImmediateExpansionRange(Loc).first);
-
-  // Dig out the buffer where the macro name was spelled and the extents of the
-  // name so that we can render it into the expansion note.
-  std::pair<FileID, unsigned> ExpansionInfo = SM.getDecomposedLoc(Loc);
-  unsigned MacroTokenLength = Lexer::MeasureTokenLength(Loc, SM, LangOpts);
-  StringRef ExpansionBuffer = SM.getBufferData(ExpansionInfo.first);
-  return ExpansionBuffer.substr(ExpansionInfo.second, MacroTokenLength);
-}
-
 TextDiagnostic::TextDiagnostic(raw_ostream &OS,
                                const SourceManager &SM,
                                const LangOptions &LangOpts,
                                const DiagnosticOptions &DiagOpts)
-  : OS(OS), SM(SM), LangOpts(LangOpts), DiagOpts(DiagOpts), LastLevel() {
-}
+  : DiagnosticRenderer(SM, LangOpts, DiagOpts), OS(OS) {}
 
-void TextDiagnostic::emitDiagnostic(SourceLocation Loc,
-                                    DiagnosticsEngine::Level Level,
-                                    StringRef Message,
-                                    ArrayRef<CharSourceRange> Ranges,
-                                    ArrayRef<FixItHint> FixItHints) {
-  PresumedLoc PLoc = getDiagnosticPresumedLoc(SM, Loc);
-
-  // First, if this diagnostic is not in the main file, print out the
-  // "included from" lines.
-  emitIncludeStack(PLoc.getIncludeLoc(), Level);
+TextDiagnostic::~TextDiagnostic() {}
 
+void
+TextDiagnostic::emitDiagnosticMessage(SourceLocation Loc,
+                                      PresumedLoc PLoc,
+                                      DiagnosticsEngine::Level Level,
+                                      StringRef Message,
+                                      ArrayRef<clang::CharSourceRange> Ranges,
+                                      const Diagnostic *Info) {
   uint64_t StartOfLocationInfo = OS.tell();
 
-  // Next emit the location of this particular diagnostic.
+  // Emit the location of this particular diagnostic.
   emitDiagnosticLoc(Loc, PLoc, Level, Ranges);
-
+  
   if (DiagOpts.ShowColors)
     OS.resetColor();
-
+  
   printDiagnosticLevel(OS, Level, DiagOpts.ShowColors);
   printDiagnosticMessage(OS, Level, Message,
                          OS.tell() - StartOfLocationInfo,
                          DiagOpts.MessageLength, DiagOpts.ShowColors);
-
-  // Only recurse if we have a valid location.
-  if (Loc.isValid()) {
-    // Get the ranges into a local array we can hack on.
-    SmallVector<CharSourceRange, 20> MutableRanges(Ranges.begin(),
-                                                   Ranges.end());
-
-    for (ArrayRef<FixItHint>::const_iterator I = FixItHints.begin(),
-                                             E = FixItHints.end();
-         I != E; ++I)
-      if (I->RemoveRange.isValid())
-        MutableRanges.push_back(I->RemoveRange);
-
-    unsigned MacroDepth = 0;
-    emitMacroExpansionsAndCarets(Loc, Level, MutableRanges, FixItHints,
-                                 MacroDepth);
-  }
-
-  LastLoc = Loc;
-  LastLevel = Level;
 }
 
 /*static*/ void
@@ -525,50 +409,6 @@
   OS << '\n';
 }
 
-/// \brief Prints an include stack when appropriate for a particular
-/// diagnostic level and location.
-///
-/// This routine handles all the logic of suppressing particular include
-/// stacks (such as those for notes) and duplicate include stacks when
-/// repeated warnings occur within the same file. It also handles the logic
-/// of customizing the formatting and display of the include stack.
-///
-/// \param Level The diagnostic level of the message this stack pertains to.
-/// \param Loc   The include location of the current file (not the diagnostic
-///              location).
-void TextDiagnostic::emitIncludeStack(SourceLocation Loc,
-                                      DiagnosticsEngine::Level Level) {
-  // Skip redundant include stacks altogether.
-  if (LastIncludeLoc == Loc)
-    return;
-  LastIncludeLoc = Loc;
-
-  if (!DiagOpts.ShowNoteIncludeStack && Level == DiagnosticsEngine::Note)
-    return;
-
-  emitIncludeStackRecursively(Loc);
-}
-
-/// \brief Helper to recursivly walk up the include stack and print each layer
-/// on the way back down.
-void TextDiagnostic::emitIncludeStackRecursively(SourceLocation Loc) {
-  if (Loc.isInvalid())
-    return;
-
-  PresumedLoc PLoc = SM.getPresumedLoc(Loc);
-  if (PLoc.isInvalid())
-    return;
-
-  // Emit the other include frames first.
-  emitIncludeStackRecursively(PLoc.getIncludeLoc());
-
-  if (DiagOpts.ShowLocation)
-    OS << "In file included from " << PLoc.getFilename()
-       << ':' << PLoc.getLine() << ":\n";
-  else
-    OS << "In included file:\n";
-}
-
 /// \brief Print out the file/line/column information and include trace.
 ///
 /// This method handlen the emission of the diagnostic location information.
@@ -676,95 +516,19 @@
   OS << ' ';
 }
 
-/// \brief Recursively emit notes for each macro expansion and caret
-/// diagnostics where appropriate.
-///
-/// Walks up the macro expansion stack printing expansion notes, the code
-/// snippet, caret, underlines and FixItHint display as appropriate at each
-/// level.
-///
-/// \param Loc The location for this caret.
-/// \param Level The diagnostic level currently being emitted.
-/// \param Ranges The underlined ranges for this code snippet.
-/// \param Hints The FixIt hints active for this diagnostic.
-/// \param MacroSkipEnd The depth to stop skipping macro expansions.
-/// \param OnMacroInst The current depth of the macro expansion stack.
-void TextDiagnostic::emitMacroExpansionsAndCarets(
-    SourceLocation Loc,
-    DiagnosticsEngine::Level Level,
-    SmallVectorImpl<CharSourceRange>& Ranges,
-    ArrayRef<FixItHint> Hints,
-    unsigned &MacroDepth,
-    unsigned OnMacroInst) {
-  assert(!Loc.isInvalid() && "must have a valid source location here");
-
-  // If this is a file source location, directly emit the source snippet and
-  // caret line. Also record the macro depth reached.
-  if (Loc.isFileID()) {
-    assert(MacroDepth == 0 && "We shouldn't hit a leaf node twice!");
-    MacroDepth = OnMacroInst;
-    emitSnippetAndCaret(Loc, Level, Ranges, Hints);
-    return;
-  }
-  // Otherwise recurse through each macro expansion layer.
-
-  // When processing macros, skip over the expansions leading up to
-  // a macro argument, and trace the argument's expansion stack instead.
-  Loc = skipToMacroArgExpansion(SM, Loc);
-
-  SourceLocation OneLevelUp = getImmediateMacroCallerLoc(SM, Loc);
-
-  // FIXME: Map ranges?
-  emitMacroExpansionsAndCarets(OneLevelUp, Level, Ranges, Hints, MacroDepth,
-                               OnMacroInst + 1);
-
-  // Save the original location so we can find the spelling of the macro call.
-  SourceLocation MacroLoc = Loc;
-
-  // Map the location.
-  Loc = getImmediateMacroCalleeLoc(SM, Loc);
-
-  unsigned MacroSkipStart = 0, MacroSkipEnd = 0;
-  if (MacroDepth > DiagOpts.MacroBacktraceLimit) {
-    MacroSkipStart = DiagOpts.MacroBacktraceLimit / 2 +
-      DiagOpts.MacroBacktraceLimit % 2;
-    MacroSkipEnd = MacroDepth - DiagOpts.MacroBacktraceLimit / 2;
-  }
-
-  // Whether to suppress printing this macro expansion.
-  bool Suppressed = (OnMacroInst >= MacroSkipStart &&
-                     OnMacroInst < MacroSkipEnd);
-
-  // Map the ranges.
-  for (SmallVectorImpl<CharSourceRange>::iterator I = Ranges.begin(),
-                                                  E = Ranges.end();
-       I != E; ++I) {
-    SourceLocation Start = I->getBegin(), End = I->getEnd();
-    if (Start.isMacroID())
-      I->setBegin(getImmediateMacroCalleeLoc(SM, Start));
-    if (End.isMacroID())
-      I->setEnd(getImmediateMacroCalleeLoc(SM, End));
-  }
-
-  if (Suppressed) {
-    // Tell the user that we've skipped contexts.
-    if (OnMacroInst == MacroSkipStart) {
-      // FIXME: Emit this as a real note diagnostic.
-      // FIXME: Format an actual diagnostic rather than a hard coded string.
-      OS << "note: (skipping " << (MacroSkipEnd - MacroSkipStart)
-         << " expansions in backtrace; use -fmacro-backtrace-limit=0 to see "
-            "all)\n";
-    }
-    return;
-  }
+void TextDiagnostic::emitBasicNote(StringRef Message) {
+  // FIXME: Emit this as a real note diagnostic.
+  // FIXME: Format an actual diagnostic rather than a hard coded string.
+  OS << "note: " << Message << "\n";
+}
 
-  llvm::SmallString<100> MessageStorage;
-  llvm::raw_svector_ostream Message(MessageStorage);
-  Message << "expanded from macro '"
-          << getImmediateMacroName(MacroLoc, SM, LangOpts) << "'";
-  emitDiagnostic(SM.getSpellingLoc(Loc), DiagnosticsEngine::Note,
-                 Message.str(),
-                 Ranges, ArrayRef<FixItHint>());
+void TextDiagnostic::emitIncludeLocation(SourceLocation Loc,
+                                         PresumedLoc PLoc) {
+  if (DiagOpts.ShowLocation)
+    OS << "In file included from " << PLoc.getFilename() << ':'
+       << PLoc.getLine() << ":\n";
+  else
+    OS << "In included file:\n"; 
 }
 
 /// \brief Emit a code snippet and caret line.

Modified: cfe/branches/tooling/lib/Frontend/VerifyDiagnosticConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/VerifyDiagnosticConsumer.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/VerifyDiagnosticConsumer.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/VerifyDiagnosticConsumer.cpp Sat Dec 17 00:38:54 2011
@@ -443,8 +443,10 @@
           break;
       }
       if (II == IE) {
-        if (D.Count == D.OneOrMoreCount && FoundOnce) {
-          // We are only interested in at least one match and we found one.
+        if (D.Count == D.OneOrMoreCount) {
+          if (!FoundOnce)
+            LeftOnly.push_back(*I);
+          // We are only interested in at least one match, so exit the loop.
           break;
         }
         // Not found.

Modified: cfe/branches/tooling/lib/Frontend/Warnings.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Frontend/Warnings.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Frontend/Warnings.cpp (original)
+++ cfe/branches/tooling/lib/Frontend/Warnings.cpp Sat Dec 17 00:38:54 2011
@@ -58,6 +58,8 @@
     Diags.setErrorLimit(Opts.ErrorLimit);
   if (Opts.TemplateBacktraceLimit)
     Diags.setTemplateBacktraceLimit(Opts.TemplateBacktraceLimit);
+  if (Opts.ConstexprBacktraceLimit)
+    Diags.setConstexprBacktraceLimit(Opts.ConstexprBacktraceLimit);
 
   // If -pedantic or -pedantic-errors was specified, then we want to map all
   // extension diagnostics onto WARNING or ERROR unless the user has futz'd

Modified: cfe/branches/tooling/lib/Headers/avxintrin.h
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Headers/avxintrin.h?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Headers/avxintrin.h (original)
+++ cfe/branches/tooling/lib/Headers/avxintrin.h Sat Dec 17 00:38:54 2011
@@ -145,17 +145,13 @@
   return (__m256)__builtin_ia32_rcpps256((__v8sf)a);
 }
 
-static __inline __m256d __attribute__((__always_inline__, __nodebug__))
-_mm256_round_pd(__m256d v, const int m)
-{
-  return (__m256d)__builtin_ia32_roundpd256((__v4df)v, m);
-}
-
-static __inline __m256 __attribute__((__always_inline__, __nodebug__))
-_mm256_round_ps(__m256 v, const int m)
-{
-  return (__m256)__builtin_ia32_roundps256((__v8sf)v, m);
-}
+#define _mm256_round_pd(V, M) __extension__ ({ \
+    __m256d __V = (V); \
+    (__m256d)__builtin_ia32_roundpd256((__v4df)__V, M); })
+
+#define _mm256_round_ps(V, M) __extension__ ({ \
+  __m256 __V = (V); \
+  (__m256)__builtin_ia32_roundps256((__v8sf)__V, M); })
 
 #define _mm256_ceil_pd(V)  _mm256_round_pd((V), _MM_FROUND_CEIL)
 #define _mm256_floor_pd(V) _mm256_round_pd((V), _MM_FROUND_FLOOR)
@@ -262,47 +258,36 @@
 						  (__v8si)c);
 }
 
-static __inline __m128d __attribute__((__always_inline__, __nodebug__))
-_mm_permute_pd(__m128d a, const int c)
-{
-  return (__m128d)__builtin_ia32_vpermilpd((__v2df)a, c);
-}
+#define _mm_permute_pd(A, C) __extension__ ({ \
+  __m128d __A = (A); \
+  (__m128d)__builtin_ia32_vpermilpd((__v2df)__A, C); })
+
+#define _mm256_permute_pd(A, C) __extension__ ({ \
+  __m256d __A = (A); \
+  (__m256d)__builtin_ia32_vpermilpd256((__v4df)__A, C); })
+
+#define _mm_permute_ps(A, C) __extension__ ({ \
+  __m128 __A = (A); \
+  (__m128)__builtin_ia32_vpermilps((__v4sf)__A, C); })
+
+#define _mm256_permute_ps(A, C) __extension__ ({ \
+  __m256 __A = (A); \
+  (__m256)__builtin_ia32_vpermilps256((__v8sf)__A, C); })
 
-static __inline __m256d __attribute__((__always_inline__, __nodebug__))
-_mm256_permute_pd(__m256d a, const int c)
-{
-  return (__m256d)__builtin_ia32_vpermilpd256((__v4df)a, c);
-}
-
-static __inline __m128 __attribute__((__always_inline__, __nodebug__))
-_mm_permute_ps(__m128 a, const int c)
-{
-  return (__m128)__builtin_ia32_vpermilps((__v4sf)a, c);
-}
-
-static __inline __m256 __attribute__((__always_inline__, __nodebug__))
-_mm256_permute_ps(__m256 a, const int c)
-{
-  return (__m256)__builtin_ia32_vpermilps256((__v8sf)a, c);
-}
-
-static __inline __m256d __attribute__((__always_inline__, __nodebug__))
-_mm256_permute2f128_pd(__m256d a, __m256d b, const int c)
-{
-  return (__m256d)__builtin_ia32_vperm2f128_pd256((__v4df)a, (__v4df)b, c);
-}
+#define _mm256_permute2f128_pd(V1, V2, M) __extension__ ({ \
+  __m256d __V1 = (V1); \
+  __m256d __V2 = (V2); \
+  (__m256d)__builtin_ia32_vperm2f128_pd256((__v4df)__V1, (__v4df)__V2, M); })
 
-static __inline __m256 __attribute__((__always_inline__, __nodebug__))
-_mm256_permute2f128_ps(__m256 a, __m256 b, const int c)
-{
-  return (__m256)__builtin_ia32_vperm2f128_ps256((__v8sf)a, (__v8sf)b, c);
-}
+#define _mm256_permute2f128_ps(V1, V2, M) __extension__ ({ \
+  __m256 __V1 = (V1); \
+  __m256 __V2 = (V2); \
+  (__m256)__builtin_ia32_vperm2f128_ps256((__v8sf)__V1, (__v8sf)__V2, M); })
 
-static __inline __m256i __attribute__((__always_inline__, __nodebug__))
-_mm256_permute2f128_si256(__m256i a, __m256i b, const int c)
-{
-  return (__m256i)__builtin_ia32_vperm2f128_si256((__v8si)a, (__v8si)b, c);
-}
+#define _mm256_permute2f128_si256(V1, V2, M) __extension__ ({ \
+  __m256i __V1 = (V1); \
+  __m256i __V2 = (V2); \
+  (__m256i)__builtin_ia32_vperm2f128_si256((__v8si)__V1, (__v8si)__V2, M); })
 
 /* Vector Blend */
 #define _mm256_blend_pd(V1, V2, M) __extension__ ({ \
@@ -417,23 +402,17 @@
   (__m128)__builtin_ia32_cmpss((__v4sf)__a, (__v4sf)__b, (c)); })
 
 /* Vector extract */
-static __inline __m128d __attribute__((__always_inline__, __nodebug__))
-_mm256_extractf128_pd(__m256d a, const int o)
-{
-  return (__m128d)__builtin_ia32_vextractf128_pd256((__v4df)a, o);
-}
-
-static __inline __m128 __attribute__((__always_inline__, __nodebug__))
-_mm256_extractf128_ps(__m256 a, const int o)
-{
-  return (__m128)__builtin_ia32_vextractf128_ps256((__v8sf)a, o);
-}
-
-static __inline __m128i __attribute__((__always_inline__, __nodebug__))
-_mm256_extractf128_si256(__m256i a, const int o)
-{
-  return (__m128i)__builtin_ia32_vextractf128_si256((__v8si)a, o);
-}
+#define _mm256_extractf128_pd(A, O) __extension__ ({ \
+  __m256d __A = (A); \
+  (__m128d)__builtin_ia32_vextractf128_pd256((__v4df)__A, O); })
+
+#define _mm256_extractf128_ps(A, O) __extension__ ({ \
+  __m256 __A = (A); \
+  (__m128)__builtin_ia32_vextractf128_ps256((__v8sf)__A, O); })
+
+#define _mm256_extractf128_si256(A, O) __extension__ ({ \
+  __m256i __A = (A); \
+  (__m128i)__builtin_ia32_vextractf128_si256((__v8si)__A, O); })
 
 static __inline int __attribute__((__always_inline__, __nodebug__))
 _mm256_extract_epi32(__m256i a, int const imm)
@@ -466,23 +445,20 @@
 #endif
 
 /* Vector insert */
-static __inline __m256d __attribute__((__always_inline__, __nodebug__))
-_mm256_insertf128_pd(__m256d a, __m128d b, const int o)
-{
-  return (__m256d)__builtin_ia32_vinsertf128_pd256((__v4df)a, (__v2df)b, o);
-}
+#define _mm256_insertf128_pd(V1, V2, O) __extension__ ({ \
+  __m256d __V1 = (V1); \
+  __m128d __V2 = (V2); \
+  (__m256d)__builtin_ia32_vinsertf128_pd256((__v4df)__V1, (__v2df)__V2, O); })
 
-static __inline __m256 __attribute__((__always_inline__, __nodebug__))
-_mm256_insertf128_ps(__m256 a, __m128 b, const int o)
-{
-  return (__m256)__builtin_ia32_vinsertf128_ps256((__v8sf)a, (__v4sf)b, o);
-}
+#define _mm256_insertf128_ps(V1, V2, O) __extension__ ({ \
+  __m256 __V1 = (V1); \
+  __m128 __V2 = (V2); \
+  (__m256)__builtin_ia32_vinsertf128_ps256((__v8sf)__V1, (__v4sf)__V2, O); })
 
-static __inline __m256i __attribute__((__always_inline__, __nodebug__))
-_mm256_insertf128_si256(__m256i a, __m128i b, const int o)
-{
-  return (__m256i)__builtin_ia32_vinsertf128_si256((__v8si)a, (__v4si)b, o);
-}
+#define _mm256_insertf128_si256(V1, V2, O) __extension__ ({ \
+  __m256i __V1 = (V1); \
+  __m128i __V2 = (V2); \
+  (__m256i)__builtin_ia32_vinsertf128_si256((__v8si)__V1, (__v4si)__V2, O); })
 
 static __inline __m256i __attribute__((__always_inline__, __nodebug__))
 _mm256_insert_epi32(__m256i a, int b, int const imm)

Modified: cfe/branches/tooling/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Lex/PPDirectives.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Lex/PPDirectives.cpp (original)
+++ cfe/branches/tooling/lib/Lex/PPDirectives.cpp Sat Dec 17 00:38:54 2011
@@ -577,9 +577,25 @@
   //   A(abc
   //     #warning blah
   //   def)
-  // If so, the user is relying on non-portable behavior, emit a diagnostic.
-  if (InMacroArgs)
+  // If so, the user is relying on undefined behavior, emit a diagnostic. Do
+  // not support this for #include-like directives, since that can result in
+  // terrible diagnostics, and does not work in GCC.
+  if (InMacroArgs) {
+    if (IdentifierInfo *II = Result.getIdentifierInfo()) {
+      switch (II->getPPKeywordID()) {
+      case tok::pp_include:
+      case tok::pp_import:
+      case tok::pp_include_next:
+      case tok::pp___include_macros:
+        Diag(Result, diag::err_embedded_include) << II->getName();
+        DiscardUntilEndOfDirective();
+        return;
+      default:
+        break;
+      }
+    }
     Diag(Result, diag::ext_embedded_directive);
+  }
 
 TryAgain:
   switch (Result.getKind()) {

Modified: cfe/branches/tooling/lib/Lex/PPMacroExpansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Lex/PPMacroExpansion.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/branches/tooling/lib/Lex/PPMacroExpansion.cpp Sat Dec 17 00:38:54 2011
@@ -116,6 +116,11 @@
   // If the token isn't an identifier, it's always literally expanded.
   if (II == 0) return true;
 
+  // If the information about this identifier is out of date, update it from
+  // the external source.
+  if (II->isOutOfDate())
+    PP.getExternalSource()->updateOutOfDateIdentifier(*II);
+
   // If the identifier is a macro, and if that macro is enabled, it may be
   // expanded so it's not a trivial expansion.
   if (II->hasMacroDefinition() && PP.getMacroInfo(II)->isEnabled() &&

Modified: cfe/branches/tooling/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseExprCXX.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseExprCXX.cpp Sat Dec 17 00:38:54 2011
@@ -1019,6 +1019,17 @@
   // Parse the tilde.
   assert(Tok.is(tok::tilde) && "ParseOptionalCXXScopeSpecifier fail");
   SourceLocation TildeLoc = ConsumeToken();
+
+  if (Tok.is(tok::kw_decltype) && !FirstTypeName.isValid() && SS.isEmpty()) {
+    DeclSpec DS(AttrFactory);
+    SourceLocation EndLoc = ParseDecltypeSpecifier(DS);
+    if (DS.getTypeSpecType() == TST_error)
+      return ExprError();
+    return Actions.ActOnPseudoDestructorExpr(getCurScope(), Base, OpLoc, 
+                                             OpKind, TildeLoc, DS, 
+                                             Tok.is(tok::l_paren));
+  }
+
   if (!Tok.is(tok::identifier)) {
     Diag(Tok, diag::err_destructor_tilde_identifier);
     return ExprError();

Modified: cfe/branches/tooling/lib/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/ParseObjc.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/ParseObjc.cpp (original)
+++ cfe/branches/tooling/lib/Parse/ParseObjc.cpp Sat Dec 17 00:38:54 2011
@@ -366,8 +366,12 @@
       allMethods.push_back(methodPrototype);
       // Consume the ';' here, since ParseObjCMethodPrototype() is re-used for
       // method definitions.
-      ExpectAndConsume(tok::semi, diag::err_expected_semi_after_method_proto,
-                       "", tok::semi);
+      if (ExpectAndConsumeSemi(diag::err_expected_semi_after_method_proto)) {
+        // We didn't find a semi and we error'ed out. Skip until a ';' or '@'.
+        SkipUntil(tok::at, /*StopAtSemi=*/true, /*DontConsume=*/true);
+        if (Tok.is(tok::semi))
+          ConsumeToken();
+      }
       continue;
     }
     if (Tok.is(tok::l_paren)) {
@@ -2564,7 +2568,10 @@
  }
 
 Decl *Parser::ParseLexedObjCMethodDefs(LexedMethod &LM) {
-    
+
+  // Save the current token position.
+  SourceLocation OrigLoc = Tok.getLocation();
+
   assert(!LM.Toks.empty() && "ParseLexedObjCMethodDef - Empty body!");
   // Append the current token at the end of the new token stream so that it
   // doesn't get lost.
@@ -2603,5 +2610,19 @@
   // Leave the function body scope.
   BodyScope.Exit();
     
-  return Actions.ActOnFinishFunctionBody(MDecl, FnBody.take());
+  MDecl = Actions.ActOnFinishFunctionBody(MDecl, FnBody.take());
+
+  if (Tok.getLocation() != OrigLoc) {
+    // Due to parsing error, we either went over the cached tokens or
+    // there are still cached tokens left. If it's the latter case skip the
+    // leftover tokens.
+    // Since this is an uncommon situation that should be avoided, use the
+    // expensive isBeforeInTranslationUnit call.
+    if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(),
+                                                     OrigLoc))
+      while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof))
+        ConsumeAnyToken();
+  }
+  
+  return MDecl;
 }

Modified: cfe/branches/tooling/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Parse/Parser.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Parse/Parser.cpp (original)
+++ cfe/branches/tooling/lib/Parse/Parser.cpp Sat Dec 17 00:38:54 2011
@@ -284,9 +284,6 @@
       ConsumeStringToken();
       break;
         
-    case tok::at:
-      return false;
-      
     case tok::semi:
       if (StopAtSemi)
         return false;

Modified: cfe/branches/tooling/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/Sema.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/Sema.cpp (original)
+++ cfe/branches/tooling/lib/Sema/Sema.cpp Sat Dec 17 00:38:54 2011
@@ -82,6 +82,7 @@
       ObjCInterfaceDecl *ProtocolDecl =
         ObjCInterfaceDecl::Create(Context, CurContext, SourceLocation(),
                                   &Context.Idents.get("Protocol"),
+                                  /*PrevDecl=*/0,
                                   SourceLocation(), true);
       Context.setObjCProtoType(Context.getObjCInterfaceType(ProtocolDecl));
       PushOnScopeChains(ProtocolDecl, TUScope, false);

Modified: cfe/branches/tooling/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaChecking.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaChecking.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaChecking.cpp Sat Dec 17 00:38:54 2011
@@ -4277,7 +4277,7 @@
 
 void Sema::CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
                             const ArraySubscriptExpr *ASE,
-                            bool AllowOnePastEnd) {
+                            bool AllowOnePastEnd, bool IndexNegated) {
   IndexExpr = IndexExpr->IgnoreParenCasts();
   if (IndexExpr->isValueDependent())
     return;
@@ -4292,6 +4292,8 @@
   llvm::APSInt index;
   if (!IndexExpr->EvaluateAsInt(index, Context))
     return;
+  if (IndexNegated)
+    index = -index;
 
   const NamedDecl *ND = NULL;
   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(BaseExpr))

Modified: cfe/branches/tooling/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaDecl.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaDecl.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaDecl.cpp Sat Dec 17 00:38:54 2011
@@ -2367,8 +2367,6 @@
   bool emittedWarning = false;
          
   if (RecordDecl *Record = dyn_cast_or_null<RecordDecl>(Tag)) {
-    ProcessDeclAttributeList(S, Record, DS.getAttributes().getList());
-    
     if (!Record->getDeclName() && Record->isCompleteDefinition() &&
         DS.getStorageClassSpec() != DeclSpec::SCS_typedef) {
       if (getLangOptions().CPlusPlus ||
@@ -2463,7 +2461,27 @@
       << Tag->getTagKind()
       << FixItHint::CreateRemoval(DS.getModulePrivateSpecLoc());
 
-  // FIXME: Warn on useless attributes
+  // Warn about ignored type attributes, for example:
+  // __attribute__((aligned)) struct A;
+  // Attributes should be placed after tag to apply to type declaration.
+  if (!DS.getAttributes().empty()) {
+    DeclSpec::TST TypeSpecType = DS.getTypeSpecType();
+    if (TypeSpecType == DeclSpec::TST_class ||
+        TypeSpecType == DeclSpec::TST_struct ||
+        TypeSpecType == DeclSpec::TST_union ||
+        TypeSpecType == DeclSpec::TST_enum) {
+      AttributeList* attrs = DS.getAttributes().getList();
+      while (attrs) {
+        Diag(attrs->getScopeLoc(),
+             diag::warn_declspec_attribute_ignored)
+        << attrs->getName()
+        << (TypeSpecType == DeclSpec::TST_class ? 0 :
+            TypeSpecType == DeclSpec::TST_struct ? 1 :
+            TypeSpecType == DeclSpec::TST_union ? 2 : 3);
+        attrs = attrs->getNext();
+      }
+    }
+  }
 
   return TagD;
 }

Modified: cfe/branches/tooling/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaDeclAttr.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaDeclAttr.cpp Sat Dec 17 00:38:54 2011
@@ -1753,10 +1753,8 @@
       return;
     }
   }
-  else {
+  else 
     S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
-    return;
-  }
   D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getRange(), S.Context));
 }
 

Modified: cfe/branches/tooling/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaDeclObjC.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaDeclObjC.cpp Sat Dec 17 00:38:54 2011
@@ -366,11 +366,11 @@
   }
 
   // Create a declaration to describe this @interface.
+  ObjCInterfaceDecl* PrevIDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
   ObjCInterfaceDecl *IDecl
     = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc, ClassName,
-                                ClassLoc);
+                                PrevIDecl, ClassLoc);
   
-  ObjCInterfaceDecl* PrevIDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
   if (PrevIDecl) {
     // Class already seen. Was it a definition?
     if (ObjCInterfaceDecl *Def = PrevIDecl->getDefinition()) {
@@ -379,9 +379,6 @@
       Diag(Def->getLocation(), diag::note_previous_definition);
       IDecl->setInvalidDecl();
     }
-
-    // Link to the previous declaration.
-    IDecl->setPreviousDeclaration(PrevIDecl);
   }
   
   if (AttrList)
@@ -870,9 +867,8 @@
     Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
     Diag(PrevDecl->getLocation(), diag::note_previous_definition);
   } else if ((IDecl = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl))) {
-    if (RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl),
-                            diag::warn_undef_interface))
-      IDecl = 0;
+    RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl),
+                        diag::warn_undef_interface);
   } else {
     // We did not find anything with the name ClassName; try to correct for 
     // typos in the class name.
@@ -928,7 +924,8 @@
     // FIXME: Do we support attributes on the @implementation? If so we should
     // copy them over.
     IDecl = ObjCInterfaceDecl::Create(Context, CurContext, AtClassImplLoc,
-                                      ClassName, ClassLoc, true);
+                                      ClassName, /*PrevDecl=*/0, ClassLoc, 
+                                      true);
     IDecl->startDefinition();
     if (SDecl) {
       IDecl->setSuperClass(SDecl);
@@ -1774,16 +1771,13 @@
     }
     
     // Create a declaration to describe this forward declaration.
+    ObjCInterfaceDecl *PrevIDecl
+      = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl);
     ObjCInterfaceDecl *IDecl
       = ObjCInterfaceDecl::Create(Context, CurContext, AtClassLoc,
-                                  IdentList[i], IdentLocs[i], true);
+                                  IdentList[i], PrevIDecl, IdentLocs[i], true);
     IDecl->setAtEndRange(IdentLocs[i]);
     
-    // If there was a previous declaration, link to it.
-    if (ObjCInterfaceDecl *PrevIDecl
-        = dyn_cast_or_null<ObjCInterfaceDecl>(PrevDecl))
-      IDecl->setPreviousDeclaration(PrevIDecl);
-
     // Create the forward declaration. Note that we intentionally do this 
     // before we add the ObjCInterfaceDecl we just created, so that the
     // rewriter sees the ObjCClassDecl first.

Modified: cfe/branches/tooling/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaExpr.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaExpr.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaExpr.cpp Sat Dec 17 00:38:54 2011
@@ -6203,11 +6203,9 @@
       if (!checkArithmeticOpPointerOperand(*this, Loc, LHS.get()))
         return QualType();
 
-      Expr *IExpr = RHS.get()->IgnoreParenCasts();
-      UnaryOperator negRex(IExpr, UO_Minus, IExpr->getType(), VK_RValue,
-                           OK_Ordinary, IExpr->getExprLoc());
       // Check array bounds for pointer arithemtic
-      CheckArrayAccess(LHS.get()->IgnoreParenCasts(), &negRex);
+      CheckArrayAccess(LHS.get(), RHS.get(), /*ArraySubscriptExpr*/0,
+                       /*AllowOnePastEnd*/true, /*IndexNegated*/true);
 
       if (CompLHSTy) *CompLHSTy = LHS.get()->getType();
       return LHS.get()->getType();

Modified: cfe/branches/tooling/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaExprCXX.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaExprCXX.cpp Sat Dec 17 00:38:54 2011
@@ -28,6 +28,7 @@
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Lex/Preprocessor.h"
+#include "TypeLocBuilder.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/ErrorHandling.h"
 using namespace clang;
@@ -4313,37 +4314,45 @@
                        /*RPLoc*/ ExpectedLParenLoc);
 }
 
-ExprResult Sema::BuildPseudoDestructorExpr(Expr *Base,
-                                           SourceLocation OpLoc,
-                                           tok::TokenKind OpKind,
-                                           const CXXScopeSpec &SS,
-                                           TypeSourceInfo *ScopeTypeInfo,
-                                           SourceLocation CCLoc,
-                                           SourceLocation TildeLoc,
-                                         PseudoDestructorTypeStorage Destructed,
-                                           bool HasTrailingLParen) {
-  TypeSourceInfo *DestructedTypeInfo = Destructed.getTypeSourceInfo();
-
+static bool CheckArrow(Sema& S, QualType& ObjectType, Expr *Base, 
+                   tok::TokenKind& OpKind, SourceLocation OpLoc) {
   // C++ [expr.pseudo]p2:
   //   The left-hand side of the dot operator shall be of scalar type. The
   //   left-hand side of the arrow operator shall be of pointer to scalar type.
   //   This scalar type is the object type.
-  QualType ObjectType = Base->getType();
   if (OpKind == tok::arrow) {
     if (const PointerType *Ptr = ObjectType->getAs<PointerType>()) {
       ObjectType = Ptr->getPointeeType();
     } else if (!Base->isTypeDependent()) {
       // The user wrote "p->" when she probably meant "p."; fix it.
-      Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
+      S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
         << ObjectType << true
         << FixItHint::CreateReplacement(OpLoc, ".");
-      if (isSFINAEContext())
-        return ExprError();
+      if (S.isSFINAEContext())
+        return true;
 
       OpKind = tok::period;
     }
   }
 
+  return false;
+}
+
+ExprResult Sema::BuildPseudoDestructorExpr(Expr *Base,
+                                           SourceLocation OpLoc,
+                                           tok::TokenKind OpKind,
+                                           const CXXScopeSpec &SS,
+                                           TypeSourceInfo *ScopeTypeInfo,
+                                           SourceLocation CCLoc,
+                                           SourceLocation TildeLoc,
+                                         PseudoDestructorTypeStorage Destructed,
+                                           bool HasTrailingLParen) {
+  TypeSourceInfo *DestructedTypeInfo = Destructed.getTypeSourceInfo();
+
+  QualType ObjectType = Base->getType();
+  if (CheckArrow(*this, ObjectType, Base, OpKind, OpLoc))
+    return ExprError();
+
   if (!ObjectType->isDependentType() && !ObjectType->isScalarType()) {
     Diag(OpLoc, diag::err_pseudo_dtor_base_not_scalar)
       << ObjectType << Base->getSourceRange();
@@ -4442,25 +4451,9 @@
           SecondTypeName.getKind() == UnqualifiedId::IK_Identifier) &&
          "Invalid second type name in pseudo-destructor");
 
-  // C++ [expr.pseudo]p2:
-  //   The left-hand side of the dot operator shall be of scalar type. The
-  //   left-hand side of the arrow operator shall be of pointer to scalar type.
-  //   This scalar type is the object type.
   QualType ObjectType = Base->getType();
-  if (OpKind == tok::arrow) {
-    if (const PointerType *Ptr = ObjectType->getAs<PointerType>()) {
-      ObjectType = Ptr->getPointeeType();
-    } else if (!ObjectType->isDependentType()) {
-      // The user wrote "p->" when she probably meant "p."; fix it.
-      Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
-        << ObjectType << true
-        << FixItHint::CreateReplacement(OpLoc, ".");
-      if (isSFINAEContext())
-        return ExprError();
-
-      OpKind = tok::period;
-    }
-  }
+  if (CheckArrow(*this, ObjectType, Base, OpKind, OpLoc))
+    return ExprError();
 
   // Compute the object type that we should use for name lookup purposes. Only
   // record types and dependent types matter.
@@ -4580,6 +4573,30 @@
                                    Destructed, HasTrailingLParen);
 }
 
+ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
+                                           SourceLocation OpLoc,
+                                           tok::TokenKind OpKind,
+                                           SourceLocation TildeLoc, 
+                                           const DeclSpec& DS,
+                                           bool HasTrailingLParen) {
+  
+  QualType ObjectType = Base->getType();
+  if (CheckArrow(*this, ObjectType, Base, OpKind, OpLoc))
+    return ExprError();
+
+  QualType T = BuildDecltypeType(DS.getRepAsExpr(), DS.getTypeSpecTypeLoc());
+
+  TypeLocBuilder TLB;
+  DecltypeTypeLoc DecltypeTL = TLB.push<DecltypeTypeLoc>(T);
+  DecltypeTL.setNameLoc(DS.getTypeSpecTypeLoc());
+  TypeSourceInfo *DestructedTypeInfo = TLB.getTypeSourceInfo(Context, T);
+  PseudoDestructorTypeStorage Destructed(DestructedTypeInfo);
+
+  return BuildPseudoDestructorExpr(Base, OpLoc, OpKind, CXXScopeSpec(),
+                                   0, SourceLocation(), TildeLoc,
+                                   Destructed, HasTrailingLParen);
+}
+
 ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl,
                                         CXXMethodDecl *Method,
                                         bool HadMultipleCandidates) {

Modified: cfe/branches/tooling/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Sema/SemaInit.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Sema/SemaInit.cpp (original)
+++ cfe/branches/tooling/lib/Sema/SemaInit.cpp Sat Dec 17 00:38:54 2011
@@ -171,6 +171,9 @@
   bool hadError;
   bool VerifyOnly; // no diagnostics, no structure building
   bool AllowBraceElision;
+  Expr *LastCheckedSubobject;
+  unsigned LastCheckedSubobjectIndex;
+  
   std::map<InitListExpr *, InitListExpr *> SyntacticToSemantic;
   InitListExpr *FullyStructuredList;
 
@@ -470,7 +473,8 @@
 InitListChecker::InitListChecker(Sema &S, const InitializedEntity &Entity,
                                  InitListExpr *IL, QualType &T,
                                  bool VerifyOnly, bool AllowBraceElision)
-  : SemaRef(S), VerifyOnly(VerifyOnly), AllowBraceElision(AllowBraceElision) {
+  : SemaRef(S), VerifyOnly(VerifyOnly), AllowBraceElision(AllowBraceElision),
+    LastCheckedSubobject(0), LastCheckedSubobjectIndex(0) {
   hadError = false;
 
   unsigned newIndex = 0;
@@ -792,13 +796,40 @@
 
     if (Seq) {
       if (!VerifyOnly) {
-        ExprResult Result =
-          Seq.Perform(SemaRef, Entity, Kind, MultiExprArg(&expr, 1));
-        if (Result.isInvalid())
-          hadError = true;
+        // struct S {
+        //   S(int);
+        // };
+        //
+        // S s[] = { [0 ... 2] = 3 };
+        //
+        // In code like this, we want to perform the initialization and then
+        // update the syntactic list with the result. However, we reach this
+        // point once for each subobject, but the update needs
+        // to be done only once for each syntactic element. For this reason,
+        // the initialization result and its syntactic Index are cached in
+        // LastCheckedSubobject and LastCheckedSubobjectIndex and reused until
+        // we move to the next Index.
+        Expr *ResultExpr = LastCheckedSubobject;
+        
+        if (!ResultExpr || Index != LastCheckedSubobjectIndex) {
+          ExprResult Result = Seq.Perform(SemaRef, Entity, Kind, MultiExprArg(&expr, 1));
+
+          if (Result.isInvalid()) {
+            hadError = true;
+            ResultExpr = 0;
+          } else {
+            ResultExpr = Result.takeAs<Expr>();
+          }
+          
+          LastCheckedSubobject = ResultExpr;
+          LastCheckedSubobjectIndex = Index;
+        }
+
+        // Update the syntactic list
+        IList->setInit(Index, ResultExpr);
 
         UpdateStructuredListElement(StructuredList, StructuredIndex,
-                                    Result.takeAs<Expr>());
+                                    ResultExpr);
       }
       ++Index;
       return;
@@ -5707,7 +5738,7 @@
            ? diag::err_init_list_constant_narrowing
            : diag::warn_init_list_constant_narrowing)
       << InitE->getSourceRange()
-      << ConstantValue
+      << ConstantValue.getAsString(S.getASTContext(), EntityType)
       << EntityType.getLocalUnqualifiedType();
   } else
     S.Diag(InitE->getLocStart(),

Modified: cfe/branches/tooling/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Serialization/ASTReader.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Serialization/ASTReader.cpp (original)
+++ cfe/branches/tooling/lib/Serialization/ASTReader.cpp Sat Dec 17 00:38:54 2011
@@ -4559,7 +4559,7 @@
     return 0;
   }
   
-if (!DeclsLoaded[Index]) {
+  if (!DeclsLoaded[Index]) {
     ReadDeclRecord(ID);
     if (DeserializationListener)
       DeserializationListener->DeclRead(ID, DeclsLoaded[Index]);
@@ -6028,6 +6028,15 @@
   assert(NumCurrentElementsDeserializing &&
          "FinishedDeserializing not paired with StartedDeserializing");
   if (NumCurrentElementsDeserializing == 1) {
+
+    // Fully load the interesting decls, including deserializing their bodies,
+    // so that any other declarations that get referenced in the body will be
+    // fully deserialized by the time we pass them to the consumer.
+    for (std::deque<Decl *>::iterator
+           I = InterestingDecls.begin(),
+           E = InterestingDecls.end(); I != E; ++I)
+      (*I)->getBody();
+
     do {
       // If any identifiers with corresponding top-level declarations have
       // been loaded, load those declarations now.

Modified: cfe/branches/tooling/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/Serialization/ASTReaderDecl.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/branches/tooling/lib/Serialization/ASTReaderDecl.cpp Sat Dec 17 00:38:54 2011
@@ -223,6 +223,9 @@
   if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) {
     // if we have a fully initialized TypeDecl, we can safely read its type now.
     TD->setTypeForDecl(Reader.GetType(TypeIDForTypeDecl).getTypePtrOrNull());
+  } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D)) {
+    // if we have a fully initialized TypeDecl, we can safely read its type now.
+    ID->TypeForDecl = Reader.GetType(TypeIDForTypeDecl).getTypePtrOrNull();
   } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     // FunctionDecl's body was written last after all other Stmts/Exprs.
     if (Record[Idx++])
@@ -556,7 +559,7 @@
 void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
   VisitRedeclarable(ID);
   VisitObjCContainerDecl(ID);
-  ID->setTypeForDecl(Reader.readType(F, Record, Idx).getTypePtrOrNull());
+  TypeIDForTypeDecl = Reader.getGlobalTypeID(F, Record[Idx++]);
   
   ObjCInterfaceDecl *Def = ReadDeclAs<ObjCInterfaceDecl>(Record, Idx);
   if (ID == Def) {
@@ -621,13 +624,13 @@
       // pending references were linked.
       Reader.PendingForwardRefs.erase(ID);
 #endif
-    } else if (Def) {
-      if (Def->Data) {
-        ID->Data = Def->Data;
-      } else {
-        // The definition is still initializing.
-        Reader.PendingForwardRefs[Def].push_back(ID);
-      }
+    }
+  } else if (Def) {
+    if (Def->Data) {
+      ID->Data = Def->Data;
+    } else {
+      // The definition is still initializing.
+      Reader.PendingForwardRefs[Def].push_back(ID);
     }
   }
 }
@@ -1561,6 +1564,8 @@
     FD->RedeclLink.setPointer(cast<FunctionDecl>(previous));
   } else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
     VD->RedeclLink.setPointer(cast<VarDecl>(previous));
+  } else if (ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(previous)) {
+    ID->RedeclLink.setPointer(cast<ObjCInterfaceDecl>(previous));
   } else {
     RedeclarableTemplateDecl *TD = cast<RedeclarableTemplateDecl>(D);
     TD->CommonOrPrev = cast<RedeclarableTemplateDecl>(previous);
@@ -1736,7 +1741,7 @@
                                Selector(), QualType(), 0, 0);
     break;
   case DECL_OBJC_INTERFACE:
-    D = ObjCInterfaceDecl::Create(Context, 0, SourceLocation(), 0);
+    D = ObjCInterfaceDecl::CreateEmpty(Context);
     break;
   case DECL_OBJC_IVAR:
     D = ObjCIvarDecl::Create(Context, 0, SourceLocation(), SourceLocation(),

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp Sat Dec 17 00:38:54 2011
@@ -18,6 +18,7 @@
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 
 using namespace clang;
@@ -25,71 +26,128 @@
 
 namespace {
 class GenericTaintChecker : public Checker< check::PostStmt<CallExpr>,
-                                            check::PostStmt<DeclRefExpr> > {
+                                            check::PreStmt<CallExpr> > {
+public:
+  enum TaintOnPreVisitKind {
+    /// No taint propagates from pre-visit to post-visit.
+    PrevisitNone = 0,
+    /// Based on the pre-visit, the return argument of the call
+    /// should be tainted.
+    PrevisitTaintRet = 1,
+    /// Based on the pre-visit, the call can taint values through it's
+    /// pointer/reference arguments.
+    PrevisitTaintArgs = 2
+  };
 
+private:
   mutable llvm::OwningPtr<BugType> BT;
   void initBugType() const;
 
   /// Given a pointer argument, get the symbol of the value it contains
   /// (points to).
   SymbolRef getPointedToSymbol(CheckerContext &C,
-                               const Expr* Arg,
+                               const Expr *Arg,
                                bool IssueWarning = true) const;
 
-  /// Functions defining the attacke surface.
-  typedef void (GenericTaintChecker::*FnCheck)(const CallExpr *,
-                                               CheckerContext &C) const;
-  void processScanf(const CallExpr *CE, CheckerContext &C) const;
-  void processFscanf(const CallExpr *CE, CheckerContext &C) const;
-  void processRetTaint(const CallExpr *CE, CheckerContext &C) const;
+  /// Functions defining the attack surface.
+  typedef const ProgramState *(GenericTaintChecker::*FnCheck)(const CallExpr *,
+                                                       CheckerContext &C) const;
+  const ProgramState *postScanf(const CallExpr *CE, CheckerContext &C) const;
+  const ProgramState *postFscanf(const CallExpr *CE, CheckerContext &C) const;
+  const ProgramState *postRetTaint(const CallExpr *CE, CheckerContext &C) const;
+  const ProgramState *postDefault(const CallExpr *CE, CheckerContext &C) const;
+
+  /// Taint the scanned input if the file is tainted.
+  const ProgramState *preFscanf(const CallExpr *CE, CheckerContext &C) const;
+  /// Taint if any of the arguments are tainted.
+  const ProgramState *preAnyArgs(const CallExpr *CE, CheckerContext &C) const;
 
+  /// Check if the region the expression evaluates to is the standard input,
+  /// and thus, is tainted.
   bool isStdin(const Expr *E, CheckerContext &C) const;
-  bool isStdin(const DeclRefExpr *E, CheckerContext &C) const;
 
 public:
+  static void *getTag() { static int Tag; return &Tag; }
+
   void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
   void checkPostStmt(const DeclRefExpr *DRE, CheckerContext &C) const;
+
+  void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
+
 };
 }
 
+/// Definitions for the checker specific state.
+namespace { struct TaintOnPreVisit {};}
+namespace clang {
+namespace ento {
+  /// A flag which is used to pass information from call pre-visit instruction
+  /// to the call post-visit. The value is an unsigned, which takes on values
+  /// of the TaintOnPreVisitKind enumeration.
+  template<>
+  struct ProgramStateTrait<TaintOnPreVisit> :
+    public ProgramStatePartialTrait<unsigned> {
+    static void *GDMIndex() { return GenericTaintChecker::getTag(); }
+  };
+}
+}
+
 inline void GenericTaintChecker::initBugType() const {
   if (!BT)
     BT.reset(new BugType("Tainted data checking", "General"));
 }
 
-void GenericTaintChecker::checkPostStmt(const CallExpr *CE,
-                                        CheckerContext &C) const {
-  if (!C.getState())
-    return;
+void GenericTaintChecker::checkPreStmt(const CallExpr *CE,
+                                       CheckerContext &C) const {
+  const ProgramState *State = C.getState();
 
+  // Set the evaluation function by switching on the callee name.
   StringRef Name = C.getCalleeName(CE);
+  FnCheck evalFunction = llvm::StringSwitch<FnCheck>(Name)
+    .Case("fscanf", &GenericTaintChecker::preFscanf)
+    .Case("atoi", &GenericTaintChecker::preAnyArgs)
+    .Case("atol", &GenericTaintChecker::preAnyArgs)
+    .Case("atoll", &GenericTaintChecker::preAnyArgs)
+    .Default(0);
+
+  // Check and evaluate the call.
+  if (evalFunction)
+    State = (this->*evalFunction)(CE, C);
+  if (!State)
+    return;
+
+  C.addTransition(State);
+}
+
+void GenericTaintChecker::checkPostStmt(const CallExpr *CE,
+                                        CheckerContext &C) const {
+  const ProgramState *State = C.getState();
   
   // Define the attack surface.
   // Set the evaluation function by switching on the callee name.
+  StringRef Name = C.getCalleeName(CE);
   FnCheck evalFunction = llvm::StringSwitch<FnCheck>(Name)
-    .Case("scanf", &GenericTaintChecker::processScanf)
-    .Case("fscanf", &GenericTaintChecker::processFscanf)
-    .Case("sscanf", &GenericTaintChecker::processFscanf)
+    .Case("scanf", &GenericTaintChecker::postScanf)
+    .Case("fscanf", &GenericTaintChecker::postFscanf)
+    .Case("sscanf", &GenericTaintChecker::postFscanf)
     // TODO: Add support for vfscanf & family.
-    .Case("getchar", &GenericTaintChecker::processRetTaint)
-    .Case("getenv", &GenericTaintChecker::processRetTaint)
-    .Case("fopen", &GenericTaintChecker::processRetTaint)
-    .Case("fdopen", &GenericTaintChecker::processRetTaint)
-    .Case("freopen", &GenericTaintChecker::processRetTaint)
-    .Default(NULL);
+    .Case("getchar", &GenericTaintChecker::postRetTaint)
+    .Case("getenv", &GenericTaintChecker::postRetTaint)
+    .Case("fopen", &GenericTaintChecker::postRetTaint)
+    .Case("fdopen", &GenericTaintChecker::postRetTaint)
+    .Case("freopen", &GenericTaintChecker::postRetTaint)
+    .Default(&GenericTaintChecker::postDefault);
 
   // If the callee isn't defined, it is not of security concern.
   // Check and evaluate the call.
   if (evalFunction)
-    (this->*evalFunction)(CE, C);
-}
+    State = (this->*evalFunction)(CE, C);
+  if (!State)
+    return;
 
-void GenericTaintChecker::checkPostStmt(const DeclRefExpr *DRE,
-                                       CheckerContext &C) const {
-  if (isStdin(DRE, C)) {
-    const ProgramState *NewState = C.getState()->addTaint(DRE);
-    C.addTransition(NewState);
-  }
+  assert(State->get<TaintOnPreVisit>() == PrevisitNone &&
+         "State has to be cleared.");
+  C.addTransition(State);
 }
 
 SymbolRef GenericTaintChecker::getPointedToSymbol(CheckerContext &C,
@@ -97,13 +155,8 @@
                                                   bool IssueWarning) const {
   const ProgramState *State = C.getState();
   SVal AddrVal = State->getSVal(Arg->IgnoreParens());
-
-  // TODO: Taint is not going to propagate? Should we ever peel off the casts
-  // IgnoreParenImpCasts()?
-  if (AddrVal.isUnknownOrUndef()) {
-    assert(State->getSVal(Arg->IgnoreParenImpCasts()).isUnknownOrUndef());
+  if (AddrVal.isUnknownOrUndef())
     return 0;
-  }
 
   Loc *AddrLoc = dyn_cast<Loc>(&AddrVal);
 
@@ -126,8 +179,45 @@
   return Val.getAsSymbol();
 }
 
-void GenericTaintChecker::processScanf(const CallExpr *CE,
-                                       CheckerContext &C) const {
+const ProgramState *GenericTaintChecker::preFscanf(const CallExpr *CE,
+                                                   CheckerContext &C) const {
+  assert(CE->getNumArgs() >= 2);
+  const ProgramState *State = C.getState();
+
+  // Check is the file descriptor is tainted.
+  if (State->isTainted(CE->getArg(0)) || isStdin(CE->getArg(0), C))
+    return State->set<TaintOnPreVisit>(PrevisitTaintArgs);
+  return 0;
+}
+
+// If any other arguments are tainted, mark state as tainted on pre-visit.
+const ProgramState * GenericTaintChecker::preAnyArgs(const CallExpr *CE,
+                                                     CheckerContext &C) const {
+  for (unsigned int i = 0; i < CE->getNumArgs(); ++i) {
+    const ProgramState *State = C.getState();
+    const Expr *Arg = CE->getArg(i);
+    if (State->isTainted(Arg) || State->isTainted(getPointedToSymbol(C, Arg)))
+      return State = State->set<TaintOnPreVisit>(PrevisitTaintRet);
+  }
+  return 0;
+}
+
+const ProgramState *GenericTaintChecker::postDefault(const CallExpr *CE,
+                                                     CheckerContext &C) const {
+  const ProgramState *State = C.getState();
+
+  // Check if we know that the result needs to be tainted based on the
+  // pre-visit analysis.
+  if (State->get<TaintOnPreVisit>() == PrevisitTaintRet) {
+    State = State->addTaint(CE);
+    return State->set<TaintOnPreVisit>(PrevisitNone);
+  }
+
+  return 0;
+}
+
+const ProgramState *GenericTaintChecker::postScanf(const CallExpr *CE,
+                                                   CheckerContext &C) const {
   const ProgramState *State = C.getState();
   assert(CE->getNumArgs() >= 2);
   SVal x = State->getSVal(CE->getArg(1));
@@ -136,23 +226,27 @@
     // The arguments are pointer arguments. The data they are pointing at is
     // tainted after the call.
     const Expr* Arg = CE->getArg(i);
-    SymbolRef Sym = getPointedToSymbol(C, Arg);
+        SymbolRef Sym = getPointedToSymbol(C, Arg);
     if (Sym)
       State = State->addTaint(Sym);
   }
-  C.addTransition(State);
+  return State;
 }
 
 /// If argument 0 (file descriptor) is tainted, all arguments except for arg 0
 /// and arg 1 should get taint.
-void GenericTaintChecker::processFscanf(const CallExpr *CE,
-                                        CheckerContext &C) const {
+const ProgramState *GenericTaintChecker::postFscanf(const CallExpr *CE,
+                                                    CheckerContext &C) const {
   const ProgramState *State = C.getState();
   assert(CE->getNumArgs() >= 2);
 
-  // Check is the file descriptor is tainted.
-  if (!State->isTainted(CE->getArg(0)) && !isStdin(CE->getArg(0), C))
-    return;
+  // Fscanf is only tainted if the input file is tainted at pre visit, so
+  // check for that first.
+  if (State->get<TaintOnPreVisit>() == PrevisitNone)
+    return 0;
+
+  // Reset the taint state.
+  State = State->set<TaintOnPreVisit>(PrevisitNone);
 
   // All arguments except for the first two should get taint.
   for (unsigned int i = 2; i < CE->getNumArgs(); ++i) {
@@ -163,39 +257,48 @@
     if (Sym)
       State = State->addTaint(Sym);
   }
-  C.addTransition(State);
+  return State;
 }
 
-void GenericTaintChecker::processRetTaint(const CallExpr *CE,
-                                          CheckerContext &C) const {
-  const ProgramState *NewState = C.getState()->addTaint(CE);
-  C.addTransition(NewState);
+const ProgramState *GenericTaintChecker::postRetTaint(const CallExpr *CE,
+                                                      CheckerContext &C) const {
+  return C.getState()->addTaint(CE);
 }
 
 bool GenericTaintChecker::isStdin(const Expr *E,
                                   CheckerContext &C) const {
-  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()))
-    return isStdin(DR, C);
-  return false;
-}
+  const ProgramState *State = C.getState();
+  SVal Val = State->getSVal(E);
 
-bool GenericTaintChecker::isStdin(const DeclRefExpr *DR,
-                                  CheckerContext &C) const {
-  const VarDecl *D = dyn_cast_or_null<VarDecl>(DR->getDecl());
-  if (!D)
+  // stdin is a pointer, so it would be a region.
+  const MemRegion *MemReg = Val.getAsRegion();
+
+  // The region should be symbolic, we do not know it's value.
+  const SymbolicRegion *SymReg = dyn_cast_or_null<SymbolicRegion>(MemReg);
+  if (!SymReg)
     return false;
 
-  D = D->getCanonicalDecl();
-  if ((D->getName().find("stdin") != StringRef::npos) && D->isExternC())
-    if (const PointerType * PtrTy =
-          dyn_cast<PointerType>(D->getType().getTypePtr()))
-      if (PtrTy->getPointeeType() == C.getASTContext().getFILEType())
-        return true;
+  // Get it's symbol and find the declaration region it's pointing to.
+  const SymbolRegionValue *Sm =dyn_cast<SymbolRegionValue>(SymReg->getSymbol());
+  if (!Sm)
+    return false;
+  const DeclRegion *DeclReg = dyn_cast_or_null<DeclRegion>(Sm->getRegion());
+  if (!DeclReg)
+    return false;
 
+  // This region corresponds to a declaration, find out if it's a global/extern
+  // variable named stdin with the proper type.
+  if (const VarDecl *D = dyn_cast_or_null<VarDecl>(DeclReg->getDecl())) {
+    D = D->getCanonicalDecl();
+    if ((D->getName().find("stdin") != StringRef::npos) && D->isExternC())
+        if (const PointerType * PtrTy =
+              dyn_cast<PointerType>(D->getType().getTypePtr()))
+          if (PtrTy->getPointeeType() == C.getASTContext().getFILEType())
+            return true;
+  }
   return false;
 }
 
-
 void ento::registerGenericTaintChecker(CheckerManager &mgr) {
   mgr.registerChecker<GenericTaintChecker>();
 }

Modified: cfe/branches/tooling/lib/StaticAnalyzer/Core/ProgramState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/lib/StaticAnalyzer/Core/ProgramState.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/lib/StaticAnalyzer/Core/ProgramState.cpp (original)
+++ cfe/branches/tooling/lib/StaticAnalyzer/Core/ProgramState.cpp Sat Dec 17 00:38:54 2011
@@ -653,6 +653,9 @@
 
 const ProgramState* ProgramState::addTaint(const Stmt *S,
                                            TaintTagType Kind) const {
+  if (const Expr *E = dyn_cast_or_null<Expr>(S))
+    S = E->IgnoreParens();
+
   SymbolRef Sym = getSVal(S).getAsSymbol();
   if (Sym)
     return addTaint(Sym, Kind);
@@ -679,6 +682,9 @@
 }
 
 bool ProgramState::isTainted(const Stmt *S, TaintTagType Kind) const {
+  if (const Expr *E = dyn_cast_or_null<Expr>(S))
+    S = E->IgnoreParens();
+
   SVal val = getSVal(S);
   return isTainted(val, Kind);
 }
@@ -686,8 +692,8 @@
 bool ProgramState::isTainted(SVal V, TaintTagType Kind) const {
   if (const SymExpr *Sym = V.getAsSymExpr())
     return isTainted(Sym, Kind);
-  if (loc::MemRegionVal *RegVal = dyn_cast<loc::MemRegionVal>(&V))
-    return isTainted(RegVal->getRegion(), Kind);
+  if (const MemRegion *Reg = V.getAsRegion())
+    return isTainted(Reg, Kind);
   return false;
 }
 

Modified: cfe/branches/tooling/test/Analysis/taint-tester.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Analysis/taint-tester.c?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/test/Analysis/taint-tester.c (original)
+++ cfe/branches/tooling/test/Analysis/taint-tester.c Sat Dec 17 00:38:54 2011
@@ -111,10 +111,6 @@
   fprintf(fp, "%s %d", s, t); // expected-warning + {{tainted}}
   fclose(fp); // expected-warning + {{tainted}}
 
-  // Check if we propagate taint from stdin when it's used in an assignment.
-  FILE *pfstd = stdin;
-  fscanf(pfstd, "%s %d", s, &t); // TODO: This should be tainted as well.
-
   // Test fscanf and fopen.
   if((fp=fopen("test","r")) == 0) // expected-warning + {{tainted}}
     return 1;
@@ -122,3 +118,62 @@
   fprintf(stdout, "%s %d", s, t); // expected-warning + {{tainted}}
   return 0;
 }
+
+// Check if we propagate taint from stdin when it's used in an assignment.
+void stdinTest1() {
+  int i;
+  fscanf(stdin, "%d", &i);
+  int j = i; // expected-warning + {{tainted}}
+}
+void stdinTest2(FILE *pIn) {
+  FILE *p = stdin;
+  FILE *pp = p;
+  int ii;
+
+  fscanf(pp, "%d", &ii);
+  int jj = ii;// expected-warning + {{tainted}}
+
+  fscanf(p, "%d", &ii);
+  int jj2 = ii;// expected-warning + {{tainted}}
+
+  ii = 3;
+  int jj3 = ii;// no warning
+
+  p = pIn;
+  fscanf(p, "%d", &ii);
+  int jj4 = ii;// no warning
+}
+
+void stdinTest3() {
+  FILE **ppp = &stdin;
+  int iii;
+  fscanf(*ppp, "%d", &iii);
+  int jjj = iii;// expected-warning + {{tainted}}
+}
+
+// Test propagation functions - the ones that propagate taint from arguments to
+// return value, ptr arguments.
+
+int atoi(const char *nptr);
+long atol(const char *nptr);
+long long atoll(const char *nptr);
+
+void atoiTest() {
+  char s[80];
+  scanf("%s", s);
+  int d = atoi(s); // expected-warning + {{tainted}}
+  int td = d; // expected-warning + {{tainted}}
+
+  // TODO: We shouldn't have to redefine the taint source here.
+  char sl[80];
+  scanf("%s", sl);
+  long l = atol(sl); // expected-warning + {{tainted}}
+  int tl = l; // expected-warning + {{tainted}}
+
+  char sll[80];
+  scanf("%s", sll);
+  long long ll = atoll(sll); // expected-warning + {{tainted}}
+  int tll = ll; // expected-warning + {{tainted}}
+
+}
+

Modified: cfe/branches/tooling/test/CXX/expr/expr.const/p2-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/expr/expr.const/p2-0x.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/expr/expr.const/p2-0x.cpp (original)
+++ cfe/branches/tooling/test/CXX/expr/expr.const/p2-0x.cpp Sat Dec 17 00:38:54 2011
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 -pedantic -verify -fcxx-exceptions %s -fconstexpr-depth 256
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -pedantic -verify -fcxx-exceptions %s -fconstexpr-depth 128
 
 // A conditional-expression is a core constant expression unless it involves one
 // of the following as a potentially evaluated subexpression [...]:
@@ -56,7 +56,7 @@
     return n; // expected-note {{reference to temporary cannot be returned from a constexpr function}}
   }
   struct NonConstExprFunction {
-    int n : id_ref( // expected-error {{constant expression}}
+    int n : id_ref( // expected-error {{constant expression}} expected-note {{in call to 'id_ref(16)'}}
         16 // expected-note {{temporary created here}}
         );
   };
@@ -64,10 +64,10 @@
     return &a; // expected-note {{pointer to 'n' cannot be returned from a constexpr function}}
   }
   constexpr const int *return_param(int n) { // expected-note {{declared here}}
-    return address_of(n);
+    return address_of(n); // expected-note {{in call to 'address_of(n)'}}
   }
   struct S {
-    int n : *return_param(0); // expected-error {{constant expression}}
+    int n : *return_param(0); // expected-error {{constant expression}} expected-note {{in call to 'return_param(0)'}}
   };
 }
 
@@ -87,7 +87,7 @@
   constexpr T t2(0); // expected-error {{must be initialized by a constant expression}}
 
   struct S {
-    int n : T(4).r; // expected-error {{constant expression}} expected-note {{temporary created here}}
+    int n : T(4).r; // expected-error {{constant expression}} expected-note {{temporary created here}} expected-note {{in call to 'T(4)'}}
   };
 }
 
@@ -95,17 +95,17 @@
 //   exceed the implementation-defined recursion limits (see Annex B);
 namespace RecursionLimits {
   constexpr int RecurseForever(int n) {
-    return n + RecurseForever(n+1); // expected-note {{constexpr evaluation exceeded maximum depth of 256 calls}}
+    return n + RecurseForever(n+1); // expected-note {{constexpr evaluation exceeded maximum depth of 128 calls}} expected-note 9{{in call to 'RecurseForever(}} expected-note {{skipping 118 calls}}
   }
   struct AlsoRecurseForever {
     constexpr AlsoRecurseForever(int n) :
-      n(AlsoRecurseForever(n+1).n) // expected-note {{constexpr evaluation exceeded maximum depth of 256 calls}}
+      n(AlsoRecurseForever(n+1).n) // expected-note {{constexpr evaluation exceeded maximum depth of 128 calls}} expected-note 9{{in call to 'AlsoRecurseForever(}} expected-note {{skipping 118 calls}}
     {}
     int n;
   };
   struct S {
-    int k : RecurseForever(0); // expected-error {{constant expression}}
-    int l : AlsoRecurseForever(0).n; // expected-error {{constant expression}}
+    int k : RecurseForever(0); // expected-error {{constant expression}} expected-note {{in call to}}
+    int l : AlsoRecurseForever(0).n; // expected-error {{constant expression}} expected-note {{in call to}}
   };
 }
 
@@ -135,7 +135,7 @@
     return q[0]; // expected-note {{dereferenced pointer past the end of subobject of 's' is not a constant expression}}
   }
   struct T {
-    int n : f(p); // expected-error {{not an integer constant expression}}
+    int n : f(p); // expected-error {{not an integer constant expression}} expected-note {{in call to 'f(&s.m + 1)'}}
   };
 }
 

Modified: cfe/branches/tooling/test/CXX/special/class.dtor/p10-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/special/class.dtor/p10-0x.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/special/class.dtor/p10-0x.cpp (original)
+++ cfe/branches/tooling/test/CXX/special/class.dtor/p10-0x.cpp Sat Dec 17 00:38:54 2011
@@ -5,16 +5,18 @@
 struct B {};
 template<typename T>
 void b(const T *x, const A *y) {
-  // FIXME: this parses as a pseudo destructor call which doesn't have decltype support yet
-  x->~decltype(T())(); // expected-error{{expected a class name after '~' to name a destructor}}
+  x->~decltype(T())();
+  x->~decltype(*x)(); // expected-error{{the type of object expression ('const int') does not match the type being destroyed ('decltype(*x)' (aka 'const int &')) in pseudo-destructor expression}} \
+                         expected-error{{no member named '~const struct A &' in 'A'}}
+  x->~decltype(int())(); // expected-error{{no member named '~int' in 'A'}}
 
   y->~decltype(*y)(); // expected-error{{destructor type 'decltype(*y)' (aka 'const A &') in object destruction expression does not match the type 'const A' of the object being destroyed}}
   y->~decltype(T())(); // expected-error{{destructor type 'decltype(T())' in object destruction expression does not match the type 'const A' of the object being destroyed}}
   y->~decltype(A())();
 }
-template void b(const int*, const A*);
-template void b(const A*,const A*);
-void a(const A *x) {
+template void b(const int*, const A*); // expected-note{{in instantiation of function template specialization 'b<int>' requested here}}
+template void b(const A*,const A*); // expected-note{{in instantiation of function template specialization 'b<A>' requested here}}
+void a(const A *x, int i, int *pi) {
   x->~decltype(A())();
   x->~decltype(*x)(); // expected-error{{destructor type 'decltype(*x)' (aka 'const A &') in object destruction expression does not match the type 'const A' of the object being destroyed}}
   x->~decltype()(); // expected-error{{expected expression}}
@@ -23,4 +25,15 @@
   // this last one could be better, mentioning that the nested-name-specifier could be removed or a type name after the ~
   x->::A::~decltype(*x)(); // expected-error{{expected a class name after '~' to name a destructor}}
   y->~decltype(A())(); // expected-error{{use of undeclared identifier 'y'}}
+
+  typedef int *intp;
+  i->~decltype(int())(); // expected-error{{member reference type 'int' is not a pointer; maybe you meant to use '.'?}}
+  i.~decltype(int())();
+  i->~decltype(intp())(); // expected-error{{member reference type 'int' is not a pointer; maybe you meant to use '.'?}} \
+                             expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}}
+  i.~decltype(intp())(); // expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}}
+  pi->~decltype(int())();
+  pi.~decltype(int())(); // expected-error{{the type of object expression ('int *') does not match the type being destroyed ('decltype(int())' (aka 'int')) in pseudo-destructor expression}}
+  pi.~decltype(intp())();
+  pi->~decltype(intp())(); // expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}}
 }

Modified: cfe/branches/tooling/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CXX/temp/temp.decls/temp.variadic/p5.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/test/CXX/temp/temp.decls/temp.variadic/p5.cpp (original)
+++ cfe/branches/tooling/test/CXX/temp/temp.decls/temp.variadic/p5.cpp Sat Dec 17 00:38:54 2011
@@ -162,8 +162,7 @@
 // Test for unexpanded parameter packs in declarations.
 template<typename T, typename... Types>
 // FIXME: this should test that the diagnostic reads "type contains..."
-alignas(Types) // expected-error{{expression contains unexpanded parameter pack 'Types'}}
-struct TestUnexpandedDecls : T{
+struct alignas(Types) TestUnexpandedDecls : T{ // expected-error{{expression contains unexpanded parameter pack 'Types'}}
   void member_function(Types);  // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
   void member_function () throw(Types); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
   operator Types() const; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}

Modified: cfe/branches/tooling/test/CodeGen/builtins-x86.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGen/builtins-x86.c?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGen/builtins-x86.c (original)
+++ cfe/branches/tooling/test/CodeGen/builtins-x86.c Sat Dec 17 00:38:54 2011
@@ -434,8 +434,8 @@
   tmp_V8f = __builtin_ia32_sqrtps256(tmp_V8f);
   tmp_V8f = __builtin_ia32_rsqrtps256(tmp_V8f);
   tmp_V8f = __builtin_ia32_rcpps256(tmp_V8f);
-  tmp_V4d = __builtin_ia32_roundpd256(tmp_V4d, tmp_i);
-  tmp_V8f = __builtin_ia32_roundps256(tmp_V8f, tmp_i);
+  tmp_V4d = __builtin_ia32_roundpd256(tmp_V4d, 0x1);
+  tmp_V8f = __builtin_ia32_roundps256(tmp_V8f, 0x1);
   tmp_i = __builtin_ia32_vtestzpd(tmp_V2d, tmp_V2d);
   tmp_i = __builtin_ia32_vtestcpd(tmp_V2d, tmp_V2d);
   tmp_i = __builtin_ia32_vtestnzcpd(tmp_V2d, tmp_V2d);

Modified: cfe/branches/tooling/test/CodeGenCXX/visibility.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenCXX/visibility.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenCXX/visibility.cpp (original)
+++ cfe/branches/tooling/test/CodeGenCXX/visibility.cpp Sat Dec 17 00:38:54 2011
@@ -156,7 +156,7 @@
 namespace Test10 {
   struct A;
 
-  DEFAULT class B {
+  class DEFAULT B {
     void foo(A*);
   };
 

Modified: cfe/branches/tooling/test/CodeGenObjC/debug-info-fwddecl.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenObjC/debug-info-fwddecl.m?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenObjC/debug-info-fwddecl.m (original)
+++ cfe/branches/tooling/test/CodeGenObjC/debug-info-fwddecl.m Sat Dec 17 00:38:54 2011
@@ -2,4 +2,4 @@
 @class ForwardObjcClass;
 ForwardObjcClass *ptr = 0;
 
-// CHECK: !8 = metadata !{i32 720915, metadata !6, metadata !"ForwardObjcClass", metadata !6, i32 2, i64 0, i64 0, i32 0, i32 4, i32 0, null, i32 16, i32 0} ; [ DW_TAG_structure_type ]
+// CHECK: !8 = metadata !{i32 720915, metadata !6, metadata !"ForwardObjcClass", metadata !6, i32 2, i64 0, i64 0, i32 0, i32 4, null, null, i32 16, i32 0} ; [ DW_TAG_structure_type ]

Modified: cfe/branches/tooling/test/CodeGenObjC/debug-info-pubtypes.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/CodeGenObjC/debug-info-pubtypes.m?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/test/CodeGenObjC/debug-info-pubtypes.m (original)
+++ cfe/branches/tooling/test/CodeGenObjC/debug-info-pubtypes.m Sat Dec 17 00:38:54 2011
@@ -1,7 +1,7 @@
 // REQUIRES: x86-64-registered-target
 // RUN: %clang -cc1 -triple x86_64-apple-darwin10 -g -emit-llvm %s -o - | FileCheck %s
 
-// CHECK: !10 = metadata !{i32 720915, metadata !6, metadata !"H", metadata !6, i32 6, i64 0, i64 8, i32 0, i32 512, i32 0, metadata !2, i32 16, i32 0} ; [ DW_TAG_structure_type ]
+// CHECK: !10 = metadata !{i32 720915, metadata !6, metadata !"H", metadata !6, i32 6, i64 0, i64 8, i32 0, i32 512, null, metadata !2, i32 16, i32 0} ; [ DW_TAG_structure_type ]
 
 @interface H
 -(void) foo;

Modified: cfe/branches/tooling/test/Misc/serialized-diags-single-issue.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Misc/serialized-diags-single-issue.c?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/test/Misc/serialized-diags-single-issue.c (original)
+++ cfe/branches/tooling/test/Misc/serialized-diags-single-issue.c Sat Dec 17 00:38:54 2011
@@ -13,7 +13,8 @@
 // CHECK: {{.*}}serialized-diags-single-issue.c:3:12: warning: variable 'voodoo' is uninitialized when used here [-Wuninitialized]
 // CHECK: Range: {{.*}}serialized-diags-single-issue.c:3:12 {{.*}}serialized-diags-single-issue.c:3:18
 // CHECK: +-{{.*}}serialized-diags-single-issue.c:2:13: note: initialize the variable 'voodoo' to silence this warning []
-// CHECK: +-FIXIT: {{.*}}serialized-diags-single-issue.c:2:13 - {{.*}}serialized-diags-single-issue.c:2:13): " = 0"
+// CHECK: +-Range: {{.*}}serialized-diags-single-issue.c:2:13 {{.*}}serialized-diags-single-issue.c:2:13
+// CHECK: +-FIXIT: ({{.*}}serialized-diags-single-issue.c:2:13 - {{.*}}serialized-diags-single-issue.c:2:13): " = 0"
 
 // Test that we handle serializing diagnostics for multiple source files
 // RUN: %clang_cc1 -Wall -fsyntax-only %s %s -serialize-diagnostic-file %t
@@ -23,11 +24,13 @@
 // CHECK-MULT: {{.*}}serialized-diags-single-issue.c:3:12: warning: variable 'voodoo' is uninitialized when used here [-Wuninitialized]
 // CHECK-MULT: Range: {{.*}}serialized-diags-single-issue.c:3:12 {{.*}}serialized-diags-single-issue.c:3:18
 // CHECK-MULT: +-{{.*}}serialized-diags-single-issue.c:2:13: note: initialize the variable 'voodoo' to silence this warning []
-// CHECK-MULT: +-FIXIT: {{.*}}serialized-diags-single-issue.c:2:13 - {{.*}}serialized-diags-single-issue.c:2:13): " = 0"
+// CHECK-MULT: +-Range: {{.*}}serialized-diags-single-issue.c:2:13 {{.*}}serialized-diags-single-issue.c:2:13
+// CHECK-MULT: +-FIXIT: ({{.*}}serialized-diags-single-issue.c:2:13 - {{.*}}serialized-diags-single-issue.c:2:13): " = 0"
 
 // CHECK-MULT: {{.*}}serialized-diags-single-issue.c:3:12: warning: variable 'voodoo' is uninitialized when used here [-Wuninitialized]
 // CHECK-MULT: Range: {{.*}}serialized-diags-single-issue.c:3:12 {{.*}}serialized-diags-single-issue.c:3:18
 // CHECK-MULT: +-{{.*}}serialized-diags-single-issue.c:2:13: note: initialize the variable 'voodoo' to silence this warning []
-// CHECK-MULT: +-FIXIT: {{.*}}serialized-diags-single-issue.c:2:13 - {{.*}}serialized-diags-single-issue.c:2:13): " = 0"
+// CHECK-MULT: +-Range: {{.*}}serialized-diags-single-issue.c:2:13 {{.*}}serialized-diags-single-issue.c:2:13
+// CHECK-MULT: +-FIXIT: ({{.*}}serialized-diags-single-issue.c:2:13 - {{.*}}serialized-diags-single-issue.c:2:13): " = 0"
 
 // CHECK-MULT: Number of diagnostics: 2

Modified: cfe/branches/tooling/test/Misc/serialized-diags.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Misc/serialized-diags.c?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/test/Misc/serialized-diags.c (original)
+++ cfe/branches/tooling/test/Misc/serialized-diags.c Sat Dec 17 00:38:54 2011
@@ -15,6 +15,16 @@
    return;
 }
 
+// Test handling of macros.
+void taz(int x, int y);
+#define false 0
+void testMacro() {
+  taz(0, 0, false);
+}
+
+// Test handling of issues from #includes.
+#include "serialized-diags.h"
+
 // RUN: rm -f %t
 // RUN: %clang -Wall -fsyntax-only %s --serialize-diagnostics %t > /dev/null 2>&1 || true
 // RUN: c-index-test -read-diagnostics %t 2>&1 | FileCheck %s
@@ -35,5 +45,15 @@
 // CHECK: +-FIXIT: ({{.*[/\\]}}serialized-diags.c:14:18 - {{.*[/\\]}}serialized-diags.c:14:19): ""
 // CHECK: +-{{.*[/\\]}}serialized-diags.c:14:10: note: use '=' to turn this equality comparison into an assignment []
 // CHECK: +-FIXIT: ({{.*[/\\]}}serialized-diags.c:14:10 - {{.*[/\\]}}serialized-diags.c:14:12): "="
-// CHECK: Number of diagnostics: 3
+// CHECK: {{.*[/\\]}}serialized-diags.c:22:13: error: too many arguments to function call, expected 2, have 3 []
+// CHECK: Range: {{.*[/\\]}}serialized-diags.c:22:3 {{.*[/\\]}}serialized-diags.c:22:6
+// CHECK: Range: {{.*[/\\]}}serialized-diags.c:22:13 {{.*[/\\]}}serialized-diags.c:22:18
+// CHECK: +-{{.*[/\\]}}serialized-diags.c:20:15: note: expanded from macro 'false' []
+// CHECK: +-Range: {{.*[/\\]}}serialized-diags.c:22:3 {{.*[/\\]}}serialized-diags.c:22:6
+// CHECK: +-Range: {{.*[/\\]}}serialized-diags.c:20:15 {{.*[/\\]}}serialized-diags.c:20:16
+// CHECK: +-{{.*[/\\]}}serialized-diags.c:19:1: note: 'taz' declared here []
+// CHECK: {{.*[/\\]}}serialized-diags.h:5:7: warning: incompatible integer to pointer conversion initializing 'char *' with an expression of type 'int';  []
+// CHECK: Range: {{.*[/\\]}}serialized-diags.h:5:16 {{.*[/\\]}}serialized-diags.h:5:17
+// CHECK: +-{{.*[/\\]}}serialized-diags.c:26:10: note: in file included from {{.*[/\\]}}serialized-diags.c:26: []
+// CHECK: Number of diagnostics: 5
 

Modified: cfe/branches/tooling/test/Misc/warning-flags.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Misc/warning-flags.c?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/test/Misc/warning-flags.c (original)
+++ cfe/branches/tooling/test/Misc/warning-flags.c Sat Dec 17 00:38:54 2011
@@ -17,7 +17,7 @@
 
 The list of warnings below should NEVER grow.  It should gradually shrink to 0.
 
-CHECK: Warnings without flags (271):
+CHECK: Warnings without flags (270):
 CHECK-NEXT:   ext_anon_param_requires_type_specifier
 CHECK-NEXT:   ext_anonymous_struct_union_qualified
 CHECK-NEXT:   ext_array_init_copy
@@ -28,7 +28,6 @@
 CHECK-NEXT:   ext_designated_init_cxx
 CHECK-NEXT:   ext_duplicate_declspec
 CHECK-NEXT:   ext_ellipsis_exception_spec
-CHECK-NEXT:   ext_embedded_directive
 CHECK-NEXT:   ext_empty_fnmacro_arg
 CHECK-NEXT:   ext_empty_source_file
 CHECK-NEXT:   ext_enum_friend

Modified: cfe/branches/tooling/test/Modules/Inputs/module.map
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Modules/Inputs/module.map?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/test/Modules/Inputs/module.map (original)
+++ cfe/branches/tooling/test/Modules/Inputs/module.map Sat Dec 17 00:38:54 2011
@@ -39,5 +39,6 @@
 
 module decldef {
   explicit module Decl { header "decl.h" }
+  explicit module Decl2 { header "decl2.h" }
   explicit module Def { header "def.h" }
 }
\ No newline at end of file

Modified: cfe/branches/tooling/test/Parser/method-def-in-class.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Parser/method-def-in-class.m?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/test/Parser/method-def-in-class.m (original)
+++ cfe/branches/tooling/test/Parser/method-def-in-class.m Sat Dec 17 00:38:54 2011
@@ -7,19 +7,8 @@
 }
 @end
 
- at interface B
--(id) f0 { // expected-error {{expected ';' after method prototype}}
-  assert(0);
- at end
-
 @interface C
 - (id) f0 { // expected-error {{expected ';' after method prototype}}
     assert(0);
 };
 @end
-
- at interface D
-- (id) f0 { // expected-error {{expected ';' after method prototype}}
-  assert(0);
- at property int P;
- at end

Modified: cfe/branches/tooling/test/Sema/array-bounds-ptr-arith.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Sema/array-bounds-ptr-arith.c?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/test/Sema/array-bounds-ptr-arith.c (original)
+++ cfe/branches/tooling/test/Sema/array-bounds-ptr-arith.c Sat Dec 17 00:38:54 2011
@@ -12,3 +12,10 @@
 {
 	 return (void *)es->s_uuid + 80; // expected-warning {{refers past the end of the array}}
 }
+
+// Test case reduced from PR11594
+struct S { int n; };
+void pr11594(struct S *s) {
+  int a[10];
+  int *p = a - s->n;
+}

Modified: cfe/branches/tooling/test/Sema/attr-deprecated.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Sema/attr-deprecated.c?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/test/Sema/attr-deprecated.c (original)
+++ cfe/branches/tooling/test/Sema/attr-deprecated.c Sat Dec 17 00:38:54 2011
@@ -44,8 +44,8 @@
 typedef struct foo foo_dep __attribute__((deprecated));
 foo_dep *test2;    // expected-warning {{'foo_dep' is deprecated}}
 
-struct bar_dep __attribute__((deprecated, 
-                              invalid_attribute));  // expected-warning {{unknown attribute 'invalid_attribute' ignored}}
+struct __attribute__((deprecated, 
+                      invalid_attribute)) bar_dep ;  // expected-warning {{unknown attribute 'invalid_attribute' ignored}}
 
 struct bar_dep *test3;   // expected-warning {{'bar_dep' is deprecated}}
 

Modified: cfe/branches/tooling/test/Sema/warn-cast-align.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/Sema/warn-cast-align.c?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/test/Sema/warn-cast-align.c (original)
+++ cfe/branches/tooling/test/Sema/warn-cast-align.c Sat Dec 17 00:38:54 2011
@@ -28,7 +28,7 @@
 }
 
 // Aligned struct.
-__attribute__((aligned(16))) struct A {
+struct __attribute__((aligned(16))) A {
   char buffer[16];
 };
 void test2(char *P) {

Modified: cfe/branches/tooling/test/SemaCXX/attr-cxx0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/attr-cxx0x.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/attr-cxx0x.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/attr-cxx0x.cpp Sat Dec 17 00:38:54 2011
@@ -9,7 +9,7 @@
   int member alignas(8);
 };
 
-template <unsigned A> alignas(A) struct align_class_template {};
+template <unsigned A> struct alignas(A) align_class_template {};
 
 // FIXME: these should not error
 template <typename... T> alignas(T...) struct align_class_temp_pack_type {}; // expected-error{{pack expansions in alignment specifiers are not supported yet}}

Modified: cfe/branches/tooling/test/SemaCXX/constant-expression-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/constant-expression-cxx11.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/constant-expression-cxx11.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/constant-expression-cxx11.cpp Sat Dec 17 00:38:54 2011
@@ -416,7 +416,11 @@
                        const int *xs, const int *ys, int c) {
   return n ? F(
                *xs, // expected-note {{subexpression not valid}}
-               *ys, ZipFoldR(F, n-1, xs+1, ys+1, c)) : c;
+               *ys,
+               ZipFoldR(F, n-1, xs+1, ys+1, c)) // \
+      expected-note {{in call to 'ZipFoldR(&SubMul, 2, &xs[4], &ys[4], 1)'}} \
+      expected-note {{in call to 'ZipFoldR(&SubMul, 1, &xs[5], &ys[5], 1)'}}
+           : c;
 }
 constexpr int MulAdd(int x, int y, int c) { return x * y + c; }
 constexpr int InnerProduct = ZipFoldR(MulAdd, 5, xs, ys, 0);
@@ -425,7 +429,9 @@
 constexpr int SubMul(int x, int y, int c) { return (x - y) * c; }
 constexpr int DiffProd = ZipFoldR(SubMul, 2, xs+3, ys+3, 1);
 static_assert(DiffProd == 8, "");
-static_assert(ZipFoldR(SubMul, 3, xs+3, ys+3, 1), ""); // expected-error {{constant expression}}
+static_assert(ZipFoldR(SubMul, 3, xs+3, ys+3, 1), ""); // \
+      expected-error {{constant expression}} \
+      expected-note {{in call to 'ZipFoldR(&SubMul, 3, &xs[3], &ys[3], 1)'}}
 
 constexpr const int *p = xs + 3;
 constexpr int xs4 = p[1]; // ok
@@ -441,6 +447,13 @@
 static_assert(**(**(zs + 1) + 1) == 11, "");
 static_assert(*(&(&(*(*&(&zs[2] - 1)[0] + 2 - 2))[2])[-1][-1] + 1) == 11, "");
 
+constexpr int fail(const int &p) {
+  return (&p)[64]; // expected-note {{subexpression}}
+}
+static_assert(fail(*(&(&(*(*&(&zs[2] - 1)[0] + 2 - 2))[2])[-1][-1] + 1)) == 11, ""); // \
+expected-error {{static_assert expression is not an integral constant expression}} \
+expected-note {{in call to 'fail(zs[1][0][1][0])'}}
+
 constexpr int arr[40] = { 1, 2, 3, [8] = 4 }; // expected-warning {{extension}}
 constexpr int SumNonzero(const int *p) {
   return *p + (*p ? SumNonzero(p+1) : 0);
@@ -906,3 +919,9 @@
 static_assert(makeComplexWrap(1,0) != complex(0, 1), "");
 
 }
+
+namespace PR11595 {
+  struct A { constexpr bool operator==(int x) { return true; } };
+  struct B { B(); ~B(); A& x; };
+  static_assert(B().x == 3, "");  // expected-error {{constant expression}}
+}

Modified: cfe/branches/tooling/test/SemaCXX/pseudo-destructors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaCXX/pseudo-destructors.cpp?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaCXX/pseudo-destructors.cpp (original)
+++ cfe/branches/tooling/test/SemaCXX/pseudo-destructors.cpp Sat Dec 17 00:38:54 2011
@@ -19,7 +19,7 @@
   cvt->T::~T(); // no-warning
 }
 
-void f(A* a, Foo *f, int *i, double *d) {
+void f(A* a, Foo *f, int *i, double *d, int ii) {
   a->~A();
   a->A::~A();
   
@@ -46,6 +46,9 @@
   i->N::~Integer(); // expected-error{{'Integer' does not refer to a type name in pseudo-destructor expression; expected the name of type 'int'}}
   i->Integer::~Double(); // expected-error{{the type of object expression ('int') does not match the type being destroyed ('Double' (aka 'double')) in pseudo-destructor expression}}
 
+  ii->~Integer(); // expected-error{{member reference type 'int' is not a pointer; maybe you meant to use '.'?}}
+  ii.~Integer();
+
   cv_test(a);
   cv_test(f);
   cv_test(i);

Modified: cfe/branches/tooling/test/SemaObjC/forward-class-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaObjC/forward-class-1.m?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaObjC/forward-class-1.m (original)
+++ cfe/branches/tooling/test/SemaObjC/forward-class-1.m Sat Dec 17 00:38:54 2011
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
- at class FOO, BAR; 
 @class FOO, BAR; // expected-note {{forward declaration of class here}}
+ at class FOO, BAR; 
 
 @interface INTF : FOO	// expected-error {{attempting to use the forward class 'FOO' as superclass of 'INTF'}}
 @end

Modified: cfe/branches/tooling/test/SemaObjC/nsobject-attribute.m
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/test/SemaObjC/nsobject-attribute.m?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/test/SemaObjC/nsobject-attribute.m (original)
+++ cfe/branches/tooling/test/SemaObjC/nsobject-attribute.m Sat Dec 17 00:38:54 2011
@@ -45,8 +45,7 @@
 {
    __attribute__((NSObject)) void * color; // expected-warning {{__attribute ((NSObject)) may be put on a typedef only, attribute is ignored}}
 }
- at property (nonatomic, retain) __attribute__((NSObject)) void * color; // expected-warning {{__attribute ((NSObject)) may be put on a typedef only, attribute is ignored}} \
-                                // expected-error {{property with 'retain (or strong)' attribute must be of object type}}
+ at property (nonatomic, retain) __attribute__((NSObject)) void * color; // expected-warning {{__attribute ((NSObject)) may be put on a typedef only, attribute is ignored}}
 @end
 void test_10453342() {
     char* __attribute__((NSObject)) string2 = 0; // expected-warning {{__attribute ((NSObject)) may be put on a typedef only, attribute is ignored}}

Modified: cfe/branches/tooling/unittests/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/unittests/CMakeLists.txt?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/unittests/CMakeLists.txt (original)
+++ cfe/branches/tooling/unittests/CMakeLists.txt Sat Dec 17 00:38:54 2011
@@ -50,11 +50,6 @@
   add_definitions("-Wno-variadic-macros")
 endif()
 
-add_clang_unittest(AST
-  AST/APValueTest.cpp
-  USED_LIBS gtest gtest_main clangAST
- )
-
 add_clang_unittest(ASTMatchers
   ASTMatchers/ASTMatchersTest.cpp
   USED_LIBS gtest gtest_main clangASTMatchers clangTooling

Modified: cfe/branches/tooling/unittests/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/tooling/unittests/Makefile?rev=146823&r1=146822&r2=146823&view=diff
==============================================================================
--- cfe/branches/tooling/unittests/Makefile (original)
+++ cfe/branches/tooling/unittests/Makefile Sat Dec 17 00:38:54 2011
@@ -14,7 +14,7 @@
 
 IS_UNITTEST_LEVEL := 1
 CLANG_LEVEL := ..
-PARALLEL_DIRS = AST ASTMatchers Basic Frontend Tooling
+PARALLEL_DIRS = ASTMatchers Basic Frontend Tooling
 
 endif  # CLANG_LEVEL
 





More information about the llvm-branch-commits mailing list